comparison third_party/bun/node_modules/react-dom/cjs/react-dom.development.js @ 12:de54585a40f1

Adding bun and node modules.
author June Park <parkjune1995@gmail.com>
date Thu, 02 Oct 2025 14:39:48 -0700
parents
children
comparison
equal deleted inserted replaced
11:f33d9ff8b6e8 12:de54585a40f1
1 /**
2 * @license React
3 * react-dom.development.js
4 *
5 * Copyright (c) Facebook, Inc. and its affiliates.
6 *
7 * This source code is licensed under the MIT license found in the
8 * LICENSE file in the root directory of this source tree.
9 */
10
11 'use strict';
12
13 if (process.env.NODE_ENV !== "production") {
14 (function() {
15
16 'use strict';
17
18 /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
19 if (
20 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
21 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart ===
22 'function'
23 ) {
24 __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
25 }
26 var React = require('react');
27 var Scheduler = require('scheduler');
28
29 var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
30
31 var suppressWarning = false;
32 function setSuppressWarning(newSuppressWarning) {
33 {
34 suppressWarning = newSuppressWarning;
35 }
36 } // In DEV, calls to console.warn and console.error get replaced
37 // by calls to these methods by a Babel plugin.
38 //
39 // In PROD (or in packages without access to React internals),
40 // they are left as they are instead.
41
42 function warn(format) {
43 {
44 if (!suppressWarning) {
45 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
46 args[_key - 1] = arguments[_key];
47 }
48
49 printWarning('warn', format, args);
50 }
51 }
52 }
53 function error(format) {
54 {
55 if (!suppressWarning) {
56 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
57 args[_key2 - 1] = arguments[_key2];
58 }
59
60 printWarning('error', format, args);
61 }
62 }
63 }
64
65 function printWarning(level, format, args) {
66 // When changing this logic, you might want to also
67 // update consoleWithStackDev.www.js as well.
68 {
69 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
70 var stack = ReactDebugCurrentFrame.getStackAddendum();
71
72 if (stack !== '') {
73 format += '%s';
74 args = args.concat([stack]);
75 } // eslint-disable-next-line react-internal/safe-string-coercion
76
77
78 var argsWithFormat = args.map(function (item) {
79 return String(item);
80 }); // Careful: RN currently depends on this prefix
81
82 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
83 // breaks IE9: https://github.com/facebook/react/issues/13610
84 // eslint-disable-next-line react-internal/no-production-logging
85
86 Function.prototype.apply.call(console[level], console, argsWithFormat);
87 }
88 }
89
90 var FunctionComponent = 0;
91 var ClassComponent = 1;
92 var IndeterminateComponent = 2; // Before we know whether it is function or class
93
94 var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
95
96 var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
97
98 var HostComponent = 5;
99 var HostText = 6;
100 var Fragment = 7;
101 var Mode = 8;
102 var ContextConsumer = 9;
103 var ContextProvider = 10;
104 var ForwardRef = 11;
105 var Profiler = 12;
106 var SuspenseComponent = 13;
107 var MemoComponent = 14;
108 var SimpleMemoComponent = 15;
109 var LazyComponent = 16;
110 var IncompleteClassComponent = 17;
111 var DehydratedFragment = 18;
112 var SuspenseListComponent = 19;
113 var ScopeComponent = 21;
114 var OffscreenComponent = 22;
115 var LegacyHiddenComponent = 23;
116 var CacheComponent = 24;
117 var TracingMarkerComponent = 25;
118
119 // -----------------------------------------------------------------------------
120
121 var enableClientRenderFallbackOnTextMismatch = true; // TODO: Need to review this code one more time before landing
122 // the react-reconciler package.
123
124 var enableNewReconciler = false; // Support legacy Primer support on internal FB www
125
126 var enableLazyContextPropagation = false; // FB-only usage. The new API has different semantics.
127
128 var enableLegacyHidden = false; // Enables unstable_avoidThisFallback feature in Fiber
129
130 var enableSuspenseAvoidThisFallback = false; // Enables unstable_avoidThisFallback feature in Fizz
131 // React DOM Chopping Block
132 //
133 // Similar to main Chopping Block but only flags related to React DOM. These are
134 // grouped because we will likely batch all of them into a single major release.
135 // -----------------------------------------------------------------------------
136 // Disable support for comment nodes as React DOM containers. Already disabled
137 // in open source, but www codebase still relies on it. Need to remove.
138
139 var disableCommentsAsDOMContainers = true; // Disable javascript: URL strings in href for XSS protection.
140 // and client rendering, mostly to allow JSX attributes to apply to the custom
141 // element's object properties instead of only HTML attributes.
142 // https://github.com/facebook/react/issues/11347
143
144 var enableCustomElementPropertySupport = false; // Disables children for <textarea> elements
145 var warnAboutStringRefs = true; // -----------------------------------------------------------------------------
146 // Debugging and DevTools
147 // -----------------------------------------------------------------------------
148 // Adds user timing marks for e.g. state updates, suspense, and work loop stuff,
149 // for an experimental timeline tool.
150
151 var enableSchedulingProfiler = true; // Helps identify side effects in render-phase lifecycle hooks and setState
152
153 var enableProfilerTimer = true; // Record durations for commit and passive effects phases.
154
155 var enableProfilerCommitHooks = true; // Phase param passed to onRender callback differentiates between an "update" and a "cascading-update".
156
157 var allNativeEvents = new Set();
158 /**
159 * Mapping from registration name to event name
160 */
161
162
163 var registrationNameDependencies = {};
164 /**
165 * Mapping from lowercase registration names to the properly cased version,
166 * used to warn in the case of missing event handlers. Available
167 * only in true.
168 * @type {Object}
169 */
170
171 var possibleRegistrationNames = {} ; // Trust the developer to only use possibleRegistrationNames in true
172
173 function registerTwoPhaseEvent(registrationName, dependencies) {
174 registerDirectEvent(registrationName, dependencies);
175 registerDirectEvent(registrationName + 'Capture', dependencies);
176 }
177 function registerDirectEvent(registrationName, dependencies) {
178 {
179 if (registrationNameDependencies[registrationName]) {
180 error('EventRegistry: More than one plugin attempted to publish the same ' + 'registration name, `%s`.', registrationName);
181 }
182 }
183
184 registrationNameDependencies[registrationName] = dependencies;
185
186 {
187 var lowerCasedName = registrationName.toLowerCase();
188 possibleRegistrationNames[lowerCasedName] = registrationName;
189
190 if (registrationName === 'onDoubleClick') {
191 possibleRegistrationNames.ondblclick = registrationName;
192 }
193 }
194
195 for (var i = 0; i < dependencies.length; i++) {
196 allNativeEvents.add(dependencies[i]);
197 }
198 }
199
200 var canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined');
201
202 var hasOwnProperty = Object.prototype.hasOwnProperty;
203
204 /*
205 * The `'' + value` pattern (used in in perf-sensitive code) throws for Symbol
206 * and Temporal.* types. See https://github.com/facebook/react/pull/22064.
207 *
208 * The functions in this module will throw an easier-to-understand,
209 * easier-to-debug exception with a clear errors message message explaining the
210 * problem. (Instead of a confusing exception thrown inside the implementation
211 * of the `value` object).
212 */
213 // $FlowFixMe only called in DEV, so void return is not possible.
214 function typeName(value) {
215 {
216 // toStringTag is needed for namespaced types like Temporal.Instant
217 var hasToStringTag = typeof Symbol === 'function' && Symbol.toStringTag;
218 var type = hasToStringTag && value[Symbol.toStringTag] || value.constructor.name || 'Object';
219 return type;
220 }
221 } // $FlowFixMe only called in DEV, so void return is not possible.
222
223
224 function willCoercionThrow(value) {
225 {
226 try {
227 testStringCoercion(value);
228 return false;
229 } catch (e) {
230 return true;
231 }
232 }
233 }
234
235 function testStringCoercion(value) {
236 // If you ended up here by following an exception call stack, here's what's
237 // happened: you supplied an object or symbol value to React (as a prop, key,
238 // DOM attribute, CSS property, string ref, etc.) and when React tried to
239 // coerce it to a string using `'' + value`, an exception was thrown.
240 //
241 // The most common types that will cause this exception are `Symbol` instances
242 // and Temporal objects like `Temporal.Instant`. But any object that has a
243 // `valueOf` or `[Symbol.toPrimitive]` method that throws will also cause this
244 // exception. (Library authors do this to prevent users from using built-in
245 // numeric operators like `+` or comparison operators like `>=` because custom
246 // methods are needed to perform accurate arithmetic or comparison.)
247 //
248 // To fix the problem, coerce this object or symbol value to a string before
249 // passing it to React. The most reliable way is usually `String(value)`.
250 //
251 // To find which value is throwing, check the browser or debugger console.
252 // Before this exception was thrown, there should be `console.error` output
253 // that shows the type (Symbol, Temporal.PlainDate, etc.) that caused the
254 // problem and how that type was used: key, atrribute, input value prop, etc.
255 // In most cases, this console output also shows the component and its
256 // ancestor components where the exception happened.
257 //
258 // eslint-disable-next-line react-internal/safe-string-coercion
259 return '' + value;
260 }
261
262 function checkAttributeStringCoercion(value, attributeName) {
263 {
264 if (willCoercionThrow(value)) {
265 error('The provided `%s` attribute is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', attributeName, typeName(value));
266
267 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
268 }
269 }
270 }
271 function checkKeyStringCoercion(value) {
272 {
273 if (willCoercionThrow(value)) {
274 error('The provided key is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', typeName(value));
275
276 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
277 }
278 }
279 }
280 function checkPropStringCoercion(value, propName) {
281 {
282 if (willCoercionThrow(value)) {
283 error('The provided `%s` prop is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', propName, typeName(value));
284
285 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
286 }
287 }
288 }
289 function checkCSSPropertyStringCoercion(value, propName) {
290 {
291 if (willCoercionThrow(value)) {
292 error('The provided `%s` CSS property is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', propName, typeName(value));
293
294 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
295 }
296 }
297 }
298 function checkHtmlStringCoercion(value) {
299 {
300 if (willCoercionThrow(value)) {
301 error('The provided HTML markup uses a value of unsupported type %s.' + ' This value must be coerced to a string before before using it here.', typeName(value));
302
303 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
304 }
305 }
306 }
307 function checkFormFieldValueStringCoercion(value) {
308 {
309 if (willCoercionThrow(value)) {
310 error('Form field values (value, checked, defaultValue, or defaultChecked props)' + ' must be strings, not %s.' + ' This value must be coerced to a string before before using it here.', typeName(value));
311
312 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
313 }
314 }
315 }
316
317 // A reserved attribute.
318 // It is handled by React separately and shouldn't be written to the DOM.
319 var RESERVED = 0; // A simple string attribute.
320 // Attributes that aren't in the filter are presumed to have this type.
321
322 var STRING = 1; // A string attribute that accepts booleans in React. In HTML, these are called
323 // "enumerated" attributes with "true" and "false" as possible values.
324 // When true, it should be set to a "true" string.
325 // When false, it should be set to a "false" string.
326
327 var BOOLEANISH_STRING = 2; // A real boolean attribute.
328 // When true, it should be present (set either to an empty string or its name).
329 // When false, it should be omitted.
330
331 var BOOLEAN = 3; // An attribute that can be used as a flag as well as with a value.
332 // When true, it should be present (set either to an empty string or its name).
333 // When false, it should be omitted.
334 // For any other value, should be present with that value.
335
336 var OVERLOADED_BOOLEAN = 4; // An attribute that must be numeric or parse as a numeric.
337 // When falsy, it should be removed.
338
339 var NUMERIC = 5; // An attribute that must be positive numeric or parse as a positive numeric.
340 // When falsy, it should be removed.
341
342 var POSITIVE_NUMERIC = 6;
343
344 /* eslint-disable max-len */
345 var ATTRIBUTE_NAME_START_CHAR = ":A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
346 /* eslint-enable max-len */
347
348 var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + "\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
349 var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
350 var illegalAttributeNameCache = {};
351 var validatedAttributeNameCache = {};
352 function isAttributeNameSafe(attributeName) {
353 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {
354 return true;
355 }
356
357 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {
358 return false;
359 }
360
361 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
362 validatedAttributeNameCache[attributeName] = true;
363 return true;
364 }
365
366 illegalAttributeNameCache[attributeName] = true;
367
368 {
369 error('Invalid attribute name: `%s`', attributeName);
370 }
371
372 return false;
373 }
374 function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
375 if (propertyInfo !== null) {
376 return propertyInfo.type === RESERVED;
377 }
378
379 if (isCustomComponentTag) {
380 return false;
381 }
382
383 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
384 return true;
385 }
386
387 return false;
388 }
389 function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
390 if (propertyInfo !== null && propertyInfo.type === RESERVED) {
391 return false;
392 }
393
394 switch (typeof value) {
395 case 'function': // $FlowIssue symbol is perfectly valid here
396
397 case 'symbol':
398 // eslint-disable-line
399 return true;
400
401 case 'boolean':
402 {
403 if (isCustomComponentTag) {
404 return false;
405 }
406
407 if (propertyInfo !== null) {
408 return !propertyInfo.acceptsBooleans;
409 } else {
410 var prefix = name.toLowerCase().slice(0, 5);
411 return prefix !== 'data-' && prefix !== 'aria-';
412 }
413 }
414
415 default:
416 return false;
417 }
418 }
419 function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
420 if (value === null || typeof value === 'undefined') {
421 return true;
422 }
423
424 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
425 return true;
426 }
427
428 if (isCustomComponentTag) {
429
430 return false;
431 }
432
433 if (propertyInfo !== null) {
434
435 switch (propertyInfo.type) {
436 case BOOLEAN:
437 return !value;
438
439 case OVERLOADED_BOOLEAN:
440 return value === false;
441
442 case NUMERIC:
443 return isNaN(value);
444
445 case POSITIVE_NUMERIC:
446 return isNaN(value) || value < 1;
447 }
448 }
449
450 return false;
451 }
452 function getPropertyInfo(name) {
453 return properties.hasOwnProperty(name) ? properties[name] : null;
454 }
455
456 function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL, removeEmptyString) {
457 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
458 this.attributeName = attributeName;
459 this.attributeNamespace = attributeNamespace;
460 this.mustUseProperty = mustUseProperty;
461 this.propertyName = name;
462 this.type = type;
463 this.sanitizeURL = sanitizeURL;
464 this.removeEmptyString = removeEmptyString;
465 } // When adding attributes to this list, be sure to also add them to
466 // the `possibleStandardNames` module to ensure casing and incorrect
467 // name warnings.
468
469
470 var properties = {}; // These props are reserved by React. They shouldn't be written to the DOM.
471
472 var reservedProps = ['children', 'dangerouslySetInnerHTML', // TODO: This prevents the assignment of defaultValue to regular
473 // elements (not just inputs). Now that ReactDOMInput assigns to the
474 // defaultValue property -- do we need this?
475 'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'];
476
477 reservedProps.forEach(function (name) {
478 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
479 name, // attributeName
480 null, // attributeNamespace
481 false, // sanitizeURL
482 false);
483 }); // A few React string attributes have a different name.
484 // This is a mapping from React prop names to the attribute names.
485
486 [['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) {
487 var name = _ref[0],
488 attributeName = _ref[1];
489 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
490 attributeName, // attributeName
491 null, // attributeNamespace
492 false, // sanitizeURL
493 false);
494 }); // These are "enumerated" HTML attributes that accept "true" and "false".
495 // In React, we let users pass `true` and `false` even though technically
496 // these aren't boolean attributes (they are coerced to strings).
497
498 ['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
499 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
500 name.toLowerCase(), // attributeName
501 null, // attributeNamespace
502 false, // sanitizeURL
503 false);
504 }); // These are "enumerated" SVG attributes that accept "true" and "false".
505 // In React, we let users pass `true` and `false` even though technically
506 // these aren't boolean attributes (they are coerced to strings).
507 // Since these are SVG attributes, their attribute names are case-sensitive.
508
509 ['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) {
510 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
511 name, // attributeName
512 null, // attributeNamespace
513 false, // sanitizeURL
514 false);
515 }); // These are HTML boolean attributes.
516
517 ['allowFullScreen', 'async', // Note: there is a special case that prevents it from being written to the DOM
518 // on the client side because the browsers are inconsistent. Instead we call focus().
519 'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'disablePictureInPicture', 'disableRemotePlayback', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless', // Microdata
520 'itemScope'].forEach(function (name) {
521 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
522 name.toLowerCase(), // attributeName
523 null, // attributeNamespace
524 false, // sanitizeURL
525 false);
526 }); // These are the few React props that we set as DOM properties
527 // rather than attributes. These are all booleans.
528
529 ['checked', // Note: `option.selected` is not updated if `select.multiple` is
530 // disabled with `removeAttribute`. We have special logic for handling this.
531 'multiple', 'muted', 'selected' // NOTE: if you add a camelCased prop to this list,
532 // you'll need to set attributeName to name.toLowerCase()
533 // instead in the assignment below.
534 ].forEach(function (name) {
535 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
536 name, // attributeName
537 null, // attributeNamespace
538 false, // sanitizeURL
539 false);
540 }); // These are HTML attributes that are "overloaded booleans": they behave like
541 // booleans, but can also accept a string value.
542
543 ['capture', 'download' // NOTE: if you add a camelCased prop to this list,
544 // you'll need to set attributeName to name.toLowerCase()
545 // instead in the assignment below.
546 ].forEach(function (name) {
547 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
548 name, // attributeName
549 null, // attributeNamespace
550 false, // sanitizeURL
551 false);
552 }); // These are HTML attributes that must be positive numbers.
553
554 ['cols', 'rows', 'size', 'span' // NOTE: if you add a camelCased prop to this list,
555 // you'll need to set attributeName to name.toLowerCase()
556 // instead in the assignment below.
557 ].forEach(function (name) {
558 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty
559 name, // attributeName
560 null, // attributeNamespace
561 false, // sanitizeURL
562 false);
563 }); // These are HTML attributes that must be numbers.
564
565 ['rowSpan', 'start'].forEach(function (name) {
566 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty
567 name.toLowerCase(), // attributeName
568 null, // attributeNamespace
569 false, // sanitizeURL
570 false);
571 });
572 var CAMELIZE = /[\-\:]([a-z])/g;
573
574 var capitalize = function (token) {
575 return token[1].toUpperCase();
576 }; // This is a list of all SVG attributes that need special casing, namespacing,
577 // or boolean value assignment. Regular attributes that just accept strings
578 // and have the same names are omitted, just like in the HTML attribute filter.
579 // Some of these attributes can be hard to find. This list was created by
580 // scraping the MDN documentation.
581
582
583 ['accent-height', 'alignment-baseline', 'arabic-form', 'baseline-shift', 'cap-height', 'clip-path', 'clip-rule', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'dominant-baseline', 'enable-background', 'fill-opacity', 'fill-rule', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-name', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'horiz-adv-x', 'horiz-origin-x', 'image-rendering', 'letter-spacing', 'lighting-color', 'marker-end', 'marker-mid', 'marker-start', 'overline-position', 'overline-thickness', 'paint-order', 'panose-1', 'pointer-events', 'rendering-intent', 'shape-rendering', 'stop-color', 'stop-opacity', 'strikethrough-position', 'strikethrough-thickness', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-anchor', 'text-decoration', 'text-rendering', 'underline-position', 'underline-thickness', 'unicode-bidi', 'unicode-range', 'units-per-em', 'v-alphabetic', 'v-hanging', 'v-ideographic', 'v-mathematical', 'vector-effect', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'word-spacing', 'writing-mode', 'xmlns:xlink', 'x-height' // NOTE: if you add a camelCased prop to this list,
584 // you'll need to set attributeName to name.toLowerCase()
585 // instead in the assignment below.
586 ].forEach(function (attributeName) {
587 var name = attributeName.replace(CAMELIZE, capitalize);
588 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
589 attributeName, null, // attributeNamespace
590 false, // sanitizeURL
591 false);
592 }); // String SVG attributes with the xlink namespace.
593
594 ['xlink:actuate', 'xlink:arcrole', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type' // NOTE: if you add a camelCased prop to this list,
595 // you'll need to set attributeName to name.toLowerCase()
596 // instead in the assignment below.
597 ].forEach(function (attributeName) {
598 var name = attributeName.replace(CAMELIZE, capitalize);
599 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
600 attributeName, 'http://www.w3.org/1999/xlink', false, // sanitizeURL
601 false);
602 }); // String SVG attributes with the xml namespace.
603
604 ['xml:base', 'xml:lang', 'xml:space' // NOTE: if you add a camelCased prop to this list,
605 // you'll need to set attributeName to name.toLowerCase()
606 // instead in the assignment below.
607 ].forEach(function (attributeName) {
608 var name = attributeName.replace(CAMELIZE, capitalize);
609 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
610 attributeName, 'http://www.w3.org/XML/1998/namespace', false, // sanitizeURL
611 false);
612 }); // These attribute exists both in HTML and SVG.
613 // The attribute name is case-sensitive in SVG so we can't just use
614 // the React name like we do for attributes that exist only in HTML.
615
616 ['tabIndex', 'crossOrigin'].forEach(function (attributeName) {
617 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
618 attributeName.toLowerCase(), // attributeName
619 null, // attributeNamespace
620 false, // sanitizeURL
621 false);
622 }); // These attributes accept URLs. These must not allow javascript: URLS.
623 // These will also need to accept Trusted Types object in the future.
624
625 var xlinkHref = 'xlinkHref';
626 properties[xlinkHref] = new PropertyInfoRecord('xlinkHref', STRING, false, // mustUseProperty
627 'xlink:href', 'http://www.w3.org/1999/xlink', true, // sanitizeURL
628 false);
629 ['src', 'href', 'action', 'formAction'].forEach(function (attributeName) {
630 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
631 attributeName.toLowerCase(), // attributeName
632 null, // attributeNamespace
633 true, // sanitizeURL
634 true);
635 });
636
637 // and any newline or tab are filtered out as if they're not part of the URL.
638 // https://url.spec.whatwg.org/#url-parsing
639 // Tab or newline are defined as \r\n\t:
640 // https://infra.spec.whatwg.org/#ascii-tab-or-newline
641 // A C0 control is a code point in the range \u0000 NULL to \u001F
642 // INFORMATION SEPARATOR ONE, inclusive:
643 // https://infra.spec.whatwg.org/#c0-control-or-space
644
645 /* eslint-disable max-len */
646
647 var isJavaScriptProtocol = /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*\:/i;
648 var didWarn = false;
649
650 function sanitizeURL(url) {
651 {
652 if (!didWarn && isJavaScriptProtocol.test(url)) {
653 didWarn = true;
654
655 error('A future version of React will block javascript: URLs as a security precaution. ' + 'Use event handlers instead if you can. If you need to generate unsafe HTML try ' + 'using dangerouslySetInnerHTML instead. React was passed %s.', JSON.stringify(url));
656 }
657 }
658 }
659
660 /**
661 * Get the value for a property on a node. Only used in DEV for SSR validation.
662 * The "expected" argument is used as a hint of what the expected value is.
663 * Some properties have multiple equivalent values.
664 */
665 function getValueForProperty(node, name, expected, propertyInfo) {
666 {
667 if (propertyInfo.mustUseProperty) {
668 var propertyName = propertyInfo.propertyName;
669 return node[propertyName];
670 } else {
671 // This check protects multiple uses of `expected`, which is why the
672 // react-internal/safe-string-coercion rule is disabled in several spots
673 // below.
674 {
675 checkAttributeStringCoercion(expected, name);
676 }
677
678 if ( propertyInfo.sanitizeURL) {
679 // If we haven't fully disabled javascript: URLs, and if
680 // the hydration is successful of a javascript: URL, we
681 // still want to warn on the client.
682 // eslint-disable-next-line react-internal/safe-string-coercion
683 sanitizeURL('' + expected);
684 }
685
686 var attributeName = propertyInfo.attributeName;
687 var stringValue = null;
688
689 if (propertyInfo.type === OVERLOADED_BOOLEAN) {
690 if (node.hasAttribute(attributeName)) {
691 var value = node.getAttribute(attributeName);
692
693 if (value === '') {
694 return true;
695 }
696
697 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
698 return value;
699 } // eslint-disable-next-line react-internal/safe-string-coercion
700
701
702 if (value === '' + expected) {
703 return expected;
704 }
705
706 return value;
707 }
708 } else if (node.hasAttribute(attributeName)) {
709 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
710 // We had an attribute but shouldn't have had one, so read it
711 // for the error message.
712 return node.getAttribute(attributeName);
713 }
714
715 if (propertyInfo.type === BOOLEAN) {
716 // If this was a boolean, it doesn't matter what the value is
717 // the fact that we have it is the same as the expected.
718 return expected;
719 } // Even if this property uses a namespace we use getAttribute
720 // because we assume its namespaced name is the same as our config.
721 // To use getAttributeNS we need the local name which we don't have
722 // in our config atm.
723
724
725 stringValue = node.getAttribute(attributeName);
726 }
727
728 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
729 return stringValue === null ? expected : stringValue; // eslint-disable-next-line react-internal/safe-string-coercion
730 } else if (stringValue === '' + expected) {
731 return expected;
732 } else {
733 return stringValue;
734 }
735 }
736 }
737 }
738 /**
739 * Get the value for a attribute on a node. Only used in DEV for SSR validation.
740 * The third argument is used as a hint of what the expected value is. Some
741 * attributes have multiple equivalent values.
742 */
743
744 function getValueForAttribute(node, name, expected, isCustomComponentTag) {
745 {
746 if (!isAttributeNameSafe(name)) {
747 return;
748 }
749
750 if (!node.hasAttribute(name)) {
751 return expected === undefined ? undefined : null;
752 }
753
754 var value = node.getAttribute(name);
755
756 {
757 checkAttributeStringCoercion(expected, name);
758 }
759
760 if (value === '' + expected) {
761 return expected;
762 }
763
764 return value;
765 }
766 }
767 /**
768 * Sets the value for a property on a node.
769 *
770 * @param {DOMElement} node
771 * @param {string} name
772 * @param {*} value
773 */
774
775 function setValueForProperty(node, name, value, isCustomComponentTag) {
776 var propertyInfo = getPropertyInfo(name);
777
778 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {
779 return;
780 }
781
782 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
783 value = null;
784 }
785
786
787 if (isCustomComponentTag || propertyInfo === null) {
788 if (isAttributeNameSafe(name)) {
789 var _attributeName = name;
790
791 if (value === null) {
792 node.removeAttribute(_attributeName);
793 } else {
794 {
795 checkAttributeStringCoercion(value, name);
796 }
797
798 node.setAttribute(_attributeName, '' + value);
799 }
800 }
801
802 return;
803 }
804
805 var mustUseProperty = propertyInfo.mustUseProperty;
806
807 if (mustUseProperty) {
808 var propertyName = propertyInfo.propertyName;
809
810 if (value === null) {
811 var type = propertyInfo.type;
812 node[propertyName] = type === BOOLEAN ? false : '';
813 } else {
814 // Contrary to `setAttribute`, object properties are properly
815 // `toString`ed by IE8/9.
816 node[propertyName] = value;
817 }
818
819 return;
820 } // The rest are treated as attributes with special cases.
821
822
823 var attributeName = propertyInfo.attributeName,
824 attributeNamespace = propertyInfo.attributeNamespace;
825
826 if (value === null) {
827 node.removeAttribute(attributeName);
828 } else {
829 var _type = propertyInfo.type;
830 var attributeValue;
831
832 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {
833 // If attribute type is boolean, we know for sure it won't be an execution sink
834 // and we won't require Trusted Type here.
835 attributeValue = '';
836 } else {
837 // `setAttribute` with objects becomes only `[object]` in IE8/9,
838 // ('' + value) makes it output the correct toString()-value.
839 {
840 {
841 checkAttributeStringCoercion(value, attributeName);
842 }
843
844 attributeValue = '' + value;
845 }
846
847 if (propertyInfo.sanitizeURL) {
848 sanitizeURL(attributeValue.toString());
849 }
850 }
851
852 if (attributeNamespace) {
853 node.setAttributeNS(attributeNamespace, attributeName, attributeValue);
854 } else {
855 node.setAttribute(attributeName, attributeValue);
856 }
857 }
858 }
859
860 // ATTENTION
861 // When adding new symbols to this file,
862 // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
863 // The Symbol used to tag the ReactElement-like types.
864 var REACT_ELEMENT_TYPE = Symbol.for('react.element');
865 var REACT_PORTAL_TYPE = Symbol.for('react.portal');
866 var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
867 var REACT_STRICT_MODE_TYPE = Symbol.for('react.strict_mode');
868 var REACT_PROFILER_TYPE = Symbol.for('react.profiler');
869 var REACT_PROVIDER_TYPE = Symbol.for('react.provider');
870 var REACT_CONTEXT_TYPE = Symbol.for('react.context');
871 var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');
872 var REACT_SUSPENSE_TYPE = Symbol.for('react.suspense');
873 var REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list');
874 var REACT_MEMO_TYPE = Symbol.for('react.memo');
875 var REACT_LAZY_TYPE = Symbol.for('react.lazy');
876 var REACT_SCOPE_TYPE = Symbol.for('react.scope');
877 var REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for('react.debug_trace_mode');
878 var REACT_OFFSCREEN_TYPE = Symbol.for('react.offscreen');
879 var REACT_LEGACY_HIDDEN_TYPE = Symbol.for('react.legacy_hidden');
880 var REACT_CACHE_TYPE = Symbol.for('react.cache');
881 var REACT_TRACING_MARKER_TYPE = Symbol.for('react.tracing_marker');
882 var MAYBE_ITERATOR_SYMBOL = Symbol.iterator;
883 var FAUX_ITERATOR_SYMBOL = '@@iterator';
884 function getIteratorFn(maybeIterable) {
885 if (maybeIterable === null || typeof maybeIterable !== 'object') {
886 return null;
887 }
888
889 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
890
891 if (typeof maybeIterator === 'function') {
892 return maybeIterator;
893 }
894
895 return null;
896 }
897
898 var assign = Object.assign;
899
900 // Helpers to patch console.logs to avoid logging during side-effect free
901 // replaying on render function. This currently only patches the object
902 // lazily which won't cover if the log function was extracted eagerly.
903 // We could also eagerly patch the method.
904 var disabledDepth = 0;
905 var prevLog;
906 var prevInfo;
907 var prevWarn;
908 var prevError;
909 var prevGroup;
910 var prevGroupCollapsed;
911 var prevGroupEnd;
912
913 function disabledLog() {}
914
915 disabledLog.__reactDisabledLog = true;
916 function disableLogs() {
917 {
918 if (disabledDepth === 0) {
919 /* eslint-disable react-internal/no-production-logging */
920 prevLog = console.log;
921 prevInfo = console.info;
922 prevWarn = console.warn;
923 prevError = console.error;
924 prevGroup = console.group;
925 prevGroupCollapsed = console.groupCollapsed;
926 prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099
927
928 var props = {
929 configurable: true,
930 enumerable: true,
931 value: disabledLog,
932 writable: true
933 }; // $FlowFixMe Flow thinks console is immutable.
934
935 Object.defineProperties(console, {
936 info: props,
937 log: props,
938 warn: props,
939 error: props,
940 group: props,
941 groupCollapsed: props,
942 groupEnd: props
943 });
944 /* eslint-enable react-internal/no-production-logging */
945 }
946
947 disabledDepth++;
948 }
949 }
950 function reenableLogs() {
951 {
952 disabledDepth--;
953
954 if (disabledDepth === 0) {
955 /* eslint-disable react-internal/no-production-logging */
956 var props = {
957 configurable: true,
958 enumerable: true,
959 writable: true
960 }; // $FlowFixMe Flow thinks console is immutable.
961
962 Object.defineProperties(console, {
963 log: assign({}, props, {
964 value: prevLog
965 }),
966 info: assign({}, props, {
967 value: prevInfo
968 }),
969 warn: assign({}, props, {
970 value: prevWarn
971 }),
972 error: assign({}, props, {
973 value: prevError
974 }),
975 group: assign({}, props, {
976 value: prevGroup
977 }),
978 groupCollapsed: assign({}, props, {
979 value: prevGroupCollapsed
980 }),
981 groupEnd: assign({}, props, {
982 value: prevGroupEnd
983 })
984 });
985 /* eslint-enable react-internal/no-production-logging */
986 }
987
988 if (disabledDepth < 0) {
989 error('disabledDepth fell below zero. ' + 'This is a bug in React. Please file an issue.');
990 }
991 }
992 }
993
994 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
995 var prefix;
996 function describeBuiltInComponentFrame(name, source, ownerFn) {
997 {
998 if (prefix === undefined) {
999 // Extract the VM specific prefix used by each line.
1000 try {
1001 throw Error();
1002 } catch (x) {
1003 var match = x.stack.trim().match(/\n( *(at )?)/);
1004 prefix = match && match[1] || '';
1005 }
1006 } // We use the prefix to ensure our stacks line up with native stack frames.
1007
1008
1009 return '\n' + prefix + name;
1010 }
1011 }
1012 var reentry = false;
1013 var componentFrameCache;
1014
1015 {
1016 var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
1017 componentFrameCache = new PossiblyWeakMap();
1018 }
1019
1020 function describeNativeComponentFrame(fn, construct) {
1021 // If something asked for a stack inside a fake render, it should get ignored.
1022 if ( !fn || reentry) {
1023 return '';
1024 }
1025
1026 {
1027 var frame = componentFrameCache.get(fn);
1028
1029 if (frame !== undefined) {
1030 return frame;
1031 }
1032 }
1033
1034 var control;
1035 reentry = true;
1036 var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe It does accept undefined.
1037
1038 Error.prepareStackTrace = undefined;
1039 var previousDispatcher;
1040
1041 {
1042 previousDispatcher = ReactCurrentDispatcher.current; // Set the dispatcher in DEV because this might be call in the render function
1043 // for warnings.
1044
1045 ReactCurrentDispatcher.current = null;
1046 disableLogs();
1047 }
1048
1049 try {
1050 // This should throw.
1051 if (construct) {
1052 // Something should be setting the props in the constructor.
1053 var Fake = function () {
1054 throw Error();
1055 }; // $FlowFixMe
1056
1057
1058 Object.defineProperty(Fake.prototype, 'props', {
1059 set: function () {
1060 // We use a throwing setter instead of frozen or non-writable props
1061 // because that won't throw in a non-strict mode function.
1062 throw Error();
1063 }
1064 });
1065
1066 if (typeof Reflect === 'object' && Reflect.construct) {
1067 // We construct a different control for this case to include any extra
1068 // frames added by the construct call.
1069 try {
1070 Reflect.construct(Fake, []);
1071 } catch (x) {
1072 control = x;
1073 }
1074
1075 Reflect.construct(fn, [], Fake);
1076 } else {
1077 try {
1078 Fake.call();
1079 } catch (x) {
1080 control = x;
1081 }
1082
1083 fn.call(Fake.prototype);
1084 }
1085 } else {
1086 try {
1087 throw Error();
1088 } catch (x) {
1089 control = x;
1090 }
1091
1092 fn();
1093 }
1094 } catch (sample) {
1095 // This is inlined manually because closure doesn't do it for us.
1096 if (sample && control && typeof sample.stack === 'string') {
1097 // This extracts the first frame from the sample that isn't also in the control.
1098 // Skipping one frame that we assume is the frame that calls the two.
1099 var sampleLines = sample.stack.split('\n');
1100 var controlLines = control.stack.split('\n');
1101 var s = sampleLines.length - 1;
1102 var c = controlLines.length - 1;
1103
1104 while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) {
1105 // We expect at least one stack frame to be shared.
1106 // Typically this will be the root most one. However, stack frames may be
1107 // cut off due to maximum stack limits. In this case, one maybe cut off
1108 // earlier than the other. We assume that the sample is longer or the same
1109 // and there for cut off earlier. So we should find the root most frame in
1110 // the sample somewhere in the control.
1111 c--;
1112 }
1113
1114 for (; s >= 1 && c >= 0; s--, c--) {
1115 // Next we find the first one that isn't the same which should be the
1116 // frame that called our sample function and the control.
1117 if (sampleLines[s] !== controlLines[c]) {
1118 // In V8, the first line is describing the message but other VMs don't.
1119 // If we're about to return the first line, and the control is also on the same
1120 // line, that's a pretty good indicator that our sample threw at same line as
1121 // the control. I.e. before we entered the sample frame. So we ignore this result.
1122 // This can happen if you passed a class to function component, or non-function.
1123 if (s !== 1 || c !== 1) {
1124 do {
1125 s--;
1126 c--; // We may still have similar intermediate frames from the construct call.
1127 // The next one that isn't the same should be our match though.
1128
1129 if (c < 0 || sampleLines[s] !== controlLines[c]) {
1130 // V8 adds a "new" prefix for native classes. Let's remove it to make it prettier.
1131 var _frame = '\n' + sampleLines[s].replace(' at new ', ' at '); // If our component frame is labeled "<anonymous>"
1132 // but we have a user-provided "displayName"
1133 // splice it in to make the stack more readable.
1134
1135
1136 if (fn.displayName && _frame.includes('<anonymous>')) {
1137 _frame = _frame.replace('<anonymous>', fn.displayName);
1138 }
1139
1140 {
1141 if (typeof fn === 'function') {
1142 componentFrameCache.set(fn, _frame);
1143 }
1144 } // Return the line we found.
1145
1146
1147 return _frame;
1148 }
1149 } while (s >= 1 && c >= 0);
1150 }
1151
1152 break;
1153 }
1154 }
1155 }
1156 } finally {
1157 reentry = false;
1158
1159 {
1160 ReactCurrentDispatcher.current = previousDispatcher;
1161 reenableLogs();
1162 }
1163
1164 Error.prepareStackTrace = previousPrepareStackTrace;
1165 } // Fallback to just using the name if we couldn't make it throw.
1166
1167
1168 var name = fn ? fn.displayName || fn.name : '';
1169 var syntheticFrame = name ? describeBuiltInComponentFrame(name) : '';
1170
1171 {
1172 if (typeof fn === 'function') {
1173 componentFrameCache.set(fn, syntheticFrame);
1174 }
1175 }
1176
1177 return syntheticFrame;
1178 }
1179
1180 function describeClassComponentFrame(ctor, source, ownerFn) {
1181 {
1182 return describeNativeComponentFrame(ctor, true);
1183 }
1184 }
1185 function describeFunctionComponentFrame(fn, source, ownerFn) {
1186 {
1187 return describeNativeComponentFrame(fn, false);
1188 }
1189 }
1190
1191 function shouldConstruct(Component) {
1192 var prototype = Component.prototype;
1193 return !!(prototype && prototype.isReactComponent);
1194 }
1195
1196 function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) {
1197
1198 if (type == null) {
1199 return '';
1200 }
1201
1202 if (typeof type === 'function') {
1203 {
1204 return describeNativeComponentFrame(type, shouldConstruct(type));
1205 }
1206 }
1207
1208 if (typeof type === 'string') {
1209 return describeBuiltInComponentFrame(type);
1210 }
1211
1212 switch (type) {
1213 case REACT_SUSPENSE_TYPE:
1214 return describeBuiltInComponentFrame('Suspense');
1215
1216 case REACT_SUSPENSE_LIST_TYPE:
1217 return describeBuiltInComponentFrame('SuspenseList');
1218 }
1219
1220 if (typeof type === 'object') {
1221 switch (type.$$typeof) {
1222 case REACT_FORWARD_REF_TYPE:
1223 return describeFunctionComponentFrame(type.render);
1224
1225 case REACT_MEMO_TYPE:
1226 // Memo may contain any component type so we recursively resolve it.
1227 return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn);
1228
1229 case REACT_LAZY_TYPE:
1230 {
1231 var lazyComponent = type;
1232 var payload = lazyComponent._payload;
1233 var init = lazyComponent._init;
1234
1235 try {
1236 // Lazy may contain any component type so we recursively resolve it.
1237 return describeUnknownElementTypeFrameInDEV(init(payload), source, ownerFn);
1238 } catch (x) {}
1239 }
1240 }
1241 }
1242
1243 return '';
1244 }
1245
1246 function describeFiber(fiber) {
1247 var owner = fiber._debugOwner ? fiber._debugOwner.type : null ;
1248 var source = fiber._debugSource ;
1249
1250 switch (fiber.tag) {
1251 case HostComponent:
1252 return describeBuiltInComponentFrame(fiber.type);
1253
1254 case LazyComponent:
1255 return describeBuiltInComponentFrame('Lazy');
1256
1257 case SuspenseComponent:
1258 return describeBuiltInComponentFrame('Suspense');
1259
1260 case SuspenseListComponent:
1261 return describeBuiltInComponentFrame('SuspenseList');
1262
1263 case FunctionComponent:
1264 case IndeterminateComponent:
1265 case SimpleMemoComponent:
1266 return describeFunctionComponentFrame(fiber.type);
1267
1268 case ForwardRef:
1269 return describeFunctionComponentFrame(fiber.type.render);
1270
1271 case ClassComponent:
1272 return describeClassComponentFrame(fiber.type);
1273
1274 default:
1275 return '';
1276 }
1277 }
1278
1279 function getStackByFiberInDevAndProd(workInProgress) {
1280 try {
1281 var info = '';
1282 var node = workInProgress;
1283
1284 do {
1285 info += describeFiber(node);
1286 node = node.return;
1287 } while (node);
1288
1289 return info;
1290 } catch (x) {
1291 return '\nError generating stack: ' + x.message + '\n' + x.stack;
1292 }
1293 }
1294
1295 function getWrappedName(outerType, innerType, wrapperName) {
1296 var displayName = outerType.displayName;
1297
1298 if (displayName) {
1299 return displayName;
1300 }
1301
1302 var functionName = innerType.displayName || innerType.name || '';
1303 return functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName;
1304 } // Keep in sync with react-reconciler/getComponentNameFromFiber
1305
1306
1307 function getContextName(type) {
1308 return type.displayName || 'Context';
1309 } // Note that the reconciler package should generally prefer to use getComponentNameFromFiber() instead.
1310
1311
1312 function getComponentNameFromType(type) {
1313 if (type == null) {
1314 // Host root, text node or just invalid type.
1315 return null;
1316 }
1317
1318 {
1319 if (typeof type.tag === 'number') {
1320 error('Received an unexpected object in getComponentNameFromType(). ' + 'This is likely a bug in React. Please file an issue.');
1321 }
1322 }
1323
1324 if (typeof type === 'function') {
1325 return type.displayName || type.name || null;
1326 }
1327
1328 if (typeof type === 'string') {
1329 return type;
1330 }
1331
1332 switch (type) {
1333 case REACT_FRAGMENT_TYPE:
1334 return 'Fragment';
1335
1336 case REACT_PORTAL_TYPE:
1337 return 'Portal';
1338
1339 case REACT_PROFILER_TYPE:
1340 return 'Profiler';
1341
1342 case REACT_STRICT_MODE_TYPE:
1343 return 'StrictMode';
1344
1345 case REACT_SUSPENSE_TYPE:
1346 return 'Suspense';
1347
1348 case REACT_SUSPENSE_LIST_TYPE:
1349 return 'SuspenseList';
1350
1351 }
1352
1353 if (typeof type === 'object') {
1354 switch (type.$$typeof) {
1355 case REACT_CONTEXT_TYPE:
1356 var context = type;
1357 return getContextName(context) + '.Consumer';
1358
1359 case REACT_PROVIDER_TYPE:
1360 var provider = type;
1361 return getContextName(provider._context) + '.Provider';
1362
1363 case REACT_FORWARD_REF_TYPE:
1364 return getWrappedName(type, type.render, 'ForwardRef');
1365
1366 case REACT_MEMO_TYPE:
1367 var outerName = type.displayName || null;
1368
1369 if (outerName !== null) {
1370 return outerName;
1371 }
1372
1373 return getComponentNameFromType(type.type) || 'Memo';
1374
1375 case REACT_LAZY_TYPE:
1376 {
1377 var lazyComponent = type;
1378 var payload = lazyComponent._payload;
1379 var init = lazyComponent._init;
1380
1381 try {
1382 return getComponentNameFromType(init(payload));
1383 } catch (x) {
1384 return null;
1385 }
1386 }
1387
1388 // eslint-disable-next-line no-fallthrough
1389 }
1390 }
1391
1392 return null;
1393 }
1394
1395 function getWrappedName$1(outerType, innerType, wrapperName) {
1396 var functionName = innerType.displayName || innerType.name || '';
1397 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
1398 } // Keep in sync with shared/getComponentNameFromType
1399
1400
1401 function getContextName$1(type) {
1402 return type.displayName || 'Context';
1403 }
1404
1405 function getComponentNameFromFiber(fiber) {
1406 var tag = fiber.tag,
1407 type = fiber.type;
1408
1409 switch (tag) {
1410 case CacheComponent:
1411 return 'Cache';
1412
1413 case ContextConsumer:
1414 var context = type;
1415 return getContextName$1(context) + '.Consumer';
1416
1417 case ContextProvider:
1418 var provider = type;
1419 return getContextName$1(provider._context) + '.Provider';
1420
1421 case DehydratedFragment:
1422 return 'DehydratedFragment';
1423
1424 case ForwardRef:
1425 return getWrappedName$1(type, type.render, 'ForwardRef');
1426
1427 case Fragment:
1428 return 'Fragment';
1429
1430 case HostComponent:
1431 // Host component type is the display name (e.g. "div", "View")
1432 return type;
1433
1434 case HostPortal:
1435 return 'Portal';
1436
1437 case HostRoot:
1438 return 'Root';
1439
1440 case HostText:
1441 return 'Text';
1442
1443 case LazyComponent:
1444 // Name comes from the type in this case; we don't have a tag.
1445 return getComponentNameFromType(type);
1446
1447 case Mode:
1448 if (type === REACT_STRICT_MODE_TYPE) {
1449 // Don't be less specific than shared/getComponentNameFromType
1450 return 'StrictMode';
1451 }
1452
1453 return 'Mode';
1454
1455 case OffscreenComponent:
1456 return 'Offscreen';
1457
1458 case Profiler:
1459 return 'Profiler';
1460
1461 case ScopeComponent:
1462 return 'Scope';
1463
1464 case SuspenseComponent:
1465 return 'Suspense';
1466
1467 case SuspenseListComponent:
1468 return 'SuspenseList';
1469
1470 case TracingMarkerComponent:
1471 return 'TracingMarker';
1472 // The display name for this tags come from the user-provided type:
1473
1474 case ClassComponent:
1475 case FunctionComponent:
1476 case IncompleteClassComponent:
1477 case IndeterminateComponent:
1478 case MemoComponent:
1479 case SimpleMemoComponent:
1480 if (typeof type === 'function') {
1481 return type.displayName || type.name || null;
1482 }
1483
1484 if (typeof type === 'string') {
1485 return type;
1486 }
1487
1488 break;
1489
1490 }
1491
1492 return null;
1493 }
1494
1495 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
1496 var current = null;
1497 var isRendering = false;
1498 function getCurrentFiberOwnerNameInDevOrNull() {
1499 {
1500 if (current === null) {
1501 return null;
1502 }
1503
1504 var owner = current._debugOwner;
1505
1506 if (owner !== null && typeof owner !== 'undefined') {
1507 return getComponentNameFromFiber(owner);
1508 }
1509 }
1510
1511 return null;
1512 }
1513
1514 function getCurrentFiberStackInDev() {
1515 {
1516 if (current === null) {
1517 return '';
1518 } // Safe because if current fiber exists, we are reconciling,
1519 // and it is guaranteed to be the work-in-progress version.
1520
1521
1522 return getStackByFiberInDevAndProd(current);
1523 }
1524 }
1525
1526 function resetCurrentFiber() {
1527 {
1528 ReactDebugCurrentFrame.getCurrentStack = null;
1529 current = null;
1530 isRendering = false;
1531 }
1532 }
1533 function setCurrentFiber(fiber) {
1534 {
1535 ReactDebugCurrentFrame.getCurrentStack = fiber === null ? null : getCurrentFiberStackInDev;
1536 current = fiber;
1537 isRendering = false;
1538 }
1539 }
1540 function getCurrentFiber() {
1541 {
1542 return current;
1543 }
1544 }
1545 function setIsRendering(rendering) {
1546 {
1547 isRendering = rendering;
1548 }
1549 }
1550
1551 // Flow does not allow string concatenation of most non-string types. To work
1552 // around this limitation, we use an opaque type that can only be obtained by
1553 // passing the value through getToStringValue first.
1554 function toString(value) {
1555 // The coercion safety check is performed in getToStringValue().
1556 // eslint-disable-next-line react-internal/safe-string-coercion
1557 return '' + value;
1558 }
1559 function getToStringValue(value) {
1560 switch (typeof value) {
1561 case 'boolean':
1562 case 'number':
1563 case 'string':
1564 case 'undefined':
1565 return value;
1566
1567 case 'object':
1568 {
1569 checkFormFieldValueStringCoercion(value);
1570 }
1571
1572 return value;
1573
1574 default:
1575 // function, symbol are assigned as empty strings
1576 return '';
1577 }
1578 }
1579
1580 var hasReadOnlyValue = {
1581 button: true,
1582 checkbox: true,
1583 image: true,
1584 hidden: true,
1585 radio: true,
1586 reset: true,
1587 submit: true
1588 };
1589 function checkControlledValueProps(tagName, props) {
1590 {
1591 if (!(hasReadOnlyValue[props.type] || props.onChange || props.onInput || props.readOnly || props.disabled || props.value == null)) {
1592 error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, ' + 'set either `onChange` or `readOnly`.');
1593 }
1594
1595 if (!(props.onChange || props.readOnly || props.disabled || props.checked == null)) {
1596 error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.');
1597 }
1598 }
1599 }
1600
1601 function isCheckable(elem) {
1602 var type = elem.type;
1603 var nodeName = elem.nodeName;
1604 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
1605 }
1606
1607 function getTracker(node) {
1608 return node._valueTracker;
1609 }
1610
1611 function detachTracker(node) {
1612 node._valueTracker = null;
1613 }
1614
1615 function getValueFromNode(node) {
1616 var value = '';
1617
1618 if (!node) {
1619 return value;
1620 }
1621
1622 if (isCheckable(node)) {
1623 value = node.checked ? 'true' : 'false';
1624 } else {
1625 value = node.value;
1626 }
1627
1628 return value;
1629 }
1630
1631 function trackValueOnNode(node) {
1632 var valueField = isCheckable(node) ? 'checked' : 'value';
1633 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
1634
1635 {
1636 checkFormFieldValueStringCoercion(node[valueField]);
1637 }
1638
1639 var currentValue = '' + node[valueField]; // if someone has already defined a value or Safari, then bail
1640 // and don't track value will cause over reporting of changes,
1641 // but it's better then a hard failure
1642 // (needed for certain tests that spyOn input values and Safari)
1643
1644 if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
1645 return;
1646 }
1647
1648 var get = descriptor.get,
1649 set = descriptor.set;
1650 Object.defineProperty(node, valueField, {
1651 configurable: true,
1652 get: function () {
1653 return get.call(this);
1654 },
1655 set: function (value) {
1656 {
1657 checkFormFieldValueStringCoercion(value);
1658 }
1659
1660 currentValue = '' + value;
1661 set.call(this, value);
1662 }
1663 }); // We could've passed this the first time
1664 // but it triggers a bug in IE11 and Edge 14/15.
1665 // Calling defineProperty() again should be equivalent.
1666 // https://github.com/facebook/react/issues/11768
1667
1668 Object.defineProperty(node, valueField, {
1669 enumerable: descriptor.enumerable
1670 });
1671 var tracker = {
1672 getValue: function () {
1673 return currentValue;
1674 },
1675 setValue: function (value) {
1676 {
1677 checkFormFieldValueStringCoercion(value);
1678 }
1679
1680 currentValue = '' + value;
1681 },
1682 stopTracking: function () {
1683 detachTracker(node);
1684 delete node[valueField];
1685 }
1686 };
1687 return tracker;
1688 }
1689
1690 function track(node) {
1691 if (getTracker(node)) {
1692 return;
1693 } // TODO: Once it's just Fiber we can move this to node._wrapperState
1694
1695
1696 node._valueTracker = trackValueOnNode(node);
1697 }
1698 function updateValueIfChanged(node) {
1699 if (!node) {
1700 return false;
1701 }
1702
1703 var tracker = getTracker(node); // if there is no tracker at this point it's unlikely
1704 // that trying again will succeed
1705
1706 if (!tracker) {
1707 return true;
1708 }
1709
1710 var lastValue = tracker.getValue();
1711 var nextValue = getValueFromNode(node);
1712
1713 if (nextValue !== lastValue) {
1714 tracker.setValue(nextValue);
1715 return true;
1716 }
1717
1718 return false;
1719 }
1720
1721 function getActiveElement(doc) {
1722 doc = doc || (typeof document !== 'undefined' ? document : undefined);
1723
1724 if (typeof doc === 'undefined') {
1725 return null;
1726 }
1727
1728 try {
1729 return doc.activeElement || doc.body;
1730 } catch (e) {
1731 return doc.body;
1732 }
1733 }
1734
1735 var didWarnValueDefaultValue = false;
1736 var didWarnCheckedDefaultChecked = false;
1737 var didWarnControlledToUncontrolled = false;
1738 var didWarnUncontrolledToControlled = false;
1739
1740 function isControlled(props) {
1741 var usesChecked = props.type === 'checkbox' || props.type === 'radio';
1742 return usesChecked ? props.checked != null : props.value != null;
1743 }
1744 /**
1745 * Implements an <input> host component that allows setting these optional
1746 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
1747 *
1748 * If `checked` or `value` are not supplied (or null/undefined), user actions
1749 * that affect the checked state or value will trigger updates to the element.
1750 *
1751 * If they are supplied (and not null/undefined), the rendered element will not
1752 * trigger updates to the element. Instead, the props must change in order for
1753 * the rendered element to be updated.
1754 *
1755 * The rendered element will be initialized as unchecked (or `defaultChecked`)
1756 * with an empty value (or `defaultValue`).
1757 *
1758 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
1759 */
1760
1761
1762 function getHostProps(element, props) {
1763 var node = element;
1764 var checked = props.checked;
1765 var hostProps = assign({}, props, {
1766 defaultChecked: undefined,
1767 defaultValue: undefined,
1768 value: undefined,
1769 checked: checked != null ? checked : node._wrapperState.initialChecked
1770 });
1771 return hostProps;
1772 }
1773 function initWrapperState(element, props) {
1774 {
1775 checkControlledValueProps('input', props);
1776
1777 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
1778 error('%s contains an input of type %s with both checked and defaultChecked props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://reactjs.org/link/controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);
1779
1780 didWarnCheckedDefaultChecked = true;
1781 }
1782
1783 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
1784 error('%s contains an input of type %s with both value and defaultValue props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://reactjs.org/link/controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);
1785
1786 didWarnValueDefaultValue = true;
1787 }
1788 }
1789
1790 var node = element;
1791 var defaultValue = props.defaultValue == null ? '' : props.defaultValue;
1792 node._wrapperState = {
1793 initialChecked: props.checked != null ? props.checked : props.defaultChecked,
1794 initialValue: getToStringValue(props.value != null ? props.value : defaultValue),
1795 controlled: isControlled(props)
1796 };
1797 }
1798 function updateChecked(element, props) {
1799 var node = element;
1800 var checked = props.checked;
1801
1802 if (checked != null) {
1803 setValueForProperty(node, 'checked', checked, false);
1804 }
1805 }
1806 function updateWrapper(element, props) {
1807 var node = element;
1808
1809 {
1810 var controlled = isControlled(props);
1811
1812 if (!node._wrapperState.controlled && controlled && !didWarnUncontrolledToControlled) {
1813 error('A component is changing an uncontrolled input to be controlled. ' + 'This is likely caused by the value changing from undefined to ' + 'a defined value, which should not happen. ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components');
1814
1815 didWarnUncontrolledToControlled = true;
1816 }
1817
1818 if (node._wrapperState.controlled && !controlled && !didWarnControlledToUncontrolled) {
1819 error('A component is changing a controlled input to be uncontrolled. ' + 'This is likely caused by the value changing from a defined to ' + 'undefined, which should not happen. ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components');
1820
1821 didWarnControlledToUncontrolled = true;
1822 }
1823 }
1824
1825 updateChecked(element, props);
1826 var value = getToStringValue(props.value);
1827 var type = props.type;
1828
1829 if (value != null) {
1830 if (type === 'number') {
1831 if (value === 0 && node.value === '' || // We explicitly want to coerce to number here if possible.
1832 // eslint-disable-next-line
1833 node.value != value) {
1834 node.value = toString(value);
1835 }
1836 } else if (node.value !== toString(value)) {
1837 node.value = toString(value);
1838 }
1839 } else if (type === 'submit' || type === 'reset') {
1840 // Submit/reset inputs need the attribute removed completely to avoid
1841 // blank-text buttons.
1842 node.removeAttribute('value');
1843 return;
1844 }
1845
1846 {
1847 // When syncing the value attribute, the value comes from a cascade of
1848 // properties:
1849 // 1. The value React property
1850 // 2. The defaultValue React property
1851 // 3. Otherwise there should be no change
1852 if (props.hasOwnProperty('value')) {
1853 setDefaultValue(node, props.type, value);
1854 } else if (props.hasOwnProperty('defaultValue')) {
1855 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
1856 }
1857 }
1858
1859 {
1860 // When syncing the checked attribute, it only changes when it needs
1861 // to be removed, such as transitioning from a checkbox into a text input
1862 if (props.checked == null && props.defaultChecked != null) {
1863 node.defaultChecked = !!props.defaultChecked;
1864 }
1865 }
1866 }
1867 function postMountWrapper(element, props, isHydrating) {
1868 var node = element; // Do not assign value if it is already set. This prevents user text input
1869 // from being lost during SSR hydration.
1870
1871 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
1872 var type = props.type;
1873 var isButton = type === 'submit' || type === 'reset'; // Avoid setting value attribute on submit/reset inputs as it overrides the
1874 // default value provided by the browser. See: #12872
1875
1876 if (isButton && (props.value === undefined || props.value === null)) {
1877 return;
1878 }
1879
1880 var initialValue = toString(node._wrapperState.initialValue); // Do not assign value if it is already set. This prevents user text input
1881 // from being lost during SSR hydration.
1882
1883 if (!isHydrating) {
1884 {
1885 // When syncing the value attribute, the value property should use
1886 // the wrapperState._initialValue property. This uses:
1887 //
1888 // 1. The value React property when present
1889 // 2. The defaultValue React property when present
1890 // 3. An empty string
1891 if (initialValue !== node.value) {
1892 node.value = initialValue;
1893 }
1894 }
1895 }
1896
1897 {
1898 // Otherwise, the value attribute is synchronized to the property,
1899 // so we assign defaultValue to the same thing as the value property
1900 // assignment step above.
1901 node.defaultValue = initialValue;
1902 }
1903 } // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
1904 // this is needed to work around a chrome bug where setting defaultChecked
1905 // will sometimes influence the value of checked (even after detachment).
1906 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
1907 // We need to temporarily unset name to avoid disrupting radio button groups.
1908
1909
1910 var name = node.name;
1911
1912 if (name !== '') {
1913 node.name = '';
1914 }
1915
1916 {
1917 // When syncing the checked attribute, both the checked property and
1918 // attribute are assigned at the same time using defaultChecked. This uses:
1919 //
1920 // 1. The checked React property when present
1921 // 2. The defaultChecked React property when present
1922 // 3. Otherwise, false
1923 node.defaultChecked = !node.defaultChecked;
1924 node.defaultChecked = !!node._wrapperState.initialChecked;
1925 }
1926
1927 if (name !== '') {
1928 node.name = name;
1929 }
1930 }
1931 function restoreControlledState(element, props) {
1932 var node = element;
1933 updateWrapper(node, props);
1934 updateNamedCousins(node, props);
1935 }
1936
1937 function updateNamedCousins(rootNode, props) {
1938 var name = props.name;
1939
1940 if (props.type === 'radio' && name != null) {
1941 var queryRoot = rootNode;
1942
1943 while (queryRoot.parentNode) {
1944 queryRoot = queryRoot.parentNode;
1945 } // If `rootNode.form` was non-null, then we could try `form.elements`,
1946 // but that sometimes behaves strangely in IE8. We could also try using
1947 // `form.getElementsByName`, but that will only return direct children
1948 // and won't include inputs that use the HTML5 `form=` attribute. Since
1949 // the input might not even be in a form. It might not even be in the
1950 // document. Let's just use the local `querySelectorAll` to ensure we don't
1951 // miss anything.
1952
1953
1954 {
1955 checkAttributeStringCoercion(name, 'name');
1956 }
1957
1958 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
1959
1960 for (var i = 0; i < group.length; i++) {
1961 var otherNode = group[i];
1962
1963 if (otherNode === rootNode || otherNode.form !== rootNode.form) {
1964 continue;
1965 } // This will throw if radio buttons rendered by different copies of React
1966 // and the same name are rendered into the same form (same as #1939).
1967 // That's probably okay; we don't support it just as we don't support
1968 // mixing React radio buttons with non-React ones.
1969
1970
1971 var otherProps = getFiberCurrentPropsFromNode(otherNode);
1972
1973 if (!otherProps) {
1974 throw new Error('ReactDOMInput: Mixing React and non-React radio inputs with the ' + 'same `name` is not supported.');
1975 } // We need update the tracked value on the named cousin since the value
1976 // was changed but the input saw no event or value set
1977
1978
1979 updateValueIfChanged(otherNode); // If this is a controlled radio button group, forcing the input that
1980 // was previously checked to update will cause it to be come re-checked
1981 // as appropriate.
1982
1983 updateWrapper(otherNode, otherProps);
1984 }
1985 }
1986 } // In Chrome, assigning defaultValue to certain input types triggers input validation.
1987 // For number inputs, the display value loses trailing decimal points. For email inputs,
1988 // Chrome raises "The specified value <x> is not a valid email address".
1989 //
1990 // Here we check to see if the defaultValue has actually changed, avoiding these problems
1991 // when the user is inputting text
1992 //
1993 // https://github.com/facebook/react/issues/7253
1994
1995
1996 function setDefaultValue(node, type, value) {
1997 if ( // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
1998 type !== 'number' || getActiveElement(node.ownerDocument) !== node) {
1999 if (value == null) {
2000 node.defaultValue = toString(node._wrapperState.initialValue);
2001 } else if (node.defaultValue !== toString(value)) {
2002 node.defaultValue = toString(value);
2003 }
2004 }
2005 }
2006
2007 var didWarnSelectedSetOnOption = false;
2008 var didWarnInvalidChild = false;
2009 var didWarnInvalidInnerHTML = false;
2010 /**
2011 * Implements an <option> host component that warns when `selected` is set.
2012 */
2013
2014 function validateProps(element, props) {
2015 {
2016 // If a value is not provided, then the children must be simple.
2017 if (props.value == null) {
2018 if (typeof props.children === 'object' && props.children !== null) {
2019 React.Children.forEach(props.children, function (child) {
2020 if (child == null) {
2021 return;
2022 }
2023
2024 if (typeof child === 'string' || typeof child === 'number') {
2025 return;
2026 }
2027
2028 if (!didWarnInvalidChild) {
2029 didWarnInvalidChild = true;
2030
2031 error('Cannot infer the option value of complex children. ' + 'Pass a `value` prop or use a plain string as children to <option>.');
2032 }
2033 });
2034 } else if (props.dangerouslySetInnerHTML != null) {
2035 if (!didWarnInvalidInnerHTML) {
2036 didWarnInvalidInnerHTML = true;
2037
2038 error('Pass a `value` prop if you set dangerouslyInnerHTML so React knows ' + 'which value should be selected.');
2039 }
2040 }
2041 } // TODO: Remove support for `selected` in <option>.
2042
2043
2044 if (props.selected != null && !didWarnSelectedSetOnOption) {
2045 error('Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
2046
2047 didWarnSelectedSetOnOption = true;
2048 }
2049 }
2050 }
2051 function postMountWrapper$1(element, props) {
2052 // value="" should make a value attribute (#6219)
2053 if (props.value != null) {
2054 element.setAttribute('value', toString(getToStringValue(props.value)));
2055 }
2056 }
2057
2058 var isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare
2059
2060 function isArray(a) {
2061 return isArrayImpl(a);
2062 }
2063
2064 var didWarnValueDefaultValue$1;
2065
2066 {
2067 didWarnValueDefaultValue$1 = false;
2068 }
2069
2070 function getDeclarationErrorAddendum() {
2071 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
2072
2073 if (ownerName) {
2074 return '\n\nCheck the render method of `' + ownerName + '`.';
2075 }
2076
2077 return '';
2078 }
2079
2080 var valuePropNames = ['value', 'defaultValue'];
2081 /**
2082 * Validation function for `value` and `defaultValue`.
2083 */
2084
2085 function checkSelectPropTypes(props) {
2086 {
2087 checkControlledValueProps('select', props);
2088
2089 for (var i = 0; i < valuePropNames.length; i++) {
2090 var propName = valuePropNames[i];
2091
2092 if (props[propName] == null) {
2093 continue;
2094 }
2095
2096 var propNameIsArray = isArray(props[propName]);
2097
2098 if (props.multiple && !propNameIsArray) {
2099 error('The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
2100 } else if (!props.multiple && propNameIsArray) {
2101 error('The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
2102 }
2103 }
2104 }
2105 }
2106
2107 function updateOptions(node, multiple, propValue, setDefaultSelected) {
2108 var options = node.options;
2109
2110 if (multiple) {
2111 var selectedValues = propValue;
2112 var selectedValue = {};
2113
2114 for (var i = 0; i < selectedValues.length; i++) {
2115 // Prefix to avoid chaos with special keys.
2116 selectedValue['$' + selectedValues[i]] = true;
2117 }
2118
2119 for (var _i = 0; _i < options.length; _i++) {
2120 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
2121
2122 if (options[_i].selected !== selected) {
2123 options[_i].selected = selected;
2124 }
2125
2126 if (selected && setDefaultSelected) {
2127 options[_i].defaultSelected = true;
2128 }
2129 }
2130 } else {
2131 // Do not set `select.value` as exact behavior isn't consistent across all
2132 // browsers for all cases.
2133 var _selectedValue = toString(getToStringValue(propValue));
2134
2135 var defaultSelected = null;
2136
2137 for (var _i2 = 0; _i2 < options.length; _i2++) {
2138 if (options[_i2].value === _selectedValue) {
2139 options[_i2].selected = true;
2140
2141 if (setDefaultSelected) {
2142 options[_i2].defaultSelected = true;
2143 }
2144
2145 return;
2146 }
2147
2148 if (defaultSelected === null && !options[_i2].disabled) {
2149 defaultSelected = options[_i2];
2150 }
2151 }
2152
2153 if (defaultSelected !== null) {
2154 defaultSelected.selected = true;
2155 }
2156 }
2157 }
2158 /**
2159 * Implements a <select> host component that allows optionally setting the
2160 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
2161 * stringable. If `multiple` is true, the prop must be an array of stringables.
2162 *
2163 * If `value` is not supplied (or null/undefined), user actions that change the
2164 * selected option will trigger updates to the rendered options.
2165 *
2166 * If it is supplied (and not null/undefined), the rendered options will not
2167 * update in response to user actions. Instead, the `value` prop must change in
2168 * order for the rendered options to update.
2169 *
2170 * If `defaultValue` is provided, any options with the supplied values will be
2171 * selected.
2172 */
2173
2174
2175 function getHostProps$1(element, props) {
2176 return assign({}, props, {
2177 value: undefined
2178 });
2179 }
2180 function initWrapperState$1(element, props) {
2181 var node = element;
2182
2183 {
2184 checkSelectPropTypes(props);
2185 }
2186
2187 node._wrapperState = {
2188 wasMultiple: !!props.multiple
2189 };
2190
2191 {
2192 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
2193 error('Select elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled select ' + 'element and remove one of these props. More info: ' + 'https://reactjs.org/link/controlled-components');
2194
2195 didWarnValueDefaultValue$1 = true;
2196 }
2197 }
2198 }
2199 function postMountWrapper$2(element, props) {
2200 var node = element;
2201 node.multiple = !!props.multiple;
2202 var value = props.value;
2203
2204 if (value != null) {
2205 updateOptions(node, !!props.multiple, value, false);
2206 } else if (props.defaultValue != null) {
2207 updateOptions(node, !!props.multiple, props.defaultValue, true);
2208 }
2209 }
2210 function postUpdateWrapper(element, props) {
2211 var node = element;
2212 var wasMultiple = node._wrapperState.wasMultiple;
2213 node._wrapperState.wasMultiple = !!props.multiple;
2214 var value = props.value;
2215
2216 if (value != null) {
2217 updateOptions(node, !!props.multiple, value, false);
2218 } else if (wasMultiple !== !!props.multiple) {
2219 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
2220 if (props.defaultValue != null) {
2221 updateOptions(node, !!props.multiple, props.defaultValue, true);
2222 } else {
2223 // Revert the select back to its default unselected state.
2224 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
2225 }
2226 }
2227 }
2228 function restoreControlledState$1(element, props) {
2229 var node = element;
2230 var value = props.value;
2231
2232 if (value != null) {
2233 updateOptions(node, !!props.multiple, value, false);
2234 }
2235 }
2236
2237 var didWarnValDefaultVal = false;
2238
2239 /**
2240 * Implements a <textarea> host component that allows setting `value`, and
2241 * `defaultValue`. This differs from the traditional DOM API because value is
2242 * usually set as PCDATA children.
2243 *
2244 * If `value` is not supplied (or null/undefined), user actions that affect the
2245 * value will trigger updates to the element.
2246 *
2247 * If `value` is supplied (and not null/undefined), the rendered element will
2248 * not trigger updates to the element. Instead, the `value` prop must change in
2249 * order for the rendered element to be updated.
2250 *
2251 * The rendered element will be initialized with an empty value, the prop
2252 * `defaultValue` if specified, or the children content (deprecated).
2253 */
2254 function getHostProps$2(element, props) {
2255 var node = element;
2256
2257 if (props.dangerouslySetInnerHTML != null) {
2258 throw new Error('`dangerouslySetInnerHTML` does not make sense on <textarea>.');
2259 } // Always set children to the same thing. In IE9, the selection range will
2260 // get reset if `textContent` is mutated. We could add a check in setTextContent
2261 // to only set the value if/when the value differs from the node value (which would
2262 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
2263 // solution. The value can be a boolean or object so that's why it's forced
2264 // to be a string.
2265
2266
2267 var hostProps = assign({}, props, {
2268 value: undefined,
2269 defaultValue: undefined,
2270 children: toString(node._wrapperState.initialValue)
2271 });
2272
2273 return hostProps;
2274 }
2275 function initWrapperState$2(element, props) {
2276 var node = element;
2277
2278 {
2279 checkControlledValueProps('textarea', props);
2280
2281 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
2282 error('%s contains a textarea with both value and defaultValue props. ' + 'Textarea elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled textarea ' + 'and remove one of these props. More info: ' + 'https://reactjs.org/link/controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
2283
2284 didWarnValDefaultVal = true;
2285 }
2286 }
2287
2288 var initialValue = props.value; // Only bother fetching default value if we're going to use it
2289
2290 if (initialValue == null) {
2291 var children = props.children,
2292 defaultValue = props.defaultValue;
2293
2294 if (children != null) {
2295 {
2296 error('Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
2297 }
2298
2299 {
2300 if (defaultValue != null) {
2301 throw new Error('If you supply `defaultValue` on a <textarea>, do not pass children.');
2302 }
2303
2304 if (isArray(children)) {
2305 if (children.length > 1) {
2306 throw new Error('<textarea> can only have at most one child.');
2307 }
2308
2309 children = children[0];
2310 }
2311
2312 defaultValue = children;
2313 }
2314 }
2315
2316 if (defaultValue == null) {
2317 defaultValue = '';
2318 }
2319
2320 initialValue = defaultValue;
2321 }
2322
2323 node._wrapperState = {
2324 initialValue: getToStringValue(initialValue)
2325 };
2326 }
2327 function updateWrapper$1(element, props) {
2328 var node = element;
2329 var value = getToStringValue(props.value);
2330 var defaultValue = getToStringValue(props.defaultValue);
2331
2332 if (value != null) {
2333 // Cast `value` to a string to ensure the value is set correctly. While
2334 // browsers typically do this as necessary, jsdom doesn't.
2335 var newValue = toString(value); // To avoid side effects (such as losing text selection), only set value if changed
2336
2337 if (newValue !== node.value) {
2338 node.value = newValue;
2339 }
2340
2341 if (props.defaultValue == null && node.defaultValue !== newValue) {
2342 node.defaultValue = newValue;
2343 }
2344 }
2345
2346 if (defaultValue != null) {
2347 node.defaultValue = toString(defaultValue);
2348 }
2349 }
2350 function postMountWrapper$3(element, props) {
2351 var node = element; // This is in postMount because we need access to the DOM node, which is not
2352 // available until after the component has mounted.
2353
2354 var textContent = node.textContent; // Only set node.value if textContent is equal to the expected
2355 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
2356 // will populate textContent as well.
2357 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
2358
2359 if (textContent === node._wrapperState.initialValue) {
2360 if (textContent !== '' && textContent !== null) {
2361 node.value = textContent;
2362 }
2363 }
2364 }
2365 function restoreControlledState$2(element, props) {
2366 // DOM component is still mounted; update
2367 updateWrapper$1(element, props);
2368 }
2369
2370 var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
2371 var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
2372 var SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; // Assumes there is no parent namespace.
2373
2374 function getIntrinsicNamespace(type) {
2375 switch (type) {
2376 case 'svg':
2377 return SVG_NAMESPACE;
2378
2379 case 'math':
2380 return MATH_NAMESPACE;
2381
2382 default:
2383 return HTML_NAMESPACE;
2384 }
2385 }
2386 function getChildNamespace(parentNamespace, type) {
2387 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE) {
2388 // No (or default) parent namespace: potential entry point.
2389 return getIntrinsicNamespace(type);
2390 }
2391
2392 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
2393 // We're leaving SVG.
2394 return HTML_NAMESPACE;
2395 } // By default, pass namespace below.
2396
2397
2398 return parentNamespace;
2399 }
2400
2401 /* globals MSApp */
2402
2403 /**
2404 * Create a function which has 'unsafe' privileges (required by windows8 apps)
2405 */
2406 var createMicrosoftUnsafeLocalFunction = function (func) {
2407 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
2408 return function (arg0, arg1, arg2, arg3) {
2409 MSApp.execUnsafeLocalFunction(function () {
2410 return func(arg0, arg1, arg2, arg3);
2411 });
2412 };
2413 } else {
2414 return func;
2415 }
2416 };
2417
2418 var reusableSVGContainer;
2419 /**
2420 * Set the innerHTML property of a node
2421 *
2422 * @param {DOMElement} node
2423 * @param {string} html
2424 * @internal
2425 */
2426
2427 var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
2428 if (node.namespaceURI === SVG_NAMESPACE) {
2429
2430 if (!('innerHTML' in node)) {
2431 // IE does not have innerHTML for SVG nodes, so instead we inject the
2432 // new markup in a temp node and then move the child nodes across into
2433 // the target node
2434 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
2435 reusableSVGContainer.innerHTML = '<svg>' + html.valueOf().toString() + '</svg>';
2436 var svgNode = reusableSVGContainer.firstChild;
2437
2438 while (node.firstChild) {
2439 node.removeChild(node.firstChild);
2440 }
2441
2442 while (svgNode.firstChild) {
2443 node.appendChild(svgNode.firstChild);
2444 }
2445
2446 return;
2447 }
2448 }
2449
2450 node.innerHTML = html;
2451 });
2452
2453 /**
2454 * HTML nodeType values that represent the type of the node
2455 */
2456 var ELEMENT_NODE = 1;
2457 var TEXT_NODE = 3;
2458 var COMMENT_NODE = 8;
2459 var DOCUMENT_NODE = 9;
2460 var DOCUMENT_FRAGMENT_NODE = 11;
2461
2462 /**
2463 * Set the textContent property of a node. For text updates, it's faster
2464 * to set the `nodeValue` of the Text node directly instead of using
2465 * `.textContent` which will remove the existing node and create a new one.
2466 *
2467 * @param {DOMElement} node
2468 * @param {string} text
2469 * @internal
2470 */
2471
2472 var setTextContent = function (node, text) {
2473 if (text) {
2474 var firstChild = node.firstChild;
2475
2476 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
2477 firstChild.nodeValue = text;
2478 return;
2479 }
2480 }
2481
2482 node.textContent = text;
2483 };
2484
2485 // List derived from Gecko source code:
2486 // https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js
2487 var shorthandToLonghand = {
2488 animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'],
2489 background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'],
2490 backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'],
2491 border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'],
2492 borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'],
2493 borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'],
2494 borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'],
2495 borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'],
2496 borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'],
2497 borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'],
2498 borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'],
2499 borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'],
2500 borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'],
2501 borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'],
2502 borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'],
2503 borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'],
2504 borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'],
2505 columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'],
2506 columns: ['columnCount', 'columnWidth'],
2507 flex: ['flexBasis', 'flexGrow', 'flexShrink'],
2508 flexFlow: ['flexDirection', 'flexWrap'],
2509 font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'],
2510 fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'],
2511 gap: ['columnGap', 'rowGap'],
2512 grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
2513 gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'],
2514 gridColumn: ['gridColumnEnd', 'gridColumnStart'],
2515 gridColumnGap: ['columnGap'],
2516 gridGap: ['columnGap', 'rowGap'],
2517 gridRow: ['gridRowEnd', 'gridRowStart'],
2518 gridRowGap: ['rowGap'],
2519 gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
2520 listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'],
2521 margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'],
2522 marker: ['markerEnd', 'markerMid', 'markerStart'],
2523 mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'],
2524 maskPosition: ['maskPositionX', 'maskPositionY'],
2525 outline: ['outlineColor', 'outlineStyle', 'outlineWidth'],
2526 overflow: ['overflowX', 'overflowY'],
2527 padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'],
2528 placeContent: ['alignContent', 'justifyContent'],
2529 placeItems: ['alignItems', 'justifyItems'],
2530 placeSelf: ['alignSelf', 'justifySelf'],
2531 textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'],
2532 textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'],
2533 transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'],
2534 wordWrap: ['overflowWrap']
2535 };
2536
2537 /**
2538 * CSS properties which accept numbers but are not in units of "px".
2539 */
2540 var isUnitlessNumber = {
2541 animationIterationCount: true,
2542 aspectRatio: true,
2543 borderImageOutset: true,
2544 borderImageSlice: true,
2545 borderImageWidth: true,
2546 boxFlex: true,
2547 boxFlexGroup: true,
2548 boxOrdinalGroup: true,
2549 columnCount: true,
2550 columns: true,
2551 flex: true,
2552 flexGrow: true,
2553 flexPositive: true,
2554 flexShrink: true,
2555 flexNegative: true,
2556 flexOrder: true,
2557 gridArea: true,
2558 gridRow: true,
2559 gridRowEnd: true,
2560 gridRowSpan: true,
2561 gridRowStart: true,
2562 gridColumn: true,
2563 gridColumnEnd: true,
2564 gridColumnSpan: true,
2565 gridColumnStart: true,
2566 fontWeight: true,
2567 lineClamp: true,
2568 lineHeight: true,
2569 opacity: true,
2570 order: true,
2571 orphans: true,
2572 tabSize: true,
2573 widows: true,
2574 zIndex: true,
2575 zoom: true,
2576 // SVG-related properties
2577 fillOpacity: true,
2578 floodOpacity: true,
2579 stopOpacity: true,
2580 strokeDasharray: true,
2581 strokeDashoffset: true,
2582 strokeMiterlimit: true,
2583 strokeOpacity: true,
2584 strokeWidth: true
2585 };
2586 /**
2587 * @param {string} prefix vendor-specific prefix, eg: Webkit
2588 * @param {string} key style name, eg: transitionDuration
2589 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
2590 * WebkitTransitionDuration
2591 */
2592
2593 function prefixKey(prefix, key) {
2594 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
2595 }
2596 /**
2597 * Support style names that may come passed in prefixed by adding permutations
2598 * of vendor prefixes.
2599 */
2600
2601
2602 var prefixes = ['Webkit', 'ms', 'Moz', 'O']; // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
2603 // infinite loop, because it iterates over the newly added props too.
2604
2605 Object.keys(isUnitlessNumber).forEach(function (prop) {
2606 prefixes.forEach(function (prefix) {
2607 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
2608 });
2609 });
2610
2611 /**
2612 * Convert a value into the proper css writable value. The style name `name`
2613 * should be logical (no hyphens), as specified
2614 * in `CSSProperty.isUnitlessNumber`.
2615 *
2616 * @param {string} name CSS property name such as `topMargin`.
2617 * @param {*} value CSS property value such as `10px`.
2618 * @return {string} Normalized style value with dimensions applied.
2619 */
2620
2621 function dangerousStyleValue(name, value, isCustomProperty) {
2622 // Note that we've removed escapeTextForBrowser() calls here since the
2623 // whole string will be escaped when the attribute is injected into
2624 // the markup. If you provide unsafe user data here they can inject
2625 // arbitrary CSS which may be problematic (I couldn't repro this):
2626 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
2627 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
2628 // This is not an XSS hole but instead a potential CSS injection issue
2629 // which has lead to a greater discussion about how we're going to
2630 // trust URLs moving forward. See #2115901
2631 var isEmpty = value == null || typeof value === 'boolean' || value === '';
2632
2633 if (isEmpty) {
2634 return '';
2635 }
2636
2637 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
2638 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
2639 }
2640
2641 {
2642 checkCSSPropertyStringCoercion(value, name);
2643 }
2644
2645 return ('' + value).trim();
2646 }
2647
2648 var uppercasePattern = /([A-Z])/g;
2649 var msPattern = /^ms-/;
2650 /**
2651 * Hyphenates a camelcased CSS property name, for example:
2652 *
2653 * > hyphenateStyleName('backgroundColor')
2654 * < "background-color"
2655 * > hyphenateStyleName('MozTransition')
2656 * < "-moz-transition"
2657 * > hyphenateStyleName('msTransition')
2658 * < "-ms-transition"
2659 *
2660 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
2661 * is converted to `-ms-`.
2662 */
2663
2664 function hyphenateStyleName(name) {
2665 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-');
2666 }
2667
2668 var warnValidStyle = function () {};
2669
2670 {
2671 // 'msTransform' is correct, but the other prefixes should be capitalized
2672 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
2673 var msPattern$1 = /^-ms-/;
2674 var hyphenPattern = /-(.)/g; // style values shouldn't contain a semicolon
2675
2676 var badStyleValueWithSemicolonPattern = /;\s*$/;
2677 var warnedStyleNames = {};
2678 var warnedStyleValues = {};
2679 var warnedForNaNValue = false;
2680 var warnedForInfinityValue = false;
2681
2682 var camelize = function (string) {
2683 return string.replace(hyphenPattern, function (_, character) {
2684 return character.toUpperCase();
2685 });
2686 };
2687
2688 var warnHyphenatedStyleName = function (name) {
2689 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
2690 return;
2691 }
2692
2693 warnedStyleNames[name] = true;
2694
2695 error('Unsupported style property %s. Did you mean %s?', name, // As Andi Smith suggests
2696 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
2697 // is converted to lowercase `ms`.
2698 camelize(name.replace(msPattern$1, 'ms-')));
2699 };
2700
2701 var warnBadVendoredStyleName = function (name) {
2702 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
2703 return;
2704 }
2705
2706 warnedStyleNames[name] = true;
2707
2708 error('Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1));
2709 };
2710
2711 var warnStyleValueWithSemicolon = function (name, value) {
2712 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
2713 return;
2714 }
2715
2716 warnedStyleValues[value] = true;
2717
2718 error("Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, ''));
2719 };
2720
2721 var warnStyleValueIsNaN = function (name, value) {
2722 if (warnedForNaNValue) {
2723 return;
2724 }
2725
2726 warnedForNaNValue = true;
2727
2728 error('`NaN` is an invalid value for the `%s` css style property.', name);
2729 };
2730
2731 var warnStyleValueIsInfinity = function (name, value) {
2732 if (warnedForInfinityValue) {
2733 return;
2734 }
2735
2736 warnedForInfinityValue = true;
2737
2738 error('`Infinity` is an invalid value for the `%s` css style property.', name);
2739 };
2740
2741 warnValidStyle = function (name, value) {
2742 if (name.indexOf('-') > -1) {
2743 warnHyphenatedStyleName(name);
2744 } else if (badVendoredStyleNamePattern.test(name)) {
2745 warnBadVendoredStyleName(name);
2746 } else if (badStyleValueWithSemicolonPattern.test(value)) {
2747 warnStyleValueWithSemicolon(name, value);
2748 }
2749
2750 if (typeof value === 'number') {
2751 if (isNaN(value)) {
2752 warnStyleValueIsNaN(name, value);
2753 } else if (!isFinite(value)) {
2754 warnStyleValueIsInfinity(name, value);
2755 }
2756 }
2757 };
2758 }
2759
2760 var warnValidStyle$1 = warnValidStyle;
2761
2762 /**
2763 * Operations for dealing with CSS properties.
2764 */
2765
2766 /**
2767 * This creates a string that is expected to be equivalent to the style
2768 * attribute generated by server-side rendering. It by-passes warnings and
2769 * security checks so it's not safe to use this value for anything other than
2770 * comparison. It is only used in DEV for SSR validation.
2771 */
2772
2773 function createDangerousStringForStyles(styles) {
2774 {
2775 var serialized = '';
2776 var delimiter = '';
2777
2778 for (var styleName in styles) {
2779 if (!styles.hasOwnProperty(styleName)) {
2780 continue;
2781 }
2782
2783 var styleValue = styles[styleName];
2784
2785 if (styleValue != null) {
2786 var isCustomProperty = styleName.indexOf('--') === 0;
2787 serialized += delimiter + (isCustomProperty ? styleName : hyphenateStyleName(styleName)) + ':';
2788 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
2789 delimiter = ';';
2790 }
2791 }
2792
2793 return serialized || null;
2794 }
2795 }
2796 /**
2797 * Sets the value for multiple styles on a node. If a value is specified as
2798 * '' (empty string), the corresponding style property will be unset.
2799 *
2800 * @param {DOMElement} node
2801 * @param {object} styles
2802 */
2803
2804 function setValueForStyles(node, styles) {
2805 var style = node.style;
2806
2807 for (var styleName in styles) {
2808 if (!styles.hasOwnProperty(styleName)) {
2809 continue;
2810 }
2811
2812 var isCustomProperty = styleName.indexOf('--') === 0;
2813
2814 {
2815 if (!isCustomProperty) {
2816 warnValidStyle$1(styleName, styles[styleName]);
2817 }
2818 }
2819
2820 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
2821
2822 if (styleName === 'float') {
2823 styleName = 'cssFloat';
2824 }
2825
2826 if (isCustomProperty) {
2827 style.setProperty(styleName, styleValue);
2828 } else {
2829 style[styleName] = styleValue;
2830 }
2831 }
2832 }
2833
2834 function isValueEmpty(value) {
2835 return value == null || typeof value === 'boolean' || value === '';
2836 }
2837 /**
2838 * Given {color: 'red', overflow: 'hidden'} returns {
2839 * color: 'color',
2840 * overflowX: 'overflow',
2841 * overflowY: 'overflow',
2842 * }. This can be read as "the overflowY property was set by the overflow
2843 * shorthand". That is, the values are the property that each was derived from.
2844 */
2845
2846
2847 function expandShorthandMap(styles) {
2848 var expanded = {};
2849
2850 for (var key in styles) {
2851 var longhands = shorthandToLonghand[key] || [key];
2852
2853 for (var i = 0; i < longhands.length; i++) {
2854 expanded[longhands[i]] = key;
2855 }
2856 }
2857
2858 return expanded;
2859 }
2860 /**
2861 * When mixing shorthand and longhand property names, we warn during updates if
2862 * we expect an incorrect result to occur. In particular, we warn for:
2863 *
2864 * Updating a shorthand property (longhand gets overwritten):
2865 * {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'}
2866 * becomes .style.font = 'baz'
2867 * Removing a shorthand property (longhand gets lost too):
2868 * {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'}
2869 * becomes .style.font = ''
2870 * Removing a longhand property (should revert to shorthand; doesn't):
2871 * {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'}
2872 * becomes .style.fontVariant = ''
2873 */
2874
2875
2876 function validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) {
2877 {
2878 if (!nextStyles) {
2879 return;
2880 }
2881
2882 var expandedUpdates = expandShorthandMap(styleUpdates);
2883 var expandedStyles = expandShorthandMap(nextStyles);
2884 var warnedAbout = {};
2885
2886 for (var key in expandedUpdates) {
2887 var originalKey = expandedUpdates[key];
2888 var correctOriginalKey = expandedStyles[key];
2889
2890 if (correctOriginalKey && originalKey !== correctOriginalKey) {
2891 var warningKey = originalKey + ',' + correctOriginalKey;
2892
2893 if (warnedAbout[warningKey]) {
2894 continue;
2895 }
2896
2897 warnedAbout[warningKey] = true;
2898
2899 error('%s a style property during rerender (%s) when a ' + 'conflicting property is set (%s) can lead to styling bugs. To ' + "avoid this, don't mix shorthand and non-shorthand properties " + 'for the same value; instead, replace the shorthand with ' + 'separate values.', isValueEmpty(styleUpdates[originalKey]) ? 'Removing' : 'Updating', originalKey, correctOriginalKey);
2900 }
2901 }
2902 }
2903 }
2904
2905 // For HTML, certain tags should omit their close tag. We keep a list for
2906 // those special-case tags.
2907 var omittedCloseTags = {
2908 area: true,
2909 base: true,
2910 br: true,
2911 col: true,
2912 embed: true,
2913 hr: true,
2914 img: true,
2915 input: true,
2916 keygen: true,
2917 link: true,
2918 meta: true,
2919 param: true,
2920 source: true,
2921 track: true,
2922 wbr: true // NOTE: menuitem's close tag should be omitted, but that causes problems.
2923
2924 };
2925
2926 // `omittedCloseTags` except that `menuitem` should still have its closing tag.
2927
2928 var voidElementTags = assign({
2929 menuitem: true
2930 }, omittedCloseTags);
2931
2932 var HTML = '__html';
2933
2934 function assertValidProps(tag, props) {
2935 if (!props) {
2936 return;
2937 } // Note the use of `==` which checks for null or undefined.
2938
2939
2940 if (voidElementTags[tag]) {
2941 if (props.children != null || props.dangerouslySetInnerHTML != null) {
2942 throw new Error(tag + " is a void element tag and must neither have `children` nor " + 'use `dangerouslySetInnerHTML`.');
2943 }
2944 }
2945
2946 if (props.dangerouslySetInnerHTML != null) {
2947 if (props.children != null) {
2948 throw new Error('Can only set one of `children` or `props.dangerouslySetInnerHTML`.');
2949 }
2950
2951 if (typeof props.dangerouslySetInnerHTML !== 'object' || !(HTML in props.dangerouslySetInnerHTML)) {
2952 throw new Error('`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + 'Please visit https://reactjs.org/link/dangerously-set-inner-html ' + 'for more information.');
2953 }
2954 }
2955
2956 {
2957 if (!props.suppressContentEditableWarning && props.contentEditable && props.children != null) {
2958 error('A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + 'probably not intentional.');
2959 }
2960 }
2961
2962 if (props.style != null && typeof props.style !== 'object') {
2963 throw new Error('The `style` prop expects a mapping from style properties to values, ' + "not a string. For example, style={{marginRight: spacing + 'em'}} when " + 'using JSX.');
2964 }
2965 }
2966
2967 function isCustomComponent(tagName, props) {
2968 if (tagName.indexOf('-') === -1) {
2969 return typeof props.is === 'string';
2970 }
2971
2972 switch (tagName) {
2973 // These are reserved SVG and MathML elements.
2974 // We don't mind this list too much because we expect it to never grow.
2975 // The alternative is to track the namespace in a few places which is convoluted.
2976 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
2977 case 'annotation-xml':
2978 case 'color-profile':
2979 case 'font-face':
2980 case 'font-face-src':
2981 case 'font-face-uri':
2982 case 'font-face-format':
2983 case 'font-face-name':
2984 case 'missing-glyph':
2985 return false;
2986
2987 default:
2988 return true;
2989 }
2990 }
2991
2992 // When adding attributes to the HTML or SVG allowed attribute list, be sure to
2993 // also add them to this module to ensure casing and incorrect name
2994 // warnings.
2995 var possibleStandardNames = {
2996 // HTML
2997 accept: 'accept',
2998 acceptcharset: 'acceptCharset',
2999 'accept-charset': 'acceptCharset',
3000 accesskey: 'accessKey',
3001 action: 'action',
3002 allowfullscreen: 'allowFullScreen',
3003 alt: 'alt',
3004 as: 'as',
3005 async: 'async',
3006 autocapitalize: 'autoCapitalize',
3007 autocomplete: 'autoComplete',
3008 autocorrect: 'autoCorrect',
3009 autofocus: 'autoFocus',
3010 autoplay: 'autoPlay',
3011 autosave: 'autoSave',
3012 capture: 'capture',
3013 cellpadding: 'cellPadding',
3014 cellspacing: 'cellSpacing',
3015 challenge: 'challenge',
3016 charset: 'charSet',
3017 checked: 'checked',
3018 children: 'children',
3019 cite: 'cite',
3020 class: 'className',
3021 classid: 'classID',
3022 classname: 'className',
3023 cols: 'cols',
3024 colspan: 'colSpan',
3025 content: 'content',
3026 contenteditable: 'contentEditable',
3027 contextmenu: 'contextMenu',
3028 controls: 'controls',
3029 controlslist: 'controlsList',
3030 coords: 'coords',
3031 crossorigin: 'crossOrigin',
3032 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
3033 data: 'data',
3034 datetime: 'dateTime',
3035 default: 'default',
3036 defaultchecked: 'defaultChecked',
3037 defaultvalue: 'defaultValue',
3038 defer: 'defer',
3039 dir: 'dir',
3040 disabled: 'disabled',
3041 disablepictureinpicture: 'disablePictureInPicture',
3042 disableremoteplayback: 'disableRemotePlayback',
3043 download: 'download',
3044 draggable: 'draggable',
3045 enctype: 'encType',
3046 enterkeyhint: 'enterKeyHint',
3047 for: 'htmlFor',
3048 form: 'form',
3049 formmethod: 'formMethod',
3050 formaction: 'formAction',
3051 formenctype: 'formEncType',
3052 formnovalidate: 'formNoValidate',
3053 formtarget: 'formTarget',
3054 frameborder: 'frameBorder',
3055 headers: 'headers',
3056 height: 'height',
3057 hidden: 'hidden',
3058 high: 'high',
3059 href: 'href',
3060 hreflang: 'hrefLang',
3061 htmlfor: 'htmlFor',
3062 httpequiv: 'httpEquiv',
3063 'http-equiv': 'httpEquiv',
3064 icon: 'icon',
3065 id: 'id',
3066 imagesizes: 'imageSizes',
3067 imagesrcset: 'imageSrcSet',
3068 innerhtml: 'innerHTML',
3069 inputmode: 'inputMode',
3070 integrity: 'integrity',
3071 is: 'is',
3072 itemid: 'itemID',
3073 itemprop: 'itemProp',
3074 itemref: 'itemRef',
3075 itemscope: 'itemScope',
3076 itemtype: 'itemType',
3077 keyparams: 'keyParams',
3078 keytype: 'keyType',
3079 kind: 'kind',
3080 label: 'label',
3081 lang: 'lang',
3082 list: 'list',
3083 loop: 'loop',
3084 low: 'low',
3085 manifest: 'manifest',
3086 marginwidth: 'marginWidth',
3087 marginheight: 'marginHeight',
3088 max: 'max',
3089 maxlength: 'maxLength',
3090 media: 'media',
3091 mediagroup: 'mediaGroup',
3092 method: 'method',
3093 min: 'min',
3094 minlength: 'minLength',
3095 multiple: 'multiple',
3096 muted: 'muted',
3097 name: 'name',
3098 nomodule: 'noModule',
3099 nonce: 'nonce',
3100 novalidate: 'noValidate',
3101 open: 'open',
3102 optimum: 'optimum',
3103 pattern: 'pattern',
3104 placeholder: 'placeholder',
3105 playsinline: 'playsInline',
3106 poster: 'poster',
3107 preload: 'preload',
3108 profile: 'profile',
3109 radiogroup: 'radioGroup',
3110 readonly: 'readOnly',
3111 referrerpolicy: 'referrerPolicy',
3112 rel: 'rel',
3113 required: 'required',
3114 reversed: 'reversed',
3115 role: 'role',
3116 rows: 'rows',
3117 rowspan: 'rowSpan',
3118 sandbox: 'sandbox',
3119 scope: 'scope',
3120 scoped: 'scoped',
3121 scrolling: 'scrolling',
3122 seamless: 'seamless',
3123 selected: 'selected',
3124 shape: 'shape',
3125 size: 'size',
3126 sizes: 'sizes',
3127 span: 'span',
3128 spellcheck: 'spellCheck',
3129 src: 'src',
3130 srcdoc: 'srcDoc',
3131 srclang: 'srcLang',
3132 srcset: 'srcSet',
3133 start: 'start',
3134 step: 'step',
3135 style: 'style',
3136 summary: 'summary',
3137 tabindex: 'tabIndex',
3138 target: 'target',
3139 title: 'title',
3140 type: 'type',
3141 usemap: 'useMap',
3142 value: 'value',
3143 width: 'width',
3144 wmode: 'wmode',
3145 wrap: 'wrap',
3146 // SVG
3147 about: 'about',
3148 accentheight: 'accentHeight',
3149 'accent-height': 'accentHeight',
3150 accumulate: 'accumulate',
3151 additive: 'additive',
3152 alignmentbaseline: 'alignmentBaseline',
3153 'alignment-baseline': 'alignmentBaseline',
3154 allowreorder: 'allowReorder',
3155 alphabetic: 'alphabetic',
3156 amplitude: 'amplitude',
3157 arabicform: 'arabicForm',
3158 'arabic-form': 'arabicForm',
3159 ascent: 'ascent',
3160 attributename: 'attributeName',
3161 attributetype: 'attributeType',
3162 autoreverse: 'autoReverse',
3163 azimuth: 'azimuth',
3164 basefrequency: 'baseFrequency',
3165 baselineshift: 'baselineShift',
3166 'baseline-shift': 'baselineShift',
3167 baseprofile: 'baseProfile',
3168 bbox: 'bbox',
3169 begin: 'begin',
3170 bias: 'bias',
3171 by: 'by',
3172 calcmode: 'calcMode',
3173 capheight: 'capHeight',
3174 'cap-height': 'capHeight',
3175 clip: 'clip',
3176 clippath: 'clipPath',
3177 'clip-path': 'clipPath',
3178 clippathunits: 'clipPathUnits',
3179 cliprule: 'clipRule',
3180 'clip-rule': 'clipRule',
3181 color: 'color',
3182 colorinterpolation: 'colorInterpolation',
3183 'color-interpolation': 'colorInterpolation',
3184 colorinterpolationfilters: 'colorInterpolationFilters',
3185 'color-interpolation-filters': 'colorInterpolationFilters',
3186 colorprofile: 'colorProfile',
3187 'color-profile': 'colorProfile',
3188 colorrendering: 'colorRendering',
3189 'color-rendering': 'colorRendering',
3190 contentscripttype: 'contentScriptType',
3191 contentstyletype: 'contentStyleType',
3192 cursor: 'cursor',
3193 cx: 'cx',
3194 cy: 'cy',
3195 d: 'd',
3196 datatype: 'datatype',
3197 decelerate: 'decelerate',
3198 descent: 'descent',
3199 diffuseconstant: 'diffuseConstant',
3200 direction: 'direction',
3201 display: 'display',
3202 divisor: 'divisor',
3203 dominantbaseline: 'dominantBaseline',
3204 'dominant-baseline': 'dominantBaseline',
3205 dur: 'dur',
3206 dx: 'dx',
3207 dy: 'dy',
3208 edgemode: 'edgeMode',
3209 elevation: 'elevation',
3210 enablebackground: 'enableBackground',
3211 'enable-background': 'enableBackground',
3212 end: 'end',
3213 exponent: 'exponent',
3214 externalresourcesrequired: 'externalResourcesRequired',
3215 fill: 'fill',
3216 fillopacity: 'fillOpacity',
3217 'fill-opacity': 'fillOpacity',
3218 fillrule: 'fillRule',
3219 'fill-rule': 'fillRule',
3220 filter: 'filter',
3221 filterres: 'filterRes',
3222 filterunits: 'filterUnits',
3223 floodopacity: 'floodOpacity',
3224 'flood-opacity': 'floodOpacity',
3225 floodcolor: 'floodColor',
3226 'flood-color': 'floodColor',
3227 focusable: 'focusable',
3228 fontfamily: 'fontFamily',
3229 'font-family': 'fontFamily',
3230 fontsize: 'fontSize',
3231 'font-size': 'fontSize',
3232 fontsizeadjust: 'fontSizeAdjust',
3233 'font-size-adjust': 'fontSizeAdjust',
3234 fontstretch: 'fontStretch',
3235 'font-stretch': 'fontStretch',
3236 fontstyle: 'fontStyle',
3237 'font-style': 'fontStyle',
3238 fontvariant: 'fontVariant',
3239 'font-variant': 'fontVariant',
3240 fontweight: 'fontWeight',
3241 'font-weight': 'fontWeight',
3242 format: 'format',
3243 from: 'from',
3244 fx: 'fx',
3245 fy: 'fy',
3246 g1: 'g1',
3247 g2: 'g2',
3248 glyphname: 'glyphName',
3249 'glyph-name': 'glyphName',
3250 glyphorientationhorizontal: 'glyphOrientationHorizontal',
3251 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
3252 glyphorientationvertical: 'glyphOrientationVertical',
3253 'glyph-orientation-vertical': 'glyphOrientationVertical',
3254 glyphref: 'glyphRef',
3255 gradienttransform: 'gradientTransform',
3256 gradientunits: 'gradientUnits',
3257 hanging: 'hanging',
3258 horizadvx: 'horizAdvX',
3259 'horiz-adv-x': 'horizAdvX',
3260 horizoriginx: 'horizOriginX',
3261 'horiz-origin-x': 'horizOriginX',
3262 ideographic: 'ideographic',
3263 imagerendering: 'imageRendering',
3264 'image-rendering': 'imageRendering',
3265 in2: 'in2',
3266 in: 'in',
3267 inlist: 'inlist',
3268 intercept: 'intercept',
3269 k1: 'k1',
3270 k2: 'k2',
3271 k3: 'k3',
3272 k4: 'k4',
3273 k: 'k',
3274 kernelmatrix: 'kernelMatrix',
3275 kernelunitlength: 'kernelUnitLength',
3276 kerning: 'kerning',
3277 keypoints: 'keyPoints',
3278 keysplines: 'keySplines',
3279 keytimes: 'keyTimes',
3280 lengthadjust: 'lengthAdjust',
3281 letterspacing: 'letterSpacing',
3282 'letter-spacing': 'letterSpacing',
3283 lightingcolor: 'lightingColor',
3284 'lighting-color': 'lightingColor',
3285 limitingconeangle: 'limitingConeAngle',
3286 local: 'local',
3287 markerend: 'markerEnd',
3288 'marker-end': 'markerEnd',
3289 markerheight: 'markerHeight',
3290 markermid: 'markerMid',
3291 'marker-mid': 'markerMid',
3292 markerstart: 'markerStart',
3293 'marker-start': 'markerStart',
3294 markerunits: 'markerUnits',
3295 markerwidth: 'markerWidth',
3296 mask: 'mask',
3297 maskcontentunits: 'maskContentUnits',
3298 maskunits: 'maskUnits',
3299 mathematical: 'mathematical',
3300 mode: 'mode',
3301 numoctaves: 'numOctaves',
3302 offset: 'offset',
3303 opacity: 'opacity',
3304 operator: 'operator',
3305 order: 'order',
3306 orient: 'orient',
3307 orientation: 'orientation',
3308 origin: 'origin',
3309 overflow: 'overflow',
3310 overlineposition: 'overlinePosition',
3311 'overline-position': 'overlinePosition',
3312 overlinethickness: 'overlineThickness',
3313 'overline-thickness': 'overlineThickness',
3314 paintorder: 'paintOrder',
3315 'paint-order': 'paintOrder',
3316 panose1: 'panose1',
3317 'panose-1': 'panose1',
3318 pathlength: 'pathLength',
3319 patterncontentunits: 'patternContentUnits',
3320 patterntransform: 'patternTransform',
3321 patternunits: 'patternUnits',
3322 pointerevents: 'pointerEvents',
3323 'pointer-events': 'pointerEvents',
3324 points: 'points',
3325 pointsatx: 'pointsAtX',
3326 pointsaty: 'pointsAtY',
3327 pointsatz: 'pointsAtZ',
3328 prefix: 'prefix',
3329 preservealpha: 'preserveAlpha',
3330 preserveaspectratio: 'preserveAspectRatio',
3331 primitiveunits: 'primitiveUnits',
3332 property: 'property',
3333 r: 'r',
3334 radius: 'radius',
3335 refx: 'refX',
3336 refy: 'refY',
3337 renderingintent: 'renderingIntent',
3338 'rendering-intent': 'renderingIntent',
3339 repeatcount: 'repeatCount',
3340 repeatdur: 'repeatDur',
3341 requiredextensions: 'requiredExtensions',
3342 requiredfeatures: 'requiredFeatures',
3343 resource: 'resource',
3344 restart: 'restart',
3345 result: 'result',
3346 results: 'results',
3347 rotate: 'rotate',
3348 rx: 'rx',
3349 ry: 'ry',
3350 scale: 'scale',
3351 security: 'security',
3352 seed: 'seed',
3353 shaperendering: 'shapeRendering',
3354 'shape-rendering': 'shapeRendering',
3355 slope: 'slope',
3356 spacing: 'spacing',
3357 specularconstant: 'specularConstant',
3358 specularexponent: 'specularExponent',
3359 speed: 'speed',
3360 spreadmethod: 'spreadMethod',
3361 startoffset: 'startOffset',
3362 stddeviation: 'stdDeviation',
3363 stemh: 'stemh',
3364 stemv: 'stemv',
3365 stitchtiles: 'stitchTiles',
3366 stopcolor: 'stopColor',
3367 'stop-color': 'stopColor',
3368 stopopacity: 'stopOpacity',
3369 'stop-opacity': 'stopOpacity',
3370 strikethroughposition: 'strikethroughPosition',
3371 'strikethrough-position': 'strikethroughPosition',
3372 strikethroughthickness: 'strikethroughThickness',
3373 'strikethrough-thickness': 'strikethroughThickness',
3374 string: 'string',
3375 stroke: 'stroke',
3376 strokedasharray: 'strokeDasharray',
3377 'stroke-dasharray': 'strokeDasharray',
3378 strokedashoffset: 'strokeDashoffset',
3379 'stroke-dashoffset': 'strokeDashoffset',
3380 strokelinecap: 'strokeLinecap',
3381 'stroke-linecap': 'strokeLinecap',
3382 strokelinejoin: 'strokeLinejoin',
3383 'stroke-linejoin': 'strokeLinejoin',
3384 strokemiterlimit: 'strokeMiterlimit',
3385 'stroke-miterlimit': 'strokeMiterlimit',
3386 strokewidth: 'strokeWidth',
3387 'stroke-width': 'strokeWidth',
3388 strokeopacity: 'strokeOpacity',
3389 'stroke-opacity': 'strokeOpacity',
3390 suppresscontenteditablewarning: 'suppressContentEditableWarning',
3391 suppresshydrationwarning: 'suppressHydrationWarning',
3392 surfacescale: 'surfaceScale',
3393 systemlanguage: 'systemLanguage',
3394 tablevalues: 'tableValues',
3395 targetx: 'targetX',
3396 targety: 'targetY',
3397 textanchor: 'textAnchor',
3398 'text-anchor': 'textAnchor',
3399 textdecoration: 'textDecoration',
3400 'text-decoration': 'textDecoration',
3401 textlength: 'textLength',
3402 textrendering: 'textRendering',
3403 'text-rendering': 'textRendering',
3404 to: 'to',
3405 transform: 'transform',
3406 typeof: 'typeof',
3407 u1: 'u1',
3408 u2: 'u2',
3409 underlineposition: 'underlinePosition',
3410 'underline-position': 'underlinePosition',
3411 underlinethickness: 'underlineThickness',
3412 'underline-thickness': 'underlineThickness',
3413 unicode: 'unicode',
3414 unicodebidi: 'unicodeBidi',
3415 'unicode-bidi': 'unicodeBidi',
3416 unicoderange: 'unicodeRange',
3417 'unicode-range': 'unicodeRange',
3418 unitsperem: 'unitsPerEm',
3419 'units-per-em': 'unitsPerEm',
3420 unselectable: 'unselectable',
3421 valphabetic: 'vAlphabetic',
3422 'v-alphabetic': 'vAlphabetic',
3423 values: 'values',
3424 vectoreffect: 'vectorEffect',
3425 'vector-effect': 'vectorEffect',
3426 version: 'version',
3427 vertadvy: 'vertAdvY',
3428 'vert-adv-y': 'vertAdvY',
3429 vertoriginx: 'vertOriginX',
3430 'vert-origin-x': 'vertOriginX',
3431 vertoriginy: 'vertOriginY',
3432 'vert-origin-y': 'vertOriginY',
3433 vhanging: 'vHanging',
3434 'v-hanging': 'vHanging',
3435 videographic: 'vIdeographic',
3436 'v-ideographic': 'vIdeographic',
3437 viewbox: 'viewBox',
3438 viewtarget: 'viewTarget',
3439 visibility: 'visibility',
3440 vmathematical: 'vMathematical',
3441 'v-mathematical': 'vMathematical',
3442 vocab: 'vocab',
3443 widths: 'widths',
3444 wordspacing: 'wordSpacing',
3445 'word-spacing': 'wordSpacing',
3446 writingmode: 'writingMode',
3447 'writing-mode': 'writingMode',
3448 x1: 'x1',
3449 x2: 'x2',
3450 x: 'x',
3451 xchannelselector: 'xChannelSelector',
3452 xheight: 'xHeight',
3453 'x-height': 'xHeight',
3454 xlinkactuate: 'xlinkActuate',
3455 'xlink:actuate': 'xlinkActuate',
3456 xlinkarcrole: 'xlinkArcrole',
3457 'xlink:arcrole': 'xlinkArcrole',
3458 xlinkhref: 'xlinkHref',
3459 'xlink:href': 'xlinkHref',
3460 xlinkrole: 'xlinkRole',
3461 'xlink:role': 'xlinkRole',
3462 xlinkshow: 'xlinkShow',
3463 'xlink:show': 'xlinkShow',
3464 xlinktitle: 'xlinkTitle',
3465 'xlink:title': 'xlinkTitle',
3466 xlinktype: 'xlinkType',
3467 'xlink:type': 'xlinkType',
3468 xmlbase: 'xmlBase',
3469 'xml:base': 'xmlBase',
3470 xmllang: 'xmlLang',
3471 'xml:lang': 'xmlLang',
3472 xmlns: 'xmlns',
3473 'xml:space': 'xmlSpace',
3474 xmlnsxlink: 'xmlnsXlink',
3475 'xmlns:xlink': 'xmlnsXlink',
3476 xmlspace: 'xmlSpace',
3477 y1: 'y1',
3478 y2: 'y2',
3479 y: 'y',
3480 ychannelselector: 'yChannelSelector',
3481 z: 'z',
3482 zoomandpan: 'zoomAndPan'
3483 };
3484
3485 var ariaProperties = {
3486 'aria-current': 0,
3487 // state
3488 'aria-description': 0,
3489 'aria-details': 0,
3490 'aria-disabled': 0,
3491 // state
3492 'aria-hidden': 0,
3493 // state
3494 'aria-invalid': 0,
3495 // state
3496 'aria-keyshortcuts': 0,
3497 'aria-label': 0,
3498 'aria-roledescription': 0,
3499 // Widget Attributes
3500 'aria-autocomplete': 0,
3501 'aria-checked': 0,
3502 'aria-expanded': 0,
3503 'aria-haspopup': 0,
3504 'aria-level': 0,
3505 'aria-modal': 0,
3506 'aria-multiline': 0,
3507 'aria-multiselectable': 0,
3508 'aria-orientation': 0,
3509 'aria-placeholder': 0,
3510 'aria-pressed': 0,
3511 'aria-readonly': 0,
3512 'aria-required': 0,
3513 'aria-selected': 0,
3514 'aria-sort': 0,
3515 'aria-valuemax': 0,
3516 'aria-valuemin': 0,
3517 'aria-valuenow': 0,
3518 'aria-valuetext': 0,
3519 // Live Region Attributes
3520 'aria-atomic': 0,
3521 'aria-busy': 0,
3522 'aria-live': 0,
3523 'aria-relevant': 0,
3524 // Drag-and-Drop Attributes
3525 'aria-dropeffect': 0,
3526 'aria-grabbed': 0,
3527 // Relationship Attributes
3528 'aria-activedescendant': 0,
3529 'aria-colcount': 0,
3530 'aria-colindex': 0,
3531 'aria-colspan': 0,
3532 'aria-controls': 0,
3533 'aria-describedby': 0,
3534 'aria-errormessage': 0,
3535 'aria-flowto': 0,
3536 'aria-labelledby': 0,
3537 'aria-owns': 0,
3538 'aria-posinset': 0,
3539 'aria-rowcount': 0,
3540 'aria-rowindex': 0,
3541 'aria-rowspan': 0,
3542 'aria-setsize': 0
3543 };
3544
3545 var warnedProperties = {};
3546 var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
3547 var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
3548
3549 function validateProperty(tagName, name) {
3550 {
3551 if (hasOwnProperty.call(warnedProperties, name) && warnedProperties[name]) {
3552 return true;
3553 }
3554
3555 if (rARIACamel.test(name)) {
3556 var ariaName = 'aria-' + name.slice(4).toLowerCase();
3557 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null; // If this is an aria-* attribute, but is not listed in the known DOM
3558 // DOM properties, then it is an invalid aria-* attribute.
3559
3560 if (correctName == null) {
3561 error('Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name);
3562
3563 warnedProperties[name] = true;
3564 return true;
3565 } // aria-* attributes should be lowercase; suggest the lowercase version.
3566
3567
3568 if (name !== correctName) {
3569 error('Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName);
3570
3571 warnedProperties[name] = true;
3572 return true;
3573 }
3574 }
3575
3576 if (rARIA.test(name)) {
3577 var lowerCasedName = name.toLowerCase();
3578 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null; // If this is an aria-* attribute, but is not listed in the known DOM
3579 // DOM properties, then it is an invalid aria-* attribute.
3580
3581 if (standardName == null) {
3582 warnedProperties[name] = true;
3583 return false;
3584 } // aria-* attributes should be lowercase; suggest the lowercase version.
3585
3586
3587 if (name !== standardName) {
3588 error('Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName);
3589
3590 warnedProperties[name] = true;
3591 return true;
3592 }
3593 }
3594 }
3595
3596 return true;
3597 }
3598
3599 function warnInvalidARIAProps(type, props) {
3600 {
3601 var invalidProps = [];
3602
3603 for (var key in props) {
3604 var isValid = validateProperty(type, key);
3605
3606 if (!isValid) {
3607 invalidProps.push(key);
3608 }
3609 }
3610
3611 var unknownPropString = invalidProps.map(function (prop) {
3612 return '`' + prop + '`';
3613 }).join(', ');
3614
3615 if (invalidProps.length === 1) {
3616 error('Invalid aria prop %s on <%s> tag. ' + 'For details, see https://reactjs.org/link/invalid-aria-props', unknownPropString, type);
3617 } else if (invalidProps.length > 1) {
3618 error('Invalid aria props %s on <%s> tag. ' + 'For details, see https://reactjs.org/link/invalid-aria-props', unknownPropString, type);
3619 }
3620 }
3621 }
3622
3623 function validateProperties(type, props) {
3624 if (isCustomComponent(type, props)) {
3625 return;
3626 }
3627
3628 warnInvalidARIAProps(type, props);
3629 }
3630
3631 var didWarnValueNull = false;
3632 function validateProperties$1(type, props) {
3633 {
3634 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
3635 return;
3636 }
3637
3638 if (props != null && props.value === null && !didWarnValueNull) {
3639 didWarnValueNull = true;
3640
3641 if (type === 'select' && props.multiple) {
3642 error('`value` prop on `%s` should not be null. ' + 'Consider using an empty array when `multiple` is set to `true` ' + 'to clear the component or `undefined` for uncontrolled components.', type);
3643 } else {
3644 error('`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', type);
3645 }
3646 }
3647 }
3648 }
3649
3650 var validateProperty$1 = function () {};
3651
3652 {
3653 var warnedProperties$1 = {};
3654 var EVENT_NAME_REGEX = /^on./;
3655 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
3656 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
3657 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
3658
3659 validateProperty$1 = function (tagName, name, value, eventRegistry) {
3660 if (hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
3661 return true;
3662 }
3663
3664 var lowerCasedName = name.toLowerCase();
3665
3666 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
3667 error('React uses onFocus and onBlur instead of onFocusIn and onFocusOut. ' + 'All React events are normalized to bubble, so onFocusIn and onFocusOut ' + 'are not needed/supported by React.');
3668
3669 warnedProperties$1[name] = true;
3670 return true;
3671 } // We can't rely on the event system being injected on the server.
3672
3673
3674 if (eventRegistry != null) {
3675 var registrationNameDependencies = eventRegistry.registrationNameDependencies,
3676 possibleRegistrationNames = eventRegistry.possibleRegistrationNames;
3677
3678 if (registrationNameDependencies.hasOwnProperty(name)) {
3679 return true;
3680 }
3681
3682 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
3683
3684 if (registrationName != null) {
3685 error('Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName);
3686
3687 warnedProperties$1[name] = true;
3688 return true;
3689 }
3690
3691 if (EVENT_NAME_REGEX.test(name)) {
3692 error('Unknown event handler property `%s`. It will be ignored.', name);
3693
3694 warnedProperties$1[name] = true;
3695 return true;
3696 }
3697 } else if (EVENT_NAME_REGEX.test(name)) {
3698 // If no event plugins have been injected, we are in a server environment.
3699 // So we can't tell if the event name is correct for sure, but we can filter
3700 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
3701 if (INVALID_EVENT_NAME_REGEX.test(name)) {
3702 error('Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name);
3703 }
3704
3705 warnedProperties$1[name] = true;
3706 return true;
3707 } // Let the ARIA attribute hook validate ARIA attributes
3708
3709
3710 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
3711 return true;
3712 }
3713
3714 if (lowerCasedName === 'innerhtml') {
3715 error('Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
3716
3717 warnedProperties$1[name] = true;
3718 return true;
3719 }
3720
3721 if (lowerCasedName === 'aria') {
3722 error('The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
3723
3724 warnedProperties$1[name] = true;
3725 return true;
3726 }
3727
3728 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
3729 error('Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value);
3730
3731 warnedProperties$1[name] = true;
3732 return true;
3733 }
3734
3735 if (typeof value === 'number' && isNaN(value)) {
3736 error('Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name);
3737
3738 warnedProperties$1[name] = true;
3739 return true;
3740 }
3741
3742 var propertyInfo = getPropertyInfo(name);
3743 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED; // Known attributes should match the casing specified in the property config.
3744
3745 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
3746 var standardName = possibleStandardNames[lowerCasedName];
3747
3748 if (standardName !== name) {
3749 error('Invalid DOM property `%s`. Did you mean `%s`?', name, standardName);
3750
3751 warnedProperties$1[name] = true;
3752 return true;
3753 }
3754 } else if (!isReserved && name !== lowerCasedName) {
3755 // Unknown attributes should have lowercase casing since that's how they
3756 // will be cased anyway with server rendering.
3757 error('React does not recognize the `%s` prop on a DOM element. If you ' + 'intentionally want it to appear in the DOM as a custom ' + 'attribute, spell it as lowercase `%s` instead. ' + 'If you accidentally passed it from a parent component, remove ' + 'it from the DOM element.', name, lowerCasedName);
3758
3759 warnedProperties$1[name] = true;
3760 return true;
3761 }
3762
3763 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
3764 if (value) {
3765 error('Received `%s` for a non-boolean attribute `%s`.\n\n' + 'If you want to write it to the DOM, pass a string instead: ' + '%s="%s" or %s={value.toString()}.', value, name, name, value, name);
3766 } else {
3767 error('Received `%s` for a non-boolean attribute `%s`.\n\n' + 'If you want to write it to the DOM, pass a string instead: ' + '%s="%s" or %s={value.toString()}.\n\n' + 'If you used to conditionally omit it with %s={condition && value}, ' + 'pass %s={condition ? value : undefined} instead.', value, name, name, value, name, name, name);
3768 }
3769
3770 warnedProperties$1[name] = true;
3771 return true;
3772 } // Now that we've validated casing, do not validate
3773 // data types for reserved props
3774
3775
3776 if (isReserved) {
3777 return true;
3778 } // Warn when a known attribute is a bad type
3779
3780
3781 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
3782 warnedProperties$1[name] = true;
3783 return false;
3784 } // Warn when passing the strings 'false' or 'true' into a boolean prop
3785
3786
3787 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) {
3788 error('Received the string `%s` for the boolean attribute `%s`. ' + '%s ' + 'Did you mean %s={%s}?', value, name, value === 'false' ? 'The browser will interpret it as a truthy value.' : 'Although this works, it will not work as expected if you pass the string "false".', name, value);
3789
3790 warnedProperties$1[name] = true;
3791 return true;
3792 }
3793
3794 return true;
3795 };
3796 }
3797
3798 var warnUnknownProperties = function (type, props, eventRegistry) {
3799 {
3800 var unknownProps = [];
3801
3802 for (var key in props) {
3803 var isValid = validateProperty$1(type, key, props[key], eventRegistry);
3804
3805 if (!isValid) {
3806 unknownProps.push(key);
3807 }
3808 }
3809
3810 var unknownPropString = unknownProps.map(function (prop) {
3811 return '`' + prop + '`';
3812 }).join(', ');
3813
3814 if (unknownProps.length === 1) {
3815 error('Invalid value for prop %s on <%s> tag. Either remove it from the element, ' + 'or pass a string or number value to keep it in the DOM. ' + 'For details, see https://reactjs.org/link/attribute-behavior ', unknownPropString, type);
3816 } else if (unknownProps.length > 1) {
3817 error('Invalid values for props %s on <%s> tag. Either remove them from the element, ' + 'or pass a string or number value to keep them in the DOM. ' + 'For details, see https://reactjs.org/link/attribute-behavior ', unknownPropString, type);
3818 }
3819 }
3820 };
3821
3822 function validateProperties$2(type, props, eventRegistry) {
3823 if (isCustomComponent(type, props)) {
3824 return;
3825 }
3826
3827 warnUnknownProperties(type, props, eventRegistry);
3828 }
3829
3830 var IS_EVENT_HANDLE_NON_MANAGED_NODE = 1;
3831 var IS_NON_DELEGATED = 1 << 1;
3832 var IS_CAPTURE_PHASE = 1 << 2;
3833 // set to LEGACY_FB_SUPPORT. LEGACY_FB_SUPPORT only gets set when
3834 // we call willDeferLaterForLegacyFBSupport, thus not bailing out
3835 // will result in endless cycles like an infinite loop.
3836 // We also don't want to defer during event replaying.
3837
3838 var SHOULD_NOT_PROCESS_POLYFILL_EVENT_PLUGINS = IS_EVENT_HANDLE_NON_MANAGED_NODE | IS_NON_DELEGATED | IS_CAPTURE_PHASE;
3839
3840 // This exists to avoid circular dependency between ReactDOMEventReplaying
3841 // and DOMPluginEventSystem.
3842 var currentReplayingEvent = null;
3843 function setReplayingEvent(event) {
3844 {
3845 if (currentReplayingEvent !== null) {
3846 error('Expected currently replaying event to be null. This error ' + 'is likely caused by a bug in React. Please file an issue.');
3847 }
3848 }
3849
3850 currentReplayingEvent = event;
3851 }
3852 function resetReplayingEvent() {
3853 {
3854 if (currentReplayingEvent === null) {
3855 error('Expected currently replaying event to not be null. This error ' + 'is likely caused by a bug in React. Please file an issue.');
3856 }
3857 }
3858
3859 currentReplayingEvent = null;
3860 }
3861 function isReplayingEvent(event) {
3862 return event === currentReplayingEvent;
3863 }
3864
3865 /**
3866 * Gets the target node from a native browser event by accounting for
3867 * inconsistencies in browser DOM APIs.
3868 *
3869 * @param {object} nativeEvent Native browser event.
3870 * @return {DOMEventTarget} Target node.
3871 */
3872
3873 function getEventTarget(nativeEvent) {
3874 // Fallback to nativeEvent.srcElement for IE9
3875 // https://github.com/facebook/react/issues/12506
3876 var target = nativeEvent.target || nativeEvent.srcElement || window; // Normalize SVG <use> element events #4963
3877
3878 if (target.correspondingUseElement) {
3879 target = target.correspondingUseElement;
3880 } // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
3881 // @see http://www.quirksmode.org/js/events_properties.html
3882
3883
3884 return target.nodeType === TEXT_NODE ? target.parentNode : target;
3885 }
3886
3887 var restoreImpl = null;
3888 var restoreTarget = null;
3889 var restoreQueue = null;
3890
3891 function restoreStateOfTarget(target) {
3892 // We perform this translation at the end of the event loop so that we
3893 // always receive the correct fiber here
3894 var internalInstance = getInstanceFromNode(target);
3895
3896 if (!internalInstance) {
3897 // Unmounted
3898 return;
3899 }
3900
3901 if (typeof restoreImpl !== 'function') {
3902 throw new Error('setRestoreImplementation() needs to be called to handle a target for controlled ' + 'events. This error is likely caused by a bug in React. Please file an issue.');
3903 }
3904
3905 var stateNode = internalInstance.stateNode; // Guard against Fiber being unmounted.
3906
3907 if (stateNode) {
3908 var _props = getFiberCurrentPropsFromNode(stateNode);
3909
3910 restoreImpl(internalInstance.stateNode, internalInstance.type, _props);
3911 }
3912 }
3913
3914 function setRestoreImplementation(impl) {
3915 restoreImpl = impl;
3916 }
3917 function enqueueStateRestore(target) {
3918 if (restoreTarget) {
3919 if (restoreQueue) {
3920 restoreQueue.push(target);
3921 } else {
3922 restoreQueue = [target];
3923 }
3924 } else {
3925 restoreTarget = target;
3926 }
3927 }
3928 function needsStateRestore() {
3929 return restoreTarget !== null || restoreQueue !== null;
3930 }
3931 function restoreStateIfNeeded() {
3932 if (!restoreTarget) {
3933 return;
3934 }
3935
3936 var target = restoreTarget;
3937 var queuedTargets = restoreQueue;
3938 restoreTarget = null;
3939 restoreQueue = null;
3940 restoreStateOfTarget(target);
3941
3942 if (queuedTargets) {
3943 for (var i = 0; i < queuedTargets.length; i++) {
3944 restoreStateOfTarget(queuedTargets[i]);
3945 }
3946 }
3947 }
3948
3949 // the renderer. Such as when we're dispatching events or if third party
3950 // libraries need to call batchedUpdates. Eventually, this API will go away when
3951 // everything is batched by default. We'll then have a similar API to opt-out of
3952 // scheduled work and instead do synchronous work.
3953 // Defaults
3954
3955 var batchedUpdatesImpl = function (fn, bookkeeping) {
3956 return fn(bookkeeping);
3957 };
3958
3959 var flushSyncImpl = function () {};
3960
3961 var isInsideEventHandler = false;
3962
3963 function finishEventHandler() {
3964 // Here we wait until all updates have propagated, which is important
3965 // when using controlled components within layers:
3966 // https://github.com/facebook/react/issues/1698
3967 // Then we restore state of any controlled component.
3968 var controlledComponentsHavePendingUpdates = needsStateRestore();
3969
3970 if (controlledComponentsHavePendingUpdates) {
3971 // If a controlled event was fired, we may need to restore the state of
3972 // the DOM node back to the controlled value. This is necessary when React
3973 // bails out of the update without touching the DOM.
3974 // TODO: Restore state in the microtask, after the discrete updates flush,
3975 // instead of early flushing them here.
3976 flushSyncImpl();
3977 restoreStateIfNeeded();
3978 }
3979 }
3980
3981 function batchedUpdates(fn, a, b) {
3982 if (isInsideEventHandler) {
3983 // If we are currently inside another batch, we need to wait until it
3984 // fully completes before restoring state.
3985 return fn(a, b);
3986 }
3987
3988 isInsideEventHandler = true;
3989
3990 try {
3991 return batchedUpdatesImpl(fn, a, b);
3992 } finally {
3993 isInsideEventHandler = false;
3994 finishEventHandler();
3995 }
3996 } // TODO: Replace with flushSync
3997 function setBatchingImplementation(_batchedUpdatesImpl, _discreteUpdatesImpl, _flushSyncImpl) {
3998 batchedUpdatesImpl = _batchedUpdatesImpl;
3999 flushSyncImpl = _flushSyncImpl;
4000 }
4001
4002 function isInteractive(tag) {
4003 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
4004 }
4005
4006 function shouldPreventMouseEvent(name, type, props) {
4007 switch (name) {
4008 case 'onClick':
4009 case 'onClickCapture':
4010 case 'onDoubleClick':
4011 case 'onDoubleClickCapture':
4012 case 'onMouseDown':
4013 case 'onMouseDownCapture':
4014 case 'onMouseMove':
4015 case 'onMouseMoveCapture':
4016 case 'onMouseUp':
4017 case 'onMouseUpCapture':
4018 case 'onMouseEnter':
4019 return !!(props.disabled && isInteractive(type));
4020
4021 default:
4022 return false;
4023 }
4024 }
4025 /**
4026 * @param {object} inst The instance, which is the source of events.
4027 * @param {string} registrationName Name of listener (e.g. `onClick`).
4028 * @return {?function} The stored callback.
4029 */
4030
4031
4032 function getListener(inst, registrationName) {
4033 var stateNode = inst.stateNode;
4034
4035 if (stateNode === null) {
4036 // Work in progress (ex: onload events in incremental mode).
4037 return null;
4038 }
4039
4040 var props = getFiberCurrentPropsFromNode(stateNode);
4041
4042 if (props === null) {
4043 // Work in progress.
4044 return null;
4045 }
4046
4047 var listener = props[registrationName];
4048
4049 if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
4050 return null;
4051 }
4052
4053 if (listener && typeof listener !== 'function') {
4054 throw new Error("Expected `" + registrationName + "` listener to be a function, instead got a value of `" + typeof listener + "` type.");
4055 }
4056
4057 return listener;
4058 }
4059
4060 var passiveBrowserEventsSupported = false; // Check if browser support events with passive listeners
4061 // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support
4062
4063 if (canUseDOM) {
4064 try {
4065 var options = {}; // $FlowFixMe: Ignore Flow complaining about needing a value
4066
4067 Object.defineProperty(options, 'passive', {
4068 get: function () {
4069 passiveBrowserEventsSupported = true;
4070 }
4071 });
4072 window.addEventListener('test', options, options);
4073 window.removeEventListener('test', options, options);
4074 } catch (e) {
4075 passiveBrowserEventsSupported = false;
4076 }
4077 }
4078
4079 function invokeGuardedCallbackProd(name, func, context, a, b, c, d, e, f) {
4080 var funcArgs = Array.prototype.slice.call(arguments, 3);
4081
4082 try {
4083 func.apply(context, funcArgs);
4084 } catch (error) {
4085 this.onError(error);
4086 }
4087 }
4088
4089 var invokeGuardedCallbackImpl = invokeGuardedCallbackProd;
4090
4091 {
4092 // In DEV mode, we swap out invokeGuardedCallback for a special version
4093 // that plays more nicely with the browser's DevTools. The idea is to preserve
4094 // "Pause on exceptions" behavior. Because React wraps all user-provided
4095 // functions in invokeGuardedCallback, and the production version of
4096 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
4097 // like caught exceptions, and the DevTools won't pause unless the developer
4098 // takes the extra step of enabling pause on caught exceptions. This is
4099 // unintuitive, though, because even though React has caught the error, from
4100 // the developer's perspective, the error is uncaught.
4101 //
4102 // To preserve the expected "Pause on exceptions" behavior, we don't use a
4103 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
4104 // DOM node, and call the user-provided callback from inside an event handler
4105 // for that fake event. If the callback throws, the error is "captured" using
4106 // a global event handler. But because the error happens in a different
4107 // event loop context, it does not interrupt the normal program flow.
4108 // Effectively, this gives us try-catch behavior without actually using
4109 // try-catch. Neat!
4110 // Check that the browser supports the APIs we need to implement our special
4111 // DEV version of invokeGuardedCallback
4112 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
4113 var fakeNode = document.createElement('react');
4114
4115 invokeGuardedCallbackImpl = function invokeGuardedCallbackDev(name, func, context, a, b, c, d, e, f) {
4116 // If document doesn't exist we know for sure we will crash in this method
4117 // when we call document.createEvent(). However this can cause confusing
4118 // errors: https://github.com/facebook/create-react-app/issues/3482
4119 // So we preemptively throw with a better message instead.
4120 if (typeof document === 'undefined' || document === null) {
4121 throw new Error('The `document` global was defined when React was initialized, but is not ' + 'defined anymore. This can happen in a test environment if a component ' + 'schedules an update from an asynchronous callback, but the test has already ' + 'finished running. To solve this, you can either unmount the component at ' + 'the end of your test (and ensure that any asynchronous operations get ' + 'canceled in `componentWillUnmount`), or you can change the test itself ' + 'to be asynchronous.');
4122 }
4123
4124 var evt = document.createEvent('Event');
4125 var didCall = false; // Keeps track of whether the user-provided callback threw an error. We
4126 // set this to true at the beginning, then set it to false right after
4127 // calling the function. If the function errors, `didError` will never be
4128 // set to false. This strategy works even if the browser is flaky and
4129 // fails to call our global error handler, because it doesn't rely on
4130 // the error event at all.
4131
4132 var didError = true; // Keeps track of the value of window.event so that we can reset it
4133 // during the callback to let user code access window.event in the
4134 // browsers that support it.
4135
4136 var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event
4137 // dispatching: https://github.com/facebook/react/issues/13688
4138
4139 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
4140
4141 function restoreAfterDispatch() {
4142 // We immediately remove the callback from event listeners so that
4143 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
4144 // nested call would trigger the fake event handlers of any call higher
4145 // in the stack.
4146 fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the
4147 // window.event assignment in both IE <= 10 as they throw an error
4148 // "Member not found" in strict mode, and in Firefox which does not
4149 // support window.event.
4150
4151 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
4152 window.event = windowEvent;
4153 }
4154 } // Create an event handler for our fake event. We will synchronously
4155 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
4156 // call the user-provided callback.
4157
4158
4159 var funcArgs = Array.prototype.slice.call(arguments, 3);
4160
4161 function callCallback() {
4162 didCall = true;
4163 restoreAfterDispatch();
4164 func.apply(context, funcArgs);
4165 didError = false;
4166 } // Create a global error event handler. We use this to capture the value
4167 // that was thrown. It's possible that this error handler will fire more
4168 // than once; for example, if non-React code also calls `dispatchEvent`
4169 // and a handler for that event throws. We should be resilient to most of
4170 // those cases. Even if our error event handler fires more than once, the
4171 // last error event is always used. If the callback actually does error,
4172 // we know that the last error event is the correct one, because it's not
4173 // possible for anything else to have happened in between our callback
4174 // erroring and the code that follows the `dispatchEvent` call below. If
4175 // the callback doesn't error, but the error event was fired, we know to
4176 // ignore it because `didError` will be false, as described above.
4177
4178
4179 var error; // Use this to track whether the error event is ever called.
4180
4181 var didSetError = false;
4182 var isCrossOriginError = false;
4183
4184 function handleWindowError(event) {
4185 error = event.error;
4186 didSetError = true;
4187
4188 if (error === null && event.colno === 0 && event.lineno === 0) {
4189 isCrossOriginError = true;
4190 }
4191
4192 if (event.defaultPrevented) {
4193 // Some other error handler has prevented default.
4194 // Browsers silence the error report if this happens.
4195 // We'll remember this to later decide whether to log it or not.
4196 if (error != null && typeof error === 'object') {
4197 try {
4198 error._suppressLogging = true;
4199 } catch (inner) {// Ignore.
4200 }
4201 }
4202 }
4203 } // Create a fake event type.
4204
4205
4206 var evtType = "react-" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers
4207
4208 window.addEventListener('error', handleWindowError);
4209 fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function
4210 // errors, it will trigger our global error handler.
4211
4212 evt.initEvent(evtType, false, false);
4213 fakeNode.dispatchEvent(evt);
4214
4215 if (windowEventDescriptor) {
4216 Object.defineProperty(window, 'event', windowEventDescriptor);
4217 }
4218
4219 if (didCall && didError) {
4220 if (!didSetError) {
4221 // The callback errored, but the error event never fired.
4222 // eslint-disable-next-line react-internal/prod-error-codes
4223 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.');
4224 } else if (isCrossOriginError) {
4225 // eslint-disable-next-line react-internal/prod-error-codes
4226 error = new Error("A cross-origin error was thrown. React doesn't have access to " + 'the actual error object in development. ' + 'See https://reactjs.org/link/crossorigin-error for more information.');
4227 }
4228
4229 this.onError(error);
4230 } // Remove our event listeners
4231
4232
4233 window.removeEventListener('error', handleWindowError);
4234
4235 if (!didCall) {
4236 // Something went really wrong, and our event was not dispatched.
4237 // https://github.com/facebook/react/issues/16734
4238 // https://github.com/facebook/react/issues/16585
4239 // Fall back to the production implementation.
4240 restoreAfterDispatch();
4241 return invokeGuardedCallbackProd.apply(this, arguments);
4242 }
4243 };
4244 }
4245 }
4246
4247 var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
4248
4249 var hasError = false;
4250 var caughtError = null; // Used by event system to capture/rethrow the first error.
4251
4252 var hasRethrowError = false;
4253 var rethrowError = null;
4254 var reporter = {
4255 onError: function (error) {
4256 hasError = true;
4257 caughtError = error;
4258 }
4259 };
4260 /**
4261 * Call a function while guarding against errors that happens within it.
4262 * Returns an error if it throws, otherwise null.
4263 *
4264 * In production, this is implemented using a try-catch. The reason we don't
4265 * use a try-catch directly is so that we can swap out a different
4266 * implementation in DEV mode.
4267 *
4268 * @param {String} name of the guard to use for logging or debugging
4269 * @param {Function} func The function to invoke
4270 * @param {*} context The context to use when calling the function
4271 * @param {...*} args Arguments for function
4272 */
4273
4274 function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
4275 hasError = false;
4276 caughtError = null;
4277 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
4278 }
4279 /**
4280 * Same as invokeGuardedCallback, but instead of returning an error, it stores
4281 * it in a global so it can be rethrown by `rethrowCaughtError` later.
4282 * TODO: See if caughtError and rethrowError can be unified.
4283 *
4284 * @param {String} name of the guard to use for logging or debugging
4285 * @param {Function} func The function to invoke
4286 * @param {*} context The context to use when calling the function
4287 * @param {...*} args Arguments for function
4288 */
4289
4290 function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) {
4291 invokeGuardedCallback.apply(this, arguments);
4292
4293 if (hasError) {
4294 var error = clearCaughtError();
4295
4296 if (!hasRethrowError) {
4297 hasRethrowError = true;
4298 rethrowError = error;
4299 }
4300 }
4301 }
4302 /**
4303 * During execution of guarded functions we will capture the first error which
4304 * we will rethrow to be handled by the top level error handler.
4305 */
4306
4307 function rethrowCaughtError() {
4308 if (hasRethrowError) {
4309 var error = rethrowError;
4310 hasRethrowError = false;
4311 rethrowError = null;
4312 throw error;
4313 }
4314 }
4315 function hasCaughtError() {
4316 return hasError;
4317 }
4318 function clearCaughtError() {
4319 if (hasError) {
4320 var error = caughtError;
4321 hasError = false;
4322 caughtError = null;
4323 return error;
4324 } else {
4325 throw new Error('clearCaughtError was called but no error was captured. This error ' + 'is likely caused by a bug in React. Please file an issue.');
4326 }
4327 }
4328
4329 /**
4330 * `ReactInstanceMap` maintains a mapping from a public facing stateful
4331 * instance (key) and the internal representation (value). This allows public
4332 * methods to accept the user facing instance as an argument and map them back
4333 * to internal methods.
4334 *
4335 * Note that this module is currently shared and assumed to be stateless.
4336 * If this becomes an actual Map, that will break.
4337 */
4338 function get(key) {
4339 return key._reactInternals;
4340 }
4341 function has(key) {
4342 return key._reactInternals !== undefined;
4343 }
4344 function set(key, value) {
4345 key._reactInternals = value;
4346 }
4347
4348 // Don't change these two values. They're used by React Dev Tools.
4349 var NoFlags =
4350 /* */
4351 0;
4352 var PerformedWork =
4353 /* */
4354 1; // You can change the rest (and add more).
4355
4356 var Placement =
4357 /* */
4358 2;
4359 var Update =
4360 /* */
4361 4;
4362 var ChildDeletion =
4363 /* */
4364 16;
4365 var ContentReset =
4366 /* */
4367 32;
4368 var Callback =
4369 /* */
4370 64;
4371 var DidCapture =
4372 /* */
4373 128;
4374 var ForceClientRender =
4375 /* */
4376 256;
4377 var Ref =
4378 /* */
4379 512;
4380 var Snapshot =
4381 /* */
4382 1024;
4383 var Passive =
4384 /* */
4385 2048;
4386 var Hydrating =
4387 /* */
4388 4096;
4389 var Visibility =
4390 /* */
4391 8192;
4392 var StoreConsistency =
4393 /* */
4394 16384;
4395 var LifecycleEffectMask = Passive | Update | Callback | Ref | Snapshot | StoreConsistency; // Union of all commit flags (flags with the lifetime of a particular commit)
4396
4397 var HostEffectMask =
4398 /* */
4399 32767; // These are not really side effects, but we still reuse this field.
4400
4401 var Incomplete =
4402 /* */
4403 32768;
4404 var ShouldCapture =
4405 /* */
4406 65536;
4407 var ForceUpdateForLegacySuspense =
4408 /* */
4409 131072;
4410 var Forked =
4411 /* */
4412 1048576; // Static tags describe aspects of a fiber that are not specific to a render,
4413 // e.g. a fiber uses a passive effect (even if there are no updates on this particular render).
4414 // This enables us to defer more work in the unmount case,
4415 // since we can defer traversing the tree during layout to look for Passive effects,
4416 // and instead rely on the static flag as a signal that there may be cleanup work.
4417
4418 var RefStatic =
4419 /* */
4420 2097152;
4421 var LayoutStatic =
4422 /* */
4423 4194304;
4424 var PassiveStatic =
4425 /* */
4426 8388608; // These flags allow us to traverse to fibers that have effects on mount
4427 // without traversing the entire tree after every commit for
4428 // double invoking
4429
4430 var MountLayoutDev =
4431 /* */
4432 16777216;
4433 var MountPassiveDev =
4434 /* */
4435 33554432; // Groups of flags that are used in the commit phase to skip over trees that
4436 // don't contain effects, by checking subtreeFlags.
4437
4438 var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visibility
4439 // flag logic (see #20043)
4440 Update | Snapshot | ( 0);
4441 var MutationMask = Placement | Update | ChildDeletion | ContentReset | Ref | Hydrating | Visibility;
4442 var LayoutMask = Update | Callback | Ref | Visibility; // TODO: Split into PassiveMountMask and PassiveUnmountMask
4443
4444 var PassiveMask = Passive | ChildDeletion; // Union of tags that don't get reset on clones.
4445 // This allows certain concepts to persist without recalculating them,
4446 // e.g. whether a subtree contains passive effects or portals.
4447
4448 var StaticMask = LayoutStatic | PassiveStatic | RefStatic;
4449
4450 var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
4451 function getNearestMountedFiber(fiber) {
4452 var node = fiber;
4453 var nearestMounted = fiber;
4454
4455 if (!fiber.alternate) {
4456 // If there is no alternate, this might be a new tree that isn't inserted
4457 // yet. If it is, then it will have a pending insertion effect on it.
4458 var nextNode = node;
4459
4460 do {
4461 node = nextNode;
4462
4463 if ((node.flags & (Placement | Hydrating)) !== NoFlags) {
4464 // This is an insertion or in-progress hydration. The nearest possible
4465 // mounted fiber is the parent but we need to continue to figure out
4466 // if that one is still mounted.
4467 nearestMounted = node.return;
4468 }
4469
4470 nextNode = node.return;
4471 } while (nextNode);
4472 } else {
4473 while (node.return) {
4474 node = node.return;
4475 }
4476 }
4477
4478 if (node.tag === HostRoot) {
4479 // TODO: Check if this was a nested HostRoot when used with
4480 // renderContainerIntoSubtree.
4481 return nearestMounted;
4482 } // If we didn't hit the root, that means that we're in an disconnected tree
4483 // that has been unmounted.
4484
4485
4486 return null;
4487 }
4488 function getSuspenseInstanceFromFiber(fiber) {
4489 if (fiber.tag === SuspenseComponent) {
4490 var suspenseState = fiber.memoizedState;
4491
4492 if (suspenseState === null) {
4493 var current = fiber.alternate;
4494
4495 if (current !== null) {
4496 suspenseState = current.memoizedState;
4497 }
4498 }
4499
4500 if (suspenseState !== null) {
4501 return suspenseState.dehydrated;
4502 }
4503 }
4504
4505 return null;
4506 }
4507 function getContainerFromFiber(fiber) {
4508 return fiber.tag === HostRoot ? fiber.stateNode.containerInfo : null;
4509 }
4510 function isFiberMounted(fiber) {
4511 return getNearestMountedFiber(fiber) === fiber;
4512 }
4513 function isMounted(component) {
4514 {
4515 var owner = ReactCurrentOwner.current;
4516
4517 if (owner !== null && owner.tag === ClassComponent) {
4518 var ownerFiber = owner;
4519 var instance = ownerFiber.stateNode;
4520
4521 if (!instance._warnedAboutRefsInRender) {
4522 error('%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentNameFromFiber(ownerFiber) || 'A component');
4523 }
4524
4525 instance._warnedAboutRefsInRender = true;
4526 }
4527 }
4528
4529 var fiber = get(component);
4530
4531 if (!fiber) {
4532 return false;
4533 }
4534
4535 return getNearestMountedFiber(fiber) === fiber;
4536 }
4537
4538 function assertIsMounted(fiber) {
4539 if (getNearestMountedFiber(fiber) !== fiber) {
4540 throw new Error('Unable to find node on an unmounted component.');
4541 }
4542 }
4543
4544 function findCurrentFiberUsingSlowPath(fiber) {
4545 var alternate = fiber.alternate;
4546
4547 if (!alternate) {
4548 // If there is no alternate, then we only need to check if it is mounted.
4549 var nearestMounted = getNearestMountedFiber(fiber);
4550
4551 if (nearestMounted === null) {
4552 throw new Error('Unable to find node on an unmounted component.');
4553 }
4554
4555 if (nearestMounted !== fiber) {
4556 return null;
4557 }
4558
4559 return fiber;
4560 } // If we have two possible branches, we'll walk backwards up to the root
4561 // to see what path the root points to. On the way we may hit one of the
4562 // special cases and we'll deal with them.
4563
4564
4565 var a = fiber;
4566 var b = alternate;
4567
4568 while (true) {
4569 var parentA = a.return;
4570
4571 if (parentA === null) {
4572 // We're at the root.
4573 break;
4574 }
4575
4576 var parentB = parentA.alternate;
4577
4578 if (parentB === null) {
4579 // There is no alternate. This is an unusual case. Currently, it only
4580 // happens when a Suspense component is hidden. An extra fragment fiber
4581 // is inserted in between the Suspense fiber and its children. Skip
4582 // over this extra fragment fiber and proceed to the next parent.
4583 var nextParent = parentA.return;
4584
4585 if (nextParent !== null) {
4586 a = b = nextParent;
4587 continue;
4588 } // If there's no parent, we're at the root.
4589
4590
4591 break;
4592 } // If both copies of the parent fiber point to the same child, we can
4593 // assume that the child is current. This happens when we bailout on low
4594 // priority: the bailed out fiber's child reuses the current child.
4595
4596
4597 if (parentA.child === parentB.child) {
4598 var child = parentA.child;
4599
4600 while (child) {
4601 if (child === a) {
4602 // We've determined that A is the current branch.
4603 assertIsMounted(parentA);
4604 return fiber;
4605 }
4606
4607 if (child === b) {
4608 // We've determined that B is the current branch.
4609 assertIsMounted(parentA);
4610 return alternate;
4611 }
4612
4613 child = child.sibling;
4614 } // We should never have an alternate for any mounting node. So the only
4615 // way this could possibly happen is if this was unmounted, if at all.
4616
4617
4618 throw new Error('Unable to find node on an unmounted component.');
4619 }
4620
4621 if (a.return !== b.return) {
4622 // The return pointer of A and the return pointer of B point to different
4623 // fibers. We assume that return pointers never criss-cross, so A must
4624 // belong to the child set of A.return, and B must belong to the child
4625 // set of B.return.
4626 a = parentA;
4627 b = parentB;
4628 } else {
4629 // The return pointers point to the same fiber. We'll have to use the
4630 // default, slow path: scan the child sets of each parent alternate to see
4631 // which child belongs to which set.
4632 //
4633 // Search parent A's child set
4634 var didFindChild = false;
4635 var _child = parentA.child;
4636
4637 while (_child) {
4638 if (_child === a) {
4639 didFindChild = true;
4640 a = parentA;
4641 b = parentB;
4642 break;
4643 }
4644
4645 if (_child === b) {
4646 didFindChild = true;
4647 b = parentA;
4648 a = parentB;
4649 break;
4650 }
4651
4652 _child = _child.sibling;
4653 }
4654
4655 if (!didFindChild) {
4656 // Search parent B's child set
4657 _child = parentB.child;
4658
4659 while (_child) {
4660 if (_child === a) {
4661 didFindChild = true;
4662 a = parentB;
4663 b = parentA;
4664 break;
4665 }
4666
4667 if (_child === b) {
4668 didFindChild = true;
4669 b = parentB;
4670 a = parentA;
4671 break;
4672 }
4673
4674 _child = _child.sibling;
4675 }
4676
4677 if (!didFindChild) {
4678 throw new Error('Child was not found in either parent set. This indicates a bug ' + 'in React related to the return pointer. Please file an issue.');
4679 }
4680 }
4681 }
4682
4683 if (a.alternate !== b) {
4684 throw new Error("Return fibers should always be each others' alternates. " + 'This error is likely caused by a bug in React. Please file an issue.');
4685 }
4686 } // If the root is not a host container, we're in a disconnected tree. I.e.
4687 // unmounted.
4688
4689
4690 if (a.tag !== HostRoot) {
4691 throw new Error('Unable to find node on an unmounted component.');
4692 }
4693
4694 if (a.stateNode.current === a) {
4695 // We've determined that A is the current branch.
4696 return fiber;
4697 } // Otherwise B has to be current branch.
4698
4699
4700 return alternate;
4701 }
4702 function findCurrentHostFiber(parent) {
4703 var currentParent = findCurrentFiberUsingSlowPath(parent);
4704 return currentParent !== null ? findCurrentHostFiberImpl(currentParent) : null;
4705 }
4706
4707 function findCurrentHostFiberImpl(node) {
4708 // Next we'll drill down this component to find the first HostComponent/Text.
4709 if (node.tag === HostComponent || node.tag === HostText) {
4710 return node;
4711 }
4712
4713 var child = node.child;
4714
4715 while (child !== null) {
4716 var match = findCurrentHostFiberImpl(child);
4717
4718 if (match !== null) {
4719 return match;
4720 }
4721
4722 child = child.sibling;
4723 }
4724
4725 return null;
4726 }
4727
4728 function findCurrentHostFiberWithNoPortals(parent) {
4729 var currentParent = findCurrentFiberUsingSlowPath(parent);
4730 return currentParent !== null ? findCurrentHostFiberWithNoPortalsImpl(currentParent) : null;
4731 }
4732
4733 function findCurrentHostFiberWithNoPortalsImpl(node) {
4734 // Next we'll drill down this component to find the first HostComponent/Text.
4735 if (node.tag === HostComponent || node.tag === HostText) {
4736 return node;
4737 }
4738
4739 var child = node.child;
4740
4741 while (child !== null) {
4742 if (child.tag !== HostPortal) {
4743 var match = findCurrentHostFiberWithNoPortalsImpl(child);
4744
4745 if (match !== null) {
4746 return match;
4747 }
4748 }
4749
4750 child = child.sibling;
4751 }
4752
4753 return null;
4754 }
4755
4756 // This module only exists as an ESM wrapper around the external CommonJS
4757 var scheduleCallback = Scheduler.unstable_scheduleCallback;
4758 var cancelCallback = Scheduler.unstable_cancelCallback;
4759 var shouldYield = Scheduler.unstable_shouldYield;
4760 var requestPaint = Scheduler.unstable_requestPaint;
4761 var now = Scheduler.unstable_now;
4762 var getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel;
4763 var ImmediatePriority = Scheduler.unstable_ImmediatePriority;
4764 var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority;
4765 var NormalPriority = Scheduler.unstable_NormalPriority;
4766 var LowPriority = Scheduler.unstable_LowPriority;
4767 var IdlePriority = Scheduler.unstable_IdlePriority;
4768 // this doesn't actually exist on the scheduler, but it *does*
4769 // on scheduler/unstable_mock, which we'll need for internal testing
4770 var unstable_yieldValue = Scheduler.unstable_yieldValue;
4771 var unstable_setDisableYieldValue = Scheduler.unstable_setDisableYieldValue;
4772
4773 var rendererID = null;
4774 var injectedHook = null;
4775 var injectedProfilingHooks = null;
4776 var hasLoggedError = false;
4777 var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
4778 function injectInternals(internals) {
4779 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
4780 // No DevTools
4781 return false;
4782 }
4783
4784 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
4785
4786 if (hook.isDisabled) {
4787 // This isn't a real property on the hook, but it can be set to opt out
4788 // of DevTools integration and associated warnings and logs.
4789 // https://github.com/facebook/react/issues/3877
4790 return true;
4791 }
4792
4793 if (!hook.supportsFiber) {
4794 {
4795 error('The installed version of React DevTools is too old and will not work ' + 'with the current version of React. Please update React DevTools. ' + 'https://reactjs.org/link/react-devtools');
4796 } // DevTools exists, even though it doesn't support Fiber.
4797
4798
4799 return true;
4800 }
4801
4802 try {
4803 if (enableSchedulingProfiler) {
4804 // Conditionally inject these hooks only if Timeline profiler is supported by this build.
4805 // This gives DevTools a way to feature detect that isn't tied to version number
4806 // (since profiling and timeline are controlled by different feature flags).
4807 internals = assign({}, internals, {
4808 getLaneLabelMap: getLaneLabelMap,
4809 injectProfilingHooks: injectProfilingHooks
4810 });
4811 }
4812
4813 rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.
4814
4815 injectedHook = hook;
4816 } catch (err) {
4817 // Catch all errors because it is unsafe to throw during initialization.
4818 {
4819 error('React instrumentation encountered an error: %s.', err);
4820 }
4821 }
4822
4823 if (hook.checkDCE) {
4824 // This is the real DevTools.
4825 return true;
4826 } else {
4827 // This is likely a hook installed by Fast Refresh runtime.
4828 return false;
4829 }
4830 }
4831 function onScheduleRoot(root, children) {
4832 {
4833 if (injectedHook && typeof injectedHook.onScheduleFiberRoot === 'function') {
4834 try {
4835 injectedHook.onScheduleFiberRoot(rendererID, root, children);
4836 } catch (err) {
4837 if ( !hasLoggedError) {
4838 hasLoggedError = true;
4839
4840 error('React instrumentation encountered an error: %s', err);
4841 }
4842 }
4843 }
4844 }
4845 }
4846 function onCommitRoot(root, eventPriority) {
4847 if (injectedHook && typeof injectedHook.onCommitFiberRoot === 'function') {
4848 try {
4849 var didError = (root.current.flags & DidCapture) === DidCapture;
4850
4851 if (enableProfilerTimer) {
4852 var schedulerPriority;
4853
4854 switch (eventPriority) {
4855 case DiscreteEventPriority:
4856 schedulerPriority = ImmediatePriority;
4857 break;
4858
4859 case ContinuousEventPriority:
4860 schedulerPriority = UserBlockingPriority;
4861 break;
4862
4863 case DefaultEventPriority:
4864 schedulerPriority = NormalPriority;
4865 break;
4866
4867 case IdleEventPriority:
4868 schedulerPriority = IdlePriority;
4869 break;
4870
4871 default:
4872 schedulerPriority = NormalPriority;
4873 break;
4874 }
4875
4876 injectedHook.onCommitFiberRoot(rendererID, root, schedulerPriority, didError);
4877 } else {
4878 injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError);
4879 }
4880 } catch (err) {
4881 {
4882 if (!hasLoggedError) {
4883 hasLoggedError = true;
4884
4885 error('React instrumentation encountered an error: %s', err);
4886 }
4887 }
4888 }
4889 }
4890 }
4891 function onPostCommitRoot(root) {
4892 if (injectedHook && typeof injectedHook.onPostCommitFiberRoot === 'function') {
4893 try {
4894 injectedHook.onPostCommitFiberRoot(rendererID, root);
4895 } catch (err) {
4896 {
4897 if (!hasLoggedError) {
4898 hasLoggedError = true;
4899
4900 error('React instrumentation encountered an error: %s', err);
4901 }
4902 }
4903 }
4904 }
4905 }
4906 function onCommitUnmount(fiber) {
4907 if (injectedHook && typeof injectedHook.onCommitFiberUnmount === 'function') {
4908 try {
4909 injectedHook.onCommitFiberUnmount(rendererID, fiber);
4910 } catch (err) {
4911 {
4912 if (!hasLoggedError) {
4913 hasLoggedError = true;
4914
4915 error('React instrumentation encountered an error: %s', err);
4916 }
4917 }
4918 }
4919 }
4920 }
4921 function setIsStrictModeForDevtools(newIsStrictMode) {
4922 {
4923 if (typeof unstable_yieldValue === 'function') {
4924 // We're in a test because Scheduler.unstable_yieldValue only exists
4925 // in SchedulerMock. To reduce the noise in strict mode tests,
4926 // suppress warnings and disable scheduler yielding during the double render
4927 unstable_setDisableYieldValue(newIsStrictMode);
4928 setSuppressWarning(newIsStrictMode);
4929 }
4930
4931 if (injectedHook && typeof injectedHook.setStrictMode === 'function') {
4932 try {
4933 injectedHook.setStrictMode(rendererID, newIsStrictMode);
4934 } catch (err) {
4935 {
4936 if (!hasLoggedError) {
4937 hasLoggedError = true;
4938
4939 error('React instrumentation encountered an error: %s', err);
4940 }
4941 }
4942 }
4943 }
4944 }
4945 } // Profiler API hooks
4946
4947 function injectProfilingHooks(profilingHooks) {
4948 injectedProfilingHooks = profilingHooks;
4949 }
4950
4951 function getLaneLabelMap() {
4952 {
4953 var map = new Map();
4954 var lane = 1;
4955
4956 for (var index = 0; index < TotalLanes; index++) {
4957 var label = getLabelForLane(lane);
4958 map.set(lane, label);
4959 lane *= 2;
4960 }
4961
4962 return map;
4963 }
4964 }
4965
4966 function markCommitStarted(lanes) {
4967 {
4968 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markCommitStarted === 'function') {
4969 injectedProfilingHooks.markCommitStarted(lanes);
4970 }
4971 }
4972 }
4973 function markCommitStopped() {
4974 {
4975 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markCommitStopped === 'function') {
4976 injectedProfilingHooks.markCommitStopped();
4977 }
4978 }
4979 }
4980 function markComponentRenderStarted(fiber) {
4981 {
4982 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentRenderStarted === 'function') {
4983 injectedProfilingHooks.markComponentRenderStarted(fiber);
4984 }
4985 }
4986 }
4987 function markComponentRenderStopped() {
4988 {
4989 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentRenderStopped === 'function') {
4990 injectedProfilingHooks.markComponentRenderStopped();
4991 }
4992 }
4993 }
4994 function markComponentPassiveEffectMountStarted(fiber) {
4995 {
4996 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectMountStarted === 'function') {
4997 injectedProfilingHooks.markComponentPassiveEffectMountStarted(fiber);
4998 }
4999 }
5000 }
5001 function markComponentPassiveEffectMountStopped() {
5002 {
5003 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectMountStopped === 'function') {
5004 injectedProfilingHooks.markComponentPassiveEffectMountStopped();
5005 }
5006 }
5007 }
5008 function markComponentPassiveEffectUnmountStarted(fiber) {
5009 {
5010 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStarted === 'function') {
5011 injectedProfilingHooks.markComponentPassiveEffectUnmountStarted(fiber);
5012 }
5013 }
5014 }
5015 function markComponentPassiveEffectUnmountStopped() {
5016 {
5017 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStopped === 'function') {
5018 injectedProfilingHooks.markComponentPassiveEffectUnmountStopped();
5019 }
5020 }
5021 }
5022 function markComponentLayoutEffectMountStarted(fiber) {
5023 {
5024 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectMountStarted === 'function') {
5025 injectedProfilingHooks.markComponentLayoutEffectMountStarted(fiber);
5026 }
5027 }
5028 }
5029 function markComponentLayoutEffectMountStopped() {
5030 {
5031 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectMountStopped === 'function') {
5032 injectedProfilingHooks.markComponentLayoutEffectMountStopped();
5033 }
5034 }
5035 }
5036 function markComponentLayoutEffectUnmountStarted(fiber) {
5037 {
5038 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStarted === 'function') {
5039 injectedProfilingHooks.markComponentLayoutEffectUnmountStarted(fiber);
5040 }
5041 }
5042 }
5043 function markComponentLayoutEffectUnmountStopped() {
5044 {
5045 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStopped === 'function') {
5046 injectedProfilingHooks.markComponentLayoutEffectUnmountStopped();
5047 }
5048 }
5049 }
5050 function markComponentErrored(fiber, thrownValue, lanes) {
5051 {
5052 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentErrored === 'function') {
5053 injectedProfilingHooks.markComponentErrored(fiber, thrownValue, lanes);
5054 }
5055 }
5056 }
5057 function markComponentSuspended(fiber, wakeable, lanes) {
5058 {
5059 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentSuspended === 'function') {
5060 injectedProfilingHooks.markComponentSuspended(fiber, wakeable, lanes);
5061 }
5062 }
5063 }
5064 function markLayoutEffectsStarted(lanes) {
5065 {
5066 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markLayoutEffectsStarted === 'function') {
5067 injectedProfilingHooks.markLayoutEffectsStarted(lanes);
5068 }
5069 }
5070 }
5071 function markLayoutEffectsStopped() {
5072 {
5073 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markLayoutEffectsStopped === 'function') {
5074 injectedProfilingHooks.markLayoutEffectsStopped();
5075 }
5076 }
5077 }
5078 function markPassiveEffectsStarted(lanes) {
5079 {
5080 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markPassiveEffectsStarted === 'function') {
5081 injectedProfilingHooks.markPassiveEffectsStarted(lanes);
5082 }
5083 }
5084 }
5085 function markPassiveEffectsStopped() {
5086 {
5087 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markPassiveEffectsStopped === 'function') {
5088 injectedProfilingHooks.markPassiveEffectsStopped();
5089 }
5090 }
5091 }
5092 function markRenderStarted(lanes) {
5093 {
5094 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderStarted === 'function') {
5095 injectedProfilingHooks.markRenderStarted(lanes);
5096 }
5097 }
5098 }
5099 function markRenderYielded() {
5100 {
5101 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderYielded === 'function') {
5102 injectedProfilingHooks.markRenderYielded();
5103 }
5104 }
5105 }
5106 function markRenderStopped() {
5107 {
5108 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderStopped === 'function') {
5109 injectedProfilingHooks.markRenderStopped();
5110 }
5111 }
5112 }
5113 function markRenderScheduled(lane) {
5114 {
5115 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderScheduled === 'function') {
5116 injectedProfilingHooks.markRenderScheduled(lane);
5117 }
5118 }
5119 }
5120 function markForceUpdateScheduled(fiber, lane) {
5121 {
5122 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markForceUpdateScheduled === 'function') {
5123 injectedProfilingHooks.markForceUpdateScheduled(fiber, lane);
5124 }
5125 }
5126 }
5127 function markStateUpdateScheduled(fiber, lane) {
5128 {
5129 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markStateUpdateScheduled === 'function') {
5130 injectedProfilingHooks.markStateUpdateScheduled(fiber, lane);
5131 }
5132 }
5133 }
5134
5135 var NoMode =
5136 /* */
5137 0; // TODO: Remove ConcurrentMode by reading from the root tag instead
5138
5139 var ConcurrentMode =
5140 /* */
5141 1;
5142 var ProfileMode =
5143 /* */
5144 2;
5145 var StrictLegacyMode =
5146 /* */
5147 8;
5148 var StrictEffectsMode =
5149 /* */
5150 16;
5151
5152 // TODO: This is pretty well supported by browsers. Maybe we can drop it.
5153 var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros.
5154 // Based on:
5155 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
5156
5157 var log = Math.log;
5158 var LN2 = Math.LN2;
5159
5160 function clz32Fallback(x) {
5161 var asUint = x >>> 0;
5162
5163 if (asUint === 0) {
5164 return 32;
5165 }
5166
5167 return 31 - (log(asUint) / LN2 | 0) | 0;
5168 }
5169
5170 // If those values are changed that package should be rebuilt and redeployed.
5171
5172 var TotalLanes = 31;
5173 var NoLanes =
5174 /* */
5175 0;
5176 var NoLane =
5177 /* */
5178 0;
5179 var SyncLane =
5180 /* */
5181 1;
5182 var InputContinuousHydrationLane =
5183 /* */
5184 2;
5185 var InputContinuousLane =
5186 /* */
5187 4;
5188 var DefaultHydrationLane =
5189 /* */
5190 8;
5191 var DefaultLane =
5192 /* */
5193 16;
5194 var TransitionHydrationLane =
5195 /* */
5196 32;
5197 var TransitionLanes =
5198 /* */
5199 4194240;
5200 var TransitionLane1 =
5201 /* */
5202 64;
5203 var TransitionLane2 =
5204 /* */
5205 128;
5206 var TransitionLane3 =
5207 /* */
5208 256;
5209 var TransitionLane4 =
5210 /* */
5211 512;
5212 var TransitionLane5 =
5213 /* */
5214 1024;
5215 var TransitionLane6 =
5216 /* */
5217 2048;
5218 var TransitionLane7 =
5219 /* */
5220 4096;
5221 var TransitionLane8 =
5222 /* */
5223 8192;
5224 var TransitionLane9 =
5225 /* */
5226 16384;
5227 var TransitionLane10 =
5228 /* */
5229 32768;
5230 var TransitionLane11 =
5231 /* */
5232 65536;
5233 var TransitionLane12 =
5234 /* */
5235 131072;
5236 var TransitionLane13 =
5237 /* */
5238 262144;
5239 var TransitionLane14 =
5240 /* */
5241 524288;
5242 var TransitionLane15 =
5243 /* */
5244 1048576;
5245 var TransitionLane16 =
5246 /* */
5247 2097152;
5248 var RetryLanes =
5249 /* */
5250 130023424;
5251 var RetryLane1 =
5252 /* */
5253 4194304;
5254 var RetryLane2 =
5255 /* */
5256 8388608;
5257 var RetryLane3 =
5258 /* */
5259 16777216;
5260 var RetryLane4 =
5261 /* */
5262 33554432;
5263 var RetryLane5 =
5264 /* */
5265 67108864;
5266 var SomeRetryLane = RetryLane1;
5267 var SelectiveHydrationLane =
5268 /* */
5269 134217728;
5270 var NonIdleLanes =
5271 /* */
5272 268435455;
5273 var IdleHydrationLane =
5274 /* */
5275 268435456;
5276 var IdleLane =
5277 /* */
5278 536870912;
5279 var OffscreenLane =
5280 /* */
5281 1073741824; // This function is used for the experimental timeline (react-devtools-timeline)
5282 // It should be kept in sync with the Lanes values above.
5283
5284 function getLabelForLane(lane) {
5285 {
5286 if (lane & SyncLane) {
5287 return 'Sync';
5288 }
5289
5290 if (lane & InputContinuousHydrationLane) {
5291 return 'InputContinuousHydration';
5292 }
5293
5294 if (lane & InputContinuousLane) {
5295 return 'InputContinuous';
5296 }
5297
5298 if (lane & DefaultHydrationLane) {
5299 return 'DefaultHydration';
5300 }
5301
5302 if (lane & DefaultLane) {
5303 return 'Default';
5304 }
5305
5306 if (lane & TransitionHydrationLane) {
5307 return 'TransitionHydration';
5308 }
5309
5310 if (lane & TransitionLanes) {
5311 return 'Transition';
5312 }
5313
5314 if (lane & RetryLanes) {
5315 return 'Retry';
5316 }
5317
5318 if (lane & SelectiveHydrationLane) {
5319 return 'SelectiveHydration';
5320 }
5321
5322 if (lane & IdleHydrationLane) {
5323 return 'IdleHydration';
5324 }
5325
5326 if (lane & IdleLane) {
5327 return 'Idle';
5328 }
5329
5330 if (lane & OffscreenLane) {
5331 return 'Offscreen';
5332 }
5333 }
5334 }
5335 var NoTimestamp = -1;
5336 var nextTransitionLane = TransitionLane1;
5337 var nextRetryLane = RetryLane1;
5338
5339 function getHighestPriorityLanes(lanes) {
5340 switch (getHighestPriorityLane(lanes)) {
5341 case SyncLane:
5342 return SyncLane;
5343
5344 case InputContinuousHydrationLane:
5345 return InputContinuousHydrationLane;
5346
5347 case InputContinuousLane:
5348 return InputContinuousLane;
5349
5350 case DefaultHydrationLane:
5351 return DefaultHydrationLane;
5352
5353 case DefaultLane:
5354 return DefaultLane;
5355
5356 case TransitionHydrationLane:
5357 return TransitionHydrationLane;
5358
5359 case TransitionLane1:
5360 case TransitionLane2:
5361 case TransitionLane3:
5362 case TransitionLane4:
5363 case TransitionLane5:
5364 case TransitionLane6:
5365 case TransitionLane7:
5366 case TransitionLane8:
5367 case TransitionLane9:
5368 case TransitionLane10:
5369 case TransitionLane11:
5370 case TransitionLane12:
5371 case TransitionLane13:
5372 case TransitionLane14:
5373 case TransitionLane15:
5374 case TransitionLane16:
5375 return lanes & TransitionLanes;
5376
5377 case RetryLane1:
5378 case RetryLane2:
5379 case RetryLane3:
5380 case RetryLane4:
5381 case RetryLane5:
5382 return lanes & RetryLanes;
5383
5384 case SelectiveHydrationLane:
5385 return SelectiveHydrationLane;
5386
5387 case IdleHydrationLane:
5388 return IdleHydrationLane;
5389
5390 case IdleLane:
5391 return IdleLane;
5392
5393 case OffscreenLane:
5394 return OffscreenLane;
5395
5396 default:
5397 {
5398 error('Should have found matching lanes. This is a bug in React.');
5399 } // This shouldn't be reachable, but as a fallback, return the entire bitmask.
5400
5401
5402 return lanes;
5403 }
5404 }
5405
5406 function getNextLanes(root, wipLanes) {
5407 // Early bailout if there's no pending work left.
5408 var pendingLanes = root.pendingLanes;
5409
5410 if (pendingLanes === NoLanes) {
5411 return NoLanes;
5412 }
5413
5414 var nextLanes = NoLanes;
5415 var suspendedLanes = root.suspendedLanes;
5416 var pingedLanes = root.pingedLanes; // Do not work on any idle work until all the non-idle work has finished,
5417 // even if the work is suspended.
5418
5419 var nonIdlePendingLanes = pendingLanes & NonIdleLanes;
5420
5421 if (nonIdlePendingLanes !== NoLanes) {
5422 var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes;
5423
5424 if (nonIdleUnblockedLanes !== NoLanes) {
5425 nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes);
5426 } else {
5427 var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes;
5428
5429 if (nonIdlePingedLanes !== NoLanes) {
5430 nextLanes = getHighestPriorityLanes(nonIdlePingedLanes);
5431 }
5432 }
5433 } else {
5434 // The only remaining work is Idle.
5435 var unblockedLanes = pendingLanes & ~suspendedLanes;
5436
5437 if (unblockedLanes !== NoLanes) {
5438 nextLanes = getHighestPriorityLanes(unblockedLanes);
5439 } else {
5440 if (pingedLanes !== NoLanes) {
5441 nextLanes = getHighestPriorityLanes(pingedLanes);
5442 }
5443 }
5444 }
5445
5446 if (nextLanes === NoLanes) {
5447 // This should only be reachable if we're suspended
5448 // TODO: Consider warning in this path if a fallback timer is not scheduled.
5449 return NoLanes;
5450 } // If we're already in the middle of a render, switching lanes will interrupt
5451 // it and we'll lose our progress. We should only do this if the new lanes are
5452 // higher priority.
5453
5454
5455 if (wipLanes !== NoLanes && wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't
5456 // bother waiting until the root is complete.
5457 (wipLanes & suspendedLanes) === NoLanes) {
5458 var nextLane = getHighestPriorityLane(nextLanes);
5459 var wipLane = getHighestPriorityLane(wipLanes);
5460
5461 if ( // Tests whether the next lane is equal or lower priority than the wip
5462 // one. This works because the bits decrease in priority as you go left.
5463 nextLane >= wipLane || // Default priority updates should not interrupt transition updates. The
5464 // only difference between default updates and transition updates is that
5465 // default updates do not support refresh transitions.
5466 nextLane === DefaultLane && (wipLane & TransitionLanes) !== NoLanes) {
5467 // Keep working on the existing in-progress tree. Do not interrupt.
5468 return wipLanes;
5469 }
5470 }
5471
5472 if ((nextLanes & InputContinuousLane) !== NoLanes) {
5473 // When updates are sync by default, we entangle continuous priority updates
5474 // and default updates, so they render in the same batch. The only reason
5475 // they use separate lanes is because continuous updates should interrupt
5476 // transitions, but default updates should not.
5477 nextLanes |= pendingLanes & DefaultLane;
5478 } // Check for entangled lanes and add them to the batch.
5479 //
5480 // A lane is said to be entangled with another when it's not allowed to render
5481 // in a batch that does not also include the other lane. Typically we do this
5482 // when multiple updates have the same source, and we only want to respond to
5483 // the most recent event from that source.
5484 //
5485 // Note that we apply entanglements *after* checking for partial work above.
5486 // This means that if a lane is entangled during an interleaved event while
5487 // it's already rendering, we won't interrupt it. This is intentional, since
5488 // entanglement is usually "best effort": we'll try our best to render the
5489 // lanes in the same batch, but it's not worth throwing out partially
5490 // completed work in order to do it.
5491 // TODO: Reconsider this. The counter-argument is that the partial work
5492 // represents an intermediate state, which we don't want to show to the user.
5493 // And by spending extra time finishing it, we're increasing the amount of
5494 // time it takes to show the final state, which is what they are actually
5495 // waiting for.
5496 //
5497 // For those exceptions where entanglement is semantically important, like
5498 // useMutableSource, we should ensure that there is no partial work at the
5499 // time we apply the entanglement.
5500
5501
5502 var entangledLanes = root.entangledLanes;
5503
5504 if (entangledLanes !== NoLanes) {
5505 var entanglements = root.entanglements;
5506 var lanes = nextLanes & entangledLanes;
5507
5508 while (lanes > 0) {
5509 var index = pickArbitraryLaneIndex(lanes);
5510 var lane = 1 << index;
5511 nextLanes |= entanglements[index];
5512 lanes &= ~lane;
5513 }
5514 }
5515
5516 return nextLanes;
5517 }
5518 function getMostRecentEventTime(root, lanes) {
5519 var eventTimes = root.eventTimes;
5520 var mostRecentEventTime = NoTimestamp;
5521
5522 while (lanes > 0) {
5523 var index = pickArbitraryLaneIndex(lanes);
5524 var lane = 1 << index;
5525 var eventTime = eventTimes[index];
5526
5527 if (eventTime > mostRecentEventTime) {
5528 mostRecentEventTime = eventTime;
5529 }
5530
5531 lanes &= ~lane;
5532 }
5533
5534 return mostRecentEventTime;
5535 }
5536
5537 function computeExpirationTime(lane, currentTime) {
5538 switch (lane) {
5539 case SyncLane:
5540 case InputContinuousHydrationLane:
5541 case InputContinuousLane:
5542 // User interactions should expire slightly more quickly.
5543 //
5544 // NOTE: This is set to the corresponding constant as in Scheduler.js.
5545 // When we made it larger, a product metric in www regressed, suggesting
5546 // there's a user interaction that's being starved by a series of
5547 // synchronous updates. If that theory is correct, the proper solution is
5548 // to fix the starvation. However, this scenario supports the idea that
5549 // expiration times are an important safeguard when starvation
5550 // does happen.
5551 return currentTime + 250;
5552
5553 case DefaultHydrationLane:
5554 case DefaultLane:
5555 case TransitionHydrationLane:
5556 case TransitionLane1:
5557 case TransitionLane2:
5558 case TransitionLane3:
5559 case TransitionLane4:
5560 case TransitionLane5:
5561 case TransitionLane6:
5562 case TransitionLane7:
5563 case TransitionLane8:
5564 case TransitionLane9:
5565 case TransitionLane10:
5566 case TransitionLane11:
5567 case TransitionLane12:
5568 case TransitionLane13:
5569 case TransitionLane14:
5570 case TransitionLane15:
5571 case TransitionLane16:
5572 return currentTime + 5000;
5573
5574 case RetryLane1:
5575 case RetryLane2:
5576 case RetryLane3:
5577 case RetryLane4:
5578 case RetryLane5:
5579 // TODO: Retries should be allowed to expire if they are CPU bound for
5580 // too long, but when I made this change it caused a spike in browser
5581 // crashes. There must be some other underlying bug; not super urgent but
5582 // ideally should figure out why and fix it. Unfortunately we don't have
5583 // a repro for the crashes, only detected via production metrics.
5584 return NoTimestamp;
5585
5586 case SelectiveHydrationLane:
5587 case IdleHydrationLane:
5588 case IdleLane:
5589 case OffscreenLane:
5590 // Anything idle priority or lower should never expire.
5591 return NoTimestamp;
5592
5593 default:
5594 {
5595 error('Should have found matching lanes. This is a bug in React.');
5596 }
5597
5598 return NoTimestamp;
5599 }
5600 }
5601
5602 function markStarvedLanesAsExpired(root, currentTime) {
5603 // TODO: This gets called every time we yield. We can optimize by storing
5604 // the earliest expiration time on the root. Then use that to quickly bail out
5605 // of this function.
5606 var pendingLanes = root.pendingLanes;
5607 var suspendedLanes = root.suspendedLanes;
5608 var pingedLanes = root.pingedLanes;
5609 var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their
5610 // expiration time. If so, we'll assume the update is being starved and mark
5611 // it as expired to force it to finish.
5612
5613 var lanes = pendingLanes;
5614
5615 while (lanes > 0) {
5616 var index = pickArbitraryLaneIndex(lanes);
5617 var lane = 1 << index;
5618 var expirationTime = expirationTimes[index];
5619
5620 if (expirationTime === NoTimestamp) {
5621 // Found a pending lane with no expiration time. If it's not suspended, or
5622 // if it's pinged, assume it's CPU-bound. Compute a new expiration time
5623 // using the current time.
5624 if ((lane & suspendedLanes) === NoLanes || (lane & pingedLanes) !== NoLanes) {
5625 // Assumes timestamps are monotonically increasing.
5626 expirationTimes[index] = computeExpirationTime(lane, currentTime);
5627 }
5628 } else if (expirationTime <= currentTime) {
5629 // This lane expired
5630 root.expiredLanes |= lane;
5631 }
5632
5633 lanes &= ~lane;
5634 }
5635 } // This returns the highest priority pending lanes regardless of whether they
5636 // are suspended.
5637
5638 function getHighestPriorityPendingLanes(root) {
5639 return getHighestPriorityLanes(root.pendingLanes);
5640 }
5641 function getLanesToRetrySynchronouslyOnError(root) {
5642 var everythingButOffscreen = root.pendingLanes & ~OffscreenLane;
5643
5644 if (everythingButOffscreen !== NoLanes) {
5645 return everythingButOffscreen;
5646 }
5647
5648 if (everythingButOffscreen & OffscreenLane) {
5649 return OffscreenLane;
5650 }
5651
5652 return NoLanes;
5653 }
5654 function includesSyncLane(lanes) {
5655 return (lanes & SyncLane) !== NoLanes;
5656 }
5657 function includesNonIdleWork(lanes) {
5658 return (lanes & NonIdleLanes) !== NoLanes;
5659 }
5660 function includesOnlyRetries(lanes) {
5661 return (lanes & RetryLanes) === lanes;
5662 }
5663 function includesOnlyNonUrgentLanes(lanes) {
5664 var UrgentLanes = SyncLane | InputContinuousLane | DefaultLane;
5665 return (lanes & UrgentLanes) === NoLanes;
5666 }
5667 function includesOnlyTransitions(lanes) {
5668 return (lanes & TransitionLanes) === lanes;
5669 }
5670 function includesBlockingLane(root, lanes) {
5671
5672 var SyncDefaultLanes = InputContinuousHydrationLane | InputContinuousLane | DefaultHydrationLane | DefaultLane;
5673 return (lanes & SyncDefaultLanes) !== NoLanes;
5674 }
5675 function includesExpiredLane(root, lanes) {
5676 // This is a separate check from includesBlockingLane because a lane can
5677 // expire after a render has already started.
5678 return (lanes & root.expiredLanes) !== NoLanes;
5679 }
5680 function isTransitionLane(lane) {
5681 return (lane & TransitionLanes) !== NoLanes;
5682 }
5683 function claimNextTransitionLane() {
5684 // Cycle through the lanes, assigning each new transition to the next lane.
5685 // In most cases, this means every transition gets its own lane, until we
5686 // run out of lanes and cycle back to the beginning.
5687 var lane = nextTransitionLane;
5688 nextTransitionLane <<= 1;
5689
5690 if ((nextTransitionLane & TransitionLanes) === NoLanes) {
5691 nextTransitionLane = TransitionLane1;
5692 }
5693
5694 return lane;
5695 }
5696 function claimNextRetryLane() {
5697 var lane = nextRetryLane;
5698 nextRetryLane <<= 1;
5699
5700 if ((nextRetryLane & RetryLanes) === NoLanes) {
5701 nextRetryLane = RetryLane1;
5702 }
5703
5704 return lane;
5705 }
5706 function getHighestPriorityLane(lanes) {
5707 return lanes & -lanes;
5708 }
5709 function pickArbitraryLane(lanes) {
5710 // This wrapper function gets inlined. Only exists so to communicate that it
5711 // doesn't matter which bit is selected; you can pick any bit without
5712 // affecting the algorithms where its used. Here I'm using
5713 // getHighestPriorityLane because it requires the fewest operations.
5714 return getHighestPriorityLane(lanes);
5715 }
5716
5717 function pickArbitraryLaneIndex(lanes) {
5718 return 31 - clz32(lanes);
5719 }
5720
5721 function laneToIndex(lane) {
5722 return pickArbitraryLaneIndex(lane);
5723 }
5724
5725 function includesSomeLane(a, b) {
5726 return (a & b) !== NoLanes;
5727 }
5728 function isSubsetOfLanes(set, subset) {
5729 return (set & subset) === subset;
5730 }
5731 function mergeLanes(a, b) {
5732 return a | b;
5733 }
5734 function removeLanes(set, subset) {
5735 return set & ~subset;
5736 }
5737 function intersectLanes(a, b) {
5738 return a & b;
5739 } // Seems redundant, but it changes the type from a single lane (used for
5740 // updates) to a group of lanes (used for flushing work).
5741
5742 function laneToLanes(lane) {
5743 return lane;
5744 }
5745 function higherPriorityLane(a, b) {
5746 // This works because the bit ranges decrease in priority as you go left.
5747 return a !== NoLane && a < b ? a : b;
5748 }
5749 function createLaneMap(initial) {
5750 // Intentionally pushing one by one.
5751 // https://v8.dev/blog/elements-kinds#avoid-creating-holes
5752 var laneMap = [];
5753
5754 for (var i = 0; i < TotalLanes; i++) {
5755 laneMap.push(initial);
5756 }
5757
5758 return laneMap;
5759 }
5760 function markRootUpdated(root, updateLane, eventTime) {
5761 root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update
5762 // could unblock them. Clear the suspended lanes so that we can try rendering
5763 // them again.
5764 //
5765 // TODO: We really only need to unsuspend only lanes that are in the
5766 // `subtreeLanes` of the updated fiber, or the update lanes of the return
5767 // path. This would exclude suspended updates in an unrelated sibling tree,
5768 // since there's no way for this update to unblock it.
5769 //
5770 // We don't do this if the incoming update is idle, because we never process
5771 // idle updates until after all the regular updates have finished; there's no
5772 // way it could unblock a transition.
5773
5774 if (updateLane !== IdleLane) {
5775 root.suspendedLanes = NoLanes;
5776 root.pingedLanes = NoLanes;
5777 }
5778
5779 var eventTimes = root.eventTimes;
5780 var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most
5781 // recent event, and we assume time is monotonically increasing.
5782
5783 eventTimes[index] = eventTime;
5784 }
5785 function markRootSuspended(root, suspendedLanes) {
5786 root.suspendedLanes |= suspendedLanes;
5787 root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times.
5788
5789 var expirationTimes = root.expirationTimes;
5790 var lanes = suspendedLanes;
5791
5792 while (lanes > 0) {
5793 var index = pickArbitraryLaneIndex(lanes);
5794 var lane = 1 << index;
5795 expirationTimes[index] = NoTimestamp;
5796 lanes &= ~lane;
5797 }
5798 }
5799 function markRootPinged(root, pingedLanes, eventTime) {
5800 root.pingedLanes |= root.suspendedLanes & pingedLanes;
5801 }
5802 function markRootFinished(root, remainingLanes) {
5803 var noLongerPendingLanes = root.pendingLanes & ~remainingLanes;
5804 root.pendingLanes = remainingLanes; // Let's try everything again
5805
5806 root.suspendedLanes = NoLanes;
5807 root.pingedLanes = NoLanes;
5808 root.expiredLanes &= remainingLanes;
5809 root.mutableReadLanes &= remainingLanes;
5810 root.entangledLanes &= remainingLanes;
5811 var entanglements = root.entanglements;
5812 var eventTimes = root.eventTimes;
5813 var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work
5814
5815 var lanes = noLongerPendingLanes;
5816
5817 while (lanes > 0) {
5818 var index = pickArbitraryLaneIndex(lanes);
5819 var lane = 1 << index;
5820 entanglements[index] = NoLanes;
5821 eventTimes[index] = NoTimestamp;
5822 expirationTimes[index] = NoTimestamp;
5823 lanes &= ~lane;
5824 }
5825 }
5826 function markRootEntangled(root, entangledLanes) {
5827 // In addition to entangling each of the given lanes with each other, we also
5828 // have to consider _transitive_ entanglements. For each lane that is already
5829 // entangled with *any* of the given lanes, that lane is now transitively
5830 // entangled with *all* the given lanes.
5831 //
5832 // Translated: If C is entangled with A, then entangling A with B also
5833 // entangles C with B.
5834 //
5835 // If this is hard to grasp, it might help to intentionally break this
5836 // function and look at the tests that fail in ReactTransition-test.js. Try
5837 // commenting out one of the conditions below.
5838 var rootEntangledLanes = root.entangledLanes |= entangledLanes;
5839 var entanglements = root.entanglements;
5840 var lanes = rootEntangledLanes;
5841
5842 while (lanes) {
5843 var index = pickArbitraryLaneIndex(lanes);
5844 var lane = 1 << index;
5845
5846 if ( // Is this one of the newly entangled lanes?
5847 lane & entangledLanes | // Is this lane transitively entangled with the newly entangled lanes?
5848 entanglements[index] & entangledLanes) {
5849 entanglements[index] |= entangledLanes;
5850 }
5851
5852 lanes &= ~lane;
5853 }
5854 }
5855 function getBumpedLaneForHydration(root, renderLanes) {
5856 var renderLane = getHighestPriorityLane(renderLanes);
5857 var lane;
5858
5859 switch (renderLane) {
5860 case InputContinuousLane:
5861 lane = InputContinuousHydrationLane;
5862 break;
5863
5864 case DefaultLane:
5865 lane = DefaultHydrationLane;
5866 break;
5867
5868 case TransitionLane1:
5869 case TransitionLane2:
5870 case TransitionLane3:
5871 case TransitionLane4:
5872 case TransitionLane5:
5873 case TransitionLane6:
5874 case TransitionLane7:
5875 case TransitionLane8:
5876 case TransitionLane9:
5877 case TransitionLane10:
5878 case TransitionLane11:
5879 case TransitionLane12:
5880 case TransitionLane13:
5881 case TransitionLane14:
5882 case TransitionLane15:
5883 case TransitionLane16:
5884 case RetryLane1:
5885 case RetryLane2:
5886 case RetryLane3:
5887 case RetryLane4:
5888 case RetryLane5:
5889 lane = TransitionHydrationLane;
5890 break;
5891
5892 case IdleLane:
5893 lane = IdleHydrationLane;
5894 break;
5895
5896 default:
5897 // Everything else is already either a hydration lane, or shouldn't
5898 // be retried at a hydration lane.
5899 lane = NoLane;
5900 break;
5901 } // Check if the lane we chose is suspended. If so, that indicates that we
5902 // already attempted and failed to hydrate at that level. Also check if we're
5903 // already rendering that lane, which is rare but could happen.
5904
5905
5906 if ((lane & (root.suspendedLanes | renderLanes)) !== NoLane) {
5907 // Give up trying to hydrate and fall back to client render.
5908 return NoLane;
5909 }
5910
5911 return lane;
5912 }
5913 function addFiberToLanesMap(root, fiber, lanes) {
5914
5915 if (!isDevToolsPresent) {
5916 return;
5917 }
5918
5919 var pendingUpdatersLaneMap = root.pendingUpdatersLaneMap;
5920
5921 while (lanes > 0) {
5922 var index = laneToIndex(lanes);
5923 var lane = 1 << index;
5924 var updaters = pendingUpdatersLaneMap[index];
5925 updaters.add(fiber);
5926 lanes &= ~lane;
5927 }
5928 }
5929 function movePendingFibersToMemoized(root, lanes) {
5930
5931 if (!isDevToolsPresent) {
5932 return;
5933 }
5934
5935 var pendingUpdatersLaneMap = root.pendingUpdatersLaneMap;
5936 var memoizedUpdaters = root.memoizedUpdaters;
5937
5938 while (lanes > 0) {
5939 var index = laneToIndex(lanes);
5940 var lane = 1 << index;
5941 var updaters = pendingUpdatersLaneMap[index];
5942
5943 if (updaters.size > 0) {
5944 updaters.forEach(function (fiber) {
5945 var alternate = fiber.alternate;
5946
5947 if (alternate === null || !memoizedUpdaters.has(alternate)) {
5948 memoizedUpdaters.add(fiber);
5949 }
5950 });
5951 updaters.clear();
5952 }
5953
5954 lanes &= ~lane;
5955 }
5956 }
5957 function getTransitionsForLanes(root, lanes) {
5958 {
5959 return null;
5960 }
5961 }
5962
5963 var DiscreteEventPriority = SyncLane;
5964 var ContinuousEventPriority = InputContinuousLane;
5965 var DefaultEventPriority = DefaultLane;
5966 var IdleEventPriority = IdleLane;
5967 var currentUpdatePriority = NoLane;
5968 function getCurrentUpdatePriority() {
5969 return currentUpdatePriority;
5970 }
5971 function setCurrentUpdatePriority(newPriority) {
5972 currentUpdatePriority = newPriority;
5973 }
5974 function runWithPriority(priority, fn) {
5975 var previousPriority = currentUpdatePriority;
5976
5977 try {
5978 currentUpdatePriority = priority;
5979 return fn();
5980 } finally {
5981 currentUpdatePriority = previousPriority;
5982 }
5983 }
5984 function higherEventPriority(a, b) {
5985 return a !== 0 && a < b ? a : b;
5986 }
5987 function lowerEventPriority(a, b) {
5988 return a === 0 || a > b ? a : b;
5989 }
5990 function isHigherEventPriority(a, b) {
5991 return a !== 0 && a < b;
5992 }
5993 function lanesToEventPriority(lanes) {
5994 var lane = getHighestPriorityLane(lanes);
5995
5996 if (!isHigherEventPriority(DiscreteEventPriority, lane)) {
5997 return DiscreteEventPriority;
5998 }
5999
6000 if (!isHigherEventPriority(ContinuousEventPriority, lane)) {
6001 return ContinuousEventPriority;
6002 }
6003
6004 if (includesNonIdleWork(lane)) {
6005 return DefaultEventPriority;
6006 }
6007
6008 return IdleEventPriority;
6009 }
6010
6011 // This is imported by the event replaying implementation in React DOM. It's
6012 // in a separate file to break a circular dependency between the renderer and
6013 // the reconciler.
6014 function isRootDehydrated(root) {
6015 var currentState = root.current.memoizedState;
6016 return currentState.isDehydrated;
6017 }
6018
6019 var _attemptSynchronousHydration;
6020
6021 function setAttemptSynchronousHydration(fn) {
6022 _attemptSynchronousHydration = fn;
6023 }
6024 function attemptSynchronousHydration(fiber) {
6025 _attemptSynchronousHydration(fiber);
6026 }
6027 var attemptContinuousHydration;
6028 function setAttemptContinuousHydration(fn) {
6029 attemptContinuousHydration = fn;
6030 }
6031 var attemptHydrationAtCurrentPriority;
6032 function setAttemptHydrationAtCurrentPriority(fn) {
6033 attemptHydrationAtCurrentPriority = fn;
6034 }
6035 var getCurrentUpdatePriority$1;
6036 function setGetCurrentUpdatePriority(fn) {
6037 getCurrentUpdatePriority$1 = fn;
6038 }
6039 var attemptHydrationAtPriority;
6040 function setAttemptHydrationAtPriority(fn) {
6041 attemptHydrationAtPriority = fn;
6042 } // TODO: Upgrade this definition once we're on a newer version of Flow that
6043 // has this definition built-in.
6044
6045 var hasScheduledReplayAttempt = false; // The queue of discrete events to be replayed.
6046
6047 var queuedDiscreteEvents = []; // Indicates if any continuous event targets are non-null for early bailout.
6048 // if the last target was dehydrated.
6049
6050 var queuedFocus = null;
6051 var queuedDrag = null;
6052 var queuedMouse = null; // For pointer events there can be one latest event per pointerId.
6053
6054 var queuedPointers = new Map();
6055 var queuedPointerCaptures = new Map(); // We could consider replaying selectionchange and touchmoves too.
6056
6057 var queuedExplicitHydrationTargets = [];
6058 var discreteReplayableEvents = ['mousedown', 'mouseup', 'touchcancel', 'touchend', 'touchstart', 'auxclick', 'dblclick', 'pointercancel', 'pointerdown', 'pointerup', 'dragend', 'dragstart', 'drop', 'compositionend', 'compositionstart', 'keydown', 'keypress', 'keyup', 'input', 'textInput', // Intentionally camelCase
6059 'copy', 'cut', 'paste', 'click', 'change', 'contextmenu', 'reset', 'submit'];
6060 function isDiscreteEventThatRequiresHydration(eventType) {
6061 return discreteReplayableEvents.indexOf(eventType) > -1;
6062 }
6063
6064 function createQueuedReplayableEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
6065 return {
6066 blockedOn: blockedOn,
6067 domEventName: domEventName,
6068 eventSystemFlags: eventSystemFlags,
6069 nativeEvent: nativeEvent,
6070 targetContainers: [targetContainer]
6071 };
6072 }
6073
6074 function clearIfContinuousEvent(domEventName, nativeEvent) {
6075 switch (domEventName) {
6076 case 'focusin':
6077 case 'focusout':
6078 queuedFocus = null;
6079 break;
6080
6081 case 'dragenter':
6082 case 'dragleave':
6083 queuedDrag = null;
6084 break;
6085
6086 case 'mouseover':
6087 case 'mouseout':
6088 queuedMouse = null;
6089 break;
6090
6091 case 'pointerover':
6092 case 'pointerout':
6093 {
6094 var pointerId = nativeEvent.pointerId;
6095 queuedPointers.delete(pointerId);
6096 break;
6097 }
6098
6099 case 'gotpointercapture':
6100 case 'lostpointercapture':
6101 {
6102 var _pointerId = nativeEvent.pointerId;
6103 queuedPointerCaptures.delete(_pointerId);
6104 break;
6105 }
6106 }
6107 }
6108
6109 function accumulateOrCreateContinuousQueuedReplayableEvent(existingQueuedEvent, blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
6110 if (existingQueuedEvent === null || existingQueuedEvent.nativeEvent !== nativeEvent) {
6111 var queuedEvent = createQueuedReplayableEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent);
6112
6113 if (blockedOn !== null) {
6114 var _fiber2 = getInstanceFromNode(blockedOn);
6115
6116 if (_fiber2 !== null) {
6117 // Attempt to increase the priority of this target.
6118 attemptContinuousHydration(_fiber2);
6119 }
6120 }
6121
6122 return queuedEvent;
6123 } // If we have already queued this exact event, then it's because
6124 // the different event systems have different DOM event listeners.
6125 // We can accumulate the flags, and the targetContainers, and
6126 // store a single event to be replayed.
6127
6128
6129 existingQueuedEvent.eventSystemFlags |= eventSystemFlags;
6130 var targetContainers = existingQueuedEvent.targetContainers;
6131
6132 if (targetContainer !== null && targetContainers.indexOf(targetContainer) === -1) {
6133 targetContainers.push(targetContainer);
6134 }
6135
6136 return existingQueuedEvent;
6137 }
6138
6139 function queueIfContinuousEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
6140 // These set relatedTarget to null because the replayed event will be treated as if we
6141 // moved from outside the window (no target) onto the target once it hydrates.
6142 // Instead of mutating we could clone the event.
6143 switch (domEventName) {
6144 case 'focusin':
6145 {
6146 var focusEvent = nativeEvent;
6147 queuedFocus = accumulateOrCreateContinuousQueuedReplayableEvent(queuedFocus, blockedOn, domEventName, eventSystemFlags, targetContainer, focusEvent);
6148 return true;
6149 }
6150
6151 case 'dragenter':
6152 {
6153 var dragEvent = nativeEvent;
6154 queuedDrag = accumulateOrCreateContinuousQueuedReplayableEvent(queuedDrag, blockedOn, domEventName, eventSystemFlags, targetContainer, dragEvent);
6155 return true;
6156 }
6157
6158 case 'mouseover':
6159 {
6160 var mouseEvent = nativeEvent;
6161 queuedMouse = accumulateOrCreateContinuousQueuedReplayableEvent(queuedMouse, blockedOn, domEventName, eventSystemFlags, targetContainer, mouseEvent);
6162 return true;
6163 }
6164
6165 case 'pointerover':
6166 {
6167 var pointerEvent = nativeEvent;
6168 var pointerId = pointerEvent.pointerId;
6169 queuedPointers.set(pointerId, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointers.get(pointerId) || null, blockedOn, domEventName, eventSystemFlags, targetContainer, pointerEvent));
6170 return true;
6171 }
6172
6173 case 'gotpointercapture':
6174 {
6175 var _pointerEvent = nativeEvent;
6176 var _pointerId2 = _pointerEvent.pointerId;
6177 queuedPointerCaptures.set(_pointerId2, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointerCaptures.get(_pointerId2) || null, blockedOn, domEventName, eventSystemFlags, targetContainer, _pointerEvent));
6178 return true;
6179 }
6180 }
6181
6182 return false;
6183 } // Check if this target is unblocked. Returns true if it's unblocked.
6184
6185 function attemptExplicitHydrationTarget(queuedTarget) {
6186 // TODO: This function shares a lot of logic with findInstanceBlockingEvent.
6187 // Try to unify them. It's a bit tricky since it would require two return
6188 // values.
6189 var targetInst = getClosestInstanceFromNode(queuedTarget.target);
6190
6191 if (targetInst !== null) {
6192 var nearestMounted = getNearestMountedFiber(targetInst);
6193
6194 if (nearestMounted !== null) {
6195 var tag = nearestMounted.tag;
6196
6197 if (tag === SuspenseComponent) {
6198 var instance = getSuspenseInstanceFromFiber(nearestMounted);
6199
6200 if (instance !== null) {
6201 // We're blocked on hydrating this boundary.
6202 // Increase its priority.
6203 queuedTarget.blockedOn = instance;
6204 attemptHydrationAtPriority(queuedTarget.priority, function () {
6205 attemptHydrationAtCurrentPriority(nearestMounted);
6206 });
6207 return;
6208 }
6209 } else if (tag === HostRoot) {
6210 var root = nearestMounted.stateNode;
6211
6212 if (isRootDehydrated(root)) {
6213 queuedTarget.blockedOn = getContainerFromFiber(nearestMounted); // We don't currently have a way to increase the priority of
6214 // a root other than sync.
6215
6216 return;
6217 }
6218 }
6219 }
6220 }
6221
6222 queuedTarget.blockedOn = null;
6223 }
6224
6225 function queueExplicitHydrationTarget(target) {
6226 // TODO: This will read the priority if it's dispatched by the React
6227 // event system but not native events. Should read window.event.type, like
6228 // we do for updates (getCurrentEventPriority).
6229 var updatePriority = getCurrentUpdatePriority$1();
6230 var queuedTarget = {
6231 blockedOn: null,
6232 target: target,
6233 priority: updatePriority
6234 };
6235 var i = 0;
6236
6237 for (; i < queuedExplicitHydrationTargets.length; i++) {
6238 // Stop once we hit the first target with lower priority than
6239 if (!isHigherEventPriority(updatePriority, queuedExplicitHydrationTargets[i].priority)) {
6240 break;
6241 }
6242 }
6243
6244 queuedExplicitHydrationTargets.splice(i, 0, queuedTarget);
6245
6246 if (i === 0) {
6247 attemptExplicitHydrationTarget(queuedTarget);
6248 }
6249 }
6250
6251 function attemptReplayContinuousQueuedEvent(queuedEvent) {
6252 if (queuedEvent.blockedOn !== null) {
6253 return false;
6254 }
6255
6256 var targetContainers = queuedEvent.targetContainers;
6257
6258 while (targetContainers.length > 0) {
6259 var targetContainer = targetContainers[0];
6260 var nextBlockedOn = findInstanceBlockingEvent(queuedEvent.domEventName, queuedEvent.eventSystemFlags, targetContainer, queuedEvent.nativeEvent);
6261
6262 if (nextBlockedOn === null) {
6263 {
6264 var nativeEvent = queuedEvent.nativeEvent;
6265 var nativeEventClone = new nativeEvent.constructor(nativeEvent.type, nativeEvent);
6266 setReplayingEvent(nativeEventClone);
6267 nativeEvent.target.dispatchEvent(nativeEventClone);
6268 resetReplayingEvent();
6269 }
6270 } else {
6271 // We're still blocked. Try again later.
6272 var _fiber3 = getInstanceFromNode(nextBlockedOn);
6273
6274 if (_fiber3 !== null) {
6275 attemptContinuousHydration(_fiber3);
6276 }
6277
6278 queuedEvent.blockedOn = nextBlockedOn;
6279 return false;
6280 } // This target container was successfully dispatched. Try the next.
6281
6282
6283 targetContainers.shift();
6284 }
6285
6286 return true;
6287 }
6288
6289 function attemptReplayContinuousQueuedEventInMap(queuedEvent, key, map) {
6290 if (attemptReplayContinuousQueuedEvent(queuedEvent)) {
6291 map.delete(key);
6292 }
6293 }
6294
6295 function replayUnblockedEvents() {
6296 hasScheduledReplayAttempt = false;
6297
6298
6299 if (queuedFocus !== null && attemptReplayContinuousQueuedEvent(queuedFocus)) {
6300 queuedFocus = null;
6301 }
6302
6303 if (queuedDrag !== null && attemptReplayContinuousQueuedEvent(queuedDrag)) {
6304 queuedDrag = null;
6305 }
6306
6307 if (queuedMouse !== null && attemptReplayContinuousQueuedEvent(queuedMouse)) {
6308 queuedMouse = null;
6309 }
6310
6311 queuedPointers.forEach(attemptReplayContinuousQueuedEventInMap);
6312 queuedPointerCaptures.forEach(attemptReplayContinuousQueuedEventInMap);
6313 }
6314
6315 function scheduleCallbackIfUnblocked(queuedEvent, unblocked) {
6316 if (queuedEvent.blockedOn === unblocked) {
6317 queuedEvent.blockedOn = null;
6318
6319 if (!hasScheduledReplayAttempt) {
6320 hasScheduledReplayAttempt = true; // Schedule a callback to attempt replaying as many events as are
6321 // now unblocked. This first might not actually be unblocked yet.
6322 // We could check it early to avoid scheduling an unnecessary callback.
6323
6324 Scheduler.unstable_scheduleCallback(Scheduler.unstable_NormalPriority, replayUnblockedEvents);
6325 }
6326 }
6327 }
6328
6329 function retryIfBlockedOn(unblocked) {
6330 // Mark anything that was blocked on this as no longer blocked
6331 // and eligible for a replay.
6332 if (queuedDiscreteEvents.length > 0) {
6333 scheduleCallbackIfUnblocked(queuedDiscreteEvents[0], unblocked); // This is a exponential search for each boundary that commits. I think it's
6334 // worth it because we expect very few discrete events to queue up and once
6335 // we are actually fully unblocked it will be fast to replay them.
6336
6337 for (var i = 1; i < queuedDiscreteEvents.length; i++) {
6338 var queuedEvent = queuedDiscreteEvents[i];
6339
6340 if (queuedEvent.blockedOn === unblocked) {
6341 queuedEvent.blockedOn = null;
6342 }
6343 }
6344 }
6345
6346 if (queuedFocus !== null) {
6347 scheduleCallbackIfUnblocked(queuedFocus, unblocked);
6348 }
6349
6350 if (queuedDrag !== null) {
6351 scheduleCallbackIfUnblocked(queuedDrag, unblocked);
6352 }
6353
6354 if (queuedMouse !== null) {
6355 scheduleCallbackIfUnblocked(queuedMouse, unblocked);
6356 }
6357
6358 var unblock = function (queuedEvent) {
6359 return scheduleCallbackIfUnblocked(queuedEvent, unblocked);
6360 };
6361
6362 queuedPointers.forEach(unblock);
6363 queuedPointerCaptures.forEach(unblock);
6364
6365 for (var _i = 0; _i < queuedExplicitHydrationTargets.length; _i++) {
6366 var queuedTarget = queuedExplicitHydrationTargets[_i];
6367
6368 if (queuedTarget.blockedOn === unblocked) {
6369 queuedTarget.blockedOn = null;
6370 }
6371 }
6372
6373 while (queuedExplicitHydrationTargets.length > 0) {
6374 var nextExplicitTarget = queuedExplicitHydrationTargets[0];
6375
6376 if (nextExplicitTarget.blockedOn !== null) {
6377 // We're still blocked.
6378 break;
6379 } else {
6380 attemptExplicitHydrationTarget(nextExplicitTarget);
6381
6382 if (nextExplicitTarget.blockedOn === null) {
6383 // We're unblocked.
6384 queuedExplicitHydrationTargets.shift();
6385 }
6386 }
6387 }
6388 }
6389
6390 var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; // TODO: can we stop exporting these?
6391
6392 var _enabled = true; // This is exported in FB builds for use by legacy FB layer infra.
6393 // We'd like to remove this but it's not clear if this is safe.
6394
6395 function setEnabled(enabled) {
6396 _enabled = !!enabled;
6397 }
6398 function isEnabled() {
6399 return _enabled;
6400 }
6401 function createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags) {
6402 var eventPriority = getEventPriority(domEventName);
6403 var listenerWrapper;
6404
6405 switch (eventPriority) {
6406 case DiscreteEventPriority:
6407 listenerWrapper = dispatchDiscreteEvent;
6408 break;
6409
6410 case ContinuousEventPriority:
6411 listenerWrapper = dispatchContinuousEvent;
6412 break;
6413
6414 case DefaultEventPriority:
6415 default:
6416 listenerWrapper = dispatchEvent;
6417 break;
6418 }
6419
6420 return listenerWrapper.bind(null, domEventName, eventSystemFlags, targetContainer);
6421 }
6422
6423 function dispatchDiscreteEvent(domEventName, eventSystemFlags, container, nativeEvent) {
6424 var previousPriority = getCurrentUpdatePriority();
6425 var prevTransition = ReactCurrentBatchConfig.transition;
6426 ReactCurrentBatchConfig.transition = null;
6427
6428 try {
6429 setCurrentUpdatePriority(DiscreteEventPriority);
6430 dispatchEvent(domEventName, eventSystemFlags, container, nativeEvent);
6431 } finally {
6432 setCurrentUpdatePriority(previousPriority);
6433 ReactCurrentBatchConfig.transition = prevTransition;
6434 }
6435 }
6436
6437 function dispatchContinuousEvent(domEventName, eventSystemFlags, container, nativeEvent) {
6438 var previousPriority = getCurrentUpdatePriority();
6439 var prevTransition = ReactCurrentBatchConfig.transition;
6440 ReactCurrentBatchConfig.transition = null;
6441
6442 try {
6443 setCurrentUpdatePriority(ContinuousEventPriority);
6444 dispatchEvent(domEventName, eventSystemFlags, container, nativeEvent);
6445 } finally {
6446 setCurrentUpdatePriority(previousPriority);
6447 ReactCurrentBatchConfig.transition = prevTransition;
6448 }
6449 }
6450
6451 function dispatchEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent) {
6452 if (!_enabled) {
6453 return;
6454 }
6455
6456 {
6457 dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay(domEventName, eventSystemFlags, targetContainer, nativeEvent);
6458 }
6459 }
6460
6461 function dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay(domEventName, eventSystemFlags, targetContainer, nativeEvent) {
6462 var blockedOn = findInstanceBlockingEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent);
6463
6464 if (blockedOn === null) {
6465 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, return_targetInst, targetContainer);
6466 clearIfContinuousEvent(domEventName, nativeEvent);
6467 return;
6468 }
6469
6470 if (queueIfContinuousEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent)) {
6471 nativeEvent.stopPropagation();
6472 return;
6473 } // We need to clear only if we didn't queue because
6474 // queueing is accumulative.
6475
6476
6477 clearIfContinuousEvent(domEventName, nativeEvent);
6478
6479 if (eventSystemFlags & IS_CAPTURE_PHASE && isDiscreteEventThatRequiresHydration(domEventName)) {
6480 while (blockedOn !== null) {
6481 var fiber = getInstanceFromNode(blockedOn);
6482
6483 if (fiber !== null) {
6484 attemptSynchronousHydration(fiber);
6485 }
6486
6487 var nextBlockedOn = findInstanceBlockingEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent);
6488
6489 if (nextBlockedOn === null) {
6490 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, return_targetInst, targetContainer);
6491 }
6492
6493 if (nextBlockedOn === blockedOn) {
6494 break;
6495 }
6496
6497 blockedOn = nextBlockedOn;
6498 }
6499
6500 if (blockedOn !== null) {
6501 nativeEvent.stopPropagation();
6502 }
6503
6504 return;
6505 } // This is not replayable so we'll invoke it but without a target,
6506 // in case the event system needs to trace it.
6507
6508
6509 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, null, targetContainer);
6510 }
6511
6512 var return_targetInst = null; // Returns a SuspenseInstance or Container if it's blocked.
6513 // The return_targetInst field above is conceptually part of the return value.
6514
6515 function findInstanceBlockingEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent) {
6516 // TODO: Warn if _enabled is false.
6517 return_targetInst = null;
6518 var nativeEventTarget = getEventTarget(nativeEvent);
6519 var targetInst = getClosestInstanceFromNode(nativeEventTarget);
6520
6521 if (targetInst !== null) {
6522 var nearestMounted = getNearestMountedFiber(targetInst);
6523
6524 if (nearestMounted === null) {
6525 // This tree has been unmounted already. Dispatch without a target.
6526 targetInst = null;
6527 } else {
6528 var tag = nearestMounted.tag;
6529
6530 if (tag === SuspenseComponent) {
6531 var instance = getSuspenseInstanceFromFiber(nearestMounted);
6532
6533 if (instance !== null) {
6534 // Queue the event to be replayed later. Abort dispatching since we
6535 // don't want this event dispatched twice through the event system.
6536 // TODO: If this is the first discrete event in the queue. Schedule an increased
6537 // priority for this boundary.
6538 return instance;
6539 } // This shouldn't happen, something went wrong but to avoid blocking
6540 // the whole system, dispatch the event without a target.
6541 // TODO: Warn.
6542
6543
6544 targetInst = null;
6545 } else if (tag === HostRoot) {
6546 var root = nearestMounted.stateNode;
6547
6548 if (isRootDehydrated(root)) {
6549 // If this happens during a replay something went wrong and it might block
6550 // the whole system.
6551 return getContainerFromFiber(nearestMounted);
6552 }
6553
6554 targetInst = null;
6555 } else if (nearestMounted !== targetInst) {
6556 // If we get an event (ex: img onload) before committing that
6557 // component's mount, ignore it for now (that is, treat it as if it was an
6558 // event on a non-React tree). We might also consider queueing events and
6559 // dispatching them after the mount.
6560 targetInst = null;
6561 }
6562 }
6563 }
6564
6565 return_targetInst = targetInst; // We're not blocked on anything.
6566
6567 return null;
6568 }
6569 function getEventPriority(domEventName) {
6570 switch (domEventName) {
6571 // Used by SimpleEventPlugin:
6572 case 'cancel':
6573 case 'click':
6574 case 'close':
6575 case 'contextmenu':
6576 case 'copy':
6577 case 'cut':
6578 case 'auxclick':
6579 case 'dblclick':
6580 case 'dragend':
6581 case 'dragstart':
6582 case 'drop':
6583 case 'focusin':
6584 case 'focusout':
6585 case 'input':
6586 case 'invalid':
6587 case 'keydown':
6588 case 'keypress':
6589 case 'keyup':
6590 case 'mousedown':
6591 case 'mouseup':
6592 case 'paste':
6593 case 'pause':
6594 case 'play':
6595 case 'pointercancel':
6596 case 'pointerdown':
6597 case 'pointerup':
6598 case 'ratechange':
6599 case 'reset':
6600 case 'resize':
6601 case 'seeked':
6602 case 'submit':
6603 case 'touchcancel':
6604 case 'touchend':
6605 case 'touchstart':
6606 case 'volumechange': // Used by polyfills:
6607 // eslint-disable-next-line no-fallthrough
6608
6609 case 'change':
6610 case 'selectionchange':
6611 case 'textInput':
6612 case 'compositionstart':
6613 case 'compositionend':
6614 case 'compositionupdate': // Only enableCreateEventHandleAPI:
6615 // eslint-disable-next-line no-fallthrough
6616
6617 case 'beforeblur':
6618 case 'afterblur': // Not used by React but could be by user code:
6619 // eslint-disable-next-line no-fallthrough
6620
6621 case 'beforeinput':
6622 case 'blur':
6623 case 'fullscreenchange':
6624 case 'focus':
6625 case 'hashchange':
6626 case 'popstate':
6627 case 'select':
6628 case 'selectstart':
6629 return DiscreteEventPriority;
6630
6631 case 'drag':
6632 case 'dragenter':
6633 case 'dragexit':
6634 case 'dragleave':
6635 case 'dragover':
6636 case 'mousemove':
6637 case 'mouseout':
6638 case 'mouseover':
6639 case 'pointermove':
6640 case 'pointerout':
6641 case 'pointerover':
6642 case 'scroll':
6643 case 'toggle':
6644 case 'touchmove':
6645 case 'wheel': // Not used by React but could be by user code:
6646 // eslint-disable-next-line no-fallthrough
6647
6648 case 'mouseenter':
6649 case 'mouseleave':
6650 case 'pointerenter':
6651 case 'pointerleave':
6652 return ContinuousEventPriority;
6653
6654 case 'message':
6655 {
6656 // We might be in the Scheduler callback.
6657 // Eventually this mechanism will be replaced by a check
6658 // of the current priority on the native scheduler.
6659 var schedulerPriority = getCurrentPriorityLevel();
6660
6661 switch (schedulerPriority) {
6662 case ImmediatePriority:
6663 return DiscreteEventPriority;
6664
6665 case UserBlockingPriority:
6666 return ContinuousEventPriority;
6667
6668 case NormalPriority:
6669 case LowPriority:
6670 // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration.
6671 return DefaultEventPriority;
6672
6673 case IdlePriority:
6674 return IdleEventPriority;
6675
6676 default:
6677 return DefaultEventPriority;
6678 }
6679 }
6680
6681 default:
6682 return DefaultEventPriority;
6683 }
6684 }
6685
6686 function addEventBubbleListener(target, eventType, listener) {
6687 target.addEventListener(eventType, listener, false);
6688 return listener;
6689 }
6690 function addEventCaptureListener(target, eventType, listener) {
6691 target.addEventListener(eventType, listener, true);
6692 return listener;
6693 }
6694 function addEventCaptureListenerWithPassiveFlag(target, eventType, listener, passive) {
6695 target.addEventListener(eventType, listener, {
6696 capture: true,
6697 passive: passive
6698 });
6699 return listener;
6700 }
6701 function addEventBubbleListenerWithPassiveFlag(target, eventType, listener, passive) {
6702 target.addEventListener(eventType, listener, {
6703 passive: passive
6704 });
6705 return listener;
6706 }
6707
6708 /**
6709 * These variables store information about text content of a target node,
6710 * allowing comparison of content before and after a given event.
6711 *
6712 * Identify the node where selection currently begins, then observe
6713 * both its text content and its current position in the DOM. Since the
6714 * browser may natively replace the target node during composition, we can
6715 * use its position to find its replacement.
6716 *
6717 *
6718 */
6719 var root = null;
6720 var startText = null;
6721 var fallbackText = null;
6722 function initialize(nativeEventTarget) {
6723 root = nativeEventTarget;
6724 startText = getText();
6725 return true;
6726 }
6727 function reset() {
6728 root = null;
6729 startText = null;
6730 fallbackText = null;
6731 }
6732 function getData() {
6733 if (fallbackText) {
6734 return fallbackText;
6735 }
6736
6737 var start;
6738 var startValue = startText;
6739 var startLength = startValue.length;
6740 var end;
6741 var endValue = getText();
6742 var endLength = endValue.length;
6743
6744 for (start = 0; start < startLength; start++) {
6745 if (startValue[start] !== endValue[start]) {
6746 break;
6747 }
6748 }
6749
6750 var minEnd = startLength - start;
6751
6752 for (end = 1; end <= minEnd; end++) {
6753 if (startValue[startLength - end] !== endValue[endLength - end]) {
6754 break;
6755 }
6756 }
6757
6758 var sliceTail = end > 1 ? 1 - end : undefined;
6759 fallbackText = endValue.slice(start, sliceTail);
6760 return fallbackText;
6761 }
6762 function getText() {
6763 if ('value' in root) {
6764 return root.value;
6765 }
6766
6767 return root.textContent;
6768 }
6769
6770 /**
6771 * `charCode` represents the actual "character code" and is safe to use with
6772 * `String.fromCharCode`. As such, only keys that correspond to printable
6773 * characters produce a valid `charCode`, the only exception to this is Enter.
6774 * The Tab-key is considered non-printable and does not have a `charCode`,
6775 * presumably because it does not produce a tab-character in browsers.
6776 *
6777 * @param {object} nativeEvent Native browser event.
6778 * @return {number} Normalized `charCode` property.
6779 */
6780 function getEventCharCode(nativeEvent) {
6781 var charCode;
6782 var keyCode = nativeEvent.keyCode;
6783
6784 if ('charCode' in nativeEvent) {
6785 charCode = nativeEvent.charCode; // FF does not set `charCode` for the Enter-key, check against `keyCode`.
6786
6787 if (charCode === 0 && keyCode === 13) {
6788 charCode = 13;
6789 }
6790 } else {
6791 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
6792 charCode = keyCode;
6793 } // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
6794 // report Enter as charCode 10 when ctrl is pressed.
6795
6796
6797 if (charCode === 10) {
6798 charCode = 13;
6799 } // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
6800 // Must not discard the (non-)printable Enter-key.
6801
6802
6803 if (charCode >= 32 || charCode === 13) {
6804 return charCode;
6805 }
6806
6807 return 0;
6808 }
6809
6810 function functionThatReturnsTrue() {
6811 return true;
6812 }
6813
6814 function functionThatReturnsFalse() {
6815 return false;
6816 } // This is intentionally a factory so that we have different returned constructors.
6817 // If we had a single constructor, it would be megamorphic and engines would deopt.
6818
6819
6820 function createSyntheticEvent(Interface) {
6821 /**
6822 * Synthetic events are dispatched by event plugins, typically in response to a
6823 * top-level event delegation handler.
6824 *
6825 * These systems should generally use pooling to reduce the frequency of garbage
6826 * collection. The system should check `isPersistent` to determine whether the
6827 * event should be released into the pool after being dispatched. Users that
6828 * need a persisted event should invoke `persist`.
6829 *
6830 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
6831 * normalizing browser quirks. Subclasses do not necessarily have to implement a
6832 * DOM interface; custom application-specific events can also subclass this.
6833 */
6834 function SyntheticBaseEvent(reactName, reactEventType, targetInst, nativeEvent, nativeEventTarget) {
6835 this._reactName = reactName;
6836 this._targetInst = targetInst;
6837 this.type = reactEventType;
6838 this.nativeEvent = nativeEvent;
6839 this.target = nativeEventTarget;
6840 this.currentTarget = null;
6841
6842 for (var _propName in Interface) {
6843 if (!Interface.hasOwnProperty(_propName)) {
6844 continue;
6845 }
6846
6847 var normalize = Interface[_propName];
6848
6849 if (normalize) {
6850 this[_propName] = normalize(nativeEvent);
6851 } else {
6852 this[_propName] = nativeEvent[_propName];
6853 }
6854 }
6855
6856 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
6857
6858 if (defaultPrevented) {
6859 this.isDefaultPrevented = functionThatReturnsTrue;
6860 } else {
6861 this.isDefaultPrevented = functionThatReturnsFalse;
6862 }
6863
6864 this.isPropagationStopped = functionThatReturnsFalse;
6865 return this;
6866 }
6867
6868 assign(SyntheticBaseEvent.prototype, {
6869 preventDefault: function () {
6870 this.defaultPrevented = true;
6871 var event = this.nativeEvent;
6872
6873 if (!event) {
6874 return;
6875 }
6876
6877 if (event.preventDefault) {
6878 event.preventDefault(); // $FlowFixMe - flow is not aware of `unknown` in IE
6879 } else if (typeof event.returnValue !== 'unknown') {
6880 event.returnValue = false;
6881 }
6882
6883 this.isDefaultPrevented = functionThatReturnsTrue;
6884 },
6885 stopPropagation: function () {
6886 var event = this.nativeEvent;
6887
6888 if (!event) {
6889 return;
6890 }
6891
6892 if (event.stopPropagation) {
6893 event.stopPropagation(); // $FlowFixMe - flow is not aware of `unknown` in IE
6894 } else if (typeof event.cancelBubble !== 'unknown') {
6895 // The ChangeEventPlugin registers a "propertychange" event for
6896 // IE. This event does not support bubbling or cancelling, and
6897 // any references to cancelBubble throw "Member not found". A
6898 // typeof check of "unknown" circumvents this issue (and is also
6899 // IE specific).
6900 event.cancelBubble = true;
6901 }
6902
6903 this.isPropagationStopped = functionThatReturnsTrue;
6904 },
6905
6906 /**
6907 * We release all dispatched `SyntheticEvent`s after each event loop, adding
6908 * them back into the pool. This allows a way to hold onto a reference that
6909 * won't be added back into the pool.
6910 */
6911 persist: function () {// Modern event system doesn't use pooling.
6912 },
6913
6914 /**
6915 * Checks if this event should be released back into the pool.
6916 *
6917 * @return {boolean} True if this should not be released, false otherwise.
6918 */
6919 isPersistent: functionThatReturnsTrue
6920 });
6921 return SyntheticBaseEvent;
6922 }
6923 /**
6924 * @interface Event
6925 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6926 */
6927
6928
6929 var EventInterface = {
6930 eventPhase: 0,
6931 bubbles: 0,
6932 cancelable: 0,
6933 timeStamp: function (event) {
6934 return event.timeStamp || Date.now();
6935 },
6936 defaultPrevented: 0,
6937 isTrusted: 0
6938 };
6939 var SyntheticEvent = createSyntheticEvent(EventInterface);
6940
6941 var UIEventInterface = assign({}, EventInterface, {
6942 view: 0,
6943 detail: 0
6944 });
6945
6946 var SyntheticUIEvent = createSyntheticEvent(UIEventInterface);
6947 var lastMovementX;
6948 var lastMovementY;
6949 var lastMouseEvent;
6950
6951 function updateMouseMovementPolyfillState(event) {
6952 if (event !== lastMouseEvent) {
6953 if (lastMouseEvent && event.type === 'mousemove') {
6954 lastMovementX = event.screenX - lastMouseEvent.screenX;
6955 lastMovementY = event.screenY - lastMouseEvent.screenY;
6956 } else {
6957 lastMovementX = 0;
6958 lastMovementY = 0;
6959 }
6960
6961 lastMouseEvent = event;
6962 }
6963 }
6964 /**
6965 * @interface MouseEvent
6966 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6967 */
6968
6969
6970 var MouseEventInterface = assign({}, UIEventInterface, {
6971 screenX: 0,
6972 screenY: 0,
6973 clientX: 0,
6974 clientY: 0,
6975 pageX: 0,
6976 pageY: 0,
6977 ctrlKey: 0,
6978 shiftKey: 0,
6979 altKey: 0,
6980 metaKey: 0,
6981 getModifierState: getEventModifierState,
6982 button: 0,
6983 buttons: 0,
6984 relatedTarget: function (event) {
6985 if (event.relatedTarget === undefined) return event.fromElement === event.srcElement ? event.toElement : event.fromElement;
6986 return event.relatedTarget;
6987 },
6988 movementX: function (event) {
6989 if ('movementX' in event) {
6990 return event.movementX;
6991 }
6992
6993 updateMouseMovementPolyfillState(event);
6994 return lastMovementX;
6995 },
6996 movementY: function (event) {
6997 if ('movementY' in event) {
6998 return event.movementY;
6999 } // Don't need to call updateMouseMovementPolyfillState() here
7000 // because it's guaranteed to have already run when movementX
7001 // was copied.
7002
7003
7004 return lastMovementY;
7005 }
7006 });
7007
7008 var SyntheticMouseEvent = createSyntheticEvent(MouseEventInterface);
7009 /**
7010 * @interface DragEvent
7011 * @see http://www.w3.org/TR/DOM-Level-3-Events/
7012 */
7013
7014 var DragEventInterface = assign({}, MouseEventInterface, {
7015 dataTransfer: 0
7016 });
7017
7018 var SyntheticDragEvent = createSyntheticEvent(DragEventInterface);
7019 /**
7020 * @interface FocusEvent
7021 * @see http://www.w3.org/TR/DOM-Level-3-Events/
7022 */
7023
7024 var FocusEventInterface = assign({}, UIEventInterface, {
7025 relatedTarget: 0
7026 });
7027
7028 var SyntheticFocusEvent = createSyntheticEvent(FocusEventInterface);
7029 /**
7030 * @interface Event
7031 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
7032 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
7033 */
7034
7035 var AnimationEventInterface = assign({}, EventInterface, {
7036 animationName: 0,
7037 elapsedTime: 0,
7038 pseudoElement: 0
7039 });
7040
7041 var SyntheticAnimationEvent = createSyntheticEvent(AnimationEventInterface);
7042 /**
7043 * @interface Event
7044 * @see http://www.w3.org/TR/clipboard-apis/
7045 */
7046
7047 var ClipboardEventInterface = assign({}, EventInterface, {
7048 clipboardData: function (event) {
7049 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
7050 }
7051 });
7052
7053 var SyntheticClipboardEvent = createSyntheticEvent(ClipboardEventInterface);
7054 /**
7055 * @interface Event
7056 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
7057 */
7058
7059 var CompositionEventInterface = assign({}, EventInterface, {
7060 data: 0
7061 });
7062
7063 var SyntheticCompositionEvent = createSyntheticEvent(CompositionEventInterface);
7064 /**
7065 * @interface Event
7066 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
7067 * /#events-inputevents
7068 */
7069 // Happens to share the same list for now.
7070
7071 var SyntheticInputEvent = SyntheticCompositionEvent;
7072 /**
7073 * Normalization of deprecated HTML5 `key` values
7074 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
7075 */
7076
7077 var normalizeKey = {
7078 Esc: 'Escape',
7079 Spacebar: ' ',
7080 Left: 'ArrowLeft',
7081 Up: 'ArrowUp',
7082 Right: 'ArrowRight',
7083 Down: 'ArrowDown',
7084 Del: 'Delete',
7085 Win: 'OS',
7086 Menu: 'ContextMenu',
7087 Apps: 'ContextMenu',
7088 Scroll: 'ScrollLock',
7089 MozPrintableKey: 'Unidentified'
7090 };
7091 /**
7092 * Translation from legacy `keyCode` to HTML5 `key`
7093 * Only special keys supported, all others depend on keyboard layout or browser
7094 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
7095 */
7096
7097 var translateToKey = {
7098 '8': 'Backspace',
7099 '9': 'Tab',
7100 '12': 'Clear',
7101 '13': 'Enter',
7102 '16': 'Shift',
7103 '17': 'Control',
7104 '18': 'Alt',
7105 '19': 'Pause',
7106 '20': 'CapsLock',
7107 '27': 'Escape',
7108 '32': ' ',
7109 '33': 'PageUp',
7110 '34': 'PageDown',
7111 '35': 'End',
7112 '36': 'Home',
7113 '37': 'ArrowLeft',
7114 '38': 'ArrowUp',
7115 '39': 'ArrowRight',
7116 '40': 'ArrowDown',
7117 '45': 'Insert',
7118 '46': 'Delete',
7119 '112': 'F1',
7120 '113': 'F2',
7121 '114': 'F3',
7122 '115': 'F4',
7123 '116': 'F5',
7124 '117': 'F6',
7125 '118': 'F7',
7126 '119': 'F8',
7127 '120': 'F9',
7128 '121': 'F10',
7129 '122': 'F11',
7130 '123': 'F12',
7131 '144': 'NumLock',
7132 '145': 'ScrollLock',
7133 '224': 'Meta'
7134 };
7135 /**
7136 * @param {object} nativeEvent Native browser event.
7137 * @return {string} Normalized `key` property.
7138 */
7139
7140 function getEventKey(nativeEvent) {
7141 if (nativeEvent.key) {
7142 // Normalize inconsistent values reported by browsers due to
7143 // implementations of a working draft specification.
7144 // FireFox implements `key` but returns `MozPrintableKey` for all
7145 // printable characters (normalized to `Unidentified`), ignore it.
7146 var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
7147
7148 if (key !== 'Unidentified') {
7149 return key;
7150 }
7151 } // Browser does not implement `key`, polyfill as much of it as we can.
7152
7153
7154 if (nativeEvent.type === 'keypress') {
7155 var charCode = getEventCharCode(nativeEvent); // The enter-key is technically both printable and non-printable and can
7156 // thus be captured by `keypress`, no other non-printable key should.
7157
7158 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
7159 }
7160
7161 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
7162 // While user keyboard layout determines the actual meaning of each
7163 // `keyCode` value, almost all function keys have a universal value.
7164 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
7165 }
7166
7167 return '';
7168 }
7169 /**
7170 * Translation from modifier key to the associated property in the event.
7171 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
7172 */
7173
7174
7175 var modifierKeyToProp = {
7176 Alt: 'altKey',
7177 Control: 'ctrlKey',
7178 Meta: 'metaKey',
7179 Shift: 'shiftKey'
7180 }; // Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support
7181 // getModifierState. If getModifierState is not supported, we map it to a set of
7182 // modifier keys exposed by the event. In this case, Lock-keys are not supported.
7183
7184 function modifierStateGetter(keyArg) {
7185 var syntheticEvent = this;
7186 var nativeEvent = syntheticEvent.nativeEvent;
7187
7188 if (nativeEvent.getModifierState) {
7189 return nativeEvent.getModifierState(keyArg);
7190 }
7191
7192 var keyProp = modifierKeyToProp[keyArg];
7193 return keyProp ? !!nativeEvent[keyProp] : false;
7194 }
7195
7196 function getEventModifierState(nativeEvent) {
7197 return modifierStateGetter;
7198 }
7199 /**
7200 * @interface KeyboardEvent
7201 * @see http://www.w3.org/TR/DOM-Level-3-Events/
7202 */
7203
7204
7205 var KeyboardEventInterface = assign({}, UIEventInterface, {
7206 key: getEventKey,
7207 code: 0,
7208 location: 0,
7209 ctrlKey: 0,
7210 shiftKey: 0,
7211 altKey: 0,
7212 metaKey: 0,
7213 repeat: 0,
7214 locale: 0,
7215 getModifierState: getEventModifierState,
7216 // Legacy Interface
7217 charCode: function (event) {
7218 // `charCode` is the result of a KeyPress event and represents the value of
7219 // the actual printable character.
7220 // KeyPress is deprecated, but its replacement is not yet final and not
7221 // implemented in any major browser. Only KeyPress has charCode.
7222 if (event.type === 'keypress') {
7223 return getEventCharCode(event);
7224 }
7225
7226 return 0;
7227 },
7228 keyCode: function (event) {
7229 // `keyCode` is the result of a KeyDown/Up event and represents the value of
7230 // physical keyboard key.
7231 // The actual meaning of the value depends on the users' keyboard layout
7232 // which cannot be detected. Assuming that it is a US keyboard layout
7233 // provides a surprisingly accurate mapping for US and European users.
7234 // Due to this, it is left to the user to implement at this time.
7235 if (event.type === 'keydown' || event.type === 'keyup') {
7236 return event.keyCode;
7237 }
7238
7239 return 0;
7240 },
7241 which: function (event) {
7242 // `which` is an alias for either `keyCode` or `charCode` depending on the
7243 // type of the event.
7244 if (event.type === 'keypress') {
7245 return getEventCharCode(event);
7246 }
7247
7248 if (event.type === 'keydown' || event.type === 'keyup') {
7249 return event.keyCode;
7250 }
7251
7252 return 0;
7253 }
7254 });
7255
7256 var SyntheticKeyboardEvent = createSyntheticEvent(KeyboardEventInterface);
7257 /**
7258 * @interface PointerEvent
7259 * @see http://www.w3.org/TR/pointerevents/
7260 */
7261
7262 var PointerEventInterface = assign({}, MouseEventInterface, {
7263 pointerId: 0,
7264 width: 0,
7265 height: 0,
7266 pressure: 0,
7267 tangentialPressure: 0,
7268 tiltX: 0,
7269 tiltY: 0,
7270 twist: 0,
7271 pointerType: 0,
7272 isPrimary: 0
7273 });
7274
7275 var SyntheticPointerEvent = createSyntheticEvent(PointerEventInterface);
7276 /**
7277 * @interface TouchEvent
7278 * @see http://www.w3.org/TR/touch-events/
7279 */
7280
7281 var TouchEventInterface = assign({}, UIEventInterface, {
7282 touches: 0,
7283 targetTouches: 0,
7284 changedTouches: 0,
7285 altKey: 0,
7286 metaKey: 0,
7287 ctrlKey: 0,
7288 shiftKey: 0,
7289 getModifierState: getEventModifierState
7290 });
7291
7292 var SyntheticTouchEvent = createSyntheticEvent(TouchEventInterface);
7293 /**
7294 * @interface Event
7295 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
7296 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
7297 */
7298
7299 var TransitionEventInterface = assign({}, EventInterface, {
7300 propertyName: 0,
7301 elapsedTime: 0,
7302 pseudoElement: 0
7303 });
7304
7305 var SyntheticTransitionEvent = createSyntheticEvent(TransitionEventInterface);
7306 /**
7307 * @interface WheelEvent
7308 * @see http://www.w3.org/TR/DOM-Level-3-Events/
7309 */
7310
7311 var WheelEventInterface = assign({}, MouseEventInterface, {
7312 deltaX: function (event) {
7313 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
7314 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
7315 },
7316 deltaY: function (event) {
7317 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
7318 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
7319 'wheelDelta' in event ? -event.wheelDelta : 0;
7320 },
7321 deltaZ: 0,
7322 // Browsers without "deltaMode" is reporting in raw wheel delta where one
7323 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
7324 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
7325 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
7326 deltaMode: 0
7327 });
7328
7329 var SyntheticWheelEvent = createSyntheticEvent(WheelEventInterface);
7330
7331 var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
7332
7333 var START_KEYCODE = 229;
7334 var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window;
7335 var documentMode = null;
7336
7337 if (canUseDOM && 'documentMode' in document) {
7338 documentMode = document.documentMode;
7339 } // Webkit offers a very useful `textInput` event that can be used to
7340 // directly represent `beforeInput`. The IE `textinput` event is not as
7341 // useful, so we don't use it.
7342
7343
7344 var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode; // In IE9+, we have access to composition events, but the data supplied
7345 // by the native compositionend event may be incorrect. Japanese ideographic
7346 // spaces, for instance (\u3000) are not recorded correctly.
7347
7348 var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
7349 var SPACEBAR_CODE = 32;
7350 var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
7351
7352 function registerEvents() {
7353 registerTwoPhaseEvent('onBeforeInput', ['compositionend', 'keypress', 'textInput', 'paste']);
7354 registerTwoPhaseEvent('onCompositionEnd', ['compositionend', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']);
7355 registerTwoPhaseEvent('onCompositionStart', ['compositionstart', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']);
7356 registerTwoPhaseEvent('onCompositionUpdate', ['compositionupdate', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']);
7357 } // Track whether we've ever handled a keypress on the space key.
7358
7359
7360 var hasSpaceKeypress = false;
7361 /**
7362 * Return whether a native keypress event is assumed to be a command.
7363 * This is required because Firefox fires `keypress` events for key commands
7364 * (cut, copy, select-all, etc.) even though no character is inserted.
7365 */
7366
7367 function isKeypressCommand(nativeEvent) {
7368 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && // ctrlKey && altKey is equivalent to AltGr, and is not a command.
7369 !(nativeEvent.ctrlKey && nativeEvent.altKey);
7370 }
7371 /**
7372 * Translate native top level events into event types.
7373 */
7374
7375
7376 function getCompositionEventType(domEventName) {
7377 switch (domEventName) {
7378 case 'compositionstart':
7379 return 'onCompositionStart';
7380
7381 case 'compositionend':
7382 return 'onCompositionEnd';
7383
7384 case 'compositionupdate':
7385 return 'onCompositionUpdate';
7386 }
7387 }
7388 /**
7389 * Does our fallback best-guess model think this event signifies that
7390 * composition has begun?
7391 */
7392
7393
7394 function isFallbackCompositionStart(domEventName, nativeEvent) {
7395 return domEventName === 'keydown' && nativeEvent.keyCode === START_KEYCODE;
7396 }
7397 /**
7398 * Does our fallback mode think that this event is the end of composition?
7399 */
7400
7401
7402 function isFallbackCompositionEnd(domEventName, nativeEvent) {
7403 switch (domEventName) {
7404 case 'keyup':
7405 // Command keys insert or clear IME input.
7406 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
7407
7408 case 'keydown':
7409 // Expect IME keyCode on each keydown. If we get any other
7410 // code we must have exited earlier.
7411 return nativeEvent.keyCode !== START_KEYCODE;
7412
7413 case 'keypress':
7414 case 'mousedown':
7415 case 'focusout':
7416 // Events are not possible without cancelling IME.
7417 return true;
7418
7419 default:
7420 return false;
7421 }
7422 }
7423 /**
7424 * Google Input Tools provides composition data via a CustomEvent,
7425 * with the `data` property populated in the `detail` object. If this
7426 * is available on the event object, use it. If not, this is a plain
7427 * composition event and we have nothing special to extract.
7428 *
7429 * @param {object} nativeEvent
7430 * @return {?string}
7431 */
7432
7433
7434 function getDataFromCustomEvent(nativeEvent) {
7435 var detail = nativeEvent.detail;
7436
7437 if (typeof detail === 'object' && 'data' in detail) {
7438 return detail.data;
7439 }
7440
7441 return null;
7442 }
7443 /**
7444 * Check if a composition event was triggered by Korean IME.
7445 * Our fallback mode does not work well with IE's Korean IME,
7446 * so just use native composition events when Korean IME is used.
7447 * Although CompositionEvent.locale property is deprecated,
7448 * it is available in IE, where our fallback mode is enabled.
7449 *
7450 * @param {object} nativeEvent
7451 * @return {boolean}
7452 */
7453
7454
7455 function isUsingKoreanIME(nativeEvent) {
7456 return nativeEvent.locale === 'ko';
7457 } // Track the current IME composition status, if any.
7458
7459
7460 var isComposing = false;
7461 /**
7462 * @return {?object} A SyntheticCompositionEvent.
7463 */
7464
7465 function extractCompositionEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget) {
7466 var eventType;
7467 var fallbackData;
7468
7469 if (canUseCompositionEvent) {
7470 eventType = getCompositionEventType(domEventName);
7471 } else if (!isComposing) {
7472 if (isFallbackCompositionStart(domEventName, nativeEvent)) {
7473 eventType = 'onCompositionStart';
7474 }
7475 } else if (isFallbackCompositionEnd(domEventName, nativeEvent)) {
7476 eventType = 'onCompositionEnd';
7477 }
7478
7479 if (!eventType) {
7480 return null;
7481 }
7482
7483 if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {
7484 // The current composition is stored statically and must not be
7485 // overwritten while composition continues.
7486 if (!isComposing && eventType === 'onCompositionStart') {
7487 isComposing = initialize(nativeEventTarget);
7488 } else if (eventType === 'onCompositionEnd') {
7489 if (isComposing) {
7490 fallbackData = getData();
7491 }
7492 }
7493 }
7494
7495 var listeners = accumulateTwoPhaseListeners(targetInst, eventType);
7496
7497 if (listeners.length > 0) {
7498 var event = new SyntheticCompositionEvent(eventType, domEventName, null, nativeEvent, nativeEventTarget);
7499 dispatchQueue.push({
7500 event: event,
7501 listeners: listeners
7502 });
7503
7504 if (fallbackData) {
7505 // Inject data generated from fallback path into the synthetic event.
7506 // This matches the property of native CompositionEventInterface.
7507 event.data = fallbackData;
7508 } else {
7509 var customData = getDataFromCustomEvent(nativeEvent);
7510
7511 if (customData !== null) {
7512 event.data = customData;
7513 }
7514 }
7515 }
7516 }
7517
7518 function getNativeBeforeInputChars(domEventName, nativeEvent) {
7519 switch (domEventName) {
7520 case 'compositionend':
7521 return getDataFromCustomEvent(nativeEvent);
7522
7523 case 'keypress':
7524 /**
7525 * If native `textInput` events are available, our goal is to make
7526 * use of them. However, there is a special case: the spacebar key.
7527 * In Webkit, preventing default on a spacebar `textInput` event
7528 * cancels character insertion, but it *also* causes the browser
7529 * to fall back to its default spacebar behavior of scrolling the
7530 * page.
7531 *
7532 * Tracking at:
7533 * https://code.google.com/p/chromium/issues/detail?id=355103
7534 *
7535 * To avoid this issue, use the keypress event as if no `textInput`
7536 * event is available.
7537 */
7538 var which = nativeEvent.which;
7539
7540 if (which !== SPACEBAR_CODE) {
7541 return null;
7542 }
7543
7544 hasSpaceKeypress = true;
7545 return SPACEBAR_CHAR;
7546
7547 case 'textInput':
7548 // Record the characters to be added to the DOM.
7549 var chars = nativeEvent.data; // If it's a spacebar character, assume that we have already handled
7550 // it at the keypress level and bail immediately. Android Chrome
7551 // doesn't give us keycodes, so we need to ignore it.
7552
7553 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
7554 return null;
7555 }
7556
7557 return chars;
7558
7559 default:
7560 // For other native event types, do nothing.
7561 return null;
7562 }
7563 }
7564 /**
7565 * For browsers that do not provide the `textInput` event, extract the
7566 * appropriate string to use for SyntheticInputEvent.
7567 */
7568
7569
7570 function getFallbackBeforeInputChars(domEventName, nativeEvent) {
7571 // If we are currently composing (IME) and using a fallback to do so,
7572 // try to extract the composed characters from the fallback object.
7573 // If composition event is available, we extract a string only at
7574 // compositionevent, otherwise extract it at fallback events.
7575 if (isComposing) {
7576 if (domEventName === 'compositionend' || !canUseCompositionEvent && isFallbackCompositionEnd(domEventName, nativeEvent)) {
7577 var chars = getData();
7578 reset();
7579 isComposing = false;
7580 return chars;
7581 }
7582
7583 return null;
7584 }
7585
7586 switch (domEventName) {
7587 case 'paste':
7588 // If a paste event occurs after a keypress, throw out the input
7589 // chars. Paste events should not lead to BeforeInput events.
7590 return null;
7591
7592 case 'keypress':
7593 /**
7594 * As of v27, Firefox may fire keypress events even when no character
7595 * will be inserted. A few possibilities:
7596 *
7597 * - `which` is `0`. Arrow keys, Esc key, etc.
7598 *
7599 * - `which` is the pressed key code, but no char is available.
7600 * Ex: 'AltGr + d` in Polish. There is no modified character for
7601 * this key combination and no character is inserted into the
7602 * document, but FF fires the keypress for char code `100` anyway.
7603 * No `input` event will occur.
7604 *
7605 * - `which` is the pressed key code, but a command combination is
7606 * being used. Ex: `Cmd+C`. No character is inserted, and no
7607 * `input` event will occur.
7608 */
7609 if (!isKeypressCommand(nativeEvent)) {
7610 // IE fires the `keypress` event when a user types an emoji via
7611 // Touch keyboard of Windows. In such a case, the `char` property
7612 // holds an emoji character like `\uD83D\uDE0A`. Because its length
7613 // is 2, the property `which` does not represent an emoji correctly.
7614 // In such a case, we directly return the `char` property instead of
7615 // using `which`.
7616 if (nativeEvent.char && nativeEvent.char.length > 1) {
7617 return nativeEvent.char;
7618 } else if (nativeEvent.which) {
7619 return String.fromCharCode(nativeEvent.which);
7620 }
7621 }
7622
7623 return null;
7624
7625 case 'compositionend':
7626 return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data;
7627
7628 default:
7629 return null;
7630 }
7631 }
7632 /**
7633 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
7634 * `textInput` or fallback behavior.
7635 *
7636 * @return {?object} A SyntheticInputEvent.
7637 */
7638
7639
7640 function extractBeforeInputEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget) {
7641 var chars;
7642
7643 if (canUseTextInputEvent) {
7644 chars = getNativeBeforeInputChars(domEventName, nativeEvent);
7645 } else {
7646 chars = getFallbackBeforeInputChars(domEventName, nativeEvent);
7647 } // If no characters are being inserted, no BeforeInput event should
7648 // be fired.
7649
7650
7651 if (!chars) {
7652 return null;
7653 }
7654
7655 var listeners = accumulateTwoPhaseListeners(targetInst, 'onBeforeInput');
7656
7657 if (listeners.length > 0) {
7658 var event = new SyntheticInputEvent('onBeforeInput', 'beforeinput', null, nativeEvent, nativeEventTarget);
7659 dispatchQueue.push({
7660 event: event,
7661 listeners: listeners
7662 });
7663 event.data = chars;
7664 }
7665 }
7666 /**
7667 * Create an `onBeforeInput` event to match
7668 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
7669 *
7670 * This event plugin is based on the native `textInput` event
7671 * available in Chrome, Safari, Opera, and IE. This event fires after
7672 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
7673 *
7674 * `beforeInput` is spec'd but not implemented in any browsers, and
7675 * the `input` event does not provide any useful information about what has
7676 * actually been added, contrary to the spec. Thus, `textInput` is the best
7677 * available event to identify the characters that have actually been inserted
7678 * into the target node.
7679 *
7680 * This plugin is also responsible for emitting `composition` events, thus
7681 * allowing us to share composition fallback code for both `beforeInput` and
7682 * `composition` event types.
7683 */
7684
7685
7686 function extractEvents(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
7687 extractCompositionEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
7688 extractBeforeInputEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
7689 }
7690
7691 /**
7692 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
7693 */
7694 var supportedInputTypes = {
7695 color: true,
7696 date: true,
7697 datetime: true,
7698 'datetime-local': true,
7699 email: true,
7700 month: true,
7701 number: true,
7702 password: true,
7703 range: true,
7704 search: true,
7705 tel: true,
7706 text: true,
7707 time: true,
7708 url: true,
7709 week: true
7710 };
7711
7712 function isTextInputElement(elem) {
7713 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
7714
7715 if (nodeName === 'input') {
7716 return !!supportedInputTypes[elem.type];
7717 }
7718
7719 if (nodeName === 'textarea') {
7720 return true;
7721 }
7722
7723 return false;
7724 }
7725
7726 /**
7727 * Checks if an event is supported in the current execution environment.
7728 *
7729 * NOTE: This will not work correctly for non-generic events such as `change`,
7730 * `reset`, `load`, `error`, and `select`.
7731 *
7732 * Borrows from Modernizr.
7733 *
7734 * @param {string} eventNameSuffix Event name, e.g. "click".
7735 * @return {boolean} True if the event is supported.
7736 * @internal
7737 * @license Modernizr 3.0.0pre (Custom Build) | MIT
7738 */
7739
7740 function isEventSupported(eventNameSuffix) {
7741 if (!canUseDOM) {
7742 return false;
7743 }
7744
7745 var eventName = 'on' + eventNameSuffix;
7746 var isSupported = (eventName in document);
7747
7748 if (!isSupported) {
7749 var element = document.createElement('div');
7750 element.setAttribute(eventName, 'return;');
7751 isSupported = typeof element[eventName] === 'function';
7752 }
7753
7754 return isSupported;
7755 }
7756
7757 function registerEvents$1() {
7758 registerTwoPhaseEvent('onChange', ['change', 'click', 'focusin', 'focusout', 'input', 'keydown', 'keyup', 'selectionchange']);
7759 }
7760
7761 function createAndAccumulateChangeEvent(dispatchQueue, inst, nativeEvent, target) {
7762 // Flag this event loop as needing state restore.
7763 enqueueStateRestore(target);
7764 var listeners = accumulateTwoPhaseListeners(inst, 'onChange');
7765
7766 if (listeners.length > 0) {
7767 var event = new SyntheticEvent('onChange', 'change', null, nativeEvent, target);
7768 dispatchQueue.push({
7769 event: event,
7770 listeners: listeners
7771 });
7772 }
7773 }
7774 /**
7775 * For IE shims
7776 */
7777
7778
7779 var activeElement = null;
7780 var activeElementInst = null;
7781 /**
7782 * SECTION: handle `change` event
7783 */
7784
7785 function shouldUseChangeEvent(elem) {
7786 var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
7787 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
7788 }
7789
7790 function manualDispatchChangeEvent(nativeEvent) {
7791 var dispatchQueue = [];
7792 createAndAccumulateChangeEvent(dispatchQueue, activeElementInst, nativeEvent, getEventTarget(nativeEvent)); // If change and propertychange bubbled, we'd just bind to it like all the
7793 // other events and have it go through ReactBrowserEventEmitter. Since it
7794 // doesn't, we manually listen for the events and so we have to enqueue and
7795 // process the abstract event manually.
7796 //
7797 // Batching is necessary here in order to ensure that all event handlers run
7798 // before the next rerender (including event handlers attached to ancestor
7799 // elements instead of directly on the input). Without this, controlled
7800 // components don't work properly in conjunction with event bubbling because
7801 // the component is rerendered and the value reverted before all the event
7802 // handlers can run. See https://github.com/facebook/react/issues/708.
7803
7804 batchedUpdates(runEventInBatch, dispatchQueue);
7805 }
7806
7807 function runEventInBatch(dispatchQueue) {
7808 processDispatchQueue(dispatchQueue, 0);
7809 }
7810
7811 function getInstIfValueChanged(targetInst) {
7812 var targetNode = getNodeFromInstance(targetInst);
7813
7814 if (updateValueIfChanged(targetNode)) {
7815 return targetInst;
7816 }
7817 }
7818
7819 function getTargetInstForChangeEvent(domEventName, targetInst) {
7820 if (domEventName === 'change') {
7821 return targetInst;
7822 }
7823 }
7824 /**
7825 * SECTION: handle `input` event
7826 */
7827
7828
7829 var isInputEventSupported = false;
7830
7831 if (canUseDOM) {
7832 // IE9 claims to support the input event but fails to trigger it when
7833 // deleting text, so we ignore its input events.
7834 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
7835 }
7836 /**
7837 * (For IE <=9) Starts tracking propertychange events on the passed-in element
7838 * and override the value property so that we can distinguish user events from
7839 * value changes in JS.
7840 */
7841
7842
7843 function startWatchingForValueChange(target, targetInst) {
7844 activeElement = target;
7845 activeElementInst = targetInst;
7846 activeElement.attachEvent('onpropertychange', handlePropertyChange);
7847 }
7848 /**
7849 * (For IE <=9) Removes the event listeners from the currently-tracked element,
7850 * if any exists.
7851 */
7852
7853
7854 function stopWatchingForValueChange() {
7855 if (!activeElement) {
7856 return;
7857 }
7858
7859 activeElement.detachEvent('onpropertychange', handlePropertyChange);
7860 activeElement = null;
7861 activeElementInst = null;
7862 }
7863 /**
7864 * (For IE <=9) Handles a propertychange event, sending a `change` event if
7865 * the value of the active element has changed.
7866 */
7867
7868
7869 function handlePropertyChange(nativeEvent) {
7870 if (nativeEvent.propertyName !== 'value') {
7871 return;
7872 }
7873
7874 if (getInstIfValueChanged(activeElementInst)) {
7875 manualDispatchChangeEvent(nativeEvent);
7876 }
7877 }
7878
7879 function handleEventsForInputEventPolyfill(domEventName, target, targetInst) {
7880 if (domEventName === 'focusin') {
7881 // In IE9, propertychange fires for most input events but is buggy and
7882 // doesn't fire when text is deleted, but conveniently, selectionchange
7883 // appears to fire in all of the remaining cases so we catch those and
7884 // forward the event if the value has changed
7885 // In either case, we don't want to call the event handler if the value
7886 // is changed from JS so we redefine a setter for `.value` that updates
7887 // our activeElementValue variable, allowing us to ignore those changes
7888 //
7889 // stopWatching() should be a noop here but we call it just in case we
7890 // missed a blur event somehow.
7891 stopWatchingForValueChange();
7892 startWatchingForValueChange(target, targetInst);
7893 } else if (domEventName === 'focusout') {
7894 stopWatchingForValueChange();
7895 }
7896 } // For IE8 and IE9.
7897
7898
7899 function getTargetInstForInputEventPolyfill(domEventName, targetInst) {
7900 if (domEventName === 'selectionchange' || domEventName === 'keyup' || domEventName === 'keydown') {
7901 // On the selectionchange event, the target is just document which isn't
7902 // helpful for us so just check activeElement instead.
7903 //
7904 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
7905 // propertychange on the first input event after setting `value` from a
7906 // script and fires only keydown, keypress, keyup. Catching keyup usually
7907 // gets it and catching keydown lets us fire an event for the first
7908 // keystroke if user does a key repeat (it'll be a little delayed: right
7909 // before the second keystroke). Other input methods (e.g., paste) seem to
7910 // fire selectionchange normally.
7911 return getInstIfValueChanged(activeElementInst);
7912 }
7913 }
7914 /**
7915 * SECTION: handle `click` event
7916 */
7917
7918
7919 function shouldUseClickEvent(elem) {
7920 // Use the `click` event to detect changes to checkbox and radio inputs.
7921 // This approach works across all browsers, whereas `change` does not fire
7922 // until `blur` in IE8.
7923 var nodeName = elem.nodeName;
7924 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
7925 }
7926
7927 function getTargetInstForClickEvent(domEventName, targetInst) {
7928 if (domEventName === 'click') {
7929 return getInstIfValueChanged(targetInst);
7930 }
7931 }
7932
7933 function getTargetInstForInputOrChangeEvent(domEventName, targetInst) {
7934 if (domEventName === 'input' || domEventName === 'change') {
7935 return getInstIfValueChanged(targetInst);
7936 }
7937 }
7938
7939 function handleControlledInputBlur(node) {
7940 var state = node._wrapperState;
7941
7942 if (!state || !state.controlled || node.type !== 'number') {
7943 return;
7944 }
7945
7946 {
7947 // If controlled, assign the value attribute to the current value on blur
7948 setDefaultValue(node, 'number', node.value);
7949 }
7950 }
7951 /**
7952 * This plugin creates an `onChange` event that normalizes change events
7953 * across form elements. This event fires at a time when it's possible to
7954 * change the element's value without seeing a flicker.
7955 *
7956 * Supported elements are:
7957 * - input (see `isTextInputElement`)
7958 * - textarea
7959 * - select
7960 */
7961
7962
7963 function extractEvents$1(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
7964 var targetNode = targetInst ? getNodeFromInstance(targetInst) : window;
7965 var getTargetInstFunc, handleEventFunc;
7966
7967 if (shouldUseChangeEvent(targetNode)) {
7968 getTargetInstFunc = getTargetInstForChangeEvent;
7969 } else if (isTextInputElement(targetNode)) {
7970 if (isInputEventSupported) {
7971 getTargetInstFunc = getTargetInstForInputOrChangeEvent;
7972 } else {
7973 getTargetInstFunc = getTargetInstForInputEventPolyfill;
7974 handleEventFunc = handleEventsForInputEventPolyfill;
7975 }
7976 } else if (shouldUseClickEvent(targetNode)) {
7977 getTargetInstFunc = getTargetInstForClickEvent;
7978 }
7979
7980 if (getTargetInstFunc) {
7981 var inst = getTargetInstFunc(domEventName, targetInst);
7982
7983 if (inst) {
7984 createAndAccumulateChangeEvent(dispatchQueue, inst, nativeEvent, nativeEventTarget);
7985 return;
7986 }
7987 }
7988
7989 if (handleEventFunc) {
7990 handleEventFunc(domEventName, targetNode, targetInst);
7991 } // When blurring, set the value attribute for number inputs
7992
7993
7994 if (domEventName === 'focusout') {
7995 handleControlledInputBlur(targetNode);
7996 }
7997 }
7998
7999 function registerEvents$2() {
8000 registerDirectEvent('onMouseEnter', ['mouseout', 'mouseover']);
8001 registerDirectEvent('onMouseLeave', ['mouseout', 'mouseover']);
8002 registerDirectEvent('onPointerEnter', ['pointerout', 'pointerover']);
8003 registerDirectEvent('onPointerLeave', ['pointerout', 'pointerover']);
8004 }
8005 /**
8006 * For almost every interaction we care about, there will be both a top-level
8007 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
8008 * we do not extract duplicate events. However, moving the mouse into the
8009 * browser from outside will not fire a `mouseout` event. In this case, we use
8010 * the `mouseover` top-level event.
8011 */
8012
8013
8014 function extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
8015 var isOverEvent = domEventName === 'mouseover' || domEventName === 'pointerover';
8016 var isOutEvent = domEventName === 'mouseout' || domEventName === 'pointerout';
8017
8018 if (isOverEvent && !isReplayingEvent(nativeEvent)) {
8019 // If this is an over event with a target, we might have already dispatched
8020 // the event in the out event of the other target. If this is replayed,
8021 // then it's because we couldn't dispatch against this target previously
8022 // so we have to do it now instead.
8023 var related = nativeEvent.relatedTarget || nativeEvent.fromElement;
8024
8025 if (related) {
8026 // If the related node is managed by React, we can assume that we have
8027 // already dispatched the corresponding events during its mouseout.
8028 if (getClosestInstanceFromNode(related) || isContainerMarkedAsRoot(related)) {
8029 return;
8030 }
8031 }
8032 }
8033
8034 if (!isOutEvent && !isOverEvent) {
8035 // Must not be a mouse or pointer in or out - ignoring.
8036 return;
8037 }
8038
8039 var win; // TODO: why is this nullable in the types but we read from it?
8040
8041 if (nativeEventTarget.window === nativeEventTarget) {
8042 // `nativeEventTarget` is probably a window object.
8043 win = nativeEventTarget;
8044 } else {
8045 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
8046 var doc = nativeEventTarget.ownerDocument;
8047
8048 if (doc) {
8049 win = doc.defaultView || doc.parentWindow;
8050 } else {
8051 win = window;
8052 }
8053 }
8054
8055 var from;
8056 var to;
8057
8058 if (isOutEvent) {
8059 var _related = nativeEvent.relatedTarget || nativeEvent.toElement;
8060
8061 from = targetInst;
8062 to = _related ? getClosestInstanceFromNode(_related) : null;
8063
8064 if (to !== null) {
8065 var nearestMounted = getNearestMountedFiber(to);
8066
8067 if (to !== nearestMounted || to.tag !== HostComponent && to.tag !== HostText) {
8068 to = null;
8069 }
8070 }
8071 } else {
8072 // Moving to a node from outside the window.
8073 from = null;
8074 to = targetInst;
8075 }
8076
8077 if (from === to) {
8078 // Nothing pertains to our managed components.
8079 return;
8080 }
8081
8082 var SyntheticEventCtor = SyntheticMouseEvent;
8083 var leaveEventType = 'onMouseLeave';
8084 var enterEventType = 'onMouseEnter';
8085 var eventTypePrefix = 'mouse';
8086
8087 if (domEventName === 'pointerout' || domEventName === 'pointerover') {
8088 SyntheticEventCtor = SyntheticPointerEvent;
8089 leaveEventType = 'onPointerLeave';
8090 enterEventType = 'onPointerEnter';
8091 eventTypePrefix = 'pointer';
8092 }
8093
8094 var fromNode = from == null ? win : getNodeFromInstance(from);
8095 var toNode = to == null ? win : getNodeFromInstance(to);
8096 var leave = new SyntheticEventCtor(leaveEventType, eventTypePrefix + 'leave', from, nativeEvent, nativeEventTarget);
8097 leave.target = fromNode;
8098 leave.relatedTarget = toNode;
8099 var enter = null; // We should only process this nativeEvent if we are processing
8100 // the first ancestor. Next time, we will ignore the event.
8101
8102 var nativeTargetInst = getClosestInstanceFromNode(nativeEventTarget);
8103
8104 if (nativeTargetInst === targetInst) {
8105 var enterEvent = new SyntheticEventCtor(enterEventType, eventTypePrefix + 'enter', to, nativeEvent, nativeEventTarget);
8106 enterEvent.target = toNode;
8107 enterEvent.relatedTarget = fromNode;
8108 enter = enterEvent;
8109 }
8110
8111 accumulateEnterLeaveTwoPhaseListeners(dispatchQueue, leave, enter, from, to);
8112 }
8113
8114 /**
8115 * inlined Object.is polyfill to avoid requiring consumers ship their own
8116 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
8117 */
8118 function is(x, y) {
8119 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
8120 ;
8121 }
8122
8123 var objectIs = typeof Object.is === 'function' ? Object.is : is;
8124
8125 /**
8126 * Performs equality by iterating through keys on an object and returning false
8127 * when any key has values which are not strictly equal between the arguments.
8128 * Returns true when the values of all keys are strictly equal.
8129 */
8130
8131 function shallowEqual(objA, objB) {
8132 if (objectIs(objA, objB)) {
8133 return true;
8134 }
8135
8136 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
8137 return false;
8138 }
8139
8140 var keysA = Object.keys(objA);
8141 var keysB = Object.keys(objB);
8142
8143 if (keysA.length !== keysB.length) {
8144 return false;
8145 } // Test for A's keys different from B.
8146
8147
8148 for (var i = 0; i < keysA.length; i++) {
8149 var currentKey = keysA[i];
8150
8151 if (!hasOwnProperty.call(objB, currentKey) || !objectIs(objA[currentKey], objB[currentKey])) {
8152 return false;
8153 }
8154 }
8155
8156 return true;
8157 }
8158
8159 /**
8160 * Given any node return the first leaf node without children.
8161 *
8162 * @param {DOMElement|DOMTextNode} node
8163 * @return {DOMElement|DOMTextNode}
8164 */
8165
8166 function getLeafNode(node) {
8167 while (node && node.firstChild) {
8168 node = node.firstChild;
8169 }
8170
8171 return node;
8172 }
8173 /**
8174 * Get the next sibling within a container. This will walk up the
8175 * DOM if a node's siblings have been exhausted.
8176 *
8177 * @param {DOMElement|DOMTextNode} node
8178 * @return {?DOMElement|DOMTextNode}
8179 */
8180
8181
8182 function getSiblingNode(node) {
8183 while (node) {
8184 if (node.nextSibling) {
8185 return node.nextSibling;
8186 }
8187
8188 node = node.parentNode;
8189 }
8190 }
8191 /**
8192 * Get object describing the nodes which contain characters at offset.
8193 *
8194 * @param {DOMElement|DOMTextNode} root
8195 * @param {number} offset
8196 * @return {?object}
8197 */
8198
8199
8200 function getNodeForCharacterOffset(root, offset) {
8201 var node = getLeafNode(root);
8202 var nodeStart = 0;
8203 var nodeEnd = 0;
8204
8205 while (node) {
8206 if (node.nodeType === TEXT_NODE) {
8207 nodeEnd = nodeStart + node.textContent.length;
8208
8209 if (nodeStart <= offset && nodeEnd >= offset) {
8210 return {
8211 node: node,
8212 offset: offset - nodeStart
8213 };
8214 }
8215
8216 nodeStart = nodeEnd;
8217 }
8218
8219 node = getLeafNode(getSiblingNode(node));
8220 }
8221 }
8222
8223 /**
8224 * @param {DOMElement} outerNode
8225 * @return {?object}
8226 */
8227
8228 function getOffsets(outerNode) {
8229 var ownerDocument = outerNode.ownerDocument;
8230 var win = ownerDocument && ownerDocument.defaultView || window;
8231 var selection = win.getSelection && win.getSelection();
8232
8233 if (!selection || selection.rangeCount === 0) {
8234 return null;
8235 }
8236
8237 var anchorNode = selection.anchorNode,
8238 anchorOffset = selection.anchorOffset,
8239 focusNode = selection.focusNode,
8240 focusOffset = selection.focusOffset; // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
8241 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
8242 // expose properties, triggering a "Permission denied error" if any of its
8243 // properties are accessed. The only seemingly possible way to avoid erroring
8244 // is to access a property that typically works for non-anonymous divs and
8245 // catch any error that may otherwise arise. See
8246 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
8247
8248 try {
8249 /* eslint-disable no-unused-expressions */
8250 anchorNode.nodeType;
8251 focusNode.nodeType;
8252 /* eslint-enable no-unused-expressions */
8253 } catch (e) {
8254 return null;
8255 }
8256
8257 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
8258 }
8259 /**
8260 * Returns {start, end} where `start` is the character/codepoint index of
8261 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
8262 * `end` is the index of (focusNode, focusOffset).
8263 *
8264 * Returns null if you pass in garbage input but we should probably just crash.
8265 *
8266 * Exported only for testing.
8267 */
8268
8269 function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
8270 var length = 0;
8271 var start = -1;
8272 var end = -1;
8273 var indexWithinAnchor = 0;
8274 var indexWithinFocus = 0;
8275 var node = outerNode;
8276 var parentNode = null;
8277
8278 outer: while (true) {
8279 var next = null;
8280
8281 while (true) {
8282 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
8283 start = length + anchorOffset;
8284 }
8285
8286 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
8287 end = length + focusOffset;
8288 }
8289
8290 if (node.nodeType === TEXT_NODE) {
8291 length += node.nodeValue.length;
8292 }
8293
8294 if ((next = node.firstChild) === null) {
8295 break;
8296 } // Moving from `node` to its first child `next`.
8297
8298
8299 parentNode = node;
8300 node = next;
8301 }
8302
8303 while (true) {
8304 if (node === outerNode) {
8305 // If `outerNode` has children, this is always the second time visiting
8306 // it. If it has no children, this is still the first loop, and the only
8307 // valid selection is anchorNode and focusNode both equal to this node
8308 // and both offsets 0, in which case we will have handled above.
8309 break outer;
8310 }
8311
8312 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
8313 start = length;
8314 }
8315
8316 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
8317 end = length;
8318 }
8319
8320 if ((next = node.nextSibling) !== null) {
8321 break;
8322 }
8323
8324 node = parentNode;
8325 parentNode = node.parentNode;
8326 } // Moving from `node` to its next sibling `next`.
8327
8328
8329 node = next;
8330 }
8331
8332 if (start === -1 || end === -1) {
8333 // This should never happen. (Would happen if the anchor/focus nodes aren't
8334 // actually inside the passed-in node.)
8335 return null;
8336 }
8337
8338 return {
8339 start: start,
8340 end: end
8341 };
8342 }
8343 /**
8344 * In modern non-IE browsers, we can support both forward and backward
8345 * selections.
8346 *
8347 * Note: IE10+ supports the Selection object, but it does not support
8348 * the `extend` method, which means that even in modern IE, it's not possible
8349 * to programmatically create a backward selection. Thus, for all IE
8350 * versions, we use the old IE API to create our selections.
8351 *
8352 * @param {DOMElement|DOMTextNode} node
8353 * @param {object} offsets
8354 */
8355
8356 function setOffsets(node, offsets) {
8357 var doc = node.ownerDocument || document;
8358 var win = doc && doc.defaultView || window; // Edge fails with "Object expected" in some scenarios.
8359 // (For instance: TinyMCE editor used in a list component that supports pasting to add more,
8360 // fails when pasting 100+ items)
8361
8362 if (!win.getSelection) {
8363 return;
8364 }
8365
8366 var selection = win.getSelection();
8367 var length = node.textContent.length;
8368 var start = Math.min(offsets.start, length);
8369 var end = offsets.end === undefined ? start : Math.min(offsets.end, length); // IE 11 uses modern selection, but doesn't support the extend method.
8370 // Flip backward selections, so we can set with a single range.
8371
8372 if (!selection.extend && start > end) {
8373 var temp = end;
8374 end = start;
8375 start = temp;
8376 }
8377
8378 var startMarker = getNodeForCharacterOffset(node, start);
8379 var endMarker = getNodeForCharacterOffset(node, end);
8380
8381 if (startMarker && endMarker) {
8382 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
8383 return;
8384 }
8385
8386 var range = doc.createRange();
8387 range.setStart(startMarker.node, startMarker.offset);
8388 selection.removeAllRanges();
8389
8390 if (start > end) {
8391 selection.addRange(range);
8392 selection.extend(endMarker.node, endMarker.offset);
8393 } else {
8394 range.setEnd(endMarker.node, endMarker.offset);
8395 selection.addRange(range);
8396 }
8397 }
8398 }
8399
8400 function isTextNode(node) {
8401 return node && node.nodeType === TEXT_NODE;
8402 }
8403
8404 function containsNode(outerNode, innerNode) {
8405 if (!outerNode || !innerNode) {
8406 return false;
8407 } else if (outerNode === innerNode) {
8408 return true;
8409 } else if (isTextNode(outerNode)) {
8410 return false;
8411 } else if (isTextNode(innerNode)) {
8412 return containsNode(outerNode, innerNode.parentNode);
8413 } else if ('contains' in outerNode) {
8414 return outerNode.contains(innerNode);
8415 } else if (outerNode.compareDocumentPosition) {
8416 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
8417 } else {
8418 return false;
8419 }
8420 }
8421
8422 function isInDocument(node) {
8423 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);
8424 }
8425
8426 function isSameOriginFrame(iframe) {
8427 try {
8428 // Accessing the contentDocument of a HTMLIframeElement can cause the browser
8429 // to throw, e.g. if it has a cross-origin src attribute.
8430 // Safari will show an error in the console when the access results in "Blocked a frame with origin". e.g:
8431 // iframe.contentDocument.defaultView;
8432 // A safety way is to access one of the cross origin properties: Window or Location
8433 // Which might result in "SecurityError" DOM Exception and it is compatible to Safari.
8434 // https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl
8435 return typeof iframe.contentWindow.location.href === 'string';
8436 } catch (err) {
8437 return false;
8438 }
8439 }
8440
8441 function getActiveElementDeep() {
8442 var win = window;
8443 var element = getActiveElement();
8444
8445 while (element instanceof win.HTMLIFrameElement) {
8446 if (isSameOriginFrame(element)) {
8447 win = element.contentWindow;
8448 } else {
8449 return element;
8450 }
8451
8452 element = getActiveElement(win.document);
8453 }
8454
8455 return element;
8456 }
8457 /**
8458 * @ReactInputSelection: React input selection module. Based on Selection.js,
8459 * but modified to be suitable for react and has a couple of bug fixes (doesn't
8460 * assume buttons have range selections allowed).
8461 * Input selection module for React.
8462 */
8463
8464 /**
8465 * @hasSelectionCapabilities: we get the element types that support selection
8466 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`
8467 * and `selectionEnd` rows.
8468 */
8469
8470
8471 function hasSelectionCapabilities(elem) {
8472 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
8473 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');
8474 }
8475 function getSelectionInformation() {
8476 var focusedElem = getActiveElementDeep();
8477 return {
8478 focusedElem: focusedElem,
8479 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection(focusedElem) : null
8480 };
8481 }
8482 /**
8483 * @restoreSelection: If any selection information was potentially lost,
8484 * restore it. This is useful when performing operations that could remove dom
8485 * nodes and place them back in, resulting in focus being lost.
8486 */
8487
8488 function restoreSelection(priorSelectionInformation) {
8489 var curFocusedElem = getActiveElementDeep();
8490 var priorFocusedElem = priorSelectionInformation.focusedElem;
8491 var priorSelectionRange = priorSelectionInformation.selectionRange;
8492
8493 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
8494 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
8495 setSelection(priorFocusedElem, priorSelectionRange);
8496 } // Focusing a node can change the scroll position, which is undesirable
8497
8498
8499 var ancestors = [];
8500 var ancestor = priorFocusedElem;
8501
8502 while (ancestor = ancestor.parentNode) {
8503 if (ancestor.nodeType === ELEMENT_NODE) {
8504 ancestors.push({
8505 element: ancestor,
8506 left: ancestor.scrollLeft,
8507 top: ancestor.scrollTop
8508 });
8509 }
8510 }
8511
8512 if (typeof priorFocusedElem.focus === 'function') {
8513 priorFocusedElem.focus();
8514 }
8515
8516 for (var i = 0; i < ancestors.length; i++) {
8517 var info = ancestors[i];
8518 info.element.scrollLeft = info.left;
8519 info.element.scrollTop = info.top;
8520 }
8521 }
8522 }
8523 /**
8524 * @getSelection: Gets the selection bounds of a focused textarea, input or
8525 * contentEditable node.
8526 * -@input: Look up selection bounds of this input
8527 * -@return {start: selectionStart, end: selectionEnd}
8528 */
8529
8530 function getSelection(input) {
8531 var selection;
8532
8533 if ('selectionStart' in input) {
8534 // Modern browser with input or textarea.
8535 selection = {
8536 start: input.selectionStart,
8537 end: input.selectionEnd
8538 };
8539 } else {
8540 // Content editable or old IE textarea.
8541 selection = getOffsets(input);
8542 }
8543
8544 return selection || {
8545 start: 0,
8546 end: 0
8547 };
8548 }
8549 /**
8550 * @setSelection: Sets the selection bounds of a textarea or input and focuses
8551 * the input.
8552 * -@input Set selection bounds of this input or textarea
8553 * -@offsets Object of same form that is returned from get*
8554 */
8555
8556 function setSelection(input, offsets) {
8557 var start = offsets.start;
8558 var end = offsets.end;
8559
8560 if (end === undefined) {
8561 end = start;
8562 }
8563
8564 if ('selectionStart' in input) {
8565 input.selectionStart = start;
8566 input.selectionEnd = Math.min(end, input.value.length);
8567 } else {
8568 setOffsets(input, offsets);
8569 }
8570 }
8571
8572 var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11;
8573
8574 function registerEvents$3() {
8575 registerTwoPhaseEvent('onSelect', ['focusout', 'contextmenu', 'dragend', 'focusin', 'keydown', 'keyup', 'mousedown', 'mouseup', 'selectionchange']);
8576 }
8577
8578 var activeElement$1 = null;
8579 var activeElementInst$1 = null;
8580 var lastSelection = null;
8581 var mouseDown = false;
8582 /**
8583 * Get an object which is a unique representation of the current selection.
8584 *
8585 * The return value will not be consistent across nodes or browsers, but
8586 * two identical selections on the same node will return identical objects.
8587 */
8588
8589 function getSelection$1(node) {
8590 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
8591 return {
8592 start: node.selectionStart,
8593 end: node.selectionEnd
8594 };
8595 } else {
8596 var win = node.ownerDocument && node.ownerDocument.defaultView || window;
8597 var selection = win.getSelection();
8598 return {
8599 anchorNode: selection.anchorNode,
8600 anchorOffset: selection.anchorOffset,
8601 focusNode: selection.focusNode,
8602 focusOffset: selection.focusOffset
8603 };
8604 }
8605 }
8606 /**
8607 * Get document associated with the event target.
8608 */
8609
8610
8611 function getEventTargetDocument(eventTarget) {
8612 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;
8613 }
8614 /**
8615 * Poll selection to see whether it's changed.
8616 *
8617 * @param {object} nativeEvent
8618 * @param {object} nativeEventTarget
8619 * @return {?SyntheticEvent}
8620 */
8621
8622
8623 function constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget) {
8624 // Ensure we have the right element, and that the user is not dragging a
8625 // selection (this matches native `select` event behavior). In HTML5, select
8626 // fires only on input and textarea thus if there's no focused element we
8627 // won't dispatch.
8628 var doc = getEventTargetDocument(nativeEventTarget);
8629
8630 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) {
8631 return;
8632 } // Only fire when selection has actually changed.
8633
8634
8635 var currentSelection = getSelection$1(activeElement$1);
8636
8637 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
8638 lastSelection = currentSelection;
8639 var listeners = accumulateTwoPhaseListeners(activeElementInst$1, 'onSelect');
8640
8641 if (listeners.length > 0) {
8642 var event = new SyntheticEvent('onSelect', 'select', null, nativeEvent, nativeEventTarget);
8643 dispatchQueue.push({
8644 event: event,
8645 listeners: listeners
8646 });
8647 event.target = activeElement$1;
8648 }
8649 }
8650 }
8651 /**
8652 * This plugin creates an `onSelect` event that normalizes select events
8653 * across form elements.
8654 *
8655 * Supported elements are:
8656 * - input (see `isTextInputElement`)
8657 * - textarea
8658 * - contentEditable
8659 *
8660 * This differs from native browser implementations in the following ways:
8661 * - Fires on contentEditable fields as well as inputs.
8662 * - Fires for collapsed selection.
8663 * - Fires after user input.
8664 */
8665
8666
8667 function extractEvents$3(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
8668 var targetNode = targetInst ? getNodeFromInstance(targetInst) : window;
8669
8670 switch (domEventName) {
8671 // Track the input node that has focus.
8672 case 'focusin':
8673 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
8674 activeElement$1 = targetNode;
8675 activeElementInst$1 = targetInst;
8676 lastSelection = null;
8677 }
8678
8679 break;
8680
8681 case 'focusout':
8682 activeElement$1 = null;
8683 activeElementInst$1 = null;
8684 lastSelection = null;
8685 break;
8686 // Don't fire the event while the user is dragging. This matches the
8687 // semantics of the native select event.
8688
8689 case 'mousedown':
8690 mouseDown = true;
8691 break;
8692
8693 case 'contextmenu':
8694 case 'mouseup':
8695 case 'dragend':
8696 mouseDown = false;
8697 constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget);
8698 break;
8699 // Chrome and IE fire non-standard event when selection is changed (and
8700 // sometimes when it hasn't). IE's event fires out of order with respect
8701 // to key and input events on deletion, so we discard it.
8702 //
8703 // Firefox doesn't support selectionchange, so check selection status
8704 // after each key entry. The selection changes after keydown and before
8705 // keyup, but we check on keydown as well in the case of holding down a
8706 // key, when multiple keydown events are fired but only one keyup is.
8707 // This is also our approach for IE handling, for the reason above.
8708
8709 case 'selectionchange':
8710 if (skipSelectionChangeEvent) {
8711 break;
8712 }
8713
8714 // falls through
8715
8716 case 'keydown':
8717 case 'keyup':
8718 constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget);
8719 }
8720 }
8721
8722 /**
8723 * Generate a mapping of standard vendor prefixes using the defined style property and event name.
8724 *
8725 * @param {string} styleProp
8726 * @param {string} eventName
8727 * @returns {object}
8728 */
8729
8730 function makePrefixMap(styleProp, eventName) {
8731 var prefixes = {};
8732 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
8733 prefixes['Webkit' + styleProp] = 'webkit' + eventName;
8734 prefixes['Moz' + styleProp] = 'moz' + eventName;
8735 return prefixes;
8736 }
8737 /**
8738 * A list of event names to a configurable list of vendor prefixes.
8739 */
8740
8741
8742 var vendorPrefixes = {
8743 animationend: makePrefixMap('Animation', 'AnimationEnd'),
8744 animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
8745 animationstart: makePrefixMap('Animation', 'AnimationStart'),
8746 transitionend: makePrefixMap('Transition', 'TransitionEnd')
8747 };
8748 /**
8749 * Event names that have already been detected and prefixed (if applicable).
8750 */
8751
8752 var prefixedEventNames = {};
8753 /**
8754 * Element to check for prefixes on.
8755 */
8756
8757 var style = {};
8758 /**
8759 * Bootstrap if a DOM exists.
8760 */
8761
8762 if (canUseDOM) {
8763 style = document.createElement('div').style; // On some platforms, in particular some releases of Android 4.x,
8764 // the un-prefixed "animation" and "transition" properties are defined on the
8765 // style object but the events that fire will still be prefixed, so we need
8766 // to check if the un-prefixed events are usable, and if not remove them from the map.
8767
8768 if (!('AnimationEvent' in window)) {
8769 delete vendorPrefixes.animationend.animation;
8770 delete vendorPrefixes.animationiteration.animation;
8771 delete vendorPrefixes.animationstart.animation;
8772 } // Same as above
8773
8774
8775 if (!('TransitionEvent' in window)) {
8776 delete vendorPrefixes.transitionend.transition;
8777 }
8778 }
8779 /**
8780 * Attempts to determine the correct vendor prefixed event name.
8781 *
8782 * @param {string} eventName
8783 * @returns {string}
8784 */
8785
8786
8787 function getVendorPrefixedEventName(eventName) {
8788 if (prefixedEventNames[eventName]) {
8789 return prefixedEventNames[eventName];
8790 } else if (!vendorPrefixes[eventName]) {
8791 return eventName;
8792 }
8793
8794 var prefixMap = vendorPrefixes[eventName];
8795
8796 for (var styleProp in prefixMap) {
8797 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
8798 return prefixedEventNames[eventName] = prefixMap[styleProp];
8799 }
8800 }
8801
8802 return eventName;
8803 }
8804
8805 var ANIMATION_END = getVendorPrefixedEventName('animationend');
8806 var ANIMATION_ITERATION = getVendorPrefixedEventName('animationiteration');
8807 var ANIMATION_START = getVendorPrefixedEventName('animationstart');
8808 var TRANSITION_END = getVendorPrefixedEventName('transitionend');
8809
8810 var topLevelEventsToReactNames = new Map(); // NOTE: Capitalization is important in this list!
8811 //
8812 // E.g. it needs "pointerDown", not "pointerdown".
8813 // This is because we derive both React name ("onPointerDown")
8814 // and DOM name ("pointerdown") from the same list.
8815 //
8816 // Exceptions that don't match this convention are listed separately.
8817 //
8818 // prettier-ignore
8819
8820 var simpleEventPluginEvents = ['abort', 'auxClick', 'cancel', 'canPlay', 'canPlayThrough', 'click', 'close', 'contextMenu', 'copy', 'cut', 'drag', 'dragEnd', 'dragEnter', 'dragExit', 'dragLeave', 'dragOver', 'dragStart', 'drop', 'durationChange', 'emptied', 'encrypted', 'ended', 'error', 'gotPointerCapture', 'input', 'invalid', 'keyDown', 'keyPress', 'keyUp', 'load', 'loadedData', 'loadedMetadata', 'loadStart', 'lostPointerCapture', 'mouseDown', 'mouseMove', 'mouseOut', 'mouseOver', 'mouseUp', 'paste', 'pause', 'play', 'playing', 'pointerCancel', 'pointerDown', 'pointerMove', 'pointerOut', 'pointerOver', 'pointerUp', 'progress', 'rateChange', 'reset', 'resize', 'seeked', 'seeking', 'stalled', 'submit', 'suspend', 'timeUpdate', 'touchCancel', 'touchEnd', 'touchStart', 'volumeChange', 'scroll', 'toggle', 'touchMove', 'waiting', 'wheel'];
8821
8822 function registerSimpleEvent(domEventName, reactName) {
8823 topLevelEventsToReactNames.set(domEventName, reactName);
8824 registerTwoPhaseEvent(reactName, [domEventName]);
8825 }
8826
8827 function registerSimpleEvents() {
8828 for (var i = 0; i < simpleEventPluginEvents.length; i++) {
8829 var eventName = simpleEventPluginEvents[i];
8830 var domEventName = eventName.toLowerCase();
8831 var capitalizedEvent = eventName[0].toUpperCase() + eventName.slice(1);
8832 registerSimpleEvent(domEventName, 'on' + capitalizedEvent);
8833 } // Special cases where event names don't match.
8834
8835
8836 registerSimpleEvent(ANIMATION_END, 'onAnimationEnd');
8837 registerSimpleEvent(ANIMATION_ITERATION, 'onAnimationIteration');
8838 registerSimpleEvent(ANIMATION_START, 'onAnimationStart');
8839 registerSimpleEvent('dblclick', 'onDoubleClick');
8840 registerSimpleEvent('focusin', 'onFocus');
8841 registerSimpleEvent('focusout', 'onBlur');
8842 registerSimpleEvent(TRANSITION_END, 'onTransitionEnd');
8843 }
8844
8845 function extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
8846 var reactName = topLevelEventsToReactNames.get(domEventName);
8847
8848 if (reactName === undefined) {
8849 return;
8850 }
8851
8852 var SyntheticEventCtor = SyntheticEvent;
8853 var reactEventType = domEventName;
8854
8855 switch (domEventName) {
8856 case 'keypress':
8857 // Firefox creates a keypress event for function keys too. This removes
8858 // the unwanted keypress events. Enter is however both printable and
8859 // non-printable. One would expect Tab to be as well (but it isn't).
8860 if (getEventCharCode(nativeEvent) === 0) {
8861 return;
8862 }
8863
8864 /* falls through */
8865
8866 case 'keydown':
8867 case 'keyup':
8868 SyntheticEventCtor = SyntheticKeyboardEvent;
8869 break;
8870
8871 case 'focusin':
8872 reactEventType = 'focus';
8873 SyntheticEventCtor = SyntheticFocusEvent;
8874 break;
8875
8876 case 'focusout':
8877 reactEventType = 'blur';
8878 SyntheticEventCtor = SyntheticFocusEvent;
8879 break;
8880
8881 case 'beforeblur':
8882 case 'afterblur':
8883 SyntheticEventCtor = SyntheticFocusEvent;
8884 break;
8885
8886 case 'click':
8887 // Firefox creates a click event on right mouse clicks. This removes the
8888 // unwanted click events.
8889 if (nativeEvent.button === 2) {
8890 return;
8891 }
8892
8893 /* falls through */
8894
8895 case 'auxclick':
8896 case 'dblclick':
8897 case 'mousedown':
8898 case 'mousemove':
8899 case 'mouseup': // TODO: Disabled elements should not respond to mouse events
8900
8901 /* falls through */
8902
8903 case 'mouseout':
8904 case 'mouseover':
8905 case 'contextmenu':
8906 SyntheticEventCtor = SyntheticMouseEvent;
8907 break;
8908
8909 case 'drag':
8910 case 'dragend':
8911 case 'dragenter':
8912 case 'dragexit':
8913 case 'dragleave':
8914 case 'dragover':
8915 case 'dragstart':
8916 case 'drop':
8917 SyntheticEventCtor = SyntheticDragEvent;
8918 break;
8919
8920 case 'touchcancel':
8921 case 'touchend':
8922 case 'touchmove':
8923 case 'touchstart':
8924 SyntheticEventCtor = SyntheticTouchEvent;
8925 break;
8926
8927 case ANIMATION_END:
8928 case ANIMATION_ITERATION:
8929 case ANIMATION_START:
8930 SyntheticEventCtor = SyntheticAnimationEvent;
8931 break;
8932
8933 case TRANSITION_END:
8934 SyntheticEventCtor = SyntheticTransitionEvent;
8935 break;
8936
8937 case 'scroll':
8938 SyntheticEventCtor = SyntheticUIEvent;
8939 break;
8940
8941 case 'wheel':
8942 SyntheticEventCtor = SyntheticWheelEvent;
8943 break;
8944
8945 case 'copy':
8946 case 'cut':
8947 case 'paste':
8948 SyntheticEventCtor = SyntheticClipboardEvent;
8949 break;
8950
8951 case 'gotpointercapture':
8952 case 'lostpointercapture':
8953 case 'pointercancel':
8954 case 'pointerdown':
8955 case 'pointermove':
8956 case 'pointerout':
8957 case 'pointerover':
8958 case 'pointerup':
8959 SyntheticEventCtor = SyntheticPointerEvent;
8960 break;
8961 }
8962
8963 var inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0;
8964
8965 {
8966 // Some events don't bubble in the browser.
8967 // In the past, React has always bubbled them, but this can be surprising.
8968 // We're going to try aligning closer to the browser behavior by not bubbling
8969 // them in React either. We'll start by not bubbling onScroll, and then expand.
8970 var accumulateTargetOnly = !inCapturePhase && // TODO: ideally, we'd eventually add all events from
8971 // nonDelegatedEvents list in DOMPluginEventSystem.
8972 // Then we can remove this special list.
8973 // This is a breaking change that can wait until React 18.
8974 domEventName === 'scroll';
8975
8976 var _listeners = accumulateSinglePhaseListeners(targetInst, reactName, nativeEvent.type, inCapturePhase, accumulateTargetOnly);
8977
8978 if (_listeners.length > 0) {
8979 // Intentionally create event lazily.
8980 var _event = new SyntheticEventCtor(reactName, reactEventType, null, nativeEvent, nativeEventTarget);
8981
8982 dispatchQueue.push({
8983 event: _event,
8984 listeners: _listeners
8985 });
8986 }
8987 }
8988 }
8989
8990 // TODO: remove top-level side effect.
8991 registerSimpleEvents();
8992 registerEvents$2();
8993 registerEvents$1();
8994 registerEvents$3();
8995 registerEvents();
8996
8997 function extractEvents$5(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
8998 // TODO: we should remove the concept of a "SimpleEventPlugin".
8999 // This is the basic functionality of the event system. All
9000 // the other plugins are essentially polyfills. So the plugin
9001 // should probably be inlined somewhere and have its logic
9002 // be core the to event system. This would potentially allow
9003 // us to ship builds of React without the polyfilled plugins below.
9004 extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
9005 var shouldProcessPolyfillPlugins = (eventSystemFlags & SHOULD_NOT_PROCESS_POLYFILL_EVENT_PLUGINS) === 0; // We don't process these events unless we are in the
9006 // event's native "bubble" phase, which means that we're
9007 // not in the capture phase. That's because we emulate
9008 // the capture phase here still. This is a trade-off,
9009 // because in an ideal world we would not emulate and use
9010 // the phases properly, like we do with the SimpleEvent
9011 // plugin. However, the plugins below either expect
9012 // emulation (EnterLeave) or use state localized to that
9013 // plugin (BeforeInput, Change, Select). The state in
9014 // these modules complicates things, as you'll essentially
9015 // get the case where the capture phase event might change
9016 // state, only for the following bubble event to come in
9017 // later and not trigger anything as the state now
9018 // invalidates the heuristics of the event plugin. We
9019 // could alter all these plugins to work in such ways, but
9020 // that might cause other unknown side-effects that we
9021 // can't foresee right now.
9022
9023 if (shouldProcessPolyfillPlugins) {
9024 extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
9025 extractEvents$1(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
9026 extractEvents$3(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
9027 extractEvents(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
9028 }
9029 } // List of events that need to be individually attached to media elements.
9030
9031
9032 var mediaEventTypes = ['abort', 'canplay', 'canplaythrough', 'durationchange', 'emptied', 'encrypted', 'ended', 'error', 'loadeddata', 'loadedmetadata', 'loadstart', 'pause', 'play', 'playing', 'progress', 'ratechange', 'resize', 'seeked', 'seeking', 'stalled', 'suspend', 'timeupdate', 'volumechange', 'waiting']; // We should not delegate these events to the container, but rather
9033 // set them on the actual target element itself. This is primarily
9034 // because these events do not consistently bubble in the DOM.
9035
9036 var nonDelegatedEvents = new Set(['cancel', 'close', 'invalid', 'load', 'scroll', 'toggle'].concat(mediaEventTypes));
9037
9038 function executeDispatch(event, listener, currentTarget) {
9039 var type = event.type || 'unknown-event';
9040 event.currentTarget = currentTarget;
9041 invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
9042 event.currentTarget = null;
9043 }
9044
9045 function processDispatchQueueItemsInOrder(event, dispatchListeners, inCapturePhase) {
9046 var previousInstance;
9047
9048 if (inCapturePhase) {
9049 for (var i = dispatchListeners.length - 1; i >= 0; i--) {
9050 var _dispatchListeners$i = dispatchListeners[i],
9051 instance = _dispatchListeners$i.instance,
9052 currentTarget = _dispatchListeners$i.currentTarget,
9053 listener = _dispatchListeners$i.listener;
9054
9055 if (instance !== previousInstance && event.isPropagationStopped()) {
9056 return;
9057 }
9058
9059 executeDispatch(event, listener, currentTarget);
9060 previousInstance = instance;
9061 }
9062 } else {
9063 for (var _i = 0; _i < dispatchListeners.length; _i++) {
9064 var _dispatchListeners$_i = dispatchListeners[_i],
9065 _instance = _dispatchListeners$_i.instance,
9066 _currentTarget = _dispatchListeners$_i.currentTarget,
9067 _listener = _dispatchListeners$_i.listener;
9068
9069 if (_instance !== previousInstance && event.isPropagationStopped()) {
9070 return;
9071 }
9072
9073 executeDispatch(event, _listener, _currentTarget);
9074 previousInstance = _instance;
9075 }
9076 }
9077 }
9078
9079 function processDispatchQueue(dispatchQueue, eventSystemFlags) {
9080 var inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0;
9081
9082 for (var i = 0; i < dispatchQueue.length; i++) {
9083 var _dispatchQueue$i = dispatchQueue[i],
9084 event = _dispatchQueue$i.event,
9085 listeners = _dispatchQueue$i.listeners;
9086 processDispatchQueueItemsInOrder(event, listeners, inCapturePhase); // event system doesn't use pooling.
9087 } // This would be a good time to rethrow if any of the event handlers threw.
9088
9089
9090 rethrowCaughtError();
9091 }
9092
9093 function dispatchEventsForPlugins(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer) {
9094 var nativeEventTarget = getEventTarget(nativeEvent);
9095 var dispatchQueue = [];
9096 extractEvents$5(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
9097 processDispatchQueue(dispatchQueue, eventSystemFlags);
9098 }
9099
9100 function listenToNonDelegatedEvent(domEventName, targetElement) {
9101 {
9102 if (!nonDelegatedEvents.has(domEventName)) {
9103 error('Did not expect a listenToNonDelegatedEvent() call for "%s". ' + 'This is a bug in React. Please file an issue.', domEventName);
9104 }
9105 }
9106
9107 var isCapturePhaseListener = false;
9108 var listenerSet = getEventListenerSet(targetElement);
9109 var listenerSetKey = getListenerSetKey(domEventName, isCapturePhaseListener);
9110
9111 if (!listenerSet.has(listenerSetKey)) {
9112 addTrappedEventListener(targetElement, domEventName, IS_NON_DELEGATED, isCapturePhaseListener);
9113 listenerSet.add(listenerSetKey);
9114 }
9115 }
9116 function listenToNativeEvent(domEventName, isCapturePhaseListener, target) {
9117 {
9118 if (nonDelegatedEvents.has(domEventName) && !isCapturePhaseListener) {
9119 error('Did not expect a listenToNativeEvent() call for "%s" in the bubble phase. ' + 'This is a bug in React. Please file an issue.', domEventName);
9120 }
9121 }
9122
9123 var eventSystemFlags = 0;
9124
9125 if (isCapturePhaseListener) {
9126 eventSystemFlags |= IS_CAPTURE_PHASE;
9127 }
9128
9129 addTrappedEventListener(target, domEventName, eventSystemFlags, isCapturePhaseListener);
9130 } // This is only used by createEventHandle when the
9131 var listeningMarker = '_reactListening' + Math.random().toString(36).slice(2);
9132 function listenToAllSupportedEvents(rootContainerElement) {
9133 if (!rootContainerElement[listeningMarker]) {
9134 rootContainerElement[listeningMarker] = true;
9135 allNativeEvents.forEach(function (domEventName) {
9136 // We handle selectionchange separately because it
9137 // doesn't bubble and needs to be on the document.
9138 if (domEventName !== 'selectionchange') {
9139 if (!nonDelegatedEvents.has(domEventName)) {
9140 listenToNativeEvent(domEventName, false, rootContainerElement);
9141 }
9142
9143 listenToNativeEvent(domEventName, true, rootContainerElement);
9144 }
9145 });
9146 var ownerDocument = rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
9147
9148 if (ownerDocument !== null) {
9149 // The selectionchange event also needs deduplication
9150 // but it is attached to the document.
9151 if (!ownerDocument[listeningMarker]) {
9152 ownerDocument[listeningMarker] = true;
9153 listenToNativeEvent('selectionchange', false, ownerDocument);
9154 }
9155 }
9156 }
9157 }
9158
9159 function addTrappedEventListener(targetContainer, domEventName, eventSystemFlags, isCapturePhaseListener, isDeferredListenerForLegacyFBSupport) {
9160 var listener = createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags); // If passive option is not supported, then the event will be
9161 // active and not passive.
9162
9163 var isPassiveListener = undefined;
9164
9165 if (passiveBrowserEventsSupported) {
9166 // Browsers introduced an intervention, making these events
9167 // passive by default on document. React doesn't bind them
9168 // to document anymore, but changing this now would undo
9169 // the performance wins from the change. So we emulate
9170 // the existing behavior manually on the roots now.
9171 // https://github.com/facebook/react/issues/19651
9172 if (domEventName === 'touchstart' || domEventName === 'touchmove' || domEventName === 'wheel') {
9173 isPassiveListener = true;
9174 }
9175 }
9176
9177 targetContainer = targetContainer;
9178 var unsubscribeListener; // When legacyFBSupport is enabled, it's for when we
9179
9180
9181 if (isCapturePhaseListener) {
9182 if (isPassiveListener !== undefined) {
9183 unsubscribeListener = addEventCaptureListenerWithPassiveFlag(targetContainer, domEventName, listener, isPassiveListener);
9184 } else {
9185 unsubscribeListener = addEventCaptureListener(targetContainer, domEventName, listener);
9186 }
9187 } else {
9188 if (isPassiveListener !== undefined) {
9189 unsubscribeListener = addEventBubbleListenerWithPassiveFlag(targetContainer, domEventName, listener, isPassiveListener);
9190 } else {
9191 unsubscribeListener = addEventBubbleListener(targetContainer, domEventName, listener);
9192 }
9193 }
9194 }
9195
9196 function isMatchingRootContainer(grandContainer, targetContainer) {
9197 return grandContainer === targetContainer || grandContainer.nodeType === COMMENT_NODE && grandContainer.parentNode === targetContainer;
9198 }
9199
9200 function dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer) {
9201 var ancestorInst = targetInst;
9202
9203 if ((eventSystemFlags & IS_EVENT_HANDLE_NON_MANAGED_NODE) === 0 && (eventSystemFlags & IS_NON_DELEGATED) === 0) {
9204 var targetContainerNode = targetContainer; // If we are using the legacy FB support flag, we
9205
9206 if (targetInst !== null) {
9207 // The below logic attempts to work out if we need to change
9208 // the target fiber to a different ancestor. We had similar logic
9209 // in the legacy event system, except the big difference between
9210 // systems is that the modern event system now has an event listener
9211 // attached to each React Root and React Portal Root. Together,
9212 // the DOM nodes representing these roots are the "rootContainer".
9213 // To figure out which ancestor instance we should use, we traverse
9214 // up the fiber tree from the target instance and attempt to find
9215 // root boundaries that match that of our current "rootContainer".
9216 // If we find that "rootContainer", we find the parent fiber
9217 // sub-tree for that root and make that our ancestor instance.
9218 var node = targetInst;
9219
9220 mainLoop: while (true) {
9221 if (node === null) {
9222 return;
9223 }
9224
9225 var nodeTag = node.tag;
9226
9227 if (nodeTag === HostRoot || nodeTag === HostPortal) {
9228 var container = node.stateNode.containerInfo;
9229
9230 if (isMatchingRootContainer(container, targetContainerNode)) {
9231 break;
9232 }
9233
9234 if (nodeTag === HostPortal) {
9235 // The target is a portal, but it's not the rootContainer we're looking for.
9236 // Normally portals handle their own events all the way down to the root.
9237 // So we should be able to stop now. However, we don't know if this portal
9238 // was part of *our* root.
9239 var grandNode = node.return;
9240
9241 while (grandNode !== null) {
9242 var grandTag = grandNode.tag;
9243
9244 if (grandTag === HostRoot || grandTag === HostPortal) {
9245 var grandContainer = grandNode.stateNode.containerInfo;
9246
9247 if (isMatchingRootContainer(grandContainer, targetContainerNode)) {
9248 // This is the rootContainer we're looking for and we found it as
9249 // a parent of the Portal. That means we can ignore it because the
9250 // Portal will bubble through to us.
9251 return;
9252 }
9253 }
9254
9255 grandNode = grandNode.return;
9256 }
9257 } // Now we need to find it's corresponding host fiber in the other
9258 // tree. To do this we can use getClosestInstanceFromNode, but we
9259 // need to validate that the fiber is a host instance, otherwise
9260 // we need to traverse up through the DOM till we find the correct
9261 // node that is from the other tree.
9262
9263
9264 while (container !== null) {
9265 var parentNode = getClosestInstanceFromNode(container);
9266
9267 if (parentNode === null) {
9268 return;
9269 }
9270
9271 var parentTag = parentNode.tag;
9272
9273 if (parentTag === HostComponent || parentTag === HostText) {
9274 node = ancestorInst = parentNode;
9275 continue mainLoop;
9276 }
9277
9278 container = container.parentNode;
9279 }
9280 }
9281
9282 node = node.return;
9283 }
9284 }
9285 }
9286
9287 batchedUpdates(function () {
9288 return dispatchEventsForPlugins(domEventName, eventSystemFlags, nativeEvent, ancestorInst);
9289 });
9290 }
9291
9292 function createDispatchListener(instance, listener, currentTarget) {
9293 return {
9294 instance: instance,
9295 listener: listener,
9296 currentTarget: currentTarget
9297 };
9298 }
9299
9300 function accumulateSinglePhaseListeners(targetFiber, reactName, nativeEventType, inCapturePhase, accumulateTargetOnly, nativeEvent) {
9301 var captureName = reactName !== null ? reactName + 'Capture' : null;
9302 var reactEventName = inCapturePhase ? captureName : reactName;
9303 var listeners = [];
9304 var instance = targetFiber;
9305 var lastHostComponent = null; // Accumulate all instances and listeners via the target -> root path.
9306
9307 while (instance !== null) {
9308 var _instance2 = instance,
9309 stateNode = _instance2.stateNode,
9310 tag = _instance2.tag; // Handle listeners that are on HostComponents (i.e. <div>)
9311
9312 if (tag === HostComponent && stateNode !== null) {
9313 lastHostComponent = stateNode; // createEventHandle listeners
9314
9315
9316 if (reactEventName !== null) {
9317 var listener = getListener(instance, reactEventName);
9318
9319 if (listener != null) {
9320 listeners.push(createDispatchListener(instance, listener, lastHostComponent));
9321 }
9322 }
9323 } // If we are only accumulating events for the target, then we don't
9324 // continue to propagate through the React fiber tree to find other
9325 // listeners.
9326
9327
9328 if (accumulateTargetOnly) {
9329 break;
9330 } // If we are processing the onBeforeBlur event, then we need to take
9331
9332 instance = instance.return;
9333 }
9334
9335 return listeners;
9336 } // We should only use this function for:
9337 // - BeforeInputEventPlugin
9338 // - ChangeEventPlugin
9339 // - SelectEventPlugin
9340 // This is because we only process these plugins
9341 // in the bubble phase, so we need to accumulate two
9342 // phase event listeners (via emulation).
9343
9344 function accumulateTwoPhaseListeners(targetFiber, reactName) {
9345 var captureName = reactName + 'Capture';
9346 var listeners = [];
9347 var instance = targetFiber; // Accumulate all instances and listeners via the target -> root path.
9348
9349 while (instance !== null) {
9350 var _instance3 = instance,
9351 stateNode = _instance3.stateNode,
9352 tag = _instance3.tag; // Handle listeners that are on HostComponents (i.e. <div>)
9353
9354 if (tag === HostComponent && stateNode !== null) {
9355 var currentTarget = stateNode;
9356 var captureListener = getListener(instance, captureName);
9357
9358 if (captureListener != null) {
9359 listeners.unshift(createDispatchListener(instance, captureListener, currentTarget));
9360 }
9361
9362 var bubbleListener = getListener(instance, reactName);
9363
9364 if (bubbleListener != null) {
9365 listeners.push(createDispatchListener(instance, bubbleListener, currentTarget));
9366 }
9367 }
9368
9369 instance = instance.return;
9370 }
9371
9372 return listeners;
9373 }
9374
9375 function getParent(inst) {
9376 if (inst === null) {
9377 return null;
9378 }
9379
9380 do {
9381 inst = inst.return; // TODO: If this is a HostRoot we might want to bail out.
9382 // That is depending on if we want nested subtrees (layers) to bubble
9383 // events to their parent. We could also go through parentNode on the
9384 // host node but that wouldn't work for React Native and doesn't let us
9385 // do the portal feature.
9386 } while (inst && inst.tag !== HostComponent);
9387
9388 if (inst) {
9389 return inst;
9390 }
9391
9392 return null;
9393 }
9394 /**
9395 * Return the lowest common ancestor of A and B, or null if they are in
9396 * different trees.
9397 */
9398
9399
9400 function getLowestCommonAncestor(instA, instB) {
9401 var nodeA = instA;
9402 var nodeB = instB;
9403 var depthA = 0;
9404
9405 for (var tempA = nodeA; tempA; tempA = getParent(tempA)) {
9406 depthA++;
9407 }
9408
9409 var depthB = 0;
9410
9411 for (var tempB = nodeB; tempB; tempB = getParent(tempB)) {
9412 depthB++;
9413 } // If A is deeper, crawl up.
9414
9415
9416 while (depthA - depthB > 0) {
9417 nodeA = getParent(nodeA);
9418 depthA--;
9419 } // If B is deeper, crawl up.
9420
9421
9422 while (depthB - depthA > 0) {
9423 nodeB = getParent(nodeB);
9424 depthB--;
9425 } // Walk in lockstep until we find a match.
9426
9427
9428 var depth = depthA;
9429
9430 while (depth--) {
9431 if (nodeA === nodeB || nodeB !== null && nodeA === nodeB.alternate) {
9432 return nodeA;
9433 }
9434
9435 nodeA = getParent(nodeA);
9436 nodeB = getParent(nodeB);
9437 }
9438
9439 return null;
9440 }
9441
9442 function accumulateEnterLeaveListenersForEvent(dispatchQueue, event, target, common, inCapturePhase) {
9443 var registrationName = event._reactName;
9444 var listeners = [];
9445 var instance = target;
9446
9447 while (instance !== null) {
9448 if (instance === common) {
9449 break;
9450 }
9451
9452 var _instance4 = instance,
9453 alternate = _instance4.alternate,
9454 stateNode = _instance4.stateNode,
9455 tag = _instance4.tag;
9456
9457 if (alternate !== null && alternate === common) {
9458 break;
9459 }
9460
9461 if (tag === HostComponent && stateNode !== null) {
9462 var currentTarget = stateNode;
9463
9464 if (inCapturePhase) {
9465 var captureListener = getListener(instance, registrationName);
9466
9467 if (captureListener != null) {
9468 listeners.unshift(createDispatchListener(instance, captureListener, currentTarget));
9469 }
9470 } else if (!inCapturePhase) {
9471 var bubbleListener = getListener(instance, registrationName);
9472
9473 if (bubbleListener != null) {
9474 listeners.push(createDispatchListener(instance, bubbleListener, currentTarget));
9475 }
9476 }
9477 }
9478
9479 instance = instance.return;
9480 }
9481
9482 if (listeners.length !== 0) {
9483 dispatchQueue.push({
9484 event: event,
9485 listeners: listeners
9486 });
9487 }
9488 } // We should only use this function for:
9489 // - EnterLeaveEventPlugin
9490 // This is because we only process this plugin
9491 // in the bubble phase, so we need to accumulate two
9492 // phase event listeners.
9493
9494
9495 function accumulateEnterLeaveTwoPhaseListeners(dispatchQueue, leaveEvent, enterEvent, from, to) {
9496 var common = from && to ? getLowestCommonAncestor(from, to) : null;
9497
9498 if (from !== null) {
9499 accumulateEnterLeaveListenersForEvent(dispatchQueue, leaveEvent, from, common, false);
9500 }
9501
9502 if (to !== null && enterEvent !== null) {
9503 accumulateEnterLeaveListenersForEvent(dispatchQueue, enterEvent, to, common, true);
9504 }
9505 }
9506 function getListenerSetKey(domEventName, capture) {
9507 return domEventName + "__" + (capture ? 'capture' : 'bubble');
9508 }
9509
9510 var didWarnInvalidHydration = false;
9511 var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
9512 var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
9513 var SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
9514 var AUTOFOCUS = 'autoFocus';
9515 var CHILDREN = 'children';
9516 var STYLE = 'style';
9517 var HTML$1 = '__html';
9518 var warnedUnknownTags;
9519 var validatePropertiesInDevelopment;
9520 var warnForPropDifference;
9521 var warnForExtraAttributes;
9522 var warnForInvalidEventListener;
9523 var canDiffStyleForHydrationWarning;
9524 var normalizeHTML;
9525
9526 {
9527 warnedUnknownTags = {
9528 // There are working polyfills for <dialog>. Let people use it.
9529 dialog: true,
9530 // Electron ships a custom <webview> tag to display external web content in
9531 // an isolated frame and process.
9532 // This tag is not present in non Electron environments such as JSDom which
9533 // is often used for testing purposes.
9534 // @see https://electronjs.org/docs/api/webview-tag
9535 webview: true
9536 };
9537
9538 validatePropertiesInDevelopment = function (type, props) {
9539 validateProperties(type, props);
9540 validateProperties$1(type, props);
9541 validateProperties$2(type, props, {
9542 registrationNameDependencies: registrationNameDependencies,
9543 possibleRegistrationNames: possibleRegistrationNames
9544 });
9545 }; // IE 11 parses & normalizes the style attribute as opposed to other
9546 // browsers. It adds spaces and sorts the properties in some
9547 // non-alphabetical order. Handling that would require sorting CSS
9548 // properties in the client & server versions or applying
9549 // `expectedStyle` to a temporary DOM node to read its `style` attribute
9550 // normalized. Since it only affects IE, we're skipping style warnings
9551 // in that browser completely in favor of doing all that work.
9552 // See https://github.com/facebook/react/issues/11807
9553
9554
9555 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode;
9556
9557 warnForPropDifference = function (propName, serverValue, clientValue) {
9558 if (didWarnInvalidHydration) {
9559 return;
9560 }
9561
9562 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
9563 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
9564
9565 if (normalizedServerValue === normalizedClientValue) {
9566 return;
9567 }
9568
9569 didWarnInvalidHydration = true;
9570
9571 error('Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
9572 };
9573
9574 warnForExtraAttributes = function (attributeNames) {
9575 if (didWarnInvalidHydration) {
9576 return;
9577 }
9578
9579 didWarnInvalidHydration = true;
9580 var names = [];
9581 attributeNames.forEach(function (name) {
9582 names.push(name);
9583 });
9584
9585 error('Extra attributes from the server: %s', names);
9586 };
9587
9588 warnForInvalidEventListener = function (registrationName, listener) {
9589 if (listener === false) {
9590 error('Expected `%s` listener to be a function, instead got `false`.\n\n' + 'If you used to conditionally omit it with %s={condition && value}, ' + 'pass %s={condition ? value : undefined} instead.', registrationName, registrationName, registrationName);
9591 } else {
9592 error('Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener);
9593 }
9594 }; // Parse the HTML and read it back to normalize the HTML string so that it
9595 // can be used for comparison.
9596
9597
9598 normalizeHTML = function (parent, html) {
9599 // We could have created a separate document here to avoid
9600 // re-initializing custom elements if they exist. But this breaks
9601 // how <noscript> is being handled. So we use the same document.
9602 // See the discussion in https://github.com/facebook/react/pull/11157.
9603 var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
9604 testElement.innerHTML = html;
9605 return testElement.innerHTML;
9606 };
9607 } // HTML parsing normalizes CR and CRLF to LF.
9608 // It also can turn \u0000 into \uFFFD inside attributes.
9609 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
9610 // If we have a mismatch, it might be caused by that.
9611 // We will still patch up in this case but not fire the warning.
9612
9613
9614 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
9615 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
9616
9617 function normalizeMarkupForTextOrAttribute(markup) {
9618 {
9619 checkHtmlStringCoercion(markup);
9620 }
9621
9622 var markupString = typeof markup === 'string' ? markup : '' + markup;
9623 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
9624 }
9625
9626 function checkForUnmatchedText(serverText, clientText, isConcurrentMode, shouldWarnDev) {
9627 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
9628 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
9629
9630 if (normalizedServerText === normalizedClientText) {
9631 return;
9632 }
9633
9634 if (shouldWarnDev) {
9635 {
9636 if (!didWarnInvalidHydration) {
9637 didWarnInvalidHydration = true;
9638
9639 error('Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
9640 }
9641 }
9642 }
9643
9644 if (isConcurrentMode && enableClientRenderFallbackOnTextMismatch) {
9645 // In concurrent roots, we throw when there's a text mismatch and revert to
9646 // client rendering, up to the nearest Suspense boundary.
9647 throw new Error('Text content does not match server-rendered HTML.');
9648 }
9649 }
9650
9651 function getOwnerDocumentFromRootContainer(rootContainerElement) {
9652 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
9653 }
9654
9655 function noop() {}
9656
9657 function trapClickOnNonInteractiveElement(node) {
9658 // Mobile Safari does not fire properly bubble click events on
9659 // non-interactive elements, which means delegated click listeners do not
9660 // fire. The workaround for this bug involves attaching an empty click
9661 // listener on the target node.
9662 // https://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
9663 // Just set it using the onclick property so that we don't have to manage any
9664 // bookkeeping for it. Not sure if we need to clear it when the listener is
9665 // removed.
9666 // TODO: Only do this for the relevant Safaris maybe?
9667 node.onclick = noop;
9668 }
9669
9670 function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
9671 for (var propKey in nextProps) {
9672 if (!nextProps.hasOwnProperty(propKey)) {
9673 continue;
9674 }
9675
9676 var nextProp = nextProps[propKey];
9677
9678 if (propKey === STYLE) {
9679 {
9680 if (nextProp) {
9681 // Freeze the next style object so that we can assume it won't be
9682 // mutated. We have already warned for this in the past.
9683 Object.freeze(nextProp);
9684 }
9685 } // Relies on `updateStylesByID` not mutating `styleUpdates`.
9686
9687
9688 setValueForStyles(domElement, nextProp);
9689 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
9690 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
9691
9692 if (nextHtml != null) {
9693 setInnerHTML(domElement, nextHtml);
9694 }
9695 } else if (propKey === CHILDREN) {
9696 if (typeof nextProp === 'string') {
9697 // Avoid setting initial textContent when the text is empty. In IE11 setting
9698 // textContent on a <textarea> will cause the placeholder to not
9699 // show within the <textarea> until it has been focused and blurred again.
9700 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
9701 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
9702
9703 if (canSetTextContent) {
9704 setTextContent(domElement, nextProp);
9705 }
9706 } else if (typeof nextProp === 'number') {
9707 setTextContent(domElement, '' + nextProp);
9708 }
9709 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (propKey === AUTOFOCUS) ; else if (registrationNameDependencies.hasOwnProperty(propKey)) {
9710 if (nextProp != null) {
9711 if ( typeof nextProp !== 'function') {
9712 warnForInvalidEventListener(propKey, nextProp);
9713 }
9714
9715 if (propKey === 'onScroll') {
9716 listenToNonDelegatedEvent('scroll', domElement);
9717 }
9718 }
9719 } else if (nextProp != null) {
9720 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
9721 }
9722 }
9723 }
9724
9725 function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
9726 // TODO: Handle wasCustomComponentTag
9727 for (var i = 0; i < updatePayload.length; i += 2) {
9728 var propKey = updatePayload[i];
9729 var propValue = updatePayload[i + 1];
9730
9731 if (propKey === STYLE) {
9732 setValueForStyles(domElement, propValue);
9733 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
9734 setInnerHTML(domElement, propValue);
9735 } else if (propKey === CHILDREN) {
9736 setTextContent(domElement, propValue);
9737 } else {
9738 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
9739 }
9740 }
9741 }
9742
9743 function createElement(type, props, rootContainerElement, parentNamespace) {
9744 var isCustomComponentTag; // We create tags in the namespace of their parent container, except HTML
9745 // tags get no namespace.
9746
9747 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
9748 var domElement;
9749 var namespaceURI = parentNamespace;
9750
9751 if (namespaceURI === HTML_NAMESPACE) {
9752 namespaceURI = getIntrinsicNamespace(type);
9753 }
9754
9755 if (namespaceURI === HTML_NAMESPACE) {
9756 {
9757 isCustomComponentTag = isCustomComponent(type, props); // Should this check be gated by parent namespace? Not sure we want to
9758 // allow <SVG> or <mATH>.
9759
9760 if (!isCustomComponentTag && type !== type.toLowerCase()) {
9761 error('<%s /> is using incorrect casing. ' + 'Use PascalCase for React components, ' + 'or lowercase for HTML elements.', type);
9762 }
9763 }
9764
9765 if (type === 'script') {
9766 // Create the script via .innerHTML so its "parser-inserted" flag is
9767 // set to true and it does not execute
9768 var div = ownerDocument.createElement('div');
9769
9770 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
9771 // This is guaranteed to yield a script element.
9772
9773 var firstChild = div.firstChild;
9774 domElement = div.removeChild(firstChild);
9775 } else if (typeof props.is === 'string') {
9776 // $FlowIssue `createElement` should be updated for Web Components
9777 domElement = ownerDocument.createElement(type, {
9778 is: props.is
9779 });
9780 } else {
9781 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
9782 // See discussion in https://github.com/facebook/react/pull/6896
9783 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
9784 domElement = ownerDocument.createElement(type); // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple` and `size`
9785 // attributes on `select`s needs to be added before `option`s are inserted.
9786 // This prevents:
9787 // - a bug where the `select` does not scroll to the correct option because singular
9788 // `select` elements automatically pick the first item #13222
9789 // - a bug where the `select` set the first item as selected despite the `size` attribute #14239
9790 // See https://github.com/facebook/react/issues/13222
9791 // and https://github.com/facebook/react/issues/14239
9792
9793 if (type === 'select') {
9794 var node = domElement;
9795
9796 if (props.multiple) {
9797 node.multiple = true;
9798 } else if (props.size) {
9799 // Setting a size greater than 1 causes a select to behave like `multiple=true`, where
9800 // it is possible that no option is selected.
9801 //
9802 // This is only necessary when a select in "single selection mode".
9803 node.size = props.size;
9804 }
9805 }
9806 }
9807 } else {
9808 domElement = ownerDocument.createElementNS(namespaceURI, type);
9809 }
9810
9811 {
9812 if (namespaceURI === HTML_NAMESPACE) {
9813 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !hasOwnProperty.call(warnedUnknownTags, type)) {
9814 warnedUnknownTags[type] = true;
9815
9816 error('The tag <%s> is unrecognized in this browser. ' + 'If you meant to render a React component, start its name with ' + 'an uppercase letter.', type);
9817 }
9818 }
9819 }
9820
9821 return domElement;
9822 }
9823 function createTextNode(text, rootContainerElement) {
9824 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
9825 }
9826 function setInitialProperties(domElement, tag, rawProps, rootContainerElement) {
9827 var isCustomComponentTag = isCustomComponent(tag, rawProps);
9828
9829 {
9830 validatePropertiesInDevelopment(tag, rawProps);
9831 } // TODO: Make sure that we check isMounted before firing any of these events.
9832
9833
9834 var props;
9835
9836 switch (tag) {
9837 case 'dialog':
9838 listenToNonDelegatedEvent('cancel', domElement);
9839 listenToNonDelegatedEvent('close', domElement);
9840 props = rawProps;
9841 break;
9842
9843 case 'iframe':
9844 case 'object':
9845 case 'embed':
9846 // We listen to this event in case to ensure emulated bubble
9847 // listeners still fire for the load event.
9848 listenToNonDelegatedEvent('load', domElement);
9849 props = rawProps;
9850 break;
9851
9852 case 'video':
9853 case 'audio':
9854 // We listen to these events in case to ensure emulated bubble
9855 // listeners still fire for all the media events.
9856 for (var i = 0; i < mediaEventTypes.length; i++) {
9857 listenToNonDelegatedEvent(mediaEventTypes[i], domElement);
9858 }
9859
9860 props = rawProps;
9861 break;
9862
9863 case 'source':
9864 // We listen to this event in case to ensure emulated bubble
9865 // listeners still fire for the error event.
9866 listenToNonDelegatedEvent('error', domElement);
9867 props = rawProps;
9868 break;
9869
9870 case 'img':
9871 case 'image':
9872 case 'link':
9873 // We listen to these events in case to ensure emulated bubble
9874 // listeners still fire for error and load events.
9875 listenToNonDelegatedEvent('error', domElement);
9876 listenToNonDelegatedEvent('load', domElement);
9877 props = rawProps;
9878 break;
9879
9880 case 'details':
9881 // We listen to this event in case to ensure emulated bubble
9882 // listeners still fire for the toggle event.
9883 listenToNonDelegatedEvent('toggle', domElement);
9884 props = rawProps;
9885 break;
9886
9887 case 'input':
9888 initWrapperState(domElement, rawProps);
9889 props = getHostProps(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9890 // listeners still fire for the invalid event.
9891
9892 listenToNonDelegatedEvent('invalid', domElement);
9893 break;
9894
9895 case 'option':
9896 validateProps(domElement, rawProps);
9897 props = rawProps;
9898 break;
9899
9900 case 'select':
9901 initWrapperState$1(domElement, rawProps);
9902 props = getHostProps$1(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9903 // listeners still fire for the invalid event.
9904
9905 listenToNonDelegatedEvent('invalid', domElement);
9906 break;
9907
9908 case 'textarea':
9909 initWrapperState$2(domElement, rawProps);
9910 props = getHostProps$2(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9911 // listeners still fire for the invalid event.
9912
9913 listenToNonDelegatedEvent('invalid', domElement);
9914 break;
9915
9916 default:
9917 props = rawProps;
9918 }
9919
9920 assertValidProps(tag, props);
9921 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
9922
9923 switch (tag) {
9924 case 'input':
9925 // TODO: Make sure we check if this is still unmounted or do any clean
9926 // up necessary since we never stop tracking anymore.
9927 track(domElement);
9928 postMountWrapper(domElement, rawProps, false);
9929 break;
9930
9931 case 'textarea':
9932 // TODO: Make sure we check if this is still unmounted or do any clean
9933 // up necessary since we never stop tracking anymore.
9934 track(domElement);
9935 postMountWrapper$3(domElement);
9936 break;
9937
9938 case 'option':
9939 postMountWrapper$1(domElement, rawProps);
9940 break;
9941
9942 case 'select':
9943 postMountWrapper$2(domElement, rawProps);
9944 break;
9945
9946 default:
9947 if (typeof props.onClick === 'function') {
9948 // TODO: This cast may not be sound for SVG, MathML or custom elements.
9949 trapClickOnNonInteractiveElement(domElement);
9950 }
9951
9952 break;
9953 }
9954 } // Calculate the diff between the two objects.
9955
9956 function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
9957 {
9958 validatePropertiesInDevelopment(tag, nextRawProps);
9959 }
9960
9961 var updatePayload = null;
9962 var lastProps;
9963 var nextProps;
9964
9965 switch (tag) {
9966 case 'input':
9967 lastProps = getHostProps(domElement, lastRawProps);
9968 nextProps = getHostProps(domElement, nextRawProps);
9969 updatePayload = [];
9970 break;
9971
9972 case 'select':
9973 lastProps = getHostProps$1(domElement, lastRawProps);
9974 nextProps = getHostProps$1(domElement, nextRawProps);
9975 updatePayload = [];
9976 break;
9977
9978 case 'textarea':
9979 lastProps = getHostProps$2(domElement, lastRawProps);
9980 nextProps = getHostProps$2(domElement, nextRawProps);
9981 updatePayload = [];
9982 break;
9983
9984 default:
9985 lastProps = lastRawProps;
9986 nextProps = nextRawProps;
9987
9988 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
9989 // TODO: This cast may not be sound for SVG, MathML or custom elements.
9990 trapClickOnNonInteractiveElement(domElement);
9991 }
9992
9993 break;
9994 }
9995
9996 assertValidProps(tag, nextProps);
9997 var propKey;
9998 var styleName;
9999 var styleUpdates = null;
10000
10001 for (propKey in lastProps) {
10002 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
10003 continue;
10004 }
10005
10006 if (propKey === STYLE) {
10007 var lastStyle = lastProps[propKey];
10008
10009 for (styleName in lastStyle) {
10010 if (lastStyle.hasOwnProperty(styleName)) {
10011 if (!styleUpdates) {
10012 styleUpdates = {};
10013 }
10014
10015 styleUpdates[styleName] = '';
10016 }
10017 }
10018 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) ; else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (propKey === AUTOFOCUS) ; else if (registrationNameDependencies.hasOwnProperty(propKey)) {
10019 // This is a special case. If any listener updates we need to ensure
10020 // that the "current" fiber pointer gets updated so we need a commit
10021 // to update this element.
10022 if (!updatePayload) {
10023 updatePayload = [];
10024 }
10025 } else {
10026 // For all other deleted properties we add it to the queue. We use
10027 // the allowed property list in the commit phase instead.
10028 (updatePayload = updatePayload || []).push(propKey, null);
10029 }
10030 }
10031
10032 for (propKey in nextProps) {
10033 var nextProp = nextProps[propKey];
10034 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
10035
10036 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
10037 continue;
10038 }
10039
10040 if (propKey === STYLE) {
10041 {
10042 if (nextProp) {
10043 // Freeze the next style object so that we can assume it won't be
10044 // mutated. We have already warned for this in the past.
10045 Object.freeze(nextProp);
10046 }
10047 }
10048
10049 if (lastProp) {
10050 // Unset styles on `lastProp` but not on `nextProp`.
10051 for (styleName in lastProp) {
10052 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
10053 if (!styleUpdates) {
10054 styleUpdates = {};
10055 }
10056
10057 styleUpdates[styleName] = '';
10058 }
10059 } // Update styles that changed since `lastProp`.
10060
10061
10062 for (styleName in nextProp) {
10063 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
10064 if (!styleUpdates) {
10065 styleUpdates = {};
10066 }
10067
10068 styleUpdates[styleName] = nextProp[styleName];
10069 }
10070 }
10071 } else {
10072 // Relies on `updateStylesByID` not mutating `styleUpdates`.
10073 if (!styleUpdates) {
10074 if (!updatePayload) {
10075 updatePayload = [];
10076 }
10077
10078 updatePayload.push(propKey, styleUpdates);
10079 }
10080
10081 styleUpdates = nextProp;
10082 }
10083 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
10084 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
10085 var lastHtml = lastProp ? lastProp[HTML$1] : undefined;
10086
10087 if (nextHtml != null) {
10088 if (lastHtml !== nextHtml) {
10089 (updatePayload = updatePayload || []).push(propKey, nextHtml);
10090 }
10091 }
10092 } else if (propKey === CHILDREN) {
10093 if (typeof nextProp === 'string' || typeof nextProp === 'number') {
10094 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
10095 }
10096 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (registrationNameDependencies.hasOwnProperty(propKey)) {
10097 if (nextProp != null) {
10098 // We eagerly listen to this even though we haven't committed yet.
10099 if ( typeof nextProp !== 'function') {
10100 warnForInvalidEventListener(propKey, nextProp);
10101 }
10102
10103 if (propKey === 'onScroll') {
10104 listenToNonDelegatedEvent('scroll', domElement);
10105 }
10106 }
10107
10108 if (!updatePayload && lastProp !== nextProp) {
10109 // This is a special case. If any listener updates we need to ensure
10110 // that the "current" props pointer gets updated so we need a commit
10111 // to update this element.
10112 updatePayload = [];
10113 }
10114 } else {
10115 // For any other property we always add it to the queue and then we
10116 // filter it out using the allowed property list during the commit.
10117 (updatePayload = updatePayload || []).push(propKey, nextProp);
10118 }
10119 }
10120
10121 if (styleUpdates) {
10122 {
10123 validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE]);
10124 }
10125
10126 (updatePayload = updatePayload || []).push(STYLE, styleUpdates);
10127 }
10128
10129 return updatePayload;
10130 } // Apply the diff.
10131
10132 function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
10133 // Update checked *before* name.
10134 // In the middle of an update, it is possible to have multiple checked.
10135 // When a checked radio tries to change name, browser makes another radio's checked false.
10136 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
10137 updateChecked(domElement, nextRawProps);
10138 }
10139
10140 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
10141 var isCustomComponentTag = isCustomComponent(tag, nextRawProps); // Apply the diff.
10142
10143 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag); // TODO: Ensure that an update gets scheduled if any of the special props
10144 // changed.
10145
10146 switch (tag) {
10147 case 'input':
10148 // Update the wrapper around inputs *after* updating props. This has to
10149 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
10150 // raise warnings and prevent the new value from being assigned.
10151 updateWrapper(domElement, nextRawProps);
10152 break;
10153
10154 case 'textarea':
10155 updateWrapper$1(domElement, nextRawProps);
10156 break;
10157
10158 case 'select':
10159 // <select> value update needs to occur after <option> children
10160 // reconciliation
10161 postUpdateWrapper(domElement, nextRawProps);
10162 break;
10163 }
10164 }
10165
10166 function getPossibleStandardName(propName) {
10167 {
10168 var lowerCasedName = propName.toLowerCase();
10169
10170 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
10171 return null;
10172 }
10173
10174 return possibleStandardNames[lowerCasedName] || null;
10175 }
10176 }
10177
10178 function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement, isConcurrentMode, shouldWarnDev) {
10179 var isCustomComponentTag;
10180 var extraAttributeNames;
10181
10182 {
10183 isCustomComponentTag = isCustomComponent(tag, rawProps);
10184 validatePropertiesInDevelopment(tag, rawProps);
10185 } // TODO: Make sure that we check isMounted before firing any of these events.
10186
10187
10188 switch (tag) {
10189 case 'dialog':
10190 listenToNonDelegatedEvent('cancel', domElement);
10191 listenToNonDelegatedEvent('close', domElement);
10192 break;
10193
10194 case 'iframe':
10195 case 'object':
10196 case 'embed':
10197 // We listen to this event in case to ensure emulated bubble
10198 // listeners still fire for the load event.
10199 listenToNonDelegatedEvent('load', domElement);
10200 break;
10201
10202 case 'video':
10203 case 'audio':
10204 // We listen to these events in case to ensure emulated bubble
10205 // listeners still fire for all the media events.
10206 for (var i = 0; i < mediaEventTypes.length; i++) {
10207 listenToNonDelegatedEvent(mediaEventTypes[i], domElement);
10208 }
10209
10210 break;
10211
10212 case 'source':
10213 // We listen to this event in case to ensure emulated bubble
10214 // listeners still fire for the error event.
10215 listenToNonDelegatedEvent('error', domElement);
10216 break;
10217
10218 case 'img':
10219 case 'image':
10220 case 'link':
10221 // We listen to these events in case to ensure emulated bubble
10222 // listeners still fire for error and load events.
10223 listenToNonDelegatedEvent('error', domElement);
10224 listenToNonDelegatedEvent('load', domElement);
10225 break;
10226
10227 case 'details':
10228 // We listen to this event in case to ensure emulated bubble
10229 // listeners still fire for the toggle event.
10230 listenToNonDelegatedEvent('toggle', domElement);
10231 break;
10232
10233 case 'input':
10234 initWrapperState(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
10235 // listeners still fire for the invalid event.
10236
10237 listenToNonDelegatedEvent('invalid', domElement);
10238 break;
10239
10240 case 'option':
10241 validateProps(domElement, rawProps);
10242 break;
10243
10244 case 'select':
10245 initWrapperState$1(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
10246 // listeners still fire for the invalid event.
10247
10248 listenToNonDelegatedEvent('invalid', domElement);
10249 break;
10250
10251 case 'textarea':
10252 initWrapperState$2(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
10253 // listeners still fire for the invalid event.
10254
10255 listenToNonDelegatedEvent('invalid', domElement);
10256 break;
10257 }
10258
10259 assertValidProps(tag, rawProps);
10260
10261 {
10262 extraAttributeNames = new Set();
10263 var attributes = domElement.attributes;
10264
10265 for (var _i = 0; _i < attributes.length; _i++) {
10266 var name = attributes[_i].name.toLowerCase();
10267
10268 switch (name) {
10269 // Controlled attributes are not validated
10270 // TODO: Only ignore them on controlled tags.
10271 case 'value':
10272 break;
10273
10274 case 'checked':
10275 break;
10276
10277 case 'selected':
10278 break;
10279
10280 default:
10281 // Intentionally use the original name.
10282 // See discussion in https://github.com/facebook/react/pull/10676.
10283 extraAttributeNames.add(attributes[_i].name);
10284 }
10285 }
10286 }
10287
10288 var updatePayload = null;
10289
10290 for (var propKey in rawProps) {
10291 if (!rawProps.hasOwnProperty(propKey)) {
10292 continue;
10293 }
10294
10295 var nextProp = rawProps[propKey];
10296
10297 if (propKey === CHILDREN) {
10298 // For text content children we compare against textContent. This
10299 // might match additional HTML that is hidden when we read it using
10300 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
10301 // satisfies our requirement. Our requirement is not to produce perfect
10302 // HTML and attributes. Ideally we should preserve structure but it's
10303 // ok not to if the visible content is still enough to indicate what
10304 // even listeners these nodes might be wired up to.
10305 // TODO: Warn if there is more than a single textNode as a child.
10306 // TODO: Should we use domElement.firstChild.nodeValue to compare?
10307 if (typeof nextProp === 'string') {
10308 if (domElement.textContent !== nextProp) {
10309 if (rawProps[SUPPRESS_HYDRATION_WARNING] !== true) {
10310 checkForUnmatchedText(domElement.textContent, nextProp, isConcurrentMode, shouldWarnDev);
10311 }
10312
10313 updatePayload = [CHILDREN, nextProp];
10314 }
10315 } else if (typeof nextProp === 'number') {
10316 if (domElement.textContent !== '' + nextProp) {
10317 if (rawProps[SUPPRESS_HYDRATION_WARNING] !== true) {
10318 checkForUnmatchedText(domElement.textContent, nextProp, isConcurrentMode, shouldWarnDev);
10319 }
10320
10321 updatePayload = [CHILDREN, '' + nextProp];
10322 }
10323 }
10324 } else if (registrationNameDependencies.hasOwnProperty(propKey)) {
10325 if (nextProp != null) {
10326 if ( typeof nextProp !== 'function') {
10327 warnForInvalidEventListener(propKey, nextProp);
10328 }
10329
10330 if (propKey === 'onScroll') {
10331 listenToNonDelegatedEvent('scroll', domElement);
10332 }
10333 }
10334 } else if (shouldWarnDev && true && // Convince Flow we've calculated it (it's DEV-only in this method.)
10335 typeof isCustomComponentTag === 'boolean') {
10336 // Validate that the properties correspond to their expected values.
10337 var serverValue = void 0;
10338 var propertyInfo = isCustomComponentTag && enableCustomElementPropertySupport ? null : getPropertyInfo(propKey);
10339
10340 if (rawProps[SUPPRESS_HYDRATION_WARNING] === true) ; else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING || // Controlled attributes are not validated
10341 // TODO: Only ignore them on controlled tags.
10342 propKey === 'value' || propKey === 'checked' || propKey === 'selected') ; else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
10343 var serverHTML = domElement.innerHTML;
10344 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
10345
10346 if (nextHtml != null) {
10347 var expectedHTML = normalizeHTML(domElement, nextHtml);
10348
10349 if (expectedHTML !== serverHTML) {
10350 warnForPropDifference(propKey, serverHTML, expectedHTML);
10351 }
10352 }
10353 } else if (propKey === STYLE) {
10354 // $FlowFixMe - Should be inferred as not undefined.
10355 extraAttributeNames.delete(propKey);
10356
10357 if (canDiffStyleForHydrationWarning) {
10358 var expectedStyle = createDangerousStringForStyles(nextProp);
10359 serverValue = domElement.getAttribute('style');
10360
10361 if (expectedStyle !== serverValue) {
10362 warnForPropDifference(propKey, serverValue, expectedStyle);
10363 }
10364 }
10365 } else if (isCustomComponentTag && !enableCustomElementPropertySupport) {
10366 // $FlowFixMe - Should be inferred as not undefined.
10367 extraAttributeNames.delete(propKey.toLowerCase());
10368 serverValue = getValueForAttribute(domElement, propKey, nextProp);
10369
10370 if (nextProp !== serverValue) {
10371 warnForPropDifference(propKey, serverValue, nextProp);
10372 }
10373 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
10374 var isMismatchDueToBadCasing = false;
10375
10376 if (propertyInfo !== null) {
10377 // $FlowFixMe - Should be inferred as not undefined.
10378 extraAttributeNames.delete(propertyInfo.attributeName);
10379 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
10380 } else {
10381 var ownNamespace = parentNamespace;
10382
10383 if (ownNamespace === HTML_NAMESPACE) {
10384 ownNamespace = getIntrinsicNamespace(tag);
10385 }
10386
10387 if (ownNamespace === HTML_NAMESPACE) {
10388 // $FlowFixMe - Should be inferred as not undefined.
10389 extraAttributeNames.delete(propKey.toLowerCase());
10390 } else {
10391 var standardName = getPossibleStandardName(propKey);
10392
10393 if (standardName !== null && standardName !== propKey) {
10394 // If an SVG prop is supplied with bad casing, it will
10395 // be successfully parsed from HTML, but will produce a mismatch
10396 // (and would be incorrectly rendered on the client).
10397 // However, we already warn about bad casing elsewhere.
10398 // So we'll skip the misleading extra mismatch warning in this case.
10399 isMismatchDueToBadCasing = true; // $FlowFixMe - Should be inferred as not undefined.
10400
10401 extraAttributeNames.delete(standardName);
10402 } // $FlowFixMe - Should be inferred as not undefined.
10403
10404
10405 extraAttributeNames.delete(propKey);
10406 }
10407
10408 serverValue = getValueForAttribute(domElement, propKey, nextProp);
10409 }
10410
10411 var dontWarnCustomElement = enableCustomElementPropertySupport ;
10412
10413 if (!dontWarnCustomElement && nextProp !== serverValue && !isMismatchDueToBadCasing) {
10414 warnForPropDifference(propKey, serverValue, nextProp);
10415 }
10416 }
10417 }
10418 }
10419
10420 {
10421 if (shouldWarnDev) {
10422 if ( // $FlowFixMe - Should be inferred as not undefined.
10423 extraAttributeNames.size > 0 && rawProps[SUPPRESS_HYDRATION_WARNING] !== true) {
10424 // $FlowFixMe - Should be inferred as not undefined.
10425 warnForExtraAttributes(extraAttributeNames);
10426 }
10427 }
10428 }
10429
10430 switch (tag) {
10431 case 'input':
10432 // TODO: Make sure we check if this is still unmounted or do any clean
10433 // up necessary since we never stop tracking anymore.
10434 track(domElement);
10435 postMountWrapper(domElement, rawProps, true);
10436 break;
10437
10438 case 'textarea':
10439 // TODO: Make sure we check if this is still unmounted or do any clean
10440 // up necessary since we never stop tracking anymore.
10441 track(domElement);
10442 postMountWrapper$3(domElement);
10443 break;
10444
10445 case 'select':
10446 case 'option':
10447 // For input and textarea we current always set the value property at
10448 // post mount to force it to diverge from attributes. However, for
10449 // option and select we don't quite do the same thing and select
10450 // is not resilient to the DOM state changing so we don't do that here.
10451 // TODO: Consider not doing this for input and textarea.
10452 break;
10453
10454 default:
10455 if (typeof rawProps.onClick === 'function') {
10456 // TODO: This cast may not be sound for SVG, MathML or custom elements.
10457 trapClickOnNonInteractiveElement(domElement);
10458 }
10459
10460 break;
10461 }
10462
10463 return updatePayload;
10464 }
10465 function diffHydratedText(textNode, text, isConcurrentMode) {
10466 var isDifferent = textNode.nodeValue !== text;
10467 return isDifferent;
10468 }
10469 function warnForDeletedHydratableElement(parentNode, child) {
10470 {
10471 if (didWarnInvalidHydration) {
10472 return;
10473 }
10474
10475 didWarnInvalidHydration = true;
10476
10477 error('Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
10478 }
10479 }
10480 function warnForDeletedHydratableText(parentNode, child) {
10481 {
10482 if (didWarnInvalidHydration) {
10483 return;
10484 }
10485
10486 didWarnInvalidHydration = true;
10487
10488 error('Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
10489 }
10490 }
10491 function warnForInsertedHydratedElement(parentNode, tag, props) {
10492 {
10493 if (didWarnInvalidHydration) {
10494 return;
10495 }
10496
10497 didWarnInvalidHydration = true;
10498
10499 error('Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
10500 }
10501 }
10502 function warnForInsertedHydratedText(parentNode, text) {
10503 {
10504 if (text === '') {
10505 // We expect to insert empty text nodes since they're not represented in
10506 // the HTML.
10507 // TODO: Remove this special case if we can just avoid inserting empty
10508 // text nodes.
10509 return;
10510 }
10511
10512 if (didWarnInvalidHydration) {
10513 return;
10514 }
10515
10516 didWarnInvalidHydration = true;
10517
10518 error('Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
10519 }
10520 }
10521 function restoreControlledState$3(domElement, tag, props) {
10522 switch (tag) {
10523 case 'input':
10524 restoreControlledState(domElement, props);
10525 return;
10526
10527 case 'textarea':
10528 restoreControlledState$2(domElement, props);
10529 return;
10530
10531 case 'select':
10532 restoreControlledState$1(domElement, props);
10533 return;
10534 }
10535 }
10536
10537 var validateDOMNesting = function () {};
10538
10539 var updatedAncestorInfo = function () {};
10540
10541 {
10542 // This validation code was written based on the HTML5 parsing spec:
10543 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
10544 //
10545 // Note: this does not catch all invalid nesting, nor does it try to (as it's
10546 // not clear what practical benefit doing so provides); instead, we warn only
10547 // for cases where the parser will give a parse tree differing from what React
10548 // intended. For example, <b><div></div></b> is invalid but we don't warn
10549 // because it still parses correctly; we do warn for other cases like nested
10550 // <p> tags where the beginning of the second element implicitly closes the
10551 // first, causing a confusing mess.
10552 // https://html.spec.whatwg.org/multipage/syntax.html#special
10553 var specialTags = ['address', 'applet', 'area', 'article', 'aside', 'base', 'basefont', 'bgsound', 'blockquote', 'body', 'br', 'button', 'caption', 'center', 'col', 'colgroup', 'dd', 'details', 'dir', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'iframe', 'img', 'input', 'isindex', 'li', 'link', 'listing', 'main', 'marquee', 'menu', 'menuitem', 'meta', 'nav', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'p', 'param', 'plaintext', 'pre', 'script', 'section', 'select', 'source', 'style', 'summary', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul', 'wbr', 'xmp']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
10554
10555 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template', // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
10556 // TODO: Distinguish by namespace here -- for <title>, including it here
10557 // errs on the side of fewer warnings
10558 'foreignObject', 'desc', 'title']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
10559
10560 var buttonScopeTags = inScopeTags.concat(['button']); // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
10561
10562 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
10563 var emptyAncestorInfo = {
10564 current: null,
10565 formTag: null,
10566 aTagInScope: null,
10567 buttonTagInScope: null,
10568 nobrTagInScope: null,
10569 pTagInButtonScope: null,
10570 listItemTagAutoclosing: null,
10571 dlItemTagAutoclosing: null
10572 };
10573
10574 updatedAncestorInfo = function (oldInfo, tag) {
10575 var ancestorInfo = assign({}, oldInfo || emptyAncestorInfo);
10576
10577 var info = {
10578 tag: tag
10579 };
10580
10581 if (inScopeTags.indexOf(tag) !== -1) {
10582 ancestorInfo.aTagInScope = null;
10583 ancestorInfo.buttonTagInScope = null;
10584 ancestorInfo.nobrTagInScope = null;
10585 }
10586
10587 if (buttonScopeTags.indexOf(tag) !== -1) {
10588 ancestorInfo.pTagInButtonScope = null;
10589 } // See rules for 'li', 'dd', 'dt' start tags in
10590 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
10591
10592
10593 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
10594 ancestorInfo.listItemTagAutoclosing = null;
10595 ancestorInfo.dlItemTagAutoclosing = null;
10596 }
10597
10598 ancestorInfo.current = info;
10599
10600 if (tag === 'form') {
10601 ancestorInfo.formTag = info;
10602 }
10603
10604 if (tag === 'a') {
10605 ancestorInfo.aTagInScope = info;
10606 }
10607
10608 if (tag === 'button') {
10609 ancestorInfo.buttonTagInScope = info;
10610 }
10611
10612 if (tag === 'nobr') {
10613 ancestorInfo.nobrTagInScope = info;
10614 }
10615
10616 if (tag === 'p') {
10617 ancestorInfo.pTagInButtonScope = info;
10618 }
10619
10620 if (tag === 'li') {
10621 ancestorInfo.listItemTagAutoclosing = info;
10622 }
10623
10624 if (tag === 'dd' || tag === 'dt') {
10625 ancestorInfo.dlItemTagAutoclosing = info;
10626 }
10627
10628 return ancestorInfo;
10629 };
10630 /**
10631 * Returns whether
10632 */
10633
10634
10635 var isTagValidWithParent = function (tag, parentTag) {
10636 // First, let's check if we're in an unusual parsing mode...
10637 switch (parentTag) {
10638 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
10639 case 'select':
10640 return tag === 'option' || tag === 'optgroup' || tag === '#text';
10641
10642 case 'optgroup':
10643 return tag === 'option' || tag === '#text';
10644 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
10645 // but
10646
10647 case 'option':
10648 return tag === '#text';
10649 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
10650 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
10651 // No special behavior since these rules fall back to "in body" mode for
10652 // all except special table nodes which cause bad parsing behavior anyway.
10653 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
10654
10655 case 'tr':
10656 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
10657 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
10658
10659 case 'tbody':
10660 case 'thead':
10661 case 'tfoot':
10662 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
10663 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
10664
10665 case 'colgroup':
10666 return tag === 'col' || tag === 'template';
10667 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
10668
10669 case 'table':
10670 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
10671 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
10672
10673 case 'head':
10674 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
10675 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
10676
10677 case 'html':
10678 return tag === 'head' || tag === 'body' || tag === 'frameset';
10679
10680 case 'frameset':
10681 return tag === 'frame';
10682
10683 case '#document':
10684 return tag === 'html';
10685 } // Probably in the "in body" parsing mode, so we outlaw only tag combos
10686 // where the parsing rules cause implicit opens or closes to be added.
10687 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
10688
10689
10690 switch (tag) {
10691 case 'h1':
10692 case 'h2':
10693 case 'h3':
10694 case 'h4':
10695 case 'h5':
10696 case 'h6':
10697 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
10698
10699 case 'rp':
10700 case 'rt':
10701 return impliedEndTags.indexOf(parentTag) === -1;
10702
10703 case 'body':
10704 case 'caption':
10705 case 'col':
10706 case 'colgroup':
10707 case 'frameset':
10708 case 'frame':
10709 case 'head':
10710 case 'html':
10711 case 'tbody':
10712 case 'td':
10713 case 'tfoot':
10714 case 'th':
10715 case 'thead':
10716 case 'tr':
10717 // These tags are only valid with a few parents that have special child
10718 // parsing rules -- if we're down here, then none of those matched and
10719 // so we allow it only if we don't know what the parent is, as all other
10720 // cases are invalid.
10721 return parentTag == null;
10722 }
10723
10724 return true;
10725 };
10726 /**
10727 * Returns whether
10728 */
10729
10730
10731 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
10732 switch (tag) {
10733 case 'address':
10734 case 'article':
10735 case 'aside':
10736 case 'blockquote':
10737 case 'center':
10738 case 'details':
10739 case 'dialog':
10740 case 'dir':
10741 case 'div':
10742 case 'dl':
10743 case 'fieldset':
10744 case 'figcaption':
10745 case 'figure':
10746 case 'footer':
10747 case 'header':
10748 case 'hgroup':
10749 case 'main':
10750 case 'menu':
10751 case 'nav':
10752 case 'ol':
10753 case 'p':
10754 case 'section':
10755 case 'summary':
10756 case 'ul':
10757 case 'pre':
10758 case 'listing':
10759 case 'table':
10760 case 'hr':
10761 case 'xmp':
10762 case 'h1':
10763 case 'h2':
10764 case 'h3':
10765 case 'h4':
10766 case 'h5':
10767 case 'h6':
10768 return ancestorInfo.pTagInButtonScope;
10769
10770 case 'form':
10771 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
10772
10773 case 'li':
10774 return ancestorInfo.listItemTagAutoclosing;
10775
10776 case 'dd':
10777 case 'dt':
10778 return ancestorInfo.dlItemTagAutoclosing;
10779
10780 case 'button':
10781 return ancestorInfo.buttonTagInScope;
10782
10783 case 'a':
10784 // Spec says something about storing a list of markers, but it sounds
10785 // equivalent to this check.
10786 return ancestorInfo.aTagInScope;
10787
10788 case 'nobr':
10789 return ancestorInfo.nobrTagInScope;
10790 }
10791
10792 return null;
10793 };
10794
10795 var didWarn$1 = {};
10796
10797 validateDOMNesting = function (childTag, childText, ancestorInfo) {
10798 ancestorInfo = ancestorInfo || emptyAncestorInfo;
10799 var parentInfo = ancestorInfo.current;
10800 var parentTag = parentInfo && parentInfo.tag;
10801
10802 if (childText != null) {
10803 if (childTag != null) {
10804 error('validateDOMNesting: when childText is passed, childTag should be null');
10805 }
10806
10807 childTag = '#text';
10808 }
10809
10810 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
10811 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
10812 var invalidParentOrAncestor = invalidParent || invalidAncestor;
10813
10814 if (!invalidParentOrAncestor) {
10815 return;
10816 }
10817
10818 var ancestorTag = invalidParentOrAncestor.tag;
10819 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag;
10820
10821 if (didWarn$1[warnKey]) {
10822 return;
10823 }
10824
10825 didWarn$1[warnKey] = true;
10826 var tagDisplayName = childTag;
10827 var whitespaceInfo = '';
10828
10829 if (childTag === '#text') {
10830 if (/\S/.test(childText)) {
10831 tagDisplayName = 'Text nodes';
10832 } else {
10833 tagDisplayName = 'Whitespace text nodes';
10834 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
10835 }
10836 } else {
10837 tagDisplayName = '<' + childTag + '>';
10838 }
10839
10840 if (invalidParent) {
10841 var info = '';
10842
10843 if (ancestorTag === 'table' && childTag === 'tr') {
10844 info += ' Add a <tbody>, <thead> or <tfoot> to your code to match the DOM tree generated by ' + 'the browser.';
10845 }
10846
10847 error('validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info);
10848 } else {
10849 error('validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.', tagDisplayName, ancestorTag);
10850 }
10851 };
10852 }
10853
10854 var SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
10855 var SUSPENSE_START_DATA = '$';
10856 var SUSPENSE_END_DATA = '/$';
10857 var SUSPENSE_PENDING_START_DATA = '$?';
10858 var SUSPENSE_FALLBACK_START_DATA = '$!';
10859 var STYLE$1 = 'style';
10860 var eventsEnabled = null;
10861 var selectionInformation = null;
10862 function getRootHostContext(rootContainerInstance) {
10863 var type;
10864 var namespace;
10865 var nodeType = rootContainerInstance.nodeType;
10866
10867 switch (nodeType) {
10868 case DOCUMENT_NODE:
10869 case DOCUMENT_FRAGMENT_NODE:
10870 {
10871 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
10872 var root = rootContainerInstance.documentElement;
10873 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
10874 break;
10875 }
10876
10877 default:
10878 {
10879 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
10880 var ownNamespace = container.namespaceURI || null;
10881 type = container.tagName;
10882 namespace = getChildNamespace(ownNamespace, type);
10883 break;
10884 }
10885 }
10886
10887 {
10888 var validatedTag = type.toLowerCase();
10889 var ancestorInfo = updatedAncestorInfo(null, validatedTag);
10890 return {
10891 namespace: namespace,
10892 ancestorInfo: ancestorInfo
10893 };
10894 }
10895 }
10896 function getChildHostContext(parentHostContext, type, rootContainerInstance) {
10897 {
10898 var parentHostContextDev = parentHostContext;
10899 var namespace = getChildNamespace(parentHostContextDev.namespace, type);
10900 var ancestorInfo = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type);
10901 return {
10902 namespace: namespace,
10903 ancestorInfo: ancestorInfo
10904 };
10905 }
10906 }
10907 function getPublicInstance(instance) {
10908 return instance;
10909 }
10910 function prepareForCommit(containerInfo) {
10911 eventsEnabled = isEnabled();
10912 selectionInformation = getSelectionInformation();
10913 var activeInstance = null;
10914
10915 setEnabled(false);
10916 return activeInstance;
10917 }
10918 function resetAfterCommit(containerInfo) {
10919 restoreSelection(selectionInformation);
10920 setEnabled(eventsEnabled);
10921 eventsEnabled = null;
10922 selectionInformation = null;
10923 }
10924 function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
10925 var parentNamespace;
10926
10927 {
10928 // TODO: take namespace into account when validating.
10929 var hostContextDev = hostContext;
10930 validateDOMNesting(type, null, hostContextDev.ancestorInfo);
10931
10932 if (typeof props.children === 'string' || typeof props.children === 'number') {
10933 var string = '' + props.children;
10934 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
10935 validateDOMNesting(null, string, ownAncestorInfo);
10936 }
10937
10938 parentNamespace = hostContextDev.namespace;
10939 }
10940
10941 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
10942 precacheFiberNode(internalInstanceHandle, domElement);
10943 updateFiberProps(domElement, props);
10944 return domElement;
10945 }
10946 function appendInitialChild(parentInstance, child) {
10947 parentInstance.appendChild(child);
10948 }
10949 function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) {
10950 setInitialProperties(domElement, type, props, rootContainerInstance);
10951
10952 switch (type) {
10953 case 'button':
10954 case 'input':
10955 case 'select':
10956 case 'textarea':
10957 return !!props.autoFocus;
10958
10959 case 'img':
10960 return true;
10961
10962 default:
10963 return false;
10964 }
10965 }
10966 function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
10967 {
10968 var hostContextDev = hostContext;
10969
10970 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
10971 var string = '' + newProps.children;
10972 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
10973 validateDOMNesting(null, string, ownAncestorInfo);
10974 }
10975 }
10976
10977 return diffProperties(domElement, type, oldProps, newProps);
10978 }
10979 function shouldSetTextContent(type, props) {
10980 return type === 'textarea' || type === 'noscript' || typeof props.children === 'string' || typeof props.children === 'number' || typeof props.dangerouslySetInnerHTML === 'object' && props.dangerouslySetInnerHTML !== null && props.dangerouslySetInnerHTML.__html != null;
10981 }
10982 function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
10983 {
10984 var hostContextDev = hostContext;
10985 validateDOMNesting(null, text, hostContextDev.ancestorInfo);
10986 }
10987
10988 var textNode = createTextNode(text, rootContainerInstance);
10989 precacheFiberNode(internalInstanceHandle, textNode);
10990 return textNode;
10991 }
10992 function getCurrentEventPriority() {
10993 var currentEvent = window.event;
10994
10995 if (currentEvent === undefined) {
10996 return DefaultEventPriority;
10997 }
10998
10999 return getEventPriority(currentEvent.type);
11000 }
11001 // if a component just imports ReactDOM (e.g. for findDOMNode).
11002 // Some environments might not have setTimeout or clearTimeout.
11003
11004 var scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined;
11005 var cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined;
11006 var noTimeout = -1;
11007 var localPromise = typeof Promise === 'function' ? Promise : undefined; // -------------------
11008 var scheduleMicrotask = typeof queueMicrotask === 'function' ? queueMicrotask : typeof localPromise !== 'undefined' ? function (callback) {
11009 return localPromise.resolve(null).then(callback).catch(handleErrorInNextTick);
11010 } : scheduleTimeout; // TODO: Determine the best fallback here.
11011
11012 function handleErrorInNextTick(error) {
11013 setTimeout(function () {
11014 throw error;
11015 });
11016 } // -------------------
11017 function commitMount(domElement, type, newProps, internalInstanceHandle) {
11018 // Despite the naming that might imply otherwise, this method only
11019 // fires if there is an `Update` effect scheduled during mounting.
11020 // This happens if `finalizeInitialChildren` returns `true` (which it
11021 // does to implement the `autoFocus` attribute on the client). But
11022 // there are also other cases when this might happen (such as patching
11023 // up text content during hydration mismatch). So we'll check this again.
11024 switch (type) {
11025 case 'button':
11026 case 'input':
11027 case 'select':
11028 case 'textarea':
11029 if (newProps.autoFocus) {
11030 domElement.focus();
11031 }
11032
11033 return;
11034
11035 case 'img':
11036 {
11037 if (newProps.src) {
11038 domElement.src = newProps.src;
11039 }
11040
11041 return;
11042 }
11043 }
11044 }
11045 function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
11046 // Apply the diff to the DOM node.
11047 updateProperties(domElement, updatePayload, type, oldProps, newProps); // Update the props handle so that we know which props are the ones with
11048 // with current event handlers.
11049
11050 updateFiberProps(domElement, newProps);
11051 }
11052 function resetTextContent(domElement) {
11053 setTextContent(domElement, '');
11054 }
11055 function commitTextUpdate(textInstance, oldText, newText) {
11056 textInstance.nodeValue = newText;
11057 }
11058 function appendChild(parentInstance, child) {
11059 parentInstance.appendChild(child);
11060 }
11061 function appendChildToContainer(container, child) {
11062 var parentNode;
11063
11064 if (container.nodeType === COMMENT_NODE) {
11065 parentNode = container.parentNode;
11066 parentNode.insertBefore(child, container);
11067 } else {
11068 parentNode = container;
11069 parentNode.appendChild(child);
11070 } // This container might be used for a portal.
11071 // If something inside a portal is clicked, that click should bubble
11072 // through the React tree. However, on Mobile Safari the click would
11073 // never bubble through the *DOM* tree unless an ancestor with onclick
11074 // event exists. So we wouldn't see it and dispatch it.
11075 // This is why we ensure that non React root containers have inline onclick
11076 // defined.
11077 // https://github.com/facebook/react/issues/11918
11078
11079
11080 var reactRootContainer = container._reactRootContainer;
11081
11082 if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) {
11083 // TODO: This cast may not be sound for SVG, MathML or custom elements.
11084 trapClickOnNonInteractiveElement(parentNode);
11085 }
11086 }
11087 function insertBefore(parentInstance, child, beforeChild) {
11088 parentInstance.insertBefore(child, beforeChild);
11089 }
11090 function insertInContainerBefore(container, child, beforeChild) {
11091 if (container.nodeType === COMMENT_NODE) {
11092 container.parentNode.insertBefore(child, beforeChild);
11093 } else {
11094 container.insertBefore(child, beforeChild);
11095 }
11096 }
11097
11098 function removeChild(parentInstance, child) {
11099 parentInstance.removeChild(child);
11100 }
11101 function removeChildFromContainer(container, child) {
11102 if (container.nodeType === COMMENT_NODE) {
11103 container.parentNode.removeChild(child);
11104 } else {
11105 container.removeChild(child);
11106 }
11107 }
11108 function clearSuspenseBoundary(parentInstance, suspenseInstance) {
11109 var node = suspenseInstance; // Delete all nodes within this suspense boundary.
11110 // There might be nested nodes so we need to keep track of how
11111 // deep we are and only break out when we're back on top.
11112
11113 var depth = 0;
11114
11115 do {
11116 var nextNode = node.nextSibling;
11117 parentInstance.removeChild(node);
11118
11119 if (nextNode && nextNode.nodeType === COMMENT_NODE) {
11120 var data = nextNode.data;
11121
11122 if (data === SUSPENSE_END_DATA) {
11123 if (depth === 0) {
11124 parentInstance.removeChild(nextNode); // Retry if any event replaying was blocked on this.
11125
11126 retryIfBlockedOn(suspenseInstance);
11127 return;
11128 } else {
11129 depth--;
11130 }
11131 } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_PENDING_START_DATA || data === SUSPENSE_FALLBACK_START_DATA) {
11132 depth++;
11133 }
11134 }
11135
11136 node = nextNode;
11137 } while (node); // TODO: Warn, we didn't find the end comment boundary.
11138 // Retry if any event replaying was blocked on this.
11139
11140
11141 retryIfBlockedOn(suspenseInstance);
11142 }
11143 function clearSuspenseBoundaryFromContainer(container, suspenseInstance) {
11144 if (container.nodeType === COMMENT_NODE) {
11145 clearSuspenseBoundary(container.parentNode, suspenseInstance);
11146 } else if (container.nodeType === ELEMENT_NODE) {
11147 clearSuspenseBoundary(container, suspenseInstance);
11148 } // Retry if any event replaying was blocked on this.
11149
11150
11151 retryIfBlockedOn(container);
11152 }
11153 function hideInstance(instance) {
11154 // TODO: Does this work for all element types? What about MathML? Should we
11155 // pass host context to this method?
11156 instance = instance;
11157 var style = instance.style;
11158
11159 if (typeof style.setProperty === 'function') {
11160 style.setProperty('display', 'none', 'important');
11161 } else {
11162 style.display = 'none';
11163 }
11164 }
11165 function hideTextInstance(textInstance) {
11166 textInstance.nodeValue = '';
11167 }
11168 function unhideInstance(instance, props) {
11169 instance = instance;
11170 var styleProp = props[STYLE$1];
11171 var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null;
11172 instance.style.display = dangerousStyleValue('display', display);
11173 }
11174 function unhideTextInstance(textInstance, text) {
11175 textInstance.nodeValue = text;
11176 }
11177 function clearContainer(container) {
11178 if (container.nodeType === ELEMENT_NODE) {
11179 container.textContent = '';
11180 } else if (container.nodeType === DOCUMENT_NODE) {
11181 if (container.documentElement) {
11182 container.removeChild(container.documentElement);
11183 }
11184 }
11185 } // -------------------
11186 function canHydrateInstance(instance, type, props) {
11187 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
11188 return null;
11189 } // This has now been refined to an element node.
11190
11191
11192 return instance;
11193 }
11194 function canHydrateTextInstance(instance, text) {
11195 if (text === '' || instance.nodeType !== TEXT_NODE) {
11196 // Empty strings are not parsed by HTML so there won't be a correct match here.
11197 return null;
11198 } // This has now been refined to a text node.
11199
11200
11201 return instance;
11202 }
11203 function canHydrateSuspenseInstance(instance) {
11204 if (instance.nodeType !== COMMENT_NODE) {
11205 // Empty strings are not parsed by HTML so there won't be a correct match here.
11206 return null;
11207 } // This has now been refined to a suspense node.
11208
11209
11210 return instance;
11211 }
11212 function isSuspenseInstancePending(instance) {
11213 return instance.data === SUSPENSE_PENDING_START_DATA;
11214 }
11215 function isSuspenseInstanceFallback(instance) {
11216 return instance.data === SUSPENSE_FALLBACK_START_DATA;
11217 }
11218 function getSuspenseInstanceFallbackErrorDetails(instance) {
11219 var dataset = instance.nextSibling && instance.nextSibling.dataset;
11220 var digest, message, stack;
11221
11222 if (dataset) {
11223 digest = dataset.dgst;
11224
11225 {
11226 message = dataset.msg;
11227 stack = dataset.stck;
11228 }
11229 }
11230
11231 {
11232 return {
11233 message: message,
11234 digest: digest,
11235 stack: stack
11236 };
11237 } // let value = {message: undefined, hash: undefined};
11238 // const nextSibling = instance.nextSibling;
11239 // if (nextSibling) {
11240 // const dataset = ((nextSibling: any): HTMLTemplateElement).dataset;
11241 // value.message = dataset.msg;
11242 // value.hash = dataset.hash;
11243 // if (true) {
11244 // value.stack = dataset.stack;
11245 // }
11246 // }
11247 // return value;
11248
11249 }
11250 function registerSuspenseInstanceRetry(instance, callback) {
11251 instance._reactRetry = callback;
11252 }
11253
11254 function getNextHydratable(node) {
11255 // Skip non-hydratable nodes.
11256 for (; node != null; node = node.nextSibling) {
11257 var nodeType = node.nodeType;
11258
11259 if (nodeType === ELEMENT_NODE || nodeType === TEXT_NODE) {
11260 break;
11261 }
11262
11263 if (nodeType === COMMENT_NODE) {
11264 var nodeData = node.data;
11265
11266 if (nodeData === SUSPENSE_START_DATA || nodeData === SUSPENSE_FALLBACK_START_DATA || nodeData === SUSPENSE_PENDING_START_DATA) {
11267 break;
11268 }
11269
11270 if (nodeData === SUSPENSE_END_DATA) {
11271 return null;
11272 }
11273 }
11274 }
11275
11276 return node;
11277 }
11278
11279 function getNextHydratableSibling(instance) {
11280 return getNextHydratable(instance.nextSibling);
11281 }
11282 function getFirstHydratableChild(parentInstance) {
11283 return getNextHydratable(parentInstance.firstChild);
11284 }
11285 function getFirstHydratableChildWithinContainer(parentContainer) {
11286 return getNextHydratable(parentContainer.firstChild);
11287 }
11288 function getFirstHydratableChildWithinSuspenseInstance(parentInstance) {
11289 return getNextHydratable(parentInstance.nextSibling);
11290 }
11291 function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle, shouldWarnDev) {
11292 precacheFiberNode(internalInstanceHandle, instance); // TODO: Possibly defer this until the commit phase where all the events
11293 // get attached.
11294
11295 updateFiberProps(instance, props);
11296 var parentNamespace;
11297
11298 {
11299 var hostContextDev = hostContext;
11300 parentNamespace = hostContextDev.namespace;
11301 } // TODO: Temporary hack to check if we're in a concurrent root. We can delete
11302 // when the legacy root API is removed.
11303
11304
11305 var isConcurrentMode = (internalInstanceHandle.mode & ConcurrentMode) !== NoMode;
11306 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance, isConcurrentMode, shouldWarnDev);
11307 }
11308 function hydrateTextInstance(textInstance, text, internalInstanceHandle, shouldWarnDev) {
11309 precacheFiberNode(internalInstanceHandle, textInstance); // TODO: Temporary hack to check if we're in a concurrent root. We can delete
11310 // when the legacy root API is removed.
11311
11312 var isConcurrentMode = (internalInstanceHandle.mode & ConcurrentMode) !== NoMode;
11313 return diffHydratedText(textInstance, text);
11314 }
11315 function hydrateSuspenseInstance(suspenseInstance, internalInstanceHandle) {
11316 precacheFiberNode(internalInstanceHandle, suspenseInstance);
11317 }
11318 function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {
11319 var node = suspenseInstance.nextSibling; // Skip past all nodes within this suspense boundary.
11320 // There might be nested nodes so we need to keep track of how
11321 // deep we are and only break out when we're back on top.
11322
11323 var depth = 0;
11324
11325 while (node) {
11326 if (node.nodeType === COMMENT_NODE) {
11327 var data = node.data;
11328
11329 if (data === SUSPENSE_END_DATA) {
11330 if (depth === 0) {
11331 return getNextHydratableSibling(node);
11332 } else {
11333 depth--;
11334 }
11335 } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
11336 depth++;
11337 }
11338 }
11339
11340 node = node.nextSibling;
11341 } // TODO: Warn, we didn't find the end comment boundary.
11342
11343
11344 return null;
11345 } // Returns the SuspenseInstance if this node is a direct child of a
11346 // SuspenseInstance. I.e. if its previous sibling is a Comment with
11347 // SUSPENSE_x_START_DATA. Otherwise, null.
11348
11349 function getParentSuspenseInstance(targetInstance) {
11350 var node = targetInstance.previousSibling; // Skip past all nodes within this suspense boundary.
11351 // There might be nested nodes so we need to keep track of how
11352 // deep we are and only break out when we're back on top.
11353
11354 var depth = 0;
11355
11356 while (node) {
11357 if (node.nodeType === COMMENT_NODE) {
11358 var data = node.data;
11359
11360 if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
11361 if (depth === 0) {
11362 return node;
11363 } else {
11364 depth--;
11365 }
11366 } else if (data === SUSPENSE_END_DATA) {
11367 depth++;
11368 }
11369 }
11370
11371 node = node.previousSibling;
11372 }
11373
11374 return null;
11375 }
11376 function commitHydratedContainer(container) {
11377 // Retry if any event replaying was blocked on this.
11378 retryIfBlockedOn(container);
11379 }
11380 function commitHydratedSuspenseInstance(suspenseInstance) {
11381 // Retry if any event replaying was blocked on this.
11382 retryIfBlockedOn(suspenseInstance);
11383 }
11384 function shouldDeleteUnhydratedTailInstances(parentType) {
11385 return parentType !== 'head' && parentType !== 'body';
11386 }
11387 function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text, isConcurrentMode) {
11388 var shouldWarnDev = true;
11389 checkForUnmatchedText(textInstance.nodeValue, text, isConcurrentMode, shouldWarnDev);
11390 }
11391 function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text, isConcurrentMode) {
11392 if (parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
11393 var shouldWarnDev = true;
11394 checkForUnmatchedText(textInstance.nodeValue, text, isConcurrentMode, shouldWarnDev);
11395 }
11396 }
11397 function didNotHydrateInstanceWithinContainer(parentContainer, instance) {
11398 {
11399 if (instance.nodeType === ELEMENT_NODE) {
11400 warnForDeletedHydratableElement(parentContainer, instance);
11401 } else if (instance.nodeType === COMMENT_NODE) ; else {
11402 warnForDeletedHydratableText(parentContainer, instance);
11403 }
11404 }
11405 }
11406 function didNotHydrateInstanceWithinSuspenseInstance(parentInstance, instance) {
11407 {
11408 // $FlowFixMe: Only Element or Document can be parent nodes.
11409 var parentNode = parentInstance.parentNode;
11410
11411 if (parentNode !== null) {
11412 if (instance.nodeType === ELEMENT_NODE) {
11413 warnForDeletedHydratableElement(parentNode, instance);
11414 } else if (instance.nodeType === COMMENT_NODE) ; else {
11415 warnForDeletedHydratableText(parentNode, instance);
11416 }
11417 }
11418 }
11419 }
11420 function didNotHydrateInstance(parentType, parentProps, parentInstance, instance, isConcurrentMode) {
11421 {
11422 if (isConcurrentMode || parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
11423 if (instance.nodeType === ELEMENT_NODE) {
11424 warnForDeletedHydratableElement(parentInstance, instance);
11425 } else if (instance.nodeType === COMMENT_NODE) ; else {
11426 warnForDeletedHydratableText(parentInstance, instance);
11427 }
11428 }
11429 }
11430 }
11431 function didNotFindHydratableInstanceWithinContainer(parentContainer, type, props) {
11432 {
11433 warnForInsertedHydratedElement(parentContainer, type);
11434 }
11435 }
11436 function didNotFindHydratableTextInstanceWithinContainer(parentContainer, text) {
11437 {
11438 warnForInsertedHydratedText(parentContainer, text);
11439 }
11440 }
11441 function didNotFindHydratableInstanceWithinSuspenseInstance(parentInstance, type, props) {
11442 {
11443 // $FlowFixMe: Only Element or Document can be parent nodes.
11444 var parentNode = parentInstance.parentNode;
11445 if (parentNode !== null) warnForInsertedHydratedElement(parentNode, type);
11446 }
11447 }
11448 function didNotFindHydratableTextInstanceWithinSuspenseInstance(parentInstance, text) {
11449 {
11450 // $FlowFixMe: Only Element or Document can be parent nodes.
11451 var parentNode = parentInstance.parentNode;
11452 if (parentNode !== null) warnForInsertedHydratedText(parentNode, text);
11453 }
11454 }
11455 function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props, isConcurrentMode) {
11456 {
11457 if (isConcurrentMode || parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
11458 warnForInsertedHydratedElement(parentInstance, type);
11459 }
11460 }
11461 }
11462 function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text, isConcurrentMode) {
11463 {
11464 if (isConcurrentMode || parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
11465 warnForInsertedHydratedText(parentInstance, text);
11466 }
11467 }
11468 }
11469 function errorHydratingContainer(parentContainer) {
11470 {
11471 // TODO: This gets logged by onRecoverableError, too, so we should be
11472 // able to remove it.
11473 error('An error occurred during hydration. The server HTML was replaced with client content in <%s>.', parentContainer.nodeName.toLowerCase());
11474 }
11475 }
11476 function preparePortalMount(portalInstance) {
11477 listenToAllSupportedEvents(portalInstance);
11478 }
11479
11480 var randomKey = Math.random().toString(36).slice(2);
11481 var internalInstanceKey = '__reactFiber$' + randomKey;
11482 var internalPropsKey = '__reactProps$' + randomKey;
11483 var internalContainerInstanceKey = '__reactContainer$' + randomKey;
11484 var internalEventHandlersKey = '__reactEvents$' + randomKey;
11485 var internalEventHandlerListenersKey = '__reactListeners$' + randomKey;
11486 var internalEventHandlesSetKey = '__reactHandles$' + randomKey;
11487 function detachDeletedInstance(node) {
11488 // TODO: This function is only called on host components. I don't think all of
11489 // these fields are relevant.
11490 delete node[internalInstanceKey];
11491 delete node[internalPropsKey];
11492 delete node[internalEventHandlersKey];
11493 delete node[internalEventHandlerListenersKey];
11494 delete node[internalEventHandlesSetKey];
11495 }
11496 function precacheFiberNode(hostInst, node) {
11497 node[internalInstanceKey] = hostInst;
11498 }
11499 function markContainerAsRoot(hostRoot, node) {
11500 node[internalContainerInstanceKey] = hostRoot;
11501 }
11502 function unmarkContainerAsRoot(node) {
11503 node[internalContainerInstanceKey] = null;
11504 }
11505 function isContainerMarkedAsRoot(node) {
11506 return !!node[internalContainerInstanceKey];
11507 } // Given a DOM node, return the closest HostComponent or HostText fiber ancestor.
11508 // If the target node is part of a hydrated or not yet rendered subtree, then
11509 // this may also return a SuspenseComponent or HostRoot to indicate that.
11510 // Conceptually the HostRoot fiber is a child of the Container node. So if you
11511 // pass the Container node as the targetNode, you will not actually get the
11512 // HostRoot back. To get to the HostRoot, you need to pass a child of it.
11513 // The same thing applies to Suspense boundaries.
11514
11515 function getClosestInstanceFromNode(targetNode) {
11516 var targetInst = targetNode[internalInstanceKey];
11517
11518 if (targetInst) {
11519 // Don't return HostRoot or SuspenseComponent here.
11520 return targetInst;
11521 } // If the direct event target isn't a React owned DOM node, we need to look
11522 // to see if one of its parents is a React owned DOM node.
11523
11524
11525 var parentNode = targetNode.parentNode;
11526
11527 while (parentNode) {
11528 // We'll check if this is a container root that could include
11529 // React nodes in the future. We need to check this first because
11530 // if we're a child of a dehydrated container, we need to first
11531 // find that inner container before moving on to finding the parent
11532 // instance. Note that we don't check this field on the targetNode
11533 // itself because the fibers are conceptually between the container
11534 // node and the first child. It isn't surrounding the container node.
11535 // If it's not a container, we check if it's an instance.
11536 targetInst = parentNode[internalContainerInstanceKey] || parentNode[internalInstanceKey];
11537
11538 if (targetInst) {
11539 // Since this wasn't the direct target of the event, we might have
11540 // stepped past dehydrated DOM nodes to get here. However they could
11541 // also have been non-React nodes. We need to answer which one.
11542 // If we the instance doesn't have any children, then there can't be
11543 // a nested suspense boundary within it. So we can use this as a fast
11544 // bailout. Most of the time, when people add non-React children to
11545 // the tree, it is using a ref to a child-less DOM node.
11546 // Normally we'd only need to check one of the fibers because if it
11547 // has ever gone from having children to deleting them or vice versa
11548 // it would have deleted the dehydrated boundary nested inside already.
11549 // However, since the HostRoot starts out with an alternate it might
11550 // have one on the alternate so we need to check in case this was a
11551 // root.
11552 var alternate = targetInst.alternate;
11553
11554 if (targetInst.child !== null || alternate !== null && alternate.child !== null) {
11555 // Next we need to figure out if the node that skipped past is
11556 // nested within a dehydrated boundary and if so, which one.
11557 var suspenseInstance = getParentSuspenseInstance(targetNode);
11558
11559 while (suspenseInstance !== null) {
11560 // We found a suspense instance. That means that we haven't
11561 // hydrated it yet. Even though we leave the comments in the
11562 // DOM after hydrating, and there are boundaries in the DOM
11563 // that could already be hydrated, we wouldn't have found them
11564 // through this pass since if the target is hydrated it would
11565 // have had an internalInstanceKey on it.
11566 // Let's get the fiber associated with the SuspenseComponent
11567 // as the deepest instance.
11568 var targetSuspenseInst = suspenseInstance[internalInstanceKey];
11569
11570 if (targetSuspenseInst) {
11571 return targetSuspenseInst;
11572 } // If we don't find a Fiber on the comment, it might be because
11573 // we haven't gotten to hydrate it yet. There might still be a
11574 // parent boundary that hasn't above this one so we need to find
11575 // the outer most that is known.
11576
11577
11578 suspenseInstance = getParentSuspenseInstance(suspenseInstance); // If we don't find one, then that should mean that the parent
11579 // host component also hasn't hydrated yet. We can return it
11580 // below since it will bail out on the isMounted check later.
11581 }
11582 }
11583
11584 return targetInst;
11585 }
11586
11587 targetNode = parentNode;
11588 parentNode = targetNode.parentNode;
11589 }
11590
11591 return null;
11592 }
11593 /**
11594 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
11595 * instance, or null if the node was not rendered by this React.
11596 */
11597
11598 function getInstanceFromNode(node) {
11599 var inst = node[internalInstanceKey] || node[internalContainerInstanceKey];
11600
11601 if (inst) {
11602 if (inst.tag === HostComponent || inst.tag === HostText || inst.tag === SuspenseComponent || inst.tag === HostRoot) {
11603 return inst;
11604 } else {
11605 return null;
11606 }
11607 }
11608
11609 return null;
11610 }
11611 /**
11612 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
11613 * DOM node.
11614 */
11615
11616 function getNodeFromInstance(inst) {
11617 if (inst.tag === HostComponent || inst.tag === HostText) {
11618 // In Fiber this, is just the state node right now. We assume it will be
11619 // a host component or host text.
11620 return inst.stateNode;
11621 } // Without this first invariant, passing a non-DOM-component triggers the next
11622 // invariant for a missing parent, which is super confusing.
11623
11624
11625 throw new Error('getNodeFromInstance: Invalid argument.');
11626 }
11627 function getFiberCurrentPropsFromNode(node) {
11628 return node[internalPropsKey] || null;
11629 }
11630 function updateFiberProps(node, props) {
11631 node[internalPropsKey] = props;
11632 }
11633 function getEventListenerSet(node) {
11634 var elementListenerSet = node[internalEventHandlersKey];
11635
11636 if (elementListenerSet === undefined) {
11637 elementListenerSet = node[internalEventHandlersKey] = new Set();
11638 }
11639
11640 return elementListenerSet;
11641 }
11642
11643 var loggedTypeFailures = {};
11644 var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
11645
11646 function setCurrentlyValidatingElement(element) {
11647 {
11648 if (element) {
11649 var owner = element._owner;
11650 var stack = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null);
11651 ReactDebugCurrentFrame$1.setExtraStackFrame(stack);
11652 } else {
11653 ReactDebugCurrentFrame$1.setExtraStackFrame(null);
11654 }
11655 }
11656 }
11657
11658 function checkPropTypes(typeSpecs, values, location, componentName, element) {
11659 {
11660 // $FlowFixMe This is okay but Flow doesn't know it.
11661 var has = Function.call.bind(hasOwnProperty);
11662
11663 for (var typeSpecName in typeSpecs) {
11664 if (has(typeSpecs, typeSpecName)) {
11665 var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to
11666 // fail the render phase where it didn't fail before. So we log it.
11667 // After these have been cleaned up, we'll let them throw.
11668
11669 try {
11670 // This is intentionally an invariant that gets caught. It's the same
11671 // behavior as without this statement except with a better message.
11672 if (typeof typeSpecs[typeSpecName] !== 'function') {
11673 // eslint-disable-next-line react-internal/prod-error-codes
11674 var err = Error((componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' + 'This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.');
11675 err.name = 'Invariant Violation';
11676 throw err;
11677 }
11678
11679 error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');
11680 } catch (ex) {
11681 error$1 = ex;
11682 }
11683
11684 if (error$1 && !(error$1 instanceof Error)) {
11685 setCurrentlyValidatingElement(element);
11686
11687 error('%s: type specification of %s' + ' `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', location, typeSpecName, typeof error$1);
11688
11689 setCurrentlyValidatingElement(null);
11690 }
11691
11692 if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) {
11693 // Only monitor this failure once because there tends to be a lot of the
11694 // same error.
11695 loggedTypeFailures[error$1.message] = true;
11696 setCurrentlyValidatingElement(element);
11697
11698 error('Failed %s type: %s', location, error$1.message);
11699
11700 setCurrentlyValidatingElement(null);
11701 }
11702 }
11703 }
11704 }
11705 }
11706
11707 var valueStack = [];
11708 var fiberStack;
11709
11710 {
11711 fiberStack = [];
11712 }
11713
11714 var index = -1;
11715
11716 function createCursor(defaultValue) {
11717 return {
11718 current: defaultValue
11719 };
11720 }
11721
11722 function pop(cursor, fiber) {
11723 if (index < 0) {
11724 {
11725 error('Unexpected pop.');
11726 }
11727
11728 return;
11729 }
11730
11731 {
11732 if (fiber !== fiberStack[index]) {
11733 error('Unexpected Fiber popped.');
11734 }
11735 }
11736
11737 cursor.current = valueStack[index];
11738 valueStack[index] = null;
11739
11740 {
11741 fiberStack[index] = null;
11742 }
11743
11744 index--;
11745 }
11746
11747 function push(cursor, value, fiber) {
11748 index++;
11749 valueStack[index] = cursor.current;
11750
11751 {
11752 fiberStack[index] = fiber;
11753 }
11754
11755 cursor.current = value;
11756 }
11757
11758 var warnedAboutMissingGetChildContext;
11759
11760 {
11761 warnedAboutMissingGetChildContext = {};
11762 }
11763
11764 var emptyContextObject = {};
11765
11766 {
11767 Object.freeze(emptyContextObject);
11768 } // A cursor to the current merged context object on the stack.
11769
11770
11771 var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed.
11772
11773 var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack.
11774 // We use this to get access to the parent context after we have already
11775 // pushed the next context provider, and now need to merge their contexts.
11776
11777 var previousContext = emptyContextObject;
11778
11779 function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
11780 {
11781 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
11782 // If the fiber is a context provider itself, when we read its context
11783 // we may have already pushed its own child context on the stack. A context
11784 // provider should not "see" its own child context. Therefore we read the
11785 // previous (parent) context instead for a context provider.
11786 return previousContext;
11787 }
11788
11789 return contextStackCursor.current;
11790 }
11791 }
11792
11793 function cacheContext(workInProgress, unmaskedContext, maskedContext) {
11794 {
11795 var instance = workInProgress.stateNode;
11796 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
11797 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
11798 }
11799 }
11800
11801 function getMaskedContext(workInProgress, unmaskedContext) {
11802 {
11803 var type = workInProgress.type;
11804 var contextTypes = type.contextTypes;
11805
11806 if (!contextTypes) {
11807 return emptyContextObject;
11808 } // Avoid recreating masked context unless unmasked context has changed.
11809 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
11810 // This may trigger infinite loops if componentWillReceiveProps calls setState.
11811
11812
11813 var instance = workInProgress.stateNode;
11814
11815 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
11816 return instance.__reactInternalMemoizedMaskedChildContext;
11817 }
11818
11819 var context = {};
11820
11821 for (var key in contextTypes) {
11822 context[key] = unmaskedContext[key];
11823 }
11824
11825 {
11826 var name = getComponentNameFromFiber(workInProgress) || 'Unknown';
11827 checkPropTypes(contextTypes, context, 'context', name);
11828 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
11829 // Context is created before the class component is instantiated so check for instance.
11830
11831
11832 if (instance) {
11833 cacheContext(workInProgress, unmaskedContext, context);
11834 }
11835
11836 return context;
11837 }
11838 }
11839
11840 function hasContextChanged() {
11841 {
11842 return didPerformWorkStackCursor.current;
11843 }
11844 }
11845
11846 function isContextProvider(type) {
11847 {
11848 var childContextTypes = type.childContextTypes;
11849 return childContextTypes !== null && childContextTypes !== undefined;
11850 }
11851 }
11852
11853 function popContext(fiber) {
11854 {
11855 pop(didPerformWorkStackCursor, fiber);
11856 pop(contextStackCursor, fiber);
11857 }
11858 }
11859
11860 function popTopLevelContextObject(fiber) {
11861 {
11862 pop(didPerformWorkStackCursor, fiber);
11863 pop(contextStackCursor, fiber);
11864 }
11865 }
11866
11867 function pushTopLevelContextObject(fiber, context, didChange) {
11868 {
11869 if (contextStackCursor.current !== emptyContextObject) {
11870 throw new Error('Unexpected context found on stack. ' + 'This error is likely caused by a bug in React. Please file an issue.');
11871 }
11872
11873 push(contextStackCursor, context, fiber);
11874 push(didPerformWorkStackCursor, didChange, fiber);
11875 }
11876 }
11877
11878 function processChildContext(fiber, type, parentContext) {
11879 {
11880 var instance = fiber.stateNode;
11881 var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future.
11882 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
11883
11884 if (typeof instance.getChildContext !== 'function') {
11885 {
11886 var componentName = getComponentNameFromFiber(fiber) || 'Unknown';
11887
11888 if (!warnedAboutMissingGetChildContext[componentName]) {
11889 warnedAboutMissingGetChildContext[componentName] = true;
11890
11891 error('%s.childContextTypes is specified but there is no getChildContext() method ' + 'on the instance. You can either define getChildContext() on %s or remove ' + 'childContextTypes from it.', componentName, componentName);
11892 }
11893 }
11894
11895 return parentContext;
11896 }
11897
11898 var childContext = instance.getChildContext();
11899
11900 for (var contextKey in childContext) {
11901 if (!(contextKey in childContextTypes)) {
11902 throw new Error((getComponentNameFromFiber(fiber) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes.");
11903 }
11904 }
11905
11906 {
11907 var name = getComponentNameFromFiber(fiber) || 'Unknown';
11908 checkPropTypes(childContextTypes, childContext, 'child context', name);
11909 }
11910
11911 return assign({}, parentContext, childContext);
11912 }
11913 }
11914
11915 function pushContextProvider(workInProgress) {
11916 {
11917 var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity.
11918 // If the instance does not exist yet, we will push null at first,
11919 // and replace it on the stack later when invalidating the context.
11920
11921 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later.
11922 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
11923
11924 previousContext = contextStackCursor.current;
11925 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
11926 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
11927 return true;
11928 }
11929 }
11930
11931 function invalidateContextProvider(workInProgress, type, didChange) {
11932 {
11933 var instance = workInProgress.stateNode;
11934
11935 if (!instance) {
11936 throw new Error('Expected to have an instance by this point. ' + 'This error is likely caused by a bug in React. Please file an issue.');
11937 }
11938
11939 if (didChange) {
11940 // Merge parent and own context.
11941 // Skip this if we're not updating due to sCU.
11942 // This avoids unnecessarily recomputing memoized values.
11943 var mergedContext = processChildContext(workInProgress, type, previousContext);
11944 instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one.
11945 // It is important to unwind the context in the reverse order.
11946
11947 pop(didPerformWorkStackCursor, workInProgress);
11948 pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed.
11949
11950 push(contextStackCursor, mergedContext, workInProgress);
11951 push(didPerformWorkStackCursor, didChange, workInProgress);
11952 } else {
11953 pop(didPerformWorkStackCursor, workInProgress);
11954 push(didPerformWorkStackCursor, didChange, workInProgress);
11955 }
11956 }
11957 }
11958
11959 function findCurrentUnmaskedContext(fiber) {
11960 {
11961 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
11962 // makes sense elsewhere
11963 if (!isFiberMounted(fiber) || fiber.tag !== ClassComponent) {
11964 throw new Error('Expected subtree parent to be a mounted class component. ' + 'This error is likely caused by a bug in React. Please file an issue.');
11965 }
11966
11967 var node = fiber;
11968
11969 do {
11970 switch (node.tag) {
11971 case HostRoot:
11972 return node.stateNode.context;
11973
11974 case ClassComponent:
11975 {
11976 var Component = node.type;
11977
11978 if (isContextProvider(Component)) {
11979 return node.stateNode.__reactInternalMemoizedMergedChildContext;
11980 }
11981
11982 break;
11983 }
11984 }
11985
11986 node = node.return;
11987 } while (node !== null);
11988
11989 throw new Error('Found unexpected detached subtree parent. ' + 'This error is likely caused by a bug in React. Please file an issue.');
11990 }
11991 }
11992
11993 var LegacyRoot = 0;
11994 var ConcurrentRoot = 1;
11995
11996 var syncQueue = null;
11997 var includesLegacySyncCallbacks = false;
11998 var isFlushingSyncQueue = false;
11999 function scheduleSyncCallback(callback) {
12000 // Push this callback into an internal queue. We'll flush these either in
12001 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
12002 if (syncQueue === null) {
12003 syncQueue = [callback];
12004 } else {
12005 // Push onto existing queue. Don't need to schedule a callback because
12006 // we already scheduled one when we created the queue.
12007 syncQueue.push(callback);
12008 }
12009 }
12010 function scheduleLegacySyncCallback(callback) {
12011 includesLegacySyncCallbacks = true;
12012 scheduleSyncCallback(callback);
12013 }
12014 function flushSyncCallbacksOnlyInLegacyMode() {
12015 // Only flushes the queue if there's a legacy sync callback scheduled.
12016 // TODO: There's only a single type of callback: performSyncOnWorkOnRoot. So
12017 // it might make more sense for the queue to be a list of roots instead of a
12018 // list of generic callbacks. Then we can have two: one for legacy roots, one
12019 // for concurrent roots. And this method would only flush the legacy ones.
12020 if (includesLegacySyncCallbacks) {
12021 flushSyncCallbacks();
12022 }
12023 }
12024 function flushSyncCallbacks() {
12025 if (!isFlushingSyncQueue && syncQueue !== null) {
12026 // Prevent re-entrance.
12027 isFlushingSyncQueue = true;
12028 var i = 0;
12029 var previousUpdatePriority = getCurrentUpdatePriority();
12030
12031 try {
12032 var isSync = true;
12033 var queue = syncQueue; // TODO: Is this necessary anymore? The only user code that runs in this
12034 // queue is in the render or commit phases.
12035
12036 setCurrentUpdatePriority(DiscreteEventPriority);
12037
12038 for (; i < queue.length; i++) {
12039 var callback = queue[i];
12040
12041 do {
12042 callback = callback(isSync);
12043 } while (callback !== null);
12044 }
12045
12046 syncQueue = null;
12047 includesLegacySyncCallbacks = false;
12048 } catch (error) {
12049 // If something throws, leave the remaining callbacks on the queue.
12050 if (syncQueue !== null) {
12051 syncQueue = syncQueue.slice(i + 1);
12052 } // Resume flushing in the next tick
12053
12054
12055 scheduleCallback(ImmediatePriority, flushSyncCallbacks);
12056 throw error;
12057 } finally {
12058 setCurrentUpdatePriority(previousUpdatePriority);
12059 isFlushingSyncQueue = false;
12060 }
12061 }
12062
12063 return null;
12064 }
12065
12066 // TODO: Use the unified fiber stack module instead of this local one?
12067 // Intentionally not using it yet to derisk the initial implementation, because
12068 // the way we push/pop these values is a bit unusual. If there's a mistake, I'd
12069 // rather the ids be wrong than crash the whole reconciler.
12070 var forkStack = [];
12071 var forkStackIndex = 0;
12072 var treeForkProvider = null;
12073 var treeForkCount = 0;
12074 var idStack = [];
12075 var idStackIndex = 0;
12076 var treeContextProvider = null;
12077 var treeContextId = 1;
12078 var treeContextOverflow = '';
12079 function isForkedChild(workInProgress) {
12080 warnIfNotHydrating();
12081 return (workInProgress.flags & Forked) !== NoFlags;
12082 }
12083 function getForksAtLevel(workInProgress) {
12084 warnIfNotHydrating();
12085 return treeForkCount;
12086 }
12087 function getTreeId() {
12088 var overflow = treeContextOverflow;
12089 var idWithLeadingBit = treeContextId;
12090 var id = idWithLeadingBit & ~getLeadingBit(idWithLeadingBit);
12091 return id.toString(32) + overflow;
12092 }
12093 function pushTreeFork(workInProgress, totalChildren) {
12094 // This is called right after we reconcile an array (or iterator) of child
12095 // fibers, because that's the only place where we know how many children in
12096 // the whole set without doing extra work later, or storing addtional
12097 // information on the fiber.
12098 //
12099 // That's why this function is separate from pushTreeId — it's called during
12100 // the render phase of the fork parent, not the child, which is where we push
12101 // the other context values.
12102 //
12103 // In the Fizz implementation this is much simpler because the child is
12104 // rendered in the same callstack as the parent.
12105 //
12106 // It might be better to just add a `forks` field to the Fiber type. It would
12107 // make this module simpler.
12108 warnIfNotHydrating();
12109 forkStack[forkStackIndex++] = treeForkCount;
12110 forkStack[forkStackIndex++] = treeForkProvider;
12111 treeForkProvider = workInProgress;
12112 treeForkCount = totalChildren;
12113 }
12114 function pushTreeId(workInProgress, totalChildren, index) {
12115 warnIfNotHydrating();
12116 idStack[idStackIndex++] = treeContextId;
12117 idStack[idStackIndex++] = treeContextOverflow;
12118 idStack[idStackIndex++] = treeContextProvider;
12119 treeContextProvider = workInProgress;
12120 var baseIdWithLeadingBit = treeContextId;
12121 var baseOverflow = treeContextOverflow; // The leftmost 1 marks the end of the sequence, non-inclusive. It's not part
12122 // of the id; we use it to account for leading 0s.
12123
12124 var baseLength = getBitLength(baseIdWithLeadingBit) - 1;
12125 var baseId = baseIdWithLeadingBit & ~(1 << baseLength);
12126 var slot = index + 1;
12127 var length = getBitLength(totalChildren) + baseLength; // 30 is the max length we can store without overflowing, taking into
12128 // consideration the leading 1 we use to mark the end of the sequence.
12129
12130 if (length > 30) {
12131 // We overflowed the bitwise-safe range. Fall back to slower algorithm.
12132 // This branch assumes the length of the base id is greater than 5; it won't
12133 // work for smaller ids, because you need 5 bits per character.
12134 //
12135 // We encode the id in multiple steps: first the base id, then the
12136 // remaining digits.
12137 //
12138 // Each 5 bit sequence corresponds to a single base 32 character. So for
12139 // example, if the current id is 23 bits long, we can convert 20 of those
12140 // bits into a string of 4 characters, with 3 bits left over.
12141 //
12142 // First calculate how many bits in the base id represent a complete
12143 // sequence of characters.
12144 var numberOfOverflowBits = baseLength - baseLength % 5; // Then create a bitmask that selects only those bits.
12145
12146 var newOverflowBits = (1 << numberOfOverflowBits) - 1; // Select the bits, and convert them to a base 32 string.
12147
12148 var newOverflow = (baseId & newOverflowBits).toString(32); // Now we can remove those bits from the base id.
12149
12150 var restOfBaseId = baseId >> numberOfOverflowBits;
12151 var restOfBaseLength = baseLength - numberOfOverflowBits; // Finally, encode the rest of the bits using the normal algorithm. Because
12152 // we made more room, this time it won't overflow.
12153
12154 var restOfLength = getBitLength(totalChildren) + restOfBaseLength;
12155 var restOfNewBits = slot << restOfBaseLength;
12156 var id = restOfNewBits | restOfBaseId;
12157 var overflow = newOverflow + baseOverflow;
12158 treeContextId = 1 << restOfLength | id;
12159 treeContextOverflow = overflow;
12160 } else {
12161 // Normal path
12162 var newBits = slot << baseLength;
12163
12164 var _id = newBits | baseId;
12165
12166 var _overflow = baseOverflow;
12167 treeContextId = 1 << length | _id;
12168 treeContextOverflow = _overflow;
12169 }
12170 }
12171 function pushMaterializedTreeId(workInProgress) {
12172 warnIfNotHydrating(); // This component materialized an id. This will affect any ids that appear
12173 // in its children.
12174
12175 var returnFiber = workInProgress.return;
12176
12177 if (returnFiber !== null) {
12178 var numberOfForks = 1;
12179 var slotIndex = 0;
12180 pushTreeFork(workInProgress, numberOfForks);
12181 pushTreeId(workInProgress, numberOfForks, slotIndex);
12182 }
12183 }
12184
12185 function getBitLength(number) {
12186 return 32 - clz32(number);
12187 }
12188
12189 function getLeadingBit(id) {
12190 return 1 << getBitLength(id) - 1;
12191 }
12192
12193 function popTreeContext(workInProgress) {
12194 // Restore the previous values.
12195 // This is a bit more complicated than other context-like modules in Fiber
12196 // because the same Fiber may appear on the stack multiple times and for
12197 // different reasons. We have to keep popping until the work-in-progress is
12198 // no longer at the top of the stack.
12199 while (workInProgress === treeForkProvider) {
12200 treeForkProvider = forkStack[--forkStackIndex];
12201 forkStack[forkStackIndex] = null;
12202 treeForkCount = forkStack[--forkStackIndex];
12203 forkStack[forkStackIndex] = null;
12204 }
12205
12206 while (workInProgress === treeContextProvider) {
12207 treeContextProvider = idStack[--idStackIndex];
12208 idStack[idStackIndex] = null;
12209 treeContextOverflow = idStack[--idStackIndex];
12210 idStack[idStackIndex] = null;
12211 treeContextId = idStack[--idStackIndex];
12212 idStack[idStackIndex] = null;
12213 }
12214 }
12215 function getSuspendedTreeContext() {
12216 warnIfNotHydrating();
12217
12218 if (treeContextProvider !== null) {
12219 return {
12220 id: treeContextId,
12221 overflow: treeContextOverflow
12222 };
12223 } else {
12224 return null;
12225 }
12226 }
12227 function restoreSuspendedTreeContext(workInProgress, suspendedContext) {
12228 warnIfNotHydrating();
12229 idStack[idStackIndex++] = treeContextId;
12230 idStack[idStackIndex++] = treeContextOverflow;
12231 idStack[idStackIndex++] = treeContextProvider;
12232 treeContextId = suspendedContext.id;
12233 treeContextOverflow = suspendedContext.overflow;
12234 treeContextProvider = workInProgress;
12235 }
12236
12237 function warnIfNotHydrating() {
12238 {
12239 if (!getIsHydrating()) {
12240 error('Expected to be hydrating. This is a bug in React. Please file ' + 'an issue.');
12241 }
12242 }
12243 }
12244
12245 // This may have been an insertion or a hydration.
12246
12247 var hydrationParentFiber = null;
12248 var nextHydratableInstance = null;
12249 var isHydrating = false; // This flag allows for warning supression when we expect there to be mismatches
12250 // due to earlier mismatches or a suspended fiber.
12251
12252 var didSuspendOrErrorDEV = false; // Hydration errors that were thrown inside this boundary
12253
12254 var hydrationErrors = null;
12255
12256 function warnIfHydrating() {
12257 {
12258 if (isHydrating) {
12259 error('We should not be hydrating here. This is a bug in React. Please file a bug.');
12260 }
12261 }
12262 }
12263
12264 function markDidThrowWhileHydratingDEV() {
12265 {
12266 didSuspendOrErrorDEV = true;
12267 }
12268 }
12269 function didSuspendOrErrorWhileHydratingDEV() {
12270 {
12271 return didSuspendOrErrorDEV;
12272 }
12273 }
12274
12275 function enterHydrationState(fiber) {
12276
12277 var parentInstance = fiber.stateNode.containerInfo;
12278 nextHydratableInstance = getFirstHydratableChildWithinContainer(parentInstance);
12279 hydrationParentFiber = fiber;
12280 isHydrating = true;
12281 hydrationErrors = null;
12282 didSuspendOrErrorDEV = false;
12283 return true;
12284 }
12285
12286 function reenterHydrationStateFromDehydratedSuspenseInstance(fiber, suspenseInstance, treeContext) {
12287
12288 nextHydratableInstance = getFirstHydratableChildWithinSuspenseInstance(suspenseInstance);
12289 hydrationParentFiber = fiber;
12290 isHydrating = true;
12291 hydrationErrors = null;
12292 didSuspendOrErrorDEV = false;
12293
12294 if (treeContext !== null) {
12295 restoreSuspendedTreeContext(fiber, treeContext);
12296 }
12297
12298 return true;
12299 }
12300
12301 function warnUnhydratedInstance(returnFiber, instance) {
12302 {
12303 switch (returnFiber.tag) {
12304 case HostRoot:
12305 {
12306 didNotHydrateInstanceWithinContainer(returnFiber.stateNode.containerInfo, instance);
12307 break;
12308 }
12309
12310 case HostComponent:
12311 {
12312 var isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
12313 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance, // TODO: Delete this argument when we remove the legacy root API.
12314 isConcurrentMode);
12315 break;
12316 }
12317
12318 case SuspenseComponent:
12319 {
12320 var suspenseState = returnFiber.memoizedState;
12321 if (suspenseState.dehydrated !== null) didNotHydrateInstanceWithinSuspenseInstance(suspenseState.dehydrated, instance);
12322 break;
12323 }
12324 }
12325 }
12326 }
12327
12328 function deleteHydratableInstance(returnFiber, instance) {
12329 warnUnhydratedInstance(returnFiber, instance);
12330 var childToDelete = createFiberFromHostInstanceForDeletion();
12331 childToDelete.stateNode = instance;
12332 childToDelete.return = returnFiber;
12333 var deletions = returnFiber.deletions;
12334
12335 if (deletions === null) {
12336 returnFiber.deletions = [childToDelete];
12337 returnFiber.flags |= ChildDeletion;
12338 } else {
12339 deletions.push(childToDelete);
12340 }
12341 }
12342
12343 function warnNonhydratedInstance(returnFiber, fiber) {
12344 {
12345 if (didSuspendOrErrorDEV) {
12346 // Inside a boundary that already suspended. We're currently rendering the
12347 // siblings of a suspended node. The mismatch may be due to the missing
12348 // data, so it's probably a false positive.
12349 return;
12350 }
12351
12352 switch (returnFiber.tag) {
12353 case HostRoot:
12354 {
12355 var parentContainer = returnFiber.stateNode.containerInfo;
12356
12357 switch (fiber.tag) {
12358 case HostComponent:
12359 var type = fiber.type;
12360 var props = fiber.pendingProps;
12361 didNotFindHydratableInstanceWithinContainer(parentContainer, type);
12362 break;
12363
12364 case HostText:
12365 var text = fiber.pendingProps;
12366 didNotFindHydratableTextInstanceWithinContainer(parentContainer, text);
12367 break;
12368 }
12369
12370 break;
12371 }
12372
12373 case HostComponent:
12374 {
12375 var parentType = returnFiber.type;
12376 var parentProps = returnFiber.memoizedProps;
12377 var parentInstance = returnFiber.stateNode;
12378
12379 switch (fiber.tag) {
12380 case HostComponent:
12381 {
12382 var _type = fiber.type;
12383 var _props = fiber.pendingProps;
12384 var isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
12385 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props, // TODO: Delete this argument when we remove the legacy root API.
12386 isConcurrentMode);
12387 break;
12388 }
12389
12390 case HostText:
12391 {
12392 var _text = fiber.pendingProps;
12393
12394 var _isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
12395
12396 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text, // TODO: Delete this argument when we remove the legacy root API.
12397 _isConcurrentMode);
12398 break;
12399 }
12400 }
12401
12402 break;
12403 }
12404
12405 case SuspenseComponent:
12406 {
12407 var suspenseState = returnFiber.memoizedState;
12408 var _parentInstance = suspenseState.dehydrated;
12409 if (_parentInstance !== null) switch (fiber.tag) {
12410 case HostComponent:
12411 var _type2 = fiber.type;
12412 var _props2 = fiber.pendingProps;
12413 didNotFindHydratableInstanceWithinSuspenseInstance(_parentInstance, _type2);
12414 break;
12415
12416 case HostText:
12417 var _text2 = fiber.pendingProps;
12418 didNotFindHydratableTextInstanceWithinSuspenseInstance(_parentInstance, _text2);
12419 break;
12420 }
12421 break;
12422 }
12423
12424 default:
12425 return;
12426 }
12427 }
12428 }
12429
12430 function insertNonHydratedInstance(returnFiber, fiber) {
12431 fiber.flags = fiber.flags & ~Hydrating | Placement;
12432 warnNonhydratedInstance(returnFiber, fiber);
12433 }
12434
12435 function tryHydrate(fiber, nextInstance) {
12436 switch (fiber.tag) {
12437 case HostComponent:
12438 {
12439 var type = fiber.type;
12440 var props = fiber.pendingProps;
12441 var instance = canHydrateInstance(nextInstance, type);
12442
12443 if (instance !== null) {
12444 fiber.stateNode = instance;
12445 hydrationParentFiber = fiber;
12446 nextHydratableInstance = getFirstHydratableChild(instance);
12447 return true;
12448 }
12449
12450 return false;
12451 }
12452
12453 case HostText:
12454 {
12455 var text = fiber.pendingProps;
12456 var textInstance = canHydrateTextInstance(nextInstance, text);
12457
12458 if (textInstance !== null) {
12459 fiber.stateNode = textInstance;
12460 hydrationParentFiber = fiber; // Text Instances don't have children so there's nothing to hydrate.
12461
12462 nextHydratableInstance = null;
12463 return true;
12464 }
12465
12466 return false;
12467 }
12468
12469 case SuspenseComponent:
12470 {
12471 var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
12472
12473 if (suspenseInstance !== null) {
12474 var suspenseState = {
12475 dehydrated: suspenseInstance,
12476 treeContext: getSuspendedTreeContext(),
12477 retryLane: OffscreenLane
12478 };
12479 fiber.memoizedState = suspenseState; // Store the dehydrated fragment as a child fiber.
12480 // This simplifies the code for getHostSibling and deleting nodes,
12481 // since it doesn't have to consider all Suspense boundaries and
12482 // check if they're dehydrated ones or not.
12483
12484 var dehydratedFragment = createFiberFromDehydratedFragment(suspenseInstance);
12485 dehydratedFragment.return = fiber;
12486 fiber.child = dehydratedFragment;
12487 hydrationParentFiber = fiber; // While a Suspense Instance does have children, we won't step into
12488 // it during the first pass. Instead, we'll reenter it later.
12489
12490 nextHydratableInstance = null;
12491 return true;
12492 }
12493
12494 return false;
12495 }
12496
12497 default:
12498 return false;
12499 }
12500 }
12501
12502 function shouldClientRenderOnMismatch(fiber) {
12503 return (fiber.mode & ConcurrentMode) !== NoMode && (fiber.flags & DidCapture) === NoFlags;
12504 }
12505
12506 function throwOnHydrationMismatch(fiber) {
12507 throw new Error('Hydration failed because the initial UI does not match what was ' + 'rendered on the server.');
12508 }
12509
12510 function tryToClaimNextHydratableInstance(fiber) {
12511 if (!isHydrating) {
12512 return;
12513 }
12514
12515 var nextInstance = nextHydratableInstance;
12516
12517 if (!nextInstance) {
12518 if (shouldClientRenderOnMismatch(fiber)) {
12519 warnNonhydratedInstance(hydrationParentFiber, fiber);
12520 throwOnHydrationMismatch();
12521 } // Nothing to hydrate. Make it an insertion.
12522
12523
12524 insertNonHydratedInstance(hydrationParentFiber, fiber);
12525 isHydrating = false;
12526 hydrationParentFiber = fiber;
12527 return;
12528 }
12529
12530 var firstAttemptedInstance = nextInstance;
12531
12532 if (!tryHydrate(fiber, nextInstance)) {
12533 if (shouldClientRenderOnMismatch(fiber)) {
12534 warnNonhydratedInstance(hydrationParentFiber, fiber);
12535 throwOnHydrationMismatch();
12536 } // If we can't hydrate this instance let's try the next one.
12537 // We use this as a heuristic. It's based on intuition and not data so it
12538 // might be flawed or unnecessary.
12539
12540
12541 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
12542 var prevHydrationParentFiber = hydrationParentFiber;
12543
12544 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
12545 // Nothing to hydrate. Make it an insertion.
12546 insertNonHydratedInstance(hydrationParentFiber, fiber);
12547 isHydrating = false;
12548 hydrationParentFiber = fiber;
12549 return;
12550 } // We matched the next one, we'll now assume that the first one was
12551 // superfluous and we'll delete it. Since we can't eagerly delete it
12552 // we'll have to schedule a deletion. To do that, this node needs a dummy
12553 // fiber associated with it.
12554
12555
12556 deleteHydratableInstance(prevHydrationParentFiber, firstAttemptedInstance);
12557 }
12558 }
12559
12560 function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
12561
12562 var instance = fiber.stateNode;
12563 var shouldWarnIfMismatchDev = !didSuspendOrErrorDEV;
12564 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber, shouldWarnIfMismatchDev); // TODO: Type this specific to this type of component.
12565
12566 fiber.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
12567 // is a new ref we mark this as an update.
12568
12569 if (updatePayload !== null) {
12570 return true;
12571 }
12572
12573 return false;
12574 }
12575
12576 function prepareToHydrateHostTextInstance(fiber) {
12577
12578 var textInstance = fiber.stateNode;
12579 var textContent = fiber.memoizedProps;
12580 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
12581
12582 if (shouldUpdate) {
12583 // We assume that prepareToHydrateHostTextInstance is called in a context where the
12584 // hydration parent is the parent host component of this host text.
12585 var returnFiber = hydrationParentFiber;
12586
12587 if (returnFiber !== null) {
12588 switch (returnFiber.tag) {
12589 case HostRoot:
12590 {
12591 var parentContainer = returnFiber.stateNode.containerInfo;
12592 var isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
12593 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent, // TODO: Delete this argument when we remove the legacy root API.
12594 isConcurrentMode);
12595 break;
12596 }
12597
12598 case HostComponent:
12599 {
12600 var parentType = returnFiber.type;
12601 var parentProps = returnFiber.memoizedProps;
12602 var parentInstance = returnFiber.stateNode;
12603
12604 var _isConcurrentMode2 = (returnFiber.mode & ConcurrentMode) !== NoMode;
12605
12606 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent, // TODO: Delete this argument when we remove the legacy root API.
12607 _isConcurrentMode2);
12608 break;
12609 }
12610 }
12611 }
12612 }
12613
12614 return shouldUpdate;
12615 }
12616
12617 function prepareToHydrateHostSuspenseInstance(fiber) {
12618
12619 var suspenseState = fiber.memoizedState;
12620 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
12621
12622 if (!suspenseInstance) {
12623 throw new Error('Expected to have a hydrated suspense instance. ' + 'This error is likely caused by a bug in React. Please file an issue.');
12624 }
12625
12626 hydrateSuspenseInstance(suspenseInstance, fiber);
12627 }
12628
12629 function skipPastDehydratedSuspenseInstance(fiber) {
12630
12631 var suspenseState = fiber.memoizedState;
12632 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
12633
12634 if (!suspenseInstance) {
12635 throw new Error('Expected to have a hydrated suspense instance. ' + 'This error is likely caused by a bug in React. Please file an issue.');
12636 }
12637
12638 return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
12639 }
12640
12641 function popToNextHostParent(fiber) {
12642 var parent = fiber.return;
12643
12644 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== SuspenseComponent) {
12645 parent = parent.return;
12646 }
12647
12648 hydrationParentFiber = parent;
12649 }
12650
12651 function popHydrationState(fiber) {
12652
12653 if (fiber !== hydrationParentFiber) {
12654 // We're deeper than the current hydration context, inside an inserted
12655 // tree.
12656 return false;
12657 }
12658
12659 if (!isHydrating) {
12660 // If we're not currently hydrating but we're in a hydration context, then
12661 // we were an insertion and now need to pop up reenter hydration of our
12662 // siblings.
12663 popToNextHostParent(fiber);
12664 isHydrating = true;
12665 return false;
12666 } // If we have any remaining hydratable nodes, we need to delete them now.
12667 // We only do this deeper than head and body since they tend to have random
12668 // other nodes in them. We also ignore components with pure text content in
12669 // side of them. We also don't delete anything inside the root container.
12670
12671
12672 if (fiber.tag !== HostRoot && (fiber.tag !== HostComponent || shouldDeleteUnhydratedTailInstances(fiber.type) && !shouldSetTextContent(fiber.type, fiber.memoizedProps))) {
12673 var nextInstance = nextHydratableInstance;
12674
12675 if (nextInstance) {
12676 if (shouldClientRenderOnMismatch(fiber)) {
12677 warnIfUnhydratedTailNodes(fiber);
12678 throwOnHydrationMismatch();
12679 } else {
12680 while (nextInstance) {
12681 deleteHydratableInstance(fiber, nextInstance);
12682 nextInstance = getNextHydratableSibling(nextInstance);
12683 }
12684 }
12685 }
12686 }
12687
12688 popToNextHostParent(fiber);
12689
12690 if (fiber.tag === SuspenseComponent) {
12691 nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber);
12692 } else {
12693 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
12694 }
12695
12696 return true;
12697 }
12698
12699 function hasUnhydratedTailNodes() {
12700 return isHydrating && nextHydratableInstance !== null;
12701 }
12702
12703 function warnIfUnhydratedTailNodes(fiber) {
12704 var nextInstance = nextHydratableInstance;
12705
12706 while (nextInstance) {
12707 warnUnhydratedInstance(fiber, nextInstance);
12708 nextInstance = getNextHydratableSibling(nextInstance);
12709 }
12710 }
12711
12712 function resetHydrationState() {
12713
12714 hydrationParentFiber = null;
12715 nextHydratableInstance = null;
12716 isHydrating = false;
12717 didSuspendOrErrorDEV = false;
12718 }
12719
12720 function upgradeHydrationErrorsToRecoverable() {
12721 if (hydrationErrors !== null) {
12722 // Successfully completed a forced client render. The errors that occurred
12723 // during the hydration attempt are now recovered. We will log them in
12724 // commit phase, once the entire tree has finished.
12725 queueRecoverableErrors(hydrationErrors);
12726 hydrationErrors = null;
12727 }
12728 }
12729
12730 function getIsHydrating() {
12731 return isHydrating;
12732 }
12733
12734 function queueHydrationError(error) {
12735 if (hydrationErrors === null) {
12736 hydrationErrors = [error];
12737 } else {
12738 hydrationErrors.push(error);
12739 }
12740 }
12741
12742 var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig;
12743 var NoTransition = null;
12744 function requestCurrentTransition() {
12745 return ReactCurrentBatchConfig$1.transition;
12746 }
12747
12748 var ReactStrictModeWarnings = {
12749 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
12750 flushPendingUnsafeLifecycleWarnings: function () {},
12751 recordLegacyContextWarning: function (fiber, instance) {},
12752 flushLegacyContextWarning: function () {},
12753 discardPendingWarnings: function () {}
12754 };
12755
12756 {
12757 var findStrictRoot = function (fiber) {
12758 var maybeStrictRoot = null;
12759 var node = fiber;
12760
12761 while (node !== null) {
12762 if (node.mode & StrictLegacyMode) {
12763 maybeStrictRoot = node;
12764 }
12765
12766 node = node.return;
12767 }
12768
12769 return maybeStrictRoot;
12770 };
12771
12772 var setToSortedString = function (set) {
12773 var array = [];
12774 set.forEach(function (value) {
12775 array.push(value);
12776 });
12777 return array.sort().join(', ');
12778 };
12779
12780 var pendingComponentWillMountWarnings = [];
12781 var pendingUNSAFE_ComponentWillMountWarnings = [];
12782 var pendingComponentWillReceivePropsWarnings = [];
12783 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
12784 var pendingComponentWillUpdateWarnings = [];
12785 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.
12786
12787 var didWarnAboutUnsafeLifecycles = new Set();
12788
12789 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
12790 // Dedupe strategy: Warn once per component.
12791 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
12792 return;
12793 }
12794
12795 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components.
12796 instance.componentWillMount.__suppressDeprecationWarning !== true) {
12797 pendingComponentWillMountWarnings.push(fiber);
12798 }
12799
12800 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillMount === 'function') {
12801 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
12802 }
12803
12804 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
12805 pendingComponentWillReceivePropsWarnings.push(fiber);
12806 }
12807
12808 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
12809 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
12810 }
12811
12812 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
12813 pendingComponentWillUpdateWarnings.push(fiber);
12814 }
12815
12816 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
12817 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
12818 }
12819 };
12820
12821 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
12822 // We do an initial pass to gather component names
12823 var componentWillMountUniqueNames = new Set();
12824
12825 if (pendingComponentWillMountWarnings.length > 0) {
12826 pendingComponentWillMountWarnings.forEach(function (fiber) {
12827 componentWillMountUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12828 didWarnAboutUnsafeLifecycles.add(fiber.type);
12829 });
12830 pendingComponentWillMountWarnings = [];
12831 }
12832
12833 var UNSAFE_componentWillMountUniqueNames = new Set();
12834
12835 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
12836 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
12837 UNSAFE_componentWillMountUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12838 didWarnAboutUnsafeLifecycles.add(fiber.type);
12839 });
12840 pendingUNSAFE_ComponentWillMountWarnings = [];
12841 }
12842
12843 var componentWillReceivePropsUniqueNames = new Set();
12844
12845 if (pendingComponentWillReceivePropsWarnings.length > 0) {
12846 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
12847 componentWillReceivePropsUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12848 didWarnAboutUnsafeLifecycles.add(fiber.type);
12849 });
12850 pendingComponentWillReceivePropsWarnings = [];
12851 }
12852
12853 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
12854
12855 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
12856 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
12857 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12858 didWarnAboutUnsafeLifecycles.add(fiber.type);
12859 });
12860 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
12861 }
12862
12863 var componentWillUpdateUniqueNames = new Set();
12864
12865 if (pendingComponentWillUpdateWarnings.length > 0) {
12866 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
12867 componentWillUpdateUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12868 didWarnAboutUnsafeLifecycles.add(fiber.type);
12869 });
12870 pendingComponentWillUpdateWarnings = [];
12871 }
12872
12873 var UNSAFE_componentWillUpdateUniqueNames = new Set();
12874
12875 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
12876 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
12877 UNSAFE_componentWillUpdateUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12878 didWarnAboutUnsafeLifecycles.add(fiber.type);
12879 });
12880 pendingUNSAFE_ComponentWillUpdateWarnings = [];
12881 } // Finally, we flush all the warnings
12882 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
12883
12884
12885 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
12886 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
12887
12888 error('Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '\nPlease update the following components: %s', sortedNames);
12889 }
12890
12891 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
12892 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
12893
12894 error('Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, " + 'refactor your code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://reactjs.org/link/derived-state\n' + '\nPlease update the following components: %s', _sortedNames);
12895 }
12896
12897 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
12898 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
12899
12900 error('Using UNSAFE_componentWillUpdate in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '\nPlease update the following components: %s', _sortedNames2);
12901 }
12902
12903 if (componentWillMountUniqueNames.size > 0) {
12904 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
12905
12906 warn('componentWillMount has been renamed, and is not recommended for use. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress ' + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames3);
12907 }
12908
12909 if (componentWillReceivePropsUniqueNames.size > 0) {
12910 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
12911
12912 warn('componentWillReceiveProps has been renamed, and is not recommended for use. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, refactor your " + 'code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://reactjs.org/link/derived-state\n' + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames4);
12913 }
12914
12915 if (componentWillUpdateUniqueNames.size > 0) {
12916 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
12917
12918 warn('componentWillUpdate has been renamed, and is not recommended for use. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress ' + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames5);
12919 }
12920 };
12921
12922 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.
12923
12924 var didWarnAboutLegacyContext = new Set();
12925
12926 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
12927 var strictRoot = findStrictRoot(fiber);
12928
12929 if (strictRoot === null) {
12930 error('Expected to find a StrictMode component in a strict mode tree. ' + 'This error is likely caused by a bug in React. Please file an issue.');
12931
12932 return;
12933 } // Dedup strategy: Warn once per component.
12934
12935
12936 if (didWarnAboutLegacyContext.has(fiber.type)) {
12937 return;
12938 }
12939
12940 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
12941
12942 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
12943 if (warningsForRoot === undefined) {
12944 warningsForRoot = [];
12945 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
12946 }
12947
12948 warningsForRoot.push(fiber);
12949 }
12950 };
12951
12952 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
12953 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
12954 if (fiberArray.length === 0) {
12955 return;
12956 }
12957
12958 var firstFiber = fiberArray[0];
12959 var uniqueNames = new Set();
12960 fiberArray.forEach(function (fiber) {
12961 uniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12962 didWarnAboutLegacyContext.add(fiber.type);
12963 });
12964 var sortedNames = setToSortedString(uniqueNames);
12965
12966 try {
12967 setCurrentFiber(firstFiber);
12968
12969 error('Legacy context API has been detected within a strict-mode tree.' + '\n\nThe old API will be supported in all 16.x releases, but applications ' + 'using it should migrate to the new version.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here: https://reactjs.org/link/legacy-context', sortedNames);
12970 } finally {
12971 resetCurrentFiber();
12972 }
12973 });
12974 };
12975
12976 ReactStrictModeWarnings.discardPendingWarnings = function () {
12977 pendingComponentWillMountWarnings = [];
12978 pendingUNSAFE_ComponentWillMountWarnings = [];
12979 pendingComponentWillReceivePropsWarnings = [];
12980 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
12981 pendingComponentWillUpdateWarnings = [];
12982 pendingUNSAFE_ComponentWillUpdateWarnings = [];
12983 pendingLegacyContextWarning = new Map();
12984 };
12985 }
12986
12987 var didWarnAboutMaps;
12988 var didWarnAboutGenerators;
12989 var didWarnAboutStringRefs;
12990 var ownerHasKeyUseWarning;
12991 var ownerHasFunctionTypeWarning;
12992
12993 var warnForMissingKey = function (child, returnFiber) {};
12994
12995 {
12996 didWarnAboutMaps = false;
12997 didWarnAboutGenerators = false;
12998 didWarnAboutStringRefs = {};
12999 /**
13000 * Warn if there's no key explicitly set on dynamic arrays of children or
13001 * object keys are not valid. This allows us to keep track of children between
13002 * updates.
13003 */
13004
13005 ownerHasKeyUseWarning = {};
13006 ownerHasFunctionTypeWarning = {};
13007
13008 warnForMissingKey = function (child, returnFiber) {
13009 if (child === null || typeof child !== 'object') {
13010 return;
13011 }
13012
13013 if (!child._store || child._store.validated || child.key != null) {
13014 return;
13015 }
13016
13017 if (typeof child._store !== 'object') {
13018 throw new Error('React Component in warnForMissingKey should have a _store. ' + 'This error is likely caused by a bug in React. Please file an issue.');
13019 }
13020
13021 child._store.validated = true;
13022 var componentName = getComponentNameFromFiber(returnFiber) || 'Component';
13023
13024 if (ownerHasKeyUseWarning[componentName]) {
13025 return;
13026 }
13027
13028 ownerHasKeyUseWarning[componentName] = true;
13029
13030 error('Each child in a list should have a unique ' + '"key" prop. See https://reactjs.org/link/warning-keys for ' + 'more information.');
13031 };
13032 }
13033
13034 function isReactClass(type) {
13035 return type.prototype && type.prototype.isReactComponent;
13036 }
13037
13038 function coerceRef(returnFiber, current, element) {
13039 var mixedRef = element.ref;
13040
13041 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
13042 {
13043 // TODO: Clean this up once we turn on the string ref warning for
13044 // everyone, because the strict mode case will no longer be relevant
13045 if ((returnFiber.mode & StrictLegacyMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs
13046 // because these cannot be automatically converted to an arrow function
13047 // using a codemod. Therefore, we don't have to warn about string refs again.
13048 !(element._owner && element._self && element._owner.stateNode !== element._self) && // Will already throw with "Function components cannot have string refs"
13049 !(element._owner && element._owner.tag !== ClassComponent) && // Will already warn with "Function components cannot be given refs"
13050 !(typeof element.type === 'function' && !isReactClass(element.type)) && // Will already throw with "Element ref was specified as a string (someStringRef) but no owner was set"
13051 element._owner) {
13052 var componentName = getComponentNameFromFiber(returnFiber) || 'Component';
13053
13054 if (!didWarnAboutStringRefs[componentName]) {
13055 {
13056 error('Component "%s" contains the string ref "%s". Support for string refs ' + 'will be removed in a future major release. We recommend using ' + 'useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://reactjs.org/link/strict-mode-string-ref', componentName, mixedRef);
13057 }
13058
13059 didWarnAboutStringRefs[componentName] = true;
13060 }
13061 }
13062 }
13063
13064 if (element._owner) {
13065 var owner = element._owner;
13066 var inst;
13067
13068 if (owner) {
13069 var ownerFiber = owner;
13070
13071 if (ownerFiber.tag !== ClassComponent) {
13072 throw new Error('Function components cannot have string refs. ' + 'We recommend using useRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://reactjs.org/link/strict-mode-string-ref');
13073 }
13074
13075 inst = ownerFiber.stateNode;
13076 }
13077
13078 if (!inst) {
13079 throw new Error("Missing owner for string ref " + mixedRef + ". This error is likely caused by a " + 'bug in React. Please file an issue.');
13080 } // Assigning this to a const so Flow knows it won't change in the closure
13081
13082
13083 var resolvedInst = inst;
13084
13085 {
13086 checkPropStringCoercion(mixedRef, 'ref');
13087 }
13088
13089 var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref
13090
13091 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
13092 return current.ref;
13093 }
13094
13095 var ref = function (value) {
13096 var refs = resolvedInst.refs;
13097
13098 if (value === null) {
13099 delete refs[stringRef];
13100 } else {
13101 refs[stringRef] = value;
13102 }
13103 };
13104
13105 ref._stringRef = stringRef;
13106 return ref;
13107 } else {
13108 if (typeof mixedRef !== 'string') {
13109 throw new Error('Expected ref to be a function, a string, an object returned by React.createRef(), or null.');
13110 }
13111
13112 if (!element._owner) {
13113 throw new Error("Element ref was specified as a string (" + mixedRef + ") but no owner was set. This could happen for one of" + ' the following reasons:\n' + '1. You may be adding a ref to a function component\n' + "2. You may be adding a ref to a component that was not created inside a component's render method\n" + '3. You have multiple copies of React loaded\n' + 'See https://reactjs.org/link/refs-must-have-owner for more information.');
13114 }
13115 }
13116 }
13117
13118 return mixedRef;
13119 }
13120
13121 function throwOnInvalidObjectType(returnFiber, newChild) {
13122 var childString = Object.prototype.toString.call(newChild);
13123 throw new Error("Objects are not valid as a React child (found: " + (childString === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : childString) + "). " + 'If you meant to render a collection of children, use an array ' + 'instead.');
13124 }
13125
13126 function warnOnFunctionType(returnFiber) {
13127 {
13128 var componentName = getComponentNameFromFiber(returnFiber) || 'Component';
13129
13130 if (ownerHasFunctionTypeWarning[componentName]) {
13131 return;
13132 }
13133
13134 ownerHasFunctionTypeWarning[componentName] = true;
13135
13136 error('Functions are not valid as a React child. This may happen if ' + 'you return a Component instead of <Component /> from render. ' + 'Or maybe you meant to call this function rather than return it.');
13137 }
13138 }
13139
13140 function resolveLazy(lazyType) {
13141 var payload = lazyType._payload;
13142 var init = lazyType._init;
13143 return init(payload);
13144 } // This wrapper function exists because I expect to clone the code in each path
13145 // to be able to optimize each path individually by branching early. This needs
13146 // a compiler or we can do it manually. Helpers that don't need this branching
13147 // live outside of this function.
13148
13149
13150 function ChildReconciler(shouldTrackSideEffects) {
13151 function deleteChild(returnFiber, childToDelete) {
13152 if (!shouldTrackSideEffects) {
13153 // Noop.
13154 return;
13155 }
13156
13157 var deletions = returnFiber.deletions;
13158
13159 if (deletions === null) {
13160 returnFiber.deletions = [childToDelete];
13161 returnFiber.flags |= ChildDeletion;
13162 } else {
13163 deletions.push(childToDelete);
13164 }
13165 }
13166
13167 function deleteRemainingChildren(returnFiber, currentFirstChild) {
13168 if (!shouldTrackSideEffects) {
13169 // Noop.
13170 return null;
13171 } // TODO: For the shouldClone case, this could be micro-optimized a bit by
13172 // assuming that after the first child we've already added everything.
13173
13174
13175 var childToDelete = currentFirstChild;
13176
13177 while (childToDelete !== null) {
13178 deleteChild(returnFiber, childToDelete);
13179 childToDelete = childToDelete.sibling;
13180 }
13181
13182 return null;
13183 }
13184
13185 function mapRemainingChildren(returnFiber, currentFirstChild) {
13186 // Add the remaining children to a temporary map so that we can find them by
13187 // keys quickly. Implicit (null) keys get added to this set with their index
13188 // instead.
13189 var existingChildren = new Map();
13190 var existingChild = currentFirstChild;
13191
13192 while (existingChild !== null) {
13193 if (existingChild.key !== null) {
13194 existingChildren.set(existingChild.key, existingChild);
13195 } else {
13196 existingChildren.set(existingChild.index, existingChild);
13197 }
13198
13199 existingChild = existingChild.sibling;
13200 }
13201
13202 return existingChildren;
13203 }
13204
13205 function useFiber(fiber, pendingProps) {
13206 // We currently set sibling to null and index to 0 here because it is easy
13207 // to forget to do before returning it. E.g. for the single child case.
13208 var clone = createWorkInProgress(fiber, pendingProps);
13209 clone.index = 0;
13210 clone.sibling = null;
13211 return clone;
13212 }
13213
13214 function placeChild(newFiber, lastPlacedIndex, newIndex) {
13215 newFiber.index = newIndex;
13216
13217 if (!shouldTrackSideEffects) {
13218 // During hydration, the useId algorithm needs to know which fibers are
13219 // part of a list of children (arrays, iterators).
13220 newFiber.flags |= Forked;
13221 return lastPlacedIndex;
13222 }
13223
13224 var current = newFiber.alternate;
13225
13226 if (current !== null) {
13227 var oldIndex = current.index;
13228
13229 if (oldIndex < lastPlacedIndex) {
13230 // This is a move.
13231 newFiber.flags |= Placement;
13232 return lastPlacedIndex;
13233 } else {
13234 // This item can stay in place.
13235 return oldIndex;
13236 }
13237 } else {
13238 // This is an insertion.
13239 newFiber.flags |= Placement;
13240 return lastPlacedIndex;
13241 }
13242 }
13243
13244 function placeSingleChild(newFiber) {
13245 // This is simpler for the single child case. We only need to do a
13246 // placement for inserting new children.
13247 if (shouldTrackSideEffects && newFiber.alternate === null) {
13248 newFiber.flags |= Placement;
13249 }
13250
13251 return newFiber;
13252 }
13253
13254 function updateTextNode(returnFiber, current, textContent, lanes) {
13255 if (current === null || current.tag !== HostText) {
13256 // Insert
13257 var created = createFiberFromText(textContent, returnFiber.mode, lanes);
13258 created.return = returnFiber;
13259 return created;
13260 } else {
13261 // Update
13262 var existing = useFiber(current, textContent);
13263 existing.return = returnFiber;
13264 return existing;
13265 }
13266 }
13267
13268 function updateElement(returnFiber, current, element, lanes) {
13269 var elementType = element.type;
13270
13271 if (elementType === REACT_FRAGMENT_TYPE) {
13272 return updateFragment(returnFiber, current, element.props.children, lanes, element.key);
13273 }
13274
13275 if (current !== null) {
13276 if (current.elementType === elementType || ( // Keep this check inline so it only runs on the false path:
13277 isCompatibleFamilyForHotReloading(current, element) ) || // Lazy types should reconcile their resolved type.
13278 // We need to do this after the Hot Reloading check above,
13279 // because hot reloading has different semantics than prod because
13280 // it doesn't resuspend. So we can't let the call below suspend.
13281 typeof elementType === 'object' && elementType !== null && elementType.$$typeof === REACT_LAZY_TYPE && resolveLazy(elementType) === current.type) {
13282 // Move based on index
13283 var existing = useFiber(current, element.props);
13284 existing.ref = coerceRef(returnFiber, current, element);
13285 existing.return = returnFiber;
13286
13287 {
13288 existing._debugSource = element._source;
13289 existing._debugOwner = element._owner;
13290 }
13291
13292 return existing;
13293 }
13294 } // Insert
13295
13296
13297 var created = createFiberFromElement(element, returnFiber.mode, lanes);
13298 created.ref = coerceRef(returnFiber, current, element);
13299 created.return = returnFiber;
13300 return created;
13301 }
13302
13303 function updatePortal(returnFiber, current, portal, lanes) {
13304 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
13305 // Insert
13306 var created = createFiberFromPortal(portal, returnFiber.mode, lanes);
13307 created.return = returnFiber;
13308 return created;
13309 } else {
13310 // Update
13311 var existing = useFiber(current, portal.children || []);
13312 existing.return = returnFiber;
13313 return existing;
13314 }
13315 }
13316
13317 function updateFragment(returnFiber, current, fragment, lanes, key) {
13318 if (current === null || current.tag !== Fragment) {
13319 // Insert
13320 var created = createFiberFromFragment(fragment, returnFiber.mode, lanes, key);
13321 created.return = returnFiber;
13322 return created;
13323 } else {
13324 // Update
13325 var existing = useFiber(current, fragment);
13326 existing.return = returnFiber;
13327 return existing;
13328 }
13329 }
13330
13331 function createChild(returnFiber, newChild, lanes) {
13332 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') {
13333 // Text nodes don't have keys. If the previous node is implicitly keyed
13334 // we can continue to replace it without aborting even if it is not a text
13335 // node.
13336 var created = createFiberFromText('' + newChild, returnFiber.mode, lanes);
13337 created.return = returnFiber;
13338 return created;
13339 }
13340
13341 if (typeof newChild === 'object' && newChild !== null) {
13342 switch (newChild.$$typeof) {
13343 case REACT_ELEMENT_TYPE:
13344 {
13345 var _created = createFiberFromElement(newChild, returnFiber.mode, lanes);
13346
13347 _created.ref = coerceRef(returnFiber, null, newChild);
13348 _created.return = returnFiber;
13349 return _created;
13350 }
13351
13352 case REACT_PORTAL_TYPE:
13353 {
13354 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, lanes);
13355
13356 _created2.return = returnFiber;
13357 return _created2;
13358 }
13359
13360 case REACT_LAZY_TYPE:
13361 {
13362 var payload = newChild._payload;
13363 var init = newChild._init;
13364 return createChild(returnFiber, init(payload), lanes);
13365 }
13366 }
13367
13368 if (isArray(newChild) || getIteratorFn(newChild)) {
13369 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, lanes, null);
13370
13371 _created3.return = returnFiber;
13372 return _created3;
13373 }
13374
13375 throwOnInvalidObjectType(returnFiber, newChild);
13376 }
13377
13378 {
13379 if (typeof newChild === 'function') {
13380 warnOnFunctionType(returnFiber);
13381 }
13382 }
13383
13384 return null;
13385 }
13386
13387 function updateSlot(returnFiber, oldFiber, newChild, lanes) {
13388 // Update the fiber if the keys match, otherwise return null.
13389 var key = oldFiber !== null ? oldFiber.key : null;
13390
13391 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') {
13392 // Text nodes don't have keys. If the previous node is implicitly keyed
13393 // we can continue to replace it without aborting even if it is not a text
13394 // node.
13395 if (key !== null) {
13396 return null;
13397 }
13398
13399 return updateTextNode(returnFiber, oldFiber, '' + newChild, lanes);
13400 }
13401
13402 if (typeof newChild === 'object' && newChild !== null) {
13403 switch (newChild.$$typeof) {
13404 case REACT_ELEMENT_TYPE:
13405 {
13406 if (newChild.key === key) {
13407 return updateElement(returnFiber, oldFiber, newChild, lanes);
13408 } else {
13409 return null;
13410 }
13411 }
13412
13413 case REACT_PORTAL_TYPE:
13414 {
13415 if (newChild.key === key) {
13416 return updatePortal(returnFiber, oldFiber, newChild, lanes);
13417 } else {
13418 return null;
13419 }
13420 }
13421
13422 case REACT_LAZY_TYPE:
13423 {
13424 var payload = newChild._payload;
13425 var init = newChild._init;
13426 return updateSlot(returnFiber, oldFiber, init(payload), lanes);
13427 }
13428 }
13429
13430 if (isArray(newChild) || getIteratorFn(newChild)) {
13431 if (key !== null) {
13432 return null;
13433 }
13434
13435 return updateFragment(returnFiber, oldFiber, newChild, lanes, null);
13436 }
13437
13438 throwOnInvalidObjectType(returnFiber, newChild);
13439 }
13440
13441 {
13442 if (typeof newChild === 'function') {
13443 warnOnFunctionType(returnFiber);
13444 }
13445 }
13446
13447 return null;
13448 }
13449
13450 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, lanes) {
13451 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') {
13452 // Text nodes don't have keys, so we neither have to check the old nor
13453 // new node for the key. If both are text nodes, they match.
13454 var matchedFiber = existingChildren.get(newIdx) || null;
13455 return updateTextNode(returnFiber, matchedFiber, '' + newChild, lanes);
13456 }
13457
13458 if (typeof newChild === 'object' && newChild !== null) {
13459 switch (newChild.$$typeof) {
13460 case REACT_ELEMENT_TYPE:
13461 {
13462 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
13463
13464 return updateElement(returnFiber, _matchedFiber, newChild, lanes);
13465 }
13466
13467 case REACT_PORTAL_TYPE:
13468 {
13469 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
13470
13471 return updatePortal(returnFiber, _matchedFiber2, newChild, lanes);
13472 }
13473
13474 case REACT_LAZY_TYPE:
13475 var payload = newChild._payload;
13476 var init = newChild._init;
13477 return updateFromMap(existingChildren, returnFiber, newIdx, init(payload), lanes);
13478 }
13479
13480 if (isArray(newChild) || getIteratorFn(newChild)) {
13481 var _matchedFiber3 = existingChildren.get(newIdx) || null;
13482
13483 return updateFragment(returnFiber, _matchedFiber3, newChild, lanes, null);
13484 }
13485
13486 throwOnInvalidObjectType(returnFiber, newChild);
13487 }
13488
13489 {
13490 if (typeof newChild === 'function') {
13491 warnOnFunctionType(returnFiber);
13492 }
13493 }
13494
13495 return null;
13496 }
13497 /**
13498 * Warns if there is a duplicate or missing key
13499 */
13500
13501
13502 function warnOnInvalidKey(child, knownKeys, returnFiber) {
13503 {
13504 if (typeof child !== 'object' || child === null) {
13505 return knownKeys;
13506 }
13507
13508 switch (child.$$typeof) {
13509 case REACT_ELEMENT_TYPE:
13510 case REACT_PORTAL_TYPE:
13511 warnForMissingKey(child, returnFiber);
13512 var key = child.key;
13513
13514 if (typeof key !== 'string') {
13515 break;
13516 }
13517
13518 if (knownKeys === null) {
13519 knownKeys = new Set();
13520 knownKeys.add(key);
13521 break;
13522 }
13523
13524 if (!knownKeys.has(key)) {
13525 knownKeys.add(key);
13526 break;
13527 }
13528
13529 error('Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key);
13530
13531 break;
13532
13533 case REACT_LAZY_TYPE:
13534 var payload = child._payload;
13535 var init = child._init;
13536 warnOnInvalidKey(init(payload), knownKeys, returnFiber);
13537 break;
13538 }
13539 }
13540
13541 return knownKeys;
13542 }
13543
13544 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, lanes) {
13545 // This algorithm can't optimize by searching from both ends since we
13546 // don't have backpointers on fibers. I'm trying to see how far we can get
13547 // with that model. If it ends up not being worth the tradeoffs, we can
13548 // add it later.
13549 // Even with a two ended optimization, we'd want to optimize for the case
13550 // where there are few changes and brute force the comparison instead of
13551 // going for the Map. It'd like to explore hitting that path first in
13552 // forward-only mode and only go for the Map once we notice that we need
13553 // lots of look ahead. This doesn't handle reversal as well as two ended
13554 // search but that's unusual. Besides, for the two ended optimization to
13555 // work on Iterables, we'd need to copy the whole set.
13556 // In this first iteration, we'll just live with hitting the bad case
13557 // (adding everything to a Map) in for every insert/move.
13558 // If you change this code, also update reconcileChildrenIterator() which
13559 // uses the same algorithm.
13560 {
13561 // First, validate keys.
13562 var knownKeys = null;
13563
13564 for (var i = 0; i < newChildren.length; i++) {
13565 var child = newChildren[i];
13566 knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber);
13567 }
13568 }
13569
13570 var resultingFirstChild = null;
13571 var previousNewFiber = null;
13572 var oldFiber = currentFirstChild;
13573 var lastPlacedIndex = 0;
13574 var newIdx = 0;
13575 var nextOldFiber = null;
13576
13577 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
13578 if (oldFiber.index > newIdx) {
13579 nextOldFiber = oldFiber;
13580 oldFiber = null;
13581 } else {
13582 nextOldFiber = oldFiber.sibling;
13583 }
13584
13585 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], lanes);
13586
13587 if (newFiber === null) {
13588 // TODO: This breaks on empty slots like null children. That's
13589 // unfortunate because it triggers the slow path all the time. We need
13590 // a better way to communicate whether this was a miss or null,
13591 // boolean, undefined, etc.
13592 if (oldFiber === null) {
13593 oldFiber = nextOldFiber;
13594 }
13595
13596 break;
13597 }
13598
13599 if (shouldTrackSideEffects) {
13600 if (oldFiber && newFiber.alternate === null) {
13601 // We matched the slot, but we didn't reuse the existing fiber, so we
13602 // need to delete the existing child.
13603 deleteChild(returnFiber, oldFiber);
13604 }
13605 }
13606
13607 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
13608
13609 if (previousNewFiber === null) {
13610 // TODO: Move out of the loop. This only happens for the first run.
13611 resultingFirstChild = newFiber;
13612 } else {
13613 // TODO: Defer siblings if we're not at the right index for this slot.
13614 // I.e. if we had null values before, then we want to defer this
13615 // for each null value. However, we also don't want to call updateSlot
13616 // with the previous one.
13617 previousNewFiber.sibling = newFiber;
13618 }
13619
13620 previousNewFiber = newFiber;
13621 oldFiber = nextOldFiber;
13622 }
13623
13624 if (newIdx === newChildren.length) {
13625 // We've reached the end of the new children. We can delete the rest.
13626 deleteRemainingChildren(returnFiber, oldFiber);
13627
13628 if (getIsHydrating()) {
13629 var numberOfForks = newIdx;
13630 pushTreeFork(returnFiber, numberOfForks);
13631 }
13632
13633 return resultingFirstChild;
13634 }
13635
13636 if (oldFiber === null) {
13637 // If we don't have any more existing children we can choose a fast path
13638 // since the rest will all be insertions.
13639 for (; newIdx < newChildren.length; newIdx++) {
13640 var _newFiber = createChild(returnFiber, newChildren[newIdx], lanes);
13641
13642 if (_newFiber === null) {
13643 continue;
13644 }
13645
13646 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
13647
13648 if (previousNewFiber === null) {
13649 // TODO: Move out of the loop. This only happens for the first run.
13650 resultingFirstChild = _newFiber;
13651 } else {
13652 previousNewFiber.sibling = _newFiber;
13653 }
13654
13655 previousNewFiber = _newFiber;
13656 }
13657
13658 if (getIsHydrating()) {
13659 var _numberOfForks = newIdx;
13660 pushTreeFork(returnFiber, _numberOfForks);
13661 }
13662
13663 return resultingFirstChild;
13664 } // Add all children to a key map for quick lookups.
13665
13666
13667 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
13668
13669 for (; newIdx < newChildren.length; newIdx++) {
13670 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], lanes);
13671
13672 if (_newFiber2 !== null) {
13673 if (shouldTrackSideEffects) {
13674 if (_newFiber2.alternate !== null) {
13675 // The new fiber is a work in progress, but if there exists a
13676 // current, that means that we reused the fiber. We need to delete
13677 // it from the child list so that we don't add it to the deletion
13678 // list.
13679 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
13680 }
13681 }
13682
13683 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
13684
13685 if (previousNewFiber === null) {
13686 resultingFirstChild = _newFiber2;
13687 } else {
13688 previousNewFiber.sibling = _newFiber2;
13689 }
13690
13691 previousNewFiber = _newFiber2;
13692 }
13693 }
13694
13695 if (shouldTrackSideEffects) {
13696 // Any existing children that weren't consumed above were deleted. We need
13697 // to add them to the deletion list.
13698 existingChildren.forEach(function (child) {
13699 return deleteChild(returnFiber, child);
13700 });
13701 }
13702
13703 if (getIsHydrating()) {
13704 var _numberOfForks2 = newIdx;
13705 pushTreeFork(returnFiber, _numberOfForks2);
13706 }
13707
13708 return resultingFirstChild;
13709 }
13710
13711 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, lanes) {
13712 // This is the same implementation as reconcileChildrenArray(),
13713 // but using the iterator instead.
13714 var iteratorFn = getIteratorFn(newChildrenIterable);
13715
13716 if (typeof iteratorFn !== 'function') {
13717 throw new Error('An object is not an iterable. This error is likely caused by a bug in ' + 'React. Please file an issue.');
13718 }
13719
13720 {
13721 // We don't support rendering Generators because it's a mutation.
13722 // See https://github.com/facebook/react/issues/12995
13723 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag
13724 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
13725 if (!didWarnAboutGenerators) {
13726 error('Using Generators as children is unsupported and will likely yield ' + 'unexpected results because enumerating a generator mutates it. ' + 'You may convert it to an array with `Array.from()` or the ' + '`[...spread]` operator before rendering. Keep in mind ' + 'you might need to polyfill these features for older browsers.');
13727 }
13728
13729 didWarnAboutGenerators = true;
13730 } // Warn about using Maps as children
13731
13732
13733 if (newChildrenIterable.entries === iteratorFn) {
13734 if (!didWarnAboutMaps) {
13735 error('Using Maps as children is not supported. ' + 'Use an array of keyed ReactElements instead.');
13736 }
13737
13738 didWarnAboutMaps = true;
13739 } // First, validate keys.
13740 // We'll get a different iterator later for the main pass.
13741
13742
13743 var _newChildren = iteratorFn.call(newChildrenIterable);
13744
13745 if (_newChildren) {
13746 var knownKeys = null;
13747
13748 var _step = _newChildren.next();
13749
13750 for (; !_step.done; _step = _newChildren.next()) {
13751 var child = _step.value;
13752 knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber);
13753 }
13754 }
13755 }
13756
13757 var newChildren = iteratorFn.call(newChildrenIterable);
13758
13759 if (newChildren == null) {
13760 throw new Error('An iterable object provided no iterator.');
13761 }
13762
13763 var resultingFirstChild = null;
13764 var previousNewFiber = null;
13765 var oldFiber = currentFirstChild;
13766 var lastPlacedIndex = 0;
13767 var newIdx = 0;
13768 var nextOldFiber = null;
13769 var step = newChildren.next();
13770
13771 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
13772 if (oldFiber.index > newIdx) {
13773 nextOldFiber = oldFiber;
13774 oldFiber = null;
13775 } else {
13776 nextOldFiber = oldFiber.sibling;
13777 }
13778
13779 var newFiber = updateSlot(returnFiber, oldFiber, step.value, lanes);
13780
13781 if (newFiber === null) {
13782 // TODO: This breaks on empty slots like null children. That's
13783 // unfortunate because it triggers the slow path all the time. We need
13784 // a better way to communicate whether this was a miss or null,
13785 // boolean, undefined, etc.
13786 if (oldFiber === null) {
13787 oldFiber = nextOldFiber;
13788 }
13789
13790 break;
13791 }
13792
13793 if (shouldTrackSideEffects) {
13794 if (oldFiber && newFiber.alternate === null) {
13795 // We matched the slot, but we didn't reuse the existing fiber, so we
13796 // need to delete the existing child.
13797 deleteChild(returnFiber, oldFiber);
13798 }
13799 }
13800
13801 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
13802
13803 if (previousNewFiber === null) {
13804 // TODO: Move out of the loop. This only happens for the first run.
13805 resultingFirstChild = newFiber;
13806 } else {
13807 // TODO: Defer siblings if we're not at the right index for this slot.
13808 // I.e. if we had null values before, then we want to defer this
13809 // for each null value. However, we also don't want to call updateSlot
13810 // with the previous one.
13811 previousNewFiber.sibling = newFiber;
13812 }
13813
13814 previousNewFiber = newFiber;
13815 oldFiber = nextOldFiber;
13816 }
13817
13818 if (step.done) {
13819 // We've reached the end of the new children. We can delete the rest.
13820 deleteRemainingChildren(returnFiber, oldFiber);
13821
13822 if (getIsHydrating()) {
13823 var numberOfForks = newIdx;
13824 pushTreeFork(returnFiber, numberOfForks);
13825 }
13826
13827 return resultingFirstChild;
13828 }
13829
13830 if (oldFiber === null) {
13831 // If we don't have any more existing children we can choose a fast path
13832 // since the rest will all be insertions.
13833 for (; !step.done; newIdx++, step = newChildren.next()) {
13834 var _newFiber3 = createChild(returnFiber, step.value, lanes);
13835
13836 if (_newFiber3 === null) {
13837 continue;
13838 }
13839
13840 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
13841
13842 if (previousNewFiber === null) {
13843 // TODO: Move out of the loop. This only happens for the first run.
13844 resultingFirstChild = _newFiber3;
13845 } else {
13846 previousNewFiber.sibling = _newFiber3;
13847 }
13848
13849 previousNewFiber = _newFiber3;
13850 }
13851
13852 if (getIsHydrating()) {
13853 var _numberOfForks3 = newIdx;
13854 pushTreeFork(returnFiber, _numberOfForks3);
13855 }
13856
13857 return resultingFirstChild;
13858 } // Add all children to a key map for quick lookups.
13859
13860
13861 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
13862
13863 for (; !step.done; newIdx++, step = newChildren.next()) {
13864 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, lanes);
13865
13866 if (_newFiber4 !== null) {
13867 if (shouldTrackSideEffects) {
13868 if (_newFiber4.alternate !== null) {
13869 // The new fiber is a work in progress, but if there exists a
13870 // current, that means that we reused the fiber. We need to delete
13871 // it from the child list so that we don't add it to the deletion
13872 // list.
13873 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
13874 }
13875 }
13876
13877 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
13878
13879 if (previousNewFiber === null) {
13880 resultingFirstChild = _newFiber4;
13881 } else {
13882 previousNewFiber.sibling = _newFiber4;
13883 }
13884
13885 previousNewFiber = _newFiber4;
13886 }
13887 }
13888
13889 if (shouldTrackSideEffects) {
13890 // Any existing children that weren't consumed above were deleted. We need
13891 // to add them to the deletion list.
13892 existingChildren.forEach(function (child) {
13893 return deleteChild(returnFiber, child);
13894 });
13895 }
13896
13897 if (getIsHydrating()) {
13898 var _numberOfForks4 = newIdx;
13899 pushTreeFork(returnFiber, _numberOfForks4);
13900 }
13901
13902 return resultingFirstChild;
13903 }
13904
13905 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, lanes) {
13906 // There's no need to check for keys on text nodes since we don't have a
13907 // way to define them.
13908 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
13909 // We already have an existing node so let's just update it and delete
13910 // the rest.
13911 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
13912 var existing = useFiber(currentFirstChild, textContent);
13913 existing.return = returnFiber;
13914 return existing;
13915 } // The existing first child is not a text node so we need to create one
13916 // and delete the existing ones.
13917
13918
13919 deleteRemainingChildren(returnFiber, currentFirstChild);
13920 var created = createFiberFromText(textContent, returnFiber.mode, lanes);
13921 created.return = returnFiber;
13922 return created;
13923 }
13924
13925 function reconcileSingleElement(returnFiber, currentFirstChild, element, lanes) {
13926 var key = element.key;
13927 var child = currentFirstChild;
13928
13929 while (child !== null) {
13930 // TODO: If key === null and child.key === null, then this only applies to
13931 // the first item in the list.
13932 if (child.key === key) {
13933 var elementType = element.type;
13934
13935 if (elementType === REACT_FRAGMENT_TYPE) {
13936 if (child.tag === Fragment) {
13937 deleteRemainingChildren(returnFiber, child.sibling);
13938 var existing = useFiber(child, element.props.children);
13939 existing.return = returnFiber;
13940
13941 {
13942 existing._debugSource = element._source;
13943 existing._debugOwner = element._owner;
13944 }
13945
13946 return existing;
13947 }
13948 } else {
13949 if (child.elementType === elementType || ( // Keep this check inline so it only runs on the false path:
13950 isCompatibleFamilyForHotReloading(child, element) ) || // Lazy types should reconcile their resolved type.
13951 // We need to do this after the Hot Reloading check above,
13952 // because hot reloading has different semantics than prod because
13953 // it doesn't resuspend. So we can't let the call below suspend.
13954 typeof elementType === 'object' && elementType !== null && elementType.$$typeof === REACT_LAZY_TYPE && resolveLazy(elementType) === child.type) {
13955 deleteRemainingChildren(returnFiber, child.sibling);
13956
13957 var _existing = useFiber(child, element.props);
13958
13959 _existing.ref = coerceRef(returnFiber, child, element);
13960 _existing.return = returnFiber;
13961
13962 {
13963 _existing._debugSource = element._source;
13964 _existing._debugOwner = element._owner;
13965 }
13966
13967 return _existing;
13968 }
13969 } // Didn't match.
13970
13971
13972 deleteRemainingChildren(returnFiber, child);
13973 break;
13974 } else {
13975 deleteChild(returnFiber, child);
13976 }
13977
13978 child = child.sibling;
13979 }
13980
13981 if (element.type === REACT_FRAGMENT_TYPE) {
13982 var created = createFiberFromFragment(element.props.children, returnFiber.mode, lanes, element.key);
13983 created.return = returnFiber;
13984 return created;
13985 } else {
13986 var _created4 = createFiberFromElement(element, returnFiber.mode, lanes);
13987
13988 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
13989 _created4.return = returnFiber;
13990 return _created4;
13991 }
13992 }
13993
13994 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, lanes) {
13995 var key = portal.key;
13996 var child = currentFirstChild;
13997
13998 while (child !== null) {
13999 // TODO: If key === null and child.key === null, then this only applies to
14000 // the first item in the list.
14001 if (child.key === key) {
14002 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
14003 deleteRemainingChildren(returnFiber, child.sibling);
14004 var existing = useFiber(child, portal.children || []);
14005 existing.return = returnFiber;
14006 return existing;
14007 } else {
14008 deleteRemainingChildren(returnFiber, child);
14009 break;
14010 }
14011 } else {
14012 deleteChild(returnFiber, child);
14013 }
14014
14015 child = child.sibling;
14016 }
14017
14018 var created = createFiberFromPortal(portal, returnFiber.mode, lanes);
14019 created.return = returnFiber;
14020 return created;
14021 } // This API will tag the children with the side-effect of the reconciliation
14022 // itself. They will be added to the side-effect list as we pass through the
14023 // children and the parent.
14024
14025
14026 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, lanes) {
14027 // This function is not recursive.
14028 // If the top level item is an array, we treat it as a set of children,
14029 // not as a fragment. Nested arrays on the other hand will be treated as
14030 // fragment nodes. Recursion happens at the normal flow.
14031 // Handle top level unkeyed fragments as if they were arrays.
14032 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
14033 // We treat the ambiguous cases above the same.
14034 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
14035
14036 if (isUnkeyedTopLevelFragment) {
14037 newChild = newChild.props.children;
14038 } // Handle object types
14039
14040
14041 if (typeof newChild === 'object' && newChild !== null) {
14042 switch (newChild.$$typeof) {
14043 case REACT_ELEMENT_TYPE:
14044 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, lanes));
14045
14046 case REACT_PORTAL_TYPE:
14047 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, lanes));
14048
14049 case REACT_LAZY_TYPE:
14050 var payload = newChild._payload;
14051 var init = newChild._init; // TODO: This function is supposed to be non-recursive.
14052
14053 return reconcileChildFibers(returnFiber, currentFirstChild, init(payload), lanes);
14054 }
14055
14056 if (isArray(newChild)) {
14057 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, lanes);
14058 }
14059
14060 if (getIteratorFn(newChild)) {
14061 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, lanes);
14062 }
14063
14064 throwOnInvalidObjectType(returnFiber, newChild);
14065 }
14066
14067 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') {
14068 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, lanes));
14069 }
14070
14071 {
14072 if (typeof newChild === 'function') {
14073 warnOnFunctionType(returnFiber);
14074 }
14075 } // Remaining cases are all treated as empty.
14076
14077
14078 return deleteRemainingChildren(returnFiber, currentFirstChild);
14079 }
14080
14081 return reconcileChildFibers;
14082 }
14083
14084 var reconcileChildFibers = ChildReconciler(true);
14085 var mountChildFibers = ChildReconciler(false);
14086 function cloneChildFibers(current, workInProgress) {
14087 if (current !== null && workInProgress.child !== current.child) {
14088 throw new Error('Resuming work not yet implemented.');
14089 }
14090
14091 if (workInProgress.child === null) {
14092 return;
14093 }
14094
14095 var currentChild = workInProgress.child;
14096 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps);
14097 workInProgress.child = newChild;
14098 newChild.return = workInProgress;
14099
14100 while (currentChild.sibling !== null) {
14101 currentChild = currentChild.sibling;
14102 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps);
14103 newChild.return = workInProgress;
14104 }
14105
14106 newChild.sibling = null;
14107 } // Reset a workInProgress child set to prepare it for a second pass.
14108
14109 function resetChildFibers(workInProgress, lanes) {
14110 var child = workInProgress.child;
14111
14112 while (child !== null) {
14113 resetWorkInProgress(child, lanes);
14114 child = child.sibling;
14115 }
14116 }
14117
14118 var valueCursor = createCursor(null);
14119 var rendererSigil;
14120
14121 {
14122 // Use this to detect multiple renderers using the same context
14123 rendererSigil = {};
14124 }
14125
14126 var currentlyRenderingFiber = null;
14127 var lastContextDependency = null;
14128 var lastFullyObservedContext = null;
14129 var isDisallowedContextReadInDEV = false;
14130 function resetContextDependencies() {
14131 // This is called right before React yields execution, to ensure `readContext`
14132 // cannot be called outside the render phase.
14133 currentlyRenderingFiber = null;
14134 lastContextDependency = null;
14135 lastFullyObservedContext = null;
14136
14137 {
14138 isDisallowedContextReadInDEV = false;
14139 }
14140 }
14141 function enterDisallowedContextReadInDEV() {
14142 {
14143 isDisallowedContextReadInDEV = true;
14144 }
14145 }
14146 function exitDisallowedContextReadInDEV() {
14147 {
14148 isDisallowedContextReadInDEV = false;
14149 }
14150 }
14151 function pushProvider(providerFiber, context, nextValue) {
14152 {
14153 push(valueCursor, context._currentValue, providerFiber);
14154 context._currentValue = nextValue;
14155
14156 {
14157 if (context._currentRenderer !== undefined && context._currentRenderer !== null && context._currentRenderer !== rendererSigil) {
14158 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.');
14159 }
14160
14161 context._currentRenderer = rendererSigil;
14162 }
14163 }
14164 }
14165 function popProvider(context, providerFiber) {
14166 var currentValue = valueCursor.current;
14167 pop(valueCursor, providerFiber);
14168
14169 {
14170 {
14171 context._currentValue = currentValue;
14172 }
14173 }
14174 }
14175 function scheduleContextWorkOnParentPath(parent, renderLanes, propagationRoot) {
14176 // Update the child lanes of all the ancestors, including the alternates.
14177 var node = parent;
14178
14179 while (node !== null) {
14180 var alternate = node.alternate;
14181
14182 if (!isSubsetOfLanes(node.childLanes, renderLanes)) {
14183 node.childLanes = mergeLanes(node.childLanes, renderLanes);
14184
14185 if (alternate !== null) {
14186 alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
14187 }
14188 } else if (alternate !== null && !isSubsetOfLanes(alternate.childLanes, renderLanes)) {
14189 alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
14190 }
14191
14192 if (node === propagationRoot) {
14193 break;
14194 }
14195
14196 node = node.return;
14197 }
14198
14199 {
14200 if (node !== propagationRoot) {
14201 error('Expected to find the propagation root when scheduling context work. ' + 'This error is likely caused by a bug in React. Please file an issue.');
14202 }
14203 }
14204 }
14205 function propagateContextChange(workInProgress, context, renderLanes) {
14206 {
14207 propagateContextChange_eager(workInProgress, context, renderLanes);
14208 }
14209 }
14210
14211 function propagateContextChange_eager(workInProgress, context, renderLanes) {
14212
14213 var fiber = workInProgress.child;
14214
14215 if (fiber !== null) {
14216 // Set the return pointer of the child to the work-in-progress fiber.
14217 fiber.return = workInProgress;
14218 }
14219
14220 while (fiber !== null) {
14221 var nextFiber = void 0; // Visit this fiber.
14222
14223 var list = fiber.dependencies;
14224
14225 if (list !== null) {
14226 nextFiber = fiber.child;
14227 var dependency = list.firstContext;
14228
14229 while (dependency !== null) {
14230 // Check if the context matches.
14231 if (dependency.context === context) {
14232 // Match! Schedule an update on this fiber.
14233 if (fiber.tag === ClassComponent) {
14234 // Schedule a force update on the work-in-progress.
14235 var lane = pickArbitraryLane(renderLanes);
14236 var update = createUpdate(NoTimestamp, lane);
14237 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the
14238 // update to the current fiber, too, which means it will persist even if
14239 // this render is thrown away. Since it's a race condition, not sure it's
14240 // worth fixing.
14241 // Inlined `enqueueUpdate` to remove interleaved update check
14242
14243 var updateQueue = fiber.updateQueue;
14244
14245 if (updateQueue === null) ; else {
14246 var sharedQueue = updateQueue.shared;
14247 var pending = sharedQueue.pending;
14248
14249 if (pending === null) {
14250 // This is the first update. Create a circular list.
14251 update.next = update;
14252 } else {
14253 update.next = pending.next;
14254 pending.next = update;
14255 }
14256
14257 sharedQueue.pending = update;
14258 }
14259 }
14260
14261 fiber.lanes = mergeLanes(fiber.lanes, renderLanes);
14262 var alternate = fiber.alternate;
14263
14264 if (alternate !== null) {
14265 alternate.lanes = mergeLanes(alternate.lanes, renderLanes);
14266 }
14267
14268 scheduleContextWorkOnParentPath(fiber.return, renderLanes, workInProgress); // Mark the updated lanes on the list, too.
14269
14270 list.lanes = mergeLanes(list.lanes, renderLanes); // Since we already found a match, we can stop traversing the
14271 // dependency list.
14272
14273 break;
14274 }
14275
14276 dependency = dependency.next;
14277 }
14278 } else if (fiber.tag === ContextProvider) {
14279 // Don't scan deeper if this is a matching provider
14280 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
14281 } else if (fiber.tag === DehydratedFragment) {
14282 // If a dehydrated suspense boundary is in this subtree, we don't know
14283 // if it will have any context consumers in it. The best we can do is
14284 // mark it as having updates.
14285 var parentSuspense = fiber.return;
14286
14287 if (parentSuspense === null) {
14288 throw new Error('We just came from a parent so we must have had a parent. This is a bug in React.');
14289 }
14290
14291 parentSuspense.lanes = mergeLanes(parentSuspense.lanes, renderLanes);
14292 var _alternate = parentSuspense.alternate;
14293
14294 if (_alternate !== null) {
14295 _alternate.lanes = mergeLanes(_alternate.lanes, renderLanes);
14296 } // This is intentionally passing this fiber as the parent
14297 // because we want to schedule this fiber as having work
14298 // on its children. We'll use the childLanes on
14299 // this fiber to indicate that a context has changed.
14300
14301
14302 scheduleContextWorkOnParentPath(parentSuspense, renderLanes, workInProgress);
14303 nextFiber = fiber.sibling;
14304 } else {
14305 // Traverse down.
14306 nextFiber = fiber.child;
14307 }
14308
14309 if (nextFiber !== null) {
14310 // Set the return pointer of the child to the work-in-progress fiber.
14311 nextFiber.return = fiber;
14312 } else {
14313 // No child. Traverse to next sibling.
14314 nextFiber = fiber;
14315
14316 while (nextFiber !== null) {
14317 if (nextFiber === workInProgress) {
14318 // We're back to the root of this subtree. Exit.
14319 nextFiber = null;
14320 break;
14321 }
14322
14323 var sibling = nextFiber.sibling;
14324
14325 if (sibling !== null) {
14326 // Set the return pointer of the sibling to the work-in-progress fiber.
14327 sibling.return = nextFiber.return;
14328 nextFiber = sibling;
14329 break;
14330 } // No more siblings. Traverse up.
14331
14332
14333 nextFiber = nextFiber.return;
14334 }
14335 }
14336
14337 fiber = nextFiber;
14338 }
14339 }
14340 function prepareToReadContext(workInProgress, renderLanes) {
14341 currentlyRenderingFiber = workInProgress;
14342 lastContextDependency = null;
14343 lastFullyObservedContext = null;
14344 var dependencies = workInProgress.dependencies;
14345
14346 if (dependencies !== null) {
14347 {
14348 var firstContext = dependencies.firstContext;
14349
14350 if (firstContext !== null) {
14351 if (includesSomeLane(dependencies.lanes, renderLanes)) {
14352 // Context list has a pending update. Mark that this fiber performed work.
14353 markWorkInProgressReceivedUpdate();
14354 } // Reset the work-in-progress list
14355
14356
14357 dependencies.firstContext = null;
14358 }
14359 }
14360 }
14361 }
14362 function readContext(context) {
14363 {
14364 // This warning would fire if you read context inside a Hook like useMemo.
14365 // Unlike the class check below, it's not enforced in production for perf.
14366 if (isDisallowedContextReadInDEV) {
14367 error('Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().');
14368 }
14369 }
14370
14371 var value = context._currentValue ;
14372
14373 if (lastFullyObservedContext === context) ; else {
14374 var contextItem = {
14375 context: context,
14376 memoizedValue: value,
14377 next: null
14378 };
14379
14380 if (lastContextDependency === null) {
14381 if (currentlyRenderingFiber === null) {
14382 throw new Error('Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().');
14383 } // This is the first dependency for this component. Create a new list.
14384
14385
14386 lastContextDependency = contextItem;
14387 currentlyRenderingFiber.dependencies = {
14388 lanes: NoLanes,
14389 firstContext: contextItem
14390 };
14391 } else {
14392 // Append a new context item.
14393 lastContextDependency = lastContextDependency.next = contextItem;
14394 }
14395 }
14396
14397 return value;
14398 }
14399
14400 // render. When this render exits, either because it finishes or because it is
14401 // interrupted, the interleaved updates will be transferred onto the main part
14402 // of the queue.
14403
14404 var concurrentQueues = null;
14405 function pushConcurrentUpdateQueue(queue) {
14406 if (concurrentQueues === null) {
14407 concurrentQueues = [queue];
14408 } else {
14409 concurrentQueues.push(queue);
14410 }
14411 }
14412 function finishQueueingConcurrentUpdates() {
14413 // Transfer the interleaved updates onto the main queue. Each queue has a
14414 // `pending` field and an `interleaved` field. When they are not null, they
14415 // point to the last node in a circular linked list. We need to append the
14416 // interleaved list to the end of the pending list by joining them into a
14417 // single, circular list.
14418 if (concurrentQueues !== null) {
14419 for (var i = 0; i < concurrentQueues.length; i++) {
14420 var queue = concurrentQueues[i];
14421 var lastInterleavedUpdate = queue.interleaved;
14422
14423 if (lastInterleavedUpdate !== null) {
14424 queue.interleaved = null;
14425 var firstInterleavedUpdate = lastInterleavedUpdate.next;
14426 var lastPendingUpdate = queue.pending;
14427
14428 if (lastPendingUpdate !== null) {
14429 var firstPendingUpdate = lastPendingUpdate.next;
14430 lastPendingUpdate.next = firstInterleavedUpdate;
14431 lastInterleavedUpdate.next = firstPendingUpdate;
14432 }
14433
14434 queue.pending = lastInterleavedUpdate;
14435 }
14436 }
14437
14438 concurrentQueues = null;
14439 }
14440 }
14441 function enqueueConcurrentHookUpdate(fiber, queue, update, lane) {
14442 var interleaved = queue.interleaved;
14443
14444 if (interleaved === null) {
14445 // This is the first update. Create a circular list.
14446 update.next = update; // At the end of the current render, this queue's interleaved updates will
14447 // be transferred to the pending queue.
14448
14449 pushConcurrentUpdateQueue(queue);
14450 } else {
14451 update.next = interleaved.next;
14452 interleaved.next = update;
14453 }
14454
14455 queue.interleaved = update;
14456 return markUpdateLaneFromFiberToRoot(fiber, lane);
14457 }
14458 function enqueueConcurrentHookUpdateAndEagerlyBailout(fiber, queue, update, lane) {
14459 var interleaved = queue.interleaved;
14460
14461 if (interleaved === null) {
14462 // This is the first update. Create a circular list.
14463 update.next = update; // At the end of the current render, this queue's interleaved updates will
14464 // be transferred to the pending queue.
14465
14466 pushConcurrentUpdateQueue(queue);
14467 } else {
14468 update.next = interleaved.next;
14469 interleaved.next = update;
14470 }
14471
14472 queue.interleaved = update;
14473 }
14474 function enqueueConcurrentClassUpdate(fiber, queue, update, lane) {
14475 var interleaved = queue.interleaved;
14476
14477 if (interleaved === null) {
14478 // This is the first update. Create a circular list.
14479 update.next = update; // At the end of the current render, this queue's interleaved updates will
14480 // be transferred to the pending queue.
14481
14482 pushConcurrentUpdateQueue(queue);
14483 } else {
14484 update.next = interleaved.next;
14485 interleaved.next = update;
14486 }
14487
14488 queue.interleaved = update;
14489 return markUpdateLaneFromFiberToRoot(fiber, lane);
14490 }
14491 function enqueueConcurrentRenderForLane(fiber, lane) {
14492 return markUpdateLaneFromFiberToRoot(fiber, lane);
14493 } // Calling this function outside this module should only be done for backwards
14494 // compatibility and should always be accompanied by a warning.
14495
14496 var unsafe_markUpdateLaneFromFiberToRoot = markUpdateLaneFromFiberToRoot;
14497
14498 function markUpdateLaneFromFiberToRoot(sourceFiber, lane) {
14499 // Update the source fiber's lanes
14500 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, lane);
14501 var alternate = sourceFiber.alternate;
14502
14503 if (alternate !== null) {
14504 alternate.lanes = mergeLanes(alternate.lanes, lane);
14505 }
14506
14507 {
14508 if (alternate === null && (sourceFiber.flags & (Placement | Hydrating)) !== NoFlags) {
14509 warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);
14510 }
14511 } // Walk the parent path to the root and update the child lanes.
14512
14513
14514 var node = sourceFiber;
14515 var parent = sourceFiber.return;
14516
14517 while (parent !== null) {
14518 parent.childLanes = mergeLanes(parent.childLanes, lane);
14519 alternate = parent.alternate;
14520
14521 if (alternate !== null) {
14522 alternate.childLanes = mergeLanes(alternate.childLanes, lane);
14523 } else {
14524 {
14525 if ((parent.flags & (Placement | Hydrating)) !== NoFlags) {
14526 warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);
14527 }
14528 }
14529 }
14530
14531 node = parent;
14532 parent = parent.return;
14533 }
14534
14535 if (node.tag === HostRoot) {
14536 var root = node.stateNode;
14537 return root;
14538 } else {
14539 return null;
14540 }
14541 }
14542
14543 var UpdateState = 0;
14544 var ReplaceState = 1;
14545 var ForceUpdate = 2;
14546 var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.
14547 // It should only be read right after calling `processUpdateQueue`, via
14548 // `checkHasForceUpdateAfterProcessing`.
14549
14550 var hasForceUpdate = false;
14551 var didWarnUpdateInsideUpdate;
14552 var currentlyProcessingQueue;
14553
14554 {
14555 didWarnUpdateInsideUpdate = false;
14556 currentlyProcessingQueue = null;
14557 }
14558
14559 function initializeUpdateQueue(fiber) {
14560 var queue = {
14561 baseState: fiber.memoizedState,
14562 firstBaseUpdate: null,
14563 lastBaseUpdate: null,
14564 shared: {
14565 pending: null,
14566 interleaved: null,
14567 lanes: NoLanes
14568 },
14569 effects: null
14570 };
14571 fiber.updateQueue = queue;
14572 }
14573 function cloneUpdateQueue(current, workInProgress) {
14574 // Clone the update queue from current. Unless it's already a clone.
14575 var queue = workInProgress.updateQueue;
14576 var currentQueue = current.updateQueue;
14577
14578 if (queue === currentQueue) {
14579 var clone = {
14580 baseState: currentQueue.baseState,
14581 firstBaseUpdate: currentQueue.firstBaseUpdate,
14582 lastBaseUpdate: currentQueue.lastBaseUpdate,
14583 shared: currentQueue.shared,
14584 effects: currentQueue.effects
14585 };
14586 workInProgress.updateQueue = clone;
14587 }
14588 }
14589 function createUpdate(eventTime, lane) {
14590 var update = {
14591 eventTime: eventTime,
14592 lane: lane,
14593 tag: UpdateState,
14594 payload: null,
14595 callback: null,
14596 next: null
14597 };
14598 return update;
14599 }
14600 function enqueueUpdate(fiber, update, lane) {
14601 var updateQueue = fiber.updateQueue;
14602
14603 if (updateQueue === null) {
14604 // Only occurs if the fiber has been unmounted.
14605 return null;
14606 }
14607
14608 var sharedQueue = updateQueue.shared;
14609
14610 {
14611 if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) {
14612 error('An update (setState, replaceState, or forceUpdate) was scheduled ' + 'from inside an update function. Update functions should be pure, ' + 'with zero side-effects. Consider using componentDidUpdate or a ' + 'callback.');
14613
14614 didWarnUpdateInsideUpdate = true;
14615 }
14616 }
14617
14618 if (isUnsafeClassRenderPhaseUpdate()) {
14619 // This is an unsafe render phase update. Add directly to the update
14620 // queue so we can process it immediately during the current render.
14621 var pending = sharedQueue.pending;
14622
14623 if (pending === null) {
14624 // This is the first update. Create a circular list.
14625 update.next = update;
14626 } else {
14627 update.next = pending.next;
14628 pending.next = update;
14629 }
14630
14631 sharedQueue.pending = update; // Update the childLanes even though we're most likely already rendering
14632 // this fiber. This is for backwards compatibility in the case where you
14633 // update a different component during render phase than the one that is
14634 // currently renderings (a pattern that is accompanied by a warning).
14635
14636 return unsafe_markUpdateLaneFromFiberToRoot(fiber, lane);
14637 } else {
14638 return enqueueConcurrentClassUpdate(fiber, sharedQueue, update, lane);
14639 }
14640 }
14641 function entangleTransitions(root, fiber, lane) {
14642 var updateQueue = fiber.updateQueue;
14643
14644 if (updateQueue === null) {
14645 // Only occurs if the fiber has been unmounted.
14646 return;
14647 }
14648
14649 var sharedQueue = updateQueue.shared;
14650
14651 if (isTransitionLane(lane)) {
14652 var queueLanes = sharedQueue.lanes; // If any entangled lanes are no longer pending on the root, then they must
14653 // have finished. We can remove them from the shared queue, which represents
14654 // a superset of the actually pending lanes. In some cases we may entangle
14655 // more than we need to, but that's OK. In fact it's worse if we *don't*
14656 // entangle when we should.
14657
14658 queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes.
14659
14660 var newQueueLanes = mergeLanes(queueLanes, lane);
14661 sharedQueue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if
14662 // the lane finished since the last time we entangled it. So we need to
14663 // entangle it again, just to be sure.
14664
14665 markRootEntangled(root, newQueueLanes);
14666 }
14667 }
14668 function enqueueCapturedUpdate(workInProgress, capturedUpdate) {
14669 // Captured updates are updates that are thrown by a child during the render
14670 // phase. They should be discarded if the render is aborted. Therefore,
14671 // we should only put them on the work-in-progress queue, not the current one.
14672 var queue = workInProgress.updateQueue; // Check if the work-in-progress queue is a clone.
14673
14674 var current = workInProgress.alternate;
14675
14676 if (current !== null) {
14677 var currentQueue = current.updateQueue;
14678
14679 if (queue === currentQueue) {
14680 // The work-in-progress queue is the same as current. This happens when
14681 // we bail out on a parent fiber that then captures an error thrown by
14682 // a child. Since we want to append the update only to the work-in
14683 // -progress queue, we need to clone the updates. We usually clone during
14684 // processUpdateQueue, but that didn't happen in this case because we
14685 // skipped over the parent when we bailed out.
14686 var newFirst = null;
14687 var newLast = null;
14688 var firstBaseUpdate = queue.firstBaseUpdate;
14689
14690 if (firstBaseUpdate !== null) {
14691 // Loop through the updates and clone them.
14692 var update = firstBaseUpdate;
14693
14694 do {
14695 var clone = {
14696 eventTime: update.eventTime,
14697 lane: update.lane,
14698 tag: update.tag,
14699 payload: update.payload,
14700 callback: update.callback,
14701 next: null
14702 };
14703
14704 if (newLast === null) {
14705 newFirst = newLast = clone;
14706 } else {
14707 newLast.next = clone;
14708 newLast = clone;
14709 }
14710
14711 update = update.next;
14712 } while (update !== null); // Append the captured update the end of the cloned list.
14713
14714
14715 if (newLast === null) {
14716 newFirst = newLast = capturedUpdate;
14717 } else {
14718 newLast.next = capturedUpdate;
14719 newLast = capturedUpdate;
14720 }
14721 } else {
14722 // There are no base updates.
14723 newFirst = newLast = capturedUpdate;
14724 }
14725
14726 queue = {
14727 baseState: currentQueue.baseState,
14728 firstBaseUpdate: newFirst,
14729 lastBaseUpdate: newLast,
14730 shared: currentQueue.shared,
14731 effects: currentQueue.effects
14732 };
14733 workInProgress.updateQueue = queue;
14734 return;
14735 }
14736 } // Append the update to the end of the list.
14737
14738
14739 var lastBaseUpdate = queue.lastBaseUpdate;
14740
14741 if (lastBaseUpdate === null) {
14742 queue.firstBaseUpdate = capturedUpdate;
14743 } else {
14744 lastBaseUpdate.next = capturedUpdate;
14745 }
14746
14747 queue.lastBaseUpdate = capturedUpdate;
14748 }
14749
14750 function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
14751 switch (update.tag) {
14752 case ReplaceState:
14753 {
14754 var payload = update.payload;
14755
14756 if (typeof payload === 'function') {
14757 // Updater function
14758 {
14759 enterDisallowedContextReadInDEV();
14760 }
14761
14762 var nextState = payload.call(instance, prevState, nextProps);
14763
14764 {
14765 if ( workInProgress.mode & StrictLegacyMode) {
14766 setIsStrictModeForDevtools(true);
14767
14768 try {
14769 payload.call(instance, prevState, nextProps);
14770 } finally {
14771 setIsStrictModeForDevtools(false);
14772 }
14773 }
14774
14775 exitDisallowedContextReadInDEV();
14776 }
14777
14778 return nextState;
14779 } // State object
14780
14781
14782 return payload;
14783 }
14784
14785 case CaptureUpdate:
14786 {
14787 workInProgress.flags = workInProgress.flags & ~ShouldCapture | DidCapture;
14788 }
14789 // Intentional fallthrough
14790
14791 case UpdateState:
14792 {
14793 var _payload = update.payload;
14794 var partialState;
14795
14796 if (typeof _payload === 'function') {
14797 // Updater function
14798 {
14799 enterDisallowedContextReadInDEV();
14800 }
14801
14802 partialState = _payload.call(instance, prevState, nextProps);
14803
14804 {
14805 if ( workInProgress.mode & StrictLegacyMode) {
14806 setIsStrictModeForDevtools(true);
14807
14808 try {
14809 _payload.call(instance, prevState, nextProps);
14810 } finally {
14811 setIsStrictModeForDevtools(false);
14812 }
14813 }
14814
14815 exitDisallowedContextReadInDEV();
14816 }
14817 } else {
14818 // Partial state object
14819 partialState = _payload;
14820 }
14821
14822 if (partialState === null || partialState === undefined) {
14823 // Null and undefined are treated as no-ops.
14824 return prevState;
14825 } // Merge the partial state and the previous state.
14826
14827
14828 return assign({}, prevState, partialState);
14829 }
14830
14831 case ForceUpdate:
14832 {
14833 hasForceUpdate = true;
14834 return prevState;
14835 }
14836 }
14837
14838 return prevState;
14839 }
14840
14841 function processUpdateQueue(workInProgress, props, instance, renderLanes) {
14842 // This is always non-null on a ClassComponent or HostRoot
14843 var queue = workInProgress.updateQueue;
14844 hasForceUpdate = false;
14845
14846 {
14847 currentlyProcessingQueue = queue.shared;
14848 }
14849
14850 var firstBaseUpdate = queue.firstBaseUpdate;
14851 var lastBaseUpdate = queue.lastBaseUpdate; // Check if there are pending updates. If so, transfer them to the base queue.
14852
14853 var pendingQueue = queue.shared.pending;
14854
14855 if (pendingQueue !== null) {
14856 queue.shared.pending = null; // The pending queue is circular. Disconnect the pointer between first
14857 // and last so that it's non-circular.
14858
14859 var lastPendingUpdate = pendingQueue;
14860 var firstPendingUpdate = lastPendingUpdate.next;
14861 lastPendingUpdate.next = null; // Append pending updates to base queue
14862
14863 if (lastBaseUpdate === null) {
14864 firstBaseUpdate = firstPendingUpdate;
14865 } else {
14866 lastBaseUpdate.next = firstPendingUpdate;
14867 }
14868
14869 lastBaseUpdate = lastPendingUpdate; // If there's a current queue, and it's different from the base queue, then
14870 // we need to transfer the updates to that queue, too. Because the base
14871 // queue is a singly-linked list with no cycles, we can append to both
14872 // lists and take advantage of structural sharing.
14873 // TODO: Pass `current` as argument
14874
14875 var current = workInProgress.alternate;
14876
14877 if (current !== null) {
14878 // This is always non-null on a ClassComponent or HostRoot
14879 var currentQueue = current.updateQueue;
14880 var currentLastBaseUpdate = currentQueue.lastBaseUpdate;
14881
14882 if (currentLastBaseUpdate !== lastBaseUpdate) {
14883 if (currentLastBaseUpdate === null) {
14884 currentQueue.firstBaseUpdate = firstPendingUpdate;
14885 } else {
14886 currentLastBaseUpdate.next = firstPendingUpdate;
14887 }
14888
14889 currentQueue.lastBaseUpdate = lastPendingUpdate;
14890 }
14891 }
14892 } // These values may change as we process the queue.
14893
14894
14895 if (firstBaseUpdate !== null) {
14896 // Iterate through the list of updates to compute the result.
14897 var newState = queue.baseState; // TODO: Don't need to accumulate this. Instead, we can remove renderLanes
14898 // from the original lanes.
14899
14900 var newLanes = NoLanes;
14901 var newBaseState = null;
14902 var newFirstBaseUpdate = null;
14903 var newLastBaseUpdate = null;
14904 var update = firstBaseUpdate;
14905
14906 do {
14907 var updateLane = update.lane;
14908 var updateEventTime = update.eventTime;
14909
14910 if (!isSubsetOfLanes(renderLanes, updateLane)) {
14911 // Priority is insufficient. Skip this update. If this is the first
14912 // skipped update, the previous update/state is the new base
14913 // update/state.
14914 var clone = {
14915 eventTime: updateEventTime,
14916 lane: updateLane,
14917 tag: update.tag,
14918 payload: update.payload,
14919 callback: update.callback,
14920 next: null
14921 };
14922
14923 if (newLastBaseUpdate === null) {
14924 newFirstBaseUpdate = newLastBaseUpdate = clone;
14925 newBaseState = newState;
14926 } else {
14927 newLastBaseUpdate = newLastBaseUpdate.next = clone;
14928 } // Update the remaining priority in the queue.
14929
14930
14931 newLanes = mergeLanes(newLanes, updateLane);
14932 } else {
14933 // This update does have sufficient priority.
14934 if (newLastBaseUpdate !== null) {
14935 var _clone = {
14936 eventTime: updateEventTime,
14937 // This update is going to be committed so we never want uncommit
14938 // it. Using NoLane works because 0 is a subset of all bitmasks, so
14939 // this will never be skipped by the check above.
14940 lane: NoLane,
14941 tag: update.tag,
14942 payload: update.payload,
14943 callback: update.callback,
14944 next: null
14945 };
14946 newLastBaseUpdate = newLastBaseUpdate.next = _clone;
14947 } // Process this update.
14948
14949
14950 newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance);
14951 var callback = update.callback;
14952
14953 if (callback !== null && // If the update was already committed, we should not queue its
14954 // callback again.
14955 update.lane !== NoLane) {
14956 workInProgress.flags |= Callback;
14957 var effects = queue.effects;
14958
14959 if (effects === null) {
14960 queue.effects = [update];
14961 } else {
14962 effects.push(update);
14963 }
14964 }
14965 }
14966
14967 update = update.next;
14968
14969 if (update === null) {
14970 pendingQueue = queue.shared.pending;
14971
14972 if (pendingQueue === null) {
14973 break;
14974 } else {
14975 // An update was scheduled from inside a reducer. Add the new
14976 // pending updates to the end of the list and keep processing.
14977 var _lastPendingUpdate = pendingQueue; // Intentionally unsound. Pending updates form a circular list, but we
14978 // unravel them when transferring them to the base queue.
14979
14980 var _firstPendingUpdate = _lastPendingUpdate.next;
14981 _lastPendingUpdate.next = null;
14982 update = _firstPendingUpdate;
14983 queue.lastBaseUpdate = _lastPendingUpdate;
14984 queue.shared.pending = null;
14985 }
14986 }
14987 } while (true);
14988
14989 if (newLastBaseUpdate === null) {
14990 newBaseState = newState;
14991 }
14992
14993 queue.baseState = newBaseState;
14994 queue.firstBaseUpdate = newFirstBaseUpdate;
14995 queue.lastBaseUpdate = newLastBaseUpdate; // Interleaved updates are stored on a separate queue. We aren't going to
14996 // process them during this render, but we do need to track which lanes
14997 // are remaining.
14998
14999 var lastInterleaved = queue.shared.interleaved;
15000
15001 if (lastInterleaved !== null) {
15002 var interleaved = lastInterleaved;
15003
15004 do {
15005 newLanes = mergeLanes(newLanes, interleaved.lane);
15006 interleaved = interleaved.next;
15007 } while (interleaved !== lastInterleaved);
15008 } else if (firstBaseUpdate === null) {
15009 // `queue.lanes` is used for entangling transitions. We can set it back to
15010 // zero once the queue is empty.
15011 queue.shared.lanes = NoLanes;
15012 } // Set the remaining expiration time to be whatever is remaining in the queue.
15013 // This should be fine because the only two other things that contribute to
15014 // expiration time are props and context. We're already in the middle of the
15015 // begin phase by the time we start processing the queue, so we've already
15016 // dealt with the props. Context in components that specify
15017 // shouldComponentUpdate is tricky; but we'll have to account for
15018 // that regardless.
15019
15020
15021 markSkippedUpdateLanes(newLanes);
15022 workInProgress.lanes = newLanes;
15023 workInProgress.memoizedState = newState;
15024 }
15025
15026 {
15027 currentlyProcessingQueue = null;
15028 }
15029 }
15030
15031 function callCallback(callback, context) {
15032 if (typeof callback !== 'function') {
15033 throw new Error('Invalid argument passed as callback. Expected a function. Instead ' + ("received: " + callback));
15034 }
15035
15036 callback.call(context);
15037 }
15038
15039 function resetHasForceUpdateBeforeProcessing() {
15040 hasForceUpdate = false;
15041 }
15042 function checkHasForceUpdateAfterProcessing() {
15043 return hasForceUpdate;
15044 }
15045 function commitUpdateQueue(finishedWork, finishedQueue, instance) {
15046 // Commit the effects
15047 var effects = finishedQueue.effects;
15048 finishedQueue.effects = null;
15049
15050 if (effects !== null) {
15051 for (var i = 0; i < effects.length; i++) {
15052 var effect = effects[i];
15053 var callback = effect.callback;
15054
15055 if (callback !== null) {
15056 effect.callback = null;
15057 callCallback(callback, instance);
15058 }
15059 }
15060 }
15061 }
15062
15063 var NO_CONTEXT = {};
15064 var contextStackCursor$1 = createCursor(NO_CONTEXT);
15065 var contextFiberStackCursor = createCursor(NO_CONTEXT);
15066 var rootInstanceStackCursor = createCursor(NO_CONTEXT);
15067
15068 function requiredContext(c) {
15069 if (c === NO_CONTEXT) {
15070 throw new Error('Expected host context to exist. This error is likely caused by a bug ' + 'in React. Please file an issue.');
15071 }
15072
15073 return c;
15074 }
15075
15076 function getRootHostContainer() {
15077 var rootInstance = requiredContext(rootInstanceStackCursor.current);
15078 return rootInstance;
15079 }
15080
15081 function pushHostContainer(fiber, nextRootInstance) {
15082 // Push current root instance onto the stack;
15083 // This allows us to reset root when portals are popped.
15084 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
15085 // This enables us to pop only Fibers that provide unique contexts.
15086
15087 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
15088 // However, we can't just call getRootHostContext() and push it because
15089 // we'd have a different number of entries on the stack depending on
15090 // whether getRootHostContext() throws somewhere in renderer code or not.
15091 // So we push an empty value first. This lets us safely unwind on errors.
15092
15093 push(contextStackCursor$1, NO_CONTEXT, fiber);
15094 var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it.
15095
15096 pop(contextStackCursor$1, fiber);
15097 push(contextStackCursor$1, nextRootContext, fiber);
15098 }
15099
15100 function popHostContainer(fiber) {
15101 pop(contextStackCursor$1, fiber);
15102 pop(contextFiberStackCursor, fiber);
15103 pop(rootInstanceStackCursor, fiber);
15104 }
15105
15106 function getHostContext() {
15107 var context = requiredContext(contextStackCursor$1.current);
15108 return context;
15109 }
15110
15111 function pushHostContext(fiber) {
15112 var rootInstance = requiredContext(rootInstanceStackCursor.current);
15113 var context = requiredContext(contextStackCursor$1.current);
15114 var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique.
15115
15116 if (context === nextContext) {
15117 return;
15118 } // Track the context and the Fiber that provided it.
15119 // This enables us to pop only Fibers that provide unique contexts.
15120
15121
15122 push(contextFiberStackCursor, fiber, fiber);
15123 push(contextStackCursor$1, nextContext, fiber);
15124 }
15125
15126 function popHostContext(fiber) {
15127 // Do not pop unless this Fiber provided the current context.
15128 // pushHostContext() only pushes Fibers that provide unique contexts.
15129 if (contextFiberStackCursor.current !== fiber) {
15130 return;
15131 }
15132
15133 pop(contextStackCursor$1, fiber);
15134 pop(contextFiberStackCursor, fiber);
15135 }
15136
15137 var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is
15138 // inherited deeply down the subtree. The upper bits only affect
15139 // this immediate suspense boundary and gets reset each new
15140 // boundary or suspense list.
15141
15142 var SubtreeSuspenseContextMask = 1; // Subtree Flags:
15143 // InvisibleParentSuspenseContext indicates that one of our parent Suspense
15144 // boundaries is not currently showing visible main content.
15145 // Either because it is already showing a fallback or is not mounted at all.
15146 // We can use this to determine if it is desirable to trigger a fallback at
15147 // the parent. If not, then we might need to trigger undesirable boundaries
15148 // and/or suspend the commit to avoid hiding the parent content.
15149
15150 var InvisibleParentSuspenseContext = 1; // Shallow Flags:
15151 // ForceSuspenseFallback can be used by SuspenseList to force newly added
15152 // items into their fallback state during one of the render passes.
15153
15154 var ForceSuspenseFallback = 2;
15155 var suspenseStackCursor = createCursor(DefaultSuspenseContext);
15156 function hasSuspenseContext(parentContext, flag) {
15157 return (parentContext & flag) !== 0;
15158 }
15159 function setDefaultShallowSuspenseContext(parentContext) {
15160 return parentContext & SubtreeSuspenseContextMask;
15161 }
15162 function setShallowSuspenseContext(parentContext, shallowContext) {
15163 return parentContext & SubtreeSuspenseContextMask | shallowContext;
15164 }
15165 function addSubtreeSuspenseContext(parentContext, subtreeContext) {
15166 return parentContext | subtreeContext;
15167 }
15168 function pushSuspenseContext(fiber, newContext) {
15169 push(suspenseStackCursor, newContext, fiber);
15170 }
15171 function popSuspenseContext(fiber) {
15172 pop(suspenseStackCursor, fiber);
15173 }
15174
15175 function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
15176 // If it was the primary children that just suspended, capture and render the
15177 // fallback. Otherwise, don't capture and bubble to the next boundary.
15178 var nextState = workInProgress.memoizedState;
15179
15180 if (nextState !== null) {
15181 if (nextState.dehydrated !== null) {
15182 // A dehydrated boundary always captures.
15183 return true;
15184 }
15185
15186 return false;
15187 }
15188
15189 var props = workInProgress.memoizedProps; // Regular boundaries always capture.
15190
15191 {
15192 return true;
15193 } // If it's a boundary we should avoid, then we prefer to bubble up to the
15194 }
15195 function findFirstSuspended(row) {
15196 var node = row;
15197
15198 while (node !== null) {
15199 if (node.tag === SuspenseComponent) {
15200 var state = node.memoizedState;
15201
15202 if (state !== null) {
15203 var dehydrated = state.dehydrated;
15204
15205 if (dehydrated === null || isSuspenseInstancePending(dehydrated) || isSuspenseInstanceFallback(dehydrated)) {
15206 return node;
15207 }
15208 }
15209 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't
15210 // keep track of whether it suspended or not.
15211 node.memoizedProps.revealOrder !== undefined) {
15212 var didSuspend = (node.flags & DidCapture) !== NoFlags;
15213
15214 if (didSuspend) {
15215 return node;
15216 }
15217 } else if (node.child !== null) {
15218 node.child.return = node;
15219 node = node.child;
15220 continue;
15221 }
15222
15223 if (node === row) {
15224 return null;
15225 }
15226
15227 while (node.sibling === null) {
15228 if (node.return === null || node.return === row) {
15229 return null;
15230 }
15231
15232 node = node.return;
15233 }
15234
15235 node.sibling.return = node.return;
15236 node = node.sibling;
15237 }
15238
15239 return null;
15240 }
15241
15242 var NoFlags$1 =
15243 /* */
15244 0; // Represents whether effect should fire.
15245
15246 var HasEffect =
15247 /* */
15248 1; // Represents the phase in which the effect (not the clean-up) fires.
15249
15250 var Insertion =
15251 /* */
15252 2;
15253 var Layout =
15254 /* */
15255 4;
15256 var Passive$1 =
15257 /* */
15258 8;
15259
15260 // and should be reset before starting a new render.
15261 // This tracks which mutable sources need to be reset after a render.
15262
15263 var workInProgressSources = [];
15264 function resetWorkInProgressVersions() {
15265 for (var i = 0; i < workInProgressSources.length; i++) {
15266 var mutableSource = workInProgressSources[i];
15267
15268 {
15269 mutableSource._workInProgressVersionPrimary = null;
15270 }
15271 }
15272
15273 workInProgressSources.length = 0;
15274 }
15275 // This ensures that the version used for server rendering matches the one
15276 // that is eventually read during hydration.
15277 // If they don't match there's a potential tear and a full deopt render is required.
15278
15279 function registerMutableSourceForHydration(root, mutableSource) {
15280 var getVersion = mutableSource._getVersion;
15281 var version = getVersion(mutableSource._source); // TODO Clear this data once all pending hydration work is finished.
15282 // Retaining it forever may interfere with GC.
15283
15284 if (root.mutableSourceEagerHydrationData == null) {
15285 root.mutableSourceEagerHydrationData = [mutableSource, version];
15286 } else {
15287 root.mutableSourceEagerHydrationData.push(mutableSource, version);
15288 }
15289 }
15290
15291 var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher,
15292 ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig;
15293 var didWarnAboutMismatchedHooksForComponent;
15294 var didWarnUncachedGetSnapshot;
15295
15296 {
15297 didWarnAboutMismatchedHooksForComponent = new Set();
15298 }
15299
15300 // These are set right before calling the component.
15301 var renderLanes = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from
15302 // the work-in-progress hook.
15303
15304 var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
15305 // current hook list is the list that belongs to the current fiber. The
15306 // work-in-progress hook list is a new list that will be added to the
15307 // work-in-progress fiber.
15308
15309 var currentHook = null;
15310 var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This
15311 // does not get reset if we do another render pass; only when we're completely
15312 // finished evaluating this component. This is an optimization so we know
15313 // whether we need to clear render phase updates after a throw.
15314
15315 var didScheduleRenderPhaseUpdate = false; // Where an update was scheduled only during the current render pass. This
15316 // gets reset after each attempt.
15317 // TODO: Maybe there's some way to consolidate this with
15318 // `didScheduleRenderPhaseUpdate`. Or with `numberOfReRenders`.
15319
15320 var didScheduleRenderPhaseUpdateDuringThisPass = false; // Counts the number of useId hooks in this component.
15321
15322 var localIdCounter = 0; // Used for ids that are generated completely client-side (i.e. not during
15323 // hydration). This counter is global, so client ids are not stable across
15324 // render attempts.
15325
15326 var globalClientIdCounter = 0;
15327 var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook
15328
15329 var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.
15330 // The list stores the order of hooks used during the initial render (mount).
15331 // Subsequent renders (updates) reference this list.
15332
15333 var hookTypesDev = null;
15334 var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore
15335 // the dependencies for Hooks that need them (e.g. useEffect or useMemo).
15336 // When true, such Hooks will always be "remounted". Only used during hot reload.
15337
15338 var ignorePreviousDependencies = false;
15339
15340 function mountHookTypesDev() {
15341 {
15342 var hookName = currentHookNameInDev;
15343
15344 if (hookTypesDev === null) {
15345 hookTypesDev = [hookName];
15346 } else {
15347 hookTypesDev.push(hookName);
15348 }
15349 }
15350 }
15351
15352 function updateHookTypesDev() {
15353 {
15354 var hookName = currentHookNameInDev;
15355
15356 if (hookTypesDev !== null) {
15357 hookTypesUpdateIndexDev++;
15358
15359 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
15360 warnOnHookMismatchInDev(hookName);
15361 }
15362 }
15363 }
15364 }
15365
15366 function checkDepsAreArrayDev(deps) {
15367 {
15368 if (deps !== undefined && deps !== null && !isArray(deps)) {
15369 // Verify deps, but only on mount to avoid extra checks.
15370 // It's unlikely their type would change as usually you define them inline.
15371 error('%s received a final argument that is not an array (instead, received `%s`). When ' + 'specified, the final argument must be an array.', currentHookNameInDev, typeof deps);
15372 }
15373 }
15374 }
15375
15376 function warnOnHookMismatchInDev(currentHookName) {
15377 {
15378 var componentName = getComponentNameFromFiber(currentlyRenderingFiber$1);
15379
15380 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
15381 didWarnAboutMismatchedHooksForComponent.add(componentName);
15382
15383 if (hookTypesDev !== null) {
15384 var table = '';
15385 var secondColumnStart = 30;
15386
15387 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
15388 var oldHookName = hookTypesDev[i];
15389 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
15390 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up
15391 // lol @ IE not supporting String#repeat
15392
15393 while (row.length < secondColumnStart) {
15394 row += ' ';
15395 }
15396
15397 row += newHookName + '\n';
15398 table += row;
15399 }
15400
15401 error('React has detected a change in the order of Hooks called by %s. ' + 'This will lead to bugs and errors if not fixed. ' + 'For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks\n\n' + ' Previous render Next render\n' + ' ------------------------------------------------------\n' + '%s' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', componentName, table);
15402 }
15403 }
15404 }
15405 }
15406
15407 function throwInvalidHookError() {
15408 throw new Error('Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + ' one of the following reasons:\n' + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + '2. You might be breaking the Rules of Hooks\n' + '3. You might have more than one copy of React in the same app\n' + 'See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.');
15409 }
15410
15411 function areHookInputsEqual(nextDeps, prevDeps) {
15412 {
15413 if (ignorePreviousDependencies) {
15414 // Only true when this component is being hot reloaded.
15415 return false;
15416 }
15417 }
15418
15419 if (prevDeps === null) {
15420 {
15421 error('%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', currentHookNameInDev);
15422 }
15423
15424 return false;
15425 }
15426
15427 {
15428 // Don't bother comparing lengths in prod because these arrays should be
15429 // passed inline.
15430 if (nextDeps.length !== prevDeps.length) {
15431 error('The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + 'Incoming: %s', currentHookNameInDev, "[" + prevDeps.join(', ') + "]", "[" + nextDeps.join(', ') + "]");
15432 }
15433 }
15434
15435 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
15436 if (objectIs(nextDeps[i], prevDeps[i])) {
15437 continue;
15438 }
15439
15440 return false;
15441 }
15442
15443 return true;
15444 }
15445
15446 function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderLanes) {
15447 renderLanes = nextRenderLanes;
15448 currentlyRenderingFiber$1 = workInProgress;
15449
15450 {
15451 hookTypesDev = current !== null ? current._debugHookTypes : null;
15452 hookTypesUpdateIndexDev = -1; // Used for hot reloading:
15453
15454 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
15455 }
15456
15457 workInProgress.memoizedState = null;
15458 workInProgress.updateQueue = null;
15459 workInProgress.lanes = NoLanes; // The following should have already been reset
15460 // currentHook = null;
15461 // workInProgressHook = null;
15462 // didScheduleRenderPhaseUpdate = false;
15463 // localIdCounter = 0;
15464 // TODO Warn if no hooks are used at all during mount, then some are used during update.
15465 // Currently we will identify the update render as a mount because memoizedState === null.
15466 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
15467 // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.
15468 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
15469 // so memoizedState would be null during updates and mounts.
15470
15471 {
15472 if (current !== null && current.memoizedState !== null) {
15473 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
15474 } else if (hookTypesDev !== null) {
15475 // This dispatcher handles an edge case where a component is updating,
15476 // but no stateful hooks have been used.
15477 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
15478 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
15479 // This dispatcher does that.
15480 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
15481 } else {
15482 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
15483 }
15484 }
15485
15486 var children = Component(props, secondArg); // Check if there was a render phase update
15487
15488 if (didScheduleRenderPhaseUpdateDuringThisPass) {
15489 // Keep rendering in a loop for as long as render phase updates continue to
15490 // be scheduled. Use a counter to prevent infinite loops.
15491 var numberOfReRenders = 0;
15492
15493 do {
15494 didScheduleRenderPhaseUpdateDuringThisPass = false;
15495 localIdCounter = 0;
15496
15497 if (numberOfReRenders >= RE_RENDER_LIMIT) {
15498 throw new Error('Too many re-renders. React limits the number of renders to prevent ' + 'an infinite loop.');
15499 }
15500
15501 numberOfReRenders += 1;
15502
15503 {
15504 // Even when hot reloading, allow dependencies to stabilize
15505 // after first render to prevent infinite render phase updates.
15506 ignorePreviousDependencies = false;
15507 } // Start over from the beginning of the list
15508
15509
15510 currentHook = null;
15511 workInProgressHook = null;
15512 workInProgress.updateQueue = null;
15513
15514 {
15515 // Also validate hook order for cascading updates.
15516 hookTypesUpdateIndexDev = -1;
15517 }
15518
15519 ReactCurrentDispatcher$1.current = HooksDispatcherOnRerenderInDEV ;
15520 children = Component(props, secondArg);
15521 } while (didScheduleRenderPhaseUpdateDuringThisPass);
15522 } // We can assume the previous dispatcher is always this one, since we set it
15523 // at the beginning of the render phase and there's no re-entrance.
15524
15525
15526 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
15527
15528 {
15529 workInProgress._debugHookTypes = hookTypesDev;
15530 } // This check uses currentHook so that it works the same in DEV and prod bundles.
15531 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
15532
15533
15534 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
15535 renderLanes = NoLanes;
15536 currentlyRenderingFiber$1 = null;
15537 currentHook = null;
15538 workInProgressHook = null;
15539
15540 {
15541 currentHookNameInDev = null;
15542 hookTypesDev = null;
15543 hookTypesUpdateIndexDev = -1; // Confirm that a static flag was not added or removed since the last
15544 // render. If this fires, it suggests that we incorrectly reset the static
15545 // flags in some other part of the codebase. This has happened before, for
15546 // example, in the SuspenseList implementation.
15547
15548 if (current !== null && (current.flags & StaticMask) !== (workInProgress.flags & StaticMask) && // Disable this warning in legacy mode, because legacy Suspense is weird
15549 // and creates false positives. To make this work in legacy mode, we'd
15550 // need to mark fibers that commit in an incomplete state, somehow. For
15551 // now I'll disable the warning that most of the bugs that would trigger
15552 // it are either exclusive to concurrent mode or exist in both.
15553 (current.mode & ConcurrentMode) !== NoMode) {
15554 error('Internal React error: Expected static flag was missing. Please ' + 'notify the React team.');
15555 }
15556 }
15557
15558 didScheduleRenderPhaseUpdate = false; // This is reset by checkDidRenderIdHook
15559 // localIdCounter = 0;
15560
15561 if (didRenderTooFewHooks) {
15562 throw new Error('Rendered fewer hooks than expected. This may be caused by an accidental ' + 'early return statement.');
15563 }
15564
15565 return children;
15566 }
15567 function checkDidRenderIdHook() {
15568 // This should be called immediately after every renderWithHooks call.
15569 // Conceptually, it's part of the return value of renderWithHooks; it's only a
15570 // separate function to avoid using an array tuple.
15571 var didRenderIdHook = localIdCounter !== 0;
15572 localIdCounter = 0;
15573 return didRenderIdHook;
15574 }
15575 function bailoutHooks(current, workInProgress, lanes) {
15576 workInProgress.updateQueue = current.updateQueue; // TODO: Don't need to reset the flags here, because they're reset in the
15577 // complete phase (bubbleProperties).
15578
15579 if ( (workInProgress.mode & StrictEffectsMode) !== NoMode) {
15580 workInProgress.flags &= ~(MountPassiveDev | MountLayoutDev | Passive | Update);
15581 } else {
15582 workInProgress.flags &= ~(Passive | Update);
15583 }
15584
15585 current.lanes = removeLanes(current.lanes, lanes);
15586 }
15587 function resetHooksAfterThrow() {
15588 // We can assume the previous dispatcher is always this one, since we set it
15589 // at the beginning of the render phase and there's no re-entrance.
15590 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
15591
15592 if (didScheduleRenderPhaseUpdate) {
15593 // There were render phase updates. These are only valid for this render
15594 // phase, which we are now aborting. Remove the updates from the queues so
15595 // they do not persist to the next render. Do not remove updates from hooks
15596 // that weren't processed.
15597 //
15598 // Only reset the updates from the queue if it has a clone. If it does
15599 // not have a clone, that means it wasn't processed, and the updates were
15600 // scheduled before we entered the render phase.
15601 var hook = currentlyRenderingFiber$1.memoizedState;
15602
15603 while (hook !== null) {
15604 var queue = hook.queue;
15605
15606 if (queue !== null) {
15607 queue.pending = null;
15608 }
15609
15610 hook = hook.next;
15611 }
15612
15613 didScheduleRenderPhaseUpdate = false;
15614 }
15615
15616 renderLanes = NoLanes;
15617 currentlyRenderingFiber$1 = null;
15618 currentHook = null;
15619 workInProgressHook = null;
15620
15621 {
15622 hookTypesDev = null;
15623 hookTypesUpdateIndexDev = -1;
15624 currentHookNameInDev = null;
15625 isUpdatingOpaqueValueInRenderPhase = false;
15626 }
15627
15628 didScheduleRenderPhaseUpdateDuringThisPass = false;
15629 localIdCounter = 0;
15630 }
15631
15632 function mountWorkInProgressHook() {
15633 var hook = {
15634 memoizedState: null,
15635 baseState: null,
15636 baseQueue: null,
15637 queue: null,
15638 next: null
15639 };
15640
15641 if (workInProgressHook === null) {
15642 // This is the first hook in the list
15643 currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;
15644 } else {
15645 // Append to the end of the list
15646 workInProgressHook = workInProgressHook.next = hook;
15647 }
15648
15649 return workInProgressHook;
15650 }
15651
15652 function updateWorkInProgressHook() {
15653 // This function is used both for updates and for re-renders triggered by a
15654 // render phase update. It assumes there is either a current hook we can
15655 // clone, or a work-in-progress hook from a previous render pass that we can
15656 // use as a base. When we reach the end of the base list, we must switch to
15657 // the dispatcher used for mounts.
15658 var nextCurrentHook;
15659
15660 if (currentHook === null) {
15661 var current = currentlyRenderingFiber$1.alternate;
15662
15663 if (current !== null) {
15664 nextCurrentHook = current.memoizedState;
15665 } else {
15666 nextCurrentHook = null;
15667 }
15668 } else {
15669 nextCurrentHook = currentHook.next;
15670 }
15671
15672 var nextWorkInProgressHook;
15673
15674 if (workInProgressHook === null) {
15675 nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState;
15676 } else {
15677 nextWorkInProgressHook = workInProgressHook.next;
15678 }
15679
15680 if (nextWorkInProgressHook !== null) {
15681 // There's already a work-in-progress. Reuse it.
15682 workInProgressHook = nextWorkInProgressHook;
15683 nextWorkInProgressHook = workInProgressHook.next;
15684 currentHook = nextCurrentHook;
15685 } else {
15686 // Clone from the current hook.
15687 if (nextCurrentHook === null) {
15688 throw new Error('Rendered more hooks than during the previous render.');
15689 }
15690
15691 currentHook = nextCurrentHook;
15692 var newHook = {
15693 memoizedState: currentHook.memoizedState,
15694 baseState: currentHook.baseState,
15695 baseQueue: currentHook.baseQueue,
15696 queue: currentHook.queue,
15697 next: null
15698 };
15699
15700 if (workInProgressHook === null) {
15701 // This is the first hook in the list.
15702 currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook;
15703 } else {
15704 // Append to the end of the list.
15705 workInProgressHook = workInProgressHook.next = newHook;
15706 }
15707 }
15708
15709 return workInProgressHook;
15710 }
15711
15712 function createFunctionComponentUpdateQueue() {
15713 return {
15714 lastEffect: null,
15715 stores: null
15716 };
15717 }
15718
15719 function basicStateReducer(state, action) {
15720 // $FlowFixMe: Flow doesn't like mixed types
15721 return typeof action === 'function' ? action(state) : action;
15722 }
15723
15724 function mountReducer(reducer, initialArg, init) {
15725 var hook = mountWorkInProgressHook();
15726 var initialState;
15727
15728 if (init !== undefined) {
15729 initialState = init(initialArg);
15730 } else {
15731 initialState = initialArg;
15732 }
15733
15734 hook.memoizedState = hook.baseState = initialState;
15735 var queue = {
15736 pending: null,
15737 interleaved: null,
15738 lanes: NoLanes,
15739 dispatch: null,
15740 lastRenderedReducer: reducer,
15741 lastRenderedState: initialState
15742 };
15743 hook.queue = queue;
15744 var dispatch = queue.dispatch = dispatchReducerAction.bind(null, currentlyRenderingFiber$1, queue);
15745 return [hook.memoizedState, dispatch];
15746 }
15747
15748 function updateReducer(reducer, initialArg, init) {
15749 var hook = updateWorkInProgressHook();
15750 var queue = hook.queue;
15751
15752 if (queue === null) {
15753 throw new Error('Should have a queue. This is likely a bug in React. Please file an issue.');
15754 }
15755
15756 queue.lastRenderedReducer = reducer;
15757 var current = currentHook; // The last rebase update that is NOT part of the base state.
15758
15759 var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet.
15760
15761 var pendingQueue = queue.pending;
15762
15763 if (pendingQueue !== null) {
15764 // We have new updates that haven't been processed yet.
15765 // We'll add them to the base queue.
15766 if (baseQueue !== null) {
15767 // Merge the pending queue and the base queue.
15768 var baseFirst = baseQueue.next;
15769 var pendingFirst = pendingQueue.next;
15770 baseQueue.next = pendingFirst;
15771 pendingQueue.next = baseFirst;
15772 }
15773
15774 {
15775 if (current.baseQueue !== baseQueue) {
15776 // Internal invariant that should never happen, but feasibly could in
15777 // the future if we implement resuming, or some form of that.
15778 error('Internal error: Expected work-in-progress queue to be a clone. ' + 'This is a bug in React.');
15779 }
15780 }
15781
15782 current.baseQueue = baseQueue = pendingQueue;
15783 queue.pending = null;
15784 }
15785
15786 if (baseQueue !== null) {
15787 // We have a queue to process.
15788 var first = baseQueue.next;
15789 var newState = current.baseState;
15790 var newBaseState = null;
15791 var newBaseQueueFirst = null;
15792 var newBaseQueueLast = null;
15793 var update = first;
15794
15795 do {
15796 var updateLane = update.lane;
15797
15798 if (!isSubsetOfLanes(renderLanes, updateLane)) {
15799 // Priority is insufficient. Skip this update. If this is the first
15800 // skipped update, the previous update/state is the new base
15801 // update/state.
15802 var clone = {
15803 lane: updateLane,
15804 action: update.action,
15805 hasEagerState: update.hasEagerState,
15806 eagerState: update.eagerState,
15807 next: null
15808 };
15809
15810 if (newBaseQueueLast === null) {
15811 newBaseQueueFirst = newBaseQueueLast = clone;
15812 newBaseState = newState;
15813 } else {
15814 newBaseQueueLast = newBaseQueueLast.next = clone;
15815 } // Update the remaining priority in the queue.
15816 // TODO: Don't need to accumulate this. Instead, we can remove
15817 // renderLanes from the original lanes.
15818
15819
15820 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, updateLane);
15821 markSkippedUpdateLanes(updateLane);
15822 } else {
15823 // This update does have sufficient priority.
15824 if (newBaseQueueLast !== null) {
15825 var _clone = {
15826 // This update is going to be committed so we never want uncommit
15827 // it. Using NoLane works because 0 is a subset of all bitmasks, so
15828 // this will never be skipped by the check above.
15829 lane: NoLane,
15830 action: update.action,
15831 hasEagerState: update.hasEagerState,
15832 eagerState: update.eagerState,
15833 next: null
15834 };
15835 newBaseQueueLast = newBaseQueueLast.next = _clone;
15836 } // Process this update.
15837
15838
15839 if (update.hasEagerState) {
15840 // If this update is a state update (not a reducer) and was processed eagerly,
15841 // we can use the eagerly computed state
15842 newState = update.eagerState;
15843 } else {
15844 var action = update.action;
15845 newState = reducer(newState, action);
15846 }
15847 }
15848
15849 update = update.next;
15850 } while (update !== null && update !== first);
15851
15852 if (newBaseQueueLast === null) {
15853 newBaseState = newState;
15854 } else {
15855 newBaseQueueLast.next = newBaseQueueFirst;
15856 } // Mark that the fiber performed work, but only if the new state is
15857 // different from the current state.
15858
15859
15860 if (!objectIs(newState, hook.memoizedState)) {
15861 markWorkInProgressReceivedUpdate();
15862 }
15863
15864 hook.memoizedState = newState;
15865 hook.baseState = newBaseState;
15866 hook.baseQueue = newBaseQueueLast;
15867 queue.lastRenderedState = newState;
15868 } // Interleaved updates are stored on a separate queue. We aren't going to
15869 // process them during this render, but we do need to track which lanes
15870 // are remaining.
15871
15872
15873 var lastInterleaved = queue.interleaved;
15874
15875 if (lastInterleaved !== null) {
15876 var interleaved = lastInterleaved;
15877
15878 do {
15879 var interleavedLane = interleaved.lane;
15880 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, interleavedLane);
15881 markSkippedUpdateLanes(interleavedLane);
15882 interleaved = interleaved.next;
15883 } while (interleaved !== lastInterleaved);
15884 } else if (baseQueue === null) {
15885 // `queue.lanes` is used for entangling transitions. We can set it back to
15886 // zero once the queue is empty.
15887 queue.lanes = NoLanes;
15888 }
15889
15890 var dispatch = queue.dispatch;
15891 return [hook.memoizedState, dispatch];
15892 }
15893
15894 function rerenderReducer(reducer, initialArg, init) {
15895 var hook = updateWorkInProgressHook();
15896 var queue = hook.queue;
15897
15898 if (queue === null) {
15899 throw new Error('Should have a queue. This is likely a bug in React. Please file an issue.');
15900 }
15901
15902 queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous
15903 // work-in-progress hook.
15904
15905 var dispatch = queue.dispatch;
15906 var lastRenderPhaseUpdate = queue.pending;
15907 var newState = hook.memoizedState;
15908
15909 if (lastRenderPhaseUpdate !== null) {
15910 // The queue doesn't persist past this render pass.
15911 queue.pending = null;
15912 var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;
15913 var update = firstRenderPhaseUpdate;
15914
15915 do {
15916 // Process this render phase update. We don't have to check the
15917 // priority because it will always be the same as the current
15918 // render's.
15919 var action = update.action;
15920 newState = reducer(newState, action);
15921 update = update.next;
15922 } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is
15923 // different from the current state.
15924
15925
15926 if (!objectIs(newState, hook.memoizedState)) {
15927 markWorkInProgressReceivedUpdate();
15928 }
15929
15930 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to
15931 // the base state unless the queue is empty.
15932 // TODO: Not sure if this is the desired semantics, but it's what we
15933 // do for gDSFP. I can't remember why.
15934
15935 if (hook.baseQueue === null) {
15936 hook.baseState = newState;
15937 }
15938
15939 queue.lastRenderedState = newState;
15940 }
15941
15942 return [newState, dispatch];
15943 }
15944
15945 function mountMutableSource(source, getSnapshot, subscribe) {
15946 {
15947 return undefined;
15948 }
15949 }
15950
15951 function updateMutableSource(source, getSnapshot, subscribe) {
15952 {
15953 return undefined;
15954 }
15955 }
15956
15957 function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
15958 var fiber = currentlyRenderingFiber$1;
15959 var hook = mountWorkInProgressHook();
15960 var nextSnapshot;
15961 var isHydrating = getIsHydrating();
15962
15963 if (isHydrating) {
15964 if (getServerSnapshot === undefined) {
15965 throw new Error('Missing getServerSnapshot, which is required for ' + 'server-rendered content. Will revert to client rendering.');
15966 }
15967
15968 nextSnapshot = getServerSnapshot();
15969
15970 {
15971 if (!didWarnUncachedGetSnapshot) {
15972 if (nextSnapshot !== getServerSnapshot()) {
15973 error('The result of getServerSnapshot should be cached to avoid an infinite loop');
15974
15975 didWarnUncachedGetSnapshot = true;
15976 }
15977 }
15978 }
15979 } else {
15980 nextSnapshot = getSnapshot();
15981
15982 {
15983 if (!didWarnUncachedGetSnapshot) {
15984 var cachedSnapshot = getSnapshot();
15985
15986 if (!objectIs(nextSnapshot, cachedSnapshot)) {
15987 error('The result of getSnapshot should be cached to avoid an infinite loop');
15988
15989 didWarnUncachedGetSnapshot = true;
15990 }
15991 }
15992 } // Unless we're rendering a blocking lane, schedule a consistency check.
15993 // Right before committing, we will walk the tree and check if any of the
15994 // stores were mutated.
15995 //
15996 // We won't do this if we're hydrating server-rendered content, because if
15997 // the content is stale, it's already visible anyway. Instead we'll patch
15998 // it up in a passive effect.
15999
16000
16001 var root = getWorkInProgressRoot();
16002
16003 if (root === null) {
16004 throw new Error('Expected a work-in-progress root. This is a bug in React. Please file an issue.');
16005 }
16006
16007 if (!includesBlockingLane(root, renderLanes)) {
16008 pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
16009 }
16010 } // Read the current snapshot from the store on every render. This breaks the
16011 // normal rules of React, and only works because store updates are
16012 // always synchronous.
16013
16014
16015 hook.memoizedState = nextSnapshot;
16016 var inst = {
16017 value: nextSnapshot,
16018 getSnapshot: getSnapshot
16019 };
16020 hook.queue = inst; // Schedule an effect to subscribe to the store.
16021
16022 mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]); // Schedule an effect to update the mutable instance fields. We will update
16023 // this whenever subscribe, getSnapshot, or value changes. Because there's no
16024 // clean-up function, and we track the deps correctly, we can call pushEffect
16025 // directly, without storing any additional state. For the same reason, we
16026 // don't need to set a static flag, either.
16027 // TODO: We can move this to the passive phase once we add a pre-commit
16028 // consistency check. See the next comment.
16029
16030 fiber.flags |= Passive;
16031 pushEffect(HasEffect | Passive$1, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), undefined, null);
16032 return nextSnapshot;
16033 }
16034
16035 function updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
16036 var fiber = currentlyRenderingFiber$1;
16037 var hook = updateWorkInProgressHook(); // Read the current snapshot from the store on every render. This breaks the
16038 // normal rules of React, and only works because store updates are
16039 // always synchronous.
16040
16041 var nextSnapshot = getSnapshot();
16042
16043 {
16044 if (!didWarnUncachedGetSnapshot) {
16045 var cachedSnapshot = getSnapshot();
16046
16047 if (!objectIs(nextSnapshot, cachedSnapshot)) {
16048 error('The result of getSnapshot should be cached to avoid an infinite loop');
16049
16050 didWarnUncachedGetSnapshot = true;
16051 }
16052 }
16053 }
16054
16055 var prevSnapshot = hook.memoizedState;
16056 var snapshotChanged = !objectIs(prevSnapshot, nextSnapshot);
16057
16058 if (snapshotChanged) {
16059 hook.memoizedState = nextSnapshot;
16060 markWorkInProgressReceivedUpdate();
16061 }
16062
16063 var inst = hook.queue;
16064 updateEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]); // Whenever getSnapshot or subscribe changes, we need to check in the
16065 // commit phase if there was an interleaved mutation. In concurrent mode
16066 // this can happen all the time, but even in synchronous mode, an earlier
16067 // effect may have mutated the store.
16068
16069 if (inst.getSnapshot !== getSnapshot || snapshotChanged || // Check if the susbcribe function changed. We can save some memory by
16070 // checking whether we scheduled a subscription effect above.
16071 workInProgressHook !== null && workInProgressHook.memoizedState.tag & HasEffect) {
16072 fiber.flags |= Passive;
16073 pushEffect(HasEffect | Passive$1, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), undefined, null); // Unless we're rendering a blocking lane, schedule a consistency check.
16074 // Right before committing, we will walk the tree and check if any of the
16075 // stores were mutated.
16076
16077 var root = getWorkInProgressRoot();
16078
16079 if (root === null) {
16080 throw new Error('Expected a work-in-progress root. This is a bug in React. Please file an issue.');
16081 }
16082
16083 if (!includesBlockingLane(root, renderLanes)) {
16084 pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
16085 }
16086 }
16087
16088 return nextSnapshot;
16089 }
16090
16091 function pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) {
16092 fiber.flags |= StoreConsistency;
16093 var check = {
16094 getSnapshot: getSnapshot,
16095 value: renderedSnapshot
16096 };
16097 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
16098
16099 if (componentUpdateQueue === null) {
16100 componentUpdateQueue = createFunctionComponentUpdateQueue();
16101 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
16102 componentUpdateQueue.stores = [check];
16103 } else {
16104 var stores = componentUpdateQueue.stores;
16105
16106 if (stores === null) {
16107 componentUpdateQueue.stores = [check];
16108 } else {
16109 stores.push(check);
16110 }
16111 }
16112 }
16113
16114 function updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) {
16115 // These are updated in the passive phase
16116 inst.value = nextSnapshot;
16117 inst.getSnapshot = getSnapshot; // Something may have been mutated in between render and commit. This could
16118 // have been in an event that fired before the passive effects, or it could
16119 // have been in a layout effect. In that case, we would have used the old
16120 // snapsho and getSnapshot values to bail out. We need to check one more time.
16121
16122 if (checkIfSnapshotChanged(inst)) {
16123 // Force a re-render.
16124 forceStoreRerender(fiber);
16125 }
16126 }
16127
16128 function subscribeToStore(fiber, inst, subscribe) {
16129 var handleStoreChange = function () {
16130 // The store changed. Check if the snapshot changed since the last time we
16131 // read from the store.
16132 if (checkIfSnapshotChanged(inst)) {
16133 // Force a re-render.
16134 forceStoreRerender(fiber);
16135 }
16136 }; // Subscribe to the store and return a clean-up function.
16137
16138
16139 return subscribe(handleStoreChange);
16140 }
16141
16142 function checkIfSnapshotChanged(inst) {
16143 var latestGetSnapshot = inst.getSnapshot;
16144 var prevValue = inst.value;
16145
16146 try {
16147 var nextValue = latestGetSnapshot();
16148 return !objectIs(prevValue, nextValue);
16149 } catch (error) {
16150 return true;
16151 }
16152 }
16153
16154 function forceStoreRerender(fiber) {
16155 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
16156
16157 if (root !== null) {
16158 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
16159 }
16160 }
16161
16162 function mountState(initialState) {
16163 var hook = mountWorkInProgressHook();
16164
16165 if (typeof initialState === 'function') {
16166 // $FlowFixMe: Flow doesn't like mixed types
16167 initialState = initialState();
16168 }
16169
16170 hook.memoizedState = hook.baseState = initialState;
16171 var queue = {
16172 pending: null,
16173 interleaved: null,
16174 lanes: NoLanes,
16175 dispatch: null,
16176 lastRenderedReducer: basicStateReducer,
16177 lastRenderedState: initialState
16178 };
16179 hook.queue = queue;
16180 var dispatch = queue.dispatch = dispatchSetState.bind(null, currentlyRenderingFiber$1, queue);
16181 return [hook.memoizedState, dispatch];
16182 }
16183
16184 function updateState(initialState) {
16185 return updateReducer(basicStateReducer);
16186 }
16187
16188 function rerenderState(initialState) {
16189 return rerenderReducer(basicStateReducer);
16190 }
16191
16192 function pushEffect(tag, create, destroy, deps) {
16193 var effect = {
16194 tag: tag,
16195 create: create,
16196 destroy: destroy,
16197 deps: deps,
16198 // Circular
16199 next: null
16200 };
16201 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
16202
16203 if (componentUpdateQueue === null) {
16204 componentUpdateQueue = createFunctionComponentUpdateQueue();
16205 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
16206 componentUpdateQueue.lastEffect = effect.next = effect;
16207 } else {
16208 var lastEffect = componentUpdateQueue.lastEffect;
16209
16210 if (lastEffect === null) {
16211 componentUpdateQueue.lastEffect = effect.next = effect;
16212 } else {
16213 var firstEffect = lastEffect.next;
16214 lastEffect.next = effect;
16215 effect.next = firstEffect;
16216 componentUpdateQueue.lastEffect = effect;
16217 }
16218 }
16219
16220 return effect;
16221 }
16222
16223 function mountRef(initialValue) {
16224 var hook = mountWorkInProgressHook();
16225
16226 {
16227 var _ref2 = {
16228 current: initialValue
16229 };
16230 hook.memoizedState = _ref2;
16231 return _ref2;
16232 }
16233 }
16234
16235 function updateRef(initialValue) {
16236 var hook = updateWorkInProgressHook();
16237 return hook.memoizedState;
16238 }
16239
16240 function mountEffectImpl(fiberFlags, hookFlags, create, deps) {
16241 var hook = mountWorkInProgressHook();
16242 var nextDeps = deps === undefined ? null : deps;
16243 currentlyRenderingFiber$1.flags |= fiberFlags;
16244 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, undefined, nextDeps);
16245 }
16246
16247 function updateEffectImpl(fiberFlags, hookFlags, create, deps) {
16248 var hook = updateWorkInProgressHook();
16249 var nextDeps = deps === undefined ? null : deps;
16250 var destroy = undefined;
16251
16252 if (currentHook !== null) {
16253 var prevEffect = currentHook.memoizedState;
16254 destroy = prevEffect.destroy;
16255
16256 if (nextDeps !== null) {
16257 var prevDeps = prevEffect.deps;
16258
16259 if (areHookInputsEqual(nextDeps, prevDeps)) {
16260 hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps);
16261 return;
16262 }
16263 }
16264 }
16265
16266 currentlyRenderingFiber$1.flags |= fiberFlags;
16267 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, destroy, nextDeps);
16268 }
16269
16270 function mountEffect(create, deps) {
16271 if ( (currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) {
16272 return mountEffectImpl(MountPassiveDev | Passive | PassiveStatic, Passive$1, create, deps);
16273 } else {
16274 return mountEffectImpl(Passive | PassiveStatic, Passive$1, create, deps);
16275 }
16276 }
16277
16278 function updateEffect(create, deps) {
16279 return updateEffectImpl(Passive, Passive$1, create, deps);
16280 }
16281
16282 function mountInsertionEffect(create, deps) {
16283 return mountEffectImpl(Update, Insertion, create, deps);
16284 }
16285
16286 function updateInsertionEffect(create, deps) {
16287 return updateEffectImpl(Update, Insertion, create, deps);
16288 }
16289
16290 function mountLayoutEffect(create, deps) {
16291 var fiberFlags = Update;
16292
16293 {
16294 fiberFlags |= LayoutStatic;
16295 }
16296
16297 if ( (currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) {
16298 fiberFlags |= MountLayoutDev;
16299 }
16300
16301 return mountEffectImpl(fiberFlags, Layout, create, deps);
16302 }
16303
16304 function updateLayoutEffect(create, deps) {
16305 return updateEffectImpl(Update, Layout, create, deps);
16306 }
16307
16308 function imperativeHandleEffect(create, ref) {
16309 if (typeof ref === 'function') {
16310 var refCallback = ref;
16311
16312 var _inst = create();
16313
16314 refCallback(_inst);
16315 return function () {
16316 refCallback(null);
16317 };
16318 } else if (ref !== null && ref !== undefined) {
16319 var refObject = ref;
16320
16321 {
16322 if (!refObject.hasOwnProperty('current')) {
16323 error('Expected useImperativeHandle() first argument to either be a ' + 'ref callback or React.createRef() object. Instead received: %s.', 'an object with keys {' + Object.keys(refObject).join(', ') + '}');
16324 }
16325 }
16326
16327 var _inst2 = create();
16328
16329 refObject.current = _inst2;
16330 return function () {
16331 refObject.current = null;
16332 };
16333 }
16334 }
16335
16336 function mountImperativeHandle(ref, create, deps) {
16337 {
16338 if (typeof create !== 'function') {
16339 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
16340 }
16341 } // TODO: If deps are provided, should we skip comparing the ref itself?
16342
16343
16344 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
16345 var fiberFlags = Update;
16346
16347 {
16348 fiberFlags |= LayoutStatic;
16349 }
16350
16351 if ( (currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) {
16352 fiberFlags |= MountLayoutDev;
16353 }
16354
16355 return mountEffectImpl(fiberFlags, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
16356 }
16357
16358 function updateImperativeHandle(ref, create, deps) {
16359 {
16360 if (typeof create !== 'function') {
16361 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
16362 }
16363 } // TODO: If deps are provided, should we skip comparing the ref itself?
16364
16365
16366 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
16367 return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
16368 }
16369
16370 function mountDebugValue(value, formatterFn) {// This hook is normally a no-op.
16371 // The react-debug-hooks package injects its own implementation
16372 // so that e.g. DevTools can display custom hook values.
16373 }
16374
16375 var updateDebugValue = mountDebugValue;
16376
16377 function mountCallback(callback, deps) {
16378 var hook = mountWorkInProgressHook();
16379 var nextDeps = deps === undefined ? null : deps;
16380 hook.memoizedState = [callback, nextDeps];
16381 return callback;
16382 }
16383
16384 function updateCallback(callback, deps) {
16385 var hook = updateWorkInProgressHook();
16386 var nextDeps = deps === undefined ? null : deps;
16387 var prevState = hook.memoizedState;
16388
16389 if (prevState !== null) {
16390 if (nextDeps !== null) {
16391 var prevDeps = prevState[1];
16392
16393 if (areHookInputsEqual(nextDeps, prevDeps)) {
16394 return prevState[0];
16395 }
16396 }
16397 }
16398
16399 hook.memoizedState = [callback, nextDeps];
16400 return callback;
16401 }
16402
16403 function mountMemo(nextCreate, deps) {
16404 var hook = mountWorkInProgressHook();
16405 var nextDeps = deps === undefined ? null : deps;
16406 var nextValue = nextCreate();
16407 hook.memoizedState = [nextValue, nextDeps];
16408 return nextValue;
16409 }
16410
16411 function updateMemo(nextCreate, deps) {
16412 var hook = updateWorkInProgressHook();
16413 var nextDeps = deps === undefined ? null : deps;
16414 var prevState = hook.memoizedState;
16415
16416 if (prevState !== null) {
16417 // Assume these are defined. If they're not, areHookInputsEqual will warn.
16418 if (nextDeps !== null) {
16419 var prevDeps = prevState[1];
16420
16421 if (areHookInputsEqual(nextDeps, prevDeps)) {
16422 return prevState[0];
16423 }
16424 }
16425 }
16426
16427 var nextValue = nextCreate();
16428 hook.memoizedState = [nextValue, nextDeps];
16429 return nextValue;
16430 }
16431
16432 function mountDeferredValue(value) {
16433 var hook = mountWorkInProgressHook();
16434 hook.memoizedState = value;
16435 return value;
16436 }
16437
16438 function updateDeferredValue(value) {
16439 var hook = updateWorkInProgressHook();
16440 var resolvedCurrentHook = currentHook;
16441 var prevValue = resolvedCurrentHook.memoizedState;
16442 return updateDeferredValueImpl(hook, prevValue, value);
16443 }
16444
16445 function rerenderDeferredValue(value) {
16446 var hook = updateWorkInProgressHook();
16447
16448 if (currentHook === null) {
16449 // This is a rerender during a mount.
16450 hook.memoizedState = value;
16451 return value;
16452 } else {
16453 // This is a rerender during an update.
16454 var prevValue = currentHook.memoizedState;
16455 return updateDeferredValueImpl(hook, prevValue, value);
16456 }
16457 }
16458
16459 function updateDeferredValueImpl(hook, prevValue, value) {
16460 var shouldDeferValue = !includesOnlyNonUrgentLanes(renderLanes);
16461
16462 if (shouldDeferValue) {
16463 // This is an urgent update. If the value has changed, keep using the
16464 // previous value and spawn a deferred render to update it later.
16465 if (!objectIs(value, prevValue)) {
16466 // Schedule a deferred render
16467 var deferredLane = claimNextTransitionLane();
16468 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, deferredLane);
16469 markSkippedUpdateLanes(deferredLane); // Set this to true to indicate that the rendered value is inconsistent
16470 // from the latest value. The name "baseState" doesn't really match how we
16471 // use it because we're reusing a state hook field instead of creating a
16472 // new one.
16473
16474 hook.baseState = true;
16475 } // Reuse the previous value
16476
16477
16478 return prevValue;
16479 } else {
16480 // This is not an urgent update, so we can use the latest value regardless
16481 // of what it is. No need to defer it.
16482 // However, if we're currently inside a spawned render, then we need to mark
16483 // this as an update to prevent the fiber from bailing out.
16484 //
16485 // `baseState` is true when the current value is different from the rendered
16486 // value. The name doesn't really match how we use it because we're reusing
16487 // a state hook field instead of creating a new one.
16488 if (hook.baseState) {
16489 // Flip this back to false.
16490 hook.baseState = false;
16491 markWorkInProgressReceivedUpdate();
16492 }
16493
16494 hook.memoizedState = value;
16495 return value;
16496 }
16497 }
16498
16499 function startTransition(setPending, callback, options) {
16500 var previousPriority = getCurrentUpdatePriority();
16501 setCurrentUpdatePriority(higherEventPriority(previousPriority, ContinuousEventPriority));
16502 setPending(true);
16503 var prevTransition = ReactCurrentBatchConfig$2.transition;
16504 ReactCurrentBatchConfig$2.transition = {};
16505 var currentTransition = ReactCurrentBatchConfig$2.transition;
16506
16507 {
16508 ReactCurrentBatchConfig$2.transition._updatedFibers = new Set();
16509 }
16510
16511 try {
16512 setPending(false);
16513 callback();
16514 } finally {
16515 setCurrentUpdatePriority(previousPriority);
16516 ReactCurrentBatchConfig$2.transition = prevTransition;
16517
16518 {
16519 if (prevTransition === null && currentTransition._updatedFibers) {
16520 var updatedFibersCount = currentTransition._updatedFibers.size;
16521
16522 if (updatedFibersCount > 10) {
16523 warn('Detected a large number of updates inside startTransition. ' + 'If this is due to a subscription please re-write it to use React provided hooks. ' + 'Otherwise concurrent mode guarantees are off the table.');
16524 }
16525
16526 currentTransition._updatedFibers.clear();
16527 }
16528 }
16529 }
16530 }
16531
16532 function mountTransition() {
16533 var _mountState = mountState(false),
16534 isPending = _mountState[0],
16535 setPending = _mountState[1]; // The `start` method never changes.
16536
16537
16538 var start = startTransition.bind(null, setPending);
16539 var hook = mountWorkInProgressHook();
16540 hook.memoizedState = start;
16541 return [isPending, start];
16542 }
16543
16544 function updateTransition() {
16545 var _updateState = updateState(),
16546 isPending = _updateState[0];
16547
16548 var hook = updateWorkInProgressHook();
16549 var start = hook.memoizedState;
16550 return [isPending, start];
16551 }
16552
16553 function rerenderTransition() {
16554 var _rerenderState = rerenderState(),
16555 isPending = _rerenderState[0];
16556
16557 var hook = updateWorkInProgressHook();
16558 var start = hook.memoizedState;
16559 return [isPending, start];
16560 }
16561
16562 var isUpdatingOpaqueValueInRenderPhase = false;
16563 function getIsUpdatingOpaqueValueInRenderPhaseInDEV() {
16564 {
16565 return isUpdatingOpaqueValueInRenderPhase;
16566 }
16567 }
16568
16569 function mountId() {
16570 var hook = mountWorkInProgressHook();
16571 var root = getWorkInProgressRoot(); // TODO: In Fizz, id generation is specific to each server config. Maybe we
16572 // should do this in Fiber, too? Deferring this decision for now because
16573 // there's no other place to store the prefix except for an internal field on
16574 // the public createRoot object, which the fiber tree does not currently have
16575 // a reference to.
16576
16577 var identifierPrefix = root.identifierPrefix;
16578 var id;
16579
16580 if (getIsHydrating()) {
16581 var treeId = getTreeId(); // Use a captial R prefix for server-generated ids.
16582
16583 id = ':' + identifierPrefix + 'R' + treeId; // Unless this is the first id at this level, append a number at the end
16584 // that represents the position of this useId hook among all the useId
16585 // hooks for this fiber.
16586
16587 var localId = localIdCounter++;
16588
16589 if (localId > 0) {
16590 id += 'H' + localId.toString(32);
16591 }
16592
16593 id += ':';
16594 } else {
16595 // Use a lowercase r prefix for client-generated ids.
16596 var globalClientId = globalClientIdCounter++;
16597 id = ':' + identifierPrefix + 'r' + globalClientId.toString(32) + ':';
16598 }
16599
16600 hook.memoizedState = id;
16601 return id;
16602 }
16603
16604 function updateId() {
16605 var hook = updateWorkInProgressHook();
16606 var id = hook.memoizedState;
16607 return id;
16608 }
16609
16610 function dispatchReducerAction(fiber, queue, action) {
16611 {
16612 if (typeof arguments[3] === 'function') {
16613 error("State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().');
16614 }
16615 }
16616
16617 var lane = requestUpdateLane(fiber);
16618 var update = {
16619 lane: lane,
16620 action: action,
16621 hasEagerState: false,
16622 eagerState: null,
16623 next: null
16624 };
16625
16626 if (isRenderPhaseUpdate(fiber)) {
16627 enqueueRenderPhaseUpdate(queue, update);
16628 } else {
16629 var root = enqueueConcurrentHookUpdate(fiber, queue, update, lane);
16630
16631 if (root !== null) {
16632 var eventTime = requestEventTime();
16633 scheduleUpdateOnFiber(root, fiber, lane, eventTime);
16634 entangleTransitionUpdate(root, queue, lane);
16635 }
16636 }
16637
16638 markUpdateInDevTools(fiber, lane);
16639 }
16640
16641 function dispatchSetState(fiber, queue, action) {
16642 {
16643 if (typeof arguments[3] === 'function') {
16644 error("State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().');
16645 }
16646 }
16647
16648 var lane = requestUpdateLane(fiber);
16649 var update = {
16650 lane: lane,
16651 action: action,
16652 hasEagerState: false,
16653 eagerState: null,
16654 next: null
16655 };
16656
16657 if (isRenderPhaseUpdate(fiber)) {
16658 enqueueRenderPhaseUpdate(queue, update);
16659 } else {
16660 var alternate = fiber.alternate;
16661
16662 if (fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes)) {
16663 // The queue is currently empty, which means we can eagerly compute the
16664 // next state before entering the render phase. If the new state is the
16665 // same as the current state, we may be able to bail out entirely.
16666 var lastRenderedReducer = queue.lastRenderedReducer;
16667
16668 if (lastRenderedReducer !== null) {
16669 var prevDispatcher;
16670
16671 {
16672 prevDispatcher = ReactCurrentDispatcher$1.current;
16673 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16674 }
16675
16676 try {
16677 var currentState = queue.lastRenderedState;
16678 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute
16679 // it, on the update object. If the reducer hasn't changed by the
16680 // time we enter the render phase, then the eager state can be used
16681 // without calling the reducer again.
16682
16683 update.hasEagerState = true;
16684 update.eagerState = eagerState;
16685
16686 if (objectIs(eagerState, currentState)) {
16687 // Fast path. We can bail out without scheduling React to re-render.
16688 // It's still possible that we'll need to rebase this update later,
16689 // if the component re-renders for a different reason and by that
16690 // time the reducer has changed.
16691 // TODO: Do we still need to entangle transitions in this case?
16692 enqueueConcurrentHookUpdateAndEagerlyBailout(fiber, queue, update, lane);
16693 return;
16694 }
16695 } catch (error) {// Suppress the error. It will throw again in the render phase.
16696 } finally {
16697 {
16698 ReactCurrentDispatcher$1.current = prevDispatcher;
16699 }
16700 }
16701 }
16702 }
16703
16704 var root = enqueueConcurrentHookUpdate(fiber, queue, update, lane);
16705
16706 if (root !== null) {
16707 var eventTime = requestEventTime();
16708 scheduleUpdateOnFiber(root, fiber, lane, eventTime);
16709 entangleTransitionUpdate(root, queue, lane);
16710 }
16711 }
16712
16713 markUpdateInDevTools(fiber, lane);
16714 }
16715
16716 function isRenderPhaseUpdate(fiber) {
16717 var alternate = fiber.alternate;
16718 return fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1;
16719 }
16720
16721 function enqueueRenderPhaseUpdate(queue, update) {
16722 // This is a render phase update. Stash it in a lazily-created map of
16723 // queue -> linked list of updates. After this render pass, we'll restart
16724 // and apply the stashed updates on top of the work-in-progress hook.
16725 didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true;
16726 var pending = queue.pending;
16727
16728 if (pending === null) {
16729 // This is the first update. Create a circular list.
16730 update.next = update;
16731 } else {
16732 update.next = pending.next;
16733 pending.next = update;
16734 }
16735
16736 queue.pending = update;
16737 } // TODO: Move to ReactFiberConcurrentUpdates?
16738
16739
16740 function entangleTransitionUpdate(root, queue, lane) {
16741 if (isTransitionLane(lane)) {
16742 var queueLanes = queue.lanes; // If any entangled lanes are no longer pending on the root, then they
16743 // must have finished. We can remove them from the shared queue, which
16744 // represents a superset of the actually pending lanes. In some cases we
16745 // may entangle more than we need to, but that's OK. In fact it's worse if
16746 // we *don't* entangle when we should.
16747
16748 queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes.
16749
16750 var newQueueLanes = mergeLanes(queueLanes, lane);
16751 queue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if
16752 // the lane finished since the last time we entangled it. So we need to
16753 // entangle it again, just to be sure.
16754
16755 markRootEntangled(root, newQueueLanes);
16756 }
16757 }
16758
16759 function markUpdateInDevTools(fiber, lane, action) {
16760
16761 {
16762 markStateUpdateScheduled(fiber, lane);
16763 }
16764 }
16765
16766 var ContextOnlyDispatcher = {
16767 readContext: readContext,
16768 useCallback: throwInvalidHookError,
16769 useContext: throwInvalidHookError,
16770 useEffect: throwInvalidHookError,
16771 useImperativeHandle: throwInvalidHookError,
16772 useInsertionEffect: throwInvalidHookError,
16773 useLayoutEffect: throwInvalidHookError,
16774 useMemo: throwInvalidHookError,
16775 useReducer: throwInvalidHookError,
16776 useRef: throwInvalidHookError,
16777 useState: throwInvalidHookError,
16778 useDebugValue: throwInvalidHookError,
16779 useDeferredValue: throwInvalidHookError,
16780 useTransition: throwInvalidHookError,
16781 useMutableSource: throwInvalidHookError,
16782 useSyncExternalStore: throwInvalidHookError,
16783 useId: throwInvalidHookError,
16784 unstable_isNewReconciler: enableNewReconciler
16785 };
16786
16787 var HooksDispatcherOnMountInDEV = null;
16788 var HooksDispatcherOnMountWithHookTypesInDEV = null;
16789 var HooksDispatcherOnUpdateInDEV = null;
16790 var HooksDispatcherOnRerenderInDEV = null;
16791 var InvalidNestedHooksDispatcherOnMountInDEV = null;
16792 var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
16793 var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
16794
16795 {
16796 var warnInvalidContextAccess = function () {
16797 error('Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().');
16798 };
16799
16800 var warnInvalidHookAccess = function () {
16801 error('Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' + 'You can only call Hooks at the top level of your React function. ' + 'For more information, see ' + 'https://reactjs.org/link/rules-of-hooks');
16802 };
16803
16804 HooksDispatcherOnMountInDEV = {
16805 readContext: function (context) {
16806 return readContext(context);
16807 },
16808 useCallback: function (callback, deps) {
16809 currentHookNameInDev = 'useCallback';
16810 mountHookTypesDev();
16811 checkDepsAreArrayDev(deps);
16812 return mountCallback(callback, deps);
16813 },
16814 useContext: function (context) {
16815 currentHookNameInDev = 'useContext';
16816 mountHookTypesDev();
16817 return readContext(context);
16818 },
16819 useEffect: function (create, deps) {
16820 currentHookNameInDev = 'useEffect';
16821 mountHookTypesDev();
16822 checkDepsAreArrayDev(deps);
16823 return mountEffect(create, deps);
16824 },
16825 useImperativeHandle: function (ref, create, deps) {
16826 currentHookNameInDev = 'useImperativeHandle';
16827 mountHookTypesDev();
16828 checkDepsAreArrayDev(deps);
16829 return mountImperativeHandle(ref, create, deps);
16830 },
16831 useInsertionEffect: function (create, deps) {
16832 currentHookNameInDev = 'useInsertionEffect';
16833 mountHookTypesDev();
16834 checkDepsAreArrayDev(deps);
16835 return mountInsertionEffect(create, deps);
16836 },
16837 useLayoutEffect: function (create, deps) {
16838 currentHookNameInDev = 'useLayoutEffect';
16839 mountHookTypesDev();
16840 checkDepsAreArrayDev(deps);
16841 return mountLayoutEffect(create, deps);
16842 },
16843 useMemo: function (create, deps) {
16844 currentHookNameInDev = 'useMemo';
16845 mountHookTypesDev();
16846 checkDepsAreArrayDev(deps);
16847 var prevDispatcher = ReactCurrentDispatcher$1.current;
16848 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16849
16850 try {
16851 return mountMemo(create, deps);
16852 } finally {
16853 ReactCurrentDispatcher$1.current = prevDispatcher;
16854 }
16855 },
16856 useReducer: function (reducer, initialArg, init) {
16857 currentHookNameInDev = 'useReducer';
16858 mountHookTypesDev();
16859 var prevDispatcher = ReactCurrentDispatcher$1.current;
16860 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16861
16862 try {
16863 return mountReducer(reducer, initialArg, init);
16864 } finally {
16865 ReactCurrentDispatcher$1.current = prevDispatcher;
16866 }
16867 },
16868 useRef: function (initialValue) {
16869 currentHookNameInDev = 'useRef';
16870 mountHookTypesDev();
16871 return mountRef(initialValue);
16872 },
16873 useState: function (initialState) {
16874 currentHookNameInDev = 'useState';
16875 mountHookTypesDev();
16876 var prevDispatcher = ReactCurrentDispatcher$1.current;
16877 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16878
16879 try {
16880 return mountState(initialState);
16881 } finally {
16882 ReactCurrentDispatcher$1.current = prevDispatcher;
16883 }
16884 },
16885 useDebugValue: function (value, formatterFn) {
16886 currentHookNameInDev = 'useDebugValue';
16887 mountHookTypesDev();
16888 return mountDebugValue();
16889 },
16890 useDeferredValue: function (value) {
16891 currentHookNameInDev = 'useDeferredValue';
16892 mountHookTypesDev();
16893 return mountDeferredValue(value);
16894 },
16895 useTransition: function () {
16896 currentHookNameInDev = 'useTransition';
16897 mountHookTypesDev();
16898 return mountTransition();
16899 },
16900 useMutableSource: function (source, getSnapshot, subscribe) {
16901 currentHookNameInDev = 'useMutableSource';
16902 mountHookTypesDev();
16903 return mountMutableSource();
16904 },
16905 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
16906 currentHookNameInDev = 'useSyncExternalStore';
16907 mountHookTypesDev();
16908 return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
16909 },
16910 useId: function () {
16911 currentHookNameInDev = 'useId';
16912 mountHookTypesDev();
16913 return mountId();
16914 },
16915 unstable_isNewReconciler: enableNewReconciler
16916 };
16917
16918 HooksDispatcherOnMountWithHookTypesInDEV = {
16919 readContext: function (context) {
16920 return readContext(context);
16921 },
16922 useCallback: function (callback, deps) {
16923 currentHookNameInDev = 'useCallback';
16924 updateHookTypesDev();
16925 return mountCallback(callback, deps);
16926 },
16927 useContext: function (context) {
16928 currentHookNameInDev = 'useContext';
16929 updateHookTypesDev();
16930 return readContext(context);
16931 },
16932 useEffect: function (create, deps) {
16933 currentHookNameInDev = 'useEffect';
16934 updateHookTypesDev();
16935 return mountEffect(create, deps);
16936 },
16937 useImperativeHandle: function (ref, create, deps) {
16938 currentHookNameInDev = 'useImperativeHandle';
16939 updateHookTypesDev();
16940 return mountImperativeHandle(ref, create, deps);
16941 },
16942 useInsertionEffect: function (create, deps) {
16943 currentHookNameInDev = 'useInsertionEffect';
16944 updateHookTypesDev();
16945 return mountInsertionEffect(create, deps);
16946 },
16947 useLayoutEffect: function (create, deps) {
16948 currentHookNameInDev = 'useLayoutEffect';
16949 updateHookTypesDev();
16950 return mountLayoutEffect(create, deps);
16951 },
16952 useMemo: function (create, deps) {
16953 currentHookNameInDev = 'useMemo';
16954 updateHookTypesDev();
16955 var prevDispatcher = ReactCurrentDispatcher$1.current;
16956 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16957
16958 try {
16959 return mountMemo(create, deps);
16960 } finally {
16961 ReactCurrentDispatcher$1.current = prevDispatcher;
16962 }
16963 },
16964 useReducer: function (reducer, initialArg, init) {
16965 currentHookNameInDev = 'useReducer';
16966 updateHookTypesDev();
16967 var prevDispatcher = ReactCurrentDispatcher$1.current;
16968 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16969
16970 try {
16971 return mountReducer(reducer, initialArg, init);
16972 } finally {
16973 ReactCurrentDispatcher$1.current = prevDispatcher;
16974 }
16975 },
16976 useRef: function (initialValue) {
16977 currentHookNameInDev = 'useRef';
16978 updateHookTypesDev();
16979 return mountRef(initialValue);
16980 },
16981 useState: function (initialState) {
16982 currentHookNameInDev = 'useState';
16983 updateHookTypesDev();
16984 var prevDispatcher = ReactCurrentDispatcher$1.current;
16985 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16986
16987 try {
16988 return mountState(initialState);
16989 } finally {
16990 ReactCurrentDispatcher$1.current = prevDispatcher;
16991 }
16992 },
16993 useDebugValue: function (value, formatterFn) {
16994 currentHookNameInDev = 'useDebugValue';
16995 updateHookTypesDev();
16996 return mountDebugValue();
16997 },
16998 useDeferredValue: function (value) {
16999 currentHookNameInDev = 'useDeferredValue';
17000 updateHookTypesDev();
17001 return mountDeferredValue(value);
17002 },
17003 useTransition: function () {
17004 currentHookNameInDev = 'useTransition';
17005 updateHookTypesDev();
17006 return mountTransition();
17007 },
17008 useMutableSource: function (source, getSnapshot, subscribe) {
17009 currentHookNameInDev = 'useMutableSource';
17010 updateHookTypesDev();
17011 return mountMutableSource();
17012 },
17013 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
17014 currentHookNameInDev = 'useSyncExternalStore';
17015 updateHookTypesDev();
17016 return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
17017 },
17018 useId: function () {
17019 currentHookNameInDev = 'useId';
17020 updateHookTypesDev();
17021 return mountId();
17022 },
17023 unstable_isNewReconciler: enableNewReconciler
17024 };
17025
17026 HooksDispatcherOnUpdateInDEV = {
17027 readContext: function (context) {
17028 return readContext(context);
17029 },
17030 useCallback: function (callback, deps) {
17031 currentHookNameInDev = 'useCallback';
17032 updateHookTypesDev();
17033 return updateCallback(callback, deps);
17034 },
17035 useContext: function (context) {
17036 currentHookNameInDev = 'useContext';
17037 updateHookTypesDev();
17038 return readContext(context);
17039 },
17040 useEffect: function (create, deps) {
17041 currentHookNameInDev = 'useEffect';
17042 updateHookTypesDev();
17043 return updateEffect(create, deps);
17044 },
17045 useImperativeHandle: function (ref, create, deps) {
17046 currentHookNameInDev = 'useImperativeHandle';
17047 updateHookTypesDev();
17048 return updateImperativeHandle(ref, create, deps);
17049 },
17050 useInsertionEffect: function (create, deps) {
17051 currentHookNameInDev = 'useInsertionEffect';
17052 updateHookTypesDev();
17053 return updateInsertionEffect(create, deps);
17054 },
17055 useLayoutEffect: function (create, deps) {
17056 currentHookNameInDev = 'useLayoutEffect';
17057 updateHookTypesDev();
17058 return updateLayoutEffect(create, deps);
17059 },
17060 useMemo: function (create, deps) {
17061 currentHookNameInDev = 'useMemo';
17062 updateHookTypesDev();
17063 var prevDispatcher = ReactCurrentDispatcher$1.current;
17064 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17065
17066 try {
17067 return updateMemo(create, deps);
17068 } finally {
17069 ReactCurrentDispatcher$1.current = prevDispatcher;
17070 }
17071 },
17072 useReducer: function (reducer, initialArg, init) {
17073 currentHookNameInDev = 'useReducer';
17074 updateHookTypesDev();
17075 var prevDispatcher = ReactCurrentDispatcher$1.current;
17076 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17077
17078 try {
17079 return updateReducer(reducer, initialArg, init);
17080 } finally {
17081 ReactCurrentDispatcher$1.current = prevDispatcher;
17082 }
17083 },
17084 useRef: function (initialValue) {
17085 currentHookNameInDev = 'useRef';
17086 updateHookTypesDev();
17087 return updateRef();
17088 },
17089 useState: function (initialState) {
17090 currentHookNameInDev = 'useState';
17091 updateHookTypesDev();
17092 var prevDispatcher = ReactCurrentDispatcher$1.current;
17093 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17094
17095 try {
17096 return updateState(initialState);
17097 } finally {
17098 ReactCurrentDispatcher$1.current = prevDispatcher;
17099 }
17100 },
17101 useDebugValue: function (value, formatterFn) {
17102 currentHookNameInDev = 'useDebugValue';
17103 updateHookTypesDev();
17104 return updateDebugValue();
17105 },
17106 useDeferredValue: function (value) {
17107 currentHookNameInDev = 'useDeferredValue';
17108 updateHookTypesDev();
17109 return updateDeferredValue(value);
17110 },
17111 useTransition: function () {
17112 currentHookNameInDev = 'useTransition';
17113 updateHookTypesDev();
17114 return updateTransition();
17115 },
17116 useMutableSource: function (source, getSnapshot, subscribe) {
17117 currentHookNameInDev = 'useMutableSource';
17118 updateHookTypesDev();
17119 return updateMutableSource();
17120 },
17121 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
17122 currentHookNameInDev = 'useSyncExternalStore';
17123 updateHookTypesDev();
17124 return updateSyncExternalStore(subscribe, getSnapshot);
17125 },
17126 useId: function () {
17127 currentHookNameInDev = 'useId';
17128 updateHookTypesDev();
17129 return updateId();
17130 },
17131 unstable_isNewReconciler: enableNewReconciler
17132 };
17133
17134 HooksDispatcherOnRerenderInDEV = {
17135 readContext: function (context) {
17136 return readContext(context);
17137 },
17138 useCallback: function (callback, deps) {
17139 currentHookNameInDev = 'useCallback';
17140 updateHookTypesDev();
17141 return updateCallback(callback, deps);
17142 },
17143 useContext: function (context) {
17144 currentHookNameInDev = 'useContext';
17145 updateHookTypesDev();
17146 return readContext(context);
17147 },
17148 useEffect: function (create, deps) {
17149 currentHookNameInDev = 'useEffect';
17150 updateHookTypesDev();
17151 return updateEffect(create, deps);
17152 },
17153 useImperativeHandle: function (ref, create, deps) {
17154 currentHookNameInDev = 'useImperativeHandle';
17155 updateHookTypesDev();
17156 return updateImperativeHandle(ref, create, deps);
17157 },
17158 useInsertionEffect: function (create, deps) {
17159 currentHookNameInDev = 'useInsertionEffect';
17160 updateHookTypesDev();
17161 return updateInsertionEffect(create, deps);
17162 },
17163 useLayoutEffect: function (create, deps) {
17164 currentHookNameInDev = 'useLayoutEffect';
17165 updateHookTypesDev();
17166 return updateLayoutEffect(create, deps);
17167 },
17168 useMemo: function (create, deps) {
17169 currentHookNameInDev = 'useMemo';
17170 updateHookTypesDev();
17171 var prevDispatcher = ReactCurrentDispatcher$1.current;
17172 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
17173
17174 try {
17175 return updateMemo(create, deps);
17176 } finally {
17177 ReactCurrentDispatcher$1.current = prevDispatcher;
17178 }
17179 },
17180 useReducer: function (reducer, initialArg, init) {
17181 currentHookNameInDev = 'useReducer';
17182 updateHookTypesDev();
17183 var prevDispatcher = ReactCurrentDispatcher$1.current;
17184 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
17185
17186 try {
17187 return rerenderReducer(reducer, initialArg, init);
17188 } finally {
17189 ReactCurrentDispatcher$1.current = prevDispatcher;
17190 }
17191 },
17192 useRef: function (initialValue) {
17193 currentHookNameInDev = 'useRef';
17194 updateHookTypesDev();
17195 return updateRef();
17196 },
17197 useState: function (initialState) {
17198 currentHookNameInDev = 'useState';
17199 updateHookTypesDev();
17200 var prevDispatcher = ReactCurrentDispatcher$1.current;
17201 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
17202
17203 try {
17204 return rerenderState(initialState);
17205 } finally {
17206 ReactCurrentDispatcher$1.current = prevDispatcher;
17207 }
17208 },
17209 useDebugValue: function (value, formatterFn) {
17210 currentHookNameInDev = 'useDebugValue';
17211 updateHookTypesDev();
17212 return updateDebugValue();
17213 },
17214 useDeferredValue: function (value) {
17215 currentHookNameInDev = 'useDeferredValue';
17216 updateHookTypesDev();
17217 return rerenderDeferredValue(value);
17218 },
17219 useTransition: function () {
17220 currentHookNameInDev = 'useTransition';
17221 updateHookTypesDev();
17222 return rerenderTransition();
17223 },
17224 useMutableSource: function (source, getSnapshot, subscribe) {
17225 currentHookNameInDev = 'useMutableSource';
17226 updateHookTypesDev();
17227 return updateMutableSource();
17228 },
17229 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
17230 currentHookNameInDev = 'useSyncExternalStore';
17231 updateHookTypesDev();
17232 return updateSyncExternalStore(subscribe, getSnapshot);
17233 },
17234 useId: function () {
17235 currentHookNameInDev = 'useId';
17236 updateHookTypesDev();
17237 return updateId();
17238 },
17239 unstable_isNewReconciler: enableNewReconciler
17240 };
17241
17242 InvalidNestedHooksDispatcherOnMountInDEV = {
17243 readContext: function (context) {
17244 warnInvalidContextAccess();
17245 return readContext(context);
17246 },
17247 useCallback: function (callback, deps) {
17248 currentHookNameInDev = 'useCallback';
17249 warnInvalidHookAccess();
17250 mountHookTypesDev();
17251 return mountCallback(callback, deps);
17252 },
17253 useContext: function (context) {
17254 currentHookNameInDev = 'useContext';
17255 warnInvalidHookAccess();
17256 mountHookTypesDev();
17257 return readContext(context);
17258 },
17259 useEffect: function (create, deps) {
17260 currentHookNameInDev = 'useEffect';
17261 warnInvalidHookAccess();
17262 mountHookTypesDev();
17263 return mountEffect(create, deps);
17264 },
17265 useImperativeHandle: function (ref, create, deps) {
17266 currentHookNameInDev = 'useImperativeHandle';
17267 warnInvalidHookAccess();
17268 mountHookTypesDev();
17269 return mountImperativeHandle(ref, create, deps);
17270 },
17271 useInsertionEffect: function (create, deps) {
17272 currentHookNameInDev = 'useInsertionEffect';
17273 warnInvalidHookAccess();
17274 mountHookTypesDev();
17275 return mountInsertionEffect(create, deps);
17276 },
17277 useLayoutEffect: function (create, deps) {
17278 currentHookNameInDev = 'useLayoutEffect';
17279 warnInvalidHookAccess();
17280 mountHookTypesDev();
17281 return mountLayoutEffect(create, deps);
17282 },
17283 useMemo: function (create, deps) {
17284 currentHookNameInDev = 'useMemo';
17285 warnInvalidHookAccess();
17286 mountHookTypesDev();
17287 var prevDispatcher = ReactCurrentDispatcher$1.current;
17288 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17289
17290 try {
17291 return mountMemo(create, deps);
17292 } finally {
17293 ReactCurrentDispatcher$1.current = prevDispatcher;
17294 }
17295 },
17296 useReducer: function (reducer, initialArg, init) {
17297 currentHookNameInDev = 'useReducer';
17298 warnInvalidHookAccess();
17299 mountHookTypesDev();
17300 var prevDispatcher = ReactCurrentDispatcher$1.current;
17301 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17302
17303 try {
17304 return mountReducer(reducer, initialArg, init);
17305 } finally {
17306 ReactCurrentDispatcher$1.current = prevDispatcher;
17307 }
17308 },
17309 useRef: function (initialValue) {
17310 currentHookNameInDev = 'useRef';
17311 warnInvalidHookAccess();
17312 mountHookTypesDev();
17313 return mountRef(initialValue);
17314 },
17315 useState: function (initialState) {
17316 currentHookNameInDev = 'useState';
17317 warnInvalidHookAccess();
17318 mountHookTypesDev();
17319 var prevDispatcher = ReactCurrentDispatcher$1.current;
17320 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17321
17322 try {
17323 return mountState(initialState);
17324 } finally {
17325 ReactCurrentDispatcher$1.current = prevDispatcher;
17326 }
17327 },
17328 useDebugValue: function (value, formatterFn) {
17329 currentHookNameInDev = 'useDebugValue';
17330 warnInvalidHookAccess();
17331 mountHookTypesDev();
17332 return mountDebugValue();
17333 },
17334 useDeferredValue: function (value) {
17335 currentHookNameInDev = 'useDeferredValue';
17336 warnInvalidHookAccess();
17337 mountHookTypesDev();
17338 return mountDeferredValue(value);
17339 },
17340 useTransition: function () {
17341 currentHookNameInDev = 'useTransition';
17342 warnInvalidHookAccess();
17343 mountHookTypesDev();
17344 return mountTransition();
17345 },
17346 useMutableSource: function (source, getSnapshot, subscribe) {
17347 currentHookNameInDev = 'useMutableSource';
17348 warnInvalidHookAccess();
17349 mountHookTypesDev();
17350 return mountMutableSource();
17351 },
17352 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
17353 currentHookNameInDev = 'useSyncExternalStore';
17354 warnInvalidHookAccess();
17355 mountHookTypesDev();
17356 return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
17357 },
17358 useId: function () {
17359 currentHookNameInDev = 'useId';
17360 warnInvalidHookAccess();
17361 mountHookTypesDev();
17362 return mountId();
17363 },
17364 unstable_isNewReconciler: enableNewReconciler
17365 };
17366
17367 InvalidNestedHooksDispatcherOnUpdateInDEV = {
17368 readContext: function (context) {
17369 warnInvalidContextAccess();
17370 return readContext(context);
17371 },
17372 useCallback: function (callback, deps) {
17373 currentHookNameInDev = 'useCallback';
17374 warnInvalidHookAccess();
17375 updateHookTypesDev();
17376 return updateCallback(callback, deps);
17377 },
17378 useContext: function (context) {
17379 currentHookNameInDev = 'useContext';
17380 warnInvalidHookAccess();
17381 updateHookTypesDev();
17382 return readContext(context);
17383 },
17384 useEffect: function (create, deps) {
17385 currentHookNameInDev = 'useEffect';
17386 warnInvalidHookAccess();
17387 updateHookTypesDev();
17388 return updateEffect(create, deps);
17389 },
17390 useImperativeHandle: function (ref, create, deps) {
17391 currentHookNameInDev = 'useImperativeHandle';
17392 warnInvalidHookAccess();
17393 updateHookTypesDev();
17394 return updateImperativeHandle(ref, create, deps);
17395 },
17396 useInsertionEffect: function (create, deps) {
17397 currentHookNameInDev = 'useInsertionEffect';
17398 warnInvalidHookAccess();
17399 updateHookTypesDev();
17400 return updateInsertionEffect(create, deps);
17401 },
17402 useLayoutEffect: function (create, deps) {
17403 currentHookNameInDev = 'useLayoutEffect';
17404 warnInvalidHookAccess();
17405 updateHookTypesDev();
17406 return updateLayoutEffect(create, deps);
17407 },
17408 useMemo: function (create, deps) {
17409 currentHookNameInDev = 'useMemo';
17410 warnInvalidHookAccess();
17411 updateHookTypesDev();
17412 var prevDispatcher = ReactCurrentDispatcher$1.current;
17413 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17414
17415 try {
17416 return updateMemo(create, deps);
17417 } finally {
17418 ReactCurrentDispatcher$1.current = prevDispatcher;
17419 }
17420 },
17421 useReducer: function (reducer, initialArg, init) {
17422 currentHookNameInDev = 'useReducer';
17423 warnInvalidHookAccess();
17424 updateHookTypesDev();
17425 var prevDispatcher = ReactCurrentDispatcher$1.current;
17426 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17427
17428 try {
17429 return updateReducer(reducer, initialArg, init);
17430 } finally {
17431 ReactCurrentDispatcher$1.current = prevDispatcher;
17432 }
17433 },
17434 useRef: function (initialValue) {
17435 currentHookNameInDev = 'useRef';
17436 warnInvalidHookAccess();
17437 updateHookTypesDev();
17438 return updateRef();
17439 },
17440 useState: function (initialState) {
17441 currentHookNameInDev = 'useState';
17442 warnInvalidHookAccess();
17443 updateHookTypesDev();
17444 var prevDispatcher = ReactCurrentDispatcher$1.current;
17445 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17446
17447 try {
17448 return updateState(initialState);
17449 } finally {
17450 ReactCurrentDispatcher$1.current = prevDispatcher;
17451 }
17452 },
17453 useDebugValue: function (value, formatterFn) {
17454 currentHookNameInDev = 'useDebugValue';
17455 warnInvalidHookAccess();
17456 updateHookTypesDev();
17457 return updateDebugValue();
17458 },
17459 useDeferredValue: function (value) {
17460 currentHookNameInDev = 'useDeferredValue';
17461 warnInvalidHookAccess();
17462 updateHookTypesDev();
17463 return updateDeferredValue(value);
17464 },
17465 useTransition: function () {
17466 currentHookNameInDev = 'useTransition';
17467 warnInvalidHookAccess();
17468 updateHookTypesDev();
17469 return updateTransition();
17470 },
17471 useMutableSource: function (source, getSnapshot, subscribe) {
17472 currentHookNameInDev = 'useMutableSource';
17473 warnInvalidHookAccess();
17474 updateHookTypesDev();
17475 return updateMutableSource();
17476 },
17477 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
17478 currentHookNameInDev = 'useSyncExternalStore';
17479 warnInvalidHookAccess();
17480 updateHookTypesDev();
17481 return updateSyncExternalStore(subscribe, getSnapshot);
17482 },
17483 useId: function () {
17484 currentHookNameInDev = 'useId';
17485 warnInvalidHookAccess();
17486 updateHookTypesDev();
17487 return updateId();
17488 },
17489 unstable_isNewReconciler: enableNewReconciler
17490 };
17491
17492 InvalidNestedHooksDispatcherOnRerenderInDEV = {
17493 readContext: function (context) {
17494 warnInvalidContextAccess();
17495 return readContext(context);
17496 },
17497 useCallback: function (callback, deps) {
17498 currentHookNameInDev = 'useCallback';
17499 warnInvalidHookAccess();
17500 updateHookTypesDev();
17501 return updateCallback(callback, deps);
17502 },
17503 useContext: function (context) {
17504 currentHookNameInDev = 'useContext';
17505 warnInvalidHookAccess();
17506 updateHookTypesDev();
17507 return readContext(context);
17508 },
17509 useEffect: function (create, deps) {
17510 currentHookNameInDev = 'useEffect';
17511 warnInvalidHookAccess();
17512 updateHookTypesDev();
17513 return updateEffect(create, deps);
17514 },
17515 useImperativeHandle: function (ref, create, deps) {
17516 currentHookNameInDev = 'useImperativeHandle';
17517 warnInvalidHookAccess();
17518 updateHookTypesDev();
17519 return updateImperativeHandle(ref, create, deps);
17520 },
17521 useInsertionEffect: function (create, deps) {
17522 currentHookNameInDev = 'useInsertionEffect';
17523 warnInvalidHookAccess();
17524 updateHookTypesDev();
17525 return updateInsertionEffect(create, deps);
17526 },
17527 useLayoutEffect: function (create, deps) {
17528 currentHookNameInDev = 'useLayoutEffect';
17529 warnInvalidHookAccess();
17530 updateHookTypesDev();
17531 return updateLayoutEffect(create, deps);
17532 },
17533 useMemo: function (create, deps) {
17534 currentHookNameInDev = 'useMemo';
17535 warnInvalidHookAccess();
17536 updateHookTypesDev();
17537 var prevDispatcher = ReactCurrentDispatcher$1.current;
17538 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17539
17540 try {
17541 return updateMemo(create, deps);
17542 } finally {
17543 ReactCurrentDispatcher$1.current = prevDispatcher;
17544 }
17545 },
17546 useReducer: function (reducer, initialArg, init) {
17547 currentHookNameInDev = 'useReducer';
17548 warnInvalidHookAccess();
17549 updateHookTypesDev();
17550 var prevDispatcher = ReactCurrentDispatcher$1.current;
17551 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17552
17553 try {
17554 return rerenderReducer(reducer, initialArg, init);
17555 } finally {
17556 ReactCurrentDispatcher$1.current = prevDispatcher;
17557 }
17558 },
17559 useRef: function (initialValue) {
17560 currentHookNameInDev = 'useRef';
17561 warnInvalidHookAccess();
17562 updateHookTypesDev();
17563 return updateRef();
17564 },
17565 useState: function (initialState) {
17566 currentHookNameInDev = 'useState';
17567 warnInvalidHookAccess();
17568 updateHookTypesDev();
17569 var prevDispatcher = ReactCurrentDispatcher$1.current;
17570 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17571
17572 try {
17573 return rerenderState(initialState);
17574 } finally {
17575 ReactCurrentDispatcher$1.current = prevDispatcher;
17576 }
17577 },
17578 useDebugValue: function (value, formatterFn) {
17579 currentHookNameInDev = 'useDebugValue';
17580 warnInvalidHookAccess();
17581 updateHookTypesDev();
17582 return updateDebugValue();
17583 },
17584 useDeferredValue: function (value) {
17585 currentHookNameInDev = 'useDeferredValue';
17586 warnInvalidHookAccess();
17587 updateHookTypesDev();
17588 return rerenderDeferredValue(value);
17589 },
17590 useTransition: function () {
17591 currentHookNameInDev = 'useTransition';
17592 warnInvalidHookAccess();
17593 updateHookTypesDev();
17594 return rerenderTransition();
17595 },
17596 useMutableSource: function (source, getSnapshot, subscribe) {
17597 currentHookNameInDev = 'useMutableSource';
17598 warnInvalidHookAccess();
17599 updateHookTypesDev();
17600 return updateMutableSource();
17601 },
17602 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
17603 currentHookNameInDev = 'useSyncExternalStore';
17604 warnInvalidHookAccess();
17605 updateHookTypesDev();
17606 return updateSyncExternalStore(subscribe, getSnapshot);
17607 },
17608 useId: function () {
17609 currentHookNameInDev = 'useId';
17610 warnInvalidHookAccess();
17611 updateHookTypesDev();
17612 return updateId();
17613 },
17614 unstable_isNewReconciler: enableNewReconciler
17615 };
17616 }
17617
17618 var now$1 = Scheduler.unstable_now;
17619 var commitTime = 0;
17620 var layoutEffectStartTime = -1;
17621 var profilerStartTime = -1;
17622 var passiveEffectStartTime = -1;
17623 /**
17624 * Tracks whether the current update was a nested/cascading update (scheduled from a layout effect).
17625 *
17626 * The overall sequence is:
17627 * 1. render
17628 * 2. commit (and call `onRender`, `onCommit`)
17629 * 3. check for nested updates
17630 * 4. flush passive effects (and call `onPostCommit`)
17631 *
17632 * Nested updates are identified in step 3 above,
17633 * but step 4 still applies to the work that was just committed.
17634 * We use two flags to track nested updates then:
17635 * one tracks whether the upcoming update is a nested update,
17636 * and the other tracks whether the current update was a nested update.
17637 * The first value gets synced to the second at the start of the render phase.
17638 */
17639
17640 var currentUpdateIsNested = false;
17641 var nestedUpdateScheduled = false;
17642
17643 function isCurrentUpdateNested() {
17644 return currentUpdateIsNested;
17645 }
17646
17647 function markNestedUpdateScheduled() {
17648 {
17649 nestedUpdateScheduled = true;
17650 }
17651 }
17652
17653 function resetNestedUpdateFlag() {
17654 {
17655 currentUpdateIsNested = false;
17656 nestedUpdateScheduled = false;
17657 }
17658 }
17659
17660 function syncNestedUpdateFlag() {
17661 {
17662 currentUpdateIsNested = nestedUpdateScheduled;
17663 nestedUpdateScheduled = false;
17664 }
17665 }
17666
17667 function getCommitTime() {
17668 return commitTime;
17669 }
17670
17671 function recordCommitTime() {
17672
17673 commitTime = now$1();
17674 }
17675
17676 function startProfilerTimer(fiber) {
17677
17678 profilerStartTime = now$1();
17679
17680 if (fiber.actualStartTime < 0) {
17681 fiber.actualStartTime = now$1();
17682 }
17683 }
17684
17685 function stopProfilerTimerIfRunning(fiber) {
17686
17687 profilerStartTime = -1;
17688 }
17689
17690 function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
17691
17692 if (profilerStartTime >= 0) {
17693 var elapsedTime = now$1() - profilerStartTime;
17694 fiber.actualDuration += elapsedTime;
17695
17696 if (overrideBaseTime) {
17697 fiber.selfBaseDuration = elapsedTime;
17698 }
17699
17700 profilerStartTime = -1;
17701 }
17702 }
17703
17704 function recordLayoutEffectDuration(fiber) {
17705
17706 if (layoutEffectStartTime >= 0) {
17707 var elapsedTime = now$1() - layoutEffectStartTime;
17708 layoutEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor
17709 // Or the root (for the DevTools Profiler to read)
17710
17711 var parentFiber = fiber.return;
17712
17713 while (parentFiber !== null) {
17714 switch (parentFiber.tag) {
17715 case HostRoot:
17716 var root = parentFiber.stateNode;
17717 root.effectDuration += elapsedTime;
17718 return;
17719
17720 case Profiler:
17721 var parentStateNode = parentFiber.stateNode;
17722 parentStateNode.effectDuration += elapsedTime;
17723 return;
17724 }
17725
17726 parentFiber = parentFiber.return;
17727 }
17728 }
17729 }
17730
17731 function recordPassiveEffectDuration(fiber) {
17732
17733 if (passiveEffectStartTime >= 0) {
17734 var elapsedTime = now$1() - passiveEffectStartTime;
17735 passiveEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor
17736 // Or the root (for the DevTools Profiler to read)
17737
17738 var parentFiber = fiber.return;
17739
17740 while (parentFiber !== null) {
17741 switch (parentFiber.tag) {
17742 case HostRoot:
17743 var root = parentFiber.stateNode;
17744
17745 if (root !== null) {
17746 root.passiveEffectDuration += elapsedTime;
17747 }
17748
17749 return;
17750
17751 case Profiler:
17752 var parentStateNode = parentFiber.stateNode;
17753
17754 if (parentStateNode !== null) {
17755 // Detached fibers have their state node cleared out.
17756 // In this case, the return pointer is also cleared out,
17757 // so we won't be able to report the time spent in this Profiler's subtree.
17758 parentStateNode.passiveEffectDuration += elapsedTime;
17759 }
17760
17761 return;
17762 }
17763
17764 parentFiber = parentFiber.return;
17765 }
17766 }
17767 }
17768
17769 function startLayoutEffectTimer() {
17770
17771 layoutEffectStartTime = now$1();
17772 }
17773
17774 function startPassiveEffectTimer() {
17775
17776 passiveEffectStartTime = now$1();
17777 }
17778
17779 function transferActualDuration(fiber) {
17780 // Transfer time spent rendering these children so we don't lose it
17781 // after we rerender. This is used as a helper in special cases
17782 // where we should count the work of multiple passes.
17783 var child = fiber.child;
17784
17785 while (child) {
17786 fiber.actualDuration += child.actualDuration;
17787 child = child.sibling;
17788 }
17789 }
17790
17791 function resolveDefaultProps(Component, baseProps) {
17792 if (Component && Component.defaultProps) {
17793 // Resolve default props. Taken from ReactElement
17794 var props = assign({}, baseProps);
17795 var defaultProps = Component.defaultProps;
17796
17797 for (var propName in defaultProps) {
17798 if (props[propName] === undefined) {
17799 props[propName] = defaultProps[propName];
17800 }
17801 }
17802
17803 return props;
17804 }
17805
17806 return baseProps;
17807 }
17808
17809 var fakeInternalInstance = {};
17810 var didWarnAboutStateAssignmentForComponent;
17811 var didWarnAboutUninitializedState;
17812 var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
17813 var didWarnAboutLegacyLifecyclesAndDerivedState;
17814 var didWarnAboutUndefinedDerivedState;
17815 var warnOnUndefinedDerivedState;
17816 var warnOnInvalidCallback;
17817 var didWarnAboutDirectlyAssigningPropsToState;
17818 var didWarnAboutContextTypeAndContextTypes;
17819 var didWarnAboutInvalidateContextType;
17820 var didWarnAboutLegacyContext$1;
17821
17822 {
17823 didWarnAboutStateAssignmentForComponent = new Set();
17824 didWarnAboutUninitializedState = new Set();
17825 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
17826 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
17827 didWarnAboutDirectlyAssigningPropsToState = new Set();
17828 didWarnAboutUndefinedDerivedState = new Set();
17829 didWarnAboutContextTypeAndContextTypes = new Set();
17830 didWarnAboutInvalidateContextType = new Set();
17831 didWarnAboutLegacyContext$1 = new Set();
17832 var didWarnOnInvalidCallback = new Set();
17833
17834 warnOnInvalidCallback = function (callback, callerName) {
17835 if (callback === null || typeof callback === 'function') {
17836 return;
17837 }
17838
17839 var key = callerName + '_' + callback;
17840
17841 if (!didWarnOnInvalidCallback.has(key)) {
17842 didWarnOnInvalidCallback.add(key);
17843
17844 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
17845 }
17846 };
17847
17848 warnOnUndefinedDerivedState = function (type, partialState) {
17849 if (partialState === undefined) {
17850 var componentName = getComponentNameFromType(type) || 'Component';
17851
17852 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
17853 didWarnAboutUndefinedDerivedState.add(componentName);
17854
17855 error('%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
17856 }
17857 }
17858 }; // This is so gross but it's at least non-critical and can be removed if
17859 // it causes problems. This is meant to give a nicer error message for
17860 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
17861 // ...)) which otherwise throws a "_processChildContext is not a function"
17862 // exception.
17863
17864
17865 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
17866 enumerable: false,
17867 value: function () {
17868 throw new Error('_processChildContext is not available in React 16+. This likely ' + 'means you have multiple copies of React and are attempting to nest ' + 'a React 15 tree inside a React 16 tree using ' + "unstable_renderSubtreeIntoContainer, which isn't supported. Try " + 'to make sure you have only one copy of React (and ideally, switch ' + 'to ReactDOM.createPortal).');
17869 }
17870 });
17871 Object.freeze(fakeInternalInstance);
17872 }
17873
17874 function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
17875 var prevState = workInProgress.memoizedState;
17876 var partialState = getDerivedStateFromProps(nextProps, prevState);
17877
17878 {
17879 if ( workInProgress.mode & StrictLegacyMode) {
17880 setIsStrictModeForDevtools(true);
17881
17882 try {
17883 // Invoke the function an extra time to help detect side-effects.
17884 partialState = getDerivedStateFromProps(nextProps, prevState);
17885 } finally {
17886 setIsStrictModeForDevtools(false);
17887 }
17888 }
17889
17890 warnOnUndefinedDerivedState(ctor, partialState);
17891 } // Merge the partial state and the previous state.
17892
17893
17894 var memoizedState = partialState === null || partialState === undefined ? prevState : assign({}, prevState, partialState);
17895 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the
17896 // base state.
17897
17898 if (workInProgress.lanes === NoLanes) {
17899 // Queue is always non-null for classes
17900 var updateQueue = workInProgress.updateQueue;
17901 updateQueue.baseState = memoizedState;
17902 }
17903 }
17904
17905 var classComponentUpdater = {
17906 isMounted: isMounted,
17907 enqueueSetState: function (inst, payload, callback) {
17908 var fiber = get(inst);
17909 var eventTime = requestEventTime();
17910 var lane = requestUpdateLane(fiber);
17911 var update = createUpdate(eventTime, lane);
17912 update.payload = payload;
17913
17914 if (callback !== undefined && callback !== null) {
17915 {
17916 warnOnInvalidCallback(callback, 'setState');
17917 }
17918
17919 update.callback = callback;
17920 }
17921
17922 var root = enqueueUpdate(fiber, update, lane);
17923
17924 if (root !== null) {
17925 scheduleUpdateOnFiber(root, fiber, lane, eventTime);
17926 entangleTransitions(root, fiber, lane);
17927 }
17928
17929 {
17930 markStateUpdateScheduled(fiber, lane);
17931 }
17932 },
17933 enqueueReplaceState: function (inst, payload, callback) {
17934 var fiber = get(inst);
17935 var eventTime = requestEventTime();
17936 var lane = requestUpdateLane(fiber);
17937 var update = createUpdate(eventTime, lane);
17938 update.tag = ReplaceState;
17939 update.payload = payload;
17940
17941 if (callback !== undefined && callback !== null) {
17942 {
17943 warnOnInvalidCallback(callback, 'replaceState');
17944 }
17945
17946 update.callback = callback;
17947 }
17948
17949 var root = enqueueUpdate(fiber, update, lane);
17950
17951 if (root !== null) {
17952 scheduleUpdateOnFiber(root, fiber, lane, eventTime);
17953 entangleTransitions(root, fiber, lane);
17954 }
17955
17956 {
17957 markStateUpdateScheduled(fiber, lane);
17958 }
17959 },
17960 enqueueForceUpdate: function (inst, callback) {
17961 var fiber = get(inst);
17962 var eventTime = requestEventTime();
17963 var lane = requestUpdateLane(fiber);
17964 var update = createUpdate(eventTime, lane);
17965 update.tag = ForceUpdate;
17966
17967 if (callback !== undefined && callback !== null) {
17968 {
17969 warnOnInvalidCallback(callback, 'forceUpdate');
17970 }
17971
17972 update.callback = callback;
17973 }
17974
17975 var root = enqueueUpdate(fiber, update, lane);
17976
17977 if (root !== null) {
17978 scheduleUpdateOnFiber(root, fiber, lane, eventTime);
17979 entangleTransitions(root, fiber, lane);
17980 }
17981
17982 {
17983 markForceUpdateScheduled(fiber, lane);
17984 }
17985 }
17986 };
17987
17988 function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
17989 var instance = workInProgress.stateNode;
17990
17991 if (typeof instance.shouldComponentUpdate === 'function') {
17992 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
17993
17994 {
17995 if ( workInProgress.mode & StrictLegacyMode) {
17996 setIsStrictModeForDevtools(true);
17997
17998 try {
17999 // Invoke the function an extra time to help detect side-effects.
18000 shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
18001 } finally {
18002 setIsStrictModeForDevtools(false);
18003 }
18004 }
18005
18006 if (shouldUpdate === undefined) {
18007 error('%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentNameFromType(ctor) || 'Component');
18008 }
18009 }
18010
18011 return shouldUpdate;
18012 }
18013
18014 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
18015 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
18016 }
18017
18018 return true;
18019 }
18020
18021 function checkClassInstance(workInProgress, ctor, newProps) {
18022 var instance = workInProgress.stateNode;
18023
18024 {
18025 var name = getComponentNameFromType(ctor) || 'Component';
18026 var renderPresent = instance.render;
18027
18028 if (!renderPresent) {
18029 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
18030 error('%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
18031 } else {
18032 error('%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
18033 }
18034 }
18035
18036 if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) {
18037 error('getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', name);
18038 }
18039
18040 if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) {
18041 error('getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', name);
18042 }
18043
18044 if (instance.propTypes) {
18045 error('propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
18046 }
18047
18048 if (instance.contextType) {
18049 error('contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name);
18050 }
18051
18052 {
18053 if (ctor.childContextTypes && !didWarnAboutLegacyContext$1.has(ctor) && // Strict Mode has its own warning for legacy context, so we can skip
18054 // this one.
18055 (workInProgress.mode & StrictLegacyMode) === NoMode) {
18056 didWarnAboutLegacyContext$1.add(ctor);
18057
18058 error('%s uses the legacy childContextTypes API which is no longer ' + 'supported and will be removed in the next major release. Use ' + 'React.createContext() instead\n\n.' + 'Learn more about this warning here: https://reactjs.org/link/legacy-context', name);
18059 }
18060
18061 if (ctor.contextTypes && !didWarnAboutLegacyContext$1.has(ctor) && // Strict Mode has its own warning for legacy context, so we can skip
18062 // this one.
18063 (workInProgress.mode & StrictLegacyMode) === NoMode) {
18064 didWarnAboutLegacyContext$1.add(ctor);
18065
18066 error('%s uses the legacy contextTypes API which is no longer supported ' + 'and will be removed in the next major release. Use ' + 'React.createContext() with static contextType instead.\n\n' + 'Learn more about this warning here: https://reactjs.org/link/legacy-context', name);
18067 }
18068
18069 if (instance.contextTypes) {
18070 error('contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);
18071 }
18072
18073 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
18074 didWarnAboutContextTypeAndContextTypes.add(ctor);
18075
18076 error('%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
18077 }
18078 }
18079
18080 if (typeof instance.componentShouldUpdate === 'function') {
18081 error('%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', name);
18082 }
18083
18084 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
18085 error('%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentNameFromType(ctor) || 'A pure component');
18086 }
18087
18088 if (typeof instance.componentDidUnmount === 'function') {
18089 error('%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
18090 }
18091
18092 if (typeof instance.componentDidReceiveProps === 'function') {
18093 error('%s has a method called ' + 'componentDidReceiveProps(). But there is no such lifecycle method. ' + 'If you meant to update the state in response to changing props, ' + 'use componentWillReceiveProps(). If you meant to fetch data or ' + 'run side-effects or mutations after React has updated the UI, use componentDidUpdate().', name);
18094 }
18095
18096 if (typeof instance.componentWillRecieveProps === 'function') {
18097 error('%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
18098 }
18099
18100 if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') {
18101 error('%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name);
18102 }
18103
18104 var hasMutatedProps = instance.props !== newProps;
18105
18106 if (instance.props !== undefined && hasMutatedProps) {
18107 error('%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name);
18108 }
18109
18110 if (instance.defaultProps) {
18111 error('Setting defaultProps as an instance property on %s is not supported and will be ignored.' + ' Instead, define defaultProps as a static property on %s.', name, name);
18112 }
18113
18114 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
18115 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
18116
18117 error('%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentNameFromType(ctor));
18118 }
18119
18120 if (typeof instance.getDerivedStateFromProps === 'function') {
18121 error('%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
18122 }
18123
18124 if (typeof instance.getDerivedStateFromError === 'function') {
18125 error('%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
18126 }
18127
18128 if (typeof ctor.getSnapshotBeforeUpdate === 'function') {
18129 error('%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name);
18130 }
18131
18132 var _state = instance.state;
18133
18134 if (_state && (typeof _state !== 'object' || isArray(_state))) {
18135 error('%s.state: must be set to an object or null', name);
18136 }
18137
18138 if (typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object') {
18139 error('%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name);
18140 }
18141 }
18142 }
18143
18144 function adoptClassInstance(workInProgress, instance) {
18145 instance.updater = classComponentUpdater;
18146 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates
18147
18148 set(instance, workInProgress);
18149
18150 {
18151 instance._reactInternalInstance = fakeInternalInstance;
18152 }
18153 }
18154
18155 function constructClassInstance(workInProgress, ctor, props) {
18156 var isLegacyContextConsumer = false;
18157 var unmaskedContext = emptyContextObject;
18158 var context = emptyContextObject;
18159 var contextType = ctor.contextType;
18160
18161 {
18162 if ('contextType' in ctor) {
18163 var isValid = // Allow null for conditional declaration
18164 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
18165
18166 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
18167 didWarnAboutInvalidateContextType.add(ctor);
18168 var addendum = '';
18169
18170 if (contextType === undefined) {
18171 addendum = ' However, it is set to undefined. ' + 'This can be caused by a typo or by mixing up named and default imports. ' + 'This can also happen due to a circular dependency, so ' + 'try moving the createContext() call to a separate file.';
18172 } else if (typeof contextType !== 'object') {
18173 addendum = ' However, it is set to a ' + typeof contextType + '.';
18174 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
18175 addendum = ' Did you accidentally pass the Context.Provider instead?';
18176 } else if (contextType._context !== undefined) {
18177 // <Context.Consumer>
18178 addendum = ' Did you accidentally pass the Context.Consumer instead?';
18179 } else {
18180 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
18181 }
18182
18183 error('%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentNameFromType(ctor) || 'Component', addendum);
18184 }
18185 }
18186 }
18187
18188 if (typeof contextType === 'object' && contextType !== null) {
18189 context = readContext(contextType);
18190 } else {
18191 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
18192 var contextTypes = ctor.contextTypes;
18193 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
18194 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
18195 }
18196
18197 var instance = new ctor(props, context); // Instantiate twice to help detect side-effects.
18198
18199 {
18200 if ( workInProgress.mode & StrictLegacyMode) {
18201 setIsStrictModeForDevtools(true);
18202
18203 try {
18204 instance = new ctor(props, context); // eslint-disable-line no-new
18205 } finally {
18206 setIsStrictModeForDevtools(false);
18207 }
18208 }
18209 }
18210
18211 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
18212 adoptClassInstance(workInProgress, instance);
18213
18214 {
18215 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
18216 var componentName = getComponentNameFromType(ctor) || 'Component';
18217
18218 if (!didWarnAboutUninitializedState.has(componentName)) {
18219 didWarnAboutUninitializedState.add(componentName);
18220
18221 error('`%s` uses `getDerivedStateFromProps` but its initial state is ' + '%s. This is not recommended. Instead, define the initial state by ' + 'assigning an object to `this.state` in the constructor of `%s`. ' + 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.', componentName, instance.state === null ? 'null' : 'undefined', componentName);
18222 }
18223 } // If new component APIs are defined, "unsafe" lifecycles won't be called.
18224 // Warn about these lifecycles if they are present.
18225 // Don't warn about react-lifecycles-compat polyfilled methods though.
18226
18227
18228 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
18229 var foundWillMountName = null;
18230 var foundWillReceivePropsName = null;
18231 var foundWillUpdateName = null;
18232
18233 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
18234 foundWillMountName = 'componentWillMount';
18235 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
18236 foundWillMountName = 'UNSAFE_componentWillMount';
18237 }
18238
18239 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
18240 foundWillReceivePropsName = 'componentWillReceiveProps';
18241 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
18242 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
18243 }
18244
18245 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
18246 foundWillUpdateName = 'componentWillUpdate';
18247 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
18248 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
18249 }
18250
18251 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
18252 var _componentName = getComponentNameFromType(ctor) || 'Component';
18253
18254 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
18255
18256 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
18257 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
18258
18259 error('Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' + '%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n' + 'The above lifecycles should be removed. Learn more about this warning here:\n' + 'https://reactjs.org/link/unsafe-component-lifecycles', _componentName, newApiName, foundWillMountName !== null ? "\n " + foundWillMountName : '', foundWillReceivePropsName !== null ? "\n " + foundWillReceivePropsName : '', foundWillUpdateName !== null ? "\n " + foundWillUpdateName : '');
18260 }
18261 }
18262 }
18263 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
18264 // ReactFiberContext usually updates this cache but can't for newly-created instances.
18265
18266
18267 if (isLegacyContextConsumer) {
18268 cacheContext(workInProgress, unmaskedContext, context);
18269 }
18270
18271 return instance;
18272 }
18273
18274 function callComponentWillMount(workInProgress, instance) {
18275 var oldState = instance.state;
18276
18277 if (typeof instance.componentWillMount === 'function') {
18278 instance.componentWillMount();
18279 }
18280
18281 if (typeof instance.UNSAFE_componentWillMount === 'function') {
18282 instance.UNSAFE_componentWillMount();
18283 }
18284
18285 if (oldState !== instance.state) {
18286 {
18287 error('%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentNameFromFiber(workInProgress) || 'Component');
18288 }
18289
18290 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
18291 }
18292 }
18293
18294 function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
18295 var oldState = instance.state;
18296
18297 if (typeof instance.componentWillReceiveProps === 'function') {
18298 instance.componentWillReceiveProps(newProps, nextContext);
18299 }
18300
18301 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
18302 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
18303 }
18304
18305 if (instance.state !== oldState) {
18306 {
18307 var componentName = getComponentNameFromFiber(workInProgress) || 'Component';
18308
18309 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
18310 didWarnAboutStateAssignmentForComponent.add(componentName);
18311
18312 error('%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
18313 }
18314 }
18315
18316 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
18317 }
18318 } // Invokes the mount life-cycles on a previously never rendered instance.
18319
18320
18321 function mountClassInstance(workInProgress, ctor, newProps, renderLanes) {
18322 {
18323 checkClassInstance(workInProgress, ctor, newProps);
18324 }
18325
18326 var instance = workInProgress.stateNode;
18327 instance.props = newProps;
18328 instance.state = workInProgress.memoizedState;
18329 instance.refs = {};
18330 initializeUpdateQueue(workInProgress);
18331 var contextType = ctor.contextType;
18332
18333 if (typeof contextType === 'object' && contextType !== null) {
18334 instance.context = readContext(contextType);
18335 } else {
18336 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
18337 instance.context = getMaskedContext(workInProgress, unmaskedContext);
18338 }
18339
18340 {
18341 if (instance.state === newProps) {
18342 var componentName = getComponentNameFromType(ctor) || 'Component';
18343
18344 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
18345 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
18346
18347 error('%s: It is not recommended to assign props directly to state ' + "because updates to props won't be reflected in state. " + 'In most cases, it is better to use props directly.', componentName);
18348 }
18349 }
18350
18351 if (workInProgress.mode & StrictLegacyMode) {
18352 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
18353 }
18354
18355 {
18356 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
18357 }
18358 }
18359
18360 instance.state = workInProgress.memoizedState;
18361 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
18362
18363 if (typeof getDerivedStateFromProps === 'function') {
18364 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
18365 instance.state = workInProgress.memoizedState;
18366 } // In order to support react-lifecycles-compat polyfilled components,
18367 // Unsafe lifecycles should not be invoked for components using the new APIs.
18368
18369
18370 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
18371 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's
18372 // process them now.
18373
18374 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
18375 instance.state = workInProgress.memoizedState;
18376 }
18377
18378 if (typeof instance.componentDidMount === 'function') {
18379 var fiberFlags = Update;
18380
18381 {
18382 fiberFlags |= LayoutStatic;
18383 }
18384
18385 if ( (workInProgress.mode & StrictEffectsMode) !== NoMode) {
18386 fiberFlags |= MountLayoutDev;
18387 }
18388
18389 workInProgress.flags |= fiberFlags;
18390 }
18391 }
18392
18393 function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) {
18394 var instance = workInProgress.stateNode;
18395 var oldProps = workInProgress.memoizedProps;
18396 instance.props = oldProps;
18397 var oldContext = instance.context;
18398 var contextType = ctor.contextType;
18399 var nextContext = emptyContextObject;
18400
18401 if (typeof contextType === 'object' && contextType !== null) {
18402 nextContext = readContext(contextType);
18403 } else {
18404 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
18405 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
18406 }
18407
18408 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
18409 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
18410 // ever the previously attempted to render - not the "current". However,
18411 // during componentDidUpdate we pass the "current" props.
18412 // In order to support react-lifecycles-compat polyfilled components,
18413 // Unsafe lifecycles should not be invoked for components using the new APIs.
18414
18415 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
18416 if (oldProps !== newProps || oldContext !== nextContext) {
18417 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
18418 }
18419 }
18420
18421 resetHasForceUpdateBeforeProcessing();
18422 var oldState = workInProgress.memoizedState;
18423 var newState = instance.state = oldState;
18424 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
18425 newState = workInProgress.memoizedState;
18426
18427 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
18428 // If an update was already in progress, we should schedule an Update
18429 // effect even though we're bailing out, so that cWU/cDU are called.
18430 if (typeof instance.componentDidMount === 'function') {
18431 var fiberFlags = Update;
18432
18433 {
18434 fiberFlags |= LayoutStatic;
18435 }
18436
18437 if ( (workInProgress.mode & StrictEffectsMode) !== NoMode) {
18438 fiberFlags |= MountLayoutDev;
18439 }
18440
18441 workInProgress.flags |= fiberFlags;
18442 }
18443
18444 return false;
18445 }
18446
18447 if (typeof getDerivedStateFromProps === 'function') {
18448 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
18449 newState = workInProgress.memoizedState;
18450 }
18451
18452 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
18453
18454 if (shouldUpdate) {
18455 // In order to support react-lifecycles-compat polyfilled components,
18456 // Unsafe lifecycles should not be invoked for components using the new APIs.
18457 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
18458 if (typeof instance.componentWillMount === 'function') {
18459 instance.componentWillMount();
18460 }
18461
18462 if (typeof instance.UNSAFE_componentWillMount === 'function') {
18463 instance.UNSAFE_componentWillMount();
18464 }
18465 }
18466
18467 if (typeof instance.componentDidMount === 'function') {
18468 var _fiberFlags = Update;
18469
18470 {
18471 _fiberFlags |= LayoutStatic;
18472 }
18473
18474 if ( (workInProgress.mode & StrictEffectsMode) !== NoMode) {
18475 _fiberFlags |= MountLayoutDev;
18476 }
18477
18478 workInProgress.flags |= _fiberFlags;
18479 }
18480 } else {
18481 // If an update was already in progress, we should schedule an Update
18482 // effect even though we're bailing out, so that cWU/cDU are called.
18483 if (typeof instance.componentDidMount === 'function') {
18484 var _fiberFlags2 = Update;
18485
18486 {
18487 _fiberFlags2 |= LayoutStatic;
18488 }
18489
18490 if ( (workInProgress.mode & StrictEffectsMode) !== NoMode) {
18491 _fiberFlags2 |= MountLayoutDev;
18492 }
18493
18494 workInProgress.flags |= _fiberFlags2;
18495 } // If shouldComponentUpdate returned false, we should still update the
18496 // memoized state to indicate that this work can be reused.
18497
18498
18499 workInProgress.memoizedProps = newProps;
18500 workInProgress.memoizedState = newState;
18501 } // Update the existing instance's state, props, and context pointers even
18502 // if shouldComponentUpdate returns false.
18503
18504
18505 instance.props = newProps;
18506 instance.state = newState;
18507 instance.context = nextContext;
18508 return shouldUpdate;
18509 } // Invokes the update life-cycles and returns false if it shouldn't rerender.
18510
18511
18512 function updateClassInstance(current, workInProgress, ctor, newProps, renderLanes) {
18513 var instance = workInProgress.stateNode;
18514 cloneUpdateQueue(current, workInProgress);
18515 var unresolvedOldProps = workInProgress.memoizedProps;
18516 var oldProps = workInProgress.type === workInProgress.elementType ? unresolvedOldProps : resolveDefaultProps(workInProgress.type, unresolvedOldProps);
18517 instance.props = oldProps;
18518 var unresolvedNewProps = workInProgress.pendingProps;
18519 var oldContext = instance.context;
18520 var contextType = ctor.contextType;
18521 var nextContext = emptyContextObject;
18522
18523 if (typeof contextType === 'object' && contextType !== null) {
18524 nextContext = readContext(contextType);
18525 } else {
18526 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
18527 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
18528 }
18529
18530 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
18531 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
18532 // ever the previously attempted to render - not the "current". However,
18533 // during componentDidUpdate we pass the "current" props.
18534 // In order to support react-lifecycles-compat polyfilled components,
18535 // Unsafe lifecycles should not be invoked for components using the new APIs.
18536
18537 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
18538 if (unresolvedOldProps !== unresolvedNewProps || oldContext !== nextContext) {
18539 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
18540 }
18541 }
18542
18543 resetHasForceUpdateBeforeProcessing();
18544 var oldState = workInProgress.memoizedState;
18545 var newState = instance.state = oldState;
18546 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
18547 newState = workInProgress.memoizedState;
18548
18549 if (unresolvedOldProps === unresolvedNewProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing() && !(enableLazyContextPropagation )) {
18550 // If an update was already in progress, we should schedule an Update
18551 // effect even though we're bailing out, so that cWU/cDU are called.
18552 if (typeof instance.componentDidUpdate === 'function') {
18553 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
18554 workInProgress.flags |= Update;
18555 }
18556 }
18557
18558 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
18559 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
18560 workInProgress.flags |= Snapshot;
18561 }
18562 }
18563
18564 return false;
18565 }
18566
18567 if (typeof getDerivedStateFromProps === 'function') {
18568 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
18569 newState = workInProgress.memoizedState;
18570 }
18571
18572 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) || // TODO: In some cases, we'll end up checking if context has changed twice,
18573 // both before and after `shouldComponentUpdate` has been called. Not ideal,
18574 // but I'm loath to refactor this function. This only happens for memoized
18575 // components so it's not that common.
18576 enableLazyContextPropagation ;
18577
18578 if (shouldUpdate) {
18579 // In order to support react-lifecycles-compat polyfilled components,
18580 // Unsafe lifecycles should not be invoked for components using the new APIs.
18581 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
18582 if (typeof instance.componentWillUpdate === 'function') {
18583 instance.componentWillUpdate(newProps, newState, nextContext);
18584 }
18585
18586 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
18587 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
18588 }
18589 }
18590
18591 if (typeof instance.componentDidUpdate === 'function') {
18592 workInProgress.flags |= Update;
18593 }
18594
18595 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
18596 workInProgress.flags |= Snapshot;
18597 }
18598 } else {
18599 // If an update was already in progress, we should schedule an Update
18600 // effect even though we're bailing out, so that cWU/cDU are called.
18601 if (typeof instance.componentDidUpdate === 'function') {
18602 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
18603 workInProgress.flags |= Update;
18604 }
18605 }
18606
18607 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
18608 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
18609 workInProgress.flags |= Snapshot;
18610 }
18611 } // If shouldComponentUpdate returned false, we should still update the
18612 // memoized props/state to indicate that this work can be reused.
18613
18614
18615 workInProgress.memoizedProps = newProps;
18616 workInProgress.memoizedState = newState;
18617 } // Update the existing instance's state, props, and context pointers even
18618 // if shouldComponentUpdate returns false.
18619
18620
18621 instance.props = newProps;
18622 instance.state = newState;
18623 instance.context = nextContext;
18624 return shouldUpdate;
18625 }
18626
18627 function createCapturedValueAtFiber(value, source) {
18628 // If the value is an error, call this function immediately after it is thrown
18629 // so the stack is accurate.
18630 return {
18631 value: value,
18632 source: source,
18633 stack: getStackByFiberInDevAndProd(source),
18634 digest: null
18635 };
18636 }
18637 function createCapturedValue(value, digest, stack) {
18638 return {
18639 value: value,
18640 source: null,
18641 stack: stack != null ? stack : null,
18642 digest: digest != null ? digest : null
18643 };
18644 }
18645
18646 // This module is forked in different environments.
18647 // By default, return `true` to log errors to the console.
18648 // Forks can return `false` if this isn't desirable.
18649 function showErrorDialog(boundary, errorInfo) {
18650 return true;
18651 }
18652
18653 function logCapturedError(boundary, errorInfo) {
18654 try {
18655 var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging.
18656 // This enables renderers like ReactNative to better manage redbox behavior.
18657
18658 if (logError === false) {
18659 return;
18660 }
18661
18662 var error = errorInfo.value;
18663
18664 if (true) {
18665 var source = errorInfo.source;
18666 var stack = errorInfo.stack;
18667 var componentStack = stack !== null ? stack : ''; // Browsers support silencing uncaught errors by calling
18668 // `preventDefault()` in window `error` handler.
18669 // We record this information as an expando on the error.
18670
18671 if (error != null && error._suppressLogging) {
18672 if (boundary.tag === ClassComponent) {
18673 // The error is recoverable and was silenced.
18674 // Ignore it and don't print the stack addendum.
18675 // This is handy for testing error boundaries without noise.
18676 return;
18677 } // The error is fatal. Since the silencing might have
18678 // been accidental, we'll surface it anyway.
18679 // However, the browser would have silenced the original error
18680 // so we'll print it first, and then print the stack addendum.
18681
18682
18683 console['error'](error); // Don't transform to our wrapper
18684 // For a more detailed description of this block, see:
18685 // https://github.com/facebook/react/pull/13384
18686 }
18687
18688 var componentName = source ? getComponentNameFromFiber(source) : null;
18689 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:';
18690 var errorBoundaryMessage;
18691
18692 if (boundary.tag === HostRoot) {
18693 errorBoundaryMessage = 'Consider adding an error boundary to your tree to customize error handling behavior.\n' + 'Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.';
18694 } else {
18695 var errorBoundaryName = getComponentNameFromFiber(boundary) || 'Anonymous';
18696 errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + ".");
18697 }
18698
18699 var combinedMessage = componentNameMessage + "\n" + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack.
18700 // We don't include the original error message and JS stack because the browser
18701 // has already printed it. Even if the application swallows the error, it is still
18702 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
18703
18704 console['error'](combinedMessage); // Don't transform to our wrapper
18705 } else {
18706 // In production, we print the error directly.
18707 // This will include the message, the JS stack, and anything the browser wants to show.
18708 // We pass the error object instead of custom message so that the browser displays the error natively.
18709 console['error'](error); // Don't transform to our wrapper
18710 }
18711 } catch (e) {
18712 // This method must not throw, or React internal state will get messed up.
18713 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
18714 // we want to report this error outside of the normal stack as a last resort.
18715 // https://github.com/facebook/react/issues/13188
18716 setTimeout(function () {
18717 throw e;
18718 });
18719 }
18720 }
18721
18722 var PossiblyWeakMap$1 = typeof WeakMap === 'function' ? WeakMap : Map;
18723
18724 function createRootErrorUpdate(fiber, errorInfo, lane) {
18725 var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null.
18726
18727 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property
18728 // being called "element".
18729
18730 update.payload = {
18731 element: null
18732 };
18733 var error = errorInfo.value;
18734
18735 update.callback = function () {
18736 onUncaughtError(error);
18737 logCapturedError(fiber, errorInfo);
18738 };
18739
18740 return update;
18741 }
18742
18743 function createClassErrorUpdate(fiber, errorInfo, lane) {
18744 var update = createUpdate(NoTimestamp, lane);
18745 update.tag = CaptureUpdate;
18746 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
18747
18748 if (typeof getDerivedStateFromError === 'function') {
18749 var error$1 = errorInfo.value;
18750
18751 update.payload = function () {
18752 return getDerivedStateFromError(error$1);
18753 };
18754
18755 update.callback = function () {
18756 {
18757 markFailedErrorBoundaryForHotReloading(fiber);
18758 }
18759
18760 logCapturedError(fiber, errorInfo);
18761 };
18762 }
18763
18764 var inst = fiber.stateNode;
18765
18766 if (inst !== null && typeof inst.componentDidCatch === 'function') {
18767 update.callback = function callback() {
18768 {
18769 markFailedErrorBoundaryForHotReloading(fiber);
18770 }
18771
18772 logCapturedError(fiber, errorInfo);
18773
18774 if (typeof getDerivedStateFromError !== 'function') {
18775 // To preserve the preexisting retry behavior of error boundaries,
18776 // we keep track of which ones already failed during this batch.
18777 // This gets reset before we yield back to the browser.
18778 // TODO: Warn in strict mode if getDerivedStateFromError is
18779 // not defined.
18780 markLegacyErrorBoundaryAsFailed(this);
18781 }
18782
18783 var error$1 = errorInfo.value;
18784 var stack = errorInfo.stack;
18785 this.componentDidCatch(error$1, {
18786 componentStack: stack !== null ? stack : ''
18787 });
18788
18789 {
18790 if (typeof getDerivedStateFromError !== 'function') {
18791 // If componentDidCatch is the only error boundary method defined,
18792 // then it needs to call setState to recover from errors.
18793 // If no state update is scheduled then the boundary will swallow the error.
18794 if (!includesSomeLane(fiber.lanes, SyncLane)) {
18795 error('%s: Error boundaries should implement getDerivedStateFromError(). ' + 'In that method, return a state update to display an error message or fallback UI.', getComponentNameFromFiber(fiber) || 'Unknown');
18796 }
18797 }
18798 }
18799 };
18800 }
18801
18802 return update;
18803 }
18804
18805 function attachPingListener(root, wakeable, lanes) {
18806 // Attach a ping listener
18807 //
18808 // The data might resolve before we have a chance to commit the fallback. Or,
18809 // in the case of a refresh, we'll never commit a fallback. So we need to
18810 // attach a listener now. When it resolves ("pings"), we can decide whether to
18811 // try rendering the tree again.
18812 //
18813 // Only attach a listener if one does not already exist for the lanes
18814 // we're currently rendering (which acts like a "thread ID" here).
18815 //
18816 // We only need to do this in concurrent mode. Legacy Suspense always
18817 // commits fallbacks synchronously, so there are no pings.
18818 var pingCache = root.pingCache;
18819 var threadIDs;
18820
18821 if (pingCache === null) {
18822 pingCache = root.pingCache = new PossiblyWeakMap$1();
18823 threadIDs = new Set();
18824 pingCache.set(wakeable, threadIDs);
18825 } else {
18826 threadIDs = pingCache.get(wakeable);
18827
18828 if (threadIDs === undefined) {
18829 threadIDs = new Set();
18830 pingCache.set(wakeable, threadIDs);
18831 }
18832 }
18833
18834 if (!threadIDs.has(lanes)) {
18835 // Memoize using the thread ID to prevent redundant listeners.
18836 threadIDs.add(lanes);
18837 var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes);
18838
18839 {
18840 if (isDevToolsPresent) {
18841 // If we have pending work still, restore the original updaters
18842 restorePendingUpdaters(root, lanes);
18843 }
18844 }
18845
18846 wakeable.then(ping, ping);
18847 }
18848 }
18849
18850 function attachRetryListener(suspenseBoundary, root, wakeable, lanes) {
18851 // Retry listener
18852 //
18853 // If the fallback does commit, we need to attach a different type of
18854 // listener. This one schedules an update on the Suspense boundary to turn
18855 // the fallback state off.
18856 //
18857 // Stash the wakeable on the boundary fiber so we can access it in the
18858 // commit phase.
18859 //
18860 // When the wakeable resolves, we'll attempt to render the boundary
18861 // again ("retry").
18862 var wakeables = suspenseBoundary.updateQueue;
18863
18864 if (wakeables === null) {
18865 var updateQueue = new Set();
18866 updateQueue.add(wakeable);
18867 suspenseBoundary.updateQueue = updateQueue;
18868 } else {
18869 wakeables.add(wakeable);
18870 }
18871 }
18872
18873 function resetSuspendedComponent(sourceFiber, rootRenderLanes) {
18874 // A legacy mode Suspense quirk, only relevant to hook components.
18875
18876
18877 var tag = sourceFiber.tag;
18878
18879 if ((sourceFiber.mode & ConcurrentMode) === NoMode && (tag === FunctionComponent || tag === ForwardRef || tag === SimpleMemoComponent)) {
18880 var currentSource = sourceFiber.alternate;
18881
18882 if (currentSource) {
18883 sourceFiber.updateQueue = currentSource.updateQueue;
18884 sourceFiber.memoizedState = currentSource.memoizedState;
18885 sourceFiber.lanes = currentSource.lanes;
18886 } else {
18887 sourceFiber.updateQueue = null;
18888 sourceFiber.memoizedState = null;
18889 }
18890 }
18891 }
18892
18893 function getNearestSuspenseBoundaryToCapture(returnFiber) {
18894 var node = returnFiber;
18895
18896 do {
18897 if (node.tag === SuspenseComponent && shouldCaptureSuspense(node)) {
18898 return node;
18899 } // This boundary already captured during this render. Continue to the next
18900 // boundary.
18901
18902
18903 node = node.return;
18904 } while (node !== null);
18905
18906 return null;
18907 }
18908
18909 function markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes) {
18910 // This marks a Suspense boundary so that when we're unwinding the stack,
18911 // it captures the suspended "exception" and does a second (fallback) pass.
18912 if ((suspenseBoundary.mode & ConcurrentMode) === NoMode) {
18913 // Legacy Mode Suspense
18914 //
18915 // If the boundary is in legacy mode, we should *not*
18916 // suspend the commit. Pretend as if the suspended component rendered
18917 // null and keep rendering. When the Suspense boundary completes,
18918 // we'll do a second pass to render the fallback.
18919 if (suspenseBoundary === returnFiber) {
18920 // Special case where we suspended while reconciling the children of
18921 // a Suspense boundary's inner Offscreen wrapper fiber. This happens
18922 // when a React.lazy component is a direct child of a
18923 // Suspense boundary.
18924 //
18925 // Suspense boundaries are implemented as multiple fibers, but they
18926 // are a single conceptual unit. The legacy mode behavior where we
18927 // pretend the suspended fiber committed as `null` won't work,
18928 // because in this case the "suspended" fiber is the inner
18929 // Offscreen wrapper.
18930 //
18931 // Because the contents of the boundary haven't started rendering
18932 // yet (i.e. nothing in the tree has partially rendered) we can
18933 // switch to the regular, concurrent mode behavior: mark the
18934 // boundary with ShouldCapture and enter the unwind phase.
18935 suspenseBoundary.flags |= ShouldCapture;
18936 } else {
18937 suspenseBoundary.flags |= DidCapture;
18938 sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete.
18939 // But we shouldn't call any lifecycle methods or callbacks. Remove
18940 // all lifecycle effect tags.
18941
18942 sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete);
18943
18944 if (sourceFiber.tag === ClassComponent) {
18945 var currentSourceFiber = sourceFiber.alternate;
18946
18947 if (currentSourceFiber === null) {
18948 // This is a new mount. Change the tag so it's not mistaken for a
18949 // completed class component. For example, we should not call
18950 // componentWillUnmount if it is deleted.
18951 sourceFiber.tag = IncompleteClassComponent;
18952 } else {
18953 // When we try rendering again, we should not reuse the current fiber,
18954 // since it's known to be in an inconsistent state. Use a force update to
18955 // prevent a bail out.
18956 var update = createUpdate(NoTimestamp, SyncLane);
18957 update.tag = ForceUpdate;
18958 enqueueUpdate(sourceFiber, update, SyncLane);
18959 }
18960 } // The source fiber did not complete. Mark it with Sync priority to
18961 // indicate that it still has pending work.
18962
18963
18964 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane);
18965 }
18966
18967 return suspenseBoundary;
18968 } // Confirmed that the boundary is in a concurrent mode tree. Continue
18969 // with the normal suspend path.
18970 //
18971 // After this we'll use a set of heuristics to determine whether this
18972 // render pass will run to completion or restart or "suspend" the commit.
18973 // The actual logic for this is spread out in different places.
18974 //
18975 // This first principle is that if we're going to suspend when we complete
18976 // a root, then we should also restart if we get an update or ping that
18977 // might unsuspend it, and vice versa. The only reason to suspend is
18978 // because you think you might want to restart before committing. However,
18979 // it doesn't make sense to restart only while in the period we're suspended.
18980 //
18981 // Restarting too aggressively is also not good because it starves out any
18982 // intermediate loading state. So we use heuristics to determine when.
18983 // Suspense Heuristics
18984 //
18985 // If nothing threw a Promise or all the same fallbacks are already showing,
18986 // then don't suspend/restart.
18987 //
18988 // If this is an initial render of a new tree of Suspense boundaries and
18989 // those trigger a fallback, then don't suspend/restart. We want to ensure
18990 // that we can show the initial loading state as quickly as possible.
18991 //
18992 // If we hit a "Delayed" case, such as when we'd switch from content back into
18993 // a fallback, then we should always suspend/restart. Transitions apply
18994 // to this case. If none is defined, JND is used instead.
18995 //
18996 // If we're already showing a fallback and it gets "retried", allowing us to show
18997 // another level, but there's still an inner boundary that would show a fallback,
18998 // then we suspend/restart for 500ms since the last time we showed a fallback
18999 // anywhere in the tree. This effectively throttles progressive loading into a
19000 // consistent train of commits. This also gives us an opportunity to restart to
19001 // get to the completed state slightly earlier.
19002 //
19003 // If there's ambiguity due to batching it's resolved in preference of:
19004 // 1) "delayed", 2) "initial render", 3) "retry".
19005 //
19006 // We want to ensure that a "busy" state doesn't get force committed. We want to
19007 // ensure that new initial loading states can commit as soon as possible.
19008
19009
19010 suspenseBoundary.flags |= ShouldCapture; // TODO: I think we can remove this, since we now use `DidCapture` in
19011 // the begin phase to prevent an early bailout.
19012
19013 suspenseBoundary.lanes = rootRenderLanes;
19014 return suspenseBoundary;
19015 }
19016
19017 function throwException(root, returnFiber, sourceFiber, value, rootRenderLanes) {
19018 // The source fiber did not complete.
19019 sourceFiber.flags |= Incomplete;
19020
19021 {
19022 if (isDevToolsPresent) {
19023 // If we have pending work still, restore the original updaters
19024 restorePendingUpdaters(root, rootRenderLanes);
19025 }
19026 }
19027
19028 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
19029 // This is a wakeable. The component suspended.
19030 var wakeable = value;
19031 resetSuspendedComponent(sourceFiber);
19032
19033 {
19034 if (getIsHydrating() && sourceFiber.mode & ConcurrentMode) {
19035 markDidThrowWhileHydratingDEV();
19036 }
19037 }
19038
19039
19040 var suspenseBoundary = getNearestSuspenseBoundaryToCapture(returnFiber);
19041
19042 if (suspenseBoundary !== null) {
19043 suspenseBoundary.flags &= ~ForceClientRender;
19044 markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes); // We only attach ping listeners in concurrent mode. Legacy Suspense always
19045 // commits fallbacks synchronously, so there are no pings.
19046
19047 if (suspenseBoundary.mode & ConcurrentMode) {
19048 attachPingListener(root, wakeable, rootRenderLanes);
19049 }
19050
19051 attachRetryListener(suspenseBoundary, root, wakeable);
19052 return;
19053 } else {
19054 // No boundary was found. Unless this is a sync update, this is OK.
19055 // We can suspend and wait for more data to arrive.
19056 if (!includesSyncLane(rootRenderLanes)) {
19057 // This is not a sync update. Suspend. Since we're not activating a
19058 // Suspense boundary, this will unwind all the way to the root without
19059 // performing a second pass to render a fallback. (This is arguably how
19060 // refresh transitions should work, too, since we're not going to commit
19061 // the fallbacks anyway.)
19062 //
19063 // This case also applies to initial hydration.
19064 attachPingListener(root, wakeable, rootRenderLanes);
19065 renderDidSuspendDelayIfPossible();
19066 return;
19067 } // This is a sync/discrete update. We treat this case like an error
19068 // because discrete renders are expected to produce a complete tree
19069 // synchronously to maintain consistency with external state.
19070
19071
19072 var uncaughtSuspenseError = new Error('A component suspended while responding to synchronous input. This ' + 'will cause the UI to be replaced with a loading indicator. To ' + 'fix, updates that suspend should be wrapped ' + 'with startTransition.'); // If we're outside a transition, fall through to the regular error path.
19073 // The error will be caught by the nearest suspense boundary.
19074
19075 value = uncaughtSuspenseError;
19076 }
19077 } else {
19078 // This is a regular error, not a Suspense wakeable.
19079 if (getIsHydrating() && sourceFiber.mode & ConcurrentMode) {
19080 markDidThrowWhileHydratingDEV();
19081
19082 var _suspenseBoundary = getNearestSuspenseBoundaryToCapture(returnFiber); // If the error was thrown during hydration, we may be able to recover by
19083 // discarding the dehydrated content and switching to a client render.
19084 // Instead of surfacing the error, find the nearest Suspense boundary
19085 // and render it again without hydration.
19086
19087
19088 if (_suspenseBoundary !== null) {
19089 if ((_suspenseBoundary.flags & ShouldCapture) === NoFlags) {
19090 // Set a flag to indicate that we should try rendering the normal
19091 // children again, not the fallback.
19092 _suspenseBoundary.flags |= ForceClientRender;
19093 }
19094
19095 markSuspenseBoundaryShouldCapture(_suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes); // Even though the user may not be affected by this error, we should
19096 // still log it so it can be fixed.
19097
19098 queueHydrationError(createCapturedValueAtFiber(value, sourceFiber));
19099 return;
19100 }
19101 }
19102 }
19103
19104 value = createCapturedValueAtFiber(value, sourceFiber);
19105 renderDidError(value); // We didn't find a boundary that could handle this type of exception. Start
19106 // over and traverse parent path again, this time treating the exception
19107 // as an error.
19108
19109 var workInProgress = returnFiber;
19110
19111 do {
19112 switch (workInProgress.tag) {
19113 case HostRoot:
19114 {
19115 var _errorInfo = value;
19116 workInProgress.flags |= ShouldCapture;
19117 var lane = pickArbitraryLane(rootRenderLanes);
19118 workInProgress.lanes = mergeLanes(workInProgress.lanes, lane);
19119 var update = createRootErrorUpdate(workInProgress, _errorInfo, lane);
19120 enqueueCapturedUpdate(workInProgress, update);
19121 return;
19122 }
19123
19124 case ClassComponent:
19125 // Capture and retry
19126 var errorInfo = value;
19127 var ctor = workInProgress.type;
19128 var instance = workInProgress.stateNode;
19129
19130 if ((workInProgress.flags & DidCapture) === NoFlags && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
19131 workInProgress.flags |= ShouldCapture;
19132
19133 var _lane = pickArbitraryLane(rootRenderLanes);
19134
19135 workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state
19136
19137 var _update = createClassErrorUpdate(workInProgress, errorInfo, _lane);
19138
19139 enqueueCapturedUpdate(workInProgress, _update);
19140 return;
19141 }
19142
19143 break;
19144 }
19145
19146 workInProgress = workInProgress.return;
19147 } while (workInProgress !== null);
19148 }
19149
19150 function getSuspendedCache() {
19151 {
19152 return null;
19153 } // This function is called when a Suspense boundary suspends. It returns the
19154 }
19155
19156 var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
19157 var didReceiveUpdate = false;
19158 var didWarnAboutBadClass;
19159 var didWarnAboutModulePatternComponent;
19160 var didWarnAboutContextTypeOnFunctionComponent;
19161 var didWarnAboutGetDerivedStateOnFunctionComponent;
19162 var didWarnAboutFunctionRefs;
19163 var didWarnAboutReassigningProps;
19164 var didWarnAboutRevealOrder;
19165 var didWarnAboutTailOptions;
19166 var didWarnAboutDefaultPropsOnFunctionComponent;
19167
19168 {
19169 didWarnAboutBadClass = {};
19170 didWarnAboutModulePatternComponent = {};
19171 didWarnAboutContextTypeOnFunctionComponent = {};
19172 didWarnAboutGetDerivedStateOnFunctionComponent = {};
19173 didWarnAboutFunctionRefs = {};
19174 didWarnAboutReassigningProps = false;
19175 didWarnAboutRevealOrder = {};
19176 didWarnAboutTailOptions = {};
19177 didWarnAboutDefaultPropsOnFunctionComponent = {};
19178 }
19179
19180 function reconcileChildren(current, workInProgress, nextChildren, renderLanes) {
19181 if (current === null) {
19182 // If this is a fresh new component that hasn't been rendered yet, we
19183 // won't update its child set by applying minimal side-effects. Instead,
19184 // we will add them all to the child before it gets rendered. That means
19185 // we can optimize this reconciliation pass by not tracking side-effects.
19186 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderLanes);
19187 } else {
19188 // If the current child is the same as the work in progress, it means that
19189 // we haven't yet started any work on these children. Therefore, we use
19190 // the clone algorithm to create a copy of all the current children.
19191 // If we had any progressed work already, that is invalid at this point so
19192 // let's throw it out.
19193 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderLanes);
19194 }
19195 }
19196
19197 function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes) {
19198 // This function is fork of reconcileChildren. It's used in cases where we
19199 // want to reconcile without matching against the existing set. This has the
19200 // effect of all current children being unmounted; even if the type and key
19201 // are the same, the old child is unmounted and a new child is created.
19202 //
19203 // To do this, we're going to go through the reconcile algorithm twice. In
19204 // the first pass, we schedule a deletion for all the current children by
19205 // passing null.
19206 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderLanes); // In the second pass, we mount the new children. The trick here is that we
19207 // pass null in place of where we usually pass the current child set. This has
19208 // the effect of remounting all children regardless of whether their
19209 // identities match.
19210
19211 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes);
19212 }
19213
19214 function updateForwardRef(current, workInProgress, Component, nextProps, renderLanes) {
19215 // TODO: current can be non-null here even if the component
19216 // hasn't yet mounted. This happens after the first render suspends.
19217 // We'll need to figure out if this is fine or can cause issues.
19218 {
19219 if (workInProgress.type !== workInProgress.elementType) {
19220 // Lazy component props can't be validated in createElement
19221 // because they're only guaranteed to be resolved here.
19222 var innerPropTypes = Component.propTypes;
19223
19224 if (innerPropTypes) {
19225 checkPropTypes(innerPropTypes, nextProps, // Resolved props
19226 'prop', getComponentNameFromType(Component));
19227 }
19228 }
19229 }
19230
19231 var render = Component.render;
19232 var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent
19233
19234 var nextChildren;
19235 var hasId;
19236 prepareToReadContext(workInProgress, renderLanes);
19237
19238 {
19239 markComponentRenderStarted(workInProgress);
19240 }
19241
19242 {
19243 ReactCurrentOwner$1.current = workInProgress;
19244 setIsRendering(true);
19245 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes);
19246 hasId = checkDidRenderIdHook();
19247
19248 if ( workInProgress.mode & StrictLegacyMode) {
19249 setIsStrictModeForDevtools(true);
19250
19251 try {
19252 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes);
19253 hasId = checkDidRenderIdHook();
19254 } finally {
19255 setIsStrictModeForDevtools(false);
19256 }
19257 }
19258
19259 setIsRendering(false);
19260 }
19261
19262 {
19263 markComponentRenderStopped();
19264 }
19265
19266 if (current !== null && !didReceiveUpdate) {
19267 bailoutHooks(current, workInProgress, renderLanes);
19268 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
19269 }
19270
19271 if (getIsHydrating() && hasId) {
19272 pushMaterializedTreeId(workInProgress);
19273 } // React DevTools reads this flag.
19274
19275
19276 workInProgress.flags |= PerformedWork;
19277 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
19278 return workInProgress.child;
19279 }
19280
19281 function updateMemoComponent(current, workInProgress, Component, nextProps, renderLanes) {
19282 if (current === null) {
19283 var type = Component.type;
19284
19285 if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either.
19286 Component.defaultProps === undefined) {
19287 var resolvedType = type;
19288
19289 {
19290 resolvedType = resolveFunctionForHotReloading(type);
19291 } // If this is a plain function component without default props,
19292 // and with only the default shallow comparison, we upgrade it
19293 // to a SimpleMemoComponent to allow fast path updates.
19294
19295
19296 workInProgress.tag = SimpleMemoComponent;
19297 workInProgress.type = resolvedType;
19298
19299 {
19300 validateFunctionComponentInDev(workInProgress, type);
19301 }
19302
19303 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, renderLanes);
19304 }
19305
19306 {
19307 var innerPropTypes = type.propTypes;
19308
19309 if (innerPropTypes) {
19310 // Inner memo component props aren't currently validated in createElement.
19311 // We could move it there, but we'd still need this for lazy code path.
19312 checkPropTypes(innerPropTypes, nextProps, // Resolved props
19313 'prop', getComponentNameFromType(type));
19314 }
19315
19316 if ( Component.defaultProps !== undefined) {
19317 var componentName = getComponentNameFromType(type) || 'Unknown';
19318
19319 if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) {
19320 error('%s: Support for defaultProps will be removed from memo components ' + 'in a future major release. Use JavaScript default parameters instead.', componentName);
19321
19322 didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true;
19323 }
19324 }
19325 }
19326
19327 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, workInProgress, workInProgress.mode, renderLanes);
19328 child.ref = workInProgress.ref;
19329 child.return = workInProgress;
19330 workInProgress.child = child;
19331 return child;
19332 }
19333
19334 {
19335 var _type = Component.type;
19336 var _innerPropTypes = _type.propTypes;
19337
19338 if (_innerPropTypes) {
19339 // Inner memo component props aren't currently validated in createElement.
19340 // We could move it there, but we'd still need this for lazy code path.
19341 checkPropTypes(_innerPropTypes, nextProps, // Resolved props
19342 'prop', getComponentNameFromType(_type));
19343 }
19344 }
19345
19346 var currentChild = current.child; // This is always exactly one child
19347
19348 var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(current, renderLanes);
19349
19350 if (!hasScheduledUpdateOrContext) {
19351 // This will be the props with resolved defaultProps,
19352 // unlike current.memoizedProps which will be the unresolved ones.
19353 var prevProps = currentChild.memoizedProps; // Default to shallow comparison
19354
19355 var compare = Component.compare;
19356 compare = compare !== null ? compare : shallowEqual;
19357
19358 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
19359 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
19360 }
19361 } // React DevTools reads this flag.
19362
19363
19364 workInProgress.flags |= PerformedWork;
19365 var newChild = createWorkInProgress(currentChild, nextProps);
19366 newChild.ref = workInProgress.ref;
19367 newChild.return = workInProgress;
19368 workInProgress.child = newChild;
19369 return newChild;
19370 }
19371
19372 function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, renderLanes) {
19373 // TODO: current can be non-null here even if the component
19374 // hasn't yet mounted. This happens when the inner render suspends.
19375 // We'll need to figure out if this is fine or can cause issues.
19376 {
19377 if (workInProgress.type !== workInProgress.elementType) {
19378 // Lazy component props can't be validated in createElement
19379 // because they're only guaranteed to be resolved here.
19380 var outerMemoType = workInProgress.elementType;
19381
19382 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
19383 // We warn when you define propTypes on lazy()
19384 // so let's just skip over it to find memo() outer wrapper.
19385 // Inner props for memo are validated later.
19386 var lazyComponent = outerMemoType;
19387 var payload = lazyComponent._payload;
19388 var init = lazyComponent._init;
19389
19390 try {
19391 outerMemoType = init(payload);
19392 } catch (x) {
19393 outerMemoType = null;
19394 } // Inner propTypes will be validated in the function component path.
19395
19396
19397 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
19398
19399 if (outerPropTypes) {
19400 checkPropTypes(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
19401 'prop', getComponentNameFromType(outerMemoType));
19402 }
19403 }
19404 }
19405 }
19406
19407 if (current !== null) {
19408 var prevProps = current.memoizedProps;
19409
19410 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload.
19411 workInProgress.type === current.type )) {
19412 didReceiveUpdate = false; // The props are shallowly equal. Reuse the previous props object, like we
19413 // would during a normal fiber bailout.
19414 //
19415 // We don't have strong guarantees that the props object is referentially
19416 // equal during updates where we can't bail out anyway — like if the props
19417 // are shallowly equal, but there's a local state or context update in the
19418 // same batch.
19419 //
19420 // However, as a principle, we should aim to make the behavior consistent
19421 // across different ways of memoizing a component. For example, React.memo
19422 // has a different internal Fiber layout if you pass a normal function
19423 // component (SimpleMemoComponent) versus if you pass a different type
19424 // like forwardRef (MemoComponent). But this is an implementation detail.
19425 // Wrapping a component in forwardRef (or React.lazy, etc) shouldn't
19426 // affect whether the props object is reused during a bailout.
19427
19428 workInProgress.pendingProps = nextProps = prevProps;
19429
19430 if (!checkScheduledUpdateOrContext(current, renderLanes)) {
19431 // The pending lanes were cleared at the beginning of beginWork. We're
19432 // about to bail out, but there might be other lanes that weren't
19433 // included in the current render. Usually, the priority level of the
19434 // remaining updates is accumulated during the evaluation of the
19435 // component (i.e. when processing the update queue). But since since
19436 // we're bailing out early *without* evaluating the component, we need
19437 // to account for it here, too. Reset to the value of the current fiber.
19438 // NOTE: This only applies to SimpleMemoComponent, not MemoComponent,
19439 // because a MemoComponent fiber does not have hooks or an update queue;
19440 // rather, it wraps around an inner component, which may or may not
19441 // contains hooks.
19442 // TODO: Move the reset at in beginWork out of the common path so that
19443 // this is no longer necessary.
19444 workInProgress.lanes = current.lanes;
19445 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
19446 } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) {
19447 // This is a special case that only exists for legacy mode.
19448 // See https://github.com/facebook/react/pull/19216.
19449 didReceiveUpdate = true;
19450 }
19451 }
19452 }
19453
19454 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes);
19455 }
19456
19457 function updateOffscreenComponent(current, workInProgress, renderLanes) {
19458 var nextProps = workInProgress.pendingProps;
19459 var nextChildren = nextProps.children;
19460 var prevState = current !== null ? current.memoizedState : null;
19461
19462 if (nextProps.mode === 'hidden' || enableLegacyHidden ) {
19463 // Rendering a hidden tree.
19464 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
19465 // In legacy sync mode, don't defer the subtree. Render it now.
19466 // TODO: Consider how Offscreen should work with transitions in the future
19467 var nextState = {
19468 baseLanes: NoLanes,
19469 cachePool: null,
19470 transitions: null
19471 };
19472 workInProgress.memoizedState = nextState;
19473
19474 pushRenderLanes(workInProgress, renderLanes);
19475 } else if (!includesSomeLane(renderLanes, OffscreenLane)) {
19476 var spawnedCachePool = null; // We're hidden, and we're not rendering at Offscreen. We will bail out
19477 // and resume this tree later.
19478
19479 var nextBaseLanes;
19480
19481 if (prevState !== null) {
19482 var prevBaseLanes = prevState.baseLanes;
19483 nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes);
19484 } else {
19485 nextBaseLanes = renderLanes;
19486 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
19487
19488
19489 workInProgress.lanes = workInProgress.childLanes = laneToLanes(OffscreenLane);
19490 var _nextState = {
19491 baseLanes: nextBaseLanes,
19492 cachePool: spawnedCachePool,
19493 transitions: null
19494 };
19495 workInProgress.memoizedState = _nextState;
19496 workInProgress.updateQueue = null;
19497 // to avoid a push/pop misalignment.
19498
19499
19500 pushRenderLanes(workInProgress, nextBaseLanes);
19501
19502 return null;
19503 } else {
19504 // This is the second render. The surrounding visible content has already
19505 // committed. Now we resume rendering the hidden tree.
19506 // Rendering at offscreen, so we can clear the base lanes.
19507 var _nextState2 = {
19508 baseLanes: NoLanes,
19509 cachePool: null,
19510 transitions: null
19511 };
19512 workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out.
19513
19514 var subtreeRenderLanes = prevState !== null ? prevState.baseLanes : renderLanes;
19515
19516 pushRenderLanes(workInProgress, subtreeRenderLanes);
19517 }
19518 } else {
19519 // Rendering a visible tree.
19520 var _subtreeRenderLanes;
19521
19522 if (prevState !== null) {
19523 // We're going from hidden -> visible.
19524 _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes);
19525
19526 workInProgress.memoizedState = null;
19527 } else {
19528 // We weren't previously hidden, and we still aren't, so there's nothing
19529 // special to do. Need to push to the stack regardless, though, to avoid
19530 // a push/pop misalignment.
19531 _subtreeRenderLanes = renderLanes;
19532 }
19533
19534 pushRenderLanes(workInProgress, _subtreeRenderLanes);
19535 }
19536
19537 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
19538 return workInProgress.child;
19539 } // Note: These happen to have identical begin phases, for now. We shouldn't hold
19540
19541 function updateFragment(current, workInProgress, renderLanes) {
19542 var nextChildren = workInProgress.pendingProps;
19543 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
19544 return workInProgress.child;
19545 }
19546
19547 function updateMode(current, workInProgress, renderLanes) {
19548 var nextChildren = workInProgress.pendingProps.children;
19549 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
19550 return workInProgress.child;
19551 }
19552
19553 function updateProfiler(current, workInProgress, renderLanes) {
19554 {
19555 workInProgress.flags |= Update;
19556
19557 {
19558 // Reset effect durations for the next eventual effect phase.
19559 // These are reset during render to allow the DevTools commit hook a chance to read them,
19560 var stateNode = workInProgress.stateNode;
19561 stateNode.effectDuration = 0;
19562 stateNode.passiveEffectDuration = 0;
19563 }
19564 }
19565
19566 var nextProps = workInProgress.pendingProps;
19567 var nextChildren = nextProps.children;
19568 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
19569 return workInProgress.child;
19570 }
19571
19572 function markRef(current, workInProgress) {
19573 var ref = workInProgress.ref;
19574
19575 if (current === null && ref !== null || current !== null && current.ref !== ref) {
19576 // Schedule a Ref effect
19577 workInProgress.flags |= Ref;
19578
19579 {
19580 workInProgress.flags |= RefStatic;
19581 }
19582 }
19583 }
19584
19585 function updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes) {
19586 {
19587 if (workInProgress.type !== workInProgress.elementType) {
19588 // Lazy component props can't be validated in createElement
19589 // because they're only guaranteed to be resolved here.
19590 var innerPropTypes = Component.propTypes;
19591
19592 if (innerPropTypes) {
19593 checkPropTypes(innerPropTypes, nextProps, // Resolved props
19594 'prop', getComponentNameFromType(Component));
19595 }
19596 }
19597 }
19598
19599 var context;
19600
19601 {
19602 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
19603 context = getMaskedContext(workInProgress, unmaskedContext);
19604 }
19605
19606 var nextChildren;
19607 var hasId;
19608 prepareToReadContext(workInProgress, renderLanes);
19609
19610 {
19611 markComponentRenderStarted(workInProgress);
19612 }
19613
19614 {
19615 ReactCurrentOwner$1.current = workInProgress;
19616 setIsRendering(true);
19617 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes);
19618 hasId = checkDidRenderIdHook();
19619
19620 if ( workInProgress.mode & StrictLegacyMode) {
19621 setIsStrictModeForDevtools(true);
19622
19623 try {
19624 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes);
19625 hasId = checkDidRenderIdHook();
19626 } finally {
19627 setIsStrictModeForDevtools(false);
19628 }
19629 }
19630
19631 setIsRendering(false);
19632 }
19633
19634 {
19635 markComponentRenderStopped();
19636 }
19637
19638 if (current !== null && !didReceiveUpdate) {
19639 bailoutHooks(current, workInProgress, renderLanes);
19640 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
19641 }
19642
19643 if (getIsHydrating() && hasId) {
19644 pushMaterializedTreeId(workInProgress);
19645 } // React DevTools reads this flag.
19646
19647
19648 workInProgress.flags |= PerformedWork;
19649 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
19650 return workInProgress.child;
19651 }
19652
19653 function updateClassComponent(current, workInProgress, Component, nextProps, renderLanes) {
19654 {
19655 // This is used by DevTools to force a boundary to error.
19656 switch (shouldError(workInProgress)) {
19657 case false:
19658 {
19659 var _instance = workInProgress.stateNode;
19660 var ctor = workInProgress.type; // TODO This way of resetting the error boundary state is a hack.
19661 // Is there a better way to do this?
19662
19663 var tempInstance = new ctor(workInProgress.memoizedProps, _instance.context);
19664 var state = tempInstance.state;
19665
19666 _instance.updater.enqueueSetState(_instance, state, null);
19667
19668 break;
19669 }
19670
19671 case true:
19672 {
19673 workInProgress.flags |= DidCapture;
19674 workInProgress.flags |= ShouldCapture; // eslint-disable-next-line react-internal/prod-error-codes
19675
19676 var error$1 = new Error('Simulated error coming from DevTools');
19677 var lane = pickArbitraryLane(renderLanes);
19678 workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); // Schedule the error boundary to re-render using updated state
19679
19680 var update = createClassErrorUpdate(workInProgress, createCapturedValueAtFiber(error$1, workInProgress), lane);
19681 enqueueCapturedUpdate(workInProgress, update);
19682 break;
19683 }
19684 }
19685
19686 if (workInProgress.type !== workInProgress.elementType) {
19687 // Lazy component props can't be validated in createElement
19688 // because they're only guaranteed to be resolved here.
19689 var innerPropTypes = Component.propTypes;
19690
19691 if (innerPropTypes) {
19692 checkPropTypes(innerPropTypes, nextProps, // Resolved props
19693 'prop', getComponentNameFromType(Component));
19694 }
19695 }
19696 } // Push context providers early to prevent context stack mismatches.
19697 // During mounting we don't know the child context yet as the instance doesn't exist.
19698 // We will invalidate the child context in finishClassComponent() right after rendering.
19699
19700
19701 var hasContext;
19702
19703 if (isContextProvider(Component)) {
19704 hasContext = true;
19705 pushContextProvider(workInProgress);
19706 } else {
19707 hasContext = false;
19708 }
19709
19710 prepareToReadContext(workInProgress, renderLanes);
19711 var instance = workInProgress.stateNode;
19712 var shouldUpdate;
19713
19714 if (instance === null) {
19715 resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); // In the initial pass we might need to construct the instance.
19716
19717 constructClassInstance(workInProgress, Component, nextProps);
19718 mountClassInstance(workInProgress, Component, nextProps, renderLanes);
19719 shouldUpdate = true;
19720 } else if (current === null) {
19721 // In a resume, we'll already have an instance we can reuse.
19722 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderLanes);
19723 } else {
19724 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderLanes);
19725 }
19726
19727 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes);
19728
19729 {
19730 var inst = workInProgress.stateNode;
19731
19732 if (shouldUpdate && inst.props !== nextProps) {
19733 if (!didWarnAboutReassigningProps) {
19734 error('It looks like %s is reassigning its own `this.props` while rendering. ' + 'This is not supported and can lead to confusing bugs.', getComponentNameFromFiber(workInProgress) || 'a component');
19735 }
19736
19737 didWarnAboutReassigningProps = true;
19738 }
19739 }
19740
19741 return nextUnitOfWork;
19742 }
19743
19744 function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes) {
19745 // Refs should update even if shouldComponentUpdate returns false
19746 markRef(current, workInProgress);
19747 var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags;
19748
19749 if (!shouldUpdate && !didCaptureError) {
19750 // Context providers should defer to sCU for rendering
19751 if (hasContext) {
19752 invalidateContextProvider(workInProgress, Component, false);
19753 }
19754
19755 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
19756 }
19757
19758 var instance = workInProgress.stateNode; // Rerender
19759
19760 ReactCurrentOwner$1.current = workInProgress;
19761 var nextChildren;
19762
19763 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
19764 // If we captured an error, but getDerivedStateFromError is not defined,
19765 // unmount all the children. componentDidCatch will schedule an update to
19766 // re-render a fallback. This is temporary until we migrate everyone to
19767 // the new API.
19768 // TODO: Warn in a future release.
19769 nextChildren = null;
19770
19771 {
19772 stopProfilerTimerIfRunning();
19773 }
19774 } else {
19775 {
19776 markComponentRenderStarted(workInProgress);
19777 }
19778
19779 {
19780 setIsRendering(true);
19781 nextChildren = instance.render();
19782
19783 if ( workInProgress.mode & StrictLegacyMode) {
19784 setIsStrictModeForDevtools(true);
19785
19786 try {
19787 instance.render();
19788 } finally {
19789 setIsStrictModeForDevtools(false);
19790 }
19791 }
19792
19793 setIsRendering(false);
19794 }
19795
19796 {
19797 markComponentRenderStopped();
19798 }
19799 } // React DevTools reads this flag.
19800
19801
19802 workInProgress.flags |= PerformedWork;
19803
19804 if (current !== null && didCaptureError) {
19805 // If we're recovering from an error, reconcile without reusing any of
19806 // the existing children. Conceptually, the normal children and the children
19807 // that are shown on error are two different sets, so we shouldn't reuse
19808 // normal children even if their identities match.
19809 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes);
19810 } else {
19811 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
19812 } // Memoize state using the values we just used to render.
19813 // TODO: Restructure so we never read values from the instance.
19814
19815
19816 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.
19817
19818 if (hasContext) {
19819 invalidateContextProvider(workInProgress, Component, true);
19820 }
19821
19822 return workInProgress.child;
19823 }
19824
19825 function pushHostRootContext(workInProgress) {
19826 var root = workInProgress.stateNode;
19827
19828 if (root.pendingContext) {
19829 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
19830 } else if (root.context) {
19831 // Should always be set
19832 pushTopLevelContextObject(workInProgress, root.context, false);
19833 }
19834
19835 pushHostContainer(workInProgress, root.containerInfo);
19836 }
19837
19838 function updateHostRoot(current, workInProgress, renderLanes) {
19839 pushHostRootContext(workInProgress);
19840
19841 if (current === null) {
19842 throw new Error('Should have a current fiber. This is a bug in React.');
19843 }
19844
19845 var nextProps = workInProgress.pendingProps;
19846 var prevState = workInProgress.memoizedState;
19847 var prevChildren = prevState.element;
19848 cloneUpdateQueue(current, workInProgress);
19849 processUpdateQueue(workInProgress, nextProps, null, renderLanes);
19850 var nextState = workInProgress.memoizedState;
19851 var root = workInProgress.stateNode;
19852 // being called "element".
19853
19854
19855 var nextChildren = nextState.element;
19856
19857 if ( prevState.isDehydrated) {
19858 // This is a hydration root whose shell has not yet hydrated. We should
19859 // attempt to hydrate.
19860 // Flip isDehydrated to false to indicate that when this render
19861 // finishes, the root will no longer be dehydrated.
19862 var overrideState = {
19863 element: nextChildren,
19864 isDehydrated: false,
19865 cache: nextState.cache,
19866 pendingSuspenseBoundaries: nextState.pendingSuspenseBoundaries,
19867 transitions: nextState.transitions
19868 };
19869 var updateQueue = workInProgress.updateQueue; // `baseState` can always be the last state because the root doesn't
19870 // have reducer functions so it doesn't need rebasing.
19871
19872 updateQueue.baseState = overrideState;
19873 workInProgress.memoizedState = overrideState;
19874
19875 if (workInProgress.flags & ForceClientRender) {
19876 // Something errored during a previous attempt to hydrate the shell, so we
19877 // forced a client render.
19878 var recoverableError = createCapturedValueAtFiber(new Error('There was an error while hydrating. Because the error happened outside ' + 'of a Suspense boundary, the entire root will switch to ' + 'client rendering.'), workInProgress);
19879 return mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes, recoverableError);
19880 } else if (nextChildren !== prevChildren) {
19881 var _recoverableError = createCapturedValueAtFiber(new Error('This root received an early update, before anything was able ' + 'hydrate. Switched the entire root to client rendering.'), workInProgress);
19882
19883 return mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes, _recoverableError);
19884 } else {
19885 // The outermost shell has not hydrated yet. Start hydrating.
19886 enterHydrationState(workInProgress);
19887
19888 var child = mountChildFibers(workInProgress, null, nextChildren, renderLanes);
19889 workInProgress.child = child;
19890 var node = child;
19891
19892 while (node) {
19893 // Mark each child as hydrating. This is a fast path to know whether this
19894 // tree is part of a hydrating tree. This is used to determine if a child
19895 // node has fully mounted yet, and for scheduling event replaying.
19896 // Conceptually this is similar to Placement in that a new subtree is
19897 // inserted into the React tree here. It just happens to not need DOM
19898 // mutations because it already exists.
19899 node.flags = node.flags & ~Placement | Hydrating;
19900 node = node.sibling;
19901 }
19902 }
19903 } else {
19904 // Root is not dehydrated. Either this is a client-only root, or it
19905 // already hydrated.
19906 resetHydrationState();
19907
19908 if (nextChildren === prevChildren) {
19909 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
19910 }
19911
19912 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
19913 }
19914
19915 return workInProgress.child;
19916 }
19917
19918 function mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes, recoverableError) {
19919 // Revert to client rendering.
19920 resetHydrationState();
19921 queueHydrationError(recoverableError);
19922 workInProgress.flags |= ForceClientRender;
19923 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
19924 return workInProgress.child;
19925 }
19926
19927 function updateHostComponent(current, workInProgress, renderLanes) {
19928 pushHostContext(workInProgress);
19929
19930 if (current === null) {
19931 tryToClaimNextHydratableInstance(workInProgress);
19932 }
19933
19934 var type = workInProgress.type;
19935 var nextProps = workInProgress.pendingProps;
19936 var prevProps = current !== null ? current.memoizedProps : null;
19937 var nextChildren = nextProps.children;
19938 var isDirectTextChild = shouldSetTextContent(type, nextProps);
19939
19940 if (isDirectTextChild) {
19941 // We special case a direct text child of a host node. This is a common
19942 // case. We won't handle it as a reified child. We will instead handle
19943 // this in the host environment that also has access to this prop. That
19944 // avoids allocating another HostText fiber and traversing it.
19945 nextChildren = null;
19946 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
19947 // If we're switching from a direct text child to a normal child, or to
19948 // empty, we need to schedule the text content to be reset.
19949 workInProgress.flags |= ContentReset;
19950 }
19951
19952 markRef(current, workInProgress);
19953 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
19954 return workInProgress.child;
19955 }
19956
19957 function updateHostText(current, workInProgress) {
19958 if (current === null) {
19959 tryToClaimNextHydratableInstance(workInProgress);
19960 } // Nothing to do here. This is terminal. We'll do the completion step
19961 // immediately after.
19962
19963
19964 return null;
19965 }
19966
19967 function mountLazyComponent(_current, workInProgress, elementType, renderLanes) {
19968 resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress);
19969 var props = workInProgress.pendingProps;
19970 var lazyComponent = elementType;
19971 var payload = lazyComponent._payload;
19972 var init = lazyComponent._init;
19973 var Component = init(payload); // Store the unwrapped component in the type.
19974
19975 workInProgress.type = Component;
19976 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
19977 var resolvedProps = resolveDefaultProps(Component, props);
19978 var child;
19979
19980 switch (resolvedTag) {
19981 case FunctionComponent:
19982 {
19983 {
19984 validateFunctionComponentInDev(workInProgress, Component);
19985 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
19986 }
19987
19988 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderLanes);
19989 return child;
19990 }
19991
19992 case ClassComponent:
19993 {
19994 {
19995 workInProgress.type = Component = resolveClassForHotReloading(Component);
19996 }
19997
19998 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderLanes);
19999 return child;
20000 }
20001
20002 case ForwardRef:
20003 {
20004 {
20005 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
20006 }
20007
20008 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderLanes);
20009 return child;
20010 }
20011
20012 case MemoComponent:
20013 {
20014 {
20015 if (workInProgress.type !== workInProgress.elementType) {
20016 var outerPropTypes = Component.propTypes;
20017
20018 if (outerPropTypes) {
20019 checkPropTypes(outerPropTypes, resolvedProps, // Resolved for outer only
20020 'prop', getComponentNameFromType(Component));
20021 }
20022 }
20023 }
20024
20025 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
20026 renderLanes);
20027 return child;
20028 }
20029 }
20030
20031 var hint = '';
20032
20033 {
20034 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
20035 hint = ' Did you wrap a component in React.lazy() more than once?';
20036 }
20037 } // This message intentionally doesn't mention ForwardRef or MemoComponent
20038 // because the fact that it's a separate type of work is an
20039 // implementation detail.
20040
20041
20042 throw new Error("Element type is invalid. Received a promise that resolves to: " + Component + ". " + ("Lazy element type must resolve to a class or function." + hint));
20043 }
20044
20045 function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderLanes) {
20046 resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); // Promote the fiber to a class and try rendering again.
20047
20048 workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent`
20049 // Push context providers early to prevent context stack mismatches.
20050 // During mounting we don't know the child context yet as the instance doesn't exist.
20051 // We will invalidate the child context in finishClassComponent() right after rendering.
20052
20053 var hasContext;
20054
20055 if (isContextProvider(Component)) {
20056 hasContext = true;
20057 pushContextProvider(workInProgress);
20058 } else {
20059 hasContext = false;
20060 }
20061
20062 prepareToReadContext(workInProgress, renderLanes);
20063 constructClassInstance(workInProgress, Component, nextProps);
20064 mountClassInstance(workInProgress, Component, nextProps, renderLanes);
20065 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes);
20066 }
20067
20068 function mountIndeterminateComponent(_current, workInProgress, Component, renderLanes) {
20069 resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress);
20070 var props = workInProgress.pendingProps;
20071 var context;
20072
20073 {
20074 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
20075 context = getMaskedContext(workInProgress, unmaskedContext);
20076 }
20077
20078 prepareToReadContext(workInProgress, renderLanes);
20079 var value;
20080 var hasId;
20081
20082 {
20083 markComponentRenderStarted(workInProgress);
20084 }
20085
20086 {
20087 if (Component.prototype && typeof Component.prototype.render === 'function') {
20088 var componentName = getComponentNameFromType(Component) || 'Unknown';
20089
20090 if (!didWarnAboutBadClass[componentName]) {
20091 error("The <%s /> component appears to have a render method, but doesn't extend React.Component. " + 'This is likely to cause errors. Change %s to extend React.Component instead.', componentName, componentName);
20092
20093 didWarnAboutBadClass[componentName] = true;
20094 }
20095 }
20096
20097 if (workInProgress.mode & StrictLegacyMode) {
20098 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
20099 }
20100
20101 setIsRendering(true);
20102 ReactCurrentOwner$1.current = workInProgress;
20103 value = renderWithHooks(null, workInProgress, Component, props, context, renderLanes);
20104 hasId = checkDidRenderIdHook();
20105 setIsRendering(false);
20106 }
20107
20108 {
20109 markComponentRenderStopped();
20110 } // React DevTools reads this flag.
20111
20112
20113 workInProgress.flags |= PerformedWork;
20114
20115 {
20116 // Support for module components is deprecated and is removed behind a flag.
20117 // Whether or not it would crash later, we want to show a good message in DEV first.
20118 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
20119 var _componentName = getComponentNameFromType(Component) || 'Unknown';
20120
20121 if (!didWarnAboutModulePatternComponent[_componentName]) {
20122 error('The <%s /> component appears to be a function component that returns a class instance. ' + 'Change %s to a class that extends React.Component instead. ' + "If you can't use a class try assigning the prototype on the function as a workaround. " + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + 'cannot be called with `new` by React.', _componentName, _componentName, _componentName);
20123
20124 didWarnAboutModulePatternComponent[_componentName] = true;
20125 }
20126 }
20127 }
20128
20129 if ( // Run these checks in production only if the flag is off.
20130 // Eventually we'll delete this branch altogether.
20131 typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
20132 {
20133 var _componentName2 = getComponentNameFromType(Component) || 'Unknown';
20134
20135 if (!didWarnAboutModulePatternComponent[_componentName2]) {
20136 error('The <%s /> component appears to be a function component that returns a class instance. ' + 'Change %s to a class that extends React.Component instead. ' + "If you can't use a class try assigning the prototype on the function as a workaround. " + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + 'cannot be called with `new` by React.', _componentName2, _componentName2, _componentName2);
20137
20138 didWarnAboutModulePatternComponent[_componentName2] = true;
20139 }
20140 } // Proceed under the assumption that this is a class instance
20141
20142
20143 workInProgress.tag = ClassComponent; // Throw out any hooks that were used.
20144
20145 workInProgress.memoizedState = null;
20146 workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches.
20147 // During mounting we don't know the child context yet as the instance doesn't exist.
20148 // We will invalidate the child context in finishClassComponent() right after rendering.
20149
20150 var hasContext = false;
20151
20152 if (isContextProvider(Component)) {
20153 hasContext = true;
20154 pushContextProvider(workInProgress);
20155 } else {
20156 hasContext = false;
20157 }
20158
20159 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
20160 initializeUpdateQueue(workInProgress);
20161 adoptClassInstance(workInProgress, value);
20162 mountClassInstance(workInProgress, Component, props, renderLanes);
20163 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes);
20164 } else {
20165 // Proceed under the assumption that this is a function component
20166 workInProgress.tag = FunctionComponent;
20167
20168 {
20169
20170 if ( workInProgress.mode & StrictLegacyMode) {
20171 setIsStrictModeForDevtools(true);
20172
20173 try {
20174 value = renderWithHooks(null, workInProgress, Component, props, context, renderLanes);
20175 hasId = checkDidRenderIdHook();
20176 } finally {
20177 setIsStrictModeForDevtools(false);
20178 }
20179 }
20180 }
20181
20182 if (getIsHydrating() && hasId) {
20183 pushMaterializedTreeId(workInProgress);
20184 }
20185
20186 reconcileChildren(null, workInProgress, value, renderLanes);
20187
20188 {
20189 validateFunctionComponentInDev(workInProgress, Component);
20190 }
20191
20192 return workInProgress.child;
20193 }
20194 }
20195
20196 function validateFunctionComponentInDev(workInProgress, Component) {
20197 {
20198 if (Component) {
20199 if (Component.childContextTypes) {
20200 error('%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component');
20201 }
20202 }
20203
20204 if (workInProgress.ref !== null) {
20205 var info = '';
20206 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
20207
20208 if (ownerName) {
20209 info += '\n\nCheck the render method of `' + ownerName + '`.';
20210 }
20211
20212 var warningKey = ownerName || '';
20213 var debugSource = workInProgress._debugSource;
20214
20215 if (debugSource) {
20216 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
20217 }
20218
20219 if (!didWarnAboutFunctionRefs[warningKey]) {
20220 didWarnAboutFunctionRefs[warningKey] = true;
20221
20222 error('Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
20223 }
20224 }
20225
20226 if ( Component.defaultProps !== undefined) {
20227 var componentName = getComponentNameFromType(Component) || 'Unknown';
20228
20229 if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) {
20230 error('%s: Support for defaultProps will be removed from function components ' + 'in a future major release. Use JavaScript default parameters instead.', componentName);
20231
20232 didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true;
20233 }
20234 }
20235
20236 if (typeof Component.getDerivedStateFromProps === 'function') {
20237 var _componentName3 = getComponentNameFromType(Component) || 'Unknown';
20238
20239 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) {
20240 error('%s: Function components do not support getDerivedStateFromProps.', _componentName3);
20241
20242 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true;
20243 }
20244 }
20245
20246 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
20247 var _componentName4 = getComponentNameFromType(Component) || 'Unknown';
20248
20249 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) {
20250 error('%s: Function components do not support contextType.', _componentName4);
20251
20252 didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true;
20253 }
20254 }
20255 }
20256 }
20257
20258 var SUSPENDED_MARKER = {
20259 dehydrated: null,
20260 treeContext: null,
20261 retryLane: NoLane
20262 };
20263
20264 function mountSuspenseOffscreenState(renderLanes) {
20265 return {
20266 baseLanes: renderLanes,
20267 cachePool: getSuspendedCache(),
20268 transitions: null
20269 };
20270 }
20271
20272 function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) {
20273 var cachePool = null;
20274
20275 return {
20276 baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes),
20277 cachePool: cachePool,
20278 transitions: prevOffscreenState.transitions
20279 };
20280 } // TODO: Probably should inline this back
20281
20282
20283 function shouldRemainOnFallback(suspenseContext, current, workInProgress, renderLanes) {
20284 // If we're already showing a fallback, there are cases where we need to
20285 // remain on that fallback regardless of whether the content has resolved.
20286 // For example, SuspenseList coordinates when nested content appears.
20287 if (current !== null) {
20288 var suspenseState = current.memoizedState;
20289
20290 if (suspenseState === null) {
20291 // Currently showing content. Don't hide it, even if ForceSuspenseFallback
20292 // is true. More precise name might be "ForceRemainSuspenseFallback".
20293 // Note: This is a factoring smell. Can't remain on a fallback if there's
20294 // no fallback to remain on.
20295 return false;
20296 }
20297 } // Not currently showing content. Consult the Suspense context.
20298
20299
20300 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
20301 }
20302
20303 function getRemainingWorkInPrimaryTree(current, renderLanes) {
20304 // TODO: Should not remove render lanes that were pinged during this render
20305 return removeLanes(current.childLanes, renderLanes);
20306 }
20307
20308 function updateSuspenseComponent(current, workInProgress, renderLanes) {
20309 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
20310
20311 {
20312 if (shouldSuspend(workInProgress)) {
20313 workInProgress.flags |= DidCapture;
20314 }
20315 }
20316
20317 var suspenseContext = suspenseStackCursor.current;
20318 var showFallback = false;
20319 var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags;
20320
20321 if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) {
20322 // Something in this boundary's subtree already suspended. Switch to
20323 // rendering the fallback children.
20324 showFallback = true;
20325 workInProgress.flags &= ~DidCapture;
20326 } else {
20327 // Attempting the main content
20328 if (current === null || current.memoizedState !== null) {
20329 // This is a new mount or this boundary is already showing a fallback state.
20330 // Mark this subtree context as having at least one invisible parent that could
20331 // handle the fallback state.
20332 // Avoided boundaries are not considered since they cannot handle preferred fallback states.
20333 {
20334 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
20335 }
20336 }
20337 }
20338
20339 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
20340 pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense
20341 // boundary's children. This involves some custom reconciliation logic. Two
20342 // main reasons this is so complicated.
20343 //
20344 // First, Legacy Mode has different semantics for backwards compatibility. The
20345 // primary tree will commit in an inconsistent state, so when we do the
20346 // second pass to render the fallback, we do some exceedingly, uh, clever
20347 // hacks to make that not totally break. Like transferring effects and
20348 // deletions from hidden tree. In Concurrent Mode, it's much simpler,
20349 // because we bailout on the primary tree completely and leave it in its old
20350 // state, no effects. Same as what we do for Offscreen (except that
20351 // Offscreen doesn't have the first render pass).
20352 //
20353 // Second is hydration. During hydration, the Suspense fiber has a slightly
20354 // different layout, where the child points to a dehydrated fragment, which
20355 // contains the DOM rendered by the server.
20356 //
20357 // Third, even if you set all that aside, Suspense is like error boundaries in
20358 // that we first we try to render one tree, and if that fails, we render again
20359 // and switch to a different tree. Like a try/catch block. So we have to track
20360 // which branch we're currently rendering. Ideally we would model this using
20361 // a stack.
20362
20363 if (current === null) {
20364 // Initial mount
20365 // Special path for hydration
20366 // If we're currently hydrating, try to hydrate this boundary.
20367 tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component.
20368
20369 var suspenseState = workInProgress.memoizedState;
20370
20371 if (suspenseState !== null) {
20372 var dehydrated = suspenseState.dehydrated;
20373
20374 if (dehydrated !== null) {
20375 return mountDehydratedSuspenseComponent(workInProgress, dehydrated);
20376 }
20377 }
20378
20379 var nextPrimaryChildren = nextProps.children;
20380 var nextFallbackChildren = nextProps.fallback;
20381
20382 if (showFallback) {
20383 var fallbackFragment = mountSuspenseFallbackChildren(workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes);
20384 var primaryChildFragment = workInProgress.child;
20385 primaryChildFragment.memoizedState = mountSuspenseOffscreenState(renderLanes);
20386 workInProgress.memoizedState = SUSPENDED_MARKER;
20387
20388 return fallbackFragment;
20389 } else {
20390 return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren);
20391 }
20392 } else {
20393 // This is an update.
20394 // Special path for hydration
20395 var prevState = current.memoizedState;
20396
20397 if (prevState !== null) {
20398 var _dehydrated = prevState.dehydrated;
20399
20400 if (_dehydrated !== null) {
20401 return updateDehydratedSuspenseComponent(current, workInProgress, didSuspend, nextProps, _dehydrated, prevState, renderLanes);
20402 }
20403 }
20404
20405 if (showFallback) {
20406 var _nextFallbackChildren = nextProps.fallback;
20407 var _nextPrimaryChildren = nextProps.children;
20408 var fallbackChildFragment = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren, _nextFallbackChildren, renderLanes);
20409 var _primaryChildFragment2 = workInProgress.child;
20410 var prevOffscreenState = current.child.memoizedState;
20411 _primaryChildFragment2.memoizedState = prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(prevOffscreenState, renderLanes);
20412
20413 _primaryChildFragment2.childLanes = getRemainingWorkInPrimaryTree(current, renderLanes);
20414 workInProgress.memoizedState = SUSPENDED_MARKER;
20415 return fallbackChildFragment;
20416 } else {
20417 var _nextPrimaryChildren2 = nextProps.children;
20418
20419 var _primaryChildFragment3 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren2, renderLanes);
20420
20421 workInProgress.memoizedState = null;
20422 return _primaryChildFragment3;
20423 }
20424 }
20425 }
20426
20427 function mountSuspensePrimaryChildren(workInProgress, primaryChildren, renderLanes) {
20428 var mode = workInProgress.mode;
20429 var primaryChildProps = {
20430 mode: 'visible',
20431 children: primaryChildren
20432 };
20433 var primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, mode);
20434 primaryChildFragment.return = workInProgress;
20435 workInProgress.child = primaryChildFragment;
20436 return primaryChildFragment;
20437 }
20438
20439 function mountSuspenseFallbackChildren(workInProgress, primaryChildren, fallbackChildren, renderLanes) {
20440 var mode = workInProgress.mode;
20441 var progressedPrimaryFragment = workInProgress.child;
20442 var primaryChildProps = {
20443 mode: 'hidden',
20444 children: primaryChildren
20445 };
20446 var primaryChildFragment;
20447 var fallbackChildFragment;
20448
20449 if ((mode & ConcurrentMode) === NoMode && progressedPrimaryFragment !== null) {
20450 // In legacy mode, we commit the primary tree as if it successfully
20451 // completed, even though it's in an inconsistent state.
20452 primaryChildFragment = progressedPrimaryFragment;
20453 primaryChildFragment.childLanes = NoLanes;
20454 primaryChildFragment.pendingProps = primaryChildProps;
20455
20456 if ( workInProgress.mode & ProfileMode) {
20457 // Reset the durations from the first pass so they aren't included in the
20458 // final amounts. This seems counterintuitive, since we're intentionally
20459 // not measuring part of the render phase, but this makes it match what we
20460 // do in Concurrent Mode.
20461 primaryChildFragment.actualDuration = 0;
20462 primaryChildFragment.actualStartTime = -1;
20463 primaryChildFragment.selfBaseDuration = 0;
20464 primaryChildFragment.treeBaseDuration = 0;
20465 }
20466
20467 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null);
20468 } else {
20469 primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, mode);
20470 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null);
20471 }
20472
20473 primaryChildFragment.return = workInProgress;
20474 fallbackChildFragment.return = workInProgress;
20475 primaryChildFragment.sibling = fallbackChildFragment;
20476 workInProgress.child = primaryChildFragment;
20477 return fallbackChildFragment;
20478 }
20479
20480 function mountWorkInProgressOffscreenFiber(offscreenProps, mode, renderLanes) {
20481 // The props argument to `createFiberFromOffscreen` is `any` typed, so we use
20482 // this wrapper function to constrain it.
20483 return createFiberFromOffscreen(offscreenProps, mode, NoLanes, null);
20484 }
20485
20486 function updateWorkInProgressOffscreenFiber(current, offscreenProps) {
20487 // The props argument to `createWorkInProgress` is `any` typed, so we use this
20488 // wrapper function to constrain it.
20489 return createWorkInProgress(current, offscreenProps);
20490 }
20491
20492 function updateSuspensePrimaryChildren(current, workInProgress, primaryChildren, renderLanes) {
20493 var currentPrimaryChildFragment = current.child;
20494 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
20495 var primaryChildFragment = updateWorkInProgressOffscreenFiber(currentPrimaryChildFragment, {
20496 mode: 'visible',
20497 children: primaryChildren
20498 });
20499
20500 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
20501 primaryChildFragment.lanes = renderLanes;
20502 }
20503
20504 primaryChildFragment.return = workInProgress;
20505 primaryChildFragment.sibling = null;
20506
20507 if (currentFallbackChildFragment !== null) {
20508 // Delete the fallback child fragment
20509 var deletions = workInProgress.deletions;
20510
20511 if (deletions === null) {
20512 workInProgress.deletions = [currentFallbackChildFragment];
20513 workInProgress.flags |= ChildDeletion;
20514 } else {
20515 deletions.push(currentFallbackChildFragment);
20516 }
20517 }
20518
20519 workInProgress.child = primaryChildFragment;
20520 return primaryChildFragment;
20521 }
20522
20523 function updateSuspenseFallbackChildren(current, workInProgress, primaryChildren, fallbackChildren, renderLanes) {
20524 var mode = workInProgress.mode;
20525 var currentPrimaryChildFragment = current.child;
20526 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
20527 var primaryChildProps = {
20528 mode: 'hidden',
20529 children: primaryChildren
20530 };
20531 var primaryChildFragment;
20532
20533 if ( // In legacy mode, we commit the primary tree as if it successfully
20534 // completed, even though it's in an inconsistent state.
20535 (mode & ConcurrentMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was
20536 // already cloned. In legacy mode, the only case where this isn't true is
20537 // when DevTools forces us to display a fallback; we skip the first render
20538 // pass entirely and go straight to rendering the fallback. (In Concurrent
20539 // Mode, SuspenseList can also trigger this scenario, but this is a legacy-
20540 // only codepath.)
20541 workInProgress.child !== currentPrimaryChildFragment) {
20542 var progressedPrimaryFragment = workInProgress.child;
20543 primaryChildFragment = progressedPrimaryFragment;
20544 primaryChildFragment.childLanes = NoLanes;
20545 primaryChildFragment.pendingProps = primaryChildProps;
20546
20547 if ( workInProgress.mode & ProfileMode) {
20548 // Reset the durations from the first pass so they aren't included in the
20549 // final amounts. This seems counterintuitive, since we're intentionally
20550 // not measuring part of the render phase, but this makes it match what we
20551 // do in Concurrent Mode.
20552 primaryChildFragment.actualDuration = 0;
20553 primaryChildFragment.actualStartTime = -1;
20554 primaryChildFragment.selfBaseDuration = currentPrimaryChildFragment.selfBaseDuration;
20555 primaryChildFragment.treeBaseDuration = currentPrimaryChildFragment.treeBaseDuration;
20556 } // The fallback fiber was added as a deletion during the first pass.
20557 // However, since we're going to remain on the fallback, we no longer want
20558 // to delete it.
20559
20560
20561 workInProgress.deletions = null;
20562 } else {
20563 primaryChildFragment = updateWorkInProgressOffscreenFiber(currentPrimaryChildFragment, primaryChildProps); // Since we're reusing a current tree, we need to reuse the flags, too.
20564 // (We don't do this in legacy mode, because in legacy mode we don't re-use
20565 // the current tree; see previous branch.)
20566
20567 primaryChildFragment.subtreeFlags = currentPrimaryChildFragment.subtreeFlags & StaticMask;
20568 }
20569
20570 var fallbackChildFragment;
20571
20572 if (currentFallbackChildFragment !== null) {
20573 fallbackChildFragment = createWorkInProgress(currentFallbackChildFragment, fallbackChildren);
20574 } else {
20575 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null); // Needs a placement effect because the parent (the Suspense boundary) already
20576 // mounted but this is a new fiber.
20577
20578 fallbackChildFragment.flags |= Placement;
20579 }
20580
20581 fallbackChildFragment.return = workInProgress;
20582 primaryChildFragment.return = workInProgress;
20583 primaryChildFragment.sibling = fallbackChildFragment;
20584 workInProgress.child = primaryChildFragment;
20585 return fallbackChildFragment;
20586 }
20587
20588 function retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, recoverableError) {
20589 // Falling back to client rendering. Because this has performance
20590 // implications, it's considered a recoverable error, even though the user
20591 // likely won't observe anything wrong with the UI.
20592 //
20593 // The error is passed in as an argument to enforce that every caller provide
20594 // a custom message, or explicitly opt out (currently the only path that opts
20595 // out is legacy mode; every concurrent path provides an error).
20596 if (recoverableError !== null) {
20597 queueHydrationError(recoverableError);
20598 } // This will add the old fiber to the deletion list
20599
20600
20601 reconcileChildFibers(workInProgress, current.child, null, renderLanes); // We're now not suspended nor dehydrated.
20602
20603 var nextProps = workInProgress.pendingProps;
20604 var primaryChildren = nextProps.children;
20605 var primaryChildFragment = mountSuspensePrimaryChildren(workInProgress, primaryChildren); // Needs a placement effect because the parent (the Suspense boundary) already
20606 // mounted but this is a new fiber.
20607
20608 primaryChildFragment.flags |= Placement;
20609 workInProgress.memoizedState = null;
20610 return primaryChildFragment;
20611 }
20612
20613 function mountSuspenseFallbackAfterRetryWithoutHydrating(current, workInProgress, primaryChildren, fallbackChildren, renderLanes) {
20614 var fiberMode = workInProgress.mode;
20615 var primaryChildProps = {
20616 mode: 'visible',
20617 children: primaryChildren
20618 };
20619 var primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, fiberMode);
20620 var fallbackChildFragment = createFiberFromFragment(fallbackChildren, fiberMode, renderLanes, null); // Needs a placement effect because the parent (the Suspense
20621 // boundary) already mounted but this is a new fiber.
20622
20623 fallbackChildFragment.flags |= Placement;
20624 primaryChildFragment.return = workInProgress;
20625 fallbackChildFragment.return = workInProgress;
20626 primaryChildFragment.sibling = fallbackChildFragment;
20627 workInProgress.child = primaryChildFragment;
20628
20629 if ((workInProgress.mode & ConcurrentMode) !== NoMode) {
20630 // We will have dropped the effect list which contains the
20631 // deletion. We need to reconcile to delete the current child.
20632 reconcileChildFibers(workInProgress, current.child, null, renderLanes);
20633 }
20634
20635 return fallbackChildFragment;
20636 }
20637
20638 function mountDehydratedSuspenseComponent(workInProgress, suspenseInstance, renderLanes) {
20639 // During the first pass, we'll bail out and not drill into the children.
20640 // Instead, we'll leave the content in place and try to hydrate it later.
20641 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
20642 {
20643 error('Cannot hydrate Suspense in legacy mode. Switch from ' + 'ReactDOM.hydrate(element, container) to ' + 'ReactDOMClient.hydrateRoot(container, <App />)' + '.render(element) or remove the Suspense components from ' + 'the server rendered components.');
20644 }
20645
20646 workInProgress.lanes = laneToLanes(SyncLane);
20647 } else if (isSuspenseInstanceFallback(suspenseInstance)) {
20648 // This is a client-only boundary. Since we won't get any content from the server
20649 // for this, we need to schedule that at a higher priority based on when it would
20650 // have timed out. In theory we could render it in this pass but it would have the
20651 // wrong priority associated with it and will prevent hydration of parent path.
20652 // Instead, we'll leave work left on it to render it in a separate commit.
20653 // TODO This time should be the time at which the server rendered response that is
20654 // a parent to this boundary was displayed. However, since we currently don't have
20655 // a protocol to transfer that time, we'll just estimate it by using the current
20656 // time. This will mean that Suspense timeouts are slightly shifted to later than
20657 // they should be.
20658 // Schedule a normal pri update to render this content.
20659 workInProgress.lanes = laneToLanes(DefaultHydrationLane);
20660 } else {
20661 // We'll continue hydrating the rest at offscreen priority since we'll already
20662 // be showing the right content coming from the server, it is no rush.
20663 workInProgress.lanes = laneToLanes(OffscreenLane);
20664 }
20665
20666 return null;
20667 }
20668
20669 function updateDehydratedSuspenseComponent(current, workInProgress, didSuspend, nextProps, suspenseInstance, suspenseState, renderLanes) {
20670 if (!didSuspend) {
20671 // This is the first render pass. Attempt to hydrate.
20672 // We should never be hydrating at this point because it is the first pass,
20673 // but after we've already committed once.
20674 warnIfHydrating();
20675
20676 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
20677 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, // TODO: When we delete legacy mode, we should make this error argument
20678 // required — every concurrent mode path that causes hydration to
20679 // de-opt to client rendering should have an error message.
20680 null);
20681 }
20682
20683 if (isSuspenseInstanceFallback(suspenseInstance)) {
20684 // This boundary is in a permanent fallback state. In this case, we'll never
20685 // get an update and we'll never be able to hydrate the final content. Let's just try the
20686 // client side render instead.
20687 var digest, message, stack;
20688
20689 {
20690 var _getSuspenseInstanceF = getSuspenseInstanceFallbackErrorDetails(suspenseInstance);
20691
20692 digest = _getSuspenseInstanceF.digest;
20693 message = _getSuspenseInstanceF.message;
20694 stack = _getSuspenseInstanceF.stack;
20695 }
20696
20697 var error;
20698
20699 if (message) {
20700 // eslint-disable-next-line react-internal/prod-error-codes
20701 error = new Error(message);
20702 } else {
20703 error = new Error('The server could not finish this Suspense boundary, likely ' + 'due to an error during server rendering. Switched to ' + 'client rendering.');
20704 }
20705
20706 var capturedValue = createCapturedValue(error, digest, stack);
20707 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, capturedValue);
20708 }
20709 // any context has changed, we need to treat is as if the input might have changed.
20710
20711
20712 var hasContextChanged = includesSomeLane(renderLanes, current.childLanes);
20713
20714 if (didReceiveUpdate || hasContextChanged) {
20715 // This boundary has changed since the first render. This means that we are now unable to
20716 // hydrate it. We might still be able to hydrate it using a higher priority lane.
20717 var root = getWorkInProgressRoot();
20718
20719 if (root !== null) {
20720 var attemptHydrationAtLane = getBumpedLaneForHydration(root, renderLanes);
20721
20722 if (attemptHydrationAtLane !== NoLane && attemptHydrationAtLane !== suspenseState.retryLane) {
20723 // Intentionally mutating since this render will get interrupted. This
20724 // is one of the very rare times where we mutate the current tree
20725 // during the render phase.
20726 suspenseState.retryLane = attemptHydrationAtLane; // TODO: Ideally this would inherit the event time of the current render
20727
20728 var eventTime = NoTimestamp;
20729 enqueueConcurrentRenderForLane(current, attemptHydrationAtLane);
20730 scheduleUpdateOnFiber(root, current, attemptHydrationAtLane, eventTime);
20731 }
20732 } // If we have scheduled higher pri work above, this will probably just abort the render
20733 // since we now have higher priority work, but in case it doesn't, we need to prepare to
20734 // render something, if we time out. Even if that requires us to delete everything and
20735 // skip hydration.
20736 // Delay having to do this as long as the suspense timeout allows us.
20737
20738
20739 renderDidSuspendDelayIfPossible();
20740
20741 var _capturedValue = createCapturedValue(new Error('This Suspense boundary received an update before it finished ' + 'hydrating. This caused the boundary to switch to client rendering. ' + 'The usual way to fix this is to wrap the original update ' + 'in startTransition.'));
20742
20743 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, _capturedValue);
20744 } else if (isSuspenseInstancePending(suspenseInstance)) {
20745 // This component is still pending more data from the server, so we can't hydrate its
20746 // content. We treat it as if this component suspended itself. It might seem as if
20747 // we could just try to render it client-side instead. However, this will perform a
20748 // lot of unnecessary work and is unlikely to complete since it often will suspend
20749 // on missing data anyway. Additionally, the server might be able to render more
20750 // than we can on the client yet. In that case we'd end up with more fallback states
20751 // on the client than if we just leave it alone. If the server times out or errors
20752 // these should update this boundary to the permanent Fallback state instead.
20753 // Mark it as having captured (i.e. suspended).
20754 workInProgress.flags |= DidCapture; // Leave the child in place. I.e. the dehydrated fragment.
20755
20756 workInProgress.child = current.child; // Register a callback to retry this boundary once the server has sent the result.
20757
20758 var retry = retryDehydratedSuspenseBoundary.bind(null, current);
20759 registerSuspenseInstanceRetry(suspenseInstance, retry);
20760 return null;
20761 } else {
20762 // This is the first attempt.
20763 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress, suspenseInstance, suspenseState.treeContext);
20764 var primaryChildren = nextProps.children;
20765 var primaryChildFragment = mountSuspensePrimaryChildren(workInProgress, primaryChildren); // Mark the children as hydrating. This is a fast path to know whether this
20766 // tree is part of a hydrating tree. This is used to determine if a child
20767 // node has fully mounted yet, and for scheduling event replaying.
20768 // Conceptually this is similar to Placement in that a new subtree is
20769 // inserted into the React tree here. It just happens to not need DOM
20770 // mutations because it already exists.
20771
20772 primaryChildFragment.flags |= Hydrating;
20773 return primaryChildFragment;
20774 }
20775 } else {
20776 // This is the second render pass. We already attempted to hydrated, but
20777 // something either suspended or errored.
20778 if (workInProgress.flags & ForceClientRender) {
20779 // Something errored during hydration. Try again without hydrating.
20780 workInProgress.flags &= ~ForceClientRender;
20781
20782 var _capturedValue2 = createCapturedValue(new Error('There was an error while hydrating this Suspense boundary. ' + 'Switched to client rendering.'));
20783
20784 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, _capturedValue2);
20785 } else if (workInProgress.memoizedState !== null) {
20786 // Something suspended and we should still be in dehydrated mode.
20787 // Leave the existing child in place.
20788 workInProgress.child = current.child; // The dehydrated completion pass expects this flag to be there
20789 // but the normal suspense pass doesn't.
20790
20791 workInProgress.flags |= DidCapture;
20792 return null;
20793 } else {
20794 // Suspended but we should no longer be in dehydrated mode.
20795 // Therefore we now have to render the fallback.
20796 var nextPrimaryChildren = nextProps.children;
20797 var nextFallbackChildren = nextProps.fallback;
20798 var fallbackChildFragment = mountSuspenseFallbackAfterRetryWithoutHydrating(current, workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes);
20799 var _primaryChildFragment4 = workInProgress.child;
20800 _primaryChildFragment4.memoizedState = mountSuspenseOffscreenState(renderLanes);
20801 workInProgress.memoizedState = SUSPENDED_MARKER;
20802 return fallbackChildFragment;
20803 }
20804 }
20805 }
20806
20807 function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) {
20808 fiber.lanes = mergeLanes(fiber.lanes, renderLanes);
20809 var alternate = fiber.alternate;
20810
20811 if (alternate !== null) {
20812 alternate.lanes = mergeLanes(alternate.lanes, renderLanes);
20813 }
20814
20815 scheduleContextWorkOnParentPath(fiber.return, renderLanes, propagationRoot);
20816 }
20817
20818 function propagateSuspenseContextChange(workInProgress, firstChild, renderLanes) {
20819 // Mark any Suspense boundaries with fallbacks as having work to do.
20820 // If they were previously forced into fallbacks, they may now be able
20821 // to unblock.
20822 var node = firstChild;
20823
20824 while (node !== null) {
20825 if (node.tag === SuspenseComponent) {
20826 var state = node.memoizedState;
20827
20828 if (state !== null) {
20829 scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress);
20830 }
20831 } else if (node.tag === SuspenseListComponent) {
20832 // If the tail is hidden there might not be an Suspense boundaries
20833 // to schedule work on. In this case we have to schedule it on the
20834 // list itself.
20835 // We don't have to traverse to the children of the list since
20836 // the list will propagate the change when it rerenders.
20837 scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress);
20838 } else if (node.child !== null) {
20839 node.child.return = node;
20840 node = node.child;
20841 continue;
20842 }
20843
20844 if (node === workInProgress) {
20845 return;
20846 }
20847
20848 while (node.sibling === null) {
20849 if (node.return === null || node.return === workInProgress) {
20850 return;
20851 }
20852
20853 node = node.return;
20854 }
20855
20856 node.sibling.return = node.return;
20857 node = node.sibling;
20858 }
20859 }
20860
20861 function findLastContentRow(firstChild) {
20862 // This is going to find the last row among these children that is already
20863 // showing content on the screen, as opposed to being in fallback state or
20864 // new. If a row has multiple Suspense boundaries, any of them being in the
20865 // fallback state, counts as the whole row being in a fallback state.
20866 // Note that the "rows" will be workInProgress, but any nested children
20867 // will still be current since we haven't rendered them yet. The mounted
20868 // order may not be the same as the new order. We use the new order.
20869 var row = firstChild;
20870 var lastContentRow = null;
20871
20872 while (row !== null) {
20873 var currentRow = row.alternate; // New rows can't be content rows.
20874
20875 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
20876 lastContentRow = row;
20877 }
20878
20879 row = row.sibling;
20880 }
20881
20882 return lastContentRow;
20883 }
20884
20885 function validateRevealOrder(revealOrder) {
20886 {
20887 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
20888 didWarnAboutRevealOrder[revealOrder] = true;
20889
20890 if (typeof revealOrder === 'string') {
20891 switch (revealOrder.toLowerCase()) {
20892 case 'together':
20893 case 'forwards':
20894 case 'backwards':
20895 {
20896 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
20897
20898 break;
20899 }
20900
20901 case 'forward':
20902 case 'backward':
20903 {
20904 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase());
20905
20906 break;
20907 }
20908
20909 default:
20910 error('"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
20911
20912 break;
20913 }
20914 } else {
20915 error('%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
20916 }
20917 }
20918 }
20919 }
20920
20921 function validateTailOptions(tailMode, revealOrder) {
20922 {
20923 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
20924 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
20925 didWarnAboutTailOptions[tailMode] = true;
20926
20927 error('"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
20928 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
20929 didWarnAboutTailOptions[tailMode] = true;
20930
20931 error('<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
20932 }
20933 }
20934 }
20935 }
20936
20937 function validateSuspenseListNestedChild(childSlot, index) {
20938 {
20939 var isAnArray = isArray(childSlot);
20940 var isIterable = !isAnArray && typeof getIteratorFn(childSlot) === 'function';
20941
20942 if (isAnArray || isIterable) {
20943 var type = isAnArray ? 'array' : 'iterable';
20944
20945 error('A nested %s was passed to row #%s in <SuspenseList />. Wrap it in ' + 'an additional SuspenseList to configure its revealOrder: ' + '<SuspenseList revealOrder=...> ... ' + '<SuspenseList revealOrder=...>{%s}</SuspenseList> ... ' + '</SuspenseList>', type, index, type);
20946
20947 return false;
20948 }
20949 }
20950
20951 return true;
20952 }
20953
20954 function validateSuspenseListChildren(children, revealOrder) {
20955 {
20956 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
20957 if (isArray(children)) {
20958 for (var i = 0; i < children.length; i++) {
20959 if (!validateSuspenseListNestedChild(children[i], i)) {
20960 return;
20961 }
20962 }
20963 } else {
20964 var iteratorFn = getIteratorFn(children);
20965
20966 if (typeof iteratorFn === 'function') {
20967 var childrenIterator = iteratorFn.call(children);
20968
20969 if (childrenIterator) {
20970 var step = childrenIterator.next();
20971 var _i = 0;
20972
20973 for (; !step.done; step = childrenIterator.next()) {
20974 if (!validateSuspenseListNestedChild(step.value, _i)) {
20975 return;
20976 }
20977
20978 _i++;
20979 }
20980 }
20981 } else {
20982 error('A single row was passed to a <SuspenseList revealOrder="%s" />. ' + 'This is not useful since it needs multiple rows. ' + 'Did you mean to pass multiple children or an array?', revealOrder);
20983 }
20984 }
20985 }
20986 }
20987 }
20988
20989 function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode) {
20990 var renderState = workInProgress.memoizedState;
20991
20992 if (renderState === null) {
20993 workInProgress.memoizedState = {
20994 isBackwards: isBackwards,
20995 rendering: null,
20996 renderingStartTime: 0,
20997 last: lastContentRow,
20998 tail: tail,
20999 tailMode: tailMode
21000 };
21001 } else {
21002 // We can reuse the existing object from previous renders.
21003 renderState.isBackwards = isBackwards;
21004 renderState.rendering = null;
21005 renderState.renderingStartTime = 0;
21006 renderState.last = lastContentRow;
21007 renderState.tail = tail;
21008 renderState.tailMode = tailMode;
21009 }
21010 } // This can end up rendering this component multiple passes.
21011 // The first pass splits the children fibers into two sets. A head and tail.
21012 // We first render the head. If anything is in fallback state, we do another
21013 // pass through beginWork to rerender all children (including the tail) with
21014 // the force suspend context. If the first render didn't have anything in
21015 // in fallback state. Then we render each row in the tail one-by-one.
21016 // That happens in the completeWork phase without going back to beginWork.
21017
21018
21019 function updateSuspenseListComponent(current, workInProgress, renderLanes) {
21020 var nextProps = workInProgress.pendingProps;
21021 var revealOrder = nextProps.revealOrder;
21022 var tailMode = nextProps.tail;
21023 var newChildren = nextProps.children;
21024 validateRevealOrder(revealOrder);
21025 validateTailOptions(tailMode, revealOrder);
21026 validateSuspenseListChildren(newChildren, revealOrder);
21027 reconcileChildren(current, workInProgress, newChildren, renderLanes);
21028 var suspenseContext = suspenseStackCursor.current;
21029 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
21030
21031 if (shouldForceFallback) {
21032 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
21033 workInProgress.flags |= DidCapture;
21034 } else {
21035 var didSuspendBefore = current !== null && (current.flags & DidCapture) !== NoFlags;
21036
21037 if (didSuspendBefore) {
21038 // If we previously forced a fallback, we need to schedule work
21039 // on any nested boundaries to let them know to try to render
21040 // again. This is the same as context updating.
21041 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderLanes);
21042 }
21043
21044 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
21045 }
21046
21047 pushSuspenseContext(workInProgress, suspenseContext);
21048
21049 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
21050 // In legacy mode, SuspenseList doesn't work so we just
21051 // use make it a noop by treating it as the default revealOrder.
21052 workInProgress.memoizedState = null;
21053 } else {
21054 switch (revealOrder) {
21055 case 'forwards':
21056 {
21057 var lastContentRow = findLastContentRow(workInProgress.child);
21058 var tail;
21059
21060 if (lastContentRow === null) {
21061 // The whole list is part of the tail.
21062 // TODO: We could fast path by just rendering the tail now.
21063 tail = workInProgress.child;
21064 workInProgress.child = null;
21065 } else {
21066 // Disconnect the tail rows after the content row.
21067 // We're going to render them separately later.
21068 tail = lastContentRow.sibling;
21069 lastContentRow.sibling = null;
21070 }
21071
21072 initSuspenseListRenderState(workInProgress, false, // isBackwards
21073 tail, lastContentRow, tailMode);
21074 break;
21075 }
21076
21077 case 'backwards':
21078 {
21079 // We're going to find the first row that has existing content.
21080 // At the same time we're going to reverse the list of everything
21081 // we pass in the meantime. That's going to be our tail in reverse
21082 // order.
21083 var _tail = null;
21084 var row = workInProgress.child;
21085 workInProgress.child = null;
21086
21087 while (row !== null) {
21088 var currentRow = row.alternate; // New rows can't be content rows.
21089
21090 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
21091 // This is the beginning of the main content.
21092 workInProgress.child = row;
21093 break;
21094 }
21095
21096 var nextRow = row.sibling;
21097 row.sibling = _tail;
21098 _tail = row;
21099 row = nextRow;
21100 } // TODO: If workInProgress.child is null, we can continue on the tail immediately.
21101
21102
21103 initSuspenseListRenderState(workInProgress, true, // isBackwards
21104 _tail, null, // last
21105 tailMode);
21106 break;
21107 }
21108
21109 case 'together':
21110 {
21111 initSuspenseListRenderState(workInProgress, false, // isBackwards
21112 null, // tail
21113 null, // last
21114 undefined);
21115 break;
21116 }
21117
21118 default:
21119 {
21120 // The default reveal order is the same as not having
21121 // a boundary.
21122 workInProgress.memoizedState = null;
21123 }
21124 }
21125 }
21126
21127 return workInProgress.child;
21128 }
21129
21130 function updatePortalComponent(current, workInProgress, renderLanes) {
21131 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
21132 var nextChildren = workInProgress.pendingProps;
21133
21134 if (current === null) {
21135 // Portals are special because we don't append the children during mount
21136 // but at commit. Therefore we need to track insertions which the normal
21137 // flow doesn't do during mount. This doesn't happen at the root because
21138 // the root always starts with a "current" with a null child.
21139 // TODO: Consider unifying this with how the root works.
21140 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes);
21141 } else {
21142 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
21143 }
21144
21145 return workInProgress.child;
21146 }
21147
21148 var hasWarnedAboutUsingNoValuePropOnContextProvider = false;
21149
21150 function updateContextProvider(current, workInProgress, renderLanes) {
21151 var providerType = workInProgress.type;
21152 var context = providerType._context;
21153 var newProps = workInProgress.pendingProps;
21154 var oldProps = workInProgress.memoizedProps;
21155 var newValue = newProps.value;
21156
21157 {
21158 if (!('value' in newProps)) {
21159 if (!hasWarnedAboutUsingNoValuePropOnContextProvider) {
21160 hasWarnedAboutUsingNoValuePropOnContextProvider = true;
21161
21162 error('The `value` prop is required for the `<Context.Provider>`. Did you misspell it or forget to pass it?');
21163 }
21164 }
21165
21166 var providerPropTypes = workInProgress.type.propTypes;
21167
21168 if (providerPropTypes) {
21169 checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider');
21170 }
21171 }
21172
21173 pushProvider(workInProgress, context, newValue);
21174
21175 {
21176 if (oldProps !== null) {
21177 var oldValue = oldProps.value;
21178
21179 if (objectIs(oldValue, newValue)) {
21180 // No change. Bailout early if children are the same.
21181 if (oldProps.children === newProps.children && !hasContextChanged()) {
21182 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
21183 }
21184 } else {
21185 // The context value changed. Search for matching consumers and schedule
21186 // them to update.
21187 propagateContextChange(workInProgress, context, renderLanes);
21188 }
21189 }
21190 }
21191
21192 var newChildren = newProps.children;
21193 reconcileChildren(current, workInProgress, newChildren, renderLanes);
21194 return workInProgress.child;
21195 }
21196
21197 var hasWarnedAboutUsingContextAsConsumer = false;
21198
21199 function updateContextConsumer(current, workInProgress, renderLanes) {
21200 var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In
21201 // DEV mode, we create a separate object for Context.Consumer that acts
21202 // like a proxy to Context. This proxy object adds unnecessary code in PROD
21203 // so we use the old behaviour (Context.Consumer references Context) to
21204 // reduce size and overhead. The separate object references context via
21205 // a property called "_context", which also gives us the ability to check
21206 // in DEV mode if this property exists or not and warn if it does not.
21207
21208 {
21209 if (context._context === undefined) {
21210 // This may be because it's a Context (rather than a Consumer).
21211 // Or it may be because it's older React where they're the same thing.
21212 // We only want to warn if we're sure it's a new React.
21213 if (context !== context.Consumer) {
21214 if (!hasWarnedAboutUsingContextAsConsumer) {
21215 hasWarnedAboutUsingContextAsConsumer = true;
21216
21217 error('Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
21218 }
21219 }
21220 } else {
21221 context = context._context;
21222 }
21223 }
21224
21225 var newProps = workInProgress.pendingProps;
21226 var render = newProps.children;
21227
21228 {
21229 if (typeof render !== 'function') {
21230 error('A context consumer was rendered with multiple children, or a child ' + "that isn't a function. A context consumer expects a single child " + 'that is a function. If you did pass a function, make sure there ' + 'is no trailing or leading whitespace around it.');
21231 }
21232 }
21233
21234 prepareToReadContext(workInProgress, renderLanes);
21235 var newValue = readContext(context);
21236
21237 {
21238 markComponentRenderStarted(workInProgress);
21239 }
21240
21241 var newChildren;
21242
21243 {
21244 ReactCurrentOwner$1.current = workInProgress;
21245 setIsRendering(true);
21246 newChildren = render(newValue);
21247 setIsRendering(false);
21248 }
21249
21250 {
21251 markComponentRenderStopped();
21252 } // React DevTools reads this flag.
21253
21254
21255 workInProgress.flags |= PerformedWork;
21256 reconcileChildren(current, workInProgress, newChildren, renderLanes);
21257 return workInProgress.child;
21258 }
21259
21260 function markWorkInProgressReceivedUpdate() {
21261 didReceiveUpdate = true;
21262 }
21263
21264 function resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress) {
21265 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
21266 if (current !== null) {
21267 // A lazy component only mounts if it suspended inside a non-
21268 // concurrent tree, in an inconsistent state. We want to treat it like
21269 // a new mount, even though an empty version of it already committed.
21270 // Disconnect the alternate pointers.
21271 current.alternate = null;
21272 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
21273
21274 workInProgress.flags |= Placement;
21275 }
21276 }
21277 }
21278
21279 function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) {
21280 if (current !== null) {
21281 // Reuse previous dependencies
21282 workInProgress.dependencies = current.dependencies;
21283 }
21284
21285 {
21286 // Don't update "base" render times for bailouts.
21287 stopProfilerTimerIfRunning();
21288 }
21289
21290 markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work.
21291
21292 if (!includesSomeLane(renderLanes, workInProgress.childLanes)) {
21293 // The children don't have any work either. We can skip them.
21294 // TODO: Once we add back resuming, we should check if the children are
21295 // a work-in-progress set. If so, we need to transfer their effects.
21296 {
21297 return null;
21298 }
21299 } // This fiber doesn't have work, but its subtree does. Clone the child
21300 // fibers and continue.
21301
21302
21303 cloneChildFibers(current, workInProgress);
21304 return workInProgress.child;
21305 }
21306
21307 function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
21308 {
21309 var returnFiber = oldWorkInProgress.return;
21310
21311 if (returnFiber === null) {
21312 // eslint-disable-next-line react-internal/prod-error-codes
21313 throw new Error('Cannot swap the root fiber.');
21314 } // Disconnect from the old current.
21315 // It will get deleted.
21316
21317
21318 current.alternate = null;
21319 oldWorkInProgress.alternate = null; // Connect to the new tree.
21320
21321 newWorkInProgress.index = oldWorkInProgress.index;
21322 newWorkInProgress.sibling = oldWorkInProgress.sibling;
21323 newWorkInProgress.return = oldWorkInProgress.return;
21324 newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it.
21325
21326 if (oldWorkInProgress === returnFiber.child) {
21327 returnFiber.child = newWorkInProgress;
21328 } else {
21329 var prevSibling = returnFiber.child;
21330
21331 if (prevSibling === null) {
21332 // eslint-disable-next-line react-internal/prod-error-codes
21333 throw new Error('Expected parent to have a child.');
21334 }
21335
21336 while (prevSibling.sibling !== oldWorkInProgress) {
21337 prevSibling = prevSibling.sibling;
21338
21339 if (prevSibling === null) {
21340 // eslint-disable-next-line react-internal/prod-error-codes
21341 throw new Error('Expected to find the previous sibling.');
21342 }
21343 }
21344
21345 prevSibling.sibling = newWorkInProgress;
21346 } // Delete the old fiber and place the new one.
21347 // Since the old fiber is disconnected, we have to schedule it manually.
21348
21349
21350 var deletions = returnFiber.deletions;
21351
21352 if (deletions === null) {
21353 returnFiber.deletions = [current];
21354 returnFiber.flags |= ChildDeletion;
21355 } else {
21356 deletions.push(current);
21357 }
21358
21359 newWorkInProgress.flags |= Placement; // Restart work from the new fiber.
21360
21361 return newWorkInProgress;
21362 }
21363 }
21364
21365 function checkScheduledUpdateOrContext(current, renderLanes) {
21366 // Before performing an early bailout, we must check if there are pending
21367 // updates or context.
21368 var updateLanes = current.lanes;
21369
21370 if (includesSomeLane(updateLanes, renderLanes)) {
21371 return true;
21372 } // No pending update, but because context is propagated lazily, we need
21373
21374 return false;
21375 }
21376
21377 function attemptEarlyBailoutIfNoScheduledUpdate(current, workInProgress, renderLanes) {
21378 // This fiber does not have any pending work. Bailout without entering
21379 // the begin phase. There's still some bookkeeping we that needs to be done
21380 // in this optimized path, mostly pushing stuff onto the stack.
21381 switch (workInProgress.tag) {
21382 case HostRoot:
21383 pushHostRootContext(workInProgress);
21384 var root = workInProgress.stateNode;
21385
21386 resetHydrationState();
21387 break;
21388
21389 case HostComponent:
21390 pushHostContext(workInProgress);
21391 break;
21392
21393 case ClassComponent:
21394 {
21395 var Component = workInProgress.type;
21396
21397 if (isContextProvider(Component)) {
21398 pushContextProvider(workInProgress);
21399 }
21400
21401 break;
21402 }
21403
21404 case HostPortal:
21405 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
21406 break;
21407
21408 case ContextProvider:
21409 {
21410 var newValue = workInProgress.memoizedProps.value;
21411 var context = workInProgress.type._context;
21412 pushProvider(workInProgress, context, newValue);
21413 break;
21414 }
21415
21416 case Profiler:
21417 {
21418 // Profiler should only call onRender when one of its descendants actually rendered.
21419 var hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes);
21420
21421 if (hasChildWork) {
21422 workInProgress.flags |= Update;
21423 }
21424
21425 {
21426 // Reset effect durations for the next eventual effect phase.
21427 // These are reset during render to allow the DevTools commit hook a chance to read them,
21428 var stateNode = workInProgress.stateNode;
21429 stateNode.effectDuration = 0;
21430 stateNode.passiveEffectDuration = 0;
21431 }
21432 }
21433
21434 break;
21435
21436 case SuspenseComponent:
21437 {
21438 var state = workInProgress.memoizedState;
21439
21440 if (state !== null) {
21441 if (state.dehydrated !== null) {
21442 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // We know that this component will suspend again because if it has
21443 // been unsuspended it has committed as a resolved Suspense component.
21444 // If it needs to be retried, it should have work scheduled on it.
21445
21446 workInProgress.flags |= DidCapture; // We should never render the children of a dehydrated boundary until we
21447 // upgrade it. We return null instead of bailoutOnAlreadyFinishedWork.
21448
21449 return null;
21450 } // If this boundary is currently timed out, we need to decide
21451 // whether to retry the primary children, or to skip over it and
21452 // go straight to the fallback. Check the priority of the primary
21453 // child fragment.
21454
21455
21456 var primaryChildFragment = workInProgress.child;
21457 var primaryChildLanes = primaryChildFragment.childLanes;
21458
21459 if (includesSomeLane(renderLanes, primaryChildLanes)) {
21460 // The primary children have pending work. Use the normal path
21461 // to attempt to render the primary children again.
21462 return updateSuspenseComponent(current, workInProgress, renderLanes);
21463 } else {
21464 // The primary child fragment does not have pending work marked
21465 // on it
21466 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient
21467 // priority. Bailout.
21468
21469 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
21470
21471 if (child !== null) {
21472 // The fallback children have pending work. Skip over the
21473 // primary children and work on the fallback.
21474 return child.sibling;
21475 } else {
21476 // Note: We can return `null` here because we already checked
21477 // whether there were nested context consumers, via the call to
21478 // `bailoutOnAlreadyFinishedWork` above.
21479 return null;
21480 }
21481 }
21482 } else {
21483 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
21484 }
21485
21486 break;
21487 }
21488
21489 case SuspenseListComponent:
21490 {
21491 var didSuspendBefore = (current.flags & DidCapture) !== NoFlags;
21492
21493 var _hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes);
21494
21495 if (didSuspendBefore) {
21496 if (_hasChildWork) {
21497 // If something was in fallback state last time, and we have all the
21498 // same children then we're still in progressive loading state.
21499 // Something might get unblocked by state updates or retries in the
21500 // tree which will affect the tail. So we need to use the normal
21501 // path to compute the correct tail.
21502 return updateSuspenseListComponent(current, workInProgress, renderLanes);
21503 } // If none of the children had any work, that means that none of
21504 // them got retried so they'll still be blocked in the same way
21505 // as before. We can fast bail out.
21506
21507
21508 workInProgress.flags |= DidCapture;
21509 } // If nothing suspended before and we're rendering the same children,
21510 // then the tail doesn't matter. Anything new that suspends will work
21511 // in the "together" mode, so we can continue from the state we had.
21512
21513
21514 var renderState = workInProgress.memoizedState;
21515
21516 if (renderState !== null) {
21517 // Reset to the "together" mode in case we've started a different
21518 // update in the past but didn't complete it.
21519 renderState.rendering = null;
21520 renderState.tail = null;
21521 renderState.lastEffect = null;
21522 }
21523
21524 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
21525
21526 if (_hasChildWork) {
21527 break;
21528 } else {
21529 // If none of the children had any work, that means that none of
21530 // them got retried so they'll still be blocked in the same way
21531 // as before. We can fast bail out.
21532 return null;
21533 }
21534 }
21535
21536 case OffscreenComponent:
21537 case LegacyHiddenComponent:
21538 {
21539 // Need to check if the tree still needs to be deferred. This is
21540 // almost identical to the logic used in the normal update path,
21541 // so we'll just enter that. The only difference is we'll bail out
21542 // at the next level instead of this one, because the child props
21543 // have not changed. Which is fine.
21544 // TODO: Probably should refactor `beginWork` to split the bailout
21545 // path from the normal path. I'm tempted to do a labeled break here
21546 // but I won't :)
21547 workInProgress.lanes = NoLanes;
21548 return updateOffscreenComponent(current, workInProgress, renderLanes);
21549 }
21550 }
21551
21552 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
21553 }
21554
21555 function beginWork(current, workInProgress, renderLanes) {
21556 {
21557 if (workInProgress._debugNeedsRemount && current !== null) {
21558 // This will restart the begin phase with a new fiber.
21559 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.lanes));
21560 }
21561 }
21562
21563 if (current !== null) {
21564 var oldProps = current.memoizedProps;
21565 var newProps = workInProgress.pendingProps;
21566
21567 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:
21568 workInProgress.type !== current.type )) {
21569 // If props or context changed, mark the fiber as having performed work.
21570 // This may be unset if the props are determined to be equal later (memo).
21571 didReceiveUpdate = true;
21572 } else {
21573 // Neither props nor legacy context changes. Check if there's a pending
21574 // update or context change.
21575 var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(current, renderLanes);
21576
21577 if (!hasScheduledUpdateOrContext && // If this is the second pass of an error or suspense boundary, there
21578 // may not be work scheduled on `current`, so we check for this flag.
21579 (workInProgress.flags & DidCapture) === NoFlags) {
21580 // No pending updates or context. Bail out now.
21581 didReceiveUpdate = false;
21582 return attemptEarlyBailoutIfNoScheduledUpdate(current, workInProgress, renderLanes);
21583 }
21584
21585 if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) {
21586 // This is a special case that only exists for legacy mode.
21587 // See https://github.com/facebook/react/pull/19216.
21588 didReceiveUpdate = true;
21589 } else {
21590 // An update was scheduled on this fiber, but there are no new props
21591 // nor legacy context. Set this to false. If an update queue or context
21592 // consumer produces a changed value, it will set this to true. Otherwise,
21593 // the component will assume the children have not changed and bail out.
21594 didReceiveUpdate = false;
21595 }
21596 }
21597 } else {
21598 didReceiveUpdate = false;
21599
21600 if (getIsHydrating() && isForkedChild(workInProgress)) {
21601 // Check if this child belongs to a list of muliple children in
21602 // its parent.
21603 //
21604 // In a true multi-threaded implementation, we would render children on
21605 // parallel threads. This would represent the beginning of a new render
21606 // thread for this subtree.
21607 //
21608 // We only use this for id generation during hydration, which is why the
21609 // logic is located in this special branch.
21610 var slotIndex = workInProgress.index;
21611 var numberOfForks = getForksAtLevel();
21612 pushTreeId(workInProgress, numberOfForks, slotIndex);
21613 }
21614 } // Before entering the begin phase, clear pending update priority.
21615 // TODO: This assumes that we're about to evaluate the component and process
21616 // the update queue. However, there's an exception: SimpleMemoComponent
21617 // sometimes bails out later in the begin phase. This indicates that we should
21618 // move this assignment out of the common path and into each branch.
21619
21620
21621 workInProgress.lanes = NoLanes;
21622
21623 switch (workInProgress.tag) {
21624 case IndeterminateComponent:
21625 {
21626 return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderLanes);
21627 }
21628
21629 case LazyComponent:
21630 {
21631 var elementType = workInProgress.elementType;
21632 return mountLazyComponent(current, workInProgress, elementType, renderLanes);
21633 }
21634
21635 case FunctionComponent:
21636 {
21637 var Component = workInProgress.type;
21638 var unresolvedProps = workInProgress.pendingProps;
21639 var resolvedProps = workInProgress.elementType === Component ? unresolvedProps : resolveDefaultProps(Component, unresolvedProps);
21640 return updateFunctionComponent(current, workInProgress, Component, resolvedProps, renderLanes);
21641 }
21642
21643 case ClassComponent:
21644 {
21645 var _Component = workInProgress.type;
21646 var _unresolvedProps = workInProgress.pendingProps;
21647
21648 var _resolvedProps = workInProgress.elementType === _Component ? _unresolvedProps : resolveDefaultProps(_Component, _unresolvedProps);
21649
21650 return updateClassComponent(current, workInProgress, _Component, _resolvedProps, renderLanes);
21651 }
21652
21653 case HostRoot:
21654 return updateHostRoot(current, workInProgress, renderLanes);
21655
21656 case HostComponent:
21657 return updateHostComponent(current, workInProgress, renderLanes);
21658
21659 case HostText:
21660 return updateHostText(current, workInProgress);
21661
21662 case SuspenseComponent:
21663 return updateSuspenseComponent(current, workInProgress, renderLanes);
21664
21665 case HostPortal:
21666 return updatePortalComponent(current, workInProgress, renderLanes);
21667
21668 case ForwardRef:
21669 {
21670 var type = workInProgress.type;
21671 var _unresolvedProps2 = workInProgress.pendingProps;
21672
21673 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
21674
21675 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderLanes);
21676 }
21677
21678 case Fragment:
21679 return updateFragment(current, workInProgress, renderLanes);
21680
21681 case Mode:
21682 return updateMode(current, workInProgress, renderLanes);
21683
21684 case Profiler:
21685 return updateProfiler(current, workInProgress, renderLanes);
21686
21687 case ContextProvider:
21688 return updateContextProvider(current, workInProgress, renderLanes);
21689
21690 case ContextConsumer:
21691 return updateContextConsumer(current, workInProgress, renderLanes);
21692
21693 case MemoComponent:
21694 {
21695 var _type2 = workInProgress.type;
21696 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.
21697
21698 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
21699
21700 {
21701 if (workInProgress.type !== workInProgress.elementType) {
21702 var outerPropTypes = _type2.propTypes;
21703
21704 if (outerPropTypes) {
21705 checkPropTypes(outerPropTypes, _resolvedProps3, // Resolved for outer only
21706 'prop', getComponentNameFromType(_type2));
21707 }
21708 }
21709 }
21710
21711 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
21712 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, renderLanes);
21713 }
21714
21715 case SimpleMemoComponent:
21716 {
21717 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, renderLanes);
21718 }
21719
21720 case IncompleteClassComponent:
21721 {
21722 var _Component2 = workInProgress.type;
21723 var _unresolvedProps4 = workInProgress.pendingProps;
21724
21725 var _resolvedProps4 = workInProgress.elementType === _Component2 ? _unresolvedProps4 : resolveDefaultProps(_Component2, _unresolvedProps4);
21726
21727 return mountIncompleteClassComponent(current, workInProgress, _Component2, _resolvedProps4, renderLanes);
21728 }
21729
21730 case SuspenseListComponent:
21731 {
21732 return updateSuspenseListComponent(current, workInProgress, renderLanes);
21733 }
21734
21735 case ScopeComponent:
21736 {
21737
21738 break;
21739 }
21740
21741 case OffscreenComponent:
21742 {
21743 return updateOffscreenComponent(current, workInProgress, renderLanes);
21744 }
21745 }
21746
21747 throw new Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in " + 'React. Please file an issue.');
21748 }
21749
21750 function markUpdate(workInProgress) {
21751 // Tag the fiber with an update effect. This turns a Placement into
21752 // a PlacementAndUpdate.
21753 workInProgress.flags |= Update;
21754 }
21755
21756 function markRef$1(workInProgress) {
21757 workInProgress.flags |= Ref;
21758
21759 {
21760 workInProgress.flags |= RefStatic;
21761 }
21762 }
21763
21764 var appendAllChildren;
21765 var updateHostContainer;
21766 var updateHostComponent$1;
21767 var updateHostText$1;
21768
21769 {
21770 // Mutation mode
21771 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
21772 // We only have the top Fiber that was created but we need recurse down its
21773 // children to find all the terminal nodes.
21774 var node = workInProgress.child;
21775
21776 while (node !== null) {
21777 if (node.tag === HostComponent || node.tag === HostText) {
21778 appendInitialChild(parent, node.stateNode);
21779 } else if (node.tag === HostPortal) ; else if (node.child !== null) {
21780 node.child.return = node;
21781 node = node.child;
21782 continue;
21783 }
21784
21785 if (node === workInProgress) {
21786 return;
21787 }
21788
21789 while (node.sibling === null) {
21790 if (node.return === null || node.return === workInProgress) {
21791 return;
21792 }
21793
21794 node = node.return;
21795 }
21796
21797 node.sibling.return = node.return;
21798 node = node.sibling;
21799 }
21800 };
21801
21802 updateHostContainer = function (current, workInProgress) {// Noop
21803 };
21804
21805 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
21806 // If we have an alternate, that means this is an update and we need to
21807 // schedule a side-effect to do the updates.
21808 var oldProps = current.memoizedProps;
21809
21810 if (oldProps === newProps) {
21811 // In mutation mode, this is sufficient for a bailout because
21812 // we won't touch this node even if children changed.
21813 return;
21814 } // If we get updated because one of our children updated, we don't
21815 // have newProps so we'll have to reuse them.
21816 // TODO: Split the update API as separate for the props vs. children.
21817 // Even better would be if children weren't special cased at all tho.
21818
21819
21820 var instance = workInProgress.stateNode;
21821 var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host
21822 // component is hitting the resume path. Figure out why. Possibly
21823 // related to `hidden`.
21824
21825 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext); // TODO: Type this specific to this type of component.
21826
21827 workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
21828 // is a new ref we mark this as an update. All the work is done in commitWork.
21829
21830 if (updatePayload) {
21831 markUpdate(workInProgress);
21832 }
21833 };
21834
21835 updateHostText$1 = function (current, workInProgress, oldText, newText) {
21836 // If the text differs, mark it as an update. All the work in done in commitWork.
21837 if (oldText !== newText) {
21838 markUpdate(workInProgress);
21839 }
21840 };
21841 }
21842
21843 function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
21844 if (getIsHydrating()) {
21845 // If we're hydrating, we should consume as many items as we can
21846 // so we don't leave any behind.
21847 return;
21848 }
21849
21850 switch (renderState.tailMode) {
21851 case 'hidden':
21852 {
21853 // Any insertions at the end of the tail list after this point
21854 // should be invisible. If there are already mounted boundaries
21855 // anything before them are not considered for collapsing.
21856 // Therefore we need to go through the whole tail to find if
21857 // there are any.
21858 var tailNode = renderState.tail;
21859 var lastTailNode = null;
21860
21861 while (tailNode !== null) {
21862 if (tailNode.alternate !== null) {
21863 lastTailNode = tailNode;
21864 }
21865
21866 tailNode = tailNode.sibling;
21867 } // Next we're simply going to delete all insertions after the
21868 // last rendered item.
21869
21870
21871 if (lastTailNode === null) {
21872 // All remaining items in the tail are insertions.
21873 renderState.tail = null;
21874 } else {
21875 // Detach the insertion after the last node that was already
21876 // inserted.
21877 lastTailNode.sibling = null;
21878 }
21879
21880 break;
21881 }
21882
21883 case 'collapsed':
21884 {
21885 // Any insertions at the end of the tail list after this point
21886 // should be invisible. If there are already mounted boundaries
21887 // anything before them are not considered for collapsing.
21888 // Therefore we need to go through the whole tail to find if
21889 // there are any.
21890 var _tailNode = renderState.tail;
21891 var _lastTailNode = null;
21892
21893 while (_tailNode !== null) {
21894 if (_tailNode.alternate !== null) {
21895 _lastTailNode = _tailNode;
21896 }
21897
21898 _tailNode = _tailNode.sibling;
21899 } // Next we're simply going to delete all insertions after the
21900 // last rendered item.
21901
21902
21903 if (_lastTailNode === null) {
21904 // All remaining items in the tail are insertions.
21905 if (!hasRenderedATailFallback && renderState.tail !== null) {
21906 // We suspended during the head. We want to show at least one
21907 // row at the tail. So we'll keep on and cut off the rest.
21908 renderState.tail.sibling = null;
21909 } else {
21910 renderState.tail = null;
21911 }
21912 } else {
21913 // Detach the insertion after the last node that was already
21914 // inserted.
21915 _lastTailNode.sibling = null;
21916 }
21917
21918 break;
21919 }
21920 }
21921 }
21922
21923 function bubbleProperties(completedWork) {
21924 var didBailout = completedWork.alternate !== null && completedWork.alternate.child === completedWork.child;
21925 var newChildLanes = NoLanes;
21926 var subtreeFlags = NoFlags;
21927
21928 if (!didBailout) {
21929 // Bubble up the earliest expiration time.
21930 if ( (completedWork.mode & ProfileMode) !== NoMode) {
21931 // In profiling mode, resetChildExpirationTime is also used to reset
21932 // profiler durations.
21933 var actualDuration = completedWork.actualDuration;
21934 var treeBaseDuration = completedWork.selfBaseDuration;
21935 var child = completedWork.child;
21936
21937 while (child !== null) {
21938 newChildLanes = mergeLanes(newChildLanes, mergeLanes(child.lanes, child.childLanes));
21939 subtreeFlags |= child.subtreeFlags;
21940 subtreeFlags |= child.flags; // When a fiber is cloned, its actualDuration is reset to 0. This value will
21941 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
21942 // When work is done, it should bubble to the parent's actualDuration. If
21943 // the fiber has not been cloned though, (meaning no work was done), then
21944 // this value will reflect the amount of time spent working on a previous
21945 // render. In that case it should not bubble. We determine whether it was
21946 // cloned by comparing the child pointer.
21947
21948 actualDuration += child.actualDuration;
21949 treeBaseDuration += child.treeBaseDuration;
21950 child = child.sibling;
21951 }
21952
21953 completedWork.actualDuration = actualDuration;
21954 completedWork.treeBaseDuration = treeBaseDuration;
21955 } else {
21956 var _child = completedWork.child;
21957
21958 while (_child !== null) {
21959 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child.lanes, _child.childLanes));
21960 subtreeFlags |= _child.subtreeFlags;
21961 subtreeFlags |= _child.flags; // Update the return pointer so the tree is consistent. This is a code
21962 // smell because it assumes the commit phase is never concurrent with
21963 // the render phase. Will address during refactor to alternate model.
21964
21965 _child.return = completedWork;
21966 _child = _child.sibling;
21967 }
21968 }
21969
21970 completedWork.subtreeFlags |= subtreeFlags;
21971 } else {
21972 // Bubble up the earliest expiration time.
21973 if ( (completedWork.mode & ProfileMode) !== NoMode) {
21974 // In profiling mode, resetChildExpirationTime is also used to reset
21975 // profiler durations.
21976 var _treeBaseDuration = completedWork.selfBaseDuration;
21977 var _child2 = completedWork.child;
21978
21979 while (_child2 !== null) {
21980 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child2.lanes, _child2.childLanes)); // "Static" flags share the lifetime of the fiber/hook they belong to,
21981 // so we should bubble those up even during a bailout. All the other
21982 // flags have a lifetime only of a single render + commit, so we should
21983 // ignore them.
21984
21985 subtreeFlags |= _child2.subtreeFlags & StaticMask;
21986 subtreeFlags |= _child2.flags & StaticMask;
21987 _treeBaseDuration += _child2.treeBaseDuration;
21988 _child2 = _child2.sibling;
21989 }
21990
21991 completedWork.treeBaseDuration = _treeBaseDuration;
21992 } else {
21993 var _child3 = completedWork.child;
21994
21995 while (_child3 !== null) {
21996 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child3.lanes, _child3.childLanes)); // "Static" flags share the lifetime of the fiber/hook they belong to,
21997 // so we should bubble those up even during a bailout. All the other
21998 // flags have a lifetime only of a single render + commit, so we should
21999 // ignore them.
22000
22001 subtreeFlags |= _child3.subtreeFlags & StaticMask;
22002 subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code
22003 // smell because it assumes the commit phase is never concurrent with
22004 // the render phase. Will address during refactor to alternate model.
22005
22006 _child3.return = completedWork;
22007 _child3 = _child3.sibling;
22008 }
22009 }
22010
22011 completedWork.subtreeFlags |= subtreeFlags;
22012 }
22013
22014 completedWork.childLanes = newChildLanes;
22015 return didBailout;
22016 }
22017
22018 function completeDehydratedSuspenseBoundary(current, workInProgress, nextState) {
22019 if (hasUnhydratedTailNodes() && (workInProgress.mode & ConcurrentMode) !== NoMode && (workInProgress.flags & DidCapture) === NoFlags) {
22020 warnIfUnhydratedTailNodes(workInProgress);
22021 resetHydrationState();
22022 workInProgress.flags |= ForceClientRender | Incomplete | ShouldCapture;
22023 return false;
22024 }
22025
22026 var wasHydrated = popHydrationState(workInProgress);
22027
22028 if (nextState !== null && nextState.dehydrated !== null) {
22029 // We might be inside a hydration state the first time we're picking up this
22030 // Suspense boundary, and also after we've reentered it for further hydration.
22031 if (current === null) {
22032 if (!wasHydrated) {
22033 throw new Error('A dehydrated suspense component was completed without a hydrated node. ' + 'This is probably a bug in React.');
22034 }
22035
22036 prepareToHydrateHostSuspenseInstance(workInProgress);
22037 bubbleProperties(workInProgress);
22038
22039 {
22040 if ((workInProgress.mode & ProfileMode) !== NoMode) {
22041 var isTimedOutSuspense = nextState !== null;
22042
22043 if (isTimedOutSuspense) {
22044 // Don't count time spent in a timed out Suspense subtree as part of the base duration.
22045 var primaryChildFragment = workInProgress.child;
22046
22047 if (primaryChildFragment !== null) {
22048 // $FlowFixMe Flow doesn't support type casting in combination with the -= operator
22049 workInProgress.treeBaseDuration -= primaryChildFragment.treeBaseDuration;
22050 }
22051 }
22052 }
22053 }
22054
22055 return false;
22056 } else {
22057 // We might have reentered this boundary to hydrate it. If so, we need to reset the hydration
22058 // state since we're now exiting out of it. popHydrationState doesn't do that for us.
22059 resetHydrationState();
22060
22061 if ((workInProgress.flags & DidCapture) === NoFlags) {
22062 // This boundary did not suspend so it's now hydrated and unsuspended.
22063 workInProgress.memoizedState = null;
22064 } // If nothing suspended, we need to schedule an effect to mark this boundary
22065 // as having hydrated so events know that they're free to be invoked.
22066 // It's also a signal to replay events and the suspense callback.
22067 // If something suspended, schedule an effect to attach retry listeners.
22068 // So we might as well always mark this.
22069
22070
22071 workInProgress.flags |= Update;
22072 bubbleProperties(workInProgress);
22073
22074 {
22075 if ((workInProgress.mode & ProfileMode) !== NoMode) {
22076 var _isTimedOutSuspense = nextState !== null;
22077
22078 if (_isTimedOutSuspense) {
22079 // Don't count time spent in a timed out Suspense subtree as part of the base duration.
22080 var _primaryChildFragment = workInProgress.child;
22081
22082 if (_primaryChildFragment !== null) {
22083 // $FlowFixMe Flow doesn't support type casting in combination with the -= operator
22084 workInProgress.treeBaseDuration -= _primaryChildFragment.treeBaseDuration;
22085 }
22086 }
22087 }
22088 }
22089
22090 return false;
22091 }
22092 } else {
22093 // Successfully completed this tree. If this was a forced client render,
22094 // there may have been recoverable errors during first hydration
22095 // attempt. If so, add them to a queue so we can log them in the
22096 // commit phase.
22097 upgradeHydrationErrorsToRecoverable(); // Fall through to normal Suspense path
22098
22099 return true;
22100 }
22101 }
22102
22103 function completeWork(current, workInProgress, renderLanes) {
22104 var newProps = workInProgress.pendingProps; // Note: This intentionally doesn't check if we're hydrating because comparing
22105 // to the current tree provider fiber is just as fast and less error-prone.
22106 // Ideally we would have a special version of the work loop only
22107 // for hydration.
22108
22109 popTreeContext(workInProgress);
22110
22111 switch (workInProgress.tag) {
22112 case IndeterminateComponent:
22113 case LazyComponent:
22114 case SimpleMemoComponent:
22115 case FunctionComponent:
22116 case ForwardRef:
22117 case Fragment:
22118 case Mode:
22119 case Profiler:
22120 case ContextConsumer:
22121 case MemoComponent:
22122 bubbleProperties(workInProgress);
22123 return null;
22124
22125 case ClassComponent:
22126 {
22127 var Component = workInProgress.type;
22128
22129 if (isContextProvider(Component)) {
22130 popContext(workInProgress);
22131 }
22132
22133 bubbleProperties(workInProgress);
22134 return null;
22135 }
22136
22137 case HostRoot:
22138 {
22139 var fiberRoot = workInProgress.stateNode;
22140 popHostContainer(workInProgress);
22141 popTopLevelContextObject(workInProgress);
22142 resetWorkInProgressVersions();
22143
22144 if (fiberRoot.pendingContext) {
22145 fiberRoot.context = fiberRoot.pendingContext;
22146 fiberRoot.pendingContext = null;
22147 }
22148
22149 if (current === null || current.child === null) {
22150 // If we hydrated, pop so that we can delete any remaining children
22151 // that weren't hydrated.
22152 var wasHydrated = popHydrationState(workInProgress);
22153
22154 if (wasHydrated) {
22155 // If we hydrated, then we'll need to schedule an update for
22156 // the commit side-effects on the root.
22157 markUpdate(workInProgress);
22158 } else {
22159 if (current !== null) {
22160 var prevState = current.memoizedState;
22161
22162 if ( // Check if this is a client root
22163 !prevState.isDehydrated || // Check if we reverted to client rendering (e.g. due to an error)
22164 (workInProgress.flags & ForceClientRender) !== NoFlags) {
22165 // Schedule an effect to clear this container at the start of the
22166 // next commit. This handles the case of React rendering into a
22167 // container with previous children. It's also safe to do for
22168 // updates too, because current.child would only be null if the
22169 // previous render was null (so the container would already
22170 // be empty).
22171 workInProgress.flags |= Snapshot; // If this was a forced client render, there may have been
22172 // recoverable errors during first hydration attempt. If so, add
22173 // them to a queue so we can log them in the commit phase.
22174
22175 upgradeHydrationErrorsToRecoverable();
22176 }
22177 }
22178 }
22179 }
22180
22181 updateHostContainer(current, workInProgress);
22182 bubbleProperties(workInProgress);
22183
22184 return null;
22185 }
22186
22187 case HostComponent:
22188 {
22189 popHostContext(workInProgress);
22190 var rootContainerInstance = getRootHostContainer();
22191 var type = workInProgress.type;
22192
22193 if (current !== null && workInProgress.stateNode != null) {
22194 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
22195
22196 if (current.ref !== workInProgress.ref) {
22197 markRef$1(workInProgress);
22198 }
22199 } else {
22200 if (!newProps) {
22201 if (workInProgress.stateNode === null) {
22202 throw new Error('We must have new props for new mounts. This error is likely ' + 'caused by a bug in React. Please file an issue.');
22203 } // This can happen when we abort work.
22204
22205
22206 bubbleProperties(workInProgress);
22207 return null;
22208 }
22209
22210 var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context
22211 // "stack" as the parent. Then append children as we go in beginWork
22212 // or completeWork depending on whether we want to add them top->down or
22213 // bottom->up. Top->down is faster in IE11.
22214
22215 var _wasHydrated = popHydrationState(workInProgress);
22216
22217 if (_wasHydrated) {
22218 // TODO: Move this and createInstance step into the beginPhase
22219 // to consolidate.
22220 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
22221 // If changes to the hydrated node need to be applied at the
22222 // commit-phase we mark this as such.
22223 markUpdate(workInProgress);
22224 }
22225 } else {
22226 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
22227 appendAllChildren(instance, workInProgress, false, false);
22228 workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount.
22229 // (eg DOM renderer supports auto-focus for certain elements).
22230 // Make sure such renderers get scheduled for later work.
22231
22232 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance)) {
22233 markUpdate(workInProgress);
22234 }
22235 }
22236
22237 if (workInProgress.ref !== null) {
22238 // If there is a ref on a host node we need to schedule a callback
22239 markRef$1(workInProgress);
22240 }
22241 }
22242
22243 bubbleProperties(workInProgress);
22244 return null;
22245 }
22246
22247 case HostText:
22248 {
22249 var newText = newProps;
22250
22251 if (current && workInProgress.stateNode != null) {
22252 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need
22253 // to schedule a side-effect to do the updates.
22254
22255 updateHostText$1(current, workInProgress, oldText, newText);
22256 } else {
22257 if (typeof newText !== 'string') {
22258 if (workInProgress.stateNode === null) {
22259 throw new Error('We must have new props for new mounts. This error is likely ' + 'caused by a bug in React. Please file an issue.');
22260 } // This can happen when we abort work.
22261
22262 }
22263
22264 var _rootContainerInstance = getRootHostContainer();
22265
22266 var _currentHostContext = getHostContext();
22267
22268 var _wasHydrated2 = popHydrationState(workInProgress);
22269
22270 if (_wasHydrated2) {
22271 if (prepareToHydrateHostTextInstance(workInProgress)) {
22272 markUpdate(workInProgress);
22273 }
22274 } else {
22275 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
22276 }
22277 }
22278
22279 bubbleProperties(workInProgress);
22280 return null;
22281 }
22282
22283 case SuspenseComponent:
22284 {
22285 popSuspenseContext(workInProgress);
22286 var nextState = workInProgress.memoizedState; // Special path for dehydrated boundaries. We may eventually move this
22287 // to its own fiber type so that we can add other kinds of hydration
22288 // boundaries that aren't associated with a Suspense tree. In anticipation
22289 // of such a refactor, all the hydration logic is contained in
22290 // this branch.
22291
22292 if (current === null || current.memoizedState !== null && current.memoizedState.dehydrated !== null) {
22293 var fallthroughToNormalSuspensePath = completeDehydratedSuspenseBoundary(current, workInProgress, nextState);
22294
22295 if (!fallthroughToNormalSuspensePath) {
22296 if (workInProgress.flags & ShouldCapture) {
22297 // Special case. There were remaining unhydrated nodes. We treat
22298 // this as a mismatch. Revert to client rendering.
22299 return workInProgress;
22300 } else {
22301 // Did not finish hydrating, either because this is the initial
22302 // render or because something suspended.
22303 return null;
22304 }
22305 } // Continue with the normal Suspense path.
22306
22307 }
22308
22309 if ((workInProgress.flags & DidCapture) !== NoFlags) {
22310 // Something suspended. Re-render with the fallback children.
22311 workInProgress.lanes = renderLanes; // Do not reset the effect list.
22312
22313 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
22314 transferActualDuration(workInProgress);
22315 } // Don't bubble properties in this case.
22316
22317
22318 return workInProgress;
22319 }
22320
22321 var nextDidTimeout = nextState !== null;
22322 var prevDidTimeout = current !== null && current.memoizedState !== null;
22323 // a passive effect, which is when we process the transitions
22324
22325
22326 if (nextDidTimeout !== prevDidTimeout) {
22327 // an effect to toggle the subtree's visibility. When we switch from
22328 // fallback -> primary, the inner Offscreen fiber schedules this effect
22329 // as part of its normal complete phase. But when we switch from
22330 // primary -> fallback, the inner Offscreen fiber does not have a complete
22331 // phase. So we need to schedule its effect here.
22332 //
22333 // We also use this flag to connect/disconnect the effects, but the same
22334 // logic applies: when re-connecting, the Offscreen fiber's complete
22335 // phase will handle scheduling the effect. It's only when the fallback
22336 // is active that we have to do anything special.
22337
22338
22339 if (nextDidTimeout) {
22340 var _offscreenFiber2 = workInProgress.child;
22341 _offscreenFiber2.flags |= Visibility; // TODO: This will still suspend a synchronous tree if anything
22342 // in the concurrent tree already suspended during this render.
22343 // This is a known bug.
22344
22345 if ((workInProgress.mode & ConcurrentMode) !== NoMode) {
22346 // TODO: Move this back to throwException because this is too late
22347 // if this is a large tree which is common for initial loads. We
22348 // don't know if we should restart a render or not until we get
22349 // this marker, and this is too late.
22350 // If this render already had a ping or lower pri updates,
22351 // and this is the first time we know we're going to suspend we
22352 // should be able to immediately restart from within throwException.
22353 var hasInvisibleChildContext = current === null && (workInProgress.memoizedProps.unstable_avoidThisFallback !== true || !enableSuspenseAvoidThisFallback);
22354
22355 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
22356 // If this was in an invisible tree or a new render, then showing
22357 // this boundary is ok.
22358 renderDidSuspend();
22359 } else {
22360 // Otherwise, we're going to have to hide content so we should
22361 // suspend for longer if possible.
22362 renderDidSuspendDelayIfPossible();
22363 }
22364 }
22365 }
22366 }
22367
22368 var wakeables = workInProgress.updateQueue;
22369
22370 if (wakeables !== null) {
22371 // Schedule an effect to attach a retry listener to the promise.
22372 // TODO: Move to passive phase
22373 workInProgress.flags |= Update;
22374 }
22375
22376 bubbleProperties(workInProgress);
22377
22378 {
22379 if ((workInProgress.mode & ProfileMode) !== NoMode) {
22380 if (nextDidTimeout) {
22381 // Don't count time spent in a timed out Suspense subtree as part of the base duration.
22382 var primaryChildFragment = workInProgress.child;
22383
22384 if (primaryChildFragment !== null) {
22385 // $FlowFixMe Flow doesn't support type casting in combination with the -= operator
22386 workInProgress.treeBaseDuration -= primaryChildFragment.treeBaseDuration;
22387 }
22388 }
22389 }
22390 }
22391
22392 return null;
22393 }
22394
22395 case HostPortal:
22396 popHostContainer(workInProgress);
22397 updateHostContainer(current, workInProgress);
22398
22399 if (current === null) {
22400 preparePortalMount(workInProgress.stateNode.containerInfo);
22401 }
22402
22403 bubbleProperties(workInProgress);
22404 return null;
22405
22406 case ContextProvider:
22407 // Pop provider fiber
22408 var context = workInProgress.type._context;
22409 popProvider(context, workInProgress);
22410 bubbleProperties(workInProgress);
22411 return null;
22412
22413 case IncompleteClassComponent:
22414 {
22415 // Same as class component case. I put it down here so that the tags are
22416 // sequential to ensure this switch is compiled to a jump table.
22417 var _Component = workInProgress.type;
22418
22419 if (isContextProvider(_Component)) {
22420 popContext(workInProgress);
22421 }
22422
22423 bubbleProperties(workInProgress);
22424 return null;
22425 }
22426
22427 case SuspenseListComponent:
22428 {
22429 popSuspenseContext(workInProgress);
22430 var renderState = workInProgress.memoizedState;
22431
22432 if (renderState === null) {
22433 // We're running in the default, "independent" mode.
22434 // We don't do anything in this mode.
22435 bubbleProperties(workInProgress);
22436 return null;
22437 }
22438
22439 var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags;
22440 var renderedTail = renderState.rendering;
22441
22442 if (renderedTail === null) {
22443 // We just rendered the head.
22444 if (!didSuspendAlready) {
22445 // This is the first pass. We need to figure out if anything is still
22446 // suspended in the rendered set.
22447 // If new content unsuspended, but there's still some content that
22448 // didn't. Then we need to do a second pass that forces everything
22449 // to keep showing their fallbacks.
22450 // We might be suspended if something in this render pass suspended, or
22451 // something in the previous committed pass suspended. Otherwise,
22452 // there's no chance so we can skip the expensive call to
22453 // findFirstSuspended.
22454 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.flags & DidCapture) === NoFlags);
22455
22456 if (!cannotBeSuspended) {
22457 var row = workInProgress.child;
22458
22459 while (row !== null) {
22460 var suspended = findFirstSuspended(row);
22461
22462 if (suspended !== null) {
22463 didSuspendAlready = true;
22464 workInProgress.flags |= DidCapture;
22465 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as
22466 // part of the second pass. In that case nothing will subscribe to
22467 // its thenables. Instead, we'll transfer its thenables to the
22468 // SuspenseList so that it can retry if they resolve.
22469 // There might be multiple of these in the list but since we're
22470 // going to wait for all of them anyway, it doesn't really matter
22471 // which ones gets to ping. In theory we could get clever and keep
22472 // track of how many dependencies remain but it gets tricky because
22473 // in the meantime, we can add/remove/change items and dependencies.
22474 // We might bail out of the loop before finding any but that
22475 // doesn't matter since that means that the other boundaries that
22476 // we did find already has their listeners attached.
22477
22478 var newThenables = suspended.updateQueue;
22479
22480 if (newThenables !== null) {
22481 workInProgress.updateQueue = newThenables;
22482 workInProgress.flags |= Update;
22483 } // Rerender the whole list, but this time, we'll force fallbacks
22484 // to stay in place.
22485 // Reset the effect flags before doing the second pass since that's now invalid.
22486 // Reset the child fibers to their original state.
22487
22488
22489 workInProgress.subtreeFlags = NoFlags;
22490 resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately
22491 // rerender the children.
22492
22493 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback)); // Don't bubble properties in this case.
22494
22495 return workInProgress.child;
22496 }
22497
22498 row = row.sibling;
22499 }
22500 }
22501
22502 if (renderState.tail !== null && now() > getRenderTargetTime()) {
22503 // We have already passed our CPU deadline but we still have rows
22504 // left in the tail. We'll just give up further attempts to render
22505 // the main content and only render fallbacks.
22506 workInProgress.flags |= DidCapture;
22507 didSuspendAlready = true;
22508 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
22509 // to get it started back up to attempt the next item. While in terms
22510 // of priority this work has the same priority as this current render,
22511 // it's not part of the same transition once the transition has
22512 // committed. If it's sync, we still want to yield so that it can be
22513 // painted. Conceptually, this is really the same as pinging.
22514 // We can use any RetryLane even if it's the one currently rendering
22515 // since we're leaving it behind on this node.
22516
22517 workInProgress.lanes = SomeRetryLane;
22518 }
22519 } else {
22520 cutOffTailIfNeeded(renderState, false);
22521 } // Next we're going to render the tail.
22522
22523 } else {
22524 // Append the rendered row to the child list.
22525 if (!didSuspendAlready) {
22526 var _suspended = findFirstSuspended(renderedTail);
22527
22528 if (_suspended !== null) {
22529 workInProgress.flags |= DidCapture;
22530 didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't
22531 // get lost if this row ends up dropped during a second pass.
22532
22533 var _newThenables = _suspended.updateQueue;
22534
22535 if (_newThenables !== null) {
22536 workInProgress.updateQueue = _newThenables;
22537 workInProgress.flags |= Update;
22538 }
22539
22540 cutOffTailIfNeeded(renderState, true); // This might have been modified.
22541
22542 if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate && !getIsHydrating() // We don't cut it if we're hydrating.
22543 ) {
22544 // We're done.
22545 bubbleProperties(workInProgress);
22546 return null;
22547 }
22548 } else if ( // The time it took to render last row is greater than the remaining
22549 // time we have to render. So rendering one more row would likely
22550 // exceed it.
22551 now() * 2 - renderState.renderingStartTime > getRenderTargetTime() && renderLanes !== OffscreenLane) {
22552 // We have now passed our CPU deadline and we'll just give up further
22553 // attempts to render the main content and only render fallbacks.
22554 // The assumption is that this is usually faster.
22555 workInProgress.flags |= DidCapture;
22556 didSuspendAlready = true;
22557 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
22558 // to get it started back up to attempt the next item. While in terms
22559 // of priority this work has the same priority as this current render,
22560 // it's not part of the same transition once the transition has
22561 // committed. If it's sync, we still want to yield so that it can be
22562 // painted. Conceptually, this is really the same as pinging.
22563 // We can use any RetryLane even if it's the one currently rendering
22564 // since we're leaving it behind on this node.
22565
22566 workInProgress.lanes = SomeRetryLane;
22567 }
22568 }
22569
22570 if (renderState.isBackwards) {
22571 // The effect list of the backwards tail will have been added
22572 // to the end. This breaks the guarantee that life-cycles fire in
22573 // sibling order but that isn't a strong guarantee promised by React.
22574 // Especially since these might also just pop in during future commits.
22575 // Append to the beginning of the list.
22576 renderedTail.sibling = workInProgress.child;
22577 workInProgress.child = renderedTail;
22578 } else {
22579 var previousSibling = renderState.last;
22580
22581 if (previousSibling !== null) {
22582 previousSibling.sibling = renderedTail;
22583 } else {
22584 workInProgress.child = renderedTail;
22585 }
22586
22587 renderState.last = renderedTail;
22588 }
22589 }
22590
22591 if (renderState.tail !== null) {
22592 // We still have tail rows to render.
22593 // Pop a row.
22594 var next = renderState.tail;
22595 renderState.rendering = next;
22596 renderState.tail = next.sibling;
22597 renderState.renderingStartTime = now();
22598 next.sibling = null; // Restore the context.
22599 // TODO: We can probably just avoid popping it instead and only
22600 // setting it the first time we go from not suspended to suspended.
22601
22602 var suspenseContext = suspenseStackCursor.current;
22603
22604 if (didSuspendAlready) {
22605 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
22606 } else {
22607 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
22608 }
22609
22610 pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.
22611 // Don't bubble properties in this case.
22612
22613 return next;
22614 }
22615
22616 bubbleProperties(workInProgress);
22617 return null;
22618 }
22619
22620 case ScopeComponent:
22621 {
22622
22623 break;
22624 }
22625
22626 case OffscreenComponent:
22627 case LegacyHiddenComponent:
22628 {
22629 popRenderLanes(workInProgress);
22630 var _nextState = workInProgress.memoizedState;
22631 var nextIsHidden = _nextState !== null;
22632
22633 if (current !== null) {
22634 var _prevState = current.memoizedState;
22635 var prevIsHidden = _prevState !== null;
22636
22637 if (prevIsHidden !== nextIsHidden && ( // LegacyHidden doesn't do any hiding — it only pre-renders.
22638 !enableLegacyHidden )) {
22639 workInProgress.flags |= Visibility;
22640 }
22641 }
22642
22643 if (!nextIsHidden || (workInProgress.mode & ConcurrentMode) === NoMode) {
22644 bubbleProperties(workInProgress);
22645 } else {
22646 // Don't bubble properties for hidden children unless we're rendering
22647 // at offscreen priority.
22648 if (includesSomeLane(subtreeRenderLanes, OffscreenLane)) {
22649 bubbleProperties(workInProgress);
22650
22651 {
22652 // Check if there was an insertion or update in the hidden subtree.
22653 // If so, we need to hide those nodes in the commit phase, so
22654 // schedule a visibility effect.
22655 if ( workInProgress.subtreeFlags & (Placement | Update)) {
22656 workInProgress.flags |= Visibility;
22657 }
22658 }
22659 }
22660 }
22661 return null;
22662 }
22663
22664 case CacheComponent:
22665 {
22666
22667 return null;
22668 }
22669
22670 case TracingMarkerComponent:
22671 {
22672
22673 return null;
22674 }
22675 }
22676
22677 throw new Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in " + 'React. Please file an issue.');
22678 }
22679
22680 function unwindWork(current, workInProgress, renderLanes) {
22681 // Note: This intentionally doesn't check if we're hydrating because comparing
22682 // to the current tree provider fiber is just as fast and less error-prone.
22683 // Ideally we would have a special version of the work loop only
22684 // for hydration.
22685 popTreeContext(workInProgress);
22686
22687 switch (workInProgress.tag) {
22688 case ClassComponent:
22689 {
22690 var Component = workInProgress.type;
22691
22692 if (isContextProvider(Component)) {
22693 popContext(workInProgress);
22694 }
22695
22696 var flags = workInProgress.flags;
22697
22698 if (flags & ShouldCapture) {
22699 workInProgress.flags = flags & ~ShouldCapture | DidCapture;
22700
22701 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
22702 transferActualDuration(workInProgress);
22703 }
22704
22705 return workInProgress;
22706 }
22707
22708 return null;
22709 }
22710
22711 case HostRoot:
22712 {
22713 var root = workInProgress.stateNode;
22714 popHostContainer(workInProgress);
22715 popTopLevelContextObject(workInProgress);
22716 resetWorkInProgressVersions();
22717 var _flags = workInProgress.flags;
22718
22719 if ((_flags & ShouldCapture) !== NoFlags && (_flags & DidCapture) === NoFlags) {
22720 // There was an error during render that wasn't captured by a suspense
22721 // boundary. Do a second pass on the root to unmount the children.
22722 workInProgress.flags = _flags & ~ShouldCapture | DidCapture;
22723 return workInProgress;
22724 } // We unwound to the root without completing it. Exit.
22725
22726
22727 return null;
22728 }
22729
22730 case HostComponent:
22731 {
22732 // TODO: popHydrationState
22733 popHostContext(workInProgress);
22734 return null;
22735 }
22736
22737 case SuspenseComponent:
22738 {
22739 popSuspenseContext(workInProgress);
22740 var suspenseState = workInProgress.memoizedState;
22741
22742 if (suspenseState !== null && suspenseState.dehydrated !== null) {
22743 if (workInProgress.alternate === null) {
22744 throw new Error('Threw in newly mounted dehydrated component. This is likely a bug in ' + 'React. Please file an issue.');
22745 }
22746
22747 resetHydrationState();
22748 }
22749
22750 var _flags2 = workInProgress.flags;
22751
22752 if (_flags2 & ShouldCapture) {
22753 workInProgress.flags = _flags2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
22754
22755 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
22756 transferActualDuration(workInProgress);
22757 }
22758
22759 return workInProgress;
22760 }
22761
22762 return null;
22763 }
22764
22765 case SuspenseListComponent:
22766 {
22767 popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been
22768 // caught by a nested boundary. If not, it should bubble through.
22769
22770 return null;
22771 }
22772
22773 case HostPortal:
22774 popHostContainer(workInProgress);
22775 return null;
22776
22777 case ContextProvider:
22778 var context = workInProgress.type._context;
22779 popProvider(context, workInProgress);
22780 return null;
22781
22782 case OffscreenComponent:
22783 case LegacyHiddenComponent:
22784 popRenderLanes(workInProgress);
22785 return null;
22786
22787 case CacheComponent:
22788
22789 return null;
22790
22791 default:
22792 return null;
22793 }
22794 }
22795
22796 function unwindInterruptedWork(current, interruptedWork, renderLanes) {
22797 // Note: This intentionally doesn't check if we're hydrating because comparing
22798 // to the current tree provider fiber is just as fast and less error-prone.
22799 // Ideally we would have a special version of the work loop only
22800 // for hydration.
22801 popTreeContext(interruptedWork);
22802
22803 switch (interruptedWork.tag) {
22804 case ClassComponent:
22805 {
22806 var childContextTypes = interruptedWork.type.childContextTypes;
22807
22808 if (childContextTypes !== null && childContextTypes !== undefined) {
22809 popContext(interruptedWork);
22810 }
22811
22812 break;
22813 }
22814
22815 case HostRoot:
22816 {
22817 var root = interruptedWork.stateNode;
22818 popHostContainer(interruptedWork);
22819 popTopLevelContextObject(interruptedWork);
22820 resetWorkInProgressVersions();
22821 break;
22822 }
22823
22824 case HostComponent:
22825 {
22826 popHostContext(interruptedWork);
22827 break;
22828 }
22829
22830 case HostPortal:
22831 popHostContainer(interruptedWork);
22832 break;
22833
22834 case SuspenseComponent:
22835 popSuspenseContext(interruptedWork);
22836 break;
22837
22838 case SuspenseListComponent:
22839 popSuspenseContext(interruptedWork);
22840 break;
22841
22842 case ContextProvider:
22843 var context = interruptedWork.type._context;
22844 popProvider(context, interruptedWork);
22845 break;
22846
22847 case OffscreenComponent:
22848 case LegacyHiddenComponent:
22849 popRenderLanes(interruptedWork);
22850 break;
22851 }
22852 }
22853
22854 var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
22855
22856 {
22857 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
22858 } // Used during the commit phase to track the state of the Offscreen component stack.
22859 // Allows us to avoid traversing the return path to find the nearest Offscreen ancestor.
22860 // Only used when enableSuspenseLayoutEffectSemantics is enabled.
22861
22862
22863 var offscreenSubtreeIsHidden = false;
22864 var offscreenSubtreeWasHidden = false;
22865 var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
22866 var nextEffect = null; // Used for Profiling builds to track updaters.
22867
22868 var inProgressLanes = null;
22869 var inProgressRoot = null;
22870 function reportUncaughtErrorInDEV(error) {
22871 // Wrapping each small part of the commit phase into a guarded
22872 // callback is a bit too slow (https://github.com/facebook/react/pull/21666).
22873 // But we rely on it to surface errors to DEV tools like overlays
22874 // (https://github.com/facebook/react/issues/21712).
22875 // As a compromise, rethrow only caught errors in a guard.
22876 {
22877 invokeGuardedCallback(null, function () {
22878 throw error;
22879 });
22880 clearCaughtError();
22881 }
22882 }
22883
22884 var callComponentWillUnmountWithTimer = function (current, instance) {
22885 instance.props = current.memoizedProps;
22886 instance.state = current.memoizedState;
22887
22888 if ( current.mode & ProfileMode) {
22889 try {
22890 startLayoutEffectTimer();
22891 instance.componentWillUnmount();
22892 } finally {
22893 recordLayoutEffectDuration(current);
22894 }
22895 } else {
22896 instance.componentWillUnmount();
22897 }
22898 }; // Capture errors so they don't interrupt mounting.
22899
22900
22901 function safelyCallCommitHookLayoutEffectListMount(current, nearestMountedAncestor) {
22902 try {
22903 commitHookEffectListMount(Layout, current);
22904 } catch (error) {
22905 captureCommitPhaseError(current, nearestMountedAncestor, error);
22906 }
22907 } // Capture errors so they don't interrupt unmounting.
22908
22909
22910 function safelyCallComponentWillUnmount(current, nearestMountedAncestor, instance) {
22911 try {
22912 callComponentWillUnmountWithTimer(current, instance);
22913 } catch (error) {
22914 captureCommitPhaseError(current, nearestMountedAncestor, error);
22915 }
22916 } // Capture errors so they don't interrupt mounting.
22917
22918
22919 function safelyCallComponentDidMount(current, nearestMountedAncestor, instance) {
22920 try {
22921 instance.componentDidMount();
22922 } catch (error) {
22923 captureCommitPhaseError(current, nearestMountedAncestor, error);
22924 }
22925 } // Capture errors so they don't interrupt mounting.
22926
22927
22928 function safelyAttachRef(current, nearestMountedAncestor) {
22929 try {
22930 commitAttachRef(current);
22931 } catch (error) {
22932 captureCommitPhaseError(current, nearestMountedAncestor, error);
22933 }
22934 }
22935
22936 function safelyDetachRef(current, nearestMountedAncestor) {
22937 var ref = current.ref;
22938
22939 if (ref !== null) {
22940 if (typeof ref === 'function') {
22941 var retVal;
22942
22943 try {
22944 if (enableProfilerTimer && enableProfilerCommitHooks && current.mode & ProfileMode) {
22945 try {
22946 startLayoutEffectTimer();
22947 retVal = ref(null);
22948 } finally {
22949 recordLayoutEffectDuration(current);
22950 }
22951 } else {
22952 retVal = ref(null);
22953 }
22954 } catch (error) {
22955 captureCommitPhaseError(current, nearestMountedAncestor, error);
22956 }
22957
22958 {
22959 if (typeof retVal === 'function') {
22960 error('Unexpected return value from a callback ref in %s. ' + 'A callback ref should not return a function.', getComponentNameFromFiber(current));
22961 }
22962 }
22963 } else {
22964 ref.current = null;
22965 }
22966 }
22967 }
22968
22969 function safelyCallDestroy(current, nearestMountedAncestor, destroy) {
22970 try {
22971 destroy();
22972 } catch (error) {
22973 captureCommitPhaseError(current, nearestMountedAncestor, error);
22974 }
22975 }
22976
22977 var focusedInstanceHandle = null;
22978 var shouldFireAfterActiveInstanceBlur = false;
22979 function commitBeforeMutationEffects(root, firstChild) {
22980 focusedInstanceHandle = prepareForCommit(root.containerInfo);
22981 nextEffect = firstChild;
22982 commitBeforeMutationEffects_begin(); // We no longer need to track the active instance fiber
22983
22984 var shouldFire = shouldFireAfterActiveInstanceBlur;
22985 shouldFireAfterActiveInstanceBlur = false;
22986 focusedInstanceHandle = null;
22987 return shouldFire;
22988 }
22989
22990 function commitBeforeMutationEffects_begin() {
22991 while (nextEffect !== null) {
22992 var fiber = nextEffect; // This phase is only used for beforeActiveInstanceBlur.
22993
22994 var child = fiber.child;
22995
22996 if ((fiber.subtreeFlags & BeforeMutationMask) !== NoFlags && child !== null) {
22997 child.return = fiber;
22998 nextEffect = child;
22999 } else {
23000 commitBeforeMutationEffects_complete();
23001 }
23002 }
23003 }
23004
23005 function commitBeforeMutationEffects_complete() {
23006 while (nextEffect !== null) {
23007 var fiber = nextEffect;
23008 setCurrentFiber(fiber);
23009
23010 try {
23011 commitBeforeMutationEffectsOnFiber(fiber);
23012 } catch (error) {
23013 captureCommitPhaseError(fiber, fiber.return, error);
23014 }
23015
23016 resetCurrentFiber();
23017 var sibling = fiber.sibling;
23018
23019 if (sibling !== null) {
23020 sibling.return = fiber.return;
23021 nextEffect = sibling;
23022 return;
23023 }
23024
23025 nextEffect = fiber.return;
23026 }
23027 }
23028
23029 function commitBeforeMutationEffectsOnFiber(finishedWork) {
23030 var current = finishedWork.alternate;
23031 var flags = finishedWork.flags;
23032
23033 if ((flags & Snapshot) !== NoFlags) {
23034 setCurrentFiber(finishedWork);
23035
23036 switch (finishedWork.tag) {
23037 case FunctionComponent:
23038 case ForwardRef:
23039 case SimpleMemoComponent:
23040 {
23041 break;
23042 }
23043
23044 case ClassComponent:
23045 {
23046 if (current !== null) {
23047 var prevProps = current.memoizedProps;
23048 var prevState = current.memoizedState;
23049 var instance = finishedWork.stateNode; // We could update instance props and state here,
23050 // but instead we rely on them being set during last render.
23051 // TODO: revisit this when we implement resuming.
23052
23053 {
23054 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
23055 if (instance.props !== finishedWork.memoizedProps) {
23056 error('Expected %s props to match memoized props before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
23057 }
23058
23059 if (instance.state !== finishedWork.memoizedState) {
23060 error('Expected %s state to match memoized state before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.state`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
23061 }
23062 }
23063 }
23064
23065 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
23066
23067 {
23068 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
23069
23070 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
23071 didWarnSet.add(finishedWork.type);
23072
23073 error('%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentNameFromFiber(finishedWork));
23074 }
23075 }
23076
23077 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
23078 }
23079
23080 break;
23081 }
23082
23083 case HostRoot:
23084 {
23085 {
23086 var root = finishedWork.stateNode;
23087 clearContainer(root.containerInfo);
23088 }
23089
23090 break;
23091 }
23092
23093 case HostComponent:
23094 case HostText:
23095 case HostPortal:
23096 case IncompleteClassComponent:
23097 // Nothing to do for these component types
23098 break;
23099
23100 default:
23101 {
23102 throw new Error('This unit of work tag should not have side-effects. This error is ' + 'likely caused by a bug in React. Please file an issue.');
23103 }
23104 }
23105
23106 resetCurrentFiber();
23107 }
23108 }
23109
23110 function commitHookEffectListUnmount(flags, finishedWork, nearestMountedAncestor) {
23111 var updateQueue = finishedWork.updateQueue;
23112 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
23113
23114 if (lastEffect !== null) {
23115 var firstEffect = lastEffect.next;
23116 var effect = firstEffect;
23117
23118 do {
23119 if ((effect.tag & flags) === flags) {
23120 // Unmount
23121 var destroy = effect.destroy;
23122 effect.destroy = undefined;
23123
23124 if (destroy !== undefined) {
23125 {
23126 if ((flags & Passive$1) !== NoFlags$1) {
23127 markComponentPassiveEffectUnmountStarted(finishedWork);
23128 } else if ((flags & Layout) !== NoFlags$1) {
23129 markComponentLayoutEffectUnmountStarted(finishedWork);
23130 }
23131 }
23132
23133 {
23134 if ((flags & Insertion) !== NoFlags$1) {
23135 setIsRunningInsertionEffect(true);
23136 }
23137 }
23138
23139 safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy);
23140
23141 {
23142 if ((flags & Insertion) !== NoFlags$1) {
23143 setIsRunningInsertionEffect(false);
23144 }
23145 }
23146
23147 {
23148 if ((flags & Passive$1) !== NoFlags$1) {
23149 markComponentPassiveEffectUnmountStopped();
23150 } else if ((flags & Layout) !== NoFlags$1) {
23151 markComponentLayoutEffectUnmountStopped();
23152 }
23153 }
23154 }
23155 }
23156
23157 effect = effect.next;
23158 } while (effect !== firstEffect);
23159 }
23160 }
23161
23162 function commitHookEffectListMount(flags, finishedWork) {
23163 var updateQueue = finishedWork.updateQueue;
23164 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
23165
23166 if (lastEffect !== null) {
23167 var firstEffect = lastEffect.next;
23168 var effect = firstEffect;
23169
23170 do {
23171 if ((effect.tag & flags) === flags) {
23172 {
23173 if ((flags & Passive$1) !== NoFlags$1) {
23174 markComponentPassiveEffectMountStarted(finishedWork);
23175 } else if ((flags & Layout) !== NoFlags$1) {
23176 markComponentLayoutEffectMountStarted(finishedWork);
23177 }
23178 } // Mount
23179
23180
23181 var create = effect.create;
23182
23183 {
23184 if ((flags & Insertion) !== NoFlags$1) {
23185 setIsRunningInsertionEffect(true);
23186 }
23187 }
23188
23189 effect.destroy = create();
23190
23191 {
23192 if ((flags & Insertion) !== NoFlags$1) {
23193 setIsRunningInsertionEffect(false);
23194 }
23195 }
23196
23197 {
23198 if ((flags & Passive$1) !== NoFlags$1) {
23199 markComponentPassiveEffectMountStopped();
23200 } else if ((flags & Layout) !== NoFlags$1) {
23201 markComponentLayoutEffectMountStopped();
23202 }
23203 }
23204
23205 {
23206 var destroy = effect.destroy;
23207
23208 if (destroy !== undefined && typeof destroy !== 'function') {
23209 var hookName = void 0;
23210
23211 if ((effect.tag & Layout) !== NoFlags) {
23212 hookName = 'useLayoutEffect';
23213 } else if ((effect.tag & Insertion) !== NoFlags) {
23214 hookName = 'useInsertionEffect';
23215 } else {
23216 hookName = 'useEffect';
23217 }
23218
23219 var addendum = void 0;
23220
23221 if (destroy === null) {
23222 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
23223 } else if (typeof destroy.then === 'function') {
23224 addendum = '\n\nIt looks like you wrote ' + hookName + '(async () => ...) or returned a Promise. ' + 'Instead, write the async function inside your effect ' + 'and call it immediately:\n\n' + hookName + '(() => {\n' + ' async function fetchData() {\n' + ' // You can await here\n' + ' const response = await MyAPI.getData(someId);\n' + ' // ...\n' + ' }\n' + ' fetchData();\n' + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + 'Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching';
23225 } else {
23226 addendum = ' You returned: ' + destroy;
23227 }
23228
23229 error('%s must not return anything besides a function, ' + 'which is used for clean-up.%s', hookName, addendum);
23230 }
23231 }
23232 }
23233
23234 effect = effect.next;
23235 } while (effect !== firstEffect);
23236 }
23237 }
23238
23239 function commitPassiveEffectDurations(finishedRoot, finishedWork) {
23240 {
23241 // Only Profilers with work in their subtree will have an Update effect scheduled.
23242 if ((finishedWork.flags & Update) !== NoFlags) {
23243 switch (finishedWork.tag) {
23244 case Profiler:
23245 {
23246 var passiveEffectDuration = finishedWork.stateNode.passiveEffectDuration;
23247 var _finishedWork$memoize = finishedWork.memoizedProps,
23248 id = _finishedWork$memoize.id,
23249 onPostCommit = _finishedWork$memoize.onPostCommit; // This value will still reflect the previous commit phase.
23250 // It does not get reset until the start of the next commit phase.
23251
23252 var commitTime = getCommitTime();
23253 var phase = finishedWork.alternate === null ? 'mount' : 'update';
23254
23255 {
23256 if (isCurrentUpdateNested()) {
23257 phase = 'nested-update';
23258 }
23259 }
23260
23261 if (typeof onPostCommit === 'function') {
23262 onPostCommit(id, phase, passiveEffectDuration, commitTime);
23263 } // Bubble times to the next nearest ancestor Profiler.
23264 // After we process that Profiler, we'll bubble further up.
23265
23266
23267 var parentFiber = finishedWork.return;
23268
23269 outer: while (parentFiber !== null) {
23270 switch (parentFiber.tag) {
23271 case HostRoot:
23272 var root = parentFiber.stateNode;
23273 root.passiveEffectDuration += passiveEffectDuration;
23274 break outer;
23275
23276 case Profiler:
23277 var parentStateNode = parentFiber.stateNode;
23278 parentStateNode.passiveEffectDuration += passiveEffectDuration;
23279 break outer;
23280 }
23281
23282 parentFiber = parentFiber.return;
23283 }
23284
23285 break;
23286 }
23287 }
23288 }
23289 }
23290 }
23291
23292 function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork, committedLanes) {
23293 if ((finishedWork.flags & LayoutMask) !== NoFlags) {
23294 switch (finishedWork.tag) {
23295 case FunctionComponent:
23296 case ForwardRef:
23297 case SimpleMemoComponent:
23298 {
23299 if ( !offscreenSubtreeWasHidden) {
23300 // At this point layout effects have already been destroyed (during mutation phase).
23301 // This is done to prevent sibling component effects from interfering with each other,
23302 // e.g. a destroy function in one component should never override a ref set
23303 // by a create function in another component during the same commit.
23304 if ( finishedWork.mode & ProfileMode) {
23305 try {
23306 startLayoutEffectTimer();
23307 commitHookEffectListMount(Layout | HasEffect, finishedWork);
23308 } finally {
23309 recordLayoutEffectDuration(finishedWork);
23310 }
23311 } else {
23312 commitHookEffectListMount(Layout | HasEffect, finishedWork);
23313 }
23314 }
23315
23316 break;
23317 }
23318
23319 case ClassComponent:
23320 {
23321 var instance = finishedWork.stateNode;
23322
23323 if (finishedWork.flags & Update) {
23324 if (!offscreenSubtreeWasHidden) {
23325 if (current === null) {
23326 // We could update instance props and state here,
23327 // but instead we rely on them being set during last render.
23328 // TODO: revisit this when we implement resuming.
23329 {
23330 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
23331 if (instance.props !== finishedWork.memoizedProps) {
23332 error('Expected %s props to match memoized props before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
23333 }
23334
23335 if (instance.state !== finishedWork.memoizedState) {
23336 error('Expected %s state to match memoized state before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.state`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
23337 }
23338 }
23339 }
23340
23341 if ( finishedWork.mode & ProfileMode) {
23342 try {
23343 startLayoutEffectTimer();
23344 instance.componentDidMount();
23345 } finally {
23346 recordLayoutEffectDuration(finishedWork);
23347 }
23348 } else {
23349 instance.componentDidMount();
23350 }
23351 } else {
23352 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
23353 var prevState = current.memoizedState; // We could update instance props and state here,
23354 // but instead we rely on them being set during last render.
23355 // TODO: revisit this when we implement resuming.
23356
23357 {
23358 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
23359 if (instance.props !== finishedWork.memoizedProps) {
23360 error('Expected %s props to match memoized props before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
23361 }
23362
23363 if (instance.state !== finishedWork.memoizedState) {
23364 error('Expected %s state to match memoized state before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.state`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
23365 }
23366 }
23367 }
23368
23369 if ( finishedWork.mode & ProfileMode) {
23370 try {
23371 startLayoutEffectTimer();
23372 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
23373 } finally {
23374 recordLayoutEffectDuration(finishedWork);
23375 }
23376 } else {
23377 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
23378 }
23379 }
23380 }
23381 } // TODO: I think this is now always non-null by the time it reaches the
23382 // commit phase. Consider removing the type check.
23383
23384
23385 var updateQueue = finishedWork.updateQueue;
23386
23387 if (updateQueue !== null) {
23388 {
23389 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
23390 if (instance.props !== finishedWork.memoizedProps) {
23391 error('Expected %s props to match memoized props before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
23392 }
23393
23394 if (instance.state !== finishedWork.memoizedState) {
23395 error('Expected %s state to match memoized state before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.state`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
23396 }
23397 }
23398 } // We could update instance props and state here,
23399 // but instead we rely on them being set during last render.
23400 // TODO: revisit this when we implement resuming.
23401
23402
23403 commitUpdateQueue(finishedWork, updateQueue, instance);
23404 }
23405
23406 break;
23407 }
23408
23409 case HostRoot:
23410 {
23411 // TODO: I think this is now always non-null by the time it reaches the
23412 // commit phase. Consider removing the type check.
23413 var _updateQueue = finishedWork.updateQueue;
23414
23415 if (_updateQueue !== null) {
23416 var _instance = null;
23417
23418 if (finishedWork.child !== null) {
23419 switch (finishedWork.child.tag) {
23420 case HostComponent:
23421 _instance = getPublicInstance(finishedWork.child.stateNode);
23422 break;
23423
23424 case ClassComponent:
23425 _instance = finishedWork.child.stateNode;
23426 break;
23427 }
23428 }
23429
23430 commitUpdateQueue(finishedWork, _updateQueue, _instance);
23431 }
23432
23433 break;
23434 }
23435
23436 case HostComponent:
23437 {
23438 var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted
23439 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
23440 // These effects should only be committed when components are first mounted,
23441 // aka when there is no current/alternate.
23442
23443 if (current === null && finishedWork.flags & Update) {
23444 var type = finishedWork.type;
23445 var props = finishedWork.memoizedProps;
23446 commitMount(_instance2, type, props);
23447 }
23448
23449 break;
23450 }
23451
23452 case HostText:
23453 {
23454 // We have no life-cycles associated with text.
23455 break;
23456 }
23457
23458 case HostPortal:
23459 {
23460 // We have no life-cycles associated with portals.
23461 break;
23462 }
23463
23464 case Profiler:
23465 {
23466 {
23467 var _finishedWork$memoize2 = finishedWork.memoizedProps,
23468 onCommit = _finishedWork$memoize2.onCommit,
23469 onRender = _finishedWork$memoize2.onRender;
23470 var effectDuration = finishedWork.stateNode.effectDuration;
23471 var commitTime = getCommitTime();
23472 var phase = current === null ? 'mount' : 'update';
23473
23474 {
23475 if (isCurrentUpdateNested()) {
23476 phase = 'nested-update';
23477 }
23478 }
23479
23480 if (typeof onRender === 'function') {
23481 onRender(finishedWork.memoizedProps.id, phase, finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, commitTime);
23482 }
23483
23484 {
23485 if (typeof onCommit === 'function') {
23486 onCommit(finishedWork.memoizedProps.id, phase, effectDuration, commitTime);
23487 } // Schedule a passive effect for this Profiler to call onPostCommit hooks.
23488 // This effect should be scheduled even if there is no onPostCommit callback for this Profiler,
23489 // because the effect is also where times bubble to parent Profilers.
23490
23491
23492 enqueuePendingPassiveProfilerEffect(finishedWork); // Propagate layout effect durations to the next nearest Profiler ancestor.
23493 // Do not reset these values until the next render so DevTools has a chance to read them first.
23494
23495 var parentFiber = finishedWork.return;
23496
23497 outer: while (parentFiber !== null) {
23498 switch (parentFiber.tag) {
23499 case HostRoot:
23500 var root = parentFiber.stateNode;
23501 root.effectDuration += effectDuration;
23502 break outer;
23503
23504 case Profiler:
23505 var parentStateNode = parentFiber.stateNode;
23506 parentStateNode.effectDuration += effectDuration;
23507 break outer;
23508 }
23509
23510 parentFiber = parentFiber.return;
23511 }
23512 }
23513 }
23514
23515 break;
23516 }
23517
23518 case SuspenseComponent:
23519 {
23520 commitSuspenseHydrationCallbacks(finishedRoot, finishedWork);
23521 break;
23522 }
23523
23524 case SuspenseListComponent:
23525 case IncompleteClassComponent:
23526 case ScopeComponent:
23527 case OffscreenComponent:
23528 case LegacyHiddenComponent:
23529 case TracingMarkerComponent:
23530 {
23531 break;
23532 }
23533
23534 default:
23535 throw new Error('This unit of work tag should not have side-effects. This error is ' + 'likely caused by a bug in React. Please file an issue.');
23536 }
23537 }
23538
23539 if ( !offscreenSubtreeWasHidden) {
23540 {
23541 if (finishedWork.flags & Ref) {
23542 commitAttachRef(finishedWork);
23543 }
23544 }
23545 }
23546 }
23547
23548 function reappearLayoutEffectsOnFiber(node) {
23549 // Turn on layout effects in a tree that previously disappeared.
23550 // TODO (Offscreen) Check: flags & LayoutStatic
23551 switch (node.tag) {
23552 case FunctionComponent:
23553 case ForwardRef:
23554 case SimpleMemoComponent:
23555 {
23556 if ( node.mode & ProfileMode) {
23557 try {
23558 startLayoutEffectTimer();
23559 safelyCallCommitHookLayoutEffectListMount(node, node.return);
23560 } finally {
23561 recordLayoutEffectDuration(node);
23562 }
23563 } else {
23564 safelyCallCommitHookLayoutEffectListMount(node, node.return);
23565 }
23566
23567 break;
23568 }
23569
23570 case ClassComponent:
23571 {
23572 var instance = node.stateNode;
23573
23574 if (typeof instance.componentDidMount === 'function') {
23575 safelyCallComponentDidMount(node, node.return, instance);
23576 }
23577
23578 safelyAttachRef(node, node.return);
23579 break;
23580 }
23581
23582 case HostComponent:
23583 {
23584 safelyAttachRef(node, node.return);
23585 break;
23586 }
23587 }
23588 }
23589
23590 function hideOrUnhideAllChildren(finishedWork, isHidden) {
23591 // Only hide or unhide the top-most host nodes.
23592 var hostSubtreeRoot = null;
23593
23594 {
23595 // We only have the top Fiber that was inserted but we need to recurse down its
23596 // children to find all the terminal nodes.
23597 var node = finishedWork;
23598
23599 while (true) {
23600 if (node.tag === HostComponent) {
23601 if (hostSubtreeRoot === null) {
23602 hostSubtreeRoot = node;
23603
23604 try {
23605 var instance = node.stateNode;
23606
23607 if (isHidden) {
23608 hideInstance(instance);
23609 } else {
23610 unhideInstance(node.stateNode, node.memoizedProps);
23611 }
23612 } catch (error) {
23613 captureCommitPhaseError(finishedWork, finishedWork.return, error);
23614 }
23615 }
23616 } else if (node.tag === HostText) {
23617 if (hostSubtreeRoot === null) {
23618 try {
23619 var _instance3 = node.stateNode;
23620
23621 if (isHidden) {
23622 hideTextInstance(_instance3);
23623 } else {
23624 unhideTextInstance(_instance3, node.memoizedProps);
23625 }
23626 } catch (error) {
23627 captureCommitPhaseError(finishedWork, finishedWork.return, error);
23628 }
23629 }
23630 } else if ((node.tag === OffscreenComponent || node.tag === LegacyHiddenComponent) && node.memoizedState !== null && node !== finishedWork) ; else if (node.child !== null) {
23631 node.child.return = node;
23632 node = node.child;
23633 continue;
23634 }
23635
23636 if (node === finishedWork) {
23637 return;
23638 }
23639
23640 while (node.sibling === null) {
23641 if (node.return === null || node.return === finishedWork) {
23642 return;
23643 }
23644
23645 if (hostSubtreeRoot === node) {
23646 hostSubtreeRoot = null;
23647 }
23648
23649 node = node.return;
23650 }
23651
23652 if (hostSubtreeRoot === node) {
23653 hostSubtreeRoot = null;
23654 }
23655
23656 node.sibling.return = node.return;
23657 node = node.sibling;
23658 }
23659 }
23660 }
23661
23662 function commitAttachRef(finishedWork) {
23663 var ref = finishedWork.ref;
23664
23665 if (ref !== null) {
23666 var instance = finishedWork.stateNode;
23667 var instanceToUse;
23668
23669 switch (finishedWork.tag) {
23670 case HostComponent:
23671 instanceToUse = getPublicInstance(instance);
23672 break;
23673
23674 default:
23675 instanceToUse = instance;
23676 } // Moved outside to ensure DCE works with this flag
23677
23678 if (typeof ref === 'function') {
23679 var retVal;
23680
23681 if ( finishedWork.mode & ProfileMode) {
23682 try {
23683 startLayoutEffectTimer();
23684 retVal = ref(instanceToUse);
23685 } finally {
23686 recordLayoutEffectDuration(finishedWork);
23687 }
23688 } else {
23689 retVal = ref(instanceToUse);
23690 }
23691
23692 {
23693 if (typeof retVal === 'function') {
23694 error('Unexpected return value from a callback ref in %s. ' + 'A callback ref should not return a function.', getComponentNameFromFiber(finishedWork));
23695 }
23696 }
23697 } else {
23698 {
23699 if (!ref.hasOwnProperty('current')) {
23700 error('Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().', getComponentNameFromFiber(finishedWork));
23701 }
23702 }
23703
23704 ref.current = instanceToUse;
23705 }
23706 }
23707 }
23708
23709 function detachFiberMutation(fiber) {
23710 // Cut off the return pointer to disconnect it from the tree.
23711 // This enables us to detect and warn against state updates on an unmounted component.
23712 // It also prevents events from bubbling from within disconnected components.
23713 //
23714 // Ideally, we should also clear the child pointer of the parent alternate to let this
23715 // get GC:ed but we don't know which for sure which parent is the current
23716 // one so we'll settle for GC:ing the subtree of this child.
23717 // This child itself will be GC:ed when the parent updates the next time.
23718 //
23719 // Note that we can't clear child or sibling pointers yet.
23720 // They're needed for passive effects and for findDOMNode.
23721 // We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects).
23722 //
23723 // Don't reset the alternate yet, either. We need that so we can detach the
23724 // alternate's fields in the passive phase. Clearing the return pointer is
23725 // sufficient for findDOMNode semantics.
23726 var alternate = fiber.alternate;
23727
23728 if (alternate !== null) {
23729 alternate.return = null;
23730 }
23731
23732 fiber.return = null;
23733 }
23734
23735 function detachFiberAfterEffects(fiber) {
23736 var alternate = fiber.alternate;
23737
23738 if (alternate !== null) {
23739 fiber.alternate = null;
23740 detachFiberAfterEffects(alternate);
23741 } // Note: Defensively using negation instead of < in case
23742 // `deletedTreeCleanUpLevel` is undefined.
23743
23744
23745 {
23746 // Clear cyclical Fiber fields. This level alone is designed to roughly
23747 // approximate the planned Fiber refactor. In that world, `setState` will be
23748 // bound to a special "instance" object instead of a Fiber. The Instance
23749 // object will not have any of these fields. It will only be connected to
23750 // the fiber tree via a single link at the root. So if this level alone is
23751 // sufficient to fix memory issues, that bodes well for our plans.
23752 fiber.child = null;
23753 fiber.deletions = null;
23754 fiber.sibling = null; // The `stateNode` is cyclical because on host nodes it points to the host
23755 // tree, which has its own pointers to children, parents, and siblings.
23756 // The other host nodes also point back to fibers, so we should detach that
23757 // one, too.
23758
23759 if (fiber.tag === HostComponent) {
23760 var hostInstance = fiber.stateNode;
23761
23762 if (hostInstance !== null) {
23763 detachDeletedInstance(hostInstance);
23764 }
23765 }
23766
23767 fiber.stateNode = null; // I'm intentionally not clearing the `return` field in this level. We
23768 // already disconnect the `return` pointer at the root of the deleted
23769 // subtree (in `detachFiberMutation`). Besides, `return` by itself is not
23770 // cyclical — it's only cyclical when combined with `child`, `sibling`, and
23771 // `alternate`. But we'll clear it in the next level anyway, just in case.
23772
23773 {
23774 fiber._debugOwner = null;
23775 }
23776
23777 {
23778 // Theoretically, nothing in here should be necessary, because we already
23779 // disconnected the fiber from the tree. So even if something leaks this
23780 // particular fiber, it won't leak anything else
23781 //
23782 // The purpose of this branch is to be super aggressive so we can measure
23783 // if there's any difference in memory impact. If there is, that could
23784 // indicate a React leak we don't know about.
23785 fiber.return = null;
23786 fiber.dependencies = null;
23787 fiber.memoizedProps = null;
23788 fiber.memoizedState = null;
23789 fiber.pendingProps = null;
23790 fiber.stateNode = null; // TODO: Move to `commitPassiveUnmountInsideDeletedTreeOnFiber` instead.
23791
23792 fiber.updateQueue = null;
23793 }
23794 }
23795 }
23796
23797 function getHostParentFiber(fiber) {
23798 var parent = fiber.return;
23799
23800 while (parent !== null) {
23801 if (isHostParent(parent)) {
23802 return parent;
23803 }
23804
23805 parent = parent.return;
23806 }
23807
23808 throw new Error('Expected to find a host parent. This error is likely caused by a bug ' + 'in React. Please file an issue.');
23809 }
23810
23811 function isHostParent(fiber) {
23812 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
23813 }
23814
23815 function getHostSibling(fiber) {
23816 // We're going to search forward into the tree until we find a sibling host
23817 // node. Unfortunately, if multiple insertions are done in a row we have to
23818 // search past them. This leads to exponential search for the next sibling.
23819 // TODO: Find a more efficient way to do this.
23820 var node = fiber;
23821
23822 siblings: while (true) {
23823 // If we didn't find anything, let's try the next sibling.
23824 while (node.sibling === null) {
23825 if (node.return === null || isHostParent(node.return)) {
23826 // If we pop out of the root or hit the parent the fiber we are the
23827 // last sibling.
23828 return null;
23829 }
23830
23831 node = node.return;
23832 }
23833
23834 node.sibling.return = node.return;
23835 node = node.sibling;
23836
23837 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) {
23838 // If it is not host node and, we might have a host node inside it.
23839 // Try to search down until we find one.
23840 if (node.flags & Placement) {
23841 // If we don't have a child, try the siblings instead.
23842 continue siblings;
23843 } // If we don't have a child, try the siblings instead.
23844 // We also skip portals because they are not part of this host tree.
23845
23846
23847 if (node.child === null || node.tag === HostPortal) {
23848 continue siblings;
23849 } else {
23850 node.child.return = node;
23851 node = node.child;
23852 }
23853 } // Check if this host node is stable or about to be placed.
23854
23855
23856 if (!(node.flags & Placement)) {
23857 // Found it!
23858 return node.stateNode;
23859 }
23860 }
23861 }
23862
23863 function commitPlacement(finishedWork) {
23864
23865
23866 var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together.
23867
23868 switch (parentFiber.tag) {
23869 case HostComponent:
23870 {
23871 var parent = parentFiber.stateNode;
23872
23873 if (parentFiber.flags & ContentReset) {
23874 // Reset the text content of the parent before doing any insertions
23875 resetTextContent(parent); // Clear ContentReset from the effect tag
23876
23877 parentFiber.flags &= ~ContentReset;
23878 }
23879
23880 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
23881 // children to find all the terminal nodes.
23882
23883 insertOrAppendPlacementNode(finishedWork, before, parent);
23884 break;
23885 }
23886
23887 case HostRoot:
23888 case HostPortal:
23889 {
23890 var _parent = parentFiber.stateNode.containerInfo;
23891
23892 var _before = getHostSibling(finishedWork);
23893
23894 insertOrAppendPlacementNodeIntoContainer(finishedWork, _before, _parent);
23895 break;
23896 }
23897 // eslint-disable-next-line-no-fallthrough
23898
23899 default:
23900 throw new Error('Invalid host parent fiber. This error is likely caused by a bug ' + 'in React. Please file an issue.');
23901 }
23902 }
23903
23904 function insertOrAppendPlacementNodeIntoContainer(node, before, parent) {
23905 var tag = node.tag;
23906 var isHost = tag === HostComponent || tag === HostText;
23907
23908 if (isHost) {
23909 var stateNode = node.stateNode;
23910
23911 if (before) {
23912 insertInContainerBefore(parent, stateNode, before);
23913 } else {
23914 appendChildToContainer(parent, stateNode);
23915 }
23916 } else if (tag === HostPortal) ; else {
23917 var child = node.child;
23918
23919 if (child !== null) {
23920 insertOrAppendPlacementNodeIntoContainer(child, before, parent);
23921 var sibling = child.sibling;
23922
23923 while (sibling !== null) {
23924 insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);
23925 sibling = sibling.sibling;
23926 }
23927 }
23928 }
23929 }
23930
23931 function insertOrAppendPlacementNode(node, before, parent) {
23932 var tag = node.tag;
23933 var isHost = tag === HostComponent || tag === HostText;
23934
23935 if (isHost) {
23936 var stateNode = node.stateNode;
23937
23938 if (before) {
23939 insertBefore(parent, stateNode, before);
23940 } else {
23941 appendChild(parent, stateNode);
23942 }
23943 } else if (tag === HostPortal) ; else {
23944 var child = node.child;
23945
23946 if (child !== null) {
23947 insertOrAppendPlacementNode(child, before, parent);
23948 var sibling = child.sibling;
23949
23950 while (sibling !== null) {
23951 insertOrAppendPlacementNode(sibling, before, parent);
23952 sibling = sibling.sibling;
23953 }
23954 }
23955 }
23956 } // These are tracked on the stack as we recursively traverse a
23957 // deleted subtree.
23958 // TODO: Update these during the whole mutation phase, not just during
23959 // a deletion.
23960
23961
23962 var hostParent = null;
23963 var hostParentIsContainer = false;
23964
23965 function commitDeletionEffects(root, returnFiber, deletedFiber) {
23966 {
23967 // We only have the top Fiber that was deleted but we need to recurse down its
23968 // children to find all the terminal nodes.
23969 // Recursively delete all host nodes from the parent, detach refs, clean
23970 // up mounted layout effects, and call componentWillUnmount.
23971 // We only need to remove the topmost host child in each branch. But then we
23972 // still need to keep traversing to unmount effects, refs, and cWU. TODO: We
23973 // could split this into two separate traversals functions, where the second
23974 // one doesn't include any removeChild logic. This is maybe the same
23975 // function as "disappearLayoutEffects" (or whatever that turns into after
23976 // the layout phase is refactored to use recursion).
23977 // Before starting, find the nearest host parent on the stack so we know
23978 // which instance/container to remove the children from.
23979 // TODO: Instead of searching up the fiber return path on every deletion, we
23980 // can track the nearest host component on the JS stack as we traverse the
23981 // tree during the commit phase. This would make insertions faster, too.
23982 var parent = returnFiber;
23983
23984 findParent: while (parent !== null) {
23985 switch (parent.tag) {
23986 case HostComponent:
23987 {
23988 hostParent = parent.stateNode;
23989 hostParentIsContainer = false;
23990 break findParent;
23991 }
23992
23993 case HostRoot:
23994 {
23995 hostParent = parent.stateNode.containerInfo;
23996 hostParentIsContainer = true;
23997 break findParent;
23998 }
23999
24000 case HostPortal:
24001 {
24002 hostParent = parent.stateNode.containerInfo;
24003 hostParentIsContainer = true;
24004 break findParent;
24005 }
24006 }
24007
24008 parent = parent.return;
24009 }
24010
24011 if (hostParent === null) {
24012 throw new Error('Expected to find a host parent. This error is likely caused by ' + 'a bug in React. Please file an issue.');
24013 }
24014
24015 commitDeletionEffectsOnFiber(root, returnFiber, deletedFiber);
24016 hostParent = null;
24017 hostParentIsContainer = false;
24018 }
24019
24020 detachFiberMutation(deletedFiber);
24021 }
24022
24023 function recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, parent) {
24024 // TODO: Use a static flag to skip trees that don't have unmount effects
24025 var child = parent.child;
24026
24027 while (child !== null) {
24028 commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, child);
24029 child = child.sibling;
24030 }
24031 }
24032
24033 function commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, deletedFiber) {
24034 onCommitUnmount(deletedFiber); // The cases in this outer switch modify the stack before they traverse
24035 // into their subtree. There are simpler cases in the inner switch
24036 // that don't modify the stack.
24037
24038 switch (deletedFiber.tag) {
24039 case HostComponent:
24040 {
24041 if (!offscreenSubtreeWasHidden) {
24042 safelyDetachRef(deletedFiber, nearestMountedAncestor);
24043 } // Intentional fallthrough to next branch
24044
24045 }
24046 // eslint-disable-next-line-no-fallthrough
24047
24048 case HostText:
24049 {
24050 // We only need to remove the nearest host child. Set the host parent
24051 // to `null` on the stack to indicate that nested children don't
24052 // need to be removed.
24053 {
24054 var prevHostParent = hostParent;
24055 var prevHostParentIsContainer = hostParentIsContainer;
24056 hostParent = null;
24057 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
24058 hostParent = prevHostParent;
24059 hostParentIsContainer = prevHostParentIsContainer;
24060
24061 if (hostParent !== null) {
24062 // Now that all the child effects have unmounted, we can remove the
24063 // node from the tree.
24064 if (hostParentIsContainer) {
24065 removeChildFromContainer(hostParent, deletedFiber.stateNode);
24066 } else {
24067 removeChild(hostParent, deletedFiber.stateNode);
24068 }
24069 }
24070 }
24071
24072 return;
24073 }
24074
24075 case DehydratedFragment:
24076 {
24077 // Delete the dehydrated suspense boundary and all of its content.
24078
24079
24080 {
24081 if (hostParent !== null) {
24082 if (hostParentIsContainer) {
24083 clearSuspenseBoundaryFromContainer(hostParent, deletedFiber.stateNode);
24084 } else {
24085 clearSuspenseBoundary(hostParent, deletedFiber.stateNode);
24086 }
24087 }
24088 }
24089
24090 return;
24091 }
24092
24093 case HostPortal:
24094 {
24095 {
24096 // When we go into a portal, it becomes the parent to remove from.
24097 var _prevHostParent = hostParent;
24098 var _prevHostParentIsContainer = hostParentIsContainer;
24099 hostParent = deletedFiber.stateNode.containerInfo;
24100 hostParentIsContainer = true;
24101 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
24102 hostParent = _prevHostParent;
24103 hostParentIsContainer = _prevHostParentIsContainer;
24104 }
24105
24106 return;
24107 }
24108
24109 case FunctionComponent:
24110 case ForwardRef:
24111 case MemoComponent:
24112 case SimpleMemoComponent:
24113 {
24114 if (!offscreenSubtreeWasHidden) {
24115 var updateQueue = deletedFiber.updateQueue;
24116
24117 if (updateQueue !== null) {
24118 var lastEffect = updateQueue.lastEffect;
24119
24120 if (lastEffect !== null) {
24121 var firstEffect = lastEffect.next;
24122 var effect = firstEffect;
24123
24124 do {
24125 var _effect = effect,
24126 destroy = _effect.destroy,
24127 tag = _effect.tag;
24128
24129 if (destroy !== undefined) {
24130 if ((tag & Insertion) !== NoFlags$1) {
24131 safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy);
24132 } else if ((tag & Layout) !== NoFlags$1) {
24133 {
24134 markComponentLayoutEffectUnmountStarted(deletedFiber);
24135 }
24136
24137 if ( deletedFiber.mode & ProfileMode) {
24138 startLayoutEffectTimer();
24139 safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy);
24140 recordLayoutEffectDuration(deletedFiber);
24141 } else {
24142 safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy);
24143 }
24144
24145 {
24146 markComponentLayoutEffectUnmountStopped();
24147 }
24148 }
24149 }
24150
24151 effect = effect.next;
24152 } while (effect !== firstEffect);
24153 }
24154 }
24155 }
24156
24157 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
24158 return;
24159 }
24160
24161 case ClassComponent:
24162 {
24163 if (!offscreenSubtreeWasHidden) {
24164 safelyDetachRef(deletedFiber, nearestMountedAncestor);
24165 var instance = deletedFiber.stateNode;
24166
24167 if (typeof instance.componentWillUnmount === 'function') {
24168 safelyCallComponentWillUnmount(deletedFiber, nearestMountedAncestor, instance);
24169 }
24170 }
24171
24172 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
24173 return;
24174 }
24175
24176 case ScopeComponent:
24177 {
24178
24179 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
24180 return;
24181 }
24182
24183 case OffscreenComponent:
24184 {
24185 if ( // TODO: Remove this dead flag
24186 deletedFiber.mode & ConcurrentMode) {
24187 // If this offscreen component is hidden, we already unmounted it. Before
24188 // deleting the children, track that it's already unmounted so that we
24189 // don't attempt to unmount the effects again.
24190 // TODO: If the tree is hidden, in most cases we should be able to skip
24191 // over the nested children entirely. An exception is we haven't yet found
24192 // the topmost host node to delete, which we already track on the stack.
24193 // But the other case is portals, which need to be detached no matter how
24194 // deeply they are nested. We should use a subtree flag to track whether a
24195 // subtree includes a nested portal.
24196 var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden;
24197 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden || deletedFiber.memoizedState !== null;
24198 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
24199 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden;
24200 } else {
24201 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
24202 }
24203
24204 break;
24205 }
24206
24207 default:
24208 {
24209 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
24210 return;
24211 }
24212 }
24213 }
24214
24215 function commitSuspenseCallback(finishedWork) {
24216 // TODO: Move this to passive phase
24217 var newState = finishedWork.memoizedState;
24218 }
24219
24220 function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) {
24221
24222 var newState = finishedWork.memoizedState;
24223
24224 if (newState === null) {
24225 var current = finishedWork.alternate;
24226
24227 if (current !== null) {
24228 var prevState = current.memoizedState;
24229
24230 if (prevState !== null) {
24231 var suspenseInstance = prevState.dehydrated;
24232
24233 if (suspenseInstance !== null) {
24234 commitHydratedSuspenseInstance(suspenseInstance);
24235 }
24236 }
24237 }
24238 }
24239 }
24240
24241 function attachSuspenseRetryListeners(finishedWork) {
24242 // If this boundary just timed out, then it will have a set of wakeables.
24243 // For each wakeable, attach a listener so that when it resolves, React
24244 // attempts to re-render the boundary in the primary (pre-timeout) state.
24245 var wakeables = finishedWork.updateQueue;
24246
24247 if (wakeables !== null) {
24248 finishedWork.updateQueue = null;
24249 var retryCache = finishedWork.stateNode;
24250
24251 if (retryCache === null) {
24252 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
24253 }
24254
24255 wakeables.forEach(function (wakeable) {
24256 // Memoize using the boundary fiber to prevent redundant listeners.
24257 var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable);
24258
24259 if (!retryCache.has(wakeable)) {
24260 retryCache.add(wakeable);
24261
24262 {
24263 if (isDevToolsPresent) {
24264 if (inProgressLanes !== null && inProgressRoot !== null) {
24265 // If we have pending work still, associate the original updaters with it.
24266 restorePendingUpdaters(inProgressRoot, inProgressLanes);
24267 } else {
24268 throw Error('Expected finished root and lanes to be set. This is a bug in React.');
24269 }
24270 }
24271 }
24272
24273 wakeable.then(retry, retry);
24274 }
24275 });
24276 }
24277 } // This function detects when a Suspense boundary goes from visible to hidden.
24278 function commitMutationEffects(root, finishedWork, committedLanes) {
24279 inProgressLanes = committedLanes;
24280 inProgressRoot = root;
24281 setCurrentFiber(finishedWork);
24282 commitMutationEffectsOnFiber(finishedWork, root);
24283 setCurrentFiber(finishedWork);
24284 inProgressLanes = null;
24285 inProgressRoot = null;
24286 }
24287
24288 function recursivelyTraverseMutationEffects(root, parentFiber, lanes) {
24289 // Deletions effects can be scheduled on any fiber type. They need to happen
24290 // before the children effects hae fired.
24291 var deletions = parentFiber.deletions;
24292
24293 if (deletions !== null) {
24294 for (var i = 0; i < deletions.length; i++) {
24295 var childToDelete = deletions[i];
24296
24297 try {
24298 commitDeletionEffects(root, parentFiber, childToDelete);
24299 } catch (error) {
24300 captureCommitPhaseError(childToDelete, parentFiber, error);
24301 }
24302 }
24303 }
24304
24305 var prevDebugFiber = getCurrentFiber();
24306
24307 if (parentFiber.subtreeFlags & MutationMask) {
24308 var child = parentFiber.child;
24309
24310 while (child !== null) {
24311 setCurrentFiber(child);
24312 commitMutationEffectsOnFiber(child, root);
24313 child = child.sibling;
24314 }
24315 }
24316
24317 setCurrentFiber(prevDebugFiber);
24318 }
24319
24320 function commitMutationEffectsOnFiber(finishedWork, root, lanes) {
24321 var current = finishedWork.alternate;
24322 var flags = finishedWork.flags; // The effect flag should be checked *after* we refine the type of fiber,
24323 // because the fiber tag is more specific. An exception is any flag related
24324 // to reconcilation, because those can be set on all fiber types.
24325
24326 switch (finishedWork.tag) {
24327 case FunctionComponent:
24328 case ForwardRef:
24329 case MemoComponent:
24330 case SimpleMemoComponent:
24331 {
24332 recursivelyTraverseMutationEffects(root, finishedWork);
24333 commitReconciliationEffects(finishedWork);
24334
24335 if (flags & Update) {
24336 try {
24337 commitHookEffectListUnmount(Insertion | HasEffect, finishedWork, finishedWork.return);
24338 commitHookEffectListMount(Insertion | HasEffect, finishedWork);
24339 } catch (error) {
24340 captureCommitPhaseError(finishedWork, finishedWork.return, error);
24341 } // Layout effects are destroyed during the mutation phase so that all
24342 // destroy functions for all fibers are called before any create functions.
24343 // This prevents sibling component effects from interfering with each other,
24344 // e.g. a destroy function in one component should never override a ref set
24345 // by a create function in another component during the same commit.
24346
24347
24348 if ( finishedWork.mode & ProfileMode) {
24349 try {
24350 startLayoutEffectTimer();
24351 commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return);
24352 } catch (error) {
24353 captureCommitPhaseError(finishedWork, finishedWork.return, error);
24354 }
24355
24356 recordLayoutEffectDuration(finishedWork);
24357 } else {
24358 try {
24359 commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return);
24360 } catch (error) {
24361 captureCommitPhaseError(finishedWork, finishedWork.return, error);
24362 }
24363 }
24364 }
24365
24366 return;
24367 }
24368
24369 case ClassComponent:
24370 {
24371 recursivelyTraverseMutationEffects(root, finishedWork);
24372 commitReconciliationEffects(finishedWork);
24373
24374 if (flags & Ref) {
24375 if (current !== null) {
24376 safelyDetachRef(current, current.return);
24377 }
24378 }
24379
24380 return;
24381 }
24382
24383 case HostComponent:
24384 {
24385 recursivelyTraverseMutationEffects(root, finishedWork);
24386 commitReconciliationEffects(finishedWork);
24387
24388 if (flags & Ref) {
24389 if (current !== null) {
24390 safelyDetachRef(current, current.return);
24391 }
24392 }
24393
24394 {
24395 // TODO: ContentReset gets cleared by the children during the commit
24396 // phase. This is a refactor hazard because it means we must read
24397 // flags the flags after `commitReconciliationEffects` has already run;
24398 // the order matters. We should refactor so that ContentReset does not
24399 // rely on mutating the flag during commit. Like by setting a flag
24400 // during the render phase instead.
24401 if (finishedWork.flags & ContentReset) {
24402 var instance = finishedWork.stateNode;
24403
24404 try {
24405 resetTextContent(instance);
24406 } catch (error) {
24407 captureCommitPhaseError(finishedWork, finishedWork.return, error);
24408 }
24409 }
24410
24411 if (flags & Update) {
24412 var _instance4 = finishedWork.stateNode;
24413
24414 if (_instance4 != null) {
24415 // Commit the work prepared earlier.
24416 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
24417 // as the newProps. The updatePayload will contain the real change in
24418 // this case.
24419
24420 var oldProps = current !== null ? current.memoizedProps : newProps;
24421 var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components.
24422
24423 var updatePayload = finishedWork.updateQueue;
24424 finishedWork.updateQueue = null;
24425
24426 if (updatePayload !== null) {
24427 try {
24428 commitUpdate(_instance4, updatePayload, type, oldProps, newProps, finishedWork);
24429 } catch (error) {
24430 captureCommitPhaseError(finishedWork, finishedWork.return, error);
24431 }
24432 }
24433 }
24434 }
24435 }
24436
24437 return;
24438 }
24439
24440 case HostText:
24441 {
24442 recursivelyTraverseMutationEffects(root, finishedWork);
24443 commitReconciliationEffects(finishedWork);
24444
24445 if (flags & Update) {
24446 {
24447 if (finishedWork.stateNode === null) {
24448 throw new Error('This should have a text node initialized. This error is likely ' + 'caused by a bug in React. Please file an issue.');
24449 }
24450
24451 var textInstance = finishedWork.stateNode;
24452 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
24453 // as the newProps. The updatePayload will contain the real change in
24454 // this case.
24455
24456 var oldText = current !== null ? current.memoizedProps : newText;
24457
24458 try {
24459 commitTextUpdate(textInstance, oldText, newText);
24460 } catch (error) {
24461 captureCommitPhaseError(finishedWork, finishedWork.return, error);
24462 }
24463 }
24464 }
24465
24466 return;
24467 }
24468
24469 case HostRoot:
24470 {
24471 recursivelyTraverseMutationEffects(root, finishedWork);
24472 commitReconciliationEffects(finishedWork);
24473
24474 if (flags & Update) {
24475 {
24476 if (current !== null) {
24477 var prevRootState = current.memoizedState;
24478
24479 if (prevRootState.isDehydrated) {
24480 try {
24481 commitHydratedContainer(root.containerInfo);
24482 } catch (error) {
24483 captureCommitPhaseError(finishedWork, finishedWork.return, error);
24484 }
24485 }
24486 }
24487 }
24488 }
24489
24490 return;
24491 }
24492
24493 case HostPortal:
24494 {
24495 recursivelyTraverseMutationEffects(root, finishedWork);
24496 commitReconciliationEffects(finishedWork);
24497
24498 return;
24499 }
24500
24501 case SuspenseComponent:
24502 {
24503 recursivelyTraverseMutationEffects(root, finishedWork);
24504 commitReconciliationEffects(finishedWork);
24505 var offscreenFiber = finishedWork.child;
24506
24507 if (offscreenFiber.flags & Visibility) {
24508 var offscreenInstance = offscreenFiber.stateNode;
24509 var newState = offscreenFiber.memoizedState;
24510 var isHidden = newState !== null; // Track the current state on the Offscreen instance so we can
24511 // read it during an event
24512
24513 offscreenInstance.isHidden = isHidden;
24514
24515 if (isHidden) {
24516 var wasHidden = offscreenFiber.alternate !== null && offscreenFiber.alternate.memoizedState !== null;
24517
24518 if (!wasHidden) {
24519 // TODO: Move to passive phase
24520 markCommitTimeOfFallback();
24521 }
24522 }
24523 }
24524
24525 if (flags & Update) {
24526 try {
24527 commitSuspenseCallback(finishedWork);
24528 } catch (error) {
24529 captureCommitPhaseError(finishedWork, finishedWork.return, error);
24530 }
24531
24532 attachSuspenseRetryListeners(finishedWork);
24533 }
24534
24535 return;
24536 }
24537
24538 case OffscreenComponent:
24539 {
24540 var _wasHidden = current !== null && current.memoizedState !== null;
24541
24542 if ( // TODO: Remove this dead flag
24543 finishedWork.mode & ConcurrentMode) {
24544 // Before committing the children, track on the stack whether this
24545 // offscreen subtree was already hidden, so that we don't unmount the
24546 // effects again.
24547 var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden;
24548 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden || _wasHidden;
24549 recursivelyTraverseMutationEffects(root, finishedWork);
24550 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden;
24551 } else {
24552 recursivelyTraverseMutationEffects(root, finishedWork);
24553 }
24554
24555 commitReconciliationEffects(finishedWork);
24556
24557 if (flags & Visibility) {
24558 var _offscreenInstance = finishedWork.stateNode;
24559 var _newState = finishedWork.memoizedState;
24560
24561 var _isHidden = _newState !== null;
24562
24563 var offscreenBoundary = finishedWork; // Track the current state on the Offscreen instance so we can
24564 // read it during an event
24565
24566 _offscreenInstance.isHidden = _isHidden;
24567
24568 {
24569 if (_isHidden) {
24570 if (!_wasHidden) {
24571 if ((offscreenBoundary.mode & ConcurrentMode) !== NoMode) {
24572 nextEffect = offscreenBoundary;
24573 var offscreenChild = offscreenBoundary.child;
24574
24575 while (offscreenChild !== null) {
24576 nextEffect = offscreenChild;
24577 disappearLayoutEffects_begin(offscreenChild);
24578 offscreenChild = offscreenChild.sibling;
24579 }
24580 }
24581 }
24582 }
24583 }
24584
24585 {
24586 // TODO: This needs to run whenever there's an insertion or update
24587 // inside a hidden Offscreen tree.
24588 hideOrUnhideAllChildren(offscreenBoundary, _isHidden);
24589 }
24590 }
24591
24592 return;
24593 }
24594
24595 case SuspenseListComponent:
24596 {
24597 recursivelyTraverseMutationEffects(root, finishedWork);
24598 commitReconciliationEffects(finishedWork);
24599
24600 if (flags & Update) {
24601 attachSuspenseRetryListeners(finishedWork);
24602 }
24603
24604 return;
24605 }
24606
24607 case ScopeComponent:
24608 {
24609
24610 return;
24611 }
24612
24613 default:
24614 {
24615 recursivelyTraverseMutationEffects(root, finishedWork);
24616 commitReconciliationEffects(finishedWork);
24617 return;
24618 }
24619 }
24620 }
24621
24622 function commitReconciliationEffects(finishedWork) {
24623 // Placement effects (insertions, reorders) can be scheduled on any fiber
24624 // type. They needs to happen after the children effects have fired, but
24625 // before the effects on this fiber have fired.
24626 var flags = finishedWork.flags;
24627
24628 if (flags & Placement) {
24629 try {
24630 commitPlacement(finishedWork);
24631 } catch (error) {
24632 captureCommitPhaseError(finishedWork, finishedWork.return, error);
24633 } // Clear the "placement" from effect tag so that we know that this is
24634 // inserted, before any life-cycles like componentDidMount gets called.
24635 // TODO: findDOMNode doesn't rely on this any more but isMounted does
24636 // and isMounted is deprecated anyway so we should be able to kill this.
24637
24638
24639 finishedWork.flags &= ~Placement;
24640 }
24641
24642 if (flags & Hydrating) {
24643 finishedWork.flags &= ~Hydrating;
24644 }
24645 }
24646
24647 function commitLayoutEffects(finishedWork, root, committedLanes) {
24648 inProgressLanes = committedLanes;
24649 inProgressRoot = root;
24650 nextEffect = finishedWork;
24651 commitLayoutEffects_begin(finishedWork, root, committedLanes);
24652 inProgressLanes = null;
24653 inProgressRoot = null;
24654 }
24655
24656 function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) {
24657 // Suspense layout effects semantics don't change for legacy roots.
24658 var isModernRoot = (subtreeRoot.mode & ConcurrentMode) !== NoMode;
24659
24660 while (nextEffect !== null) {
24661 var fiber = nextEffect;
24662 var firstChild = fiber.child;
24663
24664 if ( fiber.tag === OffscreenComponent && isModernRoot) {
24665 // Keep track of the current Offscreen stack's state.
24666 var isHidden = fiber.memoizedState !== null;
24667 var newOffscreenSubtreeIsHidden = isHidden || offscreenSubtreeIsHidden;
24668
24669 if (newOffscreenSubtreeIsHidden) {
24670 // The Offscreen tree is hidden. Skip over its layout effects.
24671 commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes);
24672 continue;
24673 } else {
24674 // TODO (Offscreen) Also check: subtreeFlags & LayoutMask
24675 var current = fiber.alternate;
24676 var wasHidden = current !== null && current.memoizedState !== null;
24677 var newOffscreenSubtreeWasHidden = wasHidden || offscreenSubtreeWasHidden;
24678 var prevOffscreenSubtreeIsHidden = offscreenSubtreeIsHidden;
24679 var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; // Traverse the Offscreen subtree with the current Offscreen as the root.
24680
24681 offscreenSubtreeIsHidden = newOffscreenSubtreeIsHidden;
24682 offscreenSubtreeWasHidden = newOffscreenSubtreeWasHidden;
24683
24684 if (offscreenSubtreeWasHidden && !prevOffscreenSubtreeWasHidden) {
24685 // This is the root of a reappearing boundary. Turn its layout effects
24686 // back on.
24687 nextEffect = fiber;
24688 reappearLayoutEffects_begin(fiber);
24689 }
24690
24691 var child = firstChild;
24692
24693 while (child !== null) {
24694 nextEffect = child;
24695 commitLayoutEffects_begin(child, // New root; bubble back up to here and stop.
24696 root, committedLanes);
24697 child = child.sibling;
24698 } // Restore Offscreen state and resume in our-progress traversal.
24699
24700
24701 nextEffect = fiber;
24702 offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden;
24703 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden;
24704 commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes);
24705 continue;
24706 }
24707 }
24708
24709 if ((fiber.subtreeFlags & LayoutMask) !== NoFlags && firstChild !== null) {
24710 firstChild.return = fiber;
24711 nextEffect = firstChild;
24712 } else {
24713 commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes);
24714 }
24715 }
24716 }
24717
24718 function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) {
24719 while (nextEffect !== null) {
24720 var fiber = nextEffect;
24721
24722 if ((fiber.flags & LayoutMask) !== NoFlags) {
24723 var current = fiber.alternate;
24724 setCurrentFiber(fiber);
24725
24726 try {
24727 commitLayoutEffectOnFiber(root, current, fiber, committedLanes);
24728 } catch (error) {
24729 captureCommitPhaseError(fiber, fiber.return, error);
24730 }
24731
24732 resetCurrentFiber();
24733 }
24734
24735 if (fiber === subtreeRoot) {
24736 nextEffect = null;
24737 return;
24738 }
24739
24740 var sibling = fiber.sibling;
24741
24742 if (sibling !== null) {
24743 sibling.return = fiber.return;
24744 nextEffect = sibling;
24745 return;
24746 }
24747
24748 nextEffect = fiber.return;
24749 }
24750 }
24751
24752 function disappearLayoutEffects_begin(subtreeRoot) {
24753 while (nextEffect !== null) {
24754 var fiber = nextEffect;
24755 var firstChild = fiber.child; // TODO (Offscreen) Check: flags & (RefStatic | LayoutStatic)
24756
24757 switch (fiber.tag) {
24758 case FunctionComponent:
24759 case ForwardRef:
24760 case MemoComponent:
24761 case SimpleMemoComponent:
24762 {
24763 if ( fiber.mode & ProfileMode) {
24764 try {
24765 startLayoutEffectTimer();
24766 commitHookEffectListUnmount(Layout, fiber, fiber.return);
24767 } finally {
24768 recordLayoutEffectDuration(fiber);
24769 }
24770 } else {
24771 commitHookEffectListUnmount(Layout, fiber, fiber.return);
24772 }
24773
24774 break;
24775 }
24776
24777 case ClassComponent:
24778 {
24779 // TODO (Offscreen) Check: flags & RefStatic
24780 safelyDetachRef(fiber, fiber.return);
24781 var instance = fiber.stateNode;
24782
24783 if (typeof instance.componentWillUnmount === 'function') {
24784 safelyCallComponentWillUnmount(fiber, fiber.return, instance);
24785 }
24786
24787 break;
24788 }
24789
24790 case HostComponent:
24791 {
24792 safelyDetachRef(fiber, fiber.return);
24793 break;
24794 }
24795
24796 case OffscreenComponent:
24797 {
24798 // Check if this is a
24799 var isHidden = fiber.memoizedState !== null;
24800
24801 if (isHidden) {
24802 // Nested Offscreen tree is already hidden. Don't disappear
24803 // its effects.
24804 disappearLayoutEffects_complete(subtreeRoot);
24805 continue;
24806 }
24807
24808 break;
24809 }
24810 } // TODO (Offscreen) Check: subtreeFlags & LayoutStatic
24811
24812
24813 if (firstChild !== null) {
24814 firstChild.return = fiber;
24815 nextEffect = firstChild;
24816 } else {
24817 disappearLayoutEffects_complete(subtreeRoot);
24818 }
24819 }
24820 }
24821
24822 function disappearLayoutEffects_complete(subtreeRoot) {
24823 while (nextEffect !== null) {
24824 var fiber = nextEffect;
24825
24826 if (fiber === subtreeRoot) {
24827 nextEffect = null;
24828 return;
24829 }
24830
24831 var sibling = fiber.sibling;
24832
24833 if (sibling !== null) {
24834 sibling.return = fiber.return;
24835 nextEffect = sibling;
24836 return;
24837 }
24838
24839 nextEffect = fiber.return;
24840 }
24841 }
24842
24843 function reappearLayoutEffects_begin(subtreeRoot) {
24844 while (nextEffect !== null) {
24845 var fiber = nextEffect;
24846 var firstChild = fiber.child;
24847
24848 if (fiber.tag === OffscreenComponent) {
24849 var isHidden = fiber.memoizedState !== null;
24850
24851 if (isHidden) {
24852 // Nested Offscreen tree is still hidden. Don't re-appear its effects.
24853 reappearLayoutEffects_complete(subtreeRoot);
24854 continue;
24855 }
24856 } // TODO (Offscreen) Check: subtreeFlags & LayoutStatic
24857
24858
24859 if (firstChild !== null) {
24860 // This node may have been reused from a previous render, so we can't
24861 // assume its return pointer is correct.
24862 firstChild.return = fiber;
24863 nextEffect = firstChild;
24864 } else {
24865 reappearLayoutEffects_complete(subtreeRoot);
24866 }
24867 }
24868 }
24869
24870 function reappearLayoutEffects_complete(subtreeRoot) {
24871 while (nextEffect !== null) {
24872 var fiber = nextEffect; // TODO (Offscreen) Check: flags & LayoutStatic
24873
24874 setCurrentFiber(fiber);
24875
24876 try {
24877 reappearLayoutEffectsOnFiber(fiber);
24878 } catch (error) {
24879 captureCommitPhaseError(fiber, fiber.return, error);
24880 }
24881
24882 resetCurrentFiber();
24883
24884 if (fiber === subtreeRoot) {
24885 nextEffect = null;
24886 return;
24887 }
24888
24889 var sibling = fiber.sibling;
24890
24891 if (sibling !== null) {
24892 // This node may have been reused from a previous render, so we can't
24893 // assume its return pointer is correct.
24894 sibling.return = fiber.return;
24895 nextEffect = sibling;
24896 return;
24897 }
24898
24899 nextEffect = fiber.return;
24900 }
24901 }
24902
24903 function commitPassiveMountEffects(root, finishedWork, committedLanes, committedTransitions) {
24904 nextEffect = finishedWork;
24905 commitPassiveMountEffects_begin(finishedWork, root, committedLanes, committedTransitions);
24906 }
24907
24908 function commitPassiveMountEffects_begin(subtreeRoot, root, committedLanes, committedTransitions) {
24909 while (nextEffect !== null) {
24910 var fiber = nextEffect;
24911 var firstChild = fiber.child;
24912
24913 if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) {
24914 firstChild.return = fiber;
24915 nextEffect = firstChild;
24916 } else {
24917 commitPassiveMountEffects_complete(subtreeRoot, root, committedLanes, committedTransitions);
24918 }
24919 }
24920 }
24921
24922 function commitPassiveMountEffects_complete(subtreeRoot, root, committedLanes, committedTransitions) {
24923 while (nextEffect !== null) {
24924 var fiber = nextEffect;
24925
24926 if ((fiber.flags & Passive) !== NoFlags) {
24927 setCurrentFiber(fiber);
24928
24929 try {
24930 commitPassiveMountOnFiber(root, fiber, committedLanes, committedTransitions);
24931 } catch (error) {
24932 captureCommitPhaseError(fiber, fiber.return, error);
24933 }
24934
24935 resetCurrentFiber();
24936 }
24937
24938 if (fiber === subtreeRoot) {
24939 nextEffect = null;
24940 return;
24941 }
24942
24943 var sibling = fiber.sibling;
24944
24945 if (sibling !== null) {
24946 sibling.return = fiber.return;
24947 nextEffect = sibling;
24948 return;
24949 }
24950
24951 nextEffect = fiber.return;
24952 }
24953 }
24954
24955 function commitPassiveMountOnFiber(finishedRoot, finishedWork, committedLanes, committedTransitions) {
24956 switch (finishedWork.tag) {
24957 case FunctionComponent:
24958 case ForwardRef:
24959 case SimpleMemoComponent:
24960 {
24961 if ( finishedWork.mode & ProfileMode) {
24962 startPassiveEffectTimer();
24963
24964 try {
24965 commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
24966 } finally {
24967 recordPassiveEffectDuration(finishedWork);
24968 }
24969 } else {
24970 commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
24971 }
24972
24973 break;
24974 }
24975 }
24976 }
24977
24978 function commitPassiveUnmountEffects(firstChild) {
24979 nextEffect = firstChild;
24980 commitPassiveUnmountEffects_begin();
24981 }
24982
24983 function commitPassiveUnmountEffects_begin() {
24984 while (nextEffect !== null) {
24985 var fiber = nextEffect;
24986 var child = fiber.child;
24987
24988 if ((nextEffect.flags & ChildDeletion) !== NoFlags) {
24989 var deletions = fiber.deletions;
24990
24991 if (deletions !== null) {
24992 for (var i = 0; i < deletions.length; i++) {
24993 var fiberToDelete = deletions[i];
24994 nextEffect = fiberToDelete;
24995 commitPassiveUnmountEffectsInsideOfDeletedTree_begin(fiberToDelete, fiber);
24996 }
24997
24998 {
24999 // A fiber was deleted from this parent fiber, but it's still part of
25000 // the previous (alternate) parent fiber's list of children. Because
25001 // children are a linked list, an earlier sibling that's still alive
25002 // will be connected to the deleted fiber via its `alternate`:
25003 //
25004 // live fiber
25005 // --alternate--> previous live fiber
25006 // --sibling--> deleted fiber
25007 //
25008 // We can't disconnect `alternate` on nodes that haven't been deleted
25009 // yet, but we can disconnect the `sibling` and `child` pointers.
25010 var previousFiber = fiber.alternate;
25011
25012 if (previousFiber !== null) {
25013 var detachedChild = previousFiber.child;
25014
25015 if (detachedChild !== null) {
25016 previousFiber.child = null;
25017
25018 do {
25019 var detachedSibling = detachedChild.sibling;
25020 detachedChild.sibling = null;
25021 detachedChild = detachedSibling;
25022 } while (detachedChild !== null);
25023 }
25024 }
25025 }
25026
25027 nextEffect = fiber;
25028 }
25029 }
25030
25031 if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && child !== null) {
25032 child.return = fiber;
25033 nextEffect = child;
25034 } else {
25035 commitPassiveUnmountEffects_complete();
25036 }
25037 }
25038 }
25039
25040 function commitPassiveUnmountEffects_complete() {
25041 while (nextEffect !== null) {
25042 var fiber = nextEffect;
25043
25044 if ((fiber.flags & Passive) !== NoFlags) {
25045 setCurrentFiber(fiber);
25046 commitPassiveUnmountOnFiber(fiber);
25047 resetCurrentFiber();
25048 }
25049
25050 var sibling = fiber.sibling;
25051
25052 if (sibling !== null) {
25053 sibling.return = fiber.return;
25054 nextEffect = sibling;
25055 return;
25056 }
25057
25058 nextEffect = fiber.return;
25059 }
25060 }
25061
25062 function commitPassiveUnmountOnFiber(finishedWork) {
25063 switch (finishedWork.tag) {
25064 case FunctionComponent:
25065 case ForwardRef:
25066 case SimpleMemoComponent:
25067 {
25068 if ( finishedWork.mode & ProfileMode) {
25069 startPassiveEffectTimer();
25070 commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork, finishedWork.return);
25071 recordPassiveEffectDuration(finishedWork);
25072 } else {
25073 commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork, finishedWork.return);
25074 }
25075
25076 break;
25077 }
25078 }
25079 }
25080
25081 function commitPassiveUnmountEffectsInsideOfDeletedTree_begin(deletedSubtreeRoot, nearestMountedAncestor) {
25082 while (nextEffect !== null) {
25083 var fiber = nextEffect; // Deletion effects fire in parent -> child order
25084 // TODO: Check if fiber has a PassiveStatic flag
25085
25086 setCurrentFiber(fiber);
25087 commitPassiveUnmountInsideDeletedTreeOnFiber(fiber, nearestMountedAncestor);
25088 resetCurrentFiber();
25089 var child = fiber.child; // TODO: Only traverse subtree if it has a PassiveStatic flag. (But, if we
25090 // do this, still need to handle `deletedTreeCleanUpLevel` correctly.)
25091
25092 if (child !== null) {
25093 child.return = fiber;
25094 nextEffect = child;
25095 } else {
25096 commitPassiveUnmountEffectsInsideOfDeletedTree_complete(deletedSubtreeRoot);
25097 }
25098 }
25099 }
25100
25101 function commitPassiveUnmountEffectsInsideOfDeletedTree_complete(deletedSubtreeRoot) {
25102 while (nextEffect !== null) {
25103 var fiber = nextEffect;
25104 var sibling = fiber.sibling;
25105 var returnFiber = fiber.return;
25106
25107 {
25108 // Recursively traverse the entire deleted tree and clean up fiber fields.
25109 // This is more aggressive than ideal, and the long term goal is to only
25110 // have to detach the deleted tree at the root.
25111 detachFiberAfterEffects(fiber);
25112
25113 if (fiber === deletedSubtreeRoot) {
25114 nextEffect = null;
25115 return;
25116 }
25117 }
25118
25119 if (sibling !== null) {
25120 sibling.return = returnFiber;
25121 nextEffect = sibling;
25122 return;
25123 }
25124
25125 nextEffect = returnFiber;
25126 }
25127 }
25128
25129 function commitPassiveUnmountInsideDeletedTreeOnFiber(current, nearestMountedAncestor) {
25130 switch (current.tag) {
25131 case FunctionComponent:
25132 case ForwardRef:
25133 case SimpleMemoComponent:
25134 {
25135 if ( current.mode & ProfileMode) {
25136 startPassiveEffectTimer();
25137 commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor);
25138 recordPassiveEffectDuration(current);
25139 } else {
25140 commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor);
25141 }
25142
25143 break;
25144 }
25145 }
25146 } // TODO: Reuse reappearLayoutEffects traversal here?
25147
25148
25149 function invokeLayoutEffectMountInDEV(fiber) {
25150 {
25151 // We don't need to re-check StrictEffectsMode here.
25152 // This function is only called if that check has already passed.
25153 switch (fiber.tag) {
25154 case FunctionComponent:
25155 case ForwardRef:
25156 case SimpleMemoComponent:
25157 {
25158 try {
25159 commitHookEffectListMount(Layout | HasEffect, fiber);
25160 } catch (error) {
25161 captureCommitPhaseError(fiber, fiber.return, error);
25162 }
25163
25164 break;
25165 }
25166
25167 case ClassComponent:
25168 {
25169 var instance = fiber.stateNode;
25170
25171 try {
25172 instance.componentDidMount();
25173 } catch (error) {
25174 captureCommitPhaseError(fiber, fiber.return, error);
25175 }
25176
25177 break;
25178 }
25179 }
25180 }
25181 }
25182
25183 function invokePassiveEffectMountInDEV(fiber) {
25184 {
25185 // We don't need to re-check StrictEffectsMode here.
25186 // This function is only called if that check has already passed.
25187 switch (fiber.tag) {
25188 case FunctionComponent:
25189 case ForwardRef:
25190 case SimpleMemoComponent:
25191 {
25192 try {
25193 commitHookEffectListMount(Passive$1 | HasEffect, fiber);
25194 } catch (error) {
25195 captureCommitPhaseError(fiber, fiber.return, error);
25196 }
25197
25198 break;
25199 }
25200 }
25201 }
25202 }
25203
25204 function invokeLayoutEffectUnmountInDEV(fiber) {
25205 {
25206 // We don't need to re-check StrictEffectsMode here.
25207 // This function is only called if that check has already passed.
25208 switch (fiber.tag) {
25209 case FunctionComponent:
25210 case ForwardRef:
25211 case SimpleMemoComponent:
25212 {
25213 try {
25214 commitHookEffectListUnmount(Layout | HasEffect, fiber, fiber.return);
25215 } catch (error) {
25216 captureCommitPhaseError(fiber, fiber.return, error);
25217 }
25218
25219 break;
25220 }
25221
25222 case ClassComponent:
25223 {
25224 var instance = fiber.stateNode;
25225
25226 if (typeof instance.componentWillUnmount === 'function') {
25227 safelyCallComponentWillUnmount(fiber, fiber.return, instance);
25228 }
25229
25230 break;
25231 }
25232 }
25233 }
25234 }
25235
25236 function invokePassiveEffectUnmountInDEV(fiber) {
25237 {
25238 // We don't need to re-check StrictEffectsMode here.
25239 // This function is only called if that check has already passed.
25240 switch (fiber.tag) {
25241 case FunctionComponent:
25242 case ForwardRef:
25243 case SimpleMemoComponent:
25244 {
25245 try {
25246 commitHookEffectListUnmount(Passive$1 | HasEffect, fiber, fiber.return);
25247 } catch (error) {
25248 captureCommitPhaseError(fiber, fiber.return, error);
25249 }
25250 }
25251 }
25252 }
25253 }
25254
25255 var COMPONENT_TYPE = 0;
25256 var HAS_PSEUDO_CLASS_TYPE = 1;
25257 var ROLE_TYPE = 2;
25258 var TEST_NAME_TYPE = 3;
25259 var TEXT_TYPE = 4;
25260
25261 if (typeof Symbol === 'function' && Symbol.for) {
25262 var symbolFor = Symbol.for;
25263 COMPONENT_TYPE = symbolFor('selector.component');
25264 HAS_PSEUDO_CLASS_TYPE = symbolFor('selector.has_pseudo_class');
25265 ROLE_TYPE = symbolFor('selector.role');
25266 TEST_NAME_TYPE = symbolFor('selector.test_id');
25267 TEXT_TYPE = symbolFor('selector.text');
25268 }
25269 var commitHooks = [];
25270 function onCommitRoot$1() {
25271 {
25272 commitHooks.forEach(function (commitHook) {
25273 return commitHook();
25274 });
25275 }
25276 }
25277
25278 var ReactCurrentActQueue = ReactSharedInternals.ReactCurrentActQueue;
25279 function isLegacyActEnvironment(fiber) {
25280 {
25281 // Legacy mode. We preserve the behavior of React 17's act. It assumes an
25282 // act environment whenever `jest` is defined, but you can still turn off
25283 // spurious warnings by setting IS_REACT_ACT_ENVIRONMENT explicitly
25284 // to false.
25285 var isReactActEnvironmentGlobal = // $FlowExpectedError – Flow doesn't know about IS_REACT_ACT_ENVIRONMENT global
25286 typeof IS_REACT_ACT_ENVIRONMENT !== 'undefined' ? IS_REACT_ACT_ENVIRONMENT : undefined; // $FlowExpectedError - Flow doesn't know about jest
25287
25288 var jestIsDefined = typeof jest !== 'undefined';
25289 return jestIsDefined && isReactActEnvironmentGlobal !== false;
25290 }
25291 }
25292 function isConcurrentActEnvironment() {
25293 {
25294 var isReactActEnvironmentGlobal = // $FlowExpectedError – Flow doesn't know about IS_REACT_ACT_ENVIRONMENT global
25295 typeof IS_REACT_ACT_ENVIRONMENT !== 'undefined' ? IS_REACT_ACT_ENVIRONMENT : undefined;
25296
25297 if (!isReactActEnvironmentGlobal && ReactCurrentActQueue.current !== null) {
25298 // TODO: Include link to relevant documentation page.
25299 error('The current testing environment is not configured to support ' + 'act(...)');
25300 }
25301
25302 return isReactActEnvironmentGlobal;
25303 }
25304 }
25305
25306 var ceil = Math.ceil;
25307 var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher,
25308 ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner,
25309 ReactCurrentBatchConfig$3 = ReactSharedInternals.ReactCurrentBatchConfig,
25310 ReactCurrentActQueue$1 = ReactSharedInternals.ReactCurrentActQueue;
25311 var NoContext =
25312 /* */
25313 0;
25314 var BatchedContext =
25315 /* */
25316 1;
25317 var RenderContext =
25318 /* */
25319 2;
25320 var CommitContext =
25321 /* */
25322 4;
25323 var RootInProgress = 0;
25324 var RootFatalErrored = 1;
25325 var RootErrored = 2;
25326 var RootSuspended = 3;
25327 var RootSuspendedWithDelay = 4;
25328 var RootCompleted = 5;
25329 var RootDidNotComplete = 6; // Describes where we are in the React execution stack
25330
25331 var executionContext = NoContext; // The root we're working on
25332
25333 var workInProgressRoot = null; // The fiber we're working on
25334
25335 var workInProgress = null; // The lanes we're rendering
25336
25337 var workInProgressRootRenderLanes = NoLanes; // Stack that allows components to change the render lanes for its subtree
25338 // This is a superset of the lanes we started working on at the root. The only
25339 // case where it's different from `workInProgressRootRenderLanes` is when we
25340 // enter a subtree that is hidden and needs to be unhidden: Suspense and
25341 // Offscreen component.
25342 //
25343 // Most things in the work loop should deal with workInProgressRootRenderLanes.
25344 // Most things in begin/complete phases should deal with subtreeRenderLanes.
25345
25346 var subtreeRenderLanes = NoLanes;
25347 var subtreeRenderLanesCursor = createCursor(NoLanes); // Whether to root completed, errored, suspended, etc.
25348
25349 var workInProgressRootExitStatus = RootInProgress; // A fatal error, if one is thrown
25350
25351 var workInProgressRootFatalError = null; // "Included" lanes refer to lanes that were worked on during this render. It's
25352 // slightly different than `renderLanes` because `renderLanes` can change as you
25353 // enter and exit an Offscreen tree. This value is the combination of all render
25354 // lanes for the entire render phase.
25355
25356 var workInProgressRootIncludedLanes = NoLanes; // The work left over by components that were visited during this render. Only
25357 // includes unprocessed updates, not work in bailed out children.
25358
25359 var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an interleaved event) during this render.
25360
25361 var workInProgressRootInterleavedUpdatedLanes = NoLanes; // Lanes that were updated during the render phase (*not* an interleaved event).
25362
25363 var workInProgressRootPingedLanes = NoLanes; // Errors that are thrown during the render phase.
25364
25365 var workInProgressRootConcurrentErrors = null; // These are errors that we recovered from without surfacing them to the UI.
25366 // We will log them once the tree commits.
25367
25368 var workInProgressRootRecoverableErrors = null; // The most recent time we committed a fallback. This lets us ensure a train
25369 // model where we don't commit new loading states in too quick succession.
25370
25371 var globalMostRecentFallbackTime = 0;
25372 var FALLBACK_THROTTLE_MS = 500; // The absolute time for when we should start giving up on rendering
25373 // more and prefer CPU suspense heuristics instead.
25374
25375 var workInProgressRootRenderTargetTime = Infinity; // How long a render is supposed to take before we start following CPU
25376 // suspense heuristics and opt out of rendering more content.
25377
25378 var RENDER_TIMEOUT_MS = 500;
25379 var workInProgressTransitions = null;
25380
25381 function resetRenderTimer() {
25382 workInProgressRootRenderTargetTime = now() + RENDER_TIMEOUT_MS;
25383 }
25384
25385 function getRenderTargetTime() {
25386 return workInProgressRootRenderTargetTime;
25387 }
25388 var hasUncaughtError = false;
25389 var firstUncaughtError = null;
25390 var legacyErrorBoundariesThatAlreadyFailed = null; // Only used when enableProfilerNestedUpdateScheduledHook is true;
25391 var rootDoesHavePassiveEffects = false;
25392 var rootWithPendingPassiveEffects = null;
25393 var pendingPassiveEffectsLanes = NoLanes;
25394 var pendingPassiveProfilerEffects = [];
25395 var pendingPassiveTransitions = null; // Use these to prevent an infinite loop of nested updates
25396
25397 var NESTED_UPDATE_LIMIT = 50;
25398 var nestedUpdateCount = 0;
25399 var rootWithNestedUpdates = null;
25400 var isFlushingPassiveEffects = false;
25401 var didScheduleUpdateDuringPassiveEffects = false;
25402 var NESTED_PASSIVE_UPDATE_LIMIT = 50;
25403 var nestedPassiveUpdateCount = 0;
25404 var rootWithPassiveNestedUpdates = null; // If two updates are scheduled within the same event, we should treat their
25405 // event times as simultaneous, even if the actual clock time has advanced
25406 // between the first and second call.
25407
25408 var currentEventTime = NoTimestamp;
25409 var currentEventTransitionLane = NoLanes;
25410 var isRunningInsertionEffect = false;
25411 function getWorkInProgressRoot() {
25412 return workInProgressRoot;
25413 }
25414 function requestEventTime() {
25415 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
25416 // We're inside React, so it's fine to read the actual time.
25417 return now();
25418 } // We're not inside React, so we may be in the middle of a browser event.
25419
25420
25421 if (currentEventTime !== NoTimestamp) {
25422 // Use the same start time for all updates until we enter React again.
25423 return currentEventTime;
25424 } // This is the first update since React yielded. Compute a new start time.
25425
25426
25427 currentEventTime = now();
25428 return currentEventTime;
25429 }
25430 function requestUpdateLane(fiber) {
25431 // Special cases
25432 var mode = fiber.mode;
25433
25434 if ((mode & ConcurrentMode) === NoMode) {
25435 return SyncLane;
25436 } else if ( (executionContext & RenderContext) !== NoContext && workInProgressRootRenderLanes !== NoLanes) {
25437 // This is a render phase update. These are not officially supported. The
25438 // old behavior is to give this the same "thread" (lanes) as
25439 // whatever is currently rendering. So if you call `setState` on a component
25440 // that happens later in the same render, it will flush. Ideally, we want to
25441 // remove the special case and treat them as if they came from an
25442 // interleaved event. Regardless, this pattern is not officially supported.
25443 // This behavior is only a fallback. The flag only exists until we can roll
25444 // out the setState warning, since existing code might accidentally rely on
25445 // the current behavior.
25446 return pickArbitraryLane(workInProgressRootRenderLanes);
25447 }
25448
25449 var isTransition = requestCurrentTransition() !== NoTransition;
25450
25451 if (isTransition) {
25452 if ( ReactCurrentBatchConfig$3.transition !== null) {
25453 var transition = ReactCurrentBatchConfig$3.transition;
25454
25455 if (!transition._updatedFibers) {
25456 transition._updatedFibers = new Set();
25457 }
25458
25459 transition._updatedFibers.add(fiber);
25460 } // The algorithm for assigning an update to a lane should be stable for all
25461 // updates at the same priority within the same event. To do this, the
25462 // inputs to the algorithm must be the same.
25463 //
25464 // The trick we use is to cache the first of each of these inputs within an
25465 // event. Then reset the cached values once we can be sure the event is
25466 // over. Our heuristic for that is whenever we enter a concurrent work loop.
25467
25468
25469 if (currentEventTransitionLane === NoLane) {
25470 // All transitions within the same event are assigned the same lane.
25471 currentEventTransitionLane = claimNextTransitionLane();
25472 }
25473
25474 return currentEventTransitionLane;
25475 } // Updates originating inside certain React methods, like flushSync, have
25476 // their priority set by tracking it with a context variable.
25477 //
25478 // The opaque type returned by the host config is internally a lane, so we can
25479 // use that directly.
25480 // TODO: Move this type conversion to the event priority module.
25481
25482
25483 var updateLane = getCurrentUpdatePriority();
25484
25485 if (updateLane !== NoLane) {
25486 return updateLane;
25487 } // This update originated outside React. Ask the host environment for an
25488 // appropriate priority, based on the type of event.
25489 //
25490 // The opaque type returned by the host config is internally a lane, so we can
25491 // use that directly.
25492 // TODO: Move this type conversion to the event priority module.
25493
25494
25495 var eventLane = getCurrentEventPriority();
25496 return eventLane;
25497 }
25498
25499 function requestRetryLane(fiber) {
25500 // This is a fork of `requestUpdateLane` designed specifically for Suspense
25501 // "retries" — a special update that attempts to flip a Suspense boundary
25502 // from its placeholder state to its primary/resolved state.
25503 // Special cases
25504 var mode = fiber.mode;
25505
25506 if ((mode & ConcurrentMode) === NoMode) {
25507 return SyncLane;
25508 }
25509
25510 return claimNextRetryLane();
25511 }
25512
25513 function scheduleUpdateOnFiber(root, fiber, lane, eventTime) {
25514 checkForNestedUpdates();
25515
25516 {
25517 if (isRunningInsertionEffect) {
25518 error('useInsertionEffect must not schedule updates.');
25519 }
25520 }
25521
25522 {
25523 if (isFlushingPassiveEffects) {
25524 didScheduleUpdateDuringPassiveEffects = true;
25525 }
25526 } // Mark that the root has a pending update.
25527
25528
25529 markRootUpdated(root, lane, eventTime);
25530
25531 if ((executionContext & RenderContext) !== NoLanes && root === workInProgressRoot) {
25532 // This update was dispatched during the render phase. This is a mistake
25533 // if the update originates from user space (with the exception of local
25534 // hook updates, which are handled differently and don't reach this
25535 // function), but there are some internal React features that use this as
25536 // an implementation detail, like selective hydration.
25537 warnAboutRenderPhaseUpdatesInDEV(fiber); // Track lanes that were updated during the render phase
25538 } else {
25539 // This is a normal update, scheduled from outside the render phase. For
25540 // example, during an input event.
25541 {
25542 if (isDevToolsPresent) {
25543 addFiberToLanesMap(root, fiber, lane);
25544 }
25545 }
25546
25547 warnIfUpdatesNotWrappedWithActDEV(fiber);
25548
25549 if (root === workInProgressRoot) {
25550 // Received an update to a tree that's in the middle of rendering. Mark
25551 // that there was an interleaved update work on this root. Unless the
25552 // `deferRenderPhaseUpdateToNextBatch` flag is off and this is a render
25553 // phase update. In that case, we don't treat render phase updates as if
25554 // they were interleaved, for backwards compat reasons.
25555 if ( (executionContext & RenderContext) === NoContext) {
25556 workInProgressRootInterleavedUpdatedLanes = mergeLanes(workInProgressRootInterleavedUpdatedLanes, lane);
25557 }
25558
25559 if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
25560 // The root already suspended with a delay, which means this render
25561 // definitely won't finish. Since we have a new update, let's mark it as
25562 // suspended now, right before marking the incoming update. This has the
25563 // effect of interrupting the current render and switching to the update.
25564 // TODO: Make sure this doesn't override pings that happen while we've
25565 // already started rendering.
25566 markRootSuspended$1(root, workInProgressRootRenderLanes);
25567 }
25568 }
25569
25570 ensureRootIsScheduled(root, eventTime);
25571
25572 if (lane === SyncLane && executionContext === NoContext && (fiber.mode & ConcurrentMode) === NoMode && // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode.
25573 !( ReactCurrentActQueue$1.isBatchingLegacy)) {
25574 // Flush the synchronous work now, unless we're already working or inside
25575 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
25576 // scheduleCallbackForFiber to preserve the ability to schedule a callback
25577 // without immediately flushing it. We only do this for user-initiated
25578 // updates, to preserve historical behavior of legacy mode.
25579 resetRenderTimer();
25580 flushSyncCallbacksOnlyInLegacyMode();
25581 }
25582 }
25583 }
25584 function scheduleInitialHydrationOnRoot(root, lane, eventTime) {
25585 // This is a special fork of scheduleUpdateOnFiber that is only used to
25586 // schedule the initial hydration of a root that has just been created. Most
25587 // of the stuff in scheduleUpdateOnFiber can be skipped.
25588 //
25589 // The main reason for this separate path, though, is to distinguish the
25590 // initial children from subsequent updates. In fully client-rendered roots
25591 // (createRoot instead of hydrateRoot), all top-level renders are modeled as
25592 // updates, but hydration roots are special because the initial render must
25593 // match what was rendered on the server.
25594 var current = root.current;
25595 current.lanes = lane;
25596 markRootUpdated(root, lane, eventTime);
25597 ensureRootIsScheduled(root, eventTime);
25598 }
25599 function isUnsafeClassRenderPhaseUpdate(fiber) {
25600 // Check if this is a render phase update. Only called by class components,
25601 // which special (deprecated) behavior for UNSAFE_componentWillReceive props.
25602 return (// TODO: Remove outdated deferRenderPhaseUpdateToNextBatch experiment. We
25603 // decided not to enable it.
25604 (executionContext & RenderContext) !== NoContext
25605 );
25606 } // Use this function to schedule a task for a root. There's only one task per
25607 // root; if a task was already scheduled, we'll check to make sure the priority
25608 // of the existing task is the same as the priority of the next level that the
25609 // root has work on. This function is called on every update, and right before
25610 // exiting a task.
25611
25612 function ensureRootIsScheduled(root, currentTime) {
25613 var existingCallbackNode = root.callbackNode; // Check if any lanes are being starved by other work. If so, mark them as
25614 // expired so we know to work on those next.
25615
25616 markStarvedLanesAsExpired(root, currentTime); // Determine the next lanes to work on, and their priority.
25617
25618 var nextLanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);
25619
25620 if (nextLanes === NoLanes) {
25621 // Special case: There's nothing to work on.
25622 if (existingCallbackNode !== null) {
25623 cancelCallback$1(existingCallbackNode);
25624 }
25625
25626 root.callbackNode = null;
25627 root.callbackPriority = NoLane;
25628 return;
25629 } // We use the highest priority lane to represent the priority of the callback.
25630
25631
25632 var newCallbackPriority = getHighestPriorityLane(nextLanes); // Check if there's an existing task. We may be able to reuse it.
25633
25634 var existingCallbackPriority = root.callbackPriority;
25635
25636 if (existingCallbackPriority === newCallbackPriority && // Special case related to `act`. If the currently scheduled task is a
25637 // Scheduler task, rather than an `act` task, cancel it and re-scheduled
25638 // on the `act` queue.
25639 !( ReactCurrentActQueue$1.current !== null && existingCallbackNode !== fakeActCallbackNode)) {
25640 {
25641 // If we're going to re-use an existing task, it needs to exist.
25642 // Assume that discrete update microtasks are non-cancellable and null.
25643 // TODO: Temporary until we confirm this warning is not fired.
25644 if (existingCallbackNode == null && existingCallbackPriority !== SyncLane) {
25645 error('Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue.');
25646 }
25647 } // The priority hasn't changed. We can reuse the existing task. Exit.
25648
25649
25650 return;
25651 }
25652
25653 if (existingCallbackNode != null) {
25654 // Cancel the existing callback. We'll schedule a new one below.
25655 cancelCallback$1(existingCallbackNode);
25656 } // Schedule a new callback.
25657
25658
25659 var newCallbackNode;
25660
25661 if (newCallbackPriority === SyncLane) {
25662 // Special case: Sync React callbacks are scheduled on a special
25663 // internal queue
25664 if (root.tag === LegacyRoot) {
25665 if ( ReactCurrentActQueue$1.isBatchingLegacy !== null) {
25666 ReactCurrentActQueue$1.didScheduleLegacyUpdate = true;
25667 }
25668
25669 scheduleLegacySyncCallback(performSyncWorkOnRoot.bind(null, root));
25670 } else {
25671 scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
25672 }
25673
25674 {
25675 // Flush the queue in a microtask.
25676 if ( ReactCurrentActQueue$1.current !== null) {
25677 // Inside `act`, use our internal `act` queue so that these get flushed
25678 // at the end of the current scope even when using the sync version
25679 // of `act`.
25680 ReactCurrentActQueue$1.current.push(flushSyncCallbacks);
25681 } else {
25682 scheduleMicrotask(function () {
25683 // In Safari, appending an iframe forces microtasks to run.
25684 // https://github.com/facebook/react/issues/22459
25685 // We don't support running callbacks in the middle of render
25686 // or commit so we need to check against that.
25687 if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
25688 // Note that this would still prematurely flush the callbacks
25689 // if this happens outside render or commit phase (e.g. in an event).
25690 flushSyncCallbacks();
25691 }
25692 });
25693 }
25694 }
25695
25696 newCallbackNode = null;
25697 } else {
25698 var schedulerPriorityLevel;
25699
25700 switch (lanesToEventPriority(nextLanes)) {
25701 case DiscreteEventPriority:
25702 schedulerPriorityLevel = ImmediatePriority;
25703 break;
25704
25705 case ContinuousEventPriority:
25706 schedulerPriorityLevel = UserBlockingPriority;
25707 break;
25708
25709 case DefaultEventPriority:
25710 schedulerPriorityLevel = NormalPriority;
25711 break;
25712
25713 case IdleEventPriority:
25714 schedulerPriorityLevel = IdlePriority;
25715 break;
25716
25717 default:
25718 schedulerPriorityLevel = NormalPriority;
25719 break;
25720 }
25721
25722 newCallbackNode = scheduleCallback$1(schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root));
25723 }
25724
25725 root.callbackPriority = newCallbackPriority;
25726 root.callbackNode = newCallbackNode;
25727 } // This is the entry point for every concurrent task, i.e. anything that
25728 // goes through Scheduler.
25729
25730
25731 function performConcurrentWorkOnRoot(root, didTimeout) {
25732 {
25733 resetNestedUpdateFlag();
25734 } // Since we know we're in a React event, we can clear the current
25735 // event time. The next update will compute a new event time.
25736
25737
25738 currentEventTime = NoTimestamp;
25739 currentEventTransitionLane = NoLanes;
25740
25741 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
25742 throw new Error('Should not already be working.');
25743 } // Flush any pending passive effects before deciding which lanes to work on,
25744 // in case they schedule additional work.
25745
25746
25747 var originalCallbackNode = root.callbackNode;
25748 var didFlushPassiveEffects = flushPassiveEffects();
25749
25750 if (didFlushPassiveEffects) {
25751 // Something in the passive effect phase may have canceled the current task.
25752 // Check if the task node for this root was changed.
25753 if (root.callbackNode !== originalCallbackNode) {
25754 // The current task was canceled. Exit. We don't need to call
25755 // `ensureRootIsScheduled` because the check above implies either that
25756 // there's a new task, or that there's no remaining work on this root.
25757 return null;
25758 }
25759 } // Determine the next lanes to work on, using the fields stored
25760 // on the root.
25761
25762
25763 var lanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);
25764
25765 if (lanes === NoLanes) {
25766 // Defensive coding. This is never expected to happen.
25767 return null;
25768 } // We disable time-slicing in some cases: if the work has been CPU-bound
25769 // for too long ("expired" work, to prevent starvation), or we're in
25770 // sync-updates-by-default mode.
25771 // TODO: We only check `didTimeout` defensively, to account for a Scheduler
25772 // bug we're still investigating. Once the bug in Scheduler is fixed,
25773 // we can remove this, since we track expiration ourselves.
25774
25775
25776 var shouldTimeSlice = !includesBlockingLane(root, lanes) && !includesExpiredLane(root, lanes) && ( !didTimeout);
25777 var exitStatus = shouldTimeSlice ? renderRootConcurrent(root, lanes) : renderRootSync(root, lanes);
25778
25779 if (exitStatus !== RootInProgress) {
25780 if (exitStatus === RootErrored) {
25781 // If something threw an error, try rendering one more time. We'll
25782 // render synchronously to block concurrent data mutations, and we'll
25783 // includes all pending updates are included. If it still fails after
25784 // the second attempt, we'll give up and commit the resulting tree.
25785 var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
25786
25787 if (errorRetryLanes !== NoLanes) {
25788 lanes = errorRetryLanes;
25789 exitStatus = recoverFromConcurrentError(root, errorRetryLanes);
25790 }
25791 }
25792
25793 if (exitStatus === RootFatalErrored) {
25794 var fatalError = workInProgressRootFatalError;
25795 prepareFreshStack(root, NoLanes);
25796 markRootSuspended$1(root, lanes);
25797 ensureRootIsScheduled(root, now());
25798 throw fatalError;
25799 }
25800
25801 if (exitStatus === RootDidNotComplete) {
25802 // The render unwound without completing the tree. This happens in special
25803 // cases where need to exit the current render without producing a
25804 // consistent tree or committing.
25805 //
25806 // This should only happen during a concurrent render, not a discrete or
25807 // synchronous update. We should have already checked for this when we
25808 // unwound the stack.
25809 markRootSuspended$1(root, lanes);
25810 } else {
25811 // The render completed.
25812 // Check if this render may have yielded to a concurrent event, and if so,
25813 // confirm that any newly rendered stores are consistent.
25814 // TODO: It's possible that even a concurrent render may never have yielded
25815 // to the main thread, if it was fast enough, or if it expired. We could
25816 // skip the consistency check in that case, too.
25817 var renderWasConcurrent = !includesBlockingLane(root, lanes);
25818 var finishedWork = root.current.alternate;
25819
25820 if (renderWasConcurrent && !isRenderConsistentWithExternalStores(finishedWork)) {
25821 // A store was mutated in an interleaved event. Render again,
25822 // synchronously, to block further mutations.
25823 exitStatus = renderRootSync(root, lanes); // We need to check again if something threw
25824
25825 if (exitStatus === RootErrored) {
25826 var _errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
25827
25828 if (_errorRetryLanes !== NoLanes) {
25829 lanes = _errorRetryLanes;
25830 exitStatus = recoverFromConcurrentError(root, _errorRetryLanes); // We assume the tree is now consistent because we didn't yield to any
25831 // concurrent events.
25832 }
25833 }
25834
25835 if (exitStatus === RootFatalErrored) {
25836 var _fatalError = workInProgressRootFatalError;
25837 prepareFreshStack(root, NoLanes);
25838 markRootSuspended$1(root, lanes);
25839 ensureRootIsScheduled(root, now());
25840 throw _fatalError;
25841 }
25842 } // We now have a consistent tree. The next step is either to commit it,
25843 // or, if something suspended, wait to commit it after a timeout.
25844
25845
25846 root.finishedWork = finishedWork;
25847 root.finishedLanes = lanes;
25848 finishConcurrentRender(root, exitStatus, lanes);
25849 }
25850 }
25851
25852 ensureRootIsScheduled(root, now());
25853
25854 if (root.callbackNode === originalCallbackNode) {
25855 // The task node scheduled for this root is the same one that's
25856 // currently executed. Need to return a continuation.
25857 return performConcurrentWorkOnRoot.bind(null, root);
25858 }
25859
25860 return null;
25861 }
25862
25863 function recoverFromConcurrentError(root, errorRetryLanes) {
25864 // If an error occurred during hydration, discard server response and fall
25865 // back to client side render.
25866 // Before rendering again, save the errors from the previous attempt.
25867 var errorsFromFirstAttempt = workInProgressRootConcurrentErrors;
25868
25869 if (isRootDehydrated(root)) {
25870 // The shell failed to hydrate. Set a flag to force a client rendering
25871 // during the next attempt. To do this, we call prepareFreshStack now
25872 // to create the root work-in-progress fiber. This is a bit weird in terms
25873 // of factoring, because it relies on renderRootSync not calling
25874 // prepareFreshStack again in the call below, which happens because the
25875 // root and lanes haven't changed.
25876 //
25877 // TODO: I think what we should do is set ForceClientRender inside
25878 // throwException, like we do for nested Suspense boundaries. The reason
25879 // it's here instead is so we can switch to the synchronous work loop, too.
25880 // Something to consider for a future refactor.
25881 var rootWorkInProgress = prepareFreshStack(root, errorRetryLanes);
25882 rootWorkInProgress.flags |= ForceClientRender;
25883
25884 {
25885 errorHydratingContainer(root.containerInfo);
25886 }
25887 }
25888
25889 var exitStatus = renderRootSync(root, errorRetryLanes);
25890
25891 if (exitStatus !== RootErrored) {
25892 // Successfully finished rendering on retry
25893 // The errors from the failed first attempt have been recovered. Add
25894 // them to the collection of recoverable errors. We'll log them in the
25895 // commit phase.
25896 var errorsFromSecondAttempt = workInProgressRootRecoverableErrors;
25897 workInProgressRootRecoverableErrors = errorsFromFirstAttempt; // The errors from the second attempt should be queued after the errors
25898 // from the first attempt, to preserve the causal sequence.
25899
25900 if (errorsFromSecondAttempt !== null) {
25901 queueRecoverableErrors(errorsFromSecondAttempt);
25902 }
25903 }
25904
25905 return exitStatus;
25906 }
25907
25908 function queueRecoverableErrors(errors) {
25909 if (workInProgressRootRecoverableErrors === null) {
25910 workInProgressRootRecoverableErrors = errors;
25911 } else {
25912 workInProgressRootRecoverableErrors.push.apply(workInProgressRootRecoverableErrors, errors);
25913 }
25914 }
25915
25916 function finishConcurrentRender(root, exitStatus, lanes) {
25917 switch (exitStatus) {
25918 case RootInProgress:
25919 case RootFatalErrored:
25920 {
25921 throw new Error('Root did not complete. This is a bug in React.');
25922 }
25923 // Flow knows about invariant, so it complains if I add a break
25924 // statement, but eslint doesn't know about invariant, so it complains
25925 // if I do. eslint-disable-next-line no-fallthrough
25926
25927 case RootErrored:
25928 {
25929 // We should have already attempted to retry this tree. If we reached
25930 // this point, it errored again. Commit it.
25931 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions);
25932 break;
25933 }
25934
25935 case RootSuspended:
25936 {
25937 markRootSuspended$1(root, lanes); // We have an acceptable loading state. We need to figure out if we
25938 // should immediately commit it or wait a bit.
25939
25940 if (includesOnlyRetries(lanes) && // do not delay if we're inside an act() scope
25941 !shouldForceFlushFallbacksInDEV()) {
25942 // This render only included retries, no updates. Throttle committing
25943 // retries so that we don't show too many loading states too quickly.
25944 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.
25945
25946 if (msUntilTimeout > 10) {
25947 var nextLanes = getNextLanes(root, NoLanes);
25948
25949 if (nextLanes !== NoLanes) {
25950 // There's additional work on this root.
25951 break;
25952 }
25953
25954 var suspendedLanes = root.suspendedLanes;
25955
25956 if (!isSubsetOfLanes(suspendedLanes, lanes)) {
25957 // We should prefer to render the fallback of at the last
25958 // suspended level. Ping the last suspended level to try
25959 // rendering it again.
25960 // FIXME: What if the suspended lanes are Idle? Should not restart.
25961 var eventTime = requestEventTime();
25962 markRootPinged(root, suspendedLanes);
25963 break;
25964 } // The render is suspended, it hasn't timed out, and there's no
25965 // lower priority work to do. Instead of committing the fallback
25966 // immediately, wait for more data to arrive.
25967
25968
25969 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root, workInProgressRootRecoverableErrors, workInProgressTransitions), msUntilTimeout);
25970 break;
25971 }
25972 } // The work expired. Commit immediately.
25973
25974
25975 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions);
25976 break;
25977 }
25978
25979 case RootSuspendedWithDelay:
25980 {
25981 markRootSuspended$1(root, lanes);
25982
25983 if (includesOnlyTransitions(lanes)) {
25984 // This is a transition, so we should exit without committing a
25985 // placeholder and without scheduling a timeout. Delay indefinitely
25986 // until we receive more data.
25987 break;
25988 }
25989
25990 if (!shouldForceFlushFallbacksInDEV()) {
25991 // This is not a transition, but we did trigger an avoided state.
25992 // Schedule a placeholder to display after a short delay, using the Just
25993 // Noticeable Difference.
25994 // TODO: Is the JND optimization worth the added complexity? If this is
25995 // the only reason we track the event time, then probably not.
25996 // Consider removing.
25997 var mostRecentEventTime = getMostRecentEventTime(root, lanes);
25998 var eventTimeMs = mostRecentEventTime;
25999 var timeElapsedMs = now() - eventTimeMs;
26000
26001 var _msUntilTimeout = jnd(timeElapsedMs) - timeElapsedMs; // Don't bother with a very short suspense time.
26002
26003
26004 if (_msUntilTimeout > 10) {
26005 // Instead of committing the fallback immediately, wait for more data
26006 // to arrive.
26007 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root, workInProgressRootRecoverableErrors, workInProgressTransitions), _msUntilTimeout);
26008 break;
26009 }
26010 } // Commit the placeholder.
26011
26012
26013 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions);
26014 break;
26015 }
26016
26017 case RootCompleted:
26018 {
26019 // The work completed. Ready to commit.
26020 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions);
26021 break;
26022 }
26023
26024 default:
26025 {
26026 throw new Error('Unknown root exit status.');
26027 }
26028 }
26029 }
26030
26031 function isRenderConsistentWithExternalStores(finishedWork) {
26032 // Search the rendered tree for external store reads, and check whether the
26033 // stores were mutated in a concurrent event. Intentionally using an iterative
26034 // loop instead of recursion so we can exit early.
26035 var node = finishedWork;
26036
26037 while (true) {
26038 if (node.flags & StoreConsistency) {
26039 var updateQueue = node.updateQueue;
26040
26041 if (updateQueue !== null) {
26042 var checks = updateQueue.stores;
26043
26044 if (checks !== null) {
26045 for (var i = 0; i < checks.length; i++) {
26046 var check = checks[i];
26047 var getSnapshot = check.getSnapshot;
26048 var renderedValue = check.value;
26049
26050 try {
26051 if (!objectIs(getSnapshot(), renderedValue)) {
26052 // Found an inconsistent store.
26053 return false;
26054 }
26055 } catch (error) {
26056 // If `getSnapshot` throws, return `false`. This will schedule
26057 // a re-render, and the error will be rethrown during render.
26058 return false;
26059 }
26060 }
26061 }
26062 }
26063 }
26064
26065 var child = node.child;
26066
26067 if (node.subtreeFlags & StoreConsistency && child !== null) {
26068 child.return = node;
26069 node = child;
26070 continue;
26071 }
26072
26073 if (node === finishedWork) {
26074 return true;
26075 }
26076
26077 while (node.sibling === null) {
26078 if (node.return === null || node.return === finishedWork) {
26079 return true;
26080 }
26081
26082 node = node.return;
26083 }
26084
26085 node.sibling.return = node.return;
26086 node = node.sibling;
26087 } // Flow doesn't know this is unreachable, but eslint does
26088 // eslint-disable-next-line no-unreachable
26089
26090
26091 return true;
26092 }
26093
26094 function markRootSuspended$1(root, suspendedLanes) {
26095 // When suspending, we should always exclude lanes that were pinged or (more
26096 // rarely, since we try to avoid it) updated during the render phase.
26097 // TODO: Lol maybe there's a better way to factor this besides this
26098 // obnoxiously named function :)
26099 suspendedLanes = removeLanes(suspendedLanes, workInProgressRootPingedLanes);
26100 suspendedLanes = removeLanes(suspendedLanes, workInProgressRootInterleavedUpdatedLanes);
26101 markRootSuspended(root, suspendedLanes);
26102 } // This is the entry point for synchronous tasks that don't go
26103 // through Scheduler
26104
26105
26106 function performSyncWorkOnRoot(root) {
26107 {
26108 syncNestedUpdateFlag();
26109 }
26110
26111 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
26112 throw new Error('Should not already be working.');
26113 }
26114
26115 flushPassiveEffects();
26116 var lanes = getNextLanes(root, NoLanes);
26117
26118 if (!includesSomeLane(lanes, SyncLane)) {
26119 // There's no remaining sync work left.
26120 ensureRootIsScheduled(root, now());
26121 return null;
26122 }
26123
26124 var exitStatus = renderRootSync(root, lanes);
26125
26126 if (root.tag !== LegacyRoot && exitStatus === RootErrored) {
26127 // If something threw an error, try rendering one more time. We'll render
26128 // synchronously to block concurrent data mutations, and we'll includes
26129 // all pending updates are included. If it still fails after the second
26130 // attempt, we'll give up and commit the resulting tree.
26131 var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
26132
26133 if (errorRetryLanes !== NoLanes) {
26134 lanes = errorRetryLanes;
26135 exitStatus = recoverFromConcurrentError(root, errorRetryLanes);
26136 }
26137 }
26138
26139 if (exitStatus === RootFatalErrored) {
26140 var fatalError = workInProgressRootFatalError;
26141 prepareFreshStack(root, NoLanes);
26142 markRootSuspended$1(root, lanes);
26143 ensureRootIsScheduled(root, now());
26144 throw fatalError;
26145 }
26146
26147 if (exitStatus === RootDidNotComplete) {
26148 throw new Error('Root did not complete. This is a bug in React.');
26149 } // We now have a consistent tree. Because this is a sync render, we
26150 // will commit it even if something suspended.
26151
26152
26153 var finishedWork = root.current.alternate;
26154 root.finishedWork = finishedWork;
26155 root.finishedLanes = lanes;
26156 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions); // Before exiting, make sure there's a callback scheduled for the next
26157 // pending level.
26158
26159 ensureRootIsScheduled(root, now());
26160 return null;
26161 }
26162
26163 function flushRoot(root, lanes) {
26164 if (lanes !== NoLanes) {
26165 markRootEntangled(root, mergeLanes(lanes, SyncLane));
26166 ensureRootIsScheduled(root, now());
26167
26168 if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
26169 resetRenderTimer();
26170 flushSyncCallbacks();
26171 }
26172 }
26173 }
26174 function batchedUpdates$1(fn, a) {
26175 var prevExecutionContext = executionContext;
26176 executionContext |= BatchedContext;
26177
26178 try {
26179 return fn(a);
26180 } finally {
26181 executionContext = prevExecutionContext; // If there were legacy sync updates, flush them at the end of the outer
26182 // most batchedUpdates-like method.
26183
26184 if (executionContext === NoContext && // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode.
26185 !( ReactCurrentActQueue$1.isBatchingLegacy)) {
26186 resetRenderTimer();
26187 flushSyncCallbacksOnlyInLegacyMode();
26188 }
26189 }
26190 }
26191 function discreteUpdates(fn, a, b, c, d) {
26192 var previousPriority = getCurrentUpdatePriority();
26193 var prevTransition = ReactCurrentBatchConfig$3.transition;
26194
26195 try {
26196 ReactCurrentBatchConfig$3.transition = null;
26197 setCurrentUpdatePriority(DiscreteEventPriority);
26198 return fn(a, b, c, d);
26199 } finally {
26200 setCurrentUpdatePriority(previousPriority);
26201 ReactCurrentBatchConfig$3.transition = prevTransition;
26202
26203 if (executionContext === NoContext) {
26204 resetRenderTimer();
26205 }
26206 }
26207 } // Overload the definition to the two valid signatures.
26208 // Warning, this opts-out of checking the function body.
26209
26210 // eslint-disable-next-line no-redeclare
26211 function flushSync(fn) {
26212 // In legacy mode, we flush pending passive effects at the beginning of the
26213 // next event, not at the end of the previous one.
26214 if (rootWithPendingPassiveEffects !== null && rootWithPendingPassiveEffects.tag === LegacyRoot && (executionContext & (RenderContext | CommitContext)) === NoContext) {
26215 flushPassiveEffects();
26216 }
26217
26218 var prevExecutionContext = executionContext;
26219 executionContext |= BatchedContext;
26220 var prevTransition = ReactCurrentBatchConfig$3.transition;
26221 var previousPriority = getCurrentUpdatePriority();
26222
26223 try {
26224 ReactCurrentBatchConfig$3.transition = null;
26225 setCurrentUpdatePriority(DiscreteEventPriority);
26226
26227 if (fn) {
26228 return fn();
26229 } else {
26230 return undefined;
26231 }
26232 } finally {
26233 setCurrentUpdatePriority(previousPriority);
26234 ReactCurrentBatchConfig$3.transition = prevTransition;
26235 executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.
26236 // Note that this will happen even if batchedUpdates is higher up
26237 // the stack.
26238
26239 if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
26240 flushSyncCallbacks();
26241 }
26242 }
26243 }
26244 function isAlreadyRendering() {
26245 // Used by the renderer to print a warning if certain APIs are called from
26246 // the wrong context.
26247 return (executionContext & (RenderContext | CommitContext)) !== NoContext;
26248 }
26249 function pushRenderLanes(fiber, lanes) {
26250 push(subtreeRenderLanesCursor, subtreeRenderLanes, fiber);
26251 subtreeRenderLanes = mergeLanes(subtreeRenderLanes, lanes);
26252 workInProgressRootIncludedLanes = mergeLanes(workInProgressRootIncludedLanes, lanes);
26253 }
26254 function popRenderLanes(fiber) {
26255 subtreeRenderLanes = subtreeRenderLanesCursor.current;
26256 pop(subtreeRenderLanesCursor, fiber);
26257 }
26258
26259 function prepareFreshStack(root, lanes) {
26260 root.finishedWork = null;
26261 root.finishedLanes = NoLanes;
26262 var timeoutHandle = root.timeoutHandle;
26263
26264 if (timeoutHandle !== noTimeout) {
26265 // The root previous suspended and scheduled a timeout to commit a fallback
26266 // state. Now that we have additional work, cancel the timeout.
26267 root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
26268
26269 cancelTimeout(timeoutHandle);
26270 }
26271
26272 if (workInProgress !== null) {
26273 var interruptedWork = workInProgress.return;
26274
26275 while (interruptedWork !== null) {
26276 var current = interruptedWork.alternate;
26277 unwindInterruptedWork(current, interruptedWork);
26278 interruptedWork = interruptedWork.return;
26279 }
26280 }
26281
26282 workInProgressRoot = root;
26283 var rootWorkInProgress = createWorkInProgress(root.current, null);
26284 workInProgress = rootWorkInProgress;
26285 workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes;
26286 workInProgressRootExitStatus = RootInProgress;
26287 workInProgressRootFatalError = null;
26288 workInProgressRootSkippedLanes = NoLanes;
26289 workInProgressRootInterleavedUpdatedLanes = NoLanes;
26290 workInProgressRootPingedLanes = NoLanes;
26291 workInProgressRootConcurrentErrors = null;
26292 workInProgressRootRecoverableErrors = null;
26293 finishQueueingConcurrentUpdates();
26294
26295 {
26296 ReactStrictModeWarnings.discardPendingWarnings();
26297 }
26298
26299 return rootWorkInProgress;
26300 }
26301
26302 function handleError(root, thrownValue) {
26303 do {
26304 var erroredWork = workInProgress;
26305
26306 try {
26307 // Reset module-level state that was set during the render phase.
26308 resetContextDependencies();
26309 resetHooksAfterThrow();
26310 resetCurrentFiber(); // TODO: I found and added this missing line while investigating a
26311 // separate issue. Write a regression test using string refs.
26312
26313 ReactCurrentOwner$2.current = null;
26314
26315 if (erroredWork === null || erroredWork.return === null) {
26316 // Expected to be working on a non-root fiber. This is a fatal error
26317 // because there's no ancestor that can handle it; the root is
26318 // supposed to capture all errors that weren't caught by an error
26319 // boundary.
26320 workInProgressRootExitStatus = RootFatalErrored;
26321 workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next
26322 // sibling, or the parent if there are no siblings. But since the root
26323 // has no siblings nor a parent, we set it to null. Usually this is
26324 // handled by `completeUnitOfWork` or `unwindWork`, but since we're
26325 // intentionally not calling those, we need set it here.
26326 // TODO: Consider calling `unwindWork` to pop the contexts.
26327
26328 workInProgress = null;
26329 return;
26330 }
26331
26332 if (enableProfilerTimer && erroredWork.mode & ProfileMode) {
26333 // Record the time spent rendering before an error was thrown. This
26334 // avoids inaccurate Profiler durations in the case of a
26335 // suspended render.
26336 stopProfilerTimerIfRunningAndRecordDelta(erroredWork, true);
26337 }
26338
26339 if (enableSchedulingProfiler) {
26340 markComponentRenderStopped();
26341
26342 if (thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function') {
26343 var wakeable = thrownValue;
26344 markComponentSuspended(erroredWork, wakeable, workInProgressRootRenderLanes);
26345 } else {
26346 markComponentErrored(erroredWork, thrownValue, workInProgressRootRenderLanes);
26347 }
26348 }
26349
26350 throwException(root, erroredWork.return, erroredWork, thrownValue, workInProgressRootRenderLanes);
26351 completeUnitOfWork(erroredWork);
26352 } catch (yetAnotherThrownValue) {
26353 // Something in the return path also threw.
26354 thrownValue = yetAnotherThrownValue;
26355
26356 if (workInProgress === erroredWork && erroredWork !== null) {
26357 // If this boundary has already errored, then we had trouble processing
26358 // the error. Bubble it to the next boundary.
26359 erroredWork = erroredWork.return;
26360 workInProgress = erroredWork;
26361 } else {
26362 erroredWork = workInProgress;
26363 }
26364
26365 continue;
26366 } // Return to the normal work loop.
26367
26368
26369 return;
26370 } while (true);
26371 }
26372
26373 function pushDispatcher() {
26374 var prevDispatcher = ReactCurrentDispatcher$2.current;
26375 ReactCurrentDispatcher$2.current = ContextOnlyDispatcher;
26376
26377 if (prevDispatcher === null) {
26378 // The React isomorphic package does not include a default dispatcher.
26379 // Instead the first renderer will lazily attach one, in order to give
26380 // nicer error messages.
26381 return ContextOnlyDispatcher;
26382 } else {
26383 return prevDispatcher;
26384 }
26385 }
26386
26387 function popDispatcher(prevDispatcher) {
26388 ReactCurrentDispatcher$2.current = prevDispatcher;
26389 }
26390
26391 function markCommitTimeOfFallback() {
26392 globalMostRecentFallbackTime = now();
26393 }
26394 function markSkippedUpdateLanes(lane) {
26395 workInProgressRootSkippedLanes = mergeLanes(lane, workInProgressRootSkippedLanes);
26396 }
26397 function renderDidSuspend() {
26398 if (workInProgressRootExitStatus === RootInProgress) {
26399 workInProgressRootExitStatus = RootSuspended;
26400 }
26401 }
26402 function renderDidSuspendDelayIfPossible() {
26403 if (workInProgressRootExitStatus === RootInProgress || workInProgressRootExitStatus === RootSuspended || workInProgressRootExitStatus === RootErrored) {
26404 workInProgressRootExitStatus = RootSuspendedWithDelay;
26405 } // Check if there are updates that we skipped tree that might have unblocked
26406 // this render.
26407
26408
26409 if (workInProgressRoot !== null && (includesNonIdleWork(workInProgressRootSkippedLanes) || includesNonIdleWork(workInProgressRootInterleavedUpdatedLanes))) {
26410 // Mark the current render as suspended so that we switch to working on
26411 // the updates that were skipped. Usually we only suspend at the end of
26412 // the render phase.
26413 // TODO: We should probably always mark the root as suspended immediately
26414 // (inside this function), since by suspending at the end of the render
26415 // phase introduces a potential mistake where we suspend lanes that were
26416 // pinged or updated while we were rendering.
26417 markRootSuspended$1(workInProgressRoot, workInProgressRootRenderLanes);
26418 }
26419 }
26420 function renderDidError(error) {
26421 if (workInProgressRootExitStatus !== RootSuspendedWithDelay) {
26422 workInProgressRootExitStatus = RootErrored;
26423 }
26424
26425 if (workInProgressRootConcurrentErrors === null) {
26426 workInProgressRootConcurrentErrors = [error];
26427 } else {
26428 workInProgressRootConcurrentErrors.push(error);
26429 }
26430 } // Called during render to determine if anything has suspended.
26431 // Returns false if we're not sure.
26432
26433 function renderHasNotSuspendedYet() {
26434 // If something errored or completed, we can't really be sure,
26435 // so those are false.
26436 return workInProgressRootExitStatus === RootInProgress;
26437 }
26438
26439 function renderRootSync(root, lanes) {
26440 var prevExecutionContext = executionContext;
26441 executionContext |= RenderContext;
26442 var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack
26443 // and prepare a fresh one. Otherwise we'll continue where we left off.
26444
26445 if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {
26446 {
26447 if (isDevToolsPresent) {
26448 var memoizedUpdaters = root.memoizedUpdaters;
26449
26450 if (memoizedUpdaters.size > 0) {
26451 restorePendingUpdaters(root, workInProgressRootRenderLanes);
26452 memoizedUpdaters.clear();
26453 } // At this point, move Fibers that scheduled the upcoming work from the Map to the Set.
26454 // If we bailout on this work, we'll move them back (like above).
26455 // It's important to move them now in case the work spawns more work at the same priority with different updaters.
26456 // That way we can keep the current update and future updates separate.
26457
26458
26459 movePendingFibersToMemoized(root, lanes);
26460 }
26461 }
26462
26463 workInProgressTransitions = getTransitionsForLanes();
26464 prepareFreshStack(root, lanes);
26465 }
26466
26467 {
26468 markRenderStarted(lanes);
26469 }
26470
26471 do {
26472 try {
26473 workLoopSync();
26474 break;
26475 } catch (thrownValue) {
26476 handleError(root, thrownValue);
26477 }
26478 } while (true);
26479
26480 resetContextDependencies();
26481 executionContext = prevExecutionContext;
26482 popDispatcher(prevDispatcher);
26483
26484 if (workInProgress !== null) {
26485 // This is a sync render, so we should have finished the whole tree.
26486 throw new Error('Cannot commit an incomplete root. This error is likely caused by a ' + 'bug in React. Please file an issue.');
26487 }
26488
26489 {
26490 markRenderStopped();
26491 } // Set this to null to indicate there's no in-progress render.
26492
26493
26494 workInProgressRoot = null;
26495 workInProgressRootRenderLanes = NoLanes;
26496 return workInProgressRootExitStatus;
26497 } // The work loop is an extremely hot path. Tell Closure not to inline it.
26498
26499 /** @noinline */
26500
26501
26502 function workLoopSync() {
26503 // Already timed out, so perform work without checking if we need to yield.
26504 while (workInProgress !== null) {
26505 performUnitOfWork(workInProgress);
26506 }
26507 }
26508
26509 function renderRootConcurrent(root, lanes) {
26510 var prevExecutionContext = executionContext;
26511 executionContext |= RenderContext;
26512 var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack
26513 // and prepare a fresh one. Otherwise we'll continue where we left off.
26514
26515 if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {
26516 {
26517 if (isDevToolsPresent) {
26518 var memoizedUpdaters = root.memoizedUpdaters;
26519
26520 if (memoizedUpdaters.size > 0) {
26521 restorePendingUpdaters(root, workInProgressRootRenderLanes);
26522 memoizedUpdaters.clear();
26523 } // At this point, move Fibers that scheduled the upcoming work from the Map to the Set.
26524 // If we bailout on this work, we'll move them back (like above).
26525 // It's important to move them now in case the work spawns more work at the same priority with different updaters.
26526 // That way we can keep the current update and future updates separate.
26527
26528
26529 movePendingFibersToMemoized(root, lanes);
26530 }
26531 }
26532
26533 workInProgressTransitions = getTransitionsForLanes();
26534 resetRenderTimer();
26535 prepareFreshStack(root, lanes);
26536 }
26537
26538 {
26539 markRenderStarted(lanes);
26540 }
26541
26542 do {
26543 try {
26544 workLoopConcurrent();
26545 break;
26546 } catch (thrownValue) {
26547 handleError(root, thrownValue);
26548 }
26549 } while (true);
26550
26551 resetContextDependencies();
26552 popDispatcher(prevDispatcher);
26553 executionContext = prevExecutionContext;
26554
26555
26556 if (workInProgress !== null) {
26557 // Still work remaining.
26558 {
26559 markRenderYielded();
26560 }
26561
26562 return RootInProgress;
26563 } else {
26564 // Completed the tree.
26565 {
26566 markRenderStopped();
26567 } // Set this to null to indicate there's no in-progress render.
26568
26569
26570 workInProgressRoot = null;
26571 workInProgressRootRenderLanes = NoLanes; // Return the final exit status.
26572
26573 return workInProgressRootExitStatus;
26574 }
26575 }
26576 /** @noinline */
26577
26578
26579 function workLoopConcurrent() {
26580 // Perform work until Scheduler asks us to yield
26581 while (workInProgress !== null && !shouldYield()) {
26582 performUnitOfWork(workInProgress);
26583 }
26584 }
26585
26586 function performUnitOfWork(unitOfWork) {
26587 // The current, flushed, state of this fiber is the alternate. Ideally
26588 // nothing should rely on this, but relying on it here means that we don't
26589 // need an additional field on the work in progress.
26590 var current = unitOfWork.alternate;
26591 setCurrentFiber(unitOfWork);
26592 var next;
26593
26594 if ( (unitOfWork.mode & ProfileMode) !== NoMode) {
26595 startProfilerTimer(unitOfWork);
26596 next = beginWork$1(current, unitOfWork, subtreeRenderLanes);
26597 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
26598 } else {
26599 next = beginWork$1(current, unitOfWork, subtreeRenderLanes);
26600 }
26601
26602 resetCurrentFiber();
26603 unitOfWork.memoizedProps = unitOfWork.pendingProps;
26604
26605 if (next === null) {
26606 // If this doesn't spawn new work, complete the current work.
26607 completeUnitOfWork(unitOfWork);
26608 } else {
26609 workInProgress = next;
26610 }
26611
26612 ReactCurrentOwner$2.current = null;
26613 }
26614
26615 function completeUnitOfWork(unitOfWork) {
26616 // Attempt to complete the current unit of work, then move to the next
26617 // sibling. If there are no more siblings, return to the parent fiber.
26618 var completedWork = unitOfWork;
26619
26620 do {
26621 // The current, flushed, state of this fiber is the alternate. Ideally
26622 // nothing should rely on this, but relying on it here means that we don't
26623 // need an additional field on the work in progress.
26624 var current = completedWork.alternate;
26625 var returnFiber = completedWork.return; // Check if the work completed or if something threw.
26626
26627 if ((completedWork.flags & Incomplete) === NoFlags) {
26628 setCurrentFiber(completedWork);
26629 var next = void 0;
26630
26631 if ( (completedWork.mode & ProfileMode) === NoMode) {
26632 next = completeWork(current, completedWork, subtreeRenderLanes);
26633 } else {
26634 startProfilerTimer(completedWork);
26635 next = completeWork(current, completedWork, subtreeRenderLanes); // Update render duration assuming we didn't error.
26636
26637 stopProfilerTimerIfRunningAndRecordDelta(completedWork, false);
26638 }
26639
26640 resetCurrentFiber();
26641
26642 if (next !== null) {
26643 // Completing this fiber spawned new work. Work on that next.
26644 workInProgress = next;
26645 return;
26646 }
26647 } else {
26648 // This fiber did not complete because something threw. Pop values off
26649 // the stack without entering the complete phase. If this is a boundary,
26650 // capture values if possible.
26651 var _next = unwindWork(current, completedWork); // Because this fiber did not complete, don't reset its lanes.
26652
26653
26654 if (_next !== null) {
26655 // If completing this work spawned new work, do that next. We'll come
26656 // back here again.
26657 // Since we're restarting, remove anything that is not a host effect
26658 // from the effect tag.
26659 _next.flags &= HostEffectMask;
26660 workInProgress = _next;
26661 return;
26662 }
26663
26664 if ( (completedWork.mode & ProfileMode) !== NoMode) {
26665 // Record the render duration for the fiber that errored.
26666 stopProfilerTimerIfRunningAndRecordDelta(completedWork, false); // Include the time spent working on failed children before continuing.
26667
26668 var actualDuration = completedWork.actualDuration;
26669 var child = completedWork.child;
26670
26671 while (child !== null) {
26672 actualDuration += child.actualDuration;
26673 child = child.sibling;
26674 }
26675
26676 completedWork.actualDuration = actualDuration;
26677 }
26678
26679 if (returnFiber !== null) {
26680 // Mark the parent fiber as incomplete and clear its subtree flags.
26681 returnFiber.flags |= Incomplete;
26682 returnFiber.subtreeFlags = NoFlags;
26683 returnFiber.deletions = null;
26684 } else {
26685 // We've unwound all the way to the root.
26686 workInProgressRootExitStatus = RootDidNotComplete;
26687 workInProgress = null;
26688 return;
26689 }
26690 }
26691
26692 var siblingFiber = completedWork.sibling;
26693
26694 if (siblingFiber !== null) {
26695 // If there is more work to do in this returnFiber, do that next.
26696 workInProgress = siblingFiber;
26697 return;
26698 } // Otherwise, return to the parent
26699
26700
26701 completedWork = returnFiber; // Update the next thing we're working on in case something throws.
26702
26703 workInProgress = completedWork;
26704 } while (completedWork !== null); // We've reached the root.
26705
26706
26707 if (workInProgressRootExitStatus === RootInProgress) {
26708 workInProgressRootExitStatus = RootCompleted;
26709 }
26710 }
26711
26712 function commitRoot(root, recoverableErrors, transitions) {
26713 // TODO: This no longer makes any sense. We already wrap the mutation and
26714 // layout phases. Should be able to remove.
26715 var previousUpdateLanePriority = getCurrentUpdatePriority();
26716 var prevTransition = ReactCurrentBatchConfig$3.transition;
26717
26718 try {
26719 ReactCurrentBatchConfig$3.transition = null;
26720 setCurrentUpdatePriority(DiscreteEventPriority);
26721 commitRootImpl(root, recoverableErrors, transitions, previousUpdateLanePriority);
26722 } finally {
26723 ReactCurrentBatchConfig$3.transition = prevTransition;
26724 setCurrentUpdatePriority(previousUpdateLanePriority);
26725 }
26726
26727 return null;
26728 }
26729
26730 function commitRootImpl(root, recoverableErrors, transitions, renderPriorityLevel) {
26731 do {
26732 // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which
26733 // means `flushPassiveEffects` will sometimes result in additional
26734 // passive effects. So we need to keep flushing in a loop until there are
26735 // no more pending effects.
26736 // TODO: Might be better if `flushPassiveEffects` did not automatically
26737 // flush synchronous work at the end, to avoid factoring hazards like this.
26738 flushPassiveEffects();
26739 } while (rootWithPendingPassiveEffects !== null);
26740
26741 flushRenderPhaseStrictModeWarningsInDEV();
26742
26743 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
26744 throw new Error('Should not already be working.');
26745 }
26746
26747 var finishedWork = root.finishedWork;
26748 var lanes = root.finishedLanes;
26749
26750 {
26751 markCommitStarted(lanes);
26752 }
26753
26754 if (finishedWork === null) {
26755
26756 {
26757 markCommitStopped();
26758 }
26759
26760 return null;
26761 } else {
26762 {
26763 if (lanes === NoLanes) {
26764 error('root.finishedLanes should not be empty during a commit. This is a ' + 'bug in React.');
26765 }
26766 }
26767 }
26768
26769 root.finishedWork = null;
26770 root.finishedLanes = NoLanes;
26771
26772 if (finishedWork === root.current) {
26773 throw new Error('Cannot commit the same tree as before. This error is likely caused by ' + 'a bug in React. Please file an issue.');
26774 } // commitRoot never returns a continuation; it always finishes synchronously.
26775 // So we can clear these now to allow a new callback to be scheduled.
26776
26777
26778 root.callbackNode = null;
26779 root.callbackPriority = NoLane; // Update the first and last pending times on this root. The new first
26780 // pending time is whatever is left on the root fiber.
26781
26782 var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes);
26783 markRootFinished(root, remainingLanes);
26784
26785 if (root === workInProgressRoot) {
26786 // We can reset these now that they are finished.
26787 workInProgressRoot = null;
26788 workInProgress = null;
26789 workInProgressRootRenderLanes = NoLanes;
26790 } // If there are pending passive effects, schedule a callback to process them.
26791 // Do this as early as possible, so it is queued before anything else that
26792 // might get scheduled in the commit phase. (See #16714.)
26793 // TODO: Delete all other places that schedule the passive effect callback
26794 // They're redundant.
26795
26796
26797 if ((finishedWork.subtreeFlags & PassiveMask) !== NoFlags || (finishedWork.flags & PassiveMask) !== NoFlags) {
26798 if (!rootDoesHavePassiveEffects) {
26799 rootDoesHavePassiveEffects = true;
26800 // to store it in pendingPassiveTransitions until they get processed
26801 // We need to pass this through as an argument to commitRoot
26802 // because workInProgressTransitions might have changed between
26803 // the previous render and commit if we throttle the commit
26804 // with setTimeout
26805
26806 pendingPassiveTransitions = transitions;
26807 scheduleCallback$1(NormalPriority, function () {
26808 flushPassiveEffects(); // This render triggered passive effects: release the root cache pool
26809 // *after* passive effects fire to avoid freeing a cache pool that may
26810 // be referenced by a node in the tree (HostRoot, Cache boundary etc)
26811
26812 return null;
26813 });
26814 }
26815 } // Check if there are any effects in the whole tree.
26816 // TODO: This is left over from the effect list implementation, where we had
26817 // to check for the existence of `firstEffect` to satisfy Flow. I think the
26818 // only other reason this optimization exists is because it affects profiling.
26819 // Reconsider whether this is necessary.
26820
26821
26822 var subtreeHasEffects = (finishedWork.subtreeFlags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags;
26823 var rootHasEffect = (finishedWork.flags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags;
26824
26825 if (subtreeHasEffects || rootHasEffect) {
26826 var prevTransition = ReactCurrentBatchConfig$3.transition;
26827 ReactCurrentBatchConfig$3.transition = null;
26828 var previousPriority = getCurrentUpdatePriority();
26829 setCurrentUpdatePriority(DiscreteEventPriority);
26830 var prevExecutionContext = executionContext;
26831 executionContext |= CommitContext; // Reset this to null before calling lifecycles
26832
26833 ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass
26834 // of the effect list for each phase: all mutation effects come before all
26835 // layout effects, and so on.
26836 // The first phase a "before mutation" phase. We use this phase to read the
26837 // state of the host tree right before we mutate it. This is where
26838 // getSnapshotBeforeUpdate is called.
26839
26840 var shouldFireAfterActiveInstanceBlur = commitBeforeMutationEffects(root, finishedWork);
26841
26842 {
26843 // Mark the current commit time to be shared by all Profilers in this
26844 // batch. This enables them to be grouped later.
26845 recordCommitTime();
26846 }
26847
26848
26849 commitMutationEffects(root, finishedWork, lanes);
26850
26851 resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after
26852 // the mutation phase, so that the previous tree is still current during
26853 // componentWillUnmount, but before the layout phase, so that the finished
26854 // work is current during componentDidMount/Update.
26855
26856 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
26857
26858 {
26859 markLayoutEffectsStarted(lanes);
26860 }
26861
26862 commitLayoutEffects(finishedWork, root, lanes);
26863
26864 {
26865 markLayoutEffectsStopped();
26866 }
26867 // opportunity to paint.
26868
26869
26870 requestPaint();
26871 executionContext = prevExecutionContext; // Reset the priority to the previous non-sync value.
26872
26873 setCurrentUpdatePriority(previousPriority);
26874 ReactCurrentBatchConfig$3.transition = prevTransition;
26875 } else {
26876 // No effects.
26877 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were
26878 // no effects.
26879 // TODO: Maybe there's a better way to report this.
26880
26881 {
26882 recordCommitTime();
26883 }
26884 }
26885
26886 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
26887
26888 if (rootDoesHavePassiveEffects) {
26889 // This commit has passive effects. Stash a reference to them. But don't
26890 // schedule a callback until after flushing layout work.
26891 rootDoesHavePassiveEffects = false;
26892 rootWithPendingPassiveEffects = root;
26893 pendingPassiveEffectsLanes = lanes;
26894 } else {
26895
26896 {
26897 nestedPassiveUpdateCount = 0;
26898 rootWithPassiveNestedUpdates = null;
26899 }
26900 } // Read this again, since an effect might have updated it
26901
26902
26903 remainingLanes = root.pendingLanes; // Check if there's remaining work on this root
26904 // TODO: This is part of the `componentDidCatch` implementation. Its purpose
26905 // is to detect whether something might have called setState inside
26906 // `componentDidCatch`. The mechanism is known to be flawed because `setState`
26907 // inside `componentDidCatch` is itself flawed — that's why we recommend
26908 // `getDerivedStateFromError` instead. However, it could be improved by
26909 // checking if remainingLanes includes Sync work, instead of whether there's
26910 // any work remaining at all (which would also include stuff like Suspense
26911 // retries or transitions). It's been like this for a while, though, so fixing
26912 // it probably isn't that urgent.
26913
26914 if (remainingLanes === NoLanes) {
26915 // If there's no remaining work, we can clear the set of already failed
26916 // error boundaries.
26917 legacyErrorBoundariesThatAlreadyFailed = null;
26918 }
26919
26920 {
26921 if (!rootDidHavePassiveEffects) {
26922 commitDoubleInvokeEffectsInDEV(root.current, false);
26923 }
26924 }
26925
26926 onCommitRoot(finishedWork.stateNode, renderPriorityLevel);
26927
26928 {
26929 if (isDevToolsPresent) {
26930 root.memoizedUpdaters.clear();
26931 }
26932 }
26933
26934 {
26935 onCommitRoot$1();
26936 } // Always call this before exiting `commitRoot`, to ensure that any
26937 // additional work on this root is scheduled.
26938
26939
26940 ensureRootIsScheduled(root, now());
26941
26942 if (recoverableErrors !== null) {
26943 // There were errors during this render, but recovered from them without
26944 // needing to surface it to the UI. We log them here.
26945 var onRecoverableError = root.onRecoverableError;
26946
26947 for (var i = 0; i < recoverableErrors.length; i++) {
26948 var recoverableError = recoverableErrors[i];
26949 var componentStack = recoverableError.stack;
26950 var digest = recoverableError.digest;
26951 onRecoverableError(recoverableError.value, {
26952 componentStack: componentStack,
26953 digest: digest
26954 });
26955 }
26956 }
26957
26958 if (hasUncaughtError) {
26959 hasUncaughtError = false;
26960 var error$1 = firstUncaughtError;
26961 firstUncaughtError = null;
26962 throw error$1;
26963 } // If the passive effects are the result of a discrete render, flush them
26964 // synchronously at the end of the current task so that the result is
26965 // immediately observable. Otherwise, we assume that they are not
26966 // order-dependent and do not need to be observed by external systems, so we
26967 // can wait until after paint.
26968 // TODO: We can optimize this by not scheduling the callback earlier. Since we
26969 // currently schedule the callback in multiple places, will wait until those
26970 // are consolidated.
26971
26972
26973 if (includesSomeLane(pendingPassiveEffectsLanes, SyncLane) && root.tag !== LegacyRoot) {
26974 flushPassiveEffects();
26975 } // Read this again, since a passive effect might have updated it
26976
26977
26978 remainingLanes = root.pendingLanes;
26979
26980 if (includesSomeLane(remainingLanes, SyncLane)) {
26981 {
26982 markNestedUpdateScheduled();
26983 } // Count the number of times the root synchronously re-renders without
26984 // finishing. If there are too many, it indicates an infinite update loop.
26985
26986
26987 if (root === rootWithNestedUpdates) {
26988 nestedUpdateCount++;
26989 } else {
26990 nestedUpdateCount = 0;
26991 rootWithNestedUpdates = root;
26992 }
26993 } else {
26994 nestedUpdateCount = 0;
26995 } // If layout work was scheduled, flush it now.
26996
26997
26998 flushSyncCallbacks();
26999
27000 {
27001 markCommitStopped();
27002 }
27003
27004 return null;
27005 }
27006
27007 function flushPassiveEffects() {
27008 // Returns whether passive effects were flushed.
27009 // TODO: Combine this check with the one in flushPassiveEFfectsImpl. We should
27010 // probably just combine the two functions. I believe they were only separate
27011 // in the first place because we used to wrap it with
27012 // `Scheduler.runWithPriority`, which accepts a function. But now we track the
27013 // priority within React itself, so we can mutate the variable directly.
27014 if (rootWithPendingPassiveEffects !== null) {
27015 var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes);
27016 var priority = lowerEventPriority(DefaultEventPriority, renderPriority);
27017 var prevTransition = ReactCurrentBatchConfig$3.transition;
27018 var previousPriority = getCurrentUpdatePriority();
27019
27020 try {
27021 ReactCurrentBatchConfig$3.transition = null;
27022 setCurrentUpdatePriority(priority);
27023 return flushPassiveEffectsImpl();
27024 } finally {
27025 setCurrentUpdatePriority(previousPriority);
27026 ReactCurrentBatchConfig$3.transition = prevTransition; // Once passive effects have run for the tree - giving components a
27027 }
27028 }
27029
27030 return false;
27031 }
27032 function enqueuePendingPassiveProfilerEffect(fiber) {
27033 {
27034 pendingPassiveProfilerEffects.push(fiber);
27035
27036 if (!rootDoesHavePassiveEffects) {
27037 rootDoesHavePassiveEffects = true;
27038 scheduleCallback$1(NormalPriority, function () {
27039 flushPassiveEffects();
27040 return null;
27041 });
27042 }
27043 }
27044 }
27045
27046 function flushPassiveEffectsImpl() {
27047 if (rootWithPendingPassiveEffects === null) {
27048 return false;
27049 } // Cache and clear the transitions flag
27050
27051
27052 var transitions = pendingPassiveTransitions;
27053 pendingPassiveTransitions = null;
27054 var root = rootWithPendingPassiveEffects;
27055 var lanes = pendingPassiveEffectsLanes;
27056 rootWithPendingPassiveEffects = null; // TODO: This is sometimes out of sync with rootWithPendingPassiveEffects.
27057 // Figure out why and fix it. It's not causing any known issues (probably
27058 // because it's only used for profiling), but it's a refactor hazard.
27059
27060 pendingPassiveEffectsLanes = NoLanes;
27061
27062 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
27063 throw new Error('Cannot flush passive effects while already rendering.');
27064 }
27065
27066 {
27067 isFlushingPassiveEffects = true;
27068 didScheduleUpdateDuringPassiveEffects = false;
27069 }
27070
27071 {
27072 markPassiveEffectsStarted(lanes);
27073 }
27074
27075 var prevExecutionContext = executionContext;
27076 executionContext |= CommitContext;
27077 commitPassiveUnmountEffects(root.current);
27078 commitPassiveMountEffects(root, root.current, lanes, transitions); // TODO: Move to commitPassiveMountEffects
27079
27080 {
27081 var profilerEffects = pendingPassiveProfilerEffects;
27082 pendingPassiveProfilerEffects = [];
27083
27084 for (var i = 0; i < profilerEffects.length; i++) {
27085 var _fiber = profilerEffects[i];
27086 commitPassiveEffectDurations(root, _fiber);
27087 }
27088 }
27089
27090 {
27091 markPassiveEffectsStopped();
27092 }
27093
27094 {
27095 commitDoubleInvokeEffectsInDEV(root.current, true);
27096 }
27097
27098 executionContext = prevExecutionContext;
27099 flushSyncCallbacks();
27100
27101 {
27102 // If additional passive effects were scheduled, increment a counter. If this
27103 // exceeds the limit, we'll fire a warning.
27104 if (didScheduleUpdateDuringPassiveEffects) {
27105 if (root === rootWithPassiveNestedUpdates) {
27106 nestedPassiveUpdateCount++;
27107 } else {
27108 nestedPassiveUpdateCount = 0;
27109 rootWithPassiveNestedUpdates = root;
27110 }
27111 } else {
27112 nestedPassiveUpdateCount = 0;
27113 }
27114
27115 isFlushingPassiveEffects = false;
27116 didScheduleUpdateDuringPassiveEffects = false;
27117 } // TODO: Move to commitPassiveMountEffects
27118
27119
27120 onPostCommitRoot(root);
27121
27122 {
27123 var stateNode = root.current.stateNode;
27124 stateNode.effectDuration = 0;
27125 stateNode.passiveEffectDuration = 0;
27126 }
27127
27128 return true;
27129 }
27130
27131 function isAlreadyFailedLegacyErrorBoundary(instance) {
27132 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
27133 }
27134 function markLegacyErrorBoundaryAsFailed(instance) {
27135 if (legacyErrorBoundariesThatAlreadyFailed === null) {
27136 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
27137 } else {
27138 legacyErrorBoundariesThatAlreadyFailed.add(instance);
27139 }
27140 }
27141
27142 function prepareToThrowUncaughtError(error) {
27143 if (!hasUncaughtError) {
27144 hasUncaughtError = true;
27145 firstUncaughtError = error;
27146 }
27147 }
27148
27149 var onUncaughtError = prepareToThrowUncaughtError;
27150
27151 function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
27152 var errorInfo = createCapturedValueAtFiber(error, sourceFiber);
27153 var update = createRootErrorUpdate(rootFiber, errorInfo, SyncLane);
27154 var root = enqueueUpdate(rootFiber, update, SyncLane);
27155 var eventTime = requestEventTime();
27156
27157 if (root !== null) {
27158 markRootUpdated(root, SyncLane, eventTime);
27159 ensureRootIsScheduled(root, eventTime);
27160 }
27161 }
27162
27163 function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) {
27164 {
27165 reportUncaughtErrorInDEV(error$1);
27166 setIsRunningInsertionEffect(false);
27167 }
27168
27169 if (sourceFiber.tag === HostRoot) {
27170 // Error was thrown at the root. There is no parent, so the root
27171 // itself should capture it.
27172 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$1);
27173 return;
27174 }
27175
27176 var fiber = null;
27177
27178 {
27179 fiber = nearestMountedAncestor;
27180 }
27181
27182 while (fiber !== null) {
27183 if (fiber.tag === HostRoot) {
27184 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$1);
27185 return;
27186 } else if (fiber.tag === ClassComponent) {
27187 var ctor = fiber.type;
27188 var instance = fiber.stateNode;
27189
27190 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
27191 var errorInfo = createCapturedValueAtFiber(error$1, sourceFiber);
27192 var update = createClassErrorUpdate(fiber, errorInfo, SyncLane);
27193 var root = enqueueUpdate(fiber, update, SyncLane);
27194 var eventTime = requestEventTime();
27195
27196 if (root !== null) {
27197 markRootUpdated(root, SyncLane, eventTime);
27198 ensureRootIsScheduled(root, eventTime);
27199 }
27200
27201 return;
27202 }
27203 }
27204
27205 fiber = fiber.return;
27206 }
27207
27208 {
27209 // TODO: Until we re-land skipUnmountedBoundaries (see #20147), this warning
27210 // will fire for errors that are thrown by destroy functions inside deleted
27211 // trees. What it should instead do is propagate the error to the parent of
27212 // the deleted tree. In the meantime, do not add this warning to the
27213 // allowlist; this is only for our internal use.
27214 error('Internal React error: Attempted to capture a commit phase error ' + 'inside a detached tree. This indicates a bug in React. Likely ' + 'causes include deleting the same fiber more than once, committing an ' + 'already-finished tree, or an inconsistent return pointer.\n\n' + 'Error message:\n\n%s', error$1);
27215 }
27216 }
27217 function pingSuspendedRoot(root, wakeable, pingedLanes) {
27218 var pingCache = root.pingCache;
27219
27220 if (pingCache !== null) {
27221 // The wakeable resolved, so we no longer need to memoize, because it will
27222 // never be thrown again.
27223 pingCache.delete(wakeable);
27224 }
27225
27226 var eventTime = requestEventTime();
27227 markRootPinged(root, pingedLanes);
27228 warnIfSuspenseResolutionNotWrappedWithActDEV(root);
27229
27230 if (workInProgressRoot === root && isSubsetOfLanes(workInProgressRootRenderLanes, pingedLanes)) {
27231 // Received a ping at the same priority level at which we're currently
27232 // rendering. We might want to restart this render. This should mirror
27233 // the logic of whether or not a root suspends once it completes.
27234 // TODO: If we're rendering sync either due to Sync, Batched or expired,
27235 // we should probably never restart.
27236 // If we're suspended with delay, or if it's a retry, we'll always suspend
27237 // so we can always restart.
27238 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && includesOnlyRetries(workInProgressRootRenderLanes) && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
27239 // Restart from the root.
27240 prepareFreshStack(root, NoLanes);
27241 } else {
27242 // Even though we can't restart right now, we might get an
27243 // opportunity later. So we mark this render as having a ping.
27244 workInProgressRootPingedLanes = mergeLanes(workInProgressRootPingedLanes, pingedLanes);
27245 }
27246 }
27247
27248 ensureRootIsScheduled(root, eventTime);
27249 }
27250
27251 function retryTimedOutBoundary(boundaryFiber, retryLane) {
27252 // The boundary fiber (a Suspense component or SuspenseList component)
27253 // previously was rendered in its fallback state. One of the promises that
27254 // suspended it has resolved, which means at least part of the tree was
27255 // likely unblocked. Try rendering again, at a new lanes.
27256 if (retryLane === NoLane) {
27257 // TODO: Assign this to `suspenseState.retryLane`? to avoid
27258 // unnecessary entanglement?
27259 retryLane = requestRetryLane(boundaryFiber);
27260 } // TODO: Special case idle priority?
27261
27262
27263 var eventTime = requestEventTime();
27264 var root = enqueueConcurrentRenderForLane(boundaryFiber, retryLane);
27265
27266 if (root !== null) {
27267 markRootUpdated(root, retryLane, eventTime);
27268 ensureRootIsScheduled(root, eventTime);
27269 }
27270 }
27271
27272 function retryDehydratedSuspenseBoundary(boundaryFiber) {
27273 var suspenseState = boundaryFiber.memoizedState;
27274 var retryLane = NoLane;
27275
27276 if (suspenseState !== null) {
27277 retryLane = suspenseState.retryLane;
27278 }
27279
27280 retryTimedOutBoundary(boundaryFiber, retryLane);
27281 }
27282 function resolveRetryWakeable(boundaryFiber, wakeable) {
27283 var retryLane = NoLane; // Default
27284
27285 var retryCache;
27286
27287 switch (boundaryFiber.tag) {
27288 case SuspenseComponent:
27289 retryCache = boundaryFiber.stateNode;
27290 var suspenseState = boundaryFiber.memoizedState;
27291
27292 if (suspenseState !== null) {
27293 retryLane = suspenseState.retryLane;
27294 }
27295
27296 break;
27297
27298 case SuspenseListComponent:
27299 retryCache = boundaryFiber.stateNode;
27300 break;
27301
27302 default:
27303 throw new Error('Pinged unknown suspense boundary type. ' + 'This is probably a bug in React.');
27304 }
27305
27306 if (retryCache !== null) {
27307 // The wakeable resolved, so we no longer need to memoize, because it will
27308 // never be thrown again.
27309 retryCache.delete(wakeable);
27310 }
27311
27312 retryTimedOutBoundary(boundaryFiber, retryLane);
27313 } // Computes the next Just Noticeable Difference (JND) boundary.
27314 // The theory is that a person can't tell the difference between small differences in time.
27315 // Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
27316 // difference in the experience. However, waiting for longer might mean that we can avoid
27317 // showing an intermediate loading state. The longer we have already waited, the harder it
27318 // is to tell small differences in time. Therefore, the longer we've already waited,
27319 // the longer we can wait additionally. At some point we have to give up though.
27320 // We pick a train model where the next boundary commits at a consistent schedule.
27321 // These particular numbers are vague estimates. We expect to adjust them based on research.
27322
27323 function jnd(timeElapsed) {
27324 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
27325 }
27326
27327 function checkForNestedUpdates() {
27328 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
27329 nestedUpdateCount = 0;
27330 rootWithNestedUpdates = null;
27331 throw new Error('Maximum update depth exceeded. This can happen when a component ' + 'repeatedly calls setState inside componentWillUpdate or ' + 'componentDidUpdate. React limits the number of nested updates to ' + 'prevent infinite loops.');
27332 }
27333
27334 {
27335 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
27336 nestedPassiveUpdateCount = 0;
27337 rootWithPassiveNestedUpdates = null;
27338
27339 error('Maximum update depth exceeded. This can happen when a component ' + "calls setState inside useEffect, but useEffect either doesn't " + 'have a dependency array, or one of the dependencies changes on ' + 'every render.');
27340 }
27341 }
27342 }
27343
27344 function flushRenderPhaseStrictModeWarningsInDEV() {
27345 {
27346 ReactStrictModeWarnings.flushLegacyContextWarning();
27347
27348 {
27349 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
27350 }
27351 }
27352 }
27353
27354 function commitDoubleInvokeEffectsInDEV(fiber, hasPassiveEffects) {
27355 {
27356 // TODO (StrictEffects) Should we set a marker on the root if it contains strict effects
27357 // so we don't traverse unnecessarily? similar to subtreeFlags but just at the root level.
27358 // Maybe not a big deal since this is DEV only behavior.
27359 setCurrentFiber(fiber);
27360 invokeEffectsInDev(fiber, MountLayoutDev, invokeLayoutEffectUnmountInDEV);
27361
27362 if (hasPassiveEffects) {
27363 invokeEffectsInDev(fiber, MountPassiveDev, invokePassiveEffectUnmountInDEV);
27364 }
27365
27366 invokeEffectsInDev(fiber, MountLayoutDev, invokeLayoutEffectMountInDEV);
27367
27368 if (hasPassiveEffects) {
27369 invokeEffectsInDev(fiber, MountPassiveDev, invokePassiveEffectMountInDEV);
27370 }
27371
27372 resetCurrentFiber();
27373 }
27374 }
27375
27376 function invokeEffectsInDev(firstChild, fiberFlags, invokeEffectFn) {
27377 {
27378 // We don't need to re-check StrictEffectsMode here.
27379 // This function is only called if that check has already passed.
27380 var current = firstChild;
27381 var subtreeRoot = null;
27382
27383 while (current !== null) {
27384 var primarySubtreeFlag = current.subtreeFlags & fiberFlags;
27385
27386 if (current !== subtreeRoot && current.child !== null && primarySubtreeFlag !== NoFlags) {
27387 current = current.child;
27388 } else {
27389 if ((current.flags & fiberFlags) !== NoFlags) {
27390 invokeEffectFn(current);
27391 }
27392
27393 if (current.sibling !== null) {
27394 current = current.sibling;
27395 } else {
27396 current = subtreeRoot = current.return;
27397 }
27398 }
27399 }
27400 }
27401 }
27402
27403 var didWarnStateUpdateForNotYetMountedComponent = null;
27404 function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) {
27405 {
27406 if ((executionContext & RenderContext) !== NoContext) {
27407 // We let the other warning about render phase updates deal with this one.
27408 return;
27409 }
27410
27411 if (!(fiber.mode & ConcurrentMode)) {
27412 return;
27413 }
27414
27415 var tag = fiber.tag;
27416
27417 if (tag !== IndeterminateComponent && tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent) {
27418 // Only warn for user-defined components, not internal ones like Suspense.
27419 return;
27420 } // We show the whole stack but dedupe on the top component's name because
27421 // the problematic code almost always lies inside that component.
27422
27423
27424 var componentName = getComponentNameFromFiber(fiber) || 'ReactComponent';
27425
27426 if (didWarnStateUpdateForNotYetMountedComponent !== null) {
27427 if (didWarnStateUpdateForNotYetMountedComponent.has(componentName)) {
27428 return;
27429 }
27430
27431 didWarnStateUpdateForNotYetMountedComponent.add(componentName);
27432 } else {
27433 didWarnStateUpdateForNotYetMountedComponent = new Set([componentName]);
27434 }
27435
27436 var previousFiber = current;
27437
27438 try {
27439 setCurrentFiber(fiber);
27440
27441 error("Can't perform a React state update on a component that hasn't mounted yet. " + 'This indicates that you have a side-effect in your render function that ' + 'asynchronously later calls tries to update the component. Move this work to ' + 'useEffect instead.');
27442 } finally {
27443 if (previousFiber) {
27444 setCurrentFiber(fiber);
27445 } else {
27446 resetCurrentFiber();
27447 }
27448 }
27449 }
27450 }
27451 var beginWork$1;
27452
27453 {
27454 var dummyFiber = null;
27455
27456 beginWork$1 = function (current, unitOfWork, lanes) {
27457 // If a component throws an error, we replay it again in a synchronously
27458 // dispatched event, so that the debugger will treat it as an uncaught
27459 // error See ReactErrorUtils for more information.
27460 // Before entering the begin phase, copy the work-in-progress onto a dummy
27461 // fiber. If beginWork throws, we'll use this to reset the state.
27462 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
27463
27464 try {
27465 return beginWork(current, unitOfWork, lanes);
27466 } catch (originalError) {
27467 if (didSuspendOrErrorWhileHydratingDEV() || originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {
27468 // Don't replay promises.
27469 // Don't replay errors if we are hydrating and have already suspended or handled an error
27470 throw originalError;
27471 } // Keep this code in sync with handleError; any changes here must have
27472 // corresponding changes there.
27473
27474
27475 resetContextDependencies();
27476 resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the
27477 // same fiber again.
27478 // Unwind the failed stack frame
27479
27480 unwindInterruptedWork(current, unitOfWork); // Restore the original properties of the fiber.
27481
27482 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
27483
27484 if ( unitOfWork.mode & ProfileMode) {
27485 // Reset the profiler timer.
27486 startProfilerTimer(unitOfWork);
27487 } // Run beginWork again.
27488
27489
27490 invokeGuardedCallback(null, beginWork, null, current, unitOfWork, lanes);
27491
27492 if (hasCaughtError()) {
27493 var replayError = clearCaughtError();
27494
27495 if (typeof replayError === 'object' && replayError !== null && replayError._suppressLogging && typeof originalError === 'object' && originalError !== null && !originalError._suppressLogging) {
27496 // If suppressed, let the flag carry over to the original error which is the one we'll rethrow.
27497 originalError._suppressLogging = true;
27498 }
27499 } // We always throw the original error in case the second render pass is not idempotent.
27500 // This can happen if a memoized function or CommonJS module doesn't throw after first invocation.
27501
27502
27503 throw originalError;
27504 }
27505 };
27506 }
27507
27508 var didWarnAboutUpdateInRender = false;
27509 var didWarnAboutUpdateInRenderForAnotherComponent;
27510
27511 {
27512 didWarnAboutUpdateInRenderForAnotherComponent = new Set();
27513 }
27514
27515 function warnAboutRenderPhaseUpdatesInDEV(fiber) {
27516 {
27517 if (isRendering && !getIsUpdatingOpaqueValueInRenderPhaseInDEV()) {
27518 switch (fiber.tag) {
27519 case FunctionComponent:
27520 case ForwardRef:
27521 case SimpleMemoComponent:
27522 {
27523 var renderingComponentName = workInProgress && getComponentNameFromFiber(workInProgress) || 'Unknown'; // Dedupe by the rendering component because it's the one that needs to be fixed.
27524
27525 var dedupeKey = renderingComponentName;
27526
27527 if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) {
27528 didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey);
27529 var setStateComponentName = getComponentNameFromFiber(fiber) || 'Unknown';
27530
27531 error('Cannot update a component (`%s`) while rendering a ' + 'different component (`%s`). To locate the bad setState() call inside `%s`, ' + 'follow the stack trace as described in https://reactjs.org/link/setstate-in-render', setStateComponentName, renderingComponentName, renderingComponentName);
27532 }
27533
27534 break;
27535 }
27536
27537 case ClassComponent:
27538 {
27539 if (!didWarnAboutUpdateInRender) {
27540 error('Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure ' + 'function of props and state.');
27541
27542 didWarnAboutUpdateInRender = true;
27543 }
27544
27545 break;
27546 }
27547 }
27548 }
27549 }
27550 }
27551
27552 function restorePendingUpdaters(root, lanes) {
27553 {
27554 if (isDevToolsPresent) {
27555 var memoizedUpdaters = root.memoizedUpdaters;
27556 memoizedUpdaters.forEach(function (schedulingFiber) {
27557 addFiberToLanesMap(root, schedulingFiber, lanes);
27558 }); // This function intentionally does not clear memoized updaters.
27559 // Those may still be relevant to the current commit
27560 // and a future one (e.g. Suspense).
27561 }
27562 }
27563 }
27564 var fakeActCallbackNode = {};
27565
27566 function scheduleCallback$1(priorityLevel, callback) {
27567 {
27568 // If we're currently inside an `act` scope, bypass Scheduler and push to
27569 // the `act` queue instead.
27570 var actQueue = ReactCurrentActQueue$1.current;
27571
27572 if (actQueue !== null) {
27573 actQueue.push(callback);
27574 return fakeActCallbackNode;
27575 } else {
27576 return scheduleCallback(priorityLevel, callback);
27577 }
27578 }
27579 }
27580
27581 function cancelCallback$1(callbackNode) {
27582 if ( callbackNode === fakeActCallbackNode) {
27583 return;
27584 } // In production, always call Scheduler. This function will be stripped out.
27585
27586
27587 return cancelCallback(callbackNode);
27588 }
27589
27590 function shouldForceFlushFallbacksInDEV() {
27591 // Never force flush in production. This function should get stripped out.
27592 return ReactCurrentActQueue$1.current !== null;
27593 }
27594
27595 function warnIfUpdatesNotWrappedWithActDEV(fiber) {
27596 {
27597 if (fiber.mode & ConcurrentMode) {
27598 if (!isConcurrentActEnvironment()) {
27599 // Not in an act environment. No need to warn.
27600 return;
27601 }
27602 } else {
27603 // Legacy mode has additional cases where we suppress a warning.
27604 if (!isLegacyActEnvironment()) {
27605 // Not in an act environment. No need to warn.
27606 return;
27607 }
27608
27609 if (executionContext !== NoContext) {
27610 // Legacy mode doesn't warn if the update is batched, i.e.
27611 // batchedUpdates or flushSync.
27612 return;
27613 }
27614
27615 if (fiber.tag !== FunctionComponent && fiber.tag !== ForwardRef && fiber.tag !== SimpleMemoComponent) {
27616 // For backwards compatibility with pre-hooks code, legacy mode only
27617 // warns for updates that originate from a hook.
27618 return;
27619 }
27620 }
27621
27622 if (ReactCurrentActQueue$1.current === null) {
27623 var previousFiber = current;
27624
27625 try {
27626 setCurrentFiber(fiber);
27627
27628 error('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://reactjs.org/link/wrap-tests-with-act', getComponentNameFromFiber(fiber));
27629 } finally {
27630 if (previousFiber) {
27631 setCurrentFiber(fiber);
27632 } else {
27633 resetCurrentFiber();
27634 }
27635 }
27636 }
27637 }
27638 }
27639
27640 function warnIfSuspenseResolutionNotWrappedWithActDEV(root) {
27641 {
27642 if (root.tag !== LegacyRoot && isConcurrentActEnvironment() && ReactCurrentActQueue$1.current === null) {
27643 error('A suspended resource finished loading inside a test, but the event ' + 'was not wrapped in act(...).\n\n' + 'When testing, code that resolves suspended data should be wrapped ' + 'into act(...):\n\n' + 'act(() => {\n' + ' /* finish loading suspended data */\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://reactjs.org/link/wrap-tests-with-act');
27644 }
27645 }
27646 }
27647
27648 function setIsRunningInsertionEffect(isRunning) {
27649 {
27650 isRunningInsertionEffect = isRunning;
27651 }
27652 }
27653
27654 /* eslint-disable react-internal/prod-error-codes */
27655 var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.
27656
27657 var failedBoundaries = null;
27658 var setRefreshHandler = function (handler) {
27659 {
27660 resolveFamily = handler;
27661 }
27662 };
27663 function resolveFunctionForHotReloading(type) {
27664 {
27665 if (resolveFamily === null) {
27666 // Hot reloading is disabled.
27667 return type;
27668 }
27669
27670 var family = resolveFamily(type);
27671
27672 if (family === undefined) {
27673 return type;
27674 } // Use the latest known implementation.
27675
27676
27677 return family.current;
27678 }
27679 }
27680 function resolveClassForHotReloading(type) {
27681 // No implementation differences.
27682 return resolveFunctionForHotReloading(type);
27683 }
27684 function resolveForwardRefForHotReloading(type) {
27685 {
27686 if (resolveFamily === null) {
27687 // Hot reloading is disabled.
27688 return type;
27689 }
27690
27691 var family = resolveFamily(type);
27692
27693 if (family === undefined) {
27694 // Check if we're dealing with a real forwardRef. Don't want to crash early.
27695 if (type !== null && type !== undefined && typeof type.render === 'function') {
27696 // ForwardRef is special because its resolved .type is an object,
27697 // but it's possible that we only have its inner render function in the map.
27698 // If that inner render function is different, we'll build a new forwardRef type.
27699 var currentRender = resolveFunctionForHotReloading(type.render);
27700
27701 if (type.render !== currentRender) {
27702 var syntheticType = {
27703 $$typeof: REACT_FORWARD_REF_TYPE,
27704 render: currentRender
27705 };
27706
27707 if (type.displayName !== undefined) {
27708 syntheticType.displayName = type.displayName;
27709 }
27710
27711 return syntheticType;
27712 }
27713 }
27714
27715 return type;
27716 } // Use the latest known implementation.
27717
27718
27719 return family.current;
27720 }
27721 }
27722 function isCompatibleFamilyForHotReloading(fiber, element) {
27723 {
27724 if (resolveFamily === null) {
27725 // Hot reloading is disabled.
27726 return false;
27727 }
27728
27729 var prevType = fiber.elementType;
27730 var nextType = element.type; // If we got here, we know types aren't === equal.
27731
27732 var needsCompareFamilies = false;
27733 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
27734
27735 switch (fiber.tag) {
27736 case ClassComponent:
27737 {
27738 if (typeof nextType === 'function') {
27739 needsCompareFamilies = true;
27740 }
27741
27742 break;
27743 }
27744
27745 case FunctionComponent:
27746 {
27747 if (typeof nextType === 'function') {
27748 needsCompareFamilies = true;
27749 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
27750 // We don't know the inner type yet.
27751 // We're going to assume that the lazy inner type is stable,
27752 // and so it is sufficient to avoid reconciling it away.
27753 // We're not going to unwrap or actually use the new lazy type.
27754 needsCompareFamilies = true;
27755 }
27756
27757 break;
27758 }
27759
27760 case ForwardRef:
27761 {
27762 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
27763 needsCompareFamilies = true;
27764 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
27765 needsCompareFamilies = true;
27766 }
27767
27768 break;
27769 }
27770
27771 case MemoComponent:
27772 case SimpleMemoComponent:
27773 {
27774 if ($$typeofNextType === REACT_MEMO_TYPE) {
27775 // TODO: if it was but can no longer be simple,
27776 // we shouldn't set this.
27777 needsCompareFamilies = true;
27778 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
27779 needsCompareFamilies = true;
27780 }
27781
27782 break;
27783 }
27784
27785 default:
27786 return false;
27787 } // Check if both types have a family and it's the same one.
27788
27789
27790 if (needsCompareFamilies) {
27791 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
27792 // This means both of them need to be registered to preserve state.
27793 // If we unwrapped and compared the inner types for wrappers instead,
27794 // then we would risk falsely saying two separate memo(Foo)
27795 // calls are equivalent because they wrap the same Foo function.
27796 var prevFamily = resolveFamily(prevType);
27797
27798 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
27799 return true;
27800 }
27801 }
27802
27803 return false;
27804 }
27805 }
27806 function markFailedErrorBoundaryForHotReloading(fiber) {
27807 {
27808 if (resolveFamily === null) {
27809 // Hot reloading is disabled.
27810 return;
27811 }
27812
27813 if (typeof WeakSet !== 'function') {
27814 return;
27815 }
27816
27817 if (failedBoundaries === null) {
27818 failedBoundaries = new WeakSet();
27819 }
27820
27821 failedBoundaries.add(fiber);
27822 }
27823 }
27824 var scheduleRefresh = function (root, update) {
27825 {
27826 if (resolveFamily === null) {
27827 // Hot reloading is disabled.
27828 return;
27829 }
27830
27831 var staleFamilies = update.staleFamilies,
27832 updatedFamilies = update.updatedFamilies;
27833 flushPassiveEffects();
27834 flushSync(function () {
27835 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);
27836 });
27837 }
27838 };
27839 var scheduleRoot = function (root, element) {
27840 {
27841 if (root.context !== emptyContextObject) {
27842 // Super edge case: root has a legacy _renderSubtree context
27843 // but we don't know the parentComponent so we can't pass it.
27844 // Just ignore. We'll delete this with _renderSubtree code path later.
27845 return;
27846 }
27847
27848 flushPassiveEffects();
27849 flushSync(function () {
27850 updateContainer(element, root, null, null);
27851 });
27852 }
27853 };
27854
27855 function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
27856 {
27857 var alternate = fiber.alternate,
27858 child = fiber.child,
27859 sibling = fiber.sibling,
27860 tag = fiber.tag,
27861 type = fiber.type;
27862 var candidateType = null;
27863
27864 switch (tag) {
27865 case FunctionComponent:
27866 case SimpleMemoComponent:
27867 case ClassComponent:
27868 candidateType = type;
27869 break;
27870
27871 case ForwardRef:
27872 candidateType = type.render;
27873 break;
27874 }
27875
27876 if (resolveFamily === null) {
27877 throw new Error('Expected resolveFamily to be set during hot reload.');
27878 }
27879
27880 var needsRender = false;
27881 var needsRemount = false;
27882
27883 if (candidateType !== null) {
27884 var family = resolveFamily(candidateType);
27885
27886 if (family !== undefined) {
27887 if (staleFamilies.has(family)) {
27888 needsRemount = true;
27889 } else if (updatedFamilies.has(family)) {
27890 if (tag === ClassComponent) {
27891 needsRemount = true;
27892 } else {
27893 needsRender = true;
27894 }
27895 }
27896 }
27897 }
27898
27899 if (failedBoundaries !== null) {
27900 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
27901 needsRemount = true;
27902 }
27903 }
27904
27905 if (needsRemount) {
27906 fiber._debugNeedsRemount = true;
27907 }
27908
27909 if (needsRemount || needsRender) {
27910 var _root = enqueueConcurrentRenderForLane(fiber, SyncLane);
27911
27912 if (_root !== null) {
27913 scheduleUpdateOnFiber(_root, fiber, SyncLane, NoTimestamp);
27914 }
27915 }
27916
27917 if (child !== null && !needsRemount) {
27918 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
27919 }
27920
27921 if (sibling !== null) {
27922 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
27923 }
27924 }
27925 }
27926
27927 var findHostInstancesForRefresh = function (root, families) {
27928 {
27929 var hostInstances = new Set();
27930 var types = new Set(families.map(function (family) {
27931 return family.current;
27932 }));
27933 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
27934 return hostInstances;
27935 }
27936 };
27937
27938 function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
27939 {
27940 var child = fiber.child,
27941 sibling = fiber.sibling,
27942 tag = fiber.tag,
27943 type = fiber.type;
27944 var candidateType = null;
27945
27946 switch (tag) {
27947 case FunctionComponent:
27948 case SimpleMemoComponent:
27949 case ClassComponent:
27950 candidateType = type;
27951 break;
27952
27953 case ForwardRef:
27954 candidateType = type.render;
27955 break;
27956 }
27957
27958 var didMatch = false;
27959
27960 if (candidateType !== null) {
27961 if (types.has(candidateType)) {
27962 didMatch = true;
27963 }
27964 }
27965
27966 if (didMatch) {
27967 // We have a match. This only drills down to the closest host components.
27968 // There's no need to search deeper because for the purpose of giving
27969 // visual feedback, "flashing" outermost parent rectangles is sufficient.
27970 findHostInstancesForFiberShallowly(fiber, hostInstances);
27971 } else {
27972 // If there's no match, maybe there will be one further down in the child tree.
27973 if (child !== null) {
27974 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
27975 }
27976 }
27977
27978 if (sibling !== null) {
27979 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
27980 }
27981 }
27982 }
27983
27984 function findHostInstancesForFiberShallowly(fiber, hostInstances) {
27985 {
27986 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
27987
27988 if (foundHostInstances) {
27989 return;
27990 } // If we didn't find any host children, fallback to closest host parent.
27991
27992
27993 var node = fiber;
27994
27995 while (true) {
27996 switch (node.tag) {
27997 case HostComponent:
27998 hostInstances.add(node.stateNode);
27999 return;
28000
28001 case HostPortal:
28002 hostInstances.add(node.stateNode.containerInfo);
28003 return;
28004
28005 case HostRoot:
28006 hostInstances.add(node.stateNode.containerInfo);
28007 return;
28008 }
28009
28010 if (node.return === null) {
28011 throw new Error('Expected to reach root first.');
28012 }
28013
28014 node = node.return;
28015 }
28016 }
28017 }
28018
28019 function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
28020 {
28021 var node = fiber;
28022 var foundHostInstances = false;
28023
28024 while (true) {
28025 if (node.tag === HostComponent) {
28026 // We got a match.
28027 foundHostInstances = true;
28028 hostInstances.add(node.stateNode); // There may still be more, so keep searching.
28029 } else if (node.child !== null) {
28030 node.child.return = node;
28031 node = node.child;
28032 continue;
28033 }
28034
28035 if (node === fiber) {
28036 return foundHostInstances;
28037 }
28038
28039 while (node.sibling === null) {
28040 if (node.return === null || node.return === fiber) {
28041 return foundHostInstances;
28042 }
28043
28044 node = node.return;
28045 }
28046
28047 node.sibling.return = node.return;
28048 node = node.sibling;
28049 }
28050 }
28051
28052 return false;
28053 }
28054
28055 var hasBadMapPolyfill;
28056
28057 {
28058 hasBadMapPolyfill = false;
28059
28060 try {
28061 var nonExtensibleObject = Object.preventExtensions({});
28062 /* eslint-disable no-new */
28063
28064 new Map([[nonExtensibleObject, null]]);
28065 new Set([nonExtensibleObject]);
28066 /* eslint-enable no-new */
28067 } catch (e) {
28068 // TODO: Consider warning about bad polyfills
28069 hasBadMapPolyfill = true;
28070 }
28071 }
28072
28073 function FiberNode(tag, pendingProps, key, mode) {
28074 // Instance
28075 this.tag = tag;
28076 this.key = key;
28077 this.elementType = null;
28078 this.type = null;
28079 this.stateNode = null; // Fiber
28080
28081 this.return = null;
28082 this.child = null;
28083 this.sibling = null;
28084 this.index = 0;
28085 this.ref = null;
28086 this.pendingProps = pendingProps;
28087 this.memoizedProps = null;
28088 this.updateQueue = null;
28089 this.memoizedState = null;
28090 this.dependencies = null;
28091 this.mode = mode; // Effects
28092
28093 this.flags = NoFlags;
28094 this.subtreeFlags = NoFlags;
28095 this.deletions = null;
28096 this.lanes = NoLanes;
28097 this.childLanes = NoLanes;
28098 this.alternate = null;
28099
28100 {
28101 // Note: The following is done to avoid a v8 performance cliff.
28102 //
28103 // Initializing the fields below to smis and later updating them with
28104 // double values will cause Fibers to end up having separate shapes.
28105 // This behavior/bug has something to do with Object.preventExtension().
28106 // Fortunately this only impacts DEV builds.
28107 // Unfortunately it makes React unusably slow for some applications.
28108 // To work around this, initialize the fields below with doubles.
28109 //
28110 // Learn more about this here:
28111 // https://github.com/facebook/react/issues/14365
28112 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
28113 this.actualDuration = Number.NaN;
28114 this.actualStartTime = Number.NaN;
28115 this.selfBaseDuration = Number.NaN;
28116 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
28117 // This won't trigger the performance cliff mentioned above,
28118 // and it simplifies other profiler code (including DevTools).
28119
28120 this.actualDuration = 0;
28121 this.actualStartTime = -1;
28122 this.selfBaseDuration = 0;
28123 this.treeBaseDuration = 0;
28124 }
28125
28126 {
28127 // This isn't directly used but is handy for debugging internals:
28128 this._debugSource = null;
28129 this._debugOwner = null;
28130 this._debugNeedsRemount = false;
28131 this._debugHookTypes = null;
28132
28133 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
28134 Object.preventExtensions(this);
28135 }
28136 }
28137 } // This is a constructor function, rather than a POJO constructor, still
28138 // please ensure we do the following:
28139 // 1) Nobody should add any instance methods on this. Instance methods can be
28140 // more difficult to predict when they get optimized and they are almost
28141 // never inlined properly in static compilers.
28142 // 2) Nobody should rely on `instanceof Fiber` for type testing. We should
28143 // always know when it is a fiber.
28144 // 3) We might want to experiment with using numeric keys since they are easier
28145 // to optimize in a non-JIT environment.
28146 // 4) We can easily go from a constructor to a createFiber object literal if that
28147 // is faster.
28148 // 5) It should be easy to port this to a C struct and keep a C implementation
28149 // compatible.
28150
28151
28152 var createFiber = function (tag, pendingProps, key, mode) {
28153 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
28154 return new FiberNode(tag, pendingProps, key, mode);
28155 };
28156
28157 function shouldConstruct$1(Component) {
28158 var prototype = Component.prototype;
28159 return !!(prototype && prototype.isReactComponent);
28160 }
28161
28162 function isSimpleFunctionComponent(type) {
28163 return typeof type === 'function' && !shouldConstruct$1(type) && type.defaultProps === undefined;
28164 }
28165 function resolveLazyComponentTag(Component) {
28166 if (typeof Component === 'function') {
28167 return shouldConstruct$1(Component) ? ClassComponent : FunctionComponent;
28168 } else if (Component !== undefined && Component !== null) {
28169 var $$typeof = Component.$$typeof;
28170
28171 if ($$typeof === REACT_FORWARD_REF_TYPE) {
28172 return ForwardRef;
28173 }
28174
28175 if ($$typeof === REACT_MEMO_TYPE) {
28176 return MemoComponent;
28177 }
28178 }
28179
28180 return IndeterminateComponent;
28181 } // This is used to create an alternate fiber to do work on.
28182
28183 function createWorkInProgress(current, pendingProps) {
28184 var workInProgress = current.alternate;
28185
28186 if (workInProgress === null) {
28187 // We use a double buffering pooling technique because we know that we'll
28188 // only ever need at most two versions of a tree. We pool the "other" unused
28189 // node that we're free to reuse. This is lazily created to avoid allocating
28190 // extra objects for things that are never updated. It also allow us to
28191 // reclaim the extra memory if needed.
28192 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
28193 workInProgress.elementType = current.elementType;
28194 workInProgress.type = current.type;
28195 workInProgress.stateNode = current.stateNode;
28196
28197 {
28198 // DEV-only fields
28199 workInProgress._debugSource = current._debugSource;
28200 workInProgress._debugOwner = current._debugOwner;
28201 workInProgress._debugHookTypes = current._debugHookTypes;
28202 }
28203
28204 workInProgress.alternate = current;
28205 current.alternate = workInProgress;
28206 } else {
28207 workInProgress.pendingProps = pendingProps; // Needed because Blocks store data on type.
28208
28209 workInProgress.type = current.type; // We already have an alternate.
28210 // Reset the effect tag.
28211
28212 workInProgress.flags = NoFlags; // The effects are no longer valid.
28213
28214 workInProgress.subtreeFlags = NoFlags;
28215 workInProgress.deletions = null;
28216
28217 {
28218 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
28219 // This prevents time from endlessly accumulating in new commits.
28220 // This has the downside of resetting values for different priority renders,
28221 // But works for yielding (the common case) and should support resuming.
28222 workInProgress.actualDuration = 0;
28223 workInProgress.actualStartTime = -1;
28224 }
28225 } // Reset all effects except static ones.
28226 // Static effects are not specific to a render.
28227
28228
28229 workInProgress.flags = current.flags & StaticMask;
28230 workInProgress.childLanes = current.childLanes;
28231 workInProgress.lanes = current.lanes;
28232 workInProgress.child = current.child;
28233 workInProgress.memoizedProps = current.memoizedProps;
28234 workInProgress.memoizedState = current.memoizedState;
28235 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
28236 // it cannot be shared with the current fiber.
28237
28238 var currentDependencies = current.dependencies;
28239 workInProgress.dependencies = currentDependencies === null ? null : {
28240 lanes: currentDependencies.lanes,
28241 firstContext: currentDependencies.firstContext
28242 }; // These will be overridden during the parent's reconciliation
28243
28244 workInProgress.sibling = current.sibling;
28245 workInProgress.index = current.index;
28246 workInProgress.ref = current.ref;
28247
28248 {
28249 workInProgress.selfBaseDuration = current.selfBaseDuration;
28250 workInProgress.treeBaseDuration = current.treeBaseDuration;
28251 }
28252
28253 {
28254 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
28255
28256 switch (workInProgress.tag) {
28257 case IndeterminateComponent:
28258 case FunctionComponent:
28259 case SimpleMemoComponent:
28260 workInProgress.type = resolveFunctionForHotReloading(current.type);
28261 break;
28262
28263 case ClassComponent:
28264 workInProgress.type = resolveClassForHotReloading(current.type);
28265 break;
28266
28267 case ForwardRef:
28268 workInProgress.type = resolveForwardRefForHotReloading(current.type);
28269 break;
28270 }
28271 }
28272
28273 return workInProgress;
28274 } // Used to reuse a Fiber for a second pass.
28275
28276 function resetWorkInProgress(workInProgress, renderLanes) {
28277 // This resets the Fiber to what createFiber or createWorkInProgress would
28278 // have set the values to before during the first pass. Ideally this wouldn't
28279 // be necessary but unfortunately many code paths reads from the workInProgress
28280 // when they should be reading from current and writing to workInProgress.
28281 // We assume pendingProps, index, key, ref, return are still untouched to
28282 // avoid doing another reconciliation.
28283 // Reset the effect flags but keep any Placement tags, since that's something
28284 // that child fiber is setting, not the reconciliation.
28285 workInProgress.flags &= StaticMask | Placement; // The effects are no longer valid.
28286
28287 var current = workInProgress.alternate;
28288
28289 if (current === null) {
28290 // Reset to createFiber's initial values.
28291 workInProgress.childLanes = NoLanes;
28292 workInProgress.lanes = renderLanes;
28293 workInProgress.child = null;
28294 workInProgress.subtreeFlags = NoFlags;
28295 workInProgress.memoizedProps = null;
28296 workInProgress.memoizedState = null;
28297 workInProgress.updateQueue = null;
28298 workInProgress.dependencies = null;
28299 workInProgress.stateNode = null;
28300
28301 {
28302 // Note: We don't reset the actualTime counts. It's useful to accumulate
28303 // actual time across multiple render passes.
28304 workInProgress.selfBaseDuration = 0;
28305 workInProgress.treeBaseDuration = 0;
28306 }
28307 } else {
28308 // Reset to the cloned values that createWorkInProgress would've.
28309 workInProgress.childLanes = current.childLanes;
28310 workInProgress.lanes = current.lanes;
28311 workInProgress.child = current.child;
28312 workInProgress.subtreeFlags = NoFlags;
28313 workInProgress.deletions = null;
28314 workInProgress.memoizedProps = current.memoizedProps;
28315 workInProgress.memoizedState = current.memoizedState;
28316 workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type.
28317
28318 workInProgress.type = current.type; // Clone the dependencies object. This is mutated during the render phase, so
28319 // it cannot be shared with the current fiber.
28320
28321 var currentDependencies = current.dependencies;
28322 workInProgress.dependencies = currentDependencies === null ? null : {
28323 lanes: currentDependencies.lanes,
28324 firstContext: currentDependencies.firstContext
28325 };
28326
28327 {
28328 // Note: We don't reset the actualTime counts. It's useful to accumulate
28329 // actual time across multiple render passes.
28330 workInProgress.selfBaseDuration = current.selfBaseDuration;
28331 workInProgress.treeBaseDuration = current.treeBaseDuration;
28332 }
28333 }
28334
28335 return workInProgress;
28336 }
28337 function createHostRootFiber(tag, isStrictMode, concurrentUpdatesByDefaultOverride) {
28338 var mode;
28339
28340 if (tag === ConcurrentRoot) {
28341 mode = ConcurrentMode;
28342
28343 if (isStrictMode === true) {
28344 mode |= StrictLegacyMode;
28345
28346 {
28347 mode |= StrictEffectsMode;
28348 }
28349 }
28350 } else {
28351 mode = NoMode;
28352 }
28353
28354 if ( isDevToolsPresent) {
28355 // Always collect profile timings when DevTools are present.
28356 // This enables DevTools to start capturing timing at any point–
28357 // Without some nodes in the tree having empty base times.
28358 mode |= ProfileMode;
28359 }
28360
28361 return createFiber(HostRoot, null, null, mode);
28362 }
28363 function createFiberFromTypeAndProps(type, // React$ElementType
28364 key, pendingProps, owner, mode, lanes) {
28365 var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
28366
28367 var resolvedType = type;
28368
28369 if (typeof type === 'function') {
28370 if (shouldConstruct$1(type)) {
28371 fiberTag = ClassComponent;
28372
28373 {
28374 resolvedType = resolveClassForHotReloading(resolvedType);
28375 }
28376 } else {
28377 {
28378 resolvedType = resolveFunctionForHotReloading(resolvedType);
28379 }
28380 }
28381 } else if (typeof type === 'string') {
28382 fiberTag = HostComponent;
28383 } else {
28384 getTag: switch (type) {
28385 case REACT_FRAGMENT_TYPE:
28386 return createFiberFromFragment(pendingProps.children, mode, lanes, key);
28387
28388 case REACT_STRICT_MODE_TYPE:
28389 fiberTag = Mode;
28390 mode |= StrictLegacyMode;
28391
28392 if ( (mode & ConcurrentMode) !== NoMode) {
28393 // Strict effects should never run on legacy roots
28394 mode |= StrictEffectsMode;
28395 }
28396
28397 break;
28398
28399 case REACT_PROFILER_TYPE:
28400 return createFiberFromProfiler(pendingProps, mode, lanes, key);
28401
28402 case REACT_SUSPENSE_TYPE:
28403 return createFiberFromSuspense(pendingProps, mode, lanes, key);
28404
28405 case REACT_SUSPENSE_LIST_TYPE:
28406 return createFiberFromSuspenseList(pendingProps, mode, lanes, key);
28407
28408 case REACT_OFFSCREEN_TYPE:
28409 return createFiberFromOffscreen(pendingProps, mode, lanes, key);
28410
28411 case REACT_LEGACY_HIDDEN_TYPE:
28412
28413 // eslint-disable-next-line no-fallthrough
28414
28415 case REACT_SCOPE_TYPE:
28416
28417 // eslint-disable-next-line no-fallthrough
28418
28419 case REACT_CACHE_TYPE:
28420
28421 // eslint-disable-next-line no-fallthrough
28422
28423 case REACT_TRACING_MARKER_TYPE:
28424
28425 // eslint-disable-next-line no-fallthrough
28426
28427 case REACT_DEBUG_TRACING_MODE_TYPE:
28428
28429 // eslint-disable-next-line no-fallthrough
28430
28431 default:
28432 {
28433 if (typeof type === 'object' && type !== null) {
28434 switch (type.$$typeof) {
28435 case REACT_PROVIDER_TYPE:
28436 fiberTag = ContextProvider;
28437 break getTag;
28438
28439 case REACT_CONTEXT_TYPE:
28440 // This is a consumer
28441 fiberTag = ContextConsumer;
28442 break getTag;
28443
28444 case REACT_FORWARD_REF_TYPE:
28445 fiberTag = ForwardRef;
28446
28447 {
28448 resolvedType = resolveForwardRefForHotReloading(resolvedType);
28449 }
28450
28451 break getTag;
28452
28453 case REACT_MEMO_TYPE:
28454 fiberTag = MemoComponent;
28455 break getTag;
28456
28457 case REACT_LAZY_TYPE:
28458 fiberTag = LazyComponent;
28459 resolvedType = null;
28460 break getTag;
28461 }
28462 }
28463
28464 var info = '';
28465
28466 {
28467 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
28468 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.';
28469 }
28470
28471 var ownerName = owner ? getComponentNameFromFiber(owner) : null;
28472
28473 if (ownerName) {
28474 info += '\n\nCheck the render method of `' + ownerName + '`.';
28475 }
28476 }
28477
28478 throw new Error('Element type is invalid: expected a string (for built-in ' + 'components) or a class/function (for composite components) ' + ("but got: " + (type == null ? type : typeof type) + "." + info));
28479 }
28480 }
28481 }
28482
28483 var fiber = createFiber(fiberTag, pendingProps, key, mode);
28484 fiber.elementType = type;
28485 fiber.type = resolvedType;
28486 fiber.lanes = lanes;
28487
28488 {
28489 fiber._debugOwner = owner;
28490 }
28491
28492 return fiber;
28493 }
28494 function createFiberFromElement(element, mode, lanes) {
28495 var owner = null;
28496
28497 {
28498 owner = element._owner;
28499 }
28500
28501 var type = element.type;
28502 var key = element.key;
28503 var pendingProps = element.props;
28504 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, lanes);
28505
28506 {
28507 fiber._debugSource = element._source;
28508 fiber._debugOwner = element._owner;
28509 }
28510
28511 return fiber;
28512 }
28513 function createFiberFromFragment(elements, mode, lanes, key) {
28514 var fiber = createFiber(Fragment, elements, key, mode);
28515 fiber.lanes = lanes;
28516 return fiber;
28517 }
28518
28519 function createFiberFromProfiler(pendingProps, mode, lanes, key) {
28520 {
28521 if (typeof pendingProps.id !== 'string') {
28522 error('Profiler must specify an "id" of type `string` as a prop. Received the type `%s` instead.', typeof pendingProps.id);
28523 }
28524 }
28525
28526 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
28527 fiber.elementType = REACT_PROFILER_TYPE;
28528 fiber.lanes = lanes;
28529
28530 {
28531 fiber.stateNode = {
28532 effectDuration: 0,
28533 passiveEffectDuration: 0
28534 };
28535 }
28536
28537 return fiber;
28538 }
28539
28540 function createFiberFromSuspense(pendingProps, mode, lanes, key) {
28541 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
28542 fiber.elementType = REACT_SUSPENSE_TYPE;
28543 fiber.lanes = lanes;
28544 return fiber;
28545 }
28546 function createFiberFromSuspenseList(pendingProps, mode, lanes, key) {
28547 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
28548 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
28549 fiber.lanes = lanes;
28550 return fiber;
28551 }
28552 function createFiberFromOffscreen(pendingProps, mode, lanes, key) {
28553 var fiber = createFiber(OffscreenComponent, pendingProps, key, mode);
28554 fiber.elementType = REACT_OFFSCREEN_TYPE;
28555 fiber.lanes = lanes;
28556 var primaryChildInstance = {
28557 isHidden: false
28558 };
28559 fiber.stateNode = primaryChildInstance;
28560 return fiber;
28561 }
28562 function createFiberFromText(content, mode, lanes) {
28563 var fiber = createFiber(HostText, content, null, mode);
28564 fiber.lanes = lanes;
28565 return fiber;
28566 }
28567 function createFiberFromHostInstanceForDeletion() {
28568 var fiber = createFiber(HostComponent, null, null, NoMode);
28569 fiber.elementType = 'DELETED';
28570 return fiber;
28571 }
28572 function createFiberFromDehydratedFragment(dehydratedNode) {
28573 var fiber = createFiber(DehydratedFragment, null, null, NoMode);
28574 fiber.stateNode = dehydratedNode;
28575 return fiber;
28576 }
28577 function createFiberFromPortal(portal, mode, lanes) {
28578 var pendingProps = portal.children !== null ? portal.children : [];
28579 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
28580 fiber.lanes = lanes;
28581 fiber.stateNode = {
28582 containerInfo: portal.containerInfo,
28583 pendingChildren: null,
28584 // Used by persistent updates
28585 implementation: portal.implementation
28586 };
28587 return fiber;
28588 } // Used for stashing WIP properties to replay failed work in DEV.
28589
28590 function assignFiberPropertiesInDEV(target, source) {
28591 if (target === null) {
28592 // This Fiber's initial properties will always be overwritten.
28593 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
28594 target = createFiber(IndeterminateComponent, null, null, NoMode);
28595 } // This is intentionally written as a list of all properties.
28596 // We tried to use Object.assign() instead but this is called in
28597 // the hottest path, and Object.assign() was too slow:
28598 // https://github.com/facebook/react/issues/12502
28599 // This code is DEV-only so size is not a concern.
28600
28601
28602 target.tag = source.tag;
28603 target.key = source.key;
28604 target.elementType = source.elementType;
28605 target.type = source.type;
28606 target.stateNode = source.stateNode;
28607 target.return = source.return;
28608 target.child = source.child;
28609 target.sibling = source.sibling;
28610 target.index = source.index;
28611 target.ref = source.ref;
28612 target.pendingProps = source.pendingProps;
28613 target.memoizedProps = source.memoizedProps;
28614 target.updateQueue = source.updateQueue;
28615 target.memoizedState = source.memoizedState;
28616 target.dependencies = source.dependencies;
28617 target.mode = source.mode;
28618 target.flags = source.flags;
28619 target.subtreeFlags = source.subtreeFlags;
28620 target.deletions = source.deletions;
28621 target.lanes = source.lanes;
28622 target.childLanes = source.childLanes;
28623 target.alternate = source.alternate;
28624
28625 {
28626 target.actualDuration = source.actualDuration;
28627 target.actualStartTime = source.actualStartTime;
28628 target.selfBaseDuration = source.selfBaseDuration;
28629 target.treeBaseDuration = source.treeBaseDuration;
28630 }
28631
28632 target._debugSource = source._debugSource;
28633 target._debugOwner = source._debugOwner;
28634 target._debugNeedsRemount = source._debugNeedsRemount;
28635 target._debugHookTypes = source._debugHookTypes;
28636 return target;
28637 }
28638
28639 function FiberRootNode(containerInfo, tag, hydrate, identifierPrefix, onRecoverableError) {
28640 this.tag = tag;
28641 this.containerInfo = containerInfo;
28642 this.pendingChildren = null;
28643 this.current = null;
28644 this.pingCache = null;
28645 this.finishedWork = null;
28646 this.timeoutHandle = noTimeout;
28647 this.context = null;
28648 this.pendingContext = null;
28649 this.callbackNode = null;
28650 this.callbackPriority = NoLane;
28651 this.eventTimes = createLaneMap(NoLanes);
28652 this.expirationTimes = createLaneMap(NoTimestamp);
28653 this.pendingLanes = NoLanes;
28654 this.suspendedLanes = NoLanes;
28655 this.pingedLanes = NoLanes;
28656 this.expiredLanes = NoLanes;
28657 this.mutableReadLanes = NoLanes;
28658 this.finishedLanes = NoLanes;
28659 this.entangledLanes = NoLanes;
28660 this.entanglements = createLaneMap(NoLanes);
28661 this.identifierPrefix = identifierPrefix;
28662 this.onRecoverableError = onRecoverableError;
28663
28664 {
28665 this.mutableSourceEagerHydrationData = null;
28666 }
28667
28668 {
28669 this.effectDuration = 0;
28670 this.passiveEffectDuration = 0;
28671 }
28672
28673 {
28674 this.memoizedUpdaters = new Set();
28675 var pendingUpdatersLaneMap = this.pendingUpdatersLaneMap = [];
28676
28677 for (var _i = 0; _i < TotalLanes; _i++) {
28678 pendingUpdatersLaneMap.push(new Set());
28679 }
28680 }
28681
28682 {
28683 switch (tag) {
28684 case ConcurrentRoot:
28685 this._debugRootType = hydrate ? 'hydrateRoot()' : 'createRoot()';
28686 break;
28687
28688 case LegacyRoot:
28689 this._debugRootType = hydrate ? 'hydrate()' : 'render()';
28690 break;
28691 }
28692 }
28693 }
28694
28695 function createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, // TODO: We have several of these arguments that are conceptually part of the
28696 // host config, but because they are passed in at runtime, we have to thread
28697 // them through the root constructor. Perhaps we should put them all into a
28698 // single type, like a DynamicHostConfig that is defined by the renderer.
28699 identifierPrefix, onRecoverableError, transitionCallbacks) {
28700 var root = new FiberRootNode(containerInfo, tag, hydrate, identifierPrefix, onRecoverableError);
28701 // stateNode is any.
28702
28703
28704 var uninitializedFiber = createHostRootFiber(tag, isStrictMode);
28705 root.current = uninitializedFiber;
28706 uninitializedFiber.stateNode = root;
28707
28708 {
28709 var _initialState = {
28710 element: initialChildren,
28711 isDehydrated: hydrate,
28712 cache: null,
28713 // not enabled yet
28714 transitions: null,
28715 pendingSuspenseBoundaries: null
28716 };
28717 uninitializedFiber.memoizedState = _initialState;
28718 }
28719
28720 initializeUpdateQueue(uninitializedFiber);
28721 return root;
28722 }
28723
28724 var ReactVersion = '18.3.1';
28725
28726 function createPortal(children, containerInfo, // TODO: figure out the API for cross-renderer implementation.
28727 implementation) {
28728 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
28729
28730 {
28731 checkKeyStringCoercion(key);
28732 }
28733
28734 return {
28735 // This tag allow us to uniquely identify this as a React Portal
28736 $$typeof: REACT_PORTAL_TYPE,
28737 key: key == null ? null : '' + key,
28738 children: children,
28739 containerInfo: containerInfo,
28740 implementation: implementation
28741 };
28742 }
28743
28744 var didWarnAboutNestedUpdates;
28745 var didWarnAboutFindNodeInStrictMode;
28746
28747 {
28748 didWarnAboutNestedUpdates = false;
28749 didWarnAboutFindNodeInStrictMode = {};
28750 }
28751
28752 function getContextForSubtree(parentComponent) {
28753 if (!parentComponent) {
28754 return emptyContextObject;
28755 }
28756
28757 var fiber = get(parentComponent);
28758 var parentContext = findCurrentUnmaskedContext(fiber);
28759
28760 if (fiber.tag === ClassComponent) {
28761 var Component = fiber.type;
28762
28763 if (isContextProvider(Component)) {
28764 return processChildContext(fiber, Component, parentContext);
28765 }
28766 }
28767
28768 return parentContext;
28769 }
28770
28771 function findHostInstanceWithWarning(component, methodName) {
28772 {
28773 var fiber = get(component);
28774
28775 if (fiber === undefined) {
28776 if (typeof component.render === 'function') {
28777 throw new Error('Unable to find node on an unmounted component.');
28778 } else {
28779 var keys = Object.keys(component).join(',');
28780 throw new Error("Argument appears to not be a ReactComponent. Keys: " + keys);
28781 }
28782 }
28783
28784 var hostFiber = findCurrentHostFiber(fiber);
28785
28786 if (hostFiber === null) {
28787 return null;
28788 }
28789
28790 if (hostFiber.mode & StrictLegacyMode) {
28791 var componentName = getComponentNameFromFiber(fiber) || 'Component';
28792
28793 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
28794 didWarnAboutFindNodeInStrictMode[componentName] = true;
28795 var previousFiber = current;
28796
28797 try {
28798 setCurrentFiber(hostFiber);
28799
28800 if (fiber.mode & StrictLegacyMode) {
28801 error('%s is deprecated in StrictMode. ' + '%s was passed an instance of %s which is inside StrictMode. ' + 'Instead, add a ref directly to the element you want to reference. ' + 'Learn more about using refs safely here: ' + 'https://reactjs.org/link/strict-mode-find-node', methodName, methodName, componentName);
28802 } else {
28803 error('%s is deprecated in StrictMode. ' + '%s was passed an instance of %s which renders StrictMode children. ' + 'Instead, add a ref directly to the element you want to reference. ' + 'Learn more about using refs safely here: ' + 'https://reactjs.org/link/strict-mode-find-node', methodName, methodName, componentName);
28804 }
28805 } finally {
28806 // Ideally this should reset to previous but this shouldn't be called in
28807 // render and there's another warning for that anyway.
28808 if (previousFiber) {
28809 setCurrentFiber(previousFiber);
28810 } else {
28811 resetCurrentFiber();
28812 }
28813 }
28814 }
28815 }
28816
28817 return hostFiber.stateNode;
28818 }
28819 }
28820
28821 function createContainer(containerInfo, tag, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError, transitionCallbacks) {
28822 var hydrate = false;
28823 var initialChildren = null;
28824 return createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError);
28825 }
28826 function createHydrationContainer(initialChildren, // TODO: Remove `callback` when we delete legacy mode.
28827 callback, containerInfo, tag, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError, transitionCallbacks) {
28828 var hydrate = true;
28829 var root = createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError); // TODO: Move this to FiberRoot constructor
28830
28831 root.context = getContextForSubtree(null); // Schedule the initial render. In a hydration root, this is different from
28832 // a regular update because the initial render must match was was rendered
28833 // on the server.
28834 // NOTE: This update intentionally doesn't have a payload. We're only using
28835 // the update to schedule work on the root fiber (and, for legacy roots, to
28836 // enqueue the callback if one is provided).
28837
28838 var current = root.current;
28839 var eventTime = requestEventTime();
28840 var lane = requestUpdateLane(current);
28841 var update = createUpdate(eventTime, lane);
28842 update.callback = callback !== undefined && callback !== null ? callback : null;
28843 enqueueUpdate(current, update, lane);
28844 scheduleInitialHydrationOnRoot(root, lane, eventTime);
28845 return root;
28846 }
28847 function updateContainer(element, container, parentComponent, callback) {
28848 {
28849 onScheduleRoot(container, element);
28850 }
28851
28852 var current$1 = container.current;
28853 var eventTime = requestEventTime();
28854 var lane = requestUpdateLane(current$1);
28855
28856 {
28857 markRenderScheduled(lane);
28858 }
28859
28860 var context = getContextForSubtree(parentComponent);
28861
28862 if (container.context === null) {
28863 container.context = context;
28864 } else {
28865 container.pendingContext = context;
28866 }
28867
28868 {
28869 if (isRendering && current !== null && !didWarnAboutNestedUpdates) {
28870 didWarnAboutNestedUpdates = true;
28871
28872 error('Render methods should be a pure function of props and state; ' + 'triggering nested component updates from render is not allowed. ' + 'If necessary, trigger nested updates in componentDidUpdate.\n\n' + 'Check the render method of %s.', getComponentNameFromFiber(current) || 'Unknown');
28873 }
28874 }
28875
28876 var update = createUpdate(eventTime, lane); // Caution: React DevTools currently depends on this property
28877 // being called "element".
28878
28879 update.payload = {
28880 element: element
28881 };
28882 callback = callback === undefined ? null : callback;
28883
28884 if (callback !== null) {
28885 {
28886 if (typeof callback !== 'function') {
28887 error('render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
28888 }
28889 }
28890
28891 update.callback = callback;
28892 }
28893
28894 var root = enqueueUpdate(current$1, update, lane);
28895
28896 if (root !== null) {
28897 scheduleUpdateOnFiber(root, current$1, lane, eventTime);
28898 entangleTransitions(root, current$1, lane);
28899 }
28900
28901 return lane;
28902 }
28903 function getPublicRootInstance(container) {
28904 var containerFiber = container.current;
28905
28906 if (!containerFiber.child) {
28907 return null;
28908 }
28909
28910 switch (containerFiber.child.tag) {
28911 case HostComponent:
28912 return getPublicInstance(containerFiber.child.stateNode);
28913
28914 default:
28915 return containerFiber.child.stateNode;
28916 }
28917 }
28918 function attemptSynchronousHydration$1(fiber) {
28919 switch (fiber.tag) {
28920 case HostRoot:
28921 {
28922 var root = fiber.stateNode;
28923
28924 if (isRootDehydrated(root)) {
28925 // Flush the first scheduled "update".
28926 var lanes = getHighestPriorityPendingLanes(root);
28927 flushRoot(root, lanes);
28928 }
28929
28930 break;
28931 }
28932
28933 case SuspenseComponent:
28934 {
28935 flushSync(function () {
28936 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
28937
28938 if (root !== null) {
28939 var eventTime = requestEventTime();
28940 scheduleUpdateOnFiber(root, fiber, SyncLane, eventTime);
28941 }
28942 }); // If we're still blocked after this, we need to increase
28943 // the priority of any promises resolving within this
28944 // boundary so that they next attempt also has higher pri.
28945
28946 var retryLane = SyncLane;
28947 markRetryLaneIfNotHydrated(fiber, retryLane);
28948 break;
28949 }
28950 }
28951 }
28952
28953 function markRetryLaneImpl(fiber, retryLane) {
28954 var suspenseState = fiber.memoizedState;
28955
28956 if (suspenseState !== null && suspenseState.dehydrated !== null) {
28957 suspenseState.retryLane = higherPriorityLane(suspenseState.retryLane, retryLane);
28958 }
28959 } // Increases the priority of thenables when they resolve within this boundary.
28960
28961
28962 function markRetryLaneIfNotHydrated(fiber, retryLane) {
28963 markRetryLaneImpl(fiber, retryLane);
28964 var alternate = fiber.alternate;
28965
28966 if (alternate) {
28967 markRetryLaneImpl(alternate, retryLane);
28968 }
28969 }
28970 function attemptContinuousHydration$1(fiber) {
28971 if (fiber.tag !== SuspenseComponent) {
28972 // We ignore HostRoots here because we can't increase
28973 // their priority and they should not suspend on I/O,
28974 // since you have to wrap anything that might suspend in
28975 // Suspense.
28976 return;
28977 }
28978
28979 var lane = SelectiveHydrationLane;
28980 var root = enqueueConcurrentRenderForLane(fiber, lane);
28981
28982 if (root !== null) {
28983 var eventTime = requestEventTime();
28984 scheduleUpdateOnFiber(root, fiber, lane, eventTime);
28985 }
28986
28987 markRetryLaneIfNotHydrated(fiber, lane);
28988 }
28989 function attemptHydrationAtCurrentPriority$1(fiber) {
28990 if (fiber.tag !== SuspenseComponent) {
28991 // We ignore HostRoots here because we can't increase
28992 // their priority other than synchronously flush it.
28993 return;
28994 }
28995
28996 var lane = requestUpdateLane(fiber);
28997 var root = enqueueConcurrentRenderForLane(fiber, lane);
28998
28999 if (root !== null) {
29000 var eventTime = requestEventTime();
29001 scheduleUpdateOnFiber(root, fiber, lane, eventTime);
29002 }
29003
29004 markRetryLaneIfNotHydrated(fiber, lane);
29005 }
29006 function findHostInstanceWithNoPortals(fiber) {
29007 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
29008
29009 if (hostFiber === null) {
29010 return null;
29011 }
29012
29013 return hostFiber.stateNode;
29014 }
29015
29016 var shouldErrorImpl = function (fiber) {
29017 return null;
29018 };
29019
29020 function shouldError(fiber) {
29021 return shouldErrorImpl(fiber);
29022 }
29023
29024 var shouldSuspendImpl = function (fiber) {
29025 return false;
29026 };
29027
29028 function shouldSuspend(fiber) {
29029 return shouldSuspendImpl(fiber);
29030 }
29031 var overrideHookState = null;
29032 var overrideHookStateDeletePath = null;
29033 var overrideHookStateRenamePath = null;
29034 var overrideProps = null;
29035 var overridePropsDeletePath = null;
29036 var overridePropsRenamePath = null;
29037 var scheduleUpdate = null;
29038 var setErrorHandler = null;
29039 var setSuspenseHandler = null;
29040
29041 {
29042 var copyWithDeleteImpl = function (obj, path, index) {
29043 var key = path[index];
29044 var updated = isArray(obj) ? obj.slice() : assign({}, obj);
29045
29046 if (index + 1 === path.length) {
29047 if (isArray(updated)) {
29048 updated.splice(key, 1);
29049 } else {
29050 delete updated[key];
29051 }
29052
29053 return updated;
29054 } // $FlowFixMe number or string is fine here
29055
29056
29057 updated[key] = copyWithDeleteImpl(obj[key], path, index + 1);
29058 return updated;
29059 };
29060
29061 var copyWithDelete = function (obj, path) {
29062 return copyWithDeleteImpl(obj, path, 0);
29063 };
29064
29065 var copyWithRenameImpl = function (obj, oldPath, newPath, index) {
29066 var oldKey = oldPath[index];
29067 var updated = isArray(obj) ? obj.slice() : assign({}, obj);
29068
29069 if (index + 1 === oldPath.length) {
29070 var newKey = newPath[index]; // $FlowFixMe number or string is fine here
29071
29072 updated[newKey] = updated[oldKey];
29073
29074 if (isArray(updated)) {
29075 updated.splice(oldKey, 1);
29076 } else {
29077 delete updated[oldKey];
29078 }
29079 } else {
29080 // $FlowFixMe number or string is fine here
29081 updated[oldKey] = copyWithRenameImpl( // $FlowFixMe number or string is fine here
29082 obj[oldKey], oldPath, newPath, index + 1);
29083 }
29084
29085 return updated;
29086 };
29087
29088 var copyWithRename = function (obj, oldPath, newPath) {
29089 if (oldPath.length !== newPath.length) {
29090 warn('copyWithRename() expects paths of the same length');
29091
29092 return;
29093 } else {
29094 for (var i = 0; i < newPath.length - 1; i++) {
29095 if (oldPath[i] !== newPath[i]) {
29096 warn('copyWithRename() expects paths to be the same except for the deepest key');
29097
29098 return;
29099 }
29100 }
29101 }
29102
29103 return copyWithRenameImpl(obj, oldPath, newPath, 0);
29104 };
29105
29106 var copyWithSetImpl = function (obj, path, index, value) {
29107 if (index >= path.length) {
29108 return value;
29109 }
29110
29111 var key = path[index];
29112 var updated = isArray(obj) ? obj.slice() : assign({}, obj); // $FlowFixMe number or string is fine here
29113
29114 updated[key] = copyWithSetImpl(obj[key], path, index + 1, value);
29115 return updated;
29116 };
29117
29118 var copyWithSet = function (obj, path, value) {
29119 return copyWithSetImpl(obj, path, 0, value);
29120 };
29121
29122 var findHook = function (fiber, id) {
29123 // For now, the "id" of stateful hooks is just the stateful hook index.
29124 // This may change in the future with e.g. nested hooks.
29125 var currentHook = fiber.memoizedState;
29126
29127 while (currentHook !== null && id > 0) {
29128 currentHook = currentHook.next;
29129 id--;
29130 }
29131
29132 return currentHook;
29133 }; // Support DevTools editable values for useState and useReducer.
29134
29135
29136 overrideHookState = function (fiber, id, path, value) {
29137 var hook = findHook(fiber, id);
29138
29139 if (hook !== null) {
29140 var newState = copyWithSet(hook.memoizedState, path, value);
29141 hook.memoizedState = newState;
29142 hook.baseState = newState; // We aren't actually adding an update to the queue,
29143 // because there is no update we can add for useReducer hooks that won't trigger an error.
29144 // (There's no appropriate action type for DevTools overrides.)
29145 // As a result though, React will see the scheduled update as a noop and bailout.
29146 // Shallow cloning props works as a workaround for now to bypass the bailout check.
29147
29148 fiber.memoizedProps = assign({}, fiber.memoizedProps);
29149 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
29150
29151 if (root !== null) {
29152 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
29153 }
29154 }
29155 };
29156
29157 overrideHookStateDeletePath = function (fiber, id, path) {
29158 var hook = findHook(fiber, id);
29159
29160 if (hook !== null) {
29161 var newState = copyWithDelete(hook.memoizedState, path);
29162 hook.memoizedState = newState;
29163 hook.baseState = newState; // We aren't actually adding an update to the queue,
29164 // because there is no update we can add for useReducer hooks that won't trigger an error.
29165 // (There's no appropriate action type for DevTools overrides.)
29166 // As a result though, React will see the scheduled update as a noop and bailout.
29167 // Shallow cloning props works as a workaround for now to bypass the bailout check.
29168
29169 fiber.memoizedProps = assign({}, fiber.memoizedProps);
29170 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
29171
29172 if (root !== null) {
29173 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
29174 }
29175 }
29176 };
29177
29178 overrideHookStateRenamePath = function (fiber, id, oldPath, newPath) {
29179 var hook = findHook(fiber, id);
29180
29181 if (hook !== null) {
29182 var newState = copyWithRename(hook.memoizedState, oldPath, newPath);
29183 hook.memoizedState = newState;
29184 hook.baseState = newState; // We aren't actually adding an update to the queue,
29185 // because there is no update we can add for useReducer hooks that won't trigger an error.
29186 // (There's no appropriate action type for DevTools overrides.)
29187 // As a result though, React will see the scheduled update as a noop and bailout.
29188 // Shallow cloning props works as a workaround for now to bypass the bailout check.
29189
29190 fiber.memoizedProps = assign({}, fiber.memoizedProps);
29191 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
29192
29193 if (root !== null) {
29194 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
29195 }
29196 }
29197 }; // Support DevTools props for function components, forwardRef, memo, host components, etc.
29198
29199
29200 overrideProps = function (fiber, path, value) {
29201 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
29202
29203 if (fiber.alternate) {
29204 fiber.alternate.pendingProps = fiber.pendingProps;
29205 }
29206
29207 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
29208
29209 if (root !== null) {
29210 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
29211 }
29212 };
29213
29214 overridePropsDeletePath = function (fiber, path) {
29215 fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path);
29216
29217 if (fiber.alternate) {
29218 fiber.alternate.pendingProps = fiber.pendingProps;
29219 }
29220
29221 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
29222
29223 if (root !== null) {
29224 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
29225 }
29226 };
29227
29228 overridePropsRenamePath = function (fiber, oldPath, newPath) {
29229 fiber.pendingProps = copyWithRename(fiber.memoizedProps, oldPath, newPath);
29230
29231 if (fiber.alternate) {
29232 fiber.alternate.pendingProps = fiber.pendingProps;
29233 }
29234
29235 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
29236
29237 if (root !== null) {
29238 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
29239 }
29240 };
29241
29242 scheduleUpdate = function (fiber) {
29243 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
29244
29245 if (root !== null) {
29246 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
29247 }
29248 };
29249
29250 setErrorHandler = function (newShouldErrorImpl) {
29251 shouldErrorImpl = newShouldErrorImpl;
29252 };
29253
29254 setSuspenseHandler = function (newShouldSuspendImpl) {
29255 shouldSuspendImpl = newShouldSuspendImpl;
29256 };
29257 }
29258
29259 function findHostInstanceByFiber(fiber) {
29260 var hostFiber = findCurrentHostFiber(fiber);
29261
29262 if (hostFiber === null) {
29263 return null;
29264 }
29265
29266 return hostFiber.stateNode;
29267 }
29268
29269 function emptyFindFiberByHostInstance(instance) {
29270 return null;
29271 }
29272
29273 function getCurrentFiberForDevTools() {
29274 return current;
29275 }
29276
29277 function injectIntoDevTools(devToolsConfig) {
29278 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
29279 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
29280 return injectInternals({
29281 bundleType: devToolsConfig.bundleType,
29282 version: devToolsConfig.version,
29283 rendererPackageName: devToolsConfig.rendererPackageName,
29284 rendererConfig: devToolsConfig.rendererConfig,
29285 overrideHookState: overrideHookState,
29286 overrideHookStateDeletePath: overrideHookStateDeletePath,
29287 overrideHookStateRenamePath: overrideHookStateRenamePath,
29288 overrideProps: overrideProps,
29289 overridePropsDeletePath: overridePropsDeletePath,
29290 overridePropsRenamePath: overridePropsRenamePath,
29291 setErrorHandler: setErrorHandler,
29292 setSuspenseHandler: setSuspenseHandler,
29293 scheduleUpdate: scheduleUpdate,
29294 currentDispatcherRef: ReactCurrentDispatcher,
29295 findHostInstanceByFiber: findHostInstanceByFiber,
29296 findFiberByHostInstance: findFiberByHostInstance || emptyFindFiberByHostInstance,
29297 // React Refresh
29298 findHostInstancesForRefresh: findHostInstancesForRefresh ,
29299 scheduleRefresh: scheduleRefresh ,
29300 scheduleRoot: scheduleRoot ,
29301 setRefreshHandler: setRefreshHandler ,
29302 // Enables DevTools to append owner stacks to error messages in DEV mode.
29303 getCurrentFiber: getCurrentFiberForDevTools ,
29304 // Enables DevTools to detect reconciler version rather than renderer version
29305 // which may not match for third party renderers.
29306 reconcilerVersion: ReactVersion
29307 });
29308 }
29309
29310 /* global reportError */
29311
29312 var defaultOnRecoverableError = typeof reportError === 'function' ? // In modern browsers, reportError will dispatch an error event,
29313 // emulating an uncaught JavaScript error.
29314 reportError : function (error) {
29315 // In older browsers and test environments, fallback to console.error.
29316 // eslint-disable-next-line react-internal/no-production-logging
29317 console['error'](error);
29318 };
29319
29320 function ReactDOMRoot(internalRoot) {
29321 this._internalRoot = internalRoot;
29322 }
29323
29324 ReactDOMHydrationRoot.prototype.render = ReactDOMRoot.prototype.render = function (children) {
29325 var root = this._internalRoot;
29326
29327 if (root === null) {
29328 throw new Error('Cannot update an unmounted root.');
29329 }
29330
29331 {
29332 if (typeof arguments[1] === 'function') {
29333 error('render(...): does not support the second callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().');
29334 } else if (isValidContainer(arguments[1])) {
29335 error('You passed a container to the second argument of root.render(...). ' + "You don't need to pass it again since you already passed it to create the root.");
29336 } else if (typeof arguments[1] !== 'undefined') {
29337 error('You passed a second argument to root.render(...) but it only accepts ' + 'one argument.');
29338 }
29339
29340 var container = root.containerInfo;
29341
29342 if (container.nodeType !== COMMENT_NODE) {
29343 var hostInstance = findHostInstanceWithNoPortals(root.current);
29344
29345 if (hostInstance) {
29346 if (hostInstance.parentNode !== container) {
29347 error('render(...): It looks like the React-rendered content of the ' + 'root container was removed without using React. This is not ' + 'supported and will cause errors. Instead, call ' + "root.unmount() to empty a root's container.");
29348 }
29349 }
29350 }
29351 }
29352
29353 updateContainer(children, root, null, null);
29354 };
29355
29356 ReactDOMHydrationRoot.prototype.unmount = ReactDOMRoot.prototype.unmount = function () {
29357 {
29358 if (typeof arguments[0] === 'function') {
29359 error('unmount(...): does not support a callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().');
29360 }
29361 }
29362
29363 var root = this._internalRoot;
29364
29365 if (root !== null) {
29366 this._internalRoot = null;
29367 var container = root.containerInfo;
29368
29369 {
29370 if (isAlreadyRendering()) {
29371 error('Attempted to synchronously unmount a root while React was already ' + 'rendering. React cannot finish unmounting the root until the ' + 'current render has completed, which may lead to a race condition.');
29372 }
29373 }
29374
29375 flushSync(function () {
29376 updateContainer(null, root, null, null);
29377 });
29378 unmarkContainerAsRoot(container);
29379 }
29380 };
29381
29382 function createRoot(container, options) {
29383 if (!isValidContainer(container)) {
29384 throw new Error('createRoot(...): Target container is not a DOM element.');
29385 }
29386
29387 warnIfReactDOMContainerInDEV(container);
29388 var isStrictMode = false;
29389 var concurrentUpdatesByDefaultOverride = false;
29390 var identifierPrefix = '';
29391 var onRecoverableError = defaultOnRecoverableError;
29392 var transitionCallbacks = null;
29393
29394 if (options !== null && options !== undefined) {
29395 {
29396 if (options.hydrate) {
29397 warn('hydrate through createRoot is deprecated. Use ReactDOMClient.hydrateRoot(container, <App />) instead.');
29398 } else {
29399 if (typeof options === 'object' && options !== null && options.$$typeof === REACT_ELEMENT_TYPE) {
29400 error('You passed a JSX element to createRoot. You probably meant to ' + 'call root.render instead. ' + 'Example usage:\n\n' + ' let root = createRoot(domContainer);\n' + ' root.render(<App />);');
29401 }
29402 }
29403 }
29404
29405 if (options.unstable_strictMode === true) {
29406 isStrictMode = true;
29407 }
29408
29409 if (options.identifierPrefix !== undefined) {
29410 identifierPrefix = options.identifierPrefix;
29411 }
29412
29413 if (options.onRecoverableError !== undefined) {
29414 onRecoverableError = options.onRecoverableError;
29415 }
29416
29417 if (options.transitionCallbacks !== undefined) {
29418 transitionCallbacks = options.transitionCallbacks;
29419 }
29420 }
29421
29422 var root = createContainer(container, ConcurrentRoot, null, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError);
29423 markContainerAsRoot(root.current, container);
29424 var rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container;
29425 listenToAllSupportedEvents(rootContainerElement);
29426 return new ReactDOMRoot(root);
29427 }
29428
29429 function ReactDOMHydrationRoot(internalRoot) {
29430 this._internalRoot = internalRoot;
29431 }
29432
29433 function scheduleHydration(target) {
29434 if (target) {
29435 queueExplicitHydrationTarget(target);
29436 }
29437 }
29438
29439 ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = scheduleHydration;
29440 function hydrateRoot(container, initialChildren, options) {
29441 if (!isValidContainer(container)) {
29442 throw new Error('hydrateRoot(...): Target container is not a DOM element.');
29443 }
29444
29445 warnIfReactDOMContainerInDEV(container);
29446
29447 {
29448 if (initialChildren === undefined) {
29449 error('Must provide initial children as second argument to hydrateRoot. ' + 'Example usage: hydrateRoot(domContainer, <App />)');
29450 }
29451 } // For now we reuse the whole bag of options since they contain
29452 // the hydration callbacks.
29453
29454
29455 var hydrationCallbacks = options != null ? options : null; // TODO: Delete this option
29456
29457 var mutableSources = options != null && options.hydratedSources || null;
29458 var isStrictMode = false;
29459 var concurrentUpdatesByDefaultOverride = false;
29460 var identifierPrefix = '';
29461 var onRecoverableError = defaultOnRecoverableError;
29462
29463 if (options !== null && options !== undefined) {
29464 if (options.unstable_strictMode === true) {
29465 isStrictMode = true;
29466 }
29467
29468 if (options.identifierPrefix !== undefined) {
29469 identifierPrefix = options.identifierPrefix;
29470 }
29471
29472 if (options.onRecoverableError !== undefined) {
29473 onRecoverableError = options.onRecoverableError;
29474 }
29475 }
29476
29477 var root = createHydrationContainer(initialChildren, null, container, ConcurrentRoot, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError);
29478 markContainerAsRoot(root.current, container); // This can't be a comment node since hydration doesn't work on comment nodes anyway.
29479
29480 listenToAllSupportedEvents(container);
29481
29482 if (mutableSources) {
29483 for (var i = 0; i < mutableSources.length; i++) {
29484 var mutableSource = mutableSources[i];
29485 registerMutableSourceForHydration(root, mutableSource);
29486 }
29487 }
29488
29489 return new ReactDOMHydrationRoot(root);
29490 }
29491 function isValidContainer(node) {
29492 return !!(node && (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE || !disableCommentsAsDOMContainers ));
29493 } // TODO: Remove this function which also includes comment nodes.
29494 // We only use it in places that are currently more relaxed.
29495
29496 function isValidContainerLegacy(node) {
29497 return !!(node && (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE || node.nodeType === COMMENT_NODE && node.nodeValue === ' react-mount-point-unstable '));
29498 }
29499
29500 function warnIfReactDOMContainerInDEV(container) {
29501 {
29502 if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === 'BODY') {
29503 error('createRoot(): Creating roots directly with document.body is ' + 'discouraged, since its children are often manipulated by third-party ' + 'scripts and browser extensions. This may lead to subtle ' + 'reconciliation issues. Try using a container element created ' + 'for your app.');
29504 }
29505
29506 if (isContainerMarkedAsRoot(container)) {
29507 if (container._reactRootContainer) {
29508 error('You are calling ReactDOMClient.createRoot() on a container that was previously ' + 'passed to ReactDOM.render(). This is not supported.');
29509 } else {
29510 error('You are calling ReactDOMClient.createRoot() on a container that ' + 'has already been passed to createRoot() before. Instead, call ' + 'root.render() on the existing root instead if you want to update it.');
29511 }
29512 }
29513 }
29514 }
29515
29516 var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
29517 var topLevelUpdateWarnings;
29518
29519 {
29520 topLevelUpdateWarnings = function (container) {
29521 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
29522 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer.current);
29523
29524 if (hostInstance) {
29525 if (hostInstance.parentNode !== container) {
29526 error('render(...): It looks like the React-rendered content of this ' + 'container was removed without using React. This is not ' + 'supported and will cause errors. Instead, call ' + 'ReactDOM.unmountComponentAtNode to empty a container.');
29527 }
29528 }
29529 }
29530
29531 var isRootRenderedBySomeReact = !!container._reactRootContainer;
29532 var rootEl = getReactRootElementInContainer(container);
29533 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode(rootEl));
29534
29535 if (hasNonRootReactChild && !isRootRenderedBySomeReact) {
29536 error('render(...): Replacing React-rendered children with a new root ' + 'component. If you intended to update the children of this node, ' + 'you should instead have the existing children update their state ' + 'and render the new components instead of calling ReactDOM.render.');
29537 }
29538
29539 if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === 'BODY') {
29540 error('render(): Rendering components directly into document.body is ' + 'discouraged, since its children are often manipulated by third-party ' + 'scripts and browser extensions. This may lead to subtle ' + 'reconciliation issues. Try rendering into a container element created ' + 'for your app.');
29541 }
29542 };
29543 }
29544
29545 function getReactRootElementInContainer(container) {
29546 if (!container) {
29547 return null;
29548 }
29549
29550 if (container.nodeType === DOCUMENT_NODE) {
29551 return container.documentElement;
29552 } else {
29553 return container.firstChild;
29554 }
29555 }
29556
29557 function noopOnRecoverableError() {// This isn't reachable because onRecoverableError isn't called in the
29558 // legacy API.
29559 }
29560
29561 function legacyCreateRootFromDOMContainer(container, initialChildren, parentComponent, callback, isHydrationContainer) {
29562 if (isHydrationContainer) {
29563 if (typeof callback === 'function') {
29564 var originalCallback = callback;
29565
29566 callback = function () {
29567 var instance = getPublicRootInstance(root);
29568 originalCallback.call(instance);
29569 };
29570 }
29571
29572 var root = createHydrationContainer(initialChildren, callback, container, LegacyRoot, null, // hydrationCallbacks
29573 false, // isStrictMode
29574 false, // concurrentUpdatesByDefaultOverride,
29575 '', // identifierPrefix
29576 noopOnRecoverableError);
29577 container._reactRootContainer = root;
29578 markContainerAsRoot(root.current, container);
29579 var rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container;
29580 listenToAllSupportedEvents(rootContainerElement);
29581 flushSync();
29582 return root;
29583 } else {
29584 // First clear any existing content.
29585 var rootSibling;
29586
29587 while (rootSibling = container.lastChild) {
29588 container.removeChild(rootSibling);
29589 }
29590
29591 if (typeof callback === 'function') {
29592 var _originalCallback = callback;
29593
29594 callback = function () {
29595 var instance = getPublicRootInstance(_root);
29596
29597 _originalCallback.call(instance);
29598 };
29599 }
29600
29601 var _root = createContainer(container, LegacyRoot, null, // hydrationCallbacks
29602 false, // isStrictMode
29603 false, // concurrentUpdatesByDefaultOverride,
29604 '', // identifierPrefix
29605 noopOnRecoverableError);
29606
29607 container._reactRootContainer = _root;
29608 markContainerAsRoot(_root.current, container);
29609
29610 var _rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container;
29611
29612 listenToAllSupportedEvents(_rootContainerElement); // Initial mount should not be batched.
29613
29614 flushSync(function () {
29615 updateContainer(initialChildren, _root, parentComponent, callback);
29616 });
29617 return _root;
29618 }
29619 }
29620
29621 function warnOnInvalidCallback$1(callback, callerName) {
29622 {
29623 if (callback !== null && typeof callback !== 'function') {
29624 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
29625 }
29626 }
29627 }
29628
29629 function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
29630 {
29631 topLevelUpdateWarnings(container);
29632 warnOnInvalidCallback$1(callback === undefined ? null : callback, 'render');
29633 }
29634
29635 var maybeRoot = container._reactRootContainer;
29636 var root;
29637
29638 if (!maybeRoot) {
29639 // Initial mount
29640 root = legacyCreateRootFromDOMContainer(container, children, parentComponent, callback, forceHydrate);
29641 } else {
29642 root = maybeRoot;
29643
29644 if (typeof callback === 'function') {
29645 var originalCallback = callback;
29646
29647 callback = function () {
29648 var instance = getPublicRootInstance(root);
29649 originalCallback.call(instance);
29650 };
29651 } // Update
29652
29653
29654 updateContainer(children, root, parentComponent, callback);
29655 }
29656
29657 return getPublicRootInstance(root);
29658 }
29659
29660 var didWarnAboutFindDOMNode = false;
29661 function findDOMNode(componentOrElement) {
29662 {
29663 if (!didWarnAboutFindDOMNode) {
29664 didWarnAboutFindDOMNode = true;
29665
29666 error('findDOMNode is deprecated and will be removed in the next major ' + 'release. Instead, add a ref directly to the element you want ' + 'to reference. Learn more about using refs safely here: ' + 'https://reactjs.org/link/strict-mode-find-node');
29667 }
29668
29669 var owner = ReactCurrentOwner$3.current;
29670
29671 if (owner !== null && owner.stateNode !== null) {
29672 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
29673
29674 if (!warnedAboutRefsInRender) {
29675 error('%s is accessing findDOMNode inside its render(). ' + '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.', getComponentNameFromType(owner.type) || 'A component');
29676 }
29677
29678 owner.stateNode._warnedAboutRefsInRender = true;
29679 }
29680 }
29681
29682 if (componentOrElement == null) {
29683 return null;
29684 }
29685
29686 if (componentOrElement.nodeType === ELEMENT_NODE) {
29687 return componentOrElement;
29688 }
29689
29690 {
29691 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');
29692 }
29693 }
29694 function hydrate(element, container, callback) {
29695 {
29696 error('ReactDOM.hydrate is no longer supported in React 18. Use hydrateRoot ' + 'instead. Until you switch to the new API, your app will behave as ' + "if it's running React 17. Learn " + 'more: https://reactjs.org/link/switch-to-createroot');
29697 }
29698
29699 if (!isValidContainerLegacy(container)) {
29700 throw new Error('Target container is not a DOM element.');
29701 }
29702
29703 {
29704 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
29705
29706 if (isModernRoot) {
29707 error('You are calling ReactDOM.hydrate() on a container that was previously ' + 'passed to ReactDOMClient.createRoot(). This is not supported. ' + 'Did you mean to call hydrateRoot(container, element)?');
29708 }
29709 } // TODO: throw or warn if we couldn't hydrate?
29710
29711
29712 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
29713 }
29714 function render(element, container, callback) {
29715 {
29716 error('ReactDOM.render is no longer supported in React 18. Use createRoot ' + 'instead. Until you switch to the new API, your app will behave as ' + "if it's running React 17. Learn " + 'more: https://reactjs.org/link/switch-to-createroot');
29717 }
29718
29719 if (!isValidContainerLegacy(container)) {
29720 throw new Error('Target container is not a DOM element.');
29721 }
29722
29723 {
29724 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
29725
29726 if (isModernRoot) {
29727 error('You are calling ReactDOM.render() on a container that was previously ' + 'passed to ReactDOMClient.createRoot(). This is not supported. ' + 'Did you mean to call root.render(element)?');
29728 }
29729 }
29730
29731 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
29732 }
29733 function unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
29734 {
29735 error('ReactDOM.unstable_renderSubtreeIntoContainer() is no longer supported ' + 'in React 18. Consider using a portal instead. Until you switch to ' + "the createRoot API, your app will behave as if it's running React " + '17. Learn more: https://reactjs.org/link/switch-to-createroot');
29736 }
29737
29738 if (!isValidContainerLegacy(containerNode)) {
29739 throw new Error('Target container is not a DOM element.');
29740 }
29741
29742 if (parentComponent == null || !has(parentComponent)) {
29743 throw new Error('parentComponent must be a valid React Component');
29744 }
29745
29746 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
29747 }
29748 var didWarnAboutUnmountComponentAtNode = false;
29749 function unmountComponentAtNode(container) {
29750 {
29751 if (!didWarnAboutUnmountComponentAtNode) {
29752 didWarnAboutUnmountComponentAtNode = true;
29753
29754 error('unmountComponentAtNode is deprecated and will be removed in the ' + 'next major release. Switch to the createRoot API. Learn ' + 'more: https://reactjs.org/link/switch-to-createroot');
29755 }
29756 }
29757
29758 if (!isValidContainerLegacy(container)) {
29759 throw new Error('unmountComponentAtNode(...): Target container is not a DOM element.');
29760 }
29761
29762 {
29763 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
29764
29765 if (isModernRoot) {
29766 error('You are calling ReactDOM.unmountComponentAtNode() on a container that was previously ' + 'passed to ReactDOMClient.createRoot(). This is not supported. Did you mean to call root.unmount()?');
29767 }
29768 }
29769
29770 if (container._reactRootContainer) {
29771 {
29772 var rootEl = getReactRootElementInContainer(container);
29773 var renderedByDifferentReact = rootEl && !getInstanceFromNode(rootEl);
29774
29775 if (renderedByDifferentReact) {
29776 error("unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.');
29777 }
29778 } // Unmount should not be batched.
29779
29780
29781 flushSync(function () {
29782 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
29783 // $FlowFixMe This should probably use `delete container._reactRootContainer`
29784 container._reactRootContainer = null;
29785 unmarkContainerAsRoot(container);
29786 });
29787 }); // If you call unmountComponentAtNode twice in quick succession, you'll
29788 // get `true` twice. That's probably fine?
29789
29790 return true;
29791 } else {
29792 {
29793 var _rootEl = getReactRootElementInContainer(container);
29794
29795 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode(_rootEl)); // Check if the container itself is a React root node.
29796
29797 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainerLegacy(container.parentNode) && !!container.parentNode._reactRootContainer;
29798
29799 if (hasNonRootReactChild) {
29800 error("unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by React and is not a top-level container. %s', isContainerReactRoot ? 'You may have accidentally passed in a React root node instead ' + 'of its container.' : 'Instead, have the parent component update its state and ' + 'rerender in order to remove this component.');
29801 }
29802 }
29803
29804 return false;
29805 }
29806 }
29807
29808 setAttemptSynchronousHydration(attemptSynchronousHydration$1);
29809 setAttemptContinuousHydration(attemptContinuousHydration$1);
29810 setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority$1);
29811 setGetCurrentUpdatePriority(getCurrentUpdatePriority);
29812 setAttemptHydrationAtPriority(runWithPriority);
29813
29814 {
29815 if (typeof Map !== 'function' || // $FlowIssue Flow incorrectly thinks Map has no prototype
29816 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' || // $FlowIssue Flow incorrectly thinks Set has no prototype
29817 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {
29818 error('React depends on Map and Set built-in types. Make sure that you load a ' + 'polyfill in older browsers. https://reactjs.org/link/react-polyfills');
29819 }
29820 }
29821
29822 setRestoreImplementation(restoreControlledState$3);
29823 setBatchingImplementation(batchedUpdates$1, discreteUpdates, flushSync);
29824
29825 function createPortal$1(children, container) {
29826 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
29827
29828 if (!isValidContainer(container)) {
29829 throw new Error('Target container is not a DOM element.');
29830 } // TODO: pass ReactDOM portal implementation as third argument
29831 // $FlowFixMe The Flow type is opaque but there's no way to actually create it.
29832
29833
29834 return createPortal(children, container, null, key);
29835 }
29836
29837 function renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
29838 return unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback);
29839 }
29840
29841 var Internals = {
29842 usingClientEntryPoint: false,
29843 // Keep in sync with ReactTestUtils.js.
29844 // This is an array for better minification.
29845 Events: [getInstanceFromNode, getNodeFromInstance, getFiberCurrentPropsFromNode, enqueueStateRestore, restoreStateIfNeeded, batchedUpdates$1]
29846 };
29847
29848 function createRoot$1(container, options) {
29849 {
29850 if (!Internals.usingClientEntryPoint && !false) {
29851 error('You are importing createRoot from "react-dom" which is not supported. ' + 'You should instead import it from "react-dom/client".');
29852 }
29853 }
29854
29855 return createRoot(container, options);
29856 }
29857
29858 function hydrateRoot$1(container, initialChildren, options) {
29859 {
29860 if (!Internals.usingClientEntryPoint && !false) {
29861 error('You are importing hydrateRoot from "react-dom" which is not supported. ' + 'You should instead import it from "react-dom/client".');
29862 }
29863 }
29864
29865 return hydrateRoot(container, initialChildren, options);
29866 } // Overload the definition to the two valid signatures.
29867 // Warning, this opts-out of checking the function body.
29868
29869
29870 // eslint-disable-next-line no-redeclare
29871 function flushSync$1(fn) {
29872 {
29873 if (isAlreadyRendering()) {
29874 error('flushSync was called from inside a lifecycle method. React cannot ' + 'flush when React is already rendering. Consider moving this call to ' + 'a scheduler task or micro task.');
29875 }
29876 }
29877
29878 return flushSync(fn);
29879 }
29880 var foundDevTools = injectIntoDevTools({
29881 findFiberByHostInstance: getClosestInstanceFromNode,
29882 bundleType: 1 ,
29883 version: ReactVersion,
29884 rendererPackageName: 'react-dom'
29885 });
29886
29887 {
29888 if (!foundDevTools && canUseDOM && window.top === window.self) {
29889 // If we're in Chrome or Firefox, provide a download link if not installed.
29890 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
29891 var protocol = window.location.protocol; // Don't warn in exotic cases like chrome-extension://.
29892
29893 if (/^(https?|file):$/.test(protocol)) {
29894 // eslint-disable-next-line react-internal/no-production-logging
29895 console.info('%cDownload the React DevTools ' + 'for a better development experience: ' + 'https://reactjs.org/link/react-devtools' + (protocol === 'file:' ? '\nYou might need to use a local HTTP server (instead of file://): ' + 'https://reactjs.org/link/react-devtools-faq' : ''), 'font-weight:bold');
29896 }
29897 }
29898 }
29899 }
29900
29901 exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals;
29902 exports.createPortal = createPortal$1;
29903 exports.createRoot = createRoot$1;
29904 exports.findDOMNode = findDOMNode;
29905 exports.flushSync = flushSync$1;
29906 exports.hydrate = hydrate;
29907 exports.hydrateRoot = hydrateRoot$1;
29908 exports.render = render;
29909 exports.unmountComponentAtNode = unmountComponentAtNode;
29910 exports.unstable_batchedUpdates = batchedUpdates$1;
29911 exports.unstable_renderSubtreeIntoContainer = renderSubtreeIntoContainer;
29912 exports.version = ReactVersion;
29913 /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
29914 if (
29915 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
29916 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop ===
29917 'function'
29918 ) {
29919 __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error());
29920 }
29921
29922 })();
29923 }