UNPKG

543 kBJavaScriptView Raw
1/** @license React v16.8.1
2 * react-art.development.js
3 *
4 * Copyright (c) Facebook, Inc. and its affiliates.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9
10'use strict';
11
12(function (global, factory) {
13 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react')) :
14 typeof define === 'function' && define.amd ? define(['react'], factory) :
15 (global.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.1';
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;
275
276// Don't change these two values. They're used by React Dev Tools.
277var NoEffect = /* */0;
278var PerformedWork = /* */1;
279
280// You can change the rest (and add more).
281var Placement = /* */2;
282var Update = /* */4;
283var PlacementAndUpdate = /* */6;
284var Deletion = /* */8;
285var ContentReset = /* */16;
286var Callback = /* */32;
287var DidCapture = /* */64;
288var Ref = /* */128;
289var Snapshot = /* */256;
290var Passive = /* */512;
291
292// Passive & Update & Callback & Ref & Snapshot
293var LifecycleEffectMask = /* */932;
294
295// Union of all host effects
296var HostEffectMask = /* */1023;
297
298var Incomplete = /* */1024;
299var ShouldCapture = /* */2048;
300
301var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
302
303var MOUNTING = 1;
304var MOUNTED = 2;
305var UNMOUNTED = 3;
306
307function isFiberMountedImpl(fiber) {
308 var node = fiber;
309 if (!fiber.alternate) {
310 // If there is no alternate, this might be a new tree that isn't inserted
311 // yet. If it is, then it will have a pending insertion effect on it.
312 if ((node.effectTag & Placement) !== NoEffect) {
313 return MOUNTING;
314 }
315 while (node.return) {
316 node = node.return;
317 if ((node.effectTag & Placement) !== NoEffect) {
318 return MOUNTING;
319 }
320 }
321 } else {
322 while (node.return) {
323 node = node.return;
324 }
325 }
326 if (node.tag === HostRoot) {
327 // TODO: Check if this was a nested HostRoot when used with
328 // renderContainerIntoSubtree.
329 return MOUNTED;
330 }
331 // If we didn't hit the root, that means that we're in an disconnected tree
332 // that has been unmounted.
333 return UNMOUNTED;
334}
335
336function isFiberMounted(fiber) {
337 return isFiberMountedImpl(fiber) === MOUNTED;
338}
339
340function isMounted(component) {
341 {
342 var owner = ReactCurrentOwner.current;
343 if (owner !== null && owner.tag === ClassComponent) {
344 var ownerFiber = owner;
345 var instance = ownerFiber.stateNode;
346 !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;
347 instance._warnedAboutRefsInRender = true;
348 }
349 }
350
351 var fiber = get(component);
352 if (!fiber) {
353 return false;
354 }
355 return isFiberMountedImpl(fiber) === MOUNTED;
356}
357
358function assertIsMounted(fiber) {
359 !(isFiberMountedImpl(fiber) === MOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
360}
361
362function findCurrentFiberUsingSlowPath(fiber) {
363 var alternate = fiber.alternate;
364 if (!alternate) {
365 // If there is no alternate, then we only need to check if it is mounted.
366 var state = isFiberMountedImpl(fiber);
367 !(state !== UNMOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
368 if (state === MOUNTING) {
369 return null;
370 }
371 return fiber;
372 }
373 // If we have two possible branches, we'll walk backwards up to the root
374 // to see what path the root points to. On the way we may hit one of the
375 // special cases and we'll deal with them.
376 var a = fiber;
377 var b = alternate;
378 while (true) {
379 var parentA = a.return;
380 var parentB = parentA ? parentA.alternate : null;
381 if (!parentA || !parentB) {
382 // We're at the root.
383 break;
384 }
385
386 // If both copies of the parent fiber point to the same child, we can
387 // assume that the child is current. This happens when we bailout on low
388 // priority: the bailed out fiber's child reuses the current child.
389 if (parentA.child === parentB.child) {
390 var child = parentA.child;
391 while (child) {
392 if (child === a) {
393 // We've determined that A is the current branch.
394 assertIsMounted(parentA);
395 return fiber;
396 }
397 if (child === b) {
398 // We've determined that B is the current branch.
399 assertIsMounted(parentA);
400 return alternate;
401 }
402 child = child.sibling;
403 }
404 // We should never have an alternate for any mounting node. So the only
405 // way this could possibly happen is if this was unmounted, if at all.
406 invariant(false, 'Unable to find node on an unmounted component.');
407 }
408
409 if (a.return !== b.return) {
410 // The return pointer of A and the return pointer of B point to different
411 // fibers. We assume that return pointers never criss-cross, so A must
412 // belong to the child set of A.return, and B must belong to the child
413 // set of B.return.
414 a = parentA;
415 b = parentB;
416 } else {
417 // The return pointers point to the same fiber. We'll have to use the
418 // default, slow path: scan the child sets of each parent alternate to see
419 // which child belongs to which set.
420 //
421 // Search parent A's child set
422 var didFindChild = false;
423 var _child = parentA.child;
424 while (_child) {
425 if (_child === a) {
426 didFindChild = true;
427 a = parentA;
428 b = parentB;
429 break;
430 }
431 if (_child === b) {
432 didFindChild = true;
433 b = parentA;
434 a = parentB;
435 break;
436 }
437 _child = _child.sibling;
438 }
439 if (!didFindChild) {
440 // Search parent B's child set
441 _child = parentB.child;
442 while (_child) {
443 if (_child === a) {
444 didFindChild = true;
445 a = parentB;
446 b = parentA;
447 break;
448 }
449 if (_child === b) {
450 didFindChild = true;
451 b = parentB;
452 a = parentA;
453 break;
454 }
455 _child = _child.sibling;
456 }
457 !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;
458 }
459 }
460
461 !(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;
462 }
463 // If the root is not a host container, we're in a disconnected tree. I.e.
464 // unmounted.
465 !(a.tag === HostRoot) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
466 if (a.stateNode.current === a) {
467 // We've determined that A is the current branch.
468 return fiber;
469 }
470 // Otherwise B has to be current branch.
471 return alternate;
472}
473
474function findCurrentHostFiber(parent) {
475 var currentParent = findCurrentFiberUsingSlowPath(parent);
476 if (!currentParent) {
477 return null;
478 }
479
480 // Next we'll drill down this component to find the first HostComponent/Text.
481 var node = currentParent;
482 while (true) {
483 if (node.tag === HostComponent || node.tag === HostText) {
484 return node;
485 } else if (node.child) {
486 node.child.return = node;
487 node = node.child;
488 continue;
489 }
490 if (node === currentParent) {
491 return null;
492 }
493 while (!node.sibling) {
494 if (!node.return || node.return === currentParent) {
495 return null;
496 }
497 node = node.return;
498 }
499 node.sibling.return = node.return;
500 node = node.sibling;
501 }
502 // Flow needs the return null here, but ESLint complains about it.
503 // eslint-disable-next-line no-unreachable
504 return null;
505}
506
507var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
508
509var _ReactInternals$Sched = ReactInternals$1.Scheduler;
510var unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback;
511var unstable_now = _ReactInternals$Sched.unstable_now;
512var unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback;
513var unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield;
514var unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode;
515var unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution;
516var unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution;
517
518var _class = function(mixins){
519 var proto = {};
520 for (var i = 0, l = arguments.length; i < l; i++){
521 var mixin = arguments[i];
522 if (typeof mixin == 'function') mixin = mixin.prototype;
523 for (var key in mixin) proto[key] = mixin[key];
524 }
525 if (!proto.initialize) proto.initialize = function(){};
526 proto.constructor = function(a,b,c,d,e,f,g,h){
527 return new proto.initialize(a,b,c,d,e,f,g,h);
528 };
529 proto.constructor.prototype = proto.initialize.prototype = proto;
530 return proto.constructor;
531};
532
533function Transform(xx, yx, xy, yy, x, y){
534 if (xx && typeof xx == 'object'){
535 yx = xx.yx; yy = xx.yy; y = xx.y;
536 xy = xx.xy; x = xx.x; xx = xx.xx;
537 }
538 this.xx = xx == null ? 1 : xx;
539 this.yx = yx || 0;
540 this.xy = xy || 0;
541 this.yy = yy == null ? 1 : yy;
542 this.x = (x == null ? this.x : x) || 0;
543 this.y = (y == null ? this.y : y) || 0;
544 this._transform();
545 return this;
546}
547
548var transform = _class({
549
550 initialize: Transform,
551
552 _transform: function(){},
553
554 xx: 1, yx: 0, x: 0,
555 xy: 0, yy: 1, y: 0,
556
557 transform: function(xx, yx, xy, yy, x, y){
558 var m = this;
559 if (xx && typeof xx == 'object'){
560 yx = xx.yx; yy = xx.yy; y = xx.y;
561 xy = xx.xy; x = xx.x; xx = xx.xx;
562 }
563 if (!x) x = 0;
564 if (!y) y = 0;
565 return this.transformTo(
566 m.xx * xx + m.xy * yx,
567 m.yx * xx + m.yy * yx,
568 m.xx * xy + m.xy * yy,
569 m.yx * xy + m.yy * yy,
570 m.xx * x + m.xy * y + m.x,
571 m.yx * x + m.yy * y + m.y
572 );
573 },
574
575 transformTo: Transform,
576
577 translate: function(x, y){
578 return this.transform(1, 0, 0, 1, x, y);
579 },
580
581 move: function(x, y){
582 this.x += x || 0;
583 this.y += y || 0;
584 this._transform();
585 return this;
586 },
587
588 scale: function(x, y){
589 if (y == null) y = x;
590 return this.transform(x, 0, 0, y, 0, 0);
591 },
592
593 rotate: function(deg, x, y){
594 if (x == null || y == null){
595 x = (this.left || 0) + (this.width || 0) / 2;
596 y = (this.top || 0) + (this.height || 0) / 2;
597 }
598
599 var rad = deg * Math.PI / 180, sin = Math.sin(rad), cos = Math.cos(rad);
600
601 this.transform(1, 0, 0, 1, x, y);
602 var m = this;
603
604 return this.transformTo(
605 cos * m.xx - sin * m.yx,
606 sin * m.xx + cos * m.yx,
607 cos * m.xy - sin * m.yy,
608 sin * m.xy + cos * m.yy,
609 m.x,
610 m.y
611 ).transform(1, 0, 0, 1, -x, -y);
612 },
613
614 moveTo: function(x, y){
615 var m = this;
616 return this.transformTo(m.xx, m.yx, m.xy, m.yy, x, y);
617 },
618
619 rotateTo: function(deg, x, y){
620 var m = this;
621 var flip = m.yx / m.xx > m.yy / m.xy ? -1 : 1;
622 if (m.xx < 0 ? m.xy >= 0 : m.xy < 0) flip = -flip;
623 return this.rotate(deg - Math.atan2(flip * m.yx, flip * m.xx) * 180 / Math.PI, x, y);
624 },
625
626 scaleTo: function(x, y){
627 // Normalize
628 var m = this;
629
630 var h = Math.sqrt(m.xx * m.xx + m.yx * m.yx);
631 m.xx /= h; m.yx /= h;
632
633 h = Math.sqrt(m.yy * m.yy + m.xy * m.xy);
634 m.yy /= h; m.xy /= h;
635
636 return this.scale(x, y);
637 },
638
639 resizeTo: function(width, height){
640 var w = this.width, h = this.height;
641 if (!w || !h) return this;
642 return this.scaleTo(width / w, height / h);
643 },
644
645 /*
646 inverse: function(){
647 var a = this.xx, b = this.yx,
648 c = this.xy, d = this.yy,
649 e = this.x, f = this.y;
650 if (a * d - b * c == 0) return null;
651 return new Transform(
652 d/(a * d-b * c), b/(b * c-a * d),
653 c/(b * c-a * d), a/(a * d-b * c),
654 (d * e-c * f)/(b * c-a * d), (b * e-a * f)/(a * d-b * c)
655 );
656 },
657 */
658
659 inversePoint: function(x, y){
660 var a = this.xx, b = this.yx,
661 c = this.xy, d = this.yy,
662 e = this.x, f = this.y;
663 var det = b * c - a * d;
664 if (det == 0) return null;
665 return {
666 x: (d * (e - x) + c * (y - f)) / det,
667 y: (a * (f - y) + b * (x - e)) / det
668 };
669 },
670
671 point: function(x, y){
672 var m = this;
673 return {
674 x: m.xx * x + m.xy * y + m.x,
675 y: m.yx * x + m.yy * y + m.y
676 };
677 }
678
679});
680
681var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
682
683
684
685
686
687function createCommonjsModule(fn, module) {
688 return module = { exports: {} }, fn(module, module.exports), module.exports;
689}
690
691var current = createCommonjsModule(function (module, exports) {
692function warning(){
693 throw new Error('You must require a mode before requiring anything else.');
694}
695
696exports.Surface = warning;
697exports.Path = warning;
698exports.Shape = warning;
699exports.Group = warning;
700exports.ClippingRectangle = warning;
701exports.Text = warning;
702
703exports.setCurrent = function(mode){
704 for (var key in mode){
705 exports[key] = mode[key];
706 }
707};
708});
709
710var current_1 = current.Surface;
711var current_2 = current.Path;
712var current_3 = current.Shape;
713var current_4 = current.Group;
714var current_5 = current.ClippingRectangle;
715var current_6 = current.Text;
716var current_7 = current.setCurrent;
717
718var TYPES = {
719 CLIPPING_RECTANGLE: 'ClippingRectangle',
720 GROUP: 'Group',
721 SHAPE: 'Shape',
722 TEXT: 'Text'
723};
724
725var EVENT_TYPES = {
726 onClick: 'click',
727 onMouseMove: 'mousemove',
728 onMouseOver: 'mouseover',
729 onMouseOut: 'mouseout',
730 onMouseUp: 'mouseup',
731 onMouseDown: 'mousedown'
732};
733
734function childrenAsString(children) {
735 if (!children) {
736 return '';
737 } else if (typeof children === 'string') {
738 return children;
739 } else if (children.length) {
740 return children.join('');
741 } else {
742 return '';
743 }
744}
745
746// Renderers that don't support persistence
747// can re-export everything from this module.
748
749function shim() {
750 invariant(false, 'The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue.');
751}
752
753// Persistence (when unsupported)
754var supportsPersistence = false;
755var cloneInstance = shim;
756var createContainerChildSet = shim;
757var appendChildToContainerChildSet = shim;
758var finalizeContainerChildren = shim;
759var replaceContainerChildren = shim;
760var cloneHiddenInstance = shim;
761var cloneUnhiddenInstance = shim;
762var createHiddenTextInstance = shim;
763
764// Renderers that don't support hydration
765// can re-export everything from this module.
766
767function shim$1() {
768 invariant(false, 'The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue.');
769}
770
771// Hydration (when unsupported)
772var supportsHydration = false;
773var canHydrateInstance = shim$1;
774var canHydrateTextInstance = shim$1;
775var getNextHydratableSibling = shim$1;
776var getFirstHydratableChild = shim$1;
777var hydrateInstance = shim$1;
778var hydrateTextInstance = shim$1;
779var didNotMatchHydratedContainerTextInstance = shim$1;
780var didNotMatchHydratedTextInstance = shim$1;
781var didNotHydrateContainerInstance = shim$1;
782var didNotHydrateInstance = shim$1;
783var didNotFindHydratableContainerInstance = shim$1;
784var didNotFindHydratableContainerTextInstance = shim$1;
785var didNotFindHydratableInstance = shim$1;
786var didNotFindHydratableTextInstance = shim$1;
787
788var pooledTransform = new transform();
789
790var NO_CONTEXT = {};
791var UPDATE_SIGNAL = {};
792{
793 Object.freeze(NO_CONTEXT);
794 Object.freeze(UPDATE_SIGNAL);
795}
796
797/** Helper Methods */
798
799function addEventListeners(instance, type, listener) {
800 // We need to explicitly unregister before unmount.
801 // For this reason we need to track subscriptions.
802 if (!instance._listeners) {
803 instance._listeners = {};
804 instance._subscriptions = {};
805 }
806
807 instance._listeners[type] = listener;
808
809 if (listener) {
810 if (!instance._subscriptions[type]) {
811 instance._subscriptions[type] = instance.subscribe(type, createEventHandler(instance), instance);
812 }
813 } else {
814 if (instance._subscriptions[type]) {
815 instance._subscriptions[type]();
816 delete instance._subscriptions[type];
817 }
818 }
819}
820
821function createEventHandler(instance) {
822 return function handleEvent(event) {
823 var listener = instance._listeners[event.type];
824
825 if (!listener) {
826 // Noop
827 } else if (typeof listener === 'function') {
828 listener.call(instance, event);
829 } else if (listener.handleEvent) {
830 listener.handleEvent(event);
831 }
832 };
833}
834
835function destroyEventListeners(instance) {
836 if (instance._subscriptions) {
837 for (var type in instance._subscriptions) {
838 instance._subscriptions[type]();
839 }
840 }
841
842 instance._subscriptions = null;
843 instance._listeners = null;
844}
845
846function getScaleX(props) {
847 if (props.scaleX != null) {
848 return props.scaleX;
849 } else if (props.scale != null) {
850 return props.scale;
851 } else {
852 return 1;
853 }
854}
855
856function getScaleY(props) {
857 if (props.scaleY != null) {
858 return props.scaleY;
859 } else if (props.scale != null) {
860 return props.scale;
861 } else {
862 return 1;
863 }
864}
865
866function isSameFont(oldFont, newFont) {
867 if (oldFont === newFont) {
868 return true;
869 } else if (typeof newFont === 'string' || typeof oldFont === 'string') {
870 return false;
871 } else {
872 return newFont.fontSize === oldFont.fontSize && newFont.fontStyle === oldFont.fontStyle && newFont.fontVariant === oldFont.fontVariant && newFont.fontWeight === oldFont.fontWeight && newFont.fontFamily === oldFont.fontFamily;
873 }
874}
875
876/** Render Methods */
877
878function applyClippingRectangleProps(instance, props) {
879 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
880
881 applyNodeProps(instance, props, prevProps);
882
883 instance.width = props.width;
884 instance.height = props.height;
885}
886
887function applyGroupProps(instance, props) {
888 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
889
890 applyNodeProps(instance, props, prevProps);
891
892 instance.width = props.width;
893 instance.height = props.height;
894}
895
896function applyNodeProps(instance, props) {
897 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
898
899 var scaleX = getScaleX(props);
900 var scaleY = getScaleY(props);
901
902 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);
903
904 if (props.transform != null) {
905 pooledTransform.transform(props.transform);
906 }
907
908 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) {
909 instance.transformTo(pooledTransform);
910 }
911
912 if (props.cursor !== prevProps.cursor || props.title !== prevProps.title) {
913 instance.indicate(props.cursor, props.title);
914 }
915
916 if (instance.blend && props.opacity !== prevProps.opacity) {
917 instance.blend(props.opacity == null ? 1 : props.opacity);
918 }
919
920 if (props.visible !== prevProps.visible) {
921 if (props.visible == null || props.visible) {
922 instance.show();
923 } else {
924 instance.hide();
925 }
926 }
927
928 for (var type in EVENT_TYPES) {
929 addEventListeners(instance, EVENT_TYPES[type], props[type]);
930 }
931}
932
933function applyRenderableNodeProps(instance, props) {
934 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
935
936 applyNodeProps(instance, props, prevProps);
937
938 if (prevProps.fill !== props.fill) {
939 if (props.fill && props.fill.applyFill) {
940 props.fill.applyFill(instance);
941 } else {
942 instance.fill(props.fill);
943 }
944 }
945 if (prevProps.stroke !== props.stroke || prevProps.strokeWidth !== props.strokeWidth || prevProps.strokeCap !== props.strokeCap || prevProps.strokeJoin !== props.strokeJoin ||
946 // TODO: Consider deep check of stokeDash; may benefit VML in IE.
947 prevProps.strokeDash !== props.strokeDash) {
948 instance.stroke(props.stroke, props.strokeWidth, props.strokeCap, props.strokeJoin, props.strokeDash);
949 }
950}
951
952function applyShapeProps(instance, props) {
953 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
954
955 applyRenderableNodeProps(instance, props, prevProps);
956
957 var path = props.d || childrenAsString(props.children);
958
959 var prevDelta = instance._prevDelta;
960 var prevPath = instance._prevPath;
961
962 if (path !== prevPath || path.delta !== prevDelta || prevProps.height !== props.height || prevProps.width !== props.width) {
963 instance.draw(path, props.width, props.height);
964
965 instance._prevDelta = path.delta;
966 instance._prevPath = path;
967 }
968}
969
970function applyTextProps(instance, props) {
971 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
972
973 applyRenderableNodeProps(instance, props, prevProps);
974
975 var string = props.children;
976
977 if (instance._currentString !== string || !isSameFont(props.font, prevProps.font) || props.alignment !== prevProps.alignment || props.path !== prevProps.path) {
978 instance.draw(string, props.font, props.alignment, props.path);
979
980 instance._currentString = string;
981 }
982}
983
984function appendInitialChild(parentInstance, child) {
985 if (typeof child === 'string') {
986 // Noop for string children of Text (eg <Text>{'foo'}{'bar'}</Text>)
987 invariant(false, 'Text children should already be flattened.');
988 return;
989 }
990
991 child.inject(parentInstance);
992}
993
994function createInstance(type, props, internalInstanceHandle) {
995 var instance = void 0;
996
997 switch (type) {
998 case TYPES.CLIPPING_RECTANGLE:
999 instance = current.ClippingRectangle();
1000 instance._applyProps = applyClippingRectangleProps;
1001 break;
1002 case TYPES.GROUP:
1003 instance = current.Group();
1004 instance._applyProps = applyGroupProps;
1005 break;
1006 case TYPES.SHAPE:
1007 instance = current.Shape();
1008 instance._applyProps = applyShapeProps;
1009 break;
1010 case TYPES.TEXT:
1011 instance = current.Text(props.children, props.font, props.alignment, props.path);
1012 instance._applyProps = applyTextProps;
1013 break;
1014 }
1015
1016 !instance ? invariant(false, 'ReactART does not support the type "%s"', type) : void 0;
1017
1018 instance._applyProps(instance, props);
1019
1020 return instance;
1021}
1022
1023function createTextInstance(text, rootContainerInstance, internalInstanceHandle) {
1024 return text;
1025}
1026
1027function finalizeInitialChildren(domElement, type, props) {
1028 return false;
1029}
1030
1031function getPublicInstance(instance) {
1032 return instance;
1033}
1034
1035function prepareForCommit() {
1036 // Noop
1037}
1038
1039function prepareUpdate(domElement, type, oldProps, newProps) {
1040 return UPDATE_SIGNAL;
1041}
1042
1043function resetAfterCommit() {
1044 // Noop
1045}
1046
1047function resetTextContent(domElement) {
1048 // Noop
1049}
1050
1051function shouldDeprioritizeSubtree(type, props) {
1052 return false;
1053}
1054
1055function getRootHostContext() {
1056 return NO_CONTEXT;
1057}
1058
1059function getChildHostContext() {
1060 return NO_CONTEXT;
1061}
1062
1063var scheduleTimeout = setTimeout;
1064var cancelTimeout = clearTimeout;
1065var noTimeout = -1;
1066var schedulePassiveEffects = unstable_scheduleCallback;
1067var cancelPassiveEffects = unstable_cancelCallback;
1068
1069function shouldSetTextContent(type, props) {
1070 return typeof props.children === 'string' || typeof props.children === 'number';
1071}
1072
1073// The ART renderer is secondary to the React DOM renderer.
1074var isPrimaryRenderer = false;
1075
1076var supportsMutation = true;
1077
1078function appendChild(parentInstance, child) {
1079 if (child.parentNode === parentInstance) {
1080 child.eject();
1081 }
1082 child.inject(parentInstance);
1083}
1084
1085function appendChildToContainer(parentInstance, child) {
1086 if (child.parentNode === parentInstance) {
1087 child.eject();
1088 }
1089 child.inject(parentInstance);
1090}
1091
1092function insertBefore(parentInstance, child, beforeChild) {
1093 !(child !== beforeChild) ? invariant(false, 'ReactART: Can not insert node before itself') : void 0;
1094 child.injectBefore(beforeChild);
1095}
1096
1097function insertInContainerBefore(parentInstance, child, beforeChild) {
1098 !(child !== beforeChild) ? invariant(false, 'ReactART: Can not insert node before itself') : void 0;
1099 child.injectBefore(beforeChild);
1100}
1101
1102function removeChild(parentInstance, child) {
1103 destroyEventListeners(child);
1104 child.eject();
1105}
1106
1107function removeChildFromContainer(parentInstance, child) {
1108 destroyEventListeners(child);
1109 child.eject();
1110}
1111
1112
1113
1114
1115
1116function commitUpdate(instance, updatePayload, type, oldProps, newProps) {
1117 instance._applyProps(instance, newProps, oldProps);
1118}
1119
1120function hideInstance(instance) {
1121 instance.hide();
1122}
1123
1124
1125
1126function unhideInstance(instance, props) {
1127 if (props.visible == null || props.visible) {
1128 instance.show();
1129 }
1130}
1131
1132function unhideTextInstance(textInstance, text) {
1133 // Noop
1134}
1135
1136/**
1137 * Copyright (c) 2013-present, Facebook, Inc.
1138 *
1139 * This source code is licensed under the MIT license found in the
1140 * LICENSE file in the root directory of this source tree.
1141 */
1142
1143
1144
1145var ReactPropTypesSecret$1 = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
1146
1147var ReactPropTypesSecret_1 = ReactPropTypesSecret$1;
1148
1149/**
1150 * Copyright (c) 2013-present, Facebook, Inc.
1151 *
1152 * This source code is licensed under the MIT license found in the
1153 * LICENSE file in the root directory of this source tree.
1154 */
1155
1156
1157
1158var printWarning = function() {};
1159
1160{
1161 var ReactPropTypesSecret = ReactPropTypesSecret_1;
1162 var loggedTypeFailures = {};
1163
1164 printWarning = function(text) {
1165 var message = 'Warning: ' + text;
1166 if (typeof console !== 'undefined') {
1167 console.error(message);
1168 }
1169 try {
1170 // --- Welcome to debugging React ---
1171 // This error was thrown as a convenience so that you can use this stack
1172 // to find the callsite that caused this warning to fire.
1173 throw new Error(message);
1174 } catch (x) {}
1175 };
1176}
1177
1178/**
1179 * Assert that the values match with the type specs.
1180 * Error messages are memorized and will only be shown once.
1181 *
1182 * @param {object} typeSpecs Map of name to a ReactPropType
1183 * @param {object} values Runtime values that need to be type-checked
1184 * @param {string} location e.g. "prop", "context", "child context"
1185 * @param {string} componentName Name of the component for error messages.
1186 * @param {?Function} getStack Returns the component stack.
1187 * @private
1188 */
1189function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
1190 {
1191 for (var typeSpecName in typeSpecs) {
1192 if (typeSpecs.hasOwnProperty(typeSpecName)) {
1193 var error;
1194 // Prop type validation may throw. In case they do, we don't want to
1195 // fail the render phase where it didn't fail before. So we log it.
1196 // After these have been cleaned up, we'll let them throw.
1197 try {
1198 // This is intentionally an invariant that gets caught. It's the same
1199 // behavior as without this statement except with a better message.
1200 if (typeof typeSpecs[typeSpecName] !== 'function') {
1201 var err = Error(
1202 (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +
1203 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.'
1204 );
1205 err.name = 'Invariant Violation';
1206 throw err;
1207 }
1208 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
1209 } catch (ex) {
1210 error = ex;
1211 }
1212 if (error && !(error instanceof Error)) {
1213 printWarning(
1214 (componentName || 'React class') + ': type specification of ' +
1215 location + ' `' + typeSpecName + '` is invalid; the type checker ' +
1216 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +
1217 'You may have forgotten to pass an argument to the type checker ' +
1218 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
1219 'shape all require an argument).'
1220 );
1221
1222 }
1223 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
1224 // Only monitor this failure once because there tends to be a lot of the
1225 // same error.
1226 loggedTypeFailures[error.message] = true;
1227
1228 var stack = getStack ? getStack() : '';
1229
1230 printWarning(
1231 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')
1232 );
1233 }
1234 }
1235 }
1236 }
1237}
1238
1239var checkPropTypes_1 = checkPropTypes;
1240
1241var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
1242
1243var describeComponentFrame = function (name, source, ownerName) {
1244 var sourceInfo = '';
1245 if (source) {
1246 var path = source.fileName;
1247 var fileName = path.replace(BEFORE_SLASH_RE, '');
1248 {
1249 // In DEV, include code for a common special case:
1250 // prefer "folder/index.js" instead of just "index.js".
1251 if (/^index\./.test(fileName)) {
1252 var match = path.match(BEFORE_SLASH_RE);
1253 if (match) {
1254 var pathBeforeSlash = match[1];
1255 if (pathBeforeSlash) {
1256 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
1257 fileName = folderName + '/' + fileName;
1258 }
1259 }
1260 }
1261 }
1262 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
1263 } else if (ownerName) {
1264 sourceInfo = ' (created by ' + ownerName + ')';
1265 }
1266 return '\n in ' + (name || 'Unknown') + sourceInfo;
1267};
1268
1269var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
1270
1271function describeFiber(fiber) {
1272 switch (fiber.tag) {
1273 case HostRoot:
1274 case HostPortal:
1275 case HostText:
1276 case Fragment:
1277 case ContextProvider:
1278 case ContextConsumer:
1279 return '';
1280 default:
1281 var owner = fiber._debugOwner;
1282 var source = fiber._debugSource;
1283 var name = getComponentName(fiber.type);
1284 var ownerName = null;
1285 if (owner) {
1286 ownerName = getComponentName(owner.type);
1287 }
1288 return describeComponentFrame(name, source, ownerName);
1289 }
1290}
1291
1292function getStackByFiberInDevAndProd(workInProgress) {
1293 var info = '';
1294 var node = workInProgress;
1295 do {
1296 info += describeFiber(node);
1297 node = node.return;
1298 } while (node);
1299 return info;
1300}
1301
1302var current$1 = null;
1303var phase = null;
1304
1305function getCurrentFiberOwnerNameInDevOrNull() {
1306 {
1307 if (current$1 === null) {
1308 return null;
1309 }
1310 var owner = current$1._debugOwner;
1311 if (owner !== null && typeof owner !== 'undefined') {
1312 return getComponentName(owner.type);
1313 }
1314 }
1315 return null;
1316}
1317
1318function getCurrentFiberStackInDev() {
1319 {
1320 if (current$1 === null) {
1321 return '';
1322 }
1323 // Safe because if current fiber exists, we are reconciling,
1324 // and it is guaranteed to be the work-in-progress version.
1325 return getStackByFiberInDevAndProd(current$1);
1326 }
1327 return '';
1328}
1329
1330function resetCurrentFiber() {
1331 {
1332 ReactDebugCurrentFrame.getCurrentStack = null;
1333 current$1 = null;
1334 phase = null;
1335 }
1336}
1337
1338function setCurrentFiber(fiber) {
1339 {
1340 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
1341 current$1 = fiber;
1342 phase = null;
1343 }
1344}
1345
1346function setCurrentPhase(lifeCyclePhase) {
1347 {
1348 phase = lifeCyclePhase;
1349 }
1350}
1351
1352var enableUserTimingAPI = true;
1353
1354// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
1355var debugRenderPhaseSideEffects = false;
1356
1357// In some cases, StrictMode should also double-render lifecycles.
1358// This can be confusing for tests though,
1359// And it can be bad for performance in production.
1360// This feature flag can be used to control the behavior:
1361var debugRenderPhaseSideEffectsForStrictMode = true;
1362
1363// To preserve the "Pause on caught exceptions" behavior of the debugger, we
1364// replay the begin phase of a failed component inside invokeGuardedCallback.
1365var replayFailedUnitOfWorkWithInvokeGuardedCallback = true;
1366
1367// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
1368var warnAboutDeprecatedLifecycles = false;
1369
1370// Gather advanced timing metrics for Profiler subtrees.
1371var enableProfilerTimer = true;
1372
1373// Trace which interactions trigger each commit.
1374var enableSchedulerTracing = true;
1375
1376// Only used in www builds.
1377 // TODO: true? Here it might just be false.
1378
1379// Only used in www builds.
1380
1381
1382// Only used in www builds.
1383
1384
1385// React Fire: prevent the value and checked attributes from syncing
1386// with their related DOM properties
1387
1388
1389// These APIs will no longer be "unstable" in the upcoming 16.7 release,
1390// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
1391
1392// Prefix measurements so that it's possible to filter them.
1393// Longer prefixes are hard to read in DevTools.
1394var reactEmoji = '\u269B';
1395var warningEmoji = '\u26D4';
1396var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
1397
1398// Keep track of current fiber so that we know the path to unwind on pause.
1399// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
1400var currentFiber = null;
1401// If we're in the middle of user code, which fiber and method is it?
1402// Reusing `currentFiber` would be confusing for this because user code fiber
1403// can change during commit phase too, but we don't need to unwind it (since
1404// lifecycles in the commit phase don't resemble a tree).
1405var currentPhase = null;
1406var currentPhaseFiber = null;
1407// Did lifecycle hook schedule an update? This is often a performance problem,
1408// so we will keep track of it, and include it in the report.
1409// Track commits caused by cascading updates.
1410var isCommitting = false;
1411var hasScheduledUpdateInCurrentCommit = false;
1412var hasScheduledUpdateInCurrentPhase = false;
1413var commitCountInCurrentWorkLoop = 0;
1414var effectCountInCurrentCommit = 0;
1415var isWaitingForCallback = false;
1416// During commits, we only show a measurement once per method name
1417// to avoid stretch the commit phase with measurement overhead.
1418var labelsInCurrentCommit = new Set();
1419
1420var formatMarkName = function (markName) {
1421 return reactEmoji + ' ' + markName;
1422};
1423
1424var formatLabel = function (label, warning) {
1425 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
1426 var suffix = warning ? ' Warning: ' + warning : '';
1427 return '' + prefix + label + suffix;
1428};
1429
1430var beginMark = function (markName) {
1431 performance.mark(formatMarkName(markName));
1432};
1433
1434var clearMark = function (markName) {
1435 performance.clearMarks(formatMarkName(markName));
1436};
1437
1438var endMark = function (label, markName, warning) {
1439 var formattedMarkName = formatMarkName(markName);
1440 var formattedLabel = formatLabel(label, warning);
1441 try {
1442 performance.measure(formattedLabel, formattedMarkName);
1443 } catch (err) {}
1444 // If previous mark was missing for some reason, this will throw.
1445 // This could only happen if React crashed in an unexpected place earlier.
1446 // Don't pile on with more errors.
1447
1448 // Clear marks immediately to avoid growing buffer.
1449 performance.clearMarks(formattedMarkName);
1450 performance.clearMeasures(formattedLabel);
1451};
1452
1453var getFiberMarkName = function (label, debugID) {
1454 return label + ' (#' + debugID + ')';
1455};
1456
1457var getFiberLabel = function (componentName, isMounted, phase) {
1458 if (phase === null) {
1459 // These are composite component total time measurements.
1460 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
1461 } else {
1462 // Composite component methods.
1463 return componentName + '.' + phase;
1464 }
1465};
1466
1467var beginFiberMark = function (fiber, phase) {
1468 var componentName = getComponentName(fiber.type) || 'Unknown';
1469 var debugID = fiber._debugID;
1470 var isMounted = fiber.alternate !== null;
1471 var label = getFiberLabel(componentName, isMounted, phase);
1472
1473 if (isCommitting && labelsInCurrentCommit.has(label)) {
1474 // During the commit phase, we don't show duplicate labels because
1475 // there is a fixed overhead for every measurement, and we don't
1476 // want to stretch the commit phase beyond necessary.
1477 return false;
1478 }
1479 labelsInCurrentCommit.add(label);
1480
1481 var markName = getFiberMarkName(label, debugID);
1482 beginMark(markName);
1483 return true;
1484};
1485
1486var clearFiberMark = function (fiber, phase) {
1487 var componentName = getComponentName(fiber.type) || 'Unknown';
1488 var debugID = fiber._debugID;
1489 var isMounted = fiber.alternate !== null;
1490 var label = getFiberLabel(componentName, isMounted, phase);
1491 var markName = getFiberMarkName(label, debugID);
1492 clearMark(markName);
1493};
1494
1495var endFiberMark = function (fiber, phase, warning) {
1496 var componentName = getComponentName(fiber.type) || 'Unknown';
1497 var debugID = fiber._debugID;
1498 var isMounted = fiber.alternate !== null;
1499 var label = getFiberLabel(componentName, isMounted, phase);
1500 var markName = getFiberMarkName(label, debugID);
1501 endMark(label, markName, warning);
1502};
1503
1504var shouldIgnoreFiber = function (fiber) {
1505 // Host components should be skipped in the timeline.
1506 // We could check typeof fiber.type, but does this work with RN?
1507 switch (fiber.tag) {
1508 case HostRoot:
1509 case HostComponent:
1510 case HostText:
1511 case HostPortal:
1512 case Fragment:
1513 case ContextProvider:
1514 case ContextConsumer:
1515 case Mode:
1516 return true;
1517 default:
1518 return false;
1519 }
1520};
1521
1522var clearPendingPhaseMeasurement = function () {
1523 if (currentPhase !== null && currentPhaseFiber !== null) {
1524 clearFiberMark(currentPhaseFiber, currentPhase);
1525 }
1526 currentPhaseFiber = null;
1527 currentPhase = null;
1528 hasScheduledUpdateInCurrentPhase = false;
1529};
1530
1531var pauseTimers = function () {
1532 // Stops all currently active measurements so that they can be resumed
1533 // if we continue in a later deferred loop from the same unit of work.
1534 var fiber = currentFiber;
1535 while (fiber) {
1536 if (fiber._debugIsCurrentlyTiming) {
1537 endFiberMark(fiber, null, null);
1538 }
1539 fiber = fiber.return;
1540 }
1541};
1542
1543var resumeTimersRecursively = function (fiber) {
1544 if (fiber.return !== null) {
1545 resumeTimersRecursively(fiber.return);
1546 }
1547 if (fiber._debugIsCurrentlyTiming) {
1548 beginFiberMark(fiber, null);
1549 }
1550};
1551
1552var resumeTimers = function () {
1553 // Resumes all measurements that were active during the last deferred loop.
1554 if (currentFiber !== null) {
1555 resumeTimersRecursively(currentFiber);
1556 }
1557};
1558
1559function recordEffect() {
1560 if (enableUserTimingAPI) {
1561 effectCountInCurrentCommit++;
1562 }
1563}
1564
1565function recordScheduleUpdate() {
1566 if (enableUserTimingAPI) {
1567 if (isCommitting) {
1568 hasScheduledUpdateInCurrentCommit = true;
1569 }
1570 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
1571 hasScheduledUpdateInCurrentPhase = true;
1572 }
1573 }
1574}
1575
1576function startRequestCallbackTimer() {
1577 if (enableUserTimingAPI) {
1578 if (supportsUserTiming && !isWaitingForCallback) {
1579 isWaitingForCallback = true;
1580 beginMark('(Waiting for async callback...)');
1581 }
1582 }
1583}
1584
1585function stopRequestCallbackTimer(didExpire, expirationTime) {
1586 if (enableUserTimingAPI) {
1587 if (supportsUserTiming) {
1588 isWaitingForCallback = false;
1589 var warning = didExpire ? 'React was blocked by main thread' : null;
1590 endMark('(Waiting for async callback... will force flush in ' + expirationTime + ' ms)', '(Waiting for async callback...)', warning);
1591 }
1592 }
1593}
1594
1595function startWorkTimer(fiber) {
1596 if (enableUserTimingAPI) {
1597 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1598 return;
1599 }
1600 // If we pause, this is the fiber to unwind from.
1601 currentFiber = fiber;
1602 if (!beginFiberMark(fiber, null)) {
1603 return;
1604 }
1605 fiber._debugIsCurrentlyTiming = true;
1606 }
1607}
1608
1609function cancelWorkTimer(fiber) {
1610 if (enableUserTimingAPI) {
1611 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1612 return;
1613 }
1614 // Remember we shouldn't complete measurement for this fiber.
1615 // Otherwise flamechart will be deep even for small updates.
1616 fiber._debugIsCurrentlyTiming = false;
1617 clearFiberMark(fiber, null);
1618 }
1619}
1620
1621function stopWorkTimer(fiber) {
1622 if (enableUserTimingAPI) {
1623 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1624 return;
1625 }
1626 // If we pause, its parent is the fiber to unwind from.
1627 currentFiber = fiber.return;
1628 if (!fiber._debugIsCurrentlyTiming) {
1629 return;
1630 }
1631 fiber._debugIsCurrentlyTiming = false;
1632 endFiberMark(fiber, null, null);
1633 }
1634}
1635
1636function stopFailedWorkTimer(fiber) {
1637 if (enableUserTimingAPI) {
1638 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1639 return;
1640 }
1641 // If we pause, its parent is the fiber to unwind from.
1642 currentFiber = fiber.return;
1643 if (!fiber._debugIsCurrentlyTiming) {
1644 return;
1645 }
1646 fiber._debugIsCurrentlyTiming = false;
1647 var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
1648 endFiberMark(fiber, null, warning);
1649 }
1650}
1651
1652function startPhaseTimer(fiber, phase) {
1653 if (enableUserTimingAPI) {
1654 if (!supportsUserTiming) {
1655 return;
1656 }
1657 clearPendingPhaseMeasurement();
1658 if (!beginFiberMark(fiber, phase)) {
1659 return;
1660 }
1661 currentPhaseFiber = fiber;
1662 currentPhase = phase;
1663 }
1664}
1665
1666function stopPhaseTimer() {
1667 if (enableUserTimingAPI) {
1668 if (!supportsUserTiming) {
1669 return;
1670 }
1671 if (currentPhase !== null && currentPhaseFiber !== null) {
1672 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
1673 endFiberMark(currentPhaseFiber, currentPhase, warning);
1674 }
1675 currentPhase = null;
1676 currentPhaseFiber = null;
1677 }
1678}
1679
1680function startWorkLoopTimer(nextUnitOfWork) {
1681 if (enableUserTimingAPI) {
1682 currentFiber = nextUnitOfWork;
1683 if (!supportsUserTiming) {
1684 return;
1685 }
1686 commitCountInCurrentWorkLoop = 0;
1687 // This is top level call.
1688 // Any other measurements are performed within.
1689 beginMark('(React Tree Reconciliation)');
1690 // Resume any measurements that were in progress during the last loop.
1691 resumeTimers();
1692 }
1693}
1694
1695function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
1696 if (enableUserTimingAPI) {
1697 if (!supportsUserTiming) {
1698 return;
1699 }
1700 var warning = null;
1701 if (interruptedBy !== null) {
1702 if (interruptedBy.tag === HostRoot) {
1703 warning = 'A top-level update interrupted the previous render';
1704 } else {
1705 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
1706 warning = 'An update to ' + componentName + ' interrupted the previous render';
1707 }
1708 } else if (commitCountInCurrentWorkLoop > 1) {
1709 warning = 'There were cascading updates';
1710 }
1711 commitCountInCurrentWorkLoop = 0;
1712 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)';
1713 // Pause any measurements until the next loop.
1714 pauseTimers();
1715 endMark(label, '(React Tree Reconciliation)', warning);
1716 }
1717}
1718
1719function startCommitTimer() {
1720 if (enableUserTimingAPI) {
1721 if (!supportsUserTiming) {
1722 return;
1723 }
1724 isCommitting = true;
1725 hasScheduledUpdateInCurrentCommit = false;
1726 labelsInCurrentCommit.clear();
1727 beginMark('(Committing Changes)');
1728 }
1729}
1730
1731function stopCommitTimer() {
1732 if (enableUserTimingAPI) {
1733 if (!supportsUserTiming) {
1734 return;
1735 }
1736
1737 var warning = null;
1738 if (hasScheduledUpdateInCurrentCommit) {
1739 warning = 'Lifecycle hook scheduled a cascading update';
1740 } else if (commitCountInCurrentWorkLoop > 0) {
1741 warning = 'Caused by a cascading update in earlier commit';
1742 }
1743 hasScheduledUpdateInCurrentCommit = false;
1744 commitCountInCurrentWorkLoop++;
1745 isCommitting = false;
1746 labelsInCurrentCommit.clear();
1747
1748 endMark('(Committing Changes)', '(Committing Changes)', warning);
1749 }
1750}
1751
1752function startCommitSnapshotEffectsTimer() {
1753 if (enableUserTimingAPI) {
1754 if (!supportsUserTiming) {
1755 return;
1756 }
1757 effectCountInCurrentCommit = 0;
1758 beginMark('(Committing Snapshot Effects)');
1759 }
1760}
1761
1762function stopCommitSnapshotEffectsTimer() {
1763 if (enableUserTimingAPI) {
1764 if (!supportsUserTiming) {
1765 return;
1766 }
1767 var count = effectCountInCurrentCommit;
1768 effectCountInCurrentCommit = 0;
1769 endMark('(Committing Snapshot Effects: ' + count + ' Total)', '(Committing Snapshot Effects)', null);
1770 }
1771}
1772
1773function startCommitHostEffectsTimer() {
1774 if (enableUserTimingAPI) {
1775 if (!supportsUserTiming) {
1776 return;
1777 }
1778 effectCountInCurrentCommit = 0;
1779 beginMark('(Committing Host Effects)');
1780 }
1781}
1782
1783function stopCommitHostEffectsTimer() {
1784 if (enableUserTimingAPI) {
1785 if (!supportsUserTiming) {
1786 return;
1787 }
1788 var count = effectCountInCurrentCommit;
1789 effectCountInCurrentCommit = 0;
1790 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
1791 }
1792}
1793
1794function startCommitLifeCyclesTimer() {
1795 if (enableUserTimingAPI) {
1796 if (!supportsUserTiming) {
1797 return;
1798 }
1799 effectCountInCurrentCommit = 0;
1800 beginMark('(Calling Lifecycle Methods)');
1801 }
1802}
1803
1804function stopCommitLifeCyclesTimer() {
1805 if (enableUserTimingAPI) {
1806 if (!supportsUserTiming) {
1807 return;
1808 }
1809 var count = effectCountInCurrentCommit;
1810 effectCountInCurrentCommit = 0;
1811 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
1812 }
1813}
1814
1815var valueStack = [];
1816
1817var fiberStack = void 0;
1818
1819{
1820 fiberStack = [];
1821}
1822
1823var index = -1;
1824
1825function createCursor(defaultValue) {
1826 return {
1827 current: defaultValue
1828 };
1829}
1830
1831function pop(cursor, fiber) {
1832 if (index < 0) {
1833 {
1834 warningWithoutStack$1(false, 'Unexpected pop.');
1835 }
1836 return;
1837 }
1838
1839 {
1840 if (fiber !== fiberStack[index]) {
1841 warningWithoutStack$1(false, 'Unexpected Fiber popped.');
1842 }
1843 }
1844
1845 cursor.current = valueStack[index];
1846
1847 valueStack[index] = null;
1848
1849 {
1850 fiberStack[index] = null;
1851 }
1852
1853 index--;
1854}
1855
1856function push(cursor, value, fiber) {
1857 index++;
1858
1859 valueStack[index] = cursor.current;
1860
1861 {
1862 fiberStack[index] = fiber;
1863 }
1864
1865 cursor.current = value;
1866}
1867
1868function checkThatStackIsEmpty() {
1869 {
1870 if (index !== -1) {
1871 warningWithoutStack$1(false, 'Expected an empty stack. Something was not reset properly.');
1872 }
1873 }
1874}
1875
1876function resetStackAfterFatalErrorInDev() {
1877 {
1878 index = -1;
1879 valueStack.length = 0;
1880 fiberStack.length = 0;
1881 }
1882}
1883
1884var warnedAboutMissingGetChildContext = void 0;
1885
1886{
1887 warnedAboutMissingGetChildContext = {};
1888}
1889
1890var emptyContextObject = {};
1891{
1892 Object.freeze(emptyContextObject);
1893}
1894
1895// A cursor to the current merged context object on the stack.
1896var contextStackCursor = createCursor(emptyContextObject);
1897// A cursor to a boolean indicating whether the context has changed.
1898var didPerformWorkStackCursor = createCursor(false);
1899// Keep track of the previous context object that was on the stack.
1900// We use this to get access to the parent context after we have already
1901// pushed the next context provider, and now need to merge their contexts.
1902var previousContext = emptyContextObject;
1903
1904function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
1905 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
1906 // If the fiber is a context provider itself, when we read its context
1907 // we may have already pushed its own child context on the stack. A context
1908 // provider should not "see" its own child context. Therefore we read the
1909 // previous (parent) context instead for a context provider.
1910 return previousContext;
1911 }
1912 return contextStackCursor.current;
1913}
1914
1915function cacheContext(workInProgress, unmaskedContext, maskedContext) {
1916 var instance = workInProgress.stateNode;
1917 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
1918 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
1919}
1920
1921function getMaskedContext(workInProgress, unmaskedContext) {
1922 var type = workInProgress.type;
1923 var contextTypes = type.contextTypes;
1924 if (!contextTypes) {
1925 return emptyContextObject;
1926 }
1927
1928 // Avoid recreating masked context unless unmasked context has changed.
1929 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
1930 // This may trigger infinite loops if componentWillReceiveProps calls setState.
1931 var instance = workInProgress.stateNode;
1932 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
1933 return instance.__reactInternalMemoizedMaskedChildContext;
1934 }
1935
1936 var context = {};
1937 for (var key in contextTypes) {
1938 context[key] = unmaskedContext[key];
1939 }
1940
1941 {
1942 var name = getComponentName(type) || 'Unknown';
1943 checkPropTypes_1(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
1944 }
1945
1946 // Cache unmasked context so we can avoid recreating masked context unless necessary.
1947 // Context is created before the class component is instantiated so check for instance.
1948 if (instance) {
1949 cacheContext(workInProgress, unmaskedContext, context);
1950 }
1951
1952 return context;
1953}
1954
1955function hasContextChanged() {
1956 return didPerformWorkStackCursor.current;
1957}
1958
1959function isContextProvider(type) {
1960 var childContextTypes = type.childContextTypes;
1961 return childContextTypes !== null && childContextTypes !== undefined;
1962}
1963
1964function popContext(fiber) {
1965 pop(didPerformWorkStackCursor, fiber);
1966 pop(contextStackCursor, fiber);
1967}
1968
1969function popTopLevelContextObject(fiber) {
1970 pop(didPerformWorkStackCursor, fiber);
1971 pop(contextStackCursor, fiber);
1972}
1973
1974function pushTopLevelContextObject(fiber, context, didChange) {
1975 !(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;
1976
1977 push(contextStackCursor, context, fiber);
1978 push(didPerformWorkStackCursor, didChange, fiber);
1979}
1980
1981function processChildContext(fiber, type, parentContext) {
1982 var instance = fiber.stateNode;
1983 var childContextTypes = type.childContextTypes;
1984
1985 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
1986 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
1987 if (typeof instance.getChildContext !== 'function') {
1988 {
1989 var componentName = getComponentName(type) || 'Unknown';
1990
1991 if (!warnedAboutMissingGetChildContext[componentName]) {
1992 warnedAboutMissingGetChildContext[componentName] = true;
1993 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);
1994 }
1995 }
1996 return parentContext;
1997 }
1998
1999 var childContext = void 0;
2000 {
2001 setCurrentPhase('getChildContext');
2002 }
2003 startPhaseTimer(fiber, 'getChildContext');
2004 childContext = instance.getChildContext();
2005 stopPhaseTimer();
2006 {
2007 setCurrentPhase(null);
2008 }
2009 for (var contextKey in childContext) {
2010 !(contextKey in childContextTypes) ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', getComponentName(type) || 'Unknown', contextKey) : void 0;
2011 }
2012 {
2013 var name = getComponentName(type) || 'Unknown';
2014 checkPropTypes_1(childContextTypes, childContext, 'child context', name,
2015 // In practice, there is one case in which we won't get a stack. It's when
2016 // somebody calls unstable_renderSubtreeIntoContainer() and we process
2017 // context from the parent component instance. The stack will be missing
2018 // because it's outside of the reconciliation, and so the pointer has not
2019 // been set. This is rare and doesn't matter. We'll also remove that API.
2020 getCurrentFiberStackInDev);
2021 }
2022
2023 return _assign({}, parentContext, childContext);
2024}
2025
2026function pushContextProvider(workInProgress) {
2027 var instance = workInProgress.stateNode;
2028 // We push the context as early as possible to ensure stack integrity.
2029 // If the instance does not exist yet, we will push null at first,
2030 // and replace it on the stack later when invalidating the context.
2031 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject;
2032
2033 // Remember the parent context so we can merge with it later.
2034 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
2035 previousContext = contextStackCursor.current;
2036 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
2037 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
2038
2039 return true;
2040}
2041
2042function invalidateContextProvider(workInProgress, type, didChange) {
2043 var instance = workInProgress.stateNode;
2044 !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;
2045
2046 if (didChange) {
2047 // Merge parent and own context.
2048 // Skip this if we're not updating due to sCU.
2049 // This avoids unnecessarily recomputing memoized values.
2050 var mergedContext = processChildContext(workInProgress, type, previousContext);
2051 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
2052
2053 // Replace the old (or empty) context with the new one.
2054 // It is important to unwind the context in the reverse order.
2055 pop(didPerformWorkStackCursor, workInProgress);
2056 pop(contextStackCursor, workInProgress);
2057 // Now push the new context and mark that it has changed.
2058 push(contextStackCursor, mergedContext, workInProgress);
2059 push(didPerformWorkStackCursor, didChange, workInProgress);
2060 } else {
2061 pop(didPerformWorkStackCursor, workInProgress);
2062 push(didPerformWorkStackCursor, didChange, workInProgress);
2063 }
2064}
2065
2066function findCurrentUnmaskedContext(fiber) {
2067 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
2068 // makes sense elsewhere
2069 !(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;
2070
2071 var node = fiber;
2072 do {
2073 switch (node.tag) {
2074 case HostRoot:
2075 return node.stateNode.context;
2076 case ClassComponent:
2077 {
2078 var Component = node.type;
2079 if (isContextProvider(Component)) {
2080 return node.stateNode.__reactInternalMemoizedMergedChildContext;
2081 }
2082 break;
2083 }
2084 }
2085 node = node.return;
2086 } while (node !== null);
2087 invariant(false, 'Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.');
2088}
2089
2090var onCommitFiberRoot = null;
2091var onCommitFiberUnmount = null;
2092var hasLoggedError = false;
2093
2094function catchErrors(fn) {
2095 return function (arg) {
2096 try {
2097 return fn(arg);
2098 } catch (err) {
2099 if (true && !hasLoggedError) {
2100 hasLoggedError = true;
2101 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
2102 }
2103 }
2104 };
2105}
2106
2107var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
2108
2109function injectInternals(internals) {
2110 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
2111 // No DevTools
2112 return false;
2113 }
2114 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
2115 if (hook.isDisabled) {
2116 // This isn't a real property on the hook, but it can be set to opt out
2117 // of DevTools integration and associated warnings and logs.
2118 // https://github.com/facebook/react/issues/3877
2119 return true;
2120 }
2121 if (!hook.supportsFiber) {
2122 {
2123 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');
2124 }
2125 // DevTools exists, even though it doesn't support Fiber.
2126 return true;
2127 }
2128 try {
2129 var rendererID = hook.inject(internals);
2130 // We have successfully injected, so now it is safe to set up hooks.
2131 onCommitFiberRoot = catchErrors(function (root) {
2132 return hook.onCommitFiberRoot(rendererID, root);
2133 });
2134 onCommitFiberUnmount = catchErrors(function (fiber) {
2135 return hook.onCommitFiberUnmount(rendererID, fiber);
2136 });
2137 } catch (err) {
2138 // Catch all errors because it is unsafe to throw during initialization.
2139 {
2140 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err);
2141 }
2142 }
2143 // DevTools exists
2144 return true;
2145}
2146
2147function onCommitRoot(root) {
2148 if (typeof onCommitFiberRoot === 'function') {
2149 onCommitFiberRoot(root);
2150 }
2151}
2152
2153function onCommitUnmount(fiber) {
2154 if (typeof onCommitFiberUnmount === 'function') {
2155 onCommitFiberUnmount(fiber);
2156 }
2157}
2158
2159// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
2160// Math.pow(2, 30) - 1
2161// 0b111111111111111111111111111111
2162var maxSigned31BitInt = 1073741823;
2163
2164var NoWork = 0;
2165var Never = 1;
2166var Sync = maxSigned31BitInt;
2167
2168var UNIT_SIZE = 10;
2169var MAGIC_NUMBER_OFFSET = maxSigned31BitInt - 1;
2170
2171// 1 unit of expiration time represents 10ms.
2172function msToExpirationTime(ms) {
2173 // Always add an offset so that we don't clash with the magic number for NoWork.
2174 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
2175}
2176
2177function expirationTimeToMs(expirationTime) {
2178 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
2179}
2180
2181function ceiling(num, precision) {
2182 return ((num / precision | 0) + 1) * precision;
2183}
2184
2185function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
2186 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
2187}
2188
2189var LOW_PRIORITY_EXPIRATION = 5000;
2190var LOW_PRIORITY_BATCH_SIZE = 250;
2191
2192function computeAsyncExpiration(currentTime) {
2193 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
2194}
2195
2196// We intentionally set a higher expiration time for interactive updates in
2197// dev than in production.
2198//
2199// If the main thread is being blocked so long that you hit the expiration,
2200// it's a problem that could be solved with better scheduling.
2201//
2202// People will be more likely to notice this and fix it with the long
2203// expiration time in development.
2204//
2205// In production we opt for better UX at the risk of masking scheduling
2206// problems, by expiring fast.
2207var HIGH_PRIORITY_EXPIRATION = 500;
2208var HIGH_PRIORITY_BATCH_SIZE = 100;
2209
2210function computeInteractiveExpiration(currentTime) {
2211 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
2212}
2213
2214var NoContext = 0;
2215var ConcurrentMode = 1;
2216var StrictMode = 2;
2217var ProfileMode = 4;
2218
2219var hasBadMapPolyfill = void 0;
2220
2221{
2222 hasBadMapPolyfill = false;
2223 try {
2224 var nonExtensibleObject = Object.preventExtensions({});
2225 var testMap = new Map([[nonExtensibleObject, null]]);
2226 var testSet = new Set([nonExtensibleObject]);
2227 // This is necessary for Rollup to not consider these unused.
2228 // https://github.com/rollup/rollup/issues/1771
2229 // TODO: we can remove these if Rollup fixes the bug.
2230 testMap.set(0, 0);
2231 testSet.add(0);
2232 } catch (e) {
2233 // TODO: Consider warning about bad polyfills
2234 hasBadMapPolyfill = true;
2235 }
2236}
2237
2238// A Fiber is work on a Component that needs to be done or was done. There can
2239// be more than one per component.
2240
2241
2242var debugCounter = void 0;
2243
2244{
2245 debugCounter = 1;
2246}
2247
2248function FiberNode(tag, pendingProps, key, mode) {
2249 // Instance
2250 this.tag = tag;
2251 this.key = key;
2252 this.elementType = null;
2253 this.type = null;
2254 this.stateNode = null;
2255
2256 // Fiber
2257 this.return = null;
2258 this.child = null;
2259 this.sibling = null;
2260 this.index = 0;
2261
2262 this.ref = null;
2263
2264 this.pendingProps = pendingProps;
2265 this.memoizedProps = null;
2266 this.updateQueue = null;
2267 this.memoizedState = null;
2268 this.contextDependencies = null;
2269
2270 this.mode = mode;
2271
2272 // Effects
2273 this.effectTag = NoEffect;
2274 this.nextEffect = null;
2275
2276 this.firstEffect = null;
2277 this.lastEffect = null;
2278
2279 this.expirationTime = NoWork;
2280 this.childExpirationTime = NoWork;
2281
2282 this.alternate = null;
2283
2284 if (enableProfilerTimer) {
2285 // Note: The following is done to avoid a v8 performance cliff.
2286 //
2287 // Initializing the fields below to smis and later updating them with
2288 // double values will cause Fibers to end up having separate shapes.
2289 // This behavior/bug has something to do with Object.preventExtension().
2290 // Fortunately this only impacts DEV builds.
2291 // Unfortunately it makes React unusably slow for some applications.
2292 // To work around this, initialize the fields below with doubles.
2293 //
2294 // Learn more about this here:
2295 // https://github.com/facebook/react/issues/14365
2296 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
2297 this.actualDuration = Number.NaN;
2298 this.actualStartTime = Number.NaN;
2299 this.selfBaseDuration = Number.NaN;
2300 this.treeBaseDuration = Number.NaN;
2301
2302 // It's okay to replace the initial doubles with smis after initialization.
2303 // This won't trigger the performance cliff mentioned above,
2304 // and it simplifies other profiler code (including DevTools).
2305 this.actualDuration = 0;
2306 this.actualStartTime = -1;
2307 this.selfBaseDuration = 0;
2308 this.treeBaseDuration = 0;
2309 }
2310
2311 {
2312 this._debugID = debugCounter++;
2313 this._debugSource = null;
2314 this._debugOwner = null;
2315 this._debugIsCurrentlyTiming = false;
2316 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
2317 Object.preventExtensions(this);
2318 }
2319 }
2320}
2321
2322// This is a constructor function, rather than a POJO constructor, still
2323// please ensure we do the following:
2324// 1) Nobody should add any instance methods on this. Instance methods can be
2325// more difficult to predict when they get optimized and they are almost
2326// never inlined properly in static compilers.
2327// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
2328// always know when it is a fiber.
2329// 3) We might want to experiment with using numeric keys since they are easier
2330// to optimize in a non-JIT environment.
2331// 4) We can easily go from a constructor to a createFiber object literal if that
2332// is faster.
2333// 5) It should be easy to port this to a C struct and keep a C implementation
2334// compatible.
2335var createFiber = function (tag, pendingProps, key, mode) {
2336 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
2337 return new FiberNode(tag, pendingProps, key, mode);
2338};
2339
2340function shouldConstruct(Component) {
2341 var prototype = Component.prototype;
2342 return !!(prototype && prototype.isReactComponent);
2343}
2344
2345function isSimpleFunctionComponent(type) {
2346 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
2347}
2348
2349function resolveLazyComponentTag(Component) {
2350 if (typeof Component === 'function') {
2351 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
2352 } else if (Component !== undefined && Component !== null) {
2353 var $$typeof = Component.$$typeof;
2354 if ($$typeof === REACT_FORWARD_REF_TYPE) {
2355 return ForwardRef;
2356 }
2357 if ($$typeof === REACT_MEMO_TYPE) {
2358 return MemoComponent;
2359 }
2360 }
2361 return IndeterminateComponent;
2362}
2363
2364// This is used to create an alternate fiber to do work on.
2365function createWorkInProgress(current, pendingProps, expirationTime) {
2366 var workInProgress = current.alternate;
2367 if (workInProgress === null) {
2368 // We use a double buffering pooling technique because we know that we'll
2369 // only ever need at most two versions of a tree. We pool the "other" unused
2370 // node that we're free to reuse. This is lazily created to avoid allocating
2371 // extra objects for things that are never updated. It also allow us to
2372 // reclaim the extra memory if needed.
2373 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
2374 workInProgress.elementType = current.elementType;
2375 workInProgress.type = current.type;
2376 workInProgress.stateNode = current.stateNode;
2377
2378 {
2379 // DEV-only fields
2380 workInProgress._debugID = current._debugID;
2381 workInProgress._debugSource = current._debugSource;
2382 workInProgress._debugOwner = current._debugOwner;
2383 }
2384
2385 workInProgress.alternate = current;
2386 current.alternate = workInProgress;
2387 } else {
2388 workInProgress.pendingProps = pendingProps;
2389
2390 // We already have an alternate.
2391 // Reset the effect tag.
2392 workInProgress.effectTag = NoEffect;
2393
2394 // The effect list is no longer valid.
2395 workInProgress.nextEffect = null;
2396 workInProgress.firstEffect = null;
2397 workInProgress.lastEffect = null;
2398
2399 if (enableProfilerTimer) {
2400 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
2401 // This prevents time from endlessly accumulating in new commits.
2402 // This has the downside of resetting values for different priority renders,
2403 // But works for yielding (the common case) and should support resuming.
2404 workInProgress.actualDuration = 0;
2405 workInProgress.actualStartTime = -1;
2406 }
2407 }
2408
2409 workInProgress.childExpirationTime = current.childExpirationTime;
2410 workInProgress.expirationTime = current.expirationTime;
2411
2412 workInProgress.child = current.child;
2413 workInProgress.memoizedProps = current.memoizedProps;
2414 workInProgress.memoizedState = current.memoizedState;
2415 workInProgress.updateQueue = current.updateQueue;
2416 workInProgress.contextDependencies = current.contextDependencies;
2417
2418 // These will be overridden during the parent's reconciliation
2419 workInProgress.sibling = current.sibling;
2420 workInProgress.index = current.index;
2421 workInProgress.ref = current.ref;
2422
2423 if (enableProfilerTimer) {
2424 workInProgress.selfBaseDuration = current.selfBaseDuration;
2425 workInProgress.treeBaseDuration = current.treeBaseDuration;
2426 }
2427
2428 return workInProgress;
2429}
2430
2431function createHostRootFiber(isConcurrent) {
2432 var mode = isConcurrent ? ConcurrentMode | StrictMode : NoContext;
2433
2434 if (enableProfilerTimer && isDevToolsPresent) {
2435 // Always collect profile timings when DevTools are present.
2436 // This enables DevTools to start capturing timing at any point–
2437 // Without some nodes in the tree having empty base times.
2438 mode |= ProfileMode;
2439 }
2440
2441 return createFiber(HostRoot, null, null, mode);
2442}
2443
2444function createFiberFromTypeAndProps(type, // React$ElementType
2445key, pendingProps, owner, mode, expirationTime) {
2446 var fiber = void 0;
2447
2448 var fiberTag = IndeterminateComponent;
2449 // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
2450 var resolvedType = type;
2451 if (typeof type === 'function') {
2452 if (shouldConstruct(type)) {
2453 fiberTag = ClassComponent;
2454 }
2455 } else if (typeof type === 'string') {
2456 fiberTag = HostComponent;
2457 } else {
2458 getTag: switch (type) {
2459 case REACT_FRAGMENT_TYPE:
2460 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
2461 case REACT_CONCURRENT_MODE_TYPE:
2462 return createFiberFromMode(pendingProps, mode | ConcurrentMode | StrictMode, expirationTime, key);
2463 case REACT_STRICT_MODE_TYPE:
2464 return createFiberFromMode(pendingProps, mode | StrictMode, expirationTime, key);
2465 case REACT_PROFILER_TYPE:
2466 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
2467 case REACT_SUSPENSE_TYPE:
2468 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
2469 default:
2470 {
2471 if (typeof type === 'object' && type !== null) {
2472 switch (type.$$typeof) {
2473 case REACT_PROVIDER_TYPE:
2474 fiberTag = ContextProvider;
2475 break getTag;
2476 case REACT_CONTEXT_TYPE:
2477 // This is a consumer
2478 fiberTag = ContextConsumer;
2479 break getTag;
2480 case REACT_FORWARD_REF_TYPE:
2481 fiberTag = ForwardRef;
2482 break getTag;
2483 case REACT_MEMO_TYPE:
2484 fiberTag = MemoComponent;
2485 break getTag;
2486 case REACT_LAZY_TYPE:
2487 fiberTag = LazyComponent;
2488 resolvedType = null;
2489 break getTag;
2490 }
2491 }
2492 var info = '';
2493 {
2494 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
2495 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.';
2496 }
2497 var ownerName = owner ? getComponentName(owner.type) : null;
2498 if (ownerName) {
2499 info += '\n\nCheck the render method of `' + ownerName + '`.';
2500 }
2501 }
2502 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);
2503 }
2504 }
2505 }
2506
2507 fiber = createFiber(fiberTag, pendingProps, key, mode);
2508 fiber.elementType = type;
2509 fiber.type = resolvedType;
2510 fiber.expirationTime = expirationTime;
2511
2512 return fiber;
2513}
2514
2515function createFiberFromElement(element, mode, expirationTime) {
2516 var owner = null;
2517 {
2518 owner = element._owner;
2519 }
2520 var type = element.type;
2521 var key = element.key;
2522 var pendingProps = element.props;
2523 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
2524 {
2525 fiber._debugSource = element._source;
2526 fiber._debugOwner = element._owner;
2527 }
2528 return fiber;
2529}
2530
2531function createFiberFromFragment(elements, mode, expirationTime, key) {
2532 var fiber = createFiber(Fragment, elements, key, mode);
2533 fiber.expirationTime = expirationTime;
2534 return fiber;
2535}
2536
2537function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
2538 {
2539 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
2540 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props');
2541 }
2542 }
2543
2544 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
2545 // TODO: The Profiler fiber shouldn't have a type. It has a tag.
2546 fiber.elementType = REACT_PROFILER_TYPE;
2547 fiber.type = REACT_PROFILER_TYPE;
2548 fiber.expirationTime = expirationTime;
2549
2550 return fiber;
2551}
2552
2553function createFiberFromMode(pendingProps, mode, expirationTime, key) {
2554 var fiber = createFiber(Mode, pendingProps, key, mode);
2555
2556 // TODO: The Mode fiber shouldn't have a type. It has a tag.
2557 var type = (mode & ConcurrentMode) === NoContext ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE;
2558 fiber.elementType = type;
2559 fiber.type = type;
2560
2561 fiber.expirationTime = expirationTime;
2562 return fiber;
2563}
2564
2565function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
2566 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
2567
2568 // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
2569 var type = REACT_SUSPENSE_TYPE;
2570 fiber.elementType = type;
2571 fiber.type = type;
2572
2573 fiber.expirationTime = expirationTime;
2574 return fiber;
2575}
2576
2577function createFiberFromText(content, mode, expirationTime) {
2578 var fiber = createFiber(HostText, content, null, mode);
2579 fiber.expirationTime = expirationTime;
2580 return fiber;
2581}
2582
2583function createFiberFromHostInstanceForDeletion() {
2584 var fiber = createFiber(HostComponent, null, null, NoContext);
2585 // TODO: These should not need a type.
2586 fiber.elementType = 'DELETED';
2587 fiber.type = 'DELETED';
2588 return fiber;
2589}
2590
2591function createFiberFromPortal(portal, mode, expirationTime) {
2592 var pendingProps = portal.children !== null ? portal.children : [];
2593 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
2594 fiber.expirationTime = expirationTime;
2595 fiber.stateNode = {
2596 containerInfo: portal.containerInfo,
2597 pendingChildren: null, // Used by persistent updates
2598 implementation: portal.implementation
2599 };
2600 return fiber;
2601}
2602
2603// Used for stashing WIP properties to replay failed work in DEV.
2604function assignFiberPropertiesInDEV(target, source) {
2605 if (target === null) {
2606 // This Fiber's initial properties will always be overwritten.
2607 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
2608 target = createFiber(IndeterminateComponent, null, null, NoContext);
2609 }
2610
2611 // This is intentionally written as a list of all properties.
2612 // We tried to use Object.assign() instead but this is called in
2613 // the hottest path, and Object.assign() was too slow:
2614 // https://github.com/facebook/react/issues/12502
2615 // This code is DEV-only so size is not a concern.
2616
2617 target.tag = source.tag;
2618 target.key = source.key;
2619 target.elementType = source.elementType;
2620 target.type = source.type;
2621 target.stateNode = source.stateNode;
2622 target.return = source.return;
2623 target.child = source.child;
2624 target.sibling = source.sibling;
2625 target.index = source.index;
2626 target.ref = source.ref;
2627 target.pendingProps = source.pendingProps;
2628 target.memoizedProps = source.memoizedProps;
2629 target.updateQueue = source.updateQueue;
2630 target.memoizedState = source.memoizedState;
2631 target.contextDependencies = source.contextDependencies;
2632 target.mode = source.mode;
2633 target.effectTag = source.effectTag;
2634 target.nextEffect = source.nextEffect;
2635 target.firstEffect = source.firstEffect;
2636 target.lastEffect = source.lastEffect;
2637 target.expirationTime = source.expirationTime;
2638 target.childExpirationTime = source.childExpirationTime;
2639 target.alternate = source.alternate;
2640 if (enableProfilerTimer) {
2641 target.actualDuration = source.actualDuration;
2642 target.actualStartTime = source.actualStartTime;
2643 target.selfBaseDuration = source.selfBaseDuration;
2644 target.treeBaseDuration = source.treeBaseDuration;
2645 }
2646 target._debugID = source._debugID;
2647 target._debugSource = source._debugSource;
2648 target._debugOwner = source._debugOwner;
2649 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
2650 return target;
2651}
2652
2653var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2654
2655var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing;
2656var __interactionsRef = _ReactInternals$Sched$1.__interactionsRef;
2657var __subscriberRef = _ReactInternals$Sched$1.__subscriberRef;
2658var unstable_clear = _ReactInternals$Sched$1.unstable_clear;
2659var unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent;
2660var unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID;
2661var unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe;
2662var unstable_trace = _ReactInternals$Sched$1.unstable_trace;
2663var unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe;
2664var unstable_wrap = _ReactInternals$Sched$1.unstable_wrap;
2665
2666// TODO: This should be lifted into the renderer.
2667
2668
2669// The following attributes are only used by interaction tracing builds.
2670// They enable interactions to be associated with their async work,
2671// And expose interaction metadata to the React DevTools Profiler plugin.
2672// Note that these attributes are only defined when the enableSchedulerTracing flag is enabled.
2673
2674
2675// Exported FiberRoot type includes all properties,
2676// To avoid requiring potentially error-prone :any casts throughout the project.
2677// Profiling properties are only safe to access in profiling builds (when enableSchedulerTracing is true).
2678// The types are defined separately within this file to ensure they stay in sync.
2679// (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.)
2680
2681
2682function createFiberRoot(containerInfo, isConcurrent, hydrate) {
2683 // Cyclic construction. This cheats the type system right now because
2684 // stateNode is any.
2685 var uninitializedFiber = createHostRootFiber(isConcurrent);
2686
2687 var root = void 0;
2688 if (enableSchedulerTracing) {
2689 root = {
2690 current: uninitializedFiber,
2691 containerInfo: containerInfo,
2692 pendingChildren: null,
2693
2694 earliestPendingTime: NoWork,
2695 latestPendingTime: NoWork,
2696 earliestSuspendedTime: NoWork,
2697 latestSuspendedTime: NoWork,
2698 latestPingedTime: NoWork,
2699
2700 pingCache: null,
2701
2702 didError: false,
2703
2704 pendingCommitExpirationTime: NoWork,
2705 finishedWork: null,
2706 timeoutHandle: noTimeout,
2707 context: null,
2708 pendingContext: null,
2709 hydrate: hydrate,
2710 nextExpirationTimeToWorkOn: NoWork,
2711 expirationTime: NoWork,
2712 firstBatch: null,
2713 nextScheduledRoot: null,
2714
2715 interactionThreadID: unstable_getThreadID(),
2716 memoizedInteractions: new Set(),
2717 pendingInteractionMap: new Map()
2718 };
2719 } else {
2720 root = {
2721 current: uninitializedFiber,
2722 containerInfo: containerInfo,
2723 pendingChildren: null,
2724
2725 pingCache: null,
2726
2727 earliestPendingTime: NoWork,
2728 latestPendingTime: NoWork,
2729 earliestSuspendedTime: NoWork,
2730 latestSuspendedTime: NoWork,
2731 latestPingedTime: NoWork,
2732
2733 didError: false,
2734
2735 pendingCommitExpirationTime: NoWork,
2736 finishedWork: null,
2737 timeoutHandle: noTimeout,
2738 context: null,
2739 pendingContext: null,
2740 hydrate: hydrate,
2741 nextExpirationTimeToWorkOn: NoWork,
2742 expirationTime: NoWork,
2743 firstBatch: null,
2744 nextScheduledRoot: null
2745 };
2746 }
2747
2748 uninitializedFiber.stateNode = root;
2749
2750 // The reason for the way the Flow types are structured in this file,
2751 // Is to avoid needing :any casts everywhere interaction tracing fields are used.
2752 // Unfortunately that requires an :any cast for non-interaction tracing capable builds.
2753 // $FlowFixMe Remove this :any cast and replace it with something better.
2754 return root;
2755}
2756
2757var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
2758 var funcArgs = Array.prototype.slice.call(arguments, 3);
2759 try {
2760 func.apply(context, funcArgs);
2761 } catch (error) {
2762 this.onError(error);
2763 }
2764};
2765
2766{
2767 // In DEV mode, we swap out invokeGuardedCallback for a special version
2768 // that plays more nicely with the browser's DevTools. The idea is to preserve
2769 // "Pause on exceptions" behavior. Because React wraps all user-provided
2770 // functions in invokeGuardedCallback, and the production version of
2771 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
2772 // like caught exceptions, and the DevTools won't pause unless the developer
2773 // takes the extra step of enabling pause on caught exceptions. This is
2774 // untintuitive, though, because even though React has caught the error, from
2775 // the developer's perspective, the error is uncaught.
2776 //
2777 // To preserve the expected "Pause on exceptions" behavior, we don't use a
2778 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
2779 // DOM node, and call the user-provided callback from inside an event handler
2780 // for that fake event. If the callback throws, the error is "captured" using
2781 // a global event handler. But because the error happens in a different
2782 // event loop context, it does not interrupt the normal program flow.
2783 // Effectively, this gives us try-catch behavior without actually using
2784 // try-catch. Neat!
2785
2786 // Check that the browser supports the APIs we need to implement our special
2787 // DEV version of invokeGuardedCallback
2788 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
2789 var fakeNode = document.createElement('react');
2790
2791 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
2792 // If document doesn't exist we know for sure we will crash in this method
2793 // when we call document.createEvent(). However this can cause confusing
2794 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
2795 // So we preemptively throw with a better message instead.
2796 !(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;
2797 var evt = document.createEvent('Event');
2798
2799 // Keeps track of whether the user-provided callback threw an error. We
2800 // set this to true at the beginning, then set it to false right after
2801 // calling the function. If the function errors, `didError` will never be
2802 // set to false. This strategy works even if the browser is flaky and
2803 // fails to call our global error handler, because it doesn't rely on
2804 // the error event at all.
2805 var didError = true;
2806
2807 // Keeps track of the value of window.event so that we can reset it
2808 // during the callback to let user code access window.event in the
2809 // browsers that support it.
2810 var windowEvent = window.event;
2811
2812 // Keeps track of the descriptor of window.event to restore it after event
2813 // dispatching: https://github.com/facebook/react/issues/13688
2814 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
2815
2816 // Create an event handler for our fake event. We will synchronously
2817 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
2818 // call the user-provided callback.
2819 var funcArgs = Array.prototype.slice.call(arguments, 3);
2820 function callCallback() {
2821 // We immediately remove the callback from event listeners so that
2822 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
2823 // nested call would trigger the fake event handlers of any call higher
2824 // in the stack.
2825 fakeNode.removeEventListener(evtType, callCallback, false);
2826
2827 // We check for window.hasOwnProperty('event') to prevent the
2828 // window.event assignment in both IE <= 10 as they throw an error
2829 // "Member not found" in strict mode, and in Firefox which does not
2830 // support window.event.
2831 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
2832 window.event = windowEvent;
2833 }
2834
2835 func.apply(context, funcArgs);
2836 didError = false;
2837 }
2838
2839 // Create a global error event handler. We use this to capture the value
2840 // that was thrown. It's possible that this error handler will fire more
2841 // than once; for example, if non-React code also calls `dispatchEvent`
2842 // and a handler for that event throws. We should be resilient to most of
2843 // those cases. Even if our error event handler fires more than once, the
2844 // last error event is always used. If the callback actually does error,
2845 // we know that the last error event is the correct one, because it's not
2846 // possible for anything else to have happened in between our callback
2847 // erroring and the code that follows the `dispatchEvent` call below. If
2848 // the callback doesn't error, but the error event was fired, we know to
2849 // ignore it because `didError` will be false, as described above.
2850 var error = void 0;
2851 // Use this to track whether the error event is ever called.
2852 var didSetError = false;
2853 var isCrossOriginError = false;
2854
2855 function handleWindowError(event) {
2856 error = event.error;
2857 didSetError = true;
2858 if (error === null && event.colno === 0 && event.lineno === 0) {
2859 isCrossOriginError = true;
2860 }
2861 if (event.defaultPrevented) {
2862 // Some other error handler has prevented default.
2863 // Browsers silence the error report if this happens.
2864 // We'll remember this to later decide whether to log it or not.
2865 if (error != null && typeof error === 'object') {
2866 try {
2867 error._suppressLogging = true;
2868 } catch (inner) {
2869 // Ignore.
2870 }
2871 }
2872 }
2873 }
2874
2875 // Create a fake event type.
2876 var evtType = 'react-' + (name ? name : 'invokeguardedcallback');
2877
2878 // Attach our event handlers
2879 window.addEventListener('error', handleWindowError);
2880 fakeNode.addEventListener(evtType, callCallback, false);
2881
2882 // Synchronously dispatch our fake event. If the user-provided function
2883 // errors, it will trigger our global error handler.
2884 evt.initEvent(evtType, false, false);
2885 fakeNode.dispatchEvent(evt);
2886
2887 if (windowEventDescriptor) {
2888 Object.defineProperty(window, 'event', windowEventDescriptor);
2889 }
2890
2891 if (didError) {
2892 if (!didSetError) {
2893 // The callback errored, but the error event never fired.
2894 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.');
2895 } else if (isCrossOriginError) {
2896 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.');
2897 }
2898 this.onError(error);
2899 }
2900
2901 // Remove our event listeners
2902 window.removeEventListener('error', handleWindowError);
2903 };
2904
2905 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
2906 }
2907}
2908
2909var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
2910
2911// Used by Fiber to simulate a try-catch.
2912var hasError = false;
2913var caughtError = null;
2914
2915var reporter = {
2916 onError: function (error) {
2917 hasError = true;
2918 caughtError = error;
2919 }
2920};
2921
2922/**
2923 * Call a function while guarding against errors that happens within it.
2924 * Returns an error if it throws, otherwise null.
2925 *
2926 * In production, this is implemented using a try-catch. The reason we don't
2927 * use a try-catch directly is so that we can swap out a different
2928 * implementation in DEV mode.
2929 *
2930 * @param {String} name of the guard to use for logging or debugging
2931 * @param {Function} func The function to invoke
2932 * @param {*} context The context to use when calling the function
2933 * @param {...*} args Arguments for function
2934 */
2935function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
2936 hasError = false;
2937 caughtError = null;
2938 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
2939}
2940
2941/**
2942 * Same as invokeGuardedCallback, but instead of returning an error, it stores
2943 * it in a global so it can be rethrown by `rethrowCaughtError` later.
2944 * TODO: See if caughtError and rethrowError can be unified.
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 */
2951
2952
2953/**
2954 * During execution of guarded functions we will capture the first error which
2955 * we will rethrow to be handled by the top level error handler.
2956 */
2957
2958
2959function hasCaughtError() {
2960 return hasError;
2961}
2962
2963function clearCaughtError() {
2964 if (hasError) {
2965 var error = caughtError;
2966 hasError = false;
2967 caughtError = null;
2968 return error;
2969 } else {
2970 invariant(false, 'clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.');
2971 }
2972}
2973
2974/**
2975 * Forked from fbjs/warning:
2976 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
2977 *
2978 * Only change is we use console.warn instead of console.error,
2979 * and do nothing when 'console' is not supported.
2980 * This really simplifies the code.
2981 * ---
2982 * Similar to invariant but only logs a warning if the condition is not met.
2983 * This can be used to log issues in development environments in critical
2984 * paths. Removing the logging code for production environments will keep the
2985 * same logic and follow the same code paths.
2986 */
2987
2988var lowPriorityWarning = function () {};
2989
2990{
2991 var printWarning$1 = function (format) {
2992 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
2993 args[_key - 1] = arguments[_key];
2994 }
2995
2996 var argIndex = 0;
2997 var message = 'Warning: ' + format.replace(/%s/g, function () {
2998 return args[argIndex++];
2999 });
3000 if (typeof console !== 'undefined') {
3001 console.warn(message);
3002 }
3003 try {
3004 // --- Welcome to debugging React ---
3005 // This error was thrown as a convenience so that you can use this stack
3006 // to find the callsite that caused this warning to fire.
3007 throw new Error(message);
3008 } catch (x) {}
3009 };
3010
3011 lowPriorityWarning = function (condition, format) {
3012 if (format === undefined) {
3013 throw new Error('`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument');
3014 }
3015 if (!condition) {
3016 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
3017 args[_key2 - 2] = arguments[_key2];
3018 }
3019
3020 printWarning$1.apply(undefined, [format].concat(args));
3021 }
3022 };
3023}
3024
3025var lowPriorityWarning$1 = lowPriorityWarning;
3026
3027var ReactStrictModeWarnings = {
3028 discardPendingWarnings: function () {},
3029 flushPendingDeprecationWarnings: function () {},
3030 flushPendingUnsafeLifecycleWarnings: function () {},
3031 recordDeprecationWarnings: function (fiber, instance) {},
3032 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
3033 recordLegacyContextWarning: function (fiber, instance) {},
3034 flushLegacyContextWarning: function () {}
3035};
3036
3037{
3038 var LIFECYCLE_SUGGESTIONS = {
3039 UNSAFE_componentWillMount: 'componentDidMount',
3040 UNSAFE_componentWillReceiveProps: 'static getDerivedStateFromProps',
3041 UNSAFE_componentWillUpdate: 'componentDidUpdate'
3042 };
3043
3044 var pendingComponentWillMountWarnings = [];
3045 var pendingComponentWillReceivePropsWarnings = [];
3046 var pendingComponentWillUpdateWarnings = [];
3047 var pendingUnsafeLifecycleWarnings = new Map();
3048 var pendingLegacyContextWarning = new Map();
3049
3050 // Tracks components we have already warned about.
3051 var didWarnAboutDeprecatedLifecycles = new Set();
3052 var didWarnAboutUnsafeLifecycles = new Set();
3053 var didWarnAboutLegacyContext = new Set();
3054
3055 var setToSortedString = function (set) {
3056 var array = [];
3057 set.forEach(function (value) {
3058 array.push(value);
3059 });
3060 return array.sort().join(', ');
3061 };
3062
3063 ReactStrictModeWarnings.discardPendingWarnings = function () {
3064 pendingComponentWillMountWarnings = [];
3065 pendingComponentWillReceivePropsWarnings = [];
3066 pendingComponentWillUpdateWarnings = [];
3067 pendingUnsafeLifecycleWarnings = new Map();
3068 pendingLegacyContextWarning = new Map();
3069 };
3070
3071 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
3072 pendingUnsafeLifecycleWarnings.forEach(function (lifecycleWarningsMap, strictRoot) {
3073 var lifecyclesWarningMessages = [];
3074
3075 Object.keys(lifecycleWarningsMap).forEach(function (lifecycle) {
3076 var lifecycleWarnings = lifecycleWarningsMap[lifecycle];
3077 if (lifecycleWarnings.length > 0) {
3078 var componentNames = new Set();
3079 lifecycleWarnings.forEach(function (fiber) {
3080 componentNames.add(getComponentName(fiber.type) || 'Component');
3081 didWarnAboutUnsafeLifecycles.add(fiber.type);
3082 });
3083
3084 var formatted = lifecycle.replace('UNSAFE_', '');
3085 var suggestion = LIFECYCLE_SUGGESTIONS[lifecycle];
3086 var sortedComponentNames = setToSortedString(componentNames);
3087
3088 lifecyclesWarningMessages.push(formatted + ': Please update the following components to use ' + (suggestion + ' instead: ' + sortedComponentNames));
3089 }
3090 });
3091
3092 if (lifecyclesWarningMessages.length > 0) {
3093 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
3094
3095 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'));
3096 }
3097 });
3098
3099 pendingUnsafeLifecycleWarnings = new Map();
3100 };
3101
3102 var findStrictRoot = function (fiber) {
3103 var maybeStrictRoot = null;
3104
3105 var node = fiber;
3106 while (node !== null) {
3107 if (node.mode & StrictMode) {
3108 maybeStrictRoot = node;
3109 }
3110 node = node.return;
3111 }
3112
3113 return maybeStrictRoot;
3114 };
3115
3116 ReactStrictModeWarnings.flushPendingDeprecationWarnings = function () {
3117 if (pendingComponentWillMountWarnings.length > 0) {
3118 var uniqueNames = new Set();
3119 pendingComponentWillMountWarnings.forEach(function (fiber) {
3120 uniqueNames.add(getComponentName(fiber.type) || 'Component');
3121 didWarnAboutDeprecatedLifecycles.add(fiber.type);
3122 });
3123
3124 var sortedNames = setToSortedString(uniqueNames);
3125
3126 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);
3127
3128 pendingComponentWillMountWarnings = [];
3129 }
3130
3131 if (pendingComponentWillReceivePropsWarnings.length > 0) {
3132 var _uniqueNames = new Set();
3133 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
3134 _uniqueNames.add(getComponentName(fiber.type) || 'Component');
3135 didWarnAboutDeprecatedLifecycles.add(fiber.type);
3136 });
3137
3138 var _sortedNames = setToSortedString(_uniqueNames);
3139
3140 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);
3141
3142 pendingComponentWillReceivePropsWarnings = [];
3143 }
3144
3145 if (pendingComponentWillUpdateWarnings.length > 0) {
3146 var _uniqueNames2 = new Set();
3147 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
3148 _uniqueNames2.add(getComponentName(fiber.type) || 'Component');
3149 didWarnAboutDeprecatedLifecycles.add(fiber.type);
3150 });
3151
3152 var _sortedNames2 = setToSortedString(_uniqueNames2);
3153
3154 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);
3155
3156 pendingComponentWillUpdateWarnings = [];
3157 }
3158 };
3159
3160 ReactStrictModeWarnings.recordDeprecationWarnings = function (fiber, instance) {
3161 // Dedup strategy: Warn once per component.
3162 if (didWarnAboutDeprecatedLifecycles.has(fiber.type)) {
3163 return;
3164 }
3165
3166 // Don't warn about react-lifecycles-compat polyfilled components.
3167 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
3168 pendingComponentWillMountWarnings.push(fiber);
3169 }
3170 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
3171 pendingComponentWillReceivePropsWarnings.push(fiber);
3172 }
3173 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
3174 pendingComponentWillUpdateWarnings.push(fiber);
3175 }
3176 };
3177
3178 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
3179 var strictRoot = findStrictRoot(fiber);
3180 if (strictRoot === null) {
3181 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.');
3182 return;
3183 }
3184
3185 // Dedup strategy: Warn once per component.
3186 // This is difficult to track any other way since component names
3187 // are often vague and are likely to collide between 3rd party libraries.
3188 // An expand property is probably okay to use here since it's DEV-only,
3189 // and will only be set in the event of serious warnings.
3190 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
3191 return;
3192 }
3193
3194 var warningsForRoot = void 0;
3195 if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) {
3196 warningsForRoot = {
3197 UNSAFE_componentWillMount: [],
3198 UNSAFE_componentWillReceiveProps: [],
3199 UNSAFE_componentWillUpdate: []
3200 };
3201
3202 pendingUnsafeLifecycleWarnings.set(strictRoot, warningsForRoot);
3203 } else {
3204 warningsForRoot = pendingUnsafeLifecycleWarnings.get(strictRoot);
3205 }
3206
3207 var unsafeLifecycles = [];
3208 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillMount === 'function') {
3209 unsafeLifecycles.push('UNSAFE_componentWillMount');
3210 }
3211 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
3212 unsafeLifecycles.push('UNSAFE_componentWillReceiveProps');
3213 }
3214 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillUpdate === 'function') {
3215 unsafeLifecycles.push('UNSAFE_componentWillUpdate');
3216 }
3217
3218 if (unsafeLifecycles.length > 0) {
3219 unsafeLifecycles.forEach(function (lifecycle) {
3220 warningsForRoot[lifecycle].push(fiber);
3221 });
3222 }
3223 };
3224
3225 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
3226 var strictRoot = findStrictRoot(fiber);
3227 if (strictRoot === null) {
3228 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.');
3229 return;
3230 }
3231
3232 // Dedup strategy: Warn once per component.
3233 if (didWarnAboutLegacyContext.has(fiber.type)) {
3234 return;
3235 }
3236
3237 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
3238
3239 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
3240 if (warningsForRoot === undefined) {
3241 warningsForRoot = [];
3242 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
3243 }
3244 warningsForRoot.push(fiber);
3245 }
3246 };
3247
3248 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
3249 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
3250 var uniqueNames = new Set();
3251 fiberArray.forEach(function (fiber) {
3252 uniqueNames.add(getComponentName(fiber.type) || 'Component');
3253 didWarnAboutLegacyContext.add(fiber.type);
3254 });
3255
3256 var sortedNames = setToSortedString(uniqueNames);
3257 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
3258
3259 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);
3260 });
3261 };
3262}
3263
3264// This lets us hook into Fiber to debug what it's doing.
3265// See https://github.com/facebook/react/pull/8033.
3266// This is not part of the public API, not even for React DevTools.
3267// You may only inject a debugTool if you work on React Fiber itself.
3268var ReactFiberInstrumentation = {
3269 debugTool: null
3270};
3271
3272var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
3273
3274// TODO: Offscreen updates should never suspend. However, a promise that
3275// suspended inside an offscreen subtree should be able to ping at the priority
3276// of the outer render.
3277
3278function markPendingPriorityLevel(root, expirationTime) {
3279 // If there's a gap between completing a failed root and retrying it,
3280 // additional updates may be scheduled. Clear `didError`, in case the update
3281 // is sufficient to fix the error.
3282 root.didError = false;
3283
3284 // Update the latest and earliest pending times
3285 var earliestPendingTime = root.earliestPendingTime;
3286 if (earliestPendingTime === NoWork) {
3287 // No other pending updates.
3288 root.earliestPendingTime = root.latestPendingTime = expirationTime;
3289 } else {
3290 if (earliestPendingTime < expirationTime) {
3291 // This is the earliest pending update.
3292 root.earliestPendingTime = expirationTime;
3293 } else {
3294 var latestPendingTime = root.latestPendingTime;
3295 if (latestPendingTime > expirationTime) {
3296 // This is the latest pending update
3297 root.latestPendingTime = expirationTime;
3298 }
3299 }
3300 }
3301 findNextExpirationTimeToWorkOn(expirationTime, root);
3302}
3303
3304function markCommittedPriorityLevels(root, earliestRemainingTime) {
3305 root.didError = false;
3306
3307 if (earliestRemainingTime === NoWork) {
3308 // Fast path. There's no remaining work. Clear everything.
3309 root.earliestPendingTime = NoWork;
3310 root.latestPendingTime = NoWork;
3311 root.earliestSuspendedTime = NoWork;
3312 root.latestSuspendedTime = NoWork;
3313 root.latestPingedTime = NoWork;
3314 findNextExpirationTimeToWorkOn(NoWork, root);
3315 return;
3316 }
3317
3318 if (earliestRemainingTime < root.latestPingedTime) {
3319 root.latestPingedTime = NoWork;
3320 }
3321
3322 // Let's see if the previous latest known pending level was just flushed.
3323 var latestPendingTime = root.latestPendingTime;
3324 if (latestPendingTime !== NoWork) {
3325 if (latestPendingTime > earliestRemainingTime) {
3326 // We've flushed all the known pending levels.
3327 root.earliestPendingTime = root.latestPendingTime = NoWork;
3328 } else {
3329 var earliestPendingTime = root.earliestPendingTime;
3330 if (earliestPendingTime > earliestRemainingTime) {
3331 // We've flushed the earliest known pending level. Set this to the
3332 // latest pending time.
3333 root.earliestPendingTime = root.latestPendingTime;
3334 }
3335 }
3336 }
3337
3338 // Now let's handle the earliest remaining level in the whole tree. We need to
3339 // decide whether to treat it as a pending level or as suspended. Check
3340 // it falls within the range of known suspended levels.
3341
3342 var earliestSuspendedTime = root.earliestSuspendedTime;
3343 if (earliestSuspendedTime === NoWork) {
3344 // There's no suspended work. Treat the earliest remaining level as a
3345 // pending level.
3346 markPendingPriorityLevel(root, earliestRemainingTime);
3347 findNextExpirationTimeToWorkOn(NoWork, root);
3348 return;
3349 }
3350
3351 var latestSuspendedTime = root.latestSuspendedTime;
3352 if (earliestRemainingTime < latestSuspendedTime) {
3353 // The earliest remaining level is later than all the suspended work. That
3354 // means we've flushed all the suspended work.
3355 root.earliestSuspendedTime = NoWork;
3356 root.latestSuspendedTime = NoWork;
3357 root.latestPingedTime = NoWork;
3358
3359 // There's no suspended work. Treat the earliest remaining level as a
3360 // pending level.
3361 markPendingPriorityLevel(root, earliestRemainingTime);
3362 findNextExpirationTimeToWorkOn(NoWork, root);
3363 return;
3364 }
3365
3366 if (earliestRemainingTime > earliestSuspendedTime) {
3367 // The earliest remaining time is earlier than all the suspended work.
3368 // Treat it as a pending update.
3369 markPendingPriorityLevel(root, earliestRemainingTime);
3370 findNextExpirationTimeToWorkOn(NoWork, root);
3371 return;
3372 }
3373
3374 // The earliest remaining time falls within the range of known suspended
3375 // levels. We should treat this as suspended work.
3376 findNextExpirationTimeToWorkOn(NoWork, root);
3377}
3378
3379function hasLowerPriorityWork(root, erroredExpirationTime) {
3380 var latestPendingTime = root.latestPendingTime;
3381 var latestSuspendedTime = root.latestSuspendedTime;
3382 var latestPingedTime = root.latestPingedTime;
3383 return latestPendingTime !== NoWork && latestPendingTime < erroredExpirationTime || latestSuspendedTime !== NoWork && latestSuspendedTime < erroredExpirationTime || latestPingedTime !== NoWork && latestPingedTime < erroredExpirationTime;
3384}
3385
3386function isPriorityLevelSuspended(root, expirationTime) {
3387 var earliestSuspendedTime = root.earliestSuspendedTime;
3388 var latestSuspendedTime = root.latestSuspendedTime;
3389 return earliestSuspendedTime !== NoWork && expirationTime <= earliestSuspendedTime && expirationTime >= latestSuspendedTime;
3390}
3391
3392function markSuspendedPriorityLevel(root, suspendedTime) {
3393 root.didError = false;
3394 clearPing(root, suspendedTime);
3395
3396 // First, check the known pending levels and update them if needed.
3397 var earliestPendingTime = root.earliestPendingTime;
3398 var latestPendingTime = root.latestPendingTime;
3399 if (earliestPendingTime === suspendedTime) {
3400 if (latestPendingTime === suspendedTime) {
3401 // Both known pending levels were suspended. Clear them.
3402 root.earliestPendingTime = root.latestPendingTime = NoWork;
3403 } else {
3404 // The earliest pending level was suspended. Clear by setting it to the
3405 // latest pending level.
3406 root.earliestPendingTime = latestPendingTime;
3407 }
3408 } else if (latestPendingTime === suspendedTime) {
3409 // The latest pending level was suspended. Clear by setting it to the
3410 // latest pending level.
3411 root.latestPendingTime = earliestPendingTime;
3412 }
3413
3414 // Finally, update the known suspended levels.
3415 var earliestSuspendedTime = root.earliestSuspendedTime;
3416 var latestSuspendedTime = root.latestSuspendedTime;
3417 if (earliestSuspendedTime === NoWork) {
3418 // No other suspended levels.
3419 root.earliestSuspendedTime = root.latestSuspendedTime = suspendedTime;
3420 } else {
3421 if (earliestSuspendedTime < suspendedTime) {
3422 // This is the earliest suspended level.
3423 root.earliestSuspendedTime = suspendedTime;
3424 } else if (latestSuspendedTime > suspendedTime) {
3425 // This is the latest suspended level
3426 root.latestSuspendedTime = suspendedTime;
3427 }
3428 }
3429
3430 findNextExpirationTimeToWorkOn(suspendedTime, root);
3431}
3432
3433function markPingedPriorityLevel(root, pingedTime) {
3434 root.didError = false;
3435
3436 // TODO: When we add back resuming, we need to ensure the progressed work
3437 // is thrown out and not reused during the restarted render. One way to
3438 // invalidate the progressed work is to restart at expirationTime + 1.
3439 var latestPingedTime = root.latestPingedTime;
3440 if (latestPingedTime === NoWork || latestPingedTime > pingedTime) {
3441 root.latestPingedTime = pingedTime;
3442 }
3443 findNextExpirationTimeToWorkOn(pingedTime, root);
3444}
3445
3446function clearPing(root, completedTime) {
3447 var latestPingedTime = root.latestPingedTime;
3448 if (latestPingedTime >= completedTime) {
3449 root.latestPingedTime = NoWork;
3450 }
3451}
3452
3453function findEarliestOutstandingPriorityLevel(root, renderExpirationTime) {
3454 var earliestExpirationTime = renderExpirationTime;
3455
3456 var earliestPendingTime = root.earliestPendingTime;
3457 var earliestSuspendedTime = root.earliestSuspendedTime;
3458 if (earliestPendingTime > earliestExpirationTime) {
3459 earliestExpirationTime = earliestPendingTime;
3460 }
3461 if (earliestSuspendedTime > earliestExpirationTime) {
3462 earliestExpirationTime = earliestSuspendedTime;
3463 }
3464 return earliestExpirationTime;
3465}
3466
3467function didExpireAtExpirationTime(root, currentTime) {
3468 var expirationTime = root.expirationTime;
3469 if (expirationTime !== NoWork && currentTime <= expirationTime) {
3470 // The root has expired. Flush all work up to the current time.
3471 root.nextExpirationTimeToWorkOn = currentTime;
3472 }
3473}
3474
3475function findNextExpirationTimeToWorkOn(completedExpirationTime, root) {
3476 var earliestSuspendedTime = root.earliestSuspendedTime;
3477 var latestSuspendedTime = root.latestSuspendedTime;
3478 var earliestPendingTime = root.earliestPendingTime;
3479 var latestPingedTime = root.latestPingedTime;
3480
3481 // Work on the earliest pending time. Failing that, work on the latest
3482 // pinged time.
3483 var nextExpirationTimeToWorkOn = earliestPendingTime !== NoWork ? earliestPendingTime : latestPingedTime;
3484
3485 // If there is no pending or pinged work, check if there's suspended work
3486 // that's lower priority than what we just completed.
3487 if (nextExpirationTimeToWorkOn === NoWork && (completedExpirationTime === NoWork || latestSuspendedTime < completedExpirationTime)) {
3488 // The lowest priority suspended work is the work most likely to be
3489 // committed next. Let's start rendering it again, so that if it times out,
3490 // it's ready to commit.
3491 nextExpirationTimeToWorkOn = latestSuspendedTime;
3492 }
3493
3494 var expirationTime = nextExpirationTimeToWorkOn;
3495 if (expirationTime !== NoWork && earliestSuspendedTime > expirationTime) {
3496 // Expire using the earliest known expiration time.
3497 expirationTime = earliestSuspendedTime;
3498 }
3499
3500 root.nextExpirationTimeToWorkOn = nextExpirationTimeToWorkOn;
3501 root.expirationTime = expirationTime;
3502}
3503
3504/**
3505 * Similar to invariant but only logs a warning if the condition is not met.
3506 * This can be used to log issues in development environments in critical
3507 * paths. Removing the logging code for production environments will keep the
3508 * same logic and follow the same code paths.
3509 */
3510
3511var warning = warningWithoutStack$1;
3512
3513{
3514 warning = function (condition, format) {
3515 if (condition) {
3516 return;
3517 }
3518 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
3519 var stack = ReactDebugCurrentFrame.getStackAddendum();
3520 // eslint-disable-next-line react-internal/warning-and-invariant-args
3521
3522 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
3523 args[_key - 2] = arguments[_key];
3524 }
3525
3526 warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack]));
3527 };
3528}
3529
3530var warning$1 = warning;
3531
3532/**
3533 * inlined Object.is polyfill to avoid requiring consumers ship their own
3534 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
3535 */
3536function is(x, y) {
3537 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
3538 ;
3539}
3540
3541var hasOwnProperty = Object.prototype.hasOwnProperty;
3542
3543/**
3544 * Performs equality by iterating through keys on an object and returning false
3545 * when any key has values which are not strictly equal between the arguments.
3546 * Returns true when the values of all keys are strictly equal.
3547 */
3548function shallowEqual(objA, objB) {
3549 if (is(objA, objB)) {
3550 return true;
3551 }
3552
3553 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
3554 return false;
3555 }
3556
3557 var keysA = Object.keys(objA);
3558 var keysB = Object.keys(objB);
3559
3560 if (keysA.length !== keysB.length) {
3561 return false;
3562 }
3563
3564 // Test for A's keys different from B.
3565 for (var i = 0; i < keysA.length; i++) {
3566 if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
3567 return false;
3568 }
3569 }
3570
3571 return true;
3572}
3573
3574function resolveDefaultProps(Component, baseProps) {
3575 if (Component && Component.defaultProps) {
3576 // Resolve default props. Taken from ReactElement
3577 var props = _assign({}, baseProps);
3578 var defaultProps = Component.defaultProps;
3579 for (var propName in defaultProps) {
3580 if (props[propName] === undefined) {
3581 props[propName] = defaultProps[propName];
3582 }
3583 }
3584 return props;
3585 }
3586 return baseProps;
3587}
3588
3589function readLazyComponentType(lazyComponent) {
3590 var status = lazyComponent._status;
3591 var result = lazyComponent._result;
3592 switch (status) {
3593 case Resolved:
3594 {
3595 var Component = result;
3596 return Component;
3597 }
3598 case Rejected:
3599 {
3600 var error = result;
3601 throw error;
3602 }
3603 case Pending:
3604 {
3605 var thenable = result;
3606 throw thenable;
3607 }
3608 default:
3609 {
3610 lazyComponent._status = Pending;
3611 var ctor = lazyComponent._ctor;
3612 var _thenable = ctor();
3613 _thenable.then(function (moduleObject) {
3614 if (lazyComponent._status === Pending) {
3615 var defaultExport = moduleObject.default;
3616 {
3617 if (defaultExport === undefined) {
3618 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);
3619 }
3620 }
3621 lazyComponent._status = Resolved;
3622 lazyComponent._result = defaultExport;
3623 }
3624 }, function (error) {
3625 if (lazyComponent._status === Pending) {
3626 lazyComponent._status = Rejected;
3627 lazyComponent._result = error;
3628 }
3629 });
3630 // Handle synchronous thenables.
3631 switch (lazyComponent._status) {
3632 case Resolved:
3633 return lazyComponent._result;
3634 case Rejected:
3635 throw lazyComponent._result;
3636 }
3637 lazyComponent._result = _thenable;
3638 throw _thenable;
3639 }
3640 }
3641}
3642
3643var fakeInternalInstance = {};
3644var isArray$1 = Array.isArray;
3645
3646// React.Component uses a shared frozen object by default.
3647// We'll use it to determine whether we need to initialize legacy refs.
3648var emptyRefsObject = new React.Component().refs;
3649
3650var didWarnAboutStateAssignmentForComponent = void 0;
3651var didWarnAboutUninitializedState = void 0;
3652var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0;
3653var didWarnAboutLegacyLifecyclesAndDerivedState = void 0;
3654var didWarnAboutUndefinedDerivedState = void 0;
3655var warnOnUndefinedDerivedState = void 0;
3656var warnOnInvalidCallback = void 0;
3657var didWarnAboutDirectlyAssigningPropsToState = void 0;
3658var didWarnAboutContextTypeAndContextTypes = void 0;
3659var didWarnAboutInvalidateContextType = void 0;
3660
3661{
3662 didWarnAboutStateAssignmentForComponent = new Set();
3663 didWarnAboutUninitializedState = new Set();
3664 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
3665 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
3666 didWarnAboutDirectlyAssigningPropsToState = new Set();
3667 didWarnAboutUndefinedDerivedState = new Set();
3668 didWarnAboutContextTypeAndContextTypes = new Set();
3669 didWarnAboutInvalidateContextType = new Set();
3670
3671 var didWarnOnInvalidCallback = new Set();
3672
3673 warnOnInvalidCallback = function (callback, callerName) {
3674 if (callback === null || typeof callback === 'function') {
3675 return;
3676 }
3677 var key = callerName + '_' + callback;
3678 if (!didWarnOnInvalidCallback.has(key)) {
3679 didWarnOnInvalidCallback.add(key);
3680 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
3681 }
3682 };
3683
3684 warnOnUndefinedDerivedState = function (type, partialState) {
3685 if (partialState === undefined) {
3686 var componentName = getComponentName(type) || 'Component';
3687 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
3688 didWarnAboutUndefinedDerivedState.add(componentName);
3689 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
3690 }
3691 }
3692 };
3693
3694 // This is so gross but it's at least non-critical and can be removed if
3695 // it causes problems. This is meant to give a nicer error message for
3696 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
3697 // ...)) which otherwise throws a "_processChildContext is not a function"
3698 // exception.
3699 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
3700 enumerable: false,
3701 value: function () {
3702 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).');
3703 }
3704 });
3705 Object.freeze(fakeInternalInstance);
3706}
3707
3708function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
3709 var prevState = workInProgress.memoizedState;
3710
3711 {
3712 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
3713 // Invoke the function an extra time to help detect side-effects.
3714 getDerivedStateFromProps(nextProps, prevState);
3715 }
3716 }
3717
3718 var partialState = getDerivedStateFromProps(nextProps, prevState);
3719
3720 {
3721 warnOnUndefinedDerivedState(ctor, partialState);
3722 }
3723 // Merge the partial state and the previous state.
3724 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
3725 workInProgress.memoizedState = memoizedState;
3726
3727 // Once the update queue is empty, persist the derived state onto the
3728 // base state.
3729 var updateQueue = workInProgress.updateQueue;
3730 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
3731 updateQueue.baseState = memoizedState;
3732 }
3733}
3734
3735var classComponentUpdater = {
3736 isMounted: isMounted,
3737 enqueueSetState: function (inst, payload, callback) {
3738 var fiber = get(inst);
3739 var currentTime = requestCurrentTime();
3740 var expirationTime = computeExpirationForFiber(currentTime, fiber);
3741
3742 var update = createUpdate(expirationTime);
3743 update.payload = payload;
3744 if (callback !== undefined && callback !== null) {
3745 {
3746 warnOnInvalidCallback(callback, 'setState');
3747 }
3748 update.callback = callback;
3749 }
3750
3751 flushPassiveEffects();
3752 enqueueUpdate(fiber, update);
3753 scheduleWork(fiber, expirationTime);
3754 },
3755 enqueueReplaceState: function (inst, payload, callback) {
3756 var fiber = get(inst);
3757 var currentTime = requestCurrentTime();
3758 var expirationTime = computeExpirationForFiber(currentTime, fiber);
3759
3760 var update = createUpdate(expirationTime);
3761 update.tag = ReplaceState;
3762 update.payload = payload;
3763
3764 if (callback !== undefined && callback !== null) {
3765 {
3766 warnOnInvalidCallback(callback, 'replaceState');
3767 }
3768 update.callback = callback;
3769 }
3770
3771 flushPassiveEffects();
3772 enqueueUpdate(fiber, update);
3773 scheduleWork(fiber, expirationTime);
3774 },
3775 enqueueForceUpdate: function (inst, callback) {
3776 var fiber = get(inst);
3777 var currentTime = requestCurrentTime();
3778 var expirationTime = computeExpirationForFiber(currentTime, fiber);
3779
3780 var update = createUpdate(expirationTime);
3781 update.tag = ForceUpdate;
3782
3783 if (callback !== undefined && callback !== null) {
3784 {
3785 warnOnInvalidCallback(callback, 'forceUpdate');
3786 }
3787 update.callback = callback;
3788 }
3789
3790 flushPassiveEffects();
3791 enqueueUpdate(fiber, update);
3792 scheduleWork(fiber, expirationTime);
3793 }
3794};
3795
3796function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
3797 var instance = workInProgress.stateNode;
3798 if (typeof instance.shouldComponentUpdate === 'function') {
3799 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
3800 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
3801 stopPhaseTimer();
3802
3803 {
3804 !(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;
3805 }
3806
3807 return shouldUpdate;
3808 }
3809
3810 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
3811 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
3812 }
3813
3814 return true;
3815}
3816
3817function checkClassInstance(workInProgress, ctor, newProps) {
3818 var instance = workInProgress.stateNode;
3819 {
3820 var name = getComponentName(ctor) || 'Component';
3821 var renderPresent = instance.render;
3822
3823 if (!renderPresent) {
3824 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
3825 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
3826 } else {
3827 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
3828 }
3829 }
3830
3831 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
3832 !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;
3833 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
3834 !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;
3835 var noInstancePropTypes = !instance.propTypes;
3836 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0;
3837 var noInstanceContextType = !instance.contextType;
3838 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0;
3839 var noInstanceContextTypes = !instance.contextTypes;
3840 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0;
3841
3842 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
3843 didWarnAboutContextTypeAndContextTypes.add(ctor);
3844 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
3845 }
3846
3847 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
3848 !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;
3849 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
3850 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');
3851 }
3852 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
3853 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0;
3854 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
3855 !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;
3856 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
3857 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0;
3858 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
3859 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0;
3860 var hasMutatedProps = instance.props !== newProps;
3861 !(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;
3862 var noInstanceDefaultProps = !instance.defaultProps;
3863 !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;
3864
3865 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
3866 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
3867 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
3868 }
3869
3870 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function';
3871 !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;
3872 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function';
3873 !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;
3874 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function';
3875 !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;
3876 var _state = instance.state;
3877 if (_state && (typeof _state !== 'object' || isArray$1(_state))) {
3878 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name);
3879 }
3880 if (typeof instance.getChildContext === 'function') {
3881 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0;
3882 }
3883 }
3884}
3885
3886function adoptClassInstance(workInProgress, instance) {
3887 instance.updater = classComponentUpdater;
3888 workInProgress.stateNode = instance;
3889 // The instance needs access to the fiber so that it can schedule updates
3890 set(instance, workInProgress);
3891 {
3892 instance._reactInternalInstance = fakeInternalInstance;
3893 }
3894}
3895
3896function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) {
3897 var isLegacyContextConsumer = false;
3898 var unmaskedContext = emptyContextObject;
3899 var context = null;
3900 var contextType = ctor.contextType;
3901 if (typeof contextType === 'object' && contextType !== null) {
3902 {
3903 if (contextType.$$typeof !== REACT_CONTEXT_TYPE && !didWarnAboutInvalidateContextType.has(ctor)) {
3904 didWarnAboutInvalidateContextType.add(ctor);
3905 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');
3906 }
3907 }
3908
3909 context = readContext(contextType);
3910 } else {
3911 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
3912 var contextTypes = ctor.contextTypes;
3913 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
3914 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
3915 }
3916
3917 // Instantiate twice to help detect side-effects.
3918 {
3919 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
3920 new ctor(props, context); // eslint-disable-line no-new
3921 }
3922 }
3923
3924 var instance = new ctor(props, context);
3925 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
3926 adoptClassInstance(workInProgress, instance);
3927
3928 {
3929 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
3930 var componentName = getComponentName(ctor) || 'Component';
3931 if (!didWarnAboutUninitializedState.has(componentName)) {
3932 didWarnAboutUninitializedState.add(componentName);
3933 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);
3934 }
3935 }
3936
3937 // If new component APIs are defined, "unsafe" lifecycles won't be called.
3938 // Warn about these lifecycles if they are present.
3939 // Don't warn about react-lifecycles-compat polyfilled methods though.
3940 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
3941 var foundWillMountName = null;
3942 var foundWillReceivePropsName = null;
3943 var foundWillUpdateName = null;
3944 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
3945 foundWillMountName = 'componentWillMount';
3946 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
3947 foundWillMountName = 'UNSAFE_componentWillMount';
3948 }
3949 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
3950 foundWillReceivePropsName = 'componentWillReceiveProps';
3951 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
3952 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
3953 }
3954 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
3955 foundWillUpdateName = 'componentWillUpdate';
3956 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
3957 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
3958 }
3959 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
3960 var _componentName = getComponentName(ctor) || 'Component';
3961 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
3962 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
3963 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
3964 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 : '');
3965 }
3966 }
3967 }
3968 }
3969
3970 // Cache unmasked context so we can avoid recreating masked context unless necessary.
3971 // ReactFiberContext usually updates this cache but can't for newly-created instances.
3972 if (isLegacyContextConsumer) {
3973 cacheContext(workInProgress, unmaskedContext, context);
3974 }
3975
3976 return instance;
3977}
3978
3979function callComponentWillMount(workInProgress, instance) {
3980 startPhaseTimer(workInProgress, 'componentWillMount');
3981 var oldState = instance.state;
3982
3983 if (typeof instance.componentWillMount === 'function') {
3984 instance.componentWillMount();
3985 }
3986 if (typeof instance.UNSAFE_componentWillMount === 'function') {
3987 instance.UNSAFE_componentWillMount();
3988 }
3989
3990 stopPhaseTimer();
3991
3992 if (oldState !== instance.state) {
3993 {
3994 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');
3995 }
3996 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
3997 }
3998}
3999
4000function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
4001 var oldState = instance.state;
4002 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
4003 if (typeof instance.componentWillReceiveProps === 'function') {
4004 instance.componentWillReceiveProps(newProps, nextContext);
4005 }
4006 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4007 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
4008 }
4009 stopPhaseTimer();
4010
4011 if (instance.state !== oldState) {
4012 {
4013 var componentName = getComponentName(workInProgress.type) || 'Component';
4014 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
4015 didWarnAboutStateAssignmentForComponent.add(componentName);
4016 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
4017 }
4018 }
4019 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4020 }
4021}
4022
4023// Invokes the mount life-cycles on a previously never rendered instance.
4024function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4025 {
4026 checkClassInstance(workInProgress, ctor, newProps);
4027 }
4028
4029 var instance = workInProgress.stateNode;
4030 instance.props = newProps;
4031 instance.state = workInProgress.memoizedState;
4032 instance.refs = emptyRefsObject;
4033
4034 var contextType = ctor.contextType;
4035 if (typeof contextType === 'object' && contextType !== null) {
4036 instance.context = readContext(contextType);
4037 } else {
4038 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4039 instance.context = getMaskedContext(workInProgress, unmaskedContext);
4040 }
4041
4042 {
4043 if (instance.state === newProps) {
4044 var componentName = getComponentName(ctor) || 'Component';
4045 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
4046 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
4047 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);
4048 }
4049 }
4050
4051 if (workInProgress.mode & StrictMode) {
4052 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
4053
4054 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
4055 }
4056
4057 if (warnAboutDeprecatedLifecycles) {
4058 ReactStrictModeWarnings.recordDeprecationWarnings(workInProgress, instance);
4059 }
4060 }
4061
4062 var updateQueue = workInProgress.updateQueue;
4063 if (updateQueue !== null) {
4064 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4065 instance.state = workInProgress.memoizedState;
4066 }
4067
4068 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4069 if (typeof getDerivedStateFromProps === 'function') {
4070 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4071 instance.state = workInProgress.memoizedState;
4072 }
4073
4074 // In order to support react-lifecycles-compat polyfilled components,
4075 // Unsafe lifecycles should not be invoked for components using the new APIs.
4076 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4077 callComponentWillMount(workInProgress, instance);
4078 // If we had additional state updates during this life-cycle, let's
4079 // process them now.
4080 updateQueue = workInProgress.updateQueue;
4081 if (updateQueue !== null) {
4082 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4083 instance.state = workInProgress.memoizedState;
4084 }
4085 }
4086
4087 if (typeof instance.componentDidMount === 'function') {
4088 workInProgress.effectTag |= Update;
4089 }
4090}
4091
4092function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4093 var instance = workInProgress.stateNode;
4094
4095 var oldProps = workInProgress.memoizedProps;
4096 instance.props = oldProps;
4097
4098 var oldContext = instance.context;
4099 var contextType = ctor.contextType;
4100 var nextContext = void 0;
4101 if (typeof contextType === 'object' && contextType !== null) {
4102 nextContext = readContext(contextType);
4103 } else {
4104 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4105 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
4106 }
4107
4108 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4109 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
4110
4111 // Note: During these life-cycles, instance.props/instance.state are what
4112 // ever the previously attempted to render - not the "current". However,
4113 // during componentDidUpdate we pass the "current" props.
4114
4115 // In order to support react-lifecycles-compat polyfilled components,
4116 // Unsafe lifecycles should not be invoked for components using the new APIs.
4117 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4118 if (oldProps !== newProps || oldContext !== nextContext) {
4119 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4120 }
4121 }
4122
4123 resetHasForceUpdateBeforeProcessing();
4124
4125 var oldState = workInProgress.memoizedState;
4126 var newState = instance.state = oldState;
4127 var updateQueue = workInProgress.updateQueue;
4128 if (updateQueue !== null) {
4129 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4130 newState = workInProgress.memoizedState;
4131 }
4132 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4133 // If an update was already in progress, we should schedule an Update
4134 // effect even though we're bailing out, so that cWU/cDU are called.
4135 if (typeof instance.componentDidMount === 'function') {
4136 workInProgress.effectTag |= Update;
4137 }
4138 return false;
4139 }
4140
4141 if (typeof getDerivedStateFromProps === 'function') {
4142 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4143 newState = workInProgress.memoizedState;
4144 }
4145
4146 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4147
4148 if (shouldUpdate) {
4149 // In order to support react-lifecycles-compat polyfilled components,
4150 // Unsafe lifecycles should not be invoked for components using the new APIs.
4151 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4152 startPhaseTimer(workInProgress, 'componentWillMount');
4153 if (typeof instance.componentWillMount === 'function') {
4154 instance.componentWillMount();
4155 }
4156 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4157 instance.UNSAFE_componentWillMount();
4158 }
4159 stopPhaseTimer();
4160 }
4161 if (typeof instance.componentDidMount === 'function') {
4162 workInProgress.effectTag |= Update;
4163 }
4164 } else {
4165 // If an update was already in progress, we should schedule an Update
4166 // effect even though we're bailing out, so that cWU/cDU are called.
4167 if (typeof instance.componentDidMount === 'function') {
4168 workInProgress.effectTag |= Update;
4169 }
4170
4171 // If shouldComponentUpdate returned false, we should still update the
4172 // memoized state to indicate that this work can be reused.
4173 workInProgress.memoizedProps = newProps;
4174 workInProgress.memoizedState = newState;
4175 }
4176
4177 // Update the existing instance's state, props, and context pointers even
4178 // if shouldComponentUpdate returns false.
4179 instance.props = newProps;
4180 instance.state = newState;
4181 instance.context = nextContext;
4182
4183 return shouldUpdate;
4184}
4185
4186// Invokes the update life-cycles and returns false if it shouldn't rerender.
4187function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
4188 var instance = workInProgress.stateNode;
4189
4190 var oldProps = workInProgress.memoizedProps;
4191 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
4192
4193 var oldContext = instance.context;
4194 var contextType = ctor.contextType;
4195 var nextContext = void 0;
4196 if (typeof contextType === 'object' && contextType !== null) {
4197 nextContext = readContext(contextType);
4198 } else {
4199 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4200 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
4201 }
4202
4203 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4204 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
4205
4206 // Note: During these life-cycles, instance.props/instance.state are what
4207 // ever the previously attempted to render - not the "current". However,
4208 // during componentDidUpdate we pass the "current" props.
4209
4210 // In order to support react-lifecycles-compat polyfilled components,
4211 // Unsafe lifecycles should not be invoked for components using the new APIs.
4212 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4213 if (oldProps !== newProps || oldContext !== nextContext) {
4214 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4215 }
4216 }
4217
4218 resetHasForceUpdateBeforeProcessing();
4219
4220 var oldState = workInProgress.memoizedState;
4221 var newState = instance.state = oldState;
4222 var updateQueue = workInProgress.updateQueue;
4223 if (updateQueue !== null) {
4224 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4225 newState = workInProgress.memoizedState;
4226 }
4227
4228 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4229 // If an update was already in progress, we should schedule an Update
4230 // effect even though we're bailing out, so that cWU/cDU are called.
4231 if (typeof instance.componentDidUpdate === 'function') {
4232 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4233 workInProgress.effectTag |= Update;
4234 }
4235 }
4236 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4237 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4238 workInProgress.effectTag |= Snapshot;
4239 }
4240 }
4241 return false;
4242 }
4243
4244 if (typeof getDerivedStateFromProps === 'function') {
4245 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4246 newState = workInProgress.memoizedState;
4247 }
4248
4249 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4250
4251 if (shouldUpdate) {
4252 // In order to support react-lifecycles-compat polyfilled components,
4253 // Unsafe lifecycles should not be invoked for components using the new APIs.
4254 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
4255 startPhaseTimer(workInProgress, 'componentWillUpdate');
4256 if (typeof instance.componentWillUpdate === 'function') {
4257 instance.componentWillUpdate(newProps, newState, nextContext);
4258 }
4259 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4260 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
4261 }
4262 stopPhaseTimer();
4263 }
4264 if (typeof instance.componentDidUpdate === 'function') {
4265 workInProgress.effectTag |= Update;
4266 }
4267 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4268 workInProgress.effectTag |= Snapshot;
4269 }
4270 } else {
4271 // If an update was already in progress, we should schedule an Update
4272 // effect even though we're bailing out, so that cWU/cDU are called.
4273 if (typeof instance.componentDidUpdate === 'function') {
4274 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4275 workInProgress.effectTag |= Update;
4276 }
4277 }
4278 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4279 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4280 workInProgress.effectTag |= Snapshot;
4281 }
4282 }
4283
4284 // If shouldComponentUpdate returned false, we should still update the
4285 // memoized props/state to indicate that this work can be reused.
4286 workInProgress.memoizedProps = newProps;
4287 workInProgress.memoizedState = newState;
4288 }
4289
4290 // Update the existing instance's state, props, and context pointers even
4291 // if shouldComponentUpdate returns false.
4292 instance.props = newProps;
4293 instance.state = newState;
4294 instance.context = nextContext;
4295
4296 return shouldUpdate;
4297}
4298
4299var didWarnAboutMaps = void 0;
4300var didWarnAboutGenerators = void 0;
4301var didWarnAboutStringRefInStrictMode = void 0;
4302var ownerHasKeyUseWarning = void 0;
4303var ownerHasFunctionTypeWarning = void 0;
4304var warnForMissingKey = function (child) {};
4305
4306{
4307 didWarnAboutMaps = false;
4308 didWarnAboutGenerators = false;
4309 didWarnAboutStringRefInStrictMode = {};
4310
4311 /**
4312 * Warn if there's no key explicitly set on dynamic arrays of children or
4313 * object keys are not valid. This allows us to keep track of children between
4314 * updates.
4315 */
4316 ownerHasKeyUseWarning = {};
4317 ownerHasFunctionTypeWarning = {};
4318
4319 warnForMissingKey = function (child) {
4320 if (child === null || typeof child !== 'object') {
4321 return;
4322 }
4323 if (!child._store || child._store.validated || child.key != null) {
4324 return;
4325 }
4326 !(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;
4327 child._store.validated = true;
4328
4329 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
4330 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
4331 return;
4332 }
4333 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
4334
4335 warning$1(false, 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
4336 };
4337}
4338
4339var isArray = Array.isArray;
4340
4341function coerceRef(returnFiber, current, element) {
4342 var mixedRef = element.ref;
4343 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
4344 {
4345 if (returnFiber.mode & StrictMode) {
4346 var componentName = getComponentName(returnFiber.type) || 'Component';
4347 if (!didWarnAboutStringRefInStrictMode[componentName]) {
4348 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));
4349 didWarnAboutStringRefInStrictMode[componentName] = true;
4350 }
4351 }
4352 }
4353
4354 if (element._owner) {
4355 var owner = element._owner;
4356 var inst = void 0;
4357 if (owner) {
4358 var ownerFiber = owner;
4359 !(ownerFiber.tag === ClassComponent) ? invariant(false, 'Function components cannot have refs. Did you mean to use React.forwardRef()?') : void 0;
4360 inst = ownerFiber.stateNode;
4361 }
4362 !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;
4363 var stringRef = '' + mixedRef;
4364 // Check if previous string ref matches new string ref
4365 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
4366 return current.ref;
4367 }
4368 var ref = function (value) {
4369 var refs = inst.refs;
4370 if (refs === emptyRefsObject) {
4371 // This is a lazy pooled frozen object, so we need to initialize.
4372 refs = inst.refs = {};
4373 }
4374 if (value === null) {
4375 delete refs[stringRef];
4376 } else {
4377 refs[stringRef] = value;
4378 }
4379 };
4380 ref._stringRef = stringRef;
4381 return ref;
4382 } else {
4383 !(typeof mixedRef === 'string') ? invariant(false, 'Expected ref to be a function, a string, an object returned by React.createRef(), or null.') : void 0;
4384 !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;
4385 }
4386 }
4387 return mixedRef;
4388}
4389
4390function throwOnInvalidObjectType(returnFiber, newChild) {
4391 if (returnFiber.type !== 'textarea') {
4392 var addendum = '';
4393 {
4394 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
4395 }
4396 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);
4397 }
4398}
4399
4400function warnOnFunctionType() {
4401 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();
4402
4403 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
4404 return;
4405 }
4406 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
4407
4408 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.');
4409}
4410
4411// This wrapper function exists because I expect to clone the code in each path
4412// to be able to optimize each path individually by branching early. This needs
4413// a compiler or we can do it manually. Helpers that don't need this branching
4414// live outside of this function.
4415function ChildReconciler(shouldTrackSideEffects) {
4416 function deleteChild(returnFiber, childToDelete) {
4417 if (!shouldTrackSideEffects) {
4418 // Noop.
4419 return;
4420 }
4421 // Deletions are added in reversed order so we add it to the front.
4422 // At this point, the return fiber's effect list is empty except for
4423 // deletions, so we can just append the deletion to the list. The remaining
4424 // effects aren't added until the complete phase. Once we implement
4425 // resuming, this may not be true.
4426 var last = returnFiber.lastEffect;
4427 if (last !== null) {
4428 last.nextEffect = childToDelete;
4429 returnFiber.lastEffect = childToDelete;
4430 } else {
4431 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
4432 }
4433 childToDelete.nextEffect = null;
4434 childToDelete.effectTag = Deletion;
4435 }
4436
4437 function deleteRemainingChildren(returnFiber, currentFirstChild) {
4438 if (!shouldTrackSideEffects) {
4439 // Noop.
4440 return null;
4441 }
4442
4443 // TODO: For the shouldClone case, this could be micro-optimized a bit by
4444 // assuming that after the first child we've already added everything.
4445 var childToDelete = currentFirstChild;
4446 while (childToDelete !== null) {
4447 deleteChild(returnFiber, childToDelete);
4448 childToDelete = childToDelete.sibling;
4449 }
4450 return null;
4451 }
4452
4453 function mapRemainingChildren(returnFiber, currentFirstChild) {
4454 // Add the remaining children to a temporary map so that we can find them by
4455 // keys quickly. Implicit (null) keys get added to this set with their index
4456 var existingChildren = new Map();
4457
4458 var existingChild = currentFirstChild;
4459 while (existingChild !== null) {
4460 if (existingChild.key !== null) {
4461 existingChildren.set(existingChild.key, existingChild);
4462 } else {
4463 existingChildren.set(existingChild.index, existingChild);
4464 }
4465 existingChild = existingChild.sibling;
4466 }
4467 return existingChildren;
4468 }
4469
4470 function useFiber(fiber, pendingProps, expirationTime) {
4471 // We currently set sibling to null and index to 0 here because it is easy
4472 // to forget to do before returning it. E.g. for the single child case.
4473 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
4474 clone.index = 0;
4475 clone.sibling = null;
4476 return clone;
4477 }
4478
4479 function placeChild(newFiber, lastPlacedIndex, newIndex) {
4480 newFiber.index = newIndex;
4481 if (!shouldTrackSideEffects) {
4482 // Noop.
4483 return lastPlacedIndex;
4484 }
4485 var current = newFiber.alternate;
4486 if (current !== null) {
4487 var oldIndex = current.index;
4488 if (oldIndex < lastPlacedIndex) {
4489 // This is a move.
4490 newFiber.effectTag = Placement;
4491 return lastPlacedIndex;
4492 } else {
4493 // This item can stay in place.
4494 return oldIndex;
4495 }
4496 } else {
4497 // This is an insertion.
4498 newFiber.effectTag = Placement;
4499 return lastPlacedIndex;
4500 }
4501 }
4502
4503 function placeSingleChild(newFiber) {
4504 // This is simpler for the single child case. We only need to do a
4505 // placement for inserting new children.
4506 if (shouldTrackSideEffects && newFiber.alternate === null) {
4507 newFiber.effectTag = Placement;
4508 }
4509 return newFiber;
4510 }
4511
4512 function updateTextNode(returnFiber, current, textContent, expirationTime) {
4513 if (current === null || current.tag !== HostText) {
4514 // Insert
4515 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
4516 created.return = returnFiber;
4517 return created;
4518 } else {
4519 // Update
4520 var existing = useFiber(current, textContent, expirationTime);
4521 existing.return = returnFiber;
4522 return existing;
4523 }
4524 }
4525
4526 function updateElement(returnFiber, current, element, expirationTime) {
4527 if (current !== null && current.elementType === element.type) {
4528 // Move based on index
4529 var existing = useFiber(current, element.props, expirationTime);
4530 existing.ref = coerceRef(returnFiber, current, element);
4531 existing.return = returnFiber;
4532 {
4533 existing._debugSource = element._source;
4534 existing._debugOwner = element._owner;
4535 }
4536 return existing;
4537 } else {
4538 // Insert
4539 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
4540 created.ref = coerceRef(returnFiber, current, element);
4541 created.return = returnFiber;
4542 return created;
4543 }
4544 }
4545
4546 function updatePortal(returnFiber, current, portal, expirationTime) {
4547 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
4548 // Insert
4549 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
4550 created.return = returnFiber;
4551 return created;
4552 } else {
4553 // Update
4554 var existing = useFiber(current, portal.children || [], expirationTime);
4555 existing.return = returnFiber;
4556 return existing;
4557 }
4558 }
4559
4560 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
4561 if (current === null || current.tag !== Fragment) {
4562 // Insert
4563 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
4564 created.return = returnFiber;
4565 return created;
4566 } else {
4567 // Update
4568 var existing = useFiber(current, fragment, expirationTime);
4569 existing.return = returnFiber;
4570 return existing;
4571 }
4572 }
4573
4574 function createChild(returnFiber, newChild, expirationTime) {
4575 if (typeof newChild === 'string' || typeof newChild === 'number') {
4576 // Text nodes don't have keys. If the previous node is implicitly keyed
4577 // we can continue to replace it without aborting even if it is not a text
4578 // node.
4579 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
4580 created.return = returnFiber;
4581 return created;
4582 }
4583
4584 if (typeof newChild === 'object' && newChild !== null) {
4585 switch (newChild.$$typeof) {
4586 case REACT_ELEMENT_TYPE:
4587 {
4588 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
4589 _created.ref = coerceRef(returnFiber, null, newChild);
4590 _created.return = returnFiber;
4591 return _created;
4592 }
4593 case REACT_PORTAL_TYPE:
4594 {
4595 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
4596 _created2.return = returnFiber;
4597 return _created2;
4598 }
4599 }
4600
4601 if (isArray(newChild) || getIteratorFn(newChild)) {
4602 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
4603 _created3.return = returnFiber;
4604 return _created3;
4605 }
4606
4607 throwOnInvalidObjectType(returnFiber, newChild);
4608 }
4609
4610 {
4611 if (typeof newChild === 'function') {
4612 warnOnFunctionType();
4613 }
4614 }
4615
4616 return null;
4617 }
4618
4619 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
4620 // Update the fiber if the keys match, otherwise return null.
4621
4622 var key = oldFiber !== null ? oldFiber.key : null;
4623
4624 if (typeof newChild === 'string' || typeof newChild === 'number') {
4625 // Text nodes don't have keys. If the previous node is implicitly keyed
4626 // we can continue to replace it without aborting even if it is not a text
4627 // node.
4628 if (key !== null) {
4629 return null;
4630 }
4631 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
4632 }
4633
4634 if (typeof newChild === 'object' && newChild !== null) {
4635 switch (newChild.$$typeof) {
4636 case REACT_ELEMENT_TYPE:
4637 {
4638 if (newChild.key === key) {
4639 if (newChild.type === REACT_FRAGMENT_TYPE) {
4640 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
4641 }
4642 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
4643 } else {
4644 return null;
4645 }
4646 }
4647 case REACT_PORTAL_TYPE:
4648 {
4649 if (newChild.key === key) {
4650 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
4651 } else {
4652 return null;
4653 }
4654 }
4655 }
4656
4657 if (isArray(newChild) || getIteratorFn(newChild)) {
4658 if (key !== null) {
4659 return null;
4660 }
4661
4662 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
4663 }
4664
4665 throwOnInvalidObjectType(returnFiber, newChild);
4666 }
4667
4668 {
4669 if (typeof newChild === 'function') {
4670 warnOnFunctionType();
4671 }
4672 }
4673
4674 return null;
4675 }
4676
4677 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
4678 if (typeof newChild === 'string' || typeof newChild === 'number') {
4679 // Text nodes don't have keys, so we neither have to check the old nor
4680 // new node for the key. If both are text nodes, they match.
4681 var matchedFiber = existingChildren.get(newIdx) || null;
4682 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
4683 }
4684
4685 if (typeof newChild === 'object' && newChild !== null) {
4686 switch (newChild.$$typeof) {
4687 case REACT_ELEMENT_TYPE:
4688 {
4689 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
4690 if (newChild.type === REACT_FRAGMENT_TYPE) {
4691 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
4692 }
4693 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
4694 }
4695 case REACT_PORTAL_TYPE:
4696 {
4697 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
4698 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
4699 }
4700 }
4701
4702 if (isArray(newChild) || getIteratorFn(newChild)) {
4703 var _matchedFiber3 = existingChildren.get(newIdx) || null;
4704 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
4705 }
4706
4707 throwOnInvalidObjectType(returnFiber, newChild);
4708 }
4709
4710 {
4711 if (typeof newChild === 'function') {
4712 warnOnFunctionType();
4713 }
4714 }
4715
4716 return null;
4717 }
4718
4719 /**
4720 * Warns if there is a duplicate or missing key
4721 */
4722 function warnOnInvalidKey(child, knownKeys) {
4723 {
4724 if (typeof child !== 'object' || child === null) {
4725 return knownKeys;
4726 }
4727 switch (child.$$typeof) {
4728 case REACT_ELEMENT_TYPE:
4729 case REACT_PORTAL_TYPE:
4730 warnForMissingKey(child);
4731 var key = child.key;
4732 if (typeof key !== 'string') {
4733 break;
4734 }
4735 if (knownKeys === null) {
4736 knownKeys = new Set();
4737 knownKeys.add(key);
4738 break;
4739 }
4740 if (!knownKeys.has(key)) {
4741 knownKeys.add(key);
4742 break;
4743 }
4744 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);
4745 break;
4746 default:
4747 break;
4748 }
4749 }
4750 return knownKeys;
4751 }
4752
4753 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
4754 // This algorithm can't optimize by searching from boths ends since we
4755 // don't have backpointers on fibers. I'm trying to see how far we can get
4756 // with that model. If it ends up not being worth the tradeoffs, we can
4757 // add it later.
4758
4759 // Even with a two ended optimization, we'd want to optimize for the case
4760 // where there are few changes and brute force the comparison instead of
4761 // going for the Map. It'd like to explore hitting that path first in
4762 // forward-only mode and only go for the Map once we notice that we need
4763 // lots of look ahead. This doesn't handle reversal as well as two ended
4764 // search but that's unusual. Besides, for the two ended optimization to
4765 // work on Iterables, we'd need to copy the whole set.
4766
4767 // In this first iteration, we'll just live with hitting the bad case
4768 // (adding everything to a Map) in for every insert/move.
4769
4770 // If you change this code, also update reconcileChildrenIterator() which
4771 // uses the same algorithm.
4772
4773 {
4774 // First, validate keys.
4775 var knownKeys = null;
4776 for (var i = 0; i < newChildren.length; i++) {
4777 var child = newChildren[i];
4778 knownKeys = warnOnInvalidKey(child, knownKeys);
4779 }
4780 }
4781
4782 var resultingFirstChild = null;
4783 var previousNewFiber = null;
4784
4785 var oldFiber = currentFirstChild;
4786 var lastPlacedIndex = 0;
4787 var newIdx = 0;
4788 var nextOldFiber = null;
4789 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
4790 if (oldFiber.index > newIdx) {
4791 nextOldFiber = oldFiber;
4792 oldFiber = null;
4793 } else {
4794 nextOldFiber = oldFiber.sibling;
4795 }
4796 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
4797 if (newFiber === null) {
4798 // TODO: This breaks on empty slots like null children. That's
4799 // unfortunate because it triggers the slow path all the time. We need
4800 // a better way to communicate whether this was a miss or null,
4801 // boolean, undefined, etc.
4802 if (oldFiber === null) {
4803 oldFiber = nextOldFiber;
4804 }
4805 break;
4806 }
4807 if (shouldTrackSideEffects) {
4808 if (oldFiber && newFiber.alternate === null) {
4809 // We matched the slot, but we didn't reuse the existing fiber, so we
4810 // need to delete the existing child.
4811 deleteChild(returnFiber, oldFiber);
4812 }
4813 }
4814 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
4815 if (previousNewFiber === null) {
4816 // TODO: Move out of the loop. This only happens for the first run.
4817 resultingFirstChild = newFiber;
4818 } else {
4819 // TODO: Defer siblings if we're not at the right index for this slot.
4820 // I.e. if we had null values before, then we want to defer this
4821 // for each null value. However, we also don't want to call updateSlot
4822 // with the previous one.
4823 previousNewFiber.sibling = newFiber;
4824 }
4825 previousNewFiber = newFiber;
4826 oldFiber = nextOldFiber;
4827 }
4828
4829 if (newIdx === newChildren.length) {
4830 // We've reached the end of the new children. We can delete the rest.
4831 deleteRemainingChildren(returnFiber, oldFiber);
4832 return resultingFirstChild;
4833 }
4834
4835 if (oldFiber === null) {
4836 // If we don't have any more existing children we can choose a fast path
4837 // since the rest will all be insertions.
4838 for (; newIdx < newChildren.length; newIdx++) {
4839 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
4840 if (!_newFiber) {
4841 continue;
4842 }
4843 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
4844 if (previousNewFiber === null) {
4845 // TODO: Move out of the loop. This only happens for the first run.
4846 resultingFirstChild = _newFiber;
4847 } else {
4848 previousNewFiber.sibling = _newFiber;
4849 }
4850 previousNewFiber = _newFiber;
4851 }
4852 return resultingFirstChild;
4853 }
4854
4855 // Add all children to a key map for quick lookups.
4856 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
4857
4858 // Keep scanning and use the map to restore deleted items as moves.
4859 for (; newIdx < newChildren.length; newIdx++) {
4860 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
4861 if (_newFiber2) {
4862 if (shouldTrackSideEffects) {
4863 if (_newFiber2.alternate !== null) {
4864 // The new fiber is a work in progress, but if there exists a
4865 // current, that means that we reused the fiber. We need to delete
4866 // it from the child list so that we don't add it to the deletion
4867 // list.
4868 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
4869 }
4870 }
4871 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
4872 if (previousNewFiber === null) {
4873 resultingFirstChild = _newFiber2;
4874 } else {
4875 previousNewFiber.sibling = _newFiber2;
4876 }
4877 previousNewFiber = _newFiber2;
4878 }
4879 }
4880
4881 if (shouldTrackSideEffects) {
4882 // Any existing children that weren't consumed above were deleted. We need
4883 // to add them to the deletion list.
4884 existingChildren.forEach(function (child) {
4885 return deleteChild(returnFiber, child);
4886 });
4887 }
4888
4889 return resultingFirstChild;
4890 }
4891
4892 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
4893 // This is the same implementation as reconcileChildrenArray(),
4894 // but using the iterator instead.
4895
4896 var iteratorFn = getIteratorFn(newChildrenIterable);
4897 !(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;
4898
4899 {
4900 // We don't support rendering Generators because it's a mutation.
4901 // See https://github.com/facebook/react/issues/12995
4902 if (typeof Symbol === 'function' &&
4903 // $FlowFixMe Flow doesn't know about toStringTag
4904 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
4905 !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;
4906 didWarnAboutGenerators = true;
4907 }
4908
4909 // Warn about using Maps as children
4910 if (newChildrenIterable.entries === iteratorFn) {
4911 !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;
4912 didWarnAboutMaps = true;
4913 }
4914
4915 // First, validate keys.
4916 // We'll get a different iterator later for the main pass.
4917 var _newChildren = iteratorFn.call(newChildrenIterable);
4918 if (_newChildren) {
4919 var knownKeys = null;
4920 var _step = _newChildren.next();
4921 for (; !_step.done; _step = _newChildren.next()) {
4922 var child = _step.value;
4923 knownKeys = warnOnInvalidKey(child, knownKeys);
4924 }
4925 }
4926 }
4927
4928 var newChildren = iteratorFn.call(newChildrenIterable);
4929 !(newChildren != null) ? invariant(false, 'An iterable object provided no iterator.') : void 0;
4930
4931 var resultingFirstChild = null;
4932 var previousNewFiber = null;
4933
4934 var oldFiber = currentFirstChild;
4935 var lastPlacedIndex = 0;
4936 var newIdx = 0;
4937 var nextOldFiber = null;
4938
4939 var step = newChildren.next();
4940 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
4941 if (oldFiber.index > newIdx) {
4942 nextOldFiber = oldFiber;
4943 oldFiber = null;
4944 } else {
4945 nextOldFiber = oldFiber.sibling;
4946 }
4947 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
4948 if (newFiber === null) {
4949 // TODO: This breaks on empty slots like null children. That's
4950 // unfortunate because it triggers the slow path all the time. We need
4951 // a better way to communicate whether this was a miss or null,
4952 // boolean, undefined, etc.
4953 if (!oldFiber) {
4954 oldFiber = nextOldFiber;
4955 }
4956 break;
4957 }
4958 if (shouldTrackSideEffects) {
4959 if (oldFiber && newFiber.alternate === null) {
4960 // We matched the slot, but we didn't reuse the existing fiber, so we
4961 // need to delete the existing child.
4962 deleteChild(returnFiber, oldFiber);
4963 }
4964 }
4965 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
4966 if (previousNewFiber === null) {
4967 // TODO: Move out of the loop. This only happens for the first run.
4968 resultingFirstChild = newFiber;
4969 } else {
4970 // TODO: Defer siblings if we're not at the right index for this slot.
4971 // I.e. if we had null values before, then we want to defer this
4972 // for each null value. However, we also don't want to call updateSlot
4973 // with the previous one.
4974 previousNewFiber.sibling = newFiber;
4975 }
4976 previousNewFiber = newFiber;
4977 oldFiber = nextOldFiber;
4978 }
4979
4980 if (step.done) {
4981 // We've reached the end of the new children. We can delete the rest.
4982 deleteRemainingChildren(returnFiber, oldFiber);
4983 return resultingFirstChild;
4984 }
4985
4986 if (oldFiber === null) {
4987 // If we don't have any more existing children we can choose a fast path
4988 // since the rest will all be insertions.
4989 for (; !step.done; newIdx++, step = newChildren.next()) {
4990 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
4991 if (_newFiber3 === null) {
4992 continue;
4993 }
4994 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
4995 if (previousNewFiber === null) {
4996 // TODO: Move out of the loop. This only happens for the first run.
4997 resultingFirstChild = _newFiber3;
4998 } else {
4999 previousNewFiber.sibling = _newFiber3;
5000 }
5001 previousNewFiber = _newFiber3;
5002 }
5003 return resultingFirstChild;
5004 }
5005
5006 // Add all children to a key map for quick lookups.
5007 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
5008
5009 // Keep scanning and use the map to restore deleted items as moves.
5010 for (; !step.done; newIdx++, step = newChildren.next()) {
5011 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
5012 if (_newFiber4 !== null) {
5013 if (shouldTrackSideEffects) {
5014 if (_newFiber4.alternate !== null) {
5015 // The new fiber is a work in progress, but if there exists a
5016 // current, that means that we reused the fiber. We need to delete
5017 // it from the child list so that we don't add it to the deletion
5018 // list.
5019 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
5020 }
5021 }
5022 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
5023 if (previousNewFiber === null) {
5024 resultingFirstChild = _newFiber4;
5025 } else {
5026 previousNewFiber.sibling = _newFiber4;
5027 }
5028 previousNewFiber = _newFiber4;
5029 }
5030 }
5031
5032 if (shouldTrackSideEffects) {
5033 // Any existing children that weren't consumed above were deleted. We need
5034 // to add them to the deletion list.
5035 existingChildren.forEach(function (child) {
5036 return deleteChild(returnFiber, child);
5037 });
5038 }
5039
5040 return resultingFirstChild;
5041 }
5042
5043 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
5044 // There's no need to check for keys on text nodes since we don't have a
5045 // way to define them.
5046 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
5047 // We already have an existing node so let's just update it and delete
5048 // the rest.
5049 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
5050 var existing = useFiber(currentFirstChild, textContent, expirationTime);
5051 existing.return = returnFiber;
5052 return existing;
5053 }
5054 // The existing first child is not a text node so we need to create one
5055 // and delete the existing ones.
5056 deleteRemainingChildren(returnFiber, currentFirstChild);
5057 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
5058 created.return = returnFiber;
5059 return created;
5060 }
5061
5062 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
5063 var key = element.key;
5064 var child = currentFirstChild;
5065 while (child !== null) {
5066 // TODO: If key === null and child.key === null, then this only applies to
5067 // the first item in the list.
5068 if (child.key === key) {
5069 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type) {
5070 deleteRemainingChildren(returnFiber, child.sibling);
5071 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
5072 existing.ref = coerceRef(returnFiber, child, element);
5073 existing.return = returnFiber;
5074 {
5075 existing._debugSource = element._source;
5076 existing._debugOwner = element._owner;
5077 }
5078 return existing;
5079 } else {
5080 deleteRemainingChildren(returnFiber, child);
5081 break;
5082 }
5083 } else {
5084 deleteChild(returnFiber, child);
5085 }
5086 child = child.sibling;
5087 }
5088
5089 if (element.type === REACT_FRAGMENT_TYPE) {
5090 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
5091 created.return = returnFiber;
5092 return created;
5093 } else {
5094 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
5095 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
5096 _created4.return = returnFiber;
5097 return _created4;
5098 }
5099 }
5100
5101 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
5102 var key = portal.key;
5103 var child = currentFirstChild;
5104 while (child !== null) {
5105 // TODO: If key === null and child.key === null, then this only applies to
5106 // the first item in the list.
5107 if (child.key === key) {
5108 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
5109 deleteRemainingChildren(returnFiber, child.sibling);
5110 var existing = useFiber(child, portal.children || [], expirationTime);
5111 existing.return = returnFiber;
5112 return existing;
5113 } else {
5114 deleteRemainingChildren(returnFiber, child);
5115 break;
5116 }
5117 } else {
5118 deleteChild(returnFiber, child);
5119 }
5120 child = child.sibling;
5121 }
5122
5123 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
5124 created.return = returnFiber;
5125 return created;
5126 }
5127
5128 // This API will tag the children with the side-effect of the reconciliation
5129 // itself. They will be added to the side-effect list as we pass through the
5130 // children and the parent.
5131 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
5132 // This function is not recursive.
5133 // If the top level item is an array, we treat it as a set of children,
5134 // not as a fragment. Nested arrays on the other hand will be treated as
5135 // fragment nodes. Recursion happens at the normal flow.
5136
5137 // Handle top level unkeyed fragments as if they were arrays.
5138 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
5139 // We treat the ambiguous cases above the same.
5140 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
5141 if (isUnkeyedTopLevelFragment) {
5142 newChild = newChild.props.children;
5143 }
5144
5145 // Handle object types
5146 var isObject = typeof newChild === 'object' && newChild !== null;
5147
5148 if (isObject) {
5149 switch (newChild.$$typeof) {
5150 case REACT_ELEMENT_TYPE:
5151 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
5152 case REACT_PORTAL_TYPE:
5153 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
5154 }
5155 }
5156
5157 if (typeof newChild === 'string' || typeof newChild === 'number') {
5158 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
5159 }
5160
5161 if (isArray(newChild)) {
5162 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
5163 }
5164
5165 if (getIteratorFn(newChild)) {
5166 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
5167 }
5168
5169 if (isObject) {
5170 throwOnInvalidObjectType(returnFiber, newChild);
5171 }
5172
5173 {
5174 if (typeof newChild === 'function') {
5175 warnOnFunctionType();
5176 }
5177 }
5178 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
5179 // If the new child is undefined, and the return fiber is a composite
5180 // component, throw an error. If Fiber return types are disabled,
5181 // we already threw above.
5182 switch (returnFiber.tag) {
5183 case ClassComponent:
5184 {
5185 {
5186 var instance = returnFiber.stateNode;
5187 if (instance.render._isMockFunction) {
5188 // We allow auto-mocks to proceed as if they're returning null.
5189 break;
5190 }
5191 }
5192 }
5193 // Intentionally fall through to the next case, which handles both
5194 // functions and classes
5195 // eslint-disable-next-lined no-fallthrough
5196 case FunctionComponent:
5197 {
5198 var Component = returnFiber.type;
5199 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');
5200 }
5201 }
5202 }
5203
5204 // Remaining cases are all treated as empty.
5205 return deleteRemainingChildren(returnFiber, currentFirstChild);
5206 }
5207
5208 return reconcileChildFibers;
5209}
5210
5211var reconcileChildFibers = ChildReconciler(true);
5212var mountChildFibers = ChildReconciler(false);
5213
5214function cloneChildFibers(current, workInProgress) {
5215 !(current === null || workInProgress.child === current.child) ? invariant(false, 'Resuming work not yet implemented.') : void 0;
5216
5217 if (workInProgress.child === null) {
5218 return;
5219 }
5220
5221 var currentChild = workInProgress.child;
5222 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
5223 workInProgress.child = newChild;
5224
5225 newChild.return = workInProgress;
5226 while (currentChild.sibling !== null) {
5227 currentChild = currentChild.sibling;
5228 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
5229 newChild.return = workInProgress;
5230 }
5231 newChild.sibling = null;
5232}
5233
5234var NO_CONTEXT$1 = {};
5235
5236var contextStackCursor$1 = createCursor(NO_CONTEXT$1);
5237var contextFiberStackCursor = createCursor(NO_CONTEXT$1);
5238var rootInstanceStackCursor = createCursor(NO_CONTEXT$1);
5239
5240function requiredContext(c) {
5241 !(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;
5242 return c;
5243}
5244
5245function getRootHostContainer() {
5246 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5247 return rootInstance;
5248}
5249
5250function pushHostContainer(fiber, nextRootInstance) {
5251 // Push current root instance onto the stack;
5252 // This allows us to reset root when portals are popped.
5253 push(rootInstanceStackCursor, nextRootInstance, fiber);
5254 // Track the context and the Fiber that provided it.
5255 // This enables us to pop only Fibers that provide unique contexts.
5256 push(contextFiberStackCursor, fiber, fiber);
5257
5258 // Finally, we need to push the host context to the stack.
5259 // However, we can't just call getRootHostContext() and push it because
5260 // we'd have a different number of entries on the stack depending on
5261 // whether getRootHostContext() throws somewhere in renderer code or not.
5262 // So we push an empty value first. This lets us safely unwind on errors.
5263 push(contextStackCursor$1, NO_CONTEXT$1, fiber);
5264 var nextRootContext = getRootHostContext(nextRootInstance);
5265 // Now that we know this function doesn't throw, replace it.
5266 pop(contextStackCursor$1, fiber);
5267 push(contextStackCursor$1, nextRootContext, fiber);
5268}
5269
5270function popHostContainer(fiber) {
5271 pop(contextStackCursor$1, fiber);
5272 pop(contextFiberStackCursor, fiber);
5273 pop(rootInstanceStackCursor, fiber);
5274}
5275
5276function getHostContext() {
5277 var context = requiredContext(contextStackCursor$1.current);
5278 return context;
5279}
5280
5281function pushHostContext(fiber) {
5282 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5283 var context = requiredContext(contextStackCursor$1.current);
5284 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
5285
5286 // Don't push this Fiber's context unless it's unique.
5287 if (context === nextContext) {
5288 return;
5289 }
5290
5291 // Track the context and the Fiber that provided it.
5292 // This enables us to pop only Fibers that provide unique contexts.
5293 push(contextFiberStackCursor, fiber, fiber);
5294 push(contextStackCursor$1, nextContext, fiber);
5295}
5296
5297function popHostContext(fiber) {
5298 // Do not pop unless this Fiber provided the current context.
5299 // pushHostContext() only pushes Fibers that provide unique contexts.
5300 if (contextFiberStackCursor.current !== fiber) {
5301 return;
5302 }
5303
5304 pop(contextStackCursor$1, fiber);
5305 pop(contextFiberStackCursor, fiber);
5306}
5307
5308var NoEffect$1 = /* */0;
5309var UnmountSnapshot = /* */2;
5310var UnmountMutation = /* */4;
5311var MountMutation = /* */8;
5312var UnmountLayout = /* */16;
5313var MountLayout = /* */32;
5314var MountPassive = /* */64;
5315var UnmountPassive = /* */128;
5316
5317var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher;
5318
5319
5320var didWarnAboutMismatchedHooksForComponent = void 0;
5321{
5322 didWarnAboutMismatchedHooksForComponent = new Set();
5323}
5324
5325// These are set right before calling the component.
5326var renderExpirationTime = NoWork;
5327// The work-in-progress fiber. I've named it differently to distinguish it from
5328// the work-in-progress hook.
5329var currentlyRenderingFiber$1 = null;
5330
5331// Hooks are stored as a linked list on the fiber's memoizedState field. The
5332// current hook list is the list that belongs to the current fiber. The
5333// work-in-progress hook list is a new list that will be added to the
5334// work-in-progress fiber.
5335var firstCurrentHook = null;
5336var currentHook = null;
5337var nextCurrentHook = null;
5338var firstWorkInProgressHook = null;
5339var workInProgressHook = null;
5340var nextWorkInProgressHook = null;
5341
5342var remainingExpirationTime = NoWork;
5343var componentUpdateQueue = null;
5344var sideEffectTag = 0;
5345
5346// Updates scheduled during render will trigger an immediate re-render at the
5347// end of the current pass. We can't store these updates on the normal queue,
5348// because if the work is aborted, they should be discarded. Because this is
5349// a relatively rare case, we also don't want to add an additional field to
5350// either the hook or queue object types. So we store them in a lazily create
5351// map of queue -> render-phase updates, which are discarded once the component
5352// completes without re-rendering.
5353
5354// Whether an update was scheduled during the currently executing render pass.
5355var didScheduleRenderPhaseUpdate = false;
5356// Lazily created map of render-phase updates
5357var renderPhaseUpdates = null;
5358// Counter to prevent infinite loops.
5359var numberOfReRenders = 0;
5360var RE_RENDER_LIMIT = 25;
5361
5362// In DEV, this is the name of the currently executing primitive hook
5363var currentHookNameInDev = null;
5364
5365function warnOnHookMismatchInDev() {
5366 {
5367 var componentName = getComponentName(currentlyRenderingFiber$1.type);
5368 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
5369 didWarnAboutMismatchedHooksForComponent.add(componentName);
5370
5371 var secondColumnStart = 22;
5372
5373 var table = '';
5374 var prevHook = firstCurrentHook;
5375 var nextHook = firstWorkInProgressHook;
5376 var n = 1;
5377 while (prevHook !== null && nextHook !== null) {
5378 var oldHookName = prevHook._debugType;
5379 var newHookName = nextHook._debugType;
5380
5381 var row = n + '. ' + oldHookName;
5382
5383 // Extra space so second column lines up
5384 // lol @ IE not supporting String#repeat
5385 while (row.length < secondColumnStart) {
5386 row += ' ';
5387 }
5388
5389 row += newHookName + '\n';
5390
5391 table += row;
5392 prevHook = prevHook.next;
5393 nextHook = nextHook.next;
5394 n++;
5395 }
5396
5397 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);
5398 }
5399 }
5400}
5401
5402function throwInvalidHookError() {
5403 invariant(false, 'Hooks can only be called inside the body of a function component. (https://fb.me/react-invalid-hook-call)');
5404}
5405
5406function areHookInputsEqual(nextDeps, prevDeps) {
5407 if (prevDeps === null) {
5408 {
5409 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);
5410 }
5411 return false;
5412 }
5413
5414 {
5415 // Don't bother comparing lengths in prod because these arrays should be
5416 // passed inline.
5417 if (nextDeps.length !== prevDeps.length) {
5418 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(', ') + ']');
5419 }
5420 }
5421 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
5422 if (is(nextDeps[i], prevDeps[i])) {
5423 continue;
5424 }
5425 return false;
5426 }
5427 return true;
5428}
5429
5430function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) {
5431 renderExpirationTime = nextRenderExpirationTime;
5432 currentlyRenderingFiber$1 = workInProgress;
5433 firstCurrentHook = nextCurrentHook = current !== null ? current.memoizedState : null;
5434
5435 // The following should have already been reset
5436 // currentHook = null;
5437 // workInProgressHook = null;
5438
5439 // remainingExpirationTime = NoWork;
5440 // componentUpdateQueue = null;
5441
5442 // didScheduleRenderPhaseUpdate = false;
5443 // renderPhaseUpdates = null;
5444 // numberOfReRenders = 0;
5445 // sideEffectTag = 0;
5446
5447 {
5448 ReactCurrentDispatcher$1.current = nextCurrentHook === null ? HooksDispatcherOnMountInDEV : HooksDispatcherOnUpdateInDEV;
5449 }
5450
5451 var children = Component(props, refOrContext);
5452
5453 if (didScheduleRenderPhaseUpdate) {
5454 do {
5455 didScheduleRenderPhaseUpdate = false;
5456 numberOfReRenders += 1;
5457
5458 // Start over from the beginning of the list
5459 firstCurrentHook = nextCurrentHook = current !== null ? current.memoizedState : null;
5460 nextWorkInProgressHook = firstWorkInProgressHook;
5461
5462 currentHook = null;
5463 workInProgressHook = null;
5464 componentUpdateQueue = null;
5465
5466 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
5467
5468 children = Component(props, refOrContext);
5469 } while (didScheduleRenderPhaseUpdate);
5470
5471 renderPhaseUpdates = null;
5472 numberOfReRenders = 0;
5473 }
5474
5475 {
5476 currentHookNameInDev = null;
5477 }
5478
5479 // We can assume the previous dispatcher is always this one, since we set it
5480 // at the beginning of the render phase and there's no re-entrancy.
5481 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
5482
5483 var renderedWork = currentlyRenderingFiber$1;
5484
5485 renderedWork.memoizedState = firstWorkInProgressHook;
5486 renderedWork.expirationTime = remainingExpirationTime;
5487 renderedWork.updateQueue = componentUpdateQueue;
5488 renderedWork.effectTag |= sideEffectTag;
5489
5490 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
5491
5492 renderExpirationTime = NoWork;
5493 currentlyRenderingFiber$1 = null;
5494
5495 firstCurrentHook = null;
5496 currentHook = null;
5497 nextCurrentHook = null;
5498 firstWorkInProgressHook = null;
5499 workInProgressHook = null;
5500 nextWorkInProgressHook = null;
5501
5502 remainingExpirationTime = NoWork;
5503 componentUpdateQueue = null;
5504 sideEffectTag = 0;
5505
5506 // These were reset above
5507 // didScheduleRenderPhaseUpdate = false;
5508 // renderPhaseUpdates = null;
5509 // numberOfReRenders = 0;
5510
5511 !!didRenderTooFewHooks ? invariant(false, 'Rendered fewer hooks than expected. This may be caused by an accidental early return statement.') : void 0;
5512
5513 return children;
5514}
5515
5516function bailoutHooks(current, workInProgress, expirationTime) {
5517 workInProgress.updateQueue = current.updateQueue;
5518 workInProgress.effectTag &= ~(Passive | Update);
5519 if (current.expirationTime <= expirationTime) {
5520 current.expirationTime = NoWork;
5521 }
5522}
5523
5524function resetHooks() {
5525 // We can assume the previous dispatcher is always this one, since we set it
5526 // at the beginning of the render phase and there's no re-entrancy.
5527 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
5528
5529 // This is used to reset the state of this module when a component throws.
5530 // It's also called inside mountIndeterminateComponent if we determine the
5531 // component is a module-style component.
5532 renderExpirationTime = NoWork;
5533 currentlyRenderingFiber$1 = null;
5534
5535 firstCurrentHook = null;
5536 currentHook = null;
5537 nextCurrentHook = null;
5538 firstWorkInProgressHook = null;
5539 workInProgressHook = null;
5540 nextWorkInProgressHook = null;
5541
5542 remainingExpirationTime = NoWork;
5543 componentUpdateQueue = null;
5544 sideEffectTag = 0;
5545
5546 {
5547 currentHookNameInDev = null;
5548 }
5549
5550 didScheduleRenderPhaseUpdate = false;
5551 renderPhaseUpdates = null;
5552 numberOfReRenders = 0;
5553}
5554
5555function mountWorkInProgressHook() {
5556 var hook = {
5557 memoizedState: null,
5558
5559 baseState: null,
5560 queue: null,
5561 baseUpdate: null,
5562
5563 next: null
5564 };
5565
5566 {
5567 hook._debugType = currentHookNameInDev;
5568 if (currentlyRenderingFiber$1 !== null && currentlyRenderingFiber$1.alternate !== null) {
5569 warning$1(false, '%s: Rendered more hooks than during the previous render. This is ' + 'not currently supported and may lead to unexpected behavior.', getComponentName(currentlyRenderingFiber$1.type));
5570 }
5571 }
5572 if (workInProgressHook === null) {
5573 // This is the first hook in the list
5574 firstWorkInProgressHook = workInProgressHook = hook;
5575 } else {
5576 // Append to the end of the list
5577 workInProgressHook = workInProgressHook.next = hook;
5578 }
5579 return workInProgressHook;
5580}
5581
5582function updateWorkInProgressHook() {
5583 // This function is used both for updates and for re-renders triggered by a
5584 // render phase update. It assumes there is either a current hook we can
5585 // clone, or a work-in-progress hook from a previous render pass that we can
5586 // use as a base. When we reach the end of the base list, we must switch to
5587 // the dispatcher used for mounts.
5588 if (nextWorkInProgressHook !== null) {
5589 // There's already a work-in-progress. Reuse it.
5590 workInProgressHook = nextWorkInProgressHook;
5591 nextWorkInProgressHook = workInProgressHook.next;
5592
5593 currentHook = nextCurrentHook;
5594 nextCurrentHook = currentHook !== null ? currentHook.next : null;
5595 } else {
5596 // Clone from the current hook.
5597 !(nextCurrentHook !== null) ? invariant(false, 'Rendered more hooks than during the previous render.') : void 0;
5598 currentHook = nextCurrentHook;
5599
5600 var newHook = {
5601 memoizedState: currentHook.memoizedState,
5602
5603 baseState: currentHook.baseState,
5604 queue: currentHook.queue,
5605 baseUpdate: currentHook.baseUpdate,
5606
5607 next: null
5608 };
5609
5610 if (workInProgressHook === null) {
5611 // This is the first hook in the list.
5612 workInProgressHook = firstWorkInProgressHook = newHook;
5613 } else {
5614 // Append to the end of the list.
5615 workInProgressHook = workInProgressHook.next = newHook;
5616 }
5617 nextCurrentHook = currentHook.next;
5618
5619 {
5620 newHook._debugType = currentHookNameInDev;
5621 if (currentHookNameInDev !== currentHook._debugType) {
5622 warnOnHookMismatchInDev();
5623 }
5624 }
5625 }
5626 return workInProgressHook;
5627}
5628
5629function createFunctionComponentUpdateQueue() {
5630 return {
5631 lastEffect: null
5632 };
5633}
5634
5635function basicStateReducer(state, action) {
5636 return typeof action === 'function' ? action(state) : action;
5637}
5638
5639function mountContext(context, observedBits) {
5640 {
5641 mountWorkInProgressHook();
5642 }
5643 return readContext(context, observedBits);
5644}
5645
5646function updateContext(context, observedBits) {
5647 {
5648 updateWorkInProgressHook();
5649 }
5650 return readContext(context, observedBits);
5651}
5652
5653function mountReducer(reducer, initialArg, init) {
5654 var hook = mountWorkInProgressHook();
5655 var initialState = void 0;
5656 if (init !== undefined) {
5657 initialState = init(initialArg);
5658 } else {
5659 initialState = initialArg;
5660 }
5661 hook.memoizedState = hook.baseState = initialState;
5662 var queue = hook.queue = {
5663 last: null,
5664 dispatch: null,
5665 eagerReducer: reducer,
5666 eagerState: initialState
5667 };
5668 var dispatch = queue.dispatch = dispatchAction.bind(null,
5669 // Flow doesn't know this is non-null, but we do.
5670 currentlyRenderingFiber$1, queue);
5671 return [hook.memoizedState, dispatch];
5672}
5673
5674function updateReducer(reducer, initialArg, init) {
5675 var hook = updateWorkInProgressHook();
5676 var queue = hook.queue;
5677 !(queue !== null) ? invariant(false, 'Should have a queue. This is likely a bug in React. Please file an issue.') : void 0;
5678
5679 if (numberOfReRenders > 0) {
5680 // This is a re-render. Apply the new render phase updates to the previous
5681 var _dispatch = queue.dispatch;
5682 if (renderPhaseUpdates !== null) {
5683 // Render phase updates are stored in a map of queue -> linked list
5684 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
5685 if (firstRenderPhaseUpdate !== undefined) {
5686 renderPhaseUpdates.delete(queue);
5687 var newState = hook.memoizedState;
5688 var update = firstRenderPhaseUpdate;
5689 do {
5690 // Process this render phase update. We don't have to check the
5691 // priority because it will always be the same as the current
5692 // render's.
5693 var _action = update.action;
5694 newState = reducer(newState, _action);
5695 update = update.next;
5696 } while (update !== null);
5697
5698 // Mark that the fiber performed work, but only if the new state is
5699 // different from the current state.
5700 if (!is(newState, hook.memoizedState)) {
5701 markWorkInProgressReceivedUpdate();
5702 }
5703
5704 hook.memoizedState = newState;
5705
5706 // Don't persist the state accumlated from the render phase updates to
5707 // the base state unless the queue is empty.
5708 // TODO: Not sure if this is the desired semantics, but it's what we
5709 // do for gDSFP. I can't remember why.
5710 if (hook.baseUpdate === queue.last) {
5711 hook.baseState = newState;
5712 }
5713
5714 return [newState, _dispatch];
5715 }
5716 }
5717 return [hook.memoizedState, _dispatch];
5718 }
5719
5720 // The last update in the entire queue
5721 var last = queue.last;
5722 // The last update that is part of the base state.
5723 var baseUpdate = hook.baseUpdate;
5724 var baseState = hook.baseState;
5725
5726 // Find the first unprocessed update.
5727 var first = void 0;
5728 if (baseUpdate !== null) {
5729 if (last !== null) {
5730 // For the first update, the queue is a circular linked list where
5731 // `queue.last.next = queue.first`. Once the first update commits, and
5732 // the `baseUpdate` is no longer empty, we can unravel the list.
5733 last.next = null;
5734 }
5735 first = baseUpdate.next;
5736 } else {
5737 first = last !== null ? last.next : null;
5738 }
5739 if (first !== null) {
5740 var _newState = baseState;
5741 var newBaseState = null;
5742 var newBaseUpdate = null;
5743 var prevUpdate = baseUpdate;
5744 var _update = first;
5745 var didSkip = false;
5746 do {
5747 var updateExpirationTime = _update.expirationTime;
5748 if (updateExpirationTime < renderExpirationTime) {
5749 // Priority is insufficient. Skip this update. If this is the first
5750 // skipped update, the previous update/state is the new base
5751 // update/state.
5752 if (!didSkip) {
5753 didSkip = true;
5754 newBaseUpdate = prevUpdate;
5755 newBaseState = _newState;
5756 }
5757 // Update the remaining priority in the queue.
5758 if (updateExpirationTime > remainingExpirationTime) {
5759 remainingExpirationTime = updateExpirationTime;
5760 }
5761 } else {
5762 // Process this update.
5763 if (_update.eagerReducer === reducer) {
5764 // If this update was processed eagerly, and its reducer matches the
5765 // current reducer, we can use the eagerly computed state.
5766 _newState = _update.eagerState;
5767 } else {
5768 var _action2 = _update.action;
5769 _newState = reducer(_newState, _action2);
5770 }
5771 }
5772 prevUpdate = _update;
5773 _update = _update.next;
5774 } while (_update !== null && _update !== first);
5775
5776 if (!didSkip) {
5777 newBaseUpdate = prevUpdate;
5778 newBaseState = _newState;
5779 }
5780
5781 // Mark that the fiber performed work, but only if the new state is
5782 // different from the current state.
5783 if (!is(_newState, hook.memoizedState)) {
5784 markWorkInProgressReceivedUpdate();
5785 }
5786
5787 hook.memoizedState = _newState;
5788 hook.baseUpdate = newBaseUpdate;
5789 hook.baseState = newBaseState;
5790
5791 queue.eagerReducer = reducer;
5792 queue.eagerState = _newState;
5793 }
5794
5795 var dispatch = queue.dispatch;
5796 return [hook.memoizedState, dispatch];
5797}
5798
5799function mountState(initialState) {
5800 var hook = mountWorkInProgressHook();
5801 if (typeof initialState === 'function') {
5802 initialState = initialState();
5803 }
5804 hook.memoizedState = hook.baseState = initialState;
5805 var queue = hook.queue = {
5806 last: null,
5807 dispatch: null,
5808 eagerReducer: basicStateReducer,
5809 eagerState: initialState
5810 };
5811 var dispatch = queue.dispatch = dispatchAction.bind(null,
5812 // Flow doesn't know this is non-null, but we do.
5813 currentlyRenderingFiber$1, queue);
5814 return [hook.memoizedState, dispatch];
5815}
5816
5817function updateState(initialState) {
5818 return updateReducer(basicStateReducer, initialState);
5819}
5820
5821function pushEffect(tag, create, destroy, deps) {
5822 var effect = {
5823 tag: tag,
5824 create: create,
5825 destroy: destroy,
5826 deps: deps,
5827 // Circular
5828 next: null
5829 };
5830 if (componentUpdateQueue === null) {
5831 componentUpdateQueue = createFunctionComponentUpdateQueue();
5832 componentUpdateQueue.lastEffect = effect.next = effect;
5833 } else {
5834 var _lastEffect = componentUpdateQueue.lastEffect;
5835 if (_lastEffect === null) {
5836 componentUpdateQueue.lastEffect = effect.next = effect;
5837 } else {
5838 var firstEffect = _lastEffect.next;
5839 _lastEffect.next = effect;
5840 effect.next = firstEffect;
5841 componentUpdateQueue.lastEffect = effect;
5842 }
5843 }
5844 return effect;
5845}
5846
5847function mountRef(initialValue) {
5848 var hook = mountWorkInProgressHook();
5849 var ref = { current: initialValue };
5850 {
5851 Object.seal(ref);
5852 }
5853 hook.memoizedState = ref;
5854 return ref;
5855}
5856
5857function updateRef(initialValue) {
5858 var hook = updateWorkInProgressHook();
5859 return hook.memoizedState;
5860}
5861
5862function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
5863 var hook = mountWorkInProgressHook();
5864 var nextDeps = deps === undefined ? null : deps;
5865 sideEffectTag |= fiberEffectTag;
5866 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps);
5867}
5868
5869function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
5870 var hook = updateWorkInProgressHook();
5871 var nextDeps = deps === undefined ? null : deps;
5872 var destroy = undefined;
5873
5874 if (currentHook !== null) {
5875 var prevEffect = currentHook.memoizedState;
5876 destroy = prevEffect.destroy;
5877 if (nextDeps !== null) {
5878 var prevDeps = prevEffect.deps;
5879 if (areHookInputsEqual(nextDeps, prevDeps)) {
5880 pushEffect(NoEffect$1, create, destroy, nextDeps);
5881 return;
5882 }
5883 }
5884 }
5885
5886 sideEffectTag |= fiberEffectTag;
5887 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps);
5888}
5889
5890function mountEffect(create, deps) {
5891 return mountEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
5892}
5893
5894function updateEffect(create, deps) {
5895 return updateEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
5896}
5897
5898function mountLayoutEffect(create, deps) {
5899 return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
5900}
5901
5902function updateLayoutEffect(create, deps) {
5903 return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
5904}
5905
5906function imperativeHandleEffect(create, ref) {
5907 if (typeof ref === 'function') {
5908 var refCallback = ref;
5909 var _inst = create();
5910 refCallback(_inst);
5911 return function () {
5912 refCallback(null);
5913 };
5914 } else if (ref !== null && ref !== undefined) {
5915 var refObject = ref;
5916 {
5917 !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;
5918 }
5919 var _inst2 = create();
5920 refObject.current = _inst2;
5921 return function () {
5922 refObject.current = null;
5923 };
5924 }
5925}
5926
5927function mountImperativeHandle(ref, create, deps) {
5928 {
5929 !(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;
5930 }
5931
5932 // TODO: If deps are provided, should we skip comparing the ref itself?
5933 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : [ref];
5934
5935 return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
5936}
5937
5938function updateImperativeHandle(ref, create, deps) {
5939 {
5940 !(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;
5941 }
5942
5943 // TODO: If deps are provided, should we skip comparing the ref itself?
5944 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : [ref];
5945
5946 return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
5947}
5948
5949function mountDebugValue(value, formatterFn) {
5950 // This hook is normally a no-op.
5951 // The react-debug-hooks package injects its own implementation
5952 // so that e.g. DevTools can display custom hook values.
5953}
5954
5955var updateDebugValue = mountDebugValue;
5956
5957function mountCallback(callback, deps) {
5958 var hook = mountWorkInProgressHook();
5959 var nextDeps = deps === undefined ? null : deps;
5960 hook.memoizedState = [callback, nextDeps];
5961 return callback;
5962}
5963
5964function updateCallback(callback, deps) {
5965 var hook = updateWorkInProgressHook();
5966 var nextDeps = deps === undefined ? null : deps;
5967 var prevState = hook.memoizedState;
5968 if (prevState !== null) {
5969 if (nextDeps !== null) {
5970 var prevDeps = prevState[1];
5971 if (areHookInputsEqual(nextDeps, prevDeps)) {
5972 return prevState[0];
5973 }
5974 }
5975 }
5976 hook.memoizedState = [callback, nextDeps];
5977 return callback;
5978}
5979
5980function mountMemo(nextCreate, deps) {
5981 var hook = mountWorkInProgressHook();
5982 var nextDeps = deps === undefined ? null : deps;
5983 var nextValue = nextCreate();
5984 hook.memoizedState = [nextValue, nextDeps];
5985 return nextValue;
5986}
5987
5988function updateMemo(nextCreate, deps) {
5989 var hook = updateWorkInProgressHook();
5990 var nextDeps = deps === undefined ? null : deps;
5991 var prevState = hook.memoizedState;
5992 if (prevState !== null) {
5993 // Assume these are defined. If they're not, areHookInputsEqual will warn.
5994 if (nextDeps !== null) {
5995 var prevDeps = prevState[1];
5996 if (areHookInputsEqual(nextDeps, prevDeps)) {
5997 return prevState[0];
5998 }
5999 }
6000 }
6001 var nextValue = nextCreate();
6002 hook.memoizedState = [nextValue, nextDeps];
6003 return nextValue;
6004}
6005
6006// in a test-like environment, we want to warn if dispatchAction()
6007// is called outside of a batchedUpdates/TestUtils.act(...) call.
6008var shouldWarnForUnbatchedSetState = false;
6009
6010{
6011 // jest isnt' a 'global', it's just exposed to tests via a wrapped function
6012 // further, this isn't a test file, so flow doesn't recognize the symbol. So...
6013 // $FlowExpectedError - because requirements don't give a damn about your type sigs.
6014 if ('undefined' !== typeof jest) {
6015 shouldWarnForUnbatchedSetState = true;
6016 }
6017}
6018
6019function dispatchAction(fiber, queue, action) {
6020 !(numberOfReRenders < RE_RENDER_LIMIT) ? invariant(false, 'Too many re-renders. React limits the number of renders to prevent an infinite loop.') : void 0;
6021
6022 {
6023 !(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;
6024 }
6025
6026 var alternate = fiber.alternate;
6027 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
6028 // This is a render phase update. Stash it in a lazily-created map of
6029 // queue -> linked list of updates. After this render pass, we'll restart
6030 // and apply the stashed updates on top of the work-in-progress hook.
6031 didScheduleRenderPhaseUpdate = true;
6032 var update = {
6033 expirationTime: renderExpirationTime,
6034 action: action,
6035 eagerReducer: null,
6036 eagerState: null,
6037 next: null
6038 };
6039 if (renderPhaseUpdates === null) {
6040 renderPhaseUpdates = new Map();
6041 }
6042 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
6043 if (firstRenderPhaseUpdate === undefined) {
6044 renderPhaseUpdates.set(queue, update);
6045 } else {
6046 // Append the update to the end of the list.
6047 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
6048 while (lastRenderPhaseUpdate.next !== null) {
6049 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
6050 }
6051 lastRenderPhaseUpdate.next = update;
6052 }
6053 } else {
6054 flushPassiveEffects();
6055
6056 var currentTime = requestCurrentTime();
6057 var _expirationTime = computeExpirationForFiber(currentTime, fiber);
6058
6059 var _update2 = {
6060 expirationTime: _expirationTime,
6061 action: action,
6062 eagerReducer: null,
6063 eagerState: null,
6064 next: null
6065 };
6066
6067 // Append the update to the end of the list.
6068 var _last = queue.last;
6069 if (_last === null) {
6070 // This is the first update. Create a circular list.
6071 _update2.next = _update2;
6072 } else {
6073 var first = _last.next;
6074 if (first !== null) {
6075 // Still circular.
6076 _update2.next = first;
6077 }
6078 _last.next = _update2;
6079 }
6080 queue.last = _update2;
6081
6082 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
6083 // The queue is currently empty, which means we can eagerly compute the
6084 // next state before entering the render phase. If the new state is the
6085 // same as the current state, we may be able to bail out entirely.
6086 var _eagerReducer = queue.eagerReducer;
6087 if (_eagerReducer !== null) {
6088 var prevDispatcher = void 0;
6089 {
6090 prevDispatcher = ReactCurrentDispatcher$1.current;
6091 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6092 }
6093 try {
6094 var currentState = queue.eagerState;
6095 var _eagerState = _eagerReducer(currentState, action);
6096 // Stash the eagerly computed state, and the reducer used to compute
6097 // it, on the update object. If the reducer hasn't changed by the
6098 // time we enter the render phase, then the eager state can be used
6099 // without calling the reducer again.
6100 _update2.eagerReducer = _eagerReducer;
6101 _update2.eagerState = _eagerState;
6102 if (is(_eagerState, currentState)) {
6103 // Fast path. We can bail out without scheduling React to re-render.
6104 // It's still possible that we'll need to rebase this update later,
6105 // if the component re-renders for a different reason and by that
6106 // time the reducer has changed.
6107 return;
6108 }
6109 } catch (error) {
6110 // Suppress the error. It will throw again in the render phase.
6111 } finally {
6112 {
6113 ReactCurrentDispatcher$1.current = prevDispatcher;
6114 }
6115 }
6116 }
6117 }
6118 {
6119 if (shouldWarnForUnbatchedSetState === true) {
6120 warnIfNotCurrentlyBatchingInDev(fiber);
6121 }
6122 }
6123 scheduleWork(fiber, _expirationTime);
6124 }
6125}
6126
6127var ContextOnlyDispatcher = {
6128 readContext: readContext,
6129
6130 useCallback: throwInvalidHookError,
6131 useContext: throwInvalidHookError,
6132 useEffect: throwInvalidHookError,
6133 useImperativeHandle: throwInvalidHookError,
6134 useLayoutEffect: throwInvalidHookError,
6135 useMemo: throwInvalidHookError,
6136 useReducer: throwInvalidHookError,
6137 useRef: throwInvalidHookError,
6138 useState: throwInvalidHookError,
6139 useDebugValue: throwInvalidHookError
6140};
6141
6142var HooksDispatcherOnMountInDEV = null;
6143var HooksDispatcherOnUpdateInDEV = null;
6144var InvalidNestedHooksDispatcherOnMountInDEV = null;
6145var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
6146
6147{
6148 var warnInvalidContextAccess = function () {
6149 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().');
6150 };
6151
6152 var warnInvalidHookAccess = function () {
6153 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');
6154 };
6155
6156 HooksDispatcherOnMountInDEV = {
6157 readContext: function (context, observedBits) {
6158 return readContext(context, observedBits);
6159 },
6160 useCallback: function (callback, deps) {
6161 currentHookNameInDev = 'useCallback';
6162 return mountCallback(callback, deps);
6163 },
6164 useContext: function (context, observedBits) {
6165 currentHookNameInDev = 'useContext';
6166 return mountContext(context, observedBits);
6167 },
6168 useEffect: function (create, deps) {
6169 currentHookNameInDev = 'useEffect';
6170 return mountEffect(create, deps);
6171 },
6172 useImperativeHandle: function (ref, create, deps) {
6173 currentHookNameInDev = 'useImperativeHandle';
6174 return mountImperativeHandle(ref, create, deps);
6175 },
6176 useLayoutEffect: function (create, deps) {
6177 currentHookNameInDev = 'useLayoutEffect';
6178 return mountLayoutEffect(create, deps);
6179 },
6180 useMemo: function (create, deps) {
6181 currentHookNameInDev = 'useMemo';
6182 var prevDispatcher = ReactCurrentDispatcher$1.current;
6183 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6184 try {
6185 return mountMemo(create, deps);
6186 } finally {
6187 ReactCurrentDispatcher$1.current = prevDispatcher;
6188 }
6189 },
6190 useReducer: function (reducer, initialArg, init) {
6191 currentHookNameInDev = 'useReducer';
6192 var prevDispatcher = ReactCurrentDispatcher$1.current;
6193 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6194 try {
6195 return mountReducer(reducer, initialArg, init);
6196 } finally {
6197 ReactCurrentDispatcher$1.current = prevDispatcher;
6198 }
6199 },
6200 useRef: function (initialValue) {
6201 currentHookNameInDev = 'useRef';
6202 return mountRef(initialValue);
6203 },
6204 useState: function (initialState) {
6205 currentHookNameInDev = 'useState';
6206 var prevDispatcher = ReactCurrentDispatcher$1.current;
6207 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6208 try {
6209 return mountState(initialState);
6210 } finally {
6211 ReactCurrentDispatcher$1.current = prevDispatcher;
6212 }
6213 },
6214 useDebugValue: function (value, formatterFn) {
6215 currentHookNameInDev = 'useDebugValue';
6216 return mountDebugValue(value, formatterFn);
6217 }
6218 };
6219
6220 HooksDispatcherOnUpdateInDEV = {
6221 readContext: function (context, observedBits) {
6222 return readContext(context, observedBits);
6223 },
6224 useCallback: function (callback, deps) {
6225 currentHookNameInDev = 'useCallback';
6226 return updateCallback(callback, deps);
6227 },
6228 useContext: function (context, observedBits) {
6229 currentHookNameInDev = 'useContext';
6230 return updateContext(context, observedBits);
6231 },
6232 useEffect: function (create, deps) {
6233 currentHookNameInDev = 'useEffect';
6234 return updateEffect(create, deps);
6235 },
6236 useImperativeHandle: function (ref, create, deps) {
6237 currentHookNameInDev = 'useImperativeHandle';
6238 return updateImperativeHandle(ref, create, deps);
6239 },
6240 useLayoutEffect: function (create, deps) {
6241 currentHookNameInDev = 'useLayoutEffect';
6242 return updateLayoutEffect(create, deps);
6243 },
6244 useMemo: function (create, deps) {
6245 currentHookNameInDev = 'useMemo';
6246 var prevDispatcher = ReactCurrentDispatcher$1.current;
6247 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6248 try {
6249 return updateMemo(create, deps);
6250 } finally {
6251 ReactCurrentDispatcher$1.current = prevDispatcher;
6252 }
6253 },
6254 useReducer: function (reducer, initialArg, init) {
6255 currentHookNameInDev = 'useReducer';
6256 var prevDispatcher = ReactCurrentDispatcher$1.current;
6257 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6258 try {
6259 return updateReducer(reducer, initialArg, init);
6260 } finally {
6261 ReactCurrentDispatcher$1.current = prevDispatcher;
6262 }
6263 },
6264 useRef: function (initialValue) {
6265 currentHookNameInDev = 'useRef';
6266 return updateRef(initialValue);
6267 },
6268 useState: function (initialState) {
6269 currentHookNameInDev = 'useState';
6270 var prevDispatcher = ReactCurrentDispatcher$1.current;
6271 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6272 try {
6273 return updateState(initialState);
6274 } finally {
6275 ReactCurrentDispatcher$1.current = prevDispatcher;
6276 }
6277 },
6278 useDebugValue: function (value, formatterFn) {
6279 currentHookNameInDev = 'useDebugValue';
6280 return updateDebugValue(value, formatterFn);
6281 }
6282 };
6283
6284 InvalidNestedHooksDispatcherOnMountInDEV = {
6285 readContext: function (context, observedBits) {
6286 warnInvalidContextAccess();
6287 return readContext(context, observedBits);
6288 },
6289 useCallback: function (callback, deps) {
6290 currentHookNameInDev = 'useCallback';
6291 warnInvalidHookAccess();
6292 return mountCallback(callback, deps);
6293 },
6294 useContext: function (context, observedBits) {
6295 currentHookNameInDev = 'useContext';
6296 warnInvalidHookAccess();
6297 return mountContext(context, observedBits);
6298 },
6299 useEffect: function (create, deps) {
6300 currentHookNameInDev = 'useEffect';
6301 warnInvalidHookAccess();
6302 return mountEffect(create, deps);
6303 },
6304 useImperativeHandle: function (ref, create, deps) {
6305 currentHookNameInDev = 'useImperativeHandle';
6306 warnInvalidHookAccess();
6307 return mountImperativeHandle(ref, create, deps);
6308 },
6309 useLayoutEffect: function (create, deps) {
6310 currentHookNameInDev = 'useLayoutEffect';
6311 warnInvalidHookAccess();
6312 return mountLayoutEffect(create, deps);
6313 },
6314 useMemo: function (create, deps) {
6315 currentHookNameInDev = 'useMemo';
6316 warnInvalidHookAccess();
6317 var prevDispatcher = ReactCurrentDispatcher$1.current;
6318 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6319 try {
6320 return mountMemo(create, deps);
6321 } finally {
6322 ReactCurrentDispatcher$1.current = prevDispatcher;
6323 }
6324 },
6325 useReducer: function (reducer, initialArg, init) {
6326 currentHookNameInDev = 'useReducer';
6327 warnInvalidHookAccess();
6328 var prevDispatcher = ReactCurrentDispatcher$1.current;
6329 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6330 try {
6331 return mountReducer(reducer, initialArg, init);
6332 } finally {
6333 ReactCurrentDispatcher$1.current = prevDispatcher;
6334 }
6335 },
6336 useRef: function (initialValue) {
6337 currentHookNameInDev = 'useRef';
6338 warnInvalidHookAccess();
6339 return mountRef(initialValue);
6340 },
6341 useState: function (initialState) {
6342 currentHookNameInDev = 'useState';
6343 warnInvalidHookAccess();
6344 var prevDispatcher = ReactCurrentDispatcher$1.current;
6345 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6346 try {
6347 return mountState(initialState);
6348 } finally {
6349 ReactCurrentDispatcher$1.current = prevDispatcher;
6350 }
6351 },
6352 useDebugValue: function (value, formatterFn) {
6353 currentHookNameInDev = 'useDebugValue';
6354 warnInvalidHookAccess();
6355 return mountDebugValue(value, formatterFn);
6356 }
6357 };
6358
6359 InvalidNestedHooksDispatcherOnUpdateInDEV = {
6360 readContext: function (context, observedBits) {
6361 warnInvalidContextAccess();
6362 return readContext(context, observedBits);
6363 },
6364 useCallback: function (callback, deps) {
6365 currentHookNameInDev = 'useCallback';
6366 warnInvalidHookAccess();
6367 return updateCallback(callback, deps);
6368 },
6369 useContext: function (context, observedBits) {
6370 currentHookNameInDev = 'useContext';
6371 warnInvalidHookAccess();
6372 return updateContext(context, observedBits);
6373 },
6374 useEffect: function (create, deps) {
6375 currentHookNameInDev = 'useEffect';
6376 warnInvalidHookAccess();
6377 return updateEffect(create, deps);
6378 },
6379 useImperativeHandle: function (ref, create, deps) {
6380 currentHookNameInDev = 'useImperativeHandle';
6381 warnInvalidHookAccess();
6382 return updateImperativeHandle(ref, create, deps);
6383 },
6384 useLayoutEffect: function (create, deps) {
6385 currentHookNameInDev = 'useLayoutEffect';
6386 warnInvalidHookAccess();
6387 return updateLayoutEffect(create, deps);
6388 },
6389 useMemo: function (create, deps) {
6390 currentHookNameInDev = 'useMemo';
6391 warnInvalidHookAccess();
6392 var prevDispatcher = ReactCurrentDispatcher$1.current;
6393 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6394 try {
6395 return updateMemo(create, deps);
6396 } finally {
6397 ReactCurrentDispatcher$1.current = prevDispatcher;
6398 }
6399 },
6400 useReducer: function (reducer, initialArg, init) {
6401 currentHookNameInDev = 'useReducer';
6402 warnInvalidHookAccess();
6403 var prevDispatcher = ReactCurrentDispatcher$1.current;
6404 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6405 try {
6406 return updateReducer(reducer, initialArg, init);
6407 } finally {
6408 ReactCurrentDispatcher$1.current = prevDispatcher;
6409 }
6410 },
6411 useRef: function (initialValue) {
6412 currentHookNameInDev = 'useRef';
6413 warnInvalidHookAccess();
6414 return updateRef(initialValue);
6415 },
6416 useState: function (initialState) {
6417 currentHookNameInDev = 'useState';
6418 warnInvalidHookAccess();
6419 var prevDispatcher = ReactCurrentDispatcher$1.current;
6420 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6421 try {
6422 return updateState(initialState);
6423 } finally {
6424 ReactCurrentDispatcher$1.current = prevDispatcher;
6425 }
6426 },
6427 useDebugValue: function (value, formatterFn) {
6428 currentHookNameInDev = 'useDebugValue';
6429 warnInvalidHookAccess();
6430 return updateDebugValue(value, formatterFn);
6431 }
6432 };
6433}
6434
6435var commitTime = 0;
6436var profilerStartTime = -1;
6437
6438function getCommitTime() {
6439 return commitTime;
6440}
6441
6442function recordCommitTime() {
6443 if (!enableProfilerTimer) {
6444 return;
6445 }
6446 commitTime = unstable_now();
6447}
6448
6449function startProfilerTimer(fiber) {
6450 if (!enableProfilerTimer) {
6451 return;
6452 }
6453
6454 profilerStartTime = unstable_now();
6455
6456 if (fiber.actualStartTime < 0) {
6457 fiber.actualStartTime = unstable_now();
6458 }
6459}
6460
6461function stopProfilerTimerIfRunning(fiber) {
6462 if (!enableProfilerTimer) {
6463 return;
6464 }
6465 profilerStartTime = -1;
6466}
6467
6468function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
6469 if (!enableProfilerTimer) {
6470 return;
6471 }
6472
6473 if (profilerStartTime >= 0) {
6474 var elapsedTime = unstable_now() - profilerStartTime;
6475 fiber.actualDuration += elapsedTime;
6476 if (overrideBaseTime) {
6477 fiber.selfBaseDuration = elapsedTime;
6478 }
6479 profilerStartTime = -1;
6480 }
6481}
6482
6483// The deepest Fiber on the stack involved in a hydration context.
6484// This may have been an insertion or a hydration.
6485var hydrationParentFiber = null;
6486var nextHydratableInstance = null;
6487var isHydrating = false;
6488
6489function enterHydrationState(fiber) {
6490 if (!supportsHydration) {
6491 return false;
6492 }
6493
6494 var parentInstance = fiber.stateNode.containerInfo;
6495 nextHydratableInstance = getFirstHydratableChild(parentInstance);
6496 hydrationParentFiber = fiber;
6497 isHydrating = true;
6498 return true;
6499}
6500
6501function deleteHydratableInstance(returnFiber, instance) {
6502 {
6503 switch (returnFiber.tag) {
6504 case HostRoot:
6505 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
6506 break;
6507 case HostComponent:
6508 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
6509 break;
6510 }
6511 }
6512
6513 var childToDelete = createFiberFromHostInstanceForDeletion();
6514 childToDelete.stateNode = instance;
6515 childToDelete.return = returnFiber;
6516 childToDelete.effectTag = Deletion;
6517
6518 // This might seem like it belongs on progressedFirstDeletion. However,
6519 // these children are not part of the reconciliation list of children.
6520 // Even if we abort and rereconcile the children, that will try to hydrate
6521 // again and the nodes are still in the host tree so these will be
6522 // recreated.
6523 if (returnFiber.lastEffect !== null) {
6524 returnFiber.lastEffect.nextEffect = childToDelete;
6525 returnFiber.lastEffect = childToDelete;
6526 } else {
6527 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
6528 }
6529}
6530
6531function insertNonHydratedInstance(returnFiber, fiber) {
6532 fiber.effectTag |= Placement;
6533 {
6534 switch (returnFiber.tag) {
6535 case HostRoot:
6536 {
6537 var parentContainer = returnFiber.stateNode.containerInfo;
6538 switch (fiber.tag) {
6539 case HostComponent:
6540 var type = fiber.type;
6541 var props = fiber.pendingProps;
6542 didNotFindHydratableContainerInstance(parentContainer, type, props);
6543 break;
6544 case HostText:
6545 var text = fiber.pendingProps;
6546 didNotFindHydratableContainerTextInstance(parentContainer, text);
6547 break;
6548 }
6549 break;
6550 }
6551 case HostComponent:
6552 {
6553 var parentType = returnFiber.type;
6554 var parentProps = returnFiber.memoizedProps;
6555 var parentInstance = returnFiber.stateNode;
6556 switch (fiber.tag) {
6557 case HostComponent:
6558 var _type = fiber.type;
6559 var _props = fiber.pendingProps;
6560 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
6561 break;
6562 case HostText:
6563 var _text = fiber.pendingProps;
6564 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
6565 break;
6566 }
6567 break;
6568 }
6569 default:
6570 return;
6571 }
6572 }
6573}
6574
6575function tryHydrate(fiber, nextInstance) {
6576 switch (fiber.tag) {
6577 case HostComponent:
6578 {
6579 var type = fiber.type;
6580 var props = fiber.pendingProps;
6581 var instance = canHydrateInstance(nextInstance, type, props);
6582 if (instance !== null) {
6583 fiber.stateNode = instance;
6584 return true;
6585 }
6586 return false;
6587 }
6588 case HostText:
6589 {
6590 var text = fiber.pendingProps;
6591 var textInstance = canHydrateTextInstance(nextInstance, text);
6592 if (textInstance !== null) {
6593 fiber.stateNode = textInstance;
6594 return true;
6595 }
6596 return false;
6597 }
6598 default:
6599 return false;
6600 }
6601}
6602
6603function tryToClaimNextHydratableInstance(fiber) {
6604 if (!isHydrating) {
6605 return;
6606 }
6607 var nextInstance = nextHydratableInstance;
6608 if (!nextInstance) {
6609 // Nothing to hydrate. Make it an insertion.
6610 insertNonHydratedInstance(hydrationParentFiber, fiber);
6611 isHydrating = false;
6612 hydrationParentFiber = fiber;
6613 return;
6614 }
6615 var firstAttemptedInstance = nextInstance;
6616 if (!tryHydrate(fiber, nextInstance)) {
6617 // If we can't hydrate this instance let's try the next one.
6618 // We use this as a heuristic. It's based on intuition and not data so it
6619 // might be flawed or unnecessary.
6620 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
6621 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
6622 // Nothing to hydrate. Make it an insertion.
6623 insertNonHydratedInstance(hydrationParentFiber, fiber);
6624 isHydrating = false;
6625 hydrationParentFiber = fiber;
6626 return;
6627 }
6628 // We matched the next one, we'll now assume that the first one was
6629 // superfluous and we'll delete it. Since we can't eagerly delete it
6630 // we'll have to schedule a deletion. To do that, this node needs a dummy
6631 // fiber associated with it.
6632 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
6633 }
6634 hydrationParentFiber = fiber;
6635 nextHydratableInstance = getFirstHydratableChild(nextInstance);
6636}
6637
6638function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
6639 if (!supportsHydration) {
6640 invariant(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
6641 }
6642
6643 var instance = fiber.stateNode;
6644 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
6645 // TODO: Type this specific to this type of component.
6646 fiber.updateQueue = updatePayload;
6647 // If the update payload indicates that there is a change or if there
6648 // is a new ref we mark this as an update.
6649 if (updatePayload !== null) {
6650 return true;
6651 }
6652 return false;
6653}
6654
6655function prepareToHydrateHostTextInstance(fiber) {
6656 if (!supportsHydration) {
6657 invariant(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
6658 }
6659
6660 var textInstance = fiber.stateNode;
6661 var textContent = fiber.memoizedProps;
6662 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
6663 {
6664 if (shouldUpdate) {
6665 // We assume that prepareToHydrateHostTextInstance is called in a context where the
6666 // hydration parent is the parent host component of this host text.
6667 var returnFiber = hydrationParentFiber;
6668 if (returnFiber !== null) {
6669 switch (returnFiber.tag) {
6670 case HostRoot:
6671 {
6672 var parentContainer = returnFiber.stateNode.containerInfo;
6673 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
6674 break;
6675 }
6676 case HostComponent:
6677 {
6678 var parentType = returnFiber.type;
6679 var parentProps = returnFiber.memoizedProps;
6680 var parentInstance = returnFiber.stateNode;
6681 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
6682 break;
6683 }
6684 }
6685 }
6686 }
6687 }
6688 return shouldUpdate;
6689}
6690
6691function popToNextHostParent(fiber) {
6692 var parent = fiber.return;
6693 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot) {
6694 parent = parent.return;
6695 }
6696 hydrationParentFiber = parent;
6697}
6698
6699function popHydrationState(fiber) {
6700 if (!supportsHydration) {
6701 return false;
6702 }
6703 if (fiber !== hydrationParentFiber) {
6704 // We're deeper than the current hydration context, inside an inserted
6705 // tree.
6706 return false;
6707 }
6708 if (!isHydrating) {
6709 // If we're not currently hydrating but we're in a hydration context, then
6710 // we were an insertion and now need to pop up reenter hydration of our
6711 // siblings.
6712 popToNextHostParent(fiber);
6713 isHydrating = true;
6714 return false;
6715 }
6716
6717 var type = fiber.type;
6718
6719 // If we have any remaining hydratable nodes, we need to delete them now.
6720 // We only do this deeper than head and body since they tend to have random
6721 // other nodes in them. We also ignore components with pure text content in
6722 // side of them.
6723 // TODO: Better heuristic.
6724 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
6725 var nextInstance = nextHydratableInstance;
6726 while (nextInstance) {
6727 deleteHydratableInstance(fiber, nextInstance);
6728 nextInstance = getNextHydratableSibling(nextInstance);
6729 }
6730 }
6731
6732 popToNextHostParent(fiber);
6733 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
6734 return true;
6735}
6736
6737function resetHydrationState() {
6738 if (!supportsHydration) {
6739 return;
6740 }
6741
6742 hydrationParentFiber = null;
6743 nextHydratableInstance = null;
6744 isHydrating = false;
6745}
6746
6747var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
6748
6749var didReceiveUpdate = false;
6750
6751var didWarnAboutBadClass = void 0;
6752var didWarnAboutContextTypeOnFunctionComponent = void 0;
6753var didWarnAboutGetDerivedStateOnFunctionComponent = void 0;
6754var didWarnAboutFunctionRefs = void 0;
6755var didWarnAboutReassigningProps = void 0;
6756
6757{
6758 didWarnAboutBadClass = {};
6759 didWarnAboutContextTypeOnFunctionComponent = {};
6760 didWarnAboutGetDerivedStateOnFunctionComponent = {};
6761 didWarnAboutFunctionRefs = {};
6762 didWarnAboutReassigningProps = false;
6763}
6764
6765function reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime) {
6766 if (current === null) {
6767 // If this is a fresh new component that hasn't been rendered yet, we
6768 // won't update its child set by applying minimal side-effects. Instead,
6769 // we will add them all to the child before it gets rendered. That means
6770 // we can optimize this reconciliation pass by not tracking side-effects.
6771 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
6772 } else {
6773 // If the current child is the same as the work in progress, it means that
6774 // we haven't yet started any work on these children. Therefore, we use
6775 // the clone algorithm to create a copy of all the current children.
6776
6777 // If we had any progressed work already, that is invalid at this point so
6778 // let's throw it out.
6779 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
6780 }
6781}
6782
6783function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime) {
6784 // This function is fork of reconcileChildren. It's used in cases where we
6785 // want to reconcile without matching against the existing set. This has the
6786 // effect of all current children being unmounted; even if the type and key
6787 // are the same, the old child is unmounted and a new child is created.
6788 //
6789 // To do this, we're going to go through the reconcile algorithm twice. In
6790 // the first pass, we schedule a deletion for all the current children by
6791 // passing null.
6792 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderExpirationTime);
6793 // In the second pass, we mount the new children. The trick here is that we
6794 // pass null in place of where we usually pass the current child set. This has
6795 // the effect of remounting all children regardless of whether their their
6796 // identity matches.
6797 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
6798}
6799
6800function updateForwardRef(current, workInProgress, Component, nextProps, renderExpirationTime) {
6801 {
6802 if (workInProgress.type !== workInProgress.elementType) {
6803 // Lazy component props can't be validated in createElement
6804 // because they're only guaranteed to be resolved here.
6805 var innerPropTypes = Component.propTypes;
6806 if (innerPropTypes) {
6807 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
6808 'prop', getComponentName(Component), getCurrentFiberStackInDev);
6809 }
6810 }
6811 }
6812
6813 var render = Component.render;
6814 var ref = workInProgress.ref;
6815
6816 // The rest is a fork of updateFunctionComponent
6817 var nextChildren = void 0;
6818 prepareToReadContext(workInProgress, renderExpirationTime);
6819 {
6820 ReactCurrentOwner$2.current = workInProgress;
6821 setCurrentPhase('render');
6822 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
6823 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
6824 // Only double-render components with Hooks
6825 if (workInProgress.memoizedState !== null) {
6826 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
6827 }
6828 }
6829 setCurrentPhase(null);
6830 }
6831
6832 if (current !== null && !didReceiveUpdate) {
6833 bailoutHooks(current, workInProgress, renderExpirationTime);
6834 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
6835 }
6836
6837 // React DevTools reads this flag.
6838 workInProgress.effectTag |= PerformedWork;
6839 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
6840 return workInProgress.child;
6841}
6842
6843function updateMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
6844 if (current === null) {
6845 var type = Component.type;
6846 if (isSimpleFunctionComponent(type) && Component.compare === null &&
6847 // SimpleMemoComponent codepath doesn't resolve outer props either.
6848 Component.defaultProps === undefined) {
6849 // If this is a plain function component without default props,
6850 // and with only the default shallow comparison, we upgrade it
6851 // to a SimpleMemoComponent to allow fast path updates.
6852 workInProgress.tag = SimpleMemoComponent;
6853 workInProgress.type = type;
6854 {
6855 validateFunctionComponentInDev(workInProgress, type);
6856 }
6857 return updateSimpleMemoComponent(current, workInProgress, type, nextProps, updateExpirationTime, renderExpirationTime);
6858 }
6859 {
6860 var innerPropTypes = type.propTypes;
6861 if (innerPropTypes) {
6862 // Inner memo component props aren't currently validated in createElement.
6863 // We could move it there, but we'd still need this for lazy code path.
6864 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
6865 'prop', getComponentName(type), getCurrentFiberStackInDev);
6866 }
6867 }
6868 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
6869 child.ref = workInProgress.ref;
6870 child.return = workInProgress;
6871 workInProgress.child = child;
6872 return child;
6873 }
6874 {
6875 var _type = Component.type;
6876 var _innerPropTypes = _type.propTypes;
6877 if (_innerPropTypes) {
6878 // Inner memo component props aren't currently validated in createElement.
6879 // We could move it there, but we'd still need this for lazy code path.
6880 checkPropTypes_1(_innerPropTypes, nextProps, // Resolved props
6881 'prop', getComponentName(_type), getCurrentFiberStackInDev);
6882 }
6883 }
6884 var currentChild = current.child; // This is always exactly one child
6885 if (updateExpirationTime < renderExpirationTime) {
6886 // This will be the props with resolved defaultProps,
6887 // unlike current.memoizedProps which will be the unresolved ones.
6888 var prevProps = currentChild.memoizedProps;
6889 // Default to shallow comparison
6890 var compare = Component.compare;
6891 compare = compare !== null ? compare : shallowEqual;
6892 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
6893 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
6894 }
6895 }
6896 // React DevTools reads this flag.
6897 workInProgress.effectTag |= PerformedWork;
6898 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime);
6899 newChild.ref = workInProgress.ref;
6900 newChild.return = workInProgress;
6901 workInProgress.child = newChild;
6902 return newChild;
6903}
6904
6905function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
6906 {
6907 if (workInProgress.type !== workInProgress.elementType) {
6908 // Lazy component props can't be validated in createElement
6909 // because they're only guaranteed to be resolved here.
6910 var outerMemoType = workInProgress.elementType;
6911 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
6912 // We warn when you define propTypes on lazy()
6913 // so let's just skip over it to find memo() outer wrapper.
6914 // Inner props for memo are validated later.
6915 outerMemoType = refineResolvedLazyComponent(outerMemoType);
6916 }
6917 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
6918 if (outerPropTypes) {
6919 checkPropTypes_1(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
6920 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
6921 }
6922 // Inner propTypes will be validated in the function component path.
6923 }
6924 }
6925 if (current !== null) {
6926 var prevProps = current.memoizedProps;
6927 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref) {
6928 didReceiveUpdate = false;
6929 if (updateExpirationTime < renderExpirationTime) {
6930 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
6931 }
6932 }
6933 }
6934 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime);
6935}
6936
6937function updateFragment(current, workInProgress, renderExpirationTime) {
6938 var nextChildren = workInProgress.pendingProps;
6939 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
6940 return workInProgress.child;
6941}
6942
6943function updateMode(current, workInProgress, renderExpirationTime) {
6944 var nextChildren = workInProgress.pendingProps.children;
6945 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
6946 return workInProgress.child;
6947}
6948
6949function updateProfiler(current, workInProgress, renderExpirationTime) {
6950 if (enableProfilerTimer) {
6951 workInProgress.effectTag |= Update;
6952 }
6953 var nextProps = workInProgress.pendingProps;
6954 var nextChildren = nextProps.children;
6955 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
6956 return workInProgress.child;
6957}
6958
6959function markRef(current, workInProgress) {
6960 var ref = workInProgress.ref;
6961 if (current === null && ref !== null || current !== null && current.ref !== ref) {
6962 // Schedule a Ref effect
6963 workInProgress.effectTag |= Ref;
6964 }
6965}
6966
6967function updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
6968 {
6969 if (workInProgress.type !== workInProgress.elementType) {
6970 // Lazy component props can't be validated in createElement
6971 // because they're only guaranteed to be resolved here.
6972 var innerPropTypes = Component.propTypes;
6973 if (innerPropTypes) {
6974 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
6975 'prop', getComponentName(Component), getCurrentFiberStackInDev);
6976 }
6977 }
6978 }
6979
6980 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
6981 var context = getMaskedContext(workInProgress, unmaskedContext);
6982
6983 var nextChildren = void 0;
6984 prepareToReadContext(workInProgress, renderExpirationTime);
6985 {
6986 ReactCurrentOwner$2.current = workInProgress;
6987 setCurrentPhase('render');
6988 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
6989 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
6990 // Only double-render components with Hooks
6991 if (workInProgress.memoizedState !== null) {
6992 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
6993 }
6994 }
6995 setCurrentPhase(null);
6996 }
6997
6998 if (current !== null && !didReceiveUpdate) {
6999 bailoutHooks(current, workInProgress, renderExpirationTime);
7000 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7001 }
7002
7003 // React DevTools reads this flag.
7004 workInProgress.effectTag |= PerformedWork;
7005 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7006 return workInProgress.child;
7007}
7008
7009function updateClassComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
7010 {
7011 if (workInProgress.type !== workInProgress.elementType) {
7012 // Lazy component props can't be validated in createElement
7013 // because they're only guaranteed to be resolved here.
7014 var innerPropTypes = Component.propTypes;
7015 if (innerPropTypes) {
7016 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
7017 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7018 }
7019 }
7020 }
7021
7022 // Push context providers early to prevent context stack mismatches.
7023 // During mounting we don't know the child context yet as the instance doesn't exist.
7024 // We will invalidate the child context in finishClassComponent() right after rendering.
7025 var hasContext = void 0;
7026 if (isContextProvider(Component)) {
7027 hasContext = true;
7028 pushContextProvider(workInProgress);
7029 } else {
7030 hasContext = false;
7031 }
7032 prepareToReadContext(workInProgress, renderExpirationTime);
7033
7034 var instance = workInProgress.stateNode;
7035 var shouldUpdate = void 0;
7036 if (instance === null) {
7037 if (current !== null) {
7038 // An class component without an instance only mounts if it suspended
7039 // inside a non- concurrent tree, in an inconsistent state. We want to
7040 // tree it like a new mount, even though an empty version of it already
7041 // committed. Disconnect the alternate pointers.
7042 current.alternate = null;
7043 workInProgress.alternate = null;
7044 // Since this is conceptually a new fiber, schedule a Placement effect
7045 workInProgress.effectTag |= Placement;
7046 }
7047 // In the initial pass we might need to construct the instance.
7048 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7049 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7050 shouldUpdate = true;
7051 } else if (current === null) {
7052 // In a resume, we'll already have an instance we can reuse.
7053 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7054 } else {
7055 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderExpirationTime);
7056 }
7057 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
7058 {
7059 var inst = workInProgress.stateNode;
7060 if (inst.props !== nextProps) {
7061 !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;
7062 didWarnAboutReassigningProps = true;
7063 }
7064 }
7065 return nextUnitOfWork;
7066}
7067
7068function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
7069 // Refs should update even if shouldComponentUpdate returns false
7070 markRef(current, workInProgress);
7071
7072 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
7073
7074 if (!shouldUpdate && !didCaptureError) {
7075 // Context providers should defer to sCU for rendering
7076 if (hasContext) {
7077 invalidateContextProvider(workInProgress, Component, false);
7078 }
7079
7080 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7081 }
7082
7083 var instance = workInProgress.stateNode;
7084
7085 // Rerender
7086 ReactCurrentOwner$2.current = workInProgress;
7087 var nextChildren = void 0;
7088 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
7089 // If we captured an error, but getDerivedStateFrom catch is not defined,
7090 // unmount all the children. componentDidCatch will schedule an update to
7091 // re-render a fallback. This is temporary until we migrate everyone to
7092 // the new API.
7093 // TODO: Warn in a future release.
7094 nextChildren = null;
7095
7096 if (enableProfilerTimer) {
7097 stopProfilerTimerIfRunning(workInProgress);
7098 }
7099 } else {
7100 {
7101 setCurrentPhase('render');
7102 nextChildren = instance.render();
7103 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7104 instance.render();
7105 }
7106 setCurrentPhase(null);
7107 }
7108 }
7109
7110 // React DevTools reads this flag.
7111 workInProgress.effectTag |= PerformedWork;
7112 if (current !== null && didCaptureError) {
7113 // If we're recovering from an error, reconcile without reusing any of
7114 // the existing children. Conceptually, the normal children and the children
7115 // that are shown on error are two different sets, so we shouldn't reuse
7116 // normal children even if their identities match.
7117 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime);
7118 } else {
7119 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7120 }
7121
7122 // Memoize state using the values we just used to render.
7123 // TODO: Restructure so we never read values from the instance.
7124 workInProgress.memoizedState = instance.state;
7125
7126 // The context might have changed so we need to recalculate it.
7127 if (hasContext) {
7128 invalidateContextProvider(workInProgress, Component, true);
7129 }
7130
7131 return workInProgress.child;
7132}
7133
7134function pushHostRootContext(workInProgress) {
7135 var root = workInProgress.stateNode;
7136 if (root.pendingContext) {
7137 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
7138 } else if (root.context) {
7139 // Should always be set
7140 pushTopLevelContextObject(workInProgress, root.context, false);
7141 }
7142 pushHostContainer(workInProgress, root.containerInfo);
7143}
7144
7145function updateHostRoot(current, workInProgress, renderExpirationTime) {
7146 pushHostRootContext(workInProgress);
7147 var updateQueue = workInProgress.updateQueue;
7148 !(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;
7149 var nextProps = workInProgress.pendingProps;
7150 var prevState = workInProgress.memoizedState;
7151 var prevChildren = prevState !== null ? prevState.element : null;
7152 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime);
7153 var nextState = workInProgress.memoizedState;
7154 // Caution: React DevTools currently depends on this property
7155 // being called "element".
7156 var nextChildren = nextState.element;
7157 if (nextChildren === prevChildren) {
7158 // If the state is the same as before, that's a bailout because we had
7159 // no work that expires at this time.
7160 resetHydrationState();
7161 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7162 }
7163 var root = workInProgress.stateNode;
7164 if ((current === null || current.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
7165 // If we don't have any current children this might be the first pass.
7166 // We always try to hydrate. If this isn't a hydration pass there won't
7167 // be any children to hydrate which is effectively the same thing as
7168 // not hydrating.
7169
7170 // This is a bit of a hack. We track the host root as a placement to
7171 // know that we're currently in a mounting state. That way isMounted
7172 // works as expected. We must reset this before committing.
7173 // TODO: Delete this when we delete isMounted and findDOMNode.
7174 workInProgress.effectTag |= Placement;
7175
7176 // Ensure that children mount into this root without tracking
7177 // side-effects. This ensures that we don't store Placement effects on
7178 // nodes that will be hydrated.
7179 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7180 } else {
7181 // Otherwise reset hydration state in case we aborted and resumed another
7182 // root.
7183 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7184 resetHydrationState();
7185 }
7186 return workInProgress.child;
7187}
7188
7189function updateHostComponent(current, workInProgress, renderExpirationTime) {
7190 pushHostContext(workInProgress);
7191
7192 if (current === null) {
7193 tryToClaimNextHydratableInstance(workInProgress);
7194 }
7195
7196 var type = workInProgress.type;
7197 var nextProps = workInProgress.pendingProps;
7198 var prevProps = current !== null ? current.memoizedProps : null;
7199
7200 var nextChildren = nextProps.children;
7201 var isDirectTextChild = shouldSetTextContent(type, nextProps);
7202
7203 if (isDirectTextChild) {
7204 // We special case a direct text child of a host node. This is a common
7205 // case. We won't handle it as a reified child. We will instead handle
7206 // this in the host environment that also have access to this prop. That
7207 // avoids allocating another HostText fiber and traversing it.
7208 nextChildren = null;
7209 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
7210 // If we're switching from a direct text child to a normal child, or to
7211 // empty, we need to schedule the text content to be reset.
7212 workInProgress.effectTag |= ContentReset;
7213 }
7214
7215 markRef(current, workInProgress);
7216
7217 // Check the host config to see if the children are offscreen/hidden.
7218 if (renderExpirationTime !== Never && workInProgress.mode & ConcurrentMode && shouldDeprioritizeSubtree(type, nextProps)) {
7219 // Schedule this fiber to re-render at offscreen priority. Then bailout.
7220 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
7221 return null;
7222 }
7223
7224 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7225 return workInProgress.child;
7226}
7227
7228function updateHostText(current, workInProgress) {
7229 if (current === null) {
7230 tryToClaimNextHydratableInstance(workInProgress);
7231 }
7232 // Nothing to do here. This is terminal. We'll do the completion step
7233 // immediately after.
7234 return null;
7235}
7236
7237function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
7238 if (_current !== null) {
7239 // An lazy component only mounts if it suspended inside a non-
7240 // concurrent tree, in an inconsistent state. We want to treat it like
7241 // a new mount, even though an empty version of it already committed.
7242 // Disconnect the alternate pointers.
7243 _current.alternate = null;
7244 workInProgress.alternate = null;
7245 // Since this is conceptually a new fiber, schedule a Placement effect
7246 workInProgress.effectTag |= Placement;
7247 }
7248
7249 var props = workInProgress.pendingProps;
7250 // We can't start a User Timing measurement with correct label yet.
7251 // Cancel and resume right after we know the tag.
7252 cancelWorkTimer(workInProgress);
7253 var Component = readLazyComponentType(elementType);
7254 // Store the unwrapped component in the type.
7255 workInProgress.type = Component;
7256 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
7257 startWorkTimer(workInProgress);
7258 var resolvedProps = resolveDefaultProps(Component, props);
7259 var child = void 0;
7260 switch (resolvedTag) {
7261 case FunctionComponent:
7262 {
7263 {
7264 validateFunctionComponentInDev(workInProgress, Component);
7265 }
7266 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7267 break;
7268 }
7269 case ClassComponent:
7270 {
7271 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7272 break;
7273 }
7274 case ForwardRef:
7275 {
7276 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7277 break;
7278 }
7279 case MemoComponent:
7280 {
7281 {
7282 if (workInProgress.type !== workInProgress.elementType) {
7283 var outerPropTypes = Component.propTypes;
7284 if (outerPropTypes) {
7285 checkPropTypes_1(outerPropTypes, resolvedProps, // Resolved for outer only
7286 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7287 }
7288 }
7289 }
7290 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
7291 updateExpirationTime, renderExpirationTime);
7292 break;
7293 }
7294 default:
7295 {
7296 var hint = '';
7297 {
7298 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
7299 hint = ' Did you wrap a component in React.lazy() more than once?';
7300 }
7301 }
7302 // This message intentionally doesn't mention ForwardRef or MemoComponent
7303 // because the fact that it's a separate type of work is an
7304 // implementation detail.
7305 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);
7306 }
7307 }
7308 return child;
7309}
7310
7311function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
7312 if (_current !== null) {
7313 // An incomplete component only mounts if it suspended inside a non-
7314 // concurrent tree, in an inconsistent state. We want to treat it like
7315 // a new mount, even though an empty version of it already committed.
7316 // Disconnect the alternate pointers.
7317 _current.alternate = null;
7318 workInProgress.alternate = null;
7319 // Since this is conceptually a new fiber, schedule a Placement effect
7320 workInProgress.effectTag |= Placement;
7321 }
7322
7323 // Promote the fiber to a class and try rendering again.
7324 workInProgress.tag = ClassComponent;
7325
7326 // The rest of this function is a fork of `updateClassComponent`
7327
7328 // Push context providers early to prevent context stack mismatches.
7329 // During mounting we don't know the child context yet as the instance doesn't exist.
7330 // We will invalidate the child context in finishClassComponent() right after rendering.
7331 var hasContext = void 0;
7332 if (isContextProvider(Component)) {
7333 hasContext = true;
7334 pushContextProvider(workInProgress);
7335 } else {
7336 hasContext = false;
7337 }
7338 prepareToReadContext(workInProgress, renderExpirationTime);
7339
7340 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7341 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7342
7343 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
7344}
7345
7346function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
7347 if (_current !== null) {
7348 // An indeterminate component only mounts if it suspended inside a non-
7349 // concurrent tree, in an inconsistent state. We want to treat it like
7350 // a new mount, even though an empty version of it already committed.
7351 // Disconnect the alternate pointers.
7352 _current.alternate = null;
7353 workInProgress.alternate = null;
7354 // Since this is conceptually a new fiber, schedule a Placement effect
7355 workInProgress.effectTag |= Placement;
7356 }
7357
7358 var props = workInProgress.pendingProps;
7359 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
7360 var context = getMaskedContext(workInProgress, unmaskedContext);
7361
7362 prepareToReadContext(workInProgress, renderExpirationTime);
7363
7364 var value = void 0;
7365
7366 {
7367 if (Component.prototype && typeof Component.prototype.render === 'function') {
7368 var componentName = getComponentName(Component) || 'Unknown';
7369
7370 if (!didWarnAboutBadClass[componentName]) {
7371 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);
7372 didWarnAboutBadClass[componentName] = true;
7373 }
7374 }
7375
7376 if (workInProgress.mode & StrictMode) {
7377 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
7378 }
7379
7380 ReactCurrentOwner$2.current = workInProgress;
7381 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
7382 }
7383 // React DevTools reads this flag.
7384 workInProgress.effectTag |= PerformedWork;
7385
7386 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
7387 // Proceed under the assumption that this is a class instance
7388 workInProgress.tag = ClassComponent;
7389
7390 // Throw out any hooks that were used.
7391 resetHooks();
7392
7393 // Push context providers early to prevent context stack mismatches.
7394 // During mounting we don't know the child context yet as the instance doesn't exist.
7395 // We will invalidate the child context in finishClassComponent() right after rendering.
7396 var hasContext = false;
7397 if (isContextProvider(Component)) {
7398 hasContext = true;
7399 pushContextProvider(workInProgress);
7400 } else {
7401 hasContext = false;
7402 }
7403
7404 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
7405
7406 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
7407 if (typeof getDerivedStateFromProps === 'function') {
7408 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
7409 }
7410
7411 adoptClassInstance(workInProgress, value);
7412 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
7413 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
7414 } else {
7415 // Proceed under the assumption that this is a function component
7416 workInProgress.tag = FunctionComponent;
7417 {
7418 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7419 // Only double-render components with Hooks
7420 if (workInProgress.memoizedState !== null) {
7421 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
7422 }
7423 }
7424 }
7425 reconcileChildren(null, workInProgress, value, renderExpirationTime);
7426 {
7427 validateFunctionComponentInDev(workInProgress, Component);
7428 }
7429 return workInProgress.child;
7430 }
7431}
7432
7433function validateFunctionComponentInDev(workInProgress, Component) {
7434 if (Component) {
7435 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0;
7436 }
7437 if (workInProgress.ref !== null) {
7438 var info = '';
7439 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
7440 if (ownerName) {
7441 info += '\n\nCheck the render method of `' + ownerName + '`.';
7442 }
7443
7444 var warningKey = ownerName || workInProgress._debugID || '';
7445 var debugSource = workInProgress._debugSource;
7446 if (debugSource) {
7447 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
7448 }
7449 if (!didWarnAboutFunctionRefs[warningKey]) {
7450 didWarnAboutFunctionRefs[warningKey] = true;
7451 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);
7452 }
7453 }
7454
7455 if (typeof Component.getDerivedStateFromProps === 'function') {
7456 var componentName = getComponentName(Component) || 'Unknown';
7457
7458 if (!didWarnAboutGetDerivedStateOnFunctionComponent[componentName]) {
7459 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', componentName);
7460 didWarnAboutGetDerivedStateOnFunctionComponent[componentName] = true;
7461 }
7462 }
7463
7464 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
7465 var _componentName = getComponentName(Component) || 'Unknown';
7466
7467 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName]) {
7468 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName);
7469 didWarnAboutContextTypeOnFunctionComponent[_componentName] = true;
7470 }
7471 }
7472}
7473
7474function updateSuspenseComponent(current, workInProgress, renderExpirationTime) {
7475 var mode = workInProgress.mode;
7476 var nextProps = workInProgress.pendingProps;
7477
7478 // We should attempt to render the primary children unless this boundary
7479 // already suspended during this render (`alreadyCaptured` is true).
7480 var nextState = workInProgress.memoizedState;
7481
7482 var nextDidTimeout = void 0;
7483 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
7484 // This is the first attempt.
7485 nextState = null;
7486 nextDidTimeout = false;
7487 } else {
7488 // Something in this boundary's subtree already suspended. Switch to
7489 // rendering the fallback children.
7490 nextState = {
7491 timedOutAt: nextState !== null ? nextState.timedOutAt : NoWork
7492 };
7493 nextDidTimeout = true;
7494 workInProgress.effectTag &= ~DidCapture;
7495 }
7496
7497 // This next part is a bit confusing. If the children timeout, we switch to
7498 // showing the fallback children in place of the "primary" children.
7499 // However, we don't want to delete the primary children because then their
7500 // state will be lost (both the React state and the host state, e.g.
7501 // uncontrolled form inputs). Instead we keep them mounted and hide them.
7502 // Both the fallback children AND the primary children are rendered at the
7503 // same time. Once the primary children are un-suspended, we can delete
7504 // the fallback children — don't need to preserve their state.
7505 //
7506 // The two sets of children are siblings in the host environment, but
7507 // semantically, for purposes of reconciliation, they are two separate sets.
7508 // So we store them using two fragment fibers.
7509 //
7510 // However, we want to avoid allocating extra fibers for every placeholder.
7511 // They're only necessary when the children time out, because that's the
7512 // only time when both sets are mounted.
7513 //
7514 // So, the extra fragment fibers are only used if the children time out.
7515 // Otherwise, we render the primary children directly. This requires some
7516 // custom reconciliation logic to preserve the state of the primary
7517 // children. It's essentially a very basic form of re-parenting.
7518
7519 // `child` points to the child fiber. In the normal case, this is the first
7520 // fiber of the primary children set. In the timed-out case, it's a
7521 // a fragment fiber containing the primary children.
7522 var child = void 0;
7523 // `next` points to the next fiber React should render. In the normal case,
7524 // it's the same as `child`: the first fiber of the primary children set.
7525 // In the timed-out case, it's a fragment fiber containing the *fallback*
7526 // children -- we skip over the primary children entirely.
7527 var next = void 0;
7528 if (current === null) {
7529 // This is the initial mount. This branch is pretty simple because there's
7530 // no previous state that needs to be preserved.
7531 if (nextDidTimeout) {
7532 // Mount separate fragments for primary and fallback children.
7533 var nextFallbackChildren = nextProps.fallback;
7534 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
7535
7536 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
7537 // Outside of concurrent mode, we commit the effects from the
7538 var progressedState = workInProgress.memoizedState;
7539 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
7540 primaryChildFragment.child = progressedPrimaryChild;
7541 }
7542
7543 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
7544 primaryChildFragment.sibling = fallbackChildFragment;
7545 child = primaryChildFragment;
7546 // Skip the primary children, and continue working on the
7547 // fallback children.
7548 next = fallbackChildFragment;
7549 child.return = next.return = workInProgress;
7550 } else {
7551 // Mount the primary children without an intermediate fragment fiber.
7552 var nextPrimaryChildren = nextProps.children;
7553 child = next = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
7554 }
7555 } else {
7556 // This is an update. This branch is more complicated because we need to
7557 // ensure the state of the primary children is preserved.
7558 var prevState = current.memoizedState;
7559 var prevDidTimeout = prevState !== null;
7560 if (prevDidTimeout) {
7561 // The current tree already timed out. That means each child set is
7562 var currentPrimaryChildFragment = current.child;
7563 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
7564 if (nextDidTimeout) {
7565 // Still timed out. Reuse the current primary children by cloning
7566 // its fragment. We're going to skip over these entirely.
7567 var _nextFallbackChildren = nextProps.fallback;
7568 var _primaryChildFragment = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork);
7569
7570 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
7571 // Outside of concurrent mode, we commit the effects from the
7572 var _progressedState = workInProgress.memoizedState;
7573 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
7574 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
7575 _primaryChildFragment.child = _progressedPrimaryChild;
7576 }
7577 }
7578
7579 // Because primaryChildFragment is a new fiber that we're inserting as the
7580 // parent of a new tree, we need to set its treeBaseDuration.
7581 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
7582 // treeBaseDuration is the sum of all the child tree base durations.
7583 var treeBaseDuration = 0;
7584 var hiddenChild = _primaryChildFragment.child;
7585 while (hiddenChild !== null) {
7586 treeBaseDuration += hiddenChild.treeBaseDuration;
7587 hiddenChild = hiddenChild.sibling;
7588 }
7589 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
7590 }
7591
7592 // Clone the fallback child fragment, too. These we'll continue
7593 // working on.
7594 var _fallbackChildFragment = _primaryChildFragment.sibling = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime);
7595 child = _primaryChildFragment;
7596 _primaryChildFragment.childExpirationTime = NoWork;
7597 // Skip the primary children, and continue working on the
7598 // fallback children.
7599 next = _fallbackChildFragment;
7600 child.return = next.return = workInProgress;
7601 } else {
7602 // No longer suspended. Switch back to showing the primary children,
7603 // and remove the intermediate fragment fiber.
7604 var _nextPrimaryChildren = nextProps.children;
7605 var currentPrimaryChild = currentPrimaryChildFragment.child;
7606 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime);
7607
7608 // If this render doesn't suspend, we need to delete the fallback
7609 // children. Wait until the complete phase, after we've confirmed the
7610 // fallback is no longer needed.
7611 // TODO: Would it be better to store the fallback fragment on
7612 // the stateNode?
7613
7614 // Continue rendering the children, like we normally do.
7615 child = next = primaryChild;
7616 }
7617 } else {
7618 // The current tree has not already timed out. That means the primary
7619 // children are not wrapped in a fragment fiber.
7620 var _currentPrimaryChild = current.child;
7621 if (nextDidTimeout) {
7622 // Timed out. Wrap the children in a fragment fiber to keep them
7623 // separate from the fallback children.
7624 var _nextFallbackChildren2 = nextProps.fallback;
7625 var _primaryChildFragment2 = createFiberFromFragment(
7626 // It shouldn't matter what the pending props are because we aren't
7627 // going to render this fragment.
7628 null, mode, NoWork, null);
7629 _primaryChildFragment2.child = _currentPrimaryChild;
7630
7631 // Even though we're creating a new fiber, there are no new children,
7632 // because we're reusing an already mounted tree. So we don't need to
7633 // schedule a placement.
7634 // primaryChildFragment.effectTag |= Placement;
7635
7636 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
7637 // Outside of concurrent mode, we commit the effects from the
7638 var _progressedState2 = workInProgress.memoizedState;
7639 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
7640 _primaryChildFragment2.child = _progressedPrimaryChild2;
7641 }
7642
7643 // Because primaryChildFragment is a new fiber that we're inserting as the
7644 // parent of a new tree, we need to set its treeBaseDuration.
7645 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
7646 // treeBaseDuration is the sum of all the child tree base durations.
7647 var _treeBaseDuration = 0;
7648 var _hiddenChild = _primaryChildFragment2.child;
7649 while (_hiddenChild !== null) {
7650 _treeBaseDuration += _hiddenChild.treeBaseDuration;
7651 _hiddenChild = _hiddenChild.sibling;
7652 }
7653 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
7654 }
7655
7656 // Create a fragment from the fallback children, too.
7657 var _fallbackChildFragment2 = _primaryChildFragment2.sibling = createFiberFromFragment(_nextFallbackChildren2, mode, renderExpirationTime, null);
7658 _fallbackChildFragment2.effectTag |= Placement;
7659 child = _primaryChildFragment2;
7660 _primaryChildFragment2.childExpirationTime = NoWork;
7661 // Skip the primary children, and continue working on the
7662 // fallback children.
7663 next = _fallbackChildFragment2;
7664 child.return = next.return = workInProgress;
7665 } else {
7666 // Still haven't timed out. Continue rendering the children, like we
7667 // normally do.
7668 var _nextPrimaryChildren2 = nextProps.children;
7669 next = child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
7670 }
7671 }
7672 workInProgress.stateNode = current.stateNode;
7673 }
7674
7675 workInProgress.memoizedState = nextState;
7676 workInProgress.child = child;
7677 return next;
7678}
7679
7680function updatePortalComponent(current, workInProgress, renderExpirationTime) {
7681 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
7682 var nextChildren = workInProgress.pendingProps;
7683 if (current === null) {
7684 // Portals are special because we don't append the children during mount
7685 // but at commit. Therefore we need to track insertions which the normal
7686 // flow doesn't do during mount. This doesn't happen at the root because
7687 // the root always starts with a "current" with a null child.
7688 // TODO: Consider unifying this with how the root works.
7689 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7690 } else {
7691 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7692 }
7693 return workInProgress.child;
7694}
7695
7696function updateContextProvider(current, workInProgress, renderExpirationTime) {
7697 var providerType = workInProgress.type;
7698 var context = providerType._context;
7699
7700 var newProps = workInProgress.pendingProps;
7701 var oldProps = workInProgress.memoizedProps;
7702
7703 var newValue = newProps.value;
7704
7705 {
7706 var providerPropTypes = workInProgress.type.propTypes;
7707
7708 if (providerPropTypes) {
7709 checkPropTypes_1(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
7710 }
7711 }
7712
7713 pushProvider(workInProgress, newValue);
7714
7715 if (oldProps !== null) {
7716 var oldValue = oldProps.value;
7717 var changedBits = calculateChangedBits(context, newValue, oldValue);
7718 if (changedBits === 0) {
7719 // No change. Bailout early if children are the same.
7720 if (oldProps.children === newProps.children && !hasContextChanged()) {
7721 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7722 }
7723 } else {
7724 // The context value changed. Search for matching consumers and schedule
7725 // them to update.
7726 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
7727 }
7728 }
7729
7730 var newChildren = newProps.children;
7731 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
7732 return workInProgress.child;
7733}
7734
7735var hasWarnedAboutUsingContextAsConsumer = false;
7736
7737function updateContextConsumer(current, workInProgress, renderExpirationTime) {
7738 var context = workInProgress.type;
7739 // The logic below for Context differs depending on PROD or DEV mode. In
7740 // DEV mode, we create a separate object for Context.Consumer that acts
7741 // like a proxy to Context. This proxy object adds unnecessary code in PROD
7742 // so we use the old behaviour (Context.Consumer references Context) to
7743 // reduce size and overhead. The separate object references context via
7744 // a property called "_context", which also gives us the ability to check
7745 // in DEV mode if this property exists or not and warn if it does not.
7746 {
7747 if (context._context === undefined) {
7748 // This may be because it's a Context (rather than a Consumer).
7749 // Or it may be because it's older React where they're the same thing.
7750 // We only want to warn if we're sure it's a new React.
7751 if (context !== context.Consumer) {
7752 if (!hasWarnedAboutUsingContextAsConsumer) {
7753 hasWarnedAboutUsingContextAsConsumer = true;
7754 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?');
7755 }
7756 }
7757 } else {
7758 context = context._context;
7759 }
7760 }
7761 var newProps = workInProgress.pendingProps;
7762 var render = newProps.children;
7763
7764 {
7765 !(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;
7766 }
7767
7768 prepareToReadContext(workInProgress, renderExpirationTime);
7769 var newValue = readContext(context, newProps.unstable_observedBits);
7770 var newChildren = void 0;
7771 {
7772 ReactCurrentOwner$2.current = workInProgress;
7773 setCurrentPhase('render');
7774 newChildren = render(newValue);
7775 setCurrentPhase(null);
7776 }
7777
7778 // React DevTools reads this flag.
7779 workInProgress.effectTag |= PerformedWork;
7780 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
7781 return workInProgress.child;
7782}
7783
7784function markWorkInProgressReceivedUpdate() {
7785 didReceiveUpdate = true;
7786}
7787
7788function bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime) {
7789 cancelWorkTimer(workInProgress);
7790
7791 if (current !== null) {
7792 // Reuse previous context list
7793 workInProgress.contextDependencies = current.contextDependencies;
7794 }
7795
7796 if (enableProfilerTimer) {
7797 // Don't update "base" render times for bailouts.
7798 stopProfilerTimerIfRunning(workInProgress);
7799 }
7800
7801 // Check if the children have any pending work.
7802 var childExpirationTime = workInProgress.childExpirationTime;
7803 if (childExpirationTime < renderExpirationTime) {
7804 // The children don't have any work either. We can skip them.
7805 // TODO: Once we add back resuming, we should check if the children are
7806 // a work-in-progress set. If so, we need to transfer their effects.
7807 return null;
7808 } else {
7809 // This fiber doesn't have work, but its subtree does. Clone the child
7810 // fibers and continue.
7811 cloneChildFibers(current, workInProgress);
7812 return workInProgress.child;
7813 }
7814}
7815
7816function beginWork(current, workInProgress, renderExpirationTime) {
7817 var updateExpirationTime = workInProgress.expirationTime;
7818
7819 if (current !== null) {
7820 var oldProps = current.memoizedProps;
7821 var newProps = workInProgress.pendingProps;
7822
7823 if (oldProps !== newProps || hasContextChanged()) {
7824 // If props or context changed, mark the fiber as having performed work.
7825 // This may be unset if the props are determined to be equal later (memo).
7826 didReceiveUpdate = true;
7827 } else if (updateExpirationTime < renderExpirationTime) {
7828 didReceiveUpdate = false;
7829 // This fiber does not have any pending work. Bailout without entering
7830 // the begin phase. There's still some bookkeeping we that needs to be done
7831 // in this optimized path, mostly pushing stuff onto the stack.
7832 switch (workInProgress.tag) {
7833 case HostRoot:
7834 pushHostRootContext(workInProgress);
7835 resetHydrationState();
7836 break;
7837 case HostComponent:
7838 pushHostContext(workInProgress);
7839 break;
7840 case ClassComponent:
7841 {
7842 var Component = workInProgress.type;
7843 if (isContextProvider(Component)) {
7844 pushContextProvider(workInProgress);
7845 }
7846 break;
7847 }
7848 case HostPortal:
7849 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
7850 break;
7851 case ContextProvider:
7852 {
7853 var newValue = workInProgress.memoizedProps.value;
7854 pushProvider(workInProgress, newValue);
7855 break;
7856 }
7857 case Profiler:
7858 if (enableProfilerTimer) {
7859 workInProgress.effectTag |= Update;
7860 }
7861 break;
7862 case SuspenseComponent:
7863 {
7864 var state = workInProgress.memoizedState;
7865 var didTimeout = state !== null;
7866 if (didTimeout) {
7867 // If this boundary is currently timed out, we need to decide
7868 // whether to retry the primary children, or to skip over it and
7869 // go straight to the fallback. Check the priority of the primary
7870 var primaryChildFragment = workInProgress.child;
7871 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
7872 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
7873 // The primary children have pending work. Use the normal path
7874 // to attempt to render the primary children again.
7875 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
7876 } else {
7877 // The primary children do not have pending work with sufficient
7878 // priority. Bailout.
7879 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7880 if (child !== null) {
7881 // The fallback children have pending work. Skip over the
7882 // primary children and work on the fallback.
7883 return child.sibling;
7884 } else {
7885 return null;
7886 }
7887 }
7888 }
7889 break;
7890 }
7891 }
7892 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7893 }
7894 } else {
7895 didReceiveUpdate = false;
7896 }
7897
7898 // Before entering the begin phase, clear the expiration time.
7899 workInProgress.expirationTime = NoWork;
7900
7901 switch (workInProgress.tag) {
7902 case IndeterminateComponent:
7903 {
7904 var elementType = workInProgress.elementType;
7905 return mountIndeterminateComponent(current, workInProgress, elementType, renderExpirationTime);
7906 }
7907 case LazyComponent:
7908 {
7909 var _elementType = workInProgress.elementType;
7910 return mountLazyComponent(current, workInProgress, _elementType, updateExpirationTime, renderExpirationTime);
7911 }
7912 case FunctionComponent:
7913 {
7914 var _Component = workInProgress.type;
7915 var unresolvedProps = workInProgress.pendingProps;
7916 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
7917 return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderExpirationTime);
7918 }
7919 case ClassComponent:
7920 {
7921 var _Component2 = workInProgress.type;
7922 var _unresolvedProps = workInProgress.pendingProps;
7923 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
7924 return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
7925 }
7926 case HostRoot:
7927 return updateHostRoot(current, workInProgress, renderExpirationTime);
7928 case HostComponent:
7929 return updateHostComponent(current, workInProgress, renderExpirationTime);
7930 case HostText:
7931 return updateHostText(current, workInProgress);
7932 case SuspenseComponent:
7933 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
7934 case HostPortal:
7935 return updatePortalComponent(current, workInProgress, renderExpirationTime);
7936 case ForwardRef:
7937 {
7938 var type = workInProgress.type;
7939 var _unresolvedProps2 = workInProgress.pendingProps;
7940 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
7941 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderExpirationTime);
7942 }
7943 case Fragment:
7944 return updateFragment(current, workInProgress, renderExpirationTime);
7945 case Mode:
7946 return updateMode(current, workInProgress, renderExpirationTime);
7947 case Profiler:
7948 return updateProfiler(current, workInProgress, renderExpirationTime);
7949 case ContextProvider:
7950 return updateContextProvider(current, workInProgress, renderExpirationTime);
7951 case ContextConsumer:
7952 return updateContextConsumer(current, workInProgress, renderExpirationTime);
7953 case MemoComponent:
7954 {
7955 var _type2 = workInProgress.type;
7956 var _unresolvedProps3 = workInProgress.pendingProps;
7957 // Resolve outer props first, then resolve inner props.
7958 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
7959 {
7960 if (workInProgress.type !== workInProgress.elementType) {
7961 var outerPropTypes = _type2.propTypes;
7962 if (outerPropTypes) {
7963 checkPropTypes_1(outerPropTypes, _resolvedProps3, // Resolved for outer only
7964 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
7965 }
7966 }
7967 }
7968 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
7969 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
7970 }
7971 case SimpleMemoComponent:
7972 {
7973 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
7974 }
7975 case IncompleteClassComponent:
7976 {
7977 var _Component3 = workInProgress.type;
7978 var _unresolvedProps4 = workInProgress.pendingProps;
7979 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
7980 return mountIncompleteClassComponent(current, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
7981 }
7982 default:
7983 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
7984 }
7985}
7986
7987var valueCursor = createCursor(null);
7988
7989var rendererSigil = void 0;
7990{
7991 // Use this to detect multiple renderers using the same context
7992 rendererSigil = {};
7993}
7994
7995var currentlyRenderingFiber = null;
7996var lastContextDependency = null;
7997var lastContextWithAllBitsObserved = null;
7998
7999var isDisallowedContextReadInDEV = false;
8000
8001function resetContextDependences() {
8002 // This is called right before React yields execution, to ensure `readContext`
8003 // cannot be called outside the render phase.
8004 currentlyRenderingFiber = null;
8005 lastContextDependency = null;
8006 lastContextWithAllBitsObserved = null;
8007 {
8008 isDisallowedContextReadInDEV = false;
8009 }
8010}
8011
8012function enterDisallowedContextReadInDEV() {
8013 {
8014 isDisallowedContextReadInDEV = true;
8015 }
8016}
8017
8018function exitDisallowedContextReadInDEV() {
8019 {
8020 isDisallowedContextReadInDEV = false;
8021 }
8022}
8023
8024function pushProvider(providerFiber, nextValue) {
8025 var context = providerFiber.type._context;
8026
8027 if (isPrimaryRenderer) {
8028 push(valueCursor, context._currentValue, providerFiber);
8029
8030 context._currentValue = nextValue;
8031 {
8032 !(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;
8033 context._currentRenderer = rendererSigil;
8034 }
8035 } else {
8036 push(valueCursor, context._currentValue2, providerFiber);
8037
8038 context._currentValue2 = nextValue;
8039 {
8040 !(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;
8041 context._currentRenderer2 = rendererSigil;
8042 }
8043 }
8044}
8045
8046function popProvider(providerFiber) {
8047 var currentValue = valueCursor.current;
8048
8049 pop(valueCursor, providerFiber);
8050
8051 var context = providerFiber.type._context;
8052 if (isPrimaryRenderer) {
8053 context._currentValue = currentValue;
8054 } else {
8055 context._currentValue2 = currentValue;
8056 }
8057}
8058
8059function calculateChangedBits(context, newValue, oldValue) {
8060 if (is(oldValue, newValue)) {
8061 // No change
8062 return 0;
8063 } else {
8064 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : maxSigned31BitInt;
8065
8066 {
8067 !((changedBits & maxSigned31BitInt) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0;
8068 }
8069 return changedBits | 0;
8070 }
8071}
8072
8073function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
8074 var fiber = workInProgress.child;
8075 if (fiber !== null) {
8076 // Set the return pointer of the child to the work-in-progress fiber.
8077 fiber.return = workInProgress;
8078 }
8079 while (fiber !== null) {
8080 var nextFiber = void 0;
8081
8082 // Visit this fiber.
8083 var list = fiber.contextDependencies;
8084 if (list !== null) {
8085 nextFiber = fiber.child;
8086
8087 var dependency = list.first;
8088 while (dependency !== null) {
8089 // Check if the context matches.
8090 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
8091 // Match! Schedule an update on this fiber.
8092
8093 if (fiber.tag === ClassComponent) {
8094 // Schedule a force update on the work-in-progress.
8095 var update = createUpdate(renderExpirationTime);
8096 update.tag = ForceUpdate;
8097 // TODO: Because we don't have a work-in-progress, this will add the
8098 // update to the current fiber, too, which means it will persist even if
8099 // this render is thrown away. Since it's a race condition, not sure it's
8100 // worth fixing.
8101 enqueueUpdate(fiber, update);
8102 }
8103
8104 if (fiber.expirationTime < renderExpirationTime) {
8105 fiber.expirationTime = renderExpirationTime;
8106 }
8107 var alternate = fiber.alternate;
8108 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
8109 alternate.expirationTime = renderExpirationTime;
8110 }
8111 // Update the child expiration time of all the ancestors, including
8112 // the alternates.
8113 var node = fiber.return;
8114 while (node !== null) {
8115 alternate = node.alternate;
8116 if (node.childExpirationTime < renderExpirationTime) {
8117 node.childExpirationTime = renderExpirationTime;
8118 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
8119 alternate.childExpirationTime = renderExpirationTime;
8120 }
8121 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
8122 alternate.childExpirationTime = renderExpirationTime;
8123 } else {
8124 // Neither alternate was updated, which means the rest of the
8125 // ancestor path already has sufficient priority.
8126 break;
8127 }
8128 node = node.return;
8129 }
8130
8131 // Mark the expiration time on the list, too.
8132 if (list.expirationTime < renderExpirationTime) {
8133 list.expirationTime = renderExpirationTime;
8134 }
8135
8136 // Since we already found a match, we can stop traversing the
8137 // dependency list.
8138 break;
8139 }
8140 dependency = dependency.next;
8141 }
8142 } else if (fiber.tag === ContextProvider) {
8143 // Don't scan deeper if this is a matching provider
8144 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
8145 } else {
8146 // Traverse down.
8147 nextFiber = fiber.child;
8148 }
8149
8150 if (nextFiber !== null) {
8151 // Set the return pointer of the child to the work-in-progress fiber.
8152 nextFiber.return = fiber;
8153 } else {
8154 // No child. Traverse to next sibling.
8155 nextFiber = fiber;
8156 while (nextFiber !== null) {
8157 if (nextFiber === workInProgress) {
8158 // We're back to the root of this subtree. Exit.
8159 nextFiber = null;
8160 break;
8161 }
8162 var sibling = nextFiber.sibling;
8163 if (sibling !== null) {
8164 // Set the return pointer of the sibling to the work-in-progress fiber.
8165 sibling.return = nextFiber.return;
8166 nextFiber = sibling;
8167 break;
8168 }
8169 // No more siblings. Traverse up.
8170 nextFiber = nextFiber.return;
8171 }
8172 }
8173 fiber = nextFiber;
8174 }
8175}
8176
8177function prepareToReadContext(workInProgress, renderExpirationTime) {
8178 currentlyRenderingFiber = workInProgress;
8179 lastContextDependency = null;
8180 lastContextWithAllBitsObserved = null;
8181
8182 var currentDependencies = workInProgress.contextDependencies;
8183 if (currentDependencies !== null && currentDependencies.expirationTime >= renderExpirationTime) {
8184 // Context list has a pending update. Mark that this fiber performed work.
8185 markWorkInProgressReceivedUpdate();
8186 }
8187
8188 // Reset the work-in-progress list
8189 workInProgress.contextDependencies = null;
8190}
8191
8192function readContext(context, observedBits) {
8193 {
8194 // This warning would fire if you read context inside a Hook like useMemo.
8195 // Unlike the class check below, it's not enforced in production for perf.
8196 !!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;
8197 }
8198
8199 if (lastContextWithAllBitsObserved === context) {
8200 // Nothing to do. We already observe everything in this context.
8201 } else if (observedBits === false || observedBits === 0) {
8202 // Do not observe any updates.
8203 } else {
8204 var resolvedObservedBits = void 0; // Avoid deopting on observable arguments or heterogeneous types.
8205 if (typeof observedBits !== 'number' || observedBits === maxSigned31BitInt) {
8206 // Observe all updates.
8207 lastContextWithAllBitsObserved = context;
8208 resolvedObservedBits = maxSigned31BitInt;
8209 } else {
8210 resolvedObservedBits = observedBits;
8211 }
8212
8213 var contextItem = {
8214 context: context,
8215 observedBits: resolvedObservedBits,
8216 next: null
8217 };
8218
8219 if (lastContextDependency === null) {
8220 !(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;
8221
8222 // This is the first dependency for this component. Create a new list.
8223 lastContextDependency = contextItem;
8224 currentlyRenderingFiber.contextDependencies = {
8225 first: contextItem,
8226 expirationTime: NoWork
8227 };
8228 } else {
8229 // Append a new context item.
8230 lastContextDependency = lastContextDependency.next = contextItem;
8231 }
8232 }
8233 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
8234}
8235
8236// UpdateQueue is a linked list of prioritized updates.
8237//
8238// Like fibers, update queues come in pairs: a current queue, which represents
8239// the visible state of the screen, and a work-in-progress queue, which can be
8240// mutated and processed asynchronously before it is committed — a form of
8241// double buffering. If a work-in-progress render is discarded before finishing,
8242// we create a new work-in-progress by cloning the current queue.
8243//
8244// Both queues share a persistent, singly-linked list structure. To schedule an
8245// update, we append it to the end of both queues. Each queue maintains a
8246// pointer to first update in the persistent list that hasn't been processed.
8247// The work-in-progress pointer always has a position equal to or greater than
8248// the current queue, since we always work on that one. The current queue's
8249// pointer is only updated during the commit phase, when we swap in the
8250// work-in-progress.
8251//
8252// For example:
8253//
8254// Current pointer: A - B - C - D - E - F
8255// Work-in-progress pointer: D - E - F
8256// ^
8257// The work-in-progress queue has
8258// processed more updates than current.
8259//
8260// The reason we append to both queues is because otherwise we might drop
8261// updates without ever processing them. For example, if we only add updates to
8262// the work-in-progress queue, some updates could be lost whenever a work-in
8263// -progress render restarts by cloning from current. Similarly, if we only add
8264// updates to the current queue, the updates will be lost whenever an already
8265// in-progress queue commits and swaps with the current queue. However, by
8266// adding to both queues, we guarantee that the update will be part of the next
8267// work-in-progress. (And because the work-in-progress queue becomes the
8268// current queue once it commits, there's no danger of applying the same
8269// update twice.)
8270//
8271// Prioritization
8272// --------------
8273//
8274// Updates are not sorted by priority, but by insertion; new updates are always
8275// appended to the end of the list.
8276//
8277// The priority is still important, though. When processing the update queue
8278// during the render phase, only the updates with sufficient priority are
8279// included in the result. If we skip an update because it has insufficient
8280// priority, it remains in the queue to be processed later, during a lower
8281// priority render. Crucially, all updates subsequent to a skipped update also
8282// remain in the queue *regardless of their priority*. That means high priority
8283// updates are sometimes processed twice, at two separate priorities. We also
8284// keep track of a base state, that represents the state before the first
8285// update in the queue is applied.
8286//
8287// For example:
8288//
8289// Given a base state of '', and the following queue of updates
8290//
8291// A1 - B2 - C1 - D2
8292//
8293// where the number indicates the priority, and the update is applied to the
8294// previous state by appending a letter, React will process these updates as
8295// two separate renders, one per distinct priority level:
8296//
8297// First render, at priority 1:
8298// Base state: ''
8299// Updates: [A1, C1]
8300// Result state: 'AC'
8301//
8302// Second render, at priority 2:
8303// Base state: 'A' <- The base state does not include C1,
8304// because B2 was skipped.
8305// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
8306// Result state: 'ABCD'
8307//
8308// Because we process updates in insertion order, and rebase high priority
8309// updates when preceding updates are skipped, the final result is deterministic
8310// regardless of priority. Intermediate state may vary according to system
8311// resources, but the final state is always the same.
8312
8313var UpdateState = 0;
8314var ReplaceState = 1;
8315var ForceUpdate = 2;
8316var CaptureUpdate = 3;
8317
8318// Global state that is reset at the beginning of calling `processUpdateQueue`.
8319// It should only be read right after calling `processUpdateQueue`, via
8320// `checkHasForceUpdateAfterProcessing`.
8321var hasForceUpdate = false;
8322
8323var didWarnUpdateInsideUpdate = void 0;
8324var currentlyProcessingQueue = void 0;
8325var resetCurrentlyProcessingQueue = void 0;
8326{
8327 didWarnUpdateInsideUpdate = false;
8328 currentlyProcessingQueue = null;
8329 resetCurrentlyProcessingQueue = function () {
8330 currentlyProcessingQueue = null;
8331 };
8332}
8333
8334function createUpdateQueue(baseState) {
8335 var queue = {
8336 baseState: baseState,
8337 firstUpdate: null,
8338 lastUpdate: null,
8339 firstCapturedUpdate: null,
8340 lastCapturedUpdate: null,
8341 firstEffect: null,
8342 lastEffect: null,
8343 firstCapturedEffect: null,
8344 lastCapturedEffect: null
8345 };
8346 return queue;
8347}
8348
8349function cloneUpdateQueue(currentQueue) {
8350 var queue = {
8351 baseState: currentQueue.baseState,
8352 firstUpdate: currentQueue.firstUpdate,
8353 lastUpdate: currentQueue.lastUpdate,
8354
8355 // TODO: With resuming, if we bail out and resuse the child tree, we should
8356 // keep these effects.
8357 firstCapturedUpdate: null,
8358 lastCapturedUpdate: null,
8359
8360 firstEffect: null,
8361 lastEffect: null,
8362
8363 firstCapturedEffect: null,
8364 lastCapturedEffect: null
8365 };
8366 return queue;
8367}
8368
8369function createUpdate(expirationTime) {
8370 return {
8371 expirationTime: expirationTime,
8372
8373 tag: UpdateState,
8374 payload: null,
8375 callback: null,
8376
8377 next: null,
8378 nextEffect: null
8379 };
8380}
8381
8382function appendUpdateToQueue(queue, update) {
8383 // Append the update to the end of the list.
8384 if (queue.lastUpdate === null) {
8385 // Queue is empty
8386 queue.firstUpdate = queue.lastUpdate = update;
8387 } else {
8388 queue.lastUpdate.next = update;
8389 queue.lastUpdate = update;
8390 }
8391}
8392
8393function enqueueUpdate(fiber, update) {
8394 // Update queues are created lazily.
8395 var alternate = fiber.alternate;
8396 var queue1 = void 0;
8397 var queue2 = void 0;
8398 if (alternate === null) {
8399 // There's only one fiber.
8400 queue1 = fiber.updateQueue;
8401 queue2 = null;
8402 if (queue1 === null) {
8403 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
8404 }
8405 } else {
8406 // There are two owners.
8407 queue1 = fiber.updateQueue;
8408 queue2 = alternate.updateQueue;
8409 if (queue1 === null) {
8410 if (queue2 === null) {
8411 // Neither fiber has an update queue. Create new ones.
8412 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
8413 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState);
8414 } else {
8415 // Only one fiber has an update queue. Clone to create a new one.
8416 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
8417 }
8418 } else {
8419 if (queue2 === null) {
8420 // Only one fiber has an update queue. Clone to create a new one.
8421 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
8422 } else {
8423 // Both owners have an update queue.
8424 }
8425 }
8426 }
8427 if (queue2 === null || queue1 === queue2) {
8428 // There's only a single queue.
8429 appendUpdateToQueue(queue1, update);
8430 } else {
8431 // There are two queues. We need to append the update to both queues,
8432 // while accounting for the persistent structure of the list — we don't
8433 // want the same update to be added multiple times.
8434 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
8435 // One of the queues is not empty. We must add the update to both queues.
8436 appendUpdateToQueue(queue1, update);
8437 appendUpdateToQueue(queue2, update);
8438 } else {
8439 // Both queues are non-empty. The last update is the same in both lists,
8440 // because of structural sharing. So, only append to one of the lists.
8441 appendUpdateToQueue(queue1, update);
8442 // But we still need to update the `lastUpdate` pointer of queue2.
8443 queue2.lastUpdate = update;
8444 }
8445 }
8446
8447 {
8448 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) {
8449 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.');
8450 didWarnUpdateInsideUpdate = true;
8451 }
8452 }
8453}
8454
8455function enqueueCapturedUpdate(workInProgress, update) {
8456 // Captured updates go into a separate list, and only on the work-in-
8457 // progress queue.
8458 var workInProgressQueue = workInProgress.updateQueue;
8459 if (workInProgressQueue === null) {
8460 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState);
8461 } else {
8462 // TODO: I put this here rather than createWorkInProgress so that we don't
8463 // clone the queue unnecessarily. There's probably a better way to
8464 // structure this.
8465 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue);
8466 }
8467
8468 // Append the update to the end of the list.
8469 if (workInProgressQueue.lastCapturedUpdate === null) {
8470 // This is the first render phase update
8471 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
8472 } else {
8473 workInProgressQueue.lastCapturedUpdate.next = update;
8474 workInProgressQueue.lastCapturedUpdate = update;
8475 }
8476}
8477
8478function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
8479 var current = workInProgress.alternate;
8480 if (current !== null) {
8481 // If the work-in-progress queue is equal to the current queue,
8482 // we need to clone it first.
8483 if (queue === current.updateQueue) {
8484 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
8485 }
8486 }
8487 return queue;
8488}
8489
8490function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
8491 switch (update.tag) {
8492 case ReplaceState:
8493 {
8494 var _payload = update.payload;
8495 if (typeof _payload === 'function') {
8496 // Updater function
8497 {
8498 enterDisallowedContextReadInDEV();
8499 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8500 _payload.call(instance, prevState, nextProps);
8501 }
8502 }
8503 var nextState = _payload.call(instance, prevState, nextProps);
8504 {
8505 exitDisallowedContextReadInDEV();
8506 }
8507 return nextState;
8508 }
8509 // State object
8510 return _payload;
8511 }
8512 case CaptureUpdate:
8513 {
8514 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
8515 }
8516 // Intentional fallthrough
8517 case UpdateState:
8518 {
8519 var _payload2 = update.payload;
8520 var partialState = void 0;
8521 if (typeof _payload2 === 'function') {
8522 // Updater function
8523 {
8524 enterDisallowedContextReadInDEV();
8525 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8526 _payload2.call(instance, prevState, nextProps);
8527 }
8528 }
8529 partialState = _payload2.call(instance, prevState, nextProps);
8530 {
8531 exitDisallowedContextReadInDEV();
8532 }
8533 } else {
8534 // Partial state object
8535 partialState = _payload2;
8536 }
8537 if (partialState === null || partialState === undefined) {
8538 // Null and undefined are treated as no-ops.
8539 return prevState;
8540 }
8541 // Merge the partial state and the previous state.
8542 return _assign({}, prevState, partialState);
8543 }
8544 case ForceUpdate:
8545 {
8546 hasForceUpdate = true;
8547 return prevState;
8548 }
8549 }
8550 return prevState;
8551}
8552
8553function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) {
8554 hasForceUpdate = false;
8555
8556 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
8557
8558 {
8559 currentlyProcessingQueue = queue;
8560 }
8561
8562 // These values may change as we process the queue.
8563 var newBaseState = queue.baseState;
8564 var newFirstUpdate = null;
8565 var newExpirationTime = NoWork;
8566
8567 // Iterate through the list of updates to compute the result.
8568 var update = queue.firstUpdate;
8569 var resultState = newBaseState;
8570 while (update !== null) {
8571 var updateExpirationTime = update.expirationTime;
8572 if (updateExpirationTime < renderExpirationTime) {
8573 // This update does not have sufficient priority. Skip it.
8574 if (newFirstUpdate === null) {
8575 // This is the first skipped update. It will be the first update in
8576 // the new list.
8577 newFirstUpdate = update;
8578 // Since this is the first update that was skipped, the current result
8579 // is the new base state.
8580 newBaseState = resultState;
8581 }
8582 // Since this update will remain in the list, update the remaining
8583 // expiration time.
8584 if (newExpirationTime < updateExpirationTime) {
8585 newExpirationTime = updateExpirationTime;
8586 }
8587 } else {
8588 // This update does have sufficient priority. Process it and compute
8589 // a new result.
8590 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
8591 var _callback = update.callback;
8592 if (_callback !== null) {
8593 workInProgress.effectTag |= Callback;
8594 // Set this to null, in case it was mutated during an aborted render.
8595 update.nextEffect = null;
8596 if (queue.lastEffect === null) {
8597 queue.firstEffect = queue.lastEffect = update;
8598 } else {
8599 queue.lastEffect.nextEffect = update;
8600 queue.lastEffect = update;
8601 }
8602 }
8603 }
8604 // Continue to the next update.
8605 update = update.next;
8606 }
8607
8608 // Separately, iterate though the list of captured updates.
8609 var newFirstCapturedUpdate = null;
8610 update = queue.firstCapturedUpdate;
8611 while (update !== null) {
8612 var _updateExpirationTime = update.expirationTime;
8613 if (_updateExpirationTime < renderExpirationTime) {
8614 // This update does not have sufficient priority. Skip it.
8615 if (newFirstCapturedUpdate === null) {
8616 // This is the first skipped captured update. It will be the first
8617 // update in the new list.
8618 newFirstCapturedUpdate = update;
8619 // If this is the first update that was skipped, the current result is
8620 // the new base state.
8621 if (newFirstUpdate === null) {
8622 newBaseState = resultState;
8623 }
8624 }
8625 // Since this update will remain in the list, update the remaining
8626 // expiration time.
8627 if (newExpirationTime < _updateExpirationTime) {
8628 newExpirationTime = _updateExpirationTime;
8629 }
8630 } else {
8631 // This update does have sufficient priority. Process it and compute
8632 // a new result.
8633 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
8634 var _callback2 = update.callback;
8635 if (_callback2 !== null) {
8636 workInProgress.effectTag |= Callback;
8637 // Set this to null, in case it was mutated during an aborted render.
8638 update.nextEffect = null;
8639 if (queue.lastCapturedEffect === null) {
8640 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
8641 } else {
8642 queue.lastCapturedEffect.nextEffect = update;
8643 queue.lastCapturedEffect = update;
8644 }
8645 }
8646 }
8647 update = update.next;
8648 }
8649
8650 if (newFirstUpdate === null) {
8651 queue.lastUpdate = null;
8652 }
8653 if (newFirstCapturedUpdate === null) {
8654 queue.lastCapturedUpdate = null;
8655 } else {
8656 workInProgress.effectTag |= Callback;
8657 }
8658 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
8659 // We processed every update, without skipping. That means the new base
8660 // state is the same as the result state.
8661 newBaseState = resultState;
8662 }
8663
8664 queue.baseState = newBaseState;
8665 queue.firstUpdate = newFirstUpdate;
8666 queue.firstCapturedUpdate = newFirstCapturedUpdate;
8667
8668 // Set the remaining expiration time to be whatever is remaining in the queue.
8669 // This should be fine because the only two other things that contribute to
8670 // expiration time are props and context. We're already in the middle of the
8671 // begin phase by the time we start processing the queue, so we've already
8672 // dealt with the props. Context in components that specify
8673 // shouldComponentUpdate is tricky; but we'll have to account for
8674 // that regardless.
8675 workInProgress.expirationTime = newExpirationTime;
8676 workInProgress.memoizedState = resultState;
8677
8678 {
8679 currentlyProcessingQueue = null;
8680 }
8681}
8682
8683function callCallback(callback, context) {
8684 !(typeof callback === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', callback) : void 0;
8685 callback.call(context);
8686}
8687
8688function resetHasForceUpdateBeforeProcessing() {
8689 hasForceUpdate = false;
8690}
8691
8692function checkHasForceUpdateAfterProcessing() {
8693 return hasForceUpdate;
8694}
8695
8696function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) {
8697 // If the finished render included captured updates, and there are still
8698 // lower priority updates left over, we need to keep the captured updates
8699 // in the queue so that they are rebased and not dropped once we process the
8700 // queue again at the lower priority.
8701 if (finishedQueue.firstCapturedUpdate !== null) {
8702 // Join the captured update list to the end of the normal list.
8703 if (finishedQueue.lastUpdate !== null) {
8704 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
8705 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
8706 }
8707 // Clear the list of captured updates.
8708 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
8709 }
8710
8711 // Commit the effects
8712 commitUpdateEffects(finishedQueue.firstEffect, instance);
8713 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
8714
8715 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
8716 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
8717}
8718
8719function commitUpdateEffects(effect, instance) {
8720 while (effect !== null) {
8721 var _callback3 = effect.callback;
8722 if (_callback3 !== null) {
8723 effect.callback = null;
8724 callCallback(_callback3, instance);
8725 }
8726 effect = effect.nextEffect;
8727 }
8728}
8729
8730function createCapturedValue(value, source) {
8731 // If the value is an error, call this function immediately after it is thrown
8732 // so the stack is accurate.
8733 return {
8734 value: value,
8735 source: source,
8736 stack: getStackByFiberInDevAndProd(source)
8737 };
8738}
8739
8740function markUpdate(workInProgress) {
8741 // Tag the fiber with an update effect. This turns a Placement into
8742 // a PlacementAndUpdate.
8743 workInProgress.effectTag |= Update;
8744}
8745
8746function markRef$1(workInProgress) {
8747 workInProgress.effectTag |= Ref;
8748}
8749
8750var appendAllChildren = void 0;
8751var updateHostContainer = void 0;
8752var updateHostComponent$1 = void 0;
8753var updateHostText$1 = void 0;
8754if (supportsMutation) {
8755 // Mutation mode
8756
8757 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
8758 // We only have the top Fiber that was created but we need recurse down its
8759 // children to find all the terminal nodes.
8760 var node = workInProgress.child;
8761 while (node !== null) {
8762 if (node.tag === HostComponent || node.tag === HostText) {
8763 appendInitialChild(parent, node.stateNode);
8764 } else if (node.tag === HostPortal) {
8765 // If we have a portal child, then we don't want to traverse
8766 // down its children. Instead, we'll get insertions from each child in
8767 // the portal directly.
8768 } else if (node.child !== null) {
8769 node.child.return = node;
8770 node = node.child;
8771 continue;
8772 }
8773 if (node === workInProgress) {
8774 return;
8775 }
8776 while (node.sibling === null) {
8777 if (node.return === null || node.return === workInProgress) {
8778 return;
8779 }
8780 node = node.return;
8781 }
8782 node.sibling.return = node.return;
8783 node = node.sibling;
8784 }
8785 };
8786
8787 updateHostContainer = function (workInProgress) {
8788 // Noop
8789 };
8790 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
8791 // If we have an alternate, that means this is an update and we need to
8792 // schedule a side-effect to do the updates.
8793 var oldProps = current.memoizedProps;
8794 if (oldProps === newProps) {
8795 // In mutation mode, this is sufficient for a bailout because
8796 // we won't touch this node even if children changed.
8797 return;
8798 }
8799
8800 // If we get updated because one of our children updated, we don't
8801 // have newProps so we'll have to reuse them.
8802 // TODO: Split the update API as separate for the props vs. children.
8803 // Even better would be if children weren't special cased at all tho.
8804 var instance = workInProgress.stateNode;
8805 var currentHostContext = getHostContext();
8806 // TODO: Experiencing an error where oldProps is null. Suggests a host
8807 // component is hitting the resume path. Figure out why. Possibly
8808 // related to `hidden`.
8809 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
8810 // TODO: Type this specific to this type of component.
8811 workInProgress.updateQueue = updatePayload;
8812 // If the update payload indicates that there is a change or if there
8813 // is a new ref we mark this as an update. All the work is done in commitWork.
8814 if (updatePayload) {
8815 markUpdate(workInProgress);
8816 }
8817 };
8818 updateHostText$1 = function (current, workInProgress, oldText, newText) {
8819 // If the text differs, mark it as an update. All the work in done in commitWork.
8820 if (oldText !== newText) {
8821 markUpdate(workInProgress);
8822 }
8823 };
8824} else if (supportsPersistence) {
8825 // Persistent host tree mode
8826
8827 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
8828 // We only have the top Fiber that was created but we need recurse down its
8829 // children to find all the terminal nodes.
8830 var node = workInProgress.child;
8831 while (node !== null) {
8832 // eslint-disable-next-line no-labels
8833 branches: if (node.tag === HostComponent) {
8834 var instance = node.stateNode;
8835 if (needsVisibilityToggle) {
8836 var props = node.memoizedProps;
8837 var type = node.type;
8838 if (isHidden) {
8839 // This child is inside a timed out tree. Hide it.
8840 instance = cloneHiddenInstance(instance, type, props, node);
8841 } else {
8842 // This child was previously inside a timed out tree. If it was not
8843 // updated during this render, it may need to be unhidden. Clone
8844 // again to be sure.
8845 instance = cloneUnhiddenInstance(instance, type, props, node);
8846 }
8847 node.stateNode = instance;
8848 }
8849 appendInitialChild(parent, instance);
8850 } else if (node.tag === HostText) {
8851 var _instance = node.stateNode;
8852 if (needsVisibilityToggle) {
8853 var text = node.memoizedProps;
8854 var rootContainerInstance = getRootHostContainer();
8855 var currentHostContext = getHostContext();
8856 if (isHidden) {
8857 _instance = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
8858 } else {
8859 _instance = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
8860 }
8861 node.stateNode = _instance;
8862 }
8863 appendInitialChild(parent, _instance);
8864 } else if (node.tag === HostPortal) {
8865 // If we have a portal child, then we don't want to traverse
8866 // down its children. Instead, we'll get insertions from each child in
8867 // the portal directly.
8868 } else if (node.tag === SuspenseComponent) {
8869 var current = node.alternate;
8870 if (current !== null) {
8871 var oldState = current.memoizedState;
8872 var newState = node.memoizedState;
8873 var oldIsHidden = oldState !== null;
8874 var newIsHidden = newState !== null;
8875 if (oldIsHidden !== newIsHidden) {
8876 // The placeholder either just timed out or switched back to the normal
8877 // children after having previously timed out. Toggle the visibility of
8878 // the direct host children.
8879 var primaryChildParent = newIsHidden ? node.child : node;
8880 if (primaryChildParent !== null) {
8881 appendAllChildren(parent, primaryChildParent, true, newIsHidden);
8882 }
8883 // eslint-disable-next-line no-labels
8884 break branches;
8885 }
8886 }
8887 if (node.child !== null) {
8888 // Continue traversing like normal
8889 node.child.return = node;
8890 node = node.child;
8891 continue;
8892 }
8893 } else if (node.child !== null) {
8894 node.child.return = node;
8895 node = node.child;
8896 continue;
8897 }
8898 // $FlowFixMe This is correct but Flow is confused by the labeled break.
8899 node = node;
8900 if (node === workInProgress) {
8901 return;
8902 }
8903 while (node.sibling === null) {
8904 if (node.return === null || node.return === workInProgress) {
8905 return;
8906 }
8907 node = node.return;
8908 }
8909 node.sibling.return = node.return;
8910 node = node.sibling;
8911 }
8912 };
8913
8914 // An unfortunate fork of appendAllChildren because we have two different parent types.
8915 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) {
8916 // We only have the top Fiber that was created but we need recurse down its
8917 // children to find all the terminal nodes.
8918 var node = workInProgress.child;
8919 while (node !== null) {
8920 // eslint-disable-next-line no-labels
8921 branches: if (node.tag === HostComponent) {
8922 var instance = node.stateNode;
8923 if (needsVisibilityToggle) {
8924 var props = node.memoizedProps;
8925 var type = node.type;
8926 if (isHidden) {
8927 // This child is inside a timed out tree. Hide it.
8928 instance = cloneHiddenInstance(instance, type, props, node);
8929 } else {
8930 // This child was previously inside a timed out tree. If it was not
8931 // updated during this render, it may need to be unhidden. Clone
8932 // again to be sure.
8933 instance = cloneUnhiddenInstance(instance, type, props, node);
8934 }
8935 node.stateNode = instance;
8936 }
8937 appendChildToContainerChildSet(containerChildSet, instance);
8938 } else if (node.tag === HostText) {
8939 var _instance2 = node.stateNode;
8940 if (needsVisibilityToggle) {
8941 var text = node.memoizedProps;
8942 var rootContainerInstance = getRootHostContainer();
8943 var currentHostContext = getHostContext();
8944 if (isHidden) {
8945 _instance2 = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
8946 } else {
8947 _instance2 = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
8948 }
8949 node.stateNode = _instance2;
8950 }
8951 appendChildToContainerChildSet(containerChildSet, _instance2);
8952 } else if (node.tag === HostPortal) {
8953 // If we have a portal child, then we don't want to traverse
8954 // down its children. Instead, we'll get insertions from each child in
8955 // the portal directly.
8956 } else if (node.tag === SuspenseComponent) {
8957 var current = node.alternate;
8958 if (current !== null) {
8959 var oldState = current.memoizedState;
8960 var newState = node.memoizedState;
8961 var oldIsHidden = oldState !== null;
8962 var newIsHidden = newState !== null;
8963 if (oldIsHidden !== newIsHidden) {
8964 // The placeholder either just timed out or switched back to the normal
8965 // children after having previously timed out. Toggle the visibility of
8966 // the direct host children.
8967 var primaryChildParent = newIsHidden ? node.child : node;
8968 if (primaryChildParent !== null) {
8969 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden);
8970 }
8971 // eslint-disable-next-line no-labels
8972 break branches;
8973 }
8974 }
8975 if (node.child !== null) {
8976 // Continue traversing like normal
8977 node.child.return = node;
8978 node = node.child;
8979 continue;
8980 }
8981 } else if (node.child !== null) {
8982 node.child.return = node;
8983 node = node.child;
8984 continue;
8985 }
8986 // $FlowFixMe This is correct but Flow is confused by the labeled break.
8987 node = node;
8988 if (node === workInProgress) {
8989 return;
8990 }
8991 while (node.sibling === null) {
8992 if (node.return === null || node.return === workInProgress) {
8993 return;
8994 }
8995 node = node.return;
8996 }
8997 node.sibling.return = node.return;
8998 node = node.sibling;
8999 }
9000 };
9001 updateHostContainer = function (workInProgress) {
9002 var portalOrRoot = workInProgress.stateNode;
9003 var childrenUnchanged = workInProgress.firstEffect === null;
9004 if (childrenUnchanged) {
9005 // No changes, just reuse the existing instance.
9006 } else {
9007 var container = portalOrRoot.containerInfo;
9008 var newChildSet = createContainerChildSet(container);
9009 // If children might have changed, we have to add them all to the set.
9010 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
9011 portalOrRoot.pendingChildren = newChildSet;
9012 // Schedule an update on the container to swap out the container.
9013 markUpdate(workInProgress);
9014 finalizeContainerChildren(container, newChildSet);
9015 }
9016 };
9017 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9018 var currentInstance = current.stateNode;
9019 var oldProps = current.memoizedProps;
9020 // If there are no effects associated with this node, then none of our children had any updates.
9021 // This guarantees that we can reuse all of them.
9022 var childrenUnchanged = workInProgress.firstEffect === null;
9023 if (childrenUnchanged && oldProps === newProps) {
9024 // No changes, just reuse the existing instance.
9025 // Note that this might release a previous clone.
9026 workInProgress.stateNode = currentInstance;
9027 return;
9028 }
9029 var recyclableInstance = workInProgress.stateNode;
9030 var currentHostContext = getHostContext();
9031 var updatePayload = null;
9032 if (oldProps !== newProps) {
9033 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9034 }
9035 if (childrenUnchanged && updatePayload === null) {
9036 // No changes, just reuse the existing instance.
9037 // Note that this might release a previous clone.
9038 workInProgress.stateNode = currentInstance;
9039 return;
9040 }
9041 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
9042 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
9043 markUpdate(workInProgress);
9044 }
9045 workInProgress.stateNode = newInstance;
9046 if (childrenUnchanged) {
9047 // If there are no other effects in this tree, we need to flag this node as having one.
9048 // Even though we're not going to use it for anything.
9049 // Otherwise parents won't know that there are new children to propagate upwards.
9050 markUpdate(workInProgress);
9051 } else {
9052 // If children might have changed, we have to add them all to the set.
9053 appendAllChildren(newInstance, workInProgress, false, false);
9054 }
9055 };
9056 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9057 if (oldText !== newText) {
9058 // If the text content differs, we'll create a new text instance for it.
9059 var rootContainerInstance = getRootHostContainer();
9060 var currentHostContext = getHostContext();
9061 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
9062 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
9063 // This lets the parents know that at least one of their children has changed.
9064 markUpdate(workInProgress);
9065 }
9066 };
9067} else {
9068 // No host operations
9069 updateHostContainer = function (workInProgress) {
9070 // Noop
9071 };
9072 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9073 // Noop
9074 };
9075 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9076 // Noop
9077 };
9078}
9079
9080function completeWork(current, workInProgress, renderExpirationTime) {
9081 var newProps = workInProgress.pendingProps;
9082
9083 switch (workInProgress.tag) {
9084 case IndeterminateComponent:
9085 break;
9086 case LazyComponent:
9087 break;
9088 case SimpleMemoComponent:
9089 case FunctionComponent:
9090 break;
9091 case ClassComponent:
9092 {
9093 var Component = workInProgress.type;
9094 if (isContextProvider(Component)) {
9095 popContext(workInProgress);
9096 }
9097 break;
9098 }
9099 case HostRoot:
9100 {
9101 popHostContainer(workInProgress);
9102 popTopLevelContextObject(workInProgress);
9103 var fiberRoot = workInProgress.stateNode;
9104 if (fiberRoot.pendingContext) {
9105 fiberRoot.context = fiberRoot.pendingContext;
9106 fiberRoot.pendingContext = null;
9107 }
9108 if (current === null || current.child === null) {
9109 // If we hydrated, pop so that we can delete any remaining children
9110 // that weren't hydrated.
9111 popHydrationState(workInProgress);
9112 // This resets the hacky state to fix isMounted before committing.
9113 // TODO: Delete this when we delete isMounted and findDOMNode.
9114 workInProgress.effectTag &= ~Placement;
9115 }
9116 updateHostContainer(workInProgress);
9117 break;
9118 }
9119 case HostComponent:
9120 {
9121 popHostContext(workInProgress);
9122 var rootContainerInstance = getRootHostContainer();
9123 var type = workInProgress.type;
9124 if (current !== null && workInProgress.stateNode != null) {
9125 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
9126
9127 if (current.ref !== workInProgress.ref) {
9128 markRef$1(workInProgress);
9129 }
9130 } else {
9131 if (!newProps) {
9132 !(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;
9133 // This can happen when we abort work.
9134 break;
9135 }
9136
9137 var currentHostContext = getHostContext();
9138 // TODO: Move createInstance to beginWork and keep it on a context
9139 // "stack" as the parent. Then append children as we go in beginWork
9140 // or completeWork depending on we want to add then top->down or
9141 // bottom->up. Top->down is faster in IE11.
9142 var wasHydrated = popHydrationState(workInProgress);
9143 if (wasHydrated) {
9144 // TODO: Move this and createInstance step into the beginPhase
9145 // to consolidate.
9146 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
9147 // If changes to the hydrated node needs to be applied at the
9148 // commit-phase we mark this as such.
9149 markUpdate(workInProgress);
9150 }
9151 } else {
9152 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
9153
9154 appendAllChildren(instance, workInProgress, false, false);
9155
9156 // Certain renderers require commit-time effects for initial mount.
9157 // (eg DOM renderer supports auto-focus for certain elements).
9158 // Make sure such renderers get scheduled for later work.
9159 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance, currentHostContext)) {
9160 markUpdate(workInProgress);
9161 }
9162 workInProgress.stateNode = instance;
9163 }
9164
9165 if (workInProgress.ref !== null) {
9166 // If there is a ref on a host node we need to schedule a callback
9167 markRef$1(workInProgress);
9168 }
9169 }
9170 break;
9171 }
9172 case HostText:
9173 {
9174 var newText = newProps;
9175 if (current && workInProgress.stateNode != null) {
9176 var oldText = current.memoizedProps;
9177 // If we have an alternate, that means this is an update and we need
9178 // to schedule a side-effect to do the updates.
9179 updateHostText$1(current, workInProgress, oldText, newText);
9180 } else {
9181 if (typeof newText !== 'string') {
9182 !(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;
9183 // This can happen when we abort work.
9184 }
9185 var _rootContainerInstance = getRootHostContainer();
9186 var _currentHostContext = getHostContext();
9187 var _wasHydrated = popHydrationState(workInProgress);
9188 if (_wasHydrated) {
9189 if (prepareToHydrateHostTextInstance(workInProgress)) {
9190 markUpdate(workInProgress);
9191 }
9192 } else {
9193 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
9194 }
9195 }
9196 break;
9197 }
9198 case ForwardRef:
9199 break;
9200 case SuspenseComponent:
9201 {
9202 var nextState = workInProgress.memoizedState;
9203 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
9204 // Something suspended. Re-render with the fallback children.
9205 workInProgress.expirationTime = renderExpirationTime;
9206 // Do not reset the effect list.
9207 return workInProgress;
9208 }
9209
9210 var nextDidTimeout = nextState !== null;
9211 var prevDidTimeout = current !== null && current.memoizedState !== null;
9212
9213 if (current !== null && !nextDidTimeout && prevDidTimeout) {
9214 // We just switched from the fallback to the normal children. Delete
9215 // the fallback.
9216 // TODO: Would it be better to store the fallback fragment on
9217 var currentFallbackChild = current.child.sibling;
9218 if (currentFallbackChild !== null) {
9219 // Deletions go at the beginning of the return fiber's effect list
9220 var first = workInProgress.firstEffect;
9221 if (first !== null) {
9222 workInProgress.firstEffect = currentFallbackChild;
9223 currentFallbackChild.nextEffect = first;
9224 } else {
9225 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
9226 currentFallbackChild.nextEffect = null;
9227 }
9228 currentFallbackChild.effectTag = Deletion;
9229 }
9230 }
9231
9232 if (nextDidTimeout || prevDidTimeout) {
9233 // If the children are hidden, or if they were previous hidden, schedule
9234 // an effect to toggle their visibility. This is also used to attach a
9235 // retry listener to the promise.
9236 workInProgress.effectTag |= Update;
9237 }
9238 break;
9239 }
9240 case Fragment:
9241 break;
9242 case Mode:
9243 break;
9244 case Profiler:
9245 break;
9246 case HostPortal:
9247 popHostContainer(workInProgress);
9248 updateHostContainer(workInProgress);
9249 break;
9250 case ContextProvider:
9251 // Pop provider fiber
9252 popProvider(workInProgress);
9253 break;
9254 case ContextConsumer:
9255 break;
9256 case MemoComponent:
9257 break;
9258 case IncompleteClassComponent:
9259 {
9260 // Same as class component case. I put it down here so that the tags are
9261 // sequential to ensure this switch is compiled to a jump table.
9262 var _Component = workInProgress.type;
9263 if (isContextProvider(_Component)) {
9264 popContext(workInProgress);
9265 }
9266 break;
9267 }
9268 default:
9269 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
9270 }
9271
9272 return null;
9273}
9274
9275function shouldCaptureSuspense(workInProgress) {
9276 // In order to capture, the Suspense component must have a fallback prop.
9277 if (workInProgress.memoizedProps.fallback === undefined) {
9278 return false;
9279 }
9280 // If it was the primary children that just suspended, capture and render the
9281 // fallback. Otherwise, don't capture and bubble to the next boundary.
9282 var nextState = workInProgress.memoizedState;
9283 return nextState === null;
9284}
9285
9286// This module is forked in different environments.
9287// By default, return `true` to log errors to the console.
9288// Forks can return `false` if this isn't desirable.
9289function showErrorDialog(capturedError) {
9290 return true;
9291}
9292
9293function logCapturedError(capturedError) {
9294 var logError = showErrorDialog(capturedError);
9295
9296 // Allow injected showErrorDialog() to prevent default console.error logging.
9297 // This enables renderers like ReactNative to better manage redbox behavior.
9298 if (logError === false) {
9299 return;
9300 }
9301
9302 var error = capturedError.error;
9303 {
9304 var componentName = capturedError.componentName,
9305 componentStack = capturedError.componentStack,
9306 errorBoundaryName = capturedError.errorBoundaryName,
9307 errorBoundaryFound = capturedError.errorBoundaryFound,
9308 willRetry = capturedError.willRetry;
9309
9310 // Browsers support silencing uncaught errors by calling
9311 // `preventDefault()` in window `error` handler.
9312 // We record this information as an expando on the error.
9313
9314 if (error != null && error._suppressLogging) {
9315 if (errorBoundaryFound && willRetry) {
9316 // The error is recoverable and was silenced.
9317 // Ignore it and don't print the stack addendum.
9318 // This is handy for testing error boundaries without noise.
9319 return;
9320 }
9321 // The error is fatal. Since the silencing might have
9322 // been accidental, we'll surface it anyway.
9323 // However, the browser would have silenced the original error
9324 // so we'll print it first, and then print the stack addendum.
9325 console.error(error);
9326 // For a more detailed description of this block, see:
9327 // https://github.com/facebook/react/pull/13384
9328 }
9329
9330 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
9331
9332 var errorBoundaryMessage = void 0;
9333 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
9334 if (errorBoundaryFound && errorBoundaryName) {
9335 if (willRetry) {
9336 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
9337 } else {
9338 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
9339 }
9340 } else {
9341 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.';
9342 }
9343 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
9344
9345 // In development, we provide our own message with just the component stack.
9346 // We don't include the original error message and JS stack because the browser
9347 // has already printed it. Even if the application swallows the error, it is still
9348 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
9349 console.error(combinedMessage);
9350 }
9351}
9352
9353var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
9354{
9355 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
9356}
9357
9358var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
9359
9360function logError(boundary, errorInfo) {
9361 var source = errorInfo.source;
9362 var stack = errorInfo.stack;
9363 if (stack === null && source !== null) {
9364 stack = getStackByFiberInDevAndProd(source);
9365 }
9366
9367 var capturedError = {
9368 componentName: source !== null ? getComponentName(source.type) : null,
9369 componentStack: stack !== null ? stack : '',
9370 error: errorInfo.value,
9371 errorBoundary: null,
9372 errorBoundaryName: null,
9373 errorBoundaryFound: false,
9374 willRetry: false
9375 };
9376
9377 if (boundary !== null && boundary.tag === ClassComponent) {
9378 capturedError.errorBoundary = boundary.stateNode;
9379 capturedError.errorBoundaryName = getComponentName(boundary.type);
9380 capturedError.errorBoundaryFound = true;
9381 capturedError.willRetry = true;
9382 }
9383
9384 try {
9385 logCapturedError(capturedError);
9386 } catch (e) {
9387 // This method must not throw, or React internal state will get messed up.
9388 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
9389 // we want to report this error outside of the normal stack as a last resort.
9390 // https://github.com/facebook/react/issues/13188
9391 setTimeout(function () {
9392 throw e;
9393 });
9394 }
9395}
9396
9397var callComponentWillUnmountWithTimer = function (current, instance) {
9398 startPhaseTimer(current, 'componentWillUnmount');
9399 instance.props = current.memoizedProps;
9400 instance.state = current.memoizedState;
9401 instance.componentWillUnmount();
9402 stopPhaseTimer();
9403};
9404
9405// Capture errors so they don't interrupt unmounting.
9406function safelyCallComponentWillUnmount(current, instance) {
9407 {
9408 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance);
9409 if (hasCaughtError()) {
9410 var unmountError = clearCaughtError();
9411 captureCommitPhaseError(current, unmountError);
9412 }
9413 }
9414}
9415
9416function safelyDetachRef(current) {
9417 var ref = current.ref;
9418 if (ref !== null) {
9419 if (typeof ref === 'function') {
9420 {
9421 invokeGuardedCallback(null, ref, null, null);
9422 if (hasCaughtError()) {
9423 var refError = clearCaughtError();
9424 captureCommitPhaseError(current, refError);
9425 }
9426 }
9427 } else {
9428 ref.current = null;
9429 }
9430 }
9431}
9432
9433function safelyCallDestroy(current, destroy) {
9434 {
9435 invokeGuardedCallback(null, destroy, null);
9436 if (hasCaughtError()) {
9437 var error = clearCaughtError();
9438 captureCommitPhaseError(current, error);
9439 }
9440 }
9441}
9442
9443function commitBeforeMutationLifeCycles(current, finishedWork) {
9444 switch (finishedWork.tag) {
9445 case FunctionComponent:
9446 case ForwardRef:
9447 case SimpleMemoComponent:
9448 {
9449 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
9450 return;
9451 }
9452 case ClassComponent:
9453 {
9454 if (finishedWork.effectTag & Snapshot) {
9455 if (current !== null) {
9456 var prevProps = current.memoizedProps;
9457 var prevState = current.memoizedState;
9458 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
9459 var instance = finishedWork.stateNode;
9460 // We could update instance props and state here,
9461 // but instead we rely on them being set during last render.
9462 // TODO: revisit this when we implement resuming.
9463 {
9464 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
9465 !(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;
9466 !(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;
9467 }
9468 }
9469 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
9470 {
9471 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
9472 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
9473 didWarnSet.add(finishedWork.type);
9474 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
9475 }
9476 }
9477 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
9478 stopPhaseTimer();
9479 }
9480 }
9481 return;
9482 }
9483 case HostRoot:
9484 case HostComponent:
9485 case HostText:
9486 case HostPortal:
9487 case IncompleteClassComponent:
9488 // Nothing to do for these component types
9489 return;
9490 default:
9491 {
9492 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.');
9493 }
9494 }
9495}
9496
9497function commitHookEffectList(unmountTag, mountTag, finishedWork) {
9498 var updateQueue = finishedWork.updateQueue;
9499 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
9500 if (lastEffect !== null) {
9501 var firstEffect = lastEffect.next;
9502 var effect = firstEffect;
9503 do {
9504 if ((effect.tag & unmountTag) !== NoEffect$1) {
9505 // Unmount
9506 var destroy = effect.destroy;
9507 effect.destroy = undefined;
9508 if (destroy !== undefined) {
9509 destroy();
9510 }
9511 }
9512 if ((effect.tag & mountTag) !== NoEffect$1) {
9513 // Mount
9514 var create = effect.create;
9515 effect.destroy = create();
9516
9517 {
9518 var _destroy = effect.destroy;
9519 if (_destroy !== undefined && typeof _destroy !== 'function') {
9520 var addendum = void 0;
9521 if (_destroy === null) {
9522 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
9523 } else if (typeof _destroy.then === 'function') {
9524 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.";
9525 } else {
9526 addendum = ' You returned: ' + _destroy;
9527 }
9528 warningWithoutStack$1(false, 'An Effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
9529 }
9530 }
9531 }
9532 effect = effect.next;
9533 } while (effect !== firstEffect);
9534 }
9535}
9536
9537function commitPassiveHookEffects(finishedWork) {
9538 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
9539 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
9540}
9541
9542function commitLifeCycles(finishedRoot, current, finishedWork, committedExpirationTime) {
9543 switch (finishedWork.tag) {
9544 case FunctionComponent:
9545 case ForwardRef:
9546 case SimpleMemoComponent:
9547 {
9548 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
9549 break;
9550 }
9551 case ClassComponent:
9552 {
9553 var instance = finishedWork.stateNode;
9554 if (finishedWork.effectTag & Update) {
9555 if (current === null) {
9556 startPhaseTimer(finishedWork, 'componentDidMount');
9557 // We could update instance props and state here,
9558 // but instead we rely on them being set during last render.
9559 // TODO: revisit this when we implement resuming.
9560 {
9561 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
9562 !(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;
9563 !(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;
9564 }
9565 }
9566 instance.componentDidMount();
9567 stopPhaseTimer();
9568 } else {
9569 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
9570 var prevState = current.memoizedState;
9571 startPhaseTimer(finishedWork, 'componentDidUpdate');
9572 // We could update instance props and state here,
9573 // but instead we rely on them being set during last render.
9574 // TODO: revisit this when we implement resuming.
9575 {
9576 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
9577 !(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;
9578 !(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;
9579 }
9580 }
9581 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
9582 stopPhaseTimer();
9583 }
9584 }
9585 var updateQueue = finishedWork.updateQueue;
9586 if (updateQueue !== null) {
9587 {
9588 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
9589 !(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;
9590 !(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;
9591 }
9592 }
9593 // We could update instance props and state here,
9594 // but instead we rely on them being set during last render.
9595 // TODO: revisit this when we implement resuming.
9596 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
9597 }
9598 return;
9599 }
9600 case HostRoot:
9601 {
9602 var _updateQueue = finishedWork.updateQueue;
9603 if (_updateQueue !== null) {
9604 var _instance = null;
9605 if (finishedWork.child !== null) {
9606 switch (finishedWork.child.tag) {
9607 case HostComponent:
9608 _instance = getPublicInstance(finishedWork.child.stateNode);
9609 break;
9610 case ClassComponent:
9611 _instance = finishedWork.child.stateNode;
9612 break;
9613 }
9614 }
9615 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime);
9616 }
9617 return;
9618 }
9619 case HostComponent:
9620 {
9621 var _instance2 = finishedWork.stateNode;
9622
9623 // Renderers may schedule work to be done after host components are mounted
9624 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
9625 // These effects should only be committed when components are first mounted,
9626 // aka when there is no current/alternate.
9627 if (current === null && finishedWork.effectTag & Update) {
9628 var type = finishedWork.type;
9629 var props = finishedWork.memoizedProps;
9630
9631 }
9632
9633 return;
9634 }
9635 case HostText:
9636 {
9637 // We have no life-cycles associated with text.
9638 return;
9639 }
9640 case HostPortal:
9641 {
9642 // We have no life-cycles associated with portals.
9643 return;
9644 }
9645 case Profiler:
9646 {
9647 if (enableProfilerTimer) {
9648 var onRender = finishedWork.memoizedProps.onRender;
9649
9650 if (enableSchedulerTracing) {
9651 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
9652 } else {
9653 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime());
9654 }
9655 }
9656 return;
9657 }
9658 case SuspenseComponent:
9659 break;
9660 case IncompleteClassComponent:
9661 break;
9662 default:
9663 {
9664 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.');
9665 }
9666 }
9667}
9668
9669function hideOrUnhideAllChildren(finishedWork, isHidden) {
9670 if (supportsMutation) {
9671 // We only have the top Fiber that was inserted but we need recurse down its
9672 var node = finishedWork;
9673 while (true) {
9674 if (node.tag === HostComponent) {
9675 var instance = node.stateNode;
9676 if (isHidden) {
9677 hideInstance(instance);
9678 } else {
9679 unhideInstance(node.stateNode, node.memoizedProps);
9680 }
9681 } else if (node.tag === HostText) {
9682 var _instance3 = node.stateNode;
9683 if (isHidden) {
9684
9685 } else {
9686 unhideTextInstance(_instance3, node.memoizedProps);
9687 }
9688 } else if (node.tag === SuspenseComponent && node.memoizedState !== null) {
9689 // Found a nested Suspense component that timed out. Skip over the
9690 var fallbackChildFragment = node.child.sibling;
9691 fallbackChildFragment.return = node;
9692 node = fallbackChildFragment;
9693 continue;
9694 } else if (node.child !== null) {
9695 node.child.return = node;
9696 node = node.child;
9697 continue;
9698 }
9699 if (node === finishedWork) {
9700 return;
9701 }
9702 while (node.sibling === null) {
9703 if (node.return === null || node.return === finishedWork) {
9704 return;
9705 }
9706 node = node.return;
9707 }
9708 node.sibling.return = node.return;
9709 node = node.sibling;
9710 }
9711 }
9712}
9713
9714function commitAttachRef(finishedWork) {
9715 var ref = finishedWork.ref;
9716 if (ref !== null) {
9717 var instance = finishedWork.stateNode;
9718 var instanceToUse = void 0;
9719 switch (finishedWork.tag) {
9720 case HostComponent:
9721 instanceToUse = getPublicInstance(instance);
9722 break;
9723 default:
9724 instanceToUse = instance;
9725 }
9726 if (typeof ref === 'function') {
9727 ref(instanceToUse);
9728 } else {
9729 {
9730 if (!ref.hasOwnProperty('current')) {
9731 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
9732 }
9733 }
9734
9735 ref.current = instanceToUse;
9736 }
9737 }
9738}
9739
9740function commitDetachRef(current) {
9741 var currentRef = current.ref;
9742 if (currentRef !== null) {
9743 if (typeof currentRef === 'function') {
9744 currentRef(null);
9745 } else {
9746 currentRef.current = null;
9747 }
9748 }
9749}
9750
9751// User-originating errors (lifecycles and refs) should not interrupt
9752// deletion, so don't let them throw. Host-originating errors should
9753// interrupt deletion, so it's okay
9754function commitUnmount(current) {
9755 onCommitUnmount(current);
9756
9757 switch (current.tag) {
9758 case FunctionComponent:
9759 case ForwardRef:
9760 case MemoComponent:
9761 case SimpleMemoComponent:
9762 {
9763 var updateQueue = current.updateQueue;
9764 if (updateQueue !== null) {
9765 var lastEffect = updateQueue.lastEffect;
9766 if (lastEffect !== null) {
9767 var firstEffect = lastEffect.next;
9768 var effect = firstEffect;
9769 do {
9770 var destroy = effect.destroy;
9771 if (destroy !== undefined) {
9772 safelyCallDestroy(current, destroy);
9773 }
9774 effect = effect.next;
9775 } while (effect !== firstEffect);
9776 }
9777 }
9778 break;
9779 }
9780 case ClassComponent:
9781 {
9782 safelyDetachRef(current);
9783 var instance = current.stateNode;
9784 if (typeof instance.componentWillUnmount === 'function') {
9785 safelyCallComponentWillUnmount(current, instance);
9786 }
9787 return;
9788 }
9789 case HostComponent:
9790 {
9791 safelyDetachRef(current);
9792 return;
9793 }
9794 case HostPortal:
9795 {
9796 // TODO: this is recursive.
9797 // We are also not using this parent because
9798 // the portal will get pushed immediately.
9799 if (supportsMutation) {
9800 unmountHostComponents(current);
9801 } else if (supportsPersistence) {
9802 emptyPortalContainer(current);
9803 }
9804 return;
9805 }
9806 }
9807}
9808
9809function commitNestedUnmounts(root) {
9810 // While we're inside a removed host node we don't want to call
9811 // removeChild on the inner nodes because they're removed by the top
9812 // call anyway. We also want to call componentWillUnmount on all
9813 // composites before this host node is removed from the tree. Therefore
9814 var node = root;
9815 while (true) {
9816 commitUnmount(node);
9817 // Visit children because they may contain more composite or host nodes.
9818 // Skip portals because commitUnmount() currently visits them recursively.
9819 if (node.child !== null && (
9820 // If we use mutation we drill down into portals using commitUnmount above.
9821 // If we don't use mutation we drill down into portals here instead.
9822 !supportsMutation || node.tag !== HostPortal)) {
9823 node.child.return = node;
9824 node = node.child;
9825 continue;
9826 }
9827 if (node === root) {
9828 return;
9829 }
9830 while (node.sibling === null) {
9831 if (node.return === null || node.return === root) {
9832 return;
9833 }
9834 node = node.return;
9835 }
9836 node.sibling.return = node.return;
9837 node = node.sibling;
9838 }
9839}
9840
9841function detachFiber(current) {
9842 // Cut off the return pointers to disconnect it from the tree. Ideally, we
9843 // should clear the child pointer of the parent alternate to let this
9844 // get GC:ed but we don't know which for sure which parent is the current
9845 // one so we'll settle for GC:ing the subtree of this child. This child
9846 // itself will be GC:ed when the parent updates the next time.
9847 current.return = null;
9848 current.child = null;
9849 current.memoizedState = null;
9850 current.updateQueue = null;
9851 var alternate = current.alternate;
9852 if (alternate !== null) {
9853 alternate.return = null;
9854 alternate.child = null;
9855 alternate.memoizedState = null;
9856 alternate.updateQueue = null;
9857 }
9858}
9859
9860function emptyPortalContainer(current) {
9861 if (!supportsPersistence) {
9862 return;
9863 }
9864
9865 var portal = current.stateNode;
9866 var containerInfo = portal.containerInfo;
9867
9868 var emptyChildSet = createContainerChildSet(containerInfo);
9869 replaceContainerChildren(containerInfo, emptyChildSet);
9870}
9871
9872function commitContainer(finishedWork) {
9873 if (!supportsPersistence) {
9874 return;
9875 }
9876
9877 switch (finishedWork.tag) {
9878 case ClassComponent:
9879 {
9880 return;
9881 }
9882 case HostComponent:
9883 {
9884 return;
9885 }
9886 case HostText:
9887 {
9888 return;
9889 }
9890 case HostRoot:
9891 case HostPortal:
9892 {
9893 var portalOrRoot = finishedWork.stateNode;
9894 var containerInfo = portalOrRoot.containerInfo,
9895 _pendingChildren = portalOrRoot.pendingChildren;
9896
9897 replaceContainerChildren(containerInfo, _pendingChildren);
9898 return;
9899 }
9900 default:
9901 {
9902 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.');
9903 }
9904 }
9905}
9906
9907function getHostParentFiber(fiber) {
9908 var parent = fiber.return;
9909 while (parent !== null) {
9910 if (isHostParent(parent)) {
9911 return parent;
9912 }
9913 parent = parent.return;
9914 }
9915 invariant(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.');
9916}
9917
9918function isHostParent(fiber) {
9919 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
9920}
9921
9922function getHostSibling(fiber) {
9923 // We're going to search forward into the tree until we find a sibling host
9924 // node. Unfortunately, if multiple insertions are done in a row we have to
9925 // search past them. This leads to exponential search for the next sibling.
9926 var node = fiber;
9927 siblings: while (true) {
9928 // If we didn't find anything, let's try the next sibling.
9929 while (node.sibling === null) {
9930 if (node.return === null || isHostParent(node.return)) {
9931 // If we pop out of the root or hit the parent the fiber we are the
9932 // last sibling.
9933 return null;
9934 }
9935 node = node.return;
9936 }
9937 node.sibling.return = node.return;
9938 node = node.sibling;
9939 while (node.tag !== HostComponent && node.tag !== HostText) {
9940 // If it is not host node and, we might have a host node inside it.
9941 // Try to search down until we find one.
9942 if (node.effectTag & Placement) {
9943 // If we don't have a child, try the siblings instead.
9944 continue siblings;
9945 }
9946 // If we don't have a child, try the siblings instead.
9947 // We also skip portals because they are not part of this host tree.
9948 if (node.child === null || node.tag === HostPortal) {
9949 continue siblings;
9950 } else {
9951 node.child.return = node;
9952 node = node.child;
9953 }
9954 }
9955 // Check if this host node is stable or about to be placed.
9956 if (!(node.effectTag & Placement)) {
9957 // Found it!
9958 return node.stateNode;
9959 }
9960 }
9961}
9962
9963function commitPlacement(finishedWork) {
9964 if (!supportsMutation) {
9965 return;
9966 }
9967
9968 // Recursively insert all host nodes into the parent.
9969 var parentFiber = getHostParentFiber(finishedWork);
9970
9971 // Note: these two variables *must* always be updated together.
9972 var parent = void 0;
9973 var isContainer = void 0;
9974
9975 switch (parentFiber.tag) {
9976 case HostComponent:
9977 parent = parentFiber.stateNode;
9978 isContainer = false;
9979 break;
9980 case HostRoot:
9981 parent = parentFiber.stateNode.containerInfo;
9982 isContainer = true;
9983 break;
9984 case HostPortal:
9985 parent = parentFiber.stateNode.containerInfo;
9986 isContainer = true;
9987 break;
9988 default:
9989 invariant(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.');
9990 }
9991 if (parentFiber.effectTag & ContentReset) {
9992 // Reset the text content of the parent before doing any insertions
9993 parentFiber.effectTag &= ~ContentReset;
9994 }
9995
9996 var before = getHostSibling(finishedWork);
9997 // We only have the top Fiber that was inserted but we need recurse down its
9998 // children to find all the terminal nodes.
9999 var node = finishedWork;
10000 while (true) {
10001 if (node.tag === HostComponent || node.tag === HostText) {
10002 if (before) {
10003 if (isContainer) {
10004 insertInContainerBefore(parent, node.stateNode, before);
10005 } else {
10006 insertBefore(parent, node.stateNode, before);
10007 }
10008 } else {
10009 if (isContainer) {
10010 appendChildToContainer(parent, node.stateNode);
10011 } else {
10012 appendChild(parent, node.stateNode);
10013 }
10014 }
10015 } else if (node.tag === HostPortal) {
10016 // If the insertion itself is a portal, then we don't want to traverse
10017 // down its children. Instead, we'll get insertions from each child in
10018 // the portal directly.
10019 } else if (node.child !== null) {
10020 node.child.return = node;
10021 node = node.child;
10022 continue;
10023 }
10024 if (node === finishedWork) {
10025 return;
10026 }
10027 while (node.sibling === null) {
10028 if (node.return === null || node.return === finishedWork) {
10029 return;
10030 }
10031 node = node.return;
10032 }
10033 node.sibling.return = node.return;
10034 node = node.sibling;
10035 }
10036}
10037
10038function unmountHostComponents(current) {
10039 // We only have the top Fiber that was deleted but we need recurse down its
10040 var node = current;
10041
10042 // Each iteration, currentParent is populated with node's host parent if not
10043 // currentParentIsValid.
10044 var currentParentIsValid = false;
10045
10046 // Note: these two variables *must* always be updated together.
10047 var currentParent = void 0;
10048 var currentParentIsContainer = void 0;
10049
10050 while (true) {
10051 if (!currentParentIsValid) {
10052 var parent = node.return;
10053 findParent: while (true) {
10054 !(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;
10055 switch (parent.tag) {
10056 case HostComponent:
10057 currentParent = parent.stateNode;
10058 currentParentIsContainer = false;
10059 break findParent;
10060 case HostRoot:
10061 currentParent = parent.stateNode.containerInfo;
10062 currentParentIsContainer = true;
10063 break findParent;
10064 case HostPortal:
10065 currentParent = parent.stateNode.containerInfo;
10066 currentParentIsContainer = true;
10067 break findParent;
10068 }
10069 parent = parent.return;
10070 }
10071 currentParentIsValid = true;
10072 }
10073
10074 if (node.tag === HostComponent || node.tag === HostText) {
10075 commitNestedUnmounts(node);
10076 // After all the children have unmounted, it is now safe to remove the
10077 // node from the tree.
10078 if (currentParentIsContainer) {
10079 removeChildFromContainer(currentParent, node.stateNode);
10080 } else {
10081 removeChild(currentParent, node.stateNode);
10082 }
10083 // Don't visit children because we already visited them.
10084 } else if (node.tag === HostPortal) {
10085 // When we go into a portal, it becomes the parent to remove from.
10086 // We will reassign it back when we pop the portal on the way up.
10087 currentParent = node.stateNode.containerInfo;
10088 currentParentIsContainer = true;
10089 // Visit children because portals might contain host components.
10090 if (node.child !== null) {
10091 node.child.return = node;
10092 node = node.child;
10093 continue;
10094 }
10095 } else {
10096 commitUnmount(node);
10097 // Visit children because we may find more host components below.
10098 if (node.child !== null) {
10099 node.child.return = node;
10100 node = node.child;
10101 continue;
10102 }
10103 }
10104 if (node === current) {
10105 return;
10106 }
10107 while (node.sibling === null) {
10108 if (node.return === null || node.return === current) {
10109 return;
10110 }
10111 node = node.return;
10112 if (node.tag === HostPortal) {
10113 // When we go out of the portal, we need to restore the parent.
10114 // Since we don't keep a stack of them, we will search for it.
10115 currentParentIsValid = false;
10116 }
10117 }
10118 node.sibling.return = node.return;
10119 node = node.sibling;
10120 }
10121}
10122
10123function commitDeletion(current) {
10124 if (supportsMutation) {
10125 // Recursively delete all host nodes from the parent.
10126 // Detach refs and call componentWillUnmount() on the whole subtree.
10127 unmountHostComponents(current);
10128 } else {
10129 // Detach refs and call componentWillUnmount() on the whole subtree.
10130 commitNestedUnmounts(current);
10131 }
10132 detachFiber(current);
10133}
10134
10135function commitWork(current, finishedWork) {
10136 if (!supportsMutation) {
10137 switch (finishedWork.tag) {
10138 case FunctionComponent:
10139 case ForwardRef:
10140 case MemoComponent:
10141 case SimpleMemoComponent:
10142 {
10143 // Note: We currently never use MountMutation, but useLayout uses
10144 // UnmountMutation.
10145 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
10146 return;
10147 }
10148 }
10149
10150 commitContainer(finishedWork);
10151 return;
10152 }
10153
10154 switch (finishedWork.tag) {
10155 case FunctionComponent:
10156 case ForwardRef:
10157 case MemoComponent:
10158 case SimpleMemoComponent:
10159 {
10160 // Note: We currently never use MountMutation, but useLayout uses
10161 // UnmountMutation.
10162 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
10163 return;
10164 }
10165 case ClassComponent:
10166 {
10167 return;
10168 }
10169 case HostComponent:
10170 {
10171 var instance = finishedWork.stateNode;
10172 if (instance != null) {
10173 // Commit the work prepared earlier.
10174 var newProps = finishedWork.memoizedProps;
10175 // For hydration we reuse the update path but we treat the oldProps
10176 // as the newProps. The updatePayload will contain the real change in
10177 // this case.
10178 var oldProps = current !== null ? current.memoizedProps : newProps;
10179 var type = finishedWork.type;
10180 // TODO: Type the updateQueue to be specific to host components.
10181 var updatePayload = finishedWork.updateQueue;
10182 finishedWork.updateQueue = null;
10183 if (updatePayload !== null) {
10184 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
10185 }
10186 }
10187 return;
10188 }
10189 case HostText:
10190 {
10191 !(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;
10192 var textInstance = finishedWork.stateNode;
10193 var newText = finishedWork.memoizedProps;
10194 // For hydration we reuse the update path but we treat the oldProps
10195 // as the newProps. The updatePayload will contain the real change in
10196 // this case.
10197 var oldText = current !== null ? current.memoizedProps : newText;
10198 return;
10199 }
10200 case HostRoot:
10201 {
10202 return;
10203 }
10204 case Profiler:
10205 {
10206 return;
10207 }
10208 case SuspenseComponent:
10209 {
10210 var newState = finishedWork.memoizedState;
10211
10212 var newDidTimeout = void 0;
10213 var primaryChildParent = finishedWork;
10214 if (newState === null) {
10215 newDidTimeout = false;
10216 } else {
10217 newDidTimeout = true;
10218 primaryChildParent = finishedWork.child;
10219 if (newState.timedOutAt === NoWork) {
10220 // If the children had not already timed out, record the time.
10221 // This is used to compute the elapsed time during subsequent
10222 // attempts to render the children.
10223 newState.timedOutAt = requestCurrentTime();
10224 }
10225 }
10226
10227 if (primaryChildParent !== null) {
10228 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
10229 }
10230
10231 // If this boundary just timed out, then it will have a set of thenables.
10232 // For each thenable, attach a listener so that when it resolves, React
10233 // attempts to re-render the boundary in the primary (pre-timeout) state.
10234 var thenables = finishedWork.updateQueue;
10235 if (thenables !== null) {
10236 finishedWork.updateQueue = null;
10237 var retryCache = finishedWork.stateNode;
10238 if (retryCache === null) {
10239 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
10240 }
10241 thenables.forEach(function (thenable) {
10242 // Memoize using the boundary fiber to prevent redundant listeners.
10243 var retry = retryTimedOutBoundary.bind(null, finishedWork, thenable);
10244 if (enableSchedulerTracing) {
10245 retry = unstable_wrap(retry);
10246 }
10247 if (!retryCache.has(thenable)) {
10248 retryCache.add(thenable);
10249 thenable.then(retry, retry);
10250 }
10251 });
10252 }
10253
10254 return;
10255 }
10256 case IncompleteClassComponent:
10257 {
10258 return;
10259 }
10260 default:
10261 {
10262 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.');
10263 }
10264 }
10265}
10266
10267function commitResetTextContent(current) {
10268 if (!supportsMutation) {
10269 return;
10270 }
10271 resetTextContent(current.stateNode);
10272}
10273
10274var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
10275
10276function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
10277 var update = createUpdate(expirationTime);
10278 // Unmount the root by rendering null.
10279 update.tag = CaptureUpdate;
10280 // Caution: React DevTools currently depends on this property
10281 // being called "element".
10282 update.payload = { element: null };
10283 var error = errorInfo.value;
10284 update.callback = function () {
10285 onUncaughtError(error);
10286 logError(fiber, errorInfo);
10287 };
10288 return update;
10289}
10290
10291function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
10292 var update = createUpdate(expirationTime);
10293 update.tag = CaptureUpdate;
10294 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
10295 if (typeof getDerivedStateFromError === 'function') {
10296 var error = errorInfo.value;
10297 update.payload = function () {
10298 return getDerivedStateFromError(error);
10299 };
10300 }
10301
10302 var inst = fiber.stateNode;
10303 if (inst !== null && typeof inst.componentDidCatch === 'function') {
10304 update.callback = function callback() {
10305 if (typeof getDerivedStateFromError !== 'function') {
10306 // To preserve the preexisting retry behavior of error boundaries,
10307 // we keep track of which ones already failed during this batch.
10308 // This gets reset before we yield back to the browser.
10309 // TODO: Warn in strict mode if getDerivedStateFromError is
10310 // not defined.
10311 markLegacyErrorBoundaryAsFailed(this);
10312 }
10313 var error = errorInfo.value;
10314 var stack = errorInfo.stack;
10315 logError(fiber, errorInfo);
10316 this.componentDidCatch(error, {
10317 componentStack: stack !== null ? stack : ''
10318 });
10319 {
10320 if (typeof getDerivedStateFromError !== 'function') {
10321 // If componentDidCatch is the only error boundary method defined,
10322 // then it needs to call setState to recover from errors.
10323 // If no state update is scheduled then the boundary will swallow the error.
10324 !(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;
10325 }
10326 }
10327 };
10328 }
10329 return update;
10330}
10331
10332function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
10333 // The source fiber did not complete.
10334 sourceFiber.effectTag |= Incomplete;
10335 // Its effect list is no longer valid.
10336 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
10337
10338 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
10339 // This is a thenable.
10340 var thenable = value;
10341
10342 // Find the earliest timeout threshold of all the placeholders in the
10343 // ancestor path. We could avoid this traversal by storing the thresholds on
10344 // the stack, but we choose not to because we only hit this path if we're
10345 // IO-bound (i.e. if something suspends). Whereas the stack is used even in
10346 // the non-IO- bound case.
10347 var _workInProgress = returnFiber;
10348 var earliestTimeoutMs = -1;
10349 var startTimeMs = -1;
10350 do {
10351 if (_workInProgress.tag === SuspenseComponent) {
10352 var current = _workInProgress.alternate;
10353 if (current !== null) {
10354 var currentState = current.memoizedState;
10355 if (currentState !== null) {
10356 // Reached a boundary that already timed out. Do not search
10357 // any further.
10358 var timedOutAt = currentState.timedOutAt;
10359 startTimeMs = expirationTimeToMs(timedOutAt);
10360 // Do not search any further.
10361 break;
10362 }
10363 }
10364 var timeoutPropMs = _workInProgress.pendingProps.maxDuration;
10365 if (typeof timeoutPropMs === 'number') {
10366 if (timeoutPropMs <= 0) {
10367 earliestTimeoutMs = 0;
10368 } else if (earliestTimeoutMs === -1 || timeoutPropMs < earliestTimeoutMs) {
10369 earliestTimeoutMs = timeoutPropMs;
10370 }
10371 }
10372 }
10373 _workInProgress = _workInProgress.return;
10374 } while (_workInProgress !== null);
10375
10376 // Schedule the nearest Suspense to re-render the timed out view.
10377 _workInProgress = returnFiber;
10378 do {
10379 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress)) {
10380 // Found the nearest boundary.
10381
10382 // Stash the promise on the boundary fiber. If the boundary times out, we'll
10383 var thenables = _workInProgress.updateQueue;
10384 if (thenables === null) {
10385 var updateQueue = new Set();
10386 updateQueue.add(thenable);
10387 _workInProgress.updateQueue = updateQueue;
10388 } else {
10389 thenables.add(thenable);
10390 }
10391
10392 // If the boundary is outside of concurrent mode, we should *not*
10393 // suspend the commit. Pretend as if the suspended component rendered
10394 // null and keep rendering. In the commit phase, we'll schedule a
10395 // subsequent synchronous update to re-render the Suspense.
10396 //
10397 // Note: It doesn't matter whether the component that suspended was
10398 // inside a concurrent mode tree. If the Suspense is outside of it, we
10399 // should *not* suspend the commit.
10400 if ((_workInProgress.mode & ConcurrentMode) === NoEffect) {
10401 _workInProgress.effectTag |= DidCapture;
10402
10403 // We're going to commit this fiber even though it didn't complete.
10404 // But we shouldn't call any lifecycle methods or callbacks. Remove
10405 // all lifecycle effect tags.
10406 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
10407
10408 if (sourceFiber.tag === ClassComponent) {
10409 var currentSourceFiber = sourceFiber.alternate;
10410 if (currentSourceFiber === null) {
10411 // This is a new mount. Change the tag so it's not mistaken for a
10412 // completed class component. For example, we should not call
10413 // componentWillUnmount if it is deleted.
10414 sourceFiber.tag = IncompleteClassComponent;
10415 } else {
10416 // When we try rendering again, we should not reuse the current fiber,
10417 // since it's known to be in an inconsistent state. Use a force updte to
10418 // prevent a bail out.
10419 var update = createUpdate(Sync);
10420 update.tag = ForceUpdate;
10421 enqueueUpdate(sourceFiber, update);
10422 }
10423 }
10424
10425 // The source fiber did not complete. Mark it with Sync priority to
10426 // indicate that it still has pending work.
10427 sourceFiber.expirationTime = Sync;
10428
10429 // Exit without suspending.
10430 return;
10431 }
10432
10433 // Confirmed that the boundary is in a concurrent mode tree. Continue
10434 // with the normal suspend path.
10435
10436 // Attach a listener to the promise to "ping" the root and retry. But
10437 // only if one does not already exist for the current render expiration
10438 // time (which acts like a "thread ID" here).
10439 var pingCache = root.pingCache;
10440 var threadIDs = void 0;
10441 if (pingCache === null) {
10442 pingCache = root.pingCache = new PossiblyWeakMap();
10443 threadIDs = new Set();
10444 pingCache.set(thenable, threadIDs);
10445 } else {
10446 threadIDs = pingCache.get(thenable);
10447 if (threadIDs === undefined) {
10448 threadIDs = new Set();
10449 pingCache.set(thenable, threadIDs);
10450 }
10451 }
10452 if (!threadIDs.has(renderExpirationTime)) {
10453 // Memoize using the thread ID to prevent redundant listeners.
10454 threadIDs.add(renderExpirationTime);
10455 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
10456 if (enableSchedulerTracing) {
10457 ping = unstable_wrap(ping);
10458 }
10459 thenable.then(ping, ping);
10460 }
10461
10462 var absoluteTimeoutMs = void 0;
10463 if (earliestTimeoutMs === -1) {
10464 // If no explicit threshold is given, default to an arbitrarily large
10465 // value. The actual size doesn't matter because the threshold for the
10466 // whole tree will be clamped to the expiration time.
10467 absoluteTimeoutMs = maxSigned31BitInt;
10468 } else {
10469 if (startTimeMs === -1) {
10470 // This suspend happened outside of any already timed-out
10471 // placeholders. We don't know exactly when the update was
10472 // scheduled, but we can infer an approximate start time from the
10473 // expiration time. First, find the earliest uncommitted expiration
10474 // time in the tree, including work that is suspended. Then subtract
10475 // the offset used to compute an async update's expiration time.
10476 // This will cause high priority (interactive) work to expire
10477 // earlier than necessary, but we can account for this by adjusting
10478 // for the Just Noticeable Difference.
10479 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, renderExpirationTime);
10480 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
10481 startTimeMs = earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
10482 }
10483 absoluteTimeoutMs = startTimeMs + earliestTimeoutMs;
10484 }
10485
10486 // Mark the earliest timeout in the suspended fiber's ancestor path.
10487 // After completing the root, we'll take the largest of all the
10488 // suspended fiber's timeouts and use it to compute a timeout for the
10489 // whole tree.
10490 renderDidSuspend(root, absoluteTimeoutMs, renderExpirationTime);
10491
10492 _workInProgress.effectTag |= ShouldCapture;
10493 _workInProgress.expirationTime = renderExpirationTime;
10494 return;
10495 }
10496 // This boundary already captured during this render. Continue to the next
10497 // boundary.
10498 _workInProgress = _workInProgress.return;
10499 } while (_workInProgress !== null);
10500 // No boundary was found. Fallthrough to error mode.
10501 // TODO: Use invariant so the message is stripped in prod?
10502 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));
10503 }
10504
10505 // We didn't find a boundary that could handle this type of exception. Start
10506 // over and traverse parent path again, this time treating the exception
10507 // as an error.
10508 renderDidError();
10509 value = createCapturedValue(value, sourceFiber);
10510 var workInProgress = returnFiber;
10511 do {
10512 switch (workInProgress.tag) {
10513 case HostRoot:
10514 {
10515 var _errorInfo = value;
10516 workInProgress.effectTag |= ShouldCapture;
10517 workInProgress.expirationTime = renderExpirationTime;
10518 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
10519 enqueueCapturedUpdate(workInProgress, _update);
10520 return;
10521 }
10522 case ClassComponent:
10523 // Capture and retry
10524 var errorInfo = value;
10525 var ctor = workInProgress.type;
10526 var instance = workInProgress.stateNode;
10527 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
10528 workInProgress.effectTag |= ShouldCapture;
10529 workInProgress.expirationTime = renderExpirationTime;
10530 // Schedule the error boundary to re-render using updated state
10531 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
10532 enqueueCapturedUpdate(workInProgress, _update2);
10533 return;
10534 }
10535 break;
10536 default:
10537 break;
10538 }
10539 workInProgress = workInProgress.return;
10540 } while (workInProgress !== null);
10541}
10542
10543function unwindWork(workInProgress, renderExpirationTime) {
10544 switch (workInProgress.tag) {
10545 case ClassComponent:
10546 {
10547 var Component = workInProgress.type;
10548 if (isContextProvider(Component)) {
10549 popContext(workInProgress);
10550 }
10551 var effectTag = workInProgress.effectTag;
10552 if (effectTag & ShouldCapture) {
10553 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
10554 return workInProgress;
10555 }
10556 return null;
10557 }
10558 case HostRoot:
10559 {
10560 popHostContainer(workInProgress);
10561 popTopLevelContextObject(workInProgress);
10562 var _effectTag = workInProgress.effectTag;
10563 !((_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;
10564 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
10565 return workInProgress;
10566 }
10567 case HostComponent:
10568 {
10569 popHostContext(workInProgress);
10570 return null;
10571 }
10572 case SuspenseComponent:
10573 {
10574 var _effectTag2 = workInProgress.effectTag;
10575 if (_effectTag2 & ShouldCapture) {
10576 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture;
10577 // Captured a suspense effect. Re-render the boundary.
10578 return workInProgress;
10579 }
10580 return null;
10581 }
10582 case HostPortal:
10583 popHostContainer(workInProgress);
10584 return null;
10585 case ContextProvider:
10586 popProvider(workInProgress);
10587 return null;
10588 default:
10589 return null;
10590 }
10591}
10592
10593function unwindInterruptedWork(interruptedWork) {
10594 switch (interruptedWork.tag) {
10595 case ClassComponent:
10596 {
10597 var childContextTypes = interruptedWork.type.childContextTypes;
10598 if (childContextTypes !== null && childContextTypes !== undefined) {
10599 popContext(interruptedWork);
10600 }
10601 break;
10602 }
10603 case HostRoot:
10604 {
10605 popHostContainer(interruptedWork);
10606 popTopLevelContextObject(interruptedWork);
10607 break;
10608 }
10609 case HostComponent:
10610 {
10611 popHostContext(interruptedWork);
10612 break;
10613 }
10614 case HostPortal:
10615 popHostContainer(interruptedWork);
10616 break;
10617 case ContextProvider:
10618 popProvider(interruptedWork);
10619 break;
10620 default:
10621 break;
10622 }
10623}
10624
10625var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
10626var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
10627
10628
10629var didWarnAboutStateTransition = void 0;
10630var didWarnSetStateChildContext = void 0;
10631var warnAboutUpdateOnUnmounted = void 0;
10632var warnAboutInvalidUpdates = void 0;
10633
10634if (enableSchedulerTracing) {
10635 // Provide explicit error message when production+profiling bundle of e.g. react-dom
10636 // is used with production (non-profiling) bundle of scheduler/tracing
10637 !(__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;
10638}
10639
10640{
10641 didWarnAboutStateTransition = false;
10642 didWarnSetStateChildContext = false;
10643 var didWarnStateUpdateForUnmountedComponent = {};
10644
10645 warnAboutUpdateOnUnmounted = function (fiber, isClass) {
10646 // We show the whole stack but dedupe on the top component's name because
10647 // the problematic code almost always lies inside that component.
10648 var componentName = getComponentName(fiber.type) || 'ReactComponent';
10649 if (didWarnStateUpdateForUnmountedComponent[componentName]) {
10650 return;
10651 }
10652 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));
10653 didWarnStateUpdateForUnmountedComponent[componentName] = true;
10654 };
10655
10656 warnAboutInvalidUpdates = function (instance) {
10657 switch (phase) {
10658 case 'getChildContext':
10659 if (didWarnSetStateChildContext) {
10660 return;
10661 }
10662 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
10663 didWarnSetStateChildContext = true;
10664 break;
10665 case 'render':
10666 if (didWarnAboutStateTransition) {
10667 return;
10668 }
10669 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.');
10670 didWarnAboutStateTransition = true;
10671 break;
10672 }
10673 };
10674}
10675
10676// Represents the expiration time that incoming updates should use. (If this
10677// is NoWork, use the default strategy: async updates in async mode, sync
10678// updates in sync mode.)
10679var expirationContext = NoWork;
10680
10681var isWorking = false;
10682
10683// The next work in progress fiber that we're currently working on.
10684var nextUnitOfWork = null;
10685var nextRoot = null;
10686// The time at which we're currently rendering work.
10687var nextRenderExpirationTime = NoWork;
10688var nextLatestAbsoluteTimeoutMs = -1;
10689var nextRenderDidError = false;
10690
10691// The next fiber with an effect that we're currently committing.
10692var nextEffect = null;
10693
10694var isCommitting$1 = false;
10695var rootWithPendingPassiveEffects = null;
10696var passiveEffectCallbackHandle = null;
10697var passiveEffectCallback = null;
10698
10699var legacyErrorBoundariesThatAlreadyFailed = null;
10700
10701// Used for performance tracking.
10702var interruptedBy = null;
10703
10704var stashedWorkInProgressProperties = void 0;
10705var replayUnitOfWork = void 0;
10706var mayReplayFailedUnitOfWork = void 0;
10707var isReplayingFailedUnitOfWork = void 0;
10708var originalReplayError = void 0;
10709var rethrowOriginalError = void 0;
10710if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
10711 stashedWorkInProgressProperties = null;
10712 mayReplayFailedUnitOfWork = true;
10713 isReplayingFailedUnitOfWork = false;
10714 originalReplayError = null;
10715 replayUnitOfWork = function (failedUnitOfWork, thrownValue, isYieldy) {
10716 if (thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function') {
10717 // Don't replay promises. Treat everything else like an error.
10718 // TODO: Need to figure out a different strategy if/when we add
10719 // support for catching other types.
10720 return;
10721 }
10722
10723 // Restore the original state of the work-in-progress
10724 if (stashedWorkInProgressProperties === null) {
10725 // This should never happen. Don't throw because this code is DEV-only.
10726 warningWithoutStack$1(false, 'Could not replay rendering after an error. This is likely a bug in React. ' + 'Please file an issue.');
10727 return;
10728 }
10729 assignFiberPropertiesInDEV(failedUnitOfWork, stashedWorkInProgressProperties);
10730
10731 switch (failedUnitOfWork.tag) {
10732 case HostRoot:
10733 popHostContainer(failedUnitOfWork);
10734 popTopLevelContextObject(failedUnitOfWork);
10735 break;
10736 case HostComponent:
10737 popHostContext(failedUnitOfWork);
10738 break;
10739 case ClassComponent:
10740 {
10741 var Component = failedUnitOfWork.type;
10742 if (isContextProvider(Component)) {
10743 popContext(failedUnitOfWork);
10744 }
10745 break;
10746 }
10747 case HostPortal:
10748 popHostContainer(failedUnitOfWork);
10749 break;
10750 case ContextProvider:
10751 popProvider(failedUnitOfWork);
10752 break;
10753 }
10754 // Replay the begin phase.
10755 isReplayingFailedUnitOfWork = true;
10756 originalReplayError = thrownValue;
10757 invokeGuardedCallback(null, workLoop, null, isYieldy);
10758 isReplayingFailedUnitOfWork = false;
10759 originalReplayError = null;
10760 if (hasCaughtError()) {
10761 var replayError = clearCaughtError();
10762 if (replayError != null && thrownValue != null) {
10763 try {
10764 // Reading the expando property is intentionally
10765 // inside `try` because it might be a getter or Proxy.
10766 if (replayError._suppressLogging) {
10767 // Also suppress logging for the original error.
10768 thrownValue._suppressLogging = true;
10769 }
10770 } catch (inner) {
10771 // Ignore.
10772 }
10773 }
10774 } else {
10775 // If the begin phase did not fail the second time, set this pointer
10776 // back to the original value.
10777 nextUnitOfWork = failedUnitOfWork;
10778 }
10779 };
10780 rethrowOriginalError = function () {
10781 throw originalReplayError;
10782 };
10783}
10784
10785function resetStack() {
10786 if (nextUnitOfWork !== null) {
10787 var interruptedWork = nextUnitOfWork.return;
10788 while (interruptedWork !== null) {
10789 unwindInterruptedWork(interruptedWork);
10790 interruptedWork = interruptedWork.return;
10791 }
10792 }
10793
10794 {
10795 ReactStrictModeWarnings.discardPendingWarnings();
10796 checkThatStackIsEmpty();
10797 }
10798
10799 nextRoot = null;
10800 nextRenderExpirationTime = NoWork;
10801 nextLatestAbsoluteTimeoutMs = -1;
10802 nextRenderDidError = false;
10803 nextUnitOfWork = null;
10804}
10805
10806function commitAllHostEffects() {
10807 while (nextEffect !== null) {
10808 {
10809 setCurrentFiber(nextEffect);
10810 }
10811 recordEffect();
10812
10813 var effectTag = nextEffect.effectTag;
10814
10815 if (effectTag & ContentReset) {
10816 commitResetTextContent(nextEffect);
10817 }
10818
10819 if (effectTag & Ref) {
10820 var current = nextEffect.alternate;
10821 if (current !== null) {
10822 commitDetachRef(current);
10823 }
10824 }
10825
10826 // The following switch statement is only concerned about placement,
10827 // updates, and deletions. To avoid needing to add a case for every
10828 // possible bitmap value, we remove the secondary effects from the
10829 // effect tag and switch on that value.
10830 var primaryEffectTag = effectTag & (Placement | Update | Deletion);
10831 switch (primaryEffectTag) {
10832 case Placement:
10833 {
10834 commitPlacement(nextEffect);
10835 // Clear the "placement" from effect tag so that we know that this is inserted, before
10836 // any life-cycles like componentDidMount gets called.
10837 // TODO: findDOMNode doesn't rely on this any more but isMounted
10838 // does and isMounted is deprecated anyway so we should be able
10839 // to kill this.
10840 nextEffect.effectTag &= ~Placement;
10841 break;
10842 }
10843 case PlacementAndUpdate:
10844 {
10845 // Placement
10846 commitPlacement(nextEffect);
10847 // Clear the "placement" from effect tag so that we know that this is inserted, before
10848 // any life-cycles like componentDidMount gets called.
10849 nextEffect.effectTag &= ~Placement;
10850
10851 // Update
10852 var _current = nextEffect.alternate;
10853 commitWork(_current, nextEffect);
10854 break;
10855 }
10856 case Update:
10857 {
10858 var _current2 = nextEffect.alternate;
10859 commitWork(_current2, nextEffect);
10860 break;
10861 }
10862 case Deletion:
10863 {
10864 commitDeletion(nextEffect);
10865 break;
10866 }
10867 }
10868 nextEffect = nextEffect.nextEffect;
10869 }
10870
10871 {
10872 resetCurrentFiber();
10873 }
10874}
10875
10876function commitBeforeMutationLifecycles() {
10877 while (nextEffect !== null) {
10878 {
10879 setCurrentFiber(nextEffect);
10880 }
10881
10882 var effectTag = nextEffect.effectTag;
10883 if (effectTag & Snapshot) {
10884 recordEffect();
10885 var current = nextEffect.alternate;
10886 commitBeforeMutationLifeCycles(current, nextEffect);
10887 }
10888
10889 nextEffect = nextEffect.nextEffect;
10890 }
10891
10892 {
10893 resetCurrentFiber();
10894 }
10895}
10896
10897function commitAllLifeCycles(finishedRoot, committedExpirationTime) {
10898 {
10899 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
10900 ReactStrictModeWarnings.flushLegacyContextWarning();
10901
10902 if (warnAboutDeprecatedLifecycles) {
10903 ReactStrictModeWarnings.flushPendingDeprecationWarnings();
10904 }
10905 }
10906 while (nextEffect !== null) {
10907 {
10908 setCurrentFiber(nextEffect);
10909 }
10910 var effectTag = nextEffect.effectTag;
10911
10912 if (effectTag & (Update | Callback)) {
10913 recordEffect();
10914 var current = nextEffect.alternate;
10915 commitLifeCycles(finishedRoot, current, nextEffect, committedExpirationTime);
10916 }
10917
10918 if (effectTag & Ref) {
10919 recordEffect();
10920 commitAttachRef(nextEffect);
10921 }
10922
10923 if (effectTag & Passive) {
10924 rootWithPendingPassiveEffects = finishedRoot;
10925 }
10926
10927 nextEffect = nextEffect.nextEffect;
10928 }
10929 {
10930 resetCurrentFiber();
10931 }
10932}
10933
10934function commitPassiveEffects(root, firstEffect) {
10935 rootWithPendingPassiveEffects = null;
10936 passiveEffectCallbackHandle = null;
10937 passiveEffectCallback = null;
10938
10939 // Set this to true to prevent re-entrancy
10940 var previousIsRendering = isRendering;
10941 isRendering = true;
10942
10943 var effect = firstEffect;
10944 do {
10945 {
10946 setCurrentFiber(effect);
10947 }
10948
10949 if (effect.effectTag & Passive) {
10950 var didError = false;
10951 var error = void 0;
10952 {
10953 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
10954 if (hasCaughtError()) {
10955 didError = true;
10956 error = clearCaughtError();
10957 }
10958 }
10959 if (didError) {
10960 captureCommitPhaseError(effect, error);
10961 }
10962 }
10963 effect = effect.nextEffect;
10964 } while (effect !== null);
10965 {
10966 resetCurrentFiber();
10967 }
10968
10969 isRendering = previousIsRendering;
10970
10971 // Check if work was scheduled by one of the effects
10972 var rootExpirationTime = root.expirationTime;
10973 if (rootExpirationTime !== NoWork) {
10974 requestWork(root, rootExpirationTime);
10975 }
10976}
10977
10978function isAlreadyFailedLegacyErrorBoundary(instance) {
10979 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
10980}
10981
10982function markLegacyErrorBoundaryAsFailed(instance) {
10983 if (legacyErrorBoundariesThatAlreadyFailed === null) {
10984 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
10985 } else {
10986 legacyErrorBoundariesThatAlreadyFailed.add(instance);
10987 }
10988}
10989
10990function flushPassiveEffects() {
10991 if (passiveEffectCallbackHandle !== null) {
10992 cancelPassiveEffects(passiveEffectCallbackHandle);
10993 }
10994 if (passiveEffectCallback !== null) {
10995 // We call the scheduled callback instead of commitPassiveEffects directly
10996 // to ensure tracing works correctly.
10997 passiveEffectCallback();
10998 }
10999}
11000
11001function commitRoot(root, finishedWork) {
11002 isWorking = true;
11003 isCommitting$1 = true;
11004 startCommitTimer();
11005
11006 !(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;
11007 var committedExpirationTime = root.pendingCommitExpirationTime;
11008 !(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;
11009 root.pendingCommitExpirationTime = NoWork;
11010
11011 // Update the pending priority levels to account for the work that we are
11012 // about to commit. This needs to happen before calling the lifecycles, since
11013 // they may schedule additional updates.
11014 var updateExpirationTimeBeforeCommit = finishedWork.expirationTime;
11015 var childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;
11016 var earliestRemainingTimeBeforeCommit = childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit ? childExpirationTimeBeforeCommit : updateExpirationTimeBeforeCommit;
11017 markCommittedPriorityLevels(root, earliestRemainingTimeBeforeCommit);
11018
11019 var prevInteractions = null;
11020 if (enableSchedulerTracing) {
11021 // Restore any pending interactions at this point,
11022 // So that cascading work triggered during the render phase will be accounted for.
11023 prevInteractions = __interactionsRef.current;
11024 __interactionsRef.current = root.memoizedInteractions;
11025 }
11026
11027 // Reset this to null before calling lifecycles
11028 ReactCurrentOwner$1.current = null;
11029
11030 var firstEffect = void 0;
11031 if (finishedWork.effectTag > PerformedWork) {
11032 // A fiber's effect list consists only of its children, not itself. So if
11033 // the root has an effect, we need to add it to the end of the list. The
11034 // resulting list is the set that would belong to the root's parent, if
11035 // it had one; that is, all the effects in the tree including the root.
11036 if (finishedWork.lastEffect !== null) {
11037 finishedWork.lastEffect.nextEffect = finishedWork;
11038 firstEffect = finishedWork.firstEffect;
11039 } else {
11040 firstEffect = finishedWork;
11041 }
11042 } else {
11043 // There is no effect on the root.
11044 firstEffect = finishedWork.firstEffect;
11045 }
11046
11047 prepareForCommit(root.containerInfo);
11048
11049 // Invoke instances of getSnapshotBeforeUpdate before mutation.
11050 nextEffect = firstEffect;
11051 startCommitSnapshotEffectsTimer();
11052 while (nextEffect !== null) {
11053 var didError = false;
11054 var error = void 0;
11055 {
11056 invokeGuardedCallback(null, commitBeforeMutationLifecycles, null);
11057 if (hasCaughtError()) {
11058 didError = true;
11059 error = clearCaughtError();
11060 }
11061 }
11062 if (didError) {
11063 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11064 captureCommitPhaseError(nextEffect, error);
11065 // Clean-up
11066 if (nextEffect !== null) {
11067 nextEffect = nextEffect.nextEffect;
11068 }
11069 }
11070 }
11071 stopCommitSnapshotEffectsTimer();
11072
11073 if (enableProfilerTimer) {
11074 // Mark the current commit time to be shared by all Profilers in this batch.
11075 // This enables them to be grouped later.
11076 recordCommitTime();
11077 }
11078
11079 // Commit all the side-effects within a tree. We'll do this in two passes.
11080 // The first pass performs all the host insertions, updates, deletions and
11081 // ref unmounts.
11082 nextEffect = firstEffect;
11083 startCommitHostEffectsTimer();
11084 while (nextEffect !== null) {
11085 var _didError = false;
11086 var _error = void 0;
11087 {
11088 invokeGuardedCallback(null, commitAllHostEffects, null);
11089 if (hasCaughtError()) {
11090 _didError = true;
11091 _error = clearCaughtError();
11092 }
11093 }
11094 if (_didError) {
11095 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11096 captureCommitPhaseError(nextEffect, _error);
11097 // Clean-up
11098 if (nextEffect !== null) {
11099 nextEffect = nextEffect.nextEffect;
11100 }
11101 }
11102 }
11103 stopCommitHostEffectsTimer();
11104
11105 resetAfterCommit(root.containerInfo);
11106
11107 // The work-in-progress tree is now the current tree. This must come after
11108 // the first pass of the commit phase, so that the previous tree is still
11109 // current during componentWillUnmount, but before the second pass, so that
11110 // the finished work is current during componentDidMount/Update.
11111 root.current = finishedWork;
11112
11113 // In the second pass we'll perform all life-cycles and ref callbacks.
11114 // Life-cycles happen as a separate pass so that all placements, updates,
11115 // and deletions in the entire tree have already been invoked.
11116 // This pass also triggers any renderer-specific initial effects.
11117 nextEffect = firstEffect;
11118 startCommitLifeCyclesTimer();
11119 while (nextEffect !== null) {
11120 var _didError2 = false;
11121 var _error2 = void 0;
11122 {
11123 invokeGuardedCallback(null, commitAllLifeCycles, null, root, committedExpirationTime);
11124 if (hasCaughtError()) {
11125 _didError2 = true;
11126 _error2 = clearCaughtError();
11127 }
11128 }
11129 if (_didError2) {
11130 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11131 captureCommitPhaseError(nextEffect, _error2);
11132 if (nextEffect !== null) {
11133 nextEffect = nextEffect.nextEffect;
11134 }
11135 }
11136 }
11137
11138 if (firstEffect !== null && rootWithPendingPassiveEffects !== null) {
11139 // This commit included a passive effect. These do not need to fire until
11140 // after the next paint. Schedule an callback to fire them in an async
11141 // event. To ensure serial execution, the callback will be flushed early if
11142 // we enter rootWithPendingPassiveEffects commit phase before then.
11143 var callback = commitPassiveEffects.bind(null, root, firstEffect);
11144 if (enableSchedulerTracing) {
11145 // TODO: Avoid this extra callback by mutating the tracing ref directly,
11146 // like we do at the beginning of commitRoot. I've opted not to do that
11147 // here because that code is still in flux.
11148 callback = unstable_wrap(callback);
11149 }
11150 passiveEffectCallbackHandle = schedulePassiveEffects(callback);
11151 passiveEffectCallback = callback;
11152 }
11153
11154 isCommitting$1 = false;
11155 isWorking = false;
11156 stopCommitLifeCyclesTimer();
11157 stopCommitTimer();
11158 onCommitRoot(finishedWork.stateNode);
11159 if (true && ReactFiberInstrumentation_1.debugTool) {
11160 ReactFiberInstrumentation_1.debugTool.onCommitWork(finishedWork);
11161 }
11162
11163 var updateExpirationTimeAfterCommit = finishedWork.expirationTime;
11164 var childExpirationTimeAfterCommit = finishedWork.childExpirationTime;
11165 var earliestRemainingTimeAfterCommit = childExpirationTimeAfterCommit > updateExpirationTimeAfterCommit ? childExpirationTimeAfterCommit : updateExpirationTimeAfterCommit;
11166 if (earliestRemainingTimeAfterCommit === NoWork) {
11167 // If there's no remaining work, we can clear the set of already failed
11168 // error boundaries.
11169 legacyErrorBoundariesThatAlreadyFailed = null;
11170 }
11171 onCommit(root, earliestRemainingTimeAfterCommit);
11172
11173 if (enableSchedulerTracing) {
11174 __interactionsRef.current = prevInteractions;
11175
11176 var subscriber = void 0;
11177
11178 try {
11179 subscriber = __subscriberRef.current;
11180 if (subscriber !== null && root.memoizedInteractions.size > 0) {
11181 var threadID = computeThreadID(committedExpirationTime, root.interactionThreadID);
11182 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
11183 }
11184 } catch (error) {
11185 // It's not safe for commitRoot() to throw.
11186 // Store the error for now and we'll re-throw in finishRendering().
11187 if (!hasUnhandledError) {
11188 hasUnhandledError = true;
11189 unhandledError = error;
11190 }
11191 } finally {
11192 // Clear completed interactions from the pending Map.
11193 // Unless the render was suspended or cascading work was scheduled,
11194 // In which case– leave pending interactions until the subsequent render.
11195 var pendingInteractionMap = root.pendingInteractionMap;
11196 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
11197 // Only decrement the pending interaction count if we're done.
11198 // If there's still work at the current priority,
11199 // That indicates that we are waiting for suspense data.
11200 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
11201 pendingInteractionMap.delete(scheduledExpirationTime);
11202
11203 scheduledInteractions.forEach(function (interaction) {
11204 interaction.__count--;
11205
11206 if (subscriber !== null && interaction.__count === 0) {
11207 try {
11208 subscriber.onInteractionScheduledWorkCompleted(interaction);
11209 } catch (error) {
11210 // It's not safe for commitRoot() to throw.
11211 // Store the error for now and we'll re-throw in finishRendering().
11212 if (!hasUnhandledError) {
11213 hasUnhandledError = true;
11214 unhandledError = error;
11215 }
11216 }
11217 }
11218 });
11219 }
11220 });
11221 }
11222 }
11223}
11224
11225function resetChildExpirationTime(workInProgress, renderTime) {
11226 if (renderTime !== Never && workInProgress.childExpirationTime === Never) {
11227 // The children of this component are hidden. Don't bubble their
11228 // expiration times.
11229 return;
11230 }
11231
11232 var newChildExpirationTime = NoWork;
11233
11234 // Bubble up the earliest expiration time.
11235 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
11236 // We're in profiling mode.
11237 // Let's use this same traversal to update the render durations.
11238 var actualDuration = workInProgress.actualDuration;
11239 var treeBaseDuration = workInProgress.selfBaseDuration;
11240
11241 // When a fiber is cloned, its actualDuration is reset to 0.
11242 // This value will only be updated if work is done on the fiber (i.e. it doesn't bailout).
11243 // When work is done, it should bubble to the parent's actualDuration.
11244 // If the fiber has not been cloned though, (meaning no work was done),
11245 // Then this value will reflect the amount of time spent working on a previous render.
11246 // In that case it should not bubble.
11247 // We determine whether it was cloned by comparing the child pointer.
11248 var shouldBubbleActualDurations = workInProgress.alternate === null || workInProgress.child !== workInProgress.alternate.child;
11249
11250 var child = workInProgress.child;
11251 while (child !== null) {
11252 var childUpdateExpirationTime = child.expirationTime;
11253 var childChildExpirationTime = child.childExpirationTime;
11254 if (childUpdateExpirationTime > newChildExpirationTime) {
11255 newChildExpirationTime = childUpdateExpirationTime;
11256 }
11257 if (childChildExpirationTime > newChildExpirationTime) {
11258 newChildExpirationTime = childChildExpirationTime;
11259 }
11260 if (shouldBubbleActualDurations) {
11261 actualDuration += child.actualDuration;
11262 }
11263 treeBaseDuration += child.treeBaseDuration;
11264 child = child.sibling;
11265 }
11266 workInProgress.actualDuration = actualDuration;
11267 workInProgress.treeBaseDuration = treeBaseDuration;
11268 } else {
11269 var _child = workInProgress.child;
11270 while (_child !== null) {
11271 var _childUpdateExpirationTime = _child.expirationTime;
11272 var _childChildExpirationTime = _child.childExpirationTime;
11273 if (_childUpdateExpirationTime > newChildExpirationTime) {
11274 newChildExpirationTime = _childUpdateExpirationTime;
11275 }
11276 if (_childChildExpirationTime > newChildExpirationTime) {
11277 newChildExpirationTime = _childChildExpirationTime;
11278 }
11279 _child = _child.sibling;
11280 }
11281 }
11282
11283 workInProgress.childExpirationTime = newChildExpirationTime;
11284}
11285
11286function completeUnitOfWork(workInProgress) {
11287 // Attempt to complete the current unit of work, then move to the
11288 // next sibling. If there are no more siblings, return to the
11289 // parent fiber.
11290 while (true) {
11291 // The current, flushed, state of this fiber is the alternate.
11292 // Ideally nothing should rely on this, but relying on it here
11293 // means that we don't need an additional field on the work in
11294 // progress.
11295 var current = workInProgress.alternate;
11296 {
11297 setCurrentFiber(workInProgress);
11298 }
11299
11300 var returnFiber = workInProgress.return;
11301 var siblingFiber = workInProgress.sibling;
11302
11303 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
11304 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11305 // Don't replay if it fails during completion phase.
11306 mayReplayFailedUnitOfWork = false;
11307 }
11308 // This fiber completed.
11309 // Remember we're completing this unit so we can find a boundary if it fails.
11310 nextUnitOfWork = workInProgress;
11311 if (enableProfilerTimer) {
11312 if (workInProgress.mode & ProfileMode) {
11313 startProfilerTimer(workInProgress);
11314 }
11315 nextUnitOfWork = completeWork(current, workInProgress, nextRenderExpirationTime);
11316 if (workInProgress.mode & ProfileMode) {
11317 // Update render duration assuming we didn't error.
11318 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
11319 }
11320 } else {
11321 nextUnitOfWork = completeWork(current, workInProgress, nextRenderExpirationTime);
11322 }
11323 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11324 // We're out of completion phase so replaying is fine now.
11325 mayReplayFailedUnitOfWork = true;
11326 }
11327 stopWorkTimer(workInProgress);
11328 resetChildExpirationTime(workInProgress, nextRenderExpirationTime);
11329 {
11330 resetCurrentFiber();
11331 }
11332
11333 if (nextUnitOfWork !== null) {
11334 // Completing this fiber spawned new work. Work on that next.
11335 return nextUnitOfWork;
11336 }
11337
11338 if (returnFiber !== null &&
11339 // Do not append effects to parents if a sibling failed to complete
11340 (returnFiber.effectTag & Incomplete) === NoEffect) {
11341 // Append all the effects of the subtree and this fiber onto the effect
11342 // list of the parent. The completion order of the children affects the
11343 // side-effect order.
11344 if (returnFiber.firstEffect === null) {
11345 returnFiber.firstEffect = workInProgress.firstEffect;
11346 }
11347 if (workInProgress.lastEffect !== null) {
11348 if (returnFiber.lastEffect !== null) {
11349 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
11350 }
11351 returnFiber.lastEffect = workInProgress.lastEffect;
11352 }
11353
11354 // If this fiber had side-effects, we append it AFTER the children's
11355 // side-effects. We can perform certain side-effects earlier if
11356 // needed, by doing multiple passes over the effect list. We don't want
11357 // to schedule our own side-effect on our own list because if end up
11358 // reusing children we'll schedule this effect onto itself since we're
11359 // at the end.
11360 var effectTag = workInProgress.effectTag;
11361 // Skip both NoWork and PerformedWork tags when creating the effect list.
11362 // PerformedWork effect is read by React DevTools but shouldn't be committed.
11363 if (effectTag > PerformedWork) {
11364 if (returnFiber.lastEffect !== null) {
11365 returnFiber.lastEffect.nextEffect = workInProgress;
11366 } else {
11367 returnFiber.firstEffect = workInProgress;
11368 }
11369 returnFiber.lastEffect = workInProgress;
11370 }
11371 }
11372
11373 if (true && ReactFiberInstrumentation_1.debugTool) {
11374 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11375 }
11376
11377 if (siblingFiber !== null) {
11378 // If there is more work to do in this returnFiber, do that next.
11379 return siblingFiber;
11380 } else if (returnFiber !== null) {
11381 // If there's no more work in this returnFiber. Complete the returnFiber.
11382 workInProgress = returnFiber;
11383 continue;
11384 } else {
11385 // We've reached the root.
11386 return null;
11387 }
11388 } else {
11389 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
11390 // Record the render duration for the fiber that errored.
11391 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
11392
11393 // Include the time spent working on failed children before continuing.
11394 var actualDuration = workInProgress.actualDuration;
11395 var child = workInProgress.child;
11396 while (child !== null) {
11397 actualDuration += child.actualDuration;
11398 child = child.sibling;
11399 }
11400 workInProgress.actualDuration = actualDuration;
11401 }
11402
11403 // This fiber did not complete because something threw. Pop values off
11404 // the stack without entering the complete phase. If this is a boundary,
11405 // capture values if possible.
11406 var next = unwindWork(workInProgress, nextRenderExpirationTime);
11407 // Because this fiber did not complete, don't reset its expiration time.
11408 if (workInProgress.effectTag & DidCapture) {
11409 // Restarting an error boundary
11410 stopFailedWorkTimer(workInProgress);
11411 } else {
11412 stopWorkTimer(workInProgress);
11413 }
11414
11415 {
11416 resetCurrentFiber();
11417 }
11418
11419 if (next !== null) {
11420 stopWorkTimer(workInProgress);
11421 if (true && ReactFiberInstrumentation_1.debugTool) {
11422 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11423 }
11424
11425 // If completing this work spawned new work, do that next. We'll come
11426 // back here again.
11427 // Since we're restarting, remove anything that is not a host effect
11428 // from the effect tag.
11429 next.effectTag &= HostEffectMask;
11430 return next;
11431 }
11432
11433 if (returnFiber !== null) {
11434 // Mark the parent fiber as incomplete and clear its effect list.
11435 returnFiber.firstEffect = returnFiber.lastEffect = null;
11436 returnFiber.effectTag |= Incomplete;
11437 }
11438
11439 if (true && ReactFiberInstrumentation_1.debugTool) {
11440 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11441 }
11442
11443 if (siblingFiber !== null) {
11444 // If there is more work to do in this returnFiber, do that next.
11445 return siblingFiber;
11446 } else if (returnFiber !== null) {
11447 // If there's no more work in this returnFiber. Complete the returnFiber.
11448 workInProgress = returnFiber;
11449 continue;
11450 } else {
11451 return null;
11452 }
11453 }
11454 }
11455
11456 // Without this explicit null return Flow complains of invalid return type
11457 // TODO Remove the above while(true) loop
11458 // eslint-disable-next-line no-unreachable
11459 return null;
11460}
11461
11462function performUnitOfWork(workInProgress) {
11463 // The current, flushed, state of this fiber is the alternate.
11464 // Ideally nothing should rely on this, but relying on it here
11465 // means that we don't need an additional field on the work in
11466 // progress.
11467 var current = workInProgress.alternate;
11468
11469 // See if beginning this work spawns more work.
11470 startWorkTimer(workInProgress);
11471 {
11472 setCurrentFiber(workInProgress);
11473 }
11474
11475 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11476 stashedWorkInProgressProperties = assignFiberPropertiesInDEV(stashedWorkInProgressProperties, workInProgress);
11477 }
11478
11479 var next = void 0;
11480 if (enableProfilerTimer) {
11481 if (workInProgress.mode & ProfileMode) {
11482 startProfilerTimer(workInProgress);
11483 }
11484
11485 next = beginWork(current, workInProgress, nextRenderExpirationTime);
11486 workInProgress.memoizedProps = workInProgress.pendingProps;
11487
11488 if (workInProgress.mode & ProfileMode) {
11489 // Record the render duration assuming we didn't bailout (or error).
11490 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
11491 }
11492 } else {
11493 next = beginWork(current, workInProgress, nextRenderExpirationTime);
11494 workInProgress.memoizedProps = workInProgress.pendingProps;
11495 }
11496
11497 {
11498 resetCurrentFiber();
11499 if (isReplayingFailedUnitOfWork) {
11500 // Currently replaying a failed unit of work. This should be unreachable,
11501 // because the render phase is meant to be idempotent, and it should
11502 // have thrown again. Since it didn't, rethrow the original error, so
11503 // React's internal stack is not misaligned.
11504 rethrowOriginalError();
11505 }
11506 }
11507 if (true && ReactFiberInstrumentation_1.debugTool) {
11508 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
11509 }
11510
11511 if (next === null) {
11512 // If this doesn't spawn new work, complete the current work.
11513 next = completeUnitOfWork(workInProgress);
11514 }
11515
11516 ReactCurrentOwner$1.current = null;
11517
11518 return next;
11519}
11520
11521function workLoop(isYieldy) {
11522 if (!isYieldy) {
11523 // Flush work without yielding
11524 while (nextUnitOfWork !== null) {
11525 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11526 }
11527 } else {
11528 // Flush asynchronous work until there's a higher priority event
11529 while (nextUnitOfWork !== null && !shouldYieldToRenderer()) {
11530 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11531 }
11532 }
11533}
11534
11535function renderRoot(root, isYieldy) {
11536 !!isWorking ? invariant(false, 'renderRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11537
11538 flushPassiveEffects();
11539
11540 isWorking = true;
11541 var previousDispatcher = ReactCurrentDispatcher.current;
11542 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
11543
11544 var expirationTime = root.nextExpirationTimeToWorkOn;
11545
11546 // Check if we're starting from a fresh stack, or if we're resuming from
11547 // previously yielded work.
11548 if (expirationTime !== nextRenderExpirationTime || root !== nextRoot || nextUnitOfWork === null) {
11549 // Reset the stack and start working from the root.
11550 resetStack();
11551 nextRoot = root;
11552 nextRenderExpirationTime = expirationTime;
11553 nextUnitOfWork = createWorkInProgress(nextRoot.current, null, nextRenderExpirationTime);
11554 root.pendingCommitExpirationTime = NoWork;
11555
11556 if (enableSchedulerTracing) {
11557 // Determine which interactions this batch of work currently includes,
11558 // So that we can accurately attribute time spent working on it,
11559 var interactions = new Set();
11560 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
11561 if (scheduledExpirationTime >= expirationTime) {
11562 scheduledInteractions.forEach(function (interaction) {
11563 return interactions.add(interaction);
11564 });
11565 }
11566 });
11567
11568 // Store the current set of interactions on the FiberRoot for a few reasons:
11569 // We can re-use it in hot functions like renderRoot() without having to recalculate it.
11570 // We will also use it in commitWork() to pass to any Profiler onRender() hooks.
11571 // This also provides DevTools with a way to access it when the onCommitRoot() hook is called.
11572 root.memoizedInteractions = interactions;
11573
11574 if (interactions.size > 0) {
11575 var subscriber = __subscriberRef.current;
11576 if (subscriber !== null) {
11577 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
11578 try {
11579 subscriber.onWorkStarted(interactions, threadID);
11580 } catch (error) {
11581 // Work thrown by an interaction tracing subscriber should be rethrown,
11582 // But only once it's safe (to avoid leaving the scheduler in an invalid state).
11583 // Store the error for now and we'll re-throw in finishRendering().
11584 if (!hasUnhandledError) {
11585 hasUnhandledError = true;
11586 unhandledError = error;
11587 }
11588 }
11589 }
11590 }
11591 }
11592 }
11593
11594 var prevInteractions = null;
11595 if (enableSchedulerTracing) {
11596 // We're about to start new traced work.
11597 // Restore pending interactions so cascading work triggered during the render phase will be accounted for.
11598 prevInteractions = __interactionsRef.current;
11599 __interactionsRef.current = root.memoizedInteractions;
11600 }
11601
11602 var didFatal = false;
11603
11604 startWorkLoopTimer(nextUnitOfWork);
11605
11606 do {
11607 try {
11608 workLoop(isYieldy);
11609 } catch (thrownValue) {
11610 resetContextDependences();
11611 resetHooks();
11612
11613 // Reset in case completion throws.
11614 // This is only used in DEV and when replaying is on.
11615 var mayReplay = void 0;
11616 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11617 mayReplay = mayReplayFailedUnitOfWork;
11618 mayReplayFailedUnitOfWork = true;
11619 }
11620
11621 if (nextUnitOfWork === null) {
11622 // This is a fatal error.
11623 didFatal = true;
11624 onUncaughtError(thrownValue);
11625 } else {
11626 if (enableProfilerTimer && nextUnitOfWork.mode & ProfileMode) {
11627 // Record the time spent rendering before an error was thrown.
11628 // This avoids inaccurate Profiler durations in the case of a suspended render.
11629 stopProfilerTimerIfRunningAndRecordDelta(nextUnitOfWork, true);
11630 }
11631
11632 {
11633 // Reset global debug state
11634 // We assume this is defined in DEV
11635 resetCurrentlyProcessingQueue();
11636 }
11637
11638 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11639 if (mayReplay) {
11640 var failedUnitOfWork = nextUnitOfWork;
11641 replayUnitOfWork(failedUnitOfWork, thrownValue, isYieldy);
11642 }
11643 }
11644
11645 // TODO: we already know this isn't true in some cases.
11646 // At least this shows a nicer error message until we figure out the cause.
11647 // https://github.com/facebook/react/issues/12449#issuecomment-386727431
11648 !(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;
11649
11650 var sourceFiber = nextUnitOfWork;
11651 var returnFiber = sourceFiber.return;
11652 if (returnFiber === null) {
11653 // This is the root. The root could capture its own errors. However,
11654 // we don't know if it errors before or after we pushed the host
11655 // context. This information is needed to avoid a stack mismatch.
11656 // Because we're not sure, treat this as a fatal error. We could track
11657 // which phase it fails in, but doesn't seem worth it. At least
11658 // for now.
11659 didFatal = true;
11660 onUncaughtError(thrownValue);
11661 } else {
11662 throwException(root, returnFiber, sourceFiber, thrownValue, nextRenderExpirationTime);
11663 nextUnitOfWork = completeUnitOfWork(sourceFiber);
11664 continue;
11665 }
11666 }
11667 }
11668 break;
11669 } while (true);
11670
11671 if (enableSchedulerTracing) {
11672 // Traced work is done for now; restore the previous interactions.
11673 __interactionsRef.current = prevInteractions;
11674 }
11675
11676 // We're done performing work. Time to clean up.
11677 isWorking = false;
11678 ReactCurrentDispatcher.current = previousDispatcher;
11679 resetContextDependences();
11680 resetHooks();
11681
11682 // Yield back to main thread.
11683 if (didFatal) {
11684 var _didCompleteRoot = false;
11685 stopWorkLoopTimer(interruptedBy, _didCompleteRoot);
11686 interruptedBy = null;
11687 // There was a fatal error.
11688 {
11689 resetStackAfterFatalErrorInDev();
11690 }
11691 // `nextRoot` points to the in-progress root. A non-null value indicates
11692 // that we're in the middle of an async render. Set it to null to indicate
11693 // there's no more work to be done in the current batch.
11694 nextRoot = null;
11695 onFatal(root);
11696 return;
11697 }
11698
11699 if (nextUnitOfWork !== null) {
11700 // There's still remaining async work in this tree, but we ran out of time
11701 // in the current frame. Yield back to the renderer. Unless we're
11702 // interrupted by a higher priority update, we'll continue later from where
11703 // we left off.
11704 var _didCompleteRoot2 = false;
11705 stopWorkLoopTimer(interruptedBy, _didCompleteRoot2);
11706 interruptedBy = null;
11707 onYield(root);
11708 return;
11709 }
11710
11711 // We completed the whole tree.
11712 var didCompleteRoot = true;
11713 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
11714 var rootWorkInProgress = root.current.alternate;
11715 !(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;
11716
11717 // `nextRoot` points to the in-progress root. A non-null value indicates
11718 // that we're in the middle of an async render. Set it to null to indicate
11719 // there's no more work to be done in the current batch.
11720 nextRoot = null;
11721 interruptedBy = null;
11722
11723 if (nextRenderDidError) {
11724 // There was an error
11725 if (hasLowerPriorityWork(root, expirationTime)) {
11726 // There's lower priority work. If so, it may have the effect of fixing
11727 // the exception that was just thrown. Exit without committing. This is
11728 // similar to a suspend, but without a timeout because we're not waiting
11729 // for a promise to resolve. React will restart at the lower
11730 // priority level.
11731 markSuspendedPriorityLevel(root, expirationTime);
11732 var suspendedExpirationTime = expirationTime;
11733 var rootExpirationTime = root.expirationTime;
11734 onSuspend(root, rootWorkInProgress, suspendedExpirationTime, rootExpirationTime, -1 // Indicates no timeout
11735 );
11736 return;
11737 } else if (
11738 // There's no lower priority work, but we're rendering asynchronously.
11739 // Synchronsouly attempt to render the same level one more time. This is
11740 // similar to a suspend, but without a timeout because we're not waiting
11741 // for a promise to resolve.
11742 !root.didError && isYieldy) {
11743 root.didError = true;
11744 var _suspendedExpirationTime = root.nextExpirationTimeToWorkOn = expirationTime;
11745 var _rootExpirationTime = root.expirationTime = Sync;
11746 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime, _rootExpirationTime, -1 // Indicates no timeout
11747 );
11748 return;
11749 }
11750 }
11751
11752 if (isYieldy && nextLatestAbsoluteTimeoutMs !== -1) {
11753 // The tree was suspended.
11754 var _suspendedExpirationTime2 = expirationTime;
11755 markSuspendedPriorityLevel(root, _suspendedExpirationTime2);
11756
11757 // Find the earliest uncommitted expiration time in the tree, including
11758 // work that is suspended. The timeout threshold cannot be longer than
11759 // the overall expiration.
11760 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, expirationTime);
11761 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
11762 if (earliestExpirationTimeMs < nextLatestAbsoluteTimeoutMs) {
11763 nextLatestAbsoluteTimeoutMs = earliestExpirationTimeMs;
11764 }
11765
11766 // Subtract the current time from the absolute timeout to get the number
11767 // of milliseconds until the timeout. In other words, convert an absolute
11768 // timestamp to a relative time. This is the value that is passed
11769 // to `setTimeout`.
11770 var currentTimeMs = expirationTimeToMs(requestCurrentTime());
11771 var msUntilTimeout = nextLatestAbsoluteTimeoutMs - currentTimeMs;
11772 msUntilTimeout = msUntilTimeout < 0 ? 0 : msUntilTimeout;
11773
11774 // TODO: Account for the Just Noticeable Difference
11775
11776 var _rootExpirationTime2 = root.expirationTime;
11777 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime2, _rootExpirationTime2, msUntilTimeout);
11778 return;
11779 }
11780
11781 // Ready to commit.
11782 onComplete(root, rootWorkInProgress, expirationTime);
11783}
11784
11785function captureCommitPhaseError(sourceFiber, value) {
11786 var expirationTime = Sync;
11787 var fiber = sourceFiber.return;
11788 while (fiber !== null) {
11789 switch (fiber.tag) {
11790 case ClassComponent:
11791 var ctor = fiber.type;
11792 var instance = fiber.stateNode;
11793 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
11794 var errorInfo = createCapturedValue(value, sourceFiber);
11795 var update = createClassErrorUpdate(fiber, errorInfo, expirationTime);
11796 enqueueUpdate(fiber, update);
11797 scheduleWork(fiber, expirationTime);
11798 return;
11799 }
11800 break;
11801 case HostRoot:
11802 {
11803 var _errorInfo = createCapturedValue(value, sourceFiber);
11804 var _update = createRootErrorUpdate(fiber, _errorInfo, expirationTime);
11805 enqueueUpdate(fiber, _update);
11806 scheduleWork(fiber, expirationTime);
11807 return;
11808 }
11809 }
11810 fiber = fiber.return;
11811 }
11812
11813 if (sourceFiber.tag === HostRoot) {
11814 // Error was thrown at the root. There is no parent, so the root
11815 // itself should capture it.
11816 var rootFiber = sourceFiber;
11817 var _errorInfo2 = createCapturedValue(value, rootFiber);
11818 var _update2 = createRootErrorUpdate(rootFiber, _errorInfo2, expirationTime);
11819 enqueueUpdate(rootFiber, _update2);
11820 scheduleWork(rootFiber, expirationTime);
11821 }
11822}
11823
11824function computeThreadID(expirationTime, interactionThreadID) {
11825 // Interaction threads are unique per root and expiration time.
11826 return expirationTime * 1000 + interactionThreadID;
11827}
11828
11829function computeExpirationForFiber(currentTime, fiber) {
11830 var expirationTime = void 0;
11831 if (expirationContext !== NoWork) {
11832 // An explicit expiration context was set;
11833 expirationTime = expirationContext;
11834 } else if (isWorking) {
11835 if (isCommitting$1) {
11836 // Updates that occur during the commit phase should have sync priority
11837 // by default.
11838 expirationTime = Sync;
11839 } else {
11840 // Updates during the render phase should expire at the same time as
11841 // the work that is being rendered.
11842 expirationTime = nextRenderExpirationTime;
11843 }
11844 } else {
11845 // No explicit expiration context was set, and we're not currently
11846 // performing work. Calculate a new expiration time.
11847 if (fiber.mode & ConcurrentMode) {
11848 if (isBatchingInteractiveUpdates) {
11849 // This is an interactive update
11850 expirationTime = computeInteractiveExpiration(currentTime);
11851 } else {
11852 // This is an async update
11853 expirationTime = computeAsyncExpiration(currentTime);
11854 }
11855 // If we're in the middle of rendering a tree, do not update at the same
11856 // expiration time that is already rendering.
11857 if (nextRoot !== null && expirationTime === nextRenderExpirationTime) {
11858 expirationTime -= 1;
11859 }
11860 } else {
11861 // This is a sync update
11862 expirationTime = Sync;
11863 }
11864 }
11865 return expirationTime;
11866}
11867
11868function renderDidSuspend(root, absoluteTimeoutMs, suspendedTime) {
11869 // Schedule the timeout.
11870 if (absoluteTimeoutMs >= 0 && nextLatestAbsoluteTimeoutMs < absoluteTimeoutMs) {
11871 nextLatestAbsoluteTimeoutMs = absoluteTimeoutMs;
11872 }
11873}
11874
11875function renderDidError() {
11876 nextRenderDidError = true;
11877}
11878
11879function pingSuspendedRoot(root, thenable, pingTime) {
11880 // A promise that previously suspended React from committing has resolved.
11881 // If React is still suspended, try again at the previous level (pingTime).
11882
11883 var pingCache = root.pingCache;
11884 if (pingCache !== null) {
11885 // The thenable resolved, so we no longer need to memoize, because it will
11886 // never be thrown again.
11887 pingCache.delete(thenable);
11888 }
11889
11890 if (nextRoot !== null && nextRenderExpirationTime === pingTime) {
11891 // Received a ping at the same priority level at which we're currently
11892 // rendering. Restart from the root.
11893 nextRoot = null;
11894 } else {
11895 // Confirm that the root is still suspended at this level. Otherwise exit.
11896 if (isPriorityLevelSuspended(root, pingTime)) {
11897 // Ping at the original level
11898 markPingedPriorityLevel(root, pingTime);
11899 var rootExpirationTime = root.expirationTime;
11900 if (rootExpirationTime !== NoWork) {
11901 requestWork(root, rootExpirationTime);
11902 }
11903 }
11904 }
11905}
11906
11907function retryTimedOutBoundary(boundaryFiber, thenable) {
11908 // The boundary fiber (a Suspense component) previously timed out and was
11909 // rendered in its fallback state. One of the promises that suspended it has
11910 // resolved, which means at least part of the tree was likely unblocked. Try
11911 var retryCache = boundaryFiber.stateNode;
11912 if (retryCache !== null) {
11913 // The thenable resolved, so we no longer need to memoize, because it will
11914 // never be thrown again.
11915 retryCache.delete(thenable);
11916 }
11917
11918 var currentTime = requestCurrentTime();
11919 var retryTime = computeExpirationForFiber(currentTime, boundaryFiber);
11920 var root = scheduleWorkToRoot(boundaryFiber, retryTime);
11921 if (root !== null) {
11922 markPendingPriorityLevel(root, retryTime);
11923 var rootExpirationTime = root.expirationTime;
11924 if (rootExpirationTime !== NoWork) {
11925 requestWork(root, rootExpirationTime);
11926 }
11927 }
11928}
11929
11930function scheduleWorkToRoot(fiber, expirationTime) {
11931 recordScheduleUpdate();
11932
11933 {
11934 if (fiber.tag === ClassComponent) {
11935 var instance = fiber.stateNode;
11936 warnAboutInvalidUpdates(instance);
11937 }
11938 }
11939
11940 // Update the source fiber's expiration time
11941 if (fiber.expirationTime < expirationTime) {
11942 fiber.expirationTime = expirationTime;
11943 }
11944 var alternate = fiber.alternate;
11945 if (alternate !== null && alternate.expirationTime < expirationTime) {
11946 alternate.expirationTime = expirationTime;
11947 }
11948 // Walk the parent path to the root and update the child expiration time.
11949 var node = fiber.return;
11950 var root = null;
11951 if (node === null && fiber.tag === HostRoot) {
11952 root = fiber.stateNode;
11953 } else {
11954 while (node !== null) {
11955 alternate = node.alternate;
11956 if (node.childExpirationTime < expirationTime) {
11957 node.childExpirationTime = expirationTime;
11958 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
11959 alternate.childExpirationTime = expirationTime;
11960 }
11961 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
11962 alternate.childExpirationTime = expirationTime;
11963 }
11964 if (node.return === null && node.tag === HostRoot) {
11965 root = node.stateNode;
11966 break;
11967 }
11968 node = node.return;
11969 }
11970 }
11971
11972 if (enableSchedulerTracing) {
11973 if (root !== null) {
11974 var interactions = __interactionsRef.current;
11975 if (interactions.size > 0) {
11976 var pendingInteractionMap = root.pendingInteractionMap;
11977 var pendingInteractions = pendingInteractionMap.get(expirationTime);
11978 if (pendingInteractions != null) {
11979 interactions.forEach(function (interaction) {
11980 if (!pendingInteractions.has(interaction)) {
11981 // Update the pending async work count for previously unscheduled interaction.
11982 interaction.__count++;
11983 }
11984
11985 pendingInteractions.add(interaction);
11986 });
11987 } else {
11988 pendingInteractionMap.set(expirationTime, new Set(interactions));
11989
11990 // Update the pending async work count for the current interactions.
11991 interactions.forEach(function (interaction) {
11992 interaction.__count++;
11993 });
11994 }
11995
11996 var subscriber = __subscriberRef.current;
11997 if (subscriber !== null) {
11998 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
11999 subscriber.onWorkScheduled(interactions, threadID);
12000 }
12001 }
12002 }
12003 }
12004 return root;
12005}
12006
12007function warnIfNotCurrentlyBatchingInDev(fiber) {
12008 {
12009 if (isRendering === false && isBatchingUpdates === false) {
12010 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', getComponentName(fiber.type));
12011 }
12012 }
12013}
12014
12015function scheduleWork(fiber, expirationTime) {
12016 var root = scheduleWorkToRoot(fiber, expirationTime);
12017 if (root === null) {
12018 {
12019 switch (fiber.tag) {
12020 case ClassComponent:
12021 warnAboutUpdateOnUnmounted(fiber, true);
12022 break;
12023 case FunctionComponent:
12024 case ForwardRef:
12025 case MemoComponent:
12026 case SimpleMemoComponent:
12027 warnAboutUpdateOnUnmounted(fiber, false);
12028 break;
12029 }
12030 }
12031 return;
12032 }
12033
12034 if (!isWorking && nextRenderExpirationTime !== NoWork && expirationTime > nextRenderExpirationTime) {
12035 // This is an interruption. (Used for performance tracking.)
12036 interruptedBy = fiber;
12037 resetStack();
12038 }
12039 markPendingPriorityLevel(root, expirationTime);
12040 if (
12041 // If we're in the render phase, we don't need to schedule this root
12042 // for an update, because we'll do it before we exit...
12043 !isWorking || isCommitting$1 ||
12044 // ...unless this is a different root than the one we're rendering.
12045 nextRoot !== root) {
12046 var rootExpirationTime = root.expirationTime;
12047 requestWork(root, rootExpirationTime);
12048 }
12049 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
12050 // Reset this back to zero so subsequent updates don't throw.
12051 nestedUpdateCount = 0;
12052 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.');
12053 }
12054}
12055
12056// TODO: Everything below this is written as if it has been lifted to the
12057// renderers. I'll do this in a follow-up.
12058
12059// Linked-list of roots
12060var firstScheduledRoot = null;
12061var lastScheduledRoot = null;
12062
12063var callbackExpirationTime = NoWork;
12064var callbackID = void 0;
12065var isRendering = false;
12066var nextFlushedRoot = null;
12067var nextFlushedExpirationTime = NoWork;
12068var hasUnhandledError = false;
12069var unhandledError = null;
12070
12071var isBatchingUpdates = false;
12072var isUnbatchingUpdates = false;
12073var isBatchingInteractiveUpdates = false;
12074
12075var completedBatches = null;
12076
12077var originalStartTimeMs = unstable_now();
12078var currentRendererTime = msToExpirationTime(originalStartTimeMs);
12079var currentSchedulerTime = currentRendererTime;
12080
12081// Use these to prevent an infinite loop of nested updates
12082var NESTED_UPDATE_LIMIT = 50;
12083var nestedUpdateCount = 0;
12084var lastCommittedRootDuringThisBatch = null;
12085
12086function recomputeCurrentRendererTime() {
12087 var currentTimeMs = unstable_now() - originalStartTimeMs;
12088 currentRendererTime = msToExpirationTime(currentTimeMs);
12089}
12090
12091function scheduleCallbackWithExpirationTime(root, expirationTime) {
12092 if (callbackExpirationTime !== NoWork) {
12093 // A callback is already scheduled. Check its expiration time (timeout).
12094 if (expirationTime < callbackExpirationTime) {
12095 // Existing callback has sufficient timeout. Exit.
12096 return;
12097 } else {
12098 if (callbackID !== null) {
12099 // Existing callback has insufficient timeout. Cancel and schedule a
12100 // new one.
12101 unstable_cancelCallback(callbackID);
12102 }
12103 }
12104 // The request callback timer is already running. Don't start a new one.
12105 } else {
12106 startRequestCallbackTimer();
12107 }
12108
12109 callbackExpirationTime = expirationTime;
12110 var currentMs = unstable_now() - originalStartTimeMs;
12111 var expirationTimeMs = expirationTimeToMs(expirationTime);
12112 var timeout = expirationTimeMs - currentMs;
12113 callbackID = unstable_scheduleCallback(performAsyncWork, { timeout: timeout });
12114}
12115
12116// For every call to renderRoot, one of onFatal, onComplete, onSuspend, and
12117// onYield is called upon exiting. We use these in lieu of returning a tuple.
12118// I've also chosen not to inline them into renderRoot because these will
12119// eventually be lifted into the renderer.
12120function onFatal(root) {
12121 root.finishedWork = null;
12122}
12123
12124function onComplete(root, finishedWork, expirationTime) {
12125 root.pendingCommitExpirationTime = expirationTime;
12126 root.finishedWork = finishedWork;
12127}
12128
12129function onSuspend(root, finishedWork, suspendedExpirationTime, rootExpirationTime, msUntilTimeout) {
12130 root.expirationTime = rootExpirationTime;
12131 if (msUntilTimeout === 0 && !shouldYieldToRenderer()) {
12132 // Don't wait an additional tick. Commit the tree immediately.
12133 root.pendingCommitExpirationTime = suspendedExpirationTime;
12134 root.finishedWork = finishedWork;
12135 } else if (msUntilTimeout > 0) {
12136 // Wait `msUntilTimeout` milliseconds before committing.
12137 root.timeoutHandle = scheduleTimeout(onTimeout.bind(null, root, finishedWork, suspendedExpirationTime), msUntilTimeout);
12138 }
12139}
12140
12141function onYield(root) {
12142 root.finishedWork = null;
12143}
12144
12145function onTimeout(root, finishedWork, suspendedExpirationTime) {
12146 // The root timed out. Commit it.
12147 root.pendingCommitExpirationTime = suspendedExpirationTime;
12148 root.finishedWork = finishedWork;
12149 // Read the current time before entering the commit phase. We can be
12150 // certain this won't cause tearing related to batching of event updates
12151 // because we're at the top of a timer event.
12152 recomputeCurrentRendererTime();
12153 currentSchedulerTime = currentRendererTime;
12154 flushRoot(root, suspendedExpirationTime);
12155}
12156
12157function onCommit(root, expirationTime) {
12158 root.expirationTime = expirationTime;
12159 root.finishedWork = null;
12160}
12161
12162function requestCurrentTime() {
12163 // requestCurrentTime is called by the scheduler to compute an expiration
12164 // time.
12165 //
12166 // Expiration times are computed by adding to the current time (the start
12167 // time). However, if two updates are scheduled within the same event, we
12168 // should treat their start times as simultaneous, even if the actual clock
12169 // time has advanced between the first and second call.
12170
12171 // In other words, because expiration times determine how updates are batched,
12172 // we want all updates of like priority that occur within the same event to
12173 // receive the same expiration time. Otherwise we get tearing.
12174 //
12175 // We keep track of two separate times: the current "renderer" time and the
12176 // current "scheduler" time. The renderer time can be updated whenever; it
12177 // only exists to minimize the calls performance.now.
12178 //
12179 // But the scheduler time can only be updated if there's no pending work, or
12180 // if we know for certain that we're not in the middle of an event.
12181
12182 if (isRendering) {
12183 // We're already rendering. Return the most recently read time.
12184 return currentSchedulerTime;
12185 }
12186 // Check if there's pending work.
12187 findHighestPriorityRoot();
12188 if (nextFlushedExpirationTime === NoWork || nextFlushedExpirationTime === Never) {
12189 // If there's no pending work, or if the pending work is offscreen, we can
12190 // read the current time without risk of tearing.
12191 recomputeCurrentRendererTime();
12192 currentSchedulerTime = currentRendererTime;
12193 return currentSchedulerTime;
12194 }
12195 // There's already pending work. We might be in the middle of a browser
12196 // event. If we were to read the current time, it could cause multiple updates
12197 // within the same event to receive different expiration times, leading to
12198 // tearing. Return the last read time. During the next idle callback, the
12199 // time will be updated.
12200 return currentSchedulerTime;
12201}
12202
12203// requestWork is called by the scheduler whenever a root receives an update.
12204// It's up to the renderer to call renderRoot at some point in the future.
12205function requestWork(root, expirationTime) {
12206 addRootToSchedule(root, expirationTime);
12207 if (isRendering) {
12208 // Prevent reentrancy. Remaining work will be scheduled at the end of
12209 // the currently rendering batch.
12210 return;
12211 }
12212
12213 if (isBatchingUpdates) {
12214 // Flush work at the end of the batch.
12215 if (isUnbatchingUpdates) {
12216 // ...unless we're inside unbatchedUpdates, in which case we should
12217 // flush it now.
12218 nextFlushedRoot = root;
12219 nextFlushedExpirationTime = Sync;
12220 performWorkOnRoot(root, Sync, false);
12221 }
12222 return;
12223 }
12224
12225 // TODO: Get rid of Sync and use current time?
12226 if (expirationTime === Sync) {
12227 performSyncWork();
12228 } else {
12229 scheduleCallbackWithExpirationTime(root, expirationTime);
12230 }
12231}
12232
12233function addRootToSchedule(root, expirationTime) {
12234 // Add the root to the schedule.
12235 // Check if this root is already part of the schedule.
12236 if (root.nextScheduledRoot === null) {
12237 // This root is not already scheduled. Add it.
12238 root.expirationTime = expirationTime;
12239 if (lastScheduledRoot === null) {
12240 firstScheduledRoot = lastScheduledRoot = root;
12241 root.nextScheduledRoot = root;
12242 } else {
12243 lastScheduledRoot.nextScheduledRoot = root;
12244 lastScheduledRoot = root;
12245 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
12246 }
12247 } else {
12248 // This root is already scheduled, but its priority may have increased.
12249 var remainingExpirationTime = root.expirationTime;
12250 if (expirationTime > remainingExpirationTime) {
12251 // Update the priority.
12252 root.expirationTime = expirationTime;
12253 }
12254 }
12255}
12256
12257function findHighestPriorityRoot() {
12258 var highestPriorityWork = NoWork;
12259 var highestPriorityRoot = null;
12260 if (lastScheduledRoot !== null) {
12261 var previousScheduledRoot = lastScheduledRoot;
12262 var root = firstScheduledRoot;
12263 while (root !== null) {
12264 var remainingExpirationTime = root.expirationTime;
12265 if (remainingExpirationTime === NoWork) {
12266 // This root no longer has work. Remove it from the scheduler.
12267
12268 // TODO: This check is redudant, but Flow is confused by the branch
12269 // below where we set lastScheduledRoot to null, even though we break
12270 // from the loop right after.
12271 !(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;
12272 if (root === root.nextScheduledRoot) {
12273 // This is the only root in the list.
12274 root.nextScheduledRoot = null;
12275 firstScheduledRoot = lastScheduledRoot = null;
12276 break;
12277 } else if (root === firstScheduledRoot) {
12278 // This is the first root in the list.
12279 var next = root.nextScheduledRoot;
12280 firstScheduledRoot = next;
12281 lastScheduledRoot.nextScheduledRoot = next;
12282 root.nextScheduledRoot = null;
12283 } else if (root === lastScheduledRoot) {
12284 // This is the last root in the list.
12285 lastScheduledRoot = previousScheduledRoot;
12286 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
12287 root.nextScheduledRoot = null;
12288 break;
12289 } else {
12290 previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot;
12291 root.nextScheduledRoot = null;
12292 }
12293 root = previousScheduledRoot.nextScheduledRoot;
12294 } else {
12295 if (remainingExpirationTime > highestPriorityWork) {
12296 // Update the priority, if it's higher
12297 highestPriorityWork = remainingExpirationTime;
12298 highestPriorityRoot = root;
12299 }
12300 if (root === lastScheduledRoot) {
12301 break;
12302 }
12303 if (highestPriorityWork === Sync) {
12304 // Sync is highest priority by definition so
12305 // we can stop searching.
12306 break;
12307 }
12308 previousScheduledRoot = root;
12309 root = root.nextScheduledRoot;
12310 }
12311 }
12312 }
12313
12314 nextFlushedRoot = highestPriorityRoot;
12315 nextFlushedExpirationTime = highestPriorityWork;
12316}
12317
12318// TODO: This wrapper exists because many of the older tests (the ones that use
12319// flushDeferredPri) rely on the number of times `shouldYield` is called. We
12320// should get rid of it.
12321var didYield = false;
12322function shouldYieldToRenderer() {
12323 if (didYield) {
12324 return true;
12325 }
12326 if (unstable_shouldYield()) {
12327 didYield = true;
12328 return true;
12329 }
12330 return false;
12331}
12332
12333function performAsyncWork() {
12334 try {
12335 if (!shouldYieldToRenderer()) {
12336 // The callback timed out. That means at least one update has expired.
12337 // Iterate through the root schedule. If they contain expired work, set
12338 // the next render expiration time to the current time. This has the effect
12339 // of flushing all expired work in a single batch, instead of flushing each
12340 // level one at a time.
12341 if (firstScheduledRoot !== null) {
12342 recomputeCurrentRendererTime();
12343 var root = firstScheduledRoot;
12344 do {
12345 didExpireAtExpirationTime(root, currentRendererTime);
12346 // The root schedule is circular, so this is never null.
12347 root = root.nextScheduledRoot;
12348 } while (root !== firstScheduledRoot);
12349 }
12350 }
12351 performWork(NoWork, true);
12352 } finally {
12353 didYield = false;
12354 }
12355}
12356
12357function performSyncWork() {
12358 performWork(Sync, false);
12359}
12360
12361function performWork(minExpirationTime, isYieldy) {
12362 // Keep working on roots until there's no more work, or until there's a higher
12363 // priority event.
12364 findHighestPriorityRoot();
12365
12366 if (isYieldy) {
12367 recomputeCurrentRendererTime();
12368 currentSchedulerTime = currentRendererTime;
12369
12370 if (enableUserTimingAPI) {
12371 var didExpire = nextFlushedExpirationTime > currentRendererTime;
12372 var timeout = expirationTimeToMs(nextFlushedExpirationTime);
12373 stopRequestCallbackTimer(didExpire, timeout);
12374 }
12375
12376 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime && !(didYield && currentRendererTime > nextFlushedExpirationTime)) {
12377 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, currentRendererTime > nextFlushedExpirationTime);
12378 findHighestPriorityRoot();
12379 recomputeCurrentRendererTime();
12380 currentSchedulerTime = currentRendererTime;
12381 }
12382 } else {
12383 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime) {
12384 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, false);
12385 findHighestPriorityRoot();
12386 }
12387 }
12388
12389 // We're done flushing work. Either we ran out of time in this callback,
12390 // or there's no more work left with sufficient priority.
12391
12392 // If we're inside a callback, set this to false since we just completed it.
12393 if (isYieldy) {
12394 callbackExpirationTime = NoWork;
12395 callbackID = null;
12396 }
12397 // If there's work left over, schedule a new callback.
12398 if (nextFlushedExpirationTime !== NoWork) {
12399 scheduleCallbackWithExpirationTime(nextFlushedRoot, nextFlushedExpirationTime);
12400 }
12401
12402 // Clean-up.
12403 finishRendering();
12404}
12405
12406function flushRoot(root, expirationTime) {
12407 !!isRendering ? invariant(false, 'work.commit(): Cannot commit while already rendering. This likely means you attempted to commit from inside a lifecycle method.') : void 0;
12408 // Perform work on root as if the given expiration time is the current time.
12409 // This has the effect of synchronously flushing all work up to and
12410 // including the given time.
12411 nextFlushedRoot = root;
12412 nextFlushedExpirationTime = expirationTime;
12413 performWorkOnRoot(root, expirationTime, false);
12414 // Flush any sync work that was scheduled by lifecycles
12415 performSyncWork();
12416}
12417
12418function finishRendering() {
12419 nestedUpdateCount = 0;
12420 lastCommittedRootDuringThisBatch = null;
12421
12422 if (completedBatches !== null) {
12423 var batches = completedBatches;
12424 completedBatches = null;
12425 for (var i = 0; i < batches.length; i++) {
12426 var batch = batches[i];
12427 try {
12428 batch._onComplete();
12429 } catch (error) {
12430 if (!hasUnhandledError) {
12431 hasUnhandledError = true;
12432 unhandledError = error;
12433 }
12434 }
12435 }
12436 }
12437
12438 if (hasUnhandledError) {
12439 var error = unhandledError;
12440 unhandledError = null;
12441 hasUnhandledError = false;
12442 throw error;
12443 }
12444}
12445
12446function performWorkOnRoot(root, expirationTime, isYieldy) {
12447 !!isRendering ? invariant(false, 'performWorkOnRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
12448
12449 isRendering = true;
12450
12451 // Check if this is async work or sync/expired work.
12452 if (!isYieldy) {
12453 // Flush work without yielding.
12454 // TODO: Non-yieldy work does not necessarily imply expired work. A renderer
12455 // may want to perform some work without yielding, but also without
12456 // requiring the root to complete (by triggering placeholders).
12457
12458 var finishedWork = root.finishedWork;
12459 if (finishedWork !== null) {
12460 // This root is already complete. We can commit it.
12461 completeRoot(root, finishedWork, expirationTime);
12462 } else {
12463 root.finishedWork = null;
12464 // If this root previously suspended, clear its existing timeout, since
12465 // we're about to try rendering again.
12466 var timeoutHandle = root.timeoutHandle;
12467 if (timeoutHandle !== noTimeout) {
12468 root.timeoutHandle = noTimeout;
12469 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
12470 cancelTimeout(timeoutHandle);
12471 }
12472 renderRoot(root, isYieldy);
12473 finishedWork = root.finishedWork;
12474 if (finishedWork !== null) {
12475 // We've completed the root. Commit it.
12476 completeRoot(root, finishedWork, expirationTime);
12477 }
12478 }
12479 } else {
12480 // Flush async work.
12481 var _finishedWork = root.finishedWork;
12482 if (_finishedWork !== null) {
12483 // This root is already complete. We can commit it.
12484 completeRoot(root, _finishedWork, expirationTime);
12485 } else {
12486 root.finishedWork = null;
12487 // If this root previously suspended, clear its existing timeout, since
12488 // we're about to try rendering again.
12489 var _timeoutHandle = root.timeoutHandle;
12490 if (_timeoutHandle !== noTimeout) {
12491 root.timeoutHandle = noTimeout;
12492 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
12493 cancelTimeout(_timeoutHandle);
12494 }
12495 renderRoot(root, isYieldy);
12496 _finishedWork = root.finishedWork;
12497 if (_finishedWork !== null) {
12498 // We've completed the root. Check the if we should yield one more time
12499 // before committing.
12500 if (!shouldYieldToRenderer()) {
12501 // Still time left. Commit the root.
12502 completeRoot(root, _finishedWork, expirationTime);
12503 } else {
12504 // There's no time left. Mark this root as complete. We'll come
12505 // back and commit it later.
12506 root.finishedWork = _finishedWork;
12507 }
12508 }
12509 }
12510 }
12511
12512 isRendering = false;
12513}
12514
12515function completeRoot(root, finishedWork, expirationTime) {
12516 // Check if there's a batch that matches this expiration time.
12517 var firstBatch = root.firstBatch;
12518 if (firstBatch !== null && firstBatch._expirationTime >= expirationTime) {
12519 if (completedBatches === null) {
12520 completedBatches = [firstBatch];
12521 } else {
12522 completedBatches.push(firstBatch);
12523 }
12524 if (firstBatch._defer) {
12525 // This root is blocked from committing by a batch. Unschedule it until
12526 // we receive another update.
12527 root.finishedWork = finishedWork;
12528 root.expirationTime = NoWork;
12529 return;
12530 }
12531 }
12532
12533 // Commit the root.
12534 root.finishedWork = null;
12535
12536 // Check if this is a nested update (a sync update scheduled during the
12537 // commit phase).
12538 if (root === lastCommittedRootDuringThisBatch) {
12539 // If the next root is the same as the previous root, this is a nested
12540 // update. To prevent an infinite loop, increment the nested update count.
12541 nestedUpdateCount++;
12542 } else {
12543 // Reset whenever we switch roots.
12544 lastCommittedRootDuringThisBatch = root;
12545 nestedUpdateCount = 0;
12546 }
12547 commitRoot(root, finishedWork);
12548}
12549
12550function onUncaughtError(error) {
12551 !(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;
12552 // Unschedule this root so we don't work on it again until there's
12553 // another update.
12554 nextFlushedRoot.expirationTime = NoWork;
12555 if (!hasUnhandledError) {
12556 hasUnhandledError = true;
12557 unhandledError = error;
12558 }
12559}
12560
12561// 0 is PROD, 1 is DEV.
12562// Might add PROFILE later.
12563
12564
12565var didWarnAboutNestedUpdates = void 0;
12566{
12567 didWarnAboutNestedUpdates = false;
12568
12569}
12570
12571function getContextForSubtree(parentComponent) {
12572 if (!parentComponent) {
12573 return emptyContextObject;
12574 }
12575
12576 var fiber = get(parentComponent);
12577 var parentContext = findCurrentUnmaskedContext(fiber);
12578
12579 if (fiber.tag === ClassComponent) {
12580 var Component = fiber.type;
12581 if (isContextProvider(Component)) {
12582 return processChildContext(fiber, Component, parentContext);
12583 }
12584 }
12585
12586 return parentContext;
12587}
12588
12589function scheduleRootUpdate(current$$1, element, expirationTime, callback) {
12590 {
12591 if (phase === 'render' && current$1 !== null && !didWarnAboutNestedUpdates) {
12592 didWarnAboutNestedUpdates = true;
12593 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');
12594 }
12595 }
12596
12597 var update = createUpdate(expirationTime);
12598 // Caution: React DevTools currently depends on this property
12599 // being called "element".
12600 update.payload = { element: element };
12601
12602 callback = callback === undefined ? null : callback;
12603 if (callback !== null) {
12604 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0;
12605 update.callback = callback;
12606 }
12607
12608 flushPassiveEffects();
12609 enqueueUpdate(current$$1, update);
12610 scheduleWork(current$$1, expirationTime);
12611
12612 return expirationTime;
12613}
12614
12615function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback) {
12616 // TODO: If this is a nested container, this won't be the root.
12617 var current$$1 = container.current;
12618
12619 {
12620 if (ReactFiberInstrumentation_1.debugTool) {
12621 if (current$$1.alternate === null) {
12622 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
12623 } else if (element === null) {
12624 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
12625 } else {
12626 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
12627 }
12628 }
12629 }
12630
12631 var context = getContextForSubtree(parentComponent);
12632 if (container.context === null) {
12633 container.context = context;
12634 } else {
12635 container.pendingContext = context;
12636 }
12637
12638 return scheduleRootUpdate(current$$1, element, expirationTime, callback);
12639}
12640
12641function createContainer(containerInfo, isConcurrent, hydrate) {
12642 return createFiberRoot(containerInfo, isConcurrent, hydrate);
12643}
12644
12645function updateContainer(element, container, parentComponent, callback) {
12646 var current$$1 = container.current;
12647 var currentTime = requestCurrentTime();
12648 var expirationTime = computeExpirationForFiber(currentTime, current$$1);
12649 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback);
12650}
12651
12652
12653
12654
12655
12656var overrideProps = null;
12657
12658{
12659 var copyWithSetImpl = function (obj, path, idx, value) {
12660 if (idx >= path.length) {
12661 return value;
12662 }
12663 var key = path[idx];
12664 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
12665 // $FlowFixMe number or string is fine here
12666 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
12667 return updated;
12668 };
12669
12670 var copyWithSet = function (obj, path, value) {
12671 return copyWithSetImpl(obj, path, 0, value);
12672 };
12673
12674 // Support DevTools props for function components, forwardRef, memo, host components, etc.
12675 overrideProps = function (fiber, path, value) {
12676 flushPassiveEffects();
12677 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
12678 if (fiber.alternate) {
12679 fiber.alternate.pendingProps = fiber.pendingProps;
12680 }
12681 scheduleWork(fiber, Sync);
12682 };
12683}
12684
12685function injectIntoDevTools(devToolsConfig) {
12686 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
12687 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
12688
12689
12690 return injectInternals(_assign({}, devToolsConfig, {
12691 overrideProps: overrideProps,
12692 currentDispatcherRef: ReactCurrentDispatcher,
12693 findHostInstanceByFiber: function (fiber) {
12694 var hostFiber = findCurrentHostFiber(fiber);
12695 if (hostFiber === null) {
12696 return null;
12697 }
12698 return hostFiber.stateNode;
12699 },
12700 findFiberByHostInstance: function (instance) {
12701 if (!findFiberByHostInstance) {
12702 // Might not be implemented by the renderer.
12703 return null;
12704 }
12705 return findFiberByHostInstance(instance);
12706 }
12707 }));
12708}
12709
12710// This file intentionally does *not* have the Flow annotation.
12711// Don't add it. See `./inline-typed.js` for an explanation.
12712
12713var container = _class({
12714
12715 grab: function(){
12716 for (var i = 0; i < arguments.length; i++) arguments[i].inject(this);
12717 return this;
12718 },
12719
12720 empty: function(){
12721 var node;
12722 while (node = this.firstChild) node.eject();
12723 return this;
12724 }
12725
12726});
12727
12728function elementFrom(node){
12729 if (node.toElement) return node.toElement();
12730 if (node.getDOMNode) return node.getDOMNode();
12731 if (node.getNode) return node.getNode();
12732 return node;
12733}
12734
12735var native_1 = _class({
12736
12737 // conventions
12738
12739 toElement: function(){
12740 return this.element;
12741 },
12742
12743 getDOMNode: function(){
12744 return this.toElement();
12745 },
12746
12747 getNode: function(){
12748 return this.toElement();
12749 },
12750
12751 // placement
12752
12753 inject: function(container){
12754 (container.containerElement || elementFrom(container))
12755 .appendChild(this.element);
12756 return this;
12757 },
12758
12759 injectBefore: function(sibling){
12760 var element = elementFrom(sibling);
12761 element.parentNode.insertBefore(this.element, element);
12762 return this;
12763 },
12764
12765 eject: function(){
12766 var element = this.element, parent = element.parentNode;
12767 if (parent) parent.removeChild(element); // TODO: VML Nodes are dead after being ejected
12768 return this;
12769 },
12770
12771 // events
12772
12773 subscribe: function(type, fn, bind){
12774 if (typeof type != 'string'){ // listen type / fn with object
12775 var subscriptions = [];
12776 for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
12777 return function(){ // unsubscribe
12778 for (var i = 0, l = subscriptions.length; i < l; i++)
12779 subscriptions[i]();
12780 return this;
12781 };
12782 } else { // listen to one
12783 if (!bind) bind = this;
12784 var bound;
12785 if (typeof fn === 'function'){
12786 bound = fn.bind ? fn.bind(bind)
12787 : function(){ return fn.apply(bind, arguments); };
12788 } else {
12789 bound = fn;
12790 }
12791 var element = this.element;
12792 if (element.addEventListener){
12793 element.addEventListener(type, bound, false);
12794 return function(){ // unsubscribe
12795 element.removeEventListener(type, bound, false);
12796 return this;
12797 };
12798 } else {
12799 element.attachEvent('on' + type, bound);
12800 return function(){ // unsubscribe
12801 element.detachEvent('on' + type, bound);
12802 return this;
12803 };
12804 }
12805 }
12806 }
12807
12808});
12809
12810var fps = 1000 / 60;
12811var invalids = [];
12812var renderTimer;
12813var renderInvalids = function(){
12814 clearTimeout(renderTimer);
12815 renderTimer = null;
12816 var canvases = invalids;
12817 invalids = [];
12818 for (var i = 0, l = canvases.length; i < l; i++){
12819 var c = canvases[i];
12820 c._valid = true;
12821 c.render();
12822 }
12823};
12824
12825var resolution = typeof window !== 'undefined' && window.devicePixelRatio || 1;
12826
12827var previousHit = null;
12828var previousHitSurface = null;
12829
12830var CanvasSurface = _class(native_1, container, {
12831
12832 initialize: function(width, height, existingElement){
12833 var element = this.element = existingElement || document.createElement('canvas');
12834 var context = this.context = element.getContext('2d');
12835 this._valid = true;
12836 if (width != null && height != null) this.resize(width, height);
12837
12838 element.addEventListener('mousemove', this, false);
12839 element.addEventListener('mouseout', this, false);
12840 element.addEventListener('mouseover', this, false);
12841 element.addEventListener('mouseup', this, false);
12842 element.addEventListener('mousedown', this, false);
12843 element.addEventListener('click', this, false);
12844 },
12845
12846 handleEvent: function(event){
12847 if (event.clientX == null) return;
12848 var element = this.element,
12849 rect = element.getBoundingClientRect(),
12850 x = event.clientX - rect.left - element.clientLeft,
12851 y = event.clientY - rect.top - element.clientTop,
12852 hit = this.hitTest(x, y);
12853
12854 if (hit !== previousHit){
12855 if (previousHit){
12856 previousHit.dispatch({
12857 type: 'mouseout',
12858 target: previousHit,
12859 relatedTarget: hit,
12860 sourceEvent: event
12861 });
12862 }
12863 if (hit){
12864 hit.dispatch({
12865 type: 'mouseover',
12866 target: hit,
12867 relatedTarget: previousHit,
12868 sourceEvent: event
12869 });
12870 }
12871 previousHit = hit;
12872 previousHitSurface = this;
12873 this.refreshCursor();
12874 }
12875
12876 if (hit) hit.dispatch(event);
12877 },
12878
12879 refreshCursor: function(){
12880 if (previousHitSurface !== this) return;
12881 var hit = previousHit, hitCursor = '', hitTooltip = '';
12882 while (hit){
12883 if (!hitCursor && hit._cursor){
12884 hitCursor = hit._cursor;
12885 if (hitTooltip) break;
12886 }
12887 if (!hitTooltip && hit._tooltip){
12888 hitTooltip = hit._tooltip;
12889 if (hitCursor) break;
12890 }
12891 hit = hit.parentNode;
12892 }
12893 // TODO: No way to set cursor/title on the surface
12894 this.element.style.cursor = hitCursor;
12895 this.element.title = hitTooltip;
12896 },
12897
12898 resize: function(width, height){
12899 var element = this.element;
12900 element.setAttribute('width', width * resolution);
12901 element.setAttribute('height', height * resolution);
12902 element.style.width = width + 'px';
12903 element.style.height = height + 'px';
12904 this.width = width;
12905 this.height = height;
12906 return this;
12907 },
12908
12909 invalidate: function(left, top, width, height){
12910 if (this._valid){
12911 this._valid = false;
12912 invalids.push(this);
12913 if (!renderTimer){
12914 if (window.mozRequestAnimationFrame){
12915 renderTimer = true;
12916 window.mozRequestAnimationFrame(renderInvalids);
12917 } else {
12918 renderTimer = setTimeout(renderInvalids, fps);
12919 }
12920 }
12921 }
12922 return this;
12923 },
12924
12925 hitTest: function(x, y){
12926 if (x < 0 || y < 0 || x > this.width || y > this.height) return null;
12927 var node = this.lastChild;
12928 while (node){
12929 var hit = node.hitTest(x, y);
12930 if (hit) return hit;
12931 node = node.previousSibling;
12932 }
12933 return null;
12934 },
12935
12936 render: function(){
12937 var node = this.firstChild, context = this.context;
12938 context.setTransform(resolution, 0, 0, resolution, 0, 0);
12939 context.clearRect(0, 0, this.width, this.height);
12940 while (node){
12941 node.renderTo(context, resolution, 0, 0, resolution, 0, 0);
12942 node = node.nextSibling;
12943 }
12944 this.refreshCursor();
12945 }
12946
12947});
12948
12949CanvasSurface.tagName = 'canvas';
12950
12951var surface = CanvasSurface;
12952
12953var path$2 = _class({
12954
12955 initialize: function(path){
12956 this.reset().push(path);
12957 },
12958
12959 /* parser */
12960
12961 push: function(){
12962 var p = Array.prototype.join.call(arguments, ' ')
12963 .match(/[a-df-z]|[\-+]?(?:[\d\.]e[\-+]?|[^\s\-+,a-z])+/ig);
12964 if (!p) return this;
12965
12966 var last, cmd = p[0], i = 1;
12967 while (cmd){
12968 switch (cmd){
12969 case 'm': this.move(p[i++], p[i++]); break;
12970 case 'l': this.line(p[i++], p[i++]); break;
12971 case 'c': this.curve(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
12972 case 's': this.curve(p[i++], p[i++], null, null, p[i++], p[i++]); break;
12973 case 'q': this.curve(p[i++], p[i++], p[i++], p[i++]); break;
12974 case 't': this.curve(p[i++], p[i++]); break;
12975 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;
12976 case 'h': this.line(p[i++], 0); break;
12977 case 'v': this.line(0, p[i++]); break;
12978
12979 case 'M': this.moveTo(p[i++], p[i++]); break;
12980 case 'L': this.lineTo(p[i++], p[i++]); break;
12981 case 'C': this.curveTo(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
12982 case 'S': this.curveTo(p[i++], p[i++], null, null, p[i++], p[i++]); break;
12983 case 'Q': this.curveTo(p[i++], p[i++], p[i++], p[i++]); break;
12984 case 'T': this.curveTo(p[i++], p[i++]); break;
12985 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;
12986 case 'H': this.lineTo(p[i++], this.penY); break;
12987 case 'V': this.lineTo(this.penX, p[i++]); break;
12988
12989 case 'Z': case 'z': this.close(); break;
12990 default: cmd = last; i--; continue;
12991 }
12992
12993 last = cmd;
12994 if (last == 'm') last = 'l';
12995 else if (last == 'M') last = 'L';
12996 cmd = p[i++];
12997 }
12998 return this;
12999 },
13000
13001 /* utility methods */
13002
13003 reset: function(){
13004 this.penX = this.penY = 0;
13005 this.penDownX = this.penDownY = null;
13006 this._pivotX = this._pivotY = 0;
13007 this.onReset();
13008 return this;
13009 },
13010
13011 move: function(x,y){
13012 this.onMove(this.penX, this.penY, this._pivotX = this.penX += (+x), this._pivotY = this.penY += (+y));
13013 return this;
13014 },
13015 moveTo: function(x,y){
13016 this.onMove(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
13017 return this;
13018 },
13019
13020 line: function(x,y){
13021 return this.lineTo(this.penX + (+x), this.penY + (+y));
13022 },
13023 lineTo: function(x,y){
13024 if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
13025 this.onLine(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
13026 return this;
13027 },
13028
13029 curve: function(c1x, c1y, c2x, c2y, ex, ey){
13030 var x = this.penX, y = this.penY;
13031 return this.curveTo(
13032 x + (+c1x), y + (+c1y),
13033 c2x == null ? null : x + (+c2x),
13034 c2y == null ? null : y + (+c2y),
13035 ex == null ? null : x + (+ex),
13036 ey == null ? null : y + (+ey)
13037 );
13038 },
13039 curveTo: function(c1x, c1y, c2x, c2y, ex, ey){
13040 var x = this.penX, y = this.penY;
13041 if (c2x == null){
13042 c2x = +c1x; c2y = +c1y;
13043 c1x = (x * 2) - (this._pivotX || 0); c1y = (y * 2) - (this._pivotY || 0);
13044 }
13045 if (ex == null){
13046 this._pivotX = +c1x; this._pivotY = +c1y;
13047 ex = +c2x; ey = +c2y;
13048 c2x = (ex + (+c1x) * 2) / 3; c2y = (ey + (+c1y) * 2) / 3;
13049 c1x = (x + (+c1x) * 2) / 3; c1y = (y + (+c1y) * 2) / 3;
13050 } else {
13051 this._pivotX = +c2x; this._pivotY = +c2y;
13052 }
13053 if (this.penDownX == null){ this.penDownX = x; this.penDownY = y; }
13054 this.onBezierCurve(x, y, +c1x, +c1y, +c2x, +c2y, this.penX = +ex, this.penY = +ey);
13055 return this;
13056 },
13057
13058 arc: function(x, y, rx, ry, outer, counterClockwise, rotation){
13059 return this.arcTo(this.penX + (+x), this.penY + (+y), rx, ry, outer, counterClockwise, rotation);
13060 },
13061 arcTo: function(x, y, rx, ry, outer, counterClockwise, rotation){
13062 ry = Math.abs(+ry || +rx || (+y - this.penY));
13063 rx = Math.abs(+rx || (+x - this.penX));
13064
13065 if (!rx || !ry || (x == this.penX && y == this.penY)) return this.lineTo(x, y);
13066
13067 var tX = this.penX, tY = this.penY, clockwise = !+counterClockwise, large = !!+outer;
13068
13069 var rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad);
13070 x -= tX; y -= tY;
13071
13072 // Ellipse Center
13073 var cx = cos * x / 2 + sin * y / 2,
13074 cy = -sin * x / 2 + cos * y / 2,
13075 rxry = rx * rx * ry * ry,
13076 rycx = ry * ry * cx * cx,
13077 rxcy = rx * rx * cy * cy,
13078 a = rxry - rxcy - rycx;
13079
13080 if (a < 0){
13081 a = Math.sqrt(1 - a / rxry);
13082 rx *= a; ry *= a;
13083 cx = x / 2; cy = y / 2;
13084 } else {
13085 a = Math.sqrt(a / (rxcy + rycx));
13086 if (large == clockwise) a = -a;
13087 var cxd = -a * cy * rx / ry,
13088 cyd = a * cx * ry / rx;
13089 cx = cos * cxd - sin * cyd + x / 2;
13090 cy = sin * cxd + cos * cyd + y / 2;
13091 }
13092
13093 // Rotation + Scale Transform
13094 var xx = cos / rx, yx = sin / rx,
13095 xy = -sin / ry, yy = cos / ry;
13096
13097 // Start and End Angle
13098 var sa = Math.atan2(xy * -cx + yy * -cy, xx * -cx + yx * -cy),
13099 ea = Math.atan2(xy * (x - cx) + yy * (y - cy), xx * (x - cx) + yx * (y - cy));
13100
13101 cx += tX; cy += tY;
13102 x += tX; y += tY;
13103
13104 // Circular Arc
13105 if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
13106 this.onArc(
13107 tX, tY, this._pivotX = this.penX = x, this._pivotY = this.penY = y,
13108 cx, cy, rx, ry, sa, ea, !clockwise, rotation
13109 );
13110 return this;
13111 },
13112
13113 counterArc: function(x, y, rx, ry, outer){
13114 return this.arc(x, y, rx, ry, outer, true);
13115 },
13116 counterArcTo: function(x, y, rx, ry, outer){
13117 return this.arcTo(x, y, rx, ry, outer, true);
13118 },
13119
13120 close: function(){
13121 if (this.penDownX != null){
13122 this.onClose(this.penX, this.penY, this.penX = this.penDownX, this.penY = this.penDownY);
13123 this.penDownX = null;
13124 }
13125 return this;
13126 },
13127
13128 /* overridable handlers */
13129
13130 onReset: function(){
13131 },
13132
13133 onMove: function(sx, sy, ex, ey){
13134 },
13135
13136 onLine: function(sx, sy, ex, ey){
13137 this.onBezierCurve(sx, sy, sx, sy, ex, ey, ex, ey);
13138 },
13139
13140 onBezierCurve: function(sx, sy, c1x, c1y, c2x, c2y, ex, ey){
13141 var gx = ex - sx, gy = ey - sy,
13142 g = gx * gx + gy * gy,
13143 v1, v2, cx, cy, u;
13144
13145 cx = c1x - sx; cy = c1y - sy;
13146 u = cx * gx + cy * gy;
13147
13148 if (u > g){
13149 cx -= gx;
13150 cy -= gy;
13151 } else if (u > 0 && g != 0){
13152 cx -= u/g * gx;
13153 cy -= u/g * gy;
13154 }
13155
13156 v1 = cx * cx + cy * cy;
13157
13158 cx = c2x - sx; cy = c2y - sy;
13159 u = cx * gx + cy * gy;
13160
13161 if (u > g){
13162 cx -= gx;
13163 cy -= gy;
13164 } else if (u > 0 && g != 0){
13165 cx -= u/g * gx;
13166 cy -= u/g * gy;
13167 }
13168
13169 v2 = cx * cx + cy * cy;
13170
13171 if (v1 < 0.01 && v2 < 0.01){
13172 this.onLine(sx, sy, ex, ey);
13173 return;
13174 }
13175
13176 // Avoid infinite recursion
13177 if (isNaN(v1) || isNaN(v2)){
13178 throw new Error('Bad input');
13179 }
13180
13181 // Split curve
13182 var s1x = (c1x + c2x) * 0.5, s1y = (c1y + c2y) * 0.5,
13183 l1x = (c1x + sx) * 0.5, l1y = (c1y + sy) * 0.5,
13184 l2x = (l1x + s1x) * 0.5, l2y = (l1y + s1y) * 0.5,
13185 r2x = (ex + c2x) * 0.5, r2y = (ey + c2y) * 0.5,
13186 r1x = (r2x + s1x) * 0.5, r1y = (r2y + s1y) * 0.5,
13187 l2r1x = (l2x + r1x) * 0.5, l2r1y = (l2y + r1y) * 0.5;
13188
13189 // TODO: Manual stack if necessary. Currently recursive without tail optimization.
13190 this.onBezierCurve(sx, sy, l1x, l1y, l2x, l2y, l2r1x, l2r1y);
13191 this.onBezierCurve(l2r1x, l2r1y, r1x, r1y, r2x, r2y, ex, ey);
13192 },
13193
13194 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
13195 // Inverse Rotation + Scale Transform
13196 var rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad),
13197 xx = cos * rx, yx = -sin * ry,
13198 xy = sin * rx, yy = cos * ry;
13199
13200 // Bezier Curve Approximation
13201 var arc = ea - sa;
13202 if (arc < 0 && !ccw) arc += Math.PI * 2;
13203 else if (arc > 0 && ccw) arc -= Math.PI * 2;
13204
13205 var n = Math.ceil(Math.abs(arc / (Math.PI / 2))),
13206 step = arc / n,
13207 k = (4 / 3) * Math.tan(step / 4);
13208
13209 var x = Math.cos(sa), y = Math.sin(sa);
13210
13211 for (var i = 0; i < n; i++){
13212 var cp1x = x - k * y, cp1y = y + k * x;
13213
13214 sa += step;
13215 x = Math.cos(sa); y = Math.sin(sa);
13216
13217 var cp2x = x + k * y, cp2y = y - k * x;
13218
13219 this.onBezierCurve(
13220 sx, sy,
13221 cx + xx * cp1x + yx * cp1y, cy + xy * cp1x + yy * cp1y,
13222 cx + xx * cp2x + yx * cp2y, cy + xy * cp2x + yy * cp2y,
13223 (sx = (cx + xx * x + yx * y)), (sy = (cy + xy * x + yy * y))
13224 );
13225 }
13226 },
13227
13228 onClose: function(sx, sy, ex, ey){
13229 this.onLine(sx, sy, ex, ey);
13230 }
13231
13232});
13233
13234var CanvasPath = _class(path$2, {
13235
13236 initialize: function(path){
13237 this.reset();
13238 if (path instanceof CanvasPath){
13239 this.path = path.path.slice(0);
13240 } else if (path){
13241 if (path.applyToPath)
13242 path.applyToPath(this);
13243 else
13244 this.push(path);
13245 }
13246 },
13247
13248 onReset: function(){
13249 this.path = [];
13250 },
13251
13252 onMove: function(sx, sy, x, y){
13253 this.path.push(function(context){
13254 context.moveTo(x, y);
13255 });
13256 },
13257
13258 onLine: function(sx, sy, x, y){
13259 this.path.push(function(context){
13260 context.lineTo(x, y);
13261 });
13262 },
13263
13264 onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
13265 this.path.push(function(context){
13266 context.bezierCurveTo(p1x, p1y, p2x, p2y, x, y);
13267 });
13268 },
13269
13270 _arcToBezier: path$2.prototype.onArc,
13271
13272 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
13273 if (rx != ry || rotation) return this._arcToBezier(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation);
13274 this.path.push(function(context){
13275 context.arc(cx, cy, rx, sa, ea, ccw);
13276 });
13277 },
13278
13279 onClose: function(){
13280 this.path.push(function(context){
13281 context.closePath();
13282 });
13283 },
13284
13285 toCommands: function(){
13286 return this.path.slice(0);
13287 }
13288
13289});
13290
13291var path = CanvasPath;
13292
13293var colors = {
13294 maroon: '#800000', red: '#ff0000', orange: '#ffA500', yellow: '#ffff00', olive: '#808000',
13295 purple: '#800080', fuchsia: "#ff00ff", white: '#ffffff', lime: '#00ff00', green: '#008000',
13296 navy: '#000080', blue: '#0000ff', aqua: '#00ffff', teal: '#008080',
13297 black: '#000000', silver: '#c0c0c0', gray: '#808080'
13298};
13299
13300var map = function(array, fn){
13301 var results = [];
13302 for (var i = 0, l = array.length; i < l; i++)
13303 results[i] = fn(array[i], i);
13304 return results;
13305};
13306
13307var Color = function(color, type){
13308
13309 if (color.isColor){
13310
13311 this.red = color.red;
13312 this.green = color.green;
13313 this.blue = color.blue;
13314 this.alpha = color.alpha;
13315
13316 } else {
13317
13318 var namedColor = colors[color];
13319 if (namedColor){
13320 color = namedColor;
13321 type = 'hex';
13322 }
13323
13324 switch (typeof color){
13325 case 'string': if (!type) type = (type = color.match(/^rgb|^hsb|^hsl/)) ? type[0] : 'hex'; break;
13326 case 'object': type = type || 'rgb'; color = color.toString(); break;
13327 case 'number': type = 'hex'; color = color.toString(16); break;
13328 }
13329
13330 color = Color['parse' + type.toUpperCase()](color);
13331 this.red = color[0];
13332 this.green = color[1];
13333 this.blue = color[2];
13334 this.alpha = color[3];
13335 }
13336
13337 this.isColor = true;
13338
13339};
13340
13341var limit = function(number, min, max){
13342 return Math.min(max, Math.max(min, number));
13343};
13344
13345var listMatch = /([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,?\s*([-.\d]*\%?)/;
13346var hexMatch = /^#?([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{0,2})$/i;
13347
13348Color.parseRGB = function(color){
13349 return map(color.match(listMatch).slice(1), function(bit, i){
13350 if (bit) bit = parseFloat(bit) * (bit[bit.length - 1] == '%' ? 2.55 : 1);
13351 return (i < 3) ? Math.round(((bit %= 256) < 0) ? bit + 256 : bit) : limit(((bit === '') ? 1 : Number(bit)), 0, 1);
13352 });
13353};
13354
13355Color.parseHEX = function(color){
13356 if (color.length == 1) color = color + color + color;
13357 return map(color.match(hexMatch).slice(1), function(bit, i){
13358 if (i == 3) return (bit) ? parseInt(bit, 16) / 255 : 1;
13359 return parseInt((bit.length == 1) ? bit + bit : bit, 16);
13360 });
13361};
13362
13363Color.parseHSB = function(color){
13364 var hsb = map(color.match(listMatch).slice(1), function(bit, i){
13365 if (bit) bit = parseFloat(bit);
13366 if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
13367 else if (i < 3) return limit(Math.round(bit), 0, 100);
13368 else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
13369 });
13370
13371 var a = hsb[3];
13372 var br = Math.round(hsb[2] / 100 * 255);
13373 if (hsb[1] == 0) return [br, br, br, a];
13374
13375 var hue = hsb[0];
13376 var f = hue % 60;
13377 var p = Math.round((hsb[2] * (100 - hsb[1])) / 10000 * 255);
13378 var q = Math.round((hsb[2] * (6000 - hsb[1] * f)) / 600000 * 255);
13379 var t = Math.round((hsb[2] * (6000 - hsb[1] * (60 - f))) / 600000 * 255);
13380
13381 switch (Math.floor(hue / 60)){
13382 case 0: return [br, t, p, a];
13383 case 1: return [q, br, p, a];
13384 case 2: return [p, br, t, a];
13385 case 3: return [p, q, br, a];
13386 case 4: return [t, p, br, a];
13387 default: return [br, p, q, a];
13388 }
13389};
13390
13391Color.parseHSL = function(color){
13392 var hsb = map(color.match(listMatch).slice(1), function(bit, i){
13393 if (bit) bit = parseFloat(bit);
13394 if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
13395 else if (i < 3) return limit(Math.round(bit), 0, 100);
13396 else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
13397 });
13398
13399 var h = hsb[0] / 60;
13400 var s = hsb[1] / 100;
13401 var l = hsb[2] / 100;
13402 var a = hsb[3];
13403
13404 var c = (1 - Math.abs(2 * l - 1)) * s;
13405 var x = c * (1 - Math.abs(h % 2 - 1));
13406 var m = l - c / 2;
13407
13408 var p = Math.round((c + m) * 255);
13409 var q = Math.round((x + m) * 255);
13410 var t = Math.round((m) * 255);
13411
13412 switch (Math.floor(h)){
13413 case 0: return [p, q, t, a];
13414 case 1: return [q, p, t, a];
13415 case 2: return [t, p, q, a];
13416 case 3: return [t, q, p, a];
13417 case 4: return [q, t, p, a];
13418 default: return [p, t, q, a];
13419 }
13420};
13421
13422var toString = function(type, array){
13423 if (array[3] != 1) type += 'a';
13424 else array.pop();
13425 return type + '(' + array.join(', ') + ')';
13426};
13427
13428Color.prototype = {
13429
13430 toHSB: function(array){
13431 var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
13432
13433 var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
13434 var hue = 0, saturation = (delta != 0) ? delta / max : 0, brightness = max / 255;
13435 if (saturation){
13436 var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
13437 hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
13438 if ((hue /= 6) < 0) hue++;
13439 }
13440
13441 var hsb = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100), alpha];
13442
13443 return (array) ? hsb : toString('hsb', hsb);
13444 },
13445
13446 toHSL: function(array){
13447 var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
13448
13449 var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
13450 var hue = 0, saturation = (delta != 0) ? delta / (255 - Math.abs((max + min) - 255)) : 0, lightness = (max + min) / 512;
13451 if (saturation){
13452 var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
13453 hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
13454 if ((hue /= 6) < 0) hue++;
13455 }
13456
13457 var hsl = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(lightness * 100), alpha];
13458
13459 return (array) ? hsl : toString('hsl', hsl);
13460 },
13461
13462 toHEX: function(array){
13463
13464 var a = this.alpha;
13465 var alpha = ((a = Math.round((a * 255)).toString(16)).length == 1) ? a + a : a;
13466
13467 var hex = map([this.red, this.green, this.blue], function(bit){
13468 bit = bit.toString(16);
13469 return (bit.length == 1) ? '0' + bit : bit;
13470 });
13471
13472 return (array) ? hex.concat(alpha) : '#' + hex.join('') + ((alpha == 'ff') ? '' : alpha);
13473 },
13474
13475 toRGB: function(array){
13476 var rgb = [this.red, this.green, this.blue, this.alpha];
13477 return (array) ? rgb : toString('rgb', rgb);
13478 }
13479
13480};
13481
13482Color.prototype.toString = Color.prototype.toRGB;
13483
13484Color.hex = function(hex){
13485 return new Color(hex, 'hex');
13486};
13487
13488if (commonjsGlobal.hex == null) commonjsGlobal.hex = Color.hex;
13489
13490Color.hsb = function(h, s, b, a){
13491 return new Color([h || 0, s || 0, b || 0, (a == null) ? 1 : a], 'hsb');
13492};
13493
13494if (commonjsGlobal.hsb == null) commonjsGlobal.hsb = Color.hsb;
13495
13496Color.hsl = function(h, s, l, a){
13497 return new Color([h || 0, s || 0, l || 0, (a == null) ? 1 : a], 'hsl');
13498};
13499
13500if (commonjsGlobal.hsl == null) commonjsGlobal.hsl = Color.hsl;
13501
13502Color.rgb = function(r, g, b, a){
13503 return new Color([r || 0, g || 0, b || 0, (a == null) ? 1 : a], 'rgb');
13504};
13505
13506if (commonjsGlobal.rgb == null) commonjsGlobal.rgb = Color.rgb;
13507
13508Color.detach = function(color){
13509 color = new Color(color);
13510 return [Color.rgb(color.red, color.green, color.blue).toString(), color.alpha];
13511};
13512
13513var color = Color;
13514
13515var dummy = _class({
13516
13517 // placement
13518
13519 _resetPlacement: function(){
13520 var container = this.parentNode;
13521 if (container){
13522 var previous = this.previousSibling, next = this.nextSibling;
13523 if (previous){
13524 previous.nextSibling = next;
13525 } else {
13526 container.firstChild = next;
13527 }
13528 if (next){
13529 next.previousSibling = previous;
13530 } else {
13531 container.lastChild = this.previousSibling;
13532 }
13533 }
13534 this.previousSibling = null;
13535 this.nextSibling = null;
13536 this.parentNode = null;
13537 return this;
13538 },
13539
13540 inject: function(container){
13541 this._resetPlacement();
13542 var last = container.lastChild;
13543 if (last){
13544 last.nextSibling = this;
13545 this.previousSibling = last;
13546 } else {
13547 container.firstChild = this;
13548 }
13549 container.lastChild = this;
13550 this.parentNode = container;
13551 this._place();
13552 return this;
13553 },
13554
13555 injectBefore: function(sibling){
13556 this._resetPlacement();
13557 var container = sibling.parentNode;
13558 if (!container) return this;
13559 var previous = sibling.previousSibling;
13560 if (previous){
13561 previous.nextSibling = this;
13562 this.previousSibling = previous;
13563 } else {
13564 container.firstChild = this;
13565 }
13566 sibling.previousSibling = this;
13567 this.nextSibling = sibling;
13568 this.parentNode = container;
13569 this._place();
13570 return this;
13571 },
13572
13573 eject: function(){
13574 this._resetPlacement();
13575 this._place();
13576 return this;
13577 },
13578
13579 _place: function(){},
13580
13581 // events
13582
13583 dispatch: function(event){
13584 var events = this._events,
13585 listeners = events && events[event.type];
13586 if (listeners){
13587 listeners = listeners.slice(0);
13588 for (var i = 0, l = listeners.length; i < l; i++){
13589 var fn = listeners[i], result;
13590 if (typeof fn == 'function')
13591 result = fn.call(this, event);
13592 else
13593 result = fn.handleEvent(event);
13594 if (result === false) event.preventDefault();
13595 }
13596 }
13597 if (this.parentNode && this.parentNode.dispatch){
13598 this.parentNode.dispatch(event);
13599 }
13600 },
13601
13602 subscribe: function(type, fn, bind){
13603 if (typeof type != 'string'){ // listen type / fn with object
13604 var subscriptions = [];
13605 for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
13606 return function(){ // unsubscribe
13607 for (var i = 0, l = subscriptions.length; i < l; i++)
13608 subscriptions[i]();
13609 return this;
13610 };
13611 } else { // listen to one
13612 var bound = typeof fn === 'function' ? fn.bind(bind || this) : fn,
13613 events = this._events || (this._events = {}),
13614 listeners = events[type] || (events[type] = []);
13615 listeners.push(bound);
13616 return function(){
13617 // unsubscribe
13618 for (var i = 0, l = listeners.length; i < l; i++){
13619 if (listeners[i] === bound){
13620 listeners.splice(i, 1);
13621 break;
13622 }
13623 }
13624 }
13625 }
13626 }
13627
13628});
13629
13630var CanvasNode = _class(transform, dummy, {
13631
13632 invalidate: function(){
13633 if (this.parentNode) this.parentNode.invalidate();
13634 if (this._layer) this._layerCache = null;
13635 return this;
13636 },
13637
13638 _place: function(){
13639 this.invalidate();
13640 },
13641
13642 _transform: function(){
13643 this.invalidate();
13644 },
13645
13646 blend: function(opacity){
13647 if (opacity >= 1 && this._layer) this._layer = null;
13648 this._opacity = opacity;
13649 if (this.parentNode) this.parentNode.invalidate();
13650 return this;
13651 },
13652
13653 // visibility
13654
13655 hide: function(){
13656 this._invisible = true;
13657 if (this.parentNode) this.parentNode.invalidate();
13658 return this;
13659 },
13660
13661 show: function(){
13662 this._invisible = false;
13663 if (this.parentNode) this.parentNode.invalidate();
13664 return this;
13665 },
13666
13667 // interaction
13668
13669 indicate: function(cursor, tooltip){
13670 this._cursor = cursor;
13671 this._tooltip = tooltip;
13672 return this.invalidate();
13673 },
13674
13675 hitTest: function(x, y){
13676 if (this._invisible) return null;
13677 var point = this.inversePoint(x, y);
13678 if (!point) return null;
13679 return this.localHitTest(point.x, point.y);
13680 },
13681
13682 // rendering
13683
13684 renderTo: function(context, xx, yx, xy, yy, x, y){
13685 var opacity = this._opacity;
13686 if (opacity == null || opacity >= 1){
13687 return this.renderLayerTo(context, xx, yx, xy, yy, x, y);
13688 }
13689
13690 // Render to a compositing layer and cache it
13691
13692 var layer = this._layer, canvas, isDirty = true,
13693 w = context.canvas.width, h = context.canvas.height;
13694 if (layer){
13695 layer.setTransform(1, 0, 0, 1, 0, 0);
13696 canvas = layer.canvas;
13697 if (canvas.width < w || canvas.height < h){
13698 canvas.width = w;
13699 canvas.height = h;
13700 } else {
13701 var c = this._layerCache;
13702 if (c && c.xx === xx && c.yx === yx && c.xy === xy
13703 && c.yy === yy && c.x === x && c.y === y){
13704 isDirty = false;
13705 } else {
13706 layer.clearRect(0, 0, w, h);
13707 }
13708 }
13709 } else {
13710 canvas = document.createElement('canvas');
13711 canvas.width = w;
13712 canvas.height = h;
13713 this._layer = layer = canvas.getContext('2d');
13714 }
13715
13716 if (isDirty){
13717 this.renderLayerTo(layer, xx, yx, xy, yy, x, y);
13718 this._layerCache = {
13719 xx: xx,
13720 yx: yx,
13721 xy: xy,
13722 yy: yy,
13723 x: x,
13724 y: y
13725 };
13726 }
13727
13728 context.globalAlpha = opacity;
13729 context.setTransform(1, 0, 0, 1, 0, 0);
13730 context.drawImage(
13731 canvas,
13732 0, 0, w, h,
13733 0, 0, w, h
13734 );
13735 context.globalAlpha = 1;
13736 }
13737
13738});
13739
13740var node = CanvasNode;
13741
13742var genericCanvas = typeof document !== 'undefined' && document.createElement('canvas');
13743var genericContext = genericCanvas && genericCanvas.getContext && genericCanvas.getContext('2d');
13744
13745function recolorImage(img, color1, color2){
13746 // TODO: Fix this experimental implementation
13747 color1 = color.detach(color1);
13748 color2 = color.detach(color2);
13749 var canvas = document.createElement('canvas'),
13750 context = canvas.getContext('2d');
13751 canvas.width = img.width;
13752 canvas.height = img.height;
13753 context.fillStyle = color2[0];
13754 context.fillRect(0, 0, img.width, img.height);
13755 context.globalCompositeOperation = 'lighter';
13756 context.drawImage(img, 0, 0);
13757 return canvas;
13758}
13759
13760var Base = _class(node, {
13761
13762 initialize: function(){
13763 this._fill = null;
13764 this._pendingFill = null;
13765 this._fillTransform = null;
13766 this._stroke = null;
13767 this._strokeCap = null;
13768 this._strokeDash = null;
13769 this._strokeJoin = null;
13770 this._strokeWidth = null;
13771 },
13772
13773 /* styles */
13774
13775 _addColors: function(gradient, stops){
13776 // Enumerate stops, assumes offsets are enumerated in order
13777 // TODO: Sort. Chrome doesn't always enumerate in expected order but requires stops to be specified in order.
13778 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++)
13779 gradient.addColorStop(i / l, new color(stops[i]).toString());
13780 else for (var offset in stops)
13781 gradient.addColorStop(offset, new color(stops[offset]).toString());
13782 return gradient;
13783 },
13784
13785
13786 fill: function(color$$1){
13787 if (arguments.length > 1) return this.fillLinear(arguments);
13788 if (this._pendingFill) this._pendingFill();
13789 this._fill = color$$1 ? new color(color$$1).toString() : null;
13790 return this.invalidate();
13791 },
13792
13793 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
13794 if (focusX == null) focusX = (this.left || 0) + (this.width || 0) * 0.5;
13795 if (focusY == null) focusY = (this.top || 0) + (this.height || 0) * 0.5;
13796 if (radiusY == null) radiusY = radiusX || (this.height * 0.5) || 0;
13797 if (radiusX == null) radiusX = (this.width || 0) * 0.5;
13798 if (centerX == null) centerX = focusX;
13799 if (centerY == null) centerY = focusY;
13800
13801 centerX += centerX - focusX;
13802 centerY += centerY - focusY;
13803
13804 if (radiusX === 0 || radiusX === '0') return this.fillLinear(stops);
13805 var ys = radiusY / radiusX;
13806
13807 if (this._pendingFill) this._pendingFill();
13808
13809 var gradient = genericContext.createRadialGradient(focusX, focusY / ys, 0, centerX, centerY / ys, radiusX * 2);
13810
13811 // Double fill radius to simulate repeating gradient
13812 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++){
13813 gradient.addColorStop(i / l / 2, new color(stops[i]).toString());
13814 gradient.addColorStop(1 - i / l / 2, new color(stops[i]).toString());
13815 } else for (var offset in stops){
13816 gradient.addColorStop(offset / 2, new color(stops[offset]).toString());
13817 gradient.addColorStop(1- offset / 2, new color(stops[offset]).toString());
13818 }
13819
13820 this._fill = gradient;
13821 this._fillTransform = new transform(1, 0, 0, ys);
13822 return this.invalidate();
13823 },
13824
13825 fillLinear: function(stops, x1, y1, x2, y2){
13826 if (arguments.length < 5){
13827 var angle = ((x1 == null) ? 270 : x1) * Math.PI / 180;
13828
13829 var x = Math.cos(angle), y = -Math.sin(angle),
13830 l = (Math.abs(x) + Math.abs(y)) / 2,
13831 w = this.width || 1, h = this.height || 1;
13832
13833 x *= l; y *= l;
13834
13835 x1 = 0.5 - x;
13836 x2 = 0.5 + x;
13837 y1 = 0.5 - y;
13838 y2 = 0.5 + y;
13839 this._fillTransform = new transform(w, 0, 0, h);
13840 } else {
13841 this._fillTransform = null;
13842 }
13843 if (this._pendingFill) this._pendingFill();
13844 var gradient = genericContext.createLinearGradient(x1, y1, x2, y2);
13845 this._addColors(gradient, stops);
13846 this._fill = gradient;
13847 return this.invalidate();
13848 },
13849
13850 fillImage: function(url, width, height, left, top, color1, color2){
13851 if (this._pendingFill) this._pendingFill();
13852 var img = url;
13853 if (!(img instanceof Image)){
13854 img = new Image();
13855 img.src = url;
13856 }
13857 if (img.width && img.height){
13858 return this._fillImage(img, width, height, left || 0, top || 0, color1, color2);
13859 }
13860
13861 // Not yet loaded
13862 this._fill = null;
13863 var self = this,
13864 callback = function(){
13865 cancel();
13866 self._fillImage(img, width, height, left || 0, top || 0, color1, color2);
13867 },
13868 cancel = function(){
13869 img.removeEventListener('load', callback, false);
13870 self._pendingFill = null;
13871 };
13872 this._pendingFill = cancel;
13873 img.addEventListener('load', callback, false);
13874 return this;
13875 },
13876
13877 _fillImage: function(img, width, height, left, top, color1, color2){
13878 var w = width ? width / img.width : 1,
13879 h = height ? height / img.height : 1;
13880 if (color1 != null) img = recolorImage(img, color1, color2);
13881 this._fill = genericContext.createPattern(img, 'repeat');
13882 this._fillTransform = new transform(w, 0, 0, h, left || 0, top || 0);
13883 return this.invalidate();
13884 },
13885
13886 stroke: function(color$$1, width, cap, join, dash){
13887 this._stroke = color$$1 ? new color(color$$1).toString() : null;
13888 this._strokeWidth = (width != null) ? width : 1;
13889 this._strokeCap = (cap != null) ? cap : 'round';
13890 this._strokeJoin = (join != null) ? join : 'round';
13891 this._strokeDash = dash;
13892 return this.invalidate();
13893 },
13894
13895 // Rendering
13896
13897 element_renderTo: node.prototype.renderTo,
13898
13899 renderTo: function(context, xx, yx, xy, yy, x, y){
13900 var opacity = this._opacity;
13901 if (opacity == null || opacity >= 1){
13902 return this.renderLayerTo(context, xx, yx, xy, yy, x, y);
13903 }
13904 if (this._fill && this._stroke){
13905 return this.element_renderTo(context, xx, yx, xy, yy, x, y);
13906 }
13907 context.globalAlpha = opacity;
13908 var r = this.renderLayerTo(context, xx, yx, xy, yy, x, y);
13909 context.globalAlpha = 1;
13910 return r;
13911 },
13912
13913 renderLayerTo: function(context, xx, yx, xy, yy, x, y){
13914 context.setTransform(xx, yx, xy, yy, x, y);
13915 this.renderShapeTo(context);
13916 }
13917
13918});
13919
13920Base._genericContext = genericContext;
13921
13922var base = Base;
13923
13924var shape = _class(base, {
13925
13926 base_initialize: base.prototype.initialize,
13927
13928 initialize: function(path$$1, width, height){
13929 this.base_initialize();
13930 this.width = width;
13931 this.height = height;
13932 if (path$$1 != null) this.draw(path$$1);
13933 },
13934
13935 draw: function(path$$1, width, height){
13936 if (!(path$$1 instanceof path)) path$$1 = new path(path$$1);
13937 this.path = path$$1;
13938 this._commands = path$$1.toCommands();
13939 if (width != null) this.width = width;
13940 if (height != null) this.height = height;
13941 return this.invalidate();
13942 },
13943
13944 localHitTest: function(x, y){
13945 if (!this._fill) return null;
13946 if (this.width == null || this.height == null){
13947 var context = base._genericContext, commands = this._commands;
13948 if (!commands) return null;
13949 context.beginPath();
13950 for (var i = 0, l = commands.length; i < l; i++)
13951 commands[i](context);
13952 return context.isPointInPath(x, y) ? this : null;
13953 }
13954 if (x > 0 && y > 0 && x < this.width && y < this.height){
13955 return this;
13956 }
13957 return null;
13958 },
13959
13960 renderShapeTo: function(context){
13961 if (this._invisible || !this._commands || (!this._fill && !this._stroke)) {
13962 return null;
13963 }
13964 context.transform(this.xx, this.yx, this.xy, this.yy, this.x, this.y);
13965 var commands = this._commands,
13966 fill = this._fill,
13967 stroke = this._stroke,
13968 dash = this._strokeDash;
13969
13970 context.beginPath();
13971
13972 if (dash) {
13973 if (context.setLineDash) {
13974 context.setLineDash(dash);
13975 } else {
13976 // TODO: Remove when FF supports setLineDash.
13977 context.mozDash = dash;
13978 }
13979 // TODO: Create fallback to other browsers.
13980 } else {
13981 if (context.setLineDash) {
13982 context.setLineDash([]);
13983 } else {
13984 context.mozDash = null;
13985 }
13986 }
13987
13988 for (var i = 0, l = commands.length; i < l; i++)
13989 commands[i](context);
13990
13991 if (fill){
13992 var m = this._fillTransform;
13993 if (m){
13994 context.save(); // TODO: Optimize away this by restoring the transform before stroking
13995 context.transform(m.xx, m.yx, m.xy, m.yy, m.x, m.y);
13996 context.fillStyle = fill;
13997 context.fill();
13998 context.restore();
13999 } else {
14000 context.fillStyle = fill;
14001 context.fill();
14002 }
14003 }
14004 if (stroke){
14005 context.strokeStyle = stroke;
14006 context.lineWidth = this._strokeWidth;
14007 context.lineCap = this._strokeCap;
14008 context.lineJoin = this._strokeJoin;
14009 context.stroke();
14010 }
14011 }
14012
14013});
14014
14015var group = _class(node, container, {
14016
14017 initialize: function(width, height){
14018 this.width = width;
14019 this.height = height;
14020 },
14021
14022 localHitTest: function(x, y){
14023 var node$$2 = this.lastChild;
14024 while (node$$2){
14025 var hit = node$$2.hitTest(x, y);
14026 if (hit) return hit;
14027 node$$2 = node$$2.previousSibling;
14028 }
14029 return null;
14030 },
14031
14032 renderLayerTo: function(context, xx, yx, xy, yy, x, y){
14033 if (this._invisible) return;
14034
14035 x = xx * this.x + xy * this.y + x;
14036 y = yx * this.x + yy * this.y + y;
14037
14038 var t = xx;
14039 xx = t * this.xx + xy * this.yx;
14040 xy = t * this.xy + xy * this.yy;
14041 t = yx;
14042 yx = t * this.xx + yy * this.yx;
14043 yy = t * this.xy + yy * this.yy;
14044
14045 var node$$2 = this.firstChild;
14046 while (node$$2){
14047 node$$2.renderTo(context, xx, yx, xy, yy, x, y);
14048 node$$2 = node$$2.nextSibling;
14049 }
14050 }
14051
14052});
14053
14054var clippingrectangle = _class(node, container, {
14055
14056 initialize: function(width, height){
14057 this.width = width;
14058 this.height = height;
14059 },
14060
14061 localHitTest: function(x, y) {
14062 var node$$2 = this.lastChild;
14063 while (node$$2){
14064 var hit = node$$2.hitTest(x, y);
14065 if (hit) return hit;
14066 node$$2 = node$$2.previousSibling;
14067 }
14068 return null;
14069 },
14070
14071 renderLayerTo: function(context, xx, yx, xy, yy, x, y) {
14072 context.setTransform(xx, yx, xy, yy, x, y);
14073 context.save();
14074 // Need beginPath to fix Firefox bug. See 3354054.
14075 context.beginPath();
14076 context.rect(this.x, this.y, this.width, this.height);
14077 context.clip();
14078
14079 var node$$2 = this.firstChild;
14080 while(node$$2) {
14081 node$$2.renderTo(context, xx, yx, xy, yy, x, y);
14082 node$$2 = node$$2.nextSibling;
14083 }
14084 context.restore();
14085 }
14086});
14087
14088var fontAnchors = { middle: 'center' };
14089
14090var text = _class(base, {
14091
14092 base_initialize: base.prototype.initialize,
14093
14094 initialize: function(text, font, alignment, path){
14095 this.base_initialize();
14096 this.draw.apply(this, arguments);
14097 },
14098
14099 draw: function(text, font, alignment, path){
14100 var em;
14101 if (typeof font == 'string'){
14102 em = Number(/(\d+)/.exec(font)[0]);
14103 } else if (font){
14104 em = parseFloat(font.fontSize || font['font-size'] || '12');
14105 font = (font.fontStyle || font['font-style'] || '') + ' ' +
14106 (font.fontVariant || font['font-variant'] || '') + ' ' +
14107 (font.fontWeight || font['font-weight'] || '') + ' ' +
14108 em + 'px ' +
14109 (font.fontFamily || font['font-family'] || 'Arial');
14110 } else {
14111 font = this._font;
14112 }
14113
14114 var lines = text && text.split(/\r?\n/);
14115 this._font = font;
14116 this._fontSize = em;
14117 this._text = lines;
14118 this._alignment = fontAnchors[alignment] || alignment || 'left';
14119
14120 var context = base._genericContext;
14121
14122 context.font = this._font;
14123 context.textAlign = this._alignment;
14124 context.textBaseline = 'middle';
14125
14126 lines = this._text;
14127 var l = lines.length, width = 0;
14128 for (var i = 0; i < l; i++){
14129 var w = context.measureText(lines[i]).width;
14130 if (w > width) width = w;
14131 }
14132 this.width = width;
14133 this.height = l ? l * 1.1 * em : 0;
14134 return this.invalidate();
14135 },
14136
14137 // Interaction
14138
14139 localHitTest: function(x, y){
14140 if (!this._fill) return null;
14141 if (x > 0 && y > 0 && x < this.width && y < this.height){
14142 return this;
14143 }
14144 return null;
14145 },
14146
14147 // Rendering
14148
14149 renderShapeTo: function(context){
14150 if (this._invisible || !this._text || (!this._fill && !this._stroke)) {
14151 return null;
14152 }
14153 context.transform(this.xx, this.yx, this.xy, this.yy, this.x, this.y);
14154 var fill = this._fill,
14155 stroke = this._stroke,
14156 text = this._text,
14157 dash = this._strokeDash;
14158
14159 context.font = this._font;
14160 context.textAlign = this._alignment;
14161 context.textBaseline = 'middle';
14162
14163 var em = this._fontSize,
14164 y = em / 2,
14165 lineHeight = 1.1 * em,
14166 lines = text,
14167 l = lines.length;
14168
14169 if (fill){
14170 context.fillStyle = fill;
14171 for (var i = 0; i < l; i++)
14172 context.fillText(lines[i], 0, y + i * lineHeight);
14173 }
14174 if (stroke){
14175 if (dash) {
14176 if (context.setLineDash) {
14177 context.setLineDash(dash);
14178 } else {
14179 // TODO: Remove when FF supports setLineDash.
14180 context.mozDash = dash;
14181 }
14182 // TODO: Create fallback to other browsers.
14183 } else {
14184 if (context.setLineDash) {
14185 context.setLineDash([]);
14186 } else {
14187 context.mozDash = null;
14188 }
14189 }
14190
14191 context.strokeStyle = stroke;
14192 context.lineWidth = this._strokeWidth;
14193 context.lineCap = this._strokeCap;
14194 context.lineJoin = this._strokeJoin;
14195 for (i = 0; i < l; i++)
14196 context.strokeText(lines[i], 0, y + i * lineHeight);
14197 }
14198 }
14199
14200});
14201
14202var VMLCSS = 'behavior:url(#default#VML);display:inline-block;position:absolute;left:0px;top:0px;';
14203
14204var styleSheet;
14205var styledTags = {};
14206var styleTag = function(tag){
14207 if (styleSheet) styledTags[tag] = styleSheet.addRule('av\\:' + tag, VMLCSS);
14208};
14209
14210var init = function(document){
14211
14212 var namespaces;
14213 try { // IE9 workaround: sometimes it throws here
14214 namespaces = document.namespaces;
14215 } catch (e) {
14216 }
14217 if (!namespaces) return false;
14218
14219 namespaces.add('av', 'urn:schemas-microsoft-com:vml');
14220 namespaces.add('ao', 'urn:schemas-microsoft-com:office:office');
14221
14222 styleSheet = document.createStyleSheet();
14223 styleSheet.addRule('vml', 'display:inline-block;position:relative;overflow:hidden;');
14224/* styleTag('skew');
14225 styleTag('fill');
14226 styleTag('stroke');
14227 styleTag('path');
14228 styleTag('textpath');
14229 styleTag('group');*/
14230
14231 styleTag('vml');
14232
14233 return true;
14234
14235};
14236
14237var createElement = function(tag){
14238 if (!(tag in styledTags)) styleTag(tag);
14239 return document.createElement('av:' + tag);
14240};
14241
14242var dom = {
14243 init: init,
14244 createElement: createElement
14245};
14246
14247var precision = 100;
14248
14249var VMLSurface = _class(native_1, container, {
14250
14251 initialize: function VMLSurface(width, height, existingElement){
14252 this.element = existingElement || document.createElement('vml');
14253 this.containerElement = dom.createElement('group');
14254 this.element.appendChild(this.containerElement);
14255 if (width != null && height != null) this.resize(width, height);
14256 },
14257
14258 resize: function(width, height){
14259 this.width = width;
14260 this.height = height;
14261
14262 var style = this.element.style;
14263 style.pixelWidth = width;
14264 style.pixelHeight = height;
14265
14266 style = this.containerElement.style;
14267 style.width = width;
14268 style.height = height;
14269
14270 var halfPixel = (0.5 * precision);
14271
14272 this.containerElement.coordorigin = halfPixel + ',' + halfPixel;
14273 this.containerElement.coordsize = (width * precision) + ',' + (height * precision);
14274
14275 return this;
14276 }
14277
14278});
14279
14280VMLSurface.tagName = 'av:vml';
14281
14282var surface$2 = VMLSurface;
14283
14284var precision$1 = 100;
14285
14286var round = Math.round;
14287
14288var VMLPath = _class(path$2, {
14289
14290 initialize: function(path){
14291 this.reset();
14292 if (path instanceof VMLPath){
14293 this.path = [Array.prototype.join.call(path.path, ' ')];
14294 } else if (path){
14295 if (path.applyToPath)
14296 path.applyToPath(this);
14297 else
14298 this.push(path);
14299 }
14300 },
14301
14302 onReset: function(){
14303 this.path = [];
14304 },
14305
14306 onMove: function(sx, sy, x, y){
14307 this.path.push('m', round(x * precision$1), round(y * precision$1));
14308 },
14309
14310 onLine: function(sx, sy, x, y){
14311 this.path.push('l', round(x * precision$1), round(y * precision$1));
14312 },
14313
14314 onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
14315 this.path.push('c',
14316 round(p1x * precision$1), round(p1y * precision$1),
14317 round(p2x * precision$1), round(p2y * precision$1),
14318 round(x * precision$1), round(y * precision$1)
14319 );
14320 },
14321
14322 _arcToBezier: path$2.prototype.onArc,
14323
14324 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
14325 if (rx != ry || rotation) return this._arcToBezier(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation);
14326 cx *= precision$1;
14327 cy *= precision$1;
14328 rx *= precision$1;
14329 this.path.push(ccw ? 'at' : 'wa',
14330 round(cx - rx), round(cy - rx),
14331 round(cx + rx), round(cy + rx),
14332 round(sx * precision$1), round(sy * precision$1),
14333 round(ex * precision$1), round(ey * precision$1)
14334 );
14335 },
14336
14337 onClose: function(){
14338 this.path.push('x');
14339 },
14340
14341 toVML: function(){
14342 return this.path.join(' ');
14343 }
14344
14345});
14346
14347VMLPath.prototype.toString = VMLPath.prototype.toVML;
14348
14349var path$4 = VMLPath;
14350
14351var shadow = _class(dummy, native_1, {
14352
14353 dummy_inject: dummy.prototype.inject,
14354 dummy_injectBefore: dummy.prototype.injectBefore,
14355 dummy_eject: dummy.prototype.eject,
14356 native_inject: native_1.prototype.inject,
14357 native_injectBefore: native_1.prototype.injectBefore,
14358 native_eject: native_1.prototype.eject,
14359
14360 inject: function(container){
14361 this.dummy_inject(container);
14362 this.native_inject(container);
14363 return this;
14364 },
14365
14366 injectBefore: function(sibling){
14367 this.dummy_injectBefore(sibling);
14368 this.native_injectBefore(sibling);
14369 return this;
14370 },
14371
14372 eject: function(){
14373 this.dummy_eject();
14374 this.native_eject();
14375 return this;
14376 }
14377
14378});
14379
14380var node$2 = _class(shadow, transform, {
14381
14382 initialize: function(tag){
14383 //this.uid = uniqueID();
14384 var element = this.element = dom.createElement(tag);
14385 //element.setAttribute('id', 'e' + this.uid);
14386 },
14387
14388 _place: function(){
14389 if (this.parentNode){
14390 this._transform();
14391 }
14392 },
14393
14394 // visibility
14395
14396 hide: function(){
14397 this.element.style.display = 'none';
14398 return this;
14399 },
14400
14401 show: function(){
14402 this.element.style.display = '';
14403 return this;
14404 },
14405
14406 // interaction
14407
14408 indicate: function(cursor, tooltip){
14409 if (cursor) this.element.style.cursor = cursor;
14410 if (tooltip) this.element.title = tooltip;
14411 return this;
14412 }
14413
14414});
14415
14416var precision$3 = 100;
14417
14418var defaultBox = { left: 0, top: 0, width: 500, height: 500 };
14419
14420var base$2 = _class(node$2, {
14421
14422 element_initialize: node$2.prototype.initialize,
14423
14424 initialize: function(tag){
14425 this.element_initialize(tag);
14426 var element = this.element;
14427
14428 var skew = this.skewElement = dom.createElement('skew');
14429 skew.on = true;
14430 element.appendChild(skew);
14431
14432 var fill = this.fillElement = dom.createElement('fill');
14433 fill.on = false;
14434 element.appendChild(fill);
14435
14436 var stroke = this.strokeElement = dom.createElement('stroke');
14437 stroke.on = false;
14438 element.appendChild(stroke);
14439 },
14440
14441 /* transform */
14442
14443 _transform: function(){
14444 var container = this.parentNode;
14445
14446 // Active Transformation Matrix
14447 var m = container ? new transform(container._activeTransform).transform(this) : this;
14448
14449 // Box in shape user space
14450
14451 var box = this._boxCoords || this._size || defaultBox;
14452
14453 var originX = box.left || 0,
14454 originY = box.top || 0,
14455 width = box.width || 1,
14456 height = box.height || 1;
14457
14458 // Flipped
14459 var flip = m.yx / m.xx > m.yy / m.xy;
14460 if (m.xx < 0 ? m.xy >= 0 : m.xy < 0) flip = !flip;
14461 flip = flip ? -1 : 1;
14462
14463 m = new transform().scale(flip, 1).transform(m);
14464
14465 // Rotation is approximated based on the transform
14466 var rotation = Math.atan2(-m.xy, m.yy) * 180 / Math.PI;
14467
14468 // Reverse the rotation, leaving the final transform in box space
14469 var rad = rotation * Math.PI / 180, sin = Math.sin(rad), cos = Math.cos(rad);
14470
14471 var transform$$2 = new transform(
14472 (m.xx * cos - m.xy * sin),
14473 (m.yx * cos - m.yy * sin) * flip,
14474 (m.xy * cos + m.xx * sin) * flip,
14475 (m.yy * cos + m.yx * sin)
14476 );
14477
14478 var rotationTransform = new transform().rotate(rotation, 0, 0);
14479
14480 var shapeToBox = new transform().rotate(-rotation, 0, 0).transform(m).moveTo(0,0);
14481
14482 // Scale box after reversing rotation
14483 width *= Math.abs(shapeToBox.xx);
14484 height *= Math.abs(shapeToBox.yy);
14485
14486 // Place box
14487 var left = m.x, top = m.y;
14488
14489 // Compensate for offset by center origin rotation
14490 var vx = -width / 2, vy = -height / 2;
14491 var point = rotationTransform.point(vx, vy);
14492 left -= point.x - vx;
14493 top -= point.y - vy;
14494
14495 // Adjust box position based on offset
14496 var rsm = new transform(m).moveTo(0,0);
14497 point = rsm.point(originX, originY);
14498 left += point.x;
14499 top += point.y;
14500
14501 if (flip < 0) left = -left - width;
14502
14503 // Place transformation origin
14504 var point0 = rsm.point(-originX, -originY);
14505 var point1 = rotationTransform.point(width, height);
14506 var point2 = rotationTransform.point(width, 0);
14507 var point3 = rotationTransform.point(0, height);
14508
14509 var minX = Math.min(0, point1.x, point2.x, point3.x),
14510 maxX = Math.max(0, point1.x, point2.x, point3.x),
14511 minY = Math.min(0, point1.y, point2.y, point3.y),
14512 maxY = Math.max(0, point1.y, point2.y, point3.y);
14513
14514 var transformOriginX = (point0.x - point1.x / 2) / (maxX - minX) * flip,
14515 transformOriginY = (point0.y - point1.y / 2) / (maxY - minY);
14516
14517 // Adjust the origin
14518 point = shapeToBox.point(originX, originY);
14519 originX = point.x;
14520 originY = point.y;
14521
14522 // Scale stroke
14523 var strokeWidth = this._strokeWidth;
14524 if (strokeWidth){
14525 // Scale is the hypothenus between the two vectors
14526 // TODO: Use area calculation instead
14527 var vx = m.xx + m.xy, vy = m.yy + m.yx;
14528 strokeWidth *= Math.sqrt(vx * vx + vy * vy) / Math.sqrt(2);
14529 }
14530
14531 // convert to multiplied precision space
14532 originX *= precision$3;
14533 originY *= precision$3;
14534 left *= precision$3;
14535 top *= precision$3;
14536 width *= precision$3;
14537 height *= precision$3;
14538
14539 // Set box
14540 var element = this.element;
14541 element.coordorigin = originX + ',' + originY;
14542 element.coordsize = width + ',' + height;
14543 element.style.left = left + 'px';
14544 element.style.top = top + 'px';
14545 element.style.width = width;
14546 element.style.height = height;
14547 element.style.rotation = rotation.toFixed(8);
14548 element.style.flip = flip < 0 ? 'x' : '';
14549
14550 // Set transform
14551 var skew = this.skewElement;
14552 skew.matrix = [transform$$2.xx.toFixed(4), transform$$2.xy.toFixed(4), transform$$2.yx.toFixed(4), transform$$2.yy.toFixed(4), 0, 0];
14553 skew.origin = transformOriginX + ',' + transformOriginY;
14554
14555 // Set stroke
14556 this.strokeElement.weight = strokeWidth + 'px';
14557 },
14558
14559 /* styles */
14560
14561 _createGradient: function(style, stops){
14562 var fill = this.fillElement;
14563
14564 // Temporarily eject the fill from the DOM
14565 this.element.removeChild(fill);
14566
14567 fill.type = style;
14568 fill.method = 'none';
14569 fill.rotate = true;
14570
14571 var colors = [], color1, color2;
14572
14573 var addColor = function(offset, color$$2){
14574 color$$2 = color.detach(color$$2);
14575 if (color1 == null) color1 = color2 = color$$2;
14576 else color2 = color$$2;
14577 colors.push(offset + ' ' + color$$2[0]);
14578 };
14579
14580 // Enumerate stops, assumes offsets are enumerated in order
14581 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++) addColor(i / l, stops[i]);
14582 else for (var offset in stops) addColor(offset, stops[offset]);
14583
14584 fill.color = color1[0];
14585 fill.color2 = color2[0];
14586
14587 //if (fill.colors) fill.colors.value = colors; else
14588 fill.colors = colors;
14589
14590 // Opacity order gets flipped when color stops are specified
14591 fill.opacity = color2[1];
14592 fill['ao:opacity2'] = color1[1];
14593
14594 fill.on = true;
14595 this.element.appendChild(fill);
14596 return fill;
14597 },
14598
14599 _setColor: function(type, color$$2){
14600 var element = type == 'fill' ? this.fillElement : this.strokeElement;
14601 if (color$$2 == null){
14602 element.on = false;
14603 } else {
14604 color$$2 = color.detach(color$$2);
14605 element.color = color$$2[0];
14606 element.opacity = color$$2[1];
14607 element.on = true;
14608 }
14609 },
14610
14611 fill: function(color$$2){
14612 if (arguments.length > 1){
14613 this.fillLinear(arguments);
14614 } else {
14615 this._boxCoords = defaultBox;
14616 var fill = this.fillElement;
14617 fill.type = 'solid';
14618 fill.color2 = '';
14619 fill['ao:opacity2'] = '';
14620 if (fill.colors) fill.colors.value = '';
14621 this._setColor('fill', color$$2);
14622 }
14623 return this;
14624 },
14625
14626 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
14627 var fill = this._createGradient('gradientradial', stops);
14628 if (focusX == null) focusX = this.left + this.width * 0.5;
14629 if (focusY == null) focusY = this.top + this.height * 0.5;
14630 if (radiusY == null) radiusY = radiusX || (this.height * 0.5);
14631 if (radiusX == null) radiusX = this.width * 0.5;
14632 if (centerX == null) centerX = focusX;
14633 if (centerY == null) centerY = focusY;
14634
14635 centerX += centerX - focusX;
14636 centerY += centerY - focusY;
14637
14638 var box = this._boxCoords = {
14639 left: centerX - radiusX * 2,
14640 top: centerY - radiusY * 2,
14641 width: radiusX * 4,
14642 height: radiusY * 4
14643 };
14644 focusX -= box.left;
14645 focusY -= box.top;
14646 focusX /= box.width;
14647 focusY /= box.height;
14648
14649 fill.focussize = '0 0';
14650 fill.focusposition = focusX + ',' + focusY;
14651 fill.focus = '50%';
14652
14653 this._transform();
14654
14655 return this;
14656 },
14657
14658 fillLinear: function(stops, x1, y1, x2, y2){
14659 var fill = this._createGradient('gradient', stops);
14660 fill.focus = '100%';
14661 if (arguments.length == 5){
14662 var w = Math.abs(x2 - x1), h = Math.abs(y2 - y1);
14663 this._boxCoords = {
14664 left: Math.min(x1, x2),
14665 top: Math.min(y1, y2),
14666 width: w < 1 ? h : w,
14667 height: h < 1 ? w : h
14668 };
14669 fill.angle = (360 + Math.atan2((x2 - x1) / h, (y2 - y1) / w) * 180 / Math.PI) % 360;
14670 } else {
14671 this._boxCoords = null;
14672 fill.angle = (x1 == null) ? 0 : (90 + x1) % 360;
14673 }
14674 this._transform();
14675 return this;
14676 },
14677
14678 fillImage: function(url, width, height, left, top, color1, color2){
14679 var fill = this.fillElement;
14680 if (color1 != null){
14681 color1 = color.detach(color1);
14682 if (color2 != null) color2 = color.detach(color2);
14683 fill.type = 'pattern';
14684 fill.color = color1[0];
14685 fill.color2 = color2 == null ? color1[0] : color2[0];
14686 fill.opacity = color2 == null ? 0 : color2[1];
14687 fill['ao:opacity2'] = color1[1];
14688 } else {
14689 fill.type = 'tile';
14690 fill.color = '';
14691 fill.color2 = '';
14692 fill.opacity = 1;
14693 fill['ao:opacity2'] = 1;
14694 }
14695 if (fill.colors) fill.colors.value = '';
14696 fill.rotate = true;
14697 fill.src = url;
14698
14699 fill.size = '1,1';
14700 fill.position = '0,0';
14701 fill.origin = '0,0';
14702 fill.aspect = 'ignore'; // ignore, atleast, atmost
14703 fill.on = true;
14704
14705 if (!left) left = 0;
14706 if (!top) top = 0;
14707 this._boxCoords = width ? { left: left + 0.5, top: top + 0.5, width: width, height: height } : null;
14708 this._transform();
14709 return this;
14710 },
14711
14712 /* stroke */
14713
14714 stroke: function(color$$2, width, cap, join){
14715 var stroke = this.strokeElement;
14716 this._strokeWidth = (width != null) ? width : 1;
14717 stroke.weight = (width != null) ? width + 'px' : 1;
14718 stroke.endcap = (cap != null) ? ((cap == 'butt') ? 'flat' : cap) : 'round';
14719 stroke.joinstyle = (join != null) ? join : 'round';
14720
14721 this._setColor('stroke', color$$2);
14722 return this;
14723 }
14724
14725});
14726
14727var precision$2 = 100;
14728
14729var shape$2 = _class(base$2, {
14730
14731 base_initialize: base$2.prototype.initialize,
14732
14733 initialize: function(path, width, height){
14734 this.base_initialize('shape');
14735
14736 var p = this.pathElement = dom.createElement('path');
14737 p.gradientshapeok = true;
14738 this.element.appendChild(p);
14739
14740 this.width = width;
14741 this.height = height;
14742
14743 if (path != null) this.draw(path);
14744 },
14745
14746 // SVG to VML
14747
14748 draw: function(path, width, height){
14749
14750 if (!(path instanceof path$4)) path = new path$4(path);
14751 this._vml = path.toVML();
14752 //this._size = path.measure();
14753
14754 if (width != null) this.width = width;
14755 if (height != null) this.height = height;
14756
14757 if (!this._boxCoords) this._transform();
14758 this._redraw(this._prefix, this._suffix);
14759
14760 return this;
14761 },
14762
14763 // radial gradient workaround
14764
14765 _redraw: function(prefix, suffix){
14766 var vml = this._vml || '';
14767
14768 this._prefix = prefix;
14769 this._suffix = suffix;
14770 if (prefix){
14771 vml = [
14772 prefix, vml, suffix,
14773 // Don't stroke the path with the extra ellipse, redraw the stroked path separately
14774 'ns e', vml, 'nf'
14775 ].join(' ');
14776 }
14777
14778 this.element.path = vml + 'e';
14779 },
14780
14781 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
14782 var fill = this._createGradient('gradientradial', stops);
14783 if (focusX == null) focusX = (this.left || 0) + (this.width || 0) * 0.5;
14784 if (focusY == null) focusY = (this.top || 0) + (this.height || 0) * 0.5;
14785 if (radiusY == null) radiusY = radiusX || (this.height * 0.5) || 0;
14786 if (radiusX == null) radiusX = (this.width || 0) * 0.5;
14787 if (centerX == null) centerX = focusX;
14788 if (centerY == null) centerY = focusY;
14789
14790 centerX += centerX - focusX;
14791 centerY += centerY - focusY;
14792
14793 var cx = Math.round(centerX * precision$2),
14794 cy = Math.round(centerY * precision$2),
14795
14796 rx = Math.round(radiusX * 2 * precision$2),
14797 ry = Math.round(radiusY * 2 * precision$2),
14798
14799 arc = ['wa', cx - rx, cy - ry, cx + rx, cy + ry].join(' ');
14800
14801 this._redraw(
14802 // Resolve rendering bug
14803 ['m', cx, cy - ry, 'l', cx, cy - ry].join(' '),
14804 // Draw an ellipse around the path to force an elliptical gradient on any shape
14805 [
14806 'm', cx, cy - ry,
14807 arc, cx, cy - ry, cx, cy + ry, arc, cx, cy + ry, cx, cy - ry,
14808 arc, cx, cy - ry, cx, cy + ry, arc, cx, cy + ry, cx, cy - ry
14809 ].join(' ')
14810 );
14811
14812 this._boxCoords = { left: focusX - 2, top: focusY - 2, width: 4, height: 4 };
14813
14814 fill.focusposition = '0.5,0.5';
14815 fill.focussize = '0 0';
14816 fill.focus = '50%';
14817
14818 this._transform();
14819
14820 return this;
14821 }
14822
14823});
14824
14825var group$2 = _class(node$2, container, {
14826
14827 element_initialize: node$2.prototype.initialize,
14828
14829 initialize: function(width, height){
14830 this.element_initialize('group');
14831 this.width = width;
14832 this.height = height;
14833 },
14834
14835 _transform: function(){
14836 var element = this.element;
14837 element.coordorigin = '0,0';
14838 element.coordsize = '1000,1000';
14839 element.style.left = 0;
14840 element.style.top = 0;
14841 element.style.width = 1000;
14842 element.style.height = 1000;
14843 element.style.rotation = 0;
14844
14845 var container$$2 = this.parentNode;
14846 this._activeTransform = container$$2 ? new transform(container$$2._activeTransform).transform(this) : this;
14847 var node = this.firstChild;
14848 while (node){
14849 node._transform();
14850 node = node.nextSibling;
14851 }
14852 }
14853
14854});
14855
14856var clippingrectangle$2 = _class(node$2, container, {
14857
14858 element_initialize: node$2.prototype.initialize,
14859
14860 initialize: function(width, height){
14861 this.element_initialize('clippingrectangle');
14862 this.width = width;
14863 this.height = height;
14864 },
14865
14866 _transform: function(){
14867 var element = this.element;
14868 element.clip = true;
14869 element.coordorigin = -this.x + ',' + (-1 * this.y);
14870 element.coordsize = this.width + ',' + this.height;
14871 // IE8 doesn't like clipBottom. Don't ask me why.
14872 // element.style.clipBottom = this.height + this.y;
14873 element.style.clipLeft = this.x;
14874 element.style.clipRight = this.width + this.x;
14875 element.style.clipTop = this.y;
14876 element.style.left = -this.x;
14877 element.style.top = -this.y;
14878 element.style.width = this.width + this.x;
14879 element.style.height = this.height + this.y;
14880 element.style.rotation = 0;
14881
14882 var container$$2 = this.parentNode;
14883 this._activeTransform = container$$2 ? new transform(container$$2._activeTransform).transform(this) : this;
14884 var node = this.firstChild;
14885 while (node){
14886 node._transform();
14887 node = node.nextSibling;
14888 }
14889 }
14890
14891});
14892
14893var fontAnchors$1 = { start: 'left', middle: 'center', end: 'right' };
14894
14895var text$2 = _class(base$2, {
14896
14897 base_initialize: base$2.prototype.initialize,
14898
14899 initialize: function(text, font, alignment, path){
14900 this.base_initialize('shape');
14901
14902 var p = this.pathElement = dom.createElement('path');
14903 p.textpathok = true;
14904 this.element.appendChild(p);
14905
14906 p = this.textPathElement = dom.createElement("textpath");
14907 p.on = true;
14908 p.style['v-text-align'] = 'left';
14909 this.element.appendChild(p);
14910
14911 this.draw.apply(this, arguments);
14912 },
14913
14914 draw: function(text, font, alignment, path){
14915 var element = this.element,
14916 textPath = this.textPathElement,
14917 style = textPath.style;
14918
14919 textPath.string = text;
14920
14921 if (font){
14922 if (typeof font == 'string'){
14923 style.font = font;
14924 } else {
14925 for (var key in font){
14926 var ckey = key.camelCase ? key.camelCase() : key;
14927 if (ckey == 'fontFamily') style[ckey] = "'" + font[key] + "'";
14928 // NOT UNIVERSALLY SUPPORTED OPTIONS
14929 // else if (ckey == 'kerning') style['v-text-kern'] = !!font[key];
14930 // else if (ckey == 'rotateGlyphs') style['v-rotate-letters'] = !!font[key];
14931 // else if (ckey == 'letterSpacing') style['v-text-spacing'] = Number(font[key]) + '';
14932 else style[ckey] = font[key];
14933 }
14934 }
14935 }
14936
14937 if (alignment) style['v-text-align'] = fontAnchors$1[alignment] || alignment;
14938
14939 if (path){
14940 this.currentPath = path = new path$4(path);
14941 this.element.path = path.toVML();
14942 } else if (!this.currentPath){
14943 var i = -1, offsetRows = '\n';
14944 while ((i = text.indexOf('\n', i + 1)) > -1) offsetRows += '\n';
14945 textPath.string = offsetRows + textPath.string;
14946 this.element.path = 'm0,0l1,0';
14947 }
14948
14949 // Measuring the bounding box is currently necessary for gradients etc.
14950
14951 // Clone element because the element is dead once it has been in the DOM
14952 element = element.cloneNode(true);
14953 style = element.style;
14954
14955 // Reset coordinates while measuring
14956 element.coordorigin = '0,0';
14957 element.coordsize = '10000,10000';
14958 style.left = '0px';
14959 style.top = '0px';
14960 style.width = '10000px';
14961 style.height = '10000px';
14962 style.rotation = 0;
14963 element.removeChild(element.firstChild); // Remove skew
14964
14965 // Inject the clone into the document
14966
14967 var canvas = new surface$2(1, 1),
14968 group = new group$2(), // Wrapping it in a group seems to alleviate some client rect weirdness
14969 body = element.ownerDocument.body;
14970
14971 canvas.inject(body);
14972 group.element.appendChild(element);
14973 group.inject(canvas);
14974
14975 var ebb = element.getBoundingClientRect(),
14976 cbb = canvas.toElement().getBoundingClientRect();
14977
14978 canvas.eject();
14979
14980 this.left = ebb.left - cbb.left;
14981 this.top = ebb.top - cbb.top;
14982 this.width = ebb.right - ebb.left;
14983 this.height = ebb.bottom - ebb.top;
14984 this.right = ebb.right - cbb.left;
14985 this.bottom = ebb.bottom - cbb.top;
14986
14987 this._transform();
14988
14989 //this._size = { left: this.left, top: this.top, width: this.width, height: this.height};
14990 return this;
14991 }
14992
14993});
14994
14995var fastNoSideEffects = createCommonjsModule(function (module, exports) {
14996var hasCanvas = function(){
14997
14998 var canvas = document.createElement('canvas');
14999 return canvas && !!canvas.getContext;
15000
15001};
15002
15003if (hasCanvas()) {
15004 exports.Surface = surface;
15005 exports.Path = path;
15006 exports.Shape = shape;
15007 exports.Group = group;
15008 exports.ClippingRectangle = clippingrectangle;
15009 exports.Text = text;
15010} else {
15011 exports.Surface = surface$2;
15012 exports.Path = path$4;
15013 exports.Shape = shape$2;
15014 exports.Group = group$2;
15015 exports.ClippingRectangle = clippingrectangle$2;
15016 exports.Text = text$2;
15017
15018 var DOM$$1 = dom;
15019 if (typeof document !== 'undefined') DOM$$1.init(document);
15020}
15021});
15022
15023var fastNoSideEffects_1 = fastNoSideEffects.Surface;
15024var fastNoSideEffects_2 = fastNoSideEffects.Path;
15025var fastNoSideEffects_3 = fastNoSideEffects.Shape;
15026var fastNoSideEffects_4 = fastNoSideEffects.Group;
15027var fastNoSideEffects_5 = fastNoSideEffects.ClippingRectangle;
15028var fastNoSideEffects_6 = fastNoSideEffects.Text;
15029
15030var _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; };
15031
15032function _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; }
15033
15034function _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; }
15035
15036function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
15037
15038current.setCurrent(
15039// Change to 'art/modes/dom' for easier debugging via SVG
15040fastNoSideEffects);
15041
15042/** Declarative fill-type objects; API design not finalized */
15043
15044var slice = Array.prototype.slice;
15045
15046var LinearGradient = function () {
15047 function LinearGradient(stops, x1, y1, x2, y2) {
15048 _classCallCheck(this, LinearGradient);
15049
15050 this._args = slice.call(arguments);
15051 }
15052
15053 LinearGradient.prototype.applyFill = function applyFill(node) {
15054 node.fillLinear.apply(node, this._args);
15055 };
15056
15057 return LinearGradient;
15058}();
15059
15060var RadialGradient = function () {
15061 function RadialGradient(stops, fx, fy, rx, ry, cx, cy) {
15062 _classCallCheck(this, RadialGradient);
15063
15064 this._args = slice.call(arguments);
15065 }
15066
15067 RadialGradient.prototype.applyFill = function applyFill(node) {
15068 node.fillRadial.apply(node, this._args);
15069 };
15070
15071 return RadialGradient;
15072}();
15073
15074var Pattern = function () {
15075 function Pattern(url, width, height, left, top) {
15076 _classCallCheck(this, Pattern);
15077
15078 this._args = slice.call(arguments);
15079 }
15080
15081 Pattern.prototype.applyFill = function applyFill(node) {
15082 node.fillImage.apply(node, this._args);
15083 };
15084
15085 return Pattern;
15086}();
15087
15088/** React Components */
15089
15090var Surface = function (_React$Component) {
15091 _inherits(Surface, _React$Component);
15092
15093 function Surface() {
15094 _classCallCheck(this, Surface);
15095
15096 return _possibleConstructorReturn(this, _React$Component.apply(this, arguments));
15097 }
15098
15099 Surface.prototype.componentDidMount = function componentDidMount() {
15100 var _props = this.props,
15101 height = _props.height,
15102 width = _props.width;
15103
15104
15105 this._surface = current.Surface(+width, +height, this._tagRef);
15106
15107 this._mountNode = createContainer(this._surface);
15108 updateContainer(this.props.children, this._mountNode, this);
15109 };
15110
15111 Surface.prototype.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
15112 var props = this.props;
15113
15114 if (props.height !== prevProps.height || props.width !== prevProps.width) {
15115 this._surface.resize(+props.width, +props.height);
15116 }
15117
15118 updateContainer(this.props.children, this._mountNode, this);
15119
15120 if (this._surface.render) {
15121 this._surface.render();
15122 }
15123 };
15124
15125 Surface.prototype.componentWillUnmount = function componentWillUnmount() {
15126 updateContainer(null, this._mountNode, this);
15127 };
15128
15129 Surface.prototype.render = function render() {
15130 var _this2 = this;
15131
15132 // This is going to be a placeholder because we don't know what it will
15133 // actually resolve to because ART may render canvas, vml or svg tags here.
15134 // We only allow a subset of properties since others might conflict with
15135 // ART's properties.
15136 var props = this.props;
15137
15138 // TODO: ART's Canvas Mode overrides surface title and cursor
15139 var Tag = current.Surface.tagName;
15140
15141 return React.createElement(Tag, {
15142 ref: function (ref) {
15143 return _this2._tagRef = ref;
15144 },
15145 accessKey: props.accessKey,
15146 className: props.className,
15147 draggable: props.draggable,
15148 role: props.role,
15149 style: props.style,
15150 tabIndex: props.tabIndex,
15151 title: props.title
15152 });
15153 };
15154
15155 return Surface;
15156}(React.Component);
15157
15158var Text = function (_React$Component2) {
15159 _inherits(Text, _React$Component2);
15160
15161 function Text(props) {
15162 _classCallCheck(this, Text);
15163
15164 // We allow reading these props. Ideally we could expose the Text node as
15165 // ref directly.
15166 var _this3 = _possibleConstructorReturn(this, _React$Component2.call(this, props));
15167
15168 ['height', 'width', 'x', 'y'].forEach(function (key) {
15169 Object.defineProperty(_this3, key, {
15170 get: function () {
15171 return this._text ? this._text[key] : undefined;
15172 }
15173 });
15174 });
15175 return _this3;
15176 }
15177
15178 Text.prototype.render = function render() {
15179 var _this4 = this;
15180
15181 // This means you can't have children that render into strings...
15182 var T = TYPES.TEXT;
15183 return React.createElement(
15184 T,
15185 _extends({}, this.props, { ref: function (t) {
15186 return _this4._text = t;
15187 } }),
15188 childrenAsString(this.props.children)
15189 );
15190 };
15191
15192 return Text;
15193}(React.Component);
15194
15195injectIntoDevTools({
15196 findFiberByHostInstance: function () {
15197 return null;
15198 },
15199 bundleType: 1,
15200 version: ReactVersion,
15201 rendererPackageName: 'react-art'
15202});
15203
15204/** API */
15205
15206var ClippingRectangle = TYPES.CLIPPING_RECTANGLE;
15207var Group = TYPES.GROUP;
15208var Shape = TYPES.SHAPE;
15209var Path = current.Path;
15210
15211
15212var ReactART = Object.freeze({
15213 ClippingRectangle: ClippingRectangle,
15214 Group: Group,
15215 Shape: Shape,
15216 Path: Path,
15217 LinearGradient: LinearGradient,
15218 Pattern: Pattern,
15219 RadialGradient: RadialGradient,
15220 Surface: Surface,
15221 Text: Text,
15222 Transform: transform
15223});
15224
15225var reactArt = ReactART;
15226
15227return reactArt;
15228
15229})));