UNPKG

555 kBJavaScriptView Raw
1/** @license React v16.8.2
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.8.2';
25
26/**
27 * Use invariant() to assert state which your program assumes to be true.
28 *
29 * Provide sprintf-style format (only %s is supported) and arguments
30 * to provide information about what broke and what you were
31 * expecting.
32 *
33 * The invariant message will be stripped in production, but the invariant
34 * will remain to ensure logic does not differ in production.
35 */
36
37var validateFormat = function () {};
38
39{
40 validateFormat = function (format) {
41 if (format === undefined) {
42 throw new Error('invariant requires an error message argument');
43 }
44 };
45}
46
47function invariant(condition, format, a, b, c, d, e, f) {
48 validateFormat(format);
49
50 if (!condition) {
51 var error = void 0;
52 if (format === undefined) {
53 error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');
54 } else {
55 var args = [a, b, c, d, e, f];
56 var argIndex = 0;
57 error = new Error(format.replace(/%s/g, function () {
58 return args[argIndex++];
59 }));
60 error.name = 'Invariant Violation';
61 }
62
63 error.framesToPop = 1; // we don't care about invariant's own frame
64 throw error;
65 }
66}
67
68// Relying on the `invariant()` implementation lets us
69// preserve the format and params in the www builds.
70
71/**
72 * Similar to invariant but only logs a warning if the condition is not met.
73 * This can be used to log issues in development environments in critical
74 * paths. Removing the logging code for production environments will keep the
75 * same logic and follow the same code paths.
76 */
77
78var warningWithoutStack = function () {};
79
80{
81 warningWithoutStack = function (condition, format) {
82 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
83 args[_key - 2] = arguments[_key];
84 }
85
86 if (format === undefined) {
87 throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
88 }
89 if (args.length > 8) {
90 // Check before the condition to catch violations early.
91 throw new Error('warningWithoutStack() currently supports at most 8 arguments.');
92 }
93 if (condition) {
94 return;
95 }
96 if (typeof console !== 'undefined') {
97 var argsWithFormat = args.map(function (item) {
98 return '' + item;
99 });
100 argsWithFormat.unshift('Warning: ' + format);
101
102 // We intentionally don't use spread (or .apply) directly because it
103 // breaks IE9: https://github.com/facebook/react/issues/13610
104 Function.prototype.apply.call(console.error, console, argsWithFormat);
105 }
106 try {
107 // --- Welcome to debugging React ---
108 // This error was thrown as a convenience so that you can use this stack
109 // to find the callsite that caused this warning to fire.
110 var argIndex = 0;
111 var message = 'Warning: ' + format.replace(/%s/g, function () {
112 return args[argIndex++];
113 });
114 throw new Error(message);
115 } catch (x) {}
116 };
117}
118
119var warningWithoutStack$1 = warningWithoutStack;
120
121/**
122 * `ReactInstanceMap` maintains a mapping from a public facing stateful
123 * instance (key) and the internal representation (value). This allows public
124 * methods to accept the user facing instance as an argument and map them back
125 * to internal methods.
126 *
127 * Note that this module is currently shared and assumed to be stateless.
128 * If this becomes an actual Map, that will break.
129 */
130
131/**
132 * This API should be called `delete` but we'd have to make sure to always
133 * transform these to strings for IE support. When this transform is fully
134 * supported we can rename it.
135 */
136
137
138function get(key) {
139 return key._reactInternalFiber;
140}
141
142
143
144function set(key, value) {
145 key._reactInternalFiber = value;
146}
147
148var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
149
150// Prevent newer renderers from RTE when used with older react package versions.
151// Current owner and dispatcher used to share the same ref,
152// but PR #14548 split them out to better support the react-debug-tools package.
153if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
154 ReactSharedInternals.ReactCurrentDispatcher = {
155 current: null
156 };
157}
158
159// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
160// nor polyfill, then a plain number is used for performance.
161var hasSymbol = typeof Symbol === 'function' && Symbol.for;
162
163var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
164var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
165var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
166var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
167var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
168var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
169var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace;
170
171var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
172var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
173var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
174var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
175var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
176
177var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
178var FAUX_ITERATOR_SYMBOL = '@@iterator';
179
180function getIteratorFn(maybeIterable) {
181 if (maybeIterable === null || typeof maybeIterable !== 'object') {
182 return null;
183 }
184 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
185 if (typeof maybeIterator === 'function') {
186 return maybeIterator;
187 }
188 return null;
189}
190
191var Pending = 0;
192var Resolved = 1;
193var Rejected = 2;
194
195function refineResolvedLazyComponent(lazyComponent) {
196 return lazyComponent._status === Resolved ? lazyComponent._result : null;
197}
198
199function getWrappedName(outerType, innerType, wrapperName) {
200 var functionName = innerType.displayName || innerType.name || '';
201 return outerType.displayName || (functionName !== '' ? wrapperName + '(' + functionName + ')' : wrapperName);
202}
203
204function getComponentName(type) {
205 if (type == null) {
206 // Host root, text node or just invalid type.
207 return null;
208 }
209 {
210 if (typeof type.tag === 'number') {
211 warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
212 }
213 }
214 if (typeof type === 'function') {
215 return type.displayName || type.name || null;
216 }
217 if (typeof type === 'string') {
218 return type;
219 }
220 switch (type) {
221 case REACT_CONCURRENT_MODE_TYPE:
222 return 'ConcurrentMode';
223 case REACT_FRAGMENT_TYPE:
224 return 'Fragment';
225 case REACT_PORTAL_TYPE:
226 return 'Portal';
227 case REACT_PROFILER_TYPE:
228 return 'Profiler';
229 case REACT_STRICT_MODE_TYPE:
230 return 'StrictMode';
231 case REACT_SUSPENSE_TYPE:
232 return 'Suspense';
233 }
234 if (typeof type === 'object') {
235 switch (type.$$typeof) {
236 case REACT_CONTEXT_TYPE:
237 return 'Context.Consumer';
238 case REACT_PROVIDER_TYPE:
239 return 'Context.Provider';
240 case REACT_FORWARD_REF_TYPE:
241 return getWrappedName(type, type.render, 'ForwardRef');
242 case REACT_MEMO_TYPE:
243 return getComponentName(type.type);
244 case REACT_LAZY_TYPE:
245 {
246 var thenable = type;
247 var resolvedThenable = refineResolvedLazyComponent(thenable);
248 if (resolvedThenable) {
249 return getComponentName(resolvedThenable);
250 }
251 }
252 }
253 }
254 return null;
255}
256
257var FunctionComponent = 0;
258var ClassComponent = 1;
259var IndeterminateComponent = 2; // Before we know whether it is function or class
260var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
261var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
262var HostComponent = 5;
263var HostText = 6;
264var Fragment = 7;
265var Mode = 8;
266var ContextConsumer = 9;
267var ContextProvider = 10;
268var ForwardRef = 11;
269var Profiler = 12;
270var SuspenseComponent = 13;
271var MemoComponent = 14;
272var SimpleMemoComponent = 15;
273var LazyComponent = 16;
274var IncompleteClassComponent = 17;
275var DehydratedSuspenseComponent = 18;
276
277// Don't change these two values. They're used by React Dev Tools.
278var NoEffect = /* */0;
279var PerformedWork = /* */1;
280
281// You can change the rest (and add more).
282var Placement = /* */2;
283var Update = /* */4;
284var PlacementAndUpdate = /* */6;
285var Deletion = /* */8;
286var ContentReset = /* */16;
287var Callback = /* */32;
288var DidCapture = /* */64;
289var Ref = /* */128;
290var Snapshot = /* */256;
291var Passive = /* */512;
292
293// Passive & Update & Callback & Ref & Snapshot
294var LifecycleEffectMask = /* */932;
295
296// Union of all host effects
297var HostEffectMask = /* */1023;
298
299var Incomplete = /* */1024;
300var ShouldCapture = /* */2048;
301
302var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
303
304var MOUNTING = 1;
305var MOUNTED = 2;
306var UNMOUNTED = 3;
307
308function isFiberMountedImpl(fiber) {
309 var node = fiber;
310 if (!fiber.alternate) {
311 // If there is no alternate, this might be a new tree that isn't inserted
312 // yet. If it is, then it will have a pending insertion effect on it.
313 if ((node.effectTag & Placement) !== NoEffect) {
314 return MOUNTING;
315 }
316 while (node.return) {
317 node = node.return;
318 if ((node.effectTag & Placement) !== NoEffect) {
319 return MOUNTING;
320 }
321 }
322 } else {
323 while (node.return) {
324 node = node.return;
325 }
326 }
327 if (node.tag === HostRoot) {
328 // TODO: Check if this was a nested HostRoot when used with
329 // renderContainerIntoSubtree.
330 return MOUNTED;
331 }
332 // If we didn't hit the root, that means that we're in an disconnected tree
333 // that has been unmounted.
334 return UNMOUNTED;
335}
336
337function isFiberMounted(fiber) {
338 return isFiberMountedImpl(fiber) === MOUNTED;
339}
340
341function isMounted(component) {
342 {
343 var owner = ReactCurrentOwner.current;
344 if (owner !== null && owner.tag === ClassComponent) {
345 var ownerFiber = owner;
346 var instance = ownerFiber.stateNode;
347 !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;
348 instance._warnedAboutRefsInRender = true;
349 }
350 }
351
352 var fiber = get(component);
353 if (!fiber) {
354 return false;
355 }
356 return isFiberMountedImpl(fiber) === MOUNTED;
357}
358
359function assertIsMounted(fiber) {
360 !(isFiberMountedImpl(fiber) === MOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
361}
362
363function findCurrentFiberUsingSlowPath(fiber) {
364 var alternate = fiber.alternate;
365 if (!alternate) {
366 // If there is no alternate, then we only need to check if it is mounted.
367 var state = isFiberMountedImpl(fiber);
368 !(state !== UNMOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
369 if (state === MOUNTING) {
370 return null;
371 }
372 return fiber;
373 }
374 // If we have two possible branches, we'll walk backwards up to the root
375 // to see what path the root points to. On the way we may hit one of the
376 // special cases and we'll deal with them.
377 var a = fiber;
378 var b = alternate;
379 while (true) {
380 var parentA = a.return;
381 var parentB = parentA ? parentA.alternate : null;
382 if (!parentA || !parentB) {
383 // We're at the root.
384 break;
385 }
386
387 // If both copies of the parent fiber point to the same child, we can
388 // assume that the child is current. This happens when we bailout on low
389 // priority: the bailed out fiber's child reuses the current child.
390 if (parentA.child === parentB.child) {
391 var child = parentA.child;
392 while (child) {
393 if (child === a) {
394 // We've determined that A is the current branch.
395 assertIsMounted(parentA);
396 return fiber;
397 }
398 if (child === b) {
399 // We've determined that B is the current branch.
400 assertIsMounted(parentA);
401 return alternate;
402 }
403 child = child.sibling;
404 }
405 // We should never have an alternate for any mounting node. So the only
406 // way this could possibly happen is if this was unmounted, if at all.
407 invariant(false, 'Unable to find node on an unmounted component.');
408 }
409
410 if (a.return !== b.return) {
411 // The return pointer of A and the return pointer of B point to different
412 // fibers. We assume that return pointers never criss-cross, so A must
413 // belong to the child set of A.return, and B must belong to the child
414 // set of B.return.
415 a = parentA;
416 b = parentB;
417 } else {
418 // The return pointers point to the same fiber. We'll have to use the
419 // default, slow path: scan the child sets of each parent alternate to see
420 // which child belongs to which set.
421 //
422 // Search parent A's child set
423 var didFindChild = false;
424 var _child = parentA.child;
425 while (_child) {
426 if (_child === a) {
427 didFindChild = true;
428 a = parentA;
429 b = parentB;
430 break;
431 }
432 if (_child === b) {
433 didFindChild = true;
434 b = parentA;
435 a = parentB;
436 break;
437 }
438 _child = _child.sibling;
439 }
440 if (!didFindChild) {
441 // Search parent B's child set
442 _child = parentB.child;
443 while (_child) {
444 if (_child === a) {
445 didFindChild = true;
446 a = parentB;
447 b = parentA;
448 break;
449 }
450 if (_child === b) {
451 didFindChild = true;
452 b = parentB;
453 a = parentA;
454 break;
455 }
456 _child = _child.sibling;
457 }
458 !didFindChild ? invariant(false, 'Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.') : void 0;
459 }
460 }
461
462 !(a.alternate === b) ? invariant(false, 'Return fibers should always be each others\' alternates. This error is likely caused by a bug in React. Please file an issue.') : void 0;
463 }
464 // If the root is not a host container, we're in a disconnected tree. I.e.
465 // unmounted.
466 !(a.tag === HostRoot) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
467 if (a.stateNode.current === a) {
468 // We've determined that A is the current branch.
469 return fiber;
470 }
471 // Otherwise B has to be current branch.
472 return alternate;
473}
474
475function findCurrentHostFiber(parent) {
476 var currentParent = findCurrentFiberUsingSlowPath(parent);
477 if (!currentParent) {
478 return null;
479 }
480
481 // Next we'll drill down this component to find the first HostComponent/Text.
482 var node = currentParent;
483 while (true) {
484 if (node.tag === HostComponent || node.tag === HostText) {
485 return node;
486 } else if (node.child) {
487 node.child.return = node;
488 node = node.child;
489 continue;
490 }
491 if (node === currentParent) {
492 return null;
493 }
494 while (!node.sibling) {
495 if (!node.return || node.return === currentParent) {
496 return null;
497 }
498 node = node.return;
499 }
500 node.sibling.return = node.return;
501 node = node.sibling;
502 }
503 // Flow needs the return null here, but ESLint complains about it.
504 // eslint-disable-next-line no-unreachable
505 return null;
506}
507
508var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
509
510var _ReactInternals$Sched = ReactInternals$1.Scheduler;
511var unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback;
512var unstable_now = _ReactInternals$Sched.unstable_now;
513var unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback;
514var unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield;
515var unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode;
516var unstable_runWithPriority = _ReactInternals$Sched.unstable_runWithPriority;
517var unstable_next = _ReactInternals$Sched.unstable_next;
518var unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution;
519var unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution;
520var unstable_getCurrentPriorityLevel = _ReactInternals$Sched.unstable_getCurrentPriorityLevel;
521var unstable_ImmediatePriority = _ReactInternals$Sched.unstable_ImmediatePriority;
522var unstable_UserBlockingPriority = _ReactInternals$Sched.unstable_UserBlockingPriority;
523var unstable_NormalPriority = _ReactInternals$Sched.unstable_NormalPriority;
524var unstable_LowPriority = _ReactInternals$Sched.unstable_LowPriority;
525var unstable_IdlePriority = _ReactInternals$Sched.unstable_IdlePriority;
526
527var _class = function(mixins){
528 var proto = {};
529 for (var i = 0, l = arguments.length; i < l; i++){
530 var mixin = arguments[i];
531 if (typeof mixin == 'function') mixin = mixin.prototype;
532 for (var key in mixin) proto[key] = mixin[key];
533 }
534 if (!proto.initialize) proto.initialize = function(){};
535 proto.constructor = function(a,b,c,d,e,f,g,h){
536 return new proto.initialize(a,b,c,d,e,f,g,h);
537 };
538 proto.constructor.prototype = proto.initialize.prototype = proto;
539 return proto.constructor;
540};
541
542function Transform(xx, yx, xy, yy, x, y){
543 if (xx && typeof xx == 'object'){
544 yx = xx.yx; yy = xx.yy; y = xx.y;
545 xy = xx.xy; x = xx.x; xx = xx.xx;
546 }
547 this.xx = xx == null ? 1 : xx;
548 this.yx = yx || 0;
549 this.xy = xy || 0;
550 this.yy = yy == null ? 1 : yy;
551 this.x = (x == null ? this.x : x) || 0;
552 this.y = (y == null ? this.y : y) || 0;
553 this._transform();
554 return this;
555}
556
557var transform = _class({
558
559 initialize: Transform,
560
561 _transform: function(){},
562
563 xx: 1, yx: 0, x: 0,
564 xy: 0, yy: 1, y: 0,
565
566 transform: function(xx, yx, xy, yy, x, y){
567 var m = this;
568 if (xx && typeof xx == 'object'){
569 yx = xx.yx; yy = xx.yy; y = xx.y;
570 xy = xx.xy; x = xx.x; xx = xx.xx;
571 }
572 if (!x) x = 0;
573 if (!y) y = 0;
574 return this.transformTo(
575 m.xx * xx + m.xy * yx,
576 m.yx * xx + m.yy * yx,
577 m.xx * xy + m.xy * yy,
578 m.yx * xy + m.yy * yy,
579 m.xx * x + m.xy * y + m.x,
580 m.yx * x + m.yy * y + m.y
581 );
582 },
583
584 transformTo: Transform,
585
586 translate: function(x, y){
587 return this.transform(1, 0, 0, 1, x, y);
588 },
589
590 move: function(x, y){
591 this.x += x || 0;
592 this.y += y || 0;
593 this._transform();
594 return this;
595 },
596
597 scale: function(x, y){
598 if (y == null) y = x;
599 return this.transform(x, 0, 0, y, 0, 0);
600 },
601
602 rotate: function(deg, x, y){
603 if (x == null || y == null){
604 x = (this.left || 0) + (this.width || 0) / 2;
605 y = (this.top || 0) + (this.height || 0) / 2;
606 }
607
608 var rad = deg * Math.PI / 180, sin = Math.sin(rad), cos = Math.cos(rad);
609
610 this.transform(1, 0, 0, 1, x, y);
611 var m = this;
612
613 return this.transformTo(
614 cos * m.xx - sin * m.yx,
615 sin * m.xx + cos * m.yx,
616 cos * m.xy - sin * m.yy,
617 sin * m.xy + cos * m.yy,
618 m.x,
619 m.y
620 ).transform(1, 0, 0, 1, -x, -y);
621 },
622
623 moveTo: function(x, y){
624 var m = this;
625 return this.transformTo(m.xx, m.yx, m.xy, m.yy, x, y);
626 },
627
628 rotateTo: function(deg, x, y){
629 var m = this;
630 var flip = m.yx / m.xx > m.yy / m.xy ? -1 : 1;
631 if (m.xx < 0 ? m.xy >= 0 : m.xy < 0) flip = -flip;
632 return this.rotate(deg - Math.atan2(flip * m.yx, flip * m.xx) * 180 / Math.PI, x, y);
633 },
634
635 scaleTo: function(x, y){
636 // Normalize
637 var m = this;
638
639 var h = Math.sqrt(m.xx * m.xx + m.yx * m.yx);
640 m.xx /= h; m.yx /= h;
641
642 h = Math.sqrt(m.yy * m.yy + m.xy * m.xy);
643 m.yy /= h; m.xy /= h;
644
645 return this.scale(x, y);
646 },
647
648 resizeTo: function(width, height){
649 var w = this.width, h = this.height;
650 if (!w || !h) return this;
651 return this.scaleTo(width / w, height / h);
652 },
653
654 /*
655 inverse: function(){
656 var a = this.xx, b = this.yx,
657 c = this.xy, d = this.yy,
658 e = this.x, f = this.y;
659 if (a * d - b * c == 0) return null;
660 return new Transform(
661 d/(a * d-b * c), b/(b * c-a * d),
662 c/(b * c-a * d), a/(a * d-b * c),
663 (d * e-c * f)/(b * c-a * d), (b * e-a * f)/(a * d-b * c)
664 );
665 },
666 */
667
668 inversePoint: function(x, y){
669 var a = this.xx, b = this.yx,
670 c = this.xy, d = this.yy,
671 e = this.x, f = this.y;
672 var det = b * c - a * d;
673 if (det == 0) return null;
674 return {
675 x: (d * (e - x) + c * (y - f)) / det,
676 y: (a * (f - y) + b * (x - e)) / det
677 };
678 },
679
680 point: function(x, y){
681 var m = this;
682 return {
683 x: m.xx * x + m.xy * y + m.x,
684 y: m.yx * x + m.yy * y + m.y
685 };
686 }
687
688});
689
690var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
691
692
693
694
695
696function createCommonjsModule(fn, module) {
697 return module = { exports: {} }, fn(module, module.exports), module.exports;
698}
699
700var current = createCommonjsModule(function (module, exports) {
701function warning(){
702 throw new Error('You must require a mode before requiring anything else.');
703}
704
705exports.Surface = warning;
706exports.Path = warning;
707exports.Shape = warning;
708exports.Group = warning;
709exports.ClippingRectangle = warning;
710exports.Text = warning;
711
712exports.setCurrent = function(mode){
713 for (var key in mode){
714 exports[key] = mode[key];
715 }
716};
717});
718
719var current_1 = current.Surface;
720var current_2 = current.Path;
721var current_3 = current.Shape;
722var current_4 = current.Group;
723var current_5 = current.ClippingRectangle;
724var current_6 = current.Text;
725var current_7 = current.setCurrent;
726
727var TYPES = {
728 CLIPPING_RECTANGLE: 'ClippingRectangle',
729 GROUP: 'Group',
730 SHAPE: 'Shape',
731 TEXT: 'Text'
732};
733
734var EVENT_TYPES = {
735 onClick: 'click',
736 onMouseMove: 'mousemove',
737 onMouseOver: 'mouseover',
738 onMouseOut: 'mouseout',
739 onMouseUp: 'mouseup',
740 onMouseDown: 'mousedown'
741};
742
743function childrenAsString(children) {
744 if (!children) {
745 return '';
746 } else if (typeof children === 'string') {
747 return children;
748 } else if (children.length) {
749 return children.join('');
750 } else {
751 return '';
752 }
753}
754
755// Renderers that don't support persistence
756// can re-export everything from this module.
757
758function shim() {
759 invariant(false, 'The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue.');
760}
761
762// Persistence (when unsupported)
763var supportsPersistence = false;
764var cloneInstance = shim;
765var createContainerChildSet = shim;
766var appendChildToContainerChildSet = shim;
767var finalizeContainerChildren = shim;
768var replaceContainerChildren = shim;
769var cloneHiddenInstance = shim;
770var cloneUnhiddenInstance = shim;
771var createHiddenTextInstance = shim;
772
773// Renderers that don't support hydration
774// can re-export everything from this module.
775
776function shim$1() {
777 invariant(false, 'The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue.');
778}
779
780// Hydration (when unsupported)
781
782var supportsHydration = false;
783var canHydrateInstance = shim$1;
784var canHydrateTextInstance = shim$1;
785var canHydrateSuspenseInstance = shim$1;
786var getNextHydratableSibling = shim$1;
787var getFirstHydratableChild = shim$1;
788var hydrateInstance = shim$1;
789var hydrateTextInstance = shim$1;
790var getNextHydratableInstanceAfterSuspenseInstance = shim$1;
791var clearSuspenseBoundary = shim$1;
792var clearSuspenseBoundaryFromContainer = shim$1;
793var didNotMatchHydratedContainerTextInstance = shim$1;
794var didNotMatchHydratedTextInstance = shim$1;
795var didNotHydrateContainerInstance = shim$1;
796var didNotHydrateInstance = shim$1;
797var didNotFindHydratableContainerInstance = shim$1;
798var didNotFindHydratableContainerTextInstance = shim$1;
799var didNotFindHydratableContainerSuspenseInstance = shim$1;
800var didNotFindHydratableInstance = shim$1;
801var didNotFindHydratableTextInstance = shim$1;
802var didNotFindHydratableSuspenseInstance = shim$1;
803
804var pooledTransform = new transform();
805
806var NO_CONTEXT = {};
807var UPDATE_SIGNAL = {};
808{
809 Object.freeze(NO_CONTEXT);
810 Object.freeze(UPDATE_SIGNAL);
811}
812
813/** Helper Methods */
814
815function addEventListeners(instance, type, listener) {
816 // We need to explicitly unregister before unmount.
817 // For this reason we need to track subscriptions.
818 if (!instance._listeners) {
819 instance._listeners = {};
820 instance._subscriptions = {};
821 }
822
823 instance._listeners[type] = listener;
824
825 if (listener) {
826 if (!instance._subscriptions[type]) {
827 instance._subscriptions[type] = instance.subscribe(type, createEventHandler(instance), instance);
828 }
829 } else {
830 if (instance._subscriptions[type]) {
831 instance._subscriptions[type]();
832 delete instance._subscriptions[type];
833 }
834 }
835}
836
837function createEventHandler(instance) {
838 return function handleEvent(event) {
839 var listener = instance._listeners[event.type];
840
841 if (!listener) {
842 // Noop
843 } else if (typeof listener === 'function') {
844 listener.call(instance, event);
845 } else if (listener.handleEvent) {
846 listener.handleEvent(event);
847 }
848 };
849}
850
851function destroyEventListeners(instance) {
852 if (instance._subscriptions) {
853 for (var type in instance._subscriptions) {
854 instance._subscriptions[type]();
855 }
856 }
857
858 instance._subscriptions = null;
859 instance._listeners = null;
860}
861
862function getScaleX(props) {
863 if (props.scaleX != null) {
864 return props.scaleX;
865 } else if (props.scale != null) {
866 return props.scale;
867 } else {
868 return 1;
869 }
870}
871
872function getScaleY(props) {
873 if (props.scaleY != null) {
874 return props.scaleY;
875 } else if (props.scale != null) {
876 return props.scale;
877 } else {
878 return 1;
879 }
880}
881
882function isSameFont(oldFont, newFont) {
883 if (oldFont === newFont) {
884 return true;
885 } else if (typeof newFont === 'string' || typeof oldFont === 'string') {
886 return false;
887 } else {
888 return newFont.fontSize === oldFont.fontSize && newFont.fontStyle === oldFont.fontStyle && newFont.fontVariant === oldFont.fontVariant && newFont.fontWeight === oldFont.fontWeight && newFont.fontFamily === oldFont.fontFamily;
889 }
890}
891
892/** Render Methods */
893
894function applyClippingRectangleProps(instance, props) {
895 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
896
897 applyNodeProps(instance, props, prevProps);
898
899 instance.width = props.width;
900 instance.height = props.height;
901}
902
903function applyGroupProps(instance, props) {
904 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
905
906 applyNodeProps(instance, props, prevProps);
907
908 instance.width = props.width;
909 instance.height = props.height;
910}
911
912function applyNodeProps(instance, props) {
913 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
914
915 var scaleX = getScaleX(props);
916 var scaleY = getScaleY(props);
917
918 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);
919
920 if (props.transform != null) {
921 pooledTransform.transform(props.transform);
922 }
923
924 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) {
925 instance.transformTo(pooledTransform);
926 }
927
928 if (props.cursor !== prevProps.cursor || props.title !== prevProps.title) {
929 instance.indicate(props.cursor, props.title);
930 }
931
932 if (instance.blend && props.opacity !== prevProps.opacity) {
933 instance.blend(props.opacity == null ? 1 : props.opacity);
934 }
935
936 if (props.visible !== prevProps.visible) {
937 if (props.visible == null || props.visible) {
938 instance.show();
939 } else {
940 instance.hide();
941 }
942 }
943
944 for (var type in EVENT_TYPES) {
945 addEventListeners(instance, EVENT_TYPES[type], props[type]);
946 }
947}
948
949function applyRenderableNodeProps(instance, props) {
950 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
951
952 applyNodeProps(instance, props, prevProps);
953
954 if (prevProps.fill !== props.fill) {
955 if (props.fill && props.fill.applyFill) {
956 props.fill.applyFill(instance);
957 } else {
958 instance.fill(props.fill);
959 }
960 }
961 if (prevProps.stroke !== props.stroke || prevProps.strokeWidth !== props.strokeWidth || prevProps.strokeCap !== props.strokeCap || prevProps.strokeJoin !== props.strokeJoin ||
962 // TODO: Consider deep check of stokeDash; may benefit VML in IE.
963 prevProps.strokeDash !== props.strokeDash) {
964 instance.stroke(props.stroke, props.strokeWidth, props.strokeCap, props.strokeJoin, props.strokeDash);
965 }
966}
967
968function applyShapeProps(instance, props) {
969 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
970
971 applyRenderableNodeProps(instance, props, prevProps);
972
973 var path = props.d || childrenAsString(props.children);
974
975 var prevDelta = instance._prevDelta;
976 var prevPath = instance._prevPath;
977
978 if (path !== prevPath || path.delta !== prevDelta || prevProps.height !== props.height || prevProps.width !== props.width) {
979 instance.draw(path, props.width, props.height);
980
981 instance._prevDelta = path.delta;
982 instance._prevPath = path;
983 }
984}
985
986function applyTextProps(instance, props) {
987 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
988
989 applyRenderableNodeProps(instance, props, prevProps);
990
991 var string = props.children;
992
993 if (instance._currentString !== string || !isSameFont(props.font, prevProps.font) || props.alignment !== prevProps.alignment || props.path !== prevProps.path) {
994 instance.draw(string, props.font, props.alignment, props.path);
995
996 instance._currentString = string;
997 }
998}
999
1000function appendInitialChild(parentInstance, child) {
1001 if (typeof child === 'string') {
1002 // Noop for string children of Text (eg <Text>{'foo'}{'bar'}</Text>)
1003 invariant(false, 'Text children should already be flattened.');
1004 return;
1005 }
1006
1007 child.inject(parentInstance);
1008}
1009
1010function createInstance(type, props, internalInstanceHandle) {
1011 var instance = void 0;
1012
1013 switch (type) {
1014 case TYPES.CLIPPING_RECTANGLE:
1015 instance = current.ClippingRectangle();
1016 instance._applyProps = applyClippingRectangleProps;
1017 break;
1018 case TYPES.GROUP:
1019 instance = current.Group();
1020 instance._applyProps = applyGroupProps;
1021 break;
1022 case TYPES.SHAPE:
1023 instance = current.Shape();
1024 instance._applyProps = applyShapeProps;
1025 break;
1026 case TYPES.TEXT:
1027 instance = current.Text(props.children, props.font, props.alignment, props.path);
1028 instance._applyProps = applyTextProps;
1029 break;
1030 }
1031
1032 !instance ? invariant(false, 'ReactART does not support the type "%s"', type) : void 0;
1033
1034 instance._applyProps(instance, props);
1035
1036 return instance;
1037}
1038
1039function createTextInstance(text, rootContainerInstance, internalInstanceHandle) {
1040 return text;
1041}
1042
1043function finalizeInitialChildren(domElement, type, props) {
1044 return false;
1045}
1046
1047function getPublicInstance(instance) {
1048 return instance;
1049}
1050
1051function prepareForCommit() {
1052 // Noop
1053}
1054
1055function prepareUpdate(domElement, type, oldProps, newProps) {
1056 return UPDATE_SIGNAL;
1057}
1058
1059function resetAfterCommit() {
1060 // Noop
1061}
1062
1063function resetTextContent(domElement) {
1064 // Noop
1065}
1066
1067function shouldDeprioritizeSubtree(type, props) {
1068 return false;
1069}
1070
1071function getRootHostContext() {
1072 return NO_CONTEXT;
1073}
1074
1075function getChildHostContext() {
1076 return NO_CONTEXT;
1077}
1078
1079var scheduleTimeout = setTimeout;
1080var cancelTimeout = clearTimeout;
1081var noTimeout = -1;
1082var schedulePassiveEffects = unstable_scheduleCallback;
1083var cancelPassiveEffects = unstable_cancelCallback;
1084
1085function shouldSetTextContent(type, props) {
1086 return typeof props.children === 'string' || typeof props.children === 'number';
1087}
1088
1089// The ART renderer is secondary to the React DOM renderer.
1090var isPrimaryRenderer = false;
1091
1092var supportsMutation = true;
1093
1094function appendChild(parentInstance, child) {
1095 if (child.parentNode === parentInstance) {
1096 child.eject();
1097 }
1098 child.inject(parentInstance);
1099}
1100
1101function appendChildToContainer(parentInstance, child) {
1102 if (child.parentNode === parentInstance) {
1103 child.eject();
1104 }
1105 child.inject(parentInstance);
1106}
1107
1108function insertBefore(parentInstance, child, beforeChild) {
1109 !(child !== beforeChild) ? invariant(false, 'ReactART: Can not insert node before itself') : void 0;
1110 child.injectBefore(beforeChild);
1111}
1112
1113function insertInContainerBefore(parentInstance, child, beforeChild) {
1114 !(child !== beforeChild) ? invariant(false, 'ReactART: Can not insert node before itself') : void 0;
1115 child.injectBefore(beforeChild);
1116}
1117
1118function removeChild(parentInstance, child) {
1119 destroyEventListeners(child);
1120 child.eject();
1121}
1122
1123function removeChildFromContainer(parentInstance, child) {
1124 destroyEventListeners(child);
1125 child.eject();
1126}
1127
1128
1129
1130
1131
1132function commitUpdate(instance, updatePayload, type, oldProps, newProps) {
1133 instance._applyProps(instance, newProps, oldProps);
1134}
1135
1136function hideInstance(instance) {
1137 instance.hide();
1138}
1139
1140
1141
1142function unhideInstance(instance, props) {
1143 if (props.visible == null || props.visible) {
1144 instance.show();
1145 }
1146}
1147
1148function unhideTextInstance(textInstance, text) {
1149 // Noop
1150}
1151
1152/**
1153 * Copyright (c) 2013-present, Facebook, Inc.
1154 *
1155 * This source code is licensed under the MIT license found in the
1156 * LICENSE file in the root directory of this source tree.
1157 */
1158
1159
1160
1161var ReactPropTypesSecret$1 = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
1162
1163var ReactPropTypesSecret_1 = ReactPropTypesSecret$1;
1164
1165/**
1166 * Copyright (c) 2013-present, Facebook, Inc.
1167 *
1168 * This source code is licensed under the MIT license found in the
1169 * LICENSE file in the root directory of this source tree.
1170 */
1171
1172
1173
1174var printWarning = function() {};
1175
1176{
1177 var ReactPropTypesSecret = ReactPropTypesSecret_1;
1178 var loggedTypeFailures = {};
1179
1180 printWarning = function(text) {
1181 var message = 'Warning: ' + text;
1182 if (typeof console !== 'undefined') {
1183 console.error(message);
1184 }
1185 try {
1186 // --- Welcome to debugging React ---
1187 // This error was thrown as a convenience so that you can use this stack
1188 // to find the callsite that caused this warning to fire.
1189 throw new Error(message);
1190 } catch (x) {}
1191 };
1192}
1193
1194/**
1195 * Assert that the values match with the type specs.
1196 * Error messages are memorized and will only be shown once.
1197 *
1198 * @param {object} typeSpecs Map of name to a ReactPropType
1199 * @param {object} values Runtime values that need to be type-checked
1200 * @param {string} location e.g. "prop", "context", "child context"
1201 * @param {string} componentName Name of the component for error messages.
1202 * @param {?Function} getStack Returns the component stack.
1203 * @private
1204 */
1205function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
1206 {
1207 for (var typeSpecName in typeSpecs) {
1208 if (typeSpecs.hasOwnProperty(typeSpecName)) {
1209 var error;
1210 // Prop type validation may throw. In case they do, we don't want to
1211 // fail the render phase where it didn't fail before. So we log it.
1212 // After these have been cleaned up, we'll let them throw.
1213 try {
1214 // This is intentionally an invariant that gets caught. It's the same
1215 // behavior as without this statement except with a better message.
1216 if (typeof typeSpecs[typeSpecName] !== 'function') {
1217 var err = Error(
1218 (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +
1219 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.'
1220 );
1221 err.name = 'Invariant Violation';
1222 throw err;
1223 }
1224 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
1225 } catch (ex) {
1226 error = ex;
1227 }
1228 if (error && !(error instanceof Error)) {
1229 printWarning(
1230 (componentName || 'React class') + ': type specification of ' +
1231 location + ' `' + typeSpecName + '` is invalid; the type checker ' +
1232 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +
1233 'You may have forgotten to pass an argument to the type checker ' +
1234 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
1235 'shape all require an argument).'
1236 );
1237
1238 }
1239 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
1240 // Only monitor this failure once because there tends to be a lot of the
1241 // same error.
1242 loggedTypeFailures[error.message] = true;
1243
1244 var stack = getStack ? getStack() : '';
1245
1246 printWarning(
1247 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')
1248 );
1249 }
1250 }
1251 }
1252 }
1253}
1254
1255var checkPropTypes_1 = checkPropTypes;
1256
1257var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
1258
1259var describeComponentFrame = function (name, source, ownerName) {
1260 var sourceInfo = '';
1261 if (source) {
1262 var path = source.fileName;
1263 var fileName = path.replace(BEFORE_SLASH_RE, '');
1264 {
1265 // In DEV, include code for a common special case:
1266 // prefer "folder/index.js" instead of just "index.js".
1267 if (/^index\./.test(fileName)) {
1268 var match = path.match(BEFORE_SLASH_RE);
1269 if (match) {
1270 var pathBeforeSlash = match[1];
1271 if (pathBeforeSlash) {
1272 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
1273 fileName = folderName + '/' + fileName;
1274 }
1275 }
1276 }
1277 }
1278 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
1279 } else if (ownerName) {
1280 sourceInfo = ' (created by ' + ownerName + ')';
1281 }
1282 return '\n in ' + (name || 'Unknown') + sourceInfo;
1283};
1284
1285var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
1286
1287function describeFiber(fiber) {
1288 switch (fiber.tag) {
1289 case HostRoot:
1290 case HostPortal:
1291 case HostText:
1292 case Fragment:
1293 case ContextProvider:
1294 case ContextConsumer:
1295 return '';
1296 default:
1297 var owner = fiber._debugOwner;
1298 var source = fiber._debugSource;
1299 var name = getComponentName(fiber.type);
1300 var ownerName = null;
1301 if (owner) {
1302 ownerName = getComponentName(owner.type);
1303 }
1304 return describeComponentFrame(name, source, ownerName);
1305 }
1306}
1307
1308function getStackByFiberInDevAndProd(workInProgress) {
1309 var info = '';
1310 var node = workInProgress;
1311 do {
1312 info += describeFiber(node);
1313 node = node.return;
1314 } while (node);
1315 return info;
1316}
1317
1318var current$1 = null;
1319var phase = null;
1320
1321function getCurrentFiberOwnerNameInDevOrNull() {
1322 {
1323 if (current$1 === null) {
1324 return null;
1325 }
1326 var owner = current$1._debugOwner;
1327 if (owner !== null && typeof owner !== 'undefined') {
1328 return getComponentName(owner.type);
1329 }
1330 }
1331 return null;
1332}
1333
1334function getCurrentFiberStackInDev() {
1335 {
1336 if (current$1 === null) {
1337 return '';
1338 }
1339 // Safe because if current fiber exists, we are reconciling,
1340 // and it is guaranteed to be the work-in-progress version.
1341 return getStackByFiberInDevAndProd(current$1);
1342 }
1343 return '';
1344}
1345
1346function resetCurrentFiber() {
1347 {
1348 ReactDebugCurrentFrame.getCurrentStack = null;
1349 current$1 = null;
1350 phase = null;
1351 }
1352}
1353
1354function setCurrentFiber(fiber) {
1355 {
1356 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
1357 current$1 = fiber;
1358 phase = null;
1359 }
1360}
1361
1362function setCurrentPhase(lifeCyclePhase) {
1363 {
1364 phase = lifeCyclePhase;
1365 }
1366}
1367
1368var enableUserTimingAPI = true;
1369
1370// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
1371var debugRenderPhaseSideEffects = false;
1372
1373// In some cases, StrictMode should also double-render lifecycles.
1374// This can be confusing for tests though,
1375// And it can be bad for performance in production.
1376// This feature flag can be used to control the behavior:
1377var debugRenderPhaseSideEffectsForStrictMode = true;
1378
1379// To preserve the "Pause on caught exceptions" behavior of the debugger, we
1380// replay the begin phase of a failed component inside invokeGuardedCallback.
1381var replayFailedUnitOfWorkWithInvokeGuardedCallback = true;
1382
1383// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
1384var warnAboutDeprecatedLifecycles = false;
1385
1386// Gather advanced timing metrics for Profiler subtrees.
1387var enableProfilerTimer = true;
1388
1389// Trace which interactions trigger each commit.
1390var enableSchedulerTracing = true;
1391
1392// Only used in www builds.
1393var enableSuspenseServerRenderer = false; // TODO: true? Here it might just be false.
1394
1395// Only used in www builds.
1396
1397
1398// Only used in www builds.
1399
1400
1401// React Fire: prevent the value and checked attributes from syncing
1402// with their related DOM properties
1403
1404
1405// These APIs will no longer be "unstable" in the upcoming 16.7 release,
1406// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
1407
1408// Prefix measurements so that it's possible to filter them.
1409// Longer prefixes are hard to read in DevTools.
1410var reactEmoji = '\u269B';
1411var warningEmoji = '\u26D4';
1412var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
1413
1414// Keep track of current fiber so that we know the path to unwind on pause.
1415// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
1416var currentFiber = null;
1417// If we're in the middle of user code, which fiber and method is it?
1418// Reusing `currentFiber` would be confusing for this because user code fiber
1419// can change during commit phase too, but we don't need to unwind it (since
1420// lifecycles in the commit phase don't resemble a tree).
1421var currentPhase = null;
1422var currentPhaseFiber = null;
1423// Did lifecycle hook schedule an update? This is often a performance problem,
1424// so we will keep track of it, and include it in the report.
1425// Track commits caused by cascading updates.
1426var isCommitting = false;
1427var hasScheduledUpdateInCurrentCommit = false;
1428var hasScheduledUpdateInCurrentPhase = false;
1429var commitCountInCurrentWorkLoop = 0;
1430var effectCountInCurrentCommit = 0;
1431var isWaitingForCallback = false;
1432// During commits, we only show a measurement once per method name
1433// to avoid stretch the commit phase with measurement overhead.
1434var labelsInCurrentCommit = new Set();
1435
1436var formatMarkName = function (markName) {
1437 return reactEmoji + ' ' + markName;
1438};
1439
1440var formatLabel = function (label, warning) {
1441 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
1442 var suffix = warning ? ' Warning: ' + warning : '';
1443 return '' + prefix + label + suffix;
1444};
1445
1446var beginMark = function (markName) {
1447 performance.mark(formatMarkName(markName));
1448};
1449
1450var clearMark = function (markName) {
1451 performance.clearMarks(formatMarkName(markName));
1452};
1453
1454var endMark = function (label, markName, warning) {
1455 var formattedMarkName = formatMarkName(markName);
1456 var formattedLabel = formatLabel(label, warning);
1457 try {
1458 performance.measure(formattedLabel, formattedMarkName);
1459 } catch (err) {}
1460 // If previous mark was missing for some reason, this will throw.
1461 // This could only happen if React crashed in an unexpected place earlier.
1462 // Don't pile on with more errors.
1463
1464 // Clear marks immediately to avoid growing buffer.
1465 performance.clearMarks(formattedMarkName);
1466 performance.clearMeasures(formattedLabel);
1467};
1468
1469var getFiberMarkName = function (label, debugID) {
1470 return label + ' (#' + debugID + ')';
1471};
1472
1473var getFiberLabel = function (componentName, isMounted, phase) {
1474 if (phase === null) {
1475 // These are composite component total time measurements.
1476 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
1477 } else {
1478 // Composite component methods.
1479 return componentName + '.' + phase;
1480 }
1481};
1482
1483var beginFiberMark = function (fiber, phase) {
1484 var componentName = getComponentName(fiber.type) || 'Unknown';
1485 var debugID = fiber._debugID;
1486 var isMounted = fiber.alternate !== null;
1487 var label = getFiberLabel(componentName, isMounted, phase);
1488
1489 if (isCommitting && labelsInCurrentCommit.has(label)) {
1490 // During the commit phase, we don't show duplicate labels because
1491 // there is a fixed overhead for every measurement, and we don't
1492 // want to stretch the commit phase beyond necessary.
1493 return false;
1494 }
1495 labelsInCurrentCommit.add(label);
1496
1497 var markName = getFiberMarkName(label, debugID);
1498 beginMark(markName);
1499 return true;
1500};
1501
1502var clearFiberMark = function (fiber, phase) {
1503 var componentName = getComponentName(fiber.type) || 'Unknown';
1504 var debugID = fiber._debugID;
1505 var isMounted = fiber.alternate !== null;
1506 var label = getFiberLabel(componentName, isMounted, phase);
1507 var markName = getFiberMarkName(label, debugID);
1508 clearMark(markName);
1509};
1510
1511var endFiberMark = function (fiber, phase, warning) {
1512 var componentName = getComponentName(fiber.type) || 'Unknown';
1513 var debugID = fiber._debugID;
1514 var isMounted = fiber.alternate !== null;
1515 var label = getFiberLabel(componentName, isMounted, phase);
1516 var markName = getFiberMarkName(label, debugID);
1517 endMark(label, markName, warning);
1518};
1519
1520var shouldIgnoreFiber = function (fiber) {
1521 // Host components should be skipped in the timeline.
1522 // We could check typeof fiber.type, but does this work with RN?
1523 switch (fiber.tag) {
1524 case HostRoot:
1525 case HostComponent:
1526 case HostText:
1527 case HostPortal:
1528 case Fragment:
1529 case ContextProvider:
1530 case ContextConsumer:
1531 case Mode:
1532 return true;
1533 default:
1534 return false;
1535 }
1536};
1537
1538var clearPendingPhaseMeasurement = function () {
1539 if (currentPhase !== null && currentPhaseFiber !== null) {
1540 clearFiberMark(currentPhaseFiber, currentPhase);
1541 }
1542 currentPhaseFiber = null;
1543 currentPhase = null;
1544 hasScheduledUpdateInCurrentPhase = false;
1545};
1546
1547var pauseTimers = function () {
1548 // Stops all currently active measurements so that they can be resumed
1549 // if we continue in a later deferred loop from the same unit of work.
1550 var fiber = currentFiber;
1551 while (fiber) {
1552 if (fiber._debugIsCurrentlyTiming) {
1553 endFiberMark(fiber, null, null);
1554 }
1555 fiber = fiber.return;
1556 }
1557};
1558
1559var resumeTimersRecursively = function (fiber) {
1560 if (fiber.return !== null) {
1561 resumeTimersRecursively(fiber.return);
1562 }
1563 if (fiber._debugIsCurrentlyTiming) {
1564 beginFiberMark(fiber, null);
1565 }
1566};
1567
1568var resumeTimers = function () {
1569 // Resumes all measurements that were active during the last deferred loop.
1570 if (currentFiber !== null) {
1571 resumeTimersRecursively(currentFiber);
1572 }
1573};
1574
1575function recordEffect() {
1576 if (enableUserTimingAPI) {
1577 effectCountInCurrentCommit++;
1578 }
1579}
1580
1581function recordScheduleUpdate() {
1582 if (enableUserTimingAPI) {
1583 if (isCommitting) {
1584 hasScheduledUpdateInCurrentCommit = true;
1585 }
1586 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
1587 hasScheduledUpdateInCurrentPhase = true;
1588 }
1589 }
1590}
1591
1592function startRequestCallbackTimer() {
1593 if (enableUserTimingAPI) {
1594 if (supportsUserTiming && !isWaitingForCallback) {
1595 isWaitingForCallback = true;
1596 beginMark('(Waiting for async callback...)');
1597 }
1598 }
1599}
1600
1601function stopRequestCallbackTimer(didExpire, expirationTime) {
1602 if (enableUserTimingAPI) {
1603 if (supportsUserTiming) {
1604 isWaitingForCallback = false;
1605 var warning = didExpire ? 'React was blocked by main thread' : null;
1606 endMark('(Waiting for async callback... will force flush in ' + expirationTime + ' ms)', '(Waiting for async callback...)', warning);
1607 }
1608 }
1609}
1610
1611function startWorkTimer(fiber) {
1612 if (enableUserTimingAPI) {
1613 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1614 return;
1615 }
1616 // If we pause, this is the fiber to unwind from.
1617 currentFiber = fiber;
1618 if (!beginFiberMark(fiber, null)) {
1619 return;
1620 }
1621 fiber._debugIsCurrentlyTiming = true;
1622 }
1623}
1624
1625function cancelWorkTimer(fiber) {
1626 if (enableUserTimingAPI) {
1627 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1628 return;
1629 }
1630 // Remember we shouldn't complete measurement for this fiber.
1631 // Otherwise flamechart will be deep even for small updates.
1632 fiber._debugIsCurrentlyTiming = false;
1633 clearFiberMark(fiber, null);
1634 }
1635}
1636
1637function stopWorkTimer(fiber) {
1638 if (enableUserTimingAPI) {
1639 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1640 return;
1641 }
1642 // If we pause, its parent is the fiber to unwind from.
1643 currentFiber = fiber.return;
1644 if (!fiber._debugIsCurrentlyTiming) {
1645 return;
1646 }
1647 fiber._debugIsCurrentlyTiming = false;
1648 endFiberMark(fiber, null, null);
1649 }
1650}
1651
1652function stopFailedWorkTimer(fiber) {
1653 if (enableUserTimingAPI) {
1654 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1655 return;
1656 }
1657 // If we pause, its parent is the fiber to unwind from.
1658 currentFiber = fiber.return;
1659 if (!fiber._debugIsCurrentlyTiming) {
1660 return;
1661 }
1662 fiber._debugIsCurrentlyTiming = false;
1663 var warning = fiber.tag === SuspenseComponent || fiber.tag === DehydratedSuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
1664 endFiberMark(fiber, null, warning);
1665 }
1666}
1667
1668function startPhaseTimer(fiber, phase) {
1669 if (enableUserTimingAPI) {
1670 if (!supportsUserTiming) {
1671 return;
1672 }
1673 clearPendingPhaseMeasurement();
1674 if (!beginFiberMark(fiber, phase)) {
1675 return;
1676 }
1677 currentPhaseFiber = fiber;
1678 currentPhase = phase;
1679 }
1680}
1681
1682function stopPhaseTimer() {
1683 if (enableUserTimingAPI) {
1684 if (!supportsUserTiming) {
1685 return;
1686 }
1687 if (currentPhase !== null && currentPhaseFiber !== null) {
1688 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
1689 endFiberMark(currentPhaseFiber, currentPhase, warning);
1690 }
1691 currentPhase = null;
1692 currentPhaseFiber = null;
1693 }
1694}
1695
1696function startWorkLoopTimer(nextUnitOfWork) {
1697 if (enableUserTimingAPI) {
1698 currentFiber = nextUnitOfWork;
1699 if (!supportsUserTiming) {
1700 return;
1701 }
1702 commitCountInCurrentWorkLoop = 0;
1703 // This is top level call.
1704 // Any other measurements are performed within.
1705 beginMark('(React Tree Reconciliation)');
1706 // Resume any measurements that were in progress during the last loop.
1707 resumeTimers();
1708 }
1709}
1710
1711function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
1712 if (enableUserTimingAPI) {
1713 if (!supportsUserTiming) {
1714 return;
1715 }
1716 var warning = null;
1717 if (interruptedBy !== null) {
1718 if (interruptedBy.tag === HostRoot) {
1719 warning = 'A top-level update interrupted the previous render';
1720 } else {
1721 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
1722 warning = 'An update to ' + componentName + ' interrupted the previous render';
1723 }
1724 } else if (commitCountInCurrentWorkLoop > 1) {
1725 warning = 'There were cascading updates';
1726 }
1727 commitCountInCurrentWorkLoop = 0;
1728 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)';
1729 // Pause any measurements until the next loop.
1730 pauseTimers();
1731 endMark(label, '(React Tree Reconciliation)', warning);
1732 }
1733}
1734
1735function startCommitTimer() {
1736 if (enableUserTimingAPI) {
1737 if (!supportsUserTiming) {
1738 return;
1739 }
1740 isCommitting = true;
1741 hasScheduledUpdateInCurrentCommit = false;
1742 labelsInCurrentCommit.clear();
1743 beginMark('(Committing Changes)');
1744 }
1745}
1746
1747function stopCommitTimer() {
1748 if (enableUserTimingAPI) {
1749 if (!supportsUserTiming) {
1750 return;
1751 }
1752
1753 var warning = null;
1754 if (hasScheduledUpdateInCurrentCommit) {
1755 warning = 'Lifecycle hook scheduled a cascading update';
1756 } else if (commitCountInCurrentWorkLoop > 0) {
1757 warning = 'Caused by a cascading update in earlier commit';
1758 }
1759 hasScheduledUpdateInCurrentCommit = false;
1760 commitCountInCurrentWorkLoop++;
1761 isCommitting = false;
1762 labelsInCurrentCommit.clear();
1763
1764 endMark('(Committing Changes)', '(Committing Changes)', warning);
1765 }
1766}
1767
1768function startCommitSnapshotEffectsTimer() {
1769 if (enableUserTimingAPI) {
1770 if (!supportsUserTiming) {
1771 return;
1772 }
1773 effectCountInCurrentCommit = 0;
1774 beginMark('(Committing Snapshot Effects)');
1775 }
1776}
1777
1778function stopCommitSnapshotEffectsTimer() {
1779 if (enableUserTimingAPI) {
1780 if (!supportsUserTiming) {
1781 return;
1782 }
1783 var count = effectCountInCurrentCommit;
1784 effectCountInCurrentCommit = 0;
1785 endMark('(Committing Snapshot Effects: ' + count + ' Total)', '(Committing Snapshot Effects)', null);
1786 }
1787}
1788
1789function startCommitHostEffectsTimer() {
1790 if (enableUserTimingAPI) {
1791 if (!supportsUserTiming) {
1792 return;
1793 }
1794 effectCountInCurrentCommit = 0;
1795 beginMark('(Committing Host Effects)');
1796 }
1797}
1798
1799function stopCommitHostEffectsTimer() {
1800 if (enableUserTimingAPI) {
1801 if (!supportsUserTiming) {
1802 return;
1803 }
1804 var count = effectCountInCurrentCommit;
1805 effectCountInCurrentCommit = 0;
1806 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
1807 }
1808}
1809
1810function startCommitLifeCyclesTimer() {
1811 if (enableUserTimingAPI) {
1812 if (!supportsUserTiming) {
1813 return;
1814 }
1815 effectCountInCurrentCommit = 0;
1816 beginMark('(Calling Lifecycle Methods)');
1817 }
1818}
1819
1820function stopCommitLifeCyclesTimer() {
1821 if (enableUserTimingAPI) {
1822 if (!supportsUserTiming) {
1823 return;
1824 }
1825 var count = effectCountInCurrentCommit;
1826 effectCountInCurrentCommit = 0;
1827 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
1828 }
1829}
1830
1831var valueStack = [];
1832
1833var fiberStack = void 0;
1834
1835{
1836 fiberStack = [];
1837}
1838
1839var index = -1;
1840
1841function createCursor(defaultValue) {
1842 return {
1843 current: defaultValue
1844 };
1845}
1846
1847function pop(cursor, fiber) {
1848 if (index < 0) {
1849 {
1850 warningWithoutStack$1(false, 'Unexpected pop.');
1851 }
1852 return;
1853 }
1854
1855 {
1856 if (fiber !== fiberStack[index]) {
1857 warningWithoutStack$1(false, 'Unexpected Fiber popped.');
1858 }
1859 }
1860
1861 cursor.current = valueStack[index];
1862
1863 valueStack[index] = null;
1864
1865 {
1866 fiberStack[index] = null;
1867 }
1868
1869 index--;
1870}
1871
1872function push(cursor, value, fiber) {
1873 index++;
1874
1875 valueStack[index] = cursor.current;
1876
1877 {
1878 fiberStack[index] = fiber;
1879 }
1880
1881 cursor.current = value;
1882}
1883
1884function checkThatStackIsEmpty() {
1885 {
1886 if (index !== -1) {
1887 warningWithoutStack$1(false, 'Expected an empty stack. Something was not reset properly.');
1888 }
1889 }
1890}
1891
1892function resetStackAfterFatalErrorInDev() {
1893 {
1894 index = -1;
1895 valueStack.length = 0;
1896 fiberStack.length = 0;
1897 }
1898}
1899
1900var warnedAboutMissingGetChildContext = void 0;
1901
1902{
1903 warnedAboutMissingGetChildContext = {};
1904}
1905
1906var emptyContextObject = {};
1907{
1908 Object.freeze(emptyContextObject);
1909}
1910
1911// A cursor to the current merged context object on the stack.
1912var contextStackCursor = createCursor(emptyContextObject);
1913// A cursor to a boolean indicating whether the context has changed.
1914var didPerformWorkStackCursor = createCursor(false);
1915// Keep track of the previous context object that was on the stack.
1916// We use this to get access to the parent context after we have already
1917// pushed the next context provider, and now need to merge their contexts.
1918var previousContext = emptyContextObject;
1919
1920function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
1921 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
1922 // If the fiber is a context provider itself, when we read its context
1923 // we may have already pushed its own child context on the stack. A context
1924 // provider should not "see" its own child context. Therefore we read the
1925 // previous (parent) context instead for a context provider.
1926 return previousContext;
1927 }
1928 return contextStackCursor.current;
1929}
1930
1931function cacheContext(workInProgress, unmaskedContext, maskedContext) {
1932 var instance = workInProgress.stateNode;
1933 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
1934 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
1935}
1936
1937function getMaskedContext(workInProgress, unmaskedContext) {
1938 var type = workInProgress.type;
1939 var contextTypes = type.contextTypes;
1940 if (!contextTypes) {
1941 return emptyContextObject;
1942 }
1943
1944 // Avoid recreating masked context unless unmasked context has changed.
1945 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
1946 // This may trigger infinite loops if componentWillReceiveProps calls setState.
1947 var instance = workInProgress.stateNode;
1948 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
1949 return instance.__reactInternalMemoizedMaskedChildContext;
1950 }
1951
1952 var context = {};
1953 for (var key in contextTypes) {
1954 context[key] = unmaskedContext[key];
1955 }
1956
1957 {
1958 var name = getComponentName(type) || 'Unknown';
1959 checkPropTypes_1(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
1960 }
1961
1962 // Cache unmasked context so we can avoid recreating masked context unless necessary.
1963 // Context is created before the class component is instantiated so check for instance.
1964 if (instance) {
1965 cacheContext(workInProgress, unmaskedContext, context);
1966 }
1967
1968 return context;
1969}
1970
1971function hasContextChanged() {
1972 return didPerformWorkStackCursor.current;
1973}
1974
1975function isContextProvider(type) {
1976 var childContextTypes = type.childContextTypes;
1977 return childContextTypes !== null && childContextTypes !== undefined;
1978}
1979
1980function popContext(fiber) {
1981 pop(didPerformWorkStackCursor, fiber);
1982 pop(contextStackCursor, fiber);
1983}
1984
1985function popTopLevelContextObject(fiber) {
1986 pop(didPerformWorkStackCursor, fiber);
1987 pop(contextStackCursor, fiber);
1988}
1989
1990function pushTopLevelContextObject(fiber, context, didChange) {
1991 !(contextStackCursor.current === emptyContextObject) ? invariant(false, 'Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue.') : void 0;
1992
1993 push(contextStackCursor, context, fiber);
1994 push(didPerformWorkStackCursor, didChange, fiber);
1995}
1996
1997function processChildContext(fiber, type, parentContext) {
1998 var instance = fiber.stateNode;
1999 var childContextTypes = type.childContextTypes;
2000
2001 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
2002 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
2003 if (typeof instance.getChildContext !== 'function') {
2004 {
2005 var componentName = getComponentName(type) || 'Unknown';
2006
2007 if (!warnedAboutMissingGetChildContext[componentName]) {
2008 warnedAboutMissingGetChildContext[componentName] = true;
2009 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);
2010 }
2011 }
2012 return parentContext;
2013 }
2014
2015 var childContext = void 0;
2016 {
2017 setCurrentPhase('getChildContext');
2018 }
2019 startPhaseTimer(fiber, 'getChildContext');
2020 childContext = instance.getChildContext();
2021 stopPhaseTimer();
2022 {
2023 setCurrentPhase(null);
2024 }
2025 for (var contextKey in childContext) {
2026 !(contextKey in childContextTypes) ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', getComponentName(type) || 'Unknown', contextKey) : void 0;
2027 }
2028 {
2029 var name = getComponentName(type) || 'Unknown';
2030 checkPropTypes_1(childContextTypes, childContext, 'child context', name,
2031 // In practice, there is one case in which we won't get a stack. It's when
2032 // somebody calls unstable_renderSubtreeIntoContainer() and we process
2033 // context from the parent component instance. The stack will be missing
2034 // because it's outside of the reconciliation, and so the pointer has not
2035 // been set. This is rare and doesn't matter. We'll also remove that API.
2036 getCurrentFiberStackInDev);
2037 }
2038
2039 return _assign({}, parentContext, childContext);
2040}
2041
2042function pushContextProvider(workInProgress) {
2043 var instance = workInProgress.stateNode;
2044 // We push the context as early as possible to ensure stack integrity.
2045 // If the instance does not exist yet, we will push null at first,
2046 // and replace it on the stack later when invalidating the context.
2047 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject;
2048
2049 // Remember the parent context so we can merge with it later.
2050 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
2051 previousContext = contextStackCursor.current;
2052 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
2053 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
2054
2055 return true;
2056}
2057
2058function invalidateContextProvider(workInProgress, type, didChange) {
2059 var instance = workInProgress.stateNode;
2060 !instance ? invariant(false, 'Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue.') : void 0;
2061
2062 if (didChange) {
2063 // Merge parent and own context.
2064 // Skip this if we're not updating due to sCU.
2065 // This avoids unnecessarily recomputing memoized values.
2066 var mergedContext = processChildContext(workInProgress, type, previousContext);
2067 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
2068
2069 // Replace the old (or empty) context with the new one.
2070 // It is important to unwind the context in the reverse order.
2071 pop(didPerformWorkStackCursor, workInProgress);
2072 pop(contextStackCursor, workInProgress);
2073 // Now push the new context and mark that it has changed.
2074 push(contextStackCursor, mergedContext, workInProgress);
2075 push(didPerformWorkStackCursor, didChange, workInProgress);
2076 } else {
2077 pop(didPerformWorkStackCursor, workInProgress);
2078 push(didPerformWorkStackCursor, didChange, workInProgress);
2079 }
2080}
2081
2082function findCurrentUnmaskedContext(fiber) {
2083 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
2084 // makes sense elsewhere
2085 !(isFiberMounted(fiber) && fiber.tag === ClassComponent) ? invariant(false, 'Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue.') : void 0;
2086
2087 var node = fiber;
2088 do {
2089 switch (node.tag) {
2090 case HostRoot:
2091 return node.stateNode.context;
2092 case ClassComponent:
2093 {
2094 var Component = node.type;
2095 if (isContextProvider(Component)) {
2096 return node.stateNode.__reactInternalMemoizedMergedChildContext;
2097 }
2098 break;
2099 }
2100 }
2101 node = node.return;
2102 } while (node !== null);
2103 invariant(false, 'Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.');
2104}
2105
2106var onCommitFiberRoot = null;
2107var onCommitFiberUnmount = null;
2108var hasLoggedError = false;
2109
2110function catchErrors(fn) {
2111 return function (arg) {
2112 try {
2113 return fn(arg);
2114 } catch (err) {
2115 if (true && !hasLoggedError) {
2116 hasLoggedError = true;
2117 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
2118 }
2119 }
2120 };
2121}
2122
2123var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
2124
2125function injectInternals(internals) {
2126 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
2127 // No DevTools
2128 return false;
2129 }
2130 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
2131 if (hook.isDisabled) {
2132 // This isn't a real property on the hook, but it can be set to opt out
2133 // of DevTools integration and associated warnings and logs.
2134 // https://github.com/facebook/react/issues/3877
2135 return true;
2136 }
2137 if (!hook.supportsFiber) {
2138 {
2139 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');
2140 }
2141 // DevTools exists, even though it doesn't support Fiber.
2142 return true;
2143 }
2144 try {
2145 var rendererID = hook.inject(internals);
2146 // We have successfully injected, so now it is safe to set up hooks.
2147 onCommitFiberRoot = catchErrors(function (root) {
2148 return hook.onCommitFiberRoot(rendererID, root);
2149 });
2150 onCommitFiberUnmount = catchErrors(function (fiber) {
2151 return hook.onCommitFiberUnmount(rendererID, fiber);
2152 });
2153 } catch (err) {
2154 // Catch all errors because it is unsafe to throw during initialization.
2155 {
2156 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err);
2157 }
2158 }
2159 // DevTools exists
2160 return true;
2161}
2162
2163function onCommitRoot(root) {
2164 if (typeof onCommitFiberRoot === 'function') {
2165 onCommitFiberRoot(root);
2166 }
2167}
2168
2169function onCommitUnmount(fiber) {
2170 if (typeof onCommitFiberUnmount === 'function') {
2171 onCommitFiberUnmount(fiber);
2172 }
2173}
2174
2175// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
2176// Math.pow(2, 30) - 1
2177// 0b111111111111111111111111111111
2178var maxSigned31BitInt = 1073741823;
2179
2180var NoWork = 0;
2181var Never = 1;
2182var Sync = maxSigned31BitInt;
2183
2184var UNIT_SIZE = 10;
2185var MAGIC_NUMBER_OFFSET = maxSigned31BitInt - 1;
2186
2187// 1 unit of expiration time represents 10ms.
2188function msToExpirationTime(ms) {
2189 // Always add an offset so that we don't clash with the magic number for NoWork.
2190 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
2191}
2192
2193function expirationTimeToMs(expirationTime) {
2194 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
2195}
2196
2197function ceiling(num, precision) {
2198 return ((num / precision | 0) + 1) * precision;
2199}
2200
2201function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
2202 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
2203}
2204
2205var LOW_PRIORITY_EXPIRATION = 5000;
2206var LOW_PRIORITY_BATCH_SIZE = 250;
2207
2208function computeAsyncExpiration(currentTime) {
2209 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
2210}
2211
2212// We intentionally set a higher expiration time for interactive updates in
2213// dev than in production.
2214//
2215// If the main thread is being blocked so long that you hit the expiration,
2216// it's a problem that could be solved with better scheduling.
2217//
2218// People will be more likely to notice this and fix it with the long
2219// expiration time in development.
2220//
2221// In production we opt for better UX at the risk of masking scheduling
2222// problems, by expiring fast.
2223var HIGH_PRIORITY_EXPIRATION = 500;
2224var HIGH_PRIORITY_BATCH_SIZE = 100;
2225
2226function computeInteractiveExpiration(currentTime) {
2227 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
2228}
2229
2230var NoContext = 0;
2231var ConcurrentMode = 1;
2232var StrictMode = 2;
2233var ProfileMode = 4;
2234
2235var hasBadMapPolyfill = void 0;
2236
2237{
2238 hasBadMapPolyfill = false;
2239 try {
2240 var nonExtensibleObject = Object.preventExtensions({});
2241 var testMap = new Map([[nonExtensibleObject, null]]);
2242 var testSet = new Set([nonExtensibleObject]);
2243 // This is necessary for Rollup to not consider these unused.
2244 // https://github.com/rollup/rollup/issues/1771
2245 // TODO: we can remove these if Rollup fixes the bug.
2246 testMap.set(0, 0);
2247 testSet.add(0);
2248 } catch (e) {
2249 // TODO: Consider warning about bad polyfills
2250 hasBadMapPolyfill = true;
2251 }
2252}
2253
2254// A Fiber is work on a Component that needs to be done or was done. There can
2255// be more than one per component.
2256
2257
2258var debugCounter = void 0;
2259
2260{
2261 debugCounter = 1;
2262}
2263
2264function FiberNode(tag, pendingProps, key, mode) {
2265 // Instance
2266 this.tag = tag;
2267 this.key = key;
2268 this.elementType = null;
2269 this.type = null;
2270 this.stateNode = null;
2271
2272 // Fiber
2273 this.return = null;
2274 this.child = null;
2275 this.sibling = null;
2276 this.index = 0;
2277
2278 this.ref = null;
2279
2280 this.pendingProps = pendingProps;
2281 this.memoizedProps = null;
2282 this.updateQueue = null;
2283 this.memoizedState = null;
2284 this.contextDependencies = null;
2285
2286 this.mode = mode;
2287
2288 // Effects
2289 this.effectTag = NoEffect;
2290 this.nextEffect = null;
2291
2292 this.firstEffect = null;
2293 this.lastEffect = null;
2294
2295 this.expirationTime = NoWork;
2296 this.childExpirationTime = NoWork;
2297
2298 this.alternate = null;
2299
2300 if (enableProfilerTimer) {
2301 // Note: The following is done to avoid a v8 performance cliff.
2302 //
2303 // Initializing the fields below to smis and later updating them with
2304 // double values will cause Fibers to end up having separate shapes.
2305 // This behavior/bug has something to do with Object.preventExtension().
2306 // Fortunately this only impacts DEV builds.
2307 // Unfortunately it makes React unusably slow for some applications.
2308 // To work around this, initialize the fields below with doubles.
2309 //
2310 // Learn more about this here:
2311 // https://github.com/facebook/react/issues/14365
2312 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
2313 this.actualDuration = Number.NaN;
2314 this.actualStartTime = Number.NaN;
2315 this.selfBaseDuration = Number.NaN;
2316 this.treeBaseDuration = Number.NaN;
2317
2318 // It's okay to replace the initial doubles with smis after initialization.
2319 // This won't trigger the performance cliff mentioned above,
2320 // and it simplifies other profiler code (including DevTools).
2321 this.actualDuration = 0;
2322 this.actualStartTime = -1;
2323 this.selfBaseDuration = 0;
2324 this.treeBaseDuration = 0;
2325 }
2326
2327 {
2328 this._debugID = debugCounter++;
2329 this._debugSource = null;
2330 this._debugOwner = null;
2331 this._debugIsCurrentlyTiming = false;
2332 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
2333 Object.preventExtensions(this);
2334 }
2335 }
2336}
2337
2338// This is a constructor function, rather than a POJO constructor, still
2339// please ensure we do the following:
2340// 1) Nobody should add any instance methods on this. Instance methods can be
2341// more difficult to predict when they get optimized and they are almost
2342// never inlined properly in static compilers.
2343// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
2344// always know when it is a fiber.
2345// 3) We might want to experiment with using numeric keys since they are easier
2346// to optimize in a non-JIT environment.
2347// 4) We can easily go from a constructor to a createFiber object literal if that
2348// is faster.
2349// 5) It should be easy to port this to a C struct and keep a C implementation
2350// compatible.
2351var createFiber = function (tag, pendingProps, key, mode) {
2352 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
2353 return new FiberNode(tag, pendingProps, key, mode);
2354};
2355
2356function shouldConstruct(Component) {
2357 var prototype = Component.prototype;
2358 return !!(prototype && prototype.isReactComponent);
2359}
2360
2361function isSimpleFunctionComponent(type) {
2362 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
2363}
2364
2365function resolveLazyComponentTag(Component) {
2366 if (typeof Component === 'function') {
2367 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
2368 } else if (Component !== undefined && Component !== null) {
2369 var $$typeof = Component.$$typeof;
2370 if ($$typeof === REACT_FORWARD_REF_TYPE) {
2371 return ForwardRef;
2372 }
2373 if ($$typeof === REACT_MEMO_TYPE) {
2374 return MemoComponent;
2375 }
2376 }
2377 return IndeterminateComponent;
2378}
2379
2380// This is used to create an alternate fiber to do work on.
2381function createWorkInProgress(current, pendingProps, expirationTime) {
2382 var workInProgress = current.alternate;
2383 if (workInProgress === null) {
2384 // We use a double buffering pooling technique because we know that we'll
2385 // only ever need at most two versions of a tree. We pool the "other" unused
2386 // node that we're free to reuse. This is lazily created to avoid allocating
2387 // extra objects for things that are never updated. It also allow us to
2388 // reclaim the extra memory if needed.
2389 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
2390 workInProgress.elementType = current.elementType;
2391 workInProgress.type = current.type;
2392 workInProgress.stateNode = current.stateNode;
2393
2394 {
2395 // DEV-only fields
2396 workInProgress._debugID = current._debugID;
2397 workInProgress._debugSource = current._debugSource;
2398 workInProgress._debugOwner = current._debugOwner;
2399 }
2400
2401 workInProgress.alternate = current;
2402 current.alternate = workInProgress;
2403 } else {
2404 workInProgress.pendingProps = pendingProps;
2405
2406 // We already have an alternate.
2407 // Reset the effect tag.
2408 workInProgress.effectTag = NoEffect;
2409
2410 // The effect list is no longer valid.
2411 workInProgress.nextEffect = null;
2412 workInProgress.firstEffect = null;
2413 workInProgress.lastEffect = null;
2414
2415 if (enableProfilerTimer) {
2416 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
2417 // This prevents time from endlessly accumulating in new commits.
2418 // This has the downside of resetting values for different priority renders,
2419 // But works for yielding (the common case) and should support resuming.
2420 workInProgress.actualDuration = 0;
2421 workInProgress.actualStartTime = -1;
2422 }
2423 }
2424
2425 workInProgress.childExpirationTime = current.childExpirationTime;
2426 workInProgress.expirationTime = current.expirationTime;
2427
2428 workInProgress.child = current.child;
2429 workInProgress.memoizedProps = current.memoizedProps;
2430 workInProgress.memoizedState = current.memoizedState;
2431 workInProgress.updateQueue = current.updateQueue;
2432 workInProgress.contextDependencies = current.contextDependencies;
2433
2434 // These will be overridden during the parent's reconciliation
2435 workInProgress.sibling = current.sibling;
2436 workInProgress.index = current.index;
2437 workInProgress.ref = current.ref;
2438
2439 if (enableProfilerTimer) {
2440 workInProgress.selfBaseDuration = current.selfBaseDuration;
2441 workInProgress.treeBaseDuration = current.treeBaseDuration;
2442 }
2443
2444 return workInProgress;
2445}
2446
2447function createHostRootFiber(isConcurrent) {
2448 var mode = isConcurrent ? ConcurrentMode | StrictMode : NoContext;
2449
2450 if (enableProfilerTimer && isDevToolsPresent) {
2451 // Always collect profile timings when DevTools are present.
2452 // This enables DevTools to start capturing timing at any point–
2453 // Without some nodes in the tree having empty base times.
2454 mode |= ProfileMode;
2455 }
2456
2457 return createFiber(HostRoot, null, null, mode);
2458}
2459
2460function createFiberFromTypeAndProps(type, // React$ElementType
2461key, pendingProps, owner, mode, expirationTime) {
2462 var fiber = void 0;
2463
2464 var fiberTag = IndeterminateComponent;
2465 // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
2466 var resolvedType = type;
2467 if (typeof type === 'function') {
2468 if (shouldConstruct(type)) {
2469 fiberTag = ClassComponent;
2470 }
2471 } else if (typeof type === 'string') {
2472 fiberTag = HostComponent;
2473 } else {
2474 getTag: switch (type) {
2475 case REACT_FRAGMENT_TYPE:
2476 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
2477 case REACT_CONCURRENT_MODE_TYPE:
2478 return createFiberFromMode(pendingProps, mode | ConcurrentMode | StrictMode, expirationTime, key);
2479 case REACT_STRICT_MODE_TYPE:
2480 return createFiberFromMode(pendingProps, mode | StrictMode, expirationTime, key);
2481 case REACT_PROFILER_TYPE:
2482 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
2483 case REACT_SUSPENSE_TYPE:
2484 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
2485 default:
2486 {
2487 if (typeof type === 'object' && type !== null) {
2488 switch (type.$$typeof) {
2489 case REACT_PROVIDER_TYPE:
2490 fiberTag = ContextProvider;
2491 break getTag;
2492 case REACT_CONTEXT_TYPE:
2493 // This is a consumer
2494 fiberTag = ContextConsumer;
2495 break getTag;
2496 case REACT_FORWARD_REF_TYPE:
2497 fiberTag = ForwardRef;
2498 break getTag;
2499 case REACT_MEMO_TYPE:
2500 fiberTag = MemoComponent;
2501 break getTag;
2502 case REACT_LAZY_TYPE:
2503 fiberTag = LazyComponent;
2504 resolvedType = null;
2505 break getTag;
2506 }
2507 }
2508 var info = '';
2509 {
2510 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
2511 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.';
2512 }
2513 var ownerName = owner ? getComponentName(owner.type) : null;
2514 if (ownerName) {
2515 info += '\n\nCheck the render method of `' + ownerName + '`.';
2516 }
2517 }
2518 invariant(false, 'Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s', type == null ? type : typeof type, info);
2519 }
2520 }
2521 }
2522
2523 fiber = createFiber(fiberTag, pendingProps, key, mode);
2524 fiber.elementType = type;
2525 fiber.type = resolvedType;
2526 fiber.expirationTime = expirationTime;
2527
2528 return fiber;
2529}
2530
2531function createFiberFromElement(element, mode, expirationTime) {
2532 var owner = null;
2533 {
2534 owner = element._owner;
2535 }
2536 var type = element.type;
2537 var key = element.key;
2538 var pendingProps = element.props;
2539 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
2540 {
2541 fiber._debugSource = element._source;
2542 fiber._debugOwner = element._owner;
2543 }
2544 return fiber;
2545}
2546
2547function createFiberFromFragment(elements, mode, expirationTime, key) {
2548 var fiber = createFiber(Fragment, elements, key, mode);
2549 fiber.expirationTime = expirationTime;
2550 return fiber;
2551}
2552
2553function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
2554 {
2555 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
2556 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props');
2557 }
2558 }
2559
2560 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
2561 // TODO: The Profiler fiber shouldn't have a type. It has a tag.
2562 fiber.elementType = REACT_PROFILER_TYPE;
2563 fiber.type = REACT_PROFILER_TYPE;
2564 fiber.expirationTime = expirationTime;
2565
2566 return fiber;
2567}
2568
2569function createFiberFromMode(pendingProps, mode, expirationTime, key) {
2570 var fiber = createFiber(Mode, pendingProps, key, mode);
2571
2572 // TODO: The Mode fiber shouldn't have a type. It has a tag.
2573 var type = (mode & ConcurrentMode) === NoContext ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE;
2574 fiber.elementType = type;
2575 fiber.type = type;
2576
2577 fiber.expirationTime = expirationTime;
2578 return fiber;
2579}
2580
2581function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
2582 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
2583
2584 // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
2585 var type = REACT_SUSPENSE_TYPE;
2586 fiber.elementType = type;
2587 fiber.type = type;
2588
2589 fiber.expirationTime = expirationTime;
2590 return fiber;
2591}
2592
2593function createFiberFromText(content, mode, expirationTime) {
2594 var fiber = createFiber(HostText, content, null, mode);
2595 fiber.expirationTime = expirationTime;
2596 return fiber;
2597}
2598
2599function createFiberFromHostInstanceForDeletion() {
2600 var fiber = createFiber(HostComponent, null, null, NoContext);
2601 // TODO: These should not need a type.
2602 fiber.elementType = 'DELETED';
2603 fiber.type = 'DELETED';
2604 return fiber;
2605}
2606
2607function createFiberFromPortal(portal, mode, expirationTime) {
2608 var pendingProps = portal.children !== null ? portal.children : [];
2609 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
2610 fiber.expirationTime = expirationTime;
2611 fiber.stateNode = {
2612 containerInfo: portal.containerInfo,
2613 pendingChildren: null, // Used by persistent updates
2614 implementation: portal.implementation
2615 };
2616 return fiber;
2617}
2618
2619// Used for stashing WIP properties to replay failed work in DEV.
2620function assignFiberPropertiesInDEV(target, source) {
2621 if (target === null) {
2622 // This Fiber's initial properties will always be overwritten.
2623 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
2624 target = createFiber(IndeterminateComponent, null, null, NoContext);
2625 }
2626
2627 // This is intentionally written as a list of all properties.
2628 // We tried to use Object.assign() instead but this is called in
2629 // the hottest path, and Object.assign() was too slow:
2630 // https://github.com/facebook/react/issues/12502
2631 // This code is DEV-only so size is not a concern.
2632
2633 target.tag = source.tag;
2634 target.key = source.key;
2635 target.elementType = source.elementType;
2636 target.type = source.type;
2637 target.stateNode = source.stateNode;
2638 target.return = source.return;
2639 target.child = source.child;
2640 target.sibling = source.sibling;
2641 target.index = source.index;
2642 target.ref = source.ref;
2643 target.pendingProps = source.pendingProps;
2644 target.memoizedProps = source.memoizedProps;
2645 target.updateQueue = source.updateQueue;
2646 target.memoizedState = source.memoizedState;
2647 target.contextDependencies = source.contextDependencies;
2648 target.mode = source.mode;
2649 target.effectTag = source.effectTag;
2650 target.nextEffect = source.nextEffect;
2651 target.firstEffect = source.firstEffect;
2652 target.lastEffect = source.lastEffect;
2653 target.expirationTime = source.expirationTime;
2654 target.childExpirationTime = source.childExpirationTime;
2655 target.alternate = source.alternate;
2656 if (enableProfilerTimer) {
2657 target.actualDuration = source.actualDuration;
2658 target.actualStartTime = source.actualStartTime;
2659 target.selfBaseDuration = source.selfBaseDuration;
2660 target.treeBaseDuration = source.treeBaseDuration;
2661 }
2662 target._debugID = source._debugID;
2663 target._debugSource = source._debugSource;
2664 target._debugOwner = source._debugOwner;
2665 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
2666 return target;
2667}
2668
2669var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2670
2671var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing;
2672var __interactionsRef = _ReactInternals$Sched$1.__interactionsRef;
2673var __subscriberRef = _ReactInternals$Sched$1.__subscriberRef;
2674var unstable_clear = _ReactInternals$Sched$1.unstable_clear;
2675var unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent;
2676var unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID;
2677var unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe;
2678var unstable_trace = _ReactInternals$Sched$1.unstable_trace;
2679var unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe;
2680var unstable_wrap = _ReactInternals$Sched$1.unstable_wrap;
2681
2682// TODO: This should be lifted into the renderer.
2683
2684
2685// The following attributes are only used by interaction tracing builds.
2686// They enable interactions to be associated with their async work,
2687// And expose interaction metadata to the React DevTools Profiler plugin.
2688// Note that these attributes are only defined when the enableSchedulerTracing flag is enabled.
2689
2690
2691// Exported FiberRoot type includes all properties,
2692// To avoid requiring potentially error-prone :any casts throughout the project.
2693// Profiling properties are only safe to access in profiling builds (when enableSchedulerTracing is true).
2694// The types are defined separately within this file to ensure they stay in sync.
2695// (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.)
2696
2697
2698function createFiberRoot(containerInfo, isConcurrent, hydrate) {
2699 // Cyclic construction. This cheats the type system right now because
2700 // stateNode is any.
2701 var uninitializedFiber = createHostRootFiber(isConcurrent);
2702
2703 var root = void 0;
2704 if (enableSchedulerTracing) {
2705 root = {
2706 current: uninitializedFiber,
2707 containerInfo: containerInfo,
2708 pendingChildren: null,
2709
2710 earliestPendingTime: NoWork,
2711 latestPendingTime: NoWork,
2712 earliestSuspendedTime: NoWork,
2713 latestSuspendedTime: NoWork,
2714 latestPingedTime: NoWork,
2715
2716 pingCache: null,
2717
2718 didError: false,
2719
2720 pendingCommitExpirationTime: NoWork,
2721 finishedWork: null,
2722 timeoutHandle: noTimeout,
2723 context: null,
2724 pendingContext: null,
2725 hydrate: hydrate,
2726 nextExpirationTimeToWorkOn: NoWork,
2727 expirationTime: NoWork,
2728 firstBatch: null,
2729 nextScheduledRoot: null,
2730
2731 interactionThreadID: unstable_getThreadID(),
2732 memoizedInteractions: new Set(),
2733 pendingInteractionMap: new Map()
2734 };
2735 } else {
2736 root = {
2737 current: uninitializedFiber,
2738 containerInfo: containerInfo,
2739 pendingChildren: null,
2740
2741 pingCache: null,
2742
2743 earliestPendingTime: NoWork,
2744 latestPendingTime: NoWork,
2745 earliestSuspendedTime: NoWork,
2746 latestSuspendedTime: NoWork,
2747 latestPingedTime: NoWork,
2748
2749 didError: false,
2750
2751 pendingCommitExpirationTime: NoWork,
2752 finishedWork: null,
2753 timeoutHandle: noTimeout,
2754 context: null,
2755 pendingContext: null,
2756 hydrate: hydrate,
2757 nextExpirationTimeToWorkOn: NoWork,
2758 expirationTime: NoWork,
2759 firstBatch: null,
2760 nextScheduledRoot: null
2761 };
2762 }
2763
2764 uninitializedFiber.stateNode = root;
2765
2766 // The reason for the way the Flow types are structured in this file,
2767 // Is to avoid needing :any casts everywhere interaction tracing fields are used.
2768 // Unfortunately that requires an :any cast for non-interaction tracing capable builds.
2769 // $FlowFixMe Remove this :any cast and replace it with something better.
2770 return root;
2771}
2772
2773var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
2774 var funcArgs = Array.prototype.slice.call(arguments, 3);
2775 try {
2776 func.apply(context, funcArgs);
2777 } catch (error) {
2778 this.onError(error);
2779 }
2780};
2781
2782{
2783 // In DEV mode, we swap out invokeGuardedCallback for a special version
2784 // that plays more nicely with the browser's DevTools. The idea is to preserve
2785 // "Pause on exceptions" behavior. Because React wraps all user-provided
2786 // functions in invokeGuardedCallback, and the production version of
2787 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
2788 // like caught exceptions, and the DevTools won't pause unless the developer
2789 // takes the extra step of enabling pause on caught exceptions. This is
2790 // unintuitive, though, because even though React has caught the error, from
2791 // the developer's perspective, the error is uncaught.
2792 //
2793 // To preserve the expected "Pause on exceptions" behavior, we don't use a
2794 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
2795 // DOM node, and call the user-provided callback from inside an event handler
2796 // for that fake event. If the callback throws, the error is "captured" using
2797 // a global event handler. But because the error happens in a different
2798 // event loop context, it does not interrupt the normal program flow.
2799 // Effectively, this gives us try-catch behavior without actually using
2800 // try-catch. Neat!
2801
2802 // Check that the browser supports the APIs we need to implement our special
2803 // DEV version of invokeGuardedCallback
2804 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
2805 var fakeNode = document.createElement('react');
2806
2807 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
2808 // If document doesn't exist we know for sure we will crash in this method
2809 // when we call document.createEvent(). However this can cause confusing
2810 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
2811 // So we preemptively throw with a better message instead.
2812 !(typeof document !== 'undefined') ? invariant(false, '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.') : void 0;
2813 var evt = document.createEvent('Event');
2814
2815 // Keeps track of whether the user-provided callback threw an error. We
2816 // set this to true at the beginning, then set it to false right after
2817 // calling the function. If the function errors, `didError` will never be
2818 // set to false. This strategy works even if the browser is flaky and
2819 // fails to call our global error handler, because it doesn't rely on
2820 // the error event at all.
2821 var didError = true;
2822
2823 // Keeps track of the value of window.event so that we can reset it
2824 // during the callback to let user code access window.event in the
2825 // browsers that support it.
2826 var windowEvent = window.event;
2827
2828 // Keeps track of the descriptor of window.event to restore it after event
2829 // dispatching: https://github.com/facebook/react/issues/13688
2830 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
2831
2832 // Create an event handler for our fake event. We will synchronously
2833 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
2834 // call the user-provided callback.
2835 var funcArgs = Array.prototype.slice.call(arguments, 3);
2836 function callCallback() {
2837 // We immediately remove the callback from event listeners so that
2838 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
2839 // nested call would trigger the fake event handlers of any call higher
2840 // in the stack.
2841 fakeNode.removeEventListener(evtType, callCallback, false);
2842
2843 // We check for window.hasOwnProperty('event') to prevent the
2844 // window.event assignment in both IE <= 10 as they throw an error
2845 // "Member not found" in strict mode, and in Firefox which does not
2846 // support window.event.
2847 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
2848 window.event = windowEvent;
2849 }
2850
2851 func.apply(context, funcArgs);
2852 didError = false;
2853 }
2854
2855 // Create a global error event handler. We use this to capture the value
2856 // that was thrown. It's possible that this error handler will fire more
2857 // than once; for example, if non-React code also calls `dispatchEvent`
2858 // and a handler for that event throws. We should be resilient to most of
2859 // those cases. Even if our error event handler fires more than once, the
2860 // last error event is always used. If the callback actually does error,
2861 // we know that the last error event is the correct one, because it's not
2862 // possible for anything else to have happened in between our callback
2863 // erroring and the code that follows the `dispatchEvent` call below. If
2864 // the callback doesn't error, but the error event was fired, we know to
2865 // ignore it because `didError` will be false, as described above.
2866 var error = void 0;
2867 // Use this to track whether the error event is ever called.
2868 var didSetError = false;
2869 var isCrossOriginError = false;
2870
2871 function handleWindowError(event) {
2872 error = event.error;
2873 didSetError = true;
2874 if (error === null && event.colno === 0 && event.lineno === 0) {
2875 isCrossOriginError = true;
2876 }
2877 if (event.defaultPrevented) {
2878 // Some other error handler has prevented default.
2879 // Browsers silence the error report if this happens.
2880 // We'll remember this to later decide whether to log it or not.
2881 if (error != null && typeof error === 'object') {
2882 try {
2883 error._suppressLogging = true;
2884 } catch (inner) {
2885 // Ignore.
2886 }
2887 }
2888 }
2889 }
2890
2891 // Create a fake event type.
2892 var evtType = 'react-' + (name ? name : 'invokeguardedcallback');
2893
2894 // Attach our event handlers
2895 window.addEventListener('error', handleWindowError);
2896 fakeNode.addEventListener(evtType, callCallback, false);
2897
2898 // Synchronously dispatch our fake event. If the user-provided function
2899 // errors, it will trigger our global error handler.
2900 evt.initEvent(evtType, false, false);
2901 fakeNode.dispatchEvent(evt);
2902
2903 if (windowEventDescriptor) {
2904 Object.defineProperty(window, 'event', windowEventDescriptor);
2905 }
2906
2907 if (didError) {
2908 if (!didSetError) {
2909 // The callback errored, but the error event never fired.
2910 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.');
2911 } else if (isCrossOriginError) {
2912 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.');
2913 }
2914 this.onError(error);
2915 }
2916
2917 // Remove our event listeners
2918 window.removeEventListener('error', handleWindowError);
2919 };
2920
2921 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
2922 }
2923}
2924
2925var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
2926
2927// Used by Fiber to simulate a try-catch.
2928var hasError = false;
2929var caughtError = null;
2930
2931var reporter = {
2932 onError: function (error) {
2933 hasError = true;
2934 caughtError = error;
2935 }
2936};
2937
2938/**
2939 * Call a function while guarding against errors that happens within it.
2940 * Returns an error if it throws, otherwise null.
2941 *
2942 * In production, this is implemented using a try-catch. The reason we don't
2943 * use a try-catch directly is so that we can swap out a different
2944 * implementation in DEV mode.
2945 *
2946 * @param {String} name of the guard to use for logging or debugging
2947 * @param {Function} func The function to invoke
2948 * @param {*} context The context to use when calling the function
2949 * @param {...*} args Arguments for function
2950 */
2951function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
2952 hasError = false;
2953 caughtError = null;
2954 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
2955}
2956
2957/**
2958 * Same as invokeGuardedCallback, but instead of returning an error, it stores
2959 * it in a global so it can be rethrown by `rethrowCaughtError` later.
2960 * TODO: See if caughtError and rethrowError can be unified.
2961 *
2962 * @param {String} name of the guard to use for logging or debugging
2963 * @param {Function} func The function to invoke
2964 * @param {*} context The context to use when calling the function
2965 * @param {...*} args Arguments for function
2966 */
2967
2968
2969/**
2970 * During execution of guarded functions we will capture the first error which
2971 * we will rethrow to be handled by the top level error handler.
2972 */
2973
2974
2975function hasCaughtError() {
2976 return hasError;
2977}
2978
2979function clearCaughtError() {
2980 if (hasError) {
2981 var error = caughtError;
2982 hasError = false;
2983 caughtError = null;
2984 return error;
2985 } else {
2986 invariant(false, 'clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.');
2987 }
2988}
2989
2990/**
2991 * Forked from fbjs/warning:
2992 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
2993 *
2994 * Only change is we use console.warn instead of console.error,
2995 * and do nothing when 'console' is not supported.
2996 * This really simplifies the code.
2997 * ---
2998 * Similar to invariant but only logs a warning if the condition is not met.
2999 * This can be used to log issues in development environments in critical
3000 * paths. Removing the logging code for production environments will keep the
3001 * same logic and follow the same code paths.
3002 */
3003
3004var lowPriorityWarning = function () {};
3005
3006{
3007 var printWarning$1 = function (format) {
3008 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
3009 args[_key - 1] = arguments[_key];
3010 }
3011
3012 var argIndex = 0;
3013 var message = 'Warning: ' + format.replace(/%s/g, function () {
3014 return args[argIndex++];
3015 });
3016 if (typeof console !== 'undefined') {
3017 console.warn(message);
3018 }
3019 try {
3020 // --- Welcome to debugging React ---
3021 // This error was thrown as a convenience so that you can use this stack
3022 // to find the callsite that caused this warning to fire.
3023 throw new Error(message);
3024 } catch (x) {}
3025 };
3026
3027 lowPriorityWarning = function (condition, format) {
3028 if (format === undefined) {
3029 throw new Error('`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument');
3030 }
3031 if (!condition) {
3032 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
3033 args[_key2 - 2] = arguments[_key2];
3034 }
3035
3036 printWarning$1.apply(undefined, [format].concat(args));
3037 }
3038 };
3039}
3040
3041var lowPriorityWarning$1 = lowPriorityWarning;
3042
3043var ReactStrictModeWarnings = {
3044 discardPendingWarnings: function () {},
3045 flushPendingDeprecationWarnings: function () {},
3046 flushPendingUnsafeLifecycleWarnings: function () {},
3047 recordDeprecationWarnings: function (fiber, instance) {},
3048 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
3049 recordLegacyContextWarning: function (fiber, instance) {},
3050 flushLegacyContextWarning: function () {}
3051};
3052
3053{
3054 var LIFECYCLE_SUGGESTIONS = {
3055 UNSAFE_componentWillMount: 'componentDidMount',
3056 UNSAFE_componentWillReceiveProps: 'static getDerivedStateFromProps',
3057 UNSAFE_componentWillUpdate: 'componentDidUpdate'
3058 };
3059
3060 var pendingComponentWillMountWarnings = [];
3061 var pendingComponentWillReceivePropsWarnings = [];
3062 var pendingComponentWillUpdateWarnings = [];
3063 var pendingUnsafeLifecycleWarnings = new Map();
3064 var pendingLegacyContextWarning = new Map();
3065
3066 // Tracks components we have already warned about.
3067 var didWarnAboutDeprecatedLifecycles = new Set();
3068 var didWarnAboutUnsafeLifecycles = new Set();
3069 var didWarnAboutLegacyContext = new Set();
3070
3071 var setToSortedString = function (set) {
3072 var array = [];
3073 set.forEach(function (value) {
3074 array.push(value);
3075 });
3076 return array.sort().join(', ');
3077 };
3078
3079 ReactStrictModeWarnings.discardPendingWarnings = function () {
3080 pendingComponentWillMountWarnings = [];
3081 pendingComponentWillReceivePropsWarnings = [];
3082 pendingComponentWillUpdateWarnings = [];
3083 pendingUnsafeLifecycleWarnings = new Map();
3084 pendingLegacyContextWarning = new Map();
3085 };
3086
3087 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
3088 pendingUnsafeLifecycleWarnings.forEach(function (lifecycleWarningsMap, strictRoot) {
3089 var lifecyclesWarningMessages = [];
3090
3091 Object.keys(lifecycleWarningsMap).forEach(function (lifecycle) {
3092 var lifecycleWarnings = lifecycleWarningsMap[lifecycle];
3093 if (lifecycleWarnings.length > 0) {
3094 var componentNames = new Set();
3095 lifecycleWarnings.forEach(function (fiber) {
3096 componentNames.add(getComponentName(fiber.type) || 'Component');
3097 didWarnAboutUnsafeLifecycles.add(fiber.type);
3098 });
3099
3100 var formatted = lifecycle.replace('UNSAFE_', '');
3101 var suggestion = LIFECYCLE_SUGGESTIONS[lifecycle];
3102 var sortedComponentNames = setToSortedString(componentNames);
3103
3104 lifecyclesWarningMessages.push(formatted + ': Please update the following components to use ' + (suggestion + ' instead: ' + sortedComponentNames));
3105 }
3106 });
3107
3108 if (lifecyclesWarningMessages.length > 0) {
3109 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
3110
3111 warningWithoutStack$1(false, 'Unsafe lifecycle methods were found within a strict-mode tree:%s' + '\n\n%s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-strict-mode-warnings', strictRootComponentStack, lifecyclesWarningMessages.join('\n\n'));
3112 }
3113 });
3114
3115 pendingUnsafeLifecycleWarnings = new Map();
3116 };
3117
3118 var findStrictRoot = function (fiber) {
3119 var maybeStrictRoot = null;
3120
3121 var node = fiber;
3122 while (node !== null) {
3123 if (node.mode & StrictMode) {
3124 maybeStrictRoot = node;
3125 }
3126 node = node.return;
3127 }
3128
3129 return maybeStrictRoot;
3130 };
3131
3132 ReactStrictModeWarnings.flushPendingDeprecationWarnings = function () {
3133 if (pendingComponentWillMountWarnings.length > 0) {
3134 var uniqueNames = new Set();
3135 pendingComponentWillMountWarnings.forEach(function (fiber) {
3136 uniqueNames.add(getComponentName(fiber.type) || 'Component');
3137 didWarnAboutDeprecatedLifecycles.add(fiber.type);
3138 });
3139
3140 var sortedNames = setToSortedString(uniqueNames);
3141
3142 lowPriorityWarning$1(false, 'componentWillMount is deprecated and will be removed in the next major version. ' + 'Use componentDidMount instead. As a temporary workaround, ' + 'you can rename to UNSAFE_componentWillMount.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-async-component-lifecycle-hooks', sortedNames);
3143
3144 pendingComponentWillMountWarnings = [];
3145 }
3146
3147 if (pendingComponentWillReceivePropsWarnings.length > 0) {
3148 var _uniqueNames = new Set();
3149 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
3150 _uniqueNames.add(getComponentName(fiber.type) || 'Component');
3151 didWarnAboutDeprecatedLifecycles.add(fiber.type);
3152 });
3153
3154 var _sortedNames = setToSortedString(_uniqueNames);
3155
3156 lowPriorityWarning$1(false, 'componentWillReceiveProps is deprecated and will be removed in the next major version. ' + 'Use static getDerivedStateFromProps instead.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-async-component-lifecycle-hooks', _sortedNames);
3157
3158 pendingComponentWillReceivePropsWarnings = [];
3159 }
3160
3161 if (pendingComponentWillUpdateWarnings.length > 0) {
3162 var _uniqueNames2 = new Set();
3163 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
3164 _uniqueNames2.add(getComponentName(fiber.type) || 'Component');
3165 didWarnAboutDeprecatedLifecycles.add(fiber.type);
3166 });
3167
3168 var _sortedNames2 = setToSortedString(_uniqueNames2);
3169
3170 lowPriorityWarning$1(false, 'componentWillUpdate is deprecated and will be removed in the next major version. ' + 'Use componentDidUpdate instead. As a temporary workaround, ' + 'you can rename to UNSAFE_componentWillUpdate.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-async-component-lifecycle-hooks', _sortedNames2);
3171
3172 pendingComponentWillUpdateWarnings = [];
3173 }
3174 };
3175
3176 ReactStrictModeWarnings.recordDeprecationWarnings = function (fiber, instance) {
3177 // Dedup strategy: Warn once per component.
3178 if (didWarnAboutDeprecatedLifecycles.has(fiber.type)) {
3179 return;
3180 }
3181
3182 // Don't warn about react-lifecycles-compat polyfilled components.
3183 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
3184 pendingComponentWillMountWarnings.push(fiber);
3185 }
3186 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
3187 pendingComponentWillReceivePropsWarnings.push(fiber);
3188 }
3189 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
3190 pendingComponentWillUpdateWarnings.push(fiber);
3191 }
3192 };
3193
3194 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
3195 var strictRoot = findStrictRoot(fiber);
3196 if (strictRoot === null) {
3197 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.');
3198 return;
3199 }
3200
3201 // Dedup strategy: Warn once per component.
3202 // This is difficult to track any other way since component names
3203 // are often vague and are likely to collide between 3rd party libraries.
3204 // An expand property is probably okay to use here since it's DEV-only,
3205 // and will only be set in the event of serious warnings.
3206 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
3207 return;
3208 }
3209
3210 var warningsForRoot = void 0;
3211 if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) {
3212 warningsForRoot = {
3213 UNSAFE_componentWillMount: [],
3214 UNSAFE_componentWillReceiveProps: [],
3215 UNSAFE_componentWillUpdate: []
3216 };
3217
3218 pendingUnsafeLifecycleWarnings.set(strictRoot, warningsForRoot);
3219 } else {
3220 warningsForRoot = pendingUnsafeLifecycleWarnings.get(strictRoot);
3221 }
3222
3223 var unsafeLifecycles = [];
3224 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillMount === 'function') {
3225 unsafeLifecycles.push('UNSAFE_componentWillMount');
3226 }
3227 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
3228 unsafeLifecycles.push('UNSAFE_componentWillReceiveProps');
3229 }
3230 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillUpdate === 'function') {
3231 unsafeLifecycles.push('UNSAFE_componentWillUpdate');
3232 }
3233
3234 if (unsafeLifecycles.length > 0) {
3235 unsafeLifecycles.forEach(function (lifecycle) {
3236 warningsForRoot[lifecycle].push(fiber);
3237 });
3238 }
3239 };
3240
3241 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
3242 var strictRoot = findStrictRoot(fiber);
3243 if (strictRoot === null) {
3244 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.');
3245 return;
3246 }
3247
3248 // Dedup strategy: Warn once per component.
3249 if (didWarnAboutLegacyContext.has(fiber.type)) {
3250 return;
3251 }
3252
3253 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
3254
3255 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
3256 if (warningsForRoot === undefined) {
3257 warningsForRoot = [];
3258 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
3259 }
3260 warningsForRoot.push(fiber);
3261 }
3262 };
3263
3264 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
3265 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
3266 var uniqueNames = new Set();
3267 fiberArray.forEach(function (fiber) {
3268 uniqueNames.add(getComponentName(fiber.type) || 'Component');
3269 didWarnAboutLegacyContext.add(fiber.type);
3270 });
3271
3272 var sortedNames = setToSortedString(uniqueNames);
3273 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
3274
3275 warningWithoutStack$1(false, 'Legacy context API has been detected within a strict-mode tree: %s' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-strict-mode-warnings', strictRootComponentStack, sortedNames);
3276 });
3277 };
3278}
3279
3280// This lets us hook into Fiber to debug what it's doing.
3281// See https://github.com/facebook/react/pull/8033.
3282// This is not part of the public API, not even for React DevTools.
3283// You may only inject a debugTool if you work on React Fiber itself.
3284var ReactFiberInstrumentation = {
3285 debugTool: null
3286};
3287
3288var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
3289
3290// TODO: Offscreen updates should never suspend. However, a promise that
3291// suspended inside an offscreen subtree should be able to ping at the priority
3292// of the outer render.
3293
3294function markPendingPriorityLevel(root, expirationTime) {
3295 // If there's a gap between completing a failed root and retrying it,
3296 // additional updates may be scheduled. Clear `didError`, in case the update
3297 // is sufficient to fix the error.
3298 root.didError = false;
3299
3300 // Update the latest and earliest pending times
3301 var earliestPendingTime = root.earliestPendingTime;
3302 if (earliestPendingTime === NoWork) {
3303 // No other pending updates.
3304 root.earliestPendingTime = root.latestPendingTime = expirationTime;
3305 } else {
3306 if (earliestPendingTime < expirationTime) {
3307 // This is the earliest pending update.
3308 root.earliestPendingTime = expirationTime;
3309 } else {
3310 var latestPendingTime = root.latestPendingTime;
3311 if (latestPendingTime > expirationTime) {
3312 // This is the latest pending update
3313 root.latestPendingTime = expirationTime;
3314 }
3315 }
3316 }
3317 findNextExpirationTimeToWorkOn(expirationTime, root);
3318}
3319
3320function markCommittedPriorityLevels(root, earliestRemainingTime) {
3321 root.didError = false;
3322
3323 if (earliestRemainingTime === NoWork) {
3324 // Fast path. There's no remaining work. Clear everything.
3325 root.earliestPendingTime = NoWork;
3326 root.latestPendingTime = NoWork;
3327 root.earliestSuspendedTime = NoWork;
3328 root.latestSuspendedTime = NoWork;
3329 root.latestPingedTime = NoWork;
3330 findNextExpirationTimeToWorkOn(NoWork, root);
3331 return;
3332 }
3333
3334 if (earliestRemainingTime < root.latestPingedTime) {
3335 root.latestPingedTime = NoWork;
3336 }
3337
3338 // Let's see if the previous latest known pending level was just flushed.
3339 var latestPendingTime = root.latestPendingTime;
3340 if (latestPendingTime !== NoWork) {
3341 if (latestPendingTime > earliestRemainingTime) {
3342 // We've flushed all the known pending levels.
3343 root.earliestPendingTime = root.latestPendingTime = NoWork;
3344 } else {
3345 var earliestPendingTime = root.earliestPendingTime;
3346 if (earliestPendingTime > earliestRemainingTime) {
3347 // We've flushed the earliest known pending level. Set this to the
3348 // latest pending time.
3349 root.earliestPendingTime = root.latestPendingTime;
3350 }
3351 }
3352 }
3353
3354 // Now let's handle the earliest remaining level in the whole tree. We need to
3355 // decide whether to treat it as a pending level or as suspended. Check
3356 // it falls within the range of known suspended levels.
3357
3358 var earliestSuspendedTime = root.earliestSuspendedTime;
3359 if (earliestSuspendedTime === NoWork) {
3360 // There's no suspended work. Treat the earliest remaining level as a
3361 // pending level.
3362 markPendingPriorityLevel(root, earliestRemainingTime);
3363 findNextExpirationTimeToWorkOn(NoWork, root);
3364 return;
3365 }
3366
3367 var latestSuspendedTime = root.latestSuspendedTime;
3368 if (earliestRemainingTime < latestSuspendedTime) {
3369 // The earliest remaining level is later than all the suspended work. That
3370 // means we've flushed all the suspended work.
3371 root.earliestSuspendedTime = NoWork;
3372 root.latestSuspendedTime = NoWork;
3373 root.latestPingedTime = NoWork;
3374
3375 // There's no suspended work. Treat the earliest remaining level as a
3376 // pending level.
3377 markPendingPriorityLevel(root, earliestRemainingTime);
3378 findNextExpirationTimeToWorkOn(NoWork, root);
3379 return;
3380 }
3381
3382 if (earliestRemainingTime > earliestSuspendedTime) {
3383 // The earliest remaining time is earlier than all the suspended work.
3384 // Treat it as a pending update.
3385 markPendingPriorityLevel(root, earliestRemainingTime);
3386 findNextExpirationTimeToWorkOn(NoWork, root);
3387 return;
3388 }
3389
3390 // The earliest remaining time falls within the range of known suspended
3391 // levels. We should treat this as suspended work.
3392 findNextExpirationTimeToWorkOn(NoWork, root);
3393}
3394
3395function hasLowerPriorityWork(root, erroredExpirationTime) {
3396 var latestPendingTime = root.latestPendingTime;
3397 var latestSuspendedTime = root.latestSuspendedTime;
3398 var latestPingedTime = root.latestPingedTime;
3399 return latestPendingTime !== NoWork && latestPendingTime < erroredExpirationTime || latestSuspendedTime !== NoWork && latestSuspendedTime < erroredExpirationTime || latestPingedTime !== NoWork && latestPingedTime < erroredExpirationTime;
3400}
3401
3402function isPriorityLevelSuspended(root, expirationTime) {
3403 var earliestSuspendedTime = root.earliestSuspendedTime;
3404 var latestSuspendedTime = root.latestSuspendedTime;
3405 return earliestSuspendedTime !== NoWork && expirationTime <= earliestSuspendedTime && expirationTime >= latestSuspendedTime;
3406}
3407
3408function markSuspendedPriorityLevel(root, suspendedTime) {
3409 root.didError = false;
3410 clearPing(root, suspendedTime);
3411
3412 // First, check the known pending levels and update them if needed.
3413 var earliestPendingTime = root.earliestPendingTime;
3414 var latestPendingTime = root.latestPendingTime;
3415 if (earliestPendingTime === suspendedTime) {
3416 if (latestPendingTime === suspendedTime) {
3417 // Both known pending levels were suspended. Clear them.
3418 root.earliestPendingTime = root.latestPendingTime = NoWork;
3419 } else {
3420 // The earliest pending level was suspended. Clear by setting it to the
3421 // latest pending level.
3422 root.earliestPendingTime = latestPendingTime;
3423 }
3424 } else if (latestPendingTime === suspendedTime) {
3425 // The latest pending level was suspended. Clear by setting it to the
3426 // latest pending level.
3427 root.latestPendingTime = earliestPendingTime;
3428 }
3429
3430 // Finally, update the known suspended levels.
3431 var earliestSuspendedTime = root.earliestSuspendedTime;
3432 var latestSuspendedTime = root.latestSuspendedTime;
3433 if (earliestSuspendedTime === NoWork) {
3434 // No other suspended levels.
3435 root.earliestSuspendedTime = root.latestSuspendedTime = suspendedTime;
3436 } else {
3437 if (earliestSuspendedTime < suspendedTime) {
3438 // This is the earliest suspended level.
3439 root.earliestSuspendedTime = suspendedTime;
3440 } else if (latestSuspendedTime > suspendedTime) {
3441 // This is the latest suspended level
3442 root.latestSuspendedTime = suspendedTime;
3443 }
3444 }
3445
3446 findNextExpirationTimeToWorkOn(suspendedTime, root);
3447}
3448
3449function markPingedPriorityLevel(root, pingedTime) {
3450 root.didError = false;
3451
3452 // TODO: When we add back resuming, we need to ensure the progressed work
3453 // is thrown out and not reused during the restarted render. One way to
3454 // invalidate the progressed work is to restart at expirationTime + 1.
3455 var latestPingedTime = root.latestPingedTime;
3456 if (latestPingedTime === NoWork || latestPingedTime > pingedTime) {
3457 root.latestPingedTime = pingedTime;
3458 }
3459 findNextExpirationTimeToWorkOn(pingedTime, root);
3460}
3461
3462function clearPing(root, completedTime) {
3463 var latestPingedTime = root.latestPingedTime;
3464 if (latestPingedTime >= completedTime) {
3465 root.latestPingedTime = NoWork;
3466 }
3467}
3468
3469function findEarliestOutstandingPriorityLevel(root, renderExpirationTime) {
3470 var earliestExpirationTime = renderExpirationTime;
3471
3472 var earliestPendingTime = root.earliestPendingTime;
3473 var earliestSuspendedTime = root.earliestSuspendedTime;
3474 if (earliestPendingTime > earliestExpirationTime) {
3475 earliestExpirationTime = earliestPendingTime;
3476 }
3477 if (earliestSuspendedTime > earliestExpirationTime) {
3478 earliestExpirationTime = earliestSuspendedTime;
3479 }
3480 return earliestExpirationTime;
3481}
3482
3483function didExpireAtExpirationTime(root, currentTime) {
3484 var expirationTime = root.expirationTime;
3485 if (expirationTime !== NoWork && currentTime <= expirationTime) {
3486 // The root has expired. Flush all work up to the current time.
3487 root.nextExpirationTimeToWorkOn = currentTime;
3488 }
3489}
3490
3491function findNextExpirationTimeToWorkOn(completedExpirationTime, root) {
3492 var earliestSuspendedTime = root.earliestSuspendedTime;
3493 var latestSuspendedTime = root.latestSuspendedTime;
3494 var earliestPendingTime = root.earliestPendingTime;
3495 var latestPingedTime = root.latestPingedTime;
3496
3497 // Work on the earliest pending time. Failing that, work on the latest
3498 // pinged time.
3499 var nextExpirationTimeToWorkOn = earliestPendingTime !== NoWork ? earliestPendingTime : latestPingedTime;
3500
3501 // If there is no pending or pinged work, check if there's suspended work
3502 // that's lower priority than what we just completed.
3503 if (nextExpirationTimeToWorkOn === NoWork && (completedExpirationTime === NoWork || latestSuspendedTime < completedExpirationTime)) {
3504 // The lowest priority suspended work is the work most likely to be
3505 // committed next. Let's start rendering it again, so that if it times out,
3506 // it's ready to commit.
3507 nextExpirationTimeToWorkOn = latestSuspendedTime;
3508 }
3509
3510 var expirationTime = nextExpirationTimeToWorkOn;
3511 if (expirationTime !== NoWork && earliestSuspendedTime > expirationTime) {
3512 // Expire using the earliest known expiration time.
3513 expirationTime = earliestSuspendedTime;
3514 }
3515
3516 root.nextExpirationTimeToWorkOn = nextExpirationTimeToWorkOn;
3517 root.expirationTime = expirationTime;
3518}
3519
3520/**
3521 * Similar to invariant but only logs a warning if the condition is not met.
3522 * This can be used to log issues in development environments in critical
3523 * paths. Removing the logging code for production environments will keep the
3524 * same logic and follow the same code paths.
3525 */
3526
3527var warning = warningWithoutStack$1;
3528
3529{
3530 warning = function (condition, format) {
3531 if (condition) {
3532 return;
3533 }
3534 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
3535 var stack = ReactDebugCurrentFrame.getStackAddendum();
3536 // eslint-disable-next-line react-internal/warning-and-invariant-args
3537
3538 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
3539 args[_key - 2] = arguments[_key];
3540 }
3541
3542 warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack]));
3543 };
3544}
3545
3546var warning$1 = warning;
3547
3548/**
3549 * inlined Object.is polyfill to avoid requiring consumers ship their own
3550 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
3551 */
3552function is(x, y) {
3553 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
3554 ;
3555}
3556
3557var hasOwnProperty = Object.prototype.hasOwnProperty;
3558
3559/**
3560 * Performs equality by iterating through keys on an object and returning false
3561 * when any key has values which are not strictly equal between the arguments.
3562 * Returns true when the values of all keys are strictly equal.
3563 */
3564function shallowEqual(objA, objB) {
3565 if (is(objA, objB)) {
3566 return true;
3567 }
3568
3569 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
3570 return false;
3571 }
3572
3573 var keysA = Object.keys(objA);
3574 var keysB = Object.keys(objB);
3575
3576 if (keysA.length !== keysB.length) {
3577 return false;
3578 }
3579
3580 // Test for A's keys different from B.
3581 for (var i = 0; i < keysA.length; i++) {
3582 if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
3583 return false;
3584 }
3585 }
3586
3587 return true;
3588}
3589
3590function resolveDefaultProps(Component, baseProps) {
3591 if (Component && Component.defaultProps) {
3592 // Resolve default props. Taken from ReactElement
3593 var props = _assign({}, baseProps);
3594 var defaultProps = Component.defaultProps;
3595 for (var propName in defaultProps) {
3596 if (props[propName] === undefined) {
3597 props[propName] = defaultProps[propName];
3598 }
3599 }
3600 return props;
3601 }
3602 return baseProps;
3603}
3604
3605function readLazyComponentType(lazyComponent) {
3606 var status = lazyComponent._status;
3607 var result = lazyComponent._result;
3608 switch (status) {
3609 case Resolved:
3610 {
3611 var Component = result;
3612 return Component;
3613 }
3614 case Rejected:
3615 {
3616 var error = result;
3617 throw error;
3618 }
3619 case Pending:
3620 {
3621 var thenable = result;
3622 throw thenable;
3623 }
3624 default:
3625 {
3626 lazyComponent._status = Pending;
3627 var ctor = lazyComponent._ctor;
3628 var _thenable = ctor();
3629 _thenable.then(function (moduleObject) {
3630 if (lazyComponent._status === Pending) {
3631 var defaultExport = moduleObject.default;
3632 {
3633 if (defaultExport === undefined) {
3634 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);
3635 }
3636 }
3637 lazyComponent._status = Resolved;
3638 lazyComponent._result = defaultExport;
3639 }
3640 }, function (error) {
3641 if (lazyComponent._status === Pending) {
3642 lazyComponent._status = Rejected;
3643 lazyComponent._result = error;
3644 }
3645 });
3646 // Handle synchronous thenables.
3647 switch (lazyComponent._status) {
3648 case Resolved:
3649 return lazyComponent._result;
3650 case Rejected:
3651 throw lazyComponent._result;
3652 }
3653 lazyComponent._result = _thenable;
3654 throw _thenable;
3655 }
3656 }
3657}
3658
3659var fakeInternalInstance = {};
3660var isArray$1 = Array.isArray;
3661
3662// React.Component uses a shared frozen object by default.
3663// We'll use it to determine whether we need to initialize legacy refs.
3664var emptyRefsObject = new React.Component().refs;
3665
3666var didWarnAboutStateAssignmentForComponent = void 0;
3667var didWarnAboutUninitializedState = void 0;
3668var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0;
3669var didWarnAboutLegacyLifecyclesAndDerivedState = void 0;
3670var didWarnAboutUndefinedDerivedState = void 0;
3671var warnOnUndefinedDerivedState = void 0;
3672var warnOnInvalidCallback = void 0;
3673var didWarnAboutDirectlyAssigningPropsToState = void 0;
3674var didWarnAboutContextTypeAndContextTypes = void 0;
3675var didWarnAboutInvalidateContextType = void 0;
3676
3677{
3678 didWarnAboutStateAssignmentForComponent = new Set();
3679 didWarnAboutUninitializedState = new Set();
3680 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
3681 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
3682 didWarnAboutDirectlyAssigningPropsToState = new Set();
3683 didWarnAboutUndefinedDerivedState = new Set();
3684 didWarnAboutContextTypeAndContextTypes = new Set();
3685 didWarnAboutInvalidateContextType = new Set();
3686
3687 var didWarnOnInvalidCallback = new Set();
3688
3689 warnOnInvalidCallback = function (callback, callerName) {
3690 if (callback === null || typeof callback === 'function') {
3691 return;
3692 }
3693 var key = callerName + '_' + callback;
3694 if (!didWarnOnInvalidCallback.has(key)) {
3695 didWarnOnInvalidCallback.add(key);
3696 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
3697 }
3698 };
3699
3700 warnOnUndefinedDerivedState = function (type, partialState) {
3701 if (partialState === undefined) {
3702 var componentName = getComponentName(type) || 'Component';
3703 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
3704 didWarnAboutUndefinedDerivedState.add(componentName);
3705 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
3706 }
3707 }
3708 };
3709
3710 // This is so gross but it's at least non-critical and can be removed if
3711 // it causes problems. This is meant to give a nicer error message for
3712 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
3713 // ...)) which otherwise throws a "_processChildContext is not a function"
3714 // exception.
3715 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
3716 enumerable: false,
3717 value: function () {
3718 invariant(false, '_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).');
3719 }
3720 });
3721 Object.freeze(fakeInternalInstance);
3722}
3723
3724function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
3725 var prevState = workInProgress.memoizedState;
3726
3727 {
3728 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
3729 // Invoke the function an extra time to help detect side-effects.
3730 getDerivedStateFromProps(nextProps, prevState);
3731 }
3732 }
3733
3734 var partialState = getDerivedStateFromProps(nextProps, prevState);
3735
3736 {
3737 warnOnUndefinedDerivedState(ctor, partialState);
3738 }
3739 // Merge the partial state and the previous state.
3740 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
3741 workInProgress.memoizedState = memoizedState;
3742
3743 // Once the update queue is empty, persist the derived state onto the
3744 // base state.
3745 var updateQueue = workInProgress.updateQueue;
3746 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
3747 updateQueue.baseState = memoizedState;
3748 }
3749}
3750
3751var classComponentUpdater = {
3752 isMounted: isMounted,
3753 enqueueSetState: function (inst, payload, callback) {
3754 var fiber = get(inst);
3755 var currentTime = requestCurrentTime();
3756 var expirationTime = computeExpirationForFiber(currentTime, fiber);
3757
3758 var update = createUpdate(expirationTime);
3759 update.payload = payload;
3760 if (callback !== undefined && callback !== null) {
3761 {
3762 warnOnInvalidCallback(callback, 'setState');
3763 }
3764 update.callback = callback;
3765 }
3766
3767 flushPassiveEffects();
3768 enqueueUpdate(fiber, update);
3769 scheduleWork(fiber, expirationTime);
3770 },
3771 enqueueReplaceState: function (inst, payload, callback) {
3772 var fiber = get(inst);
3773 var currentTime = requestCurrentTime();
3774 var expirationTime = computeExpirationForFiber(currentTime, fiber);
3775
3776 var update = createUpdate(expirationTime);
3777 update.tag = ReplaceState;
3778 update.payload = payload;
3779
3780 if (callback !== undefined && callback !== null) {
3781 {
3782 warnOnInvalidCallback(callback, 'replaceState');
3783 }
3784 update.callback = callback;
3785 }
3786
3787 flushPassiveEffects();
3788 enqueueUpdate(fiber, update);
3789 scheduleWork(fiber, expirationTime);
3790 },
3791 enqueueForceUpdate: function (inst, callback) {
3792 var fiber = get(inst);
3793 var currentTime = requestCurrentTime();
3794 var expirationTime = computeExpirationForFiber(currentTime, fiber);
3795
3796 var update = createUpdate(expirationTime);
3797 update.tag = ForceUpdate;
3798
3799 if (callback !== undefined && callback !== null) {
3800 {
3801 warnOnInvalidCallback(callback, 'forceUpdate');
3802 }
3803 update.callback = callback;
3804 }
3805
3806 flushPassiveEffects();
3807 enqueueUpdate(fiber, update);
3808 scheduleWork(fiber, expirationTime);
3809 }
3810};
3811
3812function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
3813 var instance = workInProgress.stateNode;
3814 if (typeof instance.shouldComponentUpdate === 'function') {
3815 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
3816 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
3817 stopPhaseTimer();
3818
3819 {
3820 !(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;
3821 }
3822
3823 return shouldUpdate;
3824 }
3825
3826 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
3827 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
3828 }
3829
3830 return true;
3831}
3832
3833function checkClassInstance(workInProgress, ctor, newProps) {
3834 var instance = workInProgress.stateNode;
3835 {
3836 var name = getComponentName(ctor) || 'Component';
3837 var renderPresent = instance.render;
3838
3839 if (!renderPresent) {
3840 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
3841 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
3842 } else {
3843 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
3844 }
3845 }
3846
3847 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
3848 !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;
3849 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
3850 !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;
3851 var noInstancePropTypes = !instance.propTypes;
3852 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0;
3853 var noInstanceContextType = !instance.contextType;
3854 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0;
3855 var noInstanceContextTypes = !instance.contextTypes;
3856 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0;
3857
3858 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
3859 didWarnAboutContextTypeAndContextTypes.add(ctor);
3860 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
3861 }
3862
3863 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
3864 !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;
3865 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
3866 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');
3867 }
3868 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
3869 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0;
3870 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
3871 !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;
3872 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
3873 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0;
3874 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
3875 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0;
3876 var hasMutatedProps = instance.props !== newProps;
3877 !(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;
3878 var noInstanceDefaultProps = !instance.defaultProps;
3879 !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;
3880
3881 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
3882 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
3883 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
3884 }
3885
3886 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function';
3887 !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;
3888 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function';
3889 !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;
3890 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function';
3891 !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;
3892 var _state = instance.state;
3893 if (_state && (typeof _state !== 'object' || isArray$1(_state))) {
3894 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name);
3895 }
3896 if (typeof instance.getChildContext === 'function') {
3897 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0;
3898 }
3899 }
3900}
3901
3902function adoptClassInstance(workInProgress, instance) {
3903 instance.updater = classComponentUpdater;
3904 workInProgress.stateNode = instance;
3905 // The instance needs access to the fiber so that it can schedule updates
3906 set(instance, workInProgress);
3907 {
3908 instance._reactInternalInstance = fakeInternalInstance;
3909 }
3910}
3911
3912function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) {
3913 var isLegacyContextConsumer = false;
3914 var unmaskedContext = emptyContextObject;
3915 var context = null;
3916 var contextType = ctor.contextType;
3917 if (typeof contextType === 'object' && contextType !== null) {
3918 {
3919 if (contextType.$$typeof !== REACT_CONTEXT_TYPE && !didWarnAboutInvalidateContextType.has(ctor)) {
3920 didWarnAboutInvalidateContextType.add(ctor);
3921 warningWithoutStack$1(false, '%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext(). ' + 'Did you accidentally pass the Context.Provider instead?', getComponentName(ctor) || 'Component');
3922 }
3923 }
3924
3925 context = readContext(contextType);
3926 } else {
3927 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
3928 var contextTypes = ctor.contextTypes;
3929 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
3930 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
3931 }
3932
3933 // Instantiate twice to help detect side-effects.
3934 {
3935 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
3936 new ctor(props, context); // eslint-disable-line no-new
3937 }
3938 }
3939
3940 var instance = new ctor(props, context);
3941 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
3942 adoptClassInstance(workInProgress, instance);
3943
3944 {
3945 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
3946 var componentName = getComponentName(ctor) || 'Component';
3947 if (!didWarnAboutUninitializedState.has(componentName)) {
3948 didWarnAboutUninitializedState.add(componentName);
3949 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);
3950 }
3951 }
3952
3953 // If new component APIs are defined, "unsafe" lifecycles won't be called.
3954 // Warn about these lifecycles if they are present.
3955 // Don't warn about react-lifecycles-compat polyfilled methods though.
3956 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
3957 var foundWillMountName = null;
3958 var foundWillReceivePropsName = null;
3959 var foundWillUpdateName = null;
3960 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
3961 foundWillMountName = 'componentWillMount';
3962 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
3963 foundWillMountName = 'UNSAFE_componentWillMount';
3964 }
3965 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
3966 foundWillReceivePropsName = 'componentWillReceiveProps';
3967 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
3968 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
3969 }
3970 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
3971 foundWillUpdateName = 'componentWillUpdate';
3972 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
3973 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
3974 }
3975 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
3976 var _componentName = getComponentName(ctor) || 'Component';
3977 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
3978 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
3979 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
3980 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 : '');
3981 }
3982 }
3983 }
3984 }
3985
3986 // Cache unmasked context so we can avoid recreating masked context unless necessary.
3987 // ReactFiberContext usually updates this cache but can't for newly-created instances.
3988 if (isLegacyContextConsumer) {
3989 cacheContext(workInProgress, unmaskedContext, context);
3990 }
3991
3992 return instance;
3993}
3994
3995function callComponentWillMount(workInProgress, instance) {
3996 startPhaseTimer(workInProgress, 'componentWillMount');
3997 var oldState = instance.state;
3998
3999 if (typeof instance.componentWillMount === 'function') {
4000 instance.componentWillMount();
4001 }
4002 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4003 instance.UNSAFE_componentWillMount();
4004 }
4005
4006 stopPhaseTimer();
4007
4008 if (oldState !== instance.state) {
4009 {
4010 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');
4011 }
4012 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4013 }
4014}
4015
4016function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
4017 var oldState = instance.state;
4018 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
4019 if (typeof instance.componentWillReceiveProps === 'function') {
4020 instance.componentWillReceiveProps(newProps, nextContext);
4021 }
4022 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4023 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
4024 }
4025 stopPhaseTimer();
4026
4027 if (instance.state !== oldState) {
4028 {
4029 var componentName = getComponentName(workInProgress.type) || 'Component';
4030 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
4031 didWarnAboutStateAssignmentForComponent.add(componentName);
4032 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
4033 }
4034 }
4035 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4036 }
4037}
4038
4039// Invokes the mount life-cycles on a previously never rendered instance.
4040function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4041 {
4042 checkClassInstance(workInProgress, ctor, newProps);
4043 }
4044
4045 var instance = workInProgress.stateNode;
4046 instance.props = newProps;
4047 instance.state = workInProgress.memoizedState;
4048 instance.refs = emptyRefsObject;
4049
4050 var contextType = ctor.contextType;
4051 if (typeof contextType === 'object' && contextType !== null) {
4052 instance.context = readContext(contextType);
4053 } else {
4054 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4055 instance.context = getMaskedContext(workInProgress, unmaskedContext);
4056 }
4057
4058 {
4059 if (instance.state === newProps) {
4060 var componentName = getComponentName(ctor) || 'Component';
4061 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
4062 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
4063 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);
4064 }
4065 }
4066
4067 if (workInProgress.mode & StrictMode) {
4068 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
4069
4070 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
4071 }
4072
4073 if (warnAboutDeprecatedLifecycles) {
4074 ReactStrictModeWarnings.recordDeprecationWarnings(workInProgress, instance);
4075 }
4076 }
4077
4078 var updateQueue = workInProgress.updateQueue;
4079 if (updateQueue !== null) {
4080 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4081 instance.state = workInProgress.memoizedState;
4082 }
4083
4084 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4085 if (typeof getDerivedStateFromProps === 'function') {
4086 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4087 instance.state = workInProgress.memoizedState;
4088 }
4089
4090 // In order to support react-lifecycles-compat polyfilled components,
4091 // Unsafe lifecycles should not be invoked for components using the new APIs.
4092 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4093 callComponentWillMount(workInProgress, instance);
4094 // If we had additional state updates during this life-cycle, let's
4095 // process them now.
4096 updateQueue = workInProgress.updateQueue;
4097 if (updateQueue !== null) {
4098 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4099 instance.state = workInProgress.memoizedState;
4100 }
4101 }
4102
4103 if (typeof instance.componentDidMount === 'function') {
4104 workInProgress.effectTag |= Update;
4105 }
4106}
4107
4108function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4109 var instance = workInProgress.stateNode;
4110
4111 var oldProps = workInProgress.memoizedProps;
4112 instance.props = oldProps;
4113
4114 var oldContext = instance.context;
4115 var contextType = ctor.contextType;
4116 var nextContext = void 0;
4117 if (typeof contextType === 'object' && contextType !== null) {
4118 nextContext = readContext(contextType);
4119 } else {
4120 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4121 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
4122 }
4123
4124 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4125 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
4126
4127 // Note: During these life-cycles, instance.props/instance.state are what
4128 // ever the previously attempted to render - not the "current". However,
4129 // during componentDidUpdate we pass the "current" props.
4130
4131 // In order to support react-lifecycles-compat polyfilled components,
4132 // Unsafe lifecycles should not be invoked for components using the new APIs.
4133 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4134 if (oldProps !== newProps || oldContext !== nextContext) {
4135 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4136 }
4137 }
4138
4139 resetHasForceUpdateBeforeProcessing();
4140
4141 var oldState = workInProgress.memoizedState;
4142 var newState = instance.state = oldState;
4143 var updateQueue = workInProgress.updateQueue;
4144 if (updateQueue !== null) {
4145 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4146 newState = workInProgress.memoizedState;
4147 }
4148 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4149 // If an update was already in progress, we should schedule an Update
4150 // effect even though we're bailing out, so that cWU/cDU are called.
4151 if (typeof instance.componentDidMount === 'function') {
4152 workInProgress.effectTag |= Update;
4153 }
4154 return false;
4155 }
4156
4157 if (typeof getDerivedStateFromProps === 'function') {
4158 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4159 newState = workInProgress.memoizedState;
4160 }
4161
4162 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4163
4164 if (shouldUpdate) {
4165 // In order to support react-lifecycles-compat polyfilled components,
4166 // Unsafe lifecycles should not be invoked for components using the new APIs.
4167 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4168 startPhaseTimer(workInProgress, 'componentWillMount');
4169 if (typeof instance.componentWillMount === 'function') {
4170 instance.componentWillMount();
4171 }
4172 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4173 instance.UNSAFE_componentWillMount();
4174 }
4175 stopPhaseTimer();
4176 }
4177 if (typeof instance.componentDidMount === 'function') {
4178 workInProgress.effectTag |= Update;
4179 }
4180 } else {
4181 // If an update was already in progress, we should schedule an Update
4182 // effect even though we're bailing out, so that cWU/cDU are called.
4183 if (typeof instance.componentDidMount === 'function') {
4184 workInProgress.effectTag |= Update;
4185 }
4186
4187 // If shouldComponentUpdate returned false, we should still update the
4188 // memoized state to indicate that this work can be reused.
4189 workInProgress.memoizedProps = newProps;
4190 workInProgress.memoizedState = newState;
4191 }
4192
4193 // Update the existing instance's state, props, and context pointers even
4194 // if shouldComponentUpdate returns false.
4195 instance.props = newProps;
4196 instance.state = newState;
4197 instance.context = nextContext;
4198
4199 return shouldUpdate;
4200}
4201
4202// Invokes the update life-cycles and returns false if it shouldn't rerender.
4203function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
4204 var instance = workInProgress.stateNode;
4205
4206 var oldProps = workInProgress.memoizedProps;
4207 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
4208
4209 var oldContext = instance.context;
4210 var contextType = ctor.contextType;
4211 var nextContext = void 0;
4212 if (typeof contextType === 'object' && contextType !== null) {
4213 nextContext = readContext(contextType);
4214 } else {
4215 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4216 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
4217 }
4218
4219 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4220 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
4221
4222 // Note: During these life-cycles, instance.props/instance.state are what
4223 // ever the previously attempted to render - not the "current". However,
4224 // during componentDidUpdate we pass the "current" props.
4225
4226 // In order to support react-lifecycles-compat polyfilled components,
4227 // Unsafe lifecycles should not be invoked for components using the new APIs.
4228 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4229 if (oldProps !== newProps || oldContext !== nextContext) {
4230 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4231 }
4232 }
4233
4234 resetHasForceUpdateBeforeProcessing();
4235
4236 var oldState = workInProgress.memoizedState;
4237 var newState = instance.state = oldState;
4238 var updateQueue = workInProgress.updateQueue;
4239 if (updateQueue !== null) {
4240 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4241 newState = workInProgress.memoizedState;
4242 }
4243
4244 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4245 // If an update was already in progress, we should schedule an Update
4246 // effect even though we're bailing out, so that cWU/cDU are called.
4247 if (typeof instance.componentDidUpdate === 'function') {
4248 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4249 workInProgress.effectTag |= Update;
4250 }
4251 }
4252 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4253 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4254 workInProgress.effectTag |= Snapshot;
4255 }
4256 }
4257 return false;
4258 }
4259
4260 if (typeof getDerivedStateFromProps === 'function') {
4261 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4262 newState = workInProgress.memoizedState;
4263 }
4264
4265 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4266
4267 if (shouldUpdate) {
4268 // In order to support react-lifecycles-compat polyfilled components,
4269 // Unsafe lifecycles should not be invoked for components using the new APIs.
4270 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
4271 startPhaseTimer(workInProgress, 'componentWillUpdate');
4272 if (typeof instance.componentWillUpdate === 'function') {
4273 instance.componentWillUpdate(newProps, newState, nextContext);
4274 }
4275 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4276 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
4277 }
4278 stopPhaseTimer();
4279 }
4280 if (typeof instance.componentDidUpdate === 'function') {
4281 workInProgress.effectTag |= Update;
4282 }
4283 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4284 workInProgress.effectTag |= Snapshot;
4285 }
4286 } else {
4287 // If an update was already in progress, we should schedule an Update
4288 // effect even though we're bailing out, so that cWU/cDU are called.
4289 if (typeof instance.componentDidUpdate === 'function') {
4290 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4291 workInProgress.effectTag |= Update;
4292 }
4293 }
4294 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4295 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4296 workInProgress.effectTag |= Snapshot;
4297 }
4298 }
4299
4300 // If shouldComponentUpdate returned false, we should still update the
4301 // memoized props/state to indicate that this work can be reused.
4302 workInProgress.memoizedProps = newProps;
4303 workInProgress.memoizedState = newState;
4304 }
4305
4306 // Update the existing instance's state, props, and context pointers even
4307 // if shouldComponentUpdate returns false.
4308 instance.props = newProps;
4309 instance.state = newState;
4310 instance.context = nextContext;
4311
4312 return shouldUpdate;
4313}
4314
4315var didWarnAboutMaps = void 0;
4316var didWarnAboutGenerators = void 0;
4317var didWarnAboutStringRefInStrictMode = void 0;
4318var ownerHasKeyUseWarning = void 0;
4319var ownerHasFunctionTypeWarning = void 0;
4320var warnForMissingKey = function (child) {};
4321
4322{
4323 didWarnAboutMaps = false;
4324 didWarnAboutGenerators = false;
4325 didWarnAboutStringRefInStrictMode = {};
4326
4327 /**
4328 * Warn if there's no key explicitly set on dynamic arrays of children or
4329 * object keys are not valid. This allows us to keep track of children between
4330 * updates.
4331 */
4332 ownerHasKeyUseWarning = {};
4333 ownerHasFunctionTypeWarning = {};
4334
4335 warnForMissingKey = function (child) {
4336 if (child === null || typeof child !== 'object') {
4337 return;
4338 }
4339 if (!child._store || child._store.validated || child.key != null) {
4340 return;
4341 }
4342 !(typeof child._store === 'object') ? invariant(false, 'React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue.') : void 0;
4343 child._store.validated = true;
4344
4345 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
4346 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
4347 return;
4348 }
4349 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
4350
4351 warning$1(false, 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
4352 };
4353}
4354
4355var isArray = Array.isArray;
4356
4357function coerceRef(returnFiber, current, element) {
4358 var mixedRef = element.ref;
4359 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
4360 {
4361 if (returnFiber.mode & StrictMode) {
4362 var componentName = getComponentName(returnFiber.type) || 'Component';
4363 if (!didWarnAboutStringRefInStrictMode[componentName]) {
4364 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));
4365 didWarnAboutStringRefInStrictMode[componentName] = true;
4366 }
4367 }
4368 }
4369
4370 if (element._owner) {
4371 var owner = element._owner;
4372 var inst = void 0;
4373 if (owner) {
4374 var ownerFiber = owner;
4375 !(ownerFiber.tag === ClassComponent) ? invariant(false, 'Function components cannot have refs. Did you mean to use React.forwardRef()?') : void 0;
4376 inst = ownerFiber.stateNode;
4377 }
4378 !inst ? invariant(false, 'Missing owner for string ref %s. This error is likely caused by a bug in React. Please file an issue.', mixedRef) : void 0;
4379 var stringRef = '' + mixedRef;
4380 // Check if previous string ref matches new string ref
4381 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
4382 return current.ref;
4383 }
4384 var ref = function (value) {
4385 var refs = inst.refs;
4386 if (refs === emptyRefsObject) {
4387 // This is a lazy pooled frozen object, so we need to initialize.
4388 refs = inst.refs = {};
4389 }
4390 if (value === null) {
4391 delete refs[stringRef];
4392 } else {
4393 refs[stringRef] = value;
4394 }
4395 };
4396 ref._stringRef = stringRef;
4397 return ref;
4398 } else {
4399 !(typeof mixedRef === 'string') ? invariant(false, 'Expected ref to be a function, a string, an object returned by React.createRef(), or null.') : void 0;
4400 !element._owner ? invariant(false, 'Element ref was specified as a string (%s) 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.', mixedRef) : void 0;
4401 }
4402 }
4403 return mixedRef;
4404}
4405
4406function throwOnInvalidObjectType(returnFiber, newChild) {
4407 if (returnFiber.type !== 'textarea') {
4408 var addendum = '';
4409 {
4410 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
4411 }
4412 invariant(false, 'Objects are not valid as a React child (found: %s).%s', Object.prototype.toString.call(newChild) === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : newChild, addendum);
4413 }
4414}
4415
4416function warnOnFunctionType() {
4417 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();
4418
4419 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
4420 return;
4421 }
4422 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
4423
4424 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.');
4425}
4426
4427// This wrapper function exists because I expect to clone the code in each path
4428// to be able to optimize each path individually by branching early. This needs
4429// a compiler or we can do it manually. Helpers that don't need this branching
4430// live outside of this function.
4431function ChildReconciler(shouldTrackSideEffects) {
4432 function deleteChild(returnFiber, childToDelete) {
4433 if (!shouldTrackSideEffects) {
4434 // Noop.
4435 return;
4436 }
4437 // Deletions are added in reversed order so we add it to the front.
4438 // At this point, the return fiber's effect list is empty except for
4439 // deletions, so we can just append the deletion to the list. The remaining
4440 // effects aren't added until the complete phase. Once we implement
4441 // resuming, this may not be true.
4442 var last = returnFiber.lastEffect;
4443 if (last !== null) {
4444 last.nextEffect = childToDelete;
4445 returnFiber.lastEffect = childToDelete;
4446 } else {
4447 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
4448 }
4449 childToDelete.nextEffect = null;
4450 childToDelete.effectTag = Deletion;
4451 }
4452
4453 function deleteRemainingChildren(returnFiber, currentFirstChild) {
4454 if (!shouldTrackSideEffects) {
4455 // Noop.
4456 return null;
4457 }
4458
4459 // TODO: For the shouldClone case, this could be micro-optimized a bit by
4460 // assuming that after the first child we've already added everything.
4461 var childToDelete = currentFirstChild;
4462 while (childToDelete !== null) {
4463 deleteChild(returnFiber, childToDelete);
4464 childToDelete = childToDelete.sibling;
4465 }
4466 return null;
4467 }
4468
4469 function mapRemainingChildren(returnFiber, currentFirstChild) {
4470 // Add the remaining children to a temporary map so that we can find them by
4471 // keys quickly. Implicit (null) keys get added to this set with their index
4472 var existingChildren = new Map();
4473
4474 var existingChild = currentFirstChild;
4475 while (existingChild !== null) {
4476 if (existingChild.key !== null) {
4477 existingChildren.set(existingChild.key, existingChild);
4478 } else {
4479 existingChildren.set(existingChild.index, existingChild);
4480 }
4481 existingChild = existingChild.sibling;
4482 }
4483 return existingChildren;
4484 }
4485
4486 function useFiber(fiber, pendingProps, expirationTime) {
4487 // We currently set sibling to null and index to 0 here because it is easy
4488 // to forget to do before returning it. E.g. for the single child case.
4489 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
4490 clone.index = 0;
4491 clone.sibling = null;
4492 return clone;
4493 }
4494
4495 function placeChild(newFiber, lastPlacedIndex, newIndex) {
4496 newFiber.index = newIndex;
4497 if (!shouldTrackSideEffects) {
4498 // Noop.
4499 return lastPlacedIndex;
4500 }
4501 var current = newFiber.alternate;
4502 if (current !== null) {
4503 var oldIndex = current.index;
4504 if (oldIndex < lastPlacedIndex) {
4505 // This is a move.
4506 newFiber.effectTag = Placement;
4507 return lastPlacedIndex;
4508 } else {
4509 // This item can stay in place.
4510 return oldIndex;
4511 }
4512 } else {
4513 // This is an insertion.
4514 newFiber.effectTag = Placement;
4515 return lastPlacedIndex;
4516 }
4517 }
4518
4519 function placeSingleChild(newFiber) {
4520 // This is simpler for the single child case. We only need to do a
4521 // placement for inserting new children.
4522 if (shouldTrackSideEffects && newFiber.alternate === null) {
4523 newFiber.effectTag = Placement;
4524 }
4525 return newFiber;
4526 }
4527
4528 function updateTextNode(returnFiber, current, textContent, expirationTime) {
4529 if (current === null || current.tag !== HostText) {
4530 // Insert
4531 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
4532 created.return = returnFiber;
4533 return created;
4534 } else {
4535 // Update
4536 var existing = useFiber(current, textContent, expirationTime);
4537 existing.return = returnFiber;
4538 return existing;
4539 }
4540 }
4541
4542 function updateElement(returnFiber, current, element, expirationTime) {
4543 if (current !== null && current.elementType === element.type) {
4544 // Move based on index
4545 var existing = useFiber(current, element.props, expirationTime);
4546 existing.ref = coerceRef(returnFiber, current, element);
4547 existing.return = returnFiber;
4548 {
4549 existing._debugSource = element._source;
4550 existing._debugOwner = element._owner;
4551 }
4552 return existing;
4553 } else {
4554 // Insert
4555 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
4556 created.ref = coerceRef(returnFiber, current, element);
4557 created.return = returnFiber;
4558 return created;
4559 }
4560 }
4561
4562 function updatePortal(returnFiber, current, portal, expirationTime) {
4563 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
4564 // Insert
4565 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
4566 created.return = returnFiber;
4567 return created;
4568 } else {
4569 // Update
4570 var existing = useFiber(current, portal.children || [], expirationTime);
4571 existing.return = returnFiber;
4572 return existing;
4573 }
4574 }
4575
4576 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
4577 if (current === null || current.tag !== Fragment) {
4578 // Insert
4579 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
4580 created.return = returnFiber;
4581 return created;
4582 } else {
4583 // Update
4584 var existing = useFiber(current, fragment, expirationTime);
4585 existing.return = returnFiber;
4586 return existing;
4587 }
4588 }
4589
4590 function createChild(returnFiber, newChild, expirationTime) {
4591 if (typeof newChild === 'string' || typeof newChild === 'number') {
4592 // Text nodes don't have keys. If the previous node is implicitly keyed
4593 // we can continue to replace it without aborting even if it is not a text
4594 // node.
4595 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
4596 created.return = returnFiber;
4597 return created;
4598 }
4599
4600 if (typeof newChild === 'object' && newChild !== null) {
4601 switch (newChild.$$typeof) {
4602 case REACT_ELEMENT_TYPE:
4603 {
4604 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
4605 _created.ref = coerceRef(returnFiber, null, newChild);
4606 _created.return = returnFiber;
4607 return _created;
4608 }
4609 case REACT_PORTAL_TYPE:
4610 {
4611 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
4612 _created2.return = returnFiber;
4613 return _created2;
4614 }
4615 }
4616
4617 if (isArray(newChild) || getIteratorFn(newChild)) {
4618 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
4619 _created3.return = returnFiber;
4620 return _created3;
4621 }
4622
4623 throwOnInvalidObjectType(returnFiber, newChild);
4624 }
4625
4626 {
4627 if (typeof newChild === 'function') {
4628 warnOnFunctionType();
4629 }
4630 }
4631
4632 return null;
4633 }
4634
4635 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
4636 // Update the fiber if the keys match, otherwise return null.
4637
4638 var key = oldFiber !== null ? oldFiber.key : null;
4639
4640 if (typeof newChild === 'string' || typeof newChild === 'number') {
4641 // Text nodes don't have keys. If the previous node is implicitly keyed
4642 // we can continue to replace it without aborting even if it is not a text
4643 // node.
4644 if (key !== null) {
4645 return null;
4646 }
4647 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
4648 }
4649
4650 if (typeof newChild === 'object' && newChild !== null) {
4651 switch (newChild.$$typeof) {
4652 case REACT_ELEMENT_TYPE:
4653 {
4654 if (newChild.key === key) {
4655 if (newChild.type === REACT_FRAGMENT_TYPE) {
4656 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
4657 }
4658 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
4659 } else {
4660 return null;
4661 }
4662 }
4663 case REACT_PORTAL_TYPE:
4664 {
4665 if (newChild.key === key) {
4666 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
4667 } else {
4668 return null;
4669 }
4670 }
4671 }
4672
4673 if (isArray(newChild) || getIteratorFn(newChild)) {
4674 if (key !== null) {
4675 return null;
4676 }
4677
4678 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
4679 }
4680
4681 throwOnInvalidObjectType(returnFiber, newChild);
4682 }
4683
4684 {
4685 if (typeof newChild === 'function') {
4686 warnOnFunctionType();
4687 }
4688 }
4689
4690 return null;
4691 }
4692
4693 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
4694 if (typeof newChild === 'string' || typeof newChild === 'number') {
4695 // Text nodes don't have keys, so we neither have to check the old nor
4696 // new node for the key. If both are text nodes, they match.
4697 var matchedFiber = existingChildren.get(newIdx) || null;
4698 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
4699 }
4700
4701 if (typeof newChild === 'object' && newChild !== null) {
4702 switch (newChild.$$typeof) {
4703 case REACT_ELEMENT_TYPE:
4704 {
4705 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
4706 if (newChild.type === REACT_FRAGMENT_TYPE) {
4707 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
4708 }
4709 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
4710 }
4711 case REACT_PORTAL_TYPE:
4712 {
4713 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
4714 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
4715 }
4716 }
4717
4718 if (isArray(newChild) || getIteratorFn(newChild)) {
4719 var _matchedFiber3 = existingChildren.get(newIdx) || null;
4720 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
4721 }
4722
4723 throwOnInvalidObjectType(returnFiber, newChild);
4724 }
4725
4726 {
4727 if (typeof newChild === 'function') {
4728 warnOnFunctionType();
4729 }
4730 }
4731
4732 return null;
4733 }
4734
4735 /**
4736 * Warns if there is a duplicate or missing key
4737 */
4738 function warnOnInvalidKey(child, knownKeys) {
4739 {
4740 if (typeof child !== 'object' || child === null) {
4741 return knownKeys;
4742 }
4743 switch (child.$$typeof) {
4744 case REACT_ELEMENT_TYPE:
4745 case REACT_PORTAL_TYPE:
4746 warnForMissingKey(child);
4747 var key = child.key;
4748 if (typeof key !== 'string') {
4749 break;
4750 }
4751 if (knownKeys === null) {
4752 knownKeys = new Set();
4753 knownKeys.add(key);
4754 break;
4755 }
4756 if (!knownKeys.has(key)) {
4757 knownKeys.add(key);
4758 break;
4759 }
4760 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);
4761 break;
4762 default:
4763 break;
4764 }
4765 }
4766 return knownKeys;
4767 }
4768
4769 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
4770 // This algorithm can't optimize by searching from both ends since we
4771 // don't have backpointers on fibers. I'm trying to see how far we can get
4772 // with that model. If it ends up not being worth the tradeoffs, we can
4773 // add it later.
4774
4775 // Even with a two ended optimization, we'd want to optimize for the case
4776 // where there are few changes and brute force the comparison instead of
4777 // going for the Map. It'd like to explore hitting that path first in
4778 // forward-only mode and only go for the Map once we notice that we need
4779 // lots of look ahead. This doesn't handle reversal as well as two ended
4780 // search but that's unusual. Besides, for the two ended optimization to
4781 // work on Iterables, we'd need to copy the whole set.
4782
4783 // In this first iteration, we'll just live with hitting the bad case
4784 // (adding everything to a Map) in for every insert/move.
4785
4786 // If you change this code, also update reconcileChildrenIterator() which
4787 // uses the same algorithm.
4788
4789 {
4790 // First, validate keys.
4791 var knownKeys = null;
4792 for (var i = 0; i < newChildren.length; i++) {
4793 var child = newChildren[i];
4794 knownKeys = warnOnInvalidKey(child, knownKeys);
4795 }
4796 }
4797
4798 var resultingFirstChild = null;
4799 var previousNewFiber = null;
4800
4801 var oldFiber = currentFirstChild;
4802 var lastPlacedIndex = 0;
4803 var newIdx = 0;
4804 var nextOldFiber = null;
4805 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
4806 if (oldFiber.index > newIdx) {
4807 nextOldFiber = oldFiber;
4808 oldFiber = null;
4809 } else {
4810 nextOldFiber = oldFiber.sibling;
4811 }
4812 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
4813 if (newFiber === null) {
4814 // TODO: This breaks on empty slots like null children. That's
4815 // unfortunate because it triggers the slow path all the time. We need
4816 // a better way to communicate whether this was a miss or null,
4817 // boolean, undefined, etc.
4818 if (oldFiber === null) {
4819 oldFiber = nextOldFiber;
4820 }
4821 break;
4822 }
4823 if (shouldTrackSideEffects) {
4824 if (oldFiber && newFiber.alternate === null) {
4825 // We matched the slot, but we didn't reuse the existing fiber, so we
4826 // need to delete the existing child.
4827 deleteChild(returnFiber, oldFiber);
4828 }
4829 }
4830 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
4831 if (previousNewFiber === null) {
4832 // TODO: Move out of the loop. This only happens for the first run.
4833 resultingFirstChild = newFiber;
4834 } else {
4835 // TODO: Defer siblings if we're not at the right index for this slot.
4836 // I.e. if we had null values before, then we want to defer this
4837 // for each null value. However, we also don't want to call updateSlot
4838 // with the previous one.
4839 previousNewFiber.sibling = newFiber;
4840 }
4841 previousNewFiber = newFiber;
4842 oldFiber = nextOldFiber;
4843 }
4844
4845 if (newIdx === newChildren.length) {
4846 // We've reached the end of the new children. We can delete the rest.
4847 deleteRemainingChildren(returnFiber, oldFiber);
4848 return resultingFirstChild;
4849 }
4850
4851 if (oldFiber === null) {
4852 // If we don't have any more existing children we can choose a fast path
4853 // since the rest will all be insertions.
4854 for (; newIdx < newChildren.length; newIdx++) {
4855 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
4856 if (!_newFiber) {
4857 continue;
4858 }
4859 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
4860 if (previousNewFiber === null) {
4861 // TODO: Move out of the loop. This only happens for the first run.
4862 resultingFirstChild = _newFiber;
4863 } else {
4864 previousNewFiber.sibling = _newFiber;
4865 }
4866 previousNewFiber = _newFiber;
4867 }
4868 return resultingFirstChild;
4869 }
4870
4871 // Add all children to a key map for quick lookups.
4872 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
4873
4874 // Keep scanning and use the map to restore deleted items as moves.
4875 for (; newIdx < newChildren.length; newIdx++) {
4876 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
4877 if (_newFiber2) {
4878 if (shouldTrackSideEffects) {
4879 if (_newFiber2.alternate !== null) {
4880 // The new fiber is a work in progress, but if there exists a
4881 // current, that means that we reused the fiber. We need to delete
4882 // it from the child list so that we don't add it to the deletion
4883 // list.
4884 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
4885 }
4886 }
4887 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
4888 if (previousNewFiber === null) {
4889 resultingFirstChild = _newFiber2;
4890 } else {
4891 previousNewFiber.sibling = _newFiber2;
4892 }
4893 previousNewFiber = _newFiber2;
4894 }
4895 }
4896
4897 if (shouldTrackSideEffects) {
4898 // Any existing children that weren't consumed above were deleted. We need
4899 // to add them to the deletion list.
4900 existingChildren.forEach(function (child) {
4901 return deleteChild(returnFiber, child);
4902 });
4903 }
4904
4905 return resultingFirstChild;
4906 }
4907
4908 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
4909 // This is the same implementation as reconcileChildrenArray(),
4910 // but using the iterator instead.
4911
4912 var iteratorFn = getIteratorFn(newChildrenIterable);
4913 !(typeof iteratorFn === 'function') ? invariant(false, 'An object is not an iterable. This error is likely caused by a bug in React. Please file an issue.') : void 0;
4914
4915 {
4916 // We don't support rendering Generators because it's a mutation.
4917 // See https://github.com/facebook/react/issues/12995
4918 if (typeof Symbol === 'function' &&
4919 // $FlowFixMe Flow doesn't know about toStringTag
4920 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
4921 !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;
4922 didWarnAboutGenerators = true;
4923 }
4924
4925 // Warn about using Maps as children
4926 if (newChildrenIterable.entries === iteratorFn) {
4927 !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;
4928 didWarnAboutMaps = true;
4929 }
4930
4931 // First, validate keys.
4932 // We'll get a different iterator later for the main pass.
4933 var _newChildren = iteratorFn.call(newChildrenIterable);
4934 if (_newChildren) {
4935 var knownKeys = null;
4936 var _step = _newChildren.next();
4937 for (; !_step.done; _step = _newChildren.next()) {
4938 var child = _step.value;
4939 knownKeys = warnOnInvalidKey(child, knownKeys);
4940 }
4941 }
4942 }
4943
4944 var newChildren = iteratorFn.call(newChildrenIterable);
4945 !(newChildren != null) ? invariant(false, 'An iterable object provided no iterator.') : void 0;
4946
4947 var resultingFirstChild = null;
4948 var previousNewFiber = null;
4949
4950 var oldFiber = currentFirstChild;
4951 var lastPlacedIndex = 0;
4952 var newIdx = 0;
4953 var nextOldFiber = null;
4954
4955 var step = newChildren.next();
4956 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
4957 if (oldFiber.index > newIdx) {
4958 nextOldFiber = oldFiber;
4959 oldFiber = null;
4960 } else {
4961 nextOldFiber = oldFiber.sibling;
4962 }
4963 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
4964 if (newFiber === null) {
4965 // TODO: This breaks on empty slots like null children. That's
4966 // unfortunate because it triggers the slow path all the time. We need
4967 // a better way to communicate whether this was a miss or null,
4968 // boolean, undefined, etc.
4969 if (!oldFiber) {
4970 oldFiber = nextOldFiber;
4971 }
4972 break;
4973 }
4974 if (shouldTrackSideEffects) {
4975 if (oldFiber && newFiber.alternate === null) {
4976 // We matched the slot, but we didn't reuse the existing fiber, so we
4977 // need to delete the existing child.
4978 deleteChild(returnFiber, oldFiber);
4979 }
4980 }
4981 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
4982 if (previousNewFiber === null) {
4983 // TODO: Move out of the loop. This only happens for the first run.
4984 resultingFirstChild = newFiber;
4985 } else {
4986 // TODO: Defer siblings if we're not at the right index for this slot.
4987 // I.e. if we had null values before, then we want to defer this
4988 // for each null value. However, we also don't want to call updateSlot
4989 // with the previous one.
4990 previousNewFiber.sibling = newFiber;
4991 }
4992 previousNewFiber = newFiber;
4993 oldFiber = nextOldFiber;
4994 }
4995
4996 if (step.done) {
4997 // We've reached the end of the new children. We can delete the rest.
4998 deleteRemainingChildren(returnFiber, oldFiber);
4999 return resultingFirstChild;
5000 }
5001
5002 if (oldFiber === null) {
5003 // If we don't have any more existing children we can choose a fast path
5004 // since the rest will all be insertions.
5005 for (; !step.done; newIdx++, step = newChildren.next()) {
5006 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
5007 if (_newFiber3 === null) {
5008 continue;
5009 }
5010 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
5011 if (previousNewFiber === null) {
5012 // TODO: Move out of the loop. This only happens for the first run.
5013 resultingFirstChild = _newFiber3;
5014 } else {
5015 previousNewFiber.sibling = _newFiber3;
5016 }
5017 previousNewFiber = _newFiber3;
5018 }
5019 return resultingFirstChild;
5020 }
5021
5022 // Add all children to a key map for quick lookups.
5023 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
5024
5025 // Keep scanning and use the map to restore deleted items as moves.
5026 for (; !step.done; newIdx++, step = newChildren.next()) {
5027 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
5028 if (_newFiber4 !== null) {
5029 if (shouldTrackSideEffects) {
5030 if (_newFiber4.alternate !== null) {
5031 // The new fiber is a work in progress, but if there exists a
5032 // current, that means that we reused the fiber. We need to delete
5033 // it from the child list so that we don't add it to the deletion
5034 // list.
5035 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
5036 }
5037 }
5038 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
5039 if (previousNewFiber === null) {
5040 resultingFirstChild = _newFiber4;
5041 } else {
5042 previousNewFiber.sibling = _newFiber4;
5043 }
5044 previousNewFiber = _newFiber4;
5045 }
5046 }
5047
5048 if (shouldTrackSideEffects) {
5049 // Any existing children that weren't consumed above were deleted. We need
5050 // to add them to the deletion list.
5051 existingChildren.forEach(function (child) {
5052 return deleteChild(returnFiber, child);
5053 });
5054 }
5055
5056 return resultingFirstChild;
5057 }
5058
5059 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
5060 // There's no need to check for keys on text nodes since we don't have a
5061 // way to define them.
5062 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
5063 // We already have an existing node so let's just update it and delete
5064 // the rest.
5065 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
5066 var existing = useFiber(currentFirstChild, textContent, expirationTime);
5067 existing.return = returnFiber;
5068 return existing;
5069 }
5070 // The existing first child is not a text node so we need to create one
5071 // and delete the existing ones.
5072 deleteRemainingChildren(returnFiber, currentFirstChild);
5073 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
5074 created.return = returnFiber;
5075 return created;
5076 }
5077
5078 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
5079 var key = element.key;
5080 var child = currentFirstChild;
5081 while (child !== null) {
5082 // TODO: If key === null and child.key === null, then this only applies to
5083 // the first item in the list.
5084 if (child.key === key) {
5085 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type) {
5086 deleteRemainingChildren(returnFiber, child.sibling);
5087 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
5088 existing.ref = coerceRef(returnFiber, child, element);
5089 existing.return = returnFiber;
5090 {
5091 existing._debugSource = element._source;
5092 existing._debugOwner = element._owner;
5093 }
5094 return existing;
5095 } else {
5096 deleteRemainingChildren(returnFiber, child);
5097 break;
5098 }
5099 } else {
5100 deleteChild(returnFiber, child);
5101 }
5102 child = child.sibling;
5103 }
5104
5105 if (element.type === REACT_FRAGMENT_TYPE) {
5106 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
5107 created.return = returnFiber;
5108 return created;
5109 } else {
5110 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
5111 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
5112 _created4.return = returnFiber;
5113 return _created4;
5114 }
5115 }
5116
5117 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
5118 var key = portal.key;
5119 var child = currentFirstChild;
5120 while (child !== null) {
5121 // TODO: If key === null and child.key === null, then this only applies to
5122 // the first item in the list.
5123 if (child.key === key) {
5124 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
5125 deleteRemainingChildren(returnFiber, child.sibling);
5126 var existing = useFiber(child, portal.children || [], expirationTime);
5127 existing.return = returnFiber;
5128 return existing;
5129 } else {
5130 deleteRemainingChildren(returnFiber, child);
5131 break;
5132 }
5133 } else {
5134 deleteChild(returnFiber, child);
5135 }
5136 child = child.sibling;
5137 }
5138
5139 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
5140 created.return = returnFiber;
5141 return created;
5142 }
5143
5144 // This API will tag the children with the side-effect of the reconciliation
5145 // itself. They will be added to the side-effect list as we pass through the
5146 // children and the parent.
5147 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
5148 // This function is not recursive.
5149 // If the top level item is an array, we treat it as a set of children,
5150 // not as a fragment. Nested arrays on the other hand will be treated as
5151 // fragment nodes. Recursion happens at the normal flow.
5152
5153 // Handle top level unkeyed fragments as if they were arrays.
5154 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
5155 // We treat the ambiguous cases above the same.
5156 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
5157 if (isUnkeyedTopLevelFragment) {
5158 newChild = newChild.props.children;
5159 }
5160
5161 // Handle object types
5162 var isObject = typeof newChild === 'object' && newChild !== null;
5163
5164 if (isObject) {
5165 switch (newChild.$$typeof) {
5166 case REACT_ELEMENT_TYPE:
5167 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
5168 case REACT_PORTAL_TYPE:
5169 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
5170 }
5171 }
5172
5173 if (typeof newChild === 'string' || typeof newChild === 'number') {
5174 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
5175 }
5176
5177 if (isArray(newChild)) {
5178 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
5179 }
5180
5181 if (getIteratorFn(newChild)) {
5182 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
5183 }
5184
5185 if (isObject) {
5186 throwOnInvalidObjectType(returnFiber, newChild);
5187 }
5188
5189 {
5190 if (typeof newChild === 'function') {
5191 warnOnFunctionType();
5192 }
5193 }
5194 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
5195 // If the new child is undefined, and the return fiber is a composite
5196 // component, throw an error. If Fiber return types are disabled,
5197 // we already threw above.
5198 switch (returnFiber.tag) {
5199 case ClassComponent:
5200 {
5201 {
5202 var instance = returnFiber.stateNode;
5203 if (instance.render._isMockFunction) {
5204 // We allow auto-mocks to proceed as if they're returning null.
5205 break;
5206 }
5207 }
5208 }
5209 // Intentionally fall through to the next case, which handles both
5210 // functions and classes
5211 // eslint-disable-next-lined no-fallthrough
5212 case FunctionComponent:
5213 {
5214 var Component = returnFiber.type;
5215 invariant(false, '%s(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.', Component.displayName || Component.name || 'Component');
5216 }
5217 }
5218 }
5219
5220 // Remaining cases are all treated as empty.
5221 return deleteRemainingChildren(returnFiber, currentFirstChild);
5222 }
5223
5224 return reconcileChildFibers;
5225}
5226
5227var reconcileChildFibers = ChildReconciler(true);
5228var mountChildFibers = ChildReconciler(false);
5229
5230function cloneChildFibers(current, workInProgress) {
5231 !(current === null || workInProgress.child === current.child) ? invariant(false, 'Resuming work not yet implemented.') : void 0;
5232
5233 if (workInProgress.child === null) {
5234 return;
5235 }
5236
5237 var currentChild = workInProgress.child;
5238 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
5239 workInProgress.child = newChild;
5240
5241 newChild.return = workInProgress;
5242 while (currentChild.sibling !== null) {
5243 currentChild = currentChild.sibling;
5244 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
5245 newChild.return = workInProgress;
5246 }
5247 newChild.sibling = null;
5248}
5249
5250var NO_CONTEXT$1 = {};
5251
5252var contextStackCursor$1 = createCursor(NO_CONTEXT$1);
5253var contextFiberStackCursor = createCursor(NO_CONTEXT$1);
5254var rootInstanceStackCursor = createCursor(NO_CONTEXT$1);
5255
5256function requiredContext(c) {
5257 !(c !== NO_CONTEXT$1) ? invariant(false, 'Expected host context to exist. This error is likely caused by a bug in React. Please file an issue.') : void 0;
5258 return c;
5259}
5260
5261function getRootHostContainer() {
5262 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5263 return rootInstance;
5264}
5265
5266function pushHostContainer(fiber, nextRootInstance) {
5267 // Push current root instance onto the stack;
5268 // This allows us to reset root when portals are popped.
5269 push(rootInstanceStackCursor, nextRootInstance, fiber);
5270 // Track the context and the Fiber that provided it.
5271 // This enables us to pop only Fibers that provide unique contexts.
5272 push(contextFiberStackCursor, fiber, fiber);
5273
5274 // Finally, we need to push the host context to the stack.
5275 // However, we can't just call getRootHostContext() and push it because
5276 // we'd have a different number of entries on the stack depending on
5277 // whether getRootHostContext() throws somewhere in renderer code or not.
5278 // So we push an empty value first. This lets us safely unwind on errors.
5279 push(contextStackCursor$1, NO_CONTEXT$1, fiber);
5280 var nextRootContext = getRootHostContext(nextRootInstance);
5281 // Now that we know this function doesn't throw, replace it.
5282 pop(contextStackCursor$1, fiber);
5283 push(contextStackCursor$1, nextRootContext, fiber);
5284}
5285
5286function popHostContainer(fiber) {
5287 pop(contextStackCursor$1, fiber);
5288 pop(contextFiberStackCursor, fiber);
5289 pop(rootInstanceStackCursor, fiber);
5290}
5291
5292function getHostContext() {
5293 var context = requiredContext(contextStackCursor$1.current);
5294 return context;
5295}
5296
5297function pushHostContext(fiber) {
5298 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5299 var context = requiredContext(contextStackCursor$1.current);
5300 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
5301
5302 // Don't push this Fiber's context unless it's unique.
5303 if (context === nextContext) {
5304 return;
5305 }
5306
5307 // Track the context and the Fiber that provided it.
5308 // This enables us to pop only Fibers that provide unique contexts.
5309 push(contextFiberStackCursor, fiber, fiber);
5310 push(contextStackCursor$1, nextContext, fiber);
5311}
5312
5313function popHostContext(fiber) {
5314 // Do not pop unless this Fiber provided the current context.
5315 // pushHostContext() only pushes Fibers that provide unique contexts.
5316 if (contextFiberStackCursor.current !== fiber) {
5317 return;
5318 }
5319
5320 pop(contextStackCursor$1, fiber);
5321 pop(contextFiberStackCursor, fiber);
5322}
5323
5324var NoEffect$1 = /* */0;
5325var UnmountSnapshot = /* */2;
5326var UnmountMutation = /* */4;
5327var MountMutation = /* */8;
5328var UnmountLayout = /* */16;
5329var MountLayout = /* */32;
5330var MountPassive = /* */64;
5331var UnmountPassive = /* */128;
5332
5333var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher;
5334
5335
5336var didWarnAboutMismatchedHooksForComponent = void 0;
5337{
5338 didWarnAboutMismatchedHooksForComponent = new Set();
5339}
5340
5341// These are set right before calling the component.
5342var renderExpirationTime = NoWork;
5343// The work-in-progress fiber. I've named it differently to distinguish it from
5344// the work-in-progress hook.
5345var currentlyRenderingFiber$1 = null;
5346
5347// Hooks are stored as a linked list on the fiber's memoizedState field. The
5348// current hook list is the list that belongs to the current fiber. The
5349// work-in-progress hook list is a new list that will be added to the
5350// work-in-progress fiber.
5351var firstCurrentHook = null;
5352var currentHook = null;
5353var nextCurrentHook = null;
5354var firstWorkInProgressHook = null;
5355var workInProgressHook = null;
5356var nextWorkInProgressHook = null;
5357
5358var remainingExpirationTime = NoWork;
5359var componentUpdateQueue = null;
5360var sideEffectTag = 0;
5361
5362// Updates scheduled during render will trigger an immediate re-render at the
5363// end of the current pass. We can't store these updates on the normal queue,
5364// because if the work is aborted, they should be discarded. Because this is
5365// a relatively rare case, we also don't want to add an additional field to
5366// either the hook or queue object types. So we store them in a lazily create
5367// map of queue -> render-phase updates, which are discarded once the component
5368// completes without re-rendering.
5369
5370// Whether an update was scheduled during the currently executing render pass.
5371var didScheduleRenderPhaseUpdate = false;
5372// Lazily created map of render-phase updates
5373var renderPhaseUpdates = null;
5374// Counter to prevent infinite loops.
5375var numberOfReRenders = 0;
5376var RE_RENDER_LIMIT = 25;
5377
5378// In DEV, this is the name of the currently executing primitive hook
5379var currentHookNameInDev = null;
5380
5381function warnOnHookMismatchInDev() {
5382 {
5383 var componentName = getComponentName(currentlyRenderingFiber$1.type);
5384 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
5385 didWarnAboutMismatchedHooksForComponent.add(componentName);
5386
5387 var secondColumnStart = 22;
5388
5389 var table = '';
5390 var prevHook = firstCurrentHook;
5391 var nextHook = firstWorkInProgressHook;
5392 var n = 1;
5393 while (prevHook !== null && nextHook !== null) {
5394 var oldHookName = prevHook._debugType;
5395 var newHookName = nextHook._debugType;
5396
5397 var row = n + '. ' + oldHookName;
5398
5399 // Extra space so second column lines up
5400 // lol @ IE not supporting String#repeat
5401 while (row.length < secondColumnStart) {
5402 row += ' ';
5403 }
5404
5405 row += newHookName + '\n';
5406
5407 table += row;
5408 prevHook = prevHook.next;
5409 nextHook = nextHook.next;
5410 n++;
5411 }
5412
5413 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);
5414 }
5415 }
5416}
5417
5418function throwInvalidHookError() {
5419 invariant(false, 'Hooks can only be called inside the body of a function component. (https://fb.me/react-invalid-hook-call)');
5420}
5421
5422function areHookInputsEqual(nextDeps, prevDeps) {
5423 if (prevDeps === null) {
5424 {
5425 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);
5426 }
5427 return false;
5428 }
5429
5430 {
5431 // Don't bother comparing lengths in prod because these arrays should be
5432 // passed inline.
5433 if (nextDeps.length !== prevDeps.length) {
5434 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, '[' + nextDeps.join(', ') + ']', '[' + prevDeps.join(', ') + ']');
5435 }
5436 }
5437 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
5438 if (is(nextDeps[i], prevDeps[i])) {
5439 continue;
5440 }
5441 return false;
5442 }
5443 return true;
5444}
5445
5446function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) {
5447 renderExpirationTime = nextRenderExpirationTime;
5448 currentlyRenderingFiber$1 = workInProgress;
5449 firstCurrentHook = nextCurrentHook = current !== null ? current.memoizedState : null;
5450
5451 // The following should have already been reset
5452 // currentHook = null;
5453 // workInProgressHook = null;
5454
5455 // remainingExpirationTime = NoWork;
5456 // componentUpdateQueue = null;
5457
5458 // didScheduleRenderPhaseUpdate = false;
5459 // renderPhaseUpdates = null;
5460 // numberOfReRenders = 0;
5461 // sideEffectTag = 0;
5462
5463 {
5464 ReactCurrentDispatcher$1.current = nextCurrentHook === null ? HooksDispatcherOnMountInDEV : HooksDispatcherOnUpdateInDEV;
5465 }
5466
5467 var children = Component(props, refOrContext);
5468
5469 if (didScheduleRenderPhaseUpdate) {
5470 do {
5471 didScheduleRenderPhaseUpdate = false;
5472 numberOfReRenders += 1;
5473
5474 // Start over from the beginning of the list
5475 firstCurrentHook = nextCurrentHook = current !== null ? current.memoizedState : null;
5476 nextWorkInProgressHook = firstWorkInProgressHook;
5477
5478 currentHook = null;
5479 workInProgressHook = null;
5480 componentUpdateQueue = null;
5481
5482 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
5483
5484 children = Component(props, refOrContext);
5485 } while (didScheduleRenderPhaseUpdate);
5486
5487 renderPhaseUpdates = null;
5488 numberOfReRenders = 0;
5489 }
5490
5491 {
5492 currentHookNameInDev = null;
5493 }
5494
5495 // We can assume the previous dispatcher is always this one, since we set it
5496 // at the beginning of the render phase and there's no re-entrancy.
5497 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
5498
5499 var renderedWork = currentlyRenderingFiber$1;
5500
5501 renderedWork.memoizedState = firstWorkInProgressHook;
5502 renderedWork.expirationTime = remainingExpirationTime;
5503 renderedWork.updateQueue = componentUpdateQueue;
5504 renderedWork.effectTag |= sideEffectTag;
5505
5506 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
5507
5508 renderExpirationTime = NoWork;
5509 currentlyRenderingFiber$1 = null;
5510
5511 firstCurrentHook = null;
5512 currentHook = null;
5513 nextCurrentHook = null;
5514 firstWorkInProgressHook = null;
5515 workInProgressHook = null;
5516 nextWorkInProgressHook = null;
5517
5518 remainingExpirationTime = NoWork;
5519 componentUpdateQueue = null;
5520 sideEffectTag = 0;
5521
5522 // These were reset above
5523 // didScheduleRenderPhaseUpdate = false;
5524 // renderPhaseUpdates = null;
5525 // numberOfReRenders = 0;
5526
5527 !!didRenderTooFewHooks ? invariant(false, 'Rendered fewer hooks than expected. This may be caused by an accidental early return statement.') : void 0;
5528
5529 return children;
5530}
5531
5532function bailoutHooks(current, workInProgress, expirationTime) {
5533 workInProgress.updateQueue = current.updateQueue;
5534 workInProgress.effectTag &= ~(Passive | Update);
5535 if (current.expirationTime <= expirationTime) {
5536 current.expirationTime = NoWork;
5537 }
5538}
5539
5540function resetHooks() {
5541 // We can assume the previous dispatcher is always this one, since we set it
5542 // at the beginning of the render phase and there's no re-entrancy.
5543 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
5544
5545 // This is used to reset the state of this module when a component throws.
5546 // It's also called inside mountIndeterminateComponent if we determine the
5547 // component is a module-style component.
5548 renderExpirationTime = NoWork;
5549 currentlyRenderingFiber$1 = null;
5550
5551 firstCurrentHook = null;
5552 currentHook = null;
5553 nextCurrentHook = null;
5554 firstWorkInProgressHook = null;
5555 workInProgressHook = null;
5556 nextWorkInProgressHook = null;
5557
5558 remainingExpirationTime = NoWork;
5559 componentUpdateQueue = null;
5560 sideEffectTag = 0;
5561
5562 {
5563 currentHookNameInDev = null;
5564 }
5565
5566 didScheduleRenderPhaseUpdate = false;
5567 renderPhaseUpdates = null;
5568 numberOfReRenders = 0;
5569}
5570
5571function mountWorkInProgressHook() {
5572 var hook = {
5573 memoizedState: null,
5574
5575 baseState: null,
5576 queue: null,
5577 baseUpdate: null,
5578
5579 next: null
5580 };
5581
5582 {
5583 hook._debugType = currentHookNameInDev;
5584 }
5585 if (workInProgressHook === null) {
5586 // This is the first hook in the list
5587 firstWorkInProgressHook = workInProgressHook = hook;
5588 } else {
5589 // Append to the end of the list
5590 workInProgressHook = workInProgressHook.next = hook;
5591 }
5592 return workInProgressHook;
5593}
5594
5595function updateWorkInProgressHook() {
5596 // This function is used both for updates and for re-renders triggered by a
5597 // render phase update. It assumes there is either a current hook we can
5598 // clone, or a work-in-progress hook from a previous render pass that we can
5599 // use as a base. When we reach the end of the base list, we must switch to
5600 // the dispatcher used for mounts.
5601 if (nextWorkInProgressHook !== null) {
5602 // There's already a work-in-progress. Reuse it.
5603 workInProgressHook = nextWorkInProgressHook;
5604 nextWorkInProgressHook = workInProgressHook.next;
5605
5606 currentHook = nextCurrentHook;
5607 nextCurrentHook = currentHook !== null ? currentHook.next : null;
5608 } else {
5609 // Clone from the current hook.
5610 !(nextCurrentHook !== null) ? invariant(false, 'Rendered more hooks than during the previous render.') : void 0;
5611 currentHook = nextCurrentHook;
5612
5613 var newHook = {
5614 memoizedState: currentHook.memoizedState,
5615
5616 baseState: currentHook.baseState,
5617 queue: currentHook.queue,
5618 baseUpdate: currentHook.baseUpdate,
5619
5620 next: null
5621 };
5622
5623 if (workInProgressHook === null) {
5624 // This is the first hook in the list.
5625 workInProgressHook = firstWorkInProgressHook = newHook;
5626 } else {
5627 // Append to the end of the list.
5628 workInProgressHook = workInProgressHook.next = newHook;
5629 }
5630 nextCurrentHook = currentHook.next;
5631
5632 {
5633 newHook._debugType = currentHookNameInDev;
5634 if (currentHookNameInDev !== currentHook._debugType) {
5635 warnOnHookMismatchInDev();
5636 }
5637 }
5638 }
5639 return workInProgressHook;
5640}
5641
5642function createFunctionComponentUpdateQueue() {
5643 return {
5644 lastEffect: null
5645 };
5646}
5647
5648function basicStateReducer(state, action) {
5649 return typeof action === 'function' ? action(state) : action;
5650}
5651
5652function mountContext(context, observedBits) {
5653 {
5654 mountWorkInProgressHook();
5655 }
5656 return readContext(context, observedBits);
5657}
5658
5659function updateContext(context, observedBits) {
5660 {
5661 updateWorkInProgressHook();
5662 }
5663 return readContext(context, observedBits);
5664}
5665
5666function mountReducer(reducer, initialArg, init) {
5667 var hook = mountWorkInProgressHook();
5668 var initialState = void 0;
5669 if (init !== undefined) {
5670 initialState = init(initialArg);
5671 } else {
5672 initialState = initialArg;
5673 }
5674 hook.memoizedState = hook.baseState = initialState;
5675 var queue = hook.queue = {
5676 last: null,
5677 dispatch: null,
5678 eagerReducer: reducer,
5679 eagerState: initialState
5680 };
5681 var dispatch = queue.dispatch = dispatchAction.bind(null,
5682 // Flow doesn't know this is non-null, but we do.
5683 currentlyRenderingFiber$1, queue);
5684 return [hook.memoizedState, dispatch];
5685}
5686
5687function updateReducer(reducer, initialArg, init) {
5688 var hook = updateWorkInProgressHook();
5689 var queue = hook.queue;
5690 !(queue !== null) ? invariant(false, 'Should have a queue. This is likely a bug in React. Please file an issue.') : void 0;
5691
5692 if (numberOfReRenders > 0) {
5693 // This is a re-render. Apply the new render phase updates to the previous
5694 var _dispatch = queue.dispatch;
5695 if (renderPhaseUpdates !== null) {
5696 // Render phase updates are stored in a map of queue -> linked list
5697 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
5698 if (firstRenderPhaseUpdate !== undefined) {
5699 renderPhaseUpdates.delete(queue);
5700 var newState = hook.memoizedState;
5701 var update = firstRenderPhaseUpdate;
5702 do {
5703 // Process this render phase update. We don't have to check the
5704 // priority because it will always be the same as the current
5705 // render's.
5706 var _action = update.action;
5707 newState = reducer(newState, _action);
5708 update = update.next;
5709 } while (update !== null);
5710
5711 // Mark that the fiber performed work, but only if the new state is
5712 // different from the current state.
5713 if (!is(newState, hook.memoizedState)) {
5714 markWorkInProgressReceivedUpdate();
5715 }
5716
5717 hook.memoizedState = newState;
5718
5719 // Don't persist the state accumlated from the render phase updates to
5720 // the base state unless the queue is empty.
5721 // TODO: Not sure if this is the desired semantics, but it's what we
5722 // do for gDSFP. I can't remember why.
5723 if (hook.baseUpdate === queue.last) {
5724 hook.baseState = newState;
5725 }
5726
5727 return [newState, _dispatch];
5728 }
5729 }
5730 return [hook.memoizedState, _dispatch];
5731 }
5732
5733 // The last update in the entire queue
5734 var last = queue.last;
5735 // The last update that is part of the base state.
5736 var baseUpdate = hook.baseUpdate;
5737 var baseState = hook.baseState;
5738
5739 // Find the first unprocessed update.
5740 var first = void 0;
5741 if (baseUpdate !== null) {
5742 if (last !== null) {
5743 // For the first update, the queue is a circular linked list where
5744 // `queue.last.next = queue.first`. Once the first update commits, and
5745 // the `baseUpdate` is no longer empty, we can unravel the list.
5746 last.next = null;
5747 }
5748 first = baseUpdate.next;
5749 } else {
5750 first = last !== null ? last.next : null;
5751 }
5752 if (first !== null) {
5753 var _newState = baseState;
5754 var newBaseState = null;
5755 var newBaseUpdate = null;
5756 var prevUpdate = baseUpdate;
5757 var _update = first;
5758 var didSkip = false;
5759 do {
5760 var updateExpirationTime = _update.expirationTime;
5761 if (updateExpirationTime < renderExpirationTime) {
5762 // Priority is insufficient. Skip this update. If this is the first
5763 // skipped update, the previous update/state is the new base
5764 // update/state.
5765 if (!didSkip) {
5766 didSkip = true;
5767 newBaseUpdate = prevUpdate;
5768 newBaseState = _newState;
5769 }
5770 // Update the remaining priority in the queue.
5771 if (updateExpirationTime > remainingExpirationTime) {
5772 remainingExpirationTime = updateExpirationTime;
5773 }
5774 } else {
5775 // Process this update.
5776 if (_update.eagerReducer === reducer) {
5777 // If this update was processed eagerly, and its reducer matches the
5778 // current reducer, we can use the eagerly computed state.
5779 _newState = _update.eagerState;
5780 } else {
5781 var _action2 = _update.action;
5782 _newState = reducer(_newState, _action2);
5783 }
5784 }
5785 prevUpdate = _update;
5786 _update = _update.next;
5787 } while (_update !== null && _update !== first);
5788
5789 if (!didSkip) {
5790 newBaseUpdate = prevUpdate;
5791 newBaseState = _newState;
5792 }
5793
5794 // Mark that the fiber performed work, but only if the new state is
5795 // different from the current state.
5796 if (!is(_newState, hook.memoizedState)) {
5797 markWorkInProgressReceivedUpdate();
5798 }
5799
5800 hook.memoizedState = _newState;
5801 hook.baseUpdate = newBaseUpdate;
5802 hook.baseState = newBaseState;
5803
5804 queue.eagerReducer = reducer;
5805 queue.eagerState = _newState;
5806 }
5807
5808 var dispatch = queue.dispatch;
5809 return [hook.memoizedState, dispatch];
5810}
5811
5812function mountState(initialState) {
5813 var hook = mountWorkInProgressHook();
5814 if (typeof initialState === 'function') {
5815 initialState = initialState();
5816 }
5817 hook.memoizedState = hook.baseState = initialState;
5818 var queue = hook.queue = {
5819 last: null,
5820 dispatch: null,
5821 eagerReducer: basicStateReducer,
5822 eagerState: initialState
5823 };
5824 var dispatch = queue.dispatch = dispatchAction.bind(null,
5825 // Flow doesn't know this is non-null, but we do.
5826 currentlyRenderingFiber$1, queue);
5827 return [hook.memoizedState, dispatch];
5828}
5829
5830function updateState(initialState) {
5831 return updateReducer(basicStateReducer, initialState);
5832}
5833
5834function pushEffect(tag, create, destroy, deps) {
5835 var effect = {
5836 tag: tag,
5837 create: create,
5838 destroy: destroy,
5839 deps: deps,
5840 // Circular
5841 next: null
5842 };
5843 if (componentUpdateQueue === null) {
5844 componentUpdateQueue = createFunctionComponentUpdateQueue();
5845 componentUpdateQueue.lastEffect = effect.next = effect;
5846 } else {
5847 var _lastEffect = componentUpdateQueue.lastEffect;
5848 if (_lastEffect === null) {
5849 componentUpdateQueue.lastEffect = effect.next = effect;
5850 } else {
5851 var firstEffect = _lastEffect.next;
5852 _lastEffect.next = effect;
5853 effect.next = firstEffect;
5854 componentUpdateQueue.lastEffect = effect;
5855 }
5856 }
5857 return effect;
5858}
5859
5860function mountRef(initialValue) {
5861 var hook = mountWorkInProgressHook();
5862 var ref = { current: initialValue };
5863 {
5864 Object.seal(ref);
5865 }
5866 hook.memoizedState = ref;
5867 return ref;
5868}
5869
5870function updateRef(initialValue) {
5871 var hook = updateWorkInProgressHook();
5872 return hook.memoizedState;
5873}
5874
5875function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
5876 var hook = mountWorkInProgressHook();
5877 var nextDeps = deps === undefined ? null : deps;
5878 sideEffectTag |= fiberEffectTag;
5879 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps);
5880}
5881
5882function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
5883 var hook = updateWorkInProgressHook();
5884 var nextDeps = deps === undefined ? null : deps;
5885 var destroy = undefined;
5886
5887 if (currentHook !== null) {
5888 var prevEffect = currentHook.memoizedState;
5889 destroy = prevEffect.destroy;
5890 if (nextDeps !== null) {
5891 var prevDeps = prevEffect.deps;
5892 if (areHookInputsEqual(nextDeps, prevDeps)) {
5893 pushEffect(NoEffect$1, create, destroy, nextDeps);
5894 return;
5895 }
5896 }
5897 }
5898
5899 sideEffectTag |= fiberEffectTag;
5900 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps);
5901}
5902
5903function mountEffect(create, deps) {
5904 return mountEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
5905}
5906
5907function updateEffect(create, deps) {
5908 return updateEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
5909}
5910
5911function mountLayoutEffect(create, deps) {
5912 return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
5913}
5914
5915function updateLayoutEffect(create, deps) {
5916 return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
5917}
5918
5919function imperativeHandleEffect(create, ref) {
5920 if (typeof ref === 'function') {
5921 var refCallback = ref;
5922 var _inst = create();
5923 refCallback(_inst);
5924 return function () {
5925 refCallback(null);
5926 };
5927 } else if (ref !== null && ref !== undefined) {
5928 var refObject = ref;
5929 {
5930 !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;
5931 }
5932 var _inst2 = create();
5933 refObject.current = _inst2;
5934 return function () {
5935 refObject.current = null;
5936 };
5937 }
5938}
5939
5940function mountImperativeHandle(ref, create, deps) {
5941 {
5942 !(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;
5943 }
5944
5945 // TODO: If deps are provided, should we skip comparing the ref itself?
5946 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
5947
5948 return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
5949}
5950
5951function updateImperativeHandle(ref, create, deps) {
5952 {
5953 !(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;
5954 }
5955
5956 // TODO: If deps are provided, should we skip comparing the ref itself?
5957 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
5958
5959 return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
5960}
5961
5962function mountDebugValue(value, formatterFn) {
5963 // This hook is normally a no-op.
5964 // The react-debug-hooks package injects its own implementation
5965 // so that e.g. DevTools can display custom hook values.
5966}
5967
5968var updateDebugValue = mountDebugValue;
5969
5970function mountCallback(callback, deps) {
5971 var hook = mountWorkInProgressHook();
5972 var nextDeps = deps === undefined ? null : deps;
5973 hook.memoizedState = [callback, nextDeps];
5974 return callback;
5975}
5976
5977function updateCallback(callback, deps) {
5978 var hook = updateWorkInProgressHook();
5979 var nextDeps = deps === undefined ? null : deps;
5980 var prevState = hook.memoizedState;
5981 if (prevState !== null) {
5982 if (nextDeps !== null) {
5983 var prevDeps = prevState[1];
5984 if (areHookInputsEqual(nextDeps, prevDeps)) {
5985 return prevState[0];
5986 }
5987 }
5988 }
5989 hook.memoizedState = [callback, nextDeps];
5990 return callback;
5991}
5992
5993function mountMemo(nextCreate, deps) {
5994 var hook = mountWorkInProgressHook();
5995 var nextDeps = deps === undefined ? null : deps;
5996 var nextValue = nextCreate();
5997 hook.memoizedState = [nextValue, nextDeps];
5998 return nextValue;
5999}
6000
6001function updateMemo(nextCreate, deps) {
6002 var hook = updateWorkInProgressHook();
6003 var nextDeps = deps === undefined ? null : deps;
6004 var prevState = hook.memoizedState;
6005 if (prevState !== null) {
6006 // Assume these are defined. If they're not, areHookInputsEqual will warn.
6007 if (nextDeps !== null) {
6008 var prevDeps = prevState[1];
6009 if (areHookInputsEqual(nextDeps, prevDeps)) {
6010 return prevState[0];
6011 }
6012 }
6013 }
6014 var nextValue = nextCreate();
6015 hook.memoizedState = [nextValue, nextDeps];
6016 return nextValue;
6017}
6018
6019// in a test-like environment, we want to warn if dispatchAction()
6020// is called outside of a batchedUpdates/TestUtils.act(...) call.
6021var shouldWarnForUnbatchedSetState = false;
6022
6023{
6024 // jest isn't a 'global', it's just exposed to tests via a wrapped function
6025 // further, this isn't a test file, so flow doesn't recognize the symbol. So...
6026 // $FlowExpectedError - because requirements don't give a damn about your type sigs.
6027 if ('undefined' !== typeof jest) {
6028 shouldWarnForUnbatchedSetState = true;
6029 }
6030}
6031
6032function dispatchAction(fiber, queue, action) {
6033 !(numberOfReRenders < RE_RENDER_LIMIT) ? invariant(false, 'Too many re-renders. React limits the number of renders to prevent an infinite loop.') : void 0;
6034
6035 {
6036 !(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;
6037 }
6038
6039 var alternate = fiber.alternate;
6040 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
6041 // This is a render phase update. Stash it in a lazily-created map of
6042 // queue -> linked list of updates. After this render pass, we'll restart
6043 // and apply the stashed updates on top of the work-in-progress hook.
6044 didScheduleRenderPhaseUpdate = true;
6045 var update = {
6046 expirationTime: renderExpirationTime,
6047 action: action,
6048 eagerReducer: null,
6049 eagerState: null,
6050 next: null
6051 };
6052 if (renderPhaseUpdates === null) {
6053 renderPhaseUpdates = new Map();
6054 }
6055 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
6056 if (firstRenderPhaseUpdate === undefined) {
6057 renderPhaseUpdates.set(queue, update);
6058 } else {
6059 // Append the update to the end of the list.
6060 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
6061 while (lastRenderPhaseUpdate.next !== null) {
6062 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
6063 }
6064 lastRenderPhaseUpdate.next = update;
6065 }
6066 } else {
6067 flushPassiveEffects();
6068
6069 var currentTime = requestCurrentTime();
6070 var _expirationTime = computeExpirationForFiber(currentTime, fiber);
6071
6072 var _update2 = {
6073 expirationTime: _expirationTime,
6074 action: action,
6075 eagerReducer: null,
6076 eagerState: null,
6077 next: null
6078 };
6079
6080 // Append the update to the end of the list.
6081 var _last = queue.last;
6082 if (_last === null) {
6083 // This is the first update. Create a circular list.
6084 _update2.next = _update2;
6085 } else {
6086 var first = _last.next;
6087 if (first !== null) {
6088 // Still circular.
6089 _update2.next = first;
6090 }
6091 _last.next = _update2;
6092 }
6093 queue.last = _update2;
6094
6095 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
6096 // The queue is currently empty, which means we can eagerly compute the
6097 // next state before entering the render phase. If the new state is the
6098 // same as the current state, we may be able to bail out entirely.
6099 var _eagerReducer = queue.eagerReducer;
6100 if (_eagerReducer !== null) {
6101 var prevDispatcher = void 0;
6102 {
6103 prevDispatcher = ReactCurrentDispatcher$1.current;
6104 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6105 }
6106 try {
6107 var currentState = queue.eagerState;
6108 var _eagerState = _eagerReducer(currentState, action);
6109 // Stash the eagerly computed state, and the reducer used to compute
6110 // it, on the update object. If the reducer hasn't changed by the
6111 // time we enter the render phase, then the eager state can be used
6112 // without calling the reducer again.
6113 _update2.eagerReducer = _eagerReducer;
6114 _update2.eagerState = _eagerState;
6115 if (is(_eagerState, currentState)) {
6116 // Fast path. We can bail out without scheduling React to re-render.
6117 // It's still possible that we'll need to rebase this update later,
6118 // if the component re-renders for a different reason and by that
6119 // time the reducer has changed.
6120 return;
6121 }
6122 } catch (error) {
6123 // Suppress the error. It will throw again in the render phase.
6124 } finally {
6125 {
6126 ReactCurrentDispatcher$1.current = prevDispatcher;
6127 }
6128 }
6129 }
6130 }
6131 {
6132 if (shouldWarnForUnbatchedSetState === true) {
6133 warnIfNotCurrentlyBatchingInDev(fiber);
6134 }
6135 }
6136 scheduleWork(fiber, _expirationTime);
6137 }
6138}
6139
6140var ContextOnlyDispatcher = {
6141 readContext: readContext,
6142
6143 useCallback: throwInvalidHookError,
6144 useContext: throwInvalidHookError,
6145 useEffect: throwInvalidHookError,
6146 useImperativeHandle: throwInvalidHookError,
6147 useLayoutEffect: throwInvalidHookError,
6148 useMemo: throwInvalidHookError,
6149 useReducer: throwInvalidHookError,
6150 useRef: throwInvalidHookError,
6151 useState: throwInvalidHookError,
6152 useDebugValue: throwInvalidHookError
6153};
6154
6155var HooksDispatcherOnMountInDEV = null;
6156var HooksDispatcherOnUpdateInDEV = null;
6157var InvalidNestedHooksDispatcherOnMountInDEV = null;
6158var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
6159
6160{
6161 var warnInvalidContextAccess = function () {
6162 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().');
6163 };
6164
6165 var warnInvalidHookAccess = function () {
6166 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');
6167 };
6168
6169 HooksDispatcherOnMountInDEV = {
6170 readContext: function (context, observedBits) {
6171 return readContext(context, observedBits);
6172 },
6173 useCallback: function (callback, deps) {
6174 currentHookNameInDev = 'useCallback';
6175 return mountCallback(callback, deps);
6176 },
6177 useContext: function (context, observedBits) {
6178 currentHookNameInDev = 'useContext';
6179 return mountContext(context, observedBits);
6180 },
6181 useEffect: function (create, deps) {
6182 currentHookNameInDev = 'useEffect';
6183 return mountEffect(create, deps);
6184 },
6185 useImperativeHandle: function (ref, create, deps) {
6186 currentHookNameInDev = 'useImperativeHandle';
6187 return mountImperativeHandle(ref, create, deps);
6188 },
6189 useLayoutEffect: function (create, deps) {
6190 currentHookNameInDev = 'useLayoutEffect';
6191 return mountLayoutEffect(create, deps);
6192 },
6193 useMemo: function (create, deps) {
6194 currentHookNameInDev = 'useMemo';
6195 var prevDispatcher = ReactCurrentDispatcher$1.current;
6196 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6197 try {
6198 return mountMemo(create, deps);
6199 } finally {
6200 ReactCurrentDispatcher$1.current = prevDispatcher;
6201 }
6202 },
6203 useReducer: function (reducer, initialArg, init) {
6204 currentHookNameInDev = 'useReducer';
6205 var prevDispatcher = ReactCurrentDispatcher$1.current;
6206 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6207 try {
6208 return mountReducer(reducer, initialArg, init);
6209 } finally {
6210 ReactCurrentDispatcher$1.current = prevDispatcher;
6211 }
6212 },
6213 useRef: function (initialValue) {
6214 currentHookNameInDev = 'useRef';
6215 return mountRef(initialValue);
6216 },
6217 useState: function (initialState) {
6218 currentHookNameInDev = 'useState';
6219 var prevDispatcher = ReactCurrentDispatcher$1.current;
6220 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6221 try {
6222 return mountState(initialState);
6223 } finally {
6224 ReactCurrentDispatcher$1.current = prevDispatcher;
6225 }
6226 },
6227 useDebugValue: function (value, formatterFn) {
6228 currentHookNameInDev = 'useDebugValue';
6229 return mountDebugValue(value, formatterFn);
6230 }
6231 };
6232
6233 HooksDispatcherOnUpdateInDEV = {
6234 readContext: function (context, observedBits) {
6235 return readContext(context, observedBits);
6236 },
6237 useCallback: function (callback, deps) {
6238 currentHookNameInDev = 'useCallback';
6239 return updateCallback(callback, deps);
6240 },
6241 useContext: function (context, observedBits) {
6242 currentHookNameInDev = 'useContext';
6243 return updateContext(context, observedBits);
6244 },
6245 useEffect: function (create, deps) {
6246 currentHookNameInDev = 'useEffect';
6247 return updateEffect(create, deps);
6248 },
6249 useImperativeHandle: function (ref, create, deps) {
6250 currentHookNameInDev = 'useImperativeHandle';
6251 return updateImperativeHandle(ref, create, deps);
6252 },
6253 useLayoutEffect: function (create, deps) {
6254 currentHookNameInDev = 'useLayoutEffect';
6255 return updateLayoutEffect(create, deps);
6256 },
6257 useMemo: function (create, deps) {
6258 currentHookNameInDev = 'useMemo';
6259 var prevDispatcher = ReactCurrentDispatcher$1.current;
6260 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6261 try {
6262 return updateMemo(create, deps);
6263 } finally {
6264 ReactCurrentDispatcher$1.current = prevDispatcher;
6265 }
6266 },
6267 useReducer: function (reducer, initialArg, init) {
6268 currentHookNameInDev = 'useReducer';
6269 var prevDispatcher = ReactCurrentDispatcher$1.current;
6270 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6271 try {
6272 return updateReducer(reducer, initialArg, init);
6273 } finally {
6274 ReactCurrentDispatcher$1.current = prevDispatcher;
6275 }
6276 },
6277 useRef: function (initialValue) {
6278 currentHookNameInDev = 'useRef';
6279 return updateRef(initialValue);
6280 },
6281 useState: function (initialState) {
6282 currentHookNameInDev = 'useState';
6283 var prevDispatcher = ReactCurrentDispatcher$1.current;
6284 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6285 try {
6286 return updateState(initialState);
6287 } finally {
6288 ReactCurrentDispatcher$1.current = prevDispatcher;
6289 }
6290 },
6291 useDebugValue: function (value, formatterFn) {
6292 currentHookNameInDev = 'useDebugValue';
6293 return updateDebugValue(value, formatterFn);
6294 }
6295 };
6296
6297 InvalidNestedHooksDispatcherOnMountInDEV = {
6298 readContext: function (context, observedBits) {
6299 warnInvalidContextAccess();
6300 return readContext(context, observedBits);
6301 },
6302 useCallback: function (callback, deps) {
6303 currentHookNameInDev = 'useCallback';
6304 warnInvalidHookAccess();
6305 return mountCallback(callback, deps);
6306 },
6307 useContext: function (context, observedBits) {
6308 currentHookNameInDev = 'useContext';
6309 warnInvalidHookAccess();
6310 return mountContext(context, observedBits);
6311 },
6312 useEffect: function (create, deps) {
6313 currentHookNameInDev = 'useEffect';
6314 warnInvalidHookAccess();
6315 return mountEffect(create, deps);
6316 },
6317 useImperativeHandle: function (ref, create, deps) {
6318 currentHookNameInDev = 'useImperativeHandle';
6319 warnInvalidHookAccess();
6320 return mountImperativeHandle(ref, create, deps);
6321 },
6322 useLayoutEffect: function (create, deps) {
6323 currentHookNameInDev = 'useLayoutEffect';
6324 warnInvalidHookAccess();
6325 return mountLayoutEffect(create, deps);
6326 },
6327 useMemo: function (create, deps) {
6328 currentHookNameInDev = 'useMemo';
6329 warnInvalidHookAccess();
6330 var prevDispatcher = ReactCurrentDispatcher$1.current;
6331 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6332 try {
6333 return mountMemo(create, deps);
6334 } finally {
6335 ReactCurrentDispatcher$1.current = prevDispatcher;
6336 }
6337 },
6338 useReducer: function (reducer, initialArg, init) {
6339 currentHookNameInDev = 'useReducer';
6340 warnInvalidHookAccess();
6341 var prevDispatcher = ReactCurrentDispatcher$1.current;
6342 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6343 try {
6344 return mountReducer(reducer, initialArg, init);
6345 } finally {
6346 ReactCurrentDispatcher$1.current = prevDispatcher;
6347 }
6348 },
6349 useRef: function (initialValue) {
6350 currentHookNameInDev = 'useRef';
6351 warnInvalidHookAccess();
6352 return mountRef(initialValue);
6353 },
6354 useState: function (initialState) {
6355 currentHookNameInDev = 'useState';
6356 warnInvalidHookAccess();
6357 var prevDispatcher = ReactCurrentDispatcher$1.current;
6358 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6359 try {
6360 return mountState(initialState);
6361 } finally {
6362 ReactCurrentDispatcher$1.current = prevDispatcher;
6363 }
6364 },
6365 useDebugValue: function (value, formatterFn) {
6366 currentHookNameInDev = 'useDebugValue';
6367 warnInvalidHookAccess();
6368 return mountDebugValue(value, formatterFn);
6369 }
6370 };
6371
6372 InvalidNestedHooksDispatcherOnUpdateInDEV = {
6373 readContext: function (context, observedBits) {
6374 warnInvalidContextAccess();
6375 return readContext(context, observedBits);
6376 },
6377 useCallback: function (callback, deps) {
6378 currentHookNameInDev = 'useCallback';
6379 warnInvalidHookAccess();
6380 return updateCallback(callback, deps);
6381 },
6382 useContext: function (context, observedBits) {
6383 currentHookNameInDev = 'useContext';
6384 warnInvalidHookAccess();
6385 return updateContext(context, observedBits);
6386 },
6387 useEffect: function (create, deps) {
6388 currentHookNameInDev = 'useEffect';
6389 warnInvalidHookAccess();
6390 return updateEffect(create, deps);
6391 },
6392 useImperativeHandle: function (ref, create, deps) {
6393 currentHookNameInDev = 'useImperativeHandle';
6394 warnInvalidHookAccess();
6395 return updateImperativeHandle(ref, create, deps);
6396 },
6397 useLayoutEffect: function (create, deps) {
6398 currentHookNameInDev = 'useLayoutEffect';
6399 warnInvalidHookAccess();
6400 return updateLayoutEffect(create, deps);
6401 },
6402 useMemo: function (create, deps) {
6403 currentHookNameInDev = 'useMemo';
6404 warnInvalidHookAccess();
6405 var prevDispatcher = ReactCurrentDispatcher$1.current;
6406 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6407 try {
6408 return updateMemo(create, deps);
6409 } finally {
6410 ReactCurrentDispatcher$1.current = prevDispatcher;
6411 }
6412 },
6413 useReducer: function (reducer, initialArg, init) {
6414 currentHookNameInDev = 'useReducer';
6415 warnInvalidHookAccess();
6416 var prevDispatcher = ReactCurrentDispatcher$1.current;
6417 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6418 try {
6419 return updateReducer(reducer, initialArg, init);
6420 } finally {
6421 ReactCurrentDispatcher$1.current = prevDispatcher;
6422 }
6423 },
6424 useRef: function (initialValue) {
6425 currentHookNameInDev = 'useRef';
6426 warnInvalidHookAccess();
6427 return updateRef(initialValue);
6428 },
6429 useState: function (initialState) {
6430 currentHookNameInDev = 'useState';
6431 warnInvalidHookAccess();
6432 var prevDispatcher = ReactCurrentDispatcher$1.current;
6433 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6434 try {
6435 return updateState(initialState);
6436 } finally {
6437 ReactCurrentDispatcher$1.current = prevDispatcher;
6438 }
6439 },
6440 useDebugValue: function (value, formatterFn) {
6441 currentHookNameInDev = 'useDebugValue';
6442 warnInvalidHookAccess();
6443 return updateDebugValue(value, formatterFn);
6444 }
6445 };
6446}
6447
6448var commitTime = 0;
6449var profilerStartTime = -1;
6450
6451function getCommitTime() {
6452 return commitTime;
6453}
6454
6455function recordCommitTime() {
6456 if (!enableProfilerTimer) {
6457 return;
6458 }
6459 commitTime = unstable_now();
6460}
6461
6462function startProfilerTimer(fiber) {
6463 if (!enableProfilerTimer) {
6464 return;
6465 }
6466
6467 profilerStartTime = unstable_now();
6468
6469 if (fiber.actualStartTime < 0) {
6470 fiber.actualStartTime = unstable_now();
6471 }
6472}
6473
6474function stopProfilerTimerIfRunning(fiber) {
6475 if (!enableProfilerTimer) {
6476 return;
6477 }
6478 profilerStartTime = -1;
6479}
6480
6481function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
6482 if (!enableProfilerTimer) {
6483 return;
6484 }
6485
6486 if (profilerStartTime >= 0) {
6487 var elapsedTime = unstable_now() - profilerStartTime;
6488 fiber.actualDuration += elapsedTime;
6489 if (overrideBaseTime) {
6490 fiber.selfBaseDuration = elapsedTime;
6491 }
6492 profilerStartTime = -1;
6493 }
6494}
6495
6496// The deepest Fiber on the stack involved in a hydration context.
6497// This may have been an insertion or a hydration.
6498var hydrationParentFiber = null;
6499var nextHydratableInstance = null;
6500var isHydrating = false;
6501
6502function enterHydrationState(fiber) {
6503 if (!supportsHydration) {
6504 return false;
6505 }
6506
6507 var parentInstance = fiber.stateNode.containerInfo;
6508 nextHydratableInstance = getFirstHydratableChild(parentInstance);
6509 hydrationParentFiber = fiber;
6510 isHydrating = true;
6511 return true;
6512}
6513
6514function reenterHydrationStateFromDehydratedSuspenseInstance(fiber) {
6515 if (!supportsHydration) {
6516 return false;
6517 }
6518
6519 var suspenseInstance = fiber.stateNode;
6520 nextHydratableInstance = getNextHydratableSibling(suspenseInstance);
6521 popToNextHostParent(fiber);
6522 isHydrating = true;
6523 return true;
6524}
6525
6526function deleteHydratableInstance(returnFiber, instance) {
6527 {
6528 switch (returnFiber.tag) {
6529 case HostRoot:
6530 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
6531 break;
6532 case HostComponent:
6533 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
6534 break;
6535 }
6536 }
6537
6538 var childToDelete = createFiberFromHostInstanceForDeletion();
6539 childToDelete.stateNode = instance;
6540 childToDelete.return = returnFiber;
6541 childToDelete.effectTag = Deletion;
6542
6543 // This might seem like it belongs on progressedFirstDeletion. However,
6544 // these children are not part of the reconciliation list of children.
6545 // Even if we abort and rereconcile the children, that will try to hydrate
6546 // again and the nodes are still in the host tree so these will be
6547 // recreated.
6548 if (returnFiber.lastEffect !== null) {
6549 returnFiber.lastEffect.nextEffect = childToDelete;
6550 returnFiber.lastEffect = childToDelete;
6551 } else {
6552 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
6553 }
6554}
6555
6556function insertNonHydratedInstance(returnFiber, fiber) {
6557 fiber.effectTag |= Placement;
6558 {
6559 switch (returnFiber.tag) {
6560 case HostRoot:
6561 {
6562 var parentContainer = returnFiber.stateNode.containerInfo;
6563 switch (fiber.tag) {
6564 case HostComponent:
6565 var type = fiber.type;
6566 var props = fiber.pendingProps;
6567 didNotFindHydratableContainerInstance(parentContainer, type, props);
6568 break;
6569 case HostText:
6570 var text = fiber.pendingProps;
6571 didNotFindHydratableContainerTextInstance(parentContainer, text);
6572 break;
6573 case SuspenseComponent:
6574 didNotFindHydratableContainerSuspenseInstance(parentContainer);
6575 break;
6576 }
6577 break;
6578 }
6579 case HostComponent:
6580 {
6581 var parentType = returnFiber.type;
6582 var parentProps = returnFiber.memoizedProps;
6583 var parentInstance = returnFiber.stateNode;
6584 switch (fiber.tag) {
6585 case HostComponent:
6586 var _type = fiber.type;
6587 var _props = fiber.pendingProps;
6588 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
6589 break;
6590 case HostText:
6591 var _text = fiber.pendingProps;
6592 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
6593 break;
6594 case SuspenseComponent:
6595 didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance);
6596 break;
6597 }
6598 break;
6599 }
6600 default:
6601 return;
6602 }
6603 }
6604}
6605
6606function tryHydrate(fiber, nextInstance) {
6607 switch (fiber.tag) {
6608 case HostComponent:
6609 {
6610 var type = fiber.type;
6611 var props = fiber.pendingProps;
6612 var instance = canHydrateInstance(nextInstance, type, props);
6613 if (instance !== null) {
6614 fiber.stateNode = instance;
6615 return true;
6616 }
6617 return false;
6618 }
6619 case HostText:
6620 {
6621 var text = fiber.pendingProps;
6622 var textInstance = canHydrateTextInstance(nextInstance, text);
6623 if (textInstance !== null) {
6624 fiber.stateNode = textInstance;
6625 return true;
6626 }
6627 return false;
6628 }
6629 case SuspenseComponent:
6630 {
6631 if (enableSuspenseServerRenderer) {
6632 var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
6633 if (suspenseInstance !== null) {
6634 // Downgrade the tag to a dehydrated component until we've hydrated it.
6635 fiber.tag = DehydratedSuspenseComponent;
6636 fiber.stateNode = suspenseInstance;
6637 return true;
6638 }
6639 }
6640 return false;
6641 }
6642 default:
6643 return false;
6644 }
6645}
6646
6647function tryToClaimNextHydratableInstance(fiber) {
6648 if (!isHydrating) {
6649 return;
6650 }
6651 var nextInstance = nextHydratableInstance;
6652 if (!nextInstance) {
6653 // Nothing to hydrate. Make it an insertion.
6654 insertNonHydratedInstance(hydrationParentFiber, fiber);
6655 isHydrating = false;
6656 hydrationParentFiber = fiber;
6657 return;
6658 }
6659 var firstAttemptedInstance = nextInstance;
6660 if (!tryHydrate(fiber, nextInstance)) {
6661 // If we can't hydrate this instance let's try the next one.
6662 // We use this as a heuristic. It's based on intuition and not data so it
6663 // might be flawed or unnecessary.
6664 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
6665 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
6666 // Nothing to hydrate. Make it an insertion.
6667 insertNonHydratedInstance(hydrationParentFiber, fiber);
6668 isHydrating = false;
6669 hydrationParentFiber = fiber;
6670 return;
6671 }
6672 // We matched the next one, we'll now assume that the first one was
6673 // superfluous and we'll delete it. Since we can't eagerly delete it
6674 // we'll have to schedule a deletion. To do that, this node needs a dummy
6675 // fiber associated with it.
6676 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
6677 }
6678 hydrationParentFiber = fiber;
6679 nextHydratableInstance = getFirstHydratableChild(nextInstance);
6680}
6681
6682function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
6683 if (!supportsHydration) {
6684 invariant(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
6685 }
6686
6687 var instance = fiber.stateNode;
6688 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
6689 // TODO: Type this specific to this type of component.
6690 fiber.updateQueue = updatePayload;
6691 // If the update payload indicates that there is a change or if there
6692 // is a new ref we mark this as an update.
6693 if (updatePayload !== null) {
6694 return true;
6695 }
6696 return false;
6697}
6698
6699function prepareToHydrateHostTextInstance(fiber) {
6700 if (!supportsHydration) {
6701 invariant(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
6702 }
6703
6704 var textInstance = fiber.stateNode;
6705 var textContent = fiber.memoizedProps;
6706 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
6707 {
6708 if (shouldUpdate) {
6709 // We assume that prepareToHydrateHostTextInstance is called in a context where the
6710 // hydration parent is the parent host component of this host text.
6711 var returnFiber = hydrationParentFiber;
6712 if (returnFiber !== null) {
6713 switch (returnFiber.tag) {
6714 case HostRoot:
6715 {
6716 var parentContainer = returnFiber.stateNode.containerInfo;
6717 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
6718 break;
6719 }
6720 case HostComponent:
6721 {
6722 var parentType = returnFiber.type;
6723 var parentProps = returnFiber.memoizedProps;
6724 var parentInstance = returnFiber.stateNode;
6725 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
6726 break;
6727 }
6728 }
6729 }
6730 }
6731 }
6732 return shouldUpdate;
6733}
6734
6735function skipPastDehydratedSuspenseInstance(fiber) {
6736 if (!supportsHydration) {
6737 invariant(false, 'Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
6738 }
6739 var suspenseInstance = fiber.stateNode;
6740 !suspenseInstance ? invariant(false, 'Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue.') : void 0;
6741 nextHydratableInstance = getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
6742}
6743
6744function popToNextHostParent(fiber) {
6745 var parent = fiber.return;
6746 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== DehydratedSuspenseComponent) {
6747 parent = parent.return;
6748 }
6749 hydrationParentFiber = parent;
6750}
6751
6752function popHydrationState(fiber) {
6753 if (!supportsHydration) {
6754 return false;
6755 }
6756 if (fiber !== hydrationParentFiber) {
6757 // We're deeper than the current hydration context, inside an inserted
6758 // tree.
6759 return false;
6760 }
6761 if (!isHydrating) {
6762 // If we're not currently hydrating but we're in a hydration context, then
6763 // we were an insertion and now need to pop up reenter hydration of our
6764 // siblings.
6765 popToNextHostParent(fiber);
6766 isHydrating = true;
6767 return false;
6768 }
6769
6770 var type = fiber.type;
6771
6772 // If we have any remaining hydratable nodes, we need to delete them now.
6773 // We only do this deeper than head and body since they tend to have random
6774 // other nodes in them. We also ignore components with pure text content in
6775 // side of them.
6776 // TODO: Better heuristic.
6777 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
6778 var nextInstance = nextHydratableInstance;
6779 while (nextInstance) {
6780 deleteHydratableInstance(fiber, nextInstance);
6781 nextInstance = getNextHydratableSibling(nextInstance);
6782 }
6783 }
6784
6785 popToNextHostParent(fiber);
6786 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
6787 return true;
6788}
6789
6790function resetHydrationState() {
6791 if (!supportsHydration) {
6792 return;
6793 }
6794
6795 hydrationParentFiber = null;
6796 nextHydratableInstance = null;
6797 isHydrating = false;
6798}
6799
6800var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
6801
6802var didReceiveUpdate = false;
6803
6804var didWarnAboutBadClass = void 0;
6805var didWarnAboutContextTypeOnFunctionComponent = void 0;
6806var didWarnAboutGetDerivedStateOnFunctionComponent = void 0;
6807var didWarnAboutFunctionRefs = void 0;
6808var didWarnAboutReassigningProps = void 0;
6809
6810{
6811 didWarnAboutBadClass = {};
6812 didWarnAboutContextTypeOnFunctionComponent = {};
6813 didWarnAboutGetDerivedStateOnFunctionComponent = {};
6814 didWarnAboutFunctionRefs = {};
6815 didWarnAboutReassigningProps = false;
6816}
6817
6818function reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime) {
6819 if (current === null) {
6820 // If this is a fresh new component that hasn't been rendered yet, we
6821 // won't update its child set by applying minimal side-effects. Instead,
6822 // we will add them all to the child before it gets rendered. That means
6823 // we can optimize this reconciliation pass by not tracking side-effects.
6824 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
6825 } else {
6826 // If the current child is the same as the work in progress, it means that
6827 // we haven't yet started any work on these children. Therefore, we use
6828 // the clone algorithm to create a copy of all the current children.
6829
6830 // If we had any progressed work already, that is invalid at this point so
6831 // let's throw it out.
6832 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
6833 }
6834}
6835
6836function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime) {
6837 // This function is fork of reconcileChildren. It's used in cases where we
6838 // want to reconcile without matching against the existing set. This has the
6839 // effect of all current children being unmounted; even if the type and key
6840 // are the same, the old child is unmounted and a new child is created.
6841 //
6842 // To do this, we're going to go through the reconcile algorithm twice. In
6843 // the first pass, we schedule a deletion for all the current children by
6844 // passing null.
6845 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderExpirationTime);
6846 // In the second pass, we mount the new children. The trick here is that we
6847 // pass null in place of where we usually pass the current child set. This has
6848 // the effect of remounting all children regardless of whether their their
6849 // identity matches.
6850 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
6851}
6852
6853function updateForwardRef(current, workInProgress, Component, nextProps, renderExpirationTime) {
6854 // TODO: current can be non-null here even if the component
6855 // hasn't yet mounted. This happens after the first render suspends.
6856 // We'll need to figure out if this is fine or can cause issues.
6857
6858 {
6859 if (workInProgress.type !== workInProgress.elementType) {
6860 // Lazy component props can't be validated in createElement
6861 // because they're only guaranteed to be resolved here.
6862 var innerPropTypes = Component.propTypes;
6863 if (innerPropTypes) {
6864 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
6865 'prop', getComponentName(Component), getCurrentFiberStackInDev);
6866 }
6867 }
6868 }
6869
6870 var render = Component.render;
6871 var ref = workInProgress.ref;
6872
6873 // The rest is a fork of updateFunctionComponent
6874 var nextChildren = void 0;
6875 prepareToReadContext(workInProgress, renderExpirationTime);
6876 {
6877 ReactCurrentOwner$2.current = workInProgress;
6878 setCurrentPhase('render');
6879 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
6880 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
6881 // Only double-render components with Hooks
6882 if (workInProgress.memoizedState !== null) {
6883 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
6884 }
6885 }
6886 setCurrentPhase(null);
6887 }
6888
6889 if (current !== null && !didReceiveUpdate) {
6890 bailoutHooks(current, workInProgress, renderExpirationTime);
6891 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
6892 }
6893
6894 // React DevTools reads this flag.
6895 workInProgress.effectTag |= PerformedWork;
6896 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
6897 return workInProgress.child;
6898}
6899
6900function updateMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
6901 if (current === null) {
6902 var type = Component.type;
6903 if (isSimpleFunctionComponent(type) && Component.compare === null &&
6904 // SimpleMemoComponent codepath doesn't resolve outer props either.
6905 Component.defaultProps === undefined) {
6906 // If this is a plain function component without default props,
6907 // and with only the default shallow comparison, we upgrade it
6908 // to a SimpleMemoComponent to allow fast path updates.
6909 workInProgress.tag = SimpleMemoComponent;
6910 workInProgress.type = type;
6911 {
6912 validateFunctionComponentInDev(workInProgress, type);
6913 }
6914 return updateSimpleMemoComponent(current, workInProgress, type, nextProps, updateExpirationTime, renderExpirationTime);
6915 }
6916 {
6917 var innerPropTypes = type.propTypes;
6918 if (innerPropTypes) {
6919 // Inner memo component props aren't currently validated in createElement.
6920 // We could move it there, but we'd still need this for lazy code path.
6921 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
6922 'prop', getComponentName(type), getCurrentFiberStackInDev);
6923 }
6924 }
6925 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
6926 child.ref = workInProgress.ref;
6927 child.return = workInProgress;
6928 workInProgress.child = child;
6929 return child;
6930 }
6931 {
6932 var _type = Component.type;
6933 var _innerPropTypes = _type.propTypes;
6934 if (_innerPropTypes) {
6935 // Inner memo component props aren't currently validated in createElement.
6936 // We could move it there, but we'd still need this for lazy code path.
6937 checkPropTypes_1(_innerPropTypes, nextProps, // Resolved props
6938 'prop', getComponentName(_type), getCurrentFiberStackInDev);
6939 }
6940 }
6941 var currentChild = current.child; // This is always exactly one child
6942 if (updateExpirationTime < renderExpirationTime) {
6943 // This will be the props with resolved defaultProps,
6944 // unlike current.memoizedProps which will be the unresolved ones.
6945 var prevProps = currentChild.memoizedProps;
6946 // Default to shallow comparison
6947 var compare = Component.compare;
6948 compare = compare !== null ? compare : shallowEqual;
6949 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
6950 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
6951 }
6952 }
6953 // React DevTools reads this flag.
6954 workInProgress.effectTag |= PerformedWork;
6955 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime);
6956 newChild.ref = workInProgress.ref;
6957 newChild.return = workInProgress;
6958 workInProgress.child = newChild;
6959 return newChild;
6960}
6961
6962function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
6963 // TODO: current can be non-null here even if the component
6964 // hasn't yet mounted. This happens when the inner render suspends.
6965 // We'll need to figure out if this is fine or can cause issues.
6966
6967 {
6968 if (workInProgress.type !== workInProgress.elementType) {
6969 // Lazy component props can't be validated in createElement
6970 // because they're only guaranteed to be resolved here.
6971 var outerMemoType = workInProgress.elementType;
6972 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
6973 // We warn when you define propTypes on lazy()
6974 // so let's just skip over it to find memo() outer wrapper.
6975 // Inner props for memo are validated later.
6976 outerMemoType = refineResolvedLazyComponent(outerMemoType);
6977 }
6978 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
6979 if (outerPropTypes) {
6980 checkPropTypes_1(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
6981 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
6982 }
6983 // Inner propTypes will be validated in the function component path.
6984 }
6985 }
6986 if (current !== null) {
6987 var prevProps = current.memoizedProps;
6988 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref) {
6989 didReceiveUpdate = false;
6990 if (updateExpirationTime < renderExpirationTime) {
6991 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
6992 }
6993 }
6994 }
6995 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime);
6996}
6997
6998function updateFragment(current, workInProgress, renderExpirationTime) {
6999 var nextChildren = workInProgress.pendingProps;
7000 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7001 return workInProgress.child;
7002}
7003
7004function updateMode(current, workInProgress, renderExpirationTime) {
7005 var nextChildren = workInProgress.pendingProps.children;
7006 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7007 return workInProgress.child;
7008}
7009
7010function updateProfiler(current, workInProgress, renderExpirationTime) {
7011 if (enableProfilerTimer) {
7012 workInProgress.effectTag |= Update;
7013 }
7014 var nextProps = workInProgress.pendingProps;
7015 var nextChildren = nextProps.children;
7016 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7017 return workInProgress.child;
7018}
7019
7020function markRef(current, workInProgress) {
7021 var ref = workInProgress.ref;
7022 if (current === null && ref !== null || current !== null && current.ref !== ref) {
7023 // Schedule a Ref effect
7024 workInProgress.effectTag |= Ref;
7025 }
7026}
7027
7028function updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
7029 {
7030 if (workInProgress.type !== workInProgress.elementType) {
7031 // Lazy component props can't be validated in createElement
7032 // because they're only guaranteed to be resolved here.
7033 var innerPropTypes = Component.propTypes;
7034 if (innerPropTypes) {
7035 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
7036 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7037 }
7038 }
7039 }
7040
7041 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
7042 var context = getMaskedContext(workInProgress, unmaskedContext);
7043
7044 var nextChildren = void 0;
7045 prepareToReadContext(workInProgress, renderExpirationTime);
7046 {
7047 ReactCurrentOwner$2.current = workInProgress;
7048 setCurrentPhase('render');
7049 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
7050 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7051 // Only double-render components with Hooks
7052 if (workInProgress.memoizedState !== null) {
7053 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
7054 }
7055 }
7056 setCurrentPhase(null);
7057 }
7058
7059 if (current !== null && !didReceiveUpdate) {
7060 bailoutHooks(current, workInProgress, renderExpirationTime);
7061 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7062 }
7063
7064 // React DevTools reads this flag.
7065 workInProgress.effectTag |= PerformedWork;
7066 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7067 return workInProgress.child;
7068}
7069
7070function updateClassComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
7071 {
7072 if (workInProgress.type !== workInProgress.elementType) {
7073 // Lazy component props can't be validated in createElement
7074 // because they're only guaranteed to be resolved here.
7075 var innerPropTypes = Component.propTypes;
7076 if (innerPropTypes) {
7077 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
7078 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7079 }
7080 }
7081 }
7082
7083 // Push context providers early to prevent context stack mismatches.
7084 // During mounting we don't know the child context yet as the instance doesn't exist.
7085 // We will invalidate the child context in finishClassComponent() right after rendering.
7086 var hasContext = void 0;
7087 if (isContextProvider(Component)) {
7088 hasContext = true;
7089 pushContextProvider(workInProgress);
7090 } else {
7091 hasContext = false;
7092 }
7093 prepareToReadContext(workInProgress, renderExpirationTime);
7094
7095 var instance = workInProgress.stateNode;
7096 var shouldUpdate = void 0;
7097 if (instance === null) {
7098 if (current !== null) {
7099 // An class component without an instance only mounts if it suspended
7100 // inside a non- concurrent tree, in an inconsistent state. We want to
7101 // tree it like a new mount, even though an empty version of it already
7102 // committed. Disconnect the alternate pointers.
7103 current.alternate = null;
7104 workInProgress.alternate = null;
7105 // Since this is conceptually a new fiber, schedule a Placement effect
7106 workInProgress.effectTag |= Placement;
7107 }
7108 // In the initial pass we might need to construct the instance.
7109 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7110 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7111 shouldUpdate = true;
7112 } else if (current === null) {
7113 // In a resume, we'll already have an instance we can reuse.
7114 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7115 } else {
7116 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderExpirationTime);
7117 }
7118 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
7119 {
7120 var inst = workInProgress.stateNode;
7121 if (inst.props !== nextProps) {
7122 !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;
7123 didWarnAboutReassigningProps = true;
7124 }
7125 }
7126 return nextUnitOfWork;
7127}
7128
7129function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
7130 // Refs should update even if shouldComponentUpdate returns false
7131 markRef(current, workInProgress);
7132
7133 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
7134
7135 if (!shouldUpdate && !didCaptureError) {
7136 // Context providers should defer to sCU for rendering
7137 if (hasContext) {
7138 invalidateContextProvider(workInProgress, Component, false);
7139 }
7140
7141 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7142 }
7143
7144 var instance = workInProgress.stateNode;
7145
7146 // Rerender
7147 ReactCurrentOwner$2.current = workInProgress;
7148 var nextChildren = void 0;
7149 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
7150 // If we captured an error, but getDerivedStateFrom catch is not defined,
7151 // unmount all the children. componentDidCatch will schedule an update to
7152 // re-render a fallback. This is temporary until we migrate everyone to
7153 // the new API.
7154 // TODO: Warn in a future release.
7155 nextChildren = null;
7156
7157 if (enableProfilerTimer) {
7158 stopProfilerTimerIfRunning(workInProgress);
7159 }
7160 } else {
7161 {
7162 setCurrentPhase('render');
7163 nextChildren = instance.render();
7164 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7165 instance.render();
7166 }
7167 setCurrentPhase(null);
7168 }
7169 }
7170
7171 // React DevTools reads this flag.
7172 workInProgress.effectTag |= PerformedWork;
7173 if (current !== null && didCaptureError) {
7174 // If we're recovering from an error, reconcile without reusing any of
7175 // the existing children. Conceptually, the normal children and the children
7176 // that are shown on error are two different sets, so we shouldn't reuse
7177 // normal children even if their identities match.
7178 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime);
7179 } else {
7180 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7181 }
7182
7183 // Memoize state using the values we just used to render.
7184 // TODO: Restructure so we never read values from the instance.
7185 workInProgress.memoizedState = instance.state;
7186
7187 // The context might have changed so we need to recalculate it.
7188 if (hasContext) {
7189 invalidateContextProvider(workInProgress, Component, true);
7190 }
7191
7192 return workInProgress.child;
7193}
7194
7195function pushHostRootContext(workInProgress) {
7196 var root = workInProgress.stateNode;
7197 if (root.pendingContext) {
7198 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
7199 } else if (root.context) {
7200 // Should always be set
7201 pushTopLevelContextObject(workInProgress, root.context, false);
7202 }
7203 pushHostContainer(workInProgress, root.containerInfo);
7204}
7205
7206function updateHostRoot(current, workInProgress, renderExpirationTime) {
7207 pushHostRootContext(workInProgress);
7208 var updateQueue = workInProgress.updateQueue;
7209 !(updateQueue !== null) ? invariant(false, '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.') : void 0;
7210 var nextProps = workInProgress.pendingProps;
7211 var prevState = workInProgress.memoizedState;
7212 var prevChildren = prevState !== null ? prevState.element : null;
7213 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime);
7214 var nextState = workInProgress.memoizedState;
7215 // Caution: React DevTools currently depends on this property
7216 // being called "element".
7217 var nextChildren = nextState.element;
7218 if (nextChildren === prevChildren) {
7219 // If the state is the same as before, that's a bailout because we had
7220 // no work that expires at this time.
7221 resetHydrationState();
7222 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7223 }
7224 var root = workInProgress.stateNode;
7225 if ((current === null || current.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
7226 // If we don't have any current children this might be the first pass.
7227 // We always try to hydrate. If this isn't a hydration pass there won't
7228 // be any children to hydrate which is effectively the same thing as
7229 // not hydrating.
7230
7231 // This is a bit of a hack. We track the host root as a placement to
7232 // know that we're currently in a mounting state. That way isMounted
7233 // works as expected. We must reset this before committing.
7234 // TODO: Delete this when we delete isMounted and findDOMNode.
7235 workInProgress.effectTag |= Placement;
7236
7237 // Ensure that children mount into this root without tracking
7238 // side-effects. This ensures that we don't store Placement effects on
7239 // nodes that will be hydrated.
7240 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7241 } else {
7242 // Otherwise reset hydration state in case we aborted and resumed another
7243 // root.
7244 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7245 resetHydrationState();
7246 }
7247 return workInProgress.child;
7248}
7249
7250function updateHostComponent(current, workInProgress, renderExpirationTime) {
7251 pushHostContext(workInProgress);
7252
7253 if (current === null) {
7254 tryToClaimNextHydratableInstance(workInProgress);
7255 }
7256
7257 var type = workInProgress.type;
7258 var nextProps = workInProgress.pendingProps;
7259 var prevProps = current !== null ? current.memoizedProps : null;
7260
7261 var nextChildren = nextProps.children;
7262 var isDirectTextChild = shouldSetTextContent(type, nextProps);
7263
7264 if (isDirectTextChild) {
7265 // We special case a direct text child of a host node. This is a common
7266 // case. We won't handle it as a reified child. We will instead handle
7267 // this in the host environment that also have access to this prop. That
7268 // avoids allocating another HostText fiber and traversing it.
7269 nextChildren = null;
7270 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
7271 // If we're switching from a direct text child to a normal child, or to
7272 // empty, we need to schedule the text content to be reset.
7273 workInProgress.effectTag |= ContentReset;
7274 }
7275
7276 markRef(current, workInProgress);
7277
7278 // Check the host config to see if the children are offscreen/hidden.
7279 if (renderExpirationTime !== Never && workInProgress.mode & ConcurrentMode && shouldDeprioritizeSubtree(type, nextProps)) {
7280 // Schedule this fiber to re-render at offscreen priority. Then bailout.
7281 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
7282 return null;
7283 }
7284
7285 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7286 return workInProgress.child;
7287}
7288
7289function updateHostText(current, workInProgress) {
7290 if (current === null) {
7291 tryToClaimNextHydratableInstance(workInProgress);
7292 }
7293 // Nothing to do here. This is terminal. We'll do the completion step
7294 // immediately after.
7295 return null;
7296}
7297
7298function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
7299 if (_current !== null) {
7300 // An lazy component only mounts if it suspended inside a non-
7301 // concurrent tree, in an inconsistent state. We want to treat it like
7302 // a new mount, even though an empty version of it already committed.
7303 // Disconnect the alternate pointers.
7304 _current.alternate = null;
7305 workInProgress.alternate = null;
7306 // Since this is conceptually a new fiber, schedule a Placement effect
7307 workInProgress.effectTag |= Placement;
7308 }
7309
7310 var props = workInProgress.pendingProps;
7311 // We can't start a User Timing measurement with correct label yet.
7312 // Cancel and resume right after we know the tag.
7313 cancelWorkTimer(workInProgress);
7314 var Component = readLazyComponentType(elementType);
7315 // Store the unwrapped component in the type.
7316 workInProgress.type = Component;
7317 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
7318 startWorkTimer(workInProgress);
7319 var resolvedProps = resolveDefaultProps(Component, props);
7320 var child = void 0;
7321 switch (resolvedTag) {
7322 case FunctionComponent:
7323 {
7324 {
7325 validateFunctionComponentInDev(workInProgress, Component);
7326 }
7327 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7328 break;
7329 }
7330 case ClassComponent:
7331 {
7332 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7333 break;
7334 }
7335 case ForwardRef:
7336 {
7337 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7338 break;
7339 }
7340 case MemoComponent:
7341 {
7342 {
7343 if (workInProgress.type !== workInProgress.elementType) {
7344 var outerPropTypes = Component.propTypes;
7345 if (outerPropTypes) {
7346 checkPropTypes_1(outerPropTypes, resolvedProps, // Resolved for outer only
7347 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7348 }
7349 }
7350 }
7351 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
7352 updateExpirationTime, renderExpirationTime);
7353 break;
7354 }
7355 default:
7356 {
7357 var hint = '';
7358 {
7359 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
7360 hint = ' Did you wrap a component in React.lazy() more than once?';
7361 }
7362 }
7363 // This message intentionally doesn't mention ForwardRef or MemoComponent
7364 // because the fact that it's a separate type of work is an
7365 // implementation detail.
7366 invariant(false, 'Element type is invalid. Received a promise that resolves to: %s. Lazy element type must resolve to a class or function.%s', Component, hint);
7367 }
7368 }
7369 return child;
7370}
7371
7372function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
7373 if (_current !== null) {
7374 // An incomplete component only mounts if it suspended inside a non-
7375 // concurrent tree, in an inconsistent state. We want to treat it like
7376 // a new mount, even though an empty version of it already committed.
7377 // Disconnect the alternate pointers.
7378 _current.alternate = null;
7379 workInProgress.alternate = null;
7380 // Since this is conceptually a new fiber, schedule a Placement effect
7381 workInProgress.effectTag |= Placement;
7382 }
7383
7384 // Promote the fiber to a class and try rendering again.
7385 workInProgress.tag = ClassComponent;
7386
7387 // The rest of this function is a fork of `updateClassComponent`
7388
7389 // Push context providers early to prevent context stack mismatches.
7390 // During mounting we don't know the child context yet as the instance doesn't exist.
7391 // We will invalidate the child context in finishClassComponent() right after rendering.
7392 var hasContext = void 0;
7393 if (isContextProvider(Component)) {
7394 hasContext = true;
7395 pushContextProvider(workInProgress);
7396 } else {
7397 hasContext = false;
7398 }
7399 prepareToReadContext(workInProgress, renderExpirationTime);
7400
7401 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7402 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7403
7404 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
7405}
7406
7407function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
7408 if (_current !== null) {
7409 // An indeterminate component only mounts if it suspended inside a non-
7410 // concurrent tree, in an inconsistent state. We want to treat it like
7411 // a new mount, even though an empty version of it already committed.
7412 // Disconnect the alternate pointers.
7413 _current.alternate = null;
7414 workInProgress.alternate = null;
7415 // Since this is conceptually a new fiber, schedule a Placement effect
7416 workInProgress.effectTag |= Placement;
7417 }
7418
7419 var props = workInProgress.pendingProps;
7420 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
7421 var context = getMaskedContext(workInProgress, unmaskedContext);
7422
7423 prepareToReadContext(workInProgress, renderExpirationTime);
7424
7425 var value = void 0;
7426
7427 {
7428 if (Component.prototype && typeof Component.prototype.render === 'function') {
7429 var componentName = getComponentName(Component) || 'Unknown';
7430
7431 if (!didWarnAboutBadClass[componentName]) {
7432 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);
7433 didWarnAboutBadClass[componentName] = true;
7434 }
7435 }
7436
7437 if (workInProgress.mode & StrictMode) {
7438 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
7439 }
7440
7441 ReactCurrentOwner$2.current = workInProgress;
7442 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
7443 }
7444 // React DevTools reads this flag.
7445 workInProgress.effectTag |= PerformedWork;
7446
7447 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
7448 // Proceed under the assumption that this is a class instance
7449 workInProgress.tag = ClassComponent;
7450
7451 // Throw out any hooks that were used.
7452 resetHooks();
7453
7454 // Push context providers early to prevent context stack mismatches.
7455 // During mounting we don't know the child context yet as the instance doesn't exist.
7456 // We will invalidate the child context in finishClassComponent() right after rendering.
7457 var hasContext = false;
7458 if (isContextProvider(Component)) {
7459 hasContext = true;
7460 pushContextProvider(workInProgress);
7461 } else {
7462 hasContext = false;
7463 }
7464
7465 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
7466
7467 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
7468 if (typeof getDerivedStateFromProps === 'function') {
7469 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
7470 }
7471
7472 adoptClassInstance(workInProgress, value);
7473 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
7474 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
7475 } else {
7476 // Proceed under the assumption that this is a function component
7477 workInProgress.tag = FunctionComponent;
7478 {
7479 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7480 // Only double-render components with Hooks
7481 if (workInProgress.memoizedState !== null) {
7482 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
7483 }
7484 }
7485 }
7486 reconcileChildren(null, workInProgress, value, renderExpirationTime);
7487 {
7488 validateFunctionComponentInDev(workInProgress, Component);
7489 }
7490 return workInProgress.child;
7491 }
7492}
7493
7494function validateFunctionComponentInDev(workInProgress, Component) {
7495 if (Component) {
7496 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0;
7497 }
7498 if (workInProgress.ref !== null) {
7499 var info = '';
7500 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
7501 if (ownerName) {
7502 info += '\n\nCheck the render method of `' + ownerName + '`.';
7503 }
7504
7505 var warningKey = ownerName || workInProgress._debugID || '';
7506 var debugSource = workInProgress._debugSource;
7507 if (debugSource) {
7508 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
7509 }
7510 if (!didWarnAboutFunctionRefs[warningKey]) {
7511 didWarnAboutFunctionRefs[warningKey] = true;
7512 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);
7513 }
7514 }
7515
7516 if (typeof Component.getDerivedStateFromProps === 'function') {
7517 var componentName = getComponentName(Component) || 'Unknown';
7518
7519 if (!didWarnAboutGetDerivedStateOnFunctionComponent[componentName]) {
7520 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', componentName);
7521 didWarnAboutGetDerivedStateOnFunctionComponent[componentName] = true;
7522 }
7523 }
7524
7525 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
7526 var _componentName = getComponentName(Component) || 'Unknown';
7527
7528 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName]) {
7529 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName);
7530 didWarnAboutContextTypeOnFunctionComponent[_componentName] = true;
7531 }
7532 }
7533}
7534
7535function updateSuspenseComponent(current, workInProgress, renderExpirationTime) {
7536 var mode = workInProgress.mode;
7537 var nextProps = workInProgress.pendingProps;
7538
7539 // We should attempt to render the primary children unless this boundary
7540 // already suspended during this render (`alreadyCaptured` is true).
7541 var nextState = workInProgress.memoizedState;
7542
7543 var nextDidTimeout = void 0;
7544 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
7545 // This is the first attempt.
7546 nextState = null;
7547 nextDidTimeout = false;
7548 } else {
7549 // Something in this boundary's subtree already suspended. Switch to
7550 // rendering the fallback children.
7551 nextState = {
7552 timedOutAt: nextState !== null ? nextState.timedOutAt : NoWork
7553 };
7554 nextDidTimeout = true;
7555 workInProgress.effectTag &= ~DidCapture;
7556 }
7557
7558 // This next part is a bit confusing. If the children timeout, we switch to
7559 // showing the fallback children in place of the "primary" children.
7560 // However, we don't want to delete the primary children because then their
7561 // state will be lost (both the React state and the host state, e.g.
7562 // uncontrolled form inputs). Instead we keep them mounted and hide them.
7563 // Both the fallback children AND the primary children are rendered at the
7564 // same time. Once the primary children are un-suspended, we can delete
7565 // the fallback children — don't need to preserve their state.
7566 //
7567 // The two sets of children are siblings in the host environment, but
7568 // semantically, for purposes of reconciliation, they are two separate sets.
7569 // So we store them using two fragment fibers.
7570 //
7571 // However, we want to avoid allocating extra fibers for every placeholder.
7572 // They're only necessary when the children time out, because that's the
7573 // only time when both sets are mounted.
7574 //
7575 // So, the extra fragment fibers are only used if the children time out.
7576 // Otherwise, we render the primary children directly. This requires some
7577 // custom reconciliation logic to preserve the state of the primary
7578 // children. It's essentially a very basic form of re-parenting.
7579
7580 // `child` points to the child fiber. In the normal case, this is the first
7581 // fiber of the primary children set. In the timed-out case, it's a
7582 // a fragment fiber containing the primary children.
7583 var child = void 0;
7584 // `next` points to the next fiber React should render. In the normal case,
7585 // it's the same as `child`: the first fiber of the primary children set.
7586 // In the timed-out case, it's a fragment fiber containing the *fallback*
7587 // children -- we skip over the primary children entirely.
7588 var next = void 0;
7589 if (current === null) {
7590 if (enableSuspenseServerRenderer) {
7591 // If we're currently hydrating, try to hydrate this boundary.
7592 // But only if this has a fallback.
7593 if (nextProps.fallback !== undefined) {
7594 tryToClaimNextHydratableInstance(workInProgress);
7595 // This could've changed the tag if this was a dehydrated suspense component.
7596 if (workInProgress.tag === DehydratedSuspenseComponent) {
7597 return updateDehydratedSuspenseComponent(null, workInProgress, renderExpirationTime);
7598 }
7599 }
7600 }
7601
7602 // This is the initial mount. This branch is pretty simple because there's
7603 // no previous state that needs to be preserved.
7604 if (nextDidTimeout) {
7605 // Mount separate fragments for primary and fallback children.
7606 var nextFallbackChildren = nextProps.fallback;
7607 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
7608
7609 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
7610 // Outside of concurrent mode, we commit the effects from the
7611 var progressedState = workInProgress.memoizedState;
7612 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
7613 primaryChildFragment.child = progressedPrimaryChild;
7614 }
7615
7616 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
7617 primaryChildFragment.sibling = fallbackChildFragment;
7618 child = primaryChildFragment;
7619 // Skip the primary children, and continue working on the
7620 // fallback children.
7621 next = fallbackChildFragment;
7622 child.return = next.return = workInProgress;
7623 } else {
7624 // Mount the primary children without an intermediate fragment fiber.
7625 var nextPrimaryChildren = nextProps.children;
7626 child = next = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
7627 }
7628 } else {
7629 // This is an update. This branch is more complicated because we need to
7630 // ensure the state of the primary children is preserved.
7631 var prevState = current.memoizedState;
7632 var prevDidTimeout = prevState !== null;
7633 if (prevDidTimeout) {
7634 // The current tree already timed out. That means each child set is
7635 var currentPrimaryChildFragment = current.child;
7636 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
7637 if (nextDidTimeout) {
7638 // Still timed out. Reuse the current primary children by cloning
7639 // its fragment. We're going to skip over these entirely.
7640 var _nextFallbackChildren = nextProps.fallback;
7641 var _primaryChildFragment = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork);
7642
7643 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
7644 // Outside of concurrent mode, we commit the effects from the
7645 var _progressedState = workInProgress.memoizedState;
7646 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
7647 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
7648 _primaryChildFragment.child = _progressedPrimaryChild;
7649 }
7650 }
7651
7652 // Because primaryChildFragment is a new fiber that we're inserting as the
7653 // parent of a new tree, we need to set its treeBaseDuration.
7654 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
7655 // treeBaseDuration is the sum of all the child tree base durations.
7656 var treeBaseDuration = 0;
7657 var hiddenChild = _primaryChildFragment.child;
7658 while (hiddenChild !== null) {
7659 treeBaseDuration += hiddenChild.treeBaseDuration;
7660 hiddenChild = hiddenChild.sibling;
7661 }
7662 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
7663 }
7664
7665 // Clone the fallback child fragment, too. These we'll continue
7666 // working on.
7667 var _fallbackChildFragment = _primaryChildFragment.sibling = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime);
7668 child = _primaryChildFragment;
7669 _primaryChildFragment.childExpirationTime = NoWork;
7670 // Skip the primary children, and continue working on the
7671 // fallback children.
7672 next = _fallbackChildFragment;
7673 child.return = next.return = workInProgress;
7674 } else {
7675 // No longer suspended. Switch back to showing the primary children,
7676 // and remove the intermediate fragment fiber.
7677 var _nextPrimaryChildren = nextProps.children;
7678 var currentPrimaryChild = currentPrimaryChildFragment.child;
7679 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime);
7680
7681 // If this render doesn't suspend, we need to delete the fallback
7682 // children. Wait until the complete phase, after we've confirmed the
7683 // fallback is no longer needed.
7684 // TODO: Would it be better to store the fallback fragment on
7685 // the stateNode?
7686
7687 // Continue rendering the children, like we normally do.
7688 child = next = primaryChild;
7689 }
7690 } else {
7691 // The current tree has not already timed out. That means the primary
7692 // children are not wrapped in a fragment fiber.
7693 var _currentPrimaryChild = current.child;
7694 if (nextDidTimeout) {
7695 // Timed out. Wrap the children in a fragment fiber to keep them
7696 // separate from the fallback children.
7697 var _nextFallbackChildren2 = nextProps.fallback;
7698 var _primaryChildFragment2 = createFiberFromFragment(
7699 // It shouldn't matter what the pending props are because we aren't
7700 // going to render this fragment.
7701 null, mode, NoWork, null);
7702 _primaryChildFragment2.child = _currentPrimaryChild;
7703
7704 // Even though we're creating a new fiber, there are no new children,
7705 // because we're reusing an already mounted tree. So we don't need to
7706 // schedule a placement.
7707 // primaryChildFragment.effectTag |= Placement;
7708
7709 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
7710 // Outside of concurrent mode, we commit the effects from the
7711 var _progressedState2 = workInProgress.memoizedState;
7712 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
7713 _primaryChildFragment2.child = _progressedPrimaryChild2;
7714 }
7715
7716 // Because primaryChildFragment is a new fiber that we're inserting as the
7717 // parent of a new tree, we need to set its treeBaseDuration.
7718 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
7719 // treeBaseDuration is the sum of all the child tree base durations.
7720 var _treeBaseDuration = 0;
7721 var _hiddenChild = _primaryChildFragment2.child;
7722 while (_hiddenChild !== null) {
7723 _treeBaseDuration += _hiddenChild.treeBaseDuration;
7724 _hiddenChild = _hiddenChild.sibling;
7725 }
7726 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
7727 }
7728
7729 // Create a fragment from the fallback children, too.
7730 var _fallbackChildFragment2 = _primaryChildFragment2.sibling = createFiberFromFragment(_nextFallbackChildren2, mode, renderExpirationTime, null);
7731 _fallbackChildFragment2.effectTag |= Placement;
7732 child = _primaryChildFragment2;
7733 _primaryChildFragment2.childExpirationTime = NoWork;
7734 // Skip the primary children, and continue working on the
7735 // fallback children.
7736 next = _fallbackChildFragment2;
7737 child.return = next.return = workInProgress;
7738 } else {
7739 // Still haven't timed out. Continue rendering the children, like we
7740 // normally do.
7741 var _nextPrimaryChildren2 = nextProps.children;
7742 next = child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
7743 }
7744 }
7745 workInProgress.stateNode = current.stateNode;
7746 }
7747
7748 workInProgress.memoizedState = nextState;
7749 workInProgress.child = child;
7750 return next;
7751}
7752
7753function updateDehydratedSuspenseComponent(current, workInProgress, renderExpirationTime) {
7754 if (current === null) {
7755 // During the first pass, we'll bail out and not drill into the children.
7756 // Instead, we'll leave the content in place and try to hydrate it later.
7757 workInProgress.expirationTime = Never;
7758 return null;
7759 }
7760 // We use childExpirationTime to indicate that a child might depend on context, so if
7761 // any context has changed, we need to treat is as if the input might have changed.
7762 var hasContextChanged$$1 = current.childExpirationTime >= renderExpirationTime;
7763 if (didReceiveUpdate || hasContextChanged$$1) {
7764 // This boundary has changed since the first render. This means that we are now unable to
7765 // hydrate it. We might still be able to hydrate it using an earlier expiration time but
7766 // during this render we can't. Instead, we're going to delete the whole subtree and
7767 // instead inject a new real Suspense boundary to take its place, which may render content
7768 // or fallback. The real Suspense boundary will suspend for a while so we have some time
7769 // to ensure it can produce real content, but all state and pending events will be lost.
7770
7771 // Detach from the current dehydrated boundary.
7772 current.alternate = null;
7773 workInProgress.alternate = null;
7774
7775 // Insert a deletion in the effect list.
7776 var returnFiber = workInProgress.return;
7777 !(returnFiber !== null) ? invariant(false, 'Suspense boundaries are never on the root. This is probably a bug in React.') : void 0;
7778 var last = returnFiber.lastEffect;
7779 if (last !== null) {
7780 last.nextEffect = current;
7781 returnFiber.lastEffect = current;
7782 } else {
7783 returnFiber.firstEffect = returnFiber.lastEffect = current;
7784 }
7785 current.nextEffect = null;
7786 current.effectTag = Deletion;
7787
7788 // Upgrade this work in progress to a real Suspense component.
7789 workInProgress.tag = SuspenseComponent;
7790 workInProgress.stateNode = null;
7791 workInProgress.memoizedState = null;
7792 // This is now an insertion.
7793 workInProgress.effectTag |= Placement;
7794 // Retry as a real Suspense component.
7795 return updateSuspenseComponent(null, workInProgress, renderExpirationTime);
7796 }
7797 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
7798 // This is the first attempt.
7799 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress);
7800 var nextProps = workInProgress.pendingProps;
7801 var nextChildren = nextProps.children;
7802 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7803 return workInProgress.child;
7804 } else {
7805 // Something suspended. Leave the existing children in place.
7806 // TODO: In non-concurrent mode, should we commit the nodes we have hydrated so far?
7807 workInProgress.child = null;
7808 return null;
7809 }
7810}
7811
7812function updatePortalComponent(current, workInProgress, renderExpirationTime) {
7813 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
7814 var nextChildren = workInProgress.pendingProps;
7815 if (current === null) {
7816 // Portals are special because we don't append the children during mount
7817 // but at commit. Therefore we need to track insertions which the normal
7818 // flow doesn't do during mount. This doesn't happen at the root because
7819 // the root always starts with a "current" with a null child.
7820 // TODO: Consider unifying this with how the root works.
7821 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7822 } else {
7823 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7824 }
7825 return workInProgress.child;
7826}
7827
7828function updateContextProvider(current, workInProgress, renderExpirationTime) {
7829 var providerType = workInProgress.type;
7830 var context = providerType._context;
7831
7832 var newProps = workInProgress.pendingProps;
7833 var oldProps = workInProgress.memoizedProps;
7834
7835 var newValue = newProps.value;
7836
7837 {
7838 var providerPropTypes = workInProgress.type.propTypes;
7839
7840 if (providerPropTypes) {
7841 checkPropTypes_1(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
7842 }
7843 }
7844
7845 pushProvider(workInProgress, newValue);
7846
7847 if (oldProps !== null) {
7848 var oldValue = oldProps.value;
7849 var changedBits = calculateChangedBits(context, newValue, oldValue);
7850 if (changedBits === 0) {
7851 // No change. Bailout early if children are the same.
7852 if (oldProps.children === newProps.children && !hasContextChanged()) {
7853 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7854 }
7855 } else {
7856 // The context value changed. Search for matching consumers and schedule
7857 // them to update.
7858 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
7859 }
7860 }
7861
7862 var newChildren = newProps.children;
7863 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
7864 return workInProgress.child;
7865}
7866
7867var hasWarnedAboutUsingContextAsConsumer = false;
7868
7869function updateContextConsumer(current, workInProgress, renderExpirationTime) {
7870 var context = workInProgress.type;
7871 // The logic below for Context differs depending on PROD or DEV mode. In
7872 // DEV mode, we create a separate object for Context.Consumer that acts
7873 // like a proxy to Context. This proxy object adds unnecessary code in PROD
7874 // so we use the old behaviour (Context.Consumer references Context) to
7875 // reduce size and overhead. The separate object references context via
7876 // a property called "_context", which also gives us the ability to check
7877 // in DEV mode if this property exists or not and warn if it does not.
7878 {
7879 if (context._context === undefined) {
7880 // This may be because it's a Context (rather than a Consumer).
7881 // Or it may be because it's older React where they're the same thing.
7882 // We only want to warn if we're sure it's a new React.
7883 if (context !== context.Consumer) {
7884 if (!hasWarnedAboutUsingContextAsConsumer) {
7885 hasWarnedAboutUsingContextAsConsumer = true;
7886 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?');
7887 }
7888 }
7889 } else {
7890 context = context._context;
7891 }
7892 }
7893 var newProps = workInProgress.pendingProps;
7894 var render = newProps.children;
7895
7896 {
7897 !(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;
7898 }
7899
7900 prepareToReadContext(workInProgress, renderExpirationTime);
7901 var newValue = readContext(context, newProps.unstable_observedBits);
7902 var newChildren = void 0;
7903 {
7904 ReactCurrentOwner$2.current = workInProgress;
7905 setCurrentPhase('render');
7906 newChildren = render(newValue);
7907 setCurrentPhase(null);
7908 }
7909
7910 // React DevTools reads this flag.
7911 workInProgress.effectTag |= PerformedWork;
7912 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
7913 return workInProgress.child;
7914}
7915
7916function markWorkInProgressReceivedUpdate() {
7917 didReceiveUpdate = true;
7918}
7919
7920function bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime) {
7921 cancelWorkTimer(workInProgress);
7922
7923 if (current !== null) {
7924 // Reuse previous context list
7925 workInProgress.contextDependencies = current.contextDependencies;
7926 }
7927
7928 if (enableProfilerTimer) {
7929 // Don't update "base" render times for bailouts.
7930 stopProfilerTimerIfRunning(workInProgress);
7931 }
7932
7933 // Check if the children have any pending work.
7934 var childExpirationTime = workInProgress.childExpirationTime;
7935 if (childExpirationTime < renderExpirationTime) {
7936 // The children don't have any work either. We can skip them.
7937 // TODO: Once we add back resuming, we should check if the children are
7938 // a work-in-progress set. If so, we need to transfer their effects.
7939 return null;
7940 } else {
7941 // This fiber doesn't have work, but its subtree does. Clone the child
7942 // fibers and continue.
7943 cloneChildFibers(current, workInProgress);
7944 return workInProgress.child;
7945 }
7946}
7947
7948function beginWork(current, workInProgress, renderExpirationTime) {
7949 var updateExpirationTime = workInProgress.expirationTime;
7950
7951 if (current !== null) {
7952 var oldProps = current.memoizedProps;
7953 var newProps = workInProgress.pendingProps;
7954
7955 if (oldProps !== newProps || hasContextChanged()) {
7956 // If props or context changed, mark the fiber as having performed work.
7957 // This may be unset if the props are determined to be equal later (memo).
7958 didReceiveUpdate = true;
7959 } else if (updateExpirationTime < renderExpirationTime) {
7960 didReceiveUpdate = false;
7961 // This fiber does not have any pending work. Bailout without entering
7962 // the begin phase. There's still some bookkeeping we that needs to be done
7963 // in this optimized path, mostly pushing stuff onto the stack.
7964 switch (workInProgress.tag) {
7965 case HostRoot:
7966 pushHostRootContext(workInProgress);
7967 resetHydrationState();
7968 break;
7969 case HostComponent:
7970 pushHostContext(workInProgress);
7971 break;
7972 case ClassComponent:
7973 {
7974 var Component = workInProgress.type;
7975 if (isContextProvider(Component)) {
7976 pushContextProvider(workInProgress);
7977 }
7978 break;
7979 }
7980 case HostPortal:
7981 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
7982 break;
7983 case ContextProvider:
7984 {
7985 var newValue = workInProgress.memoizedProps.value;
7986 pushProvider(workInProgress, newValue);
7987 break;
7988 }
7989 case Profiler:
7990 if (enableProfilerTimer) {
7991 workInProgress.effectTag |= Update;
7992 }
7993 break;
7994 case SuspenseComponent:
7995 {
7996 var state = workInProgress.memoizedState;
7997 var didTimeout = state !== null;
7998 if (didTimeout) {
7999 // If this boundary is currently timed out, we need to decide
8000 // whether to retry the primary children, or to skip over it and
8001 // go straight to the fallback. Check the priority of the primary
8002 var primaryChildFragment = workInProgress.child;
8003 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
8004 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
8005 // The primary children have pending work. Use the normal path
8006 // to attempt to render the primary children again.
8007 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
8008 } else {
8009 // The primary children do not have pending work with sufficient
8010 // priority. Bailout.
8011 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8012 if (child !== null) {
8013 // The fallback children have pending work. Skip over the
8014 // primary children and work on the fallback.
8015 return child.sibling;
8016 } else {
8017 return null;
8018 }
8019 }
8020 }
8021 break;
8022 }
8023 case DehydratedSuspenseComponent:
8024 {
8025 if (enableSuspenseServerRenderer) {
8026 // We know that this component will suspend again because if it has
8027 // been unsuspended it has committed as a regular Suspense component.
8028 // If it needs to be retried, it should have work scheduled on it.
8029 workInProgress.effectTag |= DidCapture;
8030 break;
8031 }
8032 }
8033 }
8034 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8035 }
8036 } else {
8037 didReceiveUpdate = false;
8038 }
8039
8040 // Before entering the begin phase, clear the expiration time.
8041 workInProgress.expirationTime = NoWork;
8042
8043 switch (workInProgress.tag) {
8044 case IndeterminateComponent:
8045 {
8046 var elementType = workInProgress.elementType;
8047 return mountIndeterminateComponent(current, workInProgress, elementType, renderExpirationTime);
8048 }
8049 case LazyComponent:
8050 {
8051 var _elementType = workInProgress.elementType;
8052 return mountLazyComponent(current, workInProgress, _elementType, updateExpirationTime, renderExpirationTime);
8053 }
8054 case FunctionComponent:
8055 {
8056 var _Component = workInProgress.type;
8057 var unresolvedProps = workInProgress.pendingProps;
8058 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
8059 return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderExpirationTime);
8060 }
8061 case ClassComponent:
8062 {
8063 var _Component2 = workInProgress.type;
8064 var _unresolvedProps = workInProgress.pendingProps;
8065 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
8066 return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
8067 }
8068 case HostRoot:
8069 return updateHostRoot(current, workInProgress, renderExpirationTime);
8070 case HostComponent:
8071 return updateHostComponent(current, workInProgress, renderExpirationTime);
8072 case HostText:
8073 return updateHostText(current, workInProgress);
8074 case SuspenseComponent:
8075 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
8076 case HostPortal:
8077 return updatePortalComponent(current, workInProgress, renderExpirationTime);
8078 case ForwardRef:
8079 {
8080 var type = workInProgress.type;
8081 var _unresolvedProps2 = workInProgress.pendingProps;
8082 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
8083 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderExpirationTime);
8084 }
8085 case Fragment:
8086 return updateFragment(current, workInProgress, renderExpirationTime);
8087 case Mode:
8088 return updateMode(current, workInProgress, renderExpirationTime);
8089 case Profiler:
8090 return updateProfiler(current, workInProgress, renderExpirationTime);
8091 case ContextProvider:
8092 return updateContextProvider(current, workInProgress, renderExpirationTime);
8093 case ContextConsumer:
8094 return updateContextConsumer(current, workInProgress, renderExpirationTime);
8095 case MemoComponent:
8096 {
8097 var _type2 = workInProgress.type;
8098 var _unresolvedProps3 = workInProgress.pendingProps;
8099 // Resolve outer props first, then resolve inner props.
8100 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
8101 {
8102 if (workInProgress.type !== workInProgress.elementType) {
8103 var outerPropTypes = _type2.propTypes;
8104 if (outerPropTypes) {
8105 checkPropTypes_1(outerPropTypes, _resolvedProps3, // Resolved for outer only
8106 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
8107 }
8108 }
8109 }
8110 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
8111 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
8112 }
8113 case SimpleMemoComponent:
8114 {
8115 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
8116 }
8117 case IncompleteClassComponent:
8118 {
8119 var _Component3 = workInProgress.type;
8120 var _unresolvedProps4 = workInProgress.pendingProps;
8121 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
8122 return mountIncompleteClassComponent(current, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
8123 }
8124 case DehydratedSuspenseComponent:
8125 {
8126 if (enableSuspenseServerRenderer) {
8127 return updateDehydratedSuspenseComponent(current, workInProgress, renderExpirationTime);
8128 }
8129 break;
8130 }
8131 }
8132 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
8133}
8134
8135var valueCursor = createCursor(null);
8136
8137var rendererSigil = void 0;
8138{
8139 // Use this to detect multiple renderers using the same context
8140 rendererSigil = {};
8141}
8142
8143var currentlyRenderingFiber = null;
8144var lastContextDependency = null;
8145var lastContextWithAllBitsObserved = null;
8146
8147var isDisallowedContextReadInDEV = false;
8148
8149function resetContextDependences() {
8150 // This is called right before React yields execution, to ensure `readContext`
8151 // cannot be called outside the render phase.
8152 currentlyRenderingFiber = null;
8153 lastContextDependency = null;
8154 lastContextWithAllBitsObserved = null;
8155 {
8156 isDisallowedContextReadInDEV = false;
8157 }
8158}
8159
8160function enterDisallowedContextReadInDEV() {
8161 {
8162 isDisallowedContextReadInDEV = true;
8163 }
8164}
8165
8166function exitDisallowedContextReadInDEV() {
8167 {
8168 isDisallowedContextReadInDEV = false;
8169 }
8170}
8171
8172function pushProvider(providerFiber, nextValue) {
8173 var context = providerFiber.type._context;
8174
8175 if (isPrimaryRenderer) {
8176 push(valueCursor, context._currentValue, providerFiber);
8177
8178 context._currentValue = nextValue;
8179 {
8180 !(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;
8181 context._currentRenderer = rendererSigil;
8182 }
8183 } else {
8184 push(valueCursor, context._currentValue2, providerFiber);
8185
8186 context._currentValue2 = nextValue;
8187 {
8188 !(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;
8189 context._currentRenderer2 = rendererSigil;
8190 }
8191 }
8192}
8193
8194function popProvider(providerFiber) {
8195 var currentValue = valueCursor.current;
8196
8197 pop(valueCursor, providerFiber);
8198
8199 var context = providerFiber.type._context;
8200 if (isPrimaryRenderer) {
8201 context._currentValue = currentValue;
8202 } else {
8203 context._currentValue2 = currentValue;
8204 }
8205}
8206
8207function calculateChangedBits(context, newValue, oldValue) {
8208 if (is(oldValue, newValue)) {
8209 // No change
8210 return 0;
8211 } else {
8212 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : maxSigned31BitInt;
8213
8214 {
8215 !((changedBits & maxSigned31BitInt) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0;
8216 }
8217 return changedBits | 0;
8218 }
8219}
8220
8221function scheduleWorkOnParentPath(parent, renderExpirationTime) {
8222 // Update the child expiration time of all the ancestors, including
8223 // the alternates.
8224 var node = parent;
8225 while (node !== null) {
8226 var alternate = node.alternate;
8227 if (node.childExpirationTime < renderExpirationTime) {
8228 node.childExpirationTime = renderExpirationTime;
8229 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
8230 alternate.childExpirationTime = renderExpirationTime;
8231 }
8232 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
8233 alternate.childExpirationTime = renderExpirationTime;
8234 } else {
8235 // Neither alternate was updated, which means the rest of the
8236 // ancestor path already has sufficient priority.
8237 break;
8238 }
8239 node = node.return;
8240 }
8241}
8242
8243function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
8244 var fiber = workInProgress.child;
8245 if (fiber !== null) {
8246 // Set the return pointer of the child to the work-in-progress fiber.
8247 fiber.return = workInProgress;
8248 }
8249 while (fiber !== null) {
8250 var nextFiber = void 0;
8251
8252 // Visit this fiber.
8253 var list = fiber.contextDependencies;
8254 if (list !== null) {
8255 nextFiber = fiber.child;
8256
8257 var dependency = list.first;
8258 while (dependency !== null) {
8259 // Check if the context matches.
8260 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
8261 // Match! Schedule an update on this fiber.
8262
8263 if (fiber.tag === ClassComponent) {
8264 // Schedule a force update on the work-in-progress.
8265 var update = createUpdate(renderExpirationTime);
8266 update.tag = ForceUpdate;
8267 // TODO: Because we don't have a work-in-progress, this will add the
8268 // update to the current fiber, too, which means it will persist even if
8269 // this render is thrown away. Since it's a race condition, not sure it's
8270 // worth fixing.
8271 enqueueUpdate(fiber, update);
8272 }
8273
8274 if (fiber.expirationTime < renderExpirationTime) {
8275 fiber.expirationTime = renderExpirationTime;
8276 }
8277 var alternate = fiber.alternate;
8278 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
8279 alternate.expirationTime = renderExpirationTime;
8280 }
8281
8282 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
8283
8284 // Mark the expiration time on the list, too.
8285 if (list.expirationTime < renderExpirationTime) {
8286 list.expirationTime = renderExpirationTime;
8287 }
8288
8289 // Since we already found a match, we can stop traversing the
8290 // dependency list.
8291 break;
8292 }
8293 dependency = dependency.next;
8294 }
8295 } else if (fiber.tag === ContextProvider) {
8296 // Don't scan deeper if this is a matching provider
8297 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
8298 } else if (enableSuspenseServerRenderer && fiber.tag === DehydratedSuspenseComponent) {
8299 // If a dehydrated suspense component is in this subtree, we don't know
8300 // if it will have any context consumers in it. The best we can do is
8301 // mark it as having updates on its children.
8302 if (fiber.expirationTime < renderExpirationTime) {
8303 fiber.expirationTime = renderExpirationTime;
8304 }
8305 var _alternate = fiber.alternate;
8306 if (_alternate !== null && _alternate.expirationTime < renderExpirationTime) {
8307 _alternate.expirationTime = renderExpirationTime;
8308 }
8309 // This is intentionally passing this fiber as the parent
8310 // because we want to schedule this fiber as having work
8311 // on its children. We'll use the childExpirationTime on
8312 // this fiber to indicate that a context has changed.
8313 scheduleWorkOnParentPath(fiber, renderExpirationTime);
8314 nextFiber = fiber.sibling;
8315 } else {
8316 // Traverse down.
8317 nextFiber = fiber.child;
8318 }
8319
8320 if (nextFiber !== null) {
8321 // Set the return pointer of the child to the work-in-progress fiber.
8322 nextFiber.return = fiber;
8323 } else {
8324 // No child. Traverse to next sibling.
8325 nextFiber = fiber;
8326 while (nextFiber !== null) {
8327 if (nextFiber === workInProgress) {
8328 // We're back to the root of this subtree. Exit.
8329 nextFiber = null;
8330 break;
8331 }
8332 var sibling = nextFiber.sibling;
8333 if (sibling !== null) {
8334 // Set the return pointer of the sibling to the work-in-progress fiber.
8335 sibling.return = nextFiber.return;
8336 nextFiber = sibling;
8337 break;
8338 }
8339 // No more siblings. Traverse up.
8340 nextFiber = nextFiber.return;
8341 }
8342 }
8343 fiber = nextFiber;
8344 }
8345}
8346
8347function prepareToReadContext(workInProgress, renderExpirationTime) {
8348 currentlyRenderingFiber = workInProgress;
8349 lastContextDependency = null;
8350 lastContextWithAllBitsObserved = null;
8351
8352 var currentDependencies = workInProgress.contextDependencies;
8353 if (currentDependencies !== null && currentDependencies.expirationTime >= renderExpirationTime) {
8354 // Context list has a pending update. Mark that this fiber performed work.
8355 markWorkInProgressReceivedUpdate();
8356 }
8357
8358 // Reset the work-in-progress list
8359 workInProgress.contextDependencies = null;
8360}
8361
8362function readContext(context, observedBits) {
8363 {
8364 // This warning would fire if you read context inside a Hook like useMemo.
8365 // Unlike the class check below, it's not enforced in production for perf.
8366 !!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;
8367 }
8368
8369 if (lastContextWithAllBitsObserved === context) {
8370 // Nothing to do. We already observe everything in this context.
8371 } else if (observedBits === false || observedBits === 0) {
8372 // Do not observe any updates.
8373 } else {
8374 var resolvedObservedBits = void 0; // Avoid deopting on observable arguments or heterogeneous types.
8375 if (typeof observedBits !== 'number' || observedBits === maxSigned31BitInt) {
8376 // Observe all updates.
8377 lastContextWithAllBitsObserved = context;
8378 resolvedObservedBits = maxSigned31BitInt;
8379 } else {
8380 resolvedObservedBits = observedBits;
8381 }
8382
8383 var contextItem = {
8384 context: context,
8385 observedBits: resolvedObservedBits,
8386 next: null
8387 };
8388
8389 if (lastContextDependency === null) {
8390 !(currentlyRenderingFiber !== null) ? invariant(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;
8391
8392 // This is the first dependency for this component. Create a new list.
8393 lastContextDependency = contextItem;
8394 currentlyRenderingFiber.contextDependencies = {
8395 first: contextItem,
8396 expirationTime: NoWork
8397 };
8398 } else {
8399 // Append a new context item.
8400 lastContextDependency = lastContextDependency.next = contextItem;
8401 }
8402 }
8403 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
8404}
8405
8406// UpdateQueue is a linked list of prioritized updates.
8407//
8408// Like fibers, update queues come in pairs: a current queue, which represents
8409// the visible state of the screen, and a work-in-progress queue, which can be
8410// mutated and processed asynchronously before it is committed — a form of
8411// double buffering. If a work-in-progress render is discarded before finishing,
8412// we create a new work-in-progress by cloning the current queue.
8413//
8414// Both queues share a persistent, singly-linked list structure. To schedule an
8415// update, we append it to the end of both queues. Each queue maintains a
8416// pointer to first update in the persistent list that hasn't been processed.
8417// The work-in-progress pointer always has a position equal to or greater than
8418// the current queue, since we always work on that one. The current queue's
8419// pointer is only updated during the commit phase, when we swap in the
8420// work-in-progress.
8421//
8422// For example:
8423//
8424// Current pointer: A - B - C - D - E - F
8425// Work-in-progress pointer: D - E - F
8426// ^
8427// The work-in-progress queue has
8428// processed more updates than current.
8429//
8430// The reason we append to both queues is because otherwise we might drop
8431// updates without ever processing them. For example, if we only add updates to
8432// the work-in-progress queue, some updates could be lost whenever a work-in
8433// -progress render restarts by cloning from current. Similarly, if we only add
8434// updates to the current queue, the updates will be lost whenever an already
8435// in-progress queue commits and swaps with the current queue. However, by
8436// adding to both queues, we guarantee that the update will be part of the next
8437// work-in-progress. (And because the work-in-progress queue becomes the
8438// current queue once it commits, there's no danger of applying the same
8439// update twice.)
8440//
8441// Prioritization
8442// --------------
8443//
8444// Updates are not sorted by priority, but by insertion; new updates are always
8445// appended to the end of the list.
8446//
8447// The priority is still important, though. When processing the update queue
8448// during the render phase, only the updates with sufficient priority are
8449// included in the result. If we skip an update because it has insufficient
8450// priority, it remains in the queue to be processed later, during a lower
8451// priority render. Crucially, all updates subsequent to a skipped update also
8452// remain in the queue *regardless of their priority*. That means high priority
8453// updates are sometimes processed twice, at two separate priorities. We also
8454// keep track of a base state, that represents the state before the first
8455// update in the queue is applied.
8456//
8457// For example:
8458//
8459// Given a base state of '', and the following queue of updates
8460//
8461// A1 - B2 - C1 - D2
8462//
8463// where the number indicates the priority, and the update is applied to the
8464// previous state by appending a letter, React will process these updates as
8465// two separate renders, one per distinct priority level:
8466//
8467// First render, at priority 1:
8468// Base state: ''
8469// Updates: [A1, C1]
8470// Result state: 'AC'
8471//
8472// Second render, at priority 2:
8473// Base state: 'A' <- The base state does not include C1,
8474// because B2 was skipped.
8475// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
8476// Result state: 'ABCD'
8477//
8478// Because we process updates in insertion order, and rebase high priority
8479// updates when preceding updates are skipped, the final result is deterministic
8480// regardless of priority. Intermediate state may vary according to system
8481// resources, but the final state is always the same.
8482
8483var UpdateState = 0;
8484var ReplaceState = 1;
8485var ForceUpdate = 2;
8486var CaptureUpdate = 3;
8487
8488// Global state that is reset at the beginning of calling `processUpdateQueue`.
8489// It should only be read right after calling `processUpdateQueue`, via
8490// `checkHasForceUpdateAfterProcessing`.
8491var hasForceUpdate = false;
8492
8493var didWarnUpdateInsideUpdate = void 0;
8494var currentlyProcessingQueue = void 0;
8495var resetCurrentlyProcessingQueue = void 0;
8496{
8497 didWarnUpdateInsideUpdate = false;
8498 currentlyProcessingQueue = null;
8499 resetCurrentlyProcessingQueue = function () {
8500 currentlyProcessingQueue = null;
8501 };
8502}
8503
8504function createUpdateQueue(baseState) {
8505 var queue = {
8506 baseState: baseState,
8507 firstUpdate: null,
8508 lastUpdate: null,
8509 firstCapturedUpdate: null,
8510 lastCapturedUpdate: null,
8511 firstEffect: null,
8512 lastEffect: null,
8513 firstCapturedEffect: null,
8514 lastCapturedEffect: null
8515 };
8516 return queue;
8517}
8518
8519function cloneUpdateQueue(currentQueue) {
8520 var queue = {
8521 baseState: currentQueue.baseState,
8522 firstUpdate: currentQueue.firstUpdate,
8523 lastUpdate: currentQueue.lastUpdate,
8524
8525 // TODO: With resuming, if we bail out and resuse the child tree, we should
8526 // keep these effects.
8527 firstCapturedUpdate: null,
8528 lastCapturedUpdate: null,
8529
8530 firstEffect: null,
8531 lastEffect: null,
8532
8533 firstCapturedEffect: null,
8534 lastCapturedEffect: null
8535 };
8536 return queue;
8537}
8538
8539function createUpdate(expirationTime) {
8540 return {
8541 expirationTime: expirationTime,
8542
8543 tag: UpdateState,
8544 payload: null,
8545 callback: null,
8546
8547 next: null,
8548 nextEffect: null
8549 };
8550}
8551
8552function appendUpdateToQueue(queue, update) {
8553 // Append the update to the end of the list.
8554 if (queue.lastUpdate === null) {
8555 // Queue is empty
8556 queue.firstUpdate = queue.lastUpdate = update;
8557 } else {
8558 queue.lastUpdate.next = update;
8559 queue.lastUpdate = update;
8560 }
8561}
8562
8563function enqueueUpdate(fiber, update) {
8564 // Update queues are created lazily.
8565 var alternate = fiber.alternate;
8566 var queue1 = void 0;
8567 var queue2 = void 0;
8568 if (alternate === null) {
8569 // There's only one fiber.
8570 queue1 = fiber.updateQueue;
8571 queue2 = null;
8572 if (queue1 === null) {
8573 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
8574 }
8575 } else {
8576 // There are two owners.
8577 queue1 = fiber.updateQueue;
8578 queue2 = alternate.updateQueue;
8579 if (queue1 === null) {
8580 if (queue2 === null) {
8581 // Neither fiber has an update queue. Create new ones.
8582 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
8583 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState);
8584 } else {
8585 // Only one fiber has an update queue. Clone to create a new one.
8586 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
8587 }
8588 } else {
8589 if (queue2 === null) {
8590 // Only one fiber has an update queue. Clone to create a new one.
8591 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
8592 } else {
8593 // Both owners have an update queue.
8594 }
8595 }
8596 }
8597 if (queue2 === null || queue1 === queue2) {
8598 // There's only a single queue.
8599 appendUpdateToQueue(queue1, update);
8600 } else {
8601 // There are two queues. We need to append the update to both queues,
8602 // while accounting for the persistent structure of the list — we don't
8603 // want the same update to be added multiple times.
8604 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
8605 // One of the queues is not empty. We must add the update to both queues.
8606 appendUpdateToQueue(queue1, update);
8607 appendUpdateToQueue(queue2, update);
8608 } else {
8609 // Both queues are non-empty. The last update is the same in both lists,
8610 // because of structural sharing. So, only append to one of the lists.
8611 appendUpdateToQueue(queue1, update);
8612 // But we still need to update the `lastUpdate` pointer of queue2.
8613 queue2.lastUpdate = update;
8614 }
8615 }
8616
8617 {
8618 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) {
8619 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.');
8620 didWarnUpdateInsideUpdate = true;
8621 }
8622 }
8623}
8624
8625function enqueueCapturedUpdate(workInProgress, update) {
8626 // Captured updates go into a separate list, and only on the work-in-
8627 // progress queue.
8628 var workInProgressQueue = workInProgress.updateQueue;
8629 if (workInProgressQueue === null) {
8630 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState);
8631 } else {
8632 // TODO: I put this here rather than createWorkInProgress so that we don't
8633 // clone the queue unnecessarily. There's probably a better way to
8634 // structure this.
8635 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue);
8636 }
8637
8638 // Append the update to the end of the list.
8639 if (workInProgressQueue.lastCapturedUpdate === null) {
8640 // This is the first render phase update
8641 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
8642 } else {
8643 workInProgressQueue.lastCapturedUpdate.next = update;
8644 workInProgressQueue.lastCapturedUpdate = update;
8645 }
8646}
8647
8648function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
8649 var current = workInProgress.alternate;
8650 if (current !== null) {
8651 // If the work-in-progress queue is equal to the current queue,
8652 // we need to clone it first.
8653 if (queue === current.updateQueue) {
8654 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
8655 }
8656 }
8657 return queue;
8658}
8659
8660function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
8661 switch (update.tag) {
8662 case ReplaceState:
8663 {
8664 var _payload = update.payload;
8665 if (typeof _payload === 'function') {
8666 // Updater function
8667 {
8668 enterDisallowedContextReadInDEV();
8669 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8670 _payload.call(instance, prevState, nextProps);
8671 }
8672 }
8673 var nextState = _payload.call(instance, prevState, nextProps);
8674 {
8675 exitDisallowedContextReadInDEV();
8676 }
8677 return nextState;
8678 }
8679 // State object
8680 return _payload;
8681 }
8682 case CaptureUpdate:
8683 {
8684 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
8685 }
8686 // Intentional fallthrough
8687 case UpdateState:
8688 {
8689 var _payload2 = update.payload;
8690 var partialState = void 0;
8691 if (typeof _payload2 === 'function') {
8692 // Updater function
8693 {
8694 enterDisallowedContextReadInDEV();
8695 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8696 _payload2.call(instance, prevState, nextProps);
8697 }
8698 }
8699 partialState = _payload2.call(instance, prevState, nextProps);
8700 {
8701 exitDisallowedContextReadInDEV();
8702 }
8703 } else {
8704 // Partial state object
8705 partialState = _payload2;
8706 }
8707 if (partialState === null || partialState === undefined) {
8708 // Null and undefined are treated as no-ops.
8709 return prevState;
8710 }
8711 // Merge the partial state and the previous state.
8712 return _assign({}, prevState, partialState);
8713 }
8714 case ForceUpdate:
8715 {
8716 hasForceUpdate = true;
8717 return prevState;
8718 }
8719 }
8720 return prevState;
8721}
8722
8723function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) {
8724 hasForceUpdate = false;
8725
8726 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
8727
8728 {
8729 currentlyProcessingQueue = queue;
8730 }
8731
8732 // These values may change as we process the queue.
8733 var newBaseState = queue.baseState;
8734 var newFirstUpdate = null;
8735 var newExpirationTime = NoWork;
8736
8737 // Iterate through the list of updates to compute the result.
8738 var update = queue.firstUpdate;
8739 var resultState = newBaseState;
8740 while (update !== null) {
8741 var updateExpirationTime = update.expirationTime;
8742 if (updateExpirationTime < renderExpirationTime) {
8743 // This update does not have sufficient priority. Skip it.
8744 if (newFirstUpdate === null) {
8745 // This is the first skipped update. It will be the first update in
8746 // the new list.
8747 newFirstUpdate = update;
8748 // Since this is the first update that was skipped, the current result
8749 // is the new base state.
8750 newBaseState = resultState;
8751 }
8752 // Since this update will remain in the list, update the remaining
8753 // expiration time.
8754 if (newExpirationTime < updateExpirationTime) {
8755 newExpirationTime = updateExpirationTime;
8756 }
8757 } else {
8758 // This update does have sufficient priority. Process it and compute
8759 // a new result.
8760 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
8761 var _callback = update.callback;
8762 if (_callback !== null) {
8763 workInProgress.effectTag |= Callback;
8764 // Set this to null, in case it was mutated during an aborted render.
8765 update.nextEffect = null;
8766 if (queue.lastEffect === null) {
8767 queue.firstEffect = queue.lastEffect = update;
8768 } else {
8769 queue.lastEffect.nextEffect = update;
8770 queue.lastEffect = update;
8771 }
8772 }
8773 }
8774 // Continue to the next update.
8775 update = update.next;
8776 }
8777
8778 // Separately, iterate though the list of captured updates.
8779 var newFirstCapturedUpdate = null;
8780 update = queue.firstCapturedUpdate;
8781 while (update !== null) {
8782 var _updateExpirationTime = update.expirationTime;
8783 if (_updateExpirationTime < renderExpirationTime) {
8784 // This update does not have sufficient priority. Skip it.
8785 if (newFirstCapturedUpdate === null) {
8786 // This is the first skipped captured update. It will be the first
8787 // update in the new list.
8788 newFirstCapturedUpdate = update;
8789 // If this is the first update that was skipped, the current result is
8790 // the new base state.
8791 if (newFirstUpdate === null) {
8792 newBaseState = resultState;
8793 }
8794 }
8795 // Since this update will remain in the list, update the remaining
8796 // expiration time.
8797 if (newExpirationTime < _updateExpirationTime) {
8798 newExpirationTime = _updateExpirationTime;
8799 }
8800 } else {
8801 // This update does have sufficient priority. Process it and compute
8802 // a new result.
8803 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
8804 var _callback2 = update.callback;
8805 if (_callback2 !== null) {
8806 workInProgress.effectTag |= Callback;
8807 // Set this to null, in case it was mutated during an aborted render.
8808 update.nextEffect = null;
8809 if (queue.lastCapturedEffect === null) {
8810 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
8811 } else {
8812 queue.lastCapturedEffect.nextEffect = update;
8813 queue.lastCapturedEffect = update;
8814 }
8815 }
8816 }
8817 update = update.next;
8818 }
8819
8820 if (newFirstUpdate === null) {
8821 queue.lastUpdate = null;
8822 }
8823 if (newFirstCapturedUpdate === null) {
8824 queue.lastCapturedUpdate = null;
8825 } else {
8826 workInProgress.effectTag |= Callback;
8827 }
8828 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
8829 // We processed every update, without skipping. That means the new base
8830 // state is the same as the result state.
8831 newBaseState = resultState;
8832 }
8833
8834 queue.baseState = newBaseState;
8835 queue.firstUpdate = newFirstUpdate;
8836 queue.firstCapturedUpdate = newFirstCapturedUpdate;
8837
8838 // Set the remaining expiration time to be whatever is remaining in the queue.
8839 // This should be fine because the only two other things that contribute to
8840 // expiration time are props and context. We're already in the middle of the
8841 // begin phase by the time we start processing the queue, so we've already
8842 // dealt with the props. Context in components that specify
8843 // shouldComponentUpdate is tricky; but we'll have to account for
8844 // that regardless.
8845 workInProgress.expirationTime = newExpirationTime;
8846 workInProgress.memoizedState = resultState;
8847
8848 {
8849 currentlyProcessingQueue = null;
8850 }
8851}
8852
8853function callCallback(callback, context) {
8854 !(typeof callback === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', callback) : void 0;
8855 callback.call(context);
8856}
8857
8858function resetHasForceUpdateBeforeProcessing() {
8859 hasForceUpdate = false;
8860}
8861
8862function checkHasForceUpdateAfterProcessing() {
8863 return hasForceUpdate;
8864}
8865
8866function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) {
8867 // If the finished render included captured updates, and there are still
8868 // lower priority updates left over, we need to keep the captured updates
8869 // in the queue so that they are rebased and not dropped once we process the
8870 // queue again at the lower priority.
8871 if (finishedQueue.firstCapturedUpdate !== null) {
8872 // Join the captured update list to the end of the normal list.
8873 if (finishedQueue.lastUpdate !== null) {
8874 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
8875 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
8876 }
8877 // Clear the list of captured updates.
8878 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
8879 }
8880
8881 // Commit the effects
8882 commitUpdateEffects(finishedQueue.firstEffect, instance);
8883 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
8884
8885 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
8886 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
8887}
8888
8889function commitUpdateEffects(effect, instance) {
8890 while (effect !== null) {
8891 var _callback3 = effect.callback;
8892 if (_callback3 !== null) {
8893 effect.callback = null;
8894 callCallback(_callback3, instance);
8895 }
8896 effect = effect.nextEffect;
8897 }
8898}
8899
8900function createCapturedValue(value, source) {
8901 // If the value is an error, call this function immediately after it is thrown
8902 // so the stack is accurate.
8903 return {
8904 value: value,
8905 source: source,
8906 stack: getStackByFiberInDevAndProd(source)
8907 };
8908}
8909
8910function markUpdate(workInProgress) {
8911 // Tag the fiber with an update effect. This turns a Placement into
8912 // a PlacementAndUpdate.
8913 workInProgress.effectTag |= Update;
8914}
8915
8916function markRef$1(workInProgress) {
8917 workInProgress.effectTag |= Ref;
8918}
8919
8920var appendAllChildren = void 0;
8921var updateHostContainer = void 0;
8922var updateHostComponent$1 = void 0;
8923var updateHostText$1 = void 0;
8924if (supportsMutation) {
8925 // Mutation mode
8926
8927 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
8928 // We only have the top Fiber that was created but we need recurse down its
8929 // children to find all the terminal nodes.
8930 var node = workInProgress.child;
8931 while (node !== null) {
8932 if (node.tag === HostComponent || node.tag === HostText) {
8933 appendInitialChild(parent, node.stateNode);
8934 } else if (node.tag === HostPortal) {
8935 // If we have a portal child, then we don't want to traverse
8936 // down its children. Instead, we'll get insertions from each child in
8937 // the portal directly.
8938 } else if (node.child !== null) {
8939 node.child.return = node;
8940 node = node.child;
8941 continue;
8942 }
8943 if (node === workInProgress) {
8944 return;
8945 }
8946 while (node.sibling === null) {
8947 if (node.return === null || node.return === workInProgress) {
8948 return;
8949 }
8950 node = node.return;
8951 }
8952 node.sibling.return = node.return;
8953 node = node.sibling;
8954 }
8955 };
8956
8957 updateHostContainer = function (workInProgress) {
8958 // Noop
8959 };
8960 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
8961 // If we have an alternate, that means this is an update and we need to
8962 // schedule a side-effect to do the updates.
8963 var oldProps = current.memoizedProps;
8964 if (oldProps === newProps) {
8965 // In mutation mode, this is sufficient for a bailout because
8966 // we won't touch this node even if children changed.
8967 return;
8968 }
8969
8970 // If we get updated because one of our children updated, we don't
8971 // have newProps so we'll have to reuse them.
8972 // TODO: Split the update API as separate for the props vs. children.
8973 // Even better would be if children weren't special cased at all tho.
8974 var instance = workInProgress.stateNode;
8975 var currentHostContext = getHostContext();
8976 // TODO: Experiencing an error where oldProps is null. Suggests a host
8977 // component is hitting the resume path. Figure out why. Possibly
8978 // related to `hidden`.
8979 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
8980 // TODO: Type this specific to this type of component.
8981 workInProgress.updateQueue = updatePayload;
8982 // If the update payload indicates that there is a change or if there
8983 // is a new ref we mark this as an update. All the work is done in commitWork.
8984 if (updatePayload) {
8985 markUpdate(workInProgress);
8986 }
8987 };
8988 updateHostText$1 = function (current, workInProgress, oldText, newText) {
8989 // If the text differs, mark it as an update. All the work in done in commitWork.
8990 if (oldText !== newText) {
8991 markUpdate(workInProgress);
8992 }
8993 };
8994} else if (supportsPersistence) {
8995 // Persistent host tree mode
8996
8997 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
8998 // We only have the top Fiber that was created but we need recurse down its
8999 // children to find all the terminal nodes.
9000 var node = workInProgress.child;
9001 while (node !== null) {
9002 // eslint-disable-next-line no-labels
9003 branches: if (node.tag === HostComponent) {
9004 var instance = node.stateNode;
9005 if (needsVisibilityToggle) {
9006 var props = node.memoizedProps;
9007 var type = node.type;
9008 if (isHidden) {
9009 // This child is inside a timed out tree. Hide it.
9010 instance = cloneHiddenInstance(instance, type, props, node);
9011 } else {
9012 // This child was previously inside a timed out tree. If it was not
9013 // updated during this render, it may need to be unhidden. Clone
9014 // again to be sure.
9015 instance = cloneUnhiddenInstance(instance, type, props, node);
9016 }
9017 node.stateNode = instance;
9018 }
9019 appendInitialChild(parent, instance);
9020 } else if (node.tag === HostText) {
9021 var _instance = node.stateNode;
9022 if (needsVisibilityToggle) {
9023 var text = node.memoizedProps;
9024 var rootContainerInstance = getRootHostContainer();
9025 var currentHostContext = getHostContext();
9026 if (isHidden) {
9027 _instance = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
9028 } else {
9029 _instance = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
9030 }
9031 node.stateNode = _instance;
9032 }
9033 appendInitialChild(parent, _instance);
9034 } else if (node.tag === HostPortal) {
9035 // If we have a portal child, then we don't want to traverse
9036 // down its children. Instead, we'll get insertions from each child in
9037 // the portal directly.
9038 } else if (node.tag === SuspenseComponent) {
9039 var current = node.alternate;
9040 if (current !== null) {
9041 var oldState = current.memoizedState;
9042 var newState = node.memoizedState;
9043 var oldIsHidden = oldState !== null;
9044 var newIsHidden = newState !== null;
9045 if (oldIsHidden !== newIsHidden) {
9046 // The placeholder either just timed out or switched back to the normal
9047 // children after having previously timed out. Toggle the visibility of
9048 // the direct host children.
9049 var primaryChildParent = newIsHidden ? node.child : node;
9050 if (primaryChildParent !== null) {
9051 appendAllChildren(parent, primaryChildParent, true, newIsHidden);
9052 }
9053 // eslint-disable-next-line no-labels
9054 break branches;
9055 }
9056 }
9057 if (node.child !== null) {
9058 // Continue traversing like normal
9059 node.child.return = node;
9060 node = node.child;
9061 continue;
9062 }
9063 } else if (node.child !== null) {
9064 node.child.return = node;
9065 node = node.child;
9066 continue;
9067 }
9068 // $FlowFixMe This is correct but Flow is confused by the labeled break.
9069 node = node;
9070 if (node === workInProgress) {
9071 return;
9072 }
9073 while (node.sibling === null) {
9074 if (node.return === null || node.return === workInProgress) {
9075 return;
9076 }
9077 node = node.return;
9078 }
9079 node.sibling.return = node.return;
9080 node = node.sibling;
9081 }
9082 };
9083
9084 // An unfortunate fork of appendAllChildren because we have two different parent types.
9085 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) {
9086 // We only have the top Fiber that was created but we need recurse down its
9087 // children to find all the terminal nodes.
9088 var node = workInProgress.child;
9089 while (node !== null) {
9090 // eslint-disable-next-line no-labels
9091 branches: if (node.tag === HostComponent) {
9092 var instance = node.stateNode;
9093 if (needsVisibilityToggle) {
9094 var props = node.memoizedProps;
9095 var type = node.type;
9096 if (isHidden) {
9097 // This child is inside a timed out tree. Hide it.
9098 instance = cloneHiddenInstance(instance, type, props, node);
9099 } else {
9100 // This child was previously inside a timed out tree. If it was not
9101 // updated during this render, it may need to be unhidden. Clone
9102 // again to be sure.
9103 instance = cloneUnhiddenInstance(instance, type, props, node);
9104 }
9105 node.stateNode = instance;
9106 }
9107 appendChildToContainerChildSet(containerChildSet, instance);
9108 } else if (node.tag === HostText) {
9109 var _instance2 = node.stateNode;
9110 if (needsVisibilityToggle) {
9111 var text = node.memoizedProps;
9112 var rootContainerInstance = getRootHostContainer();
9113 var currentHostContext = getHostContext();
9114 if (isHidden) {
9115 _instance2 = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
9116 } else {
9117 _instance2 = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
9118 }
9119 node.stateNode = _instance2;
9120 }
9121 appendChildToContainerChildSet(containerChildSet, _instance2);
9122 } else if (node.tag === HostPortal) {
9123 // If we have a portal child, then we don't want to traverse
9124 // down its children. Instead, we'll get insertions from each child in
9125 // the portal directly.
9126 } else if (node.tag === SuspenseComponent) {
9127 var current = node.alternate;
9128 if (current !== null) {
9129 var oldState = current.memoizedState;
9130 var newState = node.memoizedState;
9131 var oldIsHidden = oldState !== null;
9132 var newIsHidden = newState !== null;
9133 if (oldIsHidden !== newIsHidden) {
9134 // The placeholder either just timed out or switched back to the normal
9135 // children after having previously timed out. Toggle the visibility of
9136 // the direct host children.
9137 var primaryChildParent = newIsHidden ? node.child : node;
9138 if (primaryChildParent !== null) {
9139 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden);
9140 }
9141 // eslint-disable-next-line no-labels
9142 break branches;
9143 }
9144 }
9145 if (node.child !== null) {
9146 // Continue traversing like normal
9147 node.child.return = node;
9148 node = node.child;
9149 continue;
9150 }
9151 } else if (node.child !== null) {
9152 node.child.return = node;
9153 node = node.child;
9154 continue;
9155 }
9156 // $FlowFixMe This is correct but Flow is confused by the labeled break.
9157 node = node;
9158 if (node === workInProgress) {
9159 return;
9160 }
9161 while (node.sibling === null) {
9162 if (node.return === null || node.return === workInProgress) {
9163 return;
9164 }
9165 node = node.return;
9166 }
9167 node.sibling.return = node.return;
9168 node = node.sibling;
9169 }
9170 };
9171 updateHostContainer = function (workInProgress) {
9172 var portalOrRoot = workInProgress.stateNode;
9173 var childrenUnchanged = workInProgress.firstEffect === null;
9174 if (childrenUnchanged) {
9175 // No changes, just reuse the existing instance.
9176 } else {
9177 var container = portalOrRoot.containerInfo;
9178 var newChildSet = createContainerChildSet(container);
9179 // If children might have changed, we have to add them all to the set.
9180 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
9181 portalOrRoot.pendingChildren = newChildSet;
9182 // Schedule an update on the container to swap out the container.
9183 markUpdate(workInProgress);
9184 finalizeContainerChildren(container, newChildSet);
9185 }
9186 };
9187 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9188 var currentInstance = current.stateNode;
9189 var oldProps = current.memoizedProps;
9190 // If there are no effects associated with this node, then none of our children had any updates.
9191 // This guarantees that we can reuse all of them.
9192 var childrenUnchanged = workInProgress.firstEffect === null;
9193 if (childrenUnchanged && oldProps === newProps) {
9194 // No changes, just reuse the existing instance.
9195 // Note that this might release a previous clone.
9196 workInProgress.stateNode = currentInstance;
9197 return;
9198 }
9199 var recyclableInstance = workInProgress.stateNode;
9200 var currentHostContext = getHostContext();
9201 var updatePayload = null;
9202 if (oldProps !== newProps) {
9203 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9204 }
9205 if (childrenUnchanged && updatePayload === null) {
9206 // No changes, just reuse the existing instance.
9207 // Note that this might release a previous clone.
9208 workInProgress.stateNode = currentInstance;
9209 return;
9210 }
9211 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
9212 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
9213 markUpdate(workInProgress);
9214 }
9215 workInProgress.stateNode = newInstance;
9216 if (childrenUnchanged) {
9217 // If there are no other effects in this tree, we need to flag this node as having one.
9218 // Even though we're not going to use it for anything.
9219 // Otherwise parents won't know that there are new children to propagate upwards.
9220 markUpdate(workInProgress);
9221 } else {
9222 // If children might have changed, we have to add them all to the set.
9223 appendAllChildren(newInstance, workInProgress, false, false);
9224 }
9225 };
9226 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9227 if (oldText !== newText) {
9228 // If the text content differs, we'll create a new text instance for it.
9229 var rootContainerInstance = getRootHostContainer();
9230 var currentHostContext = getHostContext();
9231 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
9232 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
9233 // This lets the parents know that at least one of their children has changed.
9234 markUpdate(workInProgress);
9235 }
9236 };
9237} else {
9238 // No host operations
9239 updateHostContainer = function (workInProgress) {
9240 // Noop
9241 };
9242 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9243 // Noop
9244 };
9245 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9246 // Noop
9247 };
9248}
9249
9250function completeWork(current, workInProgress, renderExpirationTime) {
9251 var newProps = workInProgress.pendingProps;
9252
9253 switch (workInProgress.tag) {
9254 case IndeterminateComponent:
9255 break;
9256 case LazyComponent:
9257 break;
9258 case SimpleMemoComponent:
9259 case FunctionComponent:
9260 break;
9261 case ClassComponent:
9262 {
9263 var Component = workInProgress.type;
9264 if (isContextProvider(Component)) {
9265 popContext(workInProgress);
9266 }
9267 break;
9268 }
9269 case HostRoot:
9270 {
9271 popHostContainer(workInProgress);
9272 popTopLevelContextObject(workInProgress);
9273 var fiberRoot = workInProgress.stateNode;
9274 if (fiberRoot.pendingContext) {
9275 fiberRoot.context = fiberRoot.pendingContext;
9276 fiberRoot.pendingContext = null;
9277 }
9278 if (current === null || current.child === null) {
9279 // If we hydrated, pop so that we can delete any remaining children
9280 // that weren't hydrated.
9281 popHydrationState(workInProgress);
9282 // This resets the hacky state to fix isMounted before committing.
9283 // TODO: Delete this when we delete isMounted and findDOMNode.
9284 workInProgress.effectTag &= ~Placement;
9285 }
9286 updateHostContainer(workInProgress);
9287 break;
9288 }
9289 case HostComponent:
9290 {
9291 popHostContext(workInProgress);
9292 var rootContainerInstance = getRootHostContainer();
9293 var type = workInProgress.type;
9294 if (current !== null && workInProgress.stateNode != null) {
9295 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
9296
9297 if (current.ref !== workInProgress.ref) {
9298 markRef$1(workInProgress);
9299 }
9300 } else {
9301 if (!newProps) {
9302 !(workInProgress.stateNode !== null) ? invariant(false, 'We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.') : void 0;
9303 // This can happen when we abort work.
9304 break;
9305 }
9306
9307 var currentHostContext = getHostContext();
9308 // TODO: Move createInstance to beginWork and keep it on a context
9309 // "stack" as the parent. Then append children as we go in beginWork
9310 // or completeWork depending on we want to add then top->down or
9311 // bottom->up. Top->down is faster in IE11.
9312 var wasHydrated = popHydrationState(workInProgress);
9313 if (wasHydrated) {
9314 // TODO: Move this and createInstance step into the beginPhase
9315 // to consolidate.
9316 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
9317 // If changes to the hydrated node needs to be applied at the
9318 // commit-phase we mark this as such.
9319 markUpdate(workInProgress);
9320 }
9321 } else {
9322 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
9323
9324 appendAllChildren(instance, workInProgress, false, false);
9325
9326 // Certain renderers require commit-time effects for initial mount.
9327 // (eg DOM renderer supports auto-focus for certain elements).
9328 // Make sure such renderers get scheduled for later work.
9329 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance, currentHostContext)) {
9330 markUpdate(workInProgress);
9331 }
9332 workInProgress.stateNode = instance;
9333 }
9334
9335 if (workInProgress.ref !== null) {
9336 // If there is a ref on a host node we need to schedule a callback
9337 markRef$1(workInProgress);
9338 }
9339 }
9340 break;
9341 }
9342 case HostText:
9343 {
9344 var newText = newProps;
9345 if (current && workInProgress.stateNode != null) {
9346 var oldText = current.memoizedProps;
9347 // If we have an alternate, that means this is an update and we need
9348 // to schedule a side-effect to do the updates.
9349 updateHostText$1(current, workInProgress, oldText, newText);
9350 } else {
9351 if (typeof newText !== 'string') {
9352 !(workInProgress.stateNode !== null) ? invariant(false, 'We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.') : void 0;
9353 // This can happen when we abort work.
9354 }
9355 var _rootContainerInstance = getRootHostContainer();
9356 var _currentHostContext = getHostContext();
9357 var _wasHydrated = popHydrationState(workInProgress);
9358 if (_wasHydrated) {
9359 if (prepareToHydrateHostTextInstance(workInProgress)) {
9360 markUpdate(workInProgress);
9361 }
9362 } else {
9363 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
9364 }
9365 }
9366 break;
9367 }
9368 case ForwardRef:
9369 break;
9370 case SuspenseComponent:
9371 {
9372 var nextState = workInProgress.memoizedState;
9373 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
9374 // Something suspended. Re-render with the fallback children.
9375 workInProgress.expirationTime = renderExpirationTime;
9376 // Do not reset the effect list.
9377 return workInProgress;
9378 }
9379
9380 var nextDidTimeout = nextState !== null;
9381 var prevDidTimeout = current !== null && current.memoizedState !== null;
9382
9383 if (current !== null && !nextDidTimeout && prevDidTimeout) {
9384 // We just switched from the fallback to the normal children. Delete
9385 // the fallback.
9386 // TODO: Would it be better to store the fallback fragment on
9387 var currentFallbackChild = current.child.sibling;
9388 if (currentFallbackChild !== null) {
9389 // Deletions go at the beginning of the return fiber's effect list
9390 var first = workInProgress.firstEffect;
9391 if (first !== null) {
9392 workInProgress.firstEffect = currentFallbackChild;
9393 currentFallbackChild.nextEffect = first;
9394 } else {
9395 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
9396 currentFallbackChild.nextEffect = null;
9397 }
9398 currentFallbackChild.effectTag = Deletion;
9399 }
9400 }
9401
9402 if (nextDidTimeout || prevDidTimeout) {
9403 // If the children are hidden, or if they were previous hidden, schedule
9404 // an effect to toggle their visibility. This is also used to attach a
9405 // retry listener to the promise.
9406 workInProgress.effectTag |= Update;
9407 }
9408 break;
9409 }
9410 case Fragment:
9411 break;
9412 case Mode:
9413 break;
9414 case Profiler:
9415 break;
9416 case HostPortal:
9417 popHostContainer(workInProgress);
9418 updateHostContainer(workInProgress);
9419 break;
9420 case ContextProvider:
9421 // Pop provider fiber
9422 popProvider(workInProgress);
9423 break;
9424 case ContextConsumer:
9425 break;
9426 case MemoComponent:
9427 break;
9428 case IncompleteClassComponent:
9429 {
9430 // Same as class component case. I put it down here so that the tags are
9431 // sequential to ensure this switch is compiled to a jump table.
9432 var _Component = workInProgress.type;
9433 if (isContextProvider(_Component)) {
9434 popContext(workInProgress);
9435 }
9436 break;
9437 }
9438 case DehydratedSuspenseComponent:
9439 {
9440 if (enableSuspenseServerRenderer) {
9441 if (current === null) {
9442 var _wasHydrated2 = popHydrationState(workInProgress);
9443 !_wasHydrated2 ? invariant(false, 'A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.') : void 0;
9444 skipPastDehydratedSuspenseInstance(workInProgress);
9445 } else if ((workInProgress.effectTag & DidCapture) === NoEffect) {
9446 // This boundary did not suspend so it's now hydrated.
9447 // To handle any future suspense cases, we're going to now upgrade it
9448 // to a Suspense component. We detach it from the existing current fiber.
9449 current.alternate = null;
9450 workInProgress.alternate = null;
9451 workInProgress.tag = SuspenseComponent;
9452 workInProgress.memoizedState = null;
9453 workInProgress.stateNode = null;
9454 }
9455 }
9456 break;
9457 }
9458 default:
9459 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
9460 }
9461
9462 return null;
9463}
9464
9465function shouldCaptureSuspense(workInProgress) {
9466 // In order to capture, the Suspense component must have a fallback prop.
9467 if (workInProgress.memoizedProps.fallback === undefined) {
9468 return false;
9469 }
9470 // If it was the primary children that just suspended, capture and render the
9471 // fallback. Otherwise, don't capture and bubble to the next boundary.
9472 var nextState = workInProgress.memoizedState;
9473 return nextState === null;
9474}
9475
9476// This module is forked in different environments.
9477// By default, return `true` to log errors to the console.
9478// Forks can return `false` if this isn't desirable.
9479function showErrorDialog(capturedError) {
9480 return true;
9481}
9482
9483function logCapturedError(capturedError) {
9484 var logError = showErrorDialog(capturedError);
9485
9486 // Allow injected showErrorDialog() to prevent default console.error logging.
9487 // This enables renderers like ReactNative to better manage redbox behavior.
9488 if (logError === false) {
9489 return;
9490 }
9491
9492 var error = capturedError.error;
9493 {
9494 var componentName = capturedError.componentName,
9495 componentStack = capturedError.componentStack,
9496 errorBoundaryName = capturedError.errorBoundaryName,
9497 errorBoundaryFound = capturedError.errorBoundaryFound,
9498 willRetry = capturedError.willRetry;
9499
9500 // Browsers support silencing uncaught errors by calling
9501 // `preventDefault()` in window `error` handler.
9502 // We record this information as an expando on the error.
9503
9504 if (error != null && error._suppressLogging) {
9505 if (errorBoundaryFound && willRetry) {
9506 // The error is recoverable and was silenced.
9507 // Ignore it and don't print the stack addendum.
9508 // This is handy for testing error boundaries without noise.
9509 return;
9510 }
9511 // The error is fatal. Since the silencing might have
9512 // been accidental, we'll surface it anyway.
9513 // However, the browser would have silenced the original error
9514 // so we'll print it first, and then print the stack addendum.
9515 console.error(error);
9516 // For a more detailed description of this block, see:
9517 // https://github.com/facebook/react/pull/13384
9518 }
9519
9520 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
9521
9522 var errorBoundaryMessage = void 0;
9523 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
9524 if (errorBoundaryFound && errorBoundaryName) {
9525 if (willRetry) {
9526 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
9527 } else {
9528 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
9529 }
9530 } else {
9531 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.';
9532 }
9533 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
9534
9535 // In development, we provide our own message with just the component stack.
9536 // We don't include the original error message and JS stack because the browser
9537 // has already printed it. Even if the application swallows the error, it is still
9538 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
9539 console.error(combinedMessage);
9540 }
9541}
9542
9543var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
9544{
9545 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
9546}
9547
9548var PossiblyWeakSet$1 = typeof WeakSet === 'function' ? WeakSet : Set;
9549
9550function logError(boundary, errorInfo) {
9551 var source = errorInfo.source;
9552 var stack = errorInfo.stack;
9553 if (stack === null && source !== null) {
9554 stack = getStackByFiberInDevAndProd(source);
9555 }
9556
9557 var capturedError = {
9558 componentName: source !== null ? getComponentName(source.type) : null,
9559 componentStack: stack !== null ? stack : '',
9560 error: errorInfo.value,
9561 errorBoundary: null,
9562 errorBoundaryName: null,
9563 errorBoundaryFound: false,
9564 willRetry: false
9565 };
9566
9567 if (boundary !== null && boundary.tag === ClassComponent) {
9568 capturedError.errorBoundary = boundary.stateNode;
9569 capturedError.errorBoundaryName = getComponentName(boundary.type);
9570 capturedError.errorBoundaryFound = true;
9571 capturedError.willRetry = true;
9572 }
9573
9574 try {
9575 logCapturedError(capturedError);
9576 } catch (e) {
9577 // This method must not throw, or React internal state will get messed up.
9578 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
9579 // we want to report this error outside of the normal stack as a last resort.
9580 // https://github.com/facebook/react/issues/13188
9581 setTimeout(function () {
9582 throw e;
9583 });
9584 }
9585}
9586
9587var callComponentWillUnmountWithTimer = function (current, instance) {
9588 startPhaseTimer(current, 'componentWillUnmount');
9589 instance.props = current.memoizedProps;
9590 instance.state = current.memoizedState;
9591 instance.componentWillUnmount();
9592 stopPhaseTimer();
9593};
9594
9595// Capture errors so they don't interrupt unmounting.
9596function safelyCallComponentWillUnmount(current, instance) {
9597 {
9598 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance);
9599 if (hasCaughtError()) {
9600 var unmountError = clearCaughtError();
9601 captureCommitPhaseError(current, unmountError);
9602 }
9603 }
9604}
9605
9606function safelyDetachRef(current) {
9607 var ref = current.ref;
9608 if (ref !== null) {
9609 if (typeof ref === 'function') {
9610 {
9611 invokeGuardedCallback(null, ref, null, null);
9612 if (hasCaughtError()) {
9613 var refError = clearCaughtError();
9614 captureCommitPhaseError(current, refError);
9615 }
9616 }
9617 } else {
9618 ref.current = null;
9619 }
9620 }
9621}
9622
9623function safelyCallDestroy(current, destroy) {
9624 {
9625 invokeGuardedCallback(null, destroy, null);
9626 if (hasCaughtError()) {
9627 var error = clearCaughtError();
9628 captureCommitPhaseError(current, error);
9629 }
9630 }
9631}
9632
9633function commitBeforeMutationLifeCycles(current, finishedWork) {
9634 switch (finishedWork.tag) {
9635 case FunctionComponent:
9636 case ForwardRef:
9637 case SimpleMemoComponent:
9638 {
9639 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
9640 return;
9641 }
9642 case ClassComponent:
9643 {
9644 if (finishedWork.effectTag & Snapshot) {
9645 if (current !== null) {
9646 var prevProps = current.memoizedProps;
9647 var prevState = current.memoizedState;
9648 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
9649 var instance = finishedWork.stateNode;
9650 // We could update instance props and state here,
9651 // but instead we rely on them being set during last render.
9652 // TODO: revisit this when we implement resuming.
9653 {
9654 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
9655 !(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;
9656 !(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;
9657 }
9658 }
9659 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
9660 {
9661 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
9662 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
9663 didWarnSet.add(finishedWork.type);
9664 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
9665 }
9666 }
9667 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
9668 stopPhaseTimer();
9669 }
9670 }
9671 return;
9672 }
9673 case HostRoot:
9674 case HostComponent:
9675 case HostText:
9676 case HostPortal:
9677 case IncompleteClassComponent:
9678 // Nothing to do for these component types
9679 return;
9680 default:
9681 {
9682 invariant(false, 'This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.');
9683 }
9684 }
9685}
9686
9687function commitHookEffectList(unmountTag, mountTag, finishedWork) {
9688 var updateQueue = finishedWork.updateQueue;
9689 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
9690 if (lastEffect !== null) {
9691 var firstEffect = lastEffect.next;
9692 var effect = firstEffect;
9693 do {
9694 if ((effect.tag & unmountTag) !== NoEffect$1) {
9695 // Unmount
9696 var destroy = effect.destroy;
9697 effect.destroy = undefined;
9698 if (destroy !== undefined) {
9699 destroy();
9700 }
9701 }
9702 if ((effect.tag & mountTag) !== NoEffect$1) {
9703 // Mount
9704 var create = effect.create;
9705 effect.destroy = create();
9706
9707 {
9708 var _destroy = effect.destroy;
9709 if (_destroy !== undefined && typeof _destroy !== 'function') {
9710 var addendum = void 0;
9711 if (_destroy === null) {
9712 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
9713 } else if (typeof _destroy.then === 'function') {
9714 addendum = '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' + 'Instead, you may write an async function separately ' + 'and then call it from inside the effect:\n\n' + 'async function fetchComment(commentId) {\n' + ' // You can await here\n' + '}\n\n' + 'useEffect(() => {\n' + ' fetchComment(commentId);\n' + '}, [commentId]);\n\n' + 'In the future, React will provide a more idiomatic solution for data fetching ' + "that doesn't involve writing effects manually.";
9715 } else {
9716 addendum = ' You returned: ' + _destroy;
9717 }
9718 warningWithoutStack$1(false, 'An Effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
9719 }
9720 }
9721 }
9722 effect = effect.next;
9723 } while (effect !== firstEffect);
9724 }
9725}
9726
9727function commitPassiveHookEffects(finishedWork) {
9728 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
9729 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
9730}
9731
9732function commitLifeCycles(finishedRoot, current, finishedWork, committedExpirationTime) {
9733 switch (finishedWork.tag) {
9734 case FunctionComponent:
9735 case ForwardRef:
9736 case SimpleMemoComponent:
9737 {
9738 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
9739 break;
9740 }
9741 case ClassComponent:
9742 {
9743 var instance = finishedWork.stateNode;
9744 if (finishedWork.effectTag & Update) {
9745 if (current === null) {
9746 startPhaseTimer(finishedWork, 'componentDidMount');
9747 // We could update instance props and state here,
9748 // but instead we rely on them being set during last render.
9749 // TODO: revisit this when we implement resuming.
9750 {
9751 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
9752 !(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;
9753 !(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;
9754 }
9755 }
9756 instance.componentDidMount();
9757 stopPhaseTimer();
9758 } else {
9759 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
9760 var prevState = current.memoizedState;
9761 startPhaseTimer(finishedWork, 'componentDidUpdate');
9762 // We could update instance props and state here,
9763 // but instead we rely on them being set during last render.
9764 // TODO: revisit this when we implement resuming.
9765 {
9766 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
9767 !(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;
9768 !(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;
9769 }
9770 }
9771 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
9772 stopPhaseTimer();
9773 }
9774 }
9775 var updateQueue = finishedWork.updateQueue;
9776 if (updateQueue !== null) {
9777 {
9778 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
9779 !(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;
9780 !(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;
9781 }
9782 }
9783 // We could update instance props and state here,
9784 // but instead we rely on them being set during last render.
9785 // TODO: revisit this when we implement resuming.
9786 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
9787 }
9788 return;
9789 }
9790 case HostRoot:
9791 {
9792 var _updateQueue = finishedWork.updateQueue;
9793 if (_updateQueue !== null) {
9794 var _instance = null;
9795 if (finishedWork.child !== null) {
9796 switch (finishedWork.child.tag) {
9797 case HostComponent:
9798 _instance = getPublicInstance(finishedWork.child.stateNode);
9799 break;
9800 case ClassComponent:
9801 _instance = finishedWork.child.stateNode;
9802 break;
9803 }
9804 }
9805 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime);
9806 }
9807 return;
9808 }
9809 case HostComponent:
9810 {
9811 var _instance2 = finishedWork.stateNode;
9812
9813 // Renderers may schedule work to be done after host components are mounted
9814 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
9815 // These effects should only be committed when components are first mounted,
9816 // aka when there is no current/alternate.
9817 if (current === null && finishedWork.effectTag & Update) {
9818 var type = finishedWork.type;
9819 var props = finishedWork.memoizedProps;
9820
9821 }
9822
9823 return;
9824 }
9825 case HostText:
9826 {
9827 // We have no life-cycles associated with text.
9828 return;
9829 }
9830 case HostPortal:
9831 {
9832 // We have no life-cycles associated with portals.
9833 return;
9834 }
9835 case Profiler:
9836 {
9837 if (enableProfilerTimer) {
9838 var onRender = finishedWork.memoizedProps.onRender;
9839
9840 if (enableSchedulerTracing) {
9841 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
9842 } else {
9843 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime());
9844 }
9845 }
9846 return;
9847 }
9848 case SuspenseComponent:
9849 break;
9850 case IncompleteClassComponent:
9851 break;
9852 default:
9853 {
9854 invariant(false, 'This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.');
9855 }
9856 }
9857}
9858
9859function hideOrUnhideAllChildren(finishedWork, isHidden) {
9860 if (supportsMutation) {
9861 // We only have the top Fiber that was inserted but we need to recurse down its
9862 var node = finishedWork;
9863 while (true) {
9864 if (node.tag === HostComponent) {
9865 var instance = node.stateNode;
9866 if (isHidden) {
9867 hideInstance(instance);
9868 } else {
9869 unhideInstance(node.stateNode, node.memoizedProps);
9870 }
9871 } else if (node.tag === HostText) {
9872 var _instance3 = node.stateNode;
9873 if (isHidden) {
9874
9875 } else {
9876 unhideTextInstance(_instance3, node.memoizedProps);
9877 }
9878 } else if (node.tag === SuspenseComponent && node.memoizedState !== null) {
9879 // Found a nested Suspense component that timed out. Skip over the
9880 var fallbackChildFragment = node.child.sibling;
9881 fallbackChildFragment.return = node;
9882 node = fallbackChildFragment;
9883 continue;
9884 } else if (node.child !== null) {
9885 node.child.return = node;
9886 node = node.child;
9887 continue;
9888 }
9889 if (node === finishedWork) {
9890 return;
9891 }
9892 while (node.sibling === null) {
9893 if (node.return === null || node.return === finishedWork) {
9894 return;
9895 }
9896 node = node.return;
9897 }
9898 node.sibling.return = node.return;
9899 node = node.sibling;
9900 }
9901 }
9902}
9903
9904function commitAttachRef(finishedWork) {
9905 var ref = finishedWork.ref;
9906 if (ref !== null) {
9907 var instance = finishedWork.stateNode;
9908 var instanceToUse = void 0;
9909 switch (finishedWork.tag) {
9910 case HostComponent:
9911 instanceToUse = getPublicInstance(instance);
9912 break;
9913 default:
9914 instanceToUse = instance;
9915 }
9916 if (typeof ref === 'function') {
9917 ref(instanceToUse);
9918 } else {
9919 {
9920 if (!ref.hasOwnProperty('current')) {
9921 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
9922 }
9923 }
9924
9925 ref.current = instanceToUse;
9926 }
9927 }
9928}
9929
9930function commitDetachRef(current) {
9931 var currentRef = current.ref;
9932 if (currentRef !== null) {
9933 if (typeof currentRef === 'function') {
9934 currentRef(null);
9935 } else {
9936 currentRef.current = null;
9937 }
9938 }
9939}
9940
9941// User-originating errors (lifecycles and refs) should not interrupt
9942// deletion, so don't let them throw. Host-originating errors should
9943// interrupt deletion, so it's okay
9944function commitUnmount(current) {
9945 onCommitUnmount(current);
9946
9947 switch (current.tag) {
9948 case FunctionComponent:
9949 case ForwardRef:
9950 case MemoComponent:
9951 case SimpleMemoComponent:
9952 {
9953 var updateQueue = current.updateQueue;
9954 if (updateQueue !== null) {
9955 var lastEffect = updateQueue.lastEffect;
9956 if (lastEffect !== null) {
9957 var firstEffect = lastEffect.next;
9958 var effect = firstEffect;
9959 do {
9960 var destroy = effect.destroy;
9961 if (destroy !== undefined) {
9962 safelyCallDestroy(current, destroy);
9963 }
9964 effect = effect.next;
9965 } while (effect !== firstEffect);
9966 }
9967 }
9968 break;
9969 }
9970 case ClassComponent:
9971 {
9972 safelyDetachRef(current);
9973 var instance = current.stateNode;
9974 if (typeof instance.componentWillUnmount === 'function') {
9975 safelyCallComponentWillUnmount(current, instance);
9976 }
9977 return;
9978 }
9979 case HostComponent:
9980 {
9981 safelyDetachRef(current);
9982 return;
9983 }
9984 case HostPortal:
9985 {
9986 // TODO: this is recursive.
9987 // We are also not using this parent because
9988 // the portal will get pushed immediately.
9989 if (supportsMutation) {
9990 unmountHostComponents(current);
9991 } else if (supportsPersistence) {
9992 emptyPortalContainer(current);
9993 }
9994 return;
9995 }
9996 }
9997}
9998
9999function commitNestedUnmounts(root) {
10000 // While we're inside a removed host node we don't want to call
10001 // removeChild on the inner nodes because they're removed by the top
10002 // call anyway. We also want to call componentWillUnmount on all
10003 // composites before this host node is removed from the tree. Therefore
10004 var node = root;
10005 while (true) {
10006 commitUnmount(node);
10007 // Visit children because they may contain more composite or host nodes.
10008 // Skip portals because commitUnmount() currently visits them recursively.
10009 if (node.child !== null && (
10010 // If we use mutation we drill down into portals using commitUnmount above.
10011 // If we don't use mutation we drill down into portals here instead.
10012 !supportsMutation || node.tag !== HostPortal)) {
10013 node.child.return = node;
10014 node = node.child;
10015 continue;
10016 }
10017 if (node === root) {
10018 return;
10019 }
10020 while (node.sibling === null) {
10021 if (node.return === null || node.return === root) {
10022 return;
10023 }
10024 node = node.return;
10025 }
10026 node.sibling.return = node.return;
10027 node = node.sibling;
10028 }
10029}
10030
10031function detachFiber(current) {
10032 // Cut off the return pointers to disconnect it from the tree. Ideally, we
10033 // should clear the child pointer of the parent alternate to let this
10034 // get GC:ed but we don't know which for sure which parent is the current
10035 // one so we'll settle for GC:ing the subtree of this child. This child
10036 // itself will be GC:ed when the parent updates the next time.
10037 current.return = null;
10038 current.child = null;
10039 current.memoizedState = null;
10040 current.updateQueue = null;
10041 var alternate = current.alternate;
10042 if (alternate !== null) {
10043 alternate.return = null;
10044 alternate.child = null;
10045 alternate.memoizedState = null;
10046 alternate.updateQueue = null;
10047 }
10048}
10049
10050function emptyPortalContainer(current) {
10051 if (!supportsPersistence) {
10052 return;
10053 }
10054
10055 var portal = current.stateNode;
10056 var containerInfo = portal.containerInfo;
10057
10058 var emptyChildSet = createContainerChildSet(containerInfo);
10059 replaceContainerChildren(containerInfo, emptyChildSet);
10060}
10061
10062function commitContainer(finishedWork) {
10063 if (!supportsPersistence) {
10064 return;
10065 }
10066
10067 switch (finishedWork.tag) {
10068 case ClassComponent:
10069 {
10070 return;
10071 }
10072 case HostComponent:
10073 {
10074 return;
10075 }
10076 case HostText:
10077 {
10078 return;
10079 }
10080 case HostRoot:
10081 case HostPortal:
10082 {
10083 var portalOrRoot = finishedWork.stateNode;
10084 var containerInfo = portalOrRoot.containerInfo,
10085 _pendingChildren = portalOrRoot.pendingChildren;
10086
10087 replaceContainerChildren(containerInfo, _pendingChildren);
10088 return;
10089 }
10090 default:
10091 {
10092 invariant(false, 'This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.');
10093 }
10094 }
10095}
10096
10097function getHostParentFiber(fiber) {
10098 var parent = fiber.return;
10099 while (parent !== null) {
10100 if (isHostParent(parent)) {
10101 return parent;
10102 }
10103 parent = parent.return;
10104 }
10105 invariant(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.');
10106}
10107
10108function isHostParent(fiber) {
10109 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
10110}
10111
10112function getHostSibling(fiber) {
10113 // We're going to search forward into the tree until we find a sibling host
10114 // node. Unfortunately, if multiple insertions are done in a row we have to
10115 // search past them. This leads to exponential search for the next sibling.
10116 var node = fiber;
10117 siblings: while (true) {
10118 // If we didn't find anything, let's try the next sibling.
10119 while (node.sibling === null) {
10120 if (node.return === null || isHostParent(node.return)) {
10121 // If we pop out of the root or hit the parent the fiber we are the
10122 // last sibling.
10123 return null;
10124 }
10125 node = node.return;
10126 }
10127 node.sibling.return = node.return;
10128 node = node.sibling;
10129 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedSuspenseComponent) {
10130 // If it is not host node and, we might have a host node inside it.
10131 // Try to search down until we find one.
10132 if (node.effectTag & Placement) {
10133 // If we don't have a child, try the siblings instead.
10134 continue siblings;
10135 }
10136 // If we don't have a child, try the siblings instead.
10137 // We also skip portals because they are not part of this host tree.
10138 if (node.child === null || node.tag === HostPortal) {
10139 continue siblings;
10140 } else {
10141 node.child.return = node;
10142 node = node.child;
10143 }
10144 }
10145 // Check if this host node is stable or about to be placed.
10146 if (!(node.effectTag & Placement)) {
10147 // Found it!
10148 return node.stateNode;
10149 }
10150 }
10151}
10152
10153function commitPlacement(finishedWork) {
10154 if (!supportsMutation) {
10155 return;
10156 }
10157
10158 // Recursively insert all host nodes into the parent.
10159 var parentFiber = getHostParentFiber(finishedWork);
10160
10161 // Note: these two variables *must* always be updated together.
10162 var parent = void 0;
10163 var isContainer = void 0;
10164
10165 switch (parentFiber.tag) {
10166 case HostComponent:
10167 parent = parentFiber.stateNode;
10168 isContainer = false;
10169 break;
10170 case HostRoot:
10171 parent = parentFiber.stateNode.containerInfo;
10172 isContainer = true;
10173 break;
10174 case HostPortal:
10175 parent = parentFiber.stateNode.containerInfo;
10176 isContainer = true;
10177 break;
10178 default:
10179 invariant(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.');
10180 }
10181 if (parentFiber.effectTag & ContentReset) {
10182 // Reset the text content of the parent before doing any insertions
10183 parentFiber.effectTag &= ~ContentReset;
10184 }
10185
10186 var before = getHostSibling(finishedWork);
10187 // We only have the top Fiber that was inserted but we need to recurse down its
10188 // children to find all the terminal nodes.
10189 var node = finishedWork;
10190 while (true) {
10191 if (node.tag === HostComponent || node.tag === HostText) {
10192 if (before) {
10193 if (isContainer) {
10194 insertInContainerBefore(parent, node.stateNode, before);
10195 } else {
10196 insertBefore(parent, node.stateNode, before);
10197 }
10198 } else {
10199 if (isContainer) {
10200 appendChildToContainer(parent, node.stateNode);
10201 } else {
10202 appendChild(parent, node.stateNode);
10203 }
10204 }
10205 } else if (node.tag === HostPortal) {
10206 // If the insertion itself is a portal, then we don't want to traverse
10207 // down its children. Instead, we'll get insertions from each child in
10208 // the portal directly.
10209 } else if (node.child !== null) {
10210 node.child.return = node;
10211 node = node.child;
10212 continue;
10213 }
10214 if (node === finishedWork) {
10215 return;
10216 }
10217 while (node.sibling === null) {
10218 if (node.return === null || node.return === finishedWork) {
10219 return;
10220 }
10221 node = node.return;
10222 }
10223 node.sibling.return = node.return;
10224 node = node.sibling;
10225 }
10226}
10227
10228function unmountHostComponents(current) {
10229 // We only have the top Fiber that was deleted but we need to recurse down its
10230 var node = current;
10231
10232 // Each iteration, currentParent is populated with node's host parent if not
10233 // currentParentIsValid.
10234 var currentParentIsValid = false;
10235
10236 // Note: these two variables *must* always be updated together.
10237 var currentParent = void 0;
10238 var currentParentIsContainer = void 0;
10239
10240 while (true) {
10241 if (!currentParentIsValid) {
10242 var parent = node.return;
10243 findParent: while (true) {
10244 !(parent !== null) ? invariant(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.') : void 0;
10245 switch (parent.tag) {
10246 case HostComponent:
10247 currentParent = parent.stateNode;
10248 currentParentIsContainer = false;
10249 break findParent;
10250 case HostRoot:
10251 currentParent = parent.stateNode.containerInfo;
10252 currentParentIsContainer = true;
10253 break findParent;
10254 case HostPortal:
10255 currentParent = parent.stateNode.containerInfo;
10256 currentParentIsContainer = true;
10257 break findParent;
10258 }
10259 parent = parent.return;
10260 }
10261 currentParentIsValid = true;
10262 }
10263
10264 if (node.tag === HostComponent || node.tag === HostText) {
10265 commitNestedUnmounts(node);
10266 // After all the children have unmounted, it is now safe to remove the
10267 // node from the tree.
10268 if (currentParentIsContainer) {
10269 removeChildFromContainer(currentParent, node.stateNode);
10270 } else {
10271 removeChild(currentParent, node.stateNode);
10272 }
10273 // Don't visit children because we already visited them.
10274 } else if (enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent) {
10275 // Delete the dehydrated suspense boundary and all of its content.
10276 if (currentParentIsContainer) {
10277 clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
10278 } else {
10279 clearSuspenseBoundary(currentParent, node.stateNode);
10280 }
10281 } else if (node.tag === HostPortal) {
10282 if (node.child !== null) {
10283 // When we go into a portal, it becomes the parent to remove from.
10284 // We will reassign it back when we pop the portal on the way up.
10285 currentParent = node.stateNode.containerInfo;
10286 currentParentIsContainer = true;
10287 // Visit children because portals might contain host components.
10288 node.child.return = node;
10289 node = node.child;
10290 continue;
10291 }
10292 } else {
10293 commitUnmount(node);
10294 // Visit children because we may find more host components below.
10295 if (node.child !== null) {
10296 node.child.return = node;
10297 node = node.child;
10298 continue;
10299 }
10300 }
10301 if (node === current) {
10302 return;
10303 }
10304 while (node.sibling === null) {
10305 if (node.return === null || node.return === current) {
10306 return;
10307 }
10308 node = node.return;
10309 if (node.tag === HostPortal) {
10310 // When we go out of the portal, we need to restore the parent.
10311 // Since we don't keep a stack of them, we will search for it.
10312 currentParentIsValid = false;
10313 }
10314 }
10315 node.sibling.return = node.return;
10316 node = node.sibling;
10317 }
10318}
10319
10320function commitDeletion(current) {
10321 if (supportsMutation) {
10322 // Recursively delete all host nodes from the parent.
10323 // Detach refs and call componentWillUnmount() on the whole subtree.
10324 unmountHostComponents(current);
10325 } else {
10326 // Detach refs and call componentWillUnmount() on the whole subtree.
10327 commitNestedUnmounts(current);
10328 }
10329 detachFiber(current);
10330}
10331
10332function commitWork(current, finishedWork) {
10333 if (!supportsMutation) {
10334 switch (finishedWork.tag) {
10335 case FunctionComponent:
10336 case ForwardRef:
10337 case MemoComponent:
10338 case SimpleMemoComponent:
10339 {
10340 // Note: We currently never use MountMutation, but useLayout uses
10341 // UnmountMutation.
10342 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
10343 return;
10344 }
10345 }
10346
10347 commitContainer(finishedWork);
10348 return;
10349 }
10350
10351 switch (finishedWork.tag) {
10352 case FunctionComponent:
10353 case ForwardRef:
10354 case MemoComponent:
10355 case SimpleMemoComponent:
10356 {
10357 // Note: We currently never use MountMutation, but useLayout uses
10358 // UnmountMutation.
10359 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
10360 return;
10361 }
10362 case ClassComponent:
10363 {
10364 return;
10365 }
10366 case HostComponent:
10367 {
10368 var instance = finishedWork.stateNode;
10369 if (instance != null) {
10370 // Commit the work prepared earlier.
10371 var newProps = finishedWork.memoizedProps;
10372 // For hydration we reuse the update path but we treat the oldProps
10373 // as the newProps. The updatePayload will contain the real change in
10374 // this case.
10375 var oldProps = current !== null ? current.memoizedProps : newProps;
10376 var type = finishedWork.type;
10377 // TODO: Type the updateQueue to be specific to host components.
10378 var updatePayload = finishedWork.updateQueue;
10379 finishedWork.updateQueue = null;
10380 if (updatePayload !== null) {
10381 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
10382 }
10383 }
10384 return;
10385 }
10386 case HostText:
10387 {
10388 !(finishedWork.stateNode !== null) ? invariant(false, 'This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue.') : void 0;
10389 var textInstance = finishedWork.stateNode;
10390 var newText = finishedWork.memoizedProps;
10391 // For hydration we reuse the update path but we treat the oldProps
10392 // as the newProps. The updatePayload will contain the real change in
10393 // this case.
10394 var oldText = current !== null ? current.memoizedProps : newText;
10395 return;
10396 }
10397 case HostRoot:
10398 {
10399 return;
10400 }
10401 case Profiler:
10402 {
10403 return;
10404 }
10405 case SuspenseComponent:
10406 {
10407 var newState = finishedWork.memoizedState;
10408
10409 var newDidTimeout = void 0;
10410 var primaryChildParent = finishedWork;
10411 if (newState === null) {
10412 newDidTimeout = false;
10413 } else {
10414 newDidTimeout = true;
10415 primaryChildParent = finishedWork.child;
10416 if (newState.timedOutAt === NoWork) {
10417 // If the children had not already timed out, record the time.
10418 // This is used to compute the elapsed time during subsequent
10419 // attempts to render the children.
10420 newState.timedOutAt = requestCurrentTime();
10421 }
10422 }
10423
10424 if (primaryChildParent !== null) {
10425 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
10426 }
10427
10428 // If this boundary just timed out, then it will have a set of thenables.
10429 // For each thenable, attach a listener so that when it resolves, React
10430 // attempts to re-render the boundary in the primary (pre-timeout) state.
10431 var thenables = finishedWork.updateQueue;
10432 if (thenables !== null) {
10433 finishedWork.updateQueue = null;
10434 var retryCache = finishedWork.stateNode;
10435 if (retryCache === null) {
10436 retryCache = finishedWork.stateNode = new PossiblyWeakSet$1();
10437 }
10438 thenables.forEach(function (thenable) {
10439 // Memoize using the boundary fiber to prevent redundant listeners.
10440 var retry = retryTimedOutBoundary.bind(null, finishedWork, thenable);
10441 if (enableSchedulerTracing) {
10442 retry = unstable_wrap(retry);
10443 }
10444 if (!retryCache.has(thenable)) {
10445 retryCache.add(thenable);
10446 thenable.then(retry, retry);
10447 }
10448 });
10449 }
10450
10451 return;
10452 }
10453 case IncompleteClassComponent:
10454 {
10455 return;
10456 }
10457 default:
10458 {
10459 invariant(false, 'This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.');
10460 }
10461 }
10462}
10463
10464function commitResetTextContent(current) {
10465 if (!supportsMutation) {
10466 return;
10467 }
10468 resetTextContent(current.stateNode);
10469}
10470
10471var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
10472var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
10473
10474function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
10475 var update = createUpdate(expirationTime);
10476 // Unmount the root by rendering null.
10477 update.tag = CaptureUpdate;
10478 // Caution: React DevTools currently depends on this property
10479 // being called "element".
10480 update.payload = { element: null };
10481 var error = errorInfo.value;
10482 update.callback = function () {
10483 onUncaughtError(error);
10484 logError(fiber, errorInfo);
10485 };
10486 return update;
10487}
10488
10489function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
10490 var update = createUpdate(expirationTime);
10491 update.tag = CaptureUpdate;
10492 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
10493 if (typeof getDerivedStateFromError === 'function') {
10494 var error = errorInfo.value;
10495 update.payload = function () {
10496 return getDerivedStateFromError(error);
10497 };
10498 }
10499
10500 var inst = fiber.stateNode;
10501 if (inst !== null && typeof inst.componentDidCatch === 'function') {
10502 update.callback = function callback() {
10503 if (typeof getDerivedStateFromError !== 'function') {
10504 // To preserve the preexisting retry behavior of error boundaries,
10505 // we keep track of which ones already failed during this batch.
10506 // This gets reset before we yield back to the browser.
10507 // TODO: Warn in strict mode if getDerivedStateFromError is
10508 // not defined.
10509 markLegacyErrorBoundaryAsFailed(this);
10510 }
10511 var error = errorInfo.value;
10512 var stack = errorInfo.stack;
10513 logError(fiber, errorInfo);
10514 this.componentDidCatch(error, {
10515 componentStack: stack !== null ? stack : ''
10516 });
10517 {
10518 if (typeof getDerivedStateFromError !== 'function') {
10519 // If componentDidCatch is the only error boundary method defined,
10520 // then it needs to call setState to recover from errors.
10521 // If no state update is scheduled then the boundary will swallow the error.
10522 !(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;
10523 }
10524 }
10525 };
10526 }
10527 return update;
10528}
10529
10530function attachPingListener(root, renderExpirationTime, thenable) {
10531 // Attach a listener to the promise to "ping" the root and retry. But
10532 // only if one does not already exist for the current render expiration
10533 // time (which acts like a "thread ID" here).
10534 var pingCache = root.pingCache;
10535 var threadIDs = void 0;
10536 if (pingCache === null) {
10537 pingCache = root.pingCache = new PossiblyWeakMap();
10538 threadIDs = new Set();
10539 pingCache.set(thenable, threadIDs);
10540 } else {
10541 threadIDs = pingCache.get(thenable);
10542 if (threadIDs === undefined) {
10543 threadIDs = new Set();
10544 pingCache.set(thenable, threadIDs);
10545 }
10546 }
10547 if (!threadIDs.has(renderExpirationTime)) {
10548 // Memoize using the thread ID to prevent redundant listeners.
10549 threadIDs.add(renderExpirationTime);
10550 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
10551 if (enableSchedulerTracing) {
10552 ping = unstable_wrap(ping);
10553 }
10554 thenable.then(ping, ping);
10555 }
10556}
10557
10558function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
10559 // The source fiber did not complete.
10560 sourceFiber.effectTag |= Incomplete;
10561 // Its effect list is no longer valid.
10562 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
10563
10564 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
10565 // This is a thenable.
10566 var thenable = value;
10567
10568 // Find the earliest timeout threshold of all the placeholders in the
10569 // ancestor path. We could avoid this traversal by storing the thresholds on
10570 // the stack, but we choose not to because we only hit this path if we're
10571 // IO-bound (i.e. if something suspends). Whereas the stack is used even in
10572 // the non-IO- bound case.
10573 var _workInProgress = returnFiber;
10574 var earliestTimeoutMs = -1;
10575 var startTimeMs = -1;
10576 do {
10577 if (_workInProgress.tag === SuspenseComponent) {
10578 var current = _workInProgress.alternate;
10579 if (current !== null) {
10580 var currentState = current.memoizedState;
10581 if (currentState !== null) {
10582 // Reached a boundary that already timed out. Do not search
10583 // any further.
10584 var timedOutAt = currentState.timedOutAt;
10585 startTimeMs = expirationTimeToMs(timedOutAt);
10586 // Do not search any further.
10587 break;
10588 }
10589 }
10590 var timeoutPropMs = _workInProgress.pendingProps.maxDuration;
10591 if (typeof timeoutPropMs === 'number') {
10592 if (timeoutPropMs <= 0) {
10593 earliestTimeoutMs = 0;
10594 } else if (earliestTimeoutMs === -1 || timeoutPropMs < earliestTimeoutMs) {
10595 earliestTimeoutMs = timeoutPropMs;
10596 }
10597 }
10598 }
10599 // If there is a DehydratedSuspenseComponent we don't have to do anything because
10600 // if something suspends inside it, we will simply leave that as dehydrated. It
10601 // will never timeout.
10602 _workInProgress = _workInProgress.return;
10603 } while (_workInProgress !== null);
10604
10605 // Schedule the nearest Suspense to re-render the timed out view.
10606 _workInProgress = returnFiber;
10607 do {
10608 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress)) {
10609 // Found the nearest boundary.
10610
10611 // Stash the promise on the boundary fiber. If the boundary times out, we'll
10612 var thenables = _workInProgress.updateQueue;
10613 if (thenables === null) {
10614 var updateQueue = new Set();
10615 updateQueue.add(thenable);
10616 _workInProgress.updateQueue = updateQueue;
10617 } else {
10618 thenables.add(thenable);
10619 }
10620
10621 // If the boundary is outside of concurrent mode, we should *not*
10622 // suspend the commit. Pretend as if the suspended component rendered
10623 // null and keep rendering. In the commit phase, we'll schedule a
10624 // subsequent synchronous update to re-render the Suspense.
10625 //
10626 // Note: It doesn't matter whether the component that suspended was
10627 // inside a concurrent mode tree. If the Suspense is outside of it, we
10628 // should *not* suspend the commit.
10629 if ((_workInProgress.mode & ConcurrentMode) === NoEffect) {
10630 _workInProgress.effectTag |= DidCapture;
10631
10632 // We're going to commit this fiber even though it didn't complete.
10633 // But we shouldn't call any lifecycle methods or callbacks. Remove
10634 // all lifecycle effect tags.
10635 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
10636
10637 if (sourceFiber.tag === ClassComponent) {
10638 var currentSourceFiber = sourceFiber.alternate;
10639 if (currentSourceFiber === null) {
10640 // This is a new mount. Change the tag so it's not mistaken for a
10641 // completed class component. For example, we should not call
10642 // componentWillUnmount if it is deleted.
10643 sourceFiber.tag = IncompleteClassComponent;
10644 } else {
10645 // When we try rendering again, we should not reuse the current fiber,
10646 // since it's known to be in an inconsistent state. Use a force updte to
10647 // prevent a bail out.
10648 var update = createUpdate(Sync);
10649 update.tag = ForceUpdate;
10650 enqueueUpdate(sourceFiber, update);
10651 }
10652 }
10653
10654 // The source fiber did not complete. Mark it with Sync priority to
10655 // indicate that it still has pending work.
10656 sourceFiber.expirationTime = Sync;
10657
10658 // Exit without suspending.
10659 return;
10660 }
10661
10662 // Confirmed that the boundary is in a concurrent mode tree. Continue
10663 // with the normal suspend path.
10664
10665 attachPingListener(root, renderExpirationTime, thenable);
10666
10667 var absoluteTimeoutMs = void 0;
10668 if (earliestTimeoutMs === -1) {
10669 // If no explicit threshold is given, default to an arbitrarily large
10670 // value. The actual size doesn't matter because the threshold for the
10671 // whole tree will be clamped to the expiration time.
10672 absoluteTimeoutMs = maxSigned31BitInt;
10673 } else {
10674 if (startTimeMs === -1) {
10675 // This suspend happened outside of any already timed-out
10676 // placeholders. We don't know exactly when the update was
10677 // scheduled, but we can infer an approximate start time from the
10678 // expiration time. First, find the earliest uncommitted expiration
10679 // time in the tree, including work that is suspended. Then subtract
10680 // the offset used to compute an async update's expiration time.
10681 // This will cause high priority (interactive) work to expire
10682 // earlier than necessary, but we can account for this by adjusting
10683 // for the Just Noticeable Difference.
10684 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, renderExpirationTime);
10685 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
10686 startTimeMs = earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
10687 }
10688 absoluteTimeoutMs = startTimeMs + earliestTimeoutMs;
10689 }
10690
10691 // Mark the earliest timeout in the suspended fiber's ancestor path.
10692 // After completing the root, we'll take the largest of all the
10693 // suspended fiber's timeouts and use it to compute a timeout for the
10694 // whole tree.
10695 renderDidSuspend(root, absoluteTimeoutMs, renderExpirationTime);
10696
10697 _workInProgress.effectTag |= ShouldCapture;
10698 _workInProgress.expirationTime = renderExpirationTime;
10699 return;
10700 } else if (enableSuspenseServerRenderer && _workInProgress.tag === DehydratedSuspenseComponent) {
10701 attachPingListener(root, renderExpirationTime, thenable);
10702
10703 // Since we already have a current fiber, we can eagerly add a retry listener.
10704 var retryCache = _workInProgress.memoizedState;
10705 if (retryCache === null) {
10706 retryCache = _workInProgress.memoizedState = new PossiblyWeakSet();
10707 var _current = _workInProgress.alternate;
10708 !_current ? invariant(false, 'A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React.') : void 0;
10709 _current.memoizedState = retryCache;
10710 }
10711 // Memoize using the boundary fiber to prevent redundant listeners.
10712 if (!retryCache.has(thenable)) {
10713 retryCache.add(thenable);
10714 var retry = retryTimedOutBoundary.bind(null, _workInProgress, thenable);
10715 if (enableSchedulerTracing) {
10716 retry = unstable_wrap(retry);
10717 }
10718 thenable.then(retry, retry);
10719 }
10720 _workInProgress.effectTag |= ShouldCapture;
10721 _workInProgress.expirationTime = renderExpirationTime;
10722 return;
10723 }
10724 // This boundary already captured during this render. Continue to the next
10725 // boundary.
10726 _workInProgress = _workInProgress.return;
10727 } while (_workInProgress !== null);
10728 // No boundary was found. Fallthrough to error mode.
10729 // TODO: Use invariant so the message is stripped in prod?
10730 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));
10731 }
10732
10733 // We didn't find a boundary that could handle this type of exception. Start
10734 // over and traverse parent path again, this time treating the exception
10735 // as an error.
10736 renderDidError();
10737 value = createCapturedValue(value, sourceFiber);
10738 var workInProgress = returnFiber;
10739 do {
10740 switch (workInProgress.tag) {
10741 case HostRoot:
10742 {
10743 var _errorInfo = value;
10744 workInProgress.effectTag |= ShouldCapture;
10745 workInProgress.expirationTime = renderExpirationTime;
10746 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
10747 enqueueCapturedUpdate(workInProgress, _update);
10748 return;
10749 }
10750 case ClassComponent:
10751 // Capture and retry
10752 var errorInfo = value;
10753 var ctor = workInProgress.type;
10754 var instance = workInProgress.stateNode;
10755 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
10756 workInProgress.effectTag |= ShouldCapture;
10757 workInProgress.expirationTime = renderExpirationTime;
10758 // Schedule the error boundary to re-render using updated state
10759 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
10760 enqueueCapturedUpdate(workInProgress, _update2);
10761 return;
10762 }
10763 break;
10764 default:
10765 break;
10766 }
10767 workInProgress = workInProgress.return;
10768 } while (workInProgress !== null);
10769}
10770
10771function unwindWork(workInProgress, renderExpirationTime) {
10772 switch (workInProgress.tag) {
10773 case ClassComponent:
10774 {
10775 var Component = workInProgress.type;
10776 if (isContextProvider(Component)) {
10777 popContext(workInProgress);
10778 }
10779 var effectTag = workInProgress.effectTag;
10780 if (effectTag & ShouldCapture) {
10781 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
10782 return workInProgress;
10783 }
10784 return null;
10785 }
10786 case HostRoot:
10787 {
10788 popHostContainer(workInProgress);
10789 popTopLevelContextObject(workInProgress);
10790 var _effectTag = workInProgress.effectTag;
10791 !((_effectTag & DidCapture) === NoEffect) ? invariant(false, 'The root failed to unmount after an error. This is likely a bug in React. Please file an issue.') : void 0;
10792 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
10793 return workInProgress;
10794 }
10795 case HostComponent:
10796 {
10797 // TODO: popHydrationState
10798 popHostContext(workInProgress);
10799 return null;
10800 }
10801 case SuspenseComponent:
10802 {
10803 var _effectTag2 = workInProgress.effectTag;
10804 if (_effectTag2 & ShouldCapture) {
10805 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture;
10806 // Captured a suspense effect. Re-render the boundary.
10807 return workInProgress;
10808 }
10809 return null;
10810 }
10811 case DehydratedSuspenseComponent:
10812 {
10813 if (enableSuspenseServerRenderer) {
10814 // TODO: popHydrationState
10815 var _effectTag3 = workInProgress.effectTag;
10816 if (_effectTag3 & ShouldCapture) {
10817 workInProgress.effectTag = _effectTag3 & ~ShouldCapture | DidCapture;
10818 // Captured a suspense effect. Re-render the boundary.
10819 return workInProgress;
10820 }
10821 }
10822 return null;
10823 }
10824 case HostPortal:
10825 popHostContainer(workInProgress);
10826 return null;
10827 case ContextProvider:
10828 popProvider(workInProgress);
10829 return null;
10830 default:
10831 return null;
10832 }
10833}
10834
10835function unwindInterruptedWork(interruptedWork) {
10836 switch (interruptedWork.tag) {
10837 case ClassComponent:
10838 {
10839 var childContextTypes = interruptedWork.type.childContextTypes;
10840 if (childContextTypes !== null && childContextTypes !== undefined) {
10841 popContext(interruptedWork);
10842 }
10843 break;
10844 }
10845 case HostRoot:
10846 {
10847 popHostContainer(interruptedWork);
10848 popTopLevelContextObject(interruptedWork);
10849 break;
10850 }
10851 case HostComponent:
10852 {
10853 popHostContext(interruptedWork);
10854 break;
10855 }
10856 case HostPortal:
10857 popHostContainer(interruptedWork);
10858 break;
10859 case ContextProvider:
10860 popProvider(interruptedWork);
10861 break;
10862 default:
10863 break;
10864 }
10865}
10866
10867var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
10868var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
10869
10870
10871var didWarnAboutStateTransition = void 0;
10872var didWarnSetStateChildContext = void 0;
10873var warnAboutUpdateOnUnmounted = void 0;
10874var warnAboutInvalidUpdates = void 0;
10875
10876if (enableSchedulerTracing) {
10877 // Provide explicit error message when production+profiling bundle of e.g. react-dom
10878 // is used with production (non-profiling) bundle of scheduler/tracing
10879 !(__interactionsRef != null && __interactionsRef.current != null) ? invariant(false, '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') : void 0;
10880}
10881
10882{
10883 didWarnAboutStateTransition = false;
10884 didWarnSetStateChildContext = false;
10885 var didWarnStateUpdateForUnmountedComponent = {};
10886
10887 warnAboutUpdateOnUnmounted = function (fiber, isClass) {
10888 // We show the whole stack but dedupe on the top component's name because
10889 // the problematic code almost always lies inside that component.
10890 var componentName = getComponentName(fiber.type) || 'ReactComponent';
10891 if (didWarnStateUpdateForUnmountedComponent[componentName]) {
10892 return;
10893 }
10894 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', isClass ? 'the componentWillUnmount method' : 'a useEffect cleanup function', getStackByFiberInDevAndProd(fiber));
10895 didWarnStateUpdateForUnmountedComponent[componentName] = true;
10896 };
10897
10898 warnAboutInvalidUpdates = function (instance) {
10899 switch (phase) {
10900 case 'getChildContext':
10901 if (didWarnSetStateChildContext) {
10902 return;
10903 }
10904 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
10905 didWarnSetStateChildContext = true;
10906 break;
10907 case 'render':
10908 if (didWarnAboutStateTransition) {
10909 return;
10910 }
10911 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.');
10912 didWarnAboutStateTransition = true;
10913 break;
10914 }
10915 };
10916}
10917
10918var isWorking = false;
10919
10920// The next work in progress fiber that we're currently working on.
10921var nextUnitOfWork = null;
10922var nextRoot = null;
10923// The time at which we're currently rendering work.
10924var nextRenderExpirationTime = NoWork;
10925var nextLatestAbsoluteTimeoutMs = -1;
10926var nextRenderDidError = false;
10927
10928// The next fiber with an effect that we're currently committing.
10929var nextEffect = null;
10930
10931var isCommitting$1 = false;
10932var rootWithPendingPassiveEffects = null;
10933var passiveEffectCallbackHandle = null;
10934var passiveEffectCallback = null;
10935
10936var legacyErrorBoundariesThatAlreadyFailed = null;
10937
10938// Used for performance tracking.
10939var interruptedBy = null;
10940
10941var stashedWorkInProgressProperties = void 0;
10942var replayUnitOfWork = void 0;
10943var mayReplayFailedUnitOfWork = void 0;
10944var isReplayingFailedUnitOfWork = void 0;
10945var originalReplayError = void 0;
10946var rethrowOriginalError = void 0;
10947if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
10948 stashedWorkInProgressProperties = null;
10949 mayReplayFailedUnitOfWork = true;
10950 isReplayingFailedUnitOfWork = false;
10951 originalReplayError = null;
10952 replayUnitOfWork = function (failedUnitOfWork, thrownValue, isYieldy) {
10953 if (thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function') {
10954 // Don't replay promises. Treat everything else like an error.
10955 // TODO: Need to figure out a different strategy if/when we add
10956 // support for catching other types.
10957 return;
10958 }
10959
10960 // Restore the original state of the work-in-progress
10961 if (stashedWorkInProgressProperties === null) {
10962 // This should never happen. Don't throw because this code is DEV-only.
10963 warningWithoutStack$1(false, 'Could not replay rendering after an error. This is likely a bug in React. ' + 'Please file an issue.');
10964 return;
10965 }
10966 assignFiberPropertiesInDEV(failedUnitOfWork, stashedWorkInProgressProperties);
10967
10968 switch (failedUnitOfWork.tag) {
10969 case HostRoot:
10970 popHostContainer(failedUnitOfWork);
10971 popTopLevelContextObject(failedUnitOfWork);
10972 break;
10973 case HostComponent:
10974 popHostContext(failedUnitOfWork);
10975 break;
10976 case ClassComponent:
10977 {
10978 var Component = failedUnitOfWork.type;
10979 if (isContextProvider(Component)) {
10980 popContext(failedUnitOfWork);
10981 }
10982 break;
10983 }
10984 case HostPortal:
10985 popHostContainer(failedUnitOfWork);
10986 break;
10987 case ContextProvider:
10988 popProvider(failedUnitOfWork);
10989 break;
10990 }
10991 // Replay the begin phase.
10992 isReplayingFailedUnitOfWork = true;
10993 originalReplayError = thrownValue;
10994 invokeGuardedCallback(null, workLoop, null, isYieldy);
10995 isReplayingFailedUnitOfWork = false;
10996 originalReplayError = null;
10997 if (hasCaughtError()) {
10998 var replayError = clearCaughtError();
10999 if (replayError != null && thrownValue != null) {
11000 try {
11001 // Reading the expando property is intentionally
11002 // inside `try` because it might be a getter or Proxy.
11003 if (replayError._suppressLogging) {
11004 // Also suppress logging for the original error.
11005 thrownValue._suppressLogging = true;
11006 }
11007 } catch (inner) {
11008 // Ignore.
11009 }
11010 }
11011 } else {
11012 // If the begin phase did not fail the second time, set this pointer
11013 // back to the original value.
11014 nextUnitOfWork = failedUnitOfWork;
11015 }
11016 };
11017 rethrowOriginalError = function () {
11018 throw originalReplayError;
11019 };
11020}
11021
11022function resetStack() {
11023 if (nextUnitOfWork !== null) {
11024 var interruptedWork = nextUnitOfWork.return;
11025 while (interruptedWork !== null) {
11026 unwindInterruptedWork(interruptedWork);
11027 interruptedWork = interruptedWork.return;
11028 }
11029 }
11030
11031 {
11032 ReactStrictModeWarnings.discardPendingWarnings();
11033 checkThatStackIsEmpty();
11034 }
11035
11036 nextRoot = null;
11037 nextRenderExpirationTime = NoWork;
11038 nextLatestAbsoluteTimeoutMs = -1;
11039 nextRenderDidError = false;
11040 nextUnitOfWork = null;
11041}
11042
11043function commitAllHostEffects() {
11044 while (nextEffect !== null) {
11045 {
11046 setCurrentFiber(nextEffect);
11047 }
11048 recordEffect();
11049
11050 var effectTag = nextEffect.effectTag;
11051
11052 if (effectTag & ContentReset) {
11053 commitResetTextContent(nextEffect);
11054 }
11055
11056 if (effectTag & Ref) {
11057 var current = nextEffect.alternate;
11058 if (current !== null) {
11059 commitDetachRef(current);
11060 }
11061 }
11062
11063 // The following switch statement is only concerned about placement,
11064 // updates, and deletions. To avoid needing to add a case for every
11065 // possible bitmap value, we remove the secondary effects from the
11066 // effect tag and switch on that value.
11067 var primaryEffectTag = effectTag & (Placement | Update | Deletion);
11068 switch (primaryEffectTag) {
11069 case Placement:
11070 {
11071 commitPlacement(nextEffect);
11072 // Clear the "placement" from effect tag so that we know that this is inserted, before
11073 // any life-cycles like componentDidMount gets called.
11074 // TODO: findDOMNode doesn't rely on this any more but isMounted
11075 // does and isMounted is deprecated anyway so we should be able
11076 // to kill this.
11077 nextEffect.effectTag &= ~Placement;
11078 break;
11079 }
11080 case PlacementAndUpdate:
11081 {
11082 // Placement
11083 commitPlacement(nextEffect);
11084 // Clear the "placement" from effect tag so that we know that this is inserted, before
11085 // any life-cycles like componentDidMount gets called.
11086 nextEffect.effectTag &= ~Placement;
11087
11088 // Update
11089 var _current = nextEffect.alternate;
11090 commitWork(_current, nextEffect);
11091 break;
11092 }
11093 case Update:
11094 {
11095 var _current2 = nextEffect.alternate;
11096 commitWork(_current2, nextEffect);
11097 break;
11098 }
11099 case Deletion:
11100 {
11101 commitDeletion(nextEffect);
11102 break;
11103 }
11104 }
11105 nextEffect = nextEffect.nextEffect;
11106 }
11107
11108 {
11109 resetCurrentFiber();
11110 }
11111}
11112
11113function commitBeforeMutationLifecycles() {
11114 while (nextEffect !== null) {
11115 {
11116 setCurrentFiber(nextEffect);
11117 }
11118
11119 var effectTag = nextEffect.effectTag;
11120 if (effectTag & Snapshot) {
11121 recordEffect();
11122 var current = nextEffect.alternate;
11123 commitBeforeMutationLifeCycles(current, nextEffect);
11124 }
11125
11126 nextEffect = nextEffect.nextEffect;
11127 }
11128
11129 {
11130 resetCurrentFiber();
11131 }
11132}
11133
11134function commitAllLifeCycles(finishedRoot, committedExpirationTime) {
11135 {
11136 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
11137 ReactStrictModeWarnings.flushLegacyContextWarning();
11138
11139 if (warnAboutDeprecatedLifecycles) {
11140 ReactStrictModeWarnings.flushPendingDeprecationWarnings();
11141 }
11142 }
11143 while (nextEffect !== null) {
11144 {
11145 setCurrentFiber(nextEffect);
11146 }
11147 var effectTag = nextEffect.effectTag;
11148
11149 if (effectTag & (Update | Callback)) {
11150 recordEffect();
11151 var current = nextEffect.alternate;
11152 commitLifeCycles(finishedRoot, current, nextEffect, committedExpirationTime);
11153 }
11154
11155 if (effectTag & Ref) {
11156 recordEffect();
11157 commitAttachRef(nextEffect);
11158 }
11159
11160 if (effectTag & Passive) {
11161 rootWithPendingPassiveEffects = finishedRoot;
11162 }
11163
11164 nextEffect = nextEffect.nextEffect;
11165 }
11166 {
11167 resetCurrentFiber();
11168 }
11169}
11170
11171function commitPassiveEffects(root, firstEffect) {
11172 rootWithPendingPassiveEffects = null;
11173 passiveEffectCallbackHandle = null;
11174 passiveEffectCallback = null;
11175
11176 // Set this to true to prevent re-entrancy
11177 var previousIsRendering = isRendering;
11178 isRendering = true;
11179
11180 var effect = firstEffect;
11181 do {
11182 {
11183 setCurrentFiber(effect);
11184 }
11185
11186 if (effect.effectTag & Passive) {
11187 var didError = false;
11188 var error = void 0;
11189 {
11190 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
11191 if (hasCaughtError()) {
11192 didError = true;
11193 error = clearCaughtError();
11194 }
11195 }
11196 if (didError) {
11197 captureCommitPhaseError(effect, error);
11198 }
11199 }
11200 effect = effect.nextEffect;
11201 } while (effect !== null);
11202 {
11203 resetCurrentFiber();
11204 }
11205
11206 isRendering = previousIsRendering;
11207
11208 // Check if work was scheduled by one of the effects
11209 var rootExpirationTime = root.expirationTime;
11210 if (rootExpirationTime !== NoWork) {
11211 requestWork(root, rootExpirationTime);
11212 }
11213 // Flush any sync work that was scheduled by effects
11214 if (!isBatchingUpdates && !isRendering) {
11215 performSyncWork();
11216 }
11217}
11218
11219function isAlreadyFailedLegacyErrorBoundary(instance) {
11220 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
11221}
11222
11223function markLegacyErrorBoundaryAsFailed(instance) {
11224 if (legacyErrorBoundariesThatAlreadyFailed === null) {
11225 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
11226 } else {
11227 legacyErrorBoundariesThatAlreadyFailed.add(instance);
11228 }
11229}
11230
11231function flushPassiveEffects() {
11232 if (passiveEffectCallbackHandle !== null) {
11233 cancelPassiveEffects(passiveEffectCallbackHandle);
11234 }
11235 if (passiveEffectCallback !== null) {
11236 // We call the scheduled callback instead of commitPassiveEffects directly
11237 // to ensure tracing works correctly.
11238 passiveEffectCallback();
11239 }
11240}
11241
11242function commitRoot(root, finishedWork) {
11243 isWorking = true;
11244 isCommitting$1 = true;
11245 startCommitTimer();
11246
11247 !(root.current !== finishedWork) ? invariant(false, 'Cannot commit the same tree as before. This is probably a bug related to the return field. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11248 var committedExpirationTime = root.pendingCommitExpirationTime;
11249 !(committedExpirationTime !== NoWork) ? invariant(false, 'Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11250 root.pendingCommitExpirationTime = NoWork;
11251
11252 // Update the pending priority levels to account for the work that we are
11253 // about to commit. This needs to happen before calling the lifecycles, since
11254 // they may schedule additional updates.
11255 var updateExpirationTimeBeforeCommit = finishedWork.expirationTime;
11256 var childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;
11257 var earliestRemainingTimeBeforeCommit = childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit ? childExpirationTimeBeforeCommit : updateExpirationTimeBeforeCommit;
11258 markCommittedPriorityLevels(root, earliestRemainingTimeBeforeCommit);
11259
11260 var prevInteractions = null;
11261 if (enableSchedulerTracing) {
11262 // Restore any pending interactions at this point,
11263 // So that cascading work triggered during the render phase will be accounted for.
11264 prevInteractions = __interactionsRef.current;
11265 __interactionsRef.current = root.memoizedInteractions;
11266 }
11267
11268 // Reset this to null before calling lifecycles
11269 ReactCurrentOwner$1.current = null;
11270
11271 var firstEffect = void 0;
11272 if (finishedWork.effectTag > PerformedWork) {
11273 // A fiber's effect list consists only of its children, not itself. So if
11274 // the root has an effect, we need to add it to the end of the list. The
11275 // resulting list is the set that would belong to the root's parent, if
11276 // it had one; that is, all the effects in the tree including the root.
11277 if (finishedWork.lastEffect !== null) {
11278 finishedWork.lastEffect.nextEffect = finishedWork;
11279 firstEffect = finishedWork.firstEffect;
11280 } else {
11281 firstEffect = finishedWork;
11282 }
11283 } else {
11284 // There is no effect on the root.
11285 firstEffect = finishedWork.firstEffect;
11286 }
11287
11288 prepareForCommit(root.containerInfo);
11289
11290 // Invoke instances of getSnapshotBeforeUpdate before mutation.
11291 nextEffect = firstEffect;
11292 startCommitSnapshotEffectsTimer();
11293 while (nextEffect !== null) {
11294 var didError = false;
11295 var error = void 0;
11296 {
11297 invokeGuardedCallback(null, commitBeforeMutationLifecycles, null);
11298 if (hasCaughtError()) {
11299 didError = true;
11300 error = clearCaughtError();
11301 }
11302 }
11303 if (didError) {
11304 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11305 captureCommitPhaseError(nextEffect, error);
11306 // Clean-up
11307 if (nextEffect !== null) {
11308 nextEffect = nextEffect.nextEffect;
11309 }
11310 }
11311 }
11312 stopCommitSnapshotEffectsTimer();
11313
11314 if (enableProfilerTimer) {
11315 // Mark the current commit time to be shared by all Profilers in this batch.
11316 // This enables them to be grouped later.
11317 recordCommitTime();
11318 }
11319
11320 // Commit all the side-effects within a tree. We'll do this in two passes.
11321 // The first pass performs all the host insertions, updates, deletions and
11322 // ref unmounts.
11323 nextEffect = firstEffect;
11324 startCommitHostEffectsTimer();
11325 while (nextEffect !== null) {
11326 var _didError = false;
11327 var _error = void 0;
11328 {
11329 invokeGuardedCallback(null, commitAllHostEffects, null);
11330 if (hasCaughtError()) {
11331 _didError = true;
11332 _error = clearCaughtError();
11333 }
11334 }
11335 if (_didError) {
11336 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11337 captureCommitPhaseError(nextEffect, _error);
11338 // Clean-up
11339 if (nextEffect !== null) {
11340 nextEffect = nextEffect.nextEffect;
11341 }
11342 }
11343 }
11344 stopCommitHostEffectsTimer();
11345
11346 resetAfterCommit(root.containerInfo);
11347
11348 // The work-in-progress tree is now the current tree. This must come after
11349 // the first pass of the commit phase, so that the previous tree is still
11350 // current during componentWillUnmount, but before the second pass, so that
11351 // the finished work is current during componentDidMount/Update.
11352 root.current = finishedWork;
11353
11354 // In the second pass we'll perform all life-cycles and ref callbacks.
11355 // Life-cycles happen as a separate pass so that all placements, updates,
11356 // and deletions in the entire tree have already been invoked.
11357 // This pass also triggers any renderer-specific initial effects.
11358 nextEffect = firstEffect;
11359 startCommitLifeCyclesTimer();
11360 while (nextEffect !== null) {
11361 var _didError2 = false;
11362 var _error2 = void 0;
11363 {
11364 invokeGuardedCallback(null, commitAllLifeCycles, null, root, committedExpirationTime);
11365 if (hasCaughtError()) {
11366 _didError2 = true;
11367 _error2 = clearCaughtError();
11368 }
11369 }
11370 if (_didError2) {
11371 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11372 captureCommitPhaseError(nextEffect, _error2);
11373 if (nextEffect !== null) {
11374 nextEffect = nextEffect.nextEffect;
11375 }
11376 }
11377 }
11378
11379 if (firstEffect !== null && rootWithPendingPassiveEffects !== null) {
11380 // This commit included a passive effect. These do not need to fire until
11381 // after the next paint. Schedule an callback to fire them in an async
11382 // event. To ensure serial execution, the callback will be flushed early if
11383 // we enter rootWithPendingPassiveEffects commit phase before then.
11384 var callback = commitPassiveEffects.bind(null, root, firstEffect);
11385 if (enableSchedulerTracing) {
11386 // TODO: Avoid this extra callback by mutating the tracing ref directly,
11387 // like we do at the beginning of commitRoot. I've opted not to do that
11388 // here because that code is still in flux.
11389 callback = unstable_wrap(callback);
11390 }
11391 passiveEffectCallbackHandle = unstable_runWithPriority(unstable_NormalPriority, function () {
11392 return schedulePassiveEffects(callback);
11393 });
11394 passiveEffectCallback = callback;
11395 }
11396
11397 isCommitting$1 = false;
11398 isWorking = false;
11399 stopCommitLifeCyclesTimer();
11400 stopCommitTimer();
11401 onCommitRoot(finishedWork.stateNode);
11402 if (true && ReactFiberInstrumentation_1.debugTool) {
11403 ReactFiberInstrumentation_1.debugTool.onCommitWork(finishedWork);
11404 }
11405
11406 var updateExpirationTimeAfterCommit = finishedWork.expirationTime;
11407 var childExpirationTimeAfterCommit = finishedWork.childExpirationTime;
11408 var earliestRemainingTimeAfterCommit = childExpirationTimeAfterCommit > updateExpirationTimeAfterCommit ? childExpirationTimeAfterCommit : updateExpirationTimeAfterCommit;
11409 if (earliestRemainingTimeAfterCommit === NoWork) {
11410 // If there's no remaining work, we can clear the set of already failed
11411 // error boundaries.
11412 legacyErrorBoundariesThatAlreadyFailed = null;
11413 }
11414 onCommit(root, earliestRemainingTimeAfterCommit);
11415
11416 if (enableSchedulerTracing) {
11417 __interactionsRef.current = prevInteractions;
11418
11419 var subscriber = void 0;
11420
11421 try {
11422 subscriber = __subscriberRef.current;
11423 if (subscriber !== null && root.memoizedInteractions.size > 0) {
11424 var threadID = computeThreadID(committedExpirationTime, root.interactionThreadID);
11425 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
11426 }
11427 } catch (error) {
11428 // It's not safe for commitRoot() to throw.
11429 // Store the error for now and we'll re-throw in finishRendering().
11430 if (!hasUnhandledError) {
11431 hasUnhandledError = true;
11432 unhandledError = error;
11433 }
11434 } finally {
11435 // Clear completed interactions from the pending Map.
11436 // Unless the render was suspended or cascading work was scheduled,
11437 // In which case– leave pending interactions until the subsequent render.
11438 var pendingInteractionMap = root.pendingInteractionMap;
11439 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
11440 // Only decrement the pending interaction count if we're done.
11441 // If there's still work at the current priority,
11442 // That indicates that we are waiting for suspense data.
11443 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
11444 pendingInteractionMap.delete(scheduledExpirationTime);
11445
11446 scheduledInteractions.forEach(function (interaction) {
11447 interaction.__count--;
11448
11449 if (subscriber !== null && interaction.__count === 0) {
11450 try {
11451 subscriber.onInteractionScheduledWorkCompleted(interaction);
11452 } catch (error) {
11453 // It's not safe for commitRoot() to throw.
11454 // Store the error for now and we'll re-throw in finishRendering().
11455 if (!hasUnhandledError) {
11456 hasUnhandledError = true;
11457 unhandledError = error;
11458 }
11459 }
11460 }
11461 });
11462 }
11463 });
11464 }
11465 }
11466}
11467
11468function resetChildExpirationTime(workInProgress, renderTime) {
11469 if (renderTime !== Never && workInProgress.childExpirationTime === Never) {
11470 // The children of this component are hidden. Don't bubble their
11471 // expiration times.
11472 return;
11473 }
11474
11475 var newChildExpirationTime = NoWork;
11476
11477 // Bubble up the earliest expiration time.
11478 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
11479 // We're in profiling mode.
11480 // Let's use this same traversal to update the render durations.
11481 var actualDuration = workInProgress.actualDuration;
11482 var treeBaseDuration = workInProgress.selfBaseDuration;
11483
11484 // When a fiber is cloned, its actualDuration is reset to 0.
11485 // This value will only be updated if work is done on the fiber (i.e. it doesn't bailout).
11486 // When work is done, it should bubble to the parent's actualDuration.
11487 // If the fiber has not been cloned though, (meaning no work was done),
11488 // Then this value will reflect the amount of time spent working on a previous render.
11489 // In that case it should not bubble.
11490 // We determine whether it was cloned by comparing the child pointer.
11491 var shouldBubbleActualDurations = workInProgress.alternate === null || workInProgress.child !== workInProgress.alternate.child;
11492
11493 var child = workInProgress.child;
11494 while (child !== null) {
11495 var childUpdateExpirationTime = child.expirationTime;
11496 var childChildExpirationTime = child.childExpirationTime;
11497 if (childUpdateExpirationTime > newChildExpirationTime) {
11498 newChildExpirationTime = childUpdateExpirationTime;
11499 }
11500 if (childChildExpirationTime > newChildExpirationTime) {
11501 newChildExpirationTime = childChildExpirationTime;
11502 }
11503 if (shouldBubbleActualDurations) {
11504 actualDuration += child.actualDuration;
11505 }
11506 treeBaseDuration += child.treeBaseDuration;
11507 child = child.sibling;
11508 }
11509 workInProgress.actualDuration = actualDuration;
11510 workInProgress.treeBaseDuration = treeBaseDuration;
11511 } else {
11512 var _child = workInProgress.child;
11513 while (_child !== null) {
11514 var _childUpdateExpirationTime = _child.expirationTime;
11515 var _childChildExpirationTime = _child.childExpirationTime;
11516 if (_childUpdateExpirationTime > newChildExpirationTime) {
11517 newChildExpirationTime = _childUpdateExpirationTime;
11518 }
11519 if (_childChildExpirationTime > newChildExpirationTime) {
11520 newChildExpirationTime = _childChildExpirationTime;
11521 }
11522 _child = _child.sibling;
11523 }
11524 }
11525
11526 workInProgress.childExpirationTime = newChildExpirationTime;
11527}
11528
11529function completeUnitOfWork(workInProgress) {
11530 // Attempt to complete the current unit of work, then move to the
11531 // next sibling. If there are no more siblings, return to the
11532 // parent fiber.
11533 while (true) {
11534 // The current, flushed, state of this fiber is the alternate.
11535 // Ideally nothing should rely on this, but relying on it here
11536 // means that we don't need an additional field on the work in
11537 // progress.
11538 var current = workInProgress.alternate;
11539 {
11540 setCurrentFiber(workInProgress);
11541 }
11542
11543 var returnFiber = workInProgress.return;
11544 var siblingFiber = workInProgress.sibling;
11545
11546 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
11547 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11548 // Don't replay if it fails during completion phase.
11549 mayReplayFailedUnitOfWork = false;
11550 }
11551 // This fiber completed.
11552 // Remember we're completing this unit so we can find a boundary if it fails.
11553 nextUnitOfWork = workInProgress;
11554 if (enableProfilerTimer) {
11555 if (workInProgress.mode & ProfileMode) {
11556 startProfilerTimer(workInProgress);
11557 }
11558 nextUnitOfWork = completeWork(current, workInProgress, nextRenderExpirationTime);
11559 if (workInProgress.mode & ProfileMode) {
11560 // Update render duration assuming we didn't error.
11561 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
11562 }
11563 } else {
11564 nextUnitOfWork = completeWork(current, workInProgress, nextRenderExpirationTime);
11565 }
11566 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11567 // We're out of completion phase so replaying is fine now.
11568 mayReplayFailedUnitOfWork = true;
11569 }
11570 stopWorkTimer(workInProgress);
11571 resetChildExpirationTime(workInProgress, nextRenderExpirationTime);
11572 {
11573 resetCurrentFiber();
11574 }
11575
11576 if (nextUnitOfWork !== null) {
11577 // Completing this fiber spawned new work. Work on that next.
11578 return nextUnitOfWork;
11579 }
11580
11581 if (returnFiber !== null &&
11582 // Do not append effects to parents if a sibling failed to complete
11583 (returnFiber.effectTag & Incomplete) === NoEffect) {
11584 // Append all the effects of the subtree and this fiber onto the effect
11585 // list of the parent. The completion order of the children affects the
11586 // side-effect order.
11587 if (returnFiber.firstEffect === null) {
11588 returnFiber.firstEffect = workInProgress.firstEffect;
11589 }
11590 if (workInProgress.lastEffect !== null) {
11591 if (returnFiber.lastEffect !== null) {
11592 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
11593 }
11594 returnFiber.lastEffect = workInProgress.lastEffect;
11595 }
11596
11597 // If this fiber had side-effects, we append it AFTER the children's
11598 // side-effects. We can perform certain side-effects earlier if
11599 // needed, by doing multiple passes over the effect list. We don't want
11600 // to schedule our own side-effect on our own list because if end up
11601 // reusing children we'll schedule this effect onto itself since we're
11602 // at the end.
11603 var effectTag = workInProgress.effectTag;
11604 // Skip both NoWork and PerformedWork tags when creating the effect list.
11605 // PerformedWork effect is read by React DevTools but shouldn't be committed.
11606 if (effectTag > PerformedWork) {
11607 if (returnFiber.lastEffect !== null) {
11608 returnFiber.lastEffect.nextEffect = workInProgress;
11609 } else {
11610 returnFiber.firstEffect = workInProgress;
11611 }
11612 returnFiber.lastEffect = workInProgress;
11613 }
11614 }
11615
11616 if (true && ReactFiberInstrumentation_1.debugTool) {
11617 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11618 }
11619
11620 if (siblingFiber !== null) {
11621 // If there is more work to do in this returnFiber, do that next.
11622 return siblingFiber;
11623 } else if (returnFiber !== null) {
11624 // If there's no more work in this returnFiber. Complete the returnFiber.
11625 workInProgress = returnFiber;
11626 continue;
11627 } else {
11628 // We've reached the root.
11629 return null;
11630 }
11631 } else {
11632 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
11633 // Record the render duration for the fiber that errored.
11634 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
11635
11636 // Include the time spent working on failed children before continuing.
11637 var actualDuration = workInProgress.actualDuration;
11638 var child = workInProgress.child;
11639 while (child !== null) {
11640 actualDuration += child.actualDuration;
11641 child = child.sibling;
11642 }
11643 workInProgress.actualDuration = actualDuration;
11644 }
11645
11646 // This fiber did not complete because something threw. Pop values off
11647 // the stack without entering the complete phase. If this is a boundary,
11648 // capture values if possible.
11649 var next = unwindWork(workInProgress, nextRenderExpirationTime);
11650 // Because this fiber did not complete, don't reset its expiration time.
11651 if (workInProgress.effectTag & DidCapture) {
11652 // Restarting an error boundary
11653 stopFailedWorkTimer(workInProgress);
11654 } else {
11655 stopWorkTimer(workInProgress);
11656 }
11657
11658 {
11659 resetCurrentFiber();
11660 }
11661
11662 if (next !== null) {
11663 stopWorkTimer(workInProgress);
11664 if (true && ReactFiberInstrumentation_1.debugTool) {
11665 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11666 }
11667
11668 // If completing this work spawned new work, do that next. We'll come
11669 // back here again.
11670 // Since we're restarting, remove anything that is not a host effect
11671 // from the effect tag.
11672 next.effectTag &= HostEffectMask;
11673 return next;
11674 }
11675
11676 if (returnFiber !== null) {
11677 // Mark the parent fiber as incomplete and clear its effect list.
11678 returnFiber.firstEffect = returnFiber.lastEffect = null;
11679 returnFiber.effectTag |= Incomplete;
11680 }
11681
11682 if (true && ReactFiberInstrumentation_1.debugTool) {
11683 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11684 }
11685
11686 if (siblingFiber !== null) {
11687 // If there is more work to do in this returnFiber, do that next.
11688 return siblingFiber;
11689 } else if (returnFiber !== null) {
11690 // If there's no more work in this returnFiber. Complete the returnFiber.
11691 workInProgress = returnFiber;
11692 continue;
11693 } else {
11694 return null;
11695 }
11696 }
11697 }
11698
11699 // Without this explicit null return Flow complains of invalid return type
11700 // TODO Remove the above while(true) loop
11701 // eslint-disable-next-line no-unreachable
11702 return null;
11703}
11704
11705function performUnitOfWork(workInProgress) {
11706 // The current, flushed, state of this fiber is the alternate.
11707 // Ideally nothing should rely on this, but relying on it here
11708 // means that we don't need an additional field on the work in
11709 // progress.
11710 var current = workInProgress.alternate;
11711
11712 // See if beginning this work spawns more work.
11713 startWorkTimer(workInProgress);
11714 {
11715 setCurrentFiber(workInProgress);
11716 }
11717
11718 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11719 stashedWorkInProgressProperties = assignFiberPropertiesInDEV(stashedWorkInProgressProperties, workInProgress);
11720 }
11721
11722 var next = void 0;
11723 if (enableProfilerTimer) {
11724 if (workInProgress.mode & ProfileMode) {
11725 startProfilerTimer(workInProgress);
11726 }
11727
11728 next = beginWork(current, workInProgress, nextRenderExpirationTime);
11729 workInProgress.memoizedProps = workInProgress.pendingProps;
11730
11731 if (workInProgress.mode & ProfileMode) {
11732 // Record the render duration assuming we didn't bailout (or error).
11733 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
11734 }
11735 } else {
11736 next = beginWork(current, workInProgress, nextRenderExpirationTime);
11737 workInProgress.memoizedProps = workInProgress.pendingProps;
11738 }
11739
11740 {
11741 resetCurrentFiber();
11742 if (isReplayingFailedUnitOfWork) {
11743 // Currently replaying a failed unit of work. This should be unreachable,
11744 // because the render phase is meant to be idempotent, and it should
11745 // have thrown again. Since it didn't, rethrow the original error, so
11746 // React's internal stack is not misaligned.
11747 rethrowOriginalError();
11748 }
11749 }
11750 if (true && ReactFiberInstrumentation_1.debugTool) {
11751 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
11752 }
11753
11754 if (next === null) {
11755 // If this doesn't spawn new work, complete the current work.
11756 next = completeUnitOfWork(workInProgress);
11757 }
11758
11759 ReactCurrentOwner$1.current = null;
11760
11761 return next;
11762}
11763
11764function workLoop(isYieldy) {
11765 if (!isYieldy) {
11766 // Flush work without yielding
11767 while (nextUnitOfWork !== null) {
11768 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11769 }
11770 } else {
11771 // Flush asynchronous work until there's a higher priority event
11772 while (nextUnitOfWork !== null && !shouldYieldToRenderer()) {
11773 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11774 }
11775 }
11776}
11777
11778function renderRoot(root, isYieldy) {
11779 !!isWorking ? invariant(false, 'renderRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11780
11781 flushPassiveEffects();
11782
11783 isWorking = true;
11784 var previousDispatcher = ReactCurrentDispatcher.current;
11785 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
11786
11787 var expirationTime = root.nextExpirationTimeToWorkOn;
11788
11789 // Check if we're starting from a fresh stack, or if we're resuming from
11790 // previously yielded work.
11791 if (expirationTime !== nextRenderExpirationTime || root !== nextRoot || nextUnitOfWork === null) {
11792 // Reset the stack and start working from the root.
11793 resetStack();
11794 nextRoot = root;
11795 nextRenderExpirationTime = expirationTime;
11796 nextUnitOfWork = createWorkInProgress(nextRoot.current, null, nextRenderExpirationTime);
11797 root.pendingCommitExpirationTime = NoWork;
11798
11799 if (enableSchedulerTracing) {
11800 // Determine which interactions this batch of work currently includes,
11801 // So that we can accurately attribute time spent working on it,
11802 var interactions = new Set();
11803 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
11804 if (scheduledExpirationTime >= expirationTime) {
11805 scheduledInteractions.forEach(function (interaction) {
11806 return interactions.add(interaction);
11807 });
11808 }
11809 });
11810
11811 // Store the current set of interactions on the FiberRoot for a few reasons:
11812 // We can re-use it in hot functions like renderRoot() without having to recalculate it.
11813 // We will also use it in commitWork() to pass to any Profiler onRender() hooks.
11814 // This also provides DevTools with a way to access it when the onCommitRoot() hook is called.
11815 root.memoizedInteractions = interactions;
11816
11817 if (interactions.size > 0) {
11818 var subscriber = __subscriberRef.current;
11819 if (subscriber !== null) {
11820 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
11821 try {
11822 subscriber.onWorkStarted(interactions, threadID);
11823 } catch (error) {
11824 // Work thrown by an interaction tracing subscriber should be rethrown,
11825 // But only once it's safe (to avoid leaving the scheduler in an invalid state).
11826 // Store the error for now and we'll re-throw in finishRendering().
11827 if (!hasUnhandledError) {
11828 hasUnhandledError = true;
11829 unhandledError = error;
11830 }
11831 }
11832 }
11833 }
11834 }
11835 }
11836
11837 var prevInteractions = null;
11838 if (enableSchedulerTracing) {
11839 // We're about to start new traced work.
11840 // Restore pending interactions so cascading work triggered during the render phase will be accounted for.
11841 prevInteractions = __interactionsRef.current;
11842 __interactionsRef.current = root.memoizedInteractions;
11843 }
11844
11845 var didFatal = false;
11846
11847 startWorkLoopTimer(nextUnitOfWork);
11848
11849 do {
11850 try {
11851 workLoop(isYieldy);
11852 } catch (thrownValue) {
11853 resetContextDependences();
11854 resetHooks();
11855
11856 // Reset in case completion throws.
11857 // This is only used in DEV and when replaying is on.
11858 var mayReplay = void 0;
11859 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11860 mayReplay = mayReplayFailedUnitOfWork;
11861 mayReplayFailedUnitOfWork = true;
11862 }
11863
11864 if (nextUnitOfWork === null) {
11865 // This is a fatal error.
11866 didFatal = true;
11867 onUncaughtError(thrownValue);
11868 } else {
11869 if (enableProfilerTimer && nextUnitOfWork.mode & ProfileMode) {
11870 // Record the time spent rendering before an error was thrown.
11871 // This avoids inaccurate Profiler durations in the case of a suspended render.
11872 stopProfilerTimerIfRunningAndRecordDelta(nextUnitOfWork, true);
11873 }
11874
11875 {
11876 // Reset global debug state
11877 // We assume this is defined in DEV
11878 resetCurrentlyProcessingQueue();
11879 }
11880
11881 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11882 if (mayReplay) {
11883 var failedUnitOfWork = nextUnitOfWork;
11884 replayUnitOfWork(failedUnitOfWork, thrownValue, isYieldy);
11885 }
11886 }
11887
11888 // TODO: we already know this isn't true in some cases.
11889 // At least this shows a nicer error message until we figure out the cause.
11890 // https://github.com/facebook/react/issues/12449#issuecomment-386727431
11891 !(nextUnitOfWork !== null) ? invariant(false, 'Failed to replay rendering after an error. This is likely caused by a bug in React. Please file an issue with a reproducing case to help us find it.') : void 0;
11892
11893 var sourceFiber = nextUnitOfWork;
11894 var returnFiber = sourceFiber.return;
11895 if (returnFiber === null) {
11896 // This is the root. The root could capture its own errors. However,
11897 // we don't know if it errors before or after we pushed the host
11898 // context. This information is needed to avoid a stack mismatch.
11899 // Because we're not sure, treat this as a fatal error. We could track
11900 // which phase it fails in, but doesn't seem worth it. At least
11901 // for now.
11902 didFatal = true;
11903 onUncaughtError(thrownValue);
11904 } else {
11905 throwException(root, returnFiber, sourceFiber, thrownValue, nextRenderExpirationTime);
11906 nextUnitOfWork = completeUnitOfWork(sourceFiber);
11907 continue;
11908 }
11909 }
11910 }
11911 break;
11912 } while (true);
11913
11914 if (enableSchedulerTracing) {
11915 // Traced work is done for now; restore the previous interactions.
11916 __interactionsRef.current = prevInteractions;
11917 }
11918
11919 // We're done performing work. Time to clean up.
11920 isWorking = false;
11921 ReactCurrentDispatcher.current = previousDispatcher;
11922 resetContextDependences();
11923 resetHooks();
11924
11925 // Yield back to main thread.
11926 if (didFatal) {
11927 var _didCompleteRoot = false;
11928 stopWorkLoopTimer(interruptedBy, _didCompleteRoot);
11929 interruptedBy = null;
11930 // There was a fatal error.
11931 {
11932 resetStackAfterFatalErrorInDev();
11933 }
11934 // `nextRoot` points to the in-progress root. A non-null value indicates
11935 // that we're in the middle of an async render. Set it to null to indicate
11936 // there's no more work to be done in the current batch.
11937 nextRoot = null;
11938 onFatal(root);
11939 return;
11940 }
11941
11942 if (nextUnitOfWork !== null) {
11943 // There's still remaining async work in this tree, but we ran out of time
11944 // in the current frame. Yield back to the renderer. Unless we're
11945 // interrupted by a higher priority update, we'll continue later from where
11946 // we left off.
11947 var _didCompleteRoot2 = false;
11948 stopWorkLoopTimer(interruptedBy, _didCompleteRoot2);
11949 interruptedBy = null;
11950 onYield(root);
11951 return;
11952 }
11953
11954 // We completed the whole tree.
11955 var didCompleteRoot = true;
11956 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
11957 var rootWorkInProgress = root.current.alternate;
11958 !(rootWorkInProgress !== null) ? invariant(false, 'Finished root should have a work-in-progress. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11959
11960 // `nextRoot` points to the in-progress root. A non-null value indicates
11961 // that we're in the middle of an async render. Set it to null to indicate
11962 // there's no more work to be done in the current batch.
11963 nextRoot = null;
11964 interruptedBy = null;
11965
11966 if (nextRenderDidError) {
11967 // There was an error
11968 if (hasLowerPriorityWork(root, expirationTime)) {
11969 // There's lower priority work. If so, it may have the effect of fixing
11970 // the exception that was just thrown. Exit without committing. This is
11971 // similar to a suspend, but without a timeout because we're not waiting
11972 // for a promise to resolve. React will restart at the lower
11973 // priority level.
11974 markSuspendedPriorityLevel(root, expirationTime);
11975 var suspendedExpirationTime = expirationTime;
11976 var rootExpirationTime = root.expirationTime;
11977 onSuspend(root, rootWorkInProgress, suspendedExpirationTime, rootExpirationTime, -1 // Indicates no timeout
11978 );
11979 return;
11980 } else if (
11981 // There's no lower priority work, but we're rendering asynchronously.
11982 // Synchronously attempt to render the same level one more time. This is
11983 // similar to a suspend, but without a timeout because we're not waiting
11984 // for a promise to resolve.
11985 !root.didError && isYieldy) {
11986 root.didError = true;
11987 var _suspendedExpirationTime = root.nextExpirationTimeToWorkOn = expirationTime;
11988 var _rootExpirationTime = root.expirationTime = Sync;
11989 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime, _rootExpirationTime, -1 // Indicates no timeout
11990 );
11991 return;
11992 }
11993 }
11994
11995 if (isYieldy && nextLatestAbsoluteTimeoutMs !== -1) {
11996 // The tree was suspended.
11997 var _suspendedExpirationTime2 = expirationTime;
11998 markSuspendedPriorityLevel(root, _suspendedExpirationTime2);
11999
12000 // Find the earliest uncommitted expiration time in the tree, including
12001 // work that is suspended. The timeout threshold cannot be longer than
12002 // the overall expiration.
12003 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, expirationTime);
12004 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
12005 if (earliestExpirationTimeMs < nextLatestAbsoluteTimeoutMs) {
12006 nextLatestAbsoluteTimeoutMs = earliestExpirationTimeMs;
12007 }
12008
12009 // Subtract the current time from the absolute timeout to get the number
12010 // of milliseconds until the timeout. In other words, convert an absolute
12011 // timestamp to a relative time. This is the value that is passed
12012 // to `setTimeout`.
12013 var currentTimeMs = expirationTimeToMs(requestCurrentTime());
12014 var msUntilTimeout = nextLatestAbsoluteTimeoutMs - currentTimeMs;
12015 msUntilTimeout = msUntilTimeout < 0 ? 0 : msUntilTimeout;
12016
12017 // TODO: Account for the Just Noticeable Difference
12018
12019 var _rootExpirationTime2 = root.expirationTime;
12020 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime2, _rootExpirationTime2, msUntilTimeout);
12021 return;
12022 }
12023
12024 // Ready to commit.
12025 onComplete(root, rootWorkInProgress, expirationTime);
12026}
12027
12028function captureCommitPhaseError(sourceFiber, value) {
12029 var expirationTime = Sync;
12030 var fiber = sourceFiber.return;
12031 while (fiber !== null) {
12032 switch (fiber.tag) {
12033 case ClassComponent:
12034 var ctor = fiber.type;
12035 var instance = fiber.stateNode;
12036 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
12037 var errorInfo = createCapturedValue(value, sourceFiber);
12038 var update = createClassErrorUpdate(fiber, errorInfo, expirationTime);
12039 enqueueUpdate(fiber, update);
12040 scheduleWork(fiber, expirationTime);
12041 return;
12042 }
12043 break;
12044 case HostRoot:
12045 {
12046 var _errorInfo = createCapturedValue(value, sourceFiber);
12047 var _update = createRootErrorUpdate(fiber, _errorInfo, expirationTime);
12048 enqueueUpdate(fiber, _update);
12049 scheduleWork(fiber, expirationTime);
12050 return;
12051 }
12052 }
12053 fiber = fiber.return;
12054 }
12055
12056 if (sourceFiber.tag === HostRoot) {
12057 // Error was thrown at the root. There is no parent, so the root
12058 // itself should capture it.
12059 var rootFiber = sourceFiber;
12060 var _errorInfo2 = createCapturedValue(value, rootFiber);
12061 var _update2 = createRootErrorUpdate(rootFiber, _errorInfo2, expirationTime);
12062 enqueueUpdate(rootFiber, _update2);
12063 scheduleWork(rootFiber, expirationTime);
12064 }
12065}
12066
12067function computeThreadID(expirationTime, interactionThreadID) {
12068 // Interaction threads are unique per root and expiration time.
12069 return expirationTime * 1000 + interactionThreadID;
12070}
12071
12072function computeExpirationForFiber(currentTime, fiber) {
12073 var priorityLevel = unstable_getCurrentPriorityLevel();
12074
12075 var expirationTime = void 0;
12076 if ((fiber.mode & ConcurrentMode) === NoContext) {
12077 // Outside of concurrent mode, updates are always synchronous.
12078 expirationTime = Sync;
12079 } else if (isWorking && !isCommitting$1) {
12080 // During render phase, updates expire during as the current render.
12081 expirationTime = nextRenderExpirationTime;
12082 } else {
12083 switch (priorityLevel) {
12084 case unstable_ImmediatePriority:
12085 expirationTime = Sync;
12086 break;
12087 case unstable_UserBlockingPriority:
12088 expirationTime = computeInteractiveExpiration(currentTime);
12089 break;
12090 case unstable_NormalPriority:
12091 // This is a normal, concurrent update
12092 expirationTime = computeAsyncExpiration(currentTime);
12093 break;
12094 case unstable_LowPriority:
12095 case unstable_IdlePriority:
12096 expirationTime = Never;
12097 break;
12098 default:
12099 invariant(false, 'Unknown priority level. This error is likely caused by a bug in React. Please file an issue.');
12100 }
12101
12102 // If we're in the middle of rendering a tree, do not update at the same
12103 // expiration time that is already rendering.
12104 if (nextRoot !== null && expirationTime === nextRenderExpirationTime) {
12105 expirationTime -= 1;
12106 }
12107 }
12108
12109 // Keep track of the lowest pending interactive expiration time. This
12110 // allows us to synchronously flush all interactive updates
12111 // when needed.
12112 // TODO: Move this to renderer?
12113 return expirationTime;
12114}
12115
12116function renderDidSuspend(root, absoluteTimeoutMs, suspendedTime) {
12117 // Schedule the timeout.
12118 if (absoluteTimeoutMs >= 0 && nextLatestAbsoluteTimeoutMs < absoluteTimeoutMs) {
12119 nextLatestAbsoluteTimeoutMs = absoluteTimeoutMs;
12120 }
12121}
12122
12123function renderDidError() {
12124 nextRenderDidError = true;
12125}
12126
12127function pingSuspendedRoot(root, thenable, pingTime) {
12128 // A promise that previously suspended React from committing has resolved.
12129 // If React is still suspended, try again at the previous level (pingTime).
12130
12131 var pingCache = root.pingCache;
12132 if (pingCache !== null) {
12133 // The thenable resolved, so we no longer need to memoize, because it will
12134 // never be thrown again.
12135 pingCache.delete(thenable);
12136 }
12137
12138 if (nextRoot !== null && nextRenderExpirationTime === pingTime) {
12139 // Received a ping at the same priority level at which we're currently
12140 // rendering. Restart from the root.
12141 nextRoot = null;
12142 } else {
12143 // Confirm that the root is still suspended at this level. Otherwise exit.
12144 if (isPriorityLevelSuspended(root, pingTime)) {
12145 // Ping at the original level
12146 markPingedPriorityLevel(root, pingTime);
12147 var rootExpirationTime = root.expirationTime;
12148 if (rootExpirationTime !== NoWork) {
12149 requestWork(root, rootExpirationTime);
12150 }
12151 }
12152 }
12153}
12154
12155function retryTimedOutBoundary(boundaryFiber, thenable) {
12156 // The boundary fiber (a Suspense component) previously timed out and was
12157 // rendered in its fallback state. One of the promises that suspended it has
12158 // resolved, which means at least part of the tree was likely unblocked. Try
12159 var retryCache = void 0;
12160 if (enableSuspenseServerRenderer) {
12161 switch (boundaryFiber.tag) {
12162 case SuspenseComponent:
12163 retryCache = boundaryFiber.stateNode;
12164 break;
12165 case DehydratedSuspenseComponent:
12166 retryCache = boundaryFiber.memoizedState;
12167 break;
12168 default:
12169 invariant(false, 'Pinged unknown suspense boundary type. This is probably a bug in React.');
12170 }
12171 } else {
12172 retryCache = boundaryFiber.stateNode;
12173 }
12174 if (retryCache !== null) {
12175 // The thenable resolved, so we no longer need to memoize, because it will
12176 // never be thrown again.
12177 retryCache.delete(thenable);
12178 }
12179
12180 var currentTime = requestCurrentTime();
12181 var retryTime = computeExpirationForFiber(currentTime, boundaryFiber);
12182 var root = scheduleWorkToRoot(boundaryFiber, retryTime);
12183 if (root !== null) {
12184 markPendingPriorityLevel(root, retryTime);
12185 var rootExpirationTime = root.expirationTime;
12186 if (rootExpirationTime !== NoWork) {
12187 requestWork(root, rootExpirationTime);
12188 }
12189 }
12190}
12191
12192function scheduleWorkToRoot(fiber, expirationTime) {
12193 recordScheduleUpdate();
12194
12195 {
12196 if (fiber.tag === ClassComponent) {
12197 var instance = fiber.stateNode;
12198 warnAboutInvalidUpdates(instance);
12199 }
12200 }
12201
12202 // Update the source fiber's expiration time
12203 if (fiber.expirationTime < expirationTime) {
12204 fiber.expirationTime = expirationTime;
12205 }
12206 var alternate = fiber.alternate;
12207 if (alternate !== null && alternate.expirationTime < expirationTime) {
12208 alternate.expirationTime = expirationTime;
12209 }
12210 // Walk the parent path to the root and update the child expiration time.
12211 var node = fiber.return;
12212 var root = null;
12213 if (node === null && fiber.tag === HostRoot) {
12214 root = fiber.stateNode;
12215 } else {
12216 while (node !== null) {
12217 alternate = node.alternate;
12218 if (node.childExpirationTime < expirationTime) {
12219 node.childExpirationTime = expirationTime;
12220 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
12221 alternate.childExpirationTime = expirationTime;
12222 }
12223 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
12224 alternate.childExpirationTime = expirationTime;
12225 }
12226 if (node.return === null && node.tag === HostRoot) {
12227 root = node.stateNode;
12228 break;
12229 }
12230 node = node.return;
12231 }
12232 }
12233
12234 if (enableSchedulerTracing) {
12235 if (root !== null) {
12236 var interactions = __interactionsRef.current;
12237 if (interactions.size > 0) {
12238 var pendingInteractionMap = root.pendingInteractionMap;
12239 var pendingInteractions = pendingInteractionMap.get(expirationTime);
12240 if (pendingInteractions != null) {
12241 interactions.forEach(function (interaction) {
12242 if (!pendingInteractions.has(interaction)) {
12243 // Update the pending async work count for previously unscheduled interaction.
12244 interaction.__count++;
12245 }
12246
12247 pendingInteractions.add(interaction);
12248 });
12249 } else {
12250 pendingInteractionMap.set(expirationTime, new Set(interactions));
12251
12252 // Update the pending async work count for the current interactions.
12253 interactions.forEach(function (interaction) {
12254 interaction.__count++;
12255 });
12256 }
12257
12258 var subscriber = __subscriberRef.current;
12259 if (subscriber !== null) {
12260 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
12261 subscriber.onWorkScheduled(interactions, threadID);
12262 }
12263 }
12264 }
12265 }
12266 return root;
12267}
12268
12269function warnIfNotCurrentlyBatchingInDev(fiber) {
12270 {
12271 if (isRendering === false && isBatchingUpdates === false) {
12272 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));
12273 }
12274 }
12275}
12276
12277function scheduleWork(fiber, expirationTime) {
12278 var root = scheduleWorkToRoot(fiber, expirationTime);
12279 if (root === null) {
12280 {
12281 switch (fiber.tag) {
12282 case ClassComponent:
12283 warnAboutUpdateOnUnmounted(fiber, true);
12284 break;
12285 case FunctionComponent:
12286 case ForwardRef:
12287 case MemoComponent:
12288 case SimpleMemoComponent:
12289 warnAboutUpdateOnUnmounted(fiber, false);
12290 break;
12291 }
12292 }
12293 return;
12294 }
12295
12296 if (!isWorking && nextRenderExpirationTime !== NoWork && expirationTime > nextRenderExpirationTime) {
12297 // This is an interruption. (Used for performance tracking.)
12298 interruptedBy = fiber;
12299 resetStack();
12300 }
12301 markPendingPriorityLevel(root, expirationTime);
12302 if (
12303 // If we're in the render phase, we don't need to schedule this root
12304 // for an update, because we'll do it before we exit...
12305 !isWorking || isCommitting$1 ||
12306 // ...unless this is a different root than the one we're rendering.
12307 nextRoot !== root) {
12308 var rootExpirationTime = root.expirationTime;
12309 requestWork(root, rootExpirationTime);
12310 }
12311 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
12312 // Reset this back to zero so subsequent updates don't throw.
12313 nestedUpdateCount = 0;
12314 invariant(false, '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.');
12315 }
12316}
12317
12318// TODO: Everything below this is written as if it has been lifted to the
12319// renderers. I'll do this in a follow-up.
12320
12321// Linked-list of roots
12322var firstScheduledRoot = null;
12323var lastScheduledRoot = null;
12324
12325var callbackExpirationTime = NoWork;
12326var callbackID = void 0;
12327var isRendering = false;
12328var nextFlushedRoot = null;
12329var nextFlushedExpirationTime = NoWork;
12330var hasUnhandledError = false;
12331var unhandledError = null;
12332
12333var isBatchingUpdates = false;
12334var isUnbatchingUpdates = false;
12335
12336var completedBatches = null;
12337
12338var originalStartTimeMs = unstable_now();
12339var currentRendererTime = msToExpirationTime(originalStartTimeMs);
12340var currentSchedulerTime = currentRendererTime;
12341
12342// Use these to prevent an infinite loop of nested updates
12343var NESTED_UPDATE_LIMIT = 50;
12344var nestedUpdateCount = 0;
12345var lastCommittedRootDuringThisBatch = null;
12346
12347function recomputeCurrentRendererTime() {
12348 var currentTimeMs = unstable_now() - originalStartTimeMs;
12349 currentRendererTime = msToExpirationTime(currentTimeMs);
12350}
12351
12352function scheduleCallbackWithExpirationTime(root, expirationTime) {
12353 if (callbackExpirationTime !== NoWork) {
12354 // A callback is already scheduled. Check its expiration time (timeout).
12355 if (expirationTime < callbackExpirationTime) {
12356 // Existing callback has sufficient timeout. Exit.
12357 return;
12358 } else {
12359 if (callbackID !== null) {
12360 // Existing callback has insufficient timeout. Cancel and schedule a
12361 // new one.
12362 unstable_cancelCallback(callbackID);
12363 }
12364 }
12365 // The request callback timer is already running. Don't start a new one.
12366 } else {
12367 startRequestCallbackTimer();
12368 }
12369
12370 callbackExpirationTime = expirationTime;
12371 var currentMs = unstable_now() - originalStartTimeMs;
12372 var expirationTimeMs = expirationTimeToMs(expirationTime);
12373 var timeout = expirationTimeMs - currentMs;
12374 callbackID = unstable_scheduleCallback(performAsyncWork, { timeout: timeout });
12375}
12376
12377// For every call to renderRoot, one of onFatal, onComplete, onSuspend, and
12378// onYield is called upon exiting. We use these in lieu of returning a tuple.
12379// I've also chosen not to inline them into renderRoot because these will
12380// eventually be lifted into the renderer.
12381function onFatal(root) {
12382 root.finishedWork = null;
12383}
12384
12385function onComplete(root, finishedWork, expirationTime) {
12386 root.pendingCommitExpirationTime = expirationTime;
12387 root.finishedWork = finishedWork;
12388}
12389
12390function onSuspend(root, finishedWork, suspendedExpirationTime, rootExpirationTime, msUntilTimeout) {
12391 root.expirationTime = rootExpirationTime;
12392 if (msUntilTimeout === 0 && !shouldYieldToRenderer()) {
12393 // Don't wait an additional tick. Commit the tree immediately.
12394 root.pendingCommitExpirationTime = suspendedExpirationTime;
12395 root.finishedWork = finishedWork;
12396 } else if (msUntilTimeout > 0) {
12397 // Wait `msUntilTimeout` milliseconds before committing.
12398 root.timeoutHandle = scheduleTimeout(onTimeout.bind(null, root, finishedWork, suspendedExpirationTime), msUntilTimeout);
12399 }
12400}
12401
12402function onYield(root) {
12403 root.finishedWork = null;
12404}
12405
12406function onTimeout(root, finishedWork, suspendedExpirationTime) {
12407 // The root timed out. Commit it.
12408 root.pendingCommitExpirationTime = suspendedExpirationTime;
12409 root.finishedWork = finishedWork;
12410 // Read the current time before entering the commit phase. We can be
12411 // certain this won't cause tearing related to batching of event updates
12412 // because we're at the top of a timer event.
12413 recomputeCurrentRendererTime();
12414 currentSchedulerTime = currentRendererTime;
12415 flushRoot(root, suspendedExpirationTime);
12416}
12417
12418function onCommit(root, expirationTime) {
12419 root.expirationTime = expirationTime;
12420 root.finishedWork = null;
12421}
12422
12423function requestCurrentTime() {
12424 // requestCurrentTime is called by the scheduler to compute an expiration
12425 // time.
12426 //
12427 // Expiration times are computed by adding to the current time (the start
12428 // time). However, if two updates are scheduled within the same event, we
12429 // should treat their start times as simultaneous, even if the actual clock
12430 // time has advanced between the first and second call.
12431
12432 // In other words, because expiration times determine how updates are batched,
12433 // we want all updates of like priority that occur within the same event to
12434 // receive the same expiration time. Otherwise we get tearing.
12435 //
12436 // We keep track of two separate times: the current "renderer" time and the
12437 // current "scheduler" time. The renderer time can be updated whenever; it
12438 // only exists to minimize the calls performance.now.
12439 //
12440 // But the scheduler time can only be updated if there's no pending work, or
12441 // if we know for certain that we're not in the middle of an event.
12442
12443 if (isRendering) {
12444 // We're already rendering. Return the most recently read time.
12445 return currentSchedulerTime;
12446 }
12447 // Check if there's pending work.
12448 findHighestPriorityRoot();
12449 if (nextFlushedExpirationTime === NoWork || nextFlushedExpirationTime === Never) {
12450 // If there's no pending work, or if the pending work is offscreen, we can
12451 // read the current time without risk of tearing.
12452 recomputeCurrentRendererTime();
12453 currentSchedulerTime = currentRendererTime;
12454 return currentSchedulerTime;
12455 }
12456 // There's already pending work. We might be in the middle of a browser
12457 // event. If we were to read the current time, it could cause multiple updates
12458 // within the same event to receive different expiration times, leading to
12459 // tearing. Return the last read time. During the next idle callback, the
12460 // time will be updated.
12461 return currentSchedulerTime;
12462}
12463
12464// requestWork is called by the scheduler whenever a root receives an update.
12465// It's up to the renderer to call renderRoot at some point in the future.
12466function requestWork(root, expirationTime) {
12467 addRootToSchedule(root, expirationTime);
12468 if (isRendering) {
12469 // Prevent reentrancy. Remaining work will be scheduled at the end of
12470 // the currently rendering batch.
12471 return;
12472 }
12473
12474 if (isBatchingUpdates) {
12475 // Flush work at the end of the batch.
12476 if (isUnbatchingUpdates) {
12477 // ...unless we're inside unbatchedUpdates, in which case we should
12478 // flush it now.
12479 nextFlushedRoot = root;
12480 nextFlushedExpirationTime = Sync;
12481 performWorkOnRoot(root, Sync, false);
12482 }
12483 return;
12484 }
12485
12486 // TODO: Get rid of Sync and use current time?
12487 if (expirationTime === Sync) {
12488 performSyncWork();
12489 } else {
12490 scheduleCallbackWithExpirationTime(root, expirationTime);
12491 }
12492}
12493
12494function addRootToSchedule(root, expirationTime) {
12495 // Add the root to the schedule.
12496 // Check if this root is already part of the schedule.
12497 if (root.nextScheduledRoot === null) {
12498 // This root is not already scheduled. Add it.
12499 root.expirationTime = expirationTime;
12500 if (lastScheduledRoot === null) {
12501 firstScheduledRoot = lastScheduledRoot = root;
12502 root.nextScheduledRoot = root;
12503 } else {
12504 lastScheduledRoot.nextScheduledRoot = root;
12505 lastScheduledRoot = root;
12506 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
12507 }
12508 } else {
12509 // This root is already scheduled, but its priority may have increased.
12510 var remainingExpirationTime = root.expirationTime;
12511 if (expirationTime > remainingExpirationTime) {
12512 // Update the priority.
12513 root.expirationTime = expirationTime;
12514 }
12515 }
12516}
12517
12518function findHighestPriorityRoot() {
12519 var highestPriorityWork = NoWork;
12520 var highestPriorityRoot = null;
12521 if (lastScheduledRoot !== null) {
12522 var previousScheduledRoot = lastScheduledRoot;
12523 var root = firstScheduledRoot;
12524 while (root !== null) {
12525 var remainingExpirationTime = root.expirationTime;
12526 if (remainingExpirationTime === NoWork) {
12527 // This root no longer has work. Remove it from the scheduler.
12528
12529 // TODO: This check is redudant, but Flow is confused by the branch
12530 // below where we set lastScheduledRoot to null, even though we break
12531 // from the loop right after.
12532 !(previousScheduledRoot !== null && lastScheduledRoot !== null) ? invariant(false, 'Should have a previous and last root. This error is likely caused by a bug in React. Please file an issue.') : void 0;
12533 if (root === root.nextScheduledRoot) {
12534 // This is the only root in the list.
12535 root.nextScheduledRoot = null;
12536 firstScheduledRoot = lastScheduledRoot = null;
12537 break;
12538 } else if (root === firstScheduledRoot) {
12539 // This is the first root in the list.
12540 var next = root.nextScheduledRoot;
12541 firstScheduledRoot = next;
12542 lastScheduledRoot.nextScheduledRoot = next;
12543 root.nextScheduledRoot = null;
12544 } else if (root === lastScheduledRoot) {
12545 // This is the last root in the list.
12546 lastScheduledRoot = previousScheduledRoot;
12547 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
12548 root.nextScheduledRoot = null;
12549 break;
12550 } else {
12551 previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot;
12552 root.nextScheduledRoot = null;
12553 }
12554 root = previousScheduledRoot.nextScheduledRoot;
12555 } else {
12556 if (remainingExpirationTime > highestPriorityWork) {
12557 // Update the priority, if it's higher
12558 highestPriorityWork = remainingExpirationTime;
12559 highestPriorityRoot = root;
12560 }
12561 if (root === lastScheduledRoot) {
12562 break;
12563 }
12564 if (highestPriorityWork === Sync) {
12565 // Sync is highest priority by definition so
12566 // we can stop searching.
12567 break;
12568 }
12569 previousScheduledRoot = root;
12570 root = root.nextScheduledRoot;
12571 }
12572 }
12573 }
12574
12575 nextFlushedRoot = highestPriorityRoot;
12576 nextFlushedExpirationTime = highestPriorityWork;
12577}
12578
12579// TODO: This wrapper exists because many of the older tests (the ones that use
12580// flushDeferredPri) rely on the number of times `shouldYield` is called. We
12581// should get rid of it.
12582var didYield = false;
12583function shouldYieldToRenderer() {
12584 if (didYield) {
12585 return true;
12586 }
12587 if (unstable_shouldYield()) {
12588 didYield = true;
12589 return true;
12590 }
12591 return false;
12592}
12593
12594function performAsyncWork() {
12595 try {
12596 if (!shouldYieldToRenderer()) {
12597 // The callback timed out. That means at least one update has expired.
12598 // Iterate through the root schedule. If they contain expired work, set
12599 // the next render expiration time to the current time. This has the effect
12600 // of flushing all expired work in a single batch, instead of flushing each
12601 // level one at a time.
12602 if (firstScheduledRoot !== null) {
12603 recomputeCurrentRendererTime();
12604 var root = firstScheduledRoot;
12605 do {
12606 didExpireAtExpirationTime(root, currentRendererTime);
12607 // The root schedule is circular, so this is never null.
12608 root = root.nextScheduledRoot;
12609 } while (root !== firstScheduledRoot);
12610 }
12611 }
12612 performWork(NoWork, true);
12613 } finally {
12614 didYield = false;
12615 }
12616}
12617
12618function performSyncWork() {
12619 performWork(Sync, false);
12620}
12621
12622function performWork(minExpirationTime, isYieldy) {
12623 // Keep working on roots until there's no more work, or until there's a higher
12624 // priority event.
12625 findHighestPriorityRoot();
12626
12627 if (isYieldy) {
12628 recomputeCurrentRendererTime();
12629 currentSchedulerTime = currentRendererTime;
12630
12631 if (enableUserTimingAPI) {
12632 var didExpire = nextFlushedExpirationTime > currentRendererTime;
12633 var timeout = expirationTimeToMs(nextFlushedExpirationTime);
12634 stopRequestCallbackTimer(didExpire, timeout);
12635 }
12636
12637 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime && !(didYield && currentRendererTime > nextFlushedExpirationTime)) {
12638 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, currentRendererTime > nextFlushedExpirationTime);
12639 findHighestPriorityRoot();
12640 recomputeCurrentRendererTime();
12641 currentSchedulerTime = currentRendererTime;
12642 }
12643 } else {
12644 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime) {
12645 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, false);
12646 findHighestPriorityRoot();
12647 }
12648 }
12649
12650 // We're done flushing work. Either we ran out of time in this callback,
12651 // or there's no more work left with sufficient priority.
12652
12653 // If we're inside a callback, set this to false since we just completed it.
12654 if (isYieldy) {
12655 callbackExpirationTime = NoWork;
12656 callbackID = null;
12657 }
12658 // If there's work left over, schedule a new callback.
12659 if (nextFlushedExpirationTime !== NoWork) {
12660 scheduleCallbackWithExpirationTime(nextFlushedRoot, nextFlushedExpirationTime);
12661 }
12662
12663 // Clean-up.
12664 finishRendering();
12665}
12666
12667function flushRoot(root, expirationTime) {
12668 !!isRendering ? invariant(false, 'work.commit(): Cannot commit while already rendering. This likely means you attempted to commit from inside a lifecycle method.') : void 0;
12669 // Perform work on root as if the given expiration time is the current time.
12670 // This has the effect of synchronously flushing all work up to and
12671 // including the given time.
12672 nextFlushedRoot = root;
12673 nextFlushedExpirationTime = expirationTime;
12674 performWorkOnRoot(root, expirationTime, false);
12675 // Flush any sync work that was scheduled by lifecycles
12676 performSyncWork();
12677}
12678
12679function finishRendering() {
12680 nestedUpdateCount = 0;
12681 lastCommittedRootDuringThisBatch = null;
12682
12683 if (completedBatches !== null) {
12684 var batches = completedBatches;
12685 completedBatches = null;
12686 for (var i = 0; i < batches.length; i++) {
12687 var batch = batches[i];
12688 try {
12689 batch._onComplete();
12690 } catch (error) {
12691 if (!hasUnhandledError) {
12692 hasUnhandledError = true;
12693 unhandledError = error;
12694 }
12695 }
12696 }
12697 }
12698
12699 if (hasUnhandledError) {
12700 var error = unhandledError;
12701 unhandledError = null;
12702 hasUnhandledError = false;
12703 throw error;
12704 }
12705}
12706
12707function performWorkOnRoot(root, expirationTime, isYieldy) {
12708 !!isRendering ? invariant(false, 'performWorkOnRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
12709
12710 isRendering = true;
12711
12712 // Check if this is async work or sync/expired work.
12713 if (!isYieldy) {
12714 // Flush work without yielding.
12715 // TODO: Non-yieldy work does not necessarily imply expired work. A renderer
12716 // may want to perform some work without yielding, but also without
12717 // requiring the root to complete (by triggering placeholders).
12718
12719 var finishedWork = root.finishedWork;
12720 if (finishedWork !== null) {
12721 // This root is already complete. We can commit it.
12722 completeRoot(root, finishedWork, expirationTime);
12723 } else {
12724 root.finishedWork = null;
12725 // If this root previously suspended, clear its existing timeout, since
12726 // we're about to try rendering again.
12727 var timeoutHandle = root.timeoutHandle;
12728 if (timeoutHandle !== noTimeout) {
12729 root.timeoutHandle = noTimeout;
12730 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
12731 cancelTimeout(timeoutHandle);
12732 }
12733 renderRoot(root, isYieldy);
12734 finishedWork = root.finishedWork;
12735 if (finishedWork !== null) {
12736 // We've completed the root. Commit it.
12737 completeRoot(root, finishedWork, expirationTime);
12738 }
12739 }
12740 } else {
12741 // Flush async work.
12742 var _finishedWork = root.finishedWork;
12743 if (_finishedWork !== null) {
12744 // This root is already complete. We can commit it.
12745 completeRoot(root, _finishedWork, expirationTime);
12746 } else {
12747 root.finishedWork = null;
12748 // If this root previously suspended, clear its existing timeout, since
12749 // we're about to try rendering again.
12750 var _timeoutHandle = root.timeoutHandle;
12751 if (_timeoutHandle !== noTimeout) {
12752 root.timeoutHandle = noTimeout;
12753 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
12754 cancelTimeout(_timeoutHandle);
12755 }
12756 renderRoot(root, isYieldy);
12757 _finishedWork = root.finishedWork;
12758 if (_finishedWork !== null) {
12759 // We've completed the root. Check the if we should yield one more time
12760 // before committing.
12761 if (!shouldYieldToRenderer()) {
12762 // Still time left. Commit the root.
12763 completeRoot(root, _finishedWork, expirationTime);
12764 } else {
12765 // There's no time left. Mark this root as complete. We'll come
12766 // back and commit it later.
12767 root.finishedWork = _finishedWork;
12768 }
12769 }
12770 }
12771 }
12772
12773 isRendering = false;
12774}
12775
12776function completeRoot(root, finishedWork, expirationTime) {
12777 // Check if there's a batch that matches this expiration time.
12778 var firstBatch = root.firstBatch;
12779 if (firstBatch !== null && firstBatch._expirationTime >= expirationTime) {
12780 if (completedBatches === null) {
12781 completedBatches = [firstBatch];
12782 } else {
12783 completedBatches.push(firstBatch);
12784 }
12785 if (firstBatch._defer) {
12786 // This root is blocked from committing by a batch. Unschedule it until
12787 // we receive another update.
12788 root.finishedWork = finishedWork;
12789 root.expirationTime = NoWork;
12790 return;
12791 }
12792 }
12793
12794 // Commit the root.
12795 root.finishedWork = null;
12796
12797 // Check if this is a nested update (a sync update scheduled during the
12798 // commit phase).
12799 if (root === lastCommittedRootDuringThisBatch) {
12800 // If the next root is the same as the previous root, this is a nested
12801 // update. To prevent an infinite loop, increment the nested update count.
12802 nestedUpdateCount++;
12803 } else {
12804 // Reset whenever we switch roots.
12805 lastCommittedRootDuringThisBatch = root;
12806 nestedUpdateCount = 0;
12807 }
12808 unstable_runWithPriority(unstable_ImmediatePriority, function () {
12809 commitRoot(root, finishedWork);
12810 });
12811}
12812
12813function onUncaughtError(error) {
12814 !(nextFlushedRoot !== null) ? invariant(false, 'Should be working on a root. This error is likely caused by a bug in React. Please file an issue.') : void 0;
12815 // Unschedule this root so we don't work on it again until there's
12816 // another update.
12817 nextFlushedRoot.expirationTime = NoWork;
12818 if (!hasUnhandledError) {
12819 hasUnhandledError = true;
12820 unhandledError = error;
12821 }
12822}
12823
12824// 0 is PROD, 1 is DEV.
12825// Might add PROFILE later.
12826
12827
12828var didWarnAboutNestedUpdates = void 0;
12829{
12830 didWarnAboutNestedUpdates = false;
12831
12832}
12833
12834function getContextForSubtree(parentComponent) {
12835 if (!parentComponent) {
12836 return emptyContextObject;
12837 }
12838
12839 var fiber = get(parentComponent);
12840 var parentContext = findCurrentUnmaskedContext(fiber);
12841
12842 if (fiber.tag === ClassComponent) {
12843 var Component = fiber.type;
12844 if (isContextProvider(Component)) {
12845 return processChildContext(fiber, Component, parentContext);
12846 }
12847 }
12848
12849 return parentContext;
12850}
12851
12852function scheduleRootUpdate(current$$1, element, expirationTime, callback) {
12853 {
12854 if (phase === 'render' && current$1 !== null && !didWarnAboutNestedUpdates) {
12855 didWarnAboutNestedUpdates = true;
12856 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');
12857 }
12858 }
12859
12860 var update = createUpdate(expirationTime);
12861 // Caution: React DevTools currently depends on this property
12862 // being called "element".
12863 update.payload = { element: element };
12864
12865 callback = callback === undefined ? null : callback;
12866 if (callback !== null) {
12867 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0;
12868 update.callback = callback;
12869 }
12870
12871 flushPassiveEffects();
12872 enqueueUpdate(current$$1, update);
12873 scheduleWork(current$$1, expirationTime);
12874
12875 return expirationTime;
12876}
12877
12878function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback) {
12879 // TODO: If this is a nested container, this won't be the root.
12880 var current$$1 = container.current;
12881
12882 {
12883 if (ReactFiberInstrumentation_1.debugTool) {
12884 if (current$$1.alternate === null) {
12885 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
12886 } else if (element === null) {
12887 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
12888 } else {
12889 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
12890 }
12891 }
12892 }
12893
12894 var context = getContextForSubtree(parentComponent);
12895 if (container.context === null) {
12896 container.context = context;
12897 } else {
12898 container.pendingContext = context;
12899 }
12900
12901 return scheduleRootUpdate(current$$1, element, expirationTime, callback);
12902}
12903
12904function createContainer(containerInfo, isConcurrent, hydrate) {
12905 return createFiberRoot(containerInfo, isConcurrent, hydrate);
12906}
12907
12908function updateContainer(element, container, parentComponent, callback) {
12909 var current$$1 = container.current;
12910 var currentTime = requestCurrentTime();
12911 var expirationTime = computeExpirationForFiber(currentTime, current$$1);
12912 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback);
12913}
12914
12915
12916
12917
12918
12919var overrideProps = null;
12920
12921{
12922 var copyWithSetImpl = function (obj, path, idx, value) {
12923 if (idx >= path.length) {
12924 return value;
12925 }
12926 var key = path[idx];
12927 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
12928 // $FlowFixMe number or string is fine here
12929 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
12930 return updated;
12931 };
12932
12933 var copyWithSet = function (obj, path, value) {
12934 return copyWithSetImpl(obj, path, 0, value);
12935 };
12936
12937 // Support DevTools props for function components, forwardRef, memo, host components, etc.
12938 overrideProps = function (fiber, path, value) {
12939 flushPassiveEffects();
12940 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
12941 if (fiber.alternate) {
12942 fiber.alternate.pendingProps = fiber.pendingProps;
12943 }
12944 scheduleWork(fiber, Sync);
12945 };
12946}
12947
12948function injectIntoDevTools(devToolsConfig) {
12949 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
12950 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
12951
12952
12953 return injectInternals(_assign({}, devToolsConfig, {
12954 overrideProps: overrideProps,
12955 currentDispatcherRef: ReactCurrentDispatcher,
12956 findHostInstanceByFiber: function (fiber) {
12957 var hostFiber = findCurrentHostFiber(fiber);
12958 if (hostFiber === null) {
12959 return null;
12960 }
12961 return hostFiber.stateNode;
12962 },
12963 findFiberByHostInstance: function (instance) {
12964 if (!findFiberByHostInstance) {
12965 // Might not be implemented by the renderer.
12966 return null;
12967 }
12968 return findFiberByHostInstance(instance);
12969 }
12970 }));
12971}
12972
12973// This file intentionally does *not* have the Flow annotation.
12974// Don't add it. See `./inline-typed.js` for an explanation.
12975
12976var container = _class({
12977
12978 grab: function(){
12979 for (var i = 0; i < arguments.length; i++) arguments[i].inject(this);
12980 return this;
12981 },
12982
12983 empty: function(){
12984 var node;
12985 while (node = this.firstChild) node.eject();
12986 return this;
12987 }
12988
12989});
12990
12991function elementFrom(node){
12992 if (node.toElement) return node.toElement();
12993 if (node.getDOMNode) return node.getDOMNode();
12994 if (node.getNode) return node.getNode();
12995 return node;
12996}
12997
12998var native_1 = _class({
12999
13000 // conventions
13001
13002 toElement: function(){
13003 return this.element;
13004 },
13005
13006 getDOMNode: function(){
13007 return this.toElement();
13008 },
13009
13010 getNode: function(){
13011 return this.toElement();
13012 },
13013
13014 // placement
13015
13016 inject: function(container){
13017 (container.containerElement || elementFrom(container))
13018 .appendChild(this.element);
13019 return this;
13020 },
13021
13022 injectBefore: function(sibling){
13023 var element = elementFrom(sibling);
13024 element.parentNode.insertBefore(this.element, element);
13025 return this;
13026 },
13027
13028 eject: function(){
13029 var element = this.element, parent = element.parentNode;
13030 if (parent) parent.removeChild(element); // TODO: VML Nodes are dead after being ejected
13031 return this;
13032 },
13033
13034 // events
13035
13036 subscribe: function(type, fn, bind){
13037 if (typeof type != 'string'){ // listen type / fn with object
13038 var subscriptions = [];
13039 for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
13040 return function(){ // unsubscribe
13041 for (var i = 0, l = subscriptions.length; i < l; i++)
13042 subscriptions[i]();
13043 return this;
13044 };
13045 } else { // listen to one
13046 if (!bind) bind = this;
13047 var bound;
13048 if (typeof fn === 'function'){
13049 bound = fn.bind ? fn.bind(bind)
13050 : function(){ return fn.apply(bind, arguments); };
13051 } else {
13052 bound = fn;
13053 }
13054 var element = this.element;
13055 if (element.addEventListener){
13056 element.addEventListener(type, bound, false);
13057 return function(){ // unsubscribe
13058 element.removeEventListener(type, bound, false);
13059 return this;
13060 };
13061 } else {
13062 element.attachEvent('on' + type, bound);
13063 return function(){ // unsubscribe
13064 element.detachEvent('on' + type, bound);
13065 return this;
13066 };
13067 }
13068 }
13069 }
13070
13071});
13072
13073var fps = 1000 / 60;
13074var invalids = [];
13075var renderTimer;
13076var renderInvalids = function(){
13077 clearTimeout(renderTimer);
13078 renderTimer = null;
13079 var canvases = invalids;
13080 invalids = [];
13081 for (var i = 0, l = canvases.length; i < l; i++){
13082 var c = canvases[i];
13083 c._valid = true;
13084 c.render();
13085 }
13086};
13087
13088var resolution = typeof window !== 'undefined' && window.devicePixelRatio || 1;
13089
13090var previousHit = null;
13091var previousHitSurface = null;
13092
13093var CanvasSurface = _class(native_1, container, {
13094
13095 initialize: function(width, height, existingElement){
13096 var element = this.element = existingElement || document.createElement('canvas');
13097 var context = this.context = element.getContext('2d');
13098 this._valid = true;
13099 if (width != null && height != null) this.resize(width, height);
13100
13101 element.addEventListener('mousemove', this, false);
13102 element.addEventListener('mouseout', this, false);
13103 element.addEventListener('mouseover', this, false);
13104 element.addEventListener('mouseup', this, false);
13105 element.addEventListener('mousedown', this, false);
13106 element.addEventListener('click', this, false);
13107 },
13108
13109 handleEvent: function(event){
13110 if (event.clientX == null) return;
13111 var element = this.element,
13112 rect = element.getBoundingClientRect(),
13113 x = event.clientX - rect.left - element.clientLeft,
13114 y = event.clientY - rect.top - element.clientTop,
13115 hit = this.hitTest(x, y);
13116
13117 if (hit !== previousHit){
13118 if (previousHit){
13119 previousHit.dispatch({
13120 type: 'mouseout',
13121 target: previousHit,
13122 relatedTarget: hit,
13123 sourceEvent: event
13124 });
13125 }
13126 if (hit){
13127 hit.dispatch({
13128 type: 'mouseover',
13129 target: hit,
13130 relatedTarget: previousHit,
13131 sourceEvent: event
13132 });
13133 }
13134 previousHit = hit;
13135 previousHitSurface = this;
13136 this.refreshCursor();
13137 }
13138
13139 if (hit) hit.dispatch(event);
13140 },
13141
13142 refreshCursor: function(){
13143 if (previousHitSurface !== this) return;
13144 var hit = previousHit, hitCursor = '', hitTooltip = '';
13145 while (hit){
13146 if (!hitCursor && hit._cursor){
13147 hitCursor = hit._cursor;
13148 if (hitTooltip) break;
13149 }
13150 if (!hitTooltip && hit._tooltip){
13151 hitTooltip = hit._tooltip;
13152 if (hitCursor) break;
13153 }
13154 hit = hit.parentNode;
13155 }
13156 // TODO: No way to set cursor/title on the surface
13157 this.element.style.cursor = hitCursor;
13158 this.element.title = hitTooltip;
13159 },
13160
13161 resize: function(width, height){
13162 var element = this.element;
13163 element.setAttribute('width', width * resolution);
13164 element.setAttribute('height', height * resolution);
13165 element.style.width = width + 'px';
13166 element.style.height = height + 'px';
13167 this.width = width;
13168 this.height = height;
13169 return this;
13170 },
13171
13172 invalidate: function(left, top, width, height){
13173 if (this._valid){
13174 this._valid = false;
13175 invalids.push(this);
13176 if (!renderTimer){
13177 if (window.mozRequestAnimationFrame){
13178 renderTimer = true;
13179 window.mozRequestAnimationFrame(renderInvalids);
13180 } else {
13181 renderTimer = setTimeout(renderInvalids, fps);
13182 }
13183 }
13184 }
13185 return this;
13186 },
13187
13188 hitTest: function(x, y){
13189 if (x < 0 || y < 0 || x > this.width || y > this.height) return null;
13190 var node = this.lastChild;
13191 while (node){
13192 var hit = node.hitTest(x, y);
13193 if (hit) return hit;
13194 node = node.previousSibling;
13195 }
13196 return null;
13197 },
13198
13199 render: function(){
13200 var node = this.firstChild, context = this.context;
13201 context.setTransform(resolution, 0, 0, resolution, 0, 0);
13202 context.clearRect(0, 0, this.width, this.height);
13203 while (node){
13204 node.renderTo(context, resolution, 0, 0, resolution, 0, 0);
13205 node = node.nextSibling;
13206 }
13207 this.refreshCursor();
13208 }
13209
13210});
13211
13212CanvasSurface.tagName = 'canvas';
13213
13214var surface = CanvasSurface;
13215
13216var path$2 = _class({
13217
13218 initialize: function(path){
13219 this.reset().push(path);
13220 },
13221
13222 /* parser */
13223
13224 push: function(){
13225 var p = Array.prototype.join.call(arguments, ' ')
13226 .match(/[a-df-z]|[\-+]?(?:[\d\.]e[\-+]?|[^\s\-+,a-z])+/ig);
13227 if (!p) return this;
13228
13229 var last, cmd = p[0], i = 1;
13230 while (cmd){
13231 switch (cmd){
13232 case 'm': this.move(p[i++], p[i++]); break;
13233 case 'l': this.line(p[i++], p[i++]); break;
13234 case 'c': this.curve(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
13235 case 's': this.curve(p[i++], p[i++], null, null, p[i++], p[i++]); break;
13236 case 'q': this.curve(p[i++], p[i++], p[i++], p[i++]); break;
13237 case 't': this.curve(p[i++], p[i++]); break;
13238 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;
13239 case 'h': this.line(p[i++], 0); break;
13240 case 'v': this.line(0, p[i++]); break;
13241
13242 case 'M': this.moveTo(p[i++], p[i++]); break;
13243 case 'L': this.lineTo(p[i++], p[i++]); break;
13244 case 'C': this.curveTo(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
13245 case 'S': this.curveTo(p[i++], p[i++], null, null, p[i++], p[i++]); break;
13246 case 'Q': this.curveTo(p[i++], p[i++], p[i++], p[i++]); break;
13247 case 'T': this.curveTo(p[i++], p[i++]); break;
13248 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;
13249 case 'H': this.lineTo(p[i++], this.penY); break;
13250 case 'V': this.lineTo(this.penX, p[i++]); break;
13251
13252 case 'Z': case 'z': this.close(); break;
13253 default: cmd = last; i--; continue;
13254 }
13255
13256 last = cmd;
13257 if (last == 'm') last = 'l';
13258 else if (last == 'M') last = 'L';
13259 cmd = p[i++];
13260 }
13261 return this;
13262 },
13263
13264 /* utility methods */
13265
13266 reset: function(){
13267 this.penX = this.penY = 0;
13268 this.penDownX = this.penDownY = null;
13269 this._pivotX = this._pivotY = 0;
13270 this.onReset();
13271 return this;
13272 },
13273
13274 move: function(x,y){
13275 this.onMove(this.penX, this.penY, this._pivotX = this.penX += (+x), this._pivotY = this.penY += (+y));
13276 return this;
13277 },
13278 moveTo: function(x,y){
13279 this.onMove(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
13280 return this;
13281 },
13282
13283 line: function(x,y){
13284 return this.lineTo(this.penX + (+x), this.penY + (+y));
13285 },
13286 lineTo: function(x,y){
13287 if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
13288 this.onLine(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
13289 return this;
13290 },
13291
13292 curve: function(c1x, c1y, c2x, c2y, ex, ey){
13293 var x = this.penX, y = this.penY;
13294 return this.curveTo(
13295 x + (+c1x), y + (+c1y),
13296 c2x == null ? null : x + (+c2x),
13297 c2y == null ? null : y + (+c2y),
13298 ex == null ? null : x + (+ex),
13299 ey == null ? null : y + (+ey)
13300 );
13301 },
13302 curveTo: function(c1x, c1y, c2x, c2y, ex, ey){
13303 var x = this.penX, y = this.penY;
13304 if (c2x == null){
13305 c2x = +c1x; c2y = +c1y;
13306 c1x = (x * 2) - (this._pivotX || 0); c1y = (y * 2) - (this._pivotY || 0);
13307 }
13308 if (ex == null){
13309 this._pivotX = +c1x; this._pivotY = +c1y;
13310 ex = +c2x; ey = +c2y;
13311 c2x = (ex + (+c1x) * 2) / 3; c2y = (ey + (+c1y) * 2) / 3;
13312 c1x = (x + (+c1x) * 2) / 3; c1y = (y + (+c1y) * 2) / 3;
13313 } else {
13314 this._pivotX = +c2x; this._pivotY = +c2y;
13315 }
13316 if (this.penDownX == null){ this.penDownX = x; this.penDownY = y; }
13317 this.onBezierCurve(x, y, +c1x, +c1y, +c2x, +c2y, this.penX = +ex, this.penY = +ey);
13318 return this;
13319 },
13320
13321 arc: function(x, y, rx, ry, outer, counterClockwise, rotation){
13322 return this.arcTo(this.penX + (+x), this.penY + (+y), rx, ry, outer, counterClockwise, rotation);
13323 },
13324 arcTo: function(x, y, rx, ry, outer, counterClockwise, rotation){
13325 ry = Math.abs(+ry || +rx || (+y - this.penY));
13326 rx = Math.abs(+rx || (+x - this.penX));
13327
13328 if (!rx || !ry || (x == this.penX && y == this.penY)) return this.lineTo(x, y);
13329
13330 var tX = this.penX, tY = this.penY, clockwise = !+counterClockwise, large = !!+outer;
13331
13332 var rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad);
13333 x -= tX; y -= tY;
13334
13335 // Ellipse Center
13336 var cx = cos * x / 2 + sin * y / 2,
13337 cy = -sin * x / 2 + cos * y / 2,
13338 rxry = rx * rx * ry * ry,
13339 rycx = ry * ry * cx * cx,
13340 rxcy = rx * rx * cy * cy,
13341 a = rxry - rxcy - rycx;
13342
13343 if (a < 0){
13344 a = Math.sqrt(1 - a / rxry);
13345 rx *= a; ry *= a;
13346 cx = x / 2; cy = y / 2;
13347 } else {
13348 a = Math.sqrt(a / (rxcy + rycx));
13349 if (large == clockwise) a = -a;
13350 var cxd = -a * cy * rx / ry,
13351 cyd = a * cx * ry / rx;
13352 cx = cos * cxd - sin * cyd + x / 2;
13353 cy = sin * cxd + cos * cyd + y / 2;
13354 }
13355
13356 // Rotation + Scale Transform
13357 var xx = cos / rx, yx = sin / rx,
13358 xy = -sin / ry, yy = cos / ry;
13359
13360 // Start and End Angle
13361 var sa = Math.atan2(xy * -cx + yy * -cy, xx * -cx + yx * -cy),
13362 ea = Math.atan2(xy * (x - cx) + yy * (y - cy), xx * (x - cx) + yx * (y - cy));
13363
13364 cx += tX; cy += tY;
13365 x += tX; y += tY;
13366
13367 // Circular Arc
13368 if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
13369 this.onArc(
13370 tX, tY, this._pivotX = this.penX = x, this._pivotY = this.penY = y,
13371 cx, cy, rx, ry, sa, ea, !clockwise, rotation
13372 );
13373 return this;
13374 },
13375
13376 counterArc: function(x, y, rx, ry, outer){
13377 return this.arc(x, y, rx, ry, outer, true);
13378 },
13379 counterArcTo: function(x, y, rx, ry, outer){
13380 return this.arcTo(x, y, rx, ry, outer, true);
13381 },
13382
13383 close: function(){
13384 if (this.penDownX != null){
13385 this.onClose(this.penX, this.penY, this.penX = this.penDownX, this.penY = this.penDownY);
13386 this.penDownX = null;
13387 }
13388 return this;
13389 },
13390
13391 /* overridable handlers */
13392
13393 onReset: function(){
13394 },
13395
13396 onMove: function(sx, sy, ex, ey){
13397 },
13398
13399 onLine: function(sx, sy, ex, ey){
13400 this.onBezierCurve(sx, sy, sx, sy, ex, ey, ex, ey);
13401 },
13402
13403 onBezierCurve: function(sx, sy, c1x, c1y, c2x, c2y, ex, ey){
13404 var gx = ex - sx, gy = ey - sy,
13405 g = gx * gx + gy * gy,
13406 v1, v2, cx, cy, u;
13407
13408 cx = c1x - sx; cy = c1y - sy;
13409 u = cx * gx + cy * gy;
13410
13411 if (u > g){
13412 cx -= gx;
13413 cy -= gy;
13414 } else if (u > 0 && g != 0){
13415 cx -= u/g * gx;
13416 cy -= u/g * gy;
13417 }
13418
13419 v1 = cx * cx + cy * cy;
13420
13421 cx = c2x - sx; cy = c2y - sy;
13422 u = cx * gx + cy * gy;
13423
13424 if (u > g){
13425 cx -= gx;
13426 cy -= gy;
13427 } else if (u > 0 && g != 0){
13428 cx -= u/g * gx;
13429 cy -= u/g * gy;
13430 }
13431
13432 v2 = cx * cx + cy * cy;
13433
13434 if (v1 < 0.01 && v2 < 0.01){
13435 this.onLine(sx, sy, ex, ey);
13436 return;
13437 }
13438
13439 // Avoid infinite recursion
13440 if (isNaN(v1) || isNaN(v2)){
13441 throw new Error('Bad input');
13442 }
13443
13444 // Split curve
13445 var s1x = (c1x + c2x) * 0.5, s1y = (c1y + c2y) * 0.5,
13446 l1x = (c1x + sx) * 0.5, l1y = (c1y + sy) * 0.5,
13447 l2x = (l1x + s1x) * 0.5, l2y = (l1y + s1y) * 0.5,
13448 r2x = (ex + c2x) * 0.5, r2y = (ey + c2y) * 0.5,
13449 r1x = (r2x + s1x) * 0.5, r1y = (r2y + s1y) * 0.5,
13450 l2r1x = (l2x + r1x) * 0.5, l2r1y = (l2y + r1y) * 0.5;
13451
13452 // TODO: Manual stack if necessary. Currently recursive without tail optimization.
13453 this.onBezierCurve(sx, sy, l1x, l1y, l2x, l2y, l2r1x, l2r1y);
13454 this.onBezierCurve(l2r1x, l2r1y, r1x, r1y, r2x, r2y, ex, ey);
13455 },
13456
13457 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
13458 // Inverse Rotation + Scale Transform
13459 var rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad),
13460 xx = cos * rx, yx = -sin * ry,
13461 xy = sin * rx, yy = cos * ry;
13462
13463 // Bezier Curve Approximation
13464 var arc = ea - sa;
13465 if (arc < 0 && !ccw) arc += Math.PI * 2;
13466 else if (arc > 0 && ccw) arc -= Math.PI * 2;
13467
13468 var n = Math.ceil(Math.abs(arc / (Math.PI / 2))),
13469 step = arc / n,
13470 k = (4 / 3) * Math.tan(step / 4);
13471
13472 var x = Math.cos(sa), y = Math.sin(sa);
13473
13474 for (var i = 0; i < n; i++){
13475 var cp1x = x - k * y, cp1y = y + k * x;
13476
13477 sa += step;
13478 x = Math.cos(sa); y = Math.sin(sa);
13479
13480 var cp2x = x + k * y, cp2y = y - k * x;
13481
13482 this.onBezierCurve(
13483 sx, sy,
13484 cx + xx * cp1x + yx * cp1y, cy + xy * cp1x + yy * cp1y,
13485 cx + xx * cp2x + yx * cp2y, cy + xy * cp2x + yy * cp2y,
13486 (sx = (cx + xx * x + yx * y)), (sy = (cy + xy * x + yy * y))
13487 );
13488 }
13489 },
13490
13491 onClose: function(sx, sy, ex, ey){
13492 this.onLine(sx, sy, ex, ey);
13493 }
13494
13495});
13496
13497var CanvasPath = _class(path$2, {
13498
13499 initialize: function(path){
13500 this.reset();
13501 if (path instanceof CanvasPath){
13502 this.path = path.path.slice(0);
13503 } else if (path){
13504 if (path.applyToPath)
13505 path.applyToPath(this);
13506 else
13507 this.push(path);
13508 }
13509 },
13510
13511 onReset: function(){
13512 this.path = [];
13513 },
13514
13515 onMove: function(sx, sy, x, y){
13516 this.path.push(function(context){
13517 context.moveTo(x, y);
13518 });
13519 },
13520
13521 onLine: function(sx, sy, x, y){
13522 this.path.push(function(context){
13523 context.lineTo(x, y);
13524 });
13525 },
13526
13527 onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
13528 this.path.push(function(context){
13529 context.bezierCurveTo(p1x, p1y, p2x, p2y, x, y);
13530 });
13531 },
13532
13533 _arcToBezier: path$2.prototype.onArc,
13534
13535 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
13536 if (rx != ry || rotation) return this._arcToBezier(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation);
13537 this.path.push(function(context){
13538 context.arc(cx, cy, rx, sa, ea, ccw);
13539 });
13540 },
13541
13542 onClose: function(){
13543 this.path.push(function(context){
13544 context.closePath();
13545 });
13546 },
13547
13548 toCommands: function(){
13549 return this.path.slice(0);
13550 }
13551
13552});
13553
13554var path = CanvasPath;
13555
13556var colors = {
13557 maroon: '#800000', red: '#ff0000', orange: '#ffA500', yellow: '#ffff00', olive: '#808000',
13558 purple: '#800080', fuchsia: "#ff00ff", white: '#ffffff', lime: '#00ff00', green: '#008000',
13559 navy: '#000080', blue: '#0000ff', aqua: '#00ffff', teal: '#008080',
13560 black: '#000000', silver: '#c0c0c0', gray: '#808080'
13561};
13562
13563var map = function(array, fn){
13564 var results = [];
13565 for (var i = 0, l = array.length; i < l; i++)
13566 results[i] = fn(array[i], i);
13567 return results;
13568};
13569
13570var Color = function(color, type){
13571
13572 if (color.isColor){
13573
13574 this.red = color.red;
13575 this.green = color.green;
13576 this.blue = color.blue;
13577 this.alpha = color.alpha;
13578
13579 } else {
13580
13581 var namedColor = colors[color];
13582 if (namedColor){
13583 color = namedColor;
13584 type = 'hex';
13585 }
13586
13587 switch (typeof color){
13588 case 'string': if (!type) type = (type = color.match(/^rgb|^hsb|^hsl/)) ? type[0] : 'hex'; break;
13589 case 'object': type = type || 'rgb'; color = color.toString(); break;
13590 case 'number': type = 'hex'; color = color.toString(16); break;
13591 }
13592
13593 color = Color['parse' + type.toUpperCase()](color);
13594 this.red = color[0];
13595 this.green = color[1];
13596 this.blue = color[2];
13597 this.alpha = color[3];
13598 }
13599
13600 this.isColor = true;
13601
13602};
13603
13604var limit = function(number, min, max){
13605 return Math.min(max, Math.max(min, number));
13606};
13607
13608var listMatch = /([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,?\s*([-.\d]*\%?)/;
13609var hexMatch = /^#?([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{0,2})$/i;
13610
13611Color.parseRGB = function(color){
13612 return map(color.match(listMatch).slice(1), function(bit, i){
13613 if (bit) bit = parseFloat(bit) * (bit[bit.length - 1] == '%' ? 2.55 : 1);
13614 return (i < 3) ? Math.round(((bit %= 256) < 0) ? bit + 256 : bit) : limit(((bit === '') ? 1 : Number(bit)), 0, 1);
13615 });
13616};
13617
13618Color.parseHEX = function(color){
13619 if (color.length == 1) color = color + color + color;
13620 return map(color.match(hexMatch).slice(1), function(bit, i){
13621 if (i == 3) return (bit) ? parseInt(bit, 16) / 255 : 1;
13622 return parseInt((bit.length == 1) ? bit + bit : bit, 16);
13623 });
13624};
13625
13626Color.parseHSB = function(color){
13627 var hsb = map(color.match(listMatch).slice(1), function(bit, i){
13628 if (bit) bit = parseFloat(bit);
13629 if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
13630 else if (i < 3) return limit(Math.round(bit), 0, 100);
13631 else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
13632 });
13633
13634 var a = hsb[3];
13635 var br = Math.round(hsb[2] / 100 * 255);
13636 if (hsb[1] == 0) return [br, br, br, a];
13637
13638 var hue = hsb[0];
13639 var f = hue % 60;
13640 var p = Math.round((hsb[2] * (100 - hsb[1])) / 10000 * 255);
13641 var q = Math.round((hsb[2] * (6000 - hsb[1] * f)) / 600000 * 255);
13642 var t = Math.round((hsb[2] * (6000 - hsb[1] * (60 - f))) / 600000 * 255);
13643
13644 switch (Math.floor(hue / 60)){
13645 case 0: return [br, t, p, a];
13646 case 1: return [q, br, p, a];
13647 case 2: return [p, br, t, a];
13648 case 3: return [p, q, br, a];
13649 case 4: return [t, p, br, a];
13650 default: return [br, p, q, a];
13651 }
13652};
13653
13654Color.parseHSL = function(color){
13655 var hsb = map(color.match(listMatch).slice(1), function(bit, i){
13656 if (bit) bit = parseFloat(bit);
13657 if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
13658 else if (i < 3) return limit(Math.round(bit), 0, 100);
13659 else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
13660 });
13661
13662 var h = hsb[0] / 60;
13663 var s = hsb[1] / 100;
13664 var l = hsb[2] / 100;
13665 var a = hsb[3];
13666
13667 var c = (1 - Math.abs(2 * l - 1)) * s;
13668 var x = c * (1 - Math.abs(h % 2 - 1));
13669 var m = l - c / 2;
13670
13671 var p = Math.round((c + m) * 255);
13672 var q = Math.round((x + m) * 255);
13673 var t = Math.round((m) * 255);
13674
13675 switch (Math.floor(h)){
13676 case 0: return [p, q, t, a];
13677 case 1: return [q, p, t, a];
13678 case 2: return [t, p, q, a];
13679 case 3: return [t, q, p, a];
13680 case 4: return [q, t, p, a];
13681 default: return [p, t, q, a];
13682 }
13683};
13684
13685var toString = function(type, array){
13686 if (array[3] != 1) type += 'a';
13687 else array.pop();
13688 return type + '(' + array.join(', ') + ')';
13689};
13690
13691Color.prototype = {
13692
13693 toHSB: function(array){
13694 var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
13695
13696 var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
13697 var hue = 0, saturation = (delta != 0) ? delta / max : 0, brightness = max / 255;
13698 if (saturation){
13699 var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
13700 hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
13701 if ((hue /= 6) < 0) hue++;
13702 }
13703
13704 var hsb = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100), alpha];
13705
13706 return (array) ? hsb : toString('hsb', hsb);
13707 },
13708
13709 toHSL: function(array){
13710 var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
13711
13712 var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
13713 var hue = 0, saturation = (delta != 0) ? delta / (255 - Math.abs((max + min) - 255)) : 0, lightness = (max + min) / 512;
13714 if (saturation){
13715 var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
13716 hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
13717 if ((hue /= 6) < 0) hue++;
13718 }
13719
13720 var hsl = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(lightness * 100), alpha];
13721
13722 return (array) ? hsl : toString('hsl', hsl);
13723 },
13724
13725 toHEX: function(array){
13726
13727 var a = this.alpha;
13728 var alpha = ((a = Math.round((a * 255)).toString(16)).length == 1) ? a + a : a;
13729
13730 var hex = map([this.red, this.green, this.blue], function(bit){
13731 bit = bit.toString(16);
13732 return (bit.length == 1) ? '0' + bit : bit;
13733 });
13734
13735 return (array) ? hex.concat(alpha) : '#' + hex.join('') + ((alpha == 'ff') ? '' : alpha);
13736 },
13737
13738 toRGB: function(array){
13739 var rgb = [this.red, this.green, this.blue, this.alpha];
13740 return (array) ? rgb : toString('rgb', rgb);
13741 }
13742
13743};
13744
13745Color.prototype.toString = Color.prototype.toRGB;
13746
13747Color.hex = function(hex){
13748 return new Color(hex, 'hex');
13749};
13750
13751if (commonjsGlobal.hex == null) commonjsGlobal.hex = Color.hex;
13752
13753Color.hsb = function(h, s, b, a){
13754 return new Color([h || 0, s || 0, b || 0, (a == null) ? 1 : a], 'hsb');
13755};
13756
13757if (commonjsGlobal.hsb == null) commonjsGlobal.hsb = Color.hsb;
13758
13759Color.hsl = function(h, s, l, a){
13760 return new Color([h || 0, s || 0, l || 0, (a == null) ? 1 : a], 'hsl');
13761};
13762
13763if (commonjsGlobal.hsl == null) commonjsGlobal.hsl = Color.hsl;
13764
13765Color.rgb = function(r, g, b, a){
13766 return new Color([r || 0, g || 0, b || 0, (a == null) ? 1 : a], 'rgb');
13767};
13768
13769if (commonjsGlobal.rgb == null) commonjsGlobal.rgb = Color.rgb;
13770
13771Color.detach = function(color){
13772 color = new Color(color);
13773 return [Color.rgb(color.red, color.green, color.blue).toString(), color.alpha];
13774};
13775
13776var color = Color;
13777
13778var dummy = _class({
13779
13780 // placement
13781
13782 _resetPlacement: function(){
13783 var container = this.parentNode;
13784 if (container){
13785 var previous = this.previousSibling, next = this.nextSibling;
13786 if (previous){
13787 previous.nextSibling = next;
13788 } else {
13789 container.firstChild = next;
13790 }
13791 if (next){
13792 next.previousSibling = previous;
13793 } else {
13794 container.lastChild = this.previousSibling;
13795 }
13796 }
13797 this.previousSibling = null;
13798 this.nextSibling = null;
13799 this.parentNode = null;
13800 return this;
13801 },
13802
13803 inject: function(container){
13804 this._resetPlacement();
13805 var last = container.lastChild;
13806 if (last){
13807 last.nextSibling = this;
13808 this.previousSibling = last;
13809 } else {
13810 container.firstChild = this;
13811 }
13812 container.lastChild = this;
13813 this.parentNode = container;
13814 this._place();
13815 return this;
13816 },
13817
13818 injectBefore: function(sibling){
13819 this._resetPlacement();
13820 var container = sibling.parentNode;
13821 if (!container) return this;
13822 var previous = sibling.previousSibling;
13823 if (previous){
13824 previous.nextSibling = this;
13825 this.previousSibling = previous;
13826 } else {
13827 container.firstChild = this;
13828 }
13829 sibling.previousSibling = this;
13830 this.nextSibling = sibling;
13831 this.parentNode = container;
13832 this._place();
13833 return this;
13834 },
13835
13836 eject: function(){
13837 this._resetPlacement();
13838 this._place();
13839 return this;
13840 },
13841
13842 _place: function(){},
13843
13844 // events
13845
13846 dispatch: function(event){
13847 var events = this._events,
13848 listeners = events && events[event.type];
13849 if (listeners){
13850 listeners = listeners.slice(0);
13851 for (var i = 0, l = listeners.length; i < l; i++){
13852 var fn = listeners[i], result;
13853 if (typeof fn == 'function')
13854 result = fn.call(this, event);
13855 else
13856 result = fn.handleEvent(event);
13857 if (result === false) event.preventDefault();
13858 }
13859 }
13860 if (this.parentNode && this.parentNode.dispatch){
13861 this.parentNode.dispatch(event);
13862 }
13863 },
13864
13865 subscribe: function(type, fn, bind){
13866 if (typeof type != 'string'){ // listen type / fn with object
13867 var subscriptions = [];
13868 for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
13869 return function(){ // unsubscribe
13870 for (var i = 0, l = subscriptions.length; i < l; i++)
13871 subscriptions[i]();
13872 return this;
13873 };
13874 } else { // listen to one
13875 var bound = typeof fn === 'function' ? fn.bind(bind || this) : fn,
13876 events = this._events || (this._events = {}),
13877 listeners = events[type] || (events[type] = []);
13878 listeners.push(bound);
13879 return function(){
13880 // unsubscribe
13881 for (var i = 0, l = listeners.length; i < l; i++){
13882 if (listeners[i] === bound){
13883 listeners.splice(i, 1);
13884 break;
13885 }
13886 }
13887 }
13888 }
13889 }
13890
13891});
13892
13893var CanvasNode = _class(transform, dummy, {
13894
13895 invalidate: function(){
13896 if (this.parentNode) this.parentNode.invalidate();
13897 if (this._layer) this._layerCache = null;
13898 return this;
13899 },
13900
13901 _place: function(){
13902 this.invalidate();
13903 },
13904
13905 _transform: function(){
13906 this.invalidate();
13907 },
13908
13909 blend: function(opacity){
13910 if (opacity >= 1 && this._layer) this._layer = null;
13911 this._opacity = opacity;
13912 if (this.parentNode) this.parentNode.invalidate();
13913 return this;
13914 },
13915
13916 // visibility
13917
13918 hide: function(){
13919 this._invisible = true;
13920 if (this.parentNode) this.parentNode.invalidate();
13921 return this;
13922 },
13923
13924 show: function(){
13925 this._invisible = false;
13926 if (this.parentNode) this.parentNode.invalidate();
13927 return this;
13928 },
13929
13930 // interaction
13931
13932 indicate: function(cursor, tooltip){
13933 this._cursor = cursor;
13934 this._tooltip = tooltip;
13935 return this.invalidate();
13936 },
13937
13938 hitTest: function(x, y){
13939 if (this._invisible) return null;
13940 var point = this.inversePoint(x, y);
13941 if (!point) return null;
13942 return this.localHitTest(point.x, point.y);
13943 },
13944
13945 // rendering
13946
13947 renderTo: function(context, xx, yx, xy, yy, x, y){
13948 var opacity = this._opacity;
13949 if (opacity == null || opacity >= 1){
13950 return this.renderLayerTo(context, xx, yx, xy, yy, x, y);
13951 }
13952
13953 // Render to a compositing layer and cache it
13954
13955 var layer = this._layer, canvas, isDirty = true,
13956 w = context.canvas.width, h = context.canvas.height;
13957 if (layer){
13958 layer.setTransform(1, 0, 0, 1, 0, 0);
13959 canvas = layer.canvas;
13960 if (canvas.width < w || canvas.height < h){
13961 canvas.width = w;
13962 canvas.height = h;
13963 } else {
13964 var c = this._layerCache;
13965 if (c && c.xx === xx && c.yx === yx && c.xy === xy
13966 && c.yy === yy && c.x === x && c.y === y){
13967 isDirty = false;
13968 } else {
13969 layer.clearRect(0, 0, w, h);
13970 }
13971 }
13972 } else {
13973 canvas = document.createElement('canvas');
13974 canvas.width = w;
13975 canvas.height = h;
13976 this._layer = layer = canvas.getContext('2d');
13977 }
13978
13979 if (isDirty){
13980 this.renderLayerTo(layer, xx, yx, xy, yy, x, y);
13981 this._layerCache = {
13982 xx: xx,
13983 yx: yx,
13984 xy: xy,
13985 yy: yy,
13986 x: x,
13987 y: y
13988 };
13989 }
13990
13991 context.globalAlpha = opacity;
13992 context.setTransform(1, 0, 0, 1, 0, 0);
13993 context.drawImage(
13994 canvas,
13995 0, 0, w, h,
13996 0, 0, w, h
13997 );
13998 context.globalAlpha = 1;
13999 }
14000
14001});
14002
14003var node = CanvasNode;
14004
14005var genericCanvas = typeof document !== 'undefined' && document.createElement('canvas');
14006var genericContext = genericCanvas && genericCanvas.getContext && genericCanvas.getContext('2d');
14007
14008function recolorImage(img, color1, color2){
14009 // TODO: Fix this experimental implementation
14010 color1 = color.detach(color1);
14011 color2 = color.detach(color2);
14012 var canvas = document.createElement('canvas'),
14013 context = canvas.getContext('2d');
14014 canvas.width = img.width;
14015 canvas.height = img.height;
14016 context.fillStyle = color2[0];
14017 context.fillRect(0, 0, img.width, img.height);
14018 context.globalCompositeOperation = 'lighter';
14019 context.drawImage(img, 0, 0);
14020 return canvas;
14021}
14022
14023var Base = _class(node, {
14024
14025 initialize: function(){
14026 this._fill = null;
14027 this._pendingFill = null;
14028 this._fillTransform = null;
14029 this._stroke = null;
14030 this._strokeCap = null;
14031 this._strokeDash = null;
14032 this._strokeJoin = null;
14033 this._strokeWidth = null;
14034 },
14035
14036 /* styles */
14037
14038 _addColors: function(gradient, stops){
14039 // Enumerate stops, assumes offsets are enumerated in order
14040 // TODO: Sort. Chrome doesn't always enumerate in expected order but requires stops to be specified in order.
14041 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++)
14042 gradient.addColorStop(i / l, new color(stops[i]).toString());
14043 else for (var offset in stops)
14044 gradient.addColorStop(offset, new color(stops[offset]).toString());
14045 return gradient;
14046 },
14047
14048
14049 fill: function(color$$1){
14050 if (arguments.length > 1) return this.fillLinear(arguments);
14051 if (this._pendingFill) this._pendingFill();
14052 this._fill = color$$1 ? new color(color$$1).toString() : null;
14053 return this.invalidate();
14054 },
14055
14056 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
14057 if (focusX == null) focusX = (this.left || 0) + (this.width || 0) * 0.5;
14058 if (focusY == null) focusY = (this.top || 0) + (this.height || 0) * 0.5;
14059 if (radiusY == null) radiusY = radiusX || (this.height * 0.5) || 0;
14060 if (radiusX == null) radiusX = (this.width || 0) * 0.5;
14061 if (centerX == null) centerX = focusX;
14062 if (centerY == null) centerY = focusY;
14063
14064 centerX += centerX - focusX;
14065 centerY += centerY - focusY;
14066
14067 if (radiusX === 0 || radiusX === '0') return this.fillLinear(stops);
14068 var ys = radiusY / radiusX;
14069
14070 if (this._pendingFill) this._pendingFill();
14071
14072 var gradient = genericContext.createRadialGradient(focusX, focusY / ys, 0, centerX, centerY / ys, radiusX * 2);
14073
14074 // Double fill radius to simulate repeating gradient
14075 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++){
14076 gradient.addColorStop(i / l / 2, new color(stops[i]).toString());
14077 gradient.addColorStop(1 - i / l / 2, new color(stops[i]).toString());
14078 } else for (var offset in stops){
14079 gradient.addColorStop(offset / 2, new color(stops[offset]).toString());
14080 gradient.addColorStop(1- offset / 2, new color(stops[offset]).toString());
14081 }
14082
14083 this._fill = gradient;
14084 this._fillTransform = new transform(1, 0, 0, ys);
14085 return this.invalidate();
14086 },
14087
14088 fillLinear: function(stops, x1, y1, x2, y2){
14089 if (arguments.length < 5){
14090 var angle = ((x1 == null) ? 270 : x1) * Math.PI / 180;
14091
14092 var x = Math.cos(angle), y = -Math.sin(angle),
14093 l = (Math.abs(x) + Math.abs(y)) / 2,
14094 w = this.width || 1, h = this.height || 1;
14095
14096 x *= l; y *= l;
14097
14098 x1 = 0.5 - x;
14099 x2 = 0.5 + x;
14100 y1 = 0.5 - y;
14101 y2 = 0.5 + y;
14102 this._fillTransform = new transform(w, 0, 0, h);
14103 } else {
14104 this._fillTransform = null;
14105 }
14106 if (this._pendingFill) this._pendingFill();
14107 var gradient = genericContext.createLinearGradient(x1, y1, x2, y2);
14108 this._addColors(gradient, stops);
14109 this._fill = gradient;
14110 return this.invalidate();
14111 },
14112
14113 fillImage: function(url, width, height, left, top, color1, color2){
14114 if (this._pendingFill) this._pendingFill();
14115 var img = url;
14116 if (!(img instanceof Image)){
14117 img = new Image();
14118 img.src = url;
14119 }
14120 if (img.width && img.height){
14121 return this._fillImage(img, width, height, left || 0, top || 0, color1, color2);
14122 }
14123
14124 // Not yet loaded
14125 this._fill = null;
14126 var self = this,
14127 callback = function(){
14128 cancel();
14129 self._fillImage(img, width, height, left || 0, top || 0, color1, color2);
14130 },
14131 cancel = function(){
14132 img.removeEventListener('load', callback, false);
14133 self._pendingFill = null;
14134 };
14135 this._pendingFill = cancel;
14136 img.addEventListener('load', callback, false);
14137 return this;
14138 },
14139
14140 _fillImage: function(img, width, height, left, top, color1, color2){
14141 var w = width ? width / img.width : 1,
14142 h = height ? height / img.height : 1;
14143 if (color1 != null) img = recolorImage(img, color1, color2);
14144 this._fill = genericContext.createPattern(img, 'repeat');
14145 this._fillTransform = new transform(w, 0, 0, h, left || 0, top || 0);
14146 return this.invalidate();
14147 },
14148
14149 stroke: function(color$$1, width, cap, join, dash){
14150 this._stroke = color$$1 ? new color(color$$1).toString() : null;
14151 this._strokeWidth = (width != null) ? width : 1;
14152 this._strokeCap = (cap != null) ? cap : 'round';
14153 this._strokeJoin = (join != null) ? join : 'round';
14154 this._strokeDash = dash;
14155 return this.invalidate();
14156 },
14157
14158 // Rendering
14159
14160 element_renderTo: node.prototype.renderTo,
14161
14162 renderTo: function(context, xx, yx, xy, yy, x, y){
14163 var opacity = this._opacity;
14164 if (opacity == null || opacity >= 1){
14165 return this.renderLayerTo(context, xx, yx, xy, yy, x, y);
14166 }
14167 if (this._fill && this._stroke){
14168 return this.element_renderTo(context, xx, yx, xy, yy, x, y);
14169 }
14170 context.globalAlpha = opacity;
14171 var r = this.renderLayerTo(context, xx, yx, xy, yy, x, y);
14172 context.globalAlpha = 1;
14173 return r;
14174 },
14175
14176 renderLayerTo: function(context, xx, yx, xy, yy, x, y){
14177 context.setTransform(xx, yx, xy, yy, x, y);
14178 this.renderShapeTo(context);
14179 }
14180
14181});
14182
14183Base._genericContext = genericContext;
14184
14185var base = Base;
14186
14187var shape = _class(base, {
14188
14189 base_initialize: base.prototype.initialize,
14190
14191 initialize: function(path$$1, width, height){
14192 this.base_initialize();
14193 this.width = width;
14194 this.height = height;
14195 if (path$$1 != null) this.draw(path$$1);
14196 },
14197
14198 draw: function(path$$1, width, height){
14199 if (!(path$$1 instanceof path)) path$$1 = new path(path$$1);
14200 this.path = path$$1;
14201 this._commands = path$$1.toCommands();
14202 if (width != null) this.width = width;
14203 if (height != null) this.height = height;
14204 return this.invalidate();
14205 },
14206
14207 localHitTest: function(x, y){
14208 if (!this._fill) return null;
14209 if (this.width == null || this.height == null){
14210 var context = base._genericContext, commands = this._commands;
14211 if (!commands) return null;
14212 context.beginPath();
14213 for (var i = 0, l = commands.length; i < l; i++)
14214 commands[i](context);
14215 return context.isPointInPath(x, y) ? this : null;
14216 }
14217 if (x > 0 && y > 0 && x < this.width && y < this.height){
14218 return this;
14219 }
14220 return null;
14221 },
14222
14223 renderShapeTo: function(context){
14224 if (this._invisible || !this._commands || (!this._fill && !this._stroke)) {
14225 return null;
14226 }
14227 context.transform(this.xx, this.yx, this.xy, this.yy, this.x, this.y);
14228 var commands = this._commands,
14229 fill = this._fill,
14230 stroke = this._stroke,
14231 dash = this._strokeDash;
14232
14233 context.beginPath();
14234
14235 if (dash) {
14236 if (context.setLineDash) {
14237 context.setLineDash(dash);
14238 } else {
14239 // TODO: Remove when FF supports setLineDash.
14240 context.mozDash = dash;
14241 }
14242 // TODO: Create fallback to other browsers.
14243 } else {
14244 if (context.setLineDash) {
14245 context.setLineDash([]);
14246 } else {
14247 context.mozDash = null;
14248 }
14249 }
14250
14251 for (var i = 0, l = commands.length; i < l; i++)
14252 commands[i](context);
14253
14254 if (fill){
14255 var m = this._fillTransform;
14256 if (m){
14257 context.save(); // TODO: Optimize away this by restoring the transform before stroking
14258 context.transform(m.xx, m.yx, m.xy, m.yy, m.x, m.y);
14259 context.fillStyle = fill;
14260 context.fill();
14261 context.restore();
14262 } else {
14263 context.fillStyle = fill;
14264 context.fill();
14265 }
14266 }
14267 if (stroke){
14268 context.strokeStyle = stroke;
14269 context.lineWidth = this._strokeWidth;
14270 context.lineCap = this._strokeCap;
14271 context.lineJoin = this._strokeJoin;
14272 context.stroke();
14273 }
14274 }
14275
14276});
14277
14278var group = _class(node, container, {
14279
14280 initialize: function(width, height){
14281 this.width = width;
14282 this.height = height;
14283 },
14284
14285 localHitTest: function(x, y){
14286 var node$$2 = this.lastChild;
14287 while (node$$2){
14288 var hit = node$$2.hitTest(x, y);
14289 if (hit) return hit;
14290 node$$2 = node$$2.previousSibling;
14291 }
14292 return null;
14293 },
14294
14295 renderLayerTo: function(context, xx, yx, xy, yy, x, y){
14296 if (this._invisible) return;
14297
14298 x = xx * this.x + xy * this.y + x;
14299 y = yx * this.x + yy * this.y + y;
14300
14301 var t = xx;
14302 xx = t * this.xx + xy * this.yx;
14303 xy = t * this.xy + xy * this.yy;
14304 t = yx;
14305 yx = t * this.xx + yy * this.yx;
14306 yy = t * this.xy + yy * this.yy;
14307
14308 var node$$2 = this.firstChild;
14309 while (node$$2){
14310 node$$2.renderTo(context, xx, yx, xy, yy, x, y);
14311 node$$2 = node$$2.nextSibling;
14312 }
14313 }
14314
14315});
14316
14317var clippingrectangle = _class(node, container, {
14318
14319 initialize: function(width, height){
14320 this.width = width;
14321 this.height = height;
14322 },
14323
14324 localHitTest: function(x, y) {
14325 var node$$2 = this.lastChild;
14326 while (node$$2){
14327 var hit = node$$2.hitTest(x, y);
14328 if (hit) return hit;
14329 node$$2 = node$$2.previousSibling;
14330 }
14331 return null;
14332 },
14333
14334 renderLayerTo: function(context, xx, yx, xy, yy, x, y) {
14335 context.setTransform(xx, yx, xy, yy, x, y);
14336 context.save();
14337 // Need beginPath to fix Firefox bug. See 3354054.
14338 context.beginPath();
14339 context.rect(this.x, this.y, this.width, this.height);
14340 context.clip();
14341
14342 var node$$2 = this.firstChild;
14343 while(node$$2) {
14344 node$$2.renderTo(context, xx, yx, xy, yy, x, y);
14345 node$$2 = node$$2.nextSibling;
14346 }
14347 context.restore();
14348 }
14349});
14350
14351var fontAnchors = { middle: 'center' };
14352
14353var text = _class(base, {
14354
14355 base_initialize: base.prototype.initialize,
14356
14357 initialize: function(text, font, alignment, path){
14358 this.base_initialize();
14359 this.draw.apply(this, arguments);
14360 },
14361
14362 draw: function(text, font, alignment, path){
14363 var em;
14364 if (typeof font == 'string'){
14365 em = Number(/(\d+)/.exec(font)[0]);
14366 } else if (font){
14367 em = parseFloat(font.fontSize || font['font-size'] || '12');
14368 font = (font.fontStyle || font['font-style'] || '') + ' ' +
14369 (font.fontVariant || font['font-variant'] || '') + ' ' +
14370 (font.fontWeight || font['font-weight'] || '') + ' ' +
14371 em + 'px ' +
14372 (font.fontFamily || font['font-family'] || 'Arial');
14373 } else {
14374 font = this._font;
14375 }
14376
14377 var lines = text && text.split(/\r?\n/);
14378 this._font = font;
14379 this._fontSize = em;
14380 this._text = lines;
14381 this._alignment = fontAnchors[alignment] || alignment || 'left';
14382
14383 var context = base._genericContext;
14384
14385 context.font = this._font;
14386 context.textAlign = this._alignment;
14387 context.textBaseline = 'middle';
14388
14389 lines = this._text;
14390 var l = lines.length, width = 0;
14391 for (var i = 0; i < l; i++){
14392 var w = context.measureText(lines[i]).width;
14393 if (w > width) width = w;
14394 }
14395 this.width = width;
14396 this.height = l ? l * 1.1 * em : 0;
14397 return this.invalidate();
14398 },
14399
14400 // Interaction
14401
14402 localHitTest: function(x, y){
14403 if (!this._fill) return null;
14404 if (x > 0 && y > 0 && x < this.width && y < this.height){
14405 return this;
14406 }
14407 return null;
14408 },
14409
14410 // Rendering
14411
14412 renderShapeTo: function(context){
14413 if (this._invisible || !this._text || (!this._fill && !this._stroke)) {
14414 return null;
14415 }
14416 context.transform(this.xx, this.yx, this.xy, this.yy, this.x, this.y);
14417 var fill = this._fill,
14418 stroke = this._stroke,
14419 text = this._text,
14420 dash = this._strokeDash;
14421
14422 context.font = this._font;
14423 context.textAlign = this._alignment;
14424 context.textBaseline = 'middle';
14425
14426 var em = this._fontSize,
14427 y = em / 2,
14428 lineHeight = 1.1 * em,
14429 lines = text,
14430 l = lines.length;
14431
14432 if (fill){
14433 context.fillStyle = fill;
14434 for (var i = 0; i < l; i++)
14435 context.fillText(lines[i], 0, y + i * lineHeight);
14436 }
14437 if (stroke){
14438 if (dash) {
14439 if (context.setLineDash) {
14440 context.setLineDash(dash);
14441 } else {
14442 // TODO: Remove when FF supports setLineDash.
14443 context.mozDash = dash;
14444 }
14445 // TODO: Create fallback to other browsers.
14446 } else {
14447 if (context.setLineDash) {
14448 context.setLineDash([]);
14449 } else {
14450 context.mozDash = null;
14451 }
14452 }
14453
14454 context.strokeStyle = stroke;
14455 context.lineWidth = this._strokeWidth;
14456 context.lineCap = this._strokeCap;
14457 context.lineJoin = this._strokeJoin;
14458 for (i = 0; i < l; i++)
14459 context.strokeText(lines[i], 0, y + i * lineHeight);
14460 }
14461 }
14462
14463});
14464
14465var VMLCSS = 'behavior:url(#default#VML);display:inline-block;position:absolute;left:0px;top:0px;';
14466
14467var styleSheet;
14468var styledTags = {};
14469var styleTag = function(tag){
14470 if (styleSheet) styledTags[tag] = styleSheet.addRule('av\\:' + tag, VMLCSS);
14471};
14472
14473var init = function(document){
14474
14475 var namespaces;
14476 try { // IE9 workaround: sometimes it throws here
14477 namespaces = document.namespaces;
14478 } catch (e) {
14479 }
14480 if (!namespaces) return false;
14481
14482 namespaces.add('av', 'urn:schemas-microsoft-com:vml');
14483 namespaces.add('ao', 'urn:schemas-microsoft-com:office:office');
14484
14485 styleSheet = document.createStyleSheet();
14486 styleSheet.addRule('vml', 'display:inline-block;position:relative;overflow:hidden;');
14487/* styleTag('skew');
14488 styleTag('fill');
14489 styleTag('stroke');
14490 styleTag('path');
14491 styleTag('textpath');
14492 styleTag('group');*/
14493
14494 styleTag('vml');
14495
14496 return true;
14497
14498};
14499
14500var createElement = function(tag){
14501 if (!(tag in styledTags)) styleTag(tag);
14502 return document.createElement('av:' + tag);
14503};
14504
14505var dom = {
14506 init: init,
14507 createElement: createElement
14508};
14509
14510var precision = 100;
14511
14512var VMLSurface = _class(native_1, container, {
14513
14514 initialize: function VMLSurface(width, height, existingElement){
14515 this.element = existingElement || document.createElement('vml');
14516 this.containerElement = dom.createElement('group');
14517 this.element.appendChild(this.containerElement);
14518 if (width != null && height != null) this.resize(width, height);
14519 },
14520
14521 resize: function(width, height){
14522 this.width = width;
14523 this.height = height;
14524
14525 var style = this.element.style;
14526 style.pixelWidth = width;
14527 style.pixelHeight = height;
14528
14529 style = this.containerElement.style;
14530 style.width = width;
14531 style.height = height;
14532
14533 var halfPixel = (0.5 * precision);
14534
14535 this.containerElement.coordorigin = halfPixel + ',' + halfPixel;
14536 this.containerElement.coordsize = (width * precision) + ',' + (height * precision);
14537
14538 return this;
14539 }
14540
14541});
14542
14543VMLSurface.tagName = 'av:vml';
14544
14545var surface$2 = VMLSurface;
14546
14547var precision$1 = 100;
14548
14549var round = Math.round;
14550
14551var VMLPath = _class(path$2, {
14552
14553 initialize: function(path){
14554 this.reset();
14555 if (path instanceof VMLPath){
14556 this.path = [Array.prototype.join.call(path.path, ' ')];
14557 } else if (path){
14558 if (path.applyToPath)
14559 path.applyToPath(this);
14560 else
14561 this.push(path);
14562 }
14563 },
14564
14565 onReset: function(){
14566 this.path = [];
14567 },
14568
14569 onMove: function(sx, sy, x, y){
14570 this.path.push('m', round(x * precision$1), round(y * precision$1));
14571 },
14572
14573 onLine: function(sx, sy, x, y){
14574 this.path.push('l', round(x * precision$1), round(y * precision$1));
14575 },
14576
14577 onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
14578 this.path.push('c',
14579 round(p1x * precision$1), round(p1y * precision$1),
14580 round(p2x * precision$1), round(p2y * precision$1),
14581 round(x * precision$1), round(y * precision$1)
14582 );
14583 },
14584
14585 _arcToBezier: path$2.prototype.onArc,
14586
14587 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
14588 if (rx != ry || rotation) return this._arcToBezier(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation);
14589 cx *= precision$1;
14590 cy *= precision$1;
14591 rx *= precision$1;
14592 this.path.push(ccw ? 'at' : 'wa',
14593 round(cx - rx), round(cy - rx),
14594 round(cx + rx), round(cy + rx),
14595 round(sx * precision$1), round(sy * precision$1),
14596 round(ex * precision$1), round(ey * precision$1)
14597 );
14598 },
14599
14600 onClose: function(){
14601 this.path.push('x');
14602 },
14603
14604 toVML: function(){
14605 return this.path.join(' ');
14606 }
14607
14608});
14609
14610VMLPath.prototype.toString = VMLPath.prototype.toVML;
14611
14612var path$4 = VMLPath;
14613
14614var shadow = _class(dummy, native_1, {
14615
14616 dummy_inject: dummy.prototype.inject,
14617 dummy_injectBefore: dummy.prototype.injectBefore,
14618 dummy_eject: dummy.prototype.eject,
14619 native_inject: native_1.prototype.inject,
14620 native_injectBefore: native_1.prototype.injectBefore,
14621 native_eject: native_1.prototype.eject,
14622
14623 inject: function(container){
14624 this.dummy_inject(container);
14625 this.native_inject(container);
14626 return this;
14627 },
14628
14629 injectBefore: function(sibling){
14630 this.dummy_injectBefore(sibling);
14631 this.native_injectBefore(sibling);
14632 return this;
14633 },
14634
14635 eject: function(){
14636 this.dummy_eject();
14637 this.native_eject();
14638 return this;
14639 }
14640
14641});
14642
14643var node$2 = _class(shadow, transform, {
14644
14645 initialize: function(tag){
14646 //this.uid = uniqueID();
14647 var element = this.element = dom.createElement(tag);
14648 //element.setAttribute('id', 'e' + this.uid);
14649 },
14650
14651 _place: function(){
14652 if (this.parentNode){
14653 this._transform();
14654 }
14655 },
14656
14657 // visibility
14658
14659 hide: function(){
14660 this.element.style.display = 'none';
14661 return this;
14662 },
14663
14664 show: function(){
14665 this.element.style.display = '';
14666 return this;
14667 },
14668
14669 // interaction
14670
14671 indicate: function(cursor, tooltip){
14672 if (cursor) this.element.style.cursor = cursor;
14673 if (tooltip) this.element.title = tooltip;
14674 return this;
14675 }
14676
14677});
14678
14679var precision$3 = 100;
14680
14681var defaultBox = { left: 0, top: 0, width: 500, height: 500 };
14682
14683var base$2 = _class(node$2, {
14684
14685 element_initialize: node$2.prototype.initialize,
14686
14687 initialize: function(tag){
14688 this.element_initialize(tag);
14689 var element = this.element;
14690
14691 var skew = this.skewElement = dom.createElement('skew');
14692 skew.on = true;
14693 element.appendChild(skew);
14694
14695 var fill = this.fillElement = dom.createElement('fill');
14696 fill.on = false;
14697 element.appendChild(fill);
14698
14699 var stroke = this.strokeElement = dom.createElement('stroke');
14700 stroke.on = false;
14701 element.appendChild(stroke);
14702 },
14703
14704 /* transform */
14705
14706 _transform: function(){
14707 var container = this.parentNode;
14708
14709 // Active Transformation Matrix
14710 var m = container ? new transform(container._activeTransform).transform(this) : this;
14711
14712 // Box in shape user space
14713
14714 var box = this._boxCoords || this._size || defaultBox;
14715
14716 var originX = box.left || 0,
14717 originY = box.top || 0,
14718 width = box.width || 1,
14719 height = box.height || 1;
14720
14721 // Flipped
14722 var flip = m.yx / m.xx > m.yy / m.xy;
14723 if (m.xx < 0 ? m.xy >= 0 : m.xy < 0) flip = !flip;
14724 flip = flip ? -1 : 1;
14725
14726 m = new transform().scale(flip, 1).transform(m);
14727
14728 // Rotation is approximated based on the transform
14729 var rotation = Math.atan2(-m.xy, m.yy) * 180 / Math.PI;
14730
14731 // Reverse the rotation, leaving the final transform in box space
14732 var rad = rotation * Math.PI / 180, sin = Math.sin(rad), cos = Math.cos(rad);
14733
14734 var transform$$2 = new transform(
14735 (m.xx * cos - m.xy * sin),
14736 (m.yx * cos - m.yy * sin) * flip,
14737 (m.xy * cos + m.xx * sin) * flip,
14738 (m.yy * cos + m.yx * sin)
14739 );
14740
14741 var rotationTransform = new transform().rotate(rotation, 0, 0);
14742
14743 var shapeToBox = new transform().rotate(-rotation, 0, 0).transform(m).moveTo(0,0);
14744
14745 // Scale box after reversing rotation
14746 width *= Math.abs(shapeToBox.xx);
14747 height *= Math.abs(shapeToBox.yy);
14748
14749 // Place box
14750 var left = m.x, top = m.y;
14751
14752 // Compensate for offset by center origin rotation
14753 var vx = -width / 2, vy = -height / 2;
14754 var point = rotationTransform.point(vx, vy);
14755 left -= point.x - vx;
14756 top -= point.y - vy;
14757
14758 // Adjust box position based on offset
14759 var rsm = new transform(m).moveTo(0,0);
14760 point = rsm.point(originX, originY);
14761 left += point.x;
14762 top += point.y;
14763
14764 if (flip < 0) left = -left - width;
14765
14766 // Place transformation origin
14767 var point0 = rsm.point(-originX, -originY);
14768 var point1 = rotationTransform.point(width, height);
14769 var point2 = rotationTransform.point(width, 0);
14770 var point3 = rotationTransform.point(0, height);
14771
14772 var minX = Math.min(0, point1.x, point2.x, point3.x),
14773 maxX = Math.max(0, point1.x, point2.x, point3.x),
14774 minY = Math.min(0, point1.y, point2.y, point3.y),
14775 maxY = Math.max(0, point1.y, point2.y, point3.y);
14776
14777 var transformOriginX = (point0.x - point1.x / 2) / (maxX - minX) * flip,
14778 transformOriginY = (point0.y - point1.y / 2) / (maxY - minY);
14779
14780 // Adjust the origin
14781 point = shapeToBox.point(originX, originY);
14782 originX = point.x;
14783 originY = point.y;
14784
14785 // Scale stroke
14786 var strokeWidth = this._strokeWidth;
14787 if (strokeWidth){
14788 // Scale is the hypothenus between the two vectors
14789 // TODO: Use area calculation instead
14790 var vx = m.xx + m.xy, vy = m.yy + m.yx;
14791 strokeWidth *= Math.sqrt(vx * vx + vy * vy) / Math.sqrt(2);
14792 }
14793
14794 // convert to multiplied precision space
14795 originX *= precision$3;
14796 originY *= precision$3;
14797 left *= precision$3;
14798 top *= precision$3;
14799 width *= precision$3;
14800 height *= precision$3;
14801
14802 // Set box
14803 var element = this.element;
14804 element.coordorigin = originX + ',' + originY;
14805 element.coordsize = width + ',' + height;
14806 element.style.left = left + 'px';
14807 element.style.top = top + 'px';
14808 element.style.width = width;
14809 element.style.height = height;
14810 element.style.rotation = rotation.toFixed(8);
14811 element.style.flip = flip < 0 ? 'x' : '';
14812
14813 // Set transform
14814 var skew = this.skewElement;
14815 skew.matrix = [transform$$2.xx.toFixed(4), transform$$2.xy.toFixed(4), transform$$2.yx.toFixed(4), transform$$2.yy.toFixed(4), 0, 0];
14816 skew.origin = transformOriginX + ',' + transformOriginY;
14817
14818 // Set stroke
14819 this.strokeElement.weight = strokeWidth + 'px';
14820 },
14821
14822 /* styles */
14823
14824 _createGradient: function(style, stops){
14825 var fill = this.fillElement;
14826
14827 // Temporarily eject the fill from the DOM
14828 this.element.removeChild(fill);
14829
14830 fill.type = style;
14831 fill.method = 'none';
14832 fill.rotate = true;
14833
14834 var colors = [], color1, color2;
14835
14836 var addColor = function(offset, color$$2){
14837 color$$2 = color.detach(color$$2);
14838 if (color1 == null) color1 = color2 = color$$2;
14839 else color2 = color$$2;
14840 colors.push(offset + ' ' + color$$2[0]);
14841 };
14842
14843 // Enumerate stops, assumes offsets are enumerated in order
14844 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++) addColor(i / l, stops[i]);
14845 else for (var offset in stops) addColor(offset, stops[offset]);
14846
14847 fill.color = color1[0];
14848 fill.color2 = color2[0];
14849
14850 //if (fill.colors) fill.colors.value = colors; else
14851 fill.colors = colors;
14852
14853 // Opacity order gets flipped when color stops are specified
14854 fill.opacity = color2[1];
14855 fill['ao:opacity2'] = color1[1];
14856
14857 fill.on = true;
14858 this.element.appendChild(fill);
14859 return fill;
14860 },
14861
14862 _setColor: function(type, color$$2){
14863 var element = type == 'fill' ? this.fillElement : this.strokeElement;
14864 if (color$$2 == null){
14865 element.on = false;
14866 } else {
14867 color$$2 = color.detach(color$$2);
14868 element.color = color$$2[0];
14869 element.opacity = color$$2[1];
14870 element.on = true;
14871 }
14872 },
14873
14874 fill: function(color$$2){
14875 if (arguments.length > 1){
14876 this.fillLinear(arguments);
14877 } else {
14878 this._boxCoords = defaultBox;
14879 var fill = this.fillElement;
14880 fill.type = 'solid';
14881 fill.color2 = '';
14882 fill['ao:opacity2'] = '';
14883 if (fill.colors) fill.colors.value = '';
14884 this._setColor('fill', color$$2);
14885 }
14886 return this;
14887 },
14888
14889 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
14890 var fill = this._createGradient('gradientradial', stops);
14891 if (focusX == null) focusX = this.left + this.width * 0.5;
14892 if (focusY == null) focusY = this.top + this.height * 0.5;
14893 if (radiusY == null) radiusY = radiusX || (this.height * 0.5);
14894 if (radiusX == null) radiusX = this.width * 0.5;
14895 if (centerX == null) centerX = focusX;
14896 if (centerY == null) centerY = focusY;
14897
14898 centerX += centerX - focusX;
14899 centerY += centerY - focusY;
14900
14901 var box = this._boxCoords = {
14902 left: centerX - radiusX * 2,
14903 top: centerY - radiusY * 2,
14904 width: radiusX * 4,
14905 height: radiusY * 4
14906 };
14907 focusX -= box.left;
14908 focusY -= box.top;
14909 focusX /= box.width;
14910 focusY /= box.height;
14911
14912 fill.focussize = '0 0';
14913 fill.focusposition = focusX + ',' + focusY;
14914 fill.focus = '50%';
14915
14916 this._transform();
14917
14918 return this;
14919 },
14920
14921 fillLinear: function(stops, x1, y1, x2, y2){
14922 var fill = this._createGradient('gradient', stops);
14923 fill.focus = '100%';
14924 if (arguments.length == 5){
14925 var w = Math.abs(x2 - x1), h = Math.abs(y2 - y1);
14926 this._boxCoords = {
14927 left: Math.min(x1, x2),
14928 top: Math.min(y1, y2),
14929 width: w < 1 ? h : w,
14930 height: h < 1 ? w : h
14931 };
14932 fill.angle = (360 + Math.atan2((x2 - x1) / h, (y2 - y1) / w) * 180 / Math.PI) % 360;
14933 } else {
14934 this._boxCoords = null;
14935 fill.angle = (x1 == null) ? 0 : (90 + x1) % 360;
14936 }
14937 this._transform();
14938 return this;
14939 },
14940
14941 fillImage: function(url, width, height, left, top, color1, color2){
14942 var fill = this.fillElement;
14943 if (color1 != null){
14944 color1 = color.detach(color1);
14945 if (color2 != null) color2 = color.detach(color2);
14946 fill.type = 'pattern';
14947 fill.color = color1[0];
14948 fill.color2 = color2 == null ? color1[0] : color2[0];
14949 fill.opacity = color2 == null ? 0 : color2[1];
14950 fill['ao:opacity2'] = color1[1];
14951 } else {
14952 fill.type = 'tile';
14953 fill.color = '';
14954 fill.color2 = '';
14955 fill.opacity = 1;
14956 fill['ao:opacity2'] = 1;
14957 }
14958 if (fill.colors) fill.colors.value = '';
14959 fill.rotate = true;
14960 fill.src = url;
14961
14962 fill.size = '1,1';
14963 fill.position = '0,0';
14964 fill.origin = '0,0';
14965 fill.aspect = 'ignore'; // ignore, atleast, atmost
14966 fill.on = true;
14967
14968 if (!left) left = 0;
14969 if (!top) top = 0;
14970 this._boxCoords = width ? { left: left + 0.5, top: top + 0.5, width: width, height: height } : null;
14971 this._transform();
14972 return this;
14973 },
14974
14975 /* stroke */
14976
14977 stroke: function(color$$2, width, cap, join){
14978 var stroke = this.strokeElement;
14979 this._strokeWidth = (width != null) ? width : 1;
14980 stroke.weight = (width != null) ? width + 'px' : 1;
14981 stroke.endcap = (cap != null) ? ((cap == 'butt') ? 'flat' : cap) : 'round';
14982 stroke.joinstyle = (join != null) ? join : 'round';
14983
14984 this._setColor('stroke', color$$2);
14985 return this;
14986 }
14987
14988});
14989
14990var precision$2 = 100;
14991
14992var shape$2 = _class(base$2, {
14993
14994 base_initialize: base$2.prototype.initialize,
14995
14996 initialize: function(path, width, height){
14997 this.base_initialize('shape');
14998
14999 var p = this.pathElement = dom.createElement('path');
15000 p.gradientshapeok = true;
15001 this.element.appendChild(p);
15002
15003 this.width = width;
15004 this.height = height;
15005
15006 if (path != null) this.draw(path);
15007 },
15008
15009 // SVG to VML
15010
15011 draw: function(path, width, height){
15012
15013 if (!(path instanceof path$4)) path = new path$4(path);
15014 this._vml = path.toVML();
15015 //this._size = path.measure();
15016
15017 if (width != null) this.width = width;
15018 if (height != null) this.height = height;
15019
15020 if (!this._boxCoords) this._transform();
15021 this._redraw(this._prefix, this._suffix);
15022
15023 return this;
15024 },
15025
15026 // radial gradient workaround
15027
15028 _redraw: function(prefix, suffix){
15029 var vml = this._vml || '';
15030
15031 this._prefix = prefix;
15032 this._suffix = suffix;
15033 if (prefix){
15034 vml = [
15035 prefix, vml, suffix,
15036 // Don't stroke the path with the extra ellipse, redraw the stroked path separately
15037 'ns e', vml, 'nf'
15038 ].join(' ');
15039 }
15040
15041 this.element.path = vml + 'e';
15042 },
15043
15044 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
15045 var fill = this._createGradient('gradientradial', stops);
15046 if (focusX == null) focusX = (this.left || 0) + (this.width || 0) * 0.5;
15047 if (focusY == null) focusY = (this.top || 0) + (this.height || 0) * 0.5;
15048 if (radiusY == null) radiusY = radiusX || (this.height * 0.5) || 0;
15049 if (radiusX == null) radiusX = (this.width || 0) * 0.5;
15050 if (centerX == null) centerX = focusX;
15051 if (centerY == null) centerY = focusY;
15052
15053 centerX += centerX - focusX;
15054 centerY += centerY - focusY;
15055
15056 var cx = Math.round(centerX * precision$2),
15057 cy = Math.round(centerY * precision$2),
15058
15059 rx = Math.round(radiusX * 2 * precision$2),
15060 ry = Math.round(radiusY * 2 * precision$2),
15061
15062 arc = ['wa', cx - rx, cy - ry, cx + rx, cy + ry].join(' ');
15063
15064 this._redraw(
15065 // Resolve rendering bug
15066 ['m', cx, cy - ry, 'l', cx, cy - ry].join(' '),
15067 // Draw an ellipse around the path to force an elliptical gradient on any shape
15068 [
15069 'm', cx, cy - ry,
15070 arc, cx, cy - ry, cx, cy + ry, arc, cx, cy + ry, cx, cy - ry,
15071 arc, cx, cy - ry, cx, cy + ry, arc, cx, cy + ry, cx, cy - ry
15072 ].join(' ')
15073 );
15074
15075 this._boxCoords = { left: focusX - 2, top: focusY - 2, width: 4, height: 4 };
15076
15077 fill.focusposition = '0.5,0.5';
15078 fill.focussize = '0 0';
15079 fill.focus = '50%';
15080
15081 this._transform();
15082
15083 return this;
15084 }
15085
15086});
15087
15088var group$2 = _class(node$2, container, {
15089
15090 element_initialize: node$2.prototype.initialize,
15091
15092 initialize: function(width, height){
15093 this.element_initialize('group');
15094 this.width = width;
15095 this.height = height;
15096 },
15097
15098 _transform: function(){
15099 var element = this.element;
15100 element.coordorigin = '0,0';
15101 element.coordsize = '1000,1000';
15102 element.style.left = 0;
15103 element.style.top = 0;
15104 element.style.width = 1000;
15105 element.style.height = 1000;
15106 element.style.rotation = 0;
15107
15108 var container$$2 = this.parentNode;
15109 this._activeTransform = container$$2 ? new transform(container$$2._activeTransform).transform(this) : this;
15110 var node = this.firstChild;
15111 while (node){
15112 node._transform();
15113 node = node.nextSibling;
15114 }
15115 }
15116
15117});
15118
15119var clippingrectangle$2 = _class(node$2, container, {
15120
15121 element_initialize: node$2.prototype.initialize,
15122
15123 initialize: function(width, height){
15124 this.element_initialize('clippingrectangle');
15125 this.width = width;
15126 this.height = height;
15127 },
15128
15129 _transform: function(){
15130 var element = this.element;
15131 element.clip = true;
15132 element.coordorigin = -this.x + ',' + (-1 * this.y);
15133 element.coordsize = this.width + ',' + this.height;
15134 // IE8 doesn't like clipBottom. Don't ask me why.
15135 // element.style.clipBottom = this.height + this.y;
15136 element.style.clipLeft = this.x;
15137 element.style.clipRight = this.width + this.x;
15138 element.style.clipTop = this.y;
15139 element.style.left = -this.x;
15140 element.style.top = -this.y;
15141 element.style.width = this.width + this.x;
15142 element.style.height = this.height + this.y;
15143 element.style.rotation = 0;
15144
15145 var container$$2 = this.parentNode;
15146 this._activeTransform = container$$2 ? new transform(container$$2._activeTransform).transform(this) : this;
15147 var node = this.firstChild;
15148 while (node){
15149 node._transform();
15150 node = node.nextSibling;
15151 }
15152 }
15153
15154});
15155
15156var fontAnchors$1 = { start: 'left', middle: 'center', end: 'right' };
15157
15158var text$2 = _class(base$2, {
15159
15160 base_initialize: base$2.prototype.initialize,
15161
15162 initialize: function(text, font, alignment, path){
15163 this.base_initialize('shape');
15164
15165 var p = this.pathElement = dom.createElement('path');
15166 p.textpathok = true;
15167 this.element.appendChild(p);
15168
15169 p = this.textPathElement = dom.createElement("textpath");
15170 p.on = true;
15171 p.style['v-text-align'] = 'left';
15172 this.element.appendChild(p);
15173
15174 this.draw.apply(this, arguments);
15175 },
15176
15177 draw: function(text, font, alignment, path){
15178 var element = this.element,
15179 textPath = this.textPathElement,
15180 style = textPath.style;
15181
15182 textPath.string = text;
15183
15184 if (font){
15185 if (typeof font == 'string'){
15186 style.font = font;
15187 } else {
15188 for (var key in font){
15189 var ckey = key.camelCase ? key.camelCase() : key;
15190 if (ckey == 'fontFamily') style[ckey] = "'" + font[key] + "'";
15191 // NOT UNIVERSALLY SUPPORTED OPTIONS
15192 // else if (ckey == 'kerning') style['v-text-kern'] = !!font[key];
15193 // else if (ckey == 'rotateGlyphs') style['v-rotate-letters'] = !!font[key];
15194 // else if (ckey == 'letterSpacing') style['v-text-spacing'] = Number(font[key]) + '';
15195 else style[ckey] = font[key];
15196 }
15197 }
15198 }
15199
15200 if (alignment) style['v-text-align'] = fontAnchors$1[alignment] || alignment;
15201
15202 if (path){
15203 this.currentPath = path = new path$4(path);
15204 this.element.path = path.toVML();
15205 } else if (!this.currentPath){
15206 var i = -1, offsetRows = '\n';
15207 while ((i = text.indexOf('\n', i + 1)) > -1) offsetRows += '\n';
15208 textPath.string = offsetRows + textPath.string;
15209 this.element.path = 'm0,0l1,0';
15210 }
15211
15212 // Measuring the bounding box is currently necessary for gradients etc.
15213
15214 // Clone element because the element is dead once it has been in the DOM
15215 element = element.cloneNode(true);
15216 style = element.style;
15217
15218 // Reset coordinates while measuring
15219 element.coordorigin = '0,0';
15220 element.coordsize = '10000,10000';
15221 style.left = '0px';
15222 style.top = '0px';
15223 style.width = '10000px';
15224 style.height = '10000px';
15225 style.rotation = 0;
15226 element.removeChild(element.firstChild); // Remove skew
15227
15228 // Inject the clone into the document
15229
15230 var canvas = new surface$2(1, 1),
15231 group = new group$2(), // Wrapping it in a group seems to alleviate some client rect weirdness
15232 body = element.ownerDocument.body;
15233
15234 canvas.inject(body);
15235 group.element.appendChild(element);
15236 group.inject(canvas);
15237
15238 var ebb = element.getBoundingClientRect(),
15239 cbb = canvas.toElement().getBoundingClientRect();
15240
15241 canvas.eject();
15242
15243 this.left = ebb.left - cbb.left;
15244 this.top = ebb.top - cbb.top;
15245 this.width = ebb.right - ebb.left;
15246 this.height = ebb.bottom - ebb.top;
15247 this.right = ebb.right - cbb.left;
15248 this.bottom = ebb.bottom - cbb.top;
15249
15250 this._transform();
15251
15252 //this._size = { left: this.left, top: this.top, width: this.width, height: this.height};
15253 return this;
15254 }
15255
15256});
15257
15258var fastNoSideEffects = createCommonjsModule(function (module, exports) {
15259var hasCanvas = function(){
15260
15261 var canvas = document.createElement('canvas');
15262 return canvas && !!canvas.getContext;
15263
15264};
15265
15266if (hasCanvas()) {
15267 exports.Surface = surface;
15268 exports.Path = path;
15269 exports.Shape = shape;
15270 exports.Group = group;
15271 exports.ClippingRectangle = clippingrectangle;
15272 exports.Text = text;
15273} else {
15274 exports.Surface = surface$2;
15275 exports.Path = path$4;
15276 exports.Shape = shape$2;
15277 exports.Group = group$2;
15278 exports.ClippingRectangle = clippingrectangle$2;
15279 exports.Text = text$2;
15280
15281 var DOM$$1 = dom;
15282 if (typeof document !== 'undefined') DOM$$1.init(document);
15283}
15284});
15285
15286var fastNoSideEffects_1 = fastNoSideEffects.Surface;
15287var fastNoSideEffects_2 = fastNoSideEffects.Path;
15288var fastNoSideEffects_3 = fastNoSideEffects.Shape;
15289var fastNoSideEffects_4 = fastNoSideEffects.Group;
15290var fastNoSideEffects_5 = fastNoSideEffects.ClippingRectangle;
15291var fastNoSideEffects_6 = fastNoSideEffects.Text;
15292
15293var _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; };
15294
15295function _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; }
15296
15297function _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; }
15298
15299function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
15300
15301current.setCurrent(
15302// Change to 'art/modes/dom' for easier debugging via SVG
15303fastNoSideEffects);
15304
15305/** Declarative fill-type objects; API design not finalized */
15306
15307var slice = Array.prototype.slice;
15308
15309var LinearGradient = function () {
15310 function LinearGradient(stops, x1, y1, x2, y2) {
15311 _classCallCheck(this, LinearGradient);
15312
15313 this._args = slice.call(arguments);
15314 }
15315
15316 LinearGradient.prototype.applyFill = function applyFill(node) {
15317 node.fillLinear.apply(node, this._args);
15318 };
15319
15320 return LinearGradient;
15321}();
15322
15323var RadialGradient = function () {
15324 function RadialGradient(stops, fx, fy, rx, ry, cx, cy) {
15325 _classCallCheck(this, RadialGradient);
15326
15327 this._args = slice.call(arguments);
15328 }
15329
15330 RadialGradient.prototype.applyFill = function applyFill(node) {
15331 node.fillRadial.apply(node, this._args);
15332 };
15333
15334 return RadialGradient;
15335}();
15336
15337var Pattern = function () {
15338 function Pattern(url, width, height, left, top) {
15339 _classCallCheck(this, Pattern);
15340
15341 this._args = slice.call(arguments);
15342 }
15343
15344 Pattern.prototype.applyFill = function applyFill(node) {
15345 node.fillImage.apply(node, this._args);
15346 };
15347
15348 return Pattern;
15349}();
15350
15351/** React Components */
15352
15353var Surface = function (_React$Component) {
15354 _inherits(Surface, _React$Component);
15355
15356 function Surface() {
15357 _classCallCheck(this, Surface);
15358
15359 return _possibleConstructorReturn(this, _React$Component.apply(this, arguments));
15360 }
15361
15362 Surface.prototype.componentDidMount = function componentDidMount() {
15363 var _props = this.props,
15364 height = _props.height,
15365 width = _props.width;
15366
15367
15368 this._surface = current.Surface(+width, +height, this._tagRef);
15369
15370 this._mountNode = createContainer(this._surface);
15371 updateContainer(this.props.children, this._mountNode, this);
15372 };
15373
15374 Surface.prototype.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
15375 var props = this.props;
15376
15377 if (props.height !== prevProps.height || props.width !== prevProps.width) {
15378 this._surface.resize(+props.width, +props.height);
15379 }
15380
15381 updateContainer(this.props.children, this._mountNode, this);
15382
15383 if (this._surface.render) {
15384 this._surface.render();
15385 }
15386 };
15387
15388 Surface.prototype.componentWillUnmount = function componentWillUnmount() {
15389 updateContainer(null, this._mountNode, this);
15390 };
15391
15392 Surface.prototype.render = function render() {
15393 var _this2 = this;
15394
15395 // This is going to be a placeholder because we don't know what it will
15396 // actually resolve to because ART may render canvas, vml or svg tags here.
15397 // We only allow a subset of properties since others might conflict with
15398 // ART's properties.
15399 var props = this.props;
15400
15401 // TODO: ART's Canvas Mode overrides surface title and cursor
15402 var Tag = current.Surface.tagName;
15403
15404 return React.createElement(Tag, {
15405 ref: function (ref) {
15406 return _this2._tagRef = ref;
15407 },
15408 accessKey: props.accessKey,
15409 className: props.className,
15410 draggable: props.draggable,
15411 role: props.role,
15412 style: props.style,
15413 tabIndex: props.tabIndex,
15414 title: props.title
15415 });
15416 };
15417
15418 return Surface;
15419}(React.Component);
15420
15421var Text = function (_React$Component2) {
15422 _inherits(Text, _React$Component2);
15423
15424 function Text(props) {
15425 _classCallCheck(this, Text);
15426
15427 // We allow reading these props. Ideally we could expose the Text node as
15428 // ref directly.
15429 var _this3 = _possibleConstructorReturn(this, _React$Component2.call(this, props));
15430
15431 ['height', 'width', 'x', 'y'].forEach(function (key) {
15432 Object.defineProperty(_this3, key, {
15433 get: function () {
15434 return this._text ? this._text[key] : undefined;
15435 }
15436 });
15437 });
15438 return _this3;
15439 }
15440
15441 Text.prototype.render = function render() {
15442 var _this4 = this;
15443
15444 // This means you can't have children that render into strings...
15445 var T = TYPES.TEXT;
15446 return React.createElement(
15447 T,
15448 _extends({}, this.props, { ref: function (t) {
15449 return _this4._text = t;
15450 } }),
15451 childrenAsString(this.props.children)
15452 );
15453 };
15454
15455 return Text;
15456}(React.Component);
15457
15458injectIntoDevTools({
15459 findFiberByHostInstance: function () {
15460 return null;
15461 },
15462 bundleType: 1,
15463 version: ReactVersion,
15464 rendererPackageName: 'react-art'
15465});
15466
15467/** API */
15468
15469var ClippingRectangle = TYPES.CLIPPING_RECTANGLE;
15470var Group = TYPES.GROUP;
15471var Shape = TYPES.SHAPE;
15472var Path = current.Path;
15473
15474
15475var ReactART = Object.freeze({
15476 ClippingRectangle: ClippingRectangle,
15477 Group: Group,
15478 Shape: Shape,
15479 Path: Path,
15480 LinearGradient: LinearGradient,
15481 Pattern: Pattern,
15482 RadialGradient: RadialGradient,
15483 Surface: Surface,
15484 Text: Text,
15485 Transform: transform
15486});
15487
15488var reactArt = ReactART;
15489
15490return reactArt;
15491
15492})));