UNPKG

940 kBJavaScriptView Raw
1/** @license React v17.0.1
2 * react-dom.development.js
3 *
4 * Copyright (c) Facebook, Inc. and its affiliates.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9(function (global, factory) {
10 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) :
11 typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) :
12 (global = global || self, factory(global.ReactDOM = {}, global.React));
13}(this, (function (exports, React) { 'use strict';
14
15 var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
16
17 // by calls to these methods by a Babel plugin.
18 //
19 // In PROD (or in packages without access to React internals),
20 // they are left as they are instead.
21
22 function warn(format) {
23 {
24 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
25 args[_key - 1] = arguments[_key];
26 }
27
28 printWarning('warn', format, args);
29 }
30 }
31 function error(format) {
32 {
33 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
34 args[_key2 - 1] = arguments[_key2];
35 }
36
37 printWarning('error', format, args);
38 }
39 }
40
41 function printWarning(level, format, args) {
42 // When changing this logic, you might want to also
43 // update consoleWithStackDev.www.js as well.
44 {
45 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
46 var stack = ReactDebugCurrentFrame.getStackAddendum();
47
48 if (stack !== '') {
49 format += '%s';
50 args = args.concat([stack]);
51 }
52
53 var argsWithFormat = args.map(function (item) {
54 return '' + item;
55 }); // Careful: RN currently depends on this prefix
56
57 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
58 // breaks IE9: https://github.com/facebook/react/issues/13610
59 // eslint-disable-next-line react-internal/no-production-logging
60
61 Function.prototype.apply.call(console[level], console, argsWithFormat);
62 }
63 }
64
65 if (!React) {
66 {
67 throw Error( "ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM." );
68 }
69 }
70
71 var FunctionComponent = 0;
72 var ClassComponent = 1;
73 var IndeterminateComponent = 2; // Before we know whether it is function or class
74
75 var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
76
77 var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
78
79 var HostComponent = 5;
80 var HostText = 6;
81 var Fragment = 7;
82 var Mode = 8;
83 var ContextConsumer = 9;
84 var ContextProvider = 10;
85 var ForwardRef = 11;
86 var Profiler = 12;
87 var SuspenseComponent = 13;
88 var MemoComponent = 14;
89 var SimpleMemoComponent = 15;
90 var LazyComponent = 16;
91 var IncompleteClassComponent = 17;
92 var DehydratedFragment = 18;
93 var SuspenseListComponent = 19;
94 var FundamentalComponent = 20;
95 var ScopeComponent = 21;
96 var Block = 22;
97 var OffscreenComponent = 23;
98 var LegacyHiddenComponent = 24;
99
100 // Filter certain DOM attributes (e.g. src, href) if their values are empty strings.
101
102 var enableProfilerTimer = true; // Record durations for commit and passive effects phases.
103
104 var enableFundamentalAPI = false; // Experimental Scope support.
105 var enableNewReconciler = false; // Errors that are thrown while unmounting (or after in the case of passive effects)
106 var warnAboutStringRefs = false;
107
108 var allNativeEvents = new Set();
109 /**
110 * Mapping from registration name to event name
111 */
112
113
114 var registrationNameDependencies = {};
115 /**
116 * Mapping from lowercase registration names to the properly cased version,
117 * used to warn in the case of missing event handlers. Available
118 * only in true.
119 * @type {Object}
120 */
121
122 var possibleRegistrationNames = {} ; // Trust the developer to only use possibleRegistrationNames in true
123
124 function registerTwoPhaseEvent(registrationName, dependencies) {
125 registerDirectEvent(registrationName, dependencies);
126 registerDirectEvent(registrationName + 'Capture', dependencies);
127 }
128 function registerDirectEvent(registrationName, dependencies) {
129 {
130 if (registrationNameDependencies[registrationName]) {
131 error('EventRegistry: More than one plugin attempted to publish the same ' + 'registration name, `%s`.', registrationName);
132 }
133 }
134
135 registrationNameDependencies[registrationName] = dependencies;
136
137 {
138 var lowerCasedName = registrationName.toLowerCase();
139 possibleRegistrationNames[lowerCasedName] = registrationName;
140
141 if (registrationName === 'onDoubleClick') {
142 possibleRegistrationNames.ondblclick = registrationName;
143 }
144 }
145
146 for (var i = 0; i < dependencies.length; i++) {
147 allNativeEvents.add(dependencies[i]);
148 }
149 }
150
151 var canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined');
152
153 // A reserved attribute.
154 // It is handled by React separately and shouldn't be written to the DOM.
155 var RESERVED = 0; // A simple string attribute.
156 // Attributes that aren't in the filter are presumed to have this type.
157
158 var STRING = 1; // A string attribute that accepts booleans in React. In HTML, these are called
159 // "enumerated" attributes with "true" and "false" as possible values.
160 // When true, it should be set to a "true" string.
161 // When false, it should be set to a "false" string.
162
163 var BOOLEANISH_STRING = 2; // A real boolean attribute.
164 // When true, it should be present (set either to an empty string or its name).
165 // When false, it should be omitted.
166
167 var BOOLEAN = 3; // An attribute that can be used as a flag as well as with a value.
168 // When true, it should be present (set either to an empty string or its name).
169 // When false, it should be omitted.
170 // For any other value, should be present with that value.
171
172 var OVERLOADED_BOOLEAN = 4; // An attribute that must be numeric or parse as a numeric.
173 // When falsy, it should be removed.
174
175 var NUMERIC = 5; // An attribute that must be positive numeric or parse as a positive numeric.
176 // When falsy, it should be removed.
177
178 var POSITIVE_NUMERIC = 6;
179
180 /* eslint-disable max-len */
181 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";
182 /* eslint-enable max-len */
183
184 var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + "\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
185 var ROOT_ATTRIBUTE_NAME = 'data-reactroot';
186 var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
187 var hasOwnProperty = Object.prototype.hasOwnProperty;
188 var illegalAttributeNameCache = {};
189 var validatedAttributeNameCache = {};
190 function isAttributeNameSafe(attributeName) {
191 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {
192 return true;
193 }
194
195 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {
196 return false;
197 }
198
199 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
200 validatedAttributeNameCache[attributeName] = true;
201 return true;
202 }
203
204 illegalAttributeNameCache[attributeName] = true;
205
206 {
207 error('Invalid attribute name: `%s`', attributeName);
208 }
209
210 return false;
211 }
212 function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
213 if (propertyInfo !== null) {
214 return propertyInfo.type === RESERVED;
215 }
216
217 if (isCustomComponentTag) {
218 return false;
219 }
220
221 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
222 return true;
223 }
224
225 return false;
226 }
227 function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
228 if (propertyInfo !== null && propertyInfo.type === RESERVED) {
229 return false;
230 }
231
232 switch (typeof value) {
233 case 'function': // $FlowIssue symbol is perfectly valid here
234
235 case 'symbol':
236 // eslint-disable-line
237 return true;
238
239 case 'boolean':
240 {
241 if (isCustomComponentTag) {
242 return false;
243 }
244
245 if (propertyInfo !== null) {
246 return !propertyInfo.acceptsBooleans;
247 } else {
248 var prefix = name.toLowerCase().slice(0, 5);
249 return prefix !== 'data-' && prefix !== 'aria-';
250 }
251 }
252
253 default:
254 return false;
255 }
256 }
257 function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
258 if (value === null || typeof value === 'undefined') {
259 return true;
260 }
261
262 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
263 return true;
264 }
265
266 if (isCustomComponentTag) {
267 return false;
268 }
269
270 if (propertyInfo !== null) {
271
272 switch (propertyInfo.type) {
273 case BOOLEAN:
274 return !value;
275
276 case OVERLOADED_BOOLEAN:
277 return value === false;
278
279 case NUMERIC:
280 return isNaN(value);
281
282 case POSITIVE_NUMERIC:
283 return isNaN(value) || value < 1;
284 }
285 }
286
287 return false;
288 }
289 function getPropertyInfo(name) {
290 return properties.hasOwnProperty(name) ? properties[name] : null;
291 }
292
293 function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL, removeEmptyString) {
294 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
295 this.attributeName = attributeName;
296 this.attributeNamespace = attributeNamespace;
297 this.mustUseProperty = mustUseProperty;
298 this.propertyName = name;
299 this.type = type;
300 this.sanitizeURL = sanitizeURL;
301 this.removeEmptyString = removeEmptyString;
302 } // When adding attributes to this list, be sure to also add them to
303 // the `possibleStandardNames` module to ensure casing and incorrect
304 // name warnings.
305
306
307 var properties = {}; // These props are reserved by React. They shouldn't be written to the DOM.
308
309 var reservedProps = ['children', 'dangerouslySetInnerHTML', // TODO: This prevents the assignment of defaultValue to regular
310 // elements (not just inputs). Now that ReactDOMInput assigns to the
311 // defaultValue property -- do we need this?
312 'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'];
313 reservedProps.forEach(function (name) {
314 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
315 name, // attributeName
316 null, // attributeNamespace
317 false, // sanitizeURL
318 false);
319 }); // A few React string attributes have a different name.
320 // This is a mapping from React prop names to the attribute names.
321
322 [['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) {
323 var name = _ref[0],
324 attributeName = _ref[1];
325 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
326 attributeName, // attributeName
327 null, // attributeNamespace
328 false, // sanitizeURL
329 false);
330 }); // These are "enumerated" HTML attributes that accept "true" and "false".
331 // In React, we let users pass `true` and `false` even though technically
332 // these aren't boolean attributes (they are coerced to strings).
333
334 ['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
335 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
336 name.toLowerCase(), // attributeName
337 null, // attributeNamespace
338 false, // sanitizeURL
339 false);
340 }); // These are "enumerated" SVG attributes that accept "true" and "false".
341 // In React, we let users pass `true` and `false` even though technically
342 // these aren't boolean attributes (they are coerced to strings).
343 // Since these are SVG attributes, their attribute names are case-sensitive.
344
345 ['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) {
346 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
347 name, // attributeName
348 null, // attributeNamespace
349 false, // sanitizeURL
350 false);
351 }); // These are HTML boolean attributes.
352
353 ['allowFullScreen', 'async', // Note: there is a special case that prevents it from being written to the DOM
354 // on the client side because the browsers are inconsistent. Instead we call focus().
355 'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'disablePictureInPicture', 'disableRemotePlayback', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless', // Microdata
356 'itemScope'].forEach(function (name) {
357 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
358 name.toLowerCase(), // attributeName
359 null, // attributeNamespace
360 false, // sanitizeURL
361 false);
362 }); // These are the few React props that we set as DOM properties
363 // rather than attributes. These are all booleans.
364
365 ['checked', // Note: `option.selected` is not updated if `select.multiple` is
366 // disabled with `removeAttribute`. We have special logic for handling this.
367 'multiple', 'muted', 'selected' // NOTE: if you add a camelCased prop to this list,
368 // you'll need to set attributeName to name.toLowerCase()
369 // instead in the assignment below.
370 ].forEach(function (name) {
371 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
372 name, // attributeName
373 null, // attributeNamespace
374 false, // sanitizeURL
375 false);
376 }); // These are HTML attributes that are "overloaded booleans": they behave like
377 // booleans, but can also accept a string value.
378
379 ['capture', 'download' // NOTE: if you add a camelCased prop to this list,
380 // you'll need to set attributeName to name.toLowerCase()
381 // instead in the assignment below.
382 ].forEach(function (name) {
383 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
384 name, // attributeName
385 null, // attributeNamespace
386 false, // sanitizeURL
387 false);
388 }); // These are HTML attributes that must be positive numbers.
389
390 ['cols', 'rows', 'size', 'span' // NOTE: if you add a camelCased prop to this list,
391 // you'll need to set attributeName to name.toLowerCase()
392 // instead in the assignment below.
393 ].forEach(function (name) {
394 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty
395 name, // attributeName
396 null, // attributeNamespace
397 false, // sanitizeURL
398 false);
399 }); // These are HTML attributes that must be numbers.
400
401 ['rowSpan', 'start'].forEach(function (name) {
402 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty
403 name.toLowerCase(), // attributeName
404 null, // attributeNamespace
405 false, // sanitizeURL
406 false);
407 });
408 var CAMELIZE = /[\-\:]([a-z])/g;
409
410 var capitalize = function (token) {
411 return token[1].toUpperCase();
412 }; // This is a list of all SVG attributes that need special casing, namespacing,
413 // or boolean value assignment. Regular attributes that just accept strings
414 // and have the same names are omitted, just like in the HTML attribute filter.
415 // Some of these attributes can be hard to find. This list was created by
416 // scraping the MDN documentation.
417
418
419 ['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,
420 // you'll need to set attributeName to name.toLowerCase()
421 // instead in the assignment below.
422 ].forEach(function (attributeName) {
423 var name = attributeName.replace(CAMELIZE, capitalize);
424 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
425 attributeName, null, // attributeNamespace
426 false, // sanitizeURL
427 false);
428 }); // String SVG attributes with the xlink namespace.
429
430 ['xlink:actuate', 'xlink:arcrole', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type' // NOTE: if you add a camelCased prop to this list,
431 // you'll need to set attributeName to name.toLowerCase()
432 // instead in the assignment below.
433 ].forEach(function (attributeName) {
434 var name = attributeName.replace(CAMELIZE, capitalize);
435 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
436 attributeName, 'http://www.w3.org/1999/xlink', false, // sanitizeURL
437 false);
438 }); // String SVG attributes with the xml namespace.
439
440 ['xml:base', 'xml:lang', 'xml:space' // NOTE: if you add a camelCased prop to this list,
441 // you'll need to set attributeName to name.toLowerCase()
442 // instead in the assignment below.
443 ].forEach(function (attributeName) {
444 var name = attributeName.replace(CAMELIZE, capitalize);
445 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
446 attributeName, 'http://www.w3.org/XML/1998/namespace', false, // sanitizeURL
447 false);
448 }); // These attribute exists both in HTML and SVG.
449 // The attribute name is case-sensitive in SVG so we can't just use
450 // the React name like we do for attributes that exist only in HTML.
451
452 ['tabIndex', 'crossOrigin'].forEach(function (attributeName) {
453 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
454 attributeName.toLowerCase(), // attributeName
455 null, // attributeNamespace
456 false, // sanitizeURL
457 false);
458 }); // These attributes accept URLs. These must not allow javascript: URLS.
459 // These will also need to accept Trusted Types object in the future.
460
461 var xlinkHref = 'xlinkHref';
462 properties[xlinkHref] = new PropertyInfoRecord('xlinkHref', STRING, false, // mustUseProperty
463 'xlink:href', 'http://www.w3.org/1999/xlink', true, // sanitizeURL
464 false);
465 ['src', 'href', 'action', 'formAction'].forEach(function (attributeName) {
466 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
467 attributeName.toLowerCase(), // attributeName
468 null, // attributeNamespace
469 true, // sanitizeURL
470 true);
471 });
472
473 // and any newline or tab are filtered out as if they're not part of the URL.
474 // https://url.spec.whatwg.org/#url-parsing
475 // Tab or newline are defined as \r\n\t:
476 // https://infra.spec.whatwg.org/#ascii-tab-or-newline
477 // A C0 control is a code point in the range \u0000 NULL to \u001F
478 // INFORMATION SEPARATOR ONE, inclusive:
479 // https://infra.spec.whatwg.org/#c0-control-or-space
480
481 /* eslint-disable max-len */
482
483 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;
484 var didWarn = false;
485
486 function sanitizeURL(url) {
487 {
488 if (!didWarn && isJavaScriptProtocol.test(url)) {
489 didWarn = true;
490
491 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));
492 }
493 }
494 }
495
496 /**
497 * Get the value for a property on a node. Only used in DEV for SSR validation.
498 * The "expected" argument is used as a hint of what the expected value is.
499 * Some properties have multiple equivalent values.
500 */
501 function getValueForProperty(node, name, expected, propertyInfo) {
502 {
503 if (propertyInfo.mustUseProperty) {
504 var propertyName = propertyInfo.propertyName;
505 return node[propertyName];
506 } else {
507 if ( propertyInfo.sanitizeURL) {
508 // If we haven't fully disabled javascript: URLs, and if
509 // the hydration is successful of a javascript: URL, we
510 // still want to warn on the client.
511 sanitizeURL('' + expected);
512 }
513
514 var attributeName = propertyInfo.attributeName;
515 var stringValue = null;
516
517 if (propertyInfo.type === OVERLOADED_BOOLEAN) {
518 if (node.hasAttribute(attributeName)) {
519 var value = node.getAttribute(attributeName);
520
521 if (value === '') {
522 return true;
523 }
524
525 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
526 return value;
527 }
528
529 if (value === '' + expected) {
530 return expected;
531 }
532
533 return value;
534 }
535 } else if (node.hasAttribute(attributeName)) {
536 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
537 // We had an attribute but shouldn't have had one, so read it
538 // for the error message.
539 return node.getAttribute(attributeName);
540 }
541
542 if (propertyInfo.type === BOOLEAN) {
543 // If this was a boolean, it doesn't matter what the value is
544 // the fact that we have it is the same as the expected.
545 return expected;
546 } // Even if this property uses a namespace we use getAttribute
547 // because we assume its namespaced name is the same as our config.
548 // To use getAttributeNS we need the local name which we don't have
549 // in our config atm.
550
551
552 stringValue = node.getAttribute(attributeName);
553 }
554
555 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
556 return stringValue === null ? expected : stringValue;
557 } else if (stringValue === '' + expected) {
558 return expected;
559 } else {
560 return stringValue;
561 }
562 }
563 }
564 }
565 /**
566 * Get the value for a attribute on a node. Only used in DEV for SSR validation.
567 * The third argument is used as a hint of what the expected value is. Some
568 * attributes have multiple equivalent values.
569 */
570
571 function getValueForAttribute(node, name, expected) {
572 {
573 if (!isAttributeNameSafe(name)) {
574 return;
575 } // If the object is an opaque reference ID, it's expected that
576 // the next prop is different than the server value, so just return
577 // expected
578
579
580 if (isOpaqueHydratingObject(expected)) {
581 return expected;
582 }
583
584 if (!node.hasAttribute(name)) {
585 return expected === undefined ? undefined : null;
586 }
587
588 var value = node.getAttribute(name);
589
590 if (value === '' + expected) {
591 return expected;
592 }
593
594 return value;
595 }
596 }
597 /**
598 * Sets the value for a property on a node.
599 *
600 * @param {DOMElement} node
601 * @param {string} name
602 * @param {*} value
603 */
604
605 function setValueForProperty(node, name, value, isCustomComponentTag) {
606 var propertyInfo = getPropertyInfo(name);
607
608 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {
609 return;
610 }
611
612 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
613 value = null;
614 } // If the prop isn't in the special list, treat it as a simple attribute.
615
616
617 if (isCustomComponentTag || propertyInfo === null) {
618 if (isAttributeNameSafe(name)) {
619 var _attributeName = name;
620
621 if (value === null) {
622 node.removeAttribute(_attributeName);
623 } else {
624 node.setAttribute(_attributeName, '' + value);
625 }
626 }
627
628 return;
629 }
630
631 var mustUseProperty = propertyInfo.mustUseProperty;
632
633 if (mustUseProperty) {
634 var propertyName = propertyInfo.propertyName;
635
636 if (value === null) {
637 var type = propertyInfo.type;
638 node[propertyName] = type === BOOLEAN ? false : '';
639 } else {
640 // Contrary to `setAttribute`, object properties are properly
641 // `toString`ed by IE8/9.
642 node[propertyName] = value;
643 }
644
645 return;
646 } // The rest are treated as attributes with special cases.
647
648
649 var attributeName = propertyInfo.attributeName,
650 attributeNamespace = propertyInfo.attributeNamespace;
651
652 if (value === null) {
653 node.removeAttribute(attributeName);
654 } else {
655 var _type = propertyInfo.type;
656 var attributeValue;
657
658 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {
659 // If attribute type is boolean, we know for sure it won't be an execution sink
660 // and we won't require Trusted Type here.
661 attributeValue = '';
662 } else {
663 // `setAttribute` with objects becomes only `[object]` in IE8/9,
664 // ('' + value) makes it output the correct toString()-value.
665 {
666 attributeValue = '' + value;
667 }
668
669 if (propertyInfo.sanitizeURL) {
670 sanitizeURL(attributeValue.toString());
671 }
672 }
673
674 if (attributeNamespace) {
675 node.setAttributeNS(attributeNamespace, attributeName, attributeValue);
676 } else {
677 node.setAttribute(attributeName, attributeValue);
678 }
679 }
680 }
681
682 var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
683 var _assign = ReactInternals.assign;
684
685 // ATTENTION
686 // When adding new symbols to this file,
687 // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
688 // The Symbol used to tag the ReactElement-like types. If there is no native Symbol
689 // nor polyfill, then a plain number is used for performance.
690 var REACT_ELEMENT_TYPE = 0xeac7;
691 var REACT_PORTAL_TYPE = 0xeaca;
692 var REACT_FRAGMENT_TYPE = 0xeacb;
693 var REACT_STRICT_MODE_TYPE = 0xeacc;
694 var REACT_PROFILER_TYPE = 0xead2;
695 var REACT_PROVIDER_TYPE = 0xeacd;
696 var REACT_CONTEXT_TYPE = 0xeace;
697 var REACT_FORWARD_REF_TYPE = 0xead0;
698 var REACT_SUSPENSE_TYPE = 0xead1;
699 var REACT_SUSPENSE_LIST_TYPE = 0xead8;
700 var REACT_MEMO_TYPE = 0xead3;
701 var REACT_LAZY_TYPE = 0xead4;
702 var REACT_BLOCK_TYPE = 0xead9;
703 var REACT_SERVER_BLOCK_TYPE = 0xeada;
704 var REACT_FUNDAMENTAL_TYPE = 0xead5;
705 var REACT_SCOPE_TYPE = 0xead7;
706 var REACT_OPAQUE_ID_TYPE = 0xeae0;
707 var REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1;
708 var REACT_OFFSCREEN_TYPE = 0xeae2;
709 var REACT_LEGACY_HIDDEN_TYPE = 0xeae3;
710
711 if (typeof Symbol === 'function' && Symbol.for) {
712 var symbolFor = Symbol.for;
713 REACT_ELEMENT_TYPE = symbolFor('react.element');
714 REACT_PORTAL_TYPE = symbolFor('react.portal');
715 REACT_FRAGMENT_TYPE = symbolFor('react.fragment');
716 REACT_STRICT_MODE_TYPE = symbolFor('react.strict_mode');
717 REACT_PROFILER_TYPE = symbolFor('react.profiler');
718 REACT_PROVIDER_TYPE = symbolFor('react.provider');
719 REACT_CONTEXT_TYPE = symbolFor('react.context');
720 REACT_FORWARD_REF_TYPE = symbolFor('react.forward_ref');
721 REACT_SUSPENSE_TYPE = symbolFor('react.suspense');
722 REACT_SUSPENSE_LIST_TYPE = symbolFor('react.suspense_list');
723 REACT_MEMO_TYPE = symbolFor('react.memo');
724 REACT_LAZY_TYPE = symbolFor('react.lazy');
725 REACT_BLOCK_TYPE = symbolFor('react.block');
726 REACT_SERVER_BLOCK_TYPE = symbolFor('react.server.block');
727 REACT_FUNDAMENTAL_TYPE = symbolFor('react.fundamental');
728 REACT_SCOPE_TYPE = symbolFor('react.scope');
729 REACT_OPAQUE_ID_TYPE = symbolFor('react.opaque.id');
730 REACT_DEBUG_TRACING_MODE_TYPE = symbolFor('react.debug_trace_mode');
731 REACT_OFFSCREEN_TYPE = symbolFor('react.offscreen');
732 REACT_LEGACY_HIDDEN_TYPE = symbolFor('react.legacy_hidden');
733 }
734
735 var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
736 var FAUX_ITERATOR_SYMBOL = '@@iterator';
737 function getIteratorFn(maybeIterable) {
738 if (maybeIterable === null || typeof maybeIterable !== 'object') {
739 return null;
740 }
741
742 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
743
744 if (typeof maybeIterator === 'function') {
745 return maybeIterator;
746 }
747
748 return null;
749 }
750
751 // Helpers to patch console.logs to avoid logging during side-effect free
752 // replaying on render function. This currently only patches the object
753 // lazily which won't cover if the log function was extracted eagerly.
754 // We could also eagerly patch the method.
755 var disabledDepth = 0;
756 var prevLog;
757 var prevInfo;
758 var prevWarn;
759 var prevError;
760 var prevGroup;
761 var prevGroupCollapsed;
762 var prevGroupEnd;
763
764 function disabledLog() {}
765
766 disabledLog.__reactDisabledLog = true;
767 function disableLogs() {
768 {
769 if (disabledDepth === 0) {
770 /* eslint-disable react-internal/no-production-logging */
771 prevLog = console.log;
772 prevInfo = console.info;
773 prevWarn = console.warn;
774 prevError = console.error;
775 prevGroup = console.group;
776 prevGroupCollapsed = console.groupCollapsed;
777 prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099
778
779 var props = {
780 configurable: true,
781 enumerable: true,
782 value: disabledLog,
783 writable: true
784 }; // $FlowFixMe Flow thinks console is immutable.
785
786 Object.defineProperties(console, {
787 info: props,
788 log: props,
789 warn: props,
790 error: props,
791 group: props,
792 groupCollapsed: props,
793 groupEnd: props
794 });
795 /* eslint-enable react-internal/no-production-logging */
796 }
797
798 disabledDepth++;
799 }
800 }
801 function reenableLogs() {
802 {
803 disabledDepth--;
804
805 if (disabledDepth === 0) {
806 /* eslint-disable react-internal/no-production-logging */
807 var props = {
808 configurable: true,
809 enumerable: true,
810 writable: true
811 }; // $FlowFixMe Flow thinks console is immutable.
812
813 Object.defineProperties(console, {
814 log: _assign({}, props, {
815 value: prevLog
816 }),
817 info: _assign({}, props, {
818 value: prevInfo
819 }),
820 warn: _assign({}, props, {
821 value: prevWarn
822 }),
823 error: _assign({}, props, {
824 value: prevError
825 }),
826 group: _assign({}, props, {
827 value: prevGroup
828 }),
829 groupCollapsed: _assign({}, props, {
830 value: prevGroupCollapsed
831 }),
832 groupEnd: _assign({}, props, {
833 value: prevGroupEnd
834 })
835 });
836 /* eslint-enable react-internal/no-production-logging */
837 }
838
839 if (disabledDepth < 0) {
840 error('disabledDepth fell below zero. ' + 'This is a bug in React. Please file an issue.');
841 }
842 }
843 }
844
845 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
846 var prefix;
847 function describeBuiltInComponentFrame(name, source, ownerFn) {
848 {
849 if (prefix === undefined) {
850 // Extract the VM specific prefix used by each line.
851 try {
852 throw Error();
853 } catch (x) {
854 var match = x.stack.trim().match(/\n( *(at )?)/);
855 prefix = match && match[1] || '';
856 }
857 } // We use the prefix to ensure our stacks line up with native stack frames.
858
859
860 return '\n' + prefix + name;
861 }
862 }
863 var reentry = false;
864 var componentFrameCache;
865
866 {
867 var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
868 componentFrameCache = new PossiblyWeakMap();
869 }
870
871 function describeNativeComponentFrame(fn, construct) {
872 // If something asked for a stack inside a fake render, it should get ignored.
873 if (!fn || reentry) {
874 return '';
875 }
876
877 {
878 var frame = componentFrameCache.get(fn);
879
880 if (frame !== undefined) {
881 return frame;
882 }
883 }
884
885 var control;
886 reentry = true;
887 var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe It does accept undefined.
888
889 Error.prepareStackTrace = undefined;
890 var previousDispatcher;
891
892 {
893 previousDispatcher = ReactCurrentDispatcher.current; // Set the dispatcher in DEV because this might be call in the render function
894 // for warnings.
895
896 ReactCurrentDispatcher.current = null;
897 disableLogs();
898 }
899
900 try {
901 // This should throw.
902 if (construct) {
903 // Something should be setting the props in the constructor.
904 var Fake = function () {
905 throw Error();
906 }; // $FlowFixMe
907
908
909 Object.defineProperty(Fake.prototype, 'props', {
910 set: function () {
911 // We use a throwing setter instead of frozen or non-writable props
912 // because that won't throw in a non-strict mode function.
913 throw Error();
914 }
915 });
916
917 if (typeof Reflect === 'object' && Reflect.construct) {
918 // We construct a different control for this case to include any extra
919 // frames added by the construct call.
920 try {
921 Reflect.construct(Fake, []);
922 } catch (x) {
923 control = x;
924 }
925
926 Reflect.construct(fn, [], Fake);
927 } else {
928 try {
929 Fake.call();
930 } catch (x) {
931 control = x;
932 }
933
934 fn.call(Fake.prototype);
935 }
936 } else {
937 try {
938 throw Error();
939 } catch (x) {
940 control = x;
941 }
942
943 fn();
944 }
945 } catch (sample) {
946 // This is inlined manually because closure doesn't do it for us.
947 if (sample && control && typeof sample.stack === 'string') {
948 // This extracts the first frame from the sample that isn't also in the control.
949 // Skipping one frame that we assume is the frame that calls the two.
950 var sampleLines = sample.stack.split('\n');
951 var controlLines = control.stack.split('\n');
952 var s = sampleLines.length - 1;
953 var c = controlLines.length - 1;
954
955 while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) {
956 // We expect at least one stack frame to be shared.
957 // Typically this will be the root most one. However, stack frames may be
958 // cut off due to maximum stack limits. In this case, one maybe cut off
959 // earlier than the other. We assume that the sample is longer or the same
960 // and there for cut off earlier. So we should find the root most frame in
961 // the sample somewhere in the control.
962 c--;
963 }
964
965 for (; s >= 1 && c >= 0; s--, c--) {
966 // Next we find the first one that isn't the same which should be the
967 // frame that called our sample function and the control.
968 if (sampleLines[s] !== controlLines[c]) {
969 // In V8, the first line is describing the message but other VMs don't.
970 // If we're about to return the first line, and the control is also on the same
971 // line, that's a pretty good indicator that our sample threw at same line as
972 // the control. I.e. before we entered the sample frame. So we ignore this result.
973 // This can happen if you passed a class to function component, or non-function.
974 if (s !== 1 || c !== 1) {
975 do {
976 s--;
977 c--; // We may still have similar intermediate frames from the construct call.
978 // The next one that isn't the same should be our match though.
979
980 if (c < 0 || sampleLines[s] !== controlLines[c]) {
981 // V8 adds a "new" prefix for native classes. Let's remove it to make it prettier.
982 var _frame = '\n' + sampleLines[s].replace(' at new ', ' at ');
983
984 {
985 if (typeof fn === 'function') {
986 componentFrameCache.set(fn, _frame);
987 }
988 } // Return the line we found.
989
990
991 return _frame;
992 }
993 } while (s >= 1 && c >= 0);
994 }
995
996 break;
997 }
998 }
999 }
1000 } finally {
1001 reentry = false;
1002
1003 {
1004 ReactCurrentDispatcher.current = previousDispatcher;
1005 reenableLogs();
1006 }
1007
1008 Error.prepareStackTrace = previousPrepareStackTrace;
1009 } // Fallback to just using the name if we couldn't make it throw.
1010
1011
1012 var name = fn ? fn.displayName || fn.name : '';
1013 var syntheticFrame = name ? describeBuiltInComponentFrame(name) : '';
1014
1015 {
1016 if (typeof fn === 'function') {
1017 componentFrameCache.set(fn, syntheticFrame);
1018 }
1019 }
1020
1021 return syntheticFrame;
1022 }
1023
1024 function describeClassComponentFrame(ctor, source, ownerFn) {
1025 {
1026 return describeNativeComponentFrame(ctor, true);
1027 }
1028 }
1029 function describeFunctionComponentFrame(fn, source, ownerFn) {
1030 {
1031 return describeNativeComponentFrame(fn, false);
1032 }
1033 }
1034
1035 function shouldConstruct(Component) {
1036 var prototype = Component.prototype;
1037 return !!(prototype && prototype.isReactComponent);
1038 }
1039
1040 function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) {
1041
1042 if (type == null) {
1043 return '';
1044 }
1045
1046 if (typeof type === 'function') {
1047 {
1048 return describeNativeComponentFrame(type, shouldConstruct(type));
1049 }
1050 }
1051
1052 if (typeof type === 'string') {
1053 return describeBuiltInComponentFrame(type);
1054 }
1055
1056 switch (type) {
1057 case REACT_SUSPENSE_TYPE:
1058 return describeBuiltInComponentFrame('Suspense');
1059
1060 case REACT_SUSPENSE_LIST_TYPE:
1061 return describeBuiltInComponentFrame('SuspenseList');
1062 }
1063
1064 if (typeof type === 'object') {
1065 switch (type.$$typeof) {
1066 case REACT_FORWARD_REF_TYPE:
1067 return describeFunctionComponentFrame(type.render);
1068
1069 case REACT_MEMO_TYPE:
1070 // Memo may contain any component type so we recursively resolve it.
1071 return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn);
1072
1073 case REACT_BLOCK_TYPE:
1074 return describeFunctionComponentFrame(type._render);
1075
1076 case REACT_LAZY_TYPE:
1077 {
1078 var lazyComponent = type;
1079 var payload = lazyComponent._payload;
1080 var init = lazyComponent._init;
1081
1082 try {
1083 // Lazy may contain any component type so we recursively resolve it.
1084 return describeUnknownElementTypeFrameInDEV(init(payload), source, ownerFn);
1085 } catch (x) {}
1086 }
1087 }
1088 }
1089
1090 return '';
1091 }
1092
1093 function describeFiber(fiber) {
1094 var owner = fiber._debugOwner ? fiber._debugOwner.type : null ;
1095 var source = fiber._debugSource ;
1096
1097 switch (fiber.tag) {
1098 case HostComponent:
1099 return describeBuiltInComponentFrame(fiber.type);
1100
1101 case LazyComponent:
1102 return describeBuiltInComponentFrame('Lazy');
1103
1104 case SuspenseComponent:
1105 return describeBuiltInComponentFrame('Suspense');
1106
1107 case SuspenseListComponent:
1108 return describeBuiltInComponentFrame('SuspenseList');
1109
1110 case FunctionComponent:
1111 case IndeterminateComponent:
1112 case SimpleMemoComponent:
1113 return describeFunctionComponentFrame(fiber.type);
1114
1115 case ForwardRef:
1116 return describeFunctionComponentFrame(fiber.type.render);
1117
1118 case Block:
1119 return describeFunctionComponentFrame(fiber.type._render);
1120
1121 case ClassComponent:
1122 return describeClassComponentFrame(fiber.type);
1123
1124 default:
1125 return '';
1126 }
1127 }
1128
1129 function getStackByFiberInDevAndProd(workInProgress) {
1130 try {
1131 var info = '';
1132 var node = workInProgress;
1133
1134 do {
1135 info += describeFiber(node);
1136 node = node.return;
1137 } while (node);
1138
1139 return info;
1140 } catch (x) {
1141 return '\nError generating stack: ' + x.message + '\n' + x.stack;
1142 }
1143 }
1144
1145 function getWrappedName(outerType, innerType, wrapperName) {
1146 var functionName = innerType.displayName || innerType.name || '';
1147 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
1148 }
1149
1150 function getContextName(type) {
1151 return type.displayName || 'Context';
1152 }
1153
1154 function getComponentName(type) {
1155 if (type == null) {
1156 // Host root, text node or just invalid type.
1157 return null;
1158 }
1159
1160 {
1161 if (typeof type.tag === 'number') {
1162 error('Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
1163 }
1164 }
1165
1166 if (typeof type === 'function') {
1167 return type.displayName || type.name || null;
1168 }
1169
1170 if (typeof type === 'string') {
1171 return type;
1172 }
1173
1174 switch (type) {
1175 case REACT_FRAGMENT_TYPE:
1176 return 'Fragment';
1177
1178 case REACT_PORTAL_TYPE:
1179 return 'Portal';
1180
1181 case REACT_PROFILER_TYPE:
1182 return 'Profiler';
1183
1184 case REACT_STRICT_MODE_TYPE:
1185 return 'StrictMode';
1186
1187 case REACT_SUSPENSE_TYPE:
1188 return 'Suspense';
1189
1190 case REACT_SUSPENSE_LIST_TYPE:
1191 return 'SuspenseList';
1192 }
1193
1194 if (typeof type === 'object') {
1195 switch (type.$$typeof) {
1196 case REACT_CONTEXT_TYPE:
1197 var context = type;
1198 return getContextName(context) + '.Consumer';
1199
1200 case REACT_PROVIDER_TYPE:
1201 var provider = type;
1202 return getContextName(provider._context) + '.Provider';
1203
1204 case REACT_FORWARD_REF_TYPE:
1205 return getWrappedName(type, type.render, 'ForwardRef');
1206
1207 case REACT_MEMO_TYPE:
1208 return getComponentName(type.type);
1209
1210 case REACT_BLOCK_TYPE:
1211 return getComponentName(type._render);
1212
1213 case REACT_LAZY_TYPE:
1214 {
1215 var lazyComponent = type;
1216 var payload = lazyComponent._payload;
1217 var init = lazyComponent._init;
1218
1219 try {
1220 return getComponentName(init(payload));
1221 } catch (x) {
1222 return null;
1223 }
1224 }
1225 }
1226 }
1227
1228 return null;
1229 }
1230
1231 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
1232 var current = null;
1233 var isRendering = false;
1234 function getCurrentFiberOwnerNameInDevOrNull() {
1235 {
1236 if (current === null) {
1237 return null;
1238 }
1239
1240 var owner = current._debugOwner;
1241
1242 if (owner !== null && typeof owner !== 'undefined') {
1243 return getComponentName(owner.type);
1244 }
1245 }
1246
1247 return null;
1248 }
1249
1250 function getCurrentFiberStackInDev() {
1251 {
1252 if (current === null) {
1253 return '';
1254 } // Safe because if current fiber exists, we are reconciling,
1255 // and it is guaranteed to be the work-in-progress version.
1256
1257
1258 return getStackByFiberInDevAndProd(current);
1259 }
1260 }
1261
1262 function resetCurrentFiber() {
1263 {
1264 ReactDebugCurrentFrame.getCurrentStack = null;
1265 current = null;
1266 isRendering = false;
1267 }
1268 }
1269 function setCurrentFiber(fiber) {
1270 {
1271 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
1272 current = fiber;
1273 isRendering = false;
1274 }
1275 }
1276 function setIsRendering(rendering) {
1277 {
1278 isRendering = rendering;
1279 }
1280 }
1281 function getIsRendering() {
1282 {
1283 return isRendering;
1284 }
1285 }
1286
1287 // Flow does not allow string concatenation of most non-string types. To work
1288 // around this limitation, we use an opaque type that can only be obtained by
1289 // passing the value through getToStringValue first.
1290 function toString(value) {
1291 return '' + value;
1292 }
1293 function getToStringValue(value) {
1294 switch (typeof value) {
1295 case 'boolean':
1296 case 'number':
1297 case 'object':
1298 case 'string':
1299 case 'undefined':
1300 return value;
1301
1302 default:
1303 // function, symbol are assigned as empty strings
1304 return '';
1305 }
1306 }
1307
1308 var hasReadOnlyValue = {
1309 button: true,
1310 checkbox: true,
1311 image: true,
1312 hidden: true,
1313 radio: true,
1314 reset: true,
1315 submit: true
1316 };
1317 function checkControlledValueProps(tagName, props) {
1318 {
1319 if (!(hasReadOnlyValue[props.type] || props.onChange || props.onInput || props.readOnly || props.disabled || props.value == null)) {
1320 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`.');
1321 }
1322
1323 if (!(props.onChange || props.readOnly || props.disabled || props.checked == null)) {
1324 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`.');
1325 }
1326 }
1327 }
1328
1329 function isCheckable(elem) {
1330 var type = elem.type;
1331 var nodeName = elem.nodeName;
1332 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
1333 }
1334
1335 function getTracker(node) {
1336 return node._valueTracker;
1337 }
1338
1339 function detachTracker(node) {
1340 node._valueTracker = null;
1341 }
1342
1343 function getValueFromNode(node) {
1344 var value = '';
1345
1346 if (!node) {
1347 return value;
1348 }
1349
1350 if (isCheckable(node)) {
1351 value = node.checked ? 'true' : 'false';
1352 } else {
1353 value = node.value;
1354 }
1355
1356 return value;
1357 }
1358
1359 function trackValueOnNode(node) {
1360 var valueField = isCheckable(node) ? 'checked' : 'value';
1361 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
1362 var currentValue = '' + node[valueField]; // if someone has already defined a value or Safari, then bail
1363 // and don't track value will cause over reporting of changes,
1364 // but it's better then a hard failure
1365 // (needed for certain tests that spyOn input values and Safari)
1366
1367 if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
1368 return;
1369 }
1370
1371 var get = descriptor.get,
1372 set = descriptor.set;
1373 Object.defineProperty(node, valueField, {
1374 configurable: true,
1375 get: function () {
1376 return get.call(this);
1377 },
1378 set: function (value) {
1379 currentValue = '' + value;
1380 set.call(this, value);
1381 }
1382 }); // We could've passed this the first time
1383 // but it triggers a bug in IE11 and Edge 14/15.
1384 // Calling defineProperty() again should be equivalent.
1385 // https://github.com/facebook/react/issues/11768
1386
1387 Object.defineProperty(node, valueField, {
1388 enumerable: descriptor.enumerable
1389 });
1390 var tracker = {
1391 getValue: function () {
1392 return currentValue;
1393 },
1394 setValue: function (value) {
1395 currentValue = '' + value;
1396 },
1397 stopTracking: function () {
1398 detachTracker(node);
1399 delete node[valueField];
1400 }
1401 };
1402 return tracker;
1403 }
1404
1405 function track(node) {
1406 if (getTracker(node)) {
1407 return;
1408 } // TODO: Once it's just Fiber we can move this to node._wrapperState
1409
1410
1411 node._valueTracker = trackValueOnNode(node);
1412 }
1413 function updateValueIfChanged(node) {
1414 if (!node) {
1415 return false;
1416 }
1417
1418 var tracker = getTracker(node); // if there is no tracker at this point it's unlikely
1419 // that trying again will succeed
1420
1421 if (!tracker) {
1422 return true;
1423 }
1424
1425 var lastValue = tracker.getValue();
1426 var nextValue = getValueFromNode(node);
1427
1428 if (nextValue !== lastValue) {
1429 tracker.setValue(nextValue);
1430 return true;
1431 }
1432
1433 return false;
1434 }
1435
1436 function getActiveElement(doc) {
1437 doc = doc || (typeof document !== 'undefined' ? document : undefined);
1438
1439 if (typeof doc === 'undefined') {
1440 return null;
1441 }
1442
1443 try {
1444 return doc.activeElement || doc.body;
1445 } catch (e) {
1446 return doc.body;
1447 }
1448 }
1449
1450 var didWarnValueDefaultValue = false;
1451 var didWarnCheckedDefaultChecked = false;
1452 var didWarnControlledToUncontrolled = false;
1453 var didWarnUncontrolledToControlled = false;
1454
1455 function isControlled(props) {
1456 var usesChecked = props.type === 'checkbox' || props.type === 'radio';
1457 return usesChecked ? props.checked != null : props.value != null;
1458 }
1459 /**
1460 * Implements an <input> host component that allows setting these optional
1461 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
1462 *
1463 * If `checked` or `value` are not supplied (or null/undefined), user actions
1464 * that affect the checked state or value will trigger updates to the element.
1465 *
1466 * If they are supplied (and not null/undefined), the rendered element will not
1467 * trigger updates to the element. Instead, the props must change in order for
1468 * the rendered element to be updated.
1469 *
1470 * The rendered element will be initialized as unchecked (or `defaultChecked`)
1471 * with an empty value (or `defaultValue`).
1472 *
1473 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
1474 */
1475
1476
1477 function getHostProps(element, props) {
1478 var node = element;
1479 var checked = props.checked;
1480
1481 var hostProps = _assign({}, props, {
1482 defaultChecked: undefined,
1483 defaultValue: undefined,
1484 value: undefined,
1485 checked: checked != null ? checked : node._wrapperState.initialChecked
1486 });
1487
1488 return hostProps;
1489 }
1490 function initWrapperState(element, props) {
1491 {
1492 checkControlledValueProps('input', props);
1493
1494 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
1495 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);
1496
1497 didWarnCheckedDefaultChecked = true;
1498 }
1499
1500 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
1501 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);
1502
1503 didWarnValueDefaultValue = true;
1504 }
1505 }
1506
1507 var node = element;
1508 var defaultValue = props.defaultValue == null ? '' : props.defaultValue;
1509 node._wrapperState = {
1510 initialChecked: props.checked != null ? props.checked : props.defaultChecked,
1511 initialValue: getToStringValue(props.value != null ? props.value : defaultValue),
1512 controlled: isControlled(props)
1513 };
1514 }
1515 function updateChecked(element, props) {
1516 var node = element;
1517 var checked = props.checked;
1518
1519 if (checked != null) {
1520 setValueForProperty(node, 'checked', checked, false);
1521 }
1522 }
1523 function updateWrapper(element, props) {
1524 var node = element;
1525
1526 {
1527 var controlled = isControlled(props);
1528
1529 if (!node._wrapperState.controlled && controlled && !didWarnUncontrolledToControlled) {
1530 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');
1531
1532 didWarnUncontrolledToControlled = true;
1533 }
1534
1535 if (node._wrapperState.controlled && !controlled && !didWarnControlledToUncontrolled) {
1536 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');
1537
1538 didWarnControlledToUncontrolled = true;
1539 }
1540 }
1541
1542 updateChecked(element, props);
1543 var value = getToStringValue(props.value);
1544 var type = props.type;
1545
1546 if (value != null) {
1547 if (type === 'number') {
1548 if (value === 0 && node.value === '' || // We explicitly want to coerce to number here if possible.
1549 // eslint-disable-next-line
1550 node.value != value) {
1551 node.value = toString(value);
1552 }
1553 } else if (node.value !== toString(value)) {
1554 node.value = toString(value);
1555 }
1556 } else if (type === 'submit' || type === 'reset') {
1557 // Submit/reset inputs need the attribute removed completely to avoid
1558 // blank-text buttons.
1559 node.removeAttribute('value');
1560 return;
1561 }
1562
1563 {
1564 // When syncing the value attribute, the value comes from a cascade of
1565 // properties:
1566 // 1. The value React property
1567 // 2. The defaultValue React property
1568 // 3. Otherwise there should be no change
1569 if (props.hasOwnProperty('value')) {
1570 setDefaultValue(node, props.type, value);
1571 } else if (props.hasOwnProperty('defaultValue')) {
1572 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
1573 }
1574 }
1575
1576 {
1577 // When syncing the checked attribute, it only changes when it needs
1578 // to be removed, such as transitioning from a checkbox into a text input
1579 if (props.checked == null && props.defaultChecked != null) {
1580 node.defaultChecked = !!props.defaultChecked;
1581 }
1582 }
1583 }
1584 function postMountWrapper(element, props, isHydrating) {
1585 var node = element; // Do not assign value if it is already set. This prevents user text input
1586 // from being lost during SSR hydration.
1587
1588 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
1589 var type = props.type;
1590 var isButton = type === 'submit' || type === 'reset'; // Avoid setting value attribute on submit/reset inputs as it overrides the
1591 // default value provided by the browser. See: #12872
1592
1593 if (isButton && (props.value === undefined || props.value === null)) {
1594 return;
1595 }
1596
1597 var initialValue = toString(node._wrapperState.initialValue); // Do not assign value if it is already set. This prevents user text input
1598 // from being lost during SSR hydration.
1599
1600 if (!isHydrating) {
1601 {
1602 // When syncing the value attribute, the value property should use
1603 // the wrapperState._initialValue property. This uses:
1604 //
1605 // 1. The value React property when present
1606 // 2. The defaultValue React property when present
1607 // 3. An empty string
1608 if (initialValue !== node.value) {
1609 node.value = initialValue;
1610 }
1611 }
1612 }
1613
1614 {
1615 // Otherwise, the value attribute is synchronized to the property,
1616 // so we assign defaultValue to the same thing as the value property
1617 // assignment step above.
1618 node.defaultValue = initialValue;
1619 }
1620 } // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
1621 // this is needed to work around a chrome bug where setting defaultChecked
1622 // will sometimes influence the value of checked (even after detachment).
1623 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
1624 // We need to temporarily unset name to avoid disrupting radio button groups.
1625
1626
1627 var name = node.name;
1628
1629 if (name !== '') {
1630 node.name = '';
1631 }
1632
1633 {
1634 // When syncing the checked attribute, both the checked property and
1635 // attribute are assigned at the same time using defaultChecked. This uses:
1636 //
1637 // 1. The checked React property when present
1638 // 2. The defaultChecked React property when present
1639 // 3. Otherwise, false
1640 node.defaultChecked = !node.defaultChecked;
1641 node.defaultChecked = !!node._wrapperState.initialChecked;
1642 }
1643
1644 if (name !== '') {
1645 node.name = name;
1646 }
1647 }
1648 function restoreControlledState(element, props) {
1649 var node = element;
1650 updateWrapper(node, props);
1651 updateNamedCousins(node, props);
1652 }
1653
1654 function updateNamedCousins(rootNode, props) {
1655 var name = props.name;
1656
1657 if (props.type === 'radio' && name != null) {
1658 var queryRoot = rootNode;
1659
1660 while (queryRoot.parentNode) {
1661 queryRoot = queryRoot.parentNode;
1662 } // If `rootNode.form` was non-null, then we could try `form.elements`,
1663 // but that sometimes behaves strangely in IE8. We could also try using
1664 // `form.getElementsByName`, but that will only return direct children
1665 // and won't include inputs that use the HTML5 `form=` attribute. Since
1666 // the input might not even be in a form. It might not even be in the
1667 // document. Let's just use the local `querySelectorAll` to ensure we don't
1668 // miss anything.
1669
1670
1671 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
1672
1673 for (var i = 0; i < group.length; i++) {
1674 var otherNode = group[i];
1675
1676 if (otherNode === rootNode || otherNode.form !== rootNode.form) {
1677 continue;
1678 } // This will throw if radio buttons rendered by different copies of React
1679 // and the same name are rendered into the same form (same as #1939).
1680 // That's probably okay; we don't support it just as we don't support
1681 // mixing React radio buttons with non-React ones.
1682
1683
1684 var otherProps = getFiberCurrentPropsFromNode(otherNode);
1685
1686 if (!otherProps) {
1687 {
1688 throw Error( "ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported." );
1689 }
1690 } // We need update the tracked value on the named cousin since the value
1691 // was changed but the input saw no event or value set
1692
1693
1694 updateValueIfChanged(otherNode); // If this is a controlled radio button group, forcing the input that
1695 // was previously checked to update will cause it to be come re-checked
1696 // as appropriate.
1697
1698 updateWrapper(otherNode, otherProps);
1699 }
1700 }
1701 } // In Chrome, assigning defaultValue to certain input types triggers input validation.
1702 // For number inputs, the display value loses trailing decimal points. For email inputs,
1703 // Chrome raises "The specified value <x> is not a valid email address".
1704 //
1705 // Here we check to see if the defaultValue has actually changed, avoiding these problems
1706 // when the user is inputting text
1707 //
1708 // https://github.com/facebook/react/issues/7253
1709
1710
1711 function setDefaultValue(node, type, value) {
1712 if ( // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
1713 type !== 'number' || getActiveElement(node.ownerDocument) !== node) {
1714 if (value == null) {
1715 node.defaultValue = toString(node._wrapperState.initialValue);
1716 } else if (node.defaultValue !== toString(value)) {
1717 node.defaultValue = toString(value);
1718 }
1719 }
1720 }
1721
1722 var didWarnSelectedSetOnOption = false;
1723 var didWarnInvalidChild = false;
1724
1725 function flattenChildren(children) {
1726 var content = ''; // Flatten children. We'll warn if they are invalid
1727 // during validateProps() which runs for hydration too.
1728 // Note that this would throw on non-element objects.
1729 // Elements are stringified (which is normally irrelevant
1730 // but matters for <fbt>).
1731
1732 React.Children.forEach(children, function (child) {
1733 if (child == null) {
1734 return;
1735 }
1736
1737 content += child; // Note: we don't warn about invalid children here.
1738 // Instead, this is done separately below so that
1739 // it happens during the hydration code path too.
1740 });
1741 return content;
1742 }
1743 /**
1744 * Implements an <option> host component that warns when `selected` is set.
1745 */
1746
1747
1748 function validateProps(element, props) {
1749 {
1750 // This mirrors the code path above, but runs for hydration too.
1751 // Warn about invalid children here so that client and hydration are consistent.
1752 // TODO: this seems like it could cause a DEV-only throw for hydration
1753 // if children contains a non-element object. We should try to avoid that.
1754 if (typeof props.children === 'object' && props.children !== null) {
1755 React.Children.forEach(props.children, function (child) {
1756 if (child == null) {
1757 return;
1758 }
1759
1760 if (typeof child === 'string' || typeof child === 'number') {
1761 return;
1762 }
1763
1764 if (typeof child.type !== 'string') {
1765 return;
1766 }
1767
1768 if (!didWarnInvalidChild) {
1769 didWarnInvalidChild = true;
1770
1771 error('Only strings and numbers are supported as <option> children.');
1772 }
1773 });
1774 } // TODO: Remove support for `selected` in <option>.
1775
1776
1777 if (props.selected != null && !didWarnSelectedSetOnOption) {
1778 error('Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
1779
1780 didWarnSelectedSetOnOption = true;
1781 }
1782 }
1783 }
1784 function postMountWrapper$1(element, props) {
1785 // value="" should make a value attribute (#6219)
1786 if (props.value != null) {
1787 element.setAttribute('value', toString(getToStringValue(props.value)));
1788 }
1789 }
1790 function getHostProps$1(element, props) {
1791 var hostProps = _assign({
1792 children: undefined
1793 }, props);
1794
1795 var content = flattenChildren(props.children);
1796
1797 if (content) {
1798 hostProps.children = content;
1799 }
1800
1801 return hostProps;
1802 }
1803
1804 var didWarnValueDefaultValue$1;
1805
1806 {
1807 didWarnValueDefaultValue$1 = false;
1808 }
1809
1810 function getDeclarationErrorAddendum() {
1811 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
1812
1813 if (ownerName) {
1814 return '\n\nCheck the render method of `' + ownerName + '`.';
1815 }
1816
1817 return '';
1818 }
1819
1820 var valuePropNames = ['value', 'defaultValue'];
1821 /**
1822 * Validation function for `value` and `defaultValue`.
1823 */
1824
1825 function checkSelectPropTypes(props) {
1826 {
1827 checkControlledValueProps('select', props);
1828
1829 for (var i = 0; i < valuePropNames.length; i++) {
1830 var propName = valuePropNames[i];
1831
1832 if (props[propName] == null) {
1833 continue;
1834 }
1835
1836 var isArray = Array.isArray(props[propName]);
1837
1838 if (props.multiple && !isArray) {
1839 error('The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
1840 } else if (!props.multiple && isArray) {
1841 error('The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
1842 }
1843 }
1844 }
1845 }
1846
1847 function updateOptions(node, multiple, propValue, setDefaultSelected) {
1848 var options = node.options;
1849
1850 if (multiple) {
1851 var selectedValues = propValue;
1852 var selectedValue = {};
1853
1854 for (var i = 0; i < selectedValues.length; i++) {
1855 // Prefix to avoid chaos with special keys.
1856 selectedValue['$' + selectedValues[i]] = true;
1857 }
1858
1859 for (var _i = 0; _i < options.length; _i++) {
1860 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
1861
1862 if (options[_i].selected !== selected) {
1863 options[_i].selected = selected;
1864 }
1865
1866 if (selected && setDefaultSelected) {
1867 options[_i].defaultSelected = true;
1868 }
1869 }
1870 } else {
1871 // Do not set `select.value` as exact behavior isn't consistent across all
1872 // browsers for all cases.
1873 var _selectedValue = toString(getToStringValue(propValue));
1874
1875 var defaultSelected = null;
1876
1877 for (var _i2 = 0; _i2 < options.length; _i2++) {
1878 if (options[_i2].value === _selectedValue) {
1879 options[_i2].selected = true;
1880
1881 if (setDefaultSelected) {
1882 options[_i2].defaultSelected = true;
1883 }
1884
1885 return;
1886 }
1887
1888 if (defaultSelected === null && !options[_i2].disabled) {
1889 defaultSelected = options[_i2];
1890 }
1891 }
1892
1893 if (defaultSelected !== null) {
1894 defaultSelected.selected = true;
1895 }
1896 }
1897 }
1898 /**
1899 * Implements a <select> host component that allows optionally setting the
1900 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
1901 * stringable. If `multiple` is true, the prop must be an array of stringables.
1902 *
1903 * If `value` is not supplied (or null/undefined), user actions that change the
1904 * selected option will trigger updates to the rendered options.
1905 *
1906 * If it is supplied (and not null/undefined), the rendered options will not
1907 * update in response to user actions. Instead, the `value` prop must change in
1908 * order for the rendered options to update.
1909 *
1910 * If `defaultValue` is provided, any options with the supplied values will be
1911 * selected.
1912 */
1913
1914
1915 function getHostProps$2(element, props) {
1916 return _assign({}, props, {
1917 value: undefined
1918 });
1919 }
1920 function initWrapperState$1(element, props) {
1921 var node = element;
1922
1923 {
1924 checkSelectPropTypes(props);
1925 }
1926
1927 node._wrapperState = {
1928 wasMultiple: !!props.multiple
1929 };
1930
1931 {
1932 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
1933 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');
1934
1935 didWarnValueDefaultValue$1 = true;
1936 }
1937 }
1938 }
1939 function postMountWrapper$2(element, props) {
1940 var node = element;
1941 node.multiple = !!props.multiple;
1942 var value = props.value;
1943
1944 if (value != null) {
1945 updateOptions(node, !!props.multiple, value, false);
1946 } else if (props.defaultValue != null) {
1947 updateOptions(node, !!props.multiple, props.defaultValue, true);
1948 }
1949 }
1950 function postUpdateWrapper(element, props) {
1951 var node = element;
1952 var wasMultiple = node._wrapperState.wasMultiple;
1953 node._wrapperState.wasMultiple = !!props.multiple;
1954 var value = props.value;
1955
1956 if (value != null) {
1957 updateOptions(node, !!props.multiple, value, false);
1958 } else if (wasMultiple !== !!props.multiple) {
1959 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
1960 if (props.defaultValue != null) {
1961 updateOptions(node, !!props.multiple, props.defaultValue, true);
1962 } else {
1963 // Revert the select back to its default unselected state.
1964 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
1965 }
1966 }
1967 }
1968 function restoreControlledState$1(element, props) {
1969 var node = element;
1970 var value = props.value;
1971
1972 if (value != null) {
1973 updateOptions(node, !!props.multiple, value, false);
1974 }
1975 }
1976
1977 var didWarnValDefaultVal = false;
1978
1979 /**
1980 * Implements a <textarea> host component that allows setting `value`, and
1981 * `defaultValue`. This differs from the traditional DOM API because value is
1982 * usually set as PCDATA children.
1983 *
1984 * If `value` is not supplied (or null/undefined), user actions that affect the
1985 * value will trigger updates to the element.
1986 *
1987 * If `value` is supplied (and not null/undefined), the rendered element will
1988 * not trigger updates to the element. Instead, the `value` prop must change in
1989 * order for the rendered element to be updated.
1990 *
1991 * The rendered element will be initialized with an empty value, the prop
1992 * `defaultValue` if specified, or the children content (deprecated).
1993 */
1994 function getHostProps$3(element, props) {
1995 var node = element;
1996
1997 if (!(props.dangerouslySetInnerHTML == null)) {
1998 {
1999 throw Error( "`dangerouslySetInnerHTML` does not make sense on <textarea>." );
2000 }
2001 } // Always set children to the same thing. In IE9, the selection range will
2002 // get reset if `textContent` is mutated. We could add a check in setTextContent
2003 // to only set the value if/when the value differs from the node value (which would
2004 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
2005 // solution. The value can be a boolean or object so that's why it's forced
2006 // to be a string.
2007
2008
2009 var hostProps = _assign({}, props, {
2010 value: undefined,
2011 defaultValue: undefined,
2012 children: toString(node._wrapperState.initialValue)
2013 });
2014
2015 return hostProps;
2016 }
2017 function initWrapperState$2(element, props) {
2018 var node = element;
2019
2020 {
2021 checkControlledValueProps('textarea', props);
2022
2023 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
2024 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');
2025
2026 didWarnValDefaultVal = true;
2027 }
2028 }
2029
2030 var initialValue = props.value; // Only bother fetching default value if we're going to use it
2031
2032 if (initialValue == null) {
2033 var children = props.children,
2034 defaultValue = props.defaultValue;
2035
2036 if (children != null) {
2037 {
2038 error('Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
2039 }
2040
2041 {
2042 if (!(defaultValue == null)) {
2043 {
2044 throw Error( "If you supply `defaultValue` on a <textarea>, do not pass children." );
2045 }
2046 }
2047
2048 if (Array.isArray(children)) {
2049 if (!(children.length <= 1)) {
2050 {
2051 throw Error( "<textarea> can only have at most one child." );
2052 }
2053 }
2054
2055 children = children[0];
2056 }
2057
2058 defaultValue = children;
2059 }
2060 }
2061
2062 if (defaultValue == null) {
2063 defaultValue = '';
2064 }
2065
2066 initialValue = defaultValue;
2067 }
2068
2069 node._wrapperState = {
2070 initialValue: getToStringValue(initialValue)
2071 };
2072 }
2073 function updateWrapper$1(element, props) {
2074 var node = element;
2075 var value = getToStringValue(props.value);
2076 var defaultValue = getToStringValue(props.defaultValue);
2077
2078 if (value != null) {
2079 // Cast `value` to a string to ensure the value is set correctly. While
2080 // browsers typically do this as necessary, jsdom doesn't.
2081 var newValue = toString(value); // To avoid side effects (such as losing text selection), only set value if changed
2082
2083 if (newValue !== node.value) {
2084 node.value = newValue;
2085 }
2086
2087 if (props.defaultValue == null && node.defaultValue !== newValue) {
2088 node.defaultValue = newValue;
2089 }
2090 }
2091
2092 if (defaultValue != null) {
2093 node.defaultValue = toString(defaultValue);
2094 }
2095 }
2096 function postMountWrapper$3(element, props) {
2097 var node = element; // This is in postMount because we need access to the DOM node, which is not
2098 // available until after the component has mounted.
2099
2100 var textContent = node.textContent; // Only set node.value if textContent is equal to the expected
2101 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
2102 // will populate textContent as well.
2103 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
2104
2105 if (textContent === node._wrapperState.initialValue) {
2106 if (textContent !== '' && textContent !== null) {
2107 node.value = textContent;
2108 }
2109 }
2110 }
2111 function restoreControlledState$2(element, props) {
2112 // DOM component is still mounted; update
2113 updateWrapper$1(element, props);
2114 }
2115
2116 var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
2117 var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
2118 var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
2119 var Namespaces = {
2120 html: HTML_NAMESPACE,
2121 mathml: MATH_NAMESPACE,
2122 svg: SVG_NAMESPACE
2123 }; // Assumes there is no parent namespace.
2124
2125 function getIntrinsicNamespace(type) {
2126 switch (type) {
2127 case 'svg':
2128 return SVG_NAMESPACE;
2129
2130 case 'math':
2131 return MATH_NAMESPACE;
2132
2133 default:
2134 return HTML_NAMESPACE;
2135 }
2136 }
2137 function getChildNamespace(parentNamespace, type) {
2138 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE) {
2139 // No (or default) parent namespace: potential entry point.
2140 return getIntrinsicNamespace(type);
2141 }
2142
2143 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
2144 // We're leaving SVG.
2145 return HTML_NAMESPACE;
2146 } // By default, pass namespace below.
2147
2148
2149 return parentNamespace;
2150 }
2151
2152 /* globals MSApp */
2153
2154 /**
2155 * Create a function which has 'unsafe' privileges (required by windows8 apps)
2156 */
2157 var createMicrosoftUnsafeLocalFunction = function (func) {
2158 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
2159 return function (arg0, arg1, arg2, arg3) {
2160 MSApp.execUnsafeLocalFunction(function () {
2161 return func(arg0, arg1, arg2, arg3);
2162 });
2163 };
2164 } else {
2165 return func;
2166 }
2167 };
2168
2169 var reusableSVGContainer;
2170 /**
2171 * Set the innerHTML property of a node
2172 *
2173 * @param {DOMElement} node
2174 * @param {string} html
2175 * @internal
2176 */
2177
2178 var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
2179 if (node.namespaceURI === Namespaces.svg) {
2180
2181 if (!('innerHTML' in node)) {
2182 // IE does not have innerHTML for SVG nodes, so instead we inject the
2183 // new markup in a temp node and then move the child nodes across into
2184 // the target node
2185 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
2186 reusableSVGContainer.innerHTML = '<svg>' + html.valueOf().toString() + '</svg>';
2187 var svgNode = reusableSVGContainer.firstChild;
2188
2189 while (node.firstChild) {
2190 node.removeChild(node.firstChild);
2191 }
2192
2193 while (svgNode.firstChild) {
2194 node.appendChild(svgNode.firstChild);
2195 }
2196
2197 return;
2198 }
2199 }
2200
2201 node.innerHTML = html;
2202 });
2203
2204 /**
2205 * HTML nodeType values that represent the type of the node
2206 */
2207 var ELEMENT_NODE = 1;
2208 var TEXT_NODE = 3;
2209 var COMMENT_NODE = 8;
2210 var DOCUMENT_NODE = 9;
2211 var DOCUMENT_FRAGMENT_NODE = 11;
2212
2213 /**
2214 * Set the textContent property of a node. For text updates, it's faster
2215 * to set the `nodeValue` of the Text node directly instead of using
2216 * `.textContent` which will remove the existing node and create a new one.
2217 *
2218 * @param {DOMElement} node
2219 * @param {string} text
2220 * @internal
2221 */
2222
2223 var setTextContent = function (node, text) {
2224 if (text) {
2225 var firstChild = node.firstChild;
2226
2227 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
2228 firstChild.nodeValue = text;
2229 return;
2230 }
2231 }
2232
2233 node.textContent = text;
2234 };
2235
2236 // List derived from Gecko source code:
2237 // https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js
2238 var shorthandToLonghand = {
2239 animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'],
2240 background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'],
2241 backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'],
2242 border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'],
2243 borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'],
2244 borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'],
2245 borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'],
2246 borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'],
2247 borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'],
2248 borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'],
2249 borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'],
2250 borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'],
2251 borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'],
2252 borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'],
2253 borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'],
2254 borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'],
2255 borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'],
2256 columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'],
2257 columns: ['columnCount', 'columnWidth'],
2258 flex: ['flexBasis', 'flexGrow', 'flexShrink'],
2259 flexFlow: ['flexDirection', 'flexWrap'],
2260 font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'],
2261 fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'],
2262 gap: ['columnGap', 'rowGap'],
2263 grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
2264 gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'],
2265 gridColumn: ['gridColumnEnd', 'gridColumnStart'],
2266 gridColumnGap: ['columnGap'],
2267 gridGap: ['columnGap', 'rowGap'],
2268 gridRow: ['gridRowEnd', 'gridRowStart'],
2269 gridRowGap: ['rowGap'],
2270 gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
2271 listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'],
2272 margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'],
2273 marker: ['markerEnd', 'markerMid', 'markerStart'],
2274 mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'],
2275 maskPosition: ['maskPositionX', 'maskPositionY'],
2276 outline: ['outlineColor', 'outlineStyle', 'outlineWidth'],
2277 overflow: ['overflowX', 'overflowY'],
2278 padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'],
2279 placeContent: ['alignContent', 'justifyContent'],
2280 placeItems: ['alignItems', 'justifyItems'],
2281 placeSelf: ['alignSelf', 'justifySelf'],
2282 textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'],
2283 textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'],
2284 transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'],
2285 wordWrap: ['overflowWrap']
2286 };
2287
2288 /**
2289 * CSS properties which accept numbers but are not in units of "px".
2290 */
2291 var isUnitlessNumber = {
2292 animationIterationCount: true,
2293 borderImageOutset: true,
2294 borderImageSlice: true,
2295 borderImageWidth: true,
2296 boxFlex: true,
2297 boxFlexGroup: true,
2298 boxOrdinalGroup: true,
2299 columnCount: true,
2300 columns: true,
2301 flex: true,
2302 flexGrow: true,
2303 flexPositive: true,
2304 flexShrink: true,
2305 flexNegative: true,
2306 flexOrder: true,
2307 gridArea: true,
2308 gridRow: true,
2309 gridRowEnd: true,
2310 gridRowSpan: true,
2311 gridRowStart: true,
2312 gridColumn: true,
2313 gridColumnEnd: true,
2314 gridColumnSpan: true,
2315 gridColumnStart: true,
2316 fontWeight: true,
2317 lineClamp: true,
2318 lineHeight: true,
2319 opacity: true,
2320 order: true,
2321 orphans: true,
2322 tabSize: true,
2323 widows: true,
2324 zIndex: true,
2325 zoom: true,
2326 // SVG-related properties
2327 fillOpacity: true,
2328 floodOpacity: true,
2329 stopOpacity: true,
2330 strokeDasharray: true,
2331 strokeDashoffset: true,
2332 strokeMiterlimit: true,
2333 strokeOpacity: true,
2334 strokeWidth: true
2335 };
2336 /**
2337 * @param {string} prefix vendor-specific prefix, eg: Webkit
2338 * @param {string} key style name, eg: transitionDuration
2339 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
2340 * WebkitTransitionDuration
2341 */
2342
2343 function prefixKey(prefix, key) {
2344 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
2345 }
2346 /**
2347 * Support style names that may come passed in prefixed by adding permutations
2348 * of vendor prefixes.
2349 */
2350
2351
2352 var prefixes = ['Webkit', 'ms', 'Moz', 'O']; // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
2353 // infinite loop, because it iterates over the newly added props too.
2354
2355 Object.keys(isUnitlessNumber).forEach(function (prop) {
2356 prefixes.forEach(function (prefix) {
2357 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
2358 });
2359 });
2360
2361 /**
2362 * Convert a value into the proper css writable value. The style name `name`
2363 * should be logical (no hyphens), as specified
2364 * in `CSSProperty.isUnitlessNumber`.
2365 *
2366 * @param {string} name CSS property name such as `topMargin`.
2367 * @param {*} value CSS property value such as `10px`.
2368 * @return {string} Normalized style value with dimensions applied.
2369 */
2370
2371 function dangerousStyleValue(name, value, isCustomProperty) {
2372 // Note that we've removed escapeTextForBrowser() calls here since the
2373 // whole string will be escaped when the attribute is injected into
2374 // the markup. If you provide unsafe user data here they can inject
2375 // arbitrary CSS which may be problematic (I couldn't repro this):
2376 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
2377 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
2378 // This is not an XSS hole but instead a potential CSS injection issue
2379 // which has lead to a greater discussion about how we're going to
2380 // trust URLs moving forward. See #2115901
2381 var isEmpty = value == null || typeof value === 'boolean' || value === '';
2382
2383 if (isEmpty) {
2384 return '';
2385 }
2386
2387 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
2388 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
2389 }
2390
2391 return ('' + value).trim();
2392 }
2393
2394 var uppercasePattern = /([A-Z])/g;
2395 var msPattern = /^ms-/;
2396 /**
2397 * Hyphenates a camelcased CSS property name, for example:
2398 *
2399 * > hyphenateStyleName('backgroundColor')
2400 * < "background-color"
2401 * > hyphenateStyleName('MozTransition')
2402 * < "-moz-transition"
2403 * > hyphenateStyleName('msTransition')
2404 * < "-ms-transition"
2405 *
2406 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
2407 * is converted to `-ms-`.
2408 */
2409
2410 function hyphenateStyleName(name) {
2411 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-');
2412 }
2413
2414 var warnValidStyle = function () {};
2415
2416 {
2417 // 'msTransform' is correct, but the other prefixes should be capitalized
2418 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
2419 var msPattern$1 = /^-ms-/;
2420 var hyphenPattern = /-(.)/g; // style values shouldn't contain a semicolon
2421
2422 var badStyleValueWithSemicolonPattern = /;\s*$/;
2423 var warnedStyleNames = {};
2424 var warnedStyleValues = {};
2425 var warnedForNaNValue = false;
2426 var warnedForInfinityValue = false;
2427
2428 var camelize = function (string) {
2429 return string.replace(hyphenPattern, function (_, character) {
2430 return character.toUpperCase();
2431 });
2432 };
2433
2434 var warnHyphenatedStyleName = function (name) {
2435 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
2436 return;
2437 }
2438
2439 warnedStyleNames[name] = true;
2440
2441 error('Unsupported style property %s. Did you mean %s?', name, // As Andi Smith suggests
2442 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
2443 // is converted to lowercase `ms`.
2444 camelize(name.replace(msPattern$1, 'ms-')));
2445 };
2446
2447 var warnBadVendoredStyleName = function (name) {
2448 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
2449 return;
2450 }
2451
2452 warnedStyleNames[name] = true;
2453
2454 error('Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1));
2455 };
2456
2457 var warnStyleValueWithSemicolon = function (name, value) {
2458 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
2459 return;
2460 }
2461
2462 warnedStyleValues[value] = true;
2463
2464 error("Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, ''));
2465 };
2466
2467 var warnStyleValueIsNaN = function (name, value) {
2468 if (warnedForNaNValue) {
2469 return;
2470 }
2471
2472 warnedForNaNValue = true;
2473
2474 error('`NaN` is an invalid value for the `%s` css style property.', name);
2475 };
2476
2477 var warnStyleValueIsInfinity = function (name, value) {
2478 if (warnedForInfinityValue) {
2479 return;
2480 }
2481
2482 warnedForInfinityValue = true;
2483
2484 error('`Infinity` is an invalid value for the `%s` css style property.', name);
2485 };
2486
2487 warnValidStyle = function (name, value) {
2488 if (name.indexOf('-') > -1) {
2489 warnHyphenatedStyleName(name);
2490 } else if (badVendoredStyleNamePattern.test(name)) {
2491 warnBadVendoredStyleName(name);
2492 } else if (badStyleValueWithSemicolonPattern.test(value)) {
2493 warnStyleValueWithSemicolon(name, value);
2494 }
2495
2496 if (typeof value === 'number') {
2497 if (isNaN(value)) {
2498 warnStyleValueIsNaN(name, value);
2499 } else if (!isFinite(value)) {
2500 warnStyleValueIsInfinity(name, value);
2501 }
2502 }
2503 };
2504 }
2505
2506 var warnValidStyle$1 = warnValidStyle;
2507
2508 /**
2509 * Operations for dealing with CSS properties.
2510 */
2511
2512 /**
2513 * This creates a string that is expected to be equivalent to the style
2514 * attribute generated by server-side rendering. It by-passes warnings and
2515 * security checks so it's not safe to use this value for anything other than
2516 * comparison. It is only used in DEV for SSR validation.
2517 */
2518
2519 function createDangerousStringForStyles(styles) {
2520 {
2521 var serialized = '';
2522 var delimiter = '';
2523
2524 for (var styleName in styles) {
2525 if (!styles.hasOwnProperty(styleName)) {
2526 continue;
2527 }
2528
2529 var styleValue = styles[styleName];
2530
2531 if (styleValue != null) {
2532 var isCustomProperty = styleName.indexOf('--') === 0;
2533 serialized += delimiter + (isCustomProperty ? styleName : hyphenateStyleName(styleName)) + ':';
2534 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
2535 delimiter = ';';
2536 }
2537 }
2538
2539 return serialized || null;
2540 }
2541 }
2542 /**
2543 * Sets the value for multiple styles on a node. If a value is specified as
2544 * '' (empty string), the corresponding style property will be unset.
2545 *
2546 * @param {DOMElement} node
2547 * @param {object} styles
2548 */
2549
2550 function setValueForStyles(node, styles) {
2551 var style = node.style;
2552
2553 for (var styleName in styles) {
2554 if (!styles.hasOwnProperty(styleName)) {
2555 continue;
2556 }
2557
2558 var isCustomProperty = styleName.indexOf('--') === 0;
2559
2560 {
2561 if (!isCustomProperty) {
2562 warnValidStyle$1(styleName, styles[styleName]);
2563 }
2564 }
2565
2566 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
2567
2568 if (styleName === 'float') {
2569 styleName = 'cssFloat';
2570 }
2571
2572 if (isCustomProperty) {
2573 style.setProperty(styleName, styleValue);
2574 } else {
2575 style[styleName] = styleValue;
2576 }
2577 }
2578 }
2579
2580 function isValueEmpty(value) {
2581 return value == null || typeof value === 'boolean' || value === '';
2582 }
2583 /**
2584 * Given {color: 'red', overflow: 'hidden'} returns {
2585 * color: 'color',
2586 * overflowX: 'overflow',
2587 * overflowY: 'overflow',
2588 * }. This can be read as "the overflowY property was set by the overflow
2589 * shorthand". That is, the values are the property that each was derived from.
2590 */
2591
2592
2593 function expandShorthandMap(styles) {
2594 var expanded = {};
2595
2596 for (var key in styles) {
2597 var longhands = shorthandToLonghand[key] || [key];
2598
2599 for (var i = 0; i < longhands.length; i++) {
2600 expanded[longhands[i]] = key;
2601 }
2602 }
2603
2604 return expanded;
2605 }
2606 /**
2607 * When mixing shorthand and longhand property names, we warn during updates if
2608 * we expect an incorrect result to occur. In particular, we warn for:
2609 *
2610 * Updating a shorthand property (longhand gets overwritten):
2611 * {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'}
2612 * becomes .style.font = 'baz'
2613 * Removing a shorthand property (longhand gets lost too):
2614 * {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'}
2615 * becomes .style.font = ''
2616 * Removing a longhand property (should revert to shorthand; doesn't):
2617 * {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'}
2618 * becomes .style.fontVariant = ''
2619 */
2620
2621
2622 function validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) {
2623 {
2624 if (!nextStyles) {
2625 return;
2626 }
2627
2628 var expandedUpdates = expandShorthandMap(styleUpdates);
2629 var expandedStyles = expandShorthandMap(nextStyles);
2630 var warnedAbout = {};
2631
2632 for (var key in expandedUpdates) {
2633 var originalKey = expandedUpdates[key];
2634 var correctOriginalKey = expandedStyles[key];
2635
2636 if (correctOriginalKey && originalKey !== correctOriginalKey) {
2637 var warningKey = originalKey + ',' + correctOriginalKey;
2638
2639 if (warnedAbout[warningKey]) {
2640 continue;
2641 }
2642
2643 warnedAbout[warningKey] = true;
2644
2645 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);
2646 }
2647 }
2648 }
2649 }
2650
2651 // For HTML, certain tags should omit their close tag. We keep a list for
2652 // those special-case tags.
2653 var omittedCloseTags = {
2654 area: true,
2655 base: true,
2656 br: true,
2657 col: true,
2658 embed: true,
2659 hr: true,
2660 img: true,
2661 input: true,
2662 keygen: true,
2663 link: true,
2664 meta: true,
2665 param: true,
2666 source: true,
2667 track: true,
2668 wbr: true // NOTE: menuitem's close tag should be omitted, but that causes problems.
2669
2670 };
2671
2672 // `omittedCloseTags` except that `menuitem` should still have its closing tag.
2673
2674 var voidElementTags = _assign({
2675 menuitem: true
2676 }, omittedCloseTags);
2677
2678 var HTML = '__html';
2679
2680 function assertValidProps(tag, props) {
2681 if (!props) {
2682 return;
2683 } // Note the use of `==` which checks for null or undefined.
2684
2685
2686 if (voidElementTags[tag]) {
2687 if (!(props.children == null && props.dangerouslySetInnerHTML == null)) {
2688 {
2689 throw Error( tag + " is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`." );
2690 }
2691 }
2692 }
2693
2694 if (props.dangerouslySetInnerHTML != null) {
2695 if (!(props.children == null)) {
2696 {
2697 throw Error( "Can only set one of `children` or `props.dangerouslySetInnerHTML`." );
2698 }
2699 }
2700
2701 if (!(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML)) {
2702 {
2703 throw Error( "`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://reactjs.org/link/dangerously-set-inner-html for more information." );
2704 }
2705 }
2706 }
2707
2708 {
2709 if (!props.suppressContentEditableWarning && props.contentEditable && props.children != null) {
2710 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.');
2711 }
2712 }
2713
2714 if (!(props.style == null || typeof props.style === 'object')) {
2715 {
2716 throw Error( "The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + 'em'}} when using JSX." );
2717 }
2718 }
2719 }
2720
2721 function isCustomComponent(tagName, props) {
2722 if (tagName.indexOf('-') === -1) {
2723 return typeof props.is === 'string';
2724 }
2725
2726 switch (tagName) {
2727 // These are reserved SVG and MathML elements.
2728 // We don't mind this list too much because we expect it to never grow.
2729 // The alternative is to track the namespace in a few places which is convoluted.
2730 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
2731 case 'annotation-xml':
2732 case 'color-profile':
2733 case 'font-face':
2734 case 'font-face-src':
2735 case 'font-face-uri':
2736 case 'font-face-format':
2737 case 'font-face-name':
2738 case 'missing-glyph':
2739 return false;
2740
2741 default:
2742 return true;
2743 }
2744 }
2745
2746 // When adding attributes to the HTML or SVG allowed attribute list, be sure to
2747 // also add them to this module to ensure casing and incorrect name
2748 // warnings.
2749 var possibleStandardNames = {
2750 // HTML
2751 accept: 'accept',
2752 acceptcharset: 'acceptCharset',
2753 'accept-charset': 'acceptCharset',
2754 accesskey: 'accessKey',
2755 action: 'action',
2756 allowfullscreen: 'allowFullScreen',
2757 alt: 'alt',
2758 as: 'as',
2759 async: 'async',
2760 autocapitalize: 'autoCapitalize',
2761 autocomplete: 'autoComplete',
2762 autocorrect: 'autoCorrect',
2763 autofocus: 'autoFocus',
2764 autoplay: 'autoPlay',
2765 autosave: 'autoSave',
2766 capture: 'capture',
2767 cellpadding: 'cellPadding',
2768 cellspacing: 'cellSpacing',
2769 challenge: 'challenge',
2770 charset: 'charSet',
2771 checked: 'checked',
2772 children: 'children',
2773 cite: 'cite',
2774 class: 'className',
2775 classid: 'classID',
2776 classname: 'className',
2777 cols: 'cols',
2778 colspan: 'colSpan',
2779 content: 'content',
2780 contenteditable: 'contentEditable',
2781 contextmenu: 'contextMenu',
2782 controls: 'controls',
2783 controlslist: 'controlsList',
2784 coords: 'coords',
2785 crossorigin: 'crossOrigin',
2786 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
2787 data: 'data',
2788 datetime: 'dateTime',
2789 default: 'default',
2790 defaultchecked: 'defaultChecked',
2791 defaultvalue: 'defaultValue',
2792 defer: 'defer',
2793 dir: 'dir',
2794 disabled: 'disabled',
2795 disablepictureinpicture: 'disablePictureInPicture',
2796 disableremoteplayback: 'disableRemotePlayback',
2797 download: 'download',
2798 draggable: 'draggable',
2799 enctype: 'encType',
2800 enterkeyhint: 'enterKeyHint',
2801 for: 'htmlFor',
2802 form: 'form',
2803 formmethod: 'formMethod',
2804 formaction: 'formAction',
2805 formenctype: 'formEncType',
2806 formnovalidate: 'formNoValidate',
2807 formtarget: 'formTarget',
2808 frameborder: 'frameBorder',
2809 headers: 'headers',
2810 height: 'height',
2811 hidden: 'hidden',
2812 high: 'high',
2813 href: 'href',
2814 hreflang: 'hrefLang',
2815 htmlfor: 'htmlFor',
2816 httpequiv: 'httpEquiv',
2817 'http-equiv': 'httpEquiv',
2818 icon: 'icon',
2819 id: 'id',
2820 innerhtml: 'innerHTML',
2821 inputmode: 'inputMode',
2822 integrity: 'integrity',
2823 is: 'is',
2824 itemid: 'itemID',
2825 itemprop: 'itemProp',
2826 itemref: 'itemRef',
2827 itemscope: 'itemScope',
2828 itemtype: 'itemType',
2829 keyparams: 'keyParams',
2830 keytype: 'keyType',
2831 kind: 'kind',
2832 label: 'label',
2833 lang: 'lang',
2834 list: 'list',
2835 loop: 'loop',
2836 low: 'low',
2837 manifest: 'manifest',
2838 marginwidth: 'marginWidth',
2839 marginheight: 'marginHeight',
2840 max: 'max',
2841 maxlength: 'maxLength',
2842 media: 'media',
2843 mediagroup: 'mediaGroup',
2844 method: 'method',
2845 min: 'min',
2846 minlength: 'minLength',
2847 multiple: 'multiple',
2848 muted: 'muted',
2849 name: 'name',
2850 nomodule: 'noModule',
2851 nonce: 'nonce',
2852 novalidate: 'noValidate',
2853 open: 'open',
2854 optimum: 'optimum',
2855 pattern: 'pattern',
2856 placeholder: 'placeholder',
2857 playsinline: 'playsInline',
2858 poster: 'poster',
2859 preload: 'preload',
2860 profile: 'profile',
2861 radiogroup: 'radioGroup',
2862 readonly: 'readOnly',
2863 referrerpolicy: 'referrerPolicy',
2864 rel: 'rel',
2865 required: 'required',
2866 reversed: 'reversed',
2867 role: 'role',
2868 rows: 'rows',
2869 rowspan: 'rowSpan',
2870 sandbox: 'sandbox',
2871 scope: 'scope',
2872 scoped: 'scoped',
2873 scrolling: 'scrolling',
2874 seamless: 'seamless',
2875 selected: 'selected',
2876 shape: 'shape',
2877 size: 'size',
2878 sizes: 'sizes',
2879 span: 'span',
2880 spellcheck: 'spellCheck',
2881 src: 'src',
2882 srcdoc: 'srcDoc',
2883 srclang: 'srcLang',
2884 srcset: 'srcSet',
2885 start: 'start',
2886 step: 'step',
2887 style: 'style',
2888 summary: 'summary',
2889 tabindex: 'tabIndex',
2890 target: 'target',
2891 title: 'title',
2892 type: 'type',
2893 usemap: 'useMap',
2894 value: 'value',
2895 width: 'width',
2896 wmode: 'wmode',
2897 wrap: 'wrap',
2898 // SVG
2899 about: 'about',
2900 accentheight: 'accentHeight',
2901 'accent-height': 'accentHeight',
2902 accumulate: 'accumulate',
2903 additive: 'additive',
2904 alignmentbaseline: 'alignmentBaseline',
2905 'alignment-baseline': 'alignmentBaseline',
2906 allowreorder: 'allowReorder',
2907 alphabetic: 'alphabetic',
2908 amplitude: 'amplitude',
2909 arabicform: 'arabicForm',
2910 'arabic-form': 'arabicForm',
2911 ascent: 'ascent',
2912 attributename: 'attributeName',
2913 attributetype: 'attributeType',
2914 autoreverse: 'autoReverse',
2915 azimuth: 'azimuth',
2916 basefrequency: 'baseFrequency',
2917 baselineshift: 'baselineShift',
2918 'baseline-shift': 'baselineShift',
2919 baseprofile: 'baseProfile',
2920 bbox: 'bbox',
2921 begin: 'begin',
2922 bias: 'bias',
2923 by: 'by',
2924 calcmode: 'calcMode',
2925 capheight: 'capHeight',
2926 'cap-height': 'capHeight',
2927 clip: 'clip',
2928 clippath: 'clipPath',
2929 'clip-path': 'clipPath',
2930 clippathunits: 'clipPathUnits',
2931 cliprule: 'clipRule',
2932 'clip-rule': 'clipRule',
2933 color: 'color',
2934 colorinterpolation: 'colorInterpolation',
2935 'color-interpolation': 'colorInterpolation',
2936 colorinterpolationfilters: 'colorInterpolationFilters',
2937 'color-interpolation-filters': 'colorInterpolationFilters',
2938 colorprofile: 'colorProfile',
2939 'color-profile': 'colorProfile',
2940 colorrendering: 'colorRendering',
2941 'color-rendering': 'colorRendering',
2942 contentscripttype: 'contentScriptType',
2943 contentstyletype: 'contentStyleType',
2944 cursor: 'cursor',
2945 cx: 'cx',
2946 cy: 'cy',
2947 d: 'd',
2948 datatype: 'datatype',
2949 decelerate: 'decelerate',
2950 descent: 'descent',
2951 diffuseconstant: 'diffuseConstant',
2952 direction: 'direction',
2953 display: 'display',
2954 divisor: 'divisor',
2955 dominantbaseline: 'dominantBaseline',
2956 'dominant-baseline': 'dominantBaseline',
2957 dur: 'dur',
2958 dx: 'dx',
2959 dy: 'dy',
2960 edgemode: 'edgeMode',
2961 elevation: 'elevation',
2962 enablebackground: 'enableBackground',
2963 'enable-background': 'enableBackground',
2964 end: 'end',
2965 exponent: 'exponent',
2966 externalresourcesrequired: 'externalResourcesRequired',
2967 fill: 'fill',
2968 fillopacity: 'fillOpacity',
2969 'fill-opacity': 'fillOpacity',
2970 fillrule: 'fillRule',
2971 'fill-rule': 'fillRule',
2972 filter: 'filter',
2973 filterres: 'filterRes',
2974 filterunits: 'filterUnits',
2975 floodopacity: 'floodOpacity',
2976 'flood-opacity': 'floodOpacity',
2977 floodcolor: 'floodColor',
2978 'flood-color': 'floodColor',
2979 focusable: 'focusable',
2980 fontfamily: 'fontFamily',
2981 'font-family': 'fontFamily',
2982 fontsize: 'fontSize',
2983 'font-size': 'fontSize',
2984 fontsizeadjust: 'fontSizeAdjust',
2985 'font-size-adjust': 'fontSizeAdjust',
2986 fontstretch: 'fontStretch',
2987 'font-stretch': 'fontStretch',
2988 fontstyle: 'fontStyle',
2989 'font-style': 'fontStyle',
2990 fontvariant: 'fontVariant',
2991 'font-variant': 'fontVariant',
2992 fontweight: 'fontWeight',
2993 'font-weight': 'fontWeight',
2994 format: 'format',
2995 from: 'from',
2996 fx: 'fx',
2997 fy: 'fy',
2998 g1: 'g1',
2999 g2: 'g2',
3000 glyphname: 'glyphName',
3001 'glyph-name': 'glyphName',
3002 glyphorientationhorizontal: 'glyphOrientationHorizontal',
3003 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
3004 glyphorientationvertical: 'glyphOrientationVertical',
3005 'glyph-orientation-vertical': 'glyphOrientationVertical',
3006 glyphref: 'glyphRef',
3007 gradienttransform: 'gradientTransform',
3008 gradientunits: 'gradientUnits',
3009 hanging: 'hanging',
3010 horizadvx: 'horizAdvX',
3011 'horiz-adv-x': 'horizAdvX',
3012 horizoriginx: 'horizOriginX',
3013 'horiz-origin-x': 'horizOriginX',
3014 ideographic: 'ideographic',
3015 imagerendering: 'imageRendering',
3016 'image-rendering': 'imageRendering',
3017 in2: 'in2',
3018 in: 'in',
3019 inlist: 'inlist',
3020 intercept: 'intercept',
3021 k1: 'k1',
3022 k2: 'k2',
3023 k3: 'k3',
3024 k4: 'k4',
3025 k: 'k',
3026 kernelmatrix: 'kernelMatrix',
3027 kernelunitlength: 'kernelUnitLength',
3028 kerning: 'kerning',
3029 keypoints: 'keyPoints',
3030 keysplines: 'keySplines',
3031 keytimes: 'keyTimes',
3032 lengthadjust: 'lengthAdjust',
3033 letterspacing: 'letterSpacing',
3034 'letter-spacing': 'letterSpacing',
3035 lightingcolor: 'lightingColor',
3036 'lighting-color': 'lightingColor',
3037 limitingconeangle: 'limitingConeAngle',
3038 local: 'local',
3039 markerend: 'markerEnd',
3040 'marker-end': 'markerEnd',
3041 markerheight: 'markerHeight',
3042 markermid: 'markerMid',
3043 'marker-mid': 'markerMid',
3044 markerstart: 'markerStart',
3045 'marker-start': 'markerStart',
3046 markerunits: 'markerUnits',
3047 markerwidth: 'markerWidth',
3048 mask: 'mask',
3049 maskcontentunits: 'maskContentUnits',
3050 maskunits: 'maskUnits',
3051 mathematical: 'mathematical',
3052 mode: 'mode',
3053 numoctaves: 'numOctaves',
3054 offset: 'offset',
3055 opacity: 'opacity',
3056 operator: 'operator',
3057 order: 'order',
3058 orient: 'orient',
3059 orientation: 'orientation',
3060 origin: 'origin',
3061 overflow: 'overflow',
3062 overlineposition: 'overlinePosition',
3063 'overline-position': 'overlinePosition',
3064 overlinethickness: 'overlineThickness',
3065 'overline-thickness': 'overlineThickness',
3066 paintorder: 'paintOrder',
3067 'paint-order': 'paintOrder',
3068 panose1: 'panose1',
3069 'panose-1': 'panose1',
3070 pathlength: 'pathLength',
3071 patterncontentunits: 'patternContentUnits',
3072 patterntransform: 'patternTransform',
3073 patternunits: 'patternUnits',
3074 pointerevents: 'pointerEvents',
3075 'pointer-events': 'pointerEvents',
3076 points: 'points',
3077 pointsatx: 'pointsAtX',
3078 pointsaty: 'pointsAtY',
3079 pointsatz: 'pointsAtZ',
3080 prefix: 'prefix',
3081 preservealpha: 'preserveAlpha',
3082 preserveaspectratio: 'preserveAspectRatio',
3083 primitiveunits: 'primitiveUnits',
3084 property: 'property',
3085 r: 'r',
3086 radius: 'radius',
3087 refx: 'refX',
3088 refy: 'refY',
3089 renderingintent: 'renderingIntent',
3090 'rendering-intent': 'renderingIntent',
3091 repeatcount: 'repeatCount',
3092 repeatdur: 'repeatDur',
3093 requiredextensions: 'requiredExtensions',
3094 requiredfeatures: 'requiredFeatures',
3095 resource: 'resource',
3096 restart: 'restart',
3097 result: 'result',
3098 results: 'results',
3099 rotate: 'rotate',
3100 rx: 'rx',
3101 ry: 'ry',
3102 scale: 'scale',
3103 security: 'security',
3104 seed: 'seed',
3105 shaperendering: 'shapeRendering',
3106 'shape-rendering': 'shapeRendering',
3107 slope: 'slope',
3108 spacing: 'spacing',
3109 specularconstant: 'specularConstant',
3110 specularexponent: 'specularExponent',
3111 speed: 'speed',
3112 spreadmethod: 'spreadMethod',
3113 startoffset: 'startOffset',
3114 stddeviation: 'stdDeviation',
3115 stemh: 'stemh',
3116 stemv: 'stemv',
3117 stitchtiles: 'stitchTiles',
3118 stopcolor: 'stopColor',
3119 'stop-color': 'stopColor',
3120 stopopacity: 'stopOpacity',
3121 'stop-opacity': 'stopOpacity',
3122 strikethroughposition: 'strikethroughPosition',
3123 'strikethrough-position': 'strikethroughPosition',
3124 strikethroughthickness: 'strikethroughThickness',
3125 'strikethrough-thickness': 'strikethroughThickness',
3126 string: 'string',
3127 stroke: 'stroke',
3128 strokedasharray: 'strokeDasharray',
3129 'stroke-dasharray': 'strokeDasharray',
3130 strokedashoffset: 'strokeDashoffset',
3131 'stroke-dashoffset': 'strokeDashoffset',
3132 strokelinecap: 'strokeLinecap',
3133 'stroke-linecap': 'strokeLinecap',
3134 strokelinejoin: 'strokeLinejoin',
3135 'stroke-linejoin': 'strokeLinejoin',
3136 strokemiterlimit: 'strokeMiterlimit',
3137 'stroke-miterlimit': 'strokeMiterlimit',
3138 strokewidth: 'strokeWidth',
3139 'stroke-width': 'strokeWidth',
3140 strokeopacity: 'strokeOpacity',
3141 'stroke-opacity': 'strokeOpacity',
3142 suppresscontenteditablewarning: 'suppressContentEditableWarning',
3143 suppresshydrationwarning: 'suppressHydrationWarning',
3144 surfacescale: 'surfaceScale',
3145 systemlanguage: 'systemLanguage',
3146 tablevalues: 'tableValues',
3147 targetx: 'targetX',
3148 targety: 'targetY',
3149 textanchor: 'textAnchor',
3150 'text-anchor': 'textAnchor',
3151 textdecoration: 'textDecoration',
3152 'text-decoration': 'textDecoration',
3153 textlength: 'textLength',
3154 textrendering: 'textRendering',
3155 'text-rendering': 'textRendering',
3156 to: 'to',
3157 transform: 'transform',
3158 typeof: 'typeof',
3159 u1: 'u1',
3160 u2: 'u2',
3161 underlineposition: 'underlinePosition',
3162 'underline-position': 'underlinePosition',
3163 underlinethickness: 'underlineThickness',
3164 'underline-thickness': 'underlineThickness',
3165 unicode: 'unicode',
3166 unicodebidi: 'unicodeBidi',
3167 'unicode-bidi': 'unicodeBidi',
3168 unicoderange: 'unicodeRange',
3169 'unicode-range': 'unicodeRange',
3170 unitsperem: 'unitsPerEm',
3171 'units-per-em': 'unitsPerEm',
3172 unselectable: 'unselectable',
3173 valphabetic: 'vAlphabetic',
3174 'v-alphabetic': 'vAlphabetic',
3175 values: 'values',
3176 vectoreffect: 'vectorEffect',
3177 'vector-effect': 'vectorEffect',
3178 version: 'version',
3179 vertadvy: 'vertAdvY',
3180 'vert-adv-y': 'vertAdvY',
3181 vertoriginx: 'vertOriginX',
3182 'vert-origin-x': 'vertOriginX',
3183 vertoriginy: 'vertOriginY',
3184 'vert-origin-y': 'vertOriginY',
3185 vhanging: 'vHanging',
3186 'v-hanging': 'vHanging',
3187 videographic: 'vIdeographic',
3188 'v-ideographic': 'vIdeographic',
3189 viewbox: 'viewBox',
3190 viewtarget: 'viewTarget',
3191 visibility: 'visibility',
3192 vmathematical: 'vMathematical',
3193 'v-mathematical': 'vMathematical',
3194 vocab: 'vocab',
3195 widths: 'widths',
3196 wordspacing: 'wordSpacing',
3197 'word-spacing': 'wordSpacing',
3198 writingmode: 'writingMode',
3199 'writing-mode': 'writingMode',
3200 x1: 'x1',
3201 x2: 'x2',
3202 x: 'x',
3203 xchannelselector: 'xChannelSelector',
3204 xheight: 'xHeight',
3205 'x-height': 'xHeight',
3206 xlinkactuate: 'xlinkActuate',
3207 'xlink:actuate': 'xlinkActuate',
3208 xlinkarcrole: 'xlinkArcrole',
3209 'xlink:arcrole': 'xlinkArcrole',
3210 xlinkhref: 'xlinkHref',
3211 'xlink:href': 'xlinkHref',
3212 xlinkrole: 'xlinkRole',
3213 'xlink:role': 'xlinkRole',
3214 xlinkshow: 'xlinkShow',
3215 'xlink:show': 'xlinkShow',
3216 xlinktitle: 'xlinkTitle',
3217 'xlink:title': 'xlinkTitle',
3218 xlinktype: 'xlinkType',
3219 'xlink:type': 'xlinkType',
3220 xmlbase: 'xmlBase',
3221 'xml:base': 'xmlBase',
3222 xmllang: 'xmlLang',
3223 'xml:lang': 'xmlLang',
3224 xmlns: 'xmlns',
3225 'xml:space': 'xmlSpace',
3226 xmlnsxlink: 'xmlnsXlink',
3227 'xmlns:xlink': 'xmlnsXlink',
3228 xmlspace: 'xmlSpace',
3229 y1: 'y1',
3230 y2: 'y2',
3231 y: 'y',
3232 ychannelselector: 'yChannelSelector',
3233 z: 'z',
3234 zoomandpan: 'zoomAndPan'
3235 };
3236
3237 var ariaProperties = {
3238 'aria-current': 0,
3239 // state
3240 'aria-details': 0,
3241 'aria-disabled': 0,
3242 // state
3243 'aria-hidden': 0,
3244 // state
3245 'aria-invalid': 0,
3246 // state
3247 'aria-keyshortcuts': 0,
3248 'aria-label': 0,
3249 'aria-roledescription': 0,
3250 // Widget Attributes
3251 'aria-autocomplete': 0,
3252 'aria-checked': 0,
3253 'aria-expanded': 0,
3254 'aria-haspopup': 0,
3255 'aria-level': 0,
3256 'aria-modal': 0,
3257 'aria-multiline': 0,
3258 'aria-multiselectable': 0,
3259 'aria-orientation': 0,
3260 'aria-placeholder': 0,
3261 'aria-pressed': 0,
3262 'aria-readonly': 0,
3263 'aria-required': 0,
3264 'aria-selected': 0,
3265 'aria-sort': 0,
3266 'aria-valuemax': 0,
3267 'aria-valuemin': 0,
3268 'aria-valuenow': 0,
3269 'aria-valuetext': 0,
3270 // Live Region Attributes
3271 'aria-atomic': 0,
3272 'aria-busy': 0,
3273 'aria-live': 0,
3274 'aria-relevant': 0,
3275 // Drag-and-Drop Attributes
3276 'aria-dropeffect': 0,
3277 'aria-grabbed': 0,
3278 // Relationship Attributes
3279 'aria-activedescendant': 0,
3280 'aria-colcount': 0,
3281 'aria-colindex': 0,
3282 'aria-colspan': 0,
3283 'aria-controls': 0,
3284 'aria-describedby': 0,
3285 'aria-errormessage': 0,
3286 'aria-flowto': 0,
3287 'aria-labelledby': 0,
3288 'aria-owns': 0,
3289 'aria-posinset': 0,
3290 'aria-rowcount': 0,
3291 'aria-rowindex': 0,
3292 'aria-rowspan': 0,
3293 'aria-setsize': 0
3294 };
3295
3296 var warnedProperties = {};
3297 var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
3298 var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
3299 var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
3300
3301 function validateProperty(tagName, name) {
3302 {
3303 if (hasOwnProperty$1.call(warnedProperties, name) && warnedProperties[name]) {
3304 return true;
3305 }
3306
3307 if (rARIACamel.test(name)) {
3308 var ariaName = 'aria-' + name.slice(4).toLowerCase();
3309 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null; // If this is an aria-* attribute, but is not listed in the known DOM
3310 // DOM properties, then it is an invalid aria-* attribute.
3311
3312 if (correctName == null) {
3313 error('Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name);
3314
3315 warnedProperties[name] = true;
3316 return true;
3317 } // aria-* attributes should be lowercase; suggest the lowercase version.
3318
3319
3320 if (name !== correctName) {
3321 error('Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName);
3322
3323 warnedProperties[name] = true;
3324 return true;
3325 }
3326 }
3327
3328 if (rARIA.test(name)) {
3329 var lowerCasedName = name.toLowerCase();
3330 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null; // If this is an aria-* attribute, but is not listed in the known DOM
3331 // DOM properties, then it is an invalid aria-* attribute.
3332
3333 if (standardName == null) {
3334 warnedProperties[name] = true;
3335 return false;
3336 } // aria-* attributes should be lowercase; suggest the lowercase version.
3337
3338
3339 if (name !== standardName) {
3340 error('Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName);
3341
3342 warnedProperties[name] = true;
3343 return true;
3344 }
3345 }
3346 }
3347
3348 return true;
3349 }
3350
3351 function warnInvalidARIAProps(type, props) {
3352 {
3353 var invalidProps = [];
3354
3355 for (var key in props) {
3356 var isValid = validateProperty(type, key);
3357
3358 if (!isValid) {
3359 invalidProps.push(key);
3360 }
3361 }
3362
3363 var unknownPropString = invalidProps.map(function (prop) {
3364 return '`' + prop + '`';
3365 }).join(', ');
3366
3367 if (invalidProps.length === 1) {
3368 error('Invalid aria prop %s on <%s> tag. ' + 'For details, see https://reactjs.org/link/invalid-aria-props', unknownPropString, type);
3369 } else if (invalidProps.length > 1) {
3370 error('Invalid aria props %s on <%s> tag. ' + 'For details, see https://reactjs.org/link/invalid-aria-props', unknownPropString, type);
3371 }
3372 }
3373 }
3374
3375 function validateProperties(type, props) {
3376 if (isCustomComponent(type, props)) {
3377 return;
3378 }
3379
3380 warnInvalidARIAProps(type, props);
3381 }
3382
3383 var didWarnValueNull = false;
3384 function validateProperties$1(type, props) {
3385 {
3386 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
3387 return;
3388 }
3389
3390 if (props != null && props.value === null && !didWarnValueNull) {
3391 didWarnValueNull = true;
3392
3393 if (type === 'select' && props.multiple) {
3394 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);
3395 } else {
3396 error('`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', type);
3397 }
3398 }
3399 }
3400 }
3401
3402 var validateProperty$1 = function () {};
3403
3404 {
3405 var warnedProperties$1 = {};
3406 var _hasOwnProperty = Object.prototype.hasOwnProperty;
3407 var EVENT_NAME_REGEX = /^on./;
3408 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
3409 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
3410 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
3411
3412 validateProperty$1 = function (tagName, name, value, eventRegistry) {
3413 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
3414 return true;
3415 }
3416
3417 var lowerCasedName = name.toLowerCase();
3418
3419 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
3420 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.');
3421
3422 warnedProperties$1[name] = true;
3423 return true;
3424 } // We can't rely on the event system being injected on the server.
3425
3426
3427 if (eventRegistry != null) {
3428 var registrationNameDependencies = eventRegistry.registrationNameDependencies,
3429 possibleRegistrationNames = eventRegistry.possibleRegistrationNames;
3430
3431 if (registrationNameDependencies.hasOwnProperty(name)) {
3432 return true;
3433 }
3434
3435 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
3436
3437 if (registrationName != null) {
3438 error('Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName);
3439
3440 warnedProperties$1[name] = true;
3441 return true;
3442 }
3443
3444 if (EVENT_NAME_REGEX.test(name)) {
3445 error('Unknown event handler property `%s`. It will be ignored.', name);
3446
3447 warnedProperties$1[name] = true;
3448 return true;
3449 }
3450 } else if (EVENT_NAME_REGEX.test(name)) {
3451 // If no event plugins have been injected, we are in a server environment.
3452 // So we can't tell if the event name is correct for sure, but we can filter
3453 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
3454 if (INVALID_EVENT_NAME_REGEX.test(name)) {
3455 error('Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name);
3456 }
3457
3458 warnedProperties$1[name] = true;
3459 return true;
3460 } // Let the ARIA attribute hook validate ARIA attributes
3461
3462
3463 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
3464 return true;
3465 }
3466
3467 if (lowerCasedName === 'innerhtml') {
3468 error('Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
3469
3470 warnedProperties$1[name] = true;
3471 return true;
3472 }
3473
3474 if (lowerCasedName === 'aria') {
3475 error('The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
3476
3477 warnedProperties$1[name] = true;
3478 return true;
3479 }
3480
3481 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
3482 error('Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value);
3483
3484 warnedProperties$1[name] = true;
3485 return true;
3486 }
3487
3488 if (typeof value === 'number' && isNaN(value)) {
3489 error('Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name);
3490
3491 warnedProperties$1[name] = true;
3492 return true;
3493 }
3494
3495 var propertyInfo = getPropertyInfo(name);
3496 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED; // Known attributes should match the casing specified in the property config.
3497
3498 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
3499 var standardName = possibleStandardNames[lowerCasedName];
3500
3501 if (standardName !== name) {
3502 error('Invalid DOM property `%s`. Did you mean `%s`?', name, standardName);
3503
3504 warnedProperties$1[name] = true;
3505 return true;
3506 }
3507 } else if (!isReserved && name !== lowerCasedName) {
3508 // Unknown attributes should have lowercase casing since that's how they
3509 // will be cased anyway with server rendering.
3510 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);
3511
3512 warnedProperties$1[name] = true;
3513 return true;
3514 }
3515
3516 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
3517 if (value) {
3518 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);
3519 } else {
3520 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);
3521 }
3522
3523 warnedProperties$1[name] = true;
3524 return true;
3525 } // Now that we've validated casing, do not validate
3526 // data types for reserved props
3527
3528
3529 if (isReserved) {
3530 return true;
3531 } // Warn when a known attribute is a bad type
3532
3533
3534 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
3535 warnedProperties$1[name] = true;
3536 return false;
3537 } // Warn when passing the strings 'false' or 'true' into a boolean prop
3538
3539
3540 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) {
3541 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);
3542
3543 warnedProperties$1[name] = true;
3544 return true;
3545 }
3546
3547 return true;
3548 };
3549 }
3550
3551 var warnUnknownProperties = function (type, props, eventRegistry) {
3552 {
3553 var unknownProps = [];
3554
3555 for (var key in props) {
3556 var isValid = validateProperty$1(type, key, props[key], eventRegistry);
3557
3558 if (!isValid) {
3559 unknownProps.push(key);
3560 }
3561 }
3562
3563 var unknownPropString = unknownProps.map(function (prop) {
3564 return '`' + prop + '`';
3565 }).join(', ');
3566
3567 if (unknownProps.length === 1) {
3568 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);
3569 } else if (unknownProps.length > 1) {
3570 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);
3571 }
3572 }
3573 };
3574
3575 function validateProperties$2(type, props, eventRegistry) {
3576 if (isCustomComponent(type, props)) {
3577 return;
3578 }
3579
3580 warnUnknownProperties(type, props, eventRegistry);
3581 }
3582
3583 var IS_EVENT_HANDLE_NON_MANAGED_NODE = 1;
3584 var IS_NON_DELEGATED = 1 << 1;
3585 var IS_CAPTURE_PHASE = 1 << 2;
3586 var IS_REPLAYED = 1 << 4;
3587 // set to LEGACY_FB_SUPPORT. LEGACY_FB_SUPPORT only gets set when
3588 // we call willDeferLaterForLegacyFBSupport, thus not bailing out
3589 // will result in endless cycles like an infinite loop.
3590 // We also don't want to defer during event replaying.
3591
3592 var SHOULD_NOT_PROCESS_POLYFILL_EVENT_PLUGINS = IS_EVENT_HANDLE_NON_MANAGED_NODE | IS_NON_DELEGATED | IS_CAPTURE_PHASE;
3593
3594 /**
3595 * Gets the target node from a native browser event by accounting for
3596 * inconsistencies in browser DOM APIs.
3597 *
3598 * @param {object} nativeEvent Native browser event.
3599 * @return {DOMEventTarget} Target node.
3600 */
3601
3602 function getEventTarget(nativeEvent) {
3603 // Fallback to nativeEvent.srcElement for IE9
3604 // https://github.com/facebook/react/issues/12506
3605 var target = nativeEvent.target || nativeEvent.srcElement || window; // Normalize SVG <use> element events #4963
3606
3607 if (target.correspondingUseElement) {
3608 target = target.correspondingUseElement;
3609 } // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
3610 // @see http://www.quirksmode.org/js/events_properties.html
3611
3612
3613 return target.nodeType === TEXT_NODE ? target.parentNode : target;
3614 }
3615
3616 var restoreImpl = null;
3617 var restoreTarget = null;
3618 var restoreQueue = null;
3619
3620 function restoreStateOfTarget(target) {
3621 // We perform this translation at the end of the event loop so that we
3622 // always receive the correct fiber here
3623 var internalInstance = getInstanceFromNode(target);
3624
3625 if (!internalInstance) {
3626 // Unmounted
3627 return;
3628 }
3629
3630 if (!(typeof restoreImpl === 'function')) {
3631 {
3632 throw 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." );
3633 }
3634 }
3635
3636 var stateNode = internalInstance.stateNode; // Guard against Fiber being unmounted.
3637
3638 if (stateNode) {
3639 var _props = getFiberCurrentPropsFromNode(stateNode);
3640
3641 restoreImpl(internalInstance.stateNode, internalInstance.type, _props);
3642 }
3643 }
3644
3645 function setRestoreImplementation(impl) {
3646 restoreImpl = impl;
3647 }
3648 function enqueueStateRestore(target) {
3649 if (restoreTarget) {
3650 if (restoreQueue) {
3651 restoreQueue.push(target);
3652 } else {
3653 restoreQueue = [target];
3654 }
3655 } else {
3656 restoreTarget = target;
3657 }
3658 }
3659 function needsStateRestore() {
3660 return restoreTarget !== null || restoreQueue !== null;
3661 }
3662 function restoreStateIfNeeded() {
3663 if (!restoreTarget) {
3664 return;
3665 }
3666
3667 var target = restoreTarget;
3668 var queuedTargets = restoreQueue;
3669 restoreTarget = null;
3670 restoreQueue = null;
3671 restoreStateOfTarget(target);
3672
3673 if (queuedTargets) {
3674 for (var i = 0; i < queuedTargets.length; i++) {
3675 restoreStateOfTarget(queuedTargets[i]);
3676 }
3677 }
3678 }
3679
3680 // the renderer. Such as when we're dispatching events or if third party
3681 // libraries need to call batchedUpdates. Eventually, this API will go away when
3682 // everything is batched by default. We'll then have a similar API to opt-out of
3683 // scheduled work and instead do synchronous work.
3684 // Defaults
3685
3686 var batchedUpdatesImpl = function (fn, bookkeeping) {
3687 return fn(bookkeeping);
3688 };
3689
3690 var discreteUpdatesImpl = function (fn, a, b, c, d) {
3691 return fn(a, b, c, d);
3692 };
3693
3694 var flushDiscreteUpdatesImpl = function () {};
3695
3696 var batchedEventUpdatesImpl = batchedUpdatesImpl;
3697 var isInsideEventHandler = false;
3698 var isBatchingEventUpdates = false;
3699
3700 function finishEventHandler() {
3701 // Here we wait until all updates have propagated, which is important
3702 // when using controlled components within layers:
3703 // https://github.com/facebook/react/issues/1698
3704 // Then we restore state of any controlled component.
3705 var controlledComponentsHavePendingUpdates = needsStateRestore();
3706
3707 if (controlledComponentsHavePendingUpdates) {
3708 // If a controlled event was fired, we may need to restore the state of
3709 // the DOM node back to the controlled value. This is necessary when React
3710 // bails out of the update without touching the DOM.
3711 flushDiscreteUpdatesImpl();
3712 restoreStateIfNeeded();
3713 }
3714 }
3715
3716 function batchedUpdates(fn, bookkeeping) {
3717 if (isInsideEventHandler) {
3718 // If we are currently inside another batch, we need to wait until it
3719 // fully completes before restoring state.
3720 return fn(bookkeeping);
3721 }
3722
3723 isInsideEventHandler = true;
3724
3725 try {
3726 return batchedUpdatesImpl(fn, bookkeeping);
3727 } finally {
3728 isInsideEventHandler = false;
3729 finishEventHandler();
3730 }
3731 }
3732 function batchedEventUpdates(fn, a, b) {
3733 if (isBatchingEventUpdates) {
3734 // If we are currently inside another batch, we need to wait until it
3735 // fully completes before restoring state.
3736 return fn(a, b);
3737 }
3738
3739 isBatchingEventUpdates = true;
3740
3741 try {
3742 return batchedEventUpdatesImpl(fn, a, b);
3743 } finally {
3744 isBatchingEventUpdates = false;
3745 finishEventHandler();
3746 }
3747 }
3748 function discreteUpdates(fn, a, b, c, d) {
3749 var prevIsInsideEventHandler = isInsideEventHandler;
3750 isInsideEventHandler = true;
3751
3752 try {
3753 return discreteUpdatesImpl(fn, a, b, c, d);
3754 } finally {
3755 isInsideEventHandler = prevIsInsideEventHandler;
3756
3757 if (!isInsideEventHandler) {
3758 finishEventHandler();
3759 }
3760 }
3761 }
3762 function flushDiscreteUpdatesIfNeeded(timeStamp) {
3763 {
3764 if (!isInsideEventHandler) {
3765 flushDiscreteUpdatesImpl();
3766 }
3767 }
3768 }
3769 function setBatchingImplementation(_batchedUpdatesImpl, _discreteUpdatesImpl, _flushDiscreteUpdatesImpl, _batchedEventUpdatesImpl) {
3770 batchedUpdatesImpl = _batchedUpdatesImpl;
3771 discreteUpdatesImpl = _discreteUpdatesImpl;
3772 flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl;
3773 batchedEventUpdatesImpl = _batchedEventUpdatesImpl;
3774 }
3775
3776 function isInteractive(tag) {
3777 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
3778 }
3779
3780 function shouldPreventMouseEvent(name, type, props) {
3781 switch (name) {
3782 case 'onClick':
3783 case 'onClickCapture':
3784 case 'onDoubleClick':
3785 case 'onDoubleClickCapture':
3786 case 'onMouseDown':
3787 case 'onMouseDownCapture':
3788 case 'onMouseMove':
3789 case 'onMouseMoveCapture':
3790 case 'onMouseUp':
3791 case 'onMouseUpCapture':
3792 case 'onMouseEnter':
3793 return !!(props.disabled && isInteractive(type));
3794
3795 default:
3796 return false;
3797 }
3798 }
3799 /**
3800 * @param {object} inst The instance, which is the source of events.
3801 * @param {string} registrationName Name of listener (e.g. `onClick`).
3802 * @return {?function} The stored callback.
3803 */
3804
3805
3806 function getListener(inst, registrationName) {
3807 var stateNode = inst.stateNode;
3808
3809 if (stateNode === null) {
3810 // Work in progress (ex: onload events in incremental mode).
3811 return null;
3812 }
3813
3814 var props = getFiberCurrentPropsFromNode(stateNode);
3815
3816 if (props === null) {
3817 // Work in progress.
3818 return null;
3819 }
3820
3821 var listener = props[registrationName];
3822
3823 if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
3824 return null;
3825 }
3826
3827 if (!(!listener || typeof listener === 'function')) {
3828 {
3829 throw Error( "Expected `" + registrationName + "` listener to be a function, instead got a value of `" + typeof listener + "` type." );
3830 }
3831 }
3832
3833 return listener;
3834 }
3835
3836 var passiveBrowserEventsSupported = false; // Check if browser support events with passive listeners
3837 // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support
3838
3839 if (canUseDOM) {
3840 try {
3841 var options = {}; // $FlowFixMe: Ignore Flow complaining about needing a value
3842
3843 Object.defineProperty(options, 'passive', {
3844 get: function () {
3845 passiveBrowserEventsSupported = true;
3846 }
3847 });
3848 window.addEventListener('test', options, options);
3849 window.removeEventListener('test', options, options);
3850 } catch (e) {
3851 passiveBrowserEventsSupported = false;
3852 }
3853 }
3854
3855 function invokeGuardedCallbackProd(name, func, context, a, b, c, d, e, f) {
3856 var funcArgs = Array.prototype.slice.call(arguments, 3);
3857
3858 try {
3859 func.apply(context, funcArgs);
3860 } catch (error) {
3861 this.onError(error);
3862 }
3863 }
3864
3865 var invokeGuardedCallbackImpl = invokeGuardedCallbackProd;
3866
3867 {
3868 // In DEV mode, we swap out invokeGuardedCallback for a special version
3869 // that plays more nicely with the browser's DevTools. The idea is to preserve
3870 // "Pause on exceptions" behavior. Because React wraps all user-provided
3871 // functions in invokeGuardedCallback, and the production version of
3872 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
3873 // like caught exceptions, and the DevTools won't pause unless the developer
3874 // takes the extra step of enabling pause on caught exceptions. This is
3875 // unintuitive, though, because even though React has caught the error, from
3876 // the developer's perspective, the error is uncaught.
3877 //
3878 // To preserve the expected "Pause on exceptions" behavior, we don't use a
3879 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
3880 // DOM node, and call the user-provided callback from inside an event handler
3881 // for that fake event. If the callback throws, the error is "captured" using
3882 // a global event handler. But because the error happens in a different
3883 // event loop context, it does not interrupt the normal program flow.
3884 // Effectively, this gives us try-catch behavior without actually using
3885 // try-catch. Neat!
3886 // Check that the browser supports the APIs we need to implement our special
3887 // DEV version of invokeGuardedCallback
3888 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
3889 var fakeNode = document.createElement('react');
3890
3891 invokeGuardedCallbackImpl = function invokeGuardedCallbackDev(name, func, context, a, b, c, d, e, f) {
3892 // If document doesn't exist we know for sure we will crash in this method
3893 // when we call document.createEvent(). However this can cause confusing
3894 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
3895 // So we preemptively throw with a better message instead.
3896 if (!(typeof document !== 'undefined')) {
3897 {
3898 throw Error( "The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous." );
3899 }
3900 }
3901
3902 var evt = document.createEvent('Event');
3903 var didCall = false; // Keeps track of whether the user-provided callback threw an error. We
3904 // set this to true at the beginning, then set it to false right after
3905 // calling the function. If the function errors, `didError` will never be
3906 // set to false. This strategy works even if the browser is flaky and
3907 // fails to call our global error handler, because it doesn't rely on
3908 // the error event at all.
3909
3910 var didError = true; // Keeps track of the value of window.event so that we can reset it
3911 // during the callback to let user code access window.event in the
3912 // browsers that support it.
3913
3914 var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event
3915 // dispatching: https://github.com/facebook/react/issues/13688
3916
3917 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
3918
3919 function restoreAfterDispatch() {
3920 // We immediately remove the callback from event listeners so that
3921 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
3922 // nested call would trigger the fake event handlers of any call higher
3923 // in the stack.
3924 fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the
3925 // window.event assignment in both IE <= 10 as they throw an error
3926 // "Member not found" in strict mode, and in Firefox which does not
3927 // support window.event.
3928
3929 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
3930 window.event = windowEvent;
3931 }
3932 } // Create an event handler for our fake event. We will synchronously
3933 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
3934 // call the user-provided callback.
3935
3936
3937 var funcArgs = Array.prototype.slice.call(arguments, 3);
3938
3939 function callCallback() {
3940 didCall = true;
3941 restoreAfterDispatch();
3942 func.apply(context, funcArgs);
3943 didError = false;
3944 } // Create a global error event handler. We use this to capture the value
3945 // that was thrown. It's possible that this error handler will fire more
3946 // than once; for example, if non-React code also calls `dispatchEvent`
3947 // and a handler for that event throws. We should be resilient to most of
3948 // those cases. Even if our error event handler fires more than once, the
3949 // last error event is always used. If the callback actually does error,
3950 // we know that the last error event is the correct one, because it's not
3951 // possible for anything else to have happened in between our callback
3952 // erroring and the code that follows the `dispatchEvent` call below. If
3953 // the callback doesn't error, but the error event was fired, we know to
3954 // ignore it because `didError` will be false, as described above.
3955
3956
3957 var error; // Use this to track whether the error event is ever called.
3958
3959 var didSetError = false;
3960 var isCrossOriginError = false;
3961
3962 function handleWindowError(event) {
3963 error = event.error;
3964 didSetError = true;
3965
3966 if (error === null && event.colno === 0 && event.lineno === 0) {
3967 isCrossOriginError = true;
3968 }
3969
3970 if (event.defaultPrevented) {
3971 // Some other error handler has prevented default.
3972 // Browsers silence the error report if this happens.
3973 // We'll remember this to later decide whether to log it or not.
3974 if (error != null && typeof error === 'object') {
3975 try {
3976 error._suppressLogging = true;
3977 } catch (inner) {// Ignore.
3978 }
3979 }
3980 }
3981 } // Create a fake event type.
3982
3983
3984 var evtType = "react-" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers
3985
3986 window.addEventListener('error', handleWindowError);
3987 fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function
3988 // errors, it will trigger our global error handler.
3989
3990 evt.initEvent(evtType, false, false);
3991 fakeNode.dispatchEvent(evt);
3992
3993 if (windowEventDescriptor) {
3994 Object.defineProperty(window, 'event', windowEventDescriptor);
3995 }
3996
3997 if (didCall && didError) {
3998 if (!didSetError) {
3999 // The callback errored, but the error event never fired.
4000 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.');
4001 } else if (isCrossOriginError) {
4002 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.');
4003 }
4004
4005 this.onError(error);
4006 } // Remove our event listeners
4007
4008
4009 window.removeEventListener('error', handleWindowError);
4010
4011 if (!didCall) {
4012 // Something went really wrong, and our event was not dispatched.
4013 // https://github.com/facebook/react/issues/16734
4014 // https://github.com/facebook/react/issues/16585
4015 // Fall back to the production implementation.
4016 restoreAfterDispatch();
4017 return invokeGuardedCallbackProd.apply(this, arguments);
4018 }
4019 };
4020 }
4021 }
4022
4023 var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
4024
4025 var hasError = false;
4026 var caughtError = null; // Used by event system to capture/rethrow the first error.
4027
4028 var hasRethrowError = false;
4029 var rethrowError = null;
4030 var reporter = {
4031 onError: function (error) {
4032 hasError = true;
4033 caughtError = error;
4034 }
4035 };
4036 /**
4037 * Call a function while guarding against errors that happens within it.
4038 * Returns an error if it throws, otherwise null.
4039 *
4040 * In production, this is implemented using a try-catch. The reason we don't
4041 * use a try-catch directly is so that we can swap out a different
4042 * implementation in DEV mode.
4043 *
4044 * @param {String} name of the guard to use for logging or debugging
4045 * @param {Function} func The function to invoke
4046 * @param {*} context The context to use when calling the function
4047 * @param {...*} args Arguments for function
4048 */
4049
4050 function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
4051 hasError = false;
4052 caughtError = null;
4053 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
4054 }
4055 /**
4056 * Same as invokeGuardedCallback, but instead of returning an error, it stores
4057 * it in a global so it can be rethrown by `rethrowCaughtError` later.
4058 * TODO: See if caughtError and rethrowError can be unified.
4059 *
4060 * @param {String} name of the guard to use for logging or debugging
4061 * @param {Function} func The function to invoke
4062 * @param {*} context The context to use when calling the function
4063 * @param {...*} args Arguments for function
4064 */
4065
4066 function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) {
4067 invokeGuardedCallback.apply(this, arguments);
4068
4069 if (hasError) {
4070 var error = clearCaughtError();
4071
4072 if (!hasRethrowError) {
4073 hasRethrowError = true;
4074 rethrowError = error;
4075 }
4076 }
4077 }
4078 /**
4079 * During execution of guarded functions we will capture the first error which
4080 * we will rethrow to be handled by the top level error handler.
4081 */
4082
4083 function rethrowCaughtError() {
4084 if (hasRethrowError) {
4085 var error = rethrowError;
4086 hasRethrowError = false;
4087 rethrowError = null;
4088 throw error;
4089 }
4090 }
4091 function hasCaughtError() {
4092 return hasError;
4093 }
4094 function clearCaughtError() {
4095 if (hasError) {
4096 var error = caughtError;
4097 hasError = false;
4098 caughtError = null;
4099 return error;
4100 } else {
4101 {
4102 {
4103 throw Error( "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." );
4104 }
4105 }
4106 }
4107 }
4108
4109 var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
4110 var _ReactInternals$Sched = ReactInternals$1.Scheduler,
4111 unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback,
4112 unstable_now = _ReactInternals$Sched.unstable_now,
4113 unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback,
4114 unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield,
4115 unstable_requestPaint = _ReactInternals$Sched.unstable_requestPaint,
4116 unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode,
4117 unstable_runWithPriority = _ReactInternals$Sched.unstable_runWithPriority,
4118 unstable_next = _ReactInternals$Sched.unstable_next,
4119 unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution,
4120 unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution,
4121 unstable_getCurrentPriorityLevel = _ReactInternals$Sched.unstable_getCurrentPriorityLevel,
4122 unstable_ImmediatePriority = _ReactInternals$Sched.unstable_ImmediatePriority,
4123 unstable_UserBlockingPriority = _ReactInternals$Sched.unstable_UserBlockingPriority,
4124 unstable_NormalPriority = _ReactInternals$Sched.unstable_NormalPriority,
4125 unstable_LowPriority = _ReactInternals$Sched.unstable_LowPriority,
4126 unstable_IdlePriority = _ReactInternals$Sched.unstable_IdlePriority,
4127 unstable_forceFrameRate = _ReactInternals$Sched.unstable_forceFrameRate,
4128 unstable_flushAllWithoutAsserting = _ReactInternals$Sched.unstable_flushAllWithoutAsserting;
4129
4130 /**
4131 * `ReactInstanceMap` maintains a mapping from a public facing stateful
4132 * instance (key) and the internal representation (value). This allows public
4133 * methods to accept the user facing instance as an argument and map them back
4134 * to internal methods.
4135 *
4136 * Note that this module is currently shared and assumed to be stateless.
4137 * If this becomes an actual Map, that will break.
4138 */
4139 function get(key) {
4140 return key._reactInternals;
4141 }
4142 function has(key) {
4143 return key._reactInternals !== undefined;
4144 }
4145 function set(key, value) {
4146 key._reactInternals = value;
4147 }
4148
4149 // Don't change these two values. They're used by React Dev Tools.
4150 var NoFlags =
4151 /* */
4152 0;
4153 var PerformedWork =
4154 /* */
4155 1; // You can change the rest (and add more).
4156
4157 var Placement =
4158 /* */
4159 2;
4160 var Update =
4161 /* */
4162 4;
4163 var PlacementAndUpdate =
4164 /* */
4165 6;
4166 var Deletion =
4167 /* */
4168 8;
4169 var ContentReset =
4170 /* */
4171 16;
4172 var Callback =
4173 /* */
4174 32;
4175 var DidCapture =
4176 /* */
4177 64;
4178 var Ref =
4179 /* */
4180 128;
4181 var Snapshot =
4182 /* */
4183 256;
4184 var Passive =
4185 /* */
4186 512; // TODO (effects) Remove this bit once the new reconciler is synced to the old.
4187
4188 var PassiveUnmountPendingDev =
4189 /* */
4190 8192;
4191 var Hydrating =
4192 /* */
4193 1024;
4194 var HydratingAndUpdate =
4195 /* */
4196 1028; // Passive & Update & Callback & Ref & Snapshot
4197
4198 var LifecycleEffectMask =
4199 /* */
4200 932; // Union of all host effects
4201
4202 var HostEffectMask =
4203 /* */
4204 2047; // These are not really side effects, but we still reuse this field.
4205
4206 var Incomplete =
4207 /* */
4208 2048;
4209 var ShouldCapture =
4210 /* */
4211 4096;
4212 var ForceUpdateForLegacySuspense =
4213 /* */
4214 16384; // Static tags describe aspects of a fiber that are not specific to a render,
4215
4216 var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
4217 function getNearestMountedFiber(fiber) {
4218 var node = fiber;
4219 var nearestMounted = fiber;
4220
4221 if (!fiber.alternate) {
4222 // If there is no alternate, this might be a new tree that isn't inserted
4223 // yet. If it is, then it will have a pending insertion effect on it.
4224 var nextNode = node;
4225
4226 do {
4227 node = nextNode;
4228
4229 if ((node.flags & (Placement | Hydrating)) !== NoFlags) {
4230 // This is an insertion or in-progress hydration. The nearest possible
4231 // mounted fiber is the parent but we need to continue to figure out
4232 // if that one is still mounted.
4233 nearestMounted = node.return;
4234 }
4235
4236 nextNode = node.return;
4237 } while (nextNode);
4238 } else {
4239 while (node.return) {
4240 node = node.return;
4241 }
4242 }
4243
4244 if (node.tag === HostRoot) {
4245 // TODO: Check if this was a nested HostRoot when used with
4246 // renderContainerIntoSubtree.
4247 return nearestMounted;
4248 } // If we didn't hit the root, that means that we're in an disconnected tree
4249 // that has been unmounted.
4250
4251
4252 return null;
4253 }
4254 function getSuspenseInstanceFromFiber(fiber) {
4255 if (fiber.tag === SuspenseComponent) {
4256 var suspenseState = fiber.memoizedState;
4257
4258 if (suspenseState === null) {
4259 var current = fiber.alternate;
4260
4261 if (current !== null) {
4262 suspenseState = current.memoizedState;
4263 }
4264 }
4265
4266 if (suspenseState !== null) {
4267 return suspenseState.dehydrated;
4268 }
4269 }
4270
4271 return null;
4272 }
4273 function getContainerFromFiber(fiber) {
4274 return fiber.tag === HostRoot ? fiber.stateNode.containerInfo : null;
4275 }
4276 function isFiberMounted(fiber) {
4277 return getNearestMountedFiber(fiber) === fiber;
4278 }
4279 function isMounted(component) {
4280 {
4281 var owner = ReactCurrentOwner.current;
4282
4283 if (owner !== null && owner.tag === ClassComponent) {
4284 var ownerFiber = owner;
4285 var instance = ownerFiber.stateNode;
4286
4287 if (!instance._warnedAboutRefsInRender) {
4288 error('%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName(ownerFiber.type) || 'A component');
4289 }
4290
4291 instance._warnedAboutRefsInRender = true;
4292 }
4293 }
4294
4295 var fiber = get(component);
4296
4297 if (!fiber) {
4298 return false;
4299 }
4300
4301 return getNearestMountedFiber(fiber) === fiber;
4302 }
4303
4304 function assertIsMounted(fiber) {
4305 if (!(getNearestMountedFiber(fiber) === fiber)) {
4306 {
4307 throw Error( "Unable to find node on an unmounted component." );
4308 }
4309 }
4310 }
4311
4312 function findCurrentFiberUsingSlowPath(fiber) {
4313 var alternate = fiber.alternate;
4314
4315 if (!alternate) {
4316 // If there is no alternate, then we only need to check if it is mounted.
4317 var nearestMounted = getNearestMountedFiber(fiber);
4318
4319 if (!(nearestMounted !== null)) {
4320 {
4321 throw Error( "Unable to find node on an unmounted component." );
4322 }
4323 }
4324
4325 if (nearestMounted !== fiber) {
4326 return null;
4327 }
4328
4329 return fiber;
4330 } // If we have two possible branches, we'll walk backwards up to the root
4331 // to see what path the root points to. On the way we may hit one of the
4332 // special cases and we'll deal with them.
4333
4334
4335 var a = fiber;
4336 var b = alternate;
4337
4338 while (true) {
4339 var parentA = a.return;
4340
4341 if (parentA === null) {
4342 // We're at the root.
4343 break;
4344 }
4345
4346 var parentB = parentA.alternate;
4347
4348 if (parentB === null) {
4349 // There is no alternate. This is an unusual case. Currently, it only
4350 // happens when a Suspense component is hidden. An extra fragment fiber
4351 // is inserted in between the Suspense fiber and its children. Skip
4352 // over this extra fragment fiber and proceed to the next parent.
4353 var nextParent = parentA.return;
4354
4355 if (nextParent !== null) {
4356 a = b = nextParent;
4357 continue;
4358 } // If there's no parent, we're at the root.
4359
4360
4361 break;
4362 } // If both copies of the parent fiber point to the same child, we can
4363 // assume that the child is current. This happens when we bailout on low
4364 // priority: the bailed out fiber's child reuses the current child.
4365
4366
4367 if (parentA.child === parentB.child) {
4368 var child = parentA.child;
4369
4370 while (child) {
4371 if (child === a) {
4372 // We've determined that A is the current branch.
4373 assertIsMounted(parentA);
4374 return fiber;
4375 }
4376
4377 if (child === b) {
4378 // We've determined that B is the current branch.
4379 assertIsMounted(parentA);
4380 return alternate;
4381 }
4382
4383 child = child.sibling;
4384 } // We should never have an alternate for any mounting node. So the only
4385 // way this could possibly happen is if this was unmounted, if at all.
4386
4387
4388 {
4389 {
4390 throw Error( "Unable to find node on an unmounted component." );
4391 }
4392 }
4393 }
4394
4395 if (a.return !== b.return) {
4396 // The return pointer of A and the return pointer of B point to different
4397 // fibers. We assume that return pointers never criss-cross, so A must
4398 // belong to the child set of A.return, and B must belong to the child
4399 // set of B.return.
4400 a = parentA;
4401 b = parentB;
4402 } else {
4403 // The return pointers point to the same fiber. We'll have to use the
4404 // default, slow path: scan the child sets of each parent alternate to see
4405 // which child belongs to which set.
4406 //
4407 // Search parent A's child set
4408 var didFindChild = false;
4409 var _child = parentA.child;
4410
4411 while (_child) {
4412 if (_child === a) {
4413 didFindChild = true;
4414 a = parentA;
4415 b = parentB;
4416 break;
4417 }
4418
4419 if (_child === b) {
4420 didFindChild = true;
4421 b = parentA;
4422 a = parentB;
4423 break;
4424 }
4425
4426 _child = _child.sibling;
4427 }
4428
4429 if (!didFindChild) {
4430 // Search parent B's child set
4431 _child = parentB.child;
4432
4433 while (_child) {
4434 if (_child === a) {
4435 didFindChild = true;
4436 a = parentB;
4437 b = parentA;
4438 break;
4439 }
4440
4441 if (_child === b) {
4442 didFindChild = true;
4443 b = parentB;
4444 a = parentA;
4445 break;
4446 }
4447
4448 _child = _child.sibling;
4449 }
4450
4451 if (!didFindChild) {
4452 {
4453 throw Error( "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." );
4454 }
4455 }
4456 }
4457 }
4458
4459 if (!(a.alternate === b)) {
4460 {
4461 throw Error( "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." );
4462 }
4463 }
4464 } // If the root is not a host container, we're in a disconnected tree. I.e.
4465 // unmounted.
4466
4467
4468 if (!(a.tag === HostRoot)) {
4469 {
4470 throw Error( "Unable to find node on an unmounted component." );
4471 }
4472 }
4473
4474 if (a.stateNode.current === a) {
4475 // We've determined that A is the current branch.
4476 return fiber;
4477 } // Otherwise B has to be current branch.
4478
4479
4480 return alternate;
4481 }
4482 function findCurrentHostFiber(parent) {
4483 var currentParent = findCurrentFiberUsingSlowPath(parent);
4484
4485 if (!currentParent) {
4486 return null;
4487 } // Next we'll drill down this component to find the first HostComponent/Text.
4488
4489
4490 var node = currentParent;
4491
4492 while (true) {
4493 if (node.tag === HostComponent || node.tag === HostText) {
4494 return node;
4495 } else if (node.child) {
4496 node.child.return = node;
4497 node = node.child;
4498 continue;
4499 }
4500
4501 if (node === currentParent) {
4502 return null;
4503 }
4504
4505 while (!node.sibling) {
4506 if (!node.return || node.return === currentParent) {
4507 return null;
4508 }
4509
4510 node = node.return;
4511 }
4512
4513 node.sibling.return = node.return;
4514 node = node.sibling;
4515 } // Flow needs the return null here, but ESLint complains about it.
4516 // eslint-disable-next-line no-unreachable
4517
4518
4519 return null;
4520 }
4521 function findCurrentHostFiberWithNoPortals(parent) {
4522 var currentParent = findCurrentFiberUsingSlowPath(parent);
4523
4524 if (!currentParent) {
4525 return null;
4526 } // Next we'll drill down this component to find the first HostComponent/Text.
4527
4528
4529 var node = currentParent;
4530
4531 while (true) {
4532 if (node.tag === HostComponent || node.tag === HostText || enableFundamentalAPI ) {
4533 return node;
4534 } else if (node.child && node.tag !== HostPortal) {
4535 node.child.return = node;
4536 node = node.child;
4537 continue;
4538 }
4539
4540 if (node === currentParent) {
4541 return null;
4542 }
4543
4544 while (!node.sibling) {
4545 if (!node.return || node.return === currentParent) {
4546 return null;
4547 }
4548
4549 node = node.return;
4550 }
4551
4552 node.sibling.return = node.return;
4553 node = node.sibling;
4554 } // Flow needs the return null here, but ESLint complains about it.
4555 // eslint-disable-next-line no-unreachable
4556
4557
4558 return null;
4559 }
4560 function doesFiberContain(parentFiber, childFiber) {
4561 var node = childFiber;
4562 var parentFiberAlternate = parentFiber.alternate;
4563
4564 while (node !== null) {
4565 if (node === parentFiber || node === parentFiberAlternate) {
4566 return true;
4567 }
4568
4569 node = node.return;
4570 }
4571
4572 return false;
4573 }
4574
4575 var attemptUserBlockingHydration;
4576 function setAttemptUserBlockingHydration(fn) {
4577 attemptUserBlockingHydration = fn;
4578 }
4579 var attemptContinuousHydration;
4580 function setAttemptContinuousHydration(fn) {
4581 attemptContinuousHydration = fn;
4582 }
4583 var attemptHydrationAtCurrentPriority;
4584 function setAttemptHydrationAtCurrentPriority(fn) {
4585 attemptHydrationAtCurrentPriority = fn;
4586 }
4587 var attemptHydrationAtPriority;
4588 function setAttemptHydrationAtPriority(fn) {
4589 attemptHydrationAtPriority = fn;
4590 } // TODO: Upgrade this definition once we're on a newer version of Flow that
4591 var hasScheduledReplayAttempt = false; // The queue of discrete events to be replayed.
4592
4593 var queuedDiscreteEvents = []; // Indicates if any continuous event targets are non-null for early bailout.
4594 // if the last target was dehydrated.
4595
4596 var queuedFocus = null;
4597 var queuedDrag = null;
4598 var queuedMouse = null; // For pointer events there can be one latest event per pointerId.
4599
4600 var queuedPointers = new Map();
4601 var queuedPointerCaptures = new Map(); // We could consider replaying selectionchange and touchmoves too.
4602
4603 var queuedExplicitHydrationTargets = [];
4604 function hasQueuedDiscreteEvents() {
4605 return queuedDiscreteEvents.length > 0;
4606 }
4607 var discreteReplayableEvents = ['mousedown', 'mouseup', 'touchcancel', 'touchend', 'touchstart', 'auxclick', 'dblclick', 'pointercancel', 'pointerdown', 'pointerup', 'dragend', 'dragstart', 'drop', 'compositionend', 'compositionstart', 'keydown', 'keypress', 'keyup', 'input', 'textInput', // Intentionally camelCase
4608 'copy', 'cut', 'paste', 'click', 'change', 'contextmenu', 'reset', 'submit'];
4609 function isReplayableDiscreteEvent(eventType) {
4610 return discreteReplayableEvents.indexOf(eventType) > -1;
4611 }
4612
4613 function createQueuedReplayableEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
4614 return {
4615 blockedOn: blockedOn,
4616 domEventName: domEventName,
4617 eventSystemFlags: eventSystemFlags | IS_REPLAYED,
4618 nativeEvent: nativeEvent,
4619 targetContainers: [targetContainer]
4620 };
4621 }
4622
4623 function queueDiscreteEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
4624 var queuedEvent = createQueuedReplayableEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent);
4625 queuedDiscreteEvents.push(queuedEvent);
4626 } // Resets the replaying for this type of continuous event to no event.
4627
4628 function clearIfContinuousEvent(domEventName, nativeEvent) {
4629 switch (domEventName) {
4630 case 'focusin':
4631 case 'focusout':
4632 queuedFocus = null;
4633 break;
4634
4635 case 'dragenter':
4636 case 'dragleave':
4637 queuedDrag = null;
4638 break;
4639
4640 case 'mouseover':
4641 case 'mouseout':
4642 queuedMouse = null;
4643 break;
4644
4645 case 'pointerover':
4646 case 'pointerout':
4647 {
4648 var pointerId = nativeEvent.pointerId;
4649 queuedPointers.delete(pointerId);
4650 break;
4651 }
4652
4653 case 'gotpointercapture':
4654 case 'lostpointercapture':
4655 {
4656 var _pointerId = nativeEvent.pointerId;
4657 queuedPointerCaptures.delete(_pointerId);
4658 break;
4659 }
4660 }
4661 }
4662
4663 function accumulateOrCreateContinuousQueuedReplayableEvent(existingQueuedEvent, blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
4664 if (existingQueuedEvent === null || existingQueuedEvent.nativeEvent !== nativeEvent) {
4665 var queuedEvent = createQueuedReplayableEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent);
4666
4667 if (blockedOn !== null) {
4668 var _fiber2 = getInstanceFromNode(blockedOn);
4669
4670 if (_fiber2 !== null) {
4671 // Attempt to increase the priority of this target.
4672 attemptContinuousHydration(_fiber2);
4673 }
4674 }
4675
4676 return queuedEvent;
4677 } // If we have already queued this exact event, then it's because
4678 // the different event systems have different DOM event listeners.
4679 // We can accumulate the flags, and the targetContainers, and
4680 // store a single event to be replayed.
4681
4682
4683 existingQueuedEvent.eventSystemFlags |= eventSystemFlags;
4684 var targetContainers = existingQueuedEvent.targetContainers;
4685
4686 if (targetContainer !== null && targetContainers.indexOf(targetContainer) === -1) {
4687 targetContainers.push(targetContainer);
4688 }
4689
4690 return existingQueuedEvent;
4691 }
4692
4693 function queueIfContinuousEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
4694 // These set relatedTarget to null because the replayed event will be treated as if we
4695 // moved from outside the window (no target) onto the target once it hydrates.
4696 // Instead of mutating we could clone the event.
4697 switch (domEventName) {
4698 case 'focusin':
4699 {
4700 var focusEvent = nativeEvent;
4701 queuedFocus = accumulateOrCreateContinuousQueuedReplayableEvent(queuedFocus, blockedOn, domEventName, eventSystemFlags, targetContainer, focusEvent);
4702 return true;
4703 }
4704
4705 case 'dragenter':
4706 {
4707 var dragEvent = nativeEvent;
4708 queuedDrag = accumulateOrCreateContinuousQueuedReplayableEvent(queuedDrag, blockedOn, domEventName, eventSystemFlags, targetContainer, dragEvent);
4709 return true;
4710 }
4711
4712 case 'mouseover':
4713 {
4714 var mouseEvent = nativeEvent;
4715 queuedMouse = accumulateOrCreateContinuousQueuedReplayableEvent(queuedMouse, blockedOn, domEventName, eventSystemFlags, targetContainer, mouseEvent);
4716 return true;
4717 }
4718
4719 case 'pointerover':
4720 {
4721 var pointerEvent = nativeEvent;
4722 var pointerId = pointerEvent.pointerId;
4723 queuedPointers.set(pointerId, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointers.get(pointerId) || null, blockedOn, domEventName, eventSystemFlags, targetContainer, pointerEvent));
4724 return true;
4725 }
4726
4727 case 'gotpointercapture':
4728 {
4729 var _pointerEvent = nativeEvent;
4730 var _pointerId2 = _pointerEvent.pointerId;
4731 queuedPointerCaptures.set(_pointerId2, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointerCaptures.get(_pointerId2) || null, blockedOn, domEventName, eventSystemFlags, targetContainer, _pointerEvent));
4732 return true;
4733 }
4734 }
4735
4736 return false;
4737 } // Check if this target is unblocked. Returns true if it's unblocked.
4738
4739 function attemptExplicitHydrationTarget(queuedTarget) {
4740 // TODO: This function shares a lot of logic with attemptToDispatchEvent.
4741 // Try to unify them. It's a bit tricky since it would require two return
4742 // values.
4743 var targetInst = getClosestInstanceFromNode(queuedTarget.target);
4744
4745 if (targetInst !== null) {
4746 var nearestMounted = getNearestMountedFiber(targetInst);
4747
4748 if (nearestMounted !== null) {
4749 var tag = nearestMounted.tag;
4750
4751 if (tag === SuspenseComponent) {
4752 var instance = getSuspenseInstanceFromFiber(nearestMounted);
4753
4754 if (instance !== null) {
4755 // We're blocked on hydrating this boundary.
4756 // Increase its priority.
4757 queuedTarget.blockedOn = instance;
4758 attemptHydrationAtPriority(queuedTarget.lanePriority, function () {
4759 unstable_runWithPriority(queuedTarget.priority, function () {
4760 attemptHydrationAtCurrentPriority(nearestMounted);
4761 });
4762 });
4763 return;
4764 }
4765 } else if (tag === HostRoot) {
4766 var root = nearestMounted.stateNode;
4767
4768 if (root.hydrate) {
4769 queuedTarget.blockedOn = getContainerFromFiber(nearestMounted); // We don't currently have a way to increase the priority of
4770 // a root other than sync.
4771
4772 return;
4773 }
4774 }
4775 }
4776 }
4777
4778 queuedTarget.blockedOn = null;
4779 }
4780
4781 function attemptReplayContinuousQueuedEvent(queuedEvent) {
4782 if (queuedEvent.blockedOn !== null) {
4783 return false;
4784 }
4785
4786 var targetContainers = queuedEvent.targetContainers;
4787
4788 while (targetContainers.length > 0) {
4789 var targetContainer = targetContainers[0];
4790 var nextBlockedOn = attemptToDispatchEvent(queuedEvent.domEventName, queuedEvent.eventSystemFlags, targetContainer, queuedEvent.nativeEvent);
4791
4792 if (nextBlockedOn !== null) {
4793 // We're still blocked. Try again later.
4794 var _fiber3 = getInstanceFromNode(nextBlockedOn);
4795
4796 if (_fiber3 !== null) {
4797 attemptContinuousHydration(_fiber3);
4798 }
4799
4800 queuedEvent.blockedOn = nextBlockedOn;
4801 return false;
4802 } // This target container was successfully dispatched. Try the next.
4803
4804
4805 targetContainers.shift();
4806 }
4807
4808 return true;
4809 }
4810
4811 function attemptReplayContinuousQueuedEventInMap(queuedEvent, key, map) {
4812 if (attemptReplayContinuousQueuedEvent(queuedEvent)) {
4813 map.delete(key);
4814 }
4815 }
4816
4817 function replayUnblockedEvents() {
4818 hasScheduledReplayAttempt = false; // First replay discrete events.
4819
4820 while (queuedDiscreteEvents.length > 0) {
4821 var nextDiscreteEvent = queuedDiscreteEvents[0];
4822
4823 if (nextDiscreteEvent.blockedOn !== null) {
4824 // We're still blocked.
4825 // Increase the priority of this boundary to unblock
4826 // the next discrete event.
4827 var _fiber4 = getInstanceFromNode(nextDiscreteEvent.blockedOn);
4828
4829 if (_fiber4 !== null) {
4830 attemptUserBlockingHydration(_fiber4);
4831 }
4832
4833 break;
4834 }
4835
4836 var targetContainers = nextDiscreteEvent.targetContainers;
4837
4838 while (targetContainers.length > 0) {
4839 var targetContainer = targetContainers[0];
4840 var nextBlockedOn = attemptToDispatchEvent(nextDiscreteEvent.domEventName, nextDiscreteEvent.eventSystemFlags, targetContainer, nextDiscreteEvent.nativeEvent);
4841
4842 if (nextBlockedOn !== null) {
4843 // We're still blocked. Try again later.
4844 nextDiscreteEvent.blockedOn = nextBlockedOn;
4845 break;
4846 } // This target container was successfully dispatched. Try the next.
4847
4848
4849 targetContainers.shift();
4850 }
4851
4852 if (nextDiscreteEvent.blockedOn === null) {
4853 // We've successfully replayed the first event. Let's try the next one.
4854 queuedDiscreteEvents.shift();
4855 }
4856 } // Next replay any continuous events.
4857
4858
4859 if (queuedFocus !== null && attemptReplayContinuousQueuedEvent(queuedFocus)) {
4860 queuedFocus = null;
4861 }
4862
4863 if (queuedDrag !== null && attemptReplayContinuousQueuedEvent(queuedDrag)) {
4864 queuedDrag = null;
4865 }
4866
4867 if (queuedMouse !== null && attemptReplayContinuousQueuedEvent(queuedMouse)) {
4868 queuedMouse = null;
4869 }
4870
4871 queuedPointers.forEach(attemptReplayContinuousQueuedEventInMap);
4872 queuedPointerCaptures.forEach(attemptReplayContinuousQueuedEventInMap);
4873 }
4874
4875 function scheduleCallbackIfUnblocked(queuedEvent, unblocked) {
4876 if (queuedEvent.blockedOn === unblocked) {
4877 queuedEvent.blockedOn = null;
4878
4879 if (!hasScheduledReplayAttempt) {
4880 hasScheduledReplayAttempt = true; // Schedule a callback to attempt replaying as many events as are
4881 // now unblocked. This first might not actually be unblocked yet.
4882 // We could check it early to avoid scheduling an unnecessary callback.
4883
4884 unstable_scheduleCallback(unstable_NormalPriority, replayUnblockedEvents);
4885 }
4886 }
4887 }
4888
4889 function retryIfBlockedOn(unblocked) {
4890 // Mark anything that was blocked on this as no longer blocked
4891 // and eligible for a replay.
4892 if (queuedDiscreteEvents.length > 0) {
4893 scheduleCallbackIfUnblocked(queuedDiscreteEvents[0], unblocked); // This is a exponential search for each boundary that commits. I think it's
4894 // worth it because we expect very few discrete events to queue up and once
4895 // we are actually fully unblocked it will be fast to replay them.
4896
4897 for (var i = 1; i < queuedDiscreteEvents.length; i++) {
4898 var queuedEvent = queuedDiscreteEvents[i];
4899
4900 if (queuedEvent.blockedOn === unblocked) {
4901 queuedEvent.blockedOn = null;
4902 }
4903 }
4904 }
4905
4906 if (queuedFocus !== null) {
4907 scheduleCallbackIfUnblocked(queuedFocus, unblocked);
4908 }
4909
4910 if (queuedDrag !== null) {
4911 scheduleCallbackIfUnblocked(queuedDrag, unblocked);
4912 }
4913
4914 if (queuedMouse !== null) {
4915 scheduleCallbackIfUnblocked(queuedMouse, unblocked);
4916 }
4917
4918 var unblock = function (queuedEvent) {
4919 return scheduleCallbackIfUnblocked(queuedEvent, unblocked);
4920 };
4921
4922 queuedPointers.forEach(unblock);
4923 queuedPointerCaptures.forEach(unblock);
4924
4925 for (var _i = 0; _i < queuedExplicitHydrationTargets.length; _i++) {
4926 var queuedTarget = queuedExplicitHydrationTargets[_i];
4927
4928 if (queuedTarget.blockedOn === unblocked) {
4929 queuedTarget.blockedOn = null;
4930 }
4931 }
4932
4933 while (queuedExplicitHydrationTargets.length > 0) {
4934 var nextExplicitTarget = queuedExplicitHydrationTargets[0];
4935
4936 if (nextExplicitTarget.blockedOn !== null) {
4937 // We're still blocked.
4938 break;
4939 } else {
4940 attemptExplicitHydrationTarget(nextExplicitTarget);
4941
4942 if (nextExplicitTarget.blockedOn === null) {
4943 // We're unblocked.
4944 queuedExplicitHydrationTargets.shift();
4945 }
4946 }
4947 }
4948 }
4949
4950 var DiscreteEvent = 0;
4951 var UserBlockingEvent = 1;
4952 var ContinuousEvent = 2;
4953
4954 /**
4955 * Generate a mapping of standard vendor prefixes using the defined style property and event name.
4956 *
4957 * @param {string} styleProp
4958 * @param {string} eventName
4959 * @returns {object}
4960 */
4961
4962 function makePrefixMap(styleProp, eventName) {
4963 var prefixes = {};
4964 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
4965 prefixes['Webkit' + styleProp] = 'webkit' + eventName;
4966 prefixes['Moz' + styleProp] = 'moz' + eventName;
4967 return prefixes;
4968 }
4969 /**
4970 * A list of event names to a configurable list of vendor prefixes.
4971 */
4972
4973
4974 var vendorPrefixes = {
4975 animationend: makePrefixMap('Animation', 'AnimationEnd'),
4976 animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
4977 animationstart: makePrefixMap('Animation', 'AnimationStart'),
4978 transitionend: makePrefixMap('Transition', 'TransitionEnd')
4979 };
4980 /**
4981 * Event names that have already been detected and prefixed (if applicable).
4982 */
4983
4984 var prefixedEventNames = {};
4985 /**
4986 * Element to check for prefixes on.
4987 */
4988
4989 var style = {};
4990 /**
4991 * Bootstrap if a DOM exists.
4992 */
4993
4994 if (canUseDOM) {
4995 style = document.createElement('div').style; // On some platforms, in particular some releases of Android 4.x,
4996 // the un-prefixed "animation" and "transition" properties are defined on the
4997 // style object but the events that fire will still be prefixed, so we need
4998 // to check if the un-prefixed events are usable, and if not remove them from the map.
4999
5000 if (!('AnimationEvent' in window)) {
5001 delete vendorPrefixes.animationend.animation;
5002 delete vendorPrefixes.animationiteration.animation;
5003 delete vendorPrefixes.animationstart.animation;
5004 } // Same as above
5005
5006
5007 if (!('TransitionEvent' in window)) {
5008 delete vendorPrefixes.transitionend.transition;
5009 }
5010 }
5011 /**
5012 * Attempts to determine the correct vendor prefixed event name.
5013 *
5014 * @param {string} eventName
5015 * @returns {string}
5016 */
5017
5018
5019 function getVendorPrefixedEventName(eventName) {
5020 if (prefixedEventNames[eventName]) {
5021 return prefixedEventNames[eventName];
5022 } else if (!vendorPrefixes[eventName]) {
5023 return eventName;
5024 }
5025
5026 var prefixMap = vendorPrefixes[eventName];
5027
5028 for (var styleProp in prefixMap) {
5029 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
5030 return prefixedEventNames[eventName] = prefixMap[styleProp];
5031 }
5032 }
5033
5034 return eventName;
5035 }
5036
5037 var ANIMATION_END = getVendorPrefixedEventName('animationend');
5038 var ANIMATION_ITERATION = getVendorPrefixedEventName('animationiteration');
5039 var ANIMATION_START = getVendorPrefixedEventName('animationstart');
5040 var TRANSITION_END = getVendorPrefixedEventName('transitionend');
5041
5042 var topLevelEventsToReactNames = new Map();
5043 var eventPriorities = new Map(); // We store most of the events in this module in pairs of two strings so we can re-use
5044 // the code required to apply the same logic for event prioritization and that of the
5045 // SimpleEventPlugin. This complicates things slightly, but the aim is to reduce code
5046 // duplication (for which there would be quite a bit). For the events that are not needed
5047 // for the SimpleEventPlugin (otherDiscreteEvents) we process them separately as an
5048 // array of top level events.
5049 // Lastly, we ignore prettier so we can keep the formatting sane.
5050 // prettier-ignore
5051
5052 var discreteEventPairsForSimpleEventPlugin = ['cancel', 'cancel', 'click', 'click', 'close', 'close', 'contextmenu', 'contextMenu', 'copy', 'copy', 'cut', 'cut', 'auxclick', 'auxClick', 'dblclick', 'doubleClick', // Careful!
5053 'dragend', 'dragEnd', 'dragstart', 'dragStart', 'drop', 'drop', 'focusin', 'focus', // Careful!
5054 'focusout', 'blur', // Careful!
5055 'input', 'input', 'invalid', 'invalid', 'keydown', 'keyDown', 'keypress', 'keyPress', 'keyup', 'keyUp', 'mousedown', 'mouseDown', 'mouseup', 'mouseUp', 'paste', 'paste', 'pause', 'pause', 'play', 'play', 'pointercancel', 'pointerCancel', 'pointerdown', 'pointerDown', 'pointerup', 'pointerUp', 'ratechange', 'rateChange', 'reset', 'reset', 'seeked', 'seeked', 'submit', 'submit', 'touchcancel', 'touchCancel', 'touchend', 'touchEnd', 'touchstart', 'touchStart', 'volumechange', 'volumeChange'];
5056 var otherDiscreteEvents = ['change', 'selectionchange', 'textInput', 'compositionstart', 'compositionend', 'compositionupdate'];
5057
5058
5059 var userBlockingPairsForSimpleEventPlugin = ['drag', 'drag', 'dragenter', 'dragEnter', 'dragexit', 'dragExit', 'dragleave', 'dragLeave', 'dragover', 'dragOver', 'mousemove', 'mouseMove', 'mouseout', 'mouseOut', 'mouseover', 'mouseOver', 'pointermove', 'pointerMove', 'pointerout', 'pointerOut', 'pointerover', 'pointerOver', 'scroll', 'scroll', 'toggle', 'toggle', 'touchmove', 'touchMove', 'wheel', 'wheel']; // prettier-ignore
5060
5061 var continuousPairsForSimpleEventPlugin = ['abort', 'abort', ANIMATION_END, 'animationEnd', ANIMATION_ITERATION, 'animationIteration', ANIMATION_START, 'animationStart', 'canplay', 'canPlay', 'canplaythrough', 'canPlayThrough', 'durationchange', 'durationChange', 'emptied', 'emptied', 'encrypted', 'encrypted', 'ended', 'ended', 'error', 'error', 'gotpointercapture', 'gotPointerCapture', 'load', 'load', 'loadeddata', 'loadedData', 'loadedmetadata', 'loadedMetadata', 'loadstart', 'loadStart', 'lostpointercapture', 'lostPointerCapture', 'playing', 'playing', 'progress', 'progress', 'seeking', 'seeking', 'stalled', 'stalled', 'suspend', 'suspend', 'timeupdate', 'timeUpdate', TRANSITION_END, 'transitionEnd', 'waiting', 'waiting'];
5062 /**
5063 * Turns
5064 * ['abort', ...]
5065 *
5066 * into
5067 *
5068 * topLevelEventsToReactNames = new Map([
5069 * ['abort', 'onAbort'],
5070 * ]);
5071 *
5072 * and registers them.
5073 */
5074
5075 function registerSimplePluginEventsAndSetTheirPriorities(eventTypes, priority) {
5076 // As the event types are in pairs of two, we need to iterate
5077 // through in twos. The events are in pairs of two to save code
5078 // and improve init perf of processing this array, as it will
5079 // result in far fewer object allocations and property accesses
5080 // if we only use three arrays to process all the categories of
5081 // instead of tuples.
5082 for (var i = 0; i < eventTypes.length; i += 2) {
5083 var topEvent = eventTypes[i];
5084 var event = eventTypes[i + 1];
5085 var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
5086 var reactName = 'on' + capitalizedEvent;
5087 eventPriorities.set(topEvent, priority);
5088 topLevelEventsToReactNames.set(topEvent, reactName);
5089 registerTwoPhaseEvent(reactName, [topEvent]);
5090 }
5091 }
5092
5093 function setEventPriorities(eventTypes, priority) {
5094 for (var i = 0; i < eventTypes.length; i++) {
5095 eventPriorities.set(eventTypes[i], priority);
5096 }
5097 }
5098
5099 function getEventPriorityForPluginSystem(domEventName) {
5100 var priority = eventPriorities.get(domEventName); // Default to a ContinuousEvent. Note: we might
5101 // want to warn if we can't detect the priority
5102 // for the event.
5103
5104 return priority === undefined ? ContinuousEvent : priority;
5105 }
5106 function registerSimpleEvents() {
5107 registerSimplePluginEventsAndSetTheirPriorities(discreteEventPairsForSimpleEventPlugin, DiscreteEvent);
5108 registerSimplePluginEventsAndSetTheirPriorities(userBlockingPairsForSimpleEventPlugin, UserBlockingEvent);
5109 registerSimplePluginEventsAndSetTheirPriorities(continuousPairsForSimpleEventPlugin, ContinuousEvent);
5110 setEventPriorities(otherDiscreteEvents, DiscreteEvent);
5111 }
5112
5113 var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
5114 var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing,
5115 __interactionsRef = _ReactInternals$Sched$1.__interactionsRef,
5116 __subscriberRef = _ReactInternals$Sched$1.__subscriberRef,
5117 unstable_clear = _ReactInternals$Sched$1.unstable_clear,
5118 unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent,
5119 unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID,
5120 unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe,
5121 unstable_trace = _ReactInternals$Sched$1.unstable_trace,
5122 unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe,
5123 unstable_wrap = _ReactInternals$Sched$1.unstable_wrap;
5124
5125 var Scheduler_now = unstable_now;
5126
5127 {
5128 // Provide explicit error message when production+profiling bundle of e.g.
5129 // react-dom is used with production (non-profiling) bundle of
5130 // scheduler/tracing
5131 if (!(__interactionsRef != null && __interactionsRef.current != null)) {
5132 {
5133 throw Error( "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" );
5134 }
5135 }
5136 }
5137 // ascending numbers so we can compare them like numbers. They start at 90 to
5138 // avoid clashing with Scheduler's priorities.
5139
5140 var ImmediatePriority = 99;
5141 var UserBlockingPriority = 98;
5142 var NormalPriority = 97;
5143 var LowPriority = 96;
5144 var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only.
5145
5146 var NoPriority = 90;
5147 var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly.
5148
5149 var SyncLanePriority = 15;
5150 var SyncBatchedLanePriority = 14;
5151 var InputDiscreteHydrationLanePriority = 13;
5152 var InputDiscreteLanePriority = 12;
5153 var InputContinuousHydrationLanePriority = 11;
5154 var InputContinuousLanePriority = 10;
5155 var DefaultHydrationLanePriority = 9;
5156 var DefaultLanePriority = 8;
5157 var TransitionHydrationPriority = 7;
5158 var TransitionPriority = 6;
5159 var RetryLanePriority = 5;
5160 var SelectiveHydrationLanePriority = 4;
5161 var IdleHydrationLanePriority = 3;
5162 var IdleLanePriority = 2;
5163 var OffscreenLanePriority = 1;
5164 var NoLanePriority = 0;
5165 var TotalLanes = 31;
5166 var NoLanes =
5167 /* */
5168 0;
5169 var NoLane =
5170 /* */
5171 0;
5172 var SyncLane =
5173 /* */
5174 1;
5175 var SyncBatchedLane =
5176 /* */
5177 2;
5178 var InputDiscreteHydrationLane =
5179 /* */
5180 4;
5181 var InputDiscreteLanes =
5182 /* */
5183 24;
5184 var InputContinuousHydrationLane =
5185 /* */
5186 32;
5187 var InputContinuousLanes =
5188 /* */
5189 192;
5190 var DefaultHydrationLane =
5191 /* */
5192 256;
5193 var DefaultLanes =
5194 /* */
5195 3584;
5196 var TransitionHydrationLane =
5197 /* */
5198 4096;
5199 var TransitionLanes =
5200 /* */
5201 4186112;
5202 var RetryLanes =
5203 /* */
5204 62914560;
5205 var SomeRetryLane =
5206 /* */
5207 33554432;
5208 var SelectiveHydrationLane =
5209 /* */
5210 67108864;
5211 var NonIdleLanes =
5212 /* */
5213 134217727;
5214 var IdleHydrationLane =
5215 /* */
5216 134217728;
5217 var IdleLanes =
5218 /* */
5219 805306368;
5220 var OffscreenLane =
5221 /* */
5222 1073741824;
5223 var NoTimestamp = -1;
5224 function setCurrentUpdateLanePriority(newLanePriority) {
5225 } // "Registers" used to "return" multiple values
5226 // Used by getHighestPriorityLanes and getNextLanes:
5227
5228 var return_highestLanePriority = DefaultLanePriority;
5229
5230 function getHighestPriorityLanes(lanes) {
5231 if ((SyncLane & lanes) !== NoLanes) {
5232 return_highestLanePriority = SyncLanePriority;
5233 return SyncLane;
5234 }
5235
5236 if ((SyncBatchedLane & lanes) !== NoLanes) {
5237 return_highestLanePriority = SyncBatchedLanePriority;
5238 return SyncBatchedLane;
5239 }
5240
5241 if ((InputDiscreteHydrationLane & lanes) !== NoLanes) {
5242 return_highestLanePriority = InputDiscreteHydrationLanePriority;
5243 return InputDiscreteHydrationLane;
5244 }
5245
5246 var inputDiscreteLanes = InputDiscreteLanes & lanes;
5247
5248 if (inputDiscreteLanes !== NoLanes) {
5249 return_highestLanePriority = InputDiscreteLanePriority;
5250 return inputDiscreteLanes;
5251 }
5252
5253 if ((lanes & InputContinuousHydrationLane) !== NoLanes) {
5254 return_highestLanePriority = InputContinuousHydrationLanePriority;
5255 return InputContinuousHydrationLane;
5256 }
5257
5258 var inputContinuousLanes = InputContinuousLanes & lanes;
5259
5260 if (inputContinuousLanes !== NoLanes) {
5261 return_highestLanePriority = InputContinuousLanePriority;
5262 return inputContinuousLanes;
5263 }
5264
5265 if ((lanes & DefaultHydrationLane) !== NoLanes) {
5266 return_highestLanePriority = DefaultHydrationLanePriority;
5267 return DefaultHydrationLane;
5268 }
5269
5270 var defaultLanes = DefaultLanes & lanes;
5271
5272 if (defaultLanes !== NoLanes) {
5273 return_highestLanePriority = DefaultLanePriority;
5274 return defaultLanes;
5275 }
5276
5277 if ((lanes & TransitionHydrationLane) !== NoLanes) {
5278 return_highestLanePriority = TransitionHydrationPriority;
5279 return TransitionHydrationLane;
5280 }
5281
5282 var transitionLanes = TransitionLanes & lanes;
5283
5284 if (transitionLanes !== NoLanes) {
5285 return_highestLanePriority = TransitionPriority;
5286 return transitionLanes;
5287 }
5288
5289 var retryLanes = RetryLanes & lanes;
5290
5291 if (retryLanes !== NoLanes) {
5292 return_highestLanePriority = RetryLanePriority;
5293 return retryLanes;
5294 }
5295
5296 if (lanes & SelectiveHydrationLane) {
5297 return_highestLanePriority = SelectiveHydrationLanePriority;
5298 return SelectiveHydrationLane;
5299 }
5300
5301 if ((lanes & IdleHydrationLane) !== NoLanes) {
5302 return_highestLanePriority = IdleHydrationLanePriority;
5303 return IdleHydrationLane;
5304 }
5305
5306 var idleLanes = IdleLanes & lanes;
5307
5308 if (idleLanes !== NoLanes) {
5309 return_highestLanePriority = IdleLanePriority;
5310 return idleLanes;
5311 }
5312
5313 if ((OffscreenLane & lanes) !== NoLanes) {
5314 return_highestLanePriority = OffscreenLanePriority;
5315 return OffscreenLane;
5316 }
5317
5318 {
5319 error('Should have found matching lanes. This is a bug in React.');
5320 } // This shouldn't be reachable, but as a fallback, return the entire bitmask.
5321
5322
5323 return_highestLanePriority = DefaultLanePriority;
5324 return lanes;
5325 }
5326
5327 function schedulerPriorityToLanePriority(schedulerPriorityLevel) {
5328 switch (schedulerPriorityLevel) {
5329 case ImmediatePriority:
5330 return SyncLanePriority;
5331
5332 case UserBlockingPriority:
5333 return InputContinuousLanePriority;
5334
5335 case NormalPriority:
5336 case LowPriority:
5337 // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration.
5338 return DefaultLanePriority;
5339
5340 case IdlePriority:
5341 return IdleLanePriority;
5342
5343 default:
5344 return NoLanePriority;
5345 }
5346 }
5347 function lanePriorityToSchedulerPriority(lanePriority) {
5348 switch (lanePriority) {
5349 case SyncLanePriority:
5350 case SyncBatchedLanePriority:
5351 return ImmediatePriority;
5352
5353 case InputDiscreteHydrationLanePriority:
5354 case InputDiscreteLanePriority:
5355 case InputContinuousHydrationLanePriority:
5356 case InputContinuousLanePriority:
5357 return UserBlockingPriority;
5358
5359 case DefaultHydrationLanePriority:
5360 case DefaultLanePriority:
5361 case TransitionHydrationPriority:
5362 case TransitionPriority:
5363 case SelectiveHydrationLanePriority:
5364 case RetryLanePriority:
5365 return NormalPriority;
5366
5367 case IdleHydrationLanePriority:
5368 case IdleLanePriority:
5369 case OffscreenLanePriority:
5370 return IdlePriority;
5371
5372 case NoLanePriority:
5373 return NoPriority;
5374
5375 default:
5376 {
5377 {
5378 throw Error( "Invalid update priority: " + lanePriority + ". This is a bug in React." );
5379 }
5380 }
5381
5382 }
5383 }
5384 function getNextLanes(root, wipLanes) {
5385 // Early bailout if there's no pending work left.
5386 var pendingLanes = root.pendingLanes;
5387
5388 if (pendingLanes === NoLanes) {
5389 return_highestLanePriority = NoLanePriority;
5390 return NoLanes;
5391 }
5392
5393 var nextLanes = NoLanes;
5394 var nextLanePriority = NoLanePriority;
5395 var expiredLanes = root.expiredLanes;
5396 var suspendedLanes = root.suspendedLanes;
5397 var pingedLanes = root.pingedLanes; // Check if any work has expired.
5398
5399 if (expiredLanes !== NoLanes) {
5400 nextLanes = expiredLanes;
5401 nextLanePriority = return_highestLanePriority = SyncLanePriority;
5402 } else {
5403 // Do not work on any idle work until all the non-idle work has finished,
5404 // even if the work is suspended.
5405 var nonIdlePendingLanes = pendingLanes & NonIdleLanes;
5406
5407 if (nonIdlePendingLanes !== NoLanes) {
5408 var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes;
5409
5410 if (nonIdleUnblockedLanes !== NoLanes) {
5411 nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes);
5412 nextLanePriority = return_highestLanePriority;
5413 } else {
5414 var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes;
5415
5416 if (nonIdlePingedLanes !== NoLanes) {
5417 nextLanes = getHighestPriorityLanes(nonIdlePingedLanes);
5418 nextLanePriority = return_highestLanePriority;
5419 }
5420 }
5421 } else {
5422 // The only remaining work is Idle.
5423 var unblockedLanes = pendingLanes & ~suspendedLanes;
5424
5425 if (unblockedLanes !== NoLanes) {
5426 nextLanes = getHighestPriorityLanes(unblockedLanes);
5427 nextLanePriority = return_highestLanePriority;
5428 } else {
5429 if (pingedLanes !== NoLanes) {
5430 nextLanes = getHighestPriorityLanes(pingedLanes);
5431 nextLanePriority = return_highestLanePriority;
5432 }
5433 }
5434 }
5435 }
5436
5437 if (nextLanes === NoLanes) {
5438 // This should only be reachable if we're suspended
5439 // TODO: Consider warning in this path if a fallback timer is not scheduled.
5440 return NoLanes;
5441 } // If there are higher priority lanes, we'll include them even if they
5442 // are suspended.
5443
5444
5445 nextLanes = pendingLanes & getEqualOrHigherPriorityLanes(nextLanes); // If we're already in the middle of a render, switching lanes will interrupt
5446 // it and we'll lose our progress. We should only do this if the new lanes are
5447 // higher priority.
5448
5449 if (wipLanes !== NoLanes && wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't
5450 // bother waiting until the root is complete.
5451 (wipLanes & suspendedLanes) === NoLanes) {
5452 getHighestPriorityLanes(wipLanes);
5453 var wipLanePriority = return_highestLanePriority;
5454
5455 if (nextLanePriority <= wipLanePriority) {
5456 return wipLanes;
5457 } else {
5458 return_highestLanePriority = nextLanePriority;
5459 }
5460 } // Check for entangled lanes and add them to the batch.
5461 //
5462 // A lane is said to be entangled with another when it's not allowed to render
5463 // in a batch that does not also include the other lane. Typically we do this
5464 // when multiple updates have the same source, and we only want to respond to
5465 // the most recent event from that source.
5466 //
5467 // Note that we apply entanglements *after* checking for partial work above.
5468 // This means that if a lane is entangled during an interleaved event while
5469 // it's already rendering, we won't interrupt it. This is intentional, since
5470 // entanglement is usually "best effort": we'll try our best to render the
5471 // lanes in the same batch, but it's not worth throwing out partially
5472 // completed work in order to do it.
5473 //
5474 // For those exceptions where entanglement is semantically important, like
5475 // useMutableSource, we should ensure that there is no partial work at the
5476 // time we apply the entanglement.
5477
5478
5479 var entangledLanes = root.entangledLanes;
5480
5481 if (entangledLanes !== NoLanes) {
5482 var entanglements = root.entanglements;
5483 var lanes = nextLanes & entangledLanes;
5484
5485 while (lanes > 0) {
5486 var index = pickArbitraryLaneIndex(lanes);
5487 var lane = 1 << index;
5488 nextLanes |= entanglements[index];
5489 lanes &= ~lane;
5490 }
5491 }
5492
5493 return nextLanes;
5494 }
5495 function getMostRecentEventTime(root, lanes) {
5496 var eventTimes = root.eventTimes;
5497 var mostRecentEventTime = NoTimestamp;
5498
5499 while (lanes > 0) {
5500 var index = pickArbitraryLaneIndex(lanes);
5501 var lane = 1 << index;
5502 var eventTime = eventTimes[index];
5503
5504 if (eventTime > mostRecentEventTime) {
5505 mostRecentEventTime = eventTime;
5506 }
5507
5508 lanes &= ~lane;
5509 }
5510
5511 return mostRecentEventTime;
5512 }
5513
5514 function computeExpirationTime(lane, currentTime) {
5515 // TODO: Expiration heuristic is constant per lane, so could use a map.
5516 getHighestPriorityLanes(lane);
5517 var priority = return_highestLanePriority;
5518
5519 if (priority >= InputContinuousLanePriority) {
5520 // User interactions should expire slightly more quickly.
5521 //
5522 // NOTE: This is set to the corresponding constant as in Scheduler.js. When
5523 // we made it larger, a product metric in www regressed, suggesting there's
5524 // a user interaction that's being starved by a series of synchronous
5525 // updates. If that theory is correct, the proper solution is to fix the
5526 // starvation. However, this scenario supports the idea that expiration
5527 // times are an important safeguard when starvation does happen.
5528 //
5529 // Also note that, in the case of user input specifically, this will soon no
5530 // longer be an issue because we plan to make user input synchronous by
5531 // default (until you enter `startTransition`, of course.)
5532 //
5533 // If weren't planning to make these updates synchronous soon anyway, I
5534 // would probably make this number a configurable parameter.
5535 return currentTime + 250;
5536 } else if (priority >= TransitionPriority) {
5537 return currentTime + 5000;
5538 } else {
5539 // Anything idle priority or lower should never expire.
5540 return NoTimestamp;
5541 }
5542 }
5543
5544 function markStarvedLanesAsExpired(root, currentTime) {
5545 // TODO: This gets called every time we yield. We can optimize by storing
5546 // the earliest expiration time on the root. Then use that to quickly bail out
5547 // of this function.
5548 var pendingLanes = root.pendingLanes;
5549 var suspendedLanes = root.suspendedLanes;
5550 var pingedLanes = root.pingedLanes;
5551 var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their
5552 // expiration time. If so, we'll assume the update is being starved and mark
5553 // it as expired to force it to finish.
5554
5555 var lanes = pendingLanes;
5556
5557 while (lanes > 0) {
5558 var index = pickArbitraryLaneIndex(lanes);
5559 var lane = 1 << index;
5560 var expirationTime = expirationTimes[index];
5561
5562 if (expirationTime === NoTimestamp) {
5563 // Found a pending lane with no expiration time. If it's not suspended, or
5564 // if it's pinged, assume it's CPU-bound. Compute a new expiration time
5565 // using the current time.
5566 if ((lane & suspendedLanes) === NoLanes || (lane & pingedLanes) !== NoLanes) {
5567 // Assumes timestamps are monotonically increasing.
5568 expirationTimes[index] = computeExpirationTime(lane, currentTime);
5569 }
5570 } else if (expirationTime <= currentTime) {
5571 // This lane expired
5572 root.expiredLanes |= lane;
5573 }
5574
5575 lanes &= ~lane;
5576 }
5577 } // This returns the highest priority pending lanes regardless of whether they
5578 function getLanesToRetrySynchronouslyOnError(root) {
5579 var everythingButOffscreen = root.pendingLanes & ~OffscreenLane;
5580
5581 if (everythingButOffscreen !== NoLanes) {
5582 return everythingButOffscreen;
5583 }
5584
5585 if (everythingButOffscreen & OffscreenLane) {
5586 return OffscreenLane;
5587 }
5588
5589 return NoLanes;
5590 }
5591 function returnNextLanesPriority() {
5592 return return_highestLanePriority;
5593 }
5594 function includesNonIdleWork(lanes) {
5595 return (lanes & NonIdleLanes) !== NoLanes;
5596 }
5597 function includesOnlyRetries(lanes) {
5598 return (lanes & RetryLanes) === lanes;
5599 }
5600 function includesOnlyTransitions(lanes) {
5601 return (lanes & TransitionLanes) === lanes;
5602 } // To ensure consistency across multiple updates in the same event, this should
5603 // be a pure function, so that it always returns the same lane for given inputs.
5604
5605 function findUpdateLane(lanePriority, wipLanes) {
5606 switch (lanePriority) {
5607 case NoLanePriority:
5608 break;
5609
5610 case SyncLanePriority:
5611 return SyncLane;
5612
5613 case SyncBatchedLanePriority:
5614 return SyncBatchedLane;
5615
5616 case InputDiscreteLanePriority:
5617 {
5618 var _lane = pickArbitraryLane(InputDiscreteLanes & ~wipLanes);
5619
5620 if (_lane === NoLane) {
5621 // Shift to the next priority level
5622 return findUpdateLane(InputContinuousLanePriority, wipLanes);
5623 }
5624
5625 return _lane;
5626 }
5627
5628 case InputContinuousLanePriority:
5629 {
5630 var _lane2 = pickArbitraryLane(InputContinuousLanes & ~wipLanes);
5631
5632 if (_lane2 === NoLane) {
5633 // Shift to the next priority level
5634 return findUpdateLane(DefaultLanePriority, wipLanes);
5635 }
5636
5637 return _lane2;
5638 }
5639
5640 case DefaultLanePriority:
5641 {
5642 var _lane3 = pickArbitraryLane(DefaultLanes & ~wipLanes);
5643
5644 if (_lane3 === NoLane) {
5645 // If all the default lanes are already being worked on, look for a
5646 // lane in the transition range.
5647 _lane3 = pickArbitraryLane(TransitionLanes & ~wipLanes);
5648
5649 if (_lane3 === NoLane) {
5650 // All the transition lanes are taken, too. This should be very
5651 // rare, but as a last resort, pick a default lane. This will have
5652 // the effect of interrupting the current work-in-progress render.
5653 _lane3 = pickArbitraryLane(DefaultLanes);
5654 }
5655 }
5656
5657 return _lane3;
5658 }
5659
5660 case TransitionPriority: // Should be handled by findTransitionLane instead
5661
5662 case RetryLanePriority:
5663 // Should be handled by findRetryLane instead
5664 break;
5665
5666 case IdleLanePriority:
5667 var lane = pickArbitraryLane(IdleLanes & ~wipLanes);
5668
5669 if (lane === NoLane) {
5670 lane = pickArbitraryLane(IdleLanes);
5671 }
5672
5673 return lane;
5674 }
5675
5676 {
5677 {
5678 throw Error( "Invalid update priority: " + lanePriority + ". This is a bug in React." );
5679 }
5680 }
5681 } // To ensure consistency across multiple updates in the same event, this should
5682 // be pure function, so that it always returns the same lane for given inputs.
5683
5684 function findTransitionLane(wipLanes, pendingLanes) {
5685 // First look for lanes that are completely unclaimed, i.e. have no
5686 // pending work.
5687 var lane = pickArbitraryLane(TransitionLanes & ~pendingLanes);
5688
5689 if (lane === NoLane) {
5690 // If all lanes have pending work, look for a lane that isn't currently
5691 // being worked on.
5692 lane = pickArbitraryLane(TransitionLanes & ~wipLanes);
5693
5694 if (lane === NoLane) {
5695 // If everything is being worked on, pick any lane. This has the
5696 // effect of interrupting the current work-in-progress.
5697 lane = pickArbitraryLane(TransitionLanes);
5698 }
5699 }
5700
5701 return lane;
5702 } // To ensure consistency across multiple updates in the same event, this should
5703 // be pure function, so that it always returns the same lane for given inputs.
5704
5705 function findRetryLane(wipLanes) {
5706 // This is a fork of `findUpdateLane` designed specifically for Suspense
5707 // "retries" — a special update that attempts to flip a Suspense boundary
5708 // from its placeholder state to its primary/resolved state.
5709 var lane = pickArbitraryLane(RetryLanes & ~wipLanes);
5710
5711 if (lane === NoLane) {
5712 lane = pickArbitraryLane(RetryLanes);
5713 }
5714
5715 return lane;
5716 }
5717
5718 function getHighestPriorityLane(lanes) {
5719 return lanes & -lanes;
5720 }
5721
5722 function getLowestPriorityLane(lanes) {
5723 // This finds the most significant non-zero bit.
5724 var index = 31 - clz32(lanes);
5725 return index < 0 ? NoLanes : 1 << index;
5726 }
5727
5728 function getEqualOrHigherPriorityLanes(lanes) {
5729 return (getLowestPriorityLane(lanes) << 1) - 1;
5730 }
5731
5732 function pickArbitraryLane(lanes) {
5733 // This wrapper function gets inlined. Only exists so to communicate that it
5734 // doesn't matter which bit is selected; you can pick any bit without
5735 // affecting the algorithms where its used. Here I'm using
5736 // getHighestPriorityLane because it requires the fewest operations.
5737 return getHighestPriorityLane(lanes);
5738 }
5739
5740 function pickArbitraryLaneIndex(lanes) {
5741 return 31 - clz32(lanes);
5742 }
5743
5744 function laneToIndex(lane) {
5745 return pickArbitraryLaneIndex(lane);
5746 }
5747
5748 function includesSomeLane(a, b) {
5749 return (a & b) !== NoLanes;
5750 }
5751 function isSubsetOfLanes(set, subset) {
5752 return (set & subset) === subset;
5753 }
5754 function mergeLanes(a, b) {
5755 return a | b;
5756 }
5757 function removeLanes(set, subset) {
5758 return set & ~subset;
5759 } // Seems redundant, but it changes the type from a single lane (used for
5760 // updates) to a group of lanes (used for flushing work).
5761
5762 function laneToLanes(lane) {
5763 return lane;
5764 }
5765 function higherPriorityLane(a, b) {
5766 // This works because the bit ranges decrease in priority as you go left.
5767 return a !== NoLane && a < b ? a : b;
5768 }
5769 function createLaneMap(initial) {
5770 // Intentionally pushing one by one.
5771 // https://v8.dev/blog/elements-kinds#avoid-creating-holes
5772 var laneMap = [];
5773
5774 for (var i = 0; i < TotalLanes; i++) {
5775 laneMap.push(initial);
5776 }
5777
5778 return laneMap;
5779 }
5780 function markRootUpdated(root, updateLane, eventTime) {
5781 root.pendingLanes |= updateLane; // TODO: Theoretically, any update to any lane can unblock any other lane. But
5782 // it's not practical to try every single possible combination. We need a
5783 // heuristic to decide which lanes to attempt to render, and in which batches.
5784 // For now, we use the same heuristic as in the old ExpirationTimes model:
5785 // retry any lane at equal or lower priority, but don't try updates at higher
5786 // priority without also including the lower priority updates. This works well
5787 // when considering updates across different priority levels, but isn't
5788 // sufficient for updates within the same priority, since we want to treat
5789 // those updates as parallel.
5790 // Unsuspend any update at equal or lower priority.
5791
5792 var higherPriorityLanes = updateLane - 1; // Turns 0b1000 into 0b0111
5793
5794 root.suspendedLanes &= higherPriorityLanes;
5795 root.pingedLanes &= higherPriorityLanes;
5796 var eventTimes = root.eventTimes;
5797 var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most
5798 // recent event, and we assume time is monotonically increasing.
5799
5800 eventTimes[index] = eventTime;
5801 }
5802 function markRootSuspended(root, suspendedLanes) {
5803 root.suspendedLanes |= suspendedLanes;
5804 root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times.
5805
5806 var expirationTimes = root.expirationTimes;
5807 var lanes = suspendedLanes;
5808
5809 while (lanes > 0) {
5810 var index = pickArbitraryLaneIndex(lanes);
5811 var lane = 1 << index;
5812 expirationTimes[index] = NoTimestamp;
5813 lanes &= ~lane;
5814 }
5815 }
5816 function markRootPinged(root, pingedLanes, eventTime) {
5817 root.pingedLanes |= root.suspendedLanes & pingedLanes;
5818 }
5819 function markDiscreteUpdatesExpired(root) {
5820 root.expiredLanes |= InputDiscreteLanes & root.pendingLanes;
5821 }
5822 function hasDiscreteLanes(lanes) {
5823 return (lanes & InputDiscreteLanes) !== NoLanes;
5824 }
5825 function markRootMutableRead(root, updateLane) {
5826 root.mutableReadLanes |= updateLane & root.pendingLanes;
5827 }
5828 function markRootFinished(root, remainingLanes) {
5829 var noLongerPendingLanes = root.pendingLanes & ~remainingLanes;
5830 root.pendingLanes = remainingLanes; // Let's try everything again
5831
5832 root.suspendedLanes = 0;
5833 root.pingedLanes = 0;
5834 root.expiredLanes &= remainingLanes;
5835 root.mutableReadLanes &= remainingLanes;
5836 root.entangledLanes &= remainingLanes;
5837 var entanglements = root.entanglements;
5838 var eventTimes = root.eventTimes;
5839 var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work
5840
5841 var lanes = noLongerPendingLanes;
5842
5843 while (lanes > 0) {
5844 var index = pickArbitraryLaneIndex(lanes);
5845 var lane = 1 << index;
5846 entanglements[index] = NoLanes;
5847 eventTimes[index] = NoTimestamp;
5848 expirationTimes[index] = NoTimestamp;
5849 lanes &= ~lane;
5850 }
5851 }
5852 function markRootEntangled(root, entangledLanes) {
5853 root.entangledLanes |= entangledLanes;
5854 var entanglements = root.entanglements;
5855 var lanes = entangledLanes;
5856
5857 while (lanes > 0) {
5858 var index = pickArbitraryLaneIndex(lanes);
5859 var lane = 1 << index;
5860 entanglements[index] |= entangledLanes;
5861 lanes &= ~lane;
5862 }
5863 }
5864 var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. Only used on lanes, so assume input is an integer.
5865 // Based on:
5866 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
5867
5868 var log = Math.log;
5869 var LN2 = Math.LN2;
5870
5871 function clz32Fallback(lanes) {
5872 if (lanes === 0) {
5873 return 32;
5874 }
5875
5876 return 31 - (log(lanes) / LN2 | 0) | 0;
5877 }
5878
5879 // Intentionally not named imports because Rollup would use dynamic dispatch for
5880 var UserBlockingPriority$1 = unstable_UserBlockingPriority,
5881 runWithPriority = unstable_runWithPriority; // TODO: can we stop exporting these?
5882
5883 var _enabled = true; // This is exported in FB builds for use by legacy FB layer infra.
5884 // We'd like to remove this but it's not clear if this is safe.
5885
5886 function setEnabled(enabled) {
5887 _enabled = !!enabled;
5888 }
5889 function isEnabled() {
5890 return _enabled;
5891 }
5892 function createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags) {
5893 var eventPriority = getEventPriorityForPluginSystem(domEventName);
5894 var listenerWrapper;
5895
5896 switch (eventPriority) {
5897 case DiscreteEvent:
5898 listenerWrapper = dispatchDiscreteEvent;
5899 break;
5900
5901 case UserBlockingEvent:
5902 listenerWrapper = dispatchUserBlockingUpdate;
5903 break;
5904
5905 case ContinuousEvent:
5906 default:
5907 listenerWrapper = dispatchEvent;
5908 break;
5909 }
5910
5911 return listenerWrapper.bind(null, domEventName, eventSystemFlags, targetContainer);
5912 }
5913
5914 function dispatchDiscreteEvent(domEventName, eventSystemFlags, container, nativeEvent) {
5915 {
5916 flushDiscreteUpdatesIfNeeded(nativeEvent.timeStamp);
5917 }
5918
5919 discreteUpdates(dispatchEvent, domEventName, eventSystemFlags, container, nativeEvent);
5920 }
5921
5922 function dispatchUserBlockingUpdate(domEventName, eventSystemFlags, container, nativeEvent) {
5923 {
5924 runWithPriority(UserBlockingPriority$1, dispatchEvent.bind(null, domEventName, eventSystemFlags, container, nativeEvent));
5925 }
5926 }
5927
5928 function dispatchEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent) {
5929 if (!_enabled) {
5930 return;
5931 }
5932
5933 var allowReplay = true;
5934
5935 {
5936 // TODO: replaying capture phase events is currently broken
5937 // because we used to do it during top-level native bubble handlers
5938 // but now we use different bubble and capture handlers.
5939 // In eager mode, we attach capture listeners early, so we need
5940 // to filter them out until we fix the logic to handle them correctly.
5941 // This could've been outside the flag but I put it inside to reduce risk.
5942 allowReplay = (eventSystemFlags & IS_CAPTURE_PHASE) === 0;
5943 }
5944
5945 if (allowReplay && hasQueuedDiscreteEvents() && isReplayableDiscreteEvent(domEventName)) {
5946 // If we already have a queue of discrete events, and this is another discrete
5947 // event, then we can't dispatch it regardless of its target, since they
5948 // need to dispatch in order.
5949 queueDiscreteEvent(null, // Flags that we're not actually blocked on anything as far as we know.
5950 domEventName, eventSystemFlags, targetContainer, nativeEvent);
5951 return;
5952 }
5953
5954 var blockedOn = attemptToDispatchEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent);
5955
5956 if (blockedOn === null) {
5957 // We successfully dispatched this event.
5958 if (allowReplay) {
5959 clearIfContinuousEvent(domEventName, nativeEvent);
5960 }
5961
5962 return;
5963 }
5964
5965 if (allowReplay) {
5966 if (isReplayableDiscreteEvent(domEventName)) {
5967 // This this to be replayed later once the target is available.
5968 queueDiscreteEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent);
5969 return;
5970 }
5971
5972 if (queueIfContinuousEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent)) {
5973 return;
5974 } // We need to clear only if we didn't queue because
5975 // queueing is accummulative.
5976
5977
5978 clearIfContinuousEvent(domEventName, nativeEvent);
5979 } // This is not replayable so we'll invoke it but without a target,
5980 // in case the event system needs to trace it.
5981
5982
5983 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, null, targetContainer);
5984 } // Attempt dispatching an event. Returns a SuspenseInstance or Container if it's blocked.
5985
5986 function attemptToDispatchEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent) {
5987 // TODO: Warn if _enabled is false.
5988 var nativeEventTarget = getEventTarget(nativeEvent);
5989 var targetInst = getClosestInstanceFromNode(nativeEventTarget);
5990
5991 if (targetInst !== null) {
5992 var nearestMounted = getNearestMountedFiber(targetInst);
5993
5994 if (nearestMounted === null) {
5995 // This tree has been unmounted already. Dispatch without a target.
5996 targetInst = null;
5997 } else {
5998 var tag = nearestMounted.tag;
5999
6000 if (tag === SuspenseComponent) {
6001 var instance = getSuspenseInstanceFromFiber(nearestMounted);
6002
6003 if (instance !== null) {
6004 // Queue the event to be replayed later. Abort dispatching since we
6005 // don't want this event dispatched twice through the event system.
6006 // TODO: If this is the first discrete event in the queue. Schedule an increased
6007 // priority for this boundary.
6008 return instance;
6009 } // This shouldn't happen, something went wrong but to avoid blocking
6010 // the whole system, dispatch the event without a target.
6011 // TODO: Warn.
6012
6013
6014 targetInst = null;
6015 } else if (tag === HostRoot) {
6016 var root = nearestMounted.stateNode;
6017
6018 if (root.hydrate) {
6019 // If this happens during a replay something went wrong and it might block
6020 // the whole system.
6021 return getContainerFromFiber(nearestMounted);
6022 }
6023
6024 targetInst = null;
6025 } else if (nearestMounted !== targetInst) {
6026 // If we get an event (ex: img onload) before committing that
6027 // component's mount, ignore it for now (that is, treat it as if it was an
6028 // event on a non-React tree). We might also consider queueing events and
6029 // dispatching them after the mount.
6030 targetInst = null;
6031 }
6032 }
6033 }
6034
6035 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer); // We're not blocked on anything.
6036
6037 return null;
6038 }
6039
6040 function addEventBubbleListener(target, eventType, listener) {
6041 target.addEventListener(eventType, listener, false);
6042 return listener;
6043 }
6044 function addEventCaptureListener(target, eventType, listener) {
6045 target.addEventListener(eventType, listener, true);
6046 return listener;
6047 }
6048 function addEventCaptureListenerWithPassiveFlag(target, eventType, listener, passive) {
6049 target.addEventListener(eventType, listener, {
6050 capture: true,
6051 passive: passive
6052 });
6053 return listener;
6054 }
6055 function addEventBubbleListenerWithPassiveFlag(target, eventType, listener, passive) {
6056 target.addEventListener(eventType, listener, {
6057 passive: passive
6058 });
6059 return listener;
6060 }
6061
6062 /**
6063 * These variables store information about text content of a target node,
6064 * allowing comparison of content before and after a given event.
6065 *
6066 * Identify the node where selection currently begins, then observe
6067 * both its text content and its current position in the DOM. Since the
6068 * browser may natively replace the target node during composition, we can
6069 * use its position to find its replacement.
6070 *
6071 *
6072 */
6073 var root = null;
6074 var startText = null;
6075 var fallbackText = null;
6076 function initialize(nativeEventTarget) {
6077 root = nativeEventTarget;
6078 startText = getText();
6079 return true;
6080 }
6081 function reset() {
6082 root = null;
6083 startText = null;
6084 fallbackText = null;
6085 }
6086 function getData() {
6087 if (fallbackText) {
6088 return fallbackText;
6089 }
6090
6091 var start;
6092 var startValue = startText;
6093 var startLength = startValue.length;
6094 var end;
6095 var endValue = getText();
6096 var endLength = endValue.length;
6097
6098 for (start = 0; start < startLength; start++) {
6099 if (startValue[start] !== endValue[start]) {
6100 break;
6101 }
6102 }
6103
6104 var minEnd = startLength - start;
6105
6106 for (end = 1; end <= minEnd; end++) {
6107 if (startValue[startLength - end] !== endValue[endLength - end]) {
6108 break;
6109 }
6110 }
6111
6112 var sliceTail = end > 1 ? 1 - end : undefined;
6113 fallbackText = endValue.slice(start, sliceTail);
6114 return fallbackText;
6115 }
6116 function getText() {
6117 if ('value' in root) {
6118 return root.value;
6119 }
6120
6121 return root.textContent;
6122 }
6123
6124 /**
6125 * `charCode` represents the actual "character code" and is safe to use with
6126 * `String.fromCharCode`. As such, only keys that correspond to printable
6127 * characters produce a valid `charCode`, the only exception to this is Enter.
6128 * The Tab-key is considered non-printable and does not have a `charCode`,
6129 * presumably because it does not produce a tab-character in browsers.
6130 *
6131 * @param {object} nativeEvent Native browser event.
6132 * @return {number} Normalized `charCode` property.
6133 */
6134 function getEventCharCode(nativeEvent) {
6135 var charCode;
6136 var keyCode = nativeEvent.keyCode;
6137
6138 if ('charCode' in nativeEvent) {
6139 charCode = nativeEvent.charCode; // FF does not set `charCode` for the Enter-key, check against `keyCode`.
6140
6141 if (charCode === 0 && keyCode === 13) {
6142 charCode = 13;
6143 }
6144 } else {
6145 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
6146 charCode = keyCode;
6147 } // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
6148 // report Enter as charCode 10 when ctrl is pressed.
6149
6150
6151 if (charCode === 10) {
6152 charCode = 13;
6153 } // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
6154 // Must not discard the (non-)printable Enter-key.
6155
6156
6157 if (charCode >= 32 || charCode === 13) {
6158 return charCode;
6159 }
6160
6161 return 0;
6162 }
6163
6164 function functionThatReturnsTrue() {
6165 return true;
6166 }
6167
6168 function functionThatReturnsFalse() {
6169 return false;
6170 } // This is intentionally a factory so that we have different returned constructors.
6171 // If we had a single constructor, it would be megamorphic and engines would deopt.
6172
6173
6174 function createSyntheticEvent(Interface) {
6175 /**
6176 * Synthetic events are dispatched by event plugins, typically in response to a
6177 * top-level event delegation handler.
6178 *
6179 * These systems should generally use pooling to reduce the frequency of garbage
6180 * collection. The system should check `isPersistent` to determine whether the
6181 * event should be released into the pool after being dispatched. Users that
6182 * need a persisted event should invoke `persist`.
6183 *
6184 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
6185 * normalizing browser quirks. Subclasses do not necessarily have to implement a
6186 * DOM interface; custom application-specific events can also subclass this.
6187 */
6188 function SyntheticBaseEvent(reactName, reactEventType, targetInst, nativeEvent, nativeEventTarget) {
6189 this._reactName = reactName;
6190 this._targetInst = targetInst;
6191 this.type = reactEventType;
6192 this.nativeEvent = nativeEvent;
6193 this.target = nativeEventTarget;
6194 this.currentTarget = null;
6195
6196 for (var _propName in Interface) {
6197 if (!Interface.hasOwnProperty(_propName)) {
6198 continue;
6199 }
6200
6201 var normalize = Interface[_propName];
6202
6203 if (normalize) {
6204 this[_propName] = normalize(nativeEvent);
6205 } else {
6206 this[_propName] = nativeEvent[_propName];
6207 }
6208 }
6209
6210 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
6211
6212 if (defaultPrevented) {
6213 this.isDefaultPrevented = functionThatReturnsTrue;
6214 } else {
6215 this.isDefaultPrevented = functionThatReturnsFalse;
6216 }
6217
6218 this.isPropagationStopped = functionThatReturnsFalse;
6219 return this;
6220 }
6221
6222 _assign(SyntheticBaseEvent.prototype, {
6223 preventDefault: function () {
6224 this.defaultPrevented = true;
6225 var event = this.nativeEvent;
6226
6227 if (!event) {
6228 return;
6229 }
6230
6231 if (event.preventDefault) {
6232 event.preventDefault(); // $FlowFixMe - flow is not aware of `unknown` in IE
6233 } else if (typeof event.returnValue !== 'unknown') {
6234 event.returnValue = false;
6235 }
6236
6237 this.isDefaultPrevented = functionThatReturnsTrue;
6238 },
6239 stopPropagation: function () {
6240 var event = this.nativeEvent;
6241
6242 if (!event) {
6243 return;
6244 }
6245
6246 if (event.stopPropagation) {
6247 event.stopPropagation(); // $FlowFixMe - flow is not aware of `unknown` in IE
6248 } else if (typeof event.cancelBubble !== 'unknown') {
6249 // The ChangeEventPlugin registers a "propertychange" event for
6250 // IE. This event does not support bubbling or cancelling, and
6251 // any references to cancelBubble throw "Member not found". A
6252 // typeof check of "unknown" circumvents this issue (and is also
6253 // IE specific).
6254 event.cancelBubble = true;
6255 }
6256
6257 this.isPropagationStopped = functionThatReturnsTrue;
6258 },
6259
6260 /**
6261 * We release all dispatched `SyntheticEvent`s after each event loop, adding
6262 * them back into the pool. This allows a way to hold onto a reference that
6263 * won't be added back into the pool.
6264 */
6265 persist: function () {// Modern event system doesn't use pooling.
6266 },
6267
6268 /**
6269 * Checks if this event should be released back into the pool.
6270 *
6271 * @return {boolean} True if this should not be released, false otherwise.
6272 */
6273 isPersistent: functionThatReturnsTrue
6274 });
6275
6276 return SyntheticBaseEvent;
6277 }
6278 /**
6279 * @interface Event
6280 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6281 */
6282
6283
6284 var EventInterface = {
6285 eventPhase: 0,
6286 bubbles: 0,
6287 cancelable: 0,
6288 timeStamp: function (event) {
6289 return event.timeStamp || Date.now();
6290 },
6291 defaultPrevented: 0,
6292 isTrusted: 0
6293 };
6294 var SyntheticEvent = createSyntheticEvent(EventInterface);
6295
6296 var UIEventInterface = _assign({}, EventInterface, {
6297 view: 0,
6298 detail: 0
6299 });
6300
6301 var SyntheticUIEvent = createSyntheticEvent(UIEventInterface);
6302 var lastMovementX;
6303 var lastMovementY;
6304 var lastMouseEvent;
6305
6306 function updateMouseMovementPolyfillState(event) {
6307 if (event !== lastMouseEvent) {
6308 if (lastMouseEvent && event.type === 'mousemove') {
6309 lastMovementX = event.screenX - lastMouseEvent.screenX;
6310 lastMovementY = event.screenY - lastMouseEvent.screenY;
6311 } else {
6312 lastMovementX = 0;
6313 lastMovementY = 0;
6314 }
6315
6316 lastMouseEvent = event;
6317 }
6318 }
6319 /**
6320 * @interface MouseEvent
6321 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6322 */
6323
6324
6325 var MouseEventInterface = _assign({}, UIEventInterface, {
6326 screenX: 0,
6327 screenY: 0,
6328 clientX: 0,
6329 clientY: 0,
6330 pageX: 0,
6331 pageY: 0,
6332 ctrlKey: 0,
6333 shiftKey: 0,
6334 altKey: 0,
6335 metaKey: 0,
6336 getModifierState: getEventModifierState,
6337 button: 0,
6338 buttons: 0,
6339 relatedTarget: function (event) {
6340 if (event.relatedTarget === undefined) return event.fromElement === event.srcElement ? event.toElement : event.fromElement;
6341 return event.relatedTarget;
6342 },
6343 movementX: function (event) {
6344 if ('movementX' in event) {
6345 return event.movementX;
6346 }
6347
6348 updateMouseMovementPolyfillState(event);
6349 return lastMovementX;
6350 },
6351 movementY: function (event) {
6352 if ('movementY' in event) {
6353 return event.movementY;
6354 } // Don't need to call updateMouseMovementPolyfillState() here
6355 // because it's guaranteed to have already run when movementX
6356 // was copied.
6357
6358
6359 return lastMovementY;
6360 }
6361 });
6362
6363 var SyntheticMouseEvent = createSyntheticEvent(MouseEventInterface);
6364 /**
6365 * @interface DragEvent
6366 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6367 */
6368
6369 var DragEventInterface = _assign({}, MouseEventInterface, {
6370 dataTransfer: 0
6371 });
6372
6373 var SyntheticDragEvent = createSyntheticEvent(DragEventInterface);
6374 /**
6375 * @interface FocusEvent
6376 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6377 */
6378
6379 var FocusEventInterface = _assign({}, UIEventInterface, {
6380 relatedTarget: 0
6381 });
6382
6383 var SyntheticFocusEvent = createSyntheticEvent(FocusEventInterface);
6384 /**
6385 * @interface Event
6386 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
6387 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
6388 */
6389
6390 var AnimationEventInterface = _assign({}, EventInterface, {
6391 animationName: 0,
6392 elapsedTime: 0,
6393 pseudoElement: 0
6394 });
6395
6396 var SyntheticAnimationEvent = createSyntheticEvent(AnimationEventInterface);
6397 /**
6398 * @interface Event
6399 * @see http://www.w3.org/TR/clipboard-apis/
6400 */
6401
6402 var ClipboardEventInterface = _assign({}, EventInterface, {
6403 clipboardData: function (event) {
6404 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
6405 }
6406 });
6407
6408 var SyntheticClipboardEvent = createSyntheticEvent(ClipboardEventInterface);
6409 /**
6410 * @interface Event
6411 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
6412 */
6413
6414 var CompositionEventInterface = _assign({}, EventInterface, {
6415 data: 0
6416 });
6417
6418 var SyntheticCompositionEvent = createSyntheticEvent(CompositionEventInterface);
6419 /**
6420 * @interface Event
6421 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
6422 * /#events-inputevents
6423 */
6424 // Happens to share the same list for now.
6425
6426 var SyntheticInputEvent = SyntheticCompositionEvent;
6427 /**
6428 * Normalization of deprecated HTML5 `key` values
6429 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
6430 */
6431
6432 var normalizeKey = {
6433 Esc: 'Escape',
6434 Spacebar: ' ',
6435 Left: 'ArrowLeft',
6436 Up: 'ArrowUp',
6437 Right: 'ArrowRight',
6438 Down: 'ArrowDown',
6439 Del: 'Delete',
6440 Win: 'OS',
6441 Menu: 'ContextMenu',
6442 Apps: 'ContextMenu',
6443 Scroll: 'ScrollLock',
6444 MozPrintableKey: 'Unidentified'
6445 };
6446 /**
6447 * Translation from legacy `keyCode` to HTML5 `key`
6448 * Only special keys supported, all others depend on keyboard layout or browser
6449 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
6450 */
6451
6452 var translateToKey = {
6453 '8': 'Backspace',
6454 '9': 'Tab',
6455 '12': 'Clear',
6456 '13': 'Enter',
6457 '16': 'Shift',
6458 '17': 'Control',
6459 '18': 'Alt',
6460 '19': 'Pause',
6461 '20': 'CapsLock',
6462 '27': 'Escape',
6463 '32': ' ',
6464 '33': 'PageUp',
6465 '34': 'PageDown',
6466 '35': 'End',
6467 '36': 'Home',
6468 '37': 'ArrowLeft',
6469 '38': 'ArrowUp',
6470 '39': 'ArrowRight',
6471 '40': 'ArrowDown',
6472 '45': 'Insert',
6473 '46': 'Delete',
6474 '112': 'F1',
6475 '113': 'F2',
6476 '114': 'F3',
6477 '115': 'F4',
6478 '116': 'F5',
6479 '117': 'F6',
6480 '118': 'F7',
6481 '119': 'F8',
6482 '120': 'F9',
6483 '121': 'F10',
6484 '122': 'F11',
6485 '123': 'F12',
6486 '144': 'NumLock',
6487 '145': 'ScrollLock',
6488 '224': 'Meta'
6489 };
6490 /**
6491 * @param {object} nativeEvent Native browser event.
6492 * @return {string} Normalized `key` property.
6493 */
6494
6495 function getEventKey(nativeEvent) {
6496 if (nativeEvent.key) {
6497 // Normalize inconsistent values reported by browsers due to
6498 // implementations of a working draft specification.
6499 // FireFox implements `key` but returns `MozPrintableKey` for all
6500 // printable characters (normalized to `Unidentified`), ignore it.
6501 var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
6502
6503 if (key !== 'Unidentified') {
6504 return key;
6505 }
6506 } // Browser does not implement `key`, polyfill as much of it as we can.
6507
6508
6509 if (nativeEvent.type === 'keypress') {
6510 var charCode = getEventCharCode(nativeEvent); // The enter-key is technically both printable and non-printable and can
6511 // thus be captured by `keypress`, no other non-printable key should.
6512
6513 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
6514 }
6515
6516 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
6517 // While user keyboard layout determines the actual meaning of each
6518 // `keyCode` value, almost all function keys have a universal value.
6519 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
6520 }
6521
6522 return '';
6523 }
6524 /**
6525 * Translation from modifier key to the associated property in the event.
6526 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
6527 */
6528
6529
6530 var modifierKeyToProp = {
6531 Alt: 'altKey',
6532 Control: 'ctrlKey',
6533 Meta: 'metaKey',
6534 Shift: 'shiftKey'
6535 }; // Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support
6536 // getModifierState. If getModifierState is not supported, we map it to a set of
6537 // modifier keys exposed by the event. In this case, Lock-keys are not supported.
6538
6539 function modifierStateGetter(keyArg) {
6540 var syntheticEvent = this;
6541 var nativeEvent = syntheticEvent.nativeEvent;
6542
6543 if (nativeEvent.getModifierState) {
6544 return nativeEvent.getModifierState(keyArg);
6545 }
6546
6547 var keyProp = modifierKeyToProp[keyArg];
6548 return keyProp ? !!nativeEvent[keyProp] : false;
6549 }
6550
6551 function getEventModifierState(nativeEvent) {
6552 return modifierStateGetter;
6553 }
6554 /**
6555 * @interface KeyboardEvent
6556 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6557 */
6558
6559
6560 var KeyboardEventInterface = _assign({}, UIEventInterface, {
6561 key: getEventKey,
6562 code: 0,
6563 location: 0,
6564 ctrlKey: 0,
6565 shiftKey: 0,
6566 altKey: 0,
6567 metaKey: 0,
6568 repeat: 0,
6569 locale: 0,
6570 getModifierState: getEventModifierState,
6571 // Legacy Interface
6572 charCode: function (event) {
6573 // `charCode` is the result of a KeyPress event and represents the value of
6574 // the actual printable character.
6575 // KeyPress is deprecated, but its replacement is not yet final and not
6576 // implemented in any major browser. Only KeyPress has charCode.
6577 if (event.type === 'keypress') {
6578 return getEventCharCode(event);
6579 }
6580
6581 return 0;
6582 },
6583 keyCode: function (event) {
6584 // `keyCode` is the result of a KeyDown/Up event and represents the value of
6585 // physical keyboard key.
6586 // The actual meaning of the value depends on the users' keyboard layout
6587 // which cannot be detected. Assuming that it is a US keyboard layout
6588 // provides a surprisingly accurate mapping for US and European users.
6589 // Due to this, it is left to the user to implement at this time.
6590 if (event.type === 'keydown' || event.type === 'keyup') {
6591 return event.keyCode;
6592 }
6593
6594 return 0;
6595 },
6596 which: function (event) {
6597 // `which` is an alias for either `keyCode` or `charCode` depending on the
6598 // type of the event.
6599 if (event.type === 'keypress') {
6600 return getEventCharCode(event);
6601 }
6602
6603 if (event.type === 'keydown' || event.type === 'keyup') {
6604 return event.keyCode;
6605 }
6606
6607 return 0;
6608 }
6609 });
6610
6611 var SyntheticKeyboardEvent = createSyntheticEvent(KeyboardEventInterface);
6612 /**
6613 * @interface PointerEvent
6614 * @see http://www.w3.org/TR/pointerevents/
6615 */
6616
6617 var PointerEventInterface = _assign({}, MouseEventInterface, {
6618 pointerId: 0,
6619 width: 0,
6620 height: 0,
6621 pressure: 0,
6622 tangentialPressure: 0,
6623 tiltX: 0,
6624 tiltY: 0,
6625 twist: 0,
6626 pointerType: 0,
6627 isPrimary: 0
6628 });
6629
6630 var SyntheticPointerEvent = createSyntheticEvent(PointerEventInterface);
6631 /**
6632 * @interface TouchEvent
6633 * @see http://www.w3.org/TR/touch-events/
6634 */
6635
6636 var TouchEventInterface = _assign({}, UIEventInterface, {
6637 touches: 0,
6638 targetTouches: 0,
6639 changedTouches: 0,
6640 altKey: 0,
6641 metaKey: 0,
6642 ctrlKey: 0,
6643 shiftKey: 0,
6644 getModifierState: getEventModifierState
6645 });
6646
6647 var SyntheticTouchEvent = createSyntheticEvent(TouchEventInterface);
6648 /**
6649 * @interface Event
6650 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
6651 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
6652 */
6653
6654 var TransitionEventInterface = _assign({}, EventInterface, {
6655 propertyName: 0,
6656 elapsedTime: 0,
6657 pseudoElement: 0
6658 });
6659
6660 var SyntheticTransitionEvent = createSyntheticEvent(TransitionEventInterface);
6661 /**
6662 * @interface WheelEvent
6663 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6664 */
6665
6666 var WheelEventInterface = _assign({}, MouseEventInterface, {
6667 deltaX: function (event) {
6668 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
6669 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
6670 },
6671 deltaY: function (event) {
6672 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
6673 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
6674 'wheelDelta' in event ? -event.wheelDelta : 0;
6675 },
6676 deltaZ: 0,
6677 // Browsers without "deltaMode" is reporting in raw wheel delta where one
6678 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
6679 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
6680 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
6681 deltaMode: 0
6682 });
6683
6684 var SyntheticWheelEvent = createSyntheticEvent(WheelEventInterface);
6685
6686 var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
6687
6688 var START_KEYCODE = 229;
6689 var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window;
6690 var documentMode = null;
6691
6692 if (canUseDOM && 'documentMode' in document) {
6693 documentMode = document.documentMode;
6694 } // Webkit offers a very useful `textInput` event that can be used to
6695 // directly represent `beforeInput`. The IE `textinput` event is not as
6696 // useful, so we don't use it.
6697
6698
6699 var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode; // In IE9+, we have access to composition events, but the data supplied
6700 // by the native compositionend event may be incorrect. Japanese ideographic
6701 // spaces, for instance (\u3000) are not recorded correctly.
6702
6703 var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
6704 var SPACEBAR_CODE = 32;
6705 var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
6706
6707 function registerEvents() {
6708 registerTwoPhaseEvent('onBeforeInput', ['compositionend', 'keypress', 'textInput', 'paste']);
6709 registerTwoPhaseEvent('onCompositionEnd', ['compositionend', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']);
6710 registerTwoPhaseEvent('onCompositionStart', ['compositionstart', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']);
6711 registerTwoPhaseEvent('onCompositionUpdate', ['compositionupdate', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']);
6712 } // Track whether we've ever handled a keypress on the space key.
6713
6714
6715 var hasSpaceKeypress = false;
6716 /**
6717 * Return whether a native keypress event is assumed to be a command.
6718 * This is required because Firefox fires `keypress` events for key commands
6719 * (cut, copy, select-all, etc.) even though no character is inserted.
6720 */
6721
6722 function isKeypressCommand(nativeEvent) {
6723 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && // ctrlKey && altKey is equivalent to AltGr, and is not a command.
6724 !(nativeEvent.ctrlKey && nativeEvent.altKey);
6725 }
6726 /**
6727 * Translate native top level events into event types.
6728 */
6729
6730
6731 function getCompositionEventType(domEventName) {
6732 switch (domEventName) {
6733 case 'compositionstart':
6734 return 'onCompositionStart';
6735
6736 case 'compositionend':
6737 return 'onCompositionEnd';
6738
6739 case 'compositionupdate':
6740 return 'onCompositionUpdate';
6741 }
6742 }
6743 /**
6744 * Does our fallback best-guess model think this event signifies that
6745 * composition has begun?
6746 */
6747
6748
6749 function isFallbackCompositionStart(domEventName, nativeEvent) {
6750 return domEventName === 'keydown' && nativeEvent.keyCode === START_KEYCODE;
6751 }
6752 /**
6753 * Does our fallback mode think that this event is the end of composition?
6754 */
6755
6756
6757 function isFallbackCompositionEnd(domEventName, nativeEvent) {
6758 switch (domEventName) {
6759 case 'keyup':
6760 // Command keys insert or clear IME input.
6761 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
6762
6763 case 'keydown':
6764 // Expect IME keyCode on each keydown. If we get any other
6765 // code we must have exited earlier.
6766 return nativeEvent.keyCode !== START_KEYCODE;
6767
6768 case 'keypress':
6769 case 'mousedown':
6770 case 'focusout':
6771 // Events are not possible without cancelling IME.
6772 return true;
6773
6774 default:
6775 return false;
6776 }
6777 }
6778 /**
6779 * Google Input Tools provides composition data via a CustomEvent,
6780 * with the `data` property populated in the `detail` object. If this
6781 * is available on the event object, use it. If not, this is a plain
6782 * composition event and we have nothing special to extract.
6783 *
6784 * @param {object} nativeEvent
6785 * @return {?string}
6786 */
6787
6788
6789 function getDataFromCustomEvent(nativeEvent) {
6790 var detail = nativeEvent.detail;
6791
6792 if (typeof detail === 'object' && 'data' in detail) {
6793 return detail.data;
6794 }
6795
6796 return null;
6797 }
6798 /**
6799 * Check if a composition event was triggered by Korean IME.
6800 * Our fallback mode does not work well with IE's Korean IME,
6801 * so just use native composition events when Korean IME is used.
6802 * Although CompositionEvent.locale property is deprecated,
6803 * it is available in IE, where our fallback mode is enabled.
6804 *
6805 * @param {object} nativeEvent
6806 * @return {boolean}
6807 */
6808
6809
6810 function isUsingKoreanIME(nativeEvent) {
6811 return nativeEvent.locale === 'ko';
6812 } // Track the current IME composition status, if any.
6813
6814
6815 var isComposing = false;
6816 /**
6817 * @return {?object} A SyntheticCompositionEvent.
6818 */
6819
6820 function extractCompositionEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget) {
6821 var eventType;
6822 var fallbackData;
6823
6824 if (canUseCompositionEvent) {
6825 eventType = getCompositionEventType(domEventName);
6826 } else if (!isComposing) {
6827 if (isFallbackCompositionStart(domEventName, nativeEvent)) {
6828 eventType = 'onCompositionStart';
6829 }
6830 } else if (isFallbackCompositionEnd(domEventName, nativeEvent)) {
6831 eventType = 'onCompositionEnd';
6832 }
6833
6834 if (!eventType) {
6835 return null;
6836 }
6837
6838 if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {
6839 // The current composition is stored statically and must not be
6840 // overwritten while composition continues.
6841 if (!isComposing && eventType === 'onCompositionStart') {
6842 isComposing = initialize(nativeEventTarget);
6843 } else if (eventType === 'onCompositionEnd') {
6844 if (isComposing) {
6845 fallbackData = getData();
6846 }
6847 }
6848 }
6849
6850 var listeners = accumulateTwoPhaseListeners(targetInst, eventType);
6851
6852 if (listeners.length > 0) {
6853 var event = new SyntheticCompositionEvent(eventType, domEventName, null, nativeEvent, nativeEventTarget);
6854 dispatchQueue.push({
6855 event: event,
6856 listeners: listeners
6857 });
6858
6859 if (fallbackData) {
6860 // Inject data generated from fallback path into the synthetic event.
6861 // This matches the property of native CompositionEventInterface.
6862 event.data = fallbackData;
6863 } else {
6864 var customData = getDataFromCustomEvent(nativeEvent);
6865
6866 if (customData !== null) {
6867 event.data = customData;
6868 }
6869 }
6870 }
6871 }
6872
6873 function getNativeBeforeInputChars(domEventName, nativeEvent) {
6874 switch (domEventName) {
6875 case 'compositionend':
6876 return getDataFromCustomEvent(nativeEvent);
6877
6878 case 'keypress':
6879 /**
6880 * If native `textInput` events are available, our goal is to make
6881 * use of them. However, there is a special case: the spacebar key.
6882 * In Webkit, preventing default on a spacebar `textInput` event
6883 * cancels character insertion, but it *also* causes the browser
6884 * to fall back to its default spacebar behavior of scrolling the
6885 * page.
6886 *
6887 * Tracking at:
6888 * https://code.google.com/p/chromium/issues/detail?id=355103
6889 *
6890 * To avoid this issue, use the keypress event as if no `textInput`
6891 * event is available.
6892 */
6893 var which = nativeEvent.which;
6894
6895 if (which !== SPACEBAR_CODE) {
6896 return null;
6897 }
6898
6899 hasSpaceKeypress = true;
6900 return SPACEBAR_CHAR;
6901
6902 case 'textInput':
6903 // Record the characters to be added to the DOM.
6904 var chars = nativeEvent.data; // If it's a spacebar character, assume that we have already handled
6905 // it at the keypress level and bail immediately. Android Chrome
6906 // doesn't give us keycodes, so we need to ignore it.
6907
6908 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
6909 return null;
6910 }
6911
6912 return chars;
6913
6914 default:
6915 // For other native event types, do nothing.
6916 return null;
6917 }
6918 }
6919 /**
6920 * For browsers that do not provide the `textInput` event, extract the
6921 * appropriate string to use for SyntheticInputEvent.
6922 */
6923
6924
6925 function getFallbackBeforeInputChars(domEventName, nativeEvent) {
6926 // If we are currently composing (IME) and using a fallback to do so,
6927 // try to extract the composed characters from the fallback object.
6928 // If composition event is available, we extract a string only at
6929 // compositionevent, otherwise extract it at fallback events.
6930 if (isComposing) {
6931 if (domEventName === 'compositionend' || !canUseCompositionEvent && isFallbackCompositionEnd(domEventName, nativeEvent)) {
6932 var chars = getData();
6933 reset();
6934 isComposing = false;
6935 return chars;
6936 }
6937
6938 return null;
6939 }
6940
6941 switch (domEventName) {
6942 case 'paste':
6943 // If a paste event occurs after a keypress, throw out the input
6944 // chars. Paste events should not lead to BeforeInput events.
6945 return null;
6946
6947 case 'keypress':
6948 /**
6949 * As of v27, Firefox may fire keypress events even when no character
6950 * will be inserted. A few possibilities:
6951 *
6952 * - `which` is `0`. Arrow keys, Esc key, etc.
6953 *
6954 * - `which` is the pressed key code, but no char is available.
6955 * Ex: 'AltGr + d` in Polish. There is no modified character for
6956 * this key combination and no character is inserted into the
6957 * document, but FF fires the keypress for char code `100` anyway.
6958 * No `input` event will occur.
6959 *
6960 * - `which` is the pressed key code, but a command combination is
6961 * being used. Ex: `Cmd+C`. No character is inserted, and no
6962 * `input` event will occur.
6963 */
6964 if (!isKeypressCommand(nativeEvent)) {
6965 // IE fires the `keypress` event when a user types an emoji via
6966 // Touch keyboard of Windows. In such a case, the `char` property
6967 // holds an emoji character like `\uD83D\uDE0A`. Because its length
6968 // is 2, the property `which` does not represent an emoji correctly.
6969 // In such a case, we directly return the `char` property instead of
6970 // using `which`.
6971 if (nativeEvent.char && nativeEvent.char.length > 1) {
6972 return nativeEvent.char;
6973 } else if (nativeEvent.which) {
6974 return String.fromCharCode(nativeEvent.which);
6975 }
6976 }
6977
6978 return null;
6979
6980 case 'compositionend':
6981 return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data;
6982
6983 default:
6984 return null;
6985 }
6986 }
6987 /**
6988 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
6989 * `textInput` or fallback behavior.
6990 *
6991 * @return {?object} A SyntheticInputEvent.
6992 */
6993
6994
6995 function extractBeforeInputEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget) {
6996 var chars;
6997
6998 if (canUseTextInputEvent) {
6999 chars = getNativeBeforeInputChars(domEventName, nativeEvent);
7000 } else {
7001 chars = getFallbackBeforeInputChars(domEventName, nativeEvent);
7002 } // If no characters are being inserted, no BeforeInput event should
7003 // be fired.
7004
7005
7006 if (!chars) {
7007 return null;
7008 }
7009
7010 var listeners = accumulateTwoPhaseListeners(targetInst, 'onBeforeInput');
7011
7012 if (listeners.length > 0) {
7013 var event = new SyntheticInputEvent('onBeforeInput', 'beforeinput', null, nativeEvent, nativeEventTarget);
7014 dispatchQueue.push({
7015 event: event,
7016 listeners: listeners
7017 });
7018 event.data = chars;
7019 }
7020 }
7021 /**
7022 * Create an `onBeforeInput` event to match
7023 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
7024 *
7025 * This event plugin is based on the native `textInput` event
7026 * available in Chrome, Safari, Opera, and IE. This event fires after
7027 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
7028 *
7029 * `beforeInput` is spec'd but not implemented in any browsers, and
7030 * the `input` event does not provide any useful information about what has
7031 * actually been added, contrary to the spec. Thus, `textInput` is the best
7032 * available event to identify the characters that have actually been inserted
7033 * into the target node.
7034 *
7035 * This plugin is also responsible for emitting `composition` events, thus
7036 * allowing us to share composition fallback code for both `beforeInput` and
7037 * `composition` event types.
7038 */
7039
7040
7041 function extractEvents(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
7042 extractCompositionEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
7043 extractBeforeInputEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
7044 }
7045
7046 /**
7047 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
7048 */
7049 var supportedInputTypes = {
7050 color: true,
7051 date: true,
7052 datetime: true,
7053 'datetime-local': true,
7054 email: true,
7055 month: true,
7056 number: true,
7057 password: true,
7058 range: true,
7059 search: true,
7060 tel: true,
7061 text: true,
7062 time: true,
7063 url: true,
7064 week: true
7065 };
7066
7067 function isTextInputElement(elem) {
7068 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
7069
7070 if (nodeName === 'input') {
7071 return !!supportedInputTypes[elem.type];
7072 }
7073
7074 if (nodeName === 'textarea') {
7075 return true;
7076 }
7077
7078 return false;
7079 }
7080
7081 /**
7082 * Checks if an event is supported in the current execution environment.
7083 *
7084 * NOTE: This will not work correctly for non-generic events such as `change`,
7085 * `reset`, `load`, `error`, and `select`.
7086 *
7087 * Borrows from Modernizr.
7088 *
7089 * @param {string} eventNameSuffix Event name, e.g. "click".
7090 * @return {boolean} True if the event is supported.
7091 * @internal
7092 * @license Modernizr 3.0.0pre (Custom Build) | MIT
7093 */
7094
7095 function isEventSupported(eventNameSuffix) {
7096 if (!canUseDOM) {
7097 return false;
7098 }
7099
7100 var eventName = 'on' + eventNameSuffix;
7101 var isSupported = (eventName in document);
7102
7103 if (!isSupported) {
7104 var element = document.createElement('div');
7105 element.setAttribute(eventName, 'return;');
7106 isSupported = typeof element[eventName] === 'function';
7107 }
7108
7109 return isSupported;
7110 }
7111
7112 function registerEvents$1() {
7113 registerTwoPhaseEvent('onChange', ['change', 'click', 'focusin', 'focusout', 'input', 'keydown', 'keyup', 'selectionchange']);
7114 }
7115
7116 function createAndAccumulateChangeEvent(dispatchQueue, inst, nativeEvent, target) {
7117 // Flag this event loop as needing state restore.
7118 enqueueStateRestore(target);
7119 var listeners = accumulateTwoPhaseListeners(inst, 'onChange');
7120
7121 if (listeners.length > 0) {
7122 var event = new SyntheticEvent('onChange', 'change', null, nativeEvent, target);
7123 dispatchQueue.push({
7124 event: event,
7125 listeners: listeners
7126 });
7127 }
7128 }
7129 /**
7130 * For IE shims
7131 */
7132
7133
7134 var activeElement = null;
7135 var activeElementInst = null;
7136 /**
7137 * SECTION: handle `change` event
7138 */
7139
7140 function shouldUseChangeEvent(elem) {
7141 var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
7142 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
7143 }
7144
7145 function manualDispatchChangeEvent(nativeEvent) {
7146 var dispatchQueue = [];
7147 createAndAccumulateChangeEvent(dispatchQueue, activeElementInst, nativeEvent, getEventTarget(nativeEvent)); // If change and propertychange bubbled, we'd just bind to it like all the
7148 // other events and have it go through ReactBrowserEventEmitter. Since it
7149 // doesn't, we manually listen for the events and so we have to enqueue and
7150 // process the abstract event manually.
7151 //
7152 // Batching is necessary here in order to ensure that all event handlers run
7153 // before the next rerender (including event handlers attached to ancestor
7154 // elements instead of directly on the input). Without this, controlled
7155 // components don't work properly in conjunction with event bubbling because
7156 // the component is rerendered and the value reverted before all the event
7157 // handlers can run. See https://github.com/facebook/react/issues/708.
7158
7159 batchedUpdates(runEventInBatch, dispatchQueue);
7160 }
7161
7162 function runEventInBatch(dispatchQueue) {
7163 processDispatchQueue(dispatchQueue, 0);
7164 }
7165
7166 function getInstIfValueChanged(targetInst) {
7167 var targetNode = getNodeFromInstance(targetInst);
7168
7169 if (updateValueIfChanged(targetNode)) {
7170 return targetInst;
7171 }
7172 }
7173
7174 function getTargetInstForChangeEvent(domEventName, targetInst) {
7175 if (domEventName === 'change') {
7176 return targetInst;
7177 }
7178 }
7179 /**
7180 * SECTION: handle `input` event
7181 */
7182
7183
7184 var isInputEventSupported = false;
7185
7186 if (canUseDOM) {
7187 // IE9 claims to support the input event but fails to trigger it when
7188 // deleting text, so we ignore its input events.
7189 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
7190 }
7191 /**
7192 * (For IE <=9) Starts tracking propertychange events on the passed-in element
7193 * and override the value property so that we can distinguish user events from
7194 * value changes in JS.
7195 */
7196
7197
7198 function startWatchingForValueChange(target, targetInst) {
7199 activeElement = target;
7200 activeElementInst = targetInst;
7201 activeElement.attachEvent('onpropertychange', handlePropertyChange);
7202 }
7203 /**
7204 * (For IE <=9) Removes the event listeners from the currently-tracked element,
7205 * if any exists.
7206 */
7207
7208
7209 function stopWatchingForValueChange() {
7210 if (!activeElement) {
7211 return;
7212 }
7213
7214 activeElement.detachEvent('onpropertychange', handlePropertyChange);
7215 activeElement = null;
7216 activeElementInst = null;
7217 }
7218 /**
7219 * (For IE <=9) Handles a propertychange event, sending a `change` event if
7220 * the value of the active element has changed.
7221 */
7222
7223
7224 function handlePropertyChange(nativeEvent) {
7225 if (nativeEvent.propertyName !== 'value') {
7226 return;
7227 }
7228
7229 if (getInstIfValueChanged(activeElementInst)) {
7230 manualDispatchChangeEvent(nativeEvent);
7231 }
7232 }
7233
7234 function handleEventsForInputEventPolyfill(domEventName, target, targetInst) {
7235 if (domEventName === 'focusin') {
7236 // In IE9, propertychange fires for most input events but is buggy and
7237 // doesn't fire when text is deleted, but conveniently, selectionchange
7238 // appears to fire in all of the remaining cases so we catch those and
7239 // forward the event if the value has changed
7240 // In either case, we don't want to call the event handler if the value
7241 // is changed from JS so we redefine a setter for `.value` that updates
7242 // our activeElementValue variable, allowing us to ignore those changes
7243 //
7244 // stopWatching() should be a noop here but we call it just in case we
7245 // missed a blur event somehow.
7246 stopWatchingForValueChange();
7247 startWatchingForValueChange(target, targetInst);
7248 } else if (domEventName === 'focusout') {
7249 stopWatchingForValueChange();
7250 }
7251 } // For IE8 and IE9.
7252
7253
7254 function getTargetInstForInputEventPolyfill(domEventName, targetInst) {
7255 if (domEventName === 'selectionchange' || domEventName === 'keyup' || domEventName === 'keydown') {
7256 // On the selectionchange event, the target is just document which isn't
7257 // helpful for us so just check activeElement instead.
7258 //
7259 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
7260 // propertychange on the first input event after setting `value` from a
7261 // script and fires only keydown, keypress, keyup. Catching keyup usually
7262 // gets it and catching keydown lets us fire an event for the first
7263 // keystroke if user does a key repeat (it'll be a little delayed: right
7264 // before the second keystroke). Other input methods (e.g., paste) seem to
7265 // fire selectionchange normally.
7266 return getInstIfValueChanged(activeElementInst);
7267 }
7268 }
7269 /**
7270 * SECTION: handle `click` event
7271 */
7272
7273
7274 function shouldUseClickEvent(elem) {
7275 // Use the `click` event to detect changes to checkbox and radio inputs.
7276 // This approach works across all browsers, whereas `change` does not fire
7277 // until `blur` in IE8.
7278 var nodeName = elem.nodeName;
7279 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
7280 }
7281
7282 function getTargetInstForClickEvent(domEventName, targetInst) {
7283 if (domEventName === 'click') {
7284 return getInstIfValueChanged(targetInst);
7285 }
7286 }
7287
7288 function getTargetInstForInputOrChangeEvent(domEventName, targetInst) {
7289 if (domEventName === 'input' || domEventName === 'change') {
7290 return getInstIfValueChanged(targetInst);
7291 }
7292 }
7293
7294 function handleControlledInputBlur(node) {
7295 var state = node._wrapperState;
7296
7297 if (!state || !state.controlled || node.type !== 'number') {
7298 return;
7299 }
7300
7301 {
7302 // If controlled, assign the value attribute to the current value on blur
7303 setDefaultValue(node, 'number', node.value);
7304 }
7305 }
7306 /**
7307 * This plugin creates an `onChange` event that normalizes change events
7308 * across form elements. This event fires at a time when it's possible to
7309 * change the element's value without seeing a flicker.
7310 *
7311 * Supported elements are:
7312 * - input (see `isTextInputElement`)
7313 * - textarea
7314 * - select
7315 */
7316
7317
7318 function extractEvents$1(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
7319 var targetNode = targetInst ? getNodeFromInstance(targetInst) : window;
7320 var getTargetInstFunc, handleEventFunc;
7321
7322 if (shouldUseChangeEvent(targetNode)) {
7323 getTargetInstFunc = getTargetInstForChangeEvent;
7324 } else if (isTextInputElement(targetNode)) {
7325 if (isInputEventSupported) {
7326 getTargetInstFunc = getTargetInstForInputOrChangeEvent;
7327 } else {
7328 getTargetInstFunc = getTargetInstForInputEventPolyfill;
7329 handleEventFunc = handleEventsForInputEventPolyfill;
7330 }
7331 } else if (shouldUseClickEvent(targetNode)) {
7332 getTargetInstFunc = getTargetInstForClickEvent;
7333 }
7334
7335 if (getTargetInstFunc) {
7336 var inst = getTargetInstFunc(domEventName, targetInst);
7337
7338 if (inst) {
7339 createAndAccumulateChangeEvent(dispatchQueue, inst, nativeEvent, nativeEventTarget);
7340 return;
7341 }
7342 }
7343
7344 if (handleEventFunc) {
7345 handleEventFunc(domEventName, targetNode, targetInst);
7346 } // When blurring, set the value attribute for number inputs
7347
7348
7349 if (domEventName === 'focusout') {
7350 handleControlledInputBlur(targetNode);
7351 }
7352 }
7353
7354 function registerEvents$2() {
7355 registerDirectEvent('onMouseEnter', ['mouseout', 'mouseover']);
7356 registerDirectEvent('onMouseLeave', ['mouseout', 'mouseover']);
7357 registerDirectEvent('onPointerEnter', ['pointerout', 'pointerover']);
7358 registerDirectEvent('onPointerLeave', ['pointerout', 'pointerover']);
7359 }
7360 /**
7361 * For almost every interaction we care about, there will be both a top-level
7362 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
7363 * we do not extract duplicate events. However, moving the mouse into the
7364 * browser from outside will not fire a `mouseout` event. In this case, we use
7365 * the `mouseover` top-level event.
7366 */
7367
7368
7369 function extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
7370 var isOverEvent = domEventName === 'mouseover' || domEventName === 'pointerover';
7371 var isOutEvent = domEventName === 'mouseout' || domEventName === 'pointerout';
7372
7373 if (isOverEvent && (eventSystemFlags & IS_REPLAYED) === 0) {
7374 // If this is an over event with a target, we might have already dispatched
7375 // the event in the out event of the other target. If this is replayed,
7376 // then it's because we couldn't dispatch against this target previously
7377 // so we have to do it now instead.
7378 var related = nativeEvent.relatedTarget || nativeEvent.fromElement;
7379
7380 if (related) {
7381 // If the related node is managed by React, we can assume that we have
7382 // already dispatched the corresponding events during its mouseout.
7383 if (getClosestInstanceFromNode(related) || isContainerMarkedAsRoot(related)) {
7384 return;
7385 }
7386 }
7387 }
7388
7389 if (!isOutEvent && !isOverEvent) {
7390 // Must not be a mouse or pointer in or out - ignoring.
7391 return;
7392 }
7393
7394 var win; // TODO: why is this nullable in the types but we read from it?
7395
7396 if (nativeEventTarget.window === nativeEventTarget) {
7397 // `nativeEventTarget` is probably a window object.
7398 win = nativeEventTarget;
7399 } else {
7400 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
7401 var doc = nativeEventTarget.ownerDocument;
7402
7403 if (doc) {
7404 win = doc.defaultView || doc.parentWindow;
7405 } else {
7406 win = window;
7407 }
7408 }
7409
7410 var from;
7411 var to;
7412
7413 if (isOutEvent) {
7414 var _related = nativeEvent.relatedTarget || nativeEvent.toElement;
7415
7416 from = targetInst;
7417 to = _related ? getClosestInstanceFromNode(_related) : null;
7418
7419 if (to !== null) {
7420 var nearestMounted = getNearestMountedFiber(to);
7421
7422 if (to !== nearestMounted || to.tag !== HostComponent && to.tag !== HostText) {
7423 to = null;
7424 }
7425 }
7426 } else {
7427 // Moving to a node from outside the window.
7428 from = null;
7429 to = targetInst;
7430 }
7431
7432 if (from === to) {
7433 // Nothing pertains to our managed components.
7434 return;
7435 }
7436
7437 var SyntheticEventCtor = SyntheticMouseEvent;
7438 var leaveEventType = 'onMouseLeave';
7439 var enterEventType = 'onMouseEnter';
7440 var eventTypePrefix = 'mouse';
7441
7442 if (domEventName === 'pointerout' || domEventName === 'pointerover') {
7443 SyntheticEventCtor = SyntheticPointerEvent;
7444 leaveEventType = 'onPointerLeave';
7445 enterEventType = 'onPointerEnter';
7446 eventTypePrefix = 'pointer';
7447 }
7448
7449 var fromNode = from == null ? win : getNodeFromInstance(from);
7450 var toNode = to == null ? win : getNodeFromInstance(to);
7451 var leave = new SyntheticEventCtor(leaveEventType, eventTypePrefix + 'leave', from, nativeEvent, nativeEventTarget);
7452 leave.target = fromNode;
7453 leave.relatedTarget = toNode;
7454 var enter = null; // We should only process this nativeEvent if we are processing
7455 // the first ancestor. Next time, we will ignore the event.
7456
7457 var nativeTargetInst = getClosestInstanceFromNode(nativeEventTarget);
7458
7459 if (nativeTargetInst === targetInst) {
7460 var enterEvent = new SyntheticEventCtor(enterEventType, eventTypePrefix + 'enter', to, nativeEvent, nativeEventTarget);
7461 enterEvent.target = toNode;
7462 enterEvent.relatedTarget = fromNode;
7463 enter = enterEvent;
7464 }
7465
7466 accumulateEnterLeaveTwoPhaseListeners(dispatchQueue, leave, enter, from, to);
7467 }
7468
7469 /**
7470 * inlined Object.is polyfill to avoid requiring consumers ship their own
7471 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
7472 */
7473 function is(x, y) {
7474 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
7475 ;
7476 }
7477
7478 var objectIs = typeof Object.is === 'function' ? Object.is : is;
7479
7480 var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
7481 /**
7482 * Performs equality by iterating through keys on an object and returning false
7483 * when any key has values which are not strictly equal between the arguments.
7484 * Returns true when the values of all keys are strictly equal.
7485 */
7486
7487 function shallowEqual(objA, objB) {
7488 if (objectIs(objA, objB)) {
7489 return true;
7490 }
7491
7492 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
7493 return false;
7494 }
7495
7496 var keysA = Object.keys(objA);
7497 var keysB = Object.keys(objB);
7498
7499 if (keysA.length !== keysB.length) {
7500 return false;
7501 } // Test for A's keys different from B.
7502
7503
7504 for (var i = 0; i < keysA.length; i++) {
7505 if (!hasOwnProperty$2.call(objB, keysA[i]) || !objectIs(objA[keysA[i]], objB[keysA[i]])) {
7506 return false;
7507 }
7508 }
7509
7510 return true;
7511 }
7512
7513 /**
7514 * Given any node return the first leaf node without children.
7515 *
7516 * @param {DOMElement|DOMTextNode} node
7517 * @return {DOMElement|DOMTextNode}
7518 */
7519
7520 function getLeafNode(node) {
7521 while (node && node.firstChild) {
7522 node = node.firstChild;
7523 }
7524
7525 return node;
7526 }
7527 /**
7528 * Get the next sibling within a container. This will walk up the
7529 * DOM if a node's siblings have been exhausted.
7530 *
7531 * @param {DOMElement|DOMTextNode} node
7532 * @return {?DOMElement|DOMTextNode}
7533 */
7534
7535
7536 function getSiblingNode(node) {
7537 while (node) {
7538 if (node.nextSibling) {
7539 return node.nextSibling;
7540 }
7541
7542 node = node.parentNode;
7543 }
7544 }
7545 /**
7546 * Get object describing the nodes which contain characters at offset.
7547 *
7548 * @param {DOMElement|DOMTextNode} root
7549 * @param {number} offset
7550 * @return {?object}
7551 */
7552
7553
7554 function getNodeForCharacterOffset(root, offset) {
7555 var node = getLeafNode(root);
7556 var nodeStart = 0;
7557 var nodeEnd = 0;
7558
7559 while (node) {
7560 if (node.nodeType === TEXT_NODE) {
7561 nodeEnd = nodeStart + node.textContent.length;
7562
7563 if (nodeStart <= offset && nodeEnd >= offset) {
7564 return {
7565 node: node,
7566 offset: offset - nodeStart
7567 };
7568 }
7569
7570 nodeStart = nodeEnd;
7571 }
7572
7573 node = getLeafNode(getSiblingNode(node));
7574 }
7575 }
7576
7577 /**
7578 * @param {DOMElement} outerNode
7579 * @return {?object}
7580 */
7581
7582 function getOffsets(outerNode) {
7583 var ownerDocument = outerNode.ownerDocument;
7584 var win = ownerDocument && ownerDocument.defaultView || window;
7585 var selection = win.getSelection && win.getSelection();
7586
7587 if (!selection || selection.rangeCount === 0) {
7588 return null;
7589 }
7590
7591 var anchorNode = selection.anchorNode,
7592 anchorOffset = selection.anchorOffset,
7593 focusNode = selection.focusNode,
7594 focusOffset = selection.focusOffset; // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
7595 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
7596 // expose properties, triggering a "Permission denied error" if any of its
7597 // properties are accessed. The only seemingly possible way to avoid erroring
7598 // is to access a property that typically works for non-anonymous divs and
7599 // catch any error that may otherwise arise. See
7600 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
7601
7602 try {
7603 /* eslint-disable no-unused-expressions */
7604 anchorNode.nodeType;
7605 focusNode.nodeType;
7606 /* eslint-enable no-unused-expressions */
7607 } catch (e) {
7608 return null;
7609 }
7610
7611 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
7612 }
7613 /**
7614 * Returns {start, end} where `start` is the character/codepoint index of
7615 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
7616 * `end` is the index of (focusNode, focusOffset).
7617 *
7618 * Returns null if you pass in garbage input but we should probably just crash.
7619 *
7620 * Exported only for testing.
7621 */
7622
7623 function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
7624 var length = 0;
7625 var start = -1;
7626 var end = -1;
7627 var indexWithinAnchor = 0;
7628 var indexWithinFocus = 0;
7629 var node = outerNode;
7630 var parentNode = null;
7631
7632 outer: while (true) {
7633 var next = null;
7634
7635 while (true) {
7636 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
7637 start = length + anchorOffset;
7638 }
7639
7640 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
7641 end = length + focusOffset;
7642 }
7643
7644 if (node.nodeType === TEXT_NODE) {
7645 length += node.nodeValue.length;
7646 }
7647
7648 if ((next = node.firstChild) === null) {
7649 break;
7650 } // Moving from `node` to its first child `next`.
7651
7652
7653 parentNode = node;
7654 node = next;
7655 }
7656
7657 while (true) {
7658 if (node === outerNode) {
7659 // If `outerNode` has children, this is always the second time visiting
7660 // it. If it has no children, this is still the first loop, and the only
7661 // valid selection is anchorNode and focusNode both equal to this node
7662 // and both offsets 0, in which case we will have handled above.
7663 break outer;
7664 }
7665
7666 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
7667 start = length;
7668 }
7669
7670 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
7671 end = length;
7672 }
7673
7674 if ((next = node.nextSibling) !== null) {
7675 break;
7676 }
7677
7678 node = parentNode;
7679 parentNode = node.parentNode;
7680 } // Moving from `node` to its next sibling `next`.
7681
7682
7683 node = next;
7684 }
7685
7686 if (start === -1 || end === -1) {
7687 // This should never happen. (Would happen if the anchor/focus nodes aren't
7688 // actually inside the passed-in node.)
7689 return null;
7690 }
7691
7692 return {
7693 start: start,
7694 end: end
7695 };
7696 }
7697 /**
7698 * In modern non-IE browsers, we can support both forward and backward
7699 * selections.
7700 *
7701 * Note: IE10+ supports the Selection object, but it does not support
7702 * the `extend` method, which means that even in modern IE, it's not possible
7703 * to programmatically create a backward selection. Thus, for all IE
7704 * versions, we use the old IE API to create our selections.
7705 *
7706 * @param {DOMElement|DOMTextNode} node
7707 * @param {object} offsets
7708 */
7709
7710 function setOffsets(node, offsets) {
7711 var doc = node.ownerDocument || document;
7712 var win = doc && doc.defaultView || window; // Edge fails with "Object expected" in some scenarios.
7713 // (For instance: TinyMCE editor used in a list component that supports pasting to add more,
7714 // fails when pasting 100+ items)
7715
7716 if (!win.getSelection) {
7717 return;
7718 }
7719
7720 var selection = win.getSelection();
7721 var length = node.textContent.length;
7722 var start = Math.min(offsets.start, length);
7723 var end = offsets.end === undefined ? start : Math.min(offsets.end, length); // IE 11 uses modern selection, but doesn't support the extend method.
7724 // Flip backward selections, so we can set with a single range.
7725
7726 if (!selection.extend && start > end) {
7727 var temp = end;
7728 end = start;
7729 start = temp;
7730 }
7731
7732 var startMarker = getNodeForCharacterOffset(node, start);
7733 var endMarker = getNodeForCharacterOffset(node, end);
7734
7735 if (startMarker && endMarker) {
7736 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
7737 return;
7738 }
7739
7740 var range = doc.createRange();
7741 range.setStart(startMarker.node, startMarker.offset);
7742 selection.removeAllRanges();
7743
7744 if (start > end) {
7745 selection.addRange(range);
7746 selection.extend(endMarker.node, endMarker.offset);
7747 } else {
7748 range.setEnd(endMarker.node, endMarker.offset);
7749 selection.addRange(range);
7750 }
7751 }
7752 }
7753
7754 function isTextNode(node) {
7755 return node && node.nodeType === TEXT_NODE;
7756 }
7757
7758 function containsNode(outerNode, innerNode) {
7759 if (!outerNode || !innerNode) {
7760 return false;
7761 } else if (outerNode === innerNode) {
7762 return true;
7763 } else if (isTextNode(outerNode)) {
7764 return false;
7765 } else if (isTextNode(innerNode)) {
7766 return containsNode(outerNode, innerNode.parentNode);
7767 } else if ('contains' in outerNode) {
7768 return outerNode.contains(innerNode);
7769 } else if (outerNode.compareDocumentPosition) {
7770 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
7771 } else {
7772 return false;
7773 }
7774 }
7775
7776 function isInDocument(node) {
7777 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);
7778 }
7779
7780 function isSameOriginFrame(iframe) {
7781 try {
7782 // Accessing the contentDocument of a HTMLIframeElement can cause the browser
7783 // to throw, e.g. if it has a cross-origin src attribute.
7784 // Safari will show an error in the console when the access results in "Blocked a frame with origin". e.g:
7785 // iframe.contentDocument.defaultView;
7786 // A safety way is to access one of the cross origin properties: Window or Location
7787 // Which might result in "SecurityError" DOM Exception and it is compatible to Safari.
7788 // https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl
7789 return typeof iframe.contentWindow.location.href === 'string';
7790 } catch (err) {
7791 return false;
7792 }
7793 }
7794
7795 function getActiveElementDeep() {
7796 var win = window;
7797 var element = getActiveElement();
7798
7799 while (element instanceof win.HTMLIFrameElement) {
7800 if (isSameOriginFrame(element)) {
7801 win = element.contentWindow;
7802 } else {
7803 return element;
7804 }
7805
7806 element = getActiveElement(win.document);
7807 }
7808
7809 return element;
7810 }
7811 /**
7812 * @ReactInputSelection: React input selection module. Based on Selection.js,
7813 * but modified to be suitable for react and has a couple of bug fixes (doesn't
7814 * assume buttons have range selections allowed).
7815 * Input selection module for React.
7816 */
7817
7818 /**
7819 * @hasSelectionCapabilities: we get the element types that support selection
7820 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`
7821 * and `selectionEnd` rows.
7822 */
7823
7824
7825 function hasSelectionCapabilities(elem) {
7826 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
7827 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');
7828 }
7829 function getSelectionInformation() {
7830 var focusedElem = getActiveElementDeep();
7831 return {
7832 focusedElem: focusedElem,
7833 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection(focusedElem) : null
7834 };
7835 }
7836 /**
7837 * @restoreSelection: If any selection information was potentially lost,
7838 * restore it. This is useful when performing operations that could remove dom
7839 * nodes and place them back in, resulting in focus being lost.
7840 */
7841
7842 function restoreSelection(priorSelectionInformation) {
7843 var curFocusedElem = getActiveElementDeep();
7844 var priorFocusedElem = priorSelectionInformation.focusedElem;
7845 var priorSelectionRange = priorSelectionInformation.selectionRange;
7846
7847 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
7848 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
7849 setSelection(priorFocusedElem, priorSelectionRange);
7850 } // Focusing a node can change the scroll position, which is undesirable
7851
7852
7853 var ancestors = [];
7854 var ancestor = priorFocusedElem;
7855
7856 while (ancestor = ancestor.parentNode) {
7857 if (ancestor.nodeType === ELEMENT_NODE) {
7858 ancestors.push({
7859 element: ancestor,
7860 left: ancestor.scrollLeft,
7861 top: ancestor.scrollTop
7862 });
7863 }
7864 }
7865
7866 if (typeof priorFocusedElem.focus === 'function') {
7867 priorFocusedElem.focus();
7868 }
7869
7870 for (var i = 0; i < ancestors.length; i++) {
7871 var info = ancestors[i];
7872 info.element.scrollLeft = info.left;
7873 info.element.scrollTop = info.top;
7874 }
7875 }
7876 }
7877 /**
7878 * @getSelection: Gets the selection bounds of a focused textarea, input or
7879 * contentEditable node.
7880 * -@input: Look up selection bounds of this input
7881 * -@return {start: selectionStart, end: selectionEnd}
7882 */
7883
7884 function getSelection(input) {
7885 var selection;
7886
7887 if ('selectionStart' in input) {
7888 // Modern browser with input or textarea.
7889 selection = {
7890 start: input.selectionStart,
7891 end: input.selectionEnd
7892 };
7893 } else {
7894 // Content editable or old IE textarea.
7895 selection = getOffsets(input);
7896 }
7897
7898 return selection || {
7899 start: 0,
7900 end: 0
7901 };
7902 }
7903 /**
7904 * @setSelection: Sets the selection bounds of a textarea or input and focuses
7905 * the input.
7906 * -@input Set selection bounds of this input or textarea
7907 * -@offsets Object of same form that is returned from get*
7908 */
7909
7910 function setSelection(input, offsets) {
7911 var start = offsets.start;
7912 var end = offsets.end;
7913
7914 if (end === undefined) {
7915 end = start;
7916 }
7917
7918 if ('selectionStart' in input) {
7919 input.selectionStart = start;
7920 input.selectionEnd = Math.min(end, input.value.length);
7921 } else {
7922 setOffsets(input, offsets);
7923 }
7924 }
7925
7926 var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11;
7927
7928 function registerEvents$3() {
7929 registerTwoPhaseEvent('onSelect', ['focusout', 'contextmenu', 'dragend', 'focusin', 'keydown', 'keyup', 'mousedown', 'mouseup', 'selectionchange']);
7930 }
7931
7932 var activeElement$1 = null;
7933 var activeElementInst$1 = null;
7934 var lastSelection = null;
7935 var mouseDown = false;
7936 /**
7937 * Get an object which is a unique representation of the current selection.
7938 *
7939 * The return value will not be consistent across nodes or browsers, but
7940 * two identical selections on the same node will return identical objects.
7941 */
7942
7943 function getSelection$1(node) {
7944 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
7945 return {
7946 start: node.selectionStart,
7947 end: node.selectionEnd
7948 };
7949 } else {
7950 var win = node.ownerDocument && node.ownerDocument.defaultView || window;
7951 var selection = win.getSelection();
7952 return {
7953 anchorNode: selection.anchorNode,
7954 anchorOffset: selection.anchorOffset,
7955 focusNode: selection.focusNode,
7956 focusOffset: selection.focusOffset
7957 };
7958 }
7959 }
7960 /**
7961 * Get document associated with the event target.
7962 */
7963
7964
7965 function getEventTargetDocument(eventTarget) {
7966 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;
7967 }
7968 /**
7969 * Poll selection to see whether it's changed.
7970 *
7971 * @param {object} nativeEvent
7972 * @param {object} nativeEventTarget
7973 * @return {?SyntheticEvent}
7974 */
7975
7976
7977 function constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget) {
7978 // Ensure we have the right element, and that the user is not dragging a
7979 // selection (this matches native `select` event behavior). In HTML5, select
7980 // fires only on input and textarea thus if there's no focused element we
7981 // won't dispatch.
7982 var doc = getEventTargetDocument(nativeEventTarget);
7983
7984 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) {
7985 return;
7986 } // Only fire when selection has actually changed.
7987
7988
7989 var currentSelection = getSelection$1(activeElement$1);
7990
7991 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
7992 lastSelection = currentSelection;
7993 var listeners = accumulateTwoPhaseListeners(activeElementInst$1, 'onSelect');
7994
7995 if (listeners.length > 0) {
7996 var event = new SyntheticEvent('onSelect', 'select', null, nativeEvent, nativeEventTarget);
7997 dispatchQueue.push({
7998 event: event,
7999 listeners: listeners
8000 });
8001 event.target = activeElement$1;
8002 }
8003 }
8004 }
8005 /**
8006 * This plugin creates an `onSelect` event that normalizes select events
8007 * across form elements.
8008 *
8009 * Supported elements are:
8010 * - input (see `isTextInputElement`)
8011 * - textarea
8012 * - contentEditable
8013 *
8014 * This differs from native browser implementations in the following ways:
8015 * - Fires on contentEditable fields as well as inputs.
8016 * - Fires for collapsed selection.
8017 * - Fires after user input.
8018 */
8019
8020
8021 function extractEvents$3(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
8022
8023 var targetNode = targetInst ? getNodeFromInstance(targetInst) : window;
8024
8025 switch (domEventName) {
8026 // Track the input node that has focus.
8027 case 'focusin':
8028 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
8029 activeElement$1 = targetNode;
8030 activeElementInst$1 = targetInst;
8031 lastSelection = null;
8032 }
8033
8034 break;
8035
8036 case 'focusout':
8037 activeElement$1 = null;
8038 activeElementInst$1 = null;
8039 lastSelection = null;
8040 break;
8041 // Don't fire the event while the user is dragging. This matches the
8042 // semantics of the native select event.
8043
8044 case 'mousedown':
8045 mouseDown = true;
8046 break;
8047
8048 case 'contextmenu':
8049 case 'mouseup':
8050 case 'dragend':
8051 mouseDown = false;
8052 constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget);
8053 break;
8054 // Chrome and IE fire non-standard event when selection is changed (and
8055 // sometimes when it hasn't). IE's event fires out of order with respect
8056 // to key and input events on deletion, so we discard it.
8057 //
8058 // Firefox doesn't support selectionchange, so check selection status
8059 // after each key entry. The selection changes after keydown and before
8060 // keyup, but we check on keydown as well in the case of holding down a
8061 // key, when multiple keydown events are fired but only one keyup is.
8062 // This is also our approach for IE handling, for the reason above.
8063
8064 case 'selectionchange':
8065 if (skipSelectionChangeEvent) {
8066 break;
8067 }
8068
8069 // falls through
8070
8071 case 'keydown':
8072 case 'keyup':
8073 constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget);
8074 }
8075 }
8076
8077 function extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
8078 var reactName = topLevelEventsToReactNames.get(domEventName);
8079
8080 if (reactName === undefined) {
8081 return;
8082 }
8083
8084 var SyntheticEventCtor = SyntheticEvent;
8085 var reactEventType = domEventName;
8086
8087 switch (domEventName) {
8088 case 'keypress':
8089 // Firefox creates a keypress event for function keys too. This removes
8090 // the unwanted keypress events. Enter is however both printable and
8091 // non-printable. One would expect Tab to be as well (but it isn't).
8092 if (getEventCharCode(nativeEvent) === 0) {
8093 return;
8094 }
8095
8096 /* falls through */
8097
8098 case 'keydown':
8099 case 'keyup':
8100 SyntheticEventCtor = SyntheticKeyboardEvent;
8101 break;
8102
8103 case 'focusin':
8104 reactEventType = 'focus';
8105 SyntheticEventCtor = SyntheticFocusEvent;
8106 break;
8107
8108 case 'focusout':
8109 reactEventType = 'blur';
8110 SyntheticEventCtor = SyntheticFocusEvent;
8111 break;
8112
8113 case 'beforeblur':
8114 case 'afterblur':
8115 SyntheticEventCtor = SyntheticFocusEvent;
8116 break;
8117
8118 case 'click':
8119 // Firefox creates a click event on right mouse clicks. This removes the
8120 // unwanted click events.
8121 if (nativeEvent.button === 2) {
8122 return;
8123 }
8124
8125 /* falls through */
8126
8127 case 'auxclick':
8128 case 'dblclick':
8129 case 'mousedown':
8130 case 'mousemove':
8131 case 'mouseup': // TODO: Disabled elements should not respond to mouse events
8132
8133 /* falls through */
8134
8135 case 'mouseout':
8136 case 'mouseover':
8137 case 'contextmenu':
8138 SyntheticEventCtor = SyntheticMouseEvent;
8139 break;
8140
8141 case 'drag':
8142 case 'dragend':
8143 case 'dragenter':
8144 case 'dragexit':
8145 case 'dragleave':
8146 case 'dragover':
8147 case 'dragstart':
8148 case 'drop':
8149 SyntheticEventCtor = SyntheticDragEvent;
8150 break;
8151
8152 case 'touchcancel':
8153 case 'touchend':
8154 case 'touchmove':
8155 case 'touchstart':
8156 SyntheticEventCtor = SyntheticTouchEvent;
8157 break;
8158
8159 case ANIMATION_END:
8160 case ANIMATION_ITERATION:
8161 case ANIMATION_START:
8162 SyntheticEventCtor = SyntheticAnimationEvent;
8163 break;
8164
8165 case TRANSITION_END:
8166 SyntheticEventCtor = SyntheticTransitionEvent;
8167 break;
8168
8169 case 'scroll':
8170 SyntheticEventCtor = SyntheticUIEvent;
8171 break;
8172
8173 case 'wheel':
8174 SyntheticEventCtor = SyntheticWheelEvent;
8175 break;
8176
8177 case 'copy':
8178 case 'cut':
8179 case 'paste':
8180 SyntheticEventCtor = SyntheticClipboardEvent;
8181 break;
8182
8183 case 'gotpointercapture':
8184 case 'lostpointercapture':
8185 case 'pointercancel':
8186 case 'pointerdown':
8187 case 'pointermove':
8188 case 'pointerout':
8189 case 'pointerover':
8190 case 'pointerup':
8191 SyntheticEventCtor = SyntheticPointerEvent;
8192 break;
8193 }
8194
8195 var inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0;
8196
8197 {
8198 // Some events don't bubble in the browser.
8199 // In the past, React has always bubbled them, but this can be surprising.
8200 // We're going to try aligning closer to the browser behavior by not bubbling
8201 // them in React either. We'll start by not bubbling onScroll, and then expand.
8202 var accumulateTargetOnly = !inCapturePhase && // TODO: ideally, we'd eventually add all events from
8203 // nonDelegatedEvents list in DOMPluginEventSystem.
8204 // Then we can remove this special list.
8205 // This is a breaking change that can wait until React 18.
8206 domEventName === 'scroll';
8207
8208 var _listeners = accumulateSinglePhaseListeners(targetInst, reactName, nativeEvent.type, inCapturePhase, accumulateTargetOnly);
8209
8210 if (_listeners.length > 0) {
8211 // Intentionally create event lazily.
8212 var _event = new SyntheticEventCtor(reactName, reactEventType, null, nativeEvent, nativeEventTarget);
8213
8214 dispatchQueue.push({
8215 event: _event,
8216 listeners: _listeners
8217 });
8218 }
8219 }
8220 }
8221
8222 // TODO: remove top-level side effect.
8223 registerSimpleEvents();
8224 registerEvents$2();
8225 registerEvents$1();
8226 registerEvents$3();
8227 registerEvents();
8228
8229 function extractEvents$5(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
8230 // TODO: we should remove the concept of a "SimpleEventPlugin".
8231 // This is the basic functionality of the event system. All
8232 // the other plugins are essentially polyfills. So the plugin
8233 // should probably be inlined somewhere and have its logic
8234 // be core the to event system. This would potentially allow
8235 // us to ship builds of React without the polyfilled plugins below.
8236 extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
8237 var shouldProcessPolyfillPlugins = (eventSystemFlags & SHOULD_NOT_PROCESS_POLYFILL_EVENT_PLUGINS) === 0; // We don't process these events unless we are in the
8238 // event's native "bubble" phase, which means that we're
8239 // not in the capture phase. That's because we emulate
8240 // the capture phase here still. This is a trade-off,
8241 // because in an ideal world we would not emulate and use
8242 // the phases properly, like we do with the SimpleEvent
8243 // plugin. However, the plugins below either expect
8244 // emulation (EnterLeave) or use state localized to that
8245 // plugin (BeforeInput, Change, Select). The state in
8246 // these modules complicates things, as you'll essentially
8247 // get the case where the capture phase event might change
8248 // state, only for the following bubble event to come in
8249 // later and not trigger anything as the state now
8250 // invalidates the heuristics of the event plugin. We
8251 // could alter all these plugins to work in such ways, but
8252 // that might cause other unknown side-effects that we
8253 // can't forsee right now.
8254
8255 if (shouldProcessPolyfillPlugins) {
8256 extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
8257 extractEvents$1(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
8258 extractEvents$3(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
8259 extractEvents(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
8260 }
8261 } // List of events that need to be individually attached to media elements.
8262
8263
8264 var mediaEventTypes = ['abort', 'canplay', 'canplaythrough', 'durationchange', 'emptied', 'encrypted', 'ended', 'error', 'loadeddata', 'loadedmetadata', 'loadstart', 'pause', 'play', 'playing', 'progress', 'ratechange', 'seeked', 'seeking', 'stalled', 'suspend', 'timeupdate', 'volumechange', 'waiting']; // We should not delegate these events to the container, but rather
8265 // set them on the actual target element itself. This is primarily
8266 // because these events do not consistently bubble in the DOM.
8267
8268 var nonDelegatedEvents = new Set(['cancel', 'close', 'invalid', 'load', 'scroll', 'toggle'].concat(mediaEventTypes));
8269
8270 function executeDispatch(event, listener, currentTarget) {
8271 var type = event.type || 'unknown-event';
8272 event.currentTarget = currentTarget;
8273 invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
8274 event.currentTarget = null;
8275 }
8276
8277 function processDispatchQueueItemsInOrder(event, dispatchListeners, inCapturePhase) {
8278 var previousInstance;
8279
8280 if (inCapturePhase) {
8281 for (var i = dispatchListeners.length - 1; i >= 0; i--) {
8282 var _dispatchListeners$i = dispatchListeners[i],
8283 instance = _dispatchListeners$i.instance,
8284 currentTarget = _dispatchListeners$i.currentTarget,
8285 listener = _dispatchListeners$i.listener;
8286
8287 if (instance !== previousInstance && event.isPropagationStopped()) {
8288 return;
8289 }
8290
8291 executeDispatch(event, listener, currentTarget);
8292 previousInstance = instance;
8293 }
8294 } else {
8295 for (var _i = 0; _i < dispatchListeners.length; _i++) {
8296 var _dispatchListeners$_i = dispatchListeners[_i],
8297 _instance = _dispatchListeners$_i.instance,
8298 _currentTarget = _dispatchListeners$_i.currentTarget,
8299 _listener = _dispatchListeners$_i.listener;
8300
8301 if (_instance !== previousInstance && event.isPropagationStopped()) {
8302 return;
8303 }
8304
8305 executeDispatch(event, _listener, _currentTarget);
8306 previousInstance = _instance;
8307 }
8308 }
8309 }
8310
8311 function processDispatchQueue(dispatchQueue, eventSystemFlags) {
8312 var inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0;
8313
8314 for (var i = 0; i < dispatchQueue.length; i++) {
8315 var _dispatchQueue$i = dispatchQueue[i],
8316 event = _dispatchQueue$i.event,
8317 listeners = _dispatchQueue$i.listeners;
8318 processDispatchQueueItemsInOrder(event, listeners, inCapturePhase); // event system doesn't use pooling.
8319 } // This would be a good time to rethrow if any of the event handlers threw.
8320
8321
8322 rethrowCaughtError();
8323 }
8324
8325 function dispatchEventsForPlugins(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer) {
8326 var nativeEventTarget = getEventTarget(nativeEvent);
8327 var dispatchQueue = [];
8328 extractEvents$5(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
8329 processDispatchQueue(dispatchQueue, eventSystemFlags);
8330 }
8331
8332 function listenToNonDelegatedEvent(domEventName, targetElement) {
8333 var isCapturePhaseListener = false;
8334 var listenerSet = getEventListenerSet(targetElement);
8335 var listenerSetKey = getListenerSetKey(domEventName, isCapturePhaseListener);
8336
8337 if (!listenerSet.has(listenerSetKey)) {
8338 addTrappedEventListener(targetElement, domEventName, IS_NON_DELEGATED, isCapturePhaseListener);
8339 listenerSet.add(listenerSetKey);
8340 }
8341 }
8342 var listeningMarker = '_reactListening' + Math.random().toString(36).slice(2);
8343 function listenToAllSupportedEvents(rootContainerElement) {
8344 {
8345 if (rootContainerElement[listeningMarker]) {
8346 // Performance optimization: don't iterate through events
8347 // for the same portal container or root node more than once.
8348 // TODO: once we remove the flag, we may be able to also
8349 // remove some of the bookkeeping maps used for laziness.
8350 return;
8351 }
8352
8353 rootContainerElement[listeningMarker] = true;
8354 allNativeEvents.forEach(function (domEventName) {
8355 if (!nonDelegatedEvents.has(domEventName)) {
8356 listenToNativeEvent(domEventName, false, rootContainerElement, null);
8357 }
8358
8359 listenToNativeEvent(domEventName, true, rootContainerElement, null);
8360 });
8361 }
8362 }
8363 function listenToNativeEvent(domEventName, isCapturePhaseListener, rootContainerElement, targetElement) {
8364 var eventSystemFlags = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
8365 var target = rootContainerElement; // selectionchange needs to be attached to the document
8366 // otherwise it won't capture incoming events that are only
8367 // triggered on the document directly.
8368
8369 if (domEventName === 'selectionchange' && rootContainerElement.nodeType !== DOCUMENT_NODE) {
8370 target = rootContainerElement.ownerDocument;
8371 } // If the event can be delegated (or is capture phase), we can
8372 // register it to the root container. Otherwise, we should
8373 // register the event to the target element and mark it as
8374 // a non-delegated event.
8375
8376
8377 if (targetElement !== null && !isCapturePhaseListener && nonDelegatedEvents.has(domEventName)) {
8378 // For all non-delegated events, apart from scroll, we attach
8379 // their event listeners to the respective elements that their
8380 // events fire on. That means we can skip this step, as event
8381 // listener has already been added previously. However, we
8382 // special case the scroll event because the reality is that any
8383 // element can scroll.
8384 // TODO: ideally, we'd eventually apply the same logic to all
8385 // events from the nonDelegatedEvents list. Then we can remove
8386 // this special case and use the same logic for all events.
8387 if (domEventName !== 'scroll') {
8388 return;
8389 }
8390
8391 eventSystemFlags |= IS_NON_DELEGATED;
8392 target = targetElement;
8393 }
8394
8395 var listenerSet = getEventListenerSet(target);
8396 var listenerSetKey = getListenerSetKey(domEventName, isCapturePhaseListener); // If the listener entry is empty or we should upgrade, then
8397 // we need to trap an event listener onto the target.
8398
8399 if (!listenerSet.has(listenerSetKey)) {
8400 if (isCapturePhaseListener) {
8401 eventSystemFlags |= IS_CAPTURE_PHASE;
8402 }
8403
8404 addTrappedEventListener(target, domEventName, eventSystemFlags, isCapturePhaseListener);
8405 listenerSet.add(listenerSetKey);
8406 }
8407 }
8408
8409 function addTrappedEventListener(targetContainer, domEventName, eventSystemFlags, isCapturePhaseListener, isDeferredListenerForLegacyFBSupport) {
8410 var listener = createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags); // If passive option is not supported, then the event will be
8411 // active and not passive.
8412
8413 var isPassiveListener = undefined;
8414
8415 if (passiveBrowserEventsSupported) {
8416 // Browsers introduced an intervention, making these events
8417 // passive by default on document. React doesn't bind them
8418 // to document anymore, but changing this now would undo
8419 // the performance wins from the change. So we emulate
8420 // the existing behavior manually on the roots now.
8421 // https://github.com/facebook/react/issues/19651
8422 if (domEventName === 'touchstart' || domEventName === 'touchmove' || domEventName === 'wheel') {
8423 isPassiveListener = true;
8424 }
8425 }
8426
8427 targetContainer = targetContainer;
8428 var unsubscribeListener; // When legacyFBSupport is enabled, it's for when we
8429
8430
8431 if (isCapturePhaseListener) {
8432 if (isPassiveListener !== undefined) {
8433 unsubscribeListener = addEventCaptureListenerWithPassiveFlag(targetContainer, domEventName, listener, isPassiveListener);
8434 } else {
8435 unsubscribeListener = addEventCaptureListener(targetContainer, domEventName, listener);
8436 }
8437 } else {
8438 if (isPassiveListener !== undefined) {
8439 unsubscribeListener = addEventBubbleListenerWithPassiveFlag(targetContainer, domEventName, listener, isPassiveListener);
8440 } else {
8441 unsubscribeListener = addEventBubbleListener(targetContainer, domEventName, listener);
8442 }
8443 }
8444 }
8445
8446 function isMatchingRootContainer(grandContainer, targetContainer) {
8447 return grandContainer === targetContainer || grandContainer.nodeType === COMMENT_NODE && grandContainer.parentNode === targetContainer;
8448 }
8449
8450 function dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer) {
8451 var ancestorInst = targetInst;
8452
8453 if ((eventSystemFlags & IS_EVENT_HANDLE_NON_MANAGED_NODE) === 0 && (eventSystemFlags & IS_NON_DELEGATED) === 0) {
8454 var targetContainerNode = targetContainer; // If we are using the legacy FB support flag, we
8455
8456 if (targetInst !== null) {
8457 // The below logic attempts to work out if we need to change
8458 // the target fiber to a different ancestor. We had similar logic
8459 // in the legacy event system, except the big difference between
8460 // systems is that the modern event system now has an event listener
8461 // attached to each React Root and React Portal Root. Together,
8462 // the DOM nodes representing these roots are the "rootContainer".
8463 // To figure out which ancestor instance we should use, we traverse
8464 // up the fiber tree from the target instance and attempt to find
8465 // root boundaries that match that of our current "rootContainer".
8466 // If we find that "rootContainer", we find the parent fiber
8467 // sub-tree for that root and make that our ancestor instance.
8468 var node = targetInst;
8469
8470 mainLoop: while (true) {
8471 if (node === null) {
8472 return;
8473 }
8474
8475 var nodeTag = node.tag;
8476
8477 if (nodeTag === HostRoot || nodeTag === HostPortal) {
8478 var container = node.stateNode.containerInfo;
8479
8480 if (isMatchingRootContainer(container, targetContainerNode)) {
8481 break;
8482 }
8483
8484 if (nodeTag === HostPortal) {
8485 // The target is a portal, but it's not the rootContainer we're looking for.
8486 // Normally portals handle their own events all the way down to the root.
8487 // So we should be able to stop now. However, we don't know if this portal
8488 // was part of *our* root.
8489 var grandNode = node.return;
8490
8491 while (grandNode !== null) {
8492 var grandTag = grandNode.tag;
8493
8494 if (grandTag === HostRoot || grandTag === HostPortal) {
8495 var grandContainer = grandNode.stateNode.containerInfo;
8496
8497 if (isMatchingRootContainer(grandContainer, targetContainerNode)) {
8498 // This is the rootContainer we're looking for and we found it as
8499 // a parent of the Portal. That means we can ignore it because the
8500 // Portal will bubble through to us.
8501 return;
8502 }
8503 }
8504
8505 grandNode = grandNode.return;
8506 }
8507 } // Now we need to find it's corresponding host fiber in the other
8508 // tree. To do this we can use getClosestInstanceFromNode, but we
8509 // need to validate that the fiber is a host instance, otherwise
8510 // we need to traverse up through the DOM till we find the correct
8511 // node that is from the other tree.
8512
8513
8514 while (container !== null) {
8515 var parentNode = getClosestInstanceFromNode(container);
8516
8517 if (parentNode === null) {
8518 return;
8519 }
8520
8521 var parentTag = parentNode.tag;
8522
8523 if (parentTag === HostComponent || parentTag === HostText) {
8524 node = ancestorInst = parentNode;
8525 continue mainLoop;
8526 }
8527
8528 container = container.parentNode;
8529 }
8530 }
8531
8532 node = node.return;
8533 }
8534 }
8535 }
8536
8537 batchedEventUpdates(function () {
8538 return dispatchEventsForPlugins(domEventName, eventSystemFlags, nativeEvent, ancestorInst);
8539 });
8540 }
8541
8542 function createDispatchListener(instance, listener, currentTarget) {
8543 return {
8544 instance: instance,
8545 listener: listener,
8546 currentTarget: currentTarget
8547 };
8548 }
8549
8550 function accumulateSinglePhaseListeners(targetFiber, reactName, nativeEventType, inCapturePhase, accumulateTargetOnly) {
8551 var captureName = reactName !== null ? reactName + 'Capture' : null;
8552 var reactEventName = inCapturePhase ? captureName : reactName;
8553 var listeners = [];
8554 var instance = targetFiber;
8555 var lastHostComponent = null; // Accumulate all instances and listeners via the target -> root path.
8556
8557 while (instance !== null) {
8558 var _instance2 = instance,
8559 stateNode = _instance2.stateNode,
8560 tag = _instance2.tag; // Handle listeners that are on HostComponents (i.e. <div>)
8561
8562 if (tag === HostComponent && stateNode !== null) {
8563 lastHostComponent = stateNode; // createEventHandle listeners
8564
8565
8566 if (reactEventName !== null) {
8567 var listener = getListener(instance, reactEventName);
8568
8569 if (listener != null) {
8570 listeners.push(createDispatchListener(instance, listener, lastHostComponent));
8571 }
8572 }
8573 } // If we are only accumulating events for the target, then we don't
8574 // continue to propagate through the React fiber tree to find other
8575 // listeners.
8576
8577
8578 if (accumulateTargetOnly) {
8579 break;
8580 }
8581
8582 instance = instance.return;
8583 }
8584
8585 return listeners;
8586 } // We should only use this function for:
8587 // - BeforeInputEventPlugin
8588 // - ChangeEventPlugin
8589 // - SelectEventPlugin
8590 // This is because we only process these plugins
8591 // in the bubble phase, so we need to accumulate two
8592 // phase event listeners (via emulation).
8593
8594 function accumulateTwoPhaseListeners(targetFiber, reactName) {
8595 var captureName = reactName + 'Capture';
8596 var listeners = [];
8597 var instance = targetFiber; // Accumulate all instances and listeners via the target -> root path.
8598
8599 while (instance !== null) {
8600 var _instance3 = instance,
8601 stateNode = _instance3.stateNode,
8602 tag = _instance3.tag; // Handle listeners that are on HostComponents (i.e. <div>)
8603
8604 if (tag === HostComponent && stateNode !== null) {
8605 var currentTarget = stateNode;
8606 var captureListener = getListener(instance, captureName);
8607
8608 if (captureListener != null) {
8609 listeners.unshift(createDispatchListener(instance, captureListener, currentTarget));
8610 }
8611
8612 var bubbleListener = getListener(instance, reactName);
8613
8614 if (bubbleListener != null) {
8615 listeners.push(createDispatchListener(instance, bubbleListener, currentTarget));
8616 }
8617 }
8618
8619 instance = instance.return;
8620 }
8621
8622 return listeners;
8623 }
8624
8625 function getParent(inst) {
8626 if (inst === null) {
8627 return null;
8628 }
8629
8630 do {
8631 inst = inst.return; // TODO: If this is a HostRoot we might want to bail out.
8632 // That is depending on if we want nested subtrees (layers) to bubble
8633 // events to their parent. We could also go through parentNode on the
8634 // host node but that wouldn't work for React Native and doesn't let us
8635 // do the portal feature.
8636 } while (inst && inst.tag !== HostComponent);
8637
8638 if (inst) {
8639 return inst;
8640 }
8641
8642 return null;
8643 }
8644 /**
8645 * Return the lowest common ancestor of A and B, or null if they are in
8646 * different trees.
8647 */
8648
8649
8650 function getLowestCommonAncestor(instA, instB) {
8651 var nodeA = instA;
8652 var nodeB = instB;
8653 var depthA = 0;
8654
8655 for (var tempA = nodeA; tempA; tempA = getParent(tempA)) {
8656 depthA++;
8657 }
8658
8659 var depthB = 0;
8660
8661 for (var tempB = nodeB; tempB; tempB = getParent(tempB)) {
8662 depthB++;
8663 } // If A is deeper, crawl up.
8664
8665
8666 while (depthA - depthB > 0) {
8667 nodeA = getParent(nodeA);
8668 depthA--;
8669 } // If B is deeper, crawl up.
8670
8671
8672 while (depthB - depthA > 0) {
8673 nodeB = getParent(nodeB);
8674 depthB--;
8675 } // Walk in lockstep until we find a match.
8676
8677
8678 var depth = depthA;
8679
8680 while (depth--) {
8681 if (nodeA === nodeB || nodeB !== null && nodeA === nodeB.alternate) {
8682 return nodeA;
8683 }
8684
8685 nodeA = getParent(nodeA);
8686 nodeB = getParent(nodeB);
8687 }
8688
8689 return null;
8690 }
8691
8692 function accumulateEnterLeaveListenersForEvent(dispatchQueue, event, target, common, inCapturePhase) {
8693 var registrationName = event._reactName;
8694 var listeners = [];
8695 var instance = target;
8696
8697 while (instance !== null) {
8698 if (instance === common) {
8699 break;
8700 }
8701
8702 var _instance4 = instance,
8703 alternate = _instance4.alternate,
8704 stateNode = _instance4.stateNode,
8705 tag = _instance4.tag;
8706
8707 if (alternate !== null && alternate === common) {
8708 break;
8709 }
8710
8711 if (tag === HostComponent && stateNode !== null) {
8712 var currentTarget = stateNode;
8713
8714 if (inCapturePhase) {
8715 var captureListener = getListener(instance, registrationName);
8716
8717 if (captureListener != null) {
8718 listeners.unshift(createDispatchListener(instance, captureListener, currentTarget));
8719 }
8720 } else if (!inCapturePhase) {
8721 var bubbleListener = getListener(instance, registrationName);
8722
8723 if (bubbleListener != null) {
8724 listeners.push(createDispatchListener(instance, bubbleListener, currentTarget));
8725 }
8726 }
8727 }
8728
8729 instance = instance.return;
8730 }
8731
8732 if (listeners.length !== 0) {
8733 dispatchQueue.push({
8734 event: event,
8735 listeners: listeners
8736 });
8737 }
8738 } // We should only use this function for:
8739 // - EnterLeaveEventPlugin
8740 // This is because we only process this plugin
8741 // in the bubble phase, so we need to accumulate two
8742 // phase event listeners.
8743
8744
8745 function accumulateEnterLeaveTwoPhaseListeners(dispatchQueue, leaveEvent, enterEvent, from, to) {
8746 var common = from && to ? getLowestCommonAncestor(from, to) : null;
8747
8748 if (from !== null) {
8749 accumulateEnterLeaveListenersForEvent(dispatchQueue, leaveEvent, from, common, false);
8750 }
8751
8752 if (to !== null && enterEvent !== null) {
8753 accumulateEnterLeaveListenersForEvent(dispatchQueue, enterEvent, to, common, true);
8754 }
8755 }
8756 function getListenerSetKey(domEventName, capture) {
8757 return domEventName + "__" + (capture ? 'capture' : 'bubble');
8758 }
8759
8760 var didWarnInvalidHydration = false;
8761 var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
8762 var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
8763 var SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
8764 var AUTOFOCUS = 'autoFocus';
8765 var CHILDREN = 'children';
8766 var STYLE = 'style';
8767 var HTML$1 = '__html';
8768 var HTML_NAMESPACE$1 = Namespaces.html;
8769 var warnedUnknownTags;
8770 var suppressHydrationWarning;
8771 var validatePropertiesInDevelopment;
8772 var warnForTextDifference;
8773 var warnForPropDifference;
8774 var warnForExtraAttributes;
8775 var warnForInvalidEventListener;
8776 var canDiffStyleForHydrationWarning;
8777 var normalizeMarkupForTextOrAttribute;
8778 var normalizeHTML;
8779
8780 {
8781 warnedUnknownTags = {
8782 // There are working polyfills for <dialog>. Let people use it.
8783 dialog: true,
8784 // Electron ships a custom <webview> tag to display external web content in
8785 // an isolated frame and process.
8786 // This tag is not present in non Electron environments such as JSDom which
8787 // is often used for testing purposes.
8788 // @see https://electronjs.org/docs/api/webview-tag
8789 webview: true
8790 };
8791
8792 validatePropertiesInDevelopment = function (type, props) {
8793 validateProperties(type, props);
8794 validateProperties$1(type, props);
8795 validateProperties$2(type, props, {
8796 registrationNameDependencies: registrationNameDependencies,
8797 possibleRegistrationNames: possibleRegistrationNames
8798 });
8799 }; // IE 11 parses & normalizes the style attribute as opposed to other
8800 // browsers. It adds spaces and sorts the properties in some
8801 // non-alphabetical order. Handling that would require sorting CSS
8802 // properties in the client & server versions or applying
8803 // `expectedStyle` to a temporary DOM node to read its `style` attribute
8804 // normalized. Since it only affects IE, we're skipping style warnings
8805 // in that browser completely in favor of doing all that work.
8806 // See https://github.com/facebook/react/issues/11807
8807
8808
8809 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode; // HTML parsing normalizes CR and CRLF to LF.
8810 // It also can turn \u0000 into \uFFFD inside attributes.
8811 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
8812 // If we have a mismatch, it might be caused by that.
8813 // We will still patch up in this case but not fire the warning.
8814
8815 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
8816 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
8817
8818 normalizeMarkupForTextOrAttribute = function (markup) {
8819 var markupString = typeof markup === 'string' ? markup : '' + markup;
8820 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
8821 };
8822
8823 warnForTextDifference = function (serverText, clientText) {
8824 if (didWarnInvalidHydration) {
8825 return;
8826 }
8827
8828 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
8829 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
8830
8831 if (normalizedServerText === normalizedClientText) {
8832 return;
8833 }
8834
8835 didWarnInvalidHydration = true;
8836
8837 error('Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
8838 };
8839
8840 warnForPropDifference = function (propName, serverValue, clientValue) {
8841 if (didWarnInvalidHydration) {
8842 return;
8843 }
8844
8845 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
8846 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
8847
8848 if (normalizedServerValue === normalizedClientValue) {
8849 return;
8850 }
8851
8852 didWarnInvalidHydration = true;
8853
8854 error('Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
8855 };
8856
8857 warnForExtraAttributes = function (attributeNames) {
8858 if (didWarnInvalidHydration) {
8859 return;
8860 }
8861
8862 didWarnInvalidHydration = true;
8863 var names = [];
8864 attributeNames.forEach(function (name) {
8865 names.push(name);
8866 });
8867
8868 error('Extra attributes from the server: %s', names);
8869 };
8870
8871 warnForInvalidEventListener = function (registrationName, listener) {
8872 if (listener === false) {
8873 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);
8874 } else {
8875 error('Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener);
8876 }
8877 }; // Parse the HTML and read it back to normalize the HTML string so that it
8878 // can be used for comparison.
8879
8880
8881 normalizeHTML = function (parent, html) {
8882 // We could have created a separate document here to avoid
8883 // re-initializing custom elements if they exist. But this breaks
8884 // how <noscript> is being handled. So we use the same document.
8885 // See the discussion in https://github.com/facebook/react/pull/11157.
8886 var testElement = parent.namespaceURI === HTML_NAMESPACE$1 ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
8887 testElement.innerHTML = html;
8888 return testElement.innerHTML;
8889 };
8890 }
8891
8892 function getOwnerDocumentFromRootContainer(rootContainerElement) {
8893 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
8894 }
8895
8896 function noop() {}
8897
8898 function trapClickOnNonInteractiveElement(node) {
8899 // Mobile Safari does not fire properly bubble click events on
8900 // non-interactive elements, which means delegated click listeners do not
8901 // fire. The workaround for this bug involves attaching an empty click
8902 // listener on the target node.
8903 // https://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
8904 // Just set it using the onclick property so that we don't have to manage any
8905 // bookkeeping for it. Not sure if we need to clear it when the listener is
8906 // removed.
8907 // TODO: Only do this for the relevant Safaris maybe?
8908 node.onclick = noop;
8909 }
8910
8911 function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
8912 for (var propKey in nextProps) {
8913 if (!nextProps.hasOwnProperty(propKey)) {
8914 continue;
8915 }
8916
8917 var nextProp = nextProps[propKey];
8918
8919 if (propKey === STYLE) {
8920 {
8921 if (nextProp) {
8922 // Freeze the next style object so that we can assume it won't be
8923 // mutated. We have already warned for this in the past.
8924 Object.freeze(nextProp);
8925 }
8926 } // Relies on `updateStylesByID` not mutating `styleUpdates`.
8927
8928
8929 setValueForStyles(domElement, nextProp);
8930 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
8931 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
8932
8933 if (nextHtml != null) {
8934 setInnerHTML(domElement, nextHtml);
8935 }
8936 } else if (propKey === CHILDREN) {
8937 if (typeof nextProp === 'string') {
8938 // Avoid setting initial textContent when the text is empty. In IE11 setting
8939 // textContent on a <textarea> will cause the placeholder to not
8940 // show within the <textarea> until it has been focused and blurred again.
8941 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
8942 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
8943
8944 if (canSetTextContent) {
8945 setTextContent(domElement, nextProp);
8946 }
8947 } else if (typeof nextProp === 'number') {
8948 setTextContent(domElement, '' + nextProp);
8949 }
8950 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (propKey === AUTOFOCUS) ; else if (registrationNameDependencies.hasOwnProperty(propKey)) {
8951 if (nextProp != null) {
8952 if ( typeof nextProp !== 'function') {
8953 warnForInvalidEventListener(propKey, nextProp);
8954 }
8955
8956 if (propKey === 'onScroll') {
8957 listenToNonDelegatedEvent('scroll', domElement);
8958 }
8959 }
8960 } else if (nextProp != null) {
8961 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
8962 }
8963 }
8964 }
8965
8966 function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
8967 // TODO: Handle wasCustomComponentTag
8968 for (var i = 0; i < updatePayload.length; i += 2) {
8969 var propKey = updatePayload[i];
8970 var propValue = updatePayload[i + 1];
8971
8972 if (propKey === STYLE) {
8973 setValueForStyles(domElement, propValue);
8974 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
8975 setInnerHTML(domElement, propValue);
8976 } else if (propKey === CHILDREN) {
8977 setTextContent(domElement, propValue);
8978 } else {
8979 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
8980 }
8981 }
8982 }
8983
8984 function createElement(type, props, rootContainerElement, parentNamespace) {
8985 var isCustomComponentTag; // We create tags in the namespace of their parent container, except HTML
8986 // tags get no namespace.
8987
8988 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
8989 var domElement;
8990 var namespaceURI = parentNamespace;
8991
8992 if (namespaceURI === HTML_NAMESPACE$1) {
8993 namespaceURI = getIntrinsicNamespace(type);
8994 }
8995
8996 if (namespaceURI === HTML_NAMESPACE$1) {
8997 {
8998 isCustomComponentTag = isCustomComponent(type, props); // Should this check be gated by parent namespace? Not sure we want to
8999 // allow <SVG> or <mATH>.
9000
9001 if (!isCustomComponentTag && type !== type.toLowerCase()) {
9002 error('<%s /> is using incorrect casing. ' + 'Use PascalCase for React components, ' + 'or lowercase for HTML elements.', type);
9003 }
9004 }
9005
9006 if (type === 'script') {
9007 // Create the script via .innerHTML so its "parser-inserted" flag is
9008 // set to true and it does not execute
9009 var div = ownerDocument.createElement('div');
9010
9011 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
9012 // This is guaranteed to yield a script element.
9013
9014 var firstChild = div.firstChild;
9015 domElement = div.removeChild(firstChild);
9016 } else if (typeof props.is === 'string') {
9017 // $FlowIssue `createElement` should be updated for Web Components
9018 domElement = ownerDocument.createElement(type, {
9019 is: props.is
9020 });
9021 } else {
9022 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
9023 // See discussion in https://github.com/facebook/react/pull/6896
9024 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
9025 domElement = ownerDocument.createElement(type); // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple` and `size`
9026 // attributes on `select`s needs to be added before `option`s are inserted.
9027 // This prevents:
9028 // - a bug where the `select` does not scroll to the correct option because singular
9029 // `select` elements automatically pick the first item #13222
9030 // - a bug where the `select` set the first item as selected despite the `size` attribute #14239
9031 // See https://github.com/facebook/react/issues/13222
9032 // and https://github.com/facebook/react/issues/14239
9033
9034 if (type === 'select') {
9035 var node = domElement;
9036
9037 if (props.multiple) {
9038 node.multiple = true;
9039 } else if (props.size) {
9040 // Setting a size greater than 1 causes a select to behave like `multiple=true`, where
9041 // it is possible that no option is selected.
9042 //
9043 // This is only necessary when a select in "single selection mode".
9044 node.size = props.size;
9045 }
9046 }
9047 }
9048 } else {
9049 domElement = ownerDocument.createElementNS(namespaceURI, type);
9050 }
9051
9052 {
9053 if (namespaceURI === HTML_NAMESPACE$1) {
9054 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) {
9055 warnedUnknownTags[type] = true;
9056
9057 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);
9058 }
9059 }
9060 }
9061
9062 return domElement;
9063 }
9064 function createTextNode(text, rootContainerElement) {
9065 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
9066 }
9067 function setInitialProperties(domElement, tag, rawProps, rootContainerElement) {
9068 var isCustomComponentTag = isCustomComponent(tag, rawProps);
9069
9070 {
9071 validatePropertiesInDevelopment(tag, rawProps);
9072 } // TODO: Make sure that we check isMounted before firing any of these events.
9073
9074
9075 var props;
9076
9077 switch (tag) {
9078 case 'dialog':
9079 listenToNonDelegatedEvent('cancel', domElement);
9080 listenToNonDelegatedEvent('close', domElement);
9081 props = rawProps;
9082 break;
9083
9084 case 'iframe':
9085 case 'object':
9086 case 'embed':
9087 // We listen to this event in case to ensure emulated bubble
9088 // listeners still fire for the load event.
9089 listenToNonDelegatedEvent('load', domElement);
9090 props = rawProps;
9091 break;
9092
9093 case 'video':
9094 case 'audio':
9095 // We listen to these events in case to ensure emulated bubble
9096 // listeners still fire for all the media events.
9097 for (var i = 0; i < mediaEventTypes.length; i++) {
9098 listenToNonDelegatedEvent(mediaEventTypes[i], domElement);
9099 }
9100
9101 props = rawProps;
9102 break;
9103
9104 case 'source':
9105 // We listen to this event in case to ensure emulated bubble
9106 // listeners still fire for the error event.
9107 listenToNonDelegatedEvent('error', domElement);
9108 props = rawProps;
9109 break;
9110
9111 case 'img':
9112 case 'image':
9113 case 'link':
9114 // We listen to these events in case to ensure emulated bubble
9115 // listeners still fire for error and load events.
9116 listenToNonDelegatedEvent('error', domElement);
9117 listenToNonDelegatedEvent('load', domElement);
9118 props = rawProps;
9119 break;
9120
9121 case 'details':
9122 // We listen to this event in case to ensure emulated bubble
9123 // listeners still fire for the toggle event.
9124 listenToNonDelegatedEvent('toggle', domElement);
9125 props = rawProps;
9126 break;
9127
9128 case 'input':
9129 initWrapperState(domElement, rawProps);
9130 props = getHostProps(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9131 // listeners still fire for the invalid event.
9132
9133 listenToNonDelegatedEvent('invalid', domElement);
9134
9135 break;
9136
9137 case 'option':
9138 validateProps(domElement, rawProps);
9139 props = getHostProps$1(domElement, rawProps);
9140 break;
9141
9142 case 'select':
9143 initWrapperState$1(domElement, rawProps);
9144 props = getHostProps$2(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9145 // listeners still fire for the invalid event.
9146
9147 listenToNonDelegatedEvent('invalid', domElement);
9148
9149 break;
9150
9151 case 'textarea':
9152 initWrapperState$2(domElement, rawProps);
9153 props = getHostProps$3(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9154 // listeners still fire for the invalid event.
9155
9156 listenToNonDelegatedEvent('invalid', domElement);
9157
9158 break;
9159
9160 default:
9161 props = rawProps;
9162 }
9163
9164 assertValidProps(tag, props);
9165 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
9166
9167 switch (tag) {
9168 case 'input':
9169 // TODO: Make sure we check if this is still unmounted or do any clean
9170 // up necessary since we never stop tracking anymore.
9171 track(domElement);
9172 postMountWrapper(domElement, rawProps, false);
9173 break;
9174
9175 case 'textarea':
9176 // TODO: Make sure we check if this is still unmounted or do any clean
9177 // up necessary since we never stop tracking anymore.
9178 track(domElement);
9179 postMountWrapper$3(domElement);
9180 break;
9181
9182 case 'option':
9183 postMountWrapper$1(domElement, rawProps);
9184 break;
9185
9186 case 'select':
9187 postMountWrapper$2(domElement, rawProps);
9188 break;
9189
9190 default:
9191 if (typeof props.onClick === 'function') {
9192 // TODO: This cast may not be sound for SVG, MathML or custom elements.
9193 trapClickOnNonInteractiveElement(domElement);
9194 }
9195
9196 break;
9197 }
9198 } // Calculate the diff between the two objects.
9199
9200 function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
9201 {
9202 validatePropertiesInDevelopment(tag, nextRawProps);
9203 }
9204
9205 var updatePayload = null;
9206 var lastProps;
9207 var nextProps;
9208
9209 switch (tag) {
9210 case 'input':
9211 lastProps = getHostProps(domElement, lastRawProps);
9212 nextProps = getHostProps(domElement, nextRawProps);
9213 updatePayload = [];
9214 break;
9215
9216 case 'option':
9217 lastProps = getHostProps$1(domElement, lastRawProps);
9218 nextProps = getHostProps$1(domElement, nextRawProps);
9219 updatePayload = [];
9220 break;
9221
9222 case 'select':
9223 lastProps = getHostProps$2(domElement, lastRawProps);
9224 nextProps = getHostProps$2(domElement, nextRawProps);
9225 updatePayload = [];
9226 break;
9227
9228 case 'textarea':
9229 lastProps = getHostProps$3(domElement, lastRawProps);
9230 nextProps = getHostProps$3(domElement, nextRawProps);
9231 updatePayload = [];
9232 break;
9233
9234 default:
9235 lastProps = lastRawProps;
9236 nextProps = nextRawProps;
9237
9238 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
9239 // TODO: This cast may not be sound for SVG, MathML or custom elements.
9240 trapClickOnNonInteractiveElement(domElement);
9241 }
9242
9243 break;
9244 }
9245
9246 assertValidProps(tag, nextProps);
9247 var propKey;
9248 var styleName;
9249 var styleUpdates = null;
9250
9251 for (propKey in lastProps) {
9252 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
9253 continue;
9254 }
9255
9256 if (propKey === STYLE) {
9257 var lastStyle = lastProps[propKey];
9258
9259 for (styleName in lastStyle) {
9260 if (lastStyle.hasOwnProperty(styleName)) {
9261 if (!styleUpdates) {
9262 styleUpdates = {};
9263 }
9264
9265 styleUpdates[styleName] = '';
9266 }
9267 }
9268 } 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)) {
9269 // This is a special case. If any listener updates we need to ensure
9270 // that the "current" fiber pointer gets updated so we need a commit
9271 // to update this element.
9272 if (!updatePayload) {
9273 updatePayload = [];
9274 }
9275 } else {
9276 // For all other deleted properties we add it to the queue. We use
9277 // the allowed property list in the commit phase instead.
9278 (updatePayload = updatePayload || []).push(propKey, null);
9279 }
9280 }
9281
9282 for (propKey in nextProps) {
9283 var nextProp = nextProps[propKey];
9284 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
9285
9286 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
9287 continue;
9288 }
9289
9290 if (propKey === STYLE) {
9291 {
9292 if (nextProp) {
9293 // Freeze the next style object so that we can assume it won't be
9294 // mutated. We have already warned for this in the past.
9295 Object.freeze(nextProp);
9296 }
9297 }
9298
9299 if (lastProp) {
9300 // Unset styles on `lastProp` but not on `nextProp`.
9301 for (styleName in lastProp) {
9302 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
9303 if (!styleUpdates) {
9304 styleUpdates = {};
9305 }
9306
9307 styleUpdates[styleName] = '';
9308 }
9309 } // Update styles that changed since `lastProp`.
9310
9311
9312 for (styleName in nextProp) {
9313 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
9314 if (!styleUpdates) {
9315 styleUpdates = {};
9316 }
9317
9318 styleUpdates[styleName] = nextProp[styleName];
9319 }
9320 }
9321 } else {
9322 // Relies on `updateStylesByID` not mutating `styleUpdates`.
9323 if (!styleUpdates) {
9324 if (!updatePayload) {
9325 updatePayload = [];
9326 }
9327
9328 updatePayload.push(propKey, styleUpdates);
9329 }
9330
9331 styleUpdates = nextProp;
9332 }
9333 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
9334 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
9335 var lastHtml = lastProp ? lastProp[HTML$1] : undefined;
9336
9337 if (nextHtml != null) {
9338 if (lastHtml !== nextHtml) {
9339 (updatePayload = updatePayload || []).push(propKey, nextHtml);
9340 }
9341 }
9342 } else if (propKey === CHILDREN) {
9343 if (typeof nextProp === 'string' || typeof nextProp === 'number') {
9344 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
9345 }
9346 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (registrationNameDependencies.hasOwnProperty(propKey)) {
9347 if (nextProp != null) {
9348 // We eagerly listen to this even though we haven't committed yet.
9349 if ( typeof nextProp !== 'function') {
9350 warnForInvalidEventListener(propKey, nextProp);
9351 }
9352
9353 if (propKey === 'onScroll') {
9354 listenToNonDelegatedEvent('scroll', domElement);
9355 }
9356 }
9357
9358 if (!updatePayload && lastProp !== nextProp) {
9359 // This is a special case. If any listener updates we need to ensure
9360 // that the "current" props pointer gets updated so we need a commit
9361 // to update this element.
9362 updatePayload = [];
9363 }
9364 } else if (typeof nextProp === 'object' && nextProp !== null && nextProp.$$typeof === REACT_OPAQUE_ID_TYPE) {
9365 // If we encounter useOpaqueReference's opaque object, this means we are hydrating.
9366 // In this case, call the opaque object's toString function which generates a new client
9367 // ID so client and server IDs match and throws to rerender.
9368 nextProp.toString();
9369 } else {
9370 // For any other property we always add it to the queue and then we
9371 // filter it out using the allowed property list during the commit.
9372 (updatePayload = updatePayload || []).push(propKey, nextProp);
9373 }
9374 }
9375
9376 if (styleUpdates) {
9377 {
9378 validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE]);
9379 }
9380
9381 (updatePayload = updatePayload || []).push(STYLE, styleUpdates);
9382 }
9383
9384 return updatePayload;
9385 } // Apply the diff.
9386
9387 function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
9388 // Update checked *before* name.
9389 // In the middle of an update, it is possible to have multiple checked.
9390 // When a checked radio tries to change name, browser makes another radio's checked false.
9391 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
9392 updateChecked(domElement, nextRawProps);
9393 }
9394
9395 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
9396 var isCustomComponentTag = isCustomComponent(tag, nextRawProps); // Apply the diff.
9397
9398 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag); // TODO: Ensure that an update gets scheduled if any of the special props
9399 // changed.
9400
9401 switch (tag) {
9402 case 'input':
9403 // Update the wrapper around inputs *after* updating props. This has to
9404 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
9405 // raise warnings and prevent the new value from being assigned.
9406 updateWrapper(domElement, nextRawProps);
9407 break;
9408
9409 case 'textarea':
9410 updateWrapper$1(domElement, nextRawProps);
9411 break;
9412
9413 case 'select':
9414 // <select> value update needs to occur after <option> children
9415 // reconciliation
9416 postUpdateWrapper(domElement, nextRawProps);
9417 break;
9418 }
9419 }
9420
9421 function getPossibleStandardName(propName) {
9422 {
9423 var lowerCasedName = propName.toLowerCase();
9424
9425 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
9426 return null;
9427 }
9428
9429 return possibleStandardNames[lowerCasedName] || null;
9430 }
9431 }
9432
9433 function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement) {
9434 var isCustomComponentTag;
9435 var extraAttributeNames;
9436
9437 {
9438 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING] === true;
9439 isCustomComponentTag = isCustomComponent(tag, rawProps);
9440 validatePropertiesInDevelopment(tag, rawProps);
9441 } // TODO: Make sure that we check isMounted before firing any of these events.
9442
9443
9444 switch (tag) {
9445 case 'dialog':
9446 listenToNonDelegatedEvent('cancel', domElement);
9447 listenToNonDelegatedEvent('close', domElement);
9448 break;
9449
9450 case 'iframe':
9451 case 'object':
9452 case 'embed':
9453 // We listen to this event in case to ensure emulated bubble
9454 // listeners still fire for the load event.
9455 listenToNonDelegatedEvent('load', domElement);
9456 break;
9457
9458 case 'video':
9459 case 'audio':
9460 // We listen to these events in case to ensure emulated bubble
9461 // listeners still fire for all the media events.
9462 for (var i = 0; i < mediaEventTypes.length; i++) {
9463 listenToNonDelegatedEvent(mediaEventTypes[i], domElement);
9464 }
9465
9466 break;
9467
9468 case 'source':
9469 // We listen to this event in case to ensure emulated bubble
9470 // listeners still fire for the error event.
9471 listenToNonDelegatedEvent('error', domElement);
9472 break;
9473
9474 case 'img':
9475 case 'image':
9476 case 'link':
9477 // We listen to these events in case to ensure emulated bubble
9478 // listeners still fire for error and load events.
9479 listenToNonDelegatedEvent('error', domElement);
9480 listenToNonDelegatedEvent('load', domElement);
9481 break;
9482
9483 case 'details':
9484 // We listen to this event in case to ensure emulated bubble
9485 // listeners still fire for the toggle event.
9486 listenToNonDelegatedEvent('toggle', domElement);
9487 break;
9488
9489 case 'input':
9490 initWrapperState(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9491 // listeners still fire for the invalid event.
9492
9493 listenToNonDelegatedEvent('invalid', domElement);
9494
9495 break;
9496
9497 case 'option':
9498 validateProps(domElement, rawProps);
9499 break;
9500
9501 case 'select':
9502 initWrapperState$1(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9503 // listeners still fire for the invalid event.
9504
9505 listenToNonDelegatedEvent('invalid', domElement);
9506
9507 break;
9508
9509 case 'textarea':
9510 initWrapperState$2(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9511 // listeners still fire for the invalid event.
9512
9513 listenToNonDelegatedEvent('invalid', domElement);
9514
9515 break;
9516 }
9517
9518 assertValidProps(tag, rawProps);
9519
9520 {
9521 extraAttributeNames = new Set();
9522 var attributes = domElement.attributes;
9523
9524 for (var _i = 0; _i < attributes.length; _i++) {
9525 var name = attributes[_i].name.toLowerCase();
9526
9527 switch (name) {
9528 // Built-in SSR attribute is allowed
9529 case 'data-reactroot':
9530 break;
9531 // Controlled attributes are not validated
9532 // TODO: Only ignore them on controlled tags.
9533
9534 case 'value':
9535 break;
9536
9537 case 'checked':
9538 break;
9539
9540 case 'selected':
9541 break;
9542
9543 default:
9544 // Intentionally use the original name.
9545 // See discussion in https://github.com/facebook/react/pull/10676.
9546 extraAttributeNames.add(attributes[_i].name);
9547 }
9548 }
9549 }
9550
9551 var updatePayload = null;
9552
9553 for (var propKey in rawProps) {
9554 if (!rawProps.hasOwnProperty(propKey)) {
9555 continue;
9556 }
9557
9558 var nextProp = rawProps[propKey];
9559
9560 if (propKey === CHILDREN) {
9561 // For text content children we compare against textContent. This
9562 // might match additional HTML that is hidden when we read it using
9563 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
9564 // satisfies our requirement. Our requirement is not to produce perfect
9565 // HTML and attributes. Ideally we should preserve structure but it's
9566 // ok not to if the visible content is still enough to indicate what
9567 // even listeners these nodes might be wired up to.
9568 // TODO: Warn if there is more than a single textNode as a child.
9569 // TODO: Should we use domElement.firstChild.nodeValue to compare?
9570 if (typeof nextProp === 'string') {
9571 if (domElement.textContent !== nextProp) {
9572 if ( !suppressHydrationWarning) {
9573 warnForTextDifference(domElement.textContent, nextProp);
9574 }
9575
9576 updatePayload = [CHILDREN, nextProp];
9577 }
9578 } else if (typeof nextProp === 'number') {
9579 if (domElement.textContent !== '' + nextProp) {
9580 if ( !suppressHydrationWarning) {
9581 warnForTextDifference(domElement.textContent, nextProp);
9582 }
9583
9584 updatePayload = [CHILDREN, '' + nextProp];
9585 }
9586 }
9587 } else if (registrationNameDependencies.hasOwnProperty(propKey)) {
9588 if (nextProp != null) {
9589 if ( typeof nextProp !== 'function') {
9590 warnForInvalidEventListener(propKey, nextProp);
9591 }
9592
9593 if (propKey === 'onScroll') {
9594 listenToNonDelegatedEvent('scroll', domElement);
9595 }
9596 }
9597 } else if ( // Convince Flow we've calculated it (it's DEV-only in this method.)
9598 typeof isCustomComponentTag === 'boolean') {
9599 // Validate that the properties correspond to their expected values.
9600 var serverValue = void 0;
9601 var propertyInfo = getPropertyInfo(propKey);
9602
9603 if (suppressHydrationWarning) ; else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING || // Controlled attributes are not validated
9604 // TODO: Only ignore them on controlled tags.
9605 propKey === 'value' || propKey === 'checked' || propKey === 'selected') ; else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
9606 var serverHTML = domElement.innerHTML;
9607 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
9608
9609 if (nextHtml != null) {
9610 var expectedHTML = normalizeHTML(domElement, nextHtml);
9611
9612 if (expectedHTML !== serverHTML) {
9613 warnForPropDifference(propKey, serverHTML, expectedHTML);
9614 }
9615 }
9616 } else if (propKey === STYLE) {
9617 // $FlowFixMe - Should be inferred as not undefined.
9618 extraAttributeNames.delete(propKey);
9619
9620 if (canDiffStyleForHydrationWarning) {
9621 var expectedStyle = createDangerousStringForStyles(nextProp);
9622 serverValue = domElement.getAttribute('style');
9623
9624 if (expectedStyle !== serverValue) {
9625 warnForPropDifference(propKey, serverValue, expectedStyle);
9626 }
9627 }
9628 } else if (isCustomComponentTag) {
9629 // $FlowFixMe - Should be inferred as not undefined.
9630 extraAttributeNames.delete(propKey.toLowerCase());
9631 serverValue = getValueForAttribute(domElement, propKey, nextProp);
9632
9633 if (nextProp !== serverValue) {
9634 warnForPropDifference(propKey, serverValue, nextProp);
9635 }
9636 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
9637 var isMismatchDueToBadCasing = false;
9638
9639 if (propertyInfo !== null) {
9640 // $FlowFixMe - Should be inferred as not undefined.
9641 extraAttributeNames.delete(propertyInfo.attributeName);
9642 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
9643 } else {
9644 var ownNamespace = parentNamespace;
9645
9646 if (ownNamespace === HTML_NAMESPACE$1) {
9647 ownNamespace = getIntrinsicNamespace(tag);
9648 }
9649
9650 if (ownNamespace === HTML_NAMESPACE$1) {
9651 // $FlowFixMe - Should be inferred as not undefined.
9652 extraAttributeNames.delete(propKey.toLowerCase());
9653 } else {
9654 var standardName = getPossibleStandardName(propKey);
9655
9656 if (standardName !== null && standardName !== propKey) {
9657 // If an SVG prop is supplied with bad casing, it will
9658 // be successfully parsed from HTML, but will produce a mismatch
9659 // (and would be incorrectly rendered on the client).
9660 // However, we already warn about bad casing elsewhere.
9661 // So we'll skip the misleading extra mismatch warning in this case.
9662 isMismatchDueToBadCasing = true; // $FlowFixMe - Should be inferred as not undefined.
9663
9664 extraAttributeNames.delete(standardName);
9665 } // $FlowFixMe - Should be inferred as not undefined.
9666
9667
9668 extraAttributeNames.delete(propKey);
9669 }
9670
9671 serverValue = getValueForAttribute(domElement, propKey, nextProp);
9672 }
9673
9674 if (nextProp !== serverValue && !isMismatchDueToBadCasing) {
9675 warnForPropDifference(propKey, serverValue, nextProp);
9676 }
9677 }
9678 }
9679 }
9680
9681 {
9682 // $FlowFixMe - Should be inferred as not undefined.
9683 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
9684 // $FlowFixMe - Should be inferred as not undefined.
9685 warnForExtraAttributes(extraAttributeNames);
9686 }
9687 }
9688
9689 switch (tag) {
9690 case 'input':
9691 // TODO: Make sure we check if this is still unmounted or do any clean
9692 // up necessary since we never stop tracking anymore.
9693 track(domElement);
9694 postMountWrapper(domElement, rawProps, true);
9695 break;
9696
9697 case 'textarea':
9698 // TODO: Make sure we check if this is still unmounted or do any clean
9699 // up necessary since we never stop tracking anymore.
9700 track(domElement);
9701 postMountWrapper$3(domElement);
9702 break;
9703
9704 case 'select':
9705 case 'option':
9706 // For input and textarea we current always set the value property at
9707 // post mount to force it to diverge from attributes. However, for
9708 // option and select we don't quite do the same thing and select
9709 // is not resilient to the DOM state changing so we don't do that here.
9710 // TODO: Consider not doing this for input and textarea.
9711 break;
9712
9713 default:
9714 if (typeof rawProps.onClick === 'function') {
9715 // TODO: This cast may not be sound for SVG, MathML or custom elements.
9716 trapClickOnNonInteractiveElement(domElement);
9717 }
9718
9719 break;
9720 }
9721
9722 return updatePayload;
9723 }
9724 function diffHydratedText(textNode, text) {
9725 var isDifferent = textNode.nodeValue !== text;
9726 return isDifferent;
9727 }
9728 function warnForUnmatchedText(textNode, text) {
9729 {
9730 warnForTextDifference(textNode.nodeValue, text);
9731 }
9732 }
9733 function warnForDeletedHydratableElement(parentNode, child) {
9734 {
9735 if (didWarnInvalidHydration) {
9736 return;
9737 }
9738
9739 didWarnInvalidHydration = true;
9740
9741 error('Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
9742 }
9743 }
9744 function warnForDeletedHydratableText(parentNode, child) {
9745 {
9746 if (didWarnInvalidHydration) {
9747 return;
9748 }
9749
9750 didWarnInvalidHydration = true;
9751
9752 error('Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
9753 }
9754 }
9755 function warnForInsertedHydratedElement(parentNode, tag, props) {
9756 {
9757 if (didWarnInvalidHydration) {
9758 return;
9759 }
9760
9761 didWarnInvalidHydration = true;
9762
9763 error('Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
9764 }
9765 }
9766 function warnForInsertedHydratedText(parentNode, text) {
9767 {
9768 if (text === '') {
9769 // We expect to insert empty text nodes since they're not represented in
9770 // the HTML.
9771 // TODO: Remove this special case if we can just avoid inserting empty
9772 // text nodes.
9773 return;
9774 }
9775
9776 if (didWarnInvalidHydration) {
9777 return;
9778 }
9779
9780 didWarnInvalidHydration = true;
9781
9782 error('Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
9783 }
9784 }
9785 function restoreControlledState$3(domElement, tag, props) {
9786 switch (tag) {
9787 case 'input':
9788 restoreControlledState(domElement, props);
9789 return;
9790
9791 case 'textarea':
9792 restoreControlledState$2(domElement, props);
9793 return;
9794
9795 case 'select':
9796 restoreControlledState$1(domElement, props);
9797 return;
9798 }
9799 }
9800
9801 var validateDOMNesting = function () {};
9802
9803 var updatedAncestorInfo = function () {};
9804
9805 {
9806 // This validation code was written based on the HTML5 parsing spec:
9807 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
9808 //
9809 // Note: this does not catch all invalid nesting, nor does it try to (as it's
9810 // not clear what practical benefit doing so provides); instead, we warn only
9811 // for cases where the parser will give a parse tree differing from what React
9812 // intended. For example, <b><div></div></b> is invalid but we don't warn
9813 // because it still parses correctly; we do warn for other cases like nested
9814 // <p> tags where the beginning of the second element implicitly closes the
9815 // first, causing a confusing mess.
9816 // https://html.spec.whatwg.org/multipage/syntax.html#special
9817 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
9818
9819 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template', // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
9820 // TODO: Distinguish by namespace here -- for <title>, including it here
9821 // errs on the side of fewer warnings
9822 'foreignObject', 'desc', 'title']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
9823
9824 var buttonScopeTags = inScopeTags.concat(['button']); // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
9825
9826 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
9827 var emptyAncestorInfo = {
9828 current: null,
9829 formTag: null,
9830 aTagInScope: null,
9831 buttonTagInScope: null,
9832 nobrTagInScope: null,
9833 pTagInButtonScope: null,
9834 listItemTagAutoclosing: null,
9835 dlItemTagAutoclosing: null
9836 };
9837
9838 updatedAncestorInfo = function (oldInfo, tag) {
9839 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
9840
9841 var info = {
9842 tag: tag
9843 };
9844
9845 if (inScopeTags.indexOf(tag) !== -1) {
9846 ancestorInfo.aTagInScope = null;
9847 ancestorInfo.buttonTagInScope = null;
9848 ancestorInfo.nobrTagInScope = null;
9849 }
9850
9851 if (buttonScopeTags.indexOf(tag) !== -1) {
9852 ancestorInfo.pTagInButtonScope = null;
9853 } // See rules for 'li', 'dd', 'dt' start tags in
9854 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
9855
9856
9857 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
9858 ancestorInfo.listItemTagAutoclosing = null;
9859 ancestorInfo.dlItemTagAutoclosing = null;
9860 }
9861
9862 ancestorInfo.current = info;
9863
9864 if (tag === 'form') {
9865 ancestorInfo.formTag = info;
9866 }
9867
9868 if (tag === 'a') {
9869 ancestorInfo.aTagInScope = info;
9870 }
9871
9872 if (tag === 'button') {
9873 ancestorInfo.buttonTagInScope = info;
9874 }
9875
9876 if (tag === 'nobr') {
9877 ancestorInfo.nobrTagInScope = info;
9878 }
9879
9880 if (tag === 'p') {
9881 ancestorInfo.pTagInButtonScope = info;
9882 }
9883
9884 if (tag === 'li') {
9885 ancestorInfo.listItemTagAutoclosing = info;
9886 }
9887
9888 if (tag === 'dd' || tag === 'dt') {
9889 ancestorInfo.dlItemTagAutoclosing = info;
9890 }
9891
9892 return ancestorInfo;
9893 };
9894 /**
9895 * Returns whether
9896 */
9897
9898
9899 var isTagValidWithParent = function (tag, parentTag) {
9900 // First, let's check if we're in an unusual parsing mode...
9901 switch (parentTag) {
9902 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
9903 case 'select':
9904 return tag === 'option' || tag === 'optgroup' || tag === '#text';
9905
9906 case 'optgroup':
9907 return tag === 'option' || tag === '#text';
9908 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
9909 // but
9910
9911 case 'option':
9912 return tag === '#text';
9913 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
9914 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
9915 // No special behavior since these rules fall back to "in body" mode for
9916 // all except special table nodes which cause bad parsing behavior anyway.
9917 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
9918
9919 case 'tr':
9920 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
9921 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
9922
9923 case 'tbody':
9924 case 'thead':
9925 case 'tfoot':
9926 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
9927 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
9928
9929 case 'colgroup':
9930 return tag === 'col' || tag === 'template';
9931 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
9932
9933 case 'table':
9934 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
9935 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
9936
9937 case 'head':
9938 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
9939 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
9940
9941 case 'html':
9942 return tag === 'head' || tag === 'body' || tag === 'frameset';
9943
9944 case 'frameset':
9945 return tag === 'frame';
9946
9947 case '#document':
9948 return tag === 'html';
9949 } // Probably in the "in body" parsing mode, so we outlaw only tag combos
9950 // where the parsing rules cause implicit opens or closes to be added.
9951 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
9952
9953
9954 switch (tag) {
9955 case 'h1':
9956 case 'h2':
9957 case 'h3':
9958 case 'h4':
9959 case 'h5':
9960 case 'h6':
9961 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
9962
9963 case 'rp':
9964 case 'rt':
9965 return impliedEndTags.indexOf(parentTag) === -1;
9966
9967 case 'body':
9968 case 'caption':
9969 case 'col':
9970 case 'colgroup':
9971 case 'frameset':
9972 case 'frame':
9973 case 'head':
9974 case 'html':
9975 case 'tbody':
9976 case 'td':
9977 case 'tfoot':
9978 case 'th':
9979 case 'thead':
9980 case 'tr':
9981 // These tags are only valid with a few parents that have special child
9982 // parsing rules -- if we're down here, then none of those matched and
9983 // so we allow it only if we don't know what the parent is, as all other
9984 // cases are invalid.
9985 return parentTag == null;
9986 }
9987
9988 return true;
9989 };
9990 /**
9991 * Returns whether
9992 */
9993
9994
9995 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
9996 switch (tag) {
9997 case 'address':
9998 case 'article':
9999 case 'aside':
10000 case 'blockquote':
10001 case 'center':
10002 case 'details':
10003 case 'dialog':
10004 case 'dir':
10005 case 'div':
10006 case 'dl':
10007 case 'fieldset':
10008 case 'figcaption':
10009 case 'figure':
10010 case 'footer':
10011 case 'header':
10012 case 'hgroup':
10013 case 'main':
10014 case 'menu':
10015 case 'nav':
10016 case 'ol':
10017 case 'p':
10018 case 'section':
10019 case 'summary':
10020 case 'ul':
10021 case 'pre':
10022 case 'listing':
10023 case 'table':
10024 case 'hr':
10025 case 'xmp':
10026 case 'h1':
10027 case 'h2':
10028 case 'h3':
10029 case 'h4':
10030 case 'h5':
10031 case 'h6':
10032 return ancestorInfo.pTagInButtonScope;
10033
10034 case 'form':
10035 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
10036
10037 case 'li':
10038 return ancestorInfo.listItemTagAutoclosing;
10039
10040 case 'dd':
10041 case 'dt':
10042 return ancestorInfo.dlItemTagAutoclosing;
10043
10044 case 'button':
10045 return ancestorInfo.buttonTagInScope;
10046
10047 case 'a':
10048 // Spec says something about storing a list of markers, but it sounds
10049 // equivalent to this check.
10050 return ancestorInfo.aTagInScope;
10051
10052 case 'nobr':
10053 return ancestorInfo.nobrTagInScope;
10054 }
10055
10056 return null;
10057 };
10058
10059 var didWarn$1 = {};
10060
10061 validateDOMNesting = function (childTag, childText, ancestorInfo) {
10062 ancestorInfo = ancestorInfo || emptyAncestorInfo;
10063 var parentInfo = ancestorInfo.current;
10064 var parentTag = parentInfo && parentInfo.tag;
10065
10066 if (childText != null) {
10067 if (childTag != null) {
10068 error('validateDOMNesting: when childText is passed, childTag should be null');
10069 }
10070
10071 childTag = '#text';
10072 }
10073
10074 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
10075 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
10076 var invalidParentOrAncestor = invalidParent || invalidAncestor;
10077
10078 if (!invalidParentOrAncestor) {
10079 return;
10080 }
10081
10082 var ancestorTag = invalidParentOrAncestor.tag;
10083 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag;
10084
10085 if (didWarn$1[warnKey]) {
10086 return;
10087 }
10088
10089 didWarn$1[warnKey] = true;
10090 var tagDisplayName = childTag;
10091 var whitespaceInfo = '';
10092
10093 if (childTag === '#text') {
10094 if (/\S/.test(childText)) {
10095 tagDisplayName = 'Text nodes';
10096 } else {
10097 tagDisplayName = 'Whitespace text nodes';
10098 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
10099 }
10100 } else {
10101 tagDisplayName = '<' + childTag + '>';
10102 }
10103
10104 if (invalidParent) {
10105 var info = '';
10106
10107 if (ancestorTag === 'table' && childTag === 'tr') {
10108 info += ' Add a <tbody>, <thead> or <tfoot> to your code to match the DOM tree generated by ' + 'the browser.';
10109 }
10110
10111 error('validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info);
10112 } else {
10113 error('validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.', tagDisplayName, ancestorTag);
10114 }
10115 };
10116 }
10117
10118 var SUPPRESS_HYDRATION_WARNING$1;
10119
10120 {
10121 SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
10122 }
10123
10124 var SUSPENSE_START_DATA = '$';
10125 var SUSPENSE_END_DATA = '/$';
10126 var SUSPENSE_PENDING_START_DATA = '$?';
10127 var SUSPENSE_FALLBACK_START_DATA = '$!';
10128 var STYLE$1 = 'style';
10129 var eventsEnabled = null;
10130 var selectionInformation = null;
10131
10132 function shouldAutoFocusHostComponent(type, props) {
10133 switch (type) {
10134 case 'button':
10135 case 'input':
10136 case 'select':
10137 case 'textarea':
10138 return !!props.autoFocus;
10139 }
10140
10141 return false;
10142 }
10143 function getRootHostContext(rootContainerInstance) {
10144 var type;
10145 var namespace;
10146 var nodeType = rootContainerInstance.nodeType;
10147
10148 switch (nodeType) {
10149 case DOCUMENT_NODE:
10150 case DOCUMENT_FRAGMENT_NODE:
10151 {
10152 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
10153 var root = rootContainerInstance.documentElement;
10154 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
10155 break;
10156 }
10157
10158 default:
10159 {
10160 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
10161 var ownNamespace = container.namespaceURI || null;
10162 type = container.tagName;
10163 namespace = getChildNamespace(ownNamespace, type);
10164 break;
10165 }
10166 }
10167
10168 {
10169 var validatedTag = type.toLowerCase();
10170 var ancestorInfo = updatedAncestorInfo(null, validatedTag);
10171 return {
10172 namespace: namespace,
10173 ancestorInfo: ancestorInfo
10174 };
10175 }
10176 }
10177 function getChildHostContext(parentHostContext, type, rootContainerInstance) {
10178 {
10179 var parentHostContextDev = parentHostContext;
10180 var namespace = getChildNamespace(parentHostContextDev.namespace, type);
10181 var ancestorInfo = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type);
10182 return {
10183 namespace: namespace,
10184 ancestorInfo: ancestorInfo
10185 };
10186 }
10187 }
10188 function getPublicInstance(instance) {
10189 return instance;
10190 }
10191 function prepareForCommit(containerInfo) {
10192 eventsEnabled = isEnabled();
10193 selectionInformation = getSelectionInformation();
10194 var activeInstance = null;
10195
10196 setEnabled(false);
10197 return activeInstance;
10198 }
10199 function resetAfterCommit(containerInfo) {
10200 restoreSelection(selectionInformation);
10201 setEnabled(eventsEnabled);
10202 eventsEnabled = null;
10203 selectionInformation = null;
10204 }
10205 function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
10206 var parentNamespace;
10207
10208 {
10209 // TODO: take namespace into account when validating.
10210 var hostContextDev = hostContext;
10211 validateDOMNesting(type, null, hostContextDev.ancestorInfo);
10212
10213 if (typeof props.children === 'string' || typeof props.children === 'number') {
10214 var string = '' + props.children;
10215 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
10216 validateDOMNesting(null, string, ownAncestorInfo);
10217 }
10218
10219 parentNamespace = hostContextDev.namespace;
10220 }
10221
10222 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
10223 precacheFiberNode(internalInstanceHandle, domElement);
10224 updateFiberProps(domElement, props);
10225 return domElement;
10226 }
10227 function appendInitialChild(parentInstance, child) {
10228 parentInstance.appendChild(child);
10229 }
10230 function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) {
10231 setInitialProperties(domElement, type, props, rootContainerInstance);
10232 return shouldAutoFocusHostComponent(type, props);
10233 }
10234 function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
10235 {
10236 var hostContextDev = hostContext;
10237
10238 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
10239 var string = '' + newProps.children;
10240 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
10241 validateDOMNesting(null, string, ownAncestorInfo);
10242 }
10243 }
10244
10245 return diffProperties(domElement, type, oldProps, newProps);
10246 }
10247 function shouldSetTextContent(type, props) {
10248 return type === 'textarea' || type === 'option' || type === 'noscript' || typeof props.children === 'string' || typeof props.children === 'number' || typeof props.dangerouslySetInnerHTML === 'object' && props.dangerouslySetInnerHTML !== null && props.dangerouslySetInnerHTML.__html != null;
10249 }
10250 function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
10251 {
10252 var hostContextDev = hostContext;
10253 validateDOMNesting(null, text, hostContextDev.ancestorInfo);
10254 }
10255
10256 var textNode = createTextNode(text, rootContainerInstance);
10257 precacheFiberNode(internalInstanceHandle, textNode);
10258 return textNode;
10259 }
10260 // if a component just imports ReactDOM (e.g. for findDOMNode).
10261 // Some environments might not have setTimeout or clearTimeout.
10262
10263 var scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined;
10264 var cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined;
10265 var noTimeout = -1; // -------------------
10266 function commitMount(domElement, type, newProps, internalInstanceHandle) {
10267 // Despite the naming that might imply otherwise, this method only
10268 // fires if there is an `Update` effect scheduled during mounting.
10269 // This happens if `finalizeInitialChildren` returns `true` (which it
10270 // does to implement the `autoFocus` attribute on the client). But
10271 // there are also other cases when this might happen (such as patching
10272 // up text content during hydration mismatch). So we'll check this again.
10273 if (shouldAutoFocusHostComponent(type, newProps)) {
10274 domElement.focus();
10275 }
10276 }
10277 function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
10278 // Update the props handle so that we know which props are the ones with
10279 // with current event handlers.
10280 updateFiberProps(domElement, newProps); // Apply the diff to the DOM node.
10281
10282 updateProperties(domElement, updatePayload, type, oldProps, newProps);
10283 }
10284 function resetTextContent(domElement) {
10285 setTextContent(domElement, '');
10286 }
10287 function commitTextUpdate(textInstance, oldText, newText) {
10288 textInstance.nodeValue = newText;
10289 }
10290 function appendChild(parentInstance, child) {
10291 parentInstance.appendChild(child);
10292 }
10293 function appendChildToContainer(container, child) {
10294 var parentNode;
10295
10296 if (container.nodeType === COMMENT_NODE) {
10297 parentNode = container.parentNode;
10298 parentNode.insertBefore(child, container);
10299 } else {
10300 parentNode = container;
10301 parentNode.appendChild(child);
10302 } // This container might be used for a portal.
10303 // If something inside a portal is clicked, that click should bubble
10304 // through the React tree. However, on Mobile Safari the click would
10305 // never bubble through the *DOM* tree unless an ancestor with onclick
10306 // event exists. So we wouldn't see it and dispatch it.
10307 // This is why we ensure that non React root containers have inline onclick
10308 // defined.
10309 // https://github.com/facebook/react/issues/11918
10310
10311
10312 var reactRootContainer = container._reactRootContainer;
10313
10314 if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) {
10315 // TODO: This cast may not be sound for SVG, MathML or custom elements.
10316 trapClickOnNonInteractiveElement(parentNode);
10317 }
10318 }
10319 function insertBefore(parentInstance, child, beforeChild) {
10320 parentInstance.insertBefore(child, beforeChild);
10321 }
10322 function insertInContainerBefore(container, child, beforeChild) {
10323 if (container.nodeType === COMMENT_NODE) {
10324 container.parentNode.insertBefore(child, beforeChild);
10325 } else {
10326 container.insertBefore(child, beforeChild);
10327 }
10328 }
10329
10330 function removeChild(parentInstance, child) {
10331 parentInstance.removeChild(child);
10332 }
10333 function removeChildFromContainer(container, child) {
10334 if (container.nodeType === COMMENT_NODE) {
10335 container.parentNode.removeChild(child);
10336 } else {
10337 container.removeChild(child);
10338 }
10339 }
10340 function hideInstance(instance) {
10341 // TODO: Does this work for all element types? What about MathML? Should we
10342 // pass host context to this method?
10343 instance = instance;
10344 var style = instance.style;
10345
10346 if (typeof style.setProperty === 'function') {
10347 style.setProperty('display', 'none', 'important');
10348 } else {
10349 style.display = 'none';
10350 }
10351 }
10352 function hideTextInstance(textInstance) {
10353 textInstance.nodeValue = '';
10354 }
10355 function unhideInstance(instance, props) {
10356 instance = instance;
10357 var styleProp = props[STYLE$1];
10358 var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null;
10359 instance.style.display = dangerousStyleValue('display', display);
10360 }
10361 function unhideTextInstance(textInstance, text) {
10362 textInstance.nodeValue = text;
10363 }
10364 function clearContainer(container) {
10365 if (container.nodeType === ELEMENT_NODE) {
10366 container.textContent = '';
10367 } else if (container.nodeType === DOCUMENT_NODE) {
10368 var body = container.body;
10369
10370 if (body != null) {
10371 body.textContent = '';
10372 }
10373 }
10374 } // -------------------
10375 function canHydrateInstance(instance, type, props) {
10376 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
10377 return null;
10378 } // This has now been refined to an element node.
10379
10380
10381 return instance;
10382 }
10383 function canHydrateTextInstance(instance, text) {
10384 if (text === '' || instance.nodeType !== TEXT_NODE) {
10385 // Empty strings are not parsed by HTML so there won't be a correct match here.
10386 return null;
10387 } // This has now been refined to a text node.
10388
10389
10390 return instance;
10391 }
10392 function isSuspenseInstancePending(instance) {
10393 return instance.data === SUSPENSE_PENDING_START_DATA;
10394 }
10395 function isSuspenseInstanceFallback(instance) {
10396 return instance.data === SUSPENSE_FALLBACK_START_DATA;
10397 }
10398
10399 function getNextHydratable(node) {
10400 // Skip non-hydratable nodes.
10401 for (; node != null; node = node.nextSibling) {
10402 var nodeType = node.nodeType;
10403
10404 if (nodeType === ELEMENT_NODE || nodeType === TEXT_NODE) {
10405 break;
10406 }
10407 }
10408
10409 return node;
10410 }
10411
10412 function getNextHydratableSibling(instance) {
10413 return getNextHydratable(instance.nextSibling);
10414 }
10415 function getFirstHydratableChild(parentInstance) {
10416 return getNextHydratable(parentInstance.firstChild);
10417 }
10418 function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
10419 precacheFiberNode(internalInstanceHandle, instance); // TODO: Possibly defer this until the commit phase where all the events
10420 // get attached.
10421
10422 updateFiberProps(instance, props);
10423 var parentNamespace;
10424
10425 {
10426 var hostContextDev = hostContext;
10427 parentNamespace = hostContextDev.namespace;
10428 }
10429
10430 return diffHydratedProperties(instance, type, props, parentNamespace);
10431 }
10432 function hydrateTextInstance(textInstance, text, internalInstanceHandle) {
10433 precacheFiberNode(internalInstanceHandle, textInstance);
10434 return diffHydratedText(textInstance, text);
10435 }
10436 function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {
10437 var node = suspenseInstance.nextSibling; // Skip past all nodes within this suspense boundary.
10438 // There might be nested nodes so we need to keep track of how
10439 // deep we are and only break out when we're back on top.
10440
10441 var depth = 0;
10442
10443 while (node) {
10444 if (node.nodeType === COMMENT_NODE) {
10445 var data = node.data;
10446
10447 if (data === SUSPENSE_END_DATA) {
10448 if (depth === 0) {
10449 return getNextHydratableSibling(node);
10450 } else {
10451 depth--;
10452 }
10453 } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
10454 depth++;
10455 }
10456 }
10457
10458 node = node.nextSibling;
10459 } // TODO: Warn, we didn't find the end comment boundary.
10460
10461
10462 return null;
10463 } // Returns the SuspenseInstance if this node is a direct child of a
10464 // SuspenseInstance. I.e. if its previous sibling is a Comment with
10465 // SUSPENSE_x_START_DATA. Otherwise, null.
10466
10467 function getParentSuspenseInstance(targetInstance) {
10468 var node = targetInstance.previousSibling; // Skip past all nodes within this suspense boundary.
10469 // There might be nested nodes so we need to keep track of how
10470 // deep we are and only break out when we're back on top.
10471
10472 var depth = 0;
10473
10474 while (node) {
10475 if (node.nodeType === COMMENT_NODE) {
10476 var data = node.data;
10477
10478 if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
10479 if (depth === 0) {
10480 return node;
10481 } else {
10482 depth--;
10483 }
10484 } else if (data === SUSPENSE_END_DATA) {
10485 depth++;
10486 }
10487 }
10488
10489 node = node.previousSibling;
10490 }
10491
10492 return null;
10493 }
10494 function commitHydratedContainer(container) {
10495 // Retry if any event replaying was blocked on this.
10496 retryIfBlockedOn(container);
10497 }
10498 function commitHydratedSuspenseInstance(suspenseInstance) {
10499 // Retry if any event replaying was blocked on this.
10500 retryIfBlockedOn(suspenseInstance);
10501 }
10502 function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) {
10503 {
10504 warnForUnmatchedText(textInstance, text);
10505 }
10506 }
10507 function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text) {
10508 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
10509 warnForUnmatchedText(textInstance, text);
10510 }
10511 }
10512 function didNotHydrateContainerInstance(parentContainer, instance) {
10513 {
10514 if (instance.nodeType === ELEMENT_NODE) {
10515 warnForDeletedHydratableElement(parentContainer, instance);
10516 } else if (instance.nodeType === COMMENT_NODE) ; else {
10517 warnForDeletedHydratableText(parentContainer, instance);
10518 }
10519 }
10520 }
10521 function didNotHydrateInstance(parentType, parentProps, parentInstance, instance) {
10522 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
10523 if (instance.nodeType === ELEMENT_NODE) {
10524 warnForDeletedHydratableElement(parentInstance, instance);
10525 } else if (instance.nodeType === COMMENT_NODE) ; else {
10526 warnForDeletedHydratableText(parentInstance, instance);
10527 }
10528 }
10529 }
10530 function didNotFindHydratableContainerInstance(parentContainer, type, props) {
10531 {
10532 warnForInsertedHydratedElement(parentContainer, type);
10533 }
10534 }
10535 function didNotFindHydratableContainerTextInstance(parentContainer, text) {
10536 {
10537 warnForInsertedHydratedText(parentContainer, text);
10538 }
10539 }
10540 function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) {
10541 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
10542 warnForInsertedHydratedElement(parentInstance, type);
10543 }
10544 }
10545 function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text) {
10546 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
10547 warnForInsertedHydratedText(parentInstance, text);
10548 }
10549 }
10550 function didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance) {
10551 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) ;
10552 }
10553 var clientId = 0;
10554 function makeClientIdInDEV(warnOnAccessInDEV) {
10555 var id = 'r:' + (clientId++).toString(36);
10556 return {
10557 toString: function () {
10558 warnOnAccessInDEV();
10559 return id;
10560 },
10561 valueOf: function () {
10562 warnOnAccessInDEV();
10563 return id;
10564 }
10565 };
10566 }
10567 function isOpaqueHydratingObject(value) {
10568 return value !== null && typeof value === 'object' && value.$$typeof === REACT_OPAQUE_ID_TYPE;
10569 }
10570 function makeOpaqueHydratingObject(attemptToReadValue) {
10571 return {
10572 $$typeof: REACT_OPAQUE_ID_TYPE,
10573 toString: attemptToReadValue,
10574 valueOf: attemptToReadValue
10575 };
10576 }
10577 function preparePortalMount(portalInstance) {
10578 {
10579 listenToAllSupportedEvents(portalInstance);
10580 }
10581 }
10582
10583 var randomKey = Math.random().toString(36).slice(2);
10584 var internalInstanceKey = '__reactFiber$' + randomKey;
10585 var internalPropsKey = '__reactProps$' + randomKey;
10586 var internalContainerInstanceKey = '__reactContainer$' + randomKey;
10587 var internalEventHandlersKey = '__reactEvents$' + randomKey;
10588 function precacheFiberNode(hostInst, node) {
10589 node[internalInstanceKey] = hostInst;
10590 }
10591 function markContainerAsRoot(hostRoot, node) {
10592 node[internalContainerInstanceKey] = hostRoot;
10593 }
10594 function unmarkContainerAsRoot(node) {
10595 node[internalContainerInstanceKey] = null;
10596 }
10597 function isContainerMarkedAsRoot(node) {
10598 return !!node[internalContainerInstanceKey];
10599 } // Given a DOM node, return the closest HostComponent or HostText fiber ancestor.
10600 // If the target node is part of a hydrated or not yet rendered subtree, then
10601 // this may also return a SuspenseComponent or HostRoot to indicate that.
10602 // Conceptually the HostRoot fiber is a child of the Container node. So if you
10603 // pass the Container node as the targetNode, you will not actually get the
10604 // HostRoot back. To get to the HostRoot, you need to pass a child of it.
10605 // The same thing applies to Suspense boundaries.
10606
10607 function getClosestInstanceFromNode(targetNode) {
10608 var targetInst = targetNode[internalInstanceKey];
10609
10610 if (targetInst) {
10611 // Don't return HostRoot or SuspenseComponent here.
10612 return targetInst;
10613 } // If the direct event target isn't a React owned DOM node, we need to look
10614 // to see if one of its parents is a React owned DOM node.
10615
10616
10617 var parentNode = targetNode.parentNode;
10618
10619 while (parentNode) {
10620 // We'll check if this is a container root that could include
10621 // React nodes in the future. We need to check this first because
10622 // if we're a child of a dehydrated container, we need to first
10623 // find that inner container before moving on to finding the parent
10624 // instance. Note that we don't check this field on the targetNode
10625 // itself because the fibers are conceptually between the container
10626 // node and the first child. It isn't surrounding the container node.
10627 // If it's not a container, we check if it's an instance.
10628 targetInst = parentNode[internalContainerInstanceKey] || parentNode[internalInstanceKey];
10629
10630 if (targetInst) {
10631 // Since this wasn't the direct target of the event, we might have
10632 // stepped past dehydrated DOM nodes to get here. However they could
10633 // also have been non-React nodes. We need to answer which one.
10634 // If we the instance doesn't have any children, then there can't be
10635 // a nested suspense boundary within it. So we can use this as a fast
10636 // bailout. Most of the time, when people add non-React children to
10637 // the tree, it is using a ref to a child-less DOM node.
10638 // Normally we'd only need to check one of the fibers because if it
10639 // has ever gone from having children to deleting them or vice versa
10640 // it would have deleted the dehydrated boundary nested inside already.
10641 // However, since the HostRoot starts out with an alternate it might
10642 // have one on the alternate so we need to check in case this was a
10643 // root.
10644 var alternate = targetInst.alternate;
10645
10646 if (targetInst.child !== null || alternate !== null && alternate.child !== null) {
10647 // Next we need to figure out if the node that skipped past is
10648 // nested within a dehydrated boundary and if so, which one.
10649 var suspenseInstance = getParentSuspenseInstance(targetNode);
10650
10651 while (suspenseInstance !== null) {
10652 // We found a suspense instance. That means that we haven't
10653 // hydrated it yet. Even though we leave the comments in the
10654 // DOM after hydrating, and there are boundaries in the DOM
10655 // that could already be hydrated, we wouldn't have found them
10656 // through this pass since if the target is hydrated it would
10657 // have had an internalInstanceKey on it.
10658 // Let's get the fiber associated with the SuspenseComponent
10659 // as the deepest instance.
10660 var targetSuspenseInst = suspenseInstance[internalInstanceKey];
10661
10662 if (targetSuspenseInst) {
10663 return targetSuspenseInst;
10664 } // If we don't find a Fiber on the comment, it might be because
10665 // we haven't gotten to hydrate it yet. There might still be a
10666 // parent boundary that hasn't above this one so we need to find
10667 // the outer most that is known.
10668
10669
10670 suspenseInstance = getParentSuspenseInstance(suspenseInstance); // If we don't find one, then that should mean that the parent
10671 // host component also hasn't hydrated yet. We can return it
10672 // below since it will bail out on the isMounted check later.
10673 }
10674 }
10675
10676 return targetInst;
10677 }
10678
10679 targetNode = parentNode;
10680 parentNode = targetNode.parentNode;
10681 }
10682
10683 return null;
10684 }
10685 /**
10686 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
10687 * instance, or null if the node was not rendered by this React.
10688 */
10689
10690 function getInstanceFromNode(node) {
10691 var inst = node[internalInstanceKey] || node[internalContainerInstanceKey];
10692
10693 if (inst) {
10694 if (inst.tag === HostComponent || inst.tag === HostText || inst.tag === SuspenseComponent || inst.tag === HostRoot) {
10695 return inst;
10696 } else {
10697 return null;
10698 }
10699 }
10700
10701 return null;
10702 }
10703 /**
10704 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
10705 * DOM node.
10706 */
10707
10708 function getNodeFromInstance(inst) {
10709 if (inst.tag === HostComponent || inst.tag === HostText) {
10710 // In Fiber this, is just the state node right now. We assume it will be
10711 // a host component or host text.
10712 return inst.stateNode;
10713 } // Without this first invariant, passing a non-DOM-component triggers the next
10714 // invariant for a missing parent, which is super confusing.
10715
10716
10717 {
10718 {
10719 throw Error( "getNodeFromInstance: Invalid argument." );
10720 }
10721 }
10722 }
10723 function getFiberCurrentPropsFromNode(node) {
10724 return node[internalPropsKey] || null;
10725 }
10726 function updateFiberProps(node, props) {
10727 node[internalPropsKey] = props;
10728 }
10729 function getEventListenerSet(node) {
10730 var elementListenerSet = node[internalEventHandlersKey];
10731
10732 if (elementListenerSet === undefined) {
10733 elementListenerSet = node[internalEventHandlersKey] = new Set();
10734 }
10735
10736 return elementListenerSet;
10737 }
10738
10739 var loggedTypeFailures = {};
10740 var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
10741
10742 function setCurrentlyValidatingElement(element) {
10743 {
10744 if (element) {
10745 var owner = element._owner;
10746 var stack = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null);
10747 ReactDebugCurrentFrame$1.setExtraStackFrame(stack);
10748 } else {
10749 ReactDebugCurrentFrame$1.setExtraStackFrame(null);
10750 }
10751 }
10752 }
10753
10754 function checkPropTypes(typeSpecs, values, location, componentName, element) {
10755 {
10756 // $FlowFixMe This is okay but Flow doesn't know it.
10757 var has = Function.call.bind(Object.prototype.hasOwnProperty);
10758
10759 for (var typeSpecName in typeSpecs) {
10760 if (has(typeSpecs, typeSpecName)) {
10761 var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to
10762 // fail the render phase where it didn't fail before. So we log it.
10763 // After these have been cleaned up, we'll let them throw.
10764
10765 try {
10766 // This is intentionally an invariant that gets caught. It's the same
10767 // behavior as without this statement except with a better message.
10768 if (typeof typeSpecs[typeSpecName] !== 'function') {
10769 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`.');
10770 err.name = 'Invariant Violation';
10771 throw err;
10772 }
10773
10774 error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');
10775 } catch (ex) {
10776 error$1 = ex;
10777 }
10778
10779 if (error$1 && !(error$1 instanceof Error)) {
10780 setCurrentlyValidatingElement(element);
10781
10782 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);
10783
10784 setCurrentlyValidatingElement(null);
10785 }
10786
10787 if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) {
10788 // Only monitor this failure once because there tends to be a lot of the
10789 // same error.
10790 loggedTypeFailures[error$1.message] = true;
10791 setCurrentlyValidatingElement(element);
10792
10793 error('Failed %s type: %s', location, error$1.message);
10794
10795 setCurrentlyValidatingElement(null);
10796 }
10797 }
10798 }
10799 }
10800 }
10801
10802 var valueStack = [];
10803 var fiberStack;
10804
10805 {
10806 fiberStack = [];
10807 }
10808
10809 var index = -1;
10810
10811 function createCursor(defaultValue) {
10812 return {
10813 current: defaultValue
10814 };
10815 }
10816
10817 function pop(cursor, fiber) {
10818 if (index < 0) {
10819 {
10820 error('Unexpected pop.');
10821 }
10822
10823 return;
10824 }
10825
10826 {
10827 if (fiber !== fiberStack[index]) {
10828 error('Unexpected Fiber popped.');
10829 }
10830 }
10831
10832 cursor.current = valueStack[index];
10833 valueStack[index] = null;
10834
10835 {
10836 fiberStack[index] = null;
10837 }
10838
10839 index--;
10840 }
10841
10842 function push(cursor, value, fiber) {
10843 index++;
10844 valueStack[index] = cursor.current;
10845
10846 {
10847 fiberStack[index] = fiber;
10848 }
10849
10850 cursor.current = value;
10851 }
10852
10853 var warnedAboutMissingGetChildContext;
10854
10855 {
10856 warnedAboutMissingGetChildContext = {};
10857 }
10858
10859 var emptyContextObject = {};
10860
10861 {
10862 Object.freeze(emptyContextObject);
10863 } // A cursor to the current merged context object on the stack.
10864
10865
10866 var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed.
10867
10868 var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack.
10869 // We use this to get access to the parent context after we have already
10870 // pushed the next context provider, and now need to merge their contexts.
10871
10872 var previousContext = emptyContextObject;
10873
10874 function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
10875 {
10876 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
10877 // If the fiber is a context provider itself, when we read its context
10878 // we may have already pushed its own child context on the stack. A context
10879 // provider should not "see" its own child context. Therefore we read the
10880 // previous (parent) context instead for a context provider.
10881 return previousContext;
10882 }
10883
10884 return contextStackCursor.current;
10885 }
10886 }
10887
10888 function cacheContext(workInProgress, unmaskedContext, maskedContext) {
10889 {
10890 var instance = workInProgress.stateNode;
10891 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
10892 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
10893 }
10894 }
10895
10896 function getMaskedContext(workInProgress, unmaskedContext) {
10897 {
10898 var type = workInProgress.type;
10899 var contextTypes = type.contextTypes;
10900
10901 if (!contextTypes) {
10902 return emptyContextObject;
10903 } // Avoid recreating masked context unless unmasked context has changed.
10904 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
10905 // This may trigger infinite loops if componentWillReceiveProps calls setState.
10906
10907
10908 var instance = workInProgress.stateNode;
10909
10910 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
10911 return instance.__reactInternalMemoizedMaskedChildContext;
10912 }
10913
10914 var context = {};
10915
10916 for (var key in contextTypes) {
10917 context[key] = unmaskedContext[key];
10918 }
10919
10920 {
10921 var name = getComponentName(type) || 'Unknown';
10922 checkPropTypes(contextTypes, context, 'context', name);
10923 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
10924 // Context is created before the class component is instantiated so check for instance.
10925
10926
10927 if (instance) {
10928 cacheContext(workInProgress, unmaskedContext, context);
10929 }
10930
10931 return context;
10932 }
10933 }
10934
10935 function hasContextChanged() {
10936 {
10937 return didPerformWorkStackCursor.current;
10938 }
10939 }
10940
10941 function isContextProvider(type) {
10942 {
10943 var childContextTypes = type.childContextTypes;
10944 return childContextTypes !== null && childContextTypes !== undefined;
10945 }
10946 }
10947
10948 function popContext(fiber) {
10949 {
10950 pop(didPerformWorkStackCursor, fiber);
10951 pop(contextStackCursor, fiber);
10952 }
10953 }
10954
10955 function popTopLevelContextObject(fiber) {
10956 {
10957 pop(didPerformWorkStackCursor, fiber);
10958 pop(contextStackCursor, fiber);
10959 }
10960 }
10961
10962 function pushTopLevelContextObject(fiber, context, didChange) {
10963 {
10964 if (!(contextStackCursor.current === emptyContextObject)) {
10965 {
10966 throw Error( "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." );
10967 }
10968 }
10969
10970 push(contextStackCursor, context, fiber);
10971 push(didPerformWorkStackCursor, didChange, fiber);
10972 }
10973 }
10974
10975 function processChildContext(fiber, type, parentContext) {
10976 {
10977 var instance = fiber.stateNode;
10978 var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future.
10979 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
10980
10981 if (typeof instance.getChildContext !== 'function') {
10982 {
10983 var componentName = getComponentName(type) || 'Unknown';
10984
10985 if (!warnedAboutMissingGetChildContext[componentName]) {
10986 warnedAboutMissingGetChildContext[componentName] = true;
10987
10988 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);
10989 }
10990 }
10991
10992 return parentContext;
10993 }
10994
10995 var childContext = instance.getChildContext();
10996
10997 for (var contextKey in childContext) {
10998 if (!(contextKey in childContextTypes)) {
10999 {
11000 throw Error( (getComponentName(type) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes." );
11001 }
11002 }
11003 }
11004
11005 {
11006 var name = getComponentName(type) || 'Unknown';
11007 checkPropTypes(childContextTypes, childContext, 'child context', name);
11008 }
11009
11010 return _assign({}, parentContext, childContext);
11011 }
11012 }
11013
11014 function pushContextProvider(workInProgress) {
11015 {
11016 var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity.
11017 // If the instance does not exist yet, we will push null at first,
11018 // and replace it on the stack later when invalidating the context.
11019
11020 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later.
11021 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
11022
11023 previousContext = contextStackCursor.current;
11024 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
11025 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
11026 return true;
11027 }
11028 }
11029
11030 function invalidateContextProvider(workInProgress, type, didChange) {
11031 {
11032 var instance = workInProgress.stateNode;
11033
11034 if (!instance) {
11035 {
11036 throw Error( "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." );
11037 }
11038 }
11039
11040 if (didChange) {
11041 // Merge parent and own context.
11042 // Skip this if we're not updating due to sCU.
11043 // This avoids unnecessarily recomputing memoized values.
11044 var mergedContext = processChildContext(workInProgress, type, previousContext);
11045 instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one.
11046 // It is important to unwind the context in the reverse order.
11047
11048 pop(didPerformWorkStackCursor, workInProgress);
11049 pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed.
11050
11051 push(contextStackCursor, mergedContext, workInProgress);
11052 push(didPerformWorkStackCursor, didChange, workInProgress);
11053 } else {
11054 pop(didPerformWorkStackCursor, workInProgress);
11055 push(didPerformWorkStackCursor, didChange, workInProgress);
11056 }
11057 }
11058 }
11059
11060 function findCurrentUnmaskedContext(fiber) {
11061 {
11062 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
11063 // makes sense elsewhere
11064 if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) {
11065 {
11066 throw Error( "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." );
11067 }
11068 }
11069
11070 var node = fiber;
11071
11072 do {
11073 switch (node.tag) {
11074 case HostRoot:
11075 return node.stateNode.context;
11076
11077 case ClassComponent:
11078 {
11079 var Component = node.type;
11080
11081 if (isContextProvider(Component)) {
11082 return node.stateNode.__reactInternalMemoizedMergedChildContext;
11083 }
11084
11085 break;
11086 }
11087 }
11088
11089 node = node.return;
11090 } while (node !== null);
11091
11092 {
11093 {
11094 throw Error( "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." );
11095 }
11096 }
11097 }
11098 }
11099
11100 var LegacyRoot = 0;
11101 var BlockingRoot = 1;
11102 var ConcurrentRoot = 2;
11103
11104 var rendererID = null;
11105 var injectedHook = null;
11106 var hasLoggedError = false;
11107 var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
11108 function injectInternals(internals) {
11109 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
11110 // No DevTools
11111 return false;
11112 }
11113
11114 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
11115
11116 if (hook.isDisabled) {
11117 // This isn't a real property on the hook, but it can be set to opt out
11118 // of DevTools integration and associated warnings and logs.
11119 // https://github.com/facebook/react/issues/3877
11120 return true;
11121 }
11122
11123 if (!hook.supportsFiber) {
11124 {
11125 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');
11126 } // DevTools exists, even though it doesn't support Fiber.
11127
11128
11129 return true;
11130 }
11131
11132 try {
11133 rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.
11134
11135 injectedHook = hook;
11136 } catch (err) {
11137 // Catch all errors because it is unsafe to throw during initialization.
11138 {
11139 error('React instrumentation encountered an error: %s.', err);
11140 }
11141 } // DevTools exists
11142
11143
11144 return true;
11145 }
11146 function onScheduleRoot(root, children) {
11147 {
11148 if (injectedHook && typeof injectedHook.onScheduleFiberRoot === 'function') {
11149 try {
11150 injectedHook.onScheduleFiberRoot(rendererID, root, children);
11151 } catch (err) {
11152 if ( !hasLoggedError) {
11153 hasLoggedError = true;
11154
11155 error('React instrumentation encountered an error: %s', err);
11156 }
11157 }
11158 }
11159 }
11160 }
11161 function onCommitRoot(root, priorityLevel) {
11162 if (injectedHook && typeof injectedHook.onCommitFiberRoot === 'function') {
11163 try {
11164 var didError = (root.current.flags & DidCapture) === DidCapture;
11165
11166 if (enableProfilerTimer) {
11167 injectedHook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);
11168 } else {
11169 injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError);
11170 }
11171 } catch (err) {
11172 {
11173 if (!hasLoggedError) {
11174 hasLoggedError = true;
11175
11176 error('React instrumentation encountered an error: %s', err);
11177 }
11178 }
11179 }
11180 }
11181 }
11182 function onCommitUnmount(fiber) {
11183 if (injectedHook && typeof injectedHook.onCommitFiberUnmount === 'function') {
11184 try {
11185 injectedHook.onCommitFiberUnmount(rendererID, fiber);
11186 } catch (err) {
11187 {
11188 if (!hasLoggedError) {
11189 hasLoggedError = true;
11190
11191 error('React instrumentation encountered an error: %s', err);
11192 }
11193 }
11194 }
11195 }
11196 }
11197
11198 var Scheduler_runWithPriority = unstable_runWithPriority,
11199 Scheduler_scheduleCallback = unstable_scheduleCallback,
11200 Scheduler_cancelCallback = unstable_cancelCallback,
11201 Scheduler_shouldYield = unstable_shouldYield,
11202 Scheduler_requestPaint = unstable_requestPaint,
11203 Scheduler_now$1 = unstable_now,
11204 Scheduler_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel,
11205 Scheduler_ImmediatePriority = unstable_ImmediatePriority,
11206 Scheduler_UserBlockingPriority = unstable_UserBlockingPriority,
11207 Scheduler_NormalPriority = unstable_NormalPriority,
11208 Scheduler_LowPriority = unstable_LowPriority,
11209 Scheduler_IdlePriority = unstable_IdlePriority;
11210
11211 {
11212 // Provide explicit error message when production+profiling bundle of e.g.
11213 // react-dom is used with production (non-profiling) bundle of
11214 // scheduler/tracing
11215 if (!(__interactionsRef != null && __interactionsRef.current != null)) {
11216 {
11217 throw Error( "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" );
11218 }
11219 }
11220 }
11221
11222 var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use
11223 // ascending numbers so we can compare them like numbers. They start at 90 to
11224 // avoid clashing with Scheduler's priorities.
11225
11226 var ImmediatePriority$1 = 99;
11227 var UserBlockingPriority$2 = 98;
11228 var NormalPriority$1 = 97;
11229 var LowPriority$1 = 96;
11230 var IdlePriority$1 = 95; // NoPriority is the absence of priority. Also React-only.
11231
11232 var NoPriority$1 = 90;
11233 var shouldYield = Scheduler_shouldYield;
11234 var requestPaint = // Fall back gracefully if we're running an older version of Scheduler.
11235 Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function () {};
11236 var syncQueue = null;
11237 var immediateQueueCallbackNode = null;
11238 var isFlushingSyncQueue = false;
11239 var initialTimeMs$1 = Scheduler_now$1(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly.
11240 // This will be the case for modern browsers that support `performance.now`. In
11241 // older browsers, Scheduler falls back to `Date.now`, which returns a Unix
11242 // timestamp. In that case, subtract the module initialization time to simulate
11243 // the behavior of performance.now and keep our times small enough to fit
11244 // within 32 bits.
11245 // TODO: Consider lifting this into Scheduler.
11246
11247 var now = initialTimeMs$1 < 10000 ? Scheduler_now$1 : function () {
11248 return Scheduler_now$1() - initialTimeMs$1;
11249 };
11250 function getCurrentPriorityLevel() {
11251 switch (Scheduler_getCurrentPriorityLevel()) {
11252 case Scheduler_ImmediatePriority:
11253 return ImmediatePriority$1;
11254
11255 case Scheduler_UserBlockingPriority:
11256 return UserBlockingPriority$2;
11257
11258 case Scheduler_NormalPriority:
11259 return NormalPriority$1;
11260
11261 case Scheduler_LowPriority:
11262 return LowPriority$1;
11263
11264 case Scheduler_IdlePriority:
11265 return IdlePriority$1;
11266
11267 default:
11268 {
11269 {
11270 throw Error( "Unknown priority level." );
11271 }
11272 }
11273
11274 }
11275 }
11276
11277 function reactPriorityToSchedulerPriority(reactPriorityLevel) {
11278 switch (reactPriorityLevel) {
11279 case ImmediatePriority$1:
11280 return Scheduler_ImmediatePriority;
11281
11282 case UserBlockingPriority$2:
11283 return Scheduler_UserBlockingPriority;
11284
11285 case NormalPriority$1:
11286 return Scheduler_NormalPriority;
11287
11288 case LowPriority$1:
11289 return Scheduler_LowPriority;
11290
11291 case IdlePriority$1:
11292 return Scheduler_IdlePriority;
11293
11294 default:
11295 {
11296 {
11297 throw Error( "Unknown priority level." );
11298 }
11299 }
11300
11301 }
11302 }
11303
11304 function runWithPriority$1(reactPriorityLevel, fn) {
11305 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
11306 return Scheduler_runWithPriority(priorityLevel, fn);
11307 }
11308 function scheduleCallback(reactPriorityLevel, callback, options) {
11309 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
11310 return Scheduler_scheduleCallback(priorityLevel, callback, options);
11311 }
11312 function scheduleSyncCallback(callback) {
11313 // Push this callback into an internal queue. We'll flush these either in
11314 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
11315 if (syncQueue === null) {
11316 syncQueue = [callback]; // Flush the queue in the next tick, at the earliest.
11317
11318 immediateQueueCallbackNode = Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueueImpl);
11319 } else {
11320 // Push onto existing queue. Don't need to schedule a callback because
11321 // we already scheduled one when we created the queue.
11322 syncQueue.push(callback);
11323 }
11324
11325 return fakeCallbackNode;
11326 }
11327 function cancelCallback(callbackNode) {
11328 if (callbackNode !== fakeCallbackNode) {
11329 Scheduler_cancelCallback(callbackNode);
11330 }
11331 }
11332 function flushSyncCallbackQueue() {
11333 if (immediateQueueCallbackNode !== null) {
11334 var node = immediateQueueCallbackNode;
11335 immediateQueueCallbackNode = null;
11336 Scheduler_cancelCallback(node);
11337 }
11338
11339 flushSyncCallbackQueueImpl();
11340 }
11341
11342 function flushSyncCallbackQueueImpl() {
11343 if (!isFlushingSyncQueue && syncQueue !== null) {
11344 // Prevent re-entrancy.
11345 isFlushingSyncQueue = true;
11346 var i = 0;
11347
11348 {
11349 try {
11350 var _isSync2 = true;
11351 var _queue = syncQueue;
11352 runWithPriority$1(ImmediatePriority$1, function () {
11353 for (; i < _queue.length; i++) {
11354 var callback = _queue[i];
11355
11356 do {
11357 callback = callback(_isSync2);
11358 } while (callback !== null);
11359 }
11360 });
11361 syncQueue = null;
11362 } catch (error) {
11363 // If something throws, leave the remaining callbacks on the queue.
11364 if (syncQueue !== null) {
11365 syncQueue = syncQueue.slice(i + 1);
11366 } // Resume flushing in the next tick
11367
11368
11369 Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue);
11370 throw error;
11371 } finally {
11372 isFlushingSyncQueue = false;
11373 }
11374 }
11375 }
11376 }
11377
11378 // TODO: this is special because it gets imported during build.
11379 var ReactVersion = '17.0.1';
11380
11381 var NoMode = 0;
11382 var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root
11383 // tag instead
11384
11385 var BlockingMode = 2;
11386 var ConcurrentMode = 4;
11387 var ProfileMode = 8;
11388 var DebugTracingMode = 16;
11389
11390 var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
11391 var NoTransition = 0;
11392 function requestCurrentTransition() {
11393 return ReactCurrentBatchConfig.transition;
11394 }
11395
11396 var ReactStrictModeWarnings = {
11397 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
11398 flushPendingUnsafeLifecycleWarnings: function () {},
11399 recordLegacyContextWarning: function (fiber, instance) {},
11400 flushLegacyContextWarning: function () {},
11401 discardPendingWarnings: function () {}
11402 };
11403
11404 {
11405 var findStrictRoot = function (fiber) {
11406 var maybeStrictRoot = null;
11407 var node = fiber;
11408
11409 while (node !== null) {
11410 if (node.mode & StrictMode) {
11411 maybeStrictRoot = node;
11412 }
11413
11414 node = node.return;
11415 }
11416
11417 return maybeStrictRoot;
11418 };
11419
11420 var setToSortedString = function (set) {
11421 var array = [];
11422 set.forEach(function (value) {
11423 array.push(value);
11424 });
11425 return array.sort().join(', ');
11426 };
11427
11428 var pendingComponentWillMountWarnings = [];
11429 var pendingUNSAFE_ComponentWillMountWarnings = [];
11430 var pendingComponentWillReceivePropsWarnings = [];
11431 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11432 var pendingComponentWillUpdateWarnings = [];
11433 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.
11434
11435 var didWarnAboutUnsafeLifecycles = new Set();
11436
11437 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
11438 // Dedup strategy: Warn once per component.
11439 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
11440 return;
11441 }
11442
11443 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components.
11444 instance.componentWillMount.__suppressDeprecationWarning !== true) {
11445 pendingComponentWillMountWarnings.push(fiber);
11446 }
11447
11448 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === 'function') {
11449 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
11450 }
11451
11452 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
11453 pendingComponentWillReceivePropsWarnings.push(fiber);
11454 }
11455
11456 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
11457 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
11458 }
11459
11460 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
11461 pendingComponentWillUpdateWarnings.push(fiber);
11462 }
11463
11464 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
11465 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
11466 }
11467 };
11468
11469 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
11470 // We do an initial pass to gather component names
11471 var componentWillMountUniqueNames = new Set();
11472
11473 if (pendingComponentWillMountWarnings.length > 0) {
11474 pendingComponentWillMountWarnings.forEach(function (fiber) {
11475 componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
11476 didWarnAboutUnsafeLifecycles.add(fiber.type);
11477 });
11478 pendingComponentWillMountWarnings = [];
11479 }
11480
11481 var UNSAFE_componentWillMountUniqueNames = new Set();
11482
11483 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
11484 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
11485 UNSAFE_componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
11486 didWarnAboutUnsafeLifecycles.add(fiber.type);
11487 });
11488 pendingUNSAFE_ComponentWillMountWarnings = [];
11489 }
11490
11491 var componentWillReceivePropsUniqueNames = new Set();
11492
11493 if (pendingComponentWillReceivePropsWarnings.length > 0) {
11494 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
11495 componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
11496 didWarnAboutUnsafeLifecycles.add(fiber.type);
11497 });
11498 pendingComponentWillReceivePropsWarnings = [];
11499 }
11500
11501 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
11502
11503 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
11504 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
11505 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
11506 didWarnAboutUnsafeLifecycles.add(fiber.type);
11507 });
11508 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11509 }
11510
11511 var componentWillUpdateUniqueNames = new Set();
11512
11513 if (pendingComponentWillUpdateWarnings.length > 0) {
11514 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
11515 componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
11516 didWarnAboutUnsafeLifecycles.add(fiber.type);
11517 });
11518 pendingComponentWillUpdateWarnings = [];
11519 }
11520
11521 var UNSAFE_componentWillUpdateUniqueNames = new Set();
11522
11523 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
11524 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
11525 UNSAFE_componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
11526 didWarnAboutUnsafeLifecycles.add(fiber.type);
11527 });
11528 pendingUNSAFE_ComponentWillUpdateWarnings = [];
11529 } // Finally, we flush all the warnings
11530 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
11531
11532
11533 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
11534 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
11535
11536 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);
11537 }
11538
11539 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
11540 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
11541
11542 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);
11543 }
11544
11545 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
11546 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
11547
11548 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);
11549 }
11550
11551 if (componentWillMountUniqueNames.size > 0) {
11552 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
11553
11554 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);
11555 }
11556
11557 if (componentWillReceivePropsUniqueNames.size > 0) {
11558 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
11559
11560 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);
11561 }
11562
11563 if (componentWillUpdateUniqueNames.size > 0) {
11564 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
11565
11566 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);
11567 }
11568 };
11569
11570 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.
11571
11572 var didWarnAboutLegacyContext = new Set();
11573
11574 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
11575 var strictRoot = findStrictRoot(fiber);
11576
11577 if (strictRoot === null) {
11578 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.');
11579
11580 return;
11581 } // Dedup strategy: Warn once per component.
11582
11583
11584 if (didWarnAboutLegacyContext.has(fiber.type)) {
11585 return;
11586 }
11587
11588 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
11589
11590 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
11591 if (warningsForRoot === undefined) {
11592 warningsForRoot = [];
11593 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
11594 }
11595
11596 warningsForRoot.push(fiber);
11597 }
11598 };
11599
11600 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
11601 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
11602 if (fiberArray.length === 0) {
11603 return;
11604 }
11605
11606 var firstFiber = fiberArray[0];
11607 var uniqueNames = new Set();
11608 fiberArray.forEach(function (fiber) {
11609 uniqueNames.add(getComponentName(fiber.type) || 'Component');
11610 didWarnAboutLegacyContext.add(fiber.type);
11611 });
11612 var sortedNames = setToSortedString(uniqueNames);
11613
11614 try {
11615 setCurrentFiber(firstFiber);
11616
11617 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);
11618 } finally {
11619 resetCurrentFiber();
11620 }
11621 });
11622 };
11623
11624 ReactStrictModeWarnings.discardPendingWarnings = function () {
11625 pendingComponentWillMountWarnings = [];
11626 pendingUNSAFE_ComponentWillMountWarnings = [];
11627 pendingComponentWillReceivePropsWarnings = [];
11628 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11629 pendingComponentWillUpdateWarnings = [];
11630 pendingUNSAFE_ComponentWillUpdateWarnings = [];
11631 pendingLegacyContextWarning = new Map();
11632 };
11633 }
11634
11635 function resolveDefaultProps(Component, baseProps) {
11636 if (Component && Component.defaultProps) {
11637 // Resolve default props. Taken from ReactElement
11638 var props = _assign({}, baseProps);
11639
11640 var defaultProps = Component.defaultProps;
11641
11642 for (var propName in defaultProps) {
11643 if (props[propName] === undefined) {
11644 props[propName] = defaultProps[propName];
11645 }
11646 }
11647
11648 return props;
11649 }
11650
11651 return baseProps;
11652 }
11653
11654 // Max 31 bit integer. The max integer size in V8 for 32-bit systems.
11655 // Math.pow(2, 30) - 1
11656 // 0b111111111111111111111111111111
11657 var MAX_SIGNED_31_BIT_INT = 1073741823;
11658
11659 var valueCursor = createCursor(null);
11660 var rendererSigil;
11661
11662 {
11663 // Use this to detect multiple renderers using the same context
11664 rendererSigil = {};
11665 }
11666
11667 var currentlyRenderingFiber = null;
11668 var lastContextDependency = null;
11669 var lastContextWithAllBitsObserved = null;
11670 var isDisallowedContextReadInDEV = false;
11671 function resetContextDependencies() {
11672 // This is called right before React yields execution, to ensure `readContext`
11673 // cannot be called outside the render phase.
11674 currentlyRenderingFiber = null;
11675 lastContextDependency = null;
11676 lastContextWithAllBitsObserved = null;
11677
11678 {
11679 isDisallowedContextReadInDEV = false;
11680 }
11681 }
11682 function enterDisallowedContextReadInDEV() {
11683 {
11684 isDisallowedContextReadInDEV = true;
11685 }
11686 }
11687 function exitDisallowedContextReadInDEV() {
11688 {
11689 isDisallowedContextReadInDEV = false;
11690 }
11691 }
11692 function pushProvider(providerFiber, nextValue) {
11693 var context = providerFiber.type._context;
11694
11695 {
11696 push(valueCursor, context._currentValue, providerFiber);
11697 context._currentValue = nextValue;
11698
11699 {
11700 if (context._currentRenderer !== undefined && context._currentRenderer !== null && context._currentRenderer !== rendererSigil) {
11701 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.');
11702 }
11703
11704 context._currentRenderer = rendererSigil;
11705 }
11706 }
11707 }
11708 function popProvider(providerFiber) {
11709 var currentValue = valueCursor.current;
11710 pop(valueCursor, providerFiber);
11711 var context = providerFiber.type._context;
11712
11713 {
11714 context._currentValue = currentValue;
11715 }
11716 }
11717 function calculateChangedBits(context, newValue, oldValue) {
11718 if (objectIs(oldValue, newValue)) {
11719 // No change
11720 return 0;
11721 } else {
11722 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;
11723
11724 {
11725 if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) {
11726 error('calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits);
11727 }
11728 }
11729
11730 return changedBits | 0;
11731 }
11732 }
11733 function scheduleWorkOnParentPath(parent, renderLanes) {
11734 // Update the child lanes of all the ancestors, including the alternates.
11735 var node = parent;
11736
11737 while (node !== null) {
11738 var alternate = node.alternate;
11739
11740 if (!isSubsetOfLanes(node.childLanes, renderLanes)) {
11741 node.childLanes = mergeLanes(node.childLanes, renderLanes);
11742
11743 if (alternate !== null) {
11744 alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
11745 }
11746 } else if (alternate !== null && !isSubsetOfLanes(alternate.childLanes, renderLanes)) {
11747 alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
11748 } else {
11749 // Neither alternate was updated, which means the rest of the
11750 // ancestor path already has sufficient priority.
11751 break;
11752 }
11753
11754 node = node.return;
11755 }
11756 }
11757 function propagateContextChange(workInProgress, context, changedBits, renderLanes) {
11758 var fiber = workInProgress.child;
11759
11760 if (fiber !== null) {
11761 // Set the return pointer of the child to the work-in-progress fiber.
11762 fiber.return = workInProgress;
11763 }
11764
11765 while (fiber !== null) {
11766 var nextFiber = void 0; // Visit this fiber.
11767
11768 var list = fiber.dependencies;
11769
11770 if (list !== null) {
11771 nextFiber = fiber.child;
11772 var dependency = list.firstContext;
11773
11774 while (dependency !== null) {
11775 // Check if the context matches.
11776 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
11777 // Match! Schedule an update on this fiber.
11778 if (fiber.tag === ClassComponent) {
11779 // Schedule a force update on the work-in-progress.
11780 var update = createUpdate(NoTimestamp, pickArbitraryLane(renderLanes));
11781 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the
11782 // update to the current fiber, too, which means it will persist even if
11783 // this render is thrown away. Since it's a race condition, not sure it's
11784 // worth fixing.
11785
11786 enqueueUpdate(fiber, update);
11787 }
11788
11789 fiber.lanes = mergeLanes(fiber.lanes, renderLanes);
11790 var alternate = fiber.alternate;
11791
11792 if (alternate !== null) {
11793 alternate.lanes = mergeLanes(alternate.lanes, renderLanes);
11794 }
11795
11796 scheduleWorkOnParentPath(fiber.return, renderLanes); // Mark the updated lanes on the list, too.
11797
11798 list.lanes = mergeLanes(list.lanes, renderLanes); // Since we already found a match, we can stop traversing the
11799 // dependency list.
11800
11801 break;
11802 }
11803
11804 dependency = dependency.next;
11805 }
11806 } else if (fiber.tag === ContextProvider) {
11807 // Don't scan deeper if this is a matching provider
11808 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
11809 } else {
11810 // Traverse down.
11811 nextFiber = fiber.child;
11812 }
11813
11814 if (nextFiber !== null) {
11815 // Set the return pointer of the child to the work-in-progress fiber.
11816 nextFiber.return = fiber;
11817 } else {
11818 // No child. Traverse to next sibling.
11819 nextFiber = fiber;
11820
11821 while (nextFiber !== null) {
11822 if (nextFiber === workInProgress) {
11823 // We're back to the root of this subtree. Exit.
11824 nextFiber = null;
11825 break;
11826 }
11827
11828 var sibling = nextFiber.sibling;
11829
11830 if (sibling !== null) {
11831 // Set the return pointer of the sibling to the work-in-progress fiber.
11832 sibling.return = nextFiber.return;
11833 nextFiber = sibling;
11834 break;
11835 } // No more siblings. Traverse up.
11836
11837
11838 nextFiber = nextFiber.return;
11839 }
11840 }
11841
11842 fiber = nextFiber;
11843 }
11844 }
11845 function prepareToReadContext(workInProgress, renderLanes) {
11846 currentlyRenderingFiber = workInProgress;
11847 lastContextDependency = null;
11848 lastContextWithAllBitsObserved = null;
11849 var dependencies = workInProgress.dependencies;
11850
11851 if (dependencies !== null) {
11852 var firstContext = dependencies.firstContext;
11853
11854 if (firstContext !== null) {
11855 if (includesSomeLane(dependencies.lanes, renderLanes)) {
11856 // Context list has a pending update. Mark that this fiber performed work.
11857 markWorkInProgressReceivedUpdate();
11858 } // Reset the work-in-progress list
11859
11860
11861 dependencies.firstContext = null;
11862 }
11863 }
11864 }
11865 function readContext(context, observedBits) {
11866 {
11867 // This warning would fire if you read context inside a Hook like useMemo.
11868 // Unlike the class check below, it's not enforced in production for perf.
11869 if (isDisallowedContextReadInDEV) {
11870 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().');
11871 }
11872 }
11873
11874 if (lastContextWithAllBitsObserved === context) ; else if (observedBits === false || observedBits === 0) ; else {
11875 var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types.
11876
11877 if (typeof observedBits !== 'number' || observedBits === MAX_SIGNED_31_BIT_INT) {
11878 // Observe all updates.
11879 lastContextWithAllBitsObserved = context;
11880 resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
11881 } else {
11882 resolvedObservedBits = observedBits;
11883 }
11884
11885 var contextItem = {
11886 context: context,
11887 observedBits: resolvedObservedBits,
11888 next: null
11889 };
11890
11891 if (lastContextDependency === null) {
11892 if (!(currentlyRenderingFiber !== null)) {
11893 {
11894 throw Error( "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." );
11895 }
11896 } // This is the first dependency for this component. Create a new list.
11897
11898
11899 lastContextDependency = contextItem;
11900 currentlyRenderingFiber.dependencies = {
11901 lanes: NoLanes,
11902 firstContext: contextItem,
11903 responders: null
11904 };
11905 } else {
11906 // Append a new context item.
11907 lastContextDependency = lastContextDependency.next = contextItem;
11908 }
11909 }
11910
11911 return context._currentValue ;
11912 }
11913
11914 var UpdateState = 0;
11915 var ReplaceState = 1;
11916 var ForceUpdate = 2;
11917 var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.
11918 // It should only be read right after calling `processUpdateQueue`, via
11919 // `checkHasForceUpdateAfterProcessing`.
11920
11921 var hasForceUpdate = false;
11922 var didWarnUpdateInsideUpdate;
11923 var currentlyProcessingQueue;
11924
11925 {
11926 didWarnUpdateInsideUpdate = false;
11927 currentlyProcessingQueue = null;
11928 }
11929
11930 function initializeUpdateQueue(fiber) {
11931 var queue = {
11932 baseState: fiber.memoizedState,
11933 firstBaseUpdate: null,
11934 lastBaseUpdate: null,
11935 shared: {
11936 pending: null
11937 },
11938 effects: null
11939 };
11940 fiber.updateQueue = queue;
11941 }
11942 function cloneUpdateQueue(current, workInProgress) {
11943 // Clone the update queue from current. Unless it's already a clone.
11944 var queue = workInProgress.updateQueue;
11945 var currentQueue = current.updateQueue;
11946
11947 if (queue === currentQueue) {
11948 var clone = {
11949 baseState: currentQueue.baseState,
11950 firstBaseUpdate: currentQueue.firstBaseUpdate,
11951 lastBaseUpdate: currentQueue.lastBaseUpdate,
11952 shared: currentQueue.shared,
11953 effects: currentQueue.effects
11954 };
11955 workInProgress.updateQueue = clone;
11956 }
11957 }
11958 function createUpdate(eventTime, lane) {
11959 var update = {
11960 eventTime: eventTime,
11961 lane: lane,
11962 tag: UpdateState,
11963 payload: null,
11964 callback: null,
11965 next: null
11966 };
11967 return update;
11968 }
11969 function enqueueUpdate(fiber, update) {
11970 var updateQueue = fiber.updateQueue;
11971
11972 if (updateQueue === null) {
11973 // Only occurs if the fiber has been unmounted.
11974 return;
11975 }
11976
11977 var sharedQueue = updateQueue.shared;
11978 var pending = sharedQueue.pending;
11979
11980 if (pending === null) {
11981 // This is the first update. Create a circular list.
11982 update.next = update;
11983 } else {
11984 update.next = pending.next;
11985 pending.next = update;
11986 }
11987
11988 sharedQueue.pending = update;
11989
11990 {
11991 if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) {
11992 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.');
11993
11994 didWarnUpdateInsideUpdate = true;
11995 }
11996 }
11997 }
11998 function enqueueCapturedUpdate(workInProgress, capturedUpdate) {
11999 // Captured updates are updates that are thrown by a child during the render
12000 // phase. They should be discarded if the render is aborted. Therefore,
12001 // we should only put them on the work-in-progress queue, not the current one.
12002 var queue = workInProgress.updateQueue; // Check if the work-in-progress queue is a clone.
12003
12004 var current = workInProgress.alternate;
12005
12006 if (current !== null) {
12007 var currentQueue = current.updateQueue;
12008
12009 if (queue === currentQueue) {
12010 // The work-in-progress queue is the same as current. This happens when
12011 // we bail out on a parent fiber that then captures an error thrown by
12012 // a child. Since we want to append the update only to the work-in
12013 // -progress queue, we need to clone the updates. We usually clone during
12014 // processUpdateQueue, but that didn't happen in this case because we
12015 // skipped over the parent when we bailed out.
12016 var newFirst = null;
12017 var newLast = null;
12018 var firstBaseUpdate = queue.firstBaseUpdate;
12019
12020 if (firstBaseUpdate !== null) {
12021 // Loop through the updates and clone them.
12022 var update = firstBaseUpdate;
12023
12024 do {
12025 var clone = {
12026 eventTime: update.eventTime,
12027 lane: update.lane,
12028 tag: update.tag,
12029 payload: update.payload,
12030 callback: update.callback,
12031 next: null
12032 };
12033
12034 if (newLast === null) {
12035 newFirst = newLast = clone;
12036 } else {
12037 newLast.next = clone;
12038 newLast = clone;
12039 }
12040
12041 update = update.next;
12042 } while (update !== null); // Append the captured update the end of the cloned list.
12043
12044
12045 if (newLast === null) {
12046 newFirst = newLast = capturedUpdate;
12047 } else {
12048 newLast.next = capturedUpdate;
12049 newLast = capturedUpdate;
12050 }
12051 } else {
12052 // There are no base updates.
12053 newFirst = newLast = capturedUpdate;
12054 }
12055
12056 queue = {
12057 baseState: currentQueue.baseState,
12058 firstBaseUpdate: newFirst,
12059 lastBaseUpdate: newLast,
12060 shared: currentQueue.shared,
12061 effects: currentQueue.effects
12062 };
12063 workInProgress.updateQueue = queue;
12064 return;
12065 }
12066 } // Append the update to the end of the list.
12067
12068
12069 var lastBaseUpdate = queue.lastBaseUpdate;
12070
12071 if (lastBaseUpdate === null) {
12072 queue.firstBaseUpdate = capturedUpdate;
12073 } else {
12074 lastBaseUpdate.next = capturedUpdate;
12075 }
12076
12077 queue.lastBaseUpdate = capturedUpdate;
12078 }
12079
12080 function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
12081 switch (update.tag) {
12082 case ReplaceState:
12083 {
12084 var payload = update.payload;
12085
12086 if (typeof payload === 'function') {
12087 // Updater function
12088 {
12089 enterDisallowedContextReadInDEV();
12090 }
12091
12092 var nextState = payload.call(instance, prevState, nextProps);
12093
12094 {
12095 if ( workInProgress.mode & StrictMode) {
12096 disableLogs();
12097
12098 try {
12099 payload.call(instance, prevState, nextProps);
12100 } finally {
12101 reenableLogs();
12102 }
12103 }
12104
12105 exitDisallowedContextReadInDEV();
12106 }
12107
12108 return nextState;
12109 } // State object
12110
12111
12112 return payload;
12113 }
12114
12115 case CaptureUpdate:
12116 {
12117 workInProgress.flags = workInProgress.flags & ~ShouldCapture | DidCapture;
12118 }
12119 // Intentional fallthrough
12120
12121 case UpdateState:
12122 {
12123 var _payload = update.payload;
12124 var partialState;
12125
12126 if (typeof _payload === 'function') {
12127 // Updater function
12128 {
12129 enterDisallowedContextReadInDEV();
12130 }
12131
12132 partialState = _payload.call(instance, prevState, nextProps);
12133
12134 {
12135 if ( workInProgress.mode & StrictMode) {
12136 disableLogs();
12137
12138 try {
12139 _payload.call(instance, prevState, nextProps);
12140 } finally {
12141 reenableLogs();
12142 }
12143 }
12144
12145 exitDisallowedContextReadInDEV();
12146 }
12147 } else {
12148 // Partial state object
12149 partialState = _payload;
12150 }
12151
12152 if (partialState === null || partialState === undefined) {
12153 // Null and undefined are treated as no-ops.
12154 return prevState;
12155 } // Merge the partial state and the previous state.
12156
12157
12158 return _assign({}, prevState, partialState);
12159 }
12160
12161 case ForceUpdate:
12162 {
12163 hasForceUpdate = true;
12164 return prevState;
12165 }
12166 }
12167
12168 return prevState;
12169 }
12170
12171 function processUpdateQueue(workInProgress, props, instance, renderLanes) {
12172 // This is always non-null on a ClassComponent or HostRoot
12173 var queue = workInProgress.updateQueue;
12174 hasForceUpdate = false;
12175
12176 {
12177 currentlyProcessingQueue = queue.shared;
12178 }
12179
12180 var firstBaseUpdate = queue.firstBaseUpdate;
12181 var lastBaseUpdate = queue.lastBaseUpdate; // Check if there are pending updates. If so, transfer them to the base queue.
12182
12183 var pendingQueue = queue.shared.pending;
12184
12185 if (pendingQueue !== null) {
12186 queue.shared.pending = null; // The pending queue is circular. Disconnect the pointer between first
12187 // and last so that it's non-circular.
12188
12189 var lastPendingUpdate = pendingQueue;
12190 var firstPendingUpdate = lastPendingUpdate.next;
12191 lastPendingUpdate.next = null; // Append pending updates to base queue
12192
12193 if (lastBaseUpdate === null) {
12194 firstBaseUpdate = firstPendingUpdate;
12195 } else {
12196 lastBaseUpdate.next = firstPendingUpdate;
12197 }
12198
12199 lastBaseUpdate = lastPendingUpdate; // If there's a current queue, and it's different from the base queue, then
12200 // we need to transfer the updates to that queue, too. Because the base
12201 // queue is a singly-linked list with no cycles, we can append to both
12202 // lists and take advantage of structural sharing.
12203 // TODO: Pass `current` as argument
12204
12205 var current = workInProgress.alternate;
12206
12207 if (current !== null) {
12208 // This is always non-null on a ClassComponent or HostRoot
12209 var currentQueue = current.updateQueue;
12210 var currentLastBaseUpdate = currentQueue.lastBaseUpdate;
12211
12212 if (currentLastBaseUpdate !== lastBaseUpdate) {
12213 if (currentLastBaseUpdate === null) {
12214 currentQueue.firstBaseUpdate = firstPendingUpdate;
12215 } else {
12216 currentLastBaseUpdate.next = firstPendingUpdate;
12217 }
12218
12219 currentQueue.lastBaseUpdate = lastPendingUpdate;
12220 }
12221 }
12222 } // These values may change as we process the queue.
12223
12224
12225 if (firstBaseUpdate !== null) {
12226 // Iterate through the list of updates to compute the result.
12227 var newState = queue.baseState; // TODO: Don't need to accumulate this. Instead, we can remove renderLanes
12228 // from the original lanes.
12229
12230 var newLanes = NoLanes;
12231 var newBaseState = null;
12232 var newFirstBaseUpdate = null;
12233 var newLastBaseUpdate = null;
12234 var update = firstBaseUpdate;
12235
12236 do {
12237 var updateLane = update.lane;
12238 var updateEventTime = update.eventTime;
12239
12240 if (!isSubsetOfLanes(renderLanes, updateLane)) {
12241 // Priority is insufficient. Skip this update. If this is the first
12242 // skipped update, the previous update/state is the new base
12243 // update/state.
12244 var clone = {
12245 eventTime: updateEventTime,
12246 lane: updateLane,
12247 tag: update.tag,
12248 payload: update.payload,
12249 callback: update.callback,
12250 next: null
12251 };
12252
12253 if (newLastBaseUpdate === null) {
12254 newFirstBaseUpdate = newLastBaseUpdate = clone;
12255 newBaseState = newState;
12256 } else {
12257 newLastBaseUpdate = newLastBaseUpdate.next = clone;
12258 } // Update the remaining priority in the queue.
12259
12260
12261 newLanes = mergeLanes(newLanes, updateLane);
12262 } else {
12263 // This update does have sufficient priority.
12264 if (newLastBaseUpdate !== null) {
12265 var _clone = {
12266 eventTime: updateEventTime,
12267 // This update is going to be committed so we never want uncommit
12268 // it. Using NoLane works because 0 is a subset of all bitmasks, so
12269 // this will never be skipped by the check above.
12270 lane: NoLane,
12271 tag: update.tag,
12272 payload: update.payload,
12273 callback: update.callback,
12274 next: null
12275 };
12276 newLastBaseUpdate = newLastBaseUpdate.next = _clone;
12277 } // Process this update.
12278
12279
12280 newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance);
12281 var callback = update.callback;
12282
12283 if (callback !== null) {
12284 workInProgress.flags |= Callback;
12285 var effects = queue.effects;
12286
12287 if (effects === null) {
12288 queue.effects = [update];
12289 } else {
12290 effects.push(update);
12291 }
12292 }
12293 }
12294
12295 update = update.next;
12296
12297 if (update === null) {
12298 pendingQueue = queue.shared.pending;
12299
12300 if (pendingQueue === null) {
12301 break;
12302 } else {
12303 // An update was scheduled from inside a reducer. Add the new
12304 // pending updates to the end of the list and keep processing.
12305 var _lastPendingUpdate = pendingQueue; // Intentionally unsound. Pending updates form a circular list, but we
12306 // unravel them when transferring them to the base queue.
12307
12308 var _firstPendingUpdate = _lastPendingUpdate.next;
12309 _lastPendingUpdate.next = null;
12310 update = _firstPendingUpdate;
12311 queue.lastBaseUpdate = _lastPendingUpdate;
12312 queue.shared.pending = null;
12313 }
12314 }
12315 } while (true);
12316
12317 if (newLastBaseUpdate === null) {
12318 newBaseState = newState;
12319 }
12320
12321 queue.baseState = newBaseState;
12322 queue.firstBaseUpdate = newFirstBaseUpdate;
12323 queue.lastBaseUpdate = newLastBaseUpdate; // Set the remaining expiration time to be whatever is remaining in the queue.
12324 // This should be fine because the only two other things that contribute to
12325 // expiration time are props and context. We're already in the middle of the
12326 // begin phase by the time we start processing the queue, so we've already
12327 // dealt with the props. Context in components that specify
12328 // shouldComponentUpdate is tricky; but we'll have to account for
12329 // that regardless.
12330
12331 markSkippedUpdateLanes(newLanes);
12332 workInProgress.lanes = newLanes;
12333 workInProgress.memoizedState = newState;
12334 }
12335
12336 {
12337 currentlyProcessingQueue = null;
12338 }
12339 }
12340
12341 function callCallback(callback, context) {
12342 if (!(typeof callback === 'function')) {
12343 {
12344 throw Error( "Invalid argument passed as callback. Expected a function. Instead received: " + callback );
12345 }
12346 }
12347
12348 callback.call(context);
12349 }
12350
12351 function resetHasForceUpdateBeforeProcessing() {
12352 hasForceUpdate = false;
12353 }
12354 function checkHasForceUpdateAfterProcessing() {
12355 return hasForceUpdate;
12356 }
12357 function commitUpdateQueue(finishedWork, finishedQueue, instance) {
12358 // Commit the effects
12359 var effects = finishedQueue.effects;
12360 finishedQueue.effects = null;
12361
12362 if (effects !== null) {
12363 for (var i = 0; i < effects.length; i++) {
12364 var effect = effects[i];
12365 var callback = effect.callback;
12366
12367 if (callback !== null) {
12368 effect.callback = null;
12369 callCallback(callback, instance);
12370 }
12371 }
12372 }
12373 }
12374
12375 var fakeInternalInstance = {};
12376 var isArray = Array.isArray; // React.Component uses a shared frozen object by default.
12377 // We'll use it to determine whether we need to initialize legacy refs.
12378
12379 var emptyRefsObject = new React.Component().refs;
12380 var didWarnAboutStateAssignmentForComponent;
12381 var didWarnAboutUninitializedState;
12382 var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
12383 var didWarnAboutLegacyLifecyclesAndDerivedState;
12384 var didWarnAboutUndefinedDerivedState;
12385 var warnOnUndefinedDerivedState;
12386 var warnOnInvalidCallback;
12387 var didWarnAboutDirectlyAssigningPropsToState;
12388 var didWarnAboutContextTypeAndContextTypes;
12389 var didWarnAboutInvalidateContextType;
12390
12391 {
12392 didWarnAboutStateAssignmentForComponent = new Set();
12393 didWarnAboutUninitializedState = new Set();
12394 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
12395 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
12396 didWarnAboutDirectlyAssigningPropsToState = new Set();
12397 didWarnAboutUndefinedDerivedState = new Set();
12398 didWarnAboutContextTypeAndContextTypes = new Set();
12399 didWarnAboutInvalidateContextType = new Set();
12400 var didWarnOnInvalidCallback = new Set();
12401
12402 warnOnInvalidCallback = function (callback, callerName) {
12403 if (callback === null || typeof callback === 'function') {
12404 return;
12405 }
12406
12407 var key = callerName + '_' + callback;
12408
12409 if (!didWarnOnInvalidCallback.has(key)) {
12410 didWarnOnInvalidCallback.add(key);
12411
12412 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
12413 }
12414 };
12415
12416 warnOnUndefinedDerivedState = function (type, partialState) {
12417 if (partialState === undefined) {
12418 var componentName = getComponentName(type) || 'Component';
12419
12420 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
12421 didWarnAboutUndefinedDerivedState.add(componentName);
12422
12423 error('%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
12424 }
12425 }
12426 }; // This is so gross but it's at least non-critical and can be removed if
12427 // it causes problems. This is meant to give a nicer error message for
12428 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
12429 // ...)) which otherwise throws a "_processChildContext is not a function"
12430 // exception.
12431
12432
12433 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
12434 enumerable: false,
12435 value: function () {
12436 {
12437 {
12438 throw Error( "_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal)." );
12439 }
12440 }
12441 }
12442 });
12443 Object.freeze(fakeInternalInstance);
12444 }
12445
12446 function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
12447 var prevState = workInProgress.memoizedState;
12448
12449 {
12450 if ( workInProgress.mode & StrictMode) {
12451 disableLogs();
12452
12453 try {
12454 // Invoke the function an extra time to help detect side-effects.
12455 getDerivedStateFromProps(nextProps, prevState);
12456 } finally {
12457 reenableLogs();
12458 }
12459 }
12460 }
12461
12462 var partialState = getDerivedStateFromProps(nextProps, prevState);
12463
12464 {
12465 warnOnUndefinedDerivedState(ctor, partialState);
12466 } // Merge the partial state and the previous state.
12467
12468
12469 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
12470 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the
12471 // base state.
12472
12473 if (workInProgress.lanes === NoLanes) {
12474 // Queue is always non-null for classes
12475 var updateQueue = workInProgress.updateQueue;
12476 updateQueue.baseState = memoizedState;
12477 }
12478 }
12479 var classComponentUpdater = {
12480 isMounted: isMounted,
12481 enqueueSetState: function (inst, payload, callback) {
12482 var fiber = get(inst);
12483 var eventTime = requestEventTime();
12484 var lane = requestUpdateLane(fiber);
12485 var update = createUpdate(eventTime, lane);
12486 update.payload = payload;
12487
12488 if (callback !== undefined && callback !== null) {
12489 {
12490 warnOnInvalidCallback(callback, 'setState');
12491 }
12492
12493 update.callback = callback;
12494 }
12495
12496 enqueueUpdate(fiber, update);
12497 scheduleUpdateOnFiber(fiber, lane, eventTime);
12498 },
12499 enqueueReplaceState: function (inst, payload, callback) {
12500 var fiber = get(inst);
12501 var eventTime = requestEventTime();
12502 var lane = requestUpdateLane(fiber);
12503 var update = createUpdate(eventTime, lane);
12504 update.tag = ReplaceState;
12505 update.payload = payload;
12506
12507 if (callback !== undefined && callback !== null) {
12508 {
12509 warnOnInvalidCallback(callback, 'replaceState');
12510 }
12511
12512 update.callback = callback;
12513 }
12514
12515 enqueueUpdate(fiber, update);
12516 scheduleUpdateOnFiber(fiber, lane, eventTime);
12517 },
12518 enqueueForceUpdate: function (inst, callback) {
12519 var fiber = get(inst);
12520 var eventTime = requestEventTime();
12521 var lane = requestUpdateLane(fiber);
12522 var update = createUpdate(eventTime, lane);
12523 update.tag = ForceUpdate;
12524
12525 if (callback !== undefined && callback !== null) {
12526 {
12527 warnOnInvalidCallback(callback, 'forceUpdate');
12528 }
12529
12530 update.callback = callback;
12531 }
12532
12533 enqueueUpdate(fiber, update);
12534 scheduleUpdateOnFiber(fiber, lane, eventTime);
12535 }
12536 };
12537
12538 function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
12539 var instance = workInProgress.stateNode;
12540
12541 if (typeof instance.shouldComponentUpdate === 'function') {
12542 {
12543 if ( workInProgress.mode & StrictMode) {
12544 disableLogs();
12545
12546 try {
12547 // Invoke the function an extra time to help detect side-effects.
12548 instance.shouldComponentUpdate(newProps, newState, nextContext);
12549 } finally {
12550 reenableLogs();
12551 }
12552 }
12553 }
12554
12555 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
12556
12557 {
12558 if (shouldUpdate === undefined) {
12559 error('%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component');
12560 }
12561 }
12562
12563 return shouldUpdate;
12564 }
12565
12566 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
12567 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
12568 }
12569
12570 return true;
12571 }
12572
12573 function checkClassInstance(workInProgress, ctor, newProps) {
12574 var instance = workInProgress.stateNode;
12575
12576 {
12577 var name = getComponentName(ctor) || 'Component';
12578 var renderPresent = instance.render;
12579
12580 if (!renderPresent) {
12581 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
12582 error('%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
12583 } else {
12584 error('%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
12585 }
12586 }
12587
12588 if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) {
12589 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);
12590 }
12591
12592 if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) {
12593 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);
12594 }
12595
12596 if (instance.propTypes) {
12597 error('propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
12598 }
12599
12600 if (instance.contextType) {
12601 error('contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name);
12602 }
12603
12604 {
12605 if (instance.contextTypes) {
12606 error('contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);
12607 }
12608
12609 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
12610 didWarnAboutContextTypeAndContextTypes.add(ctor);
12611
12612 error('%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
12613 }
12614 }
12615
12616 if (typeof instance.componentShouldUpdate === 'function') {
12617 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);
12618 }
12619
12620 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
12621 error('%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentName(ctor) || 'A pure component');
12622 }
12623
12624 if (typeof instance.componentDidUnmount === 'function') {
12625 error('%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
12626 }
12627
12628 if (typeof instance.componentDidReceiveProps === 'function') {
12629 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);
12630 }
12631
12632 if (typeof instance.componentWillRecieveProps === 'function') {
12633 error('%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
12634 }
12635
12636 if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') {
12637 error('%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name);
12638 }
12639
12640 var hasMutatedProps = instance.props !== newProps;
12641
12642 if (instance.props !== undefined && hasMutatedProps) {
12643 error('%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name);
12644 }
12645
12646 if (instance.defaultProps) {
12647 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);
12648 }
12649
12650 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
12651 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
12652
12653 error('%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
12654 }
12655
12656 if (typeof instance.getDerivedStateFromProps === 'function') {
12657 error('%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
12658 }
12659
12660 if (typeof instance.getDerivedStateFromError === 'function') {
12661 error('%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
12662 }
12663
12664 if (typeof ctor.getSnapshotBeforeUpdate === 'function') {
12665 error('%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name);
12666 }
12667
12668 var _state = instance.state;
12669
12670 if (_state && (typeof _state !== 'object' || isArray(_state))) {
12671 error('%s.state: must be set to an object or null', name);
12672 }
12673
12674 if (typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object') {
12675 error('%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name);
12676 }
12677 }
12678 }
12679
12680 function adoptClassInstance(workInProgress, instance) {
12681 instance.updater = classComponentUpdater;
12682 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates
12683
12684 set(instance, workInProgress);
12685
12686 {
12687 instance._reactInternalInstance = fakeInternalInstance;
12688 }
12689 }
12690
12691 function constructClassInstance(workInProgress, ctor, props) {
12692 var isLegacyContextConsumer = false;
12693 var unmaskedContext = emptyContextObject;
12694 var context = emptyContextObject;
12695 var contextType = ctor.contextType;
12696
12697 {
12698 if ('contextType' in ctor) {
12699 var isValid = // Allow null for conditional declaration
12700 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
12701
12702 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
12703 didWarnAboutInvalidateContextType.add(ctor);
12704 var addendum = '';
12705
12706 if (contextType === undefined) {
12707 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.';
12708 } else if (typeof contextType !== 'object') {
12709 addendum = ' However, it is set to a ' + typeof contextType + '.';
12710 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
12711 addendum = ' Did you accidentally pass the Context.Provider instead?';
12712 } else if (contextType._context !== undefined) {
12713 // <Context.Consumer>
12714 addendum = ' Did you accidentally pass the Context.Consumer instead?';
12715 } else {
12716 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
12717 }
12718
12719 error('%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
12720 }
12721 }
12722 }
12723
12724 if (typeof contextType === 'object' && contextType !== null) {
12725 context = readContext(contextType);
12726 } else {
12727 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
12728 var contextTypes = ctor.contextTypes;
12729 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
12730 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
12731 } // Instantiate twice to help detect side-effects.
12732
12733
12734 {
12735 if ( workInProgress.mode & StrictMode) {
12736 disableLogs();
12737
12738 try {
12739 new ctor(props, context); // eslint-disable-line no-new
12740 } finally {
12741 reenableLogs();
12742 }
12743 }
12744 }
12745
12746 var instance = new ctor(props, context);
12747 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
12748 adoptClassInstance(workInProgress, instance);
12749
12750 {
12751 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
12752 var componentName = getComponentName(ctor) || 'Component';
12753
12754 if (!didWarnAboutUninitializedState.has(componentName)) {
12755 didWarnAboutUninitializedState.add(componentName);
12756
12757 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);
12758 }
12759 } // If new component APIs are defined, "unsafe" lifecycles won't be called.
12760 // Warn about these lifecycles if they are present.
12761 // Don't warn about react-lifecycles-compat polyfilled methods though.
12762
12763
12764 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
12765 var foundWillMountName = null;
12766 var foundWillReceivePropsName = null;
12767 var foundWillUpdateName = null;
12768
12769 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
12770 foundWillMountName = 'componentWillMount';
12771 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
12772 foundWillMountName = 'UNSAFE_componentWillMount';
12773 }
12774
12775 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
12776 foundWillReceivePropsName = 'componentWillReceiveProps';
12777 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
12778 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
12779 }
12780
12781 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
12782 foundWillUpdateName = 'componentWillUpdate';
12783 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
12784 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
12785 }
12786
12787 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
12788 var _componentName = getComponentName(ctor) || 'Component';
12789
12790 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
12791
12792 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
12793 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
12794
12795 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 : '');
12796 }
12797 }
12798 }
12799 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
12800 // ReactFiberContext usually updates this cache but can't for newly-created instances.
12801
12802
12803 if (isLegacyContextConsumer) {
12804 cacheContext(workInProgress, unmaskedContext, context);
12805 }
12806
12807 return instance;
12808 }
12809
12810 function callComponentWillMount(workInProgress, instance) {
12811 var oldState = instance.state;
12812
12813 if (typeof instance.componentWillMount === 'function') {
12814 instance.componentWillMount();
12815 }
12816
12817 if (typeof instance.UNSAFE_componentWillMount === 'function') {
12818 instance.UNSAFE_componentWillMount();
12819 }
12820
12821 if (oldState !== instance.state) {
12822 {
12823 error('%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress.type) || 'Component');
12824 }
12825
12826 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
12827 }
12828 }
12829
12830 function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
12831 var oldState = instance.state;
12832
12833 if (typeof instance.componentWillReceiveProps === 'function') {
12834 instance.componentWillReceiveProps(newProps, nextContext);
12835 }
12836
12837 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
12838 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
12839 }
12840
12841 if (instance.state !== oldState) {
12842 {
12843 var componentName = getComponentName(workInProgress.type) || 'Component';
12844
12845 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
12846 didWarnAboutStateAssignmentForComponent.add(componentName);
12847
12848 error('%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
12849 }
12850 }
12851
12852 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
12853 }
12854 } // Invokes the mount life-cycles on a previously never rendered instance.
12855
12856
12857 function mountClassInstance(workInProgress, ctor, newProps, renderLanes) {
12858 {
12859 checkClassInstance(workInProgress, ctor, newProps);
12860 }
12861
12862 var instance = workInProgress.stateNode;
12863 instance.props = newProps;
12864 instance.state = workInProgress.memoizedState;
12865 instance.refs = emptyRefsObject;
12866 initializeUpdateQueue(workInProgress);
12867 var contextType = ctor.contextType;
12868
12869 if (typeof contextType === 'object' && contextType !== null) {
12870 instance.context = readContext(contextType);
12871 } else {
12872 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
12873 instance.context = getMaskedContext(workInProgress, unmaskedContext);
12874 }
12875
12876 {
12877 if (instance.state === newProps) {
12878 var componentName = getComponentName(ctor) || 'Component';
12879
12880 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
12881 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
12882
12883 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);
12884 }
12885 }
12886
12887 if (workInProgress.mode & StrictMode) {
12888 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
12889 }
12890
12891 {
12892 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
12893 }
12894 }
12895
12896 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
12897 instance.state = workInProgress.memoizedState;
12898 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
12899
12900 if (typeof getDerivedStateFromProps === 'function') {
12901 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
12902 instance.state = workInProgress.memoizedState;
12903 } // In order to support react-lifecycles-compat polyfilled components,
12904 // Unsafe lifecycles should not be invoked for components using the new APIs.
12905
12906
12907 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
12908 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's
12909 // process them now.
12910
12911 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
12912 instance.state = workInProgress.memoizedState;
12913 }
12914
12915 if (typeof instance.componentDidMount === 'function') {
12916 workInProgress.flags |= Update;
12917 }
12918 }
12919
12920 function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) {
12921 var instance = workInProgress.stateNode;
12922 var oldProps = workInProgress.memoizedProps;
12923 instance.props = oldProps;
12924 var oldContext = instance.context;
12925 var contextType = ctor.contextType;
12926 var nextContext = emptyContextObject;
12927
12928 if (typeof contextType === 'object' && contextType !== null) {
12929 nextContext = readContext(contextType);
12930 } else {
12931 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
12932 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
12933 }
12934
12935 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
12936 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
12937 // ever the previously attempted to render - not the "current". However,
12938 // during componentDidUpdate we pass the "current" props.
12939 // In order to support react-lifecycles-compat polyfilled components,
12940 // Unsafe lifecycles should not be invoked for components using the new APIs.
12941
12942 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
12943 if (oldProps !== newProps || oldContext !== nextContext) {
12944 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
12945 }
12946 }
12947
12948 resetHasForceUpdateBeforeProcessing();
12949 var oldState = workInProgress.memoizedState;
12950 var newState = instance.state = oldState;
12951 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
12952 newState = workInProgress.memoizedState;
12953
12954 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
12955 // If an update was already in progress, we should schedule an Update
12956 // effect even though we're bailing out, so that cWU/cDU are called.
12957 if (typeof instance.componentDidMount === 'function') {
12958 workInProgress.flags |= Update;
12959 }
12960
12961 return false;
12962 }
12963
12964 if (typeof getDerivedStateFromProps === 'function') {
12965 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
12966 newState = workInProgress.memoizedState;
12967 }
12968
12969 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
12970
12971 if (shouldUpdate) {
12972 // In order to support react-lifecycles-compat polyfilled components,
12973 // Unsafe lifecycles should not be invoked for components using the new APIs.
12974 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
12975 if (typeof instance.componentWillMount === 'function') {
12976 instance.componentWillMount();
12977 }
12978
12979 if (typeof instance.UNSAFE_componentWillMount === 'function') {
12980 instance.UNSAFE_componentWillMount();
12981 }
12982 }
12983
12984 if (typeof instance.componentDidMount === 'function') {
12985 workInProgress.flags |= Update;
12986 }
12987 } else {
12988 // If an update was already in progress, we should schedule an Update
12989 // effect even though we're bailing out, so that cWU/cDU are called.
12990 if (typeof instance.componentDidMount === 'function') {
12991 workInProgress.flags |= Update;
12992 } // If shouldComponentUpdate returned false, we should still update the
12993 // memoized state to indicate that this work can be reused.
12994
12995
12996 workInProgress.memoizedProps = newProps;
12997 workInProgress.memoizedState = newState;
12998 } // Update the existing instance's state, props, and context pointers even
12999 // if shouldComponentUpdate returns false.
13000
13001
13002 instance.props = newProps;
13003 instance.state = newState;
13004 instance.context = nextContext;
13005 return shouldUpdate;
13006 } // Invokes the update life-cycles and returns false if it shouldn't rerender.
13007
13008
13009 function updateClassInstance(current, workInProgress, ctor, newProps, renderLanes) {
13010 var instance = workInProgress.stateNode;
13011 cloneUpdateQueue(current, workInProgress);
13012 var unresolvedOldProps = workInProgress.memoizedProps;
13013 var oldProps = workInProgress.type === workInProgress.elementType ? unresolvedOldProps : resolveDefaultProps(workInProgress.type, unresolvedOldProps);
13014 instance.props = oldProps;
13015 var unresolvedNewProps = workInProgress.pendingProps;
13016 var oldContext = instance.context;
13017 var contextType = ctor.contextType;
13018 var nextContext = emptyContextObject;
13019
13020 if (typeof contextType === 'object' && contextType !== null) {
13021 nextContext = readContext(contextType);
13022 } else {
13023 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13024 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
13025 }
13026
13027 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13028 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
13029 // ever the previously attempted to render - not the "current". However,
13030 // during componentDidUpdate we pass the "current" props.
13031 // In order to support react-lifecycles-compat polyfilled components,
13032 // Unsafe lifecycles should not be invoked for components using the new APIs.
13033
13034 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
13035 if (unresolvedOldProps !== unresolvedNewProps || oldContext !== nextContext) {
13036 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
13037 }
13038 }
13039
13040 resetHasForceUpdateBeforeProcessing();
13041 var oldState = workInProgress.memoizedState;
13042 var newState = instance.state = oldState;
13043 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
13044 newState = workInProgress.memoizedState;
13045
13046 if (unresolvedOldProps === unresolvedNewProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
13047 // If an update was already in progress, we should schedule an Update
13048 // effect even though we're bailing out, so that cWU/cDU are called.
13049 if (typeof instance.componentDidUpdate === 'function') {
13050 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13051 workInProgress.flags |= Update;
13052 }
13053 }
13054
13055 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13056 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13057 workInProgress.flags |= Snapshot;
13058 }
13059 }
13060
13061 return false;
13062 }
13063
13064 if (typeof getDerivedStateFromProps === 'function') {
13065 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13066 newState = workInProgress.memoizedState;
13067 }
13068
13069 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
13070
13071 if (shouldUpdate) {
13072 // In order to support react-lifecycles-compat polyfilled components,
13073 // Unsafe lifecycles should not be invoked for components using the new APIs.
13074 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
13075 if (typeof instance.componentWillUpdate === 'function') {
13076 instance.componentWillUpdate(newProps, newState, nextContext);
13077 }
13078
13079 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
13080 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
13081 }
13082 }
13083
13084 if (typeof instance.componentDidUpdate === 'function') {
13085 workInProgress.flags |= Update;
13086 }
13087
13088 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13089 workInProgress.flags |= Snapshot;
13090 }
13091 } else {
13092 // If an update was already in progress, we should schedule an Update
13093 // effect even though we're bailing out, so that cWU/cDU are called.
13094 if (typeof instance.componentDidUpdate === 'function') {
13095 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13096 workInProgress.flags |= Update;
13097 }
13098 }
13099
13100 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13101 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13102 workInProgress.flags |= Snapshot;
13103 }
13104 } // If shouldComponentUpdate returned false, we should still update the
13105 // memoized props/state to indicate that this work can be reused.
13106
13107
13108 workInProgress.memoizedProps = newProps;
13109 workInProgress.memoizedState = newState;
13110 } // Update the existing instance's state, props, and context pointers even
13111 // if shouldComponentUpdate returns false.
13112
13113
13114 instance.props = newProps;
13115 instance.state = newState;
13116 instance.context = nextContext;
13117 return shouldUpdate;
13118 }
13119
13120 var didWarnAboutMaps;
13121 var didWarnAboutGenerators;
13122 var didWarnAboutStringRefs;
13123 var ownerHasKeyUseWarning;
13124 var ownerHasFunctionTypeWarning;
13125
13126 var warnForMissingKey = function (child, returnFiber) {};
13127
13128 {
13129 didWarnAboutMaps = false;
13130 didWarnAboutGenerators = false;
13131 didWarnAboutStringRefs = {};
13132 /**
13133 * Warn if there's no key explicitly set on dynamic arrays of children or
13134 * object keys are not valid. This allows us to keep track of children between
13135 * updates.
13136 */
13137
13138 ownerHasKeyUseWarning = {};
13139 ownerHasFunctionTypeWarning = {};
13140
13141 warnForMissingKey = function (child, returnFiber) {
13142 if (child === null || typeof child !== 'object') {
13143 return;
13144 }
13145
13146 if (!child._store || child._store.validated || child.key != null) {
13147 return;
13148 }
13149
13150 if (!(typeof child._store === 'object')) {
13151 {
13152 throw Error( "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." );
13153 }
13154 }
13155
13156 child._store.validated = true;
13157 var componentName = getComponentName(returnFiber.type) || 'Component';
13158
13159 if (ownerHasKeyUseWarning[componentName]) {
13160 return;
13161 }
13162
13163 ownerHasKeyUseWarning[componentName] = true;
13164
13165 error('Each child in a list should have a unique ' + '"key" prop. See https://reactjs.org/link/warning-keys for ' + 'more information.');
13166 };
13167 }
13168
13169 var isArray$1 = Array.isArray;
13170
13171 function coerceRef(returnFiber, current, element) {
13172 var mixedRef = element.ref;
13173
13174 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
13175 {
13176 // TODO: Clean this up once we turn on the string ref warning for
13177 // everyone, because the strict mode case will no longer be relevant
13178 if ((returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs
13179 // because these cannot be automatically converted to an arrow function
13180 // using a codemod. Therefore, we don't have to warn about string refs again.
13181 !(element._owner && element._self && element._owner.stateNode !== element._self)) {
13182 var componentName = getComponentName(returnFiber.type) || 'Component';
13183
13184 if (!didWarnAboutStringRefs[componentName]) {
13185 {
13186 error('A string ref, "%s", has been found within a strict mode tree. ' + 'String refs are a source of potential bugs and should be avoided. ' + 'We recommend using useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://reactjs.org/link/strict-mode-string-ref', mixedRef);
13187 }
13188
13189 didWarnAboutStringRefs[componentName] = true;
13190 }
13191 }
13192 }
13193
13194 if (element._owner) {
13195 var owner = element._owner;
13196 var inst;
13197
13198 if (owner) {
13199 var ownerFiber = owner;
13200
13201 if (!(ownerFiber.tag === ClassComponent)) {
13202 {
13203 throw 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" );
13204 }
13205 }
13206
13207 inst = ownerFiber.stateNode;
13208 }
13209
13210 if (!inst) {
13211 {
13212 throw Error( "Missing owner for string ref " + mixedRef + ". This error is likely caused by a bug in React. Please file an issue." );
13213 }
13214 }
13215
13216 var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref
13217
13218 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
13219 return current.ref;
13220 }
13221
13222 var ref = function (value) {
13223 var refs = inst.refs;
13224
13225 if (refs === emptyRefsObject) {
13226 // This is a lazy pooled frozen object, so we need to initialize.
13227 refs = inst.refs = {};
13228 }
13229
13230 if (value === null) {
13231 delete refs[stringRef];
13232 } else {
13233 refs[stringRef] = value;
13234 }
13235 };
13236
13237 ref._stringRef = stringRef;
13238 return ref;
13239 } else {
13240 if (!(typeof mixedRef === 'string')) {
13241 {
13242 throw Error( "Expected ref to be a function, a string, an object returned by React.createRef(), or null." );
13243 }
13244 }
13245
13246 if (!element._owner) {
13247 {
13248 throw Error( "Element ref was specified as a string (" + mixedRef + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://reactjs.org/link/refs-must-have-owner for more information." );
13249 }
13250 }
13251 }
13252 }
13253
13254 return mixedRef;
13255 }
13256
13257 function throwOnInvalidObjectType(returnFiber, newChild) {
13258 if (returnFiber.type !== 'textarea') {
13259 {
13260 {
13261 throw Error( "Objects are not valid as a React child (found: " + (Object.prototype.toString.call(newChild) === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : newChild) + "). If you meant to render a collection of children, use an array instead." );
13262 }
13263 }
13264 }
13265 }
13266
13267 function warnOnFunctionType(returnFiber) {
13268 {
13269 var componentName = getComponentName(returnFiber.type) || 'Component';
13270
13271 if (ownerHasFunctionTypeWarning[componentName]) {
13272 return;
13273 }
13274
13275 ownerHasFunctionTypeWarning[componentName] = true;
13276
13277 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.');
13278 }
13279 } // We avoid inlining this to avoid potential deopts from using try/catch.
13280 // to be able to optimize each path individually by branching early. This needs
13281 // a compiler or we can do it manually. Helpers that don't need this branching
13282 // live outside of this function.
13283
13284
13285 function ChildReconciler(shouldTrackSideEffects) {
13286 function deleteChild(returnFiber, childToDelete) {
13287 if (!shouldTrackSideEffects) {
13288 // Noop.
13289 return;
13290 } // Deletions are added in reversed order so we add it to the front.
13291 // At this point, the return fiber's effect list is empty except for
13292 // deletions, so we can just append the deletion to the list. The remaining
13293 // effects aren't added until the complete phase. Once we implement
13294 // resuming, this may not be true.
13295
13296
13297 var last = returnFiber.lastEffect;
13298
13299 if (last !== null) {
13300 last.nextEffect = childToDelete;
13301 returnFiber.lastEffect = childToDelete;
13302 } else {
13303 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
13304 }
13305
13306 childToDelete.nextEffect = null;
13307 childToDelete.flags = Deletion;
13308 }
13309
13310 function deleteRemainingChildren(returnFiber, currentFirstChild) {
13311 if (!shouldTrackSideEffects) {
13312 // Noop.
13313 return null;
13314 } // TODO: For the shouldClone case, this could be micro-optimized a bit by
13315 // assuming that after the first child we've already added everything.
13316
13317
13318 var childToDelete = currentFirstChild;
13319
13320 while (childToDelete !== null) {
13321 deleteChild(returnFiber, childToDelete);
13322 childToDelete = childToDelete.sibling;
13323 }
13324
13325 return null;
13326 }
13327
13328 function mapRemainingChildren(returnFiber, currentFirstChild) {
13329 // Add the remaining children to a temporary map so that we can find them by
13330 // keys quickly. Implicit (null) keys get added to this set with their index
13331 // instead.
13332 var existingChildren = new Map();
13333 var existingChild = currentFirstChild;
13334
13335 while (existingChild !== null) {
13336 if (existingChild.key !== null) {
13337 existingChildren.set(existingChild.key, existingChild);
13338 } else {
13339 existingChildren.set(existingChild.index, existingChild);
13340 }
13341
13342 existingChild = existingChild.sibling;
13343 }
13344
13345 return existingChildren;
13346 }
13347
13348 function useFiber(fiber, pendingProps) {
13349 // We currently set sibling to null and index to 0 here because it is easy
13350 // to forget to do before returning it. E.g. for the single child case.
13351 var clone = createWorkInProgress(fiber, pendingProps);
13352 clone.index = 0;
13353 clone.sibling = null;
13354 return clone;
13355 }
13356
13357 function placeChild(newFiber, lastPlacedIndex, newIndex) {
13358 newFiber.index = newIndex;
13359
13360 if (!shouldTrackSideEffects) {
13361 // Noop.
13362 return lastPlacedIndex;
13363 }
13364
13365 var current = newFiber.alternate;
13366
13367 if (current !== null) {
13368 var oldIndex = current.index;
13369
13370 if (oldIndex < lastPlacedIndex) {
13371 // This is a move.
13372 newFiber.flags = Placement;
13373 return lastPlacedIndex;
13374 } else {
13375 // This item can stay in place.
13376 return oldIndex;
13377 }
13378 } else {
13379 // This is an insertion.
13380 newFiber.flags = Placement;
13381 return lastPlacedIndex;
13382 }
13383 }
13384
13385 function placeSingleChild(newFiber) {
13386 // This is simpler for the single child case. We only need to do a
13387 // placement for inserting new children.
13388 if (shouldTrackSideEffects && newFiber.alternate === null) {
13389 newFiber.flags = Placement;
13390 }
13391
13392 return newFiber;
13393 }
13394
13395 function updateTextNode(returnFiber, current, textContent, lanes) {
13396 if (current === null || current.tag !== HostText) {
13397 // Insert
13398 var created = createFiberFromText(textContent, returnFiber.mode, lanes);
13399 created.return = returnFiber;
13400 return created;
13401 } else {
13402 // Update
13403 var existing = useFiber(current, textContent);
13404 existing.return = returnFiber;
13405 return existing;
13406 }
13407 }
13408
13409 function updateElement(returnFiber, current, element, lanes) {
13410 if (current !== null) {
13411 if (current.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
13412 isCompatibleFamilyForHotReloading(current, element) )) {
13413 // Move based on index
13414 var existing = useFiber(current, element.props);
13415 existing.ref = coerceRef(returnFiber, current, element);
13416 existing.return = returnFiber;
13417
13418 {
13419 existing._debugSource = element._source;
13420 existing._debugOwner = element._owner;
13421 }
13422
13423 return existing;
13424 }
13425 } // Insert
13426
13427
13428 var created = createFiberFromElement(element, returnFiber.mode, lanes);
13429 created.ref = coerceRef(returnFiber, current, element);
13430 created.return = returnFiber;
13431 return created;
13432 }
13433
13434 function updatePortal(returnFiber, current, portal, lanes) {
13435 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
13436 // Insert
13437 var created = createFiberFromPortal(portal, returnFiber.mode, lanes);
13438 created.return = returnFiber;
13439 return created;
13440 } else {
13441 // Update
13442 var existing = useFiber(current, portal.children || []);
13443 existing.return = returnFiber;
13444 return existing;
13445 }
13446 }
13447
13448 function updateFragment(returnFiber, current, fragment, lanes, key) {
13449 if (current === null || current.tag !== Fragment) {
13450 // Insert
13451 var created = createFiberFromFragment(fragment, returnFiber.mode, lanes, key);
13452 created.return = returnFiber;
13453 return created;
13454 } else {
13455 // Update
13456 var existing = useFiber(current, fragment);
13457 existing.return = returnFiber;
13458 return existing;
13459 }
13460 }
13461
13462 function createChild(returnFiber, newChild, lanes) {
13463 if (typeof newChild === 'string' || typeof newChild === 'number') {
13464 // Text nodes don't have keys. If the previous node is implicitly keyed
13465 // we can continue to replace it without aborting even if it is not a text
13466 // node.
13467 var created = createFiberFromText('' + newChild, returnFiber.mode, lanes);
13468 created.return = returnFiber;
13469 return created;
13470 }
13471
13472 if (typeof newChild === 'object' && newChild !== null) {
13473 switch (newChild.$$typeof) {
13474 case REACT_ELEMENT_TYPE:
13475 {
13476 var _created = createFiberFromElement(newChild, returnFiber.mode, lanes);
13477
13478 _created.ref = coerceRef(returnFiber, null, newChild);
13479 _created.return = returnFiber;
13480 return _created;
13481 }
13482
13483 case REACT_PORTAL_TYPE:
13484 {
13485 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, lanes);
13486
13487 _created2.return = returnFiber;
13488 return _created2;
13489 }
13490 }
13491
13492 if (isArray$1(newChild) || getIteratorFn(newChild)) {
13493 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, lanes, null);
13494
13495 _created3.return = returnFiber;
13496 return _created3;
13497 }
13498
13499 throwOnInvalidObjectType(returnFiber, newChild);
13500 }
13501
13502 {
13503 if (typeof newChild === 'function') {
13504 warnOnFunctionType(returnFiber);
13505 }
13506 }
13507
13508 return null;
13509 }
13510
13511 function updateSlot(returnFiber, oldFiber, newChild, lanes) {
13512 // Update the fiber if the keys match, otherwise return null.
13513 var key = oldFiber !== null ? oldFiber.key : null;
13514
13515 if (typeof newChild === 'string' || typeof newChild === 'number') {
13516 // Text nodes don't have keys. If the previous node is implicitly keyed
13517 // we can continue to replace it without aborting even if it is not a text
13518 // node.
13519 if (key !== null) {
13520 return null;
13521 }
13522
13523 return updateTextNode(returnFiber, oldFiber, '' + newChild, lanes);
13524 }
13525
13526 if (typeof newChild === 'object' && newChild !== null) {
13527 switch (newChild.$$typeof) {
13528 case REACT_ELEMENT_TYPE:
13529 {
13530 if (newChild.key === key) {
13531 if (newChild.type === REACT_FRAGMENT_TYPE) {
13532 return updateFragment(returnFiber, oldFiber, newChild.props.children, lanes, key);
13533 }
13534
13535 return updateElement(returnFiber, oldFiber, newChild, lanes);
13536 } else {
13537 return null;
13538 }
13539 }
13540
13541 case REACT_PORTAL_TYPE:
13542 {
13543 if (newChild.key === key) {
13544 return updatePortal(returnFiber, oldFiber, newChild, lanes);
13545 } else {
13546 return null;
13547 }
13548 }
13549 }
13550
13551 if (isArray$1(newChild) || getIteratorFn(newChild)) {
13552 if (key !== null) {
13553 return null;
13554 }
13555
13556 return updateFragment(returnFiber, oldFiber, newChild, lanes, null);
13557 }
13558
13559 throwOnInvalidObjectType(returnFiber, newChild);
13560 }
13561
13562 {
13563 if (typeof newChild === 'function') {
13564 warnOnFunctionType(returnFiber);
13565 }
13566 }
13567
13568 return null;
13569 }
13570
13571 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, lanes) {
13572 if (typeof newChild === 'string' || typeof newChild === 'number') {
13573 // Text nodes don't have keys, so we neither have to check the old nor
13574 // new node for the key. If both are text nodes, they match.
13575 var matchedFiber = existingChildren.get(newIdx) || null;
13576 return updateTextNode(returnFiber, matchedFiber, '' + newChild, lanes);
13577 }
13578
13579 if (typeof newChild === 'object' && newChild !== null) {
13580 switch (newChild.$$typeof) {
13581 case REACT_ELEMENT_TYPE:
13582 {
13583 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
13584
13585 if (newChild.type === REACT_FRAGMENT_TYPE) {
13586 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, lanes, newChild.key);
13587 }
13588
13589 return updateElement(returnFiber, _matchedFiber, newChild, lanes);
13590 }
13591
13592 case REACT_PORTAL_TYPE:
13593 {
13594 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
13595
13596 return updatePortal(returnFiber, _matchedFiber2, newChild, lanes);
13597 }
13598
13599 }
13600
13601 if (isArray$1(newChild) || getIteratorFn(newChild)) {
13602 var _matchedFiber3 = existingChildren.get(newIdx) || null;
13603
13604 return updateFragment(returnFiber, _matchedFiber3, newChild, lanes, null);
13605 }
13606
13607 throwOnInvalidObjectType(returnFiber, newChild);
13608 }
13609
13610 {
13611 if (typeof newChild === 'function') {
13612 warnOnFunctionType(returnFiber);
13613 }
13614 }
13615
13616 return null;
13617 }
13618 /**
13619 * Warns if there is a duplicate or missing key
13620 */
13621
13622
13623 function warnOnInvalidKey(child, knownKeys, returnFiber) {
13624 {
13625 if (typeof child !== 'object' || child === null) {
13626 return knownKeys;
13627 }
13628
13629 switch (child.$$typeof) {
13630 case REACT_ELEMENT_TYPE:
13631 case REACT_PORTAL_TYPE:
13632 warnForMissingKey(child, returnFiber);
13633 var key = child.key;
13634
13635 if (typeof key !== 'string') {
13636 break;
13637 }
13638
13639 if (knownKeys === null) {
13640 knownKeys = new Set();
13641 knownKeys.add(key);
13642 break;
13643 }
13644
13645 if (!knownKeys.has(key)) {
13646 knownKeys.add(key);
13647 break;
13648 }
13649
13650 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);
13651
13652 break;
13653 }
13654 }
13655
13656 return knownKeys;
13657 }
13658
13659 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, lanes) {
13660 // This algorithm can't optimize by searching from both ends since we
13661 // don't have backpointers on fibers. I'm trying to see how far we can get
13662 // with that model. If it ends up not being worth the tradeoffs, we can
13663 // add it later.
13664 // Even with a two ended optimization, we'd want to optimize for the case
13665 // where there are few changes and brute force the comparison instead of
13666 // going for the Map. It'd like to explore hitting that path first in
13667 // forward-only mode and only go for the Map once we notice that we need
13668 // lots of look ahead. This doesn't handle reversal as well as two ended
13669 // search but that's unusual. Besides, for the two ended optimization to
13670 // work on Iterables, we'd need to copy the whole set.
13671 // In this first iteration, we'll just live with hitting the bad case
13672 // (adding everything to a Map) in for every insert/move.
13673 // If you change this code, also update reconcileChildrenIterator() which
13674 // uses the same algorithm.
13675 {
13676 // First, validate keys.
13677 var knownKeys = null;
13678
13679 for (var i = 0; i < newChildren.length; i++) {
13680 var child = newChildren[i];
13681 knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber);
13682 }
13683 }
13684
13685 var resultingFirstChild = null;
13686 var previousNewFiber = null;
13687 var oldFiber = currentFirstChild;
13688 var lastPlacedIndex = 0;
13689 var newIdx = 0;
13690 var nextOldFiber = null;
13691
13692 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
13693 if (oldFiber.index > newIdx) {
13694 nextOldFiber = oldFiber;
13695 oldFiber = null;
13696 } else {
13697 nextOldFiber = oldFiber.sibling;
13698 }
13699
13700 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], lanes);
13701
13702 if (newFiber === null) {
13703 // TODO: This breaks on empty slots like null children. That's
13704 // unfortunate because it triggers the slow path all the time. We need
13705 // a better way to communicate whether this was a miss or null,
13706 // boolean, undefined, etc.
13707 if (oldFiber === null) {
13708 oldFiber = nextOldFiber;
13709 }
13710
13711 break;
13712 }
13713
13714 if (shouldTrackSideEffects) {
13715 if (oldFiber && newFiber.alternate === null) {
13716 // We matched the slot, but we didn't reuse the existing fiber, so we
13717 // need to delete the existing child.
13718 deleteChild(returnFiber, oldFiber);
13719 }
13720 }
13721
13722 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
13723
13724 if (previousNewFiber === null) {
13725 // TODO: Move out of the loop. This only happens for the first run.
13726 resultingFirstChild = newFiber;
13727 } else {
13728 // TODO: Defer siblings if we're not at the right index for this slot.
13729 // I.e. if we had null values before, then we want to defer this
13730 // for each null value. However, we also don't want to call updateSlot
13731 // with the previous one.
13732 previousNewFiber.sibling = newFiber;
13733 }
13734
13735 previousNewFiber = newFiber;
13736 oldFiber = nextOldFiber;
13737 }
13738
13739 if (newIdx === newChildren.length) {
13740 // We've reached the end of the new children. We can delete the rest.
13741 deleteRemainingChildren(returnFiber, oldFiber);
13742 return resultingFirstChild;
13743 }
13744
13745 if (oldFiber === null) {
13746 // If we don't have any more existing children we can choose a fast path
13747 // since the rest will all be insertions.
13748 for (; newIdx < newChildren.length; newIdx++) {
13749 var _newFiber = createChild(returnFiber, newChildren[newIdx], lanes);
13750
13751 if (_newFiber === null) {
13752 continue;
13753 }
13754
13755 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
13756
13757 if (previousNewFiber === null) {
13758 // TODO: Move out of the loop. This only happens for the first run.
13759 resultingFirstChild = _newFiber;
13760 } else {
13761 previousNewFiber.sibling = _newFiber;
13762 }
13763
13764 previousNewFiber = _newFiber;
13765 }
13766
13767 return resultingFirstChild;
13768 } // Add all children to a key map for quick lookups.
13769
13770
13771 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
13772
13773 for (; newIdx < newChildren.length; newIdx++) {
13774 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], lanes);
13775
13776 if (_newFiber2 !== null) {
13777 if (shouldTrackSideEffects) {
13778 if (_newFiber2.alternate !== null) {
13779 // The new fiber is a work in progress, but if there exists a
13780 // current, that means that we reused the fiber. We need to delete
13781 // it from the child list so that we don't add it to the deletion
13782 // list.
13783 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
13784 }
13785 }
13786
13787 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
13788
13789 if (previousNewFiber === null) {
13790 resultingFirstChild = _newFiber2;
13791 } else {
13792 previousNewFiber.sibling = _newFiber2;
13793 }
13794
13795 previousNewFiber = _newFiber2;
13796 }
13797 }
13798
13799 if (shouldTrackSideEffects) {
13800 // Any existing children that weren't consumed above were deleted. We need
13801 // to add them to the deletion list.
13802 existingChildren.forEach(function (child) {
13803 return deleteChild(returnFiber, child);
13804 });
13805 }
13806
13807 return resultingFirstChild;
13808 }
13809
13810 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, lanes) {
13811 // This is the same implementation as reconcileChildrenArray(),
13812 // but using the iterator instead.
13813 var iteratorFn = getIteratorFn(newChildrenIterable);
13814
13815 if (!(typeof iteratorFn === 'function')) {
13816 {
13817 throw Error( "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." );
13818 }
13819 }
13820
13821 {
13822 // We don't support rendering Generators because it's a mutation.
13823 // See https://github.com/facebook/react/issues/12995
13824 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag
13825 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
13826 if (!didWarnAboutGenerators) {
13827 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.');
13828 }
13829
13830 didWarnAboutGenerators = true;
13831 } // Warn about using Maps as children
13832
13833
13834 if (newChildrenIterable.entries === iteratorFn) {
13835 if (!didWarnAboutMaps) {
13836 error('Using Maps as children is not supported. ' + 'Use an array of keyed ReactElements instead.');
13837 }
13838
13839 didWarnAboutMaps = true;
13840 } // First, validate keys.
13841 // We'll get a different iterator later for the main pass.
13842
13843
13844 var _newChildren = iteratorFn.call(newChildrenIterable);
13845
13846 if (_newChildren) {
13847 var knownKeys = null;
13848
13849 var _step = _newChildren.next();
13850
13851 for (; !_step.done; _step = _newChildren.next()) {
13852 var child = _step.value;
13853 knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber);
13854 }
13855 }
13856 }
13857
13858 var newChildren = iteratorFn.call(newChildrenIterable);
13859
13860 if (!(newChildren != null)) {
13861 {
13862 throw Error( "An iterable object provided no iterator." );
13863 }
13864 }
13865
13866 var resultingFirstChild = null;
13867 var previousNewFiber = null;
13868 var oldFiber = currentFirstChild;
13869 var lastPlacedIndex = 0;
13870 var newIdx = 0;
13871 var nextOldFiber = null;
13872 var step = newChildren.next();
13873
13874 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
13875 if (oldFiber.index > newIdx) {
13876 nextOldFiber = oldFiber;
13877 oldFiber = null;
13878 } else {
13879 nextOldFiber = oldFiber.sibling;
13880 }
13881
13882 var newFiber = updateSlot(returnFiber, oldFiber, step.value, lanes);
13883
13884 if (newFiber === null) {
13885 // TODO: This breaks on empty slots like null children. That's
13886 // unfortunate because it triggers the slow path all the time. We need
13887 // a better way to communicate whether this was a miss or null,
13888 // boolean, undefined, etc.
13889 if (oldFiber === null) {
13890 oldFiber = nextOldFiber;
13891 }
13892
13893 break;
13894 }
13895
13896 if (shouldTrackSideEffects) {
13897 if (oldFiber && newFiber.alternate === null) {
13898 // We matched the slot, but we didn't reuse the existing fiber, so we
13899 // need to delete the existing child.
13900 deleteChild(returnFiber, oldFiber);
13901 }
13902 }
13903
13904 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
13905
13906 if (previousNewFiber === null) {
13907 // TODO: Move out of the loop. This only happens for the first run.
13908 resultingFirstChild = newFiber;
13909 } else {
13910 // TODO: Defer siblings if we're not at the right index for this slot.
13911 // I.e. if we had null values before, then we want to defer this
13912 // for each null value. However, we also don't want to call updateSlot
13913 // with the previous one.
13914 previousNewFiber.sibling = newFiber;
13915 }
13916
13917 previousNewFiber = newFiber;
13918 oldFiber = nextOldFiber;
13919 }
13920
13921 if (step.done) {
13922 // We've reached the end of the new children. We can delete the rest.
13923 deleteRemainingChildren(returnFiber, oldFiber);
13924 return resultingFirstChild;
13925 }
13926
13927 if (oldFiber === null) {
13928 // If we don't have any more existing children we can choose a fast path
13929 // since the rest will all be insertions.
13930 for (; !step.done; newIdx++, step = newChildren.next()) {
13931 var _newFiber3 = createChild(returnFiber, step.value, lanes);
13932
13933 if (_newFiber3 === null) {
13934 continue;
13935 }
13936
13937 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
13938
13939 if (previousNewFiber === null) {
13940 // TODO: Move out of the loop. This only happens for the first run.
13941 resultingFirstChild = _newFiber3;
13942 } else {
13943 previousNewFiber.sibling = _newFiber3;
13944 }
13945
13946 previousNewFiber = _newFiber3;
13947 }
13948
13949 return resultingFirstChild;
13950 } // Add all children to a key map for quick lookups.
13951
13952
13953 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
13954
13955 for (; !step.done; newIdx++, step = newChildren.next()) {
13956 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, lanes);
13957
13958 if (_newFiber4 !== null) {
13959 if (shouldTrackSideEffects) {
13960 if (_newFiber4.alternate !== null) {
13961 // The new fiber is a work in progress, but if there exists a
13962 // current, that means that we reused the fiber. We need to delete
13963 // it from the child list so that we don't add it to the deletion
13964 // list.
13965 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
13966 }
13967 }
13968
13969 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
13970
13971 if (previousNewFiber === null) {
13972 resultingFirstChild = _newFiber4;
13973 } else {
13974 previousNewFiber.sibling = _newFiber4;
13975 }
13976
13977 previousNewFiber = _newFiber4;
13978 }
13979 }
13980
13981 if (shouldTrackSideEffects) {
13982 // Any existing children that weren't consumed above were deleted. We need
13983 // to add them to the deletion list.
13984 existingChildren.forEach(function (child) {
13985 return deleteChild(returnFiber, child);
13986 });
13987 }
13988
13989 return resultingFirstChild;
13990 }
13991
13992 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, lanes) {
13993 // There's no need to check for keys on text nodes since we don't have a
13994 // way to define them.
13995 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
13996 // We already have an existing node so let's just update it and delete
13997 // the rest.
13998 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
13999 var existing = useFiber(currentFirstChild, textContent);
14000 existing.return = returnFiber;
14001 return existing;
14002 } // The existing first child is not a text node so we need to create one
14003 // and delete the existing ones.
14004
14005
14006 deleteRemainingChildren(returnFiber, currentFirstChild);
14007 var created = createFiberFromText(textContent, returnFiber.mode, lanes);
14008 created.return = returnFiber;
14009 return created;
14010 }
14011
14012 function reconcileSingleElement(returnFiber, currentFirstChild, element, lanes) {
14013 var key = element.key;
14014 var child = currentFirstChild;
14015
14016 while (child !== null) {
14017 // TODO: If key === null and child.key === null, then this only applies to
14018 // the first item in the list.
14019 if (child.key === key) {
14020 switch (child.tag) {
14021 case Fragment:
14022 {
14023 if (element.type === REACT_FRAGMENT_TYPE) {
14024 deleteRemainingChildren(returnFiber, child.sibling);
14025 var existing = useFiber(child, element.props.children);
14026 existing.return = returnFiber;
14027
14028 {
14029 existing._debugSource = element._source;
14030 existing._debugOwner = element._owner;
14031 }
14032
14033 return existing;
14034 }
14035
14036 break;
14037 }
14038
14039 case Block:
14040
14041 // We intentionally fallthrough here if enableBlocksAPI is not on.
14042 // eslint-disable-next-lined no-fallthrough
14043
14044 default:
14045 {
14046 if (child.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
14047 isCompatibleFamilyForHotReloading(child, element) )) {
14048 deleteRemainingChildren(returnFiber, child.sibling);
14049
14050 var _existing3 = useFiber(child, element.props);
14051
14052 _existing3.ref = coerceRef(returnFiber, child, element);
14053 _existing3.return = returnFiber;
14054
14055 {
14056 _existing3._debugSource = element._source;
14057 _existing3._debugOwner = element._owner;
14058 }
14059
14060 return _existing3;
14061 }
14062
14063 break;
14064 }
14065 } // Didn't match.
14066
14067
14068 deleteRemainingChildren(returnFiber, child);
14069 break;
14070 } else {
14071 deleteChild(returnFiber, child);
14072 }
14073
14074 child = child.sibling;
14075 }
14076
14077 if (element.type === REACT_FRAGMENT_TYPE) {
14078 var created = createFiberFromFragment(element.props.children, returnFiber.mode, lanes, element.key);
14079 created.return = returnFiber;
14080 return created;
14081 } else {
14082 var _created4 = createFiberFromElement(element, returnFiber.mode, lanes);
14083
14084 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
14085 _created4.return = returnFiber;
14086 return _created4;
14087 }
14088 }
14089
14090 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, lanes) {
14091 var key = portal.key;
14092 var child = currentFirstChild;
14093
14094 while (child !== null) {
14095 // TODO: If key === null and child.key === null, then this only applies to
14096 // the first item in the list.
14097 if (child.key === key) {
14098 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
14099 deleteRemainingChildren(returnFiber, child.sibling);
14100 var existing = useFiber(child, portal.children || []);
14101 existing.return = returnFiber;
14102 return existing;
14103 } else {
14104 deleteRemainingChildren(returnFiber, child);
14105 break;
14106 }
14107 } else {
14108 deleteChild(returnFiber, child);
14109 }
14110
14111 child = child.sibling;
14112 }
14113
14114 var created = createFiberFromPortal(portal, returnFiber.mode, lanes);
14115 created.return = returnFiber;
14116 return created;
14117 } // This API will tag the children with the side-effect of the reconciliation
14118 // itself. They will be added to the side-effect list as we pass through the
14119 // children and the parent.
14120
14121
14122 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, lanes) {
14123 // This function is not recursive.
14124 // If the top level item is an array, we treat it as a set of children,
14125 // not as a fragment. Nested arrays on the other hand will be treated as
14126 // fragment nodes. Recursion happens at the normal flow.
14127 // Handle top level unkeyed fragments as if they were arrays.
14128 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
14129 // We treat the ambiguous cases above the same.
14130 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
14131
14132 if (isUnkeyedTopLevelFragment) {
14133 newChild = newChild.props.children;
14134 } // Handle object types
14135
14136
14137 var isObject = typeof newChild === 'object' && newChild !== null;
14138
14139 if (isObject) {
14140 switch (newChild.$$typeof) {
14141 case REACT_ELEMENT_TYPE:
14142 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, lanes));
14143
14144 case REACT_PORTAL_TYPE:
14145 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, lanes));
14146
14147 }
14148 }
14149
14150 if (typeof newChild === 'string' || typeof newChild === 'number') {
14151 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, lanes));
14152 }
14153
14154 if (isArray$1(newChild)) {
14155 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, lanes);
14156 }
14157
14158 if (getIteratorFn(newChild)) {
14159 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, lanes);
14160 }
14161
14162 if (isObject) {
14163 throwOnInvalidObjectType(returnFiber, newChild);
14164 }
14165
14166 {
14167 if (typeof newChild === 'function') {
14168 warnOnFunctionType(returnFiber);
14169 }
14170 }
14171
14172 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
14173 // If the new child is undefined, and the return fiber is a composite
14174 // component, throw an error. If Fiber return types are disabled,
14175 // we already threw above.
14176 switch (returnFiber.tag) {
14177 case ClassComponent:
14178 {
14179 {
14180 var instance = returnFiber.stateNode;
14181
14182 if (instance.render._isMockFunction) {
14183 // We allow auto-mocks to proceed as if they're returning null.
14184 break;
14185 }
14186 }
14187 }
14188 // Intentionally fall through to the next case, which handles both
14189 // functions and classes
14190 // eslint-disable-next-lined no-fallthrough
14191
14192 case Block:
14193 case FunctionComponent:
14194 case ForwardRef:
14195 case SimpleMemoComponent:
14196 {
14197 {
14198 {
14199 throw Error( (getComponentName(returnFiber.type) || 'Component') + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." );
14200 }
14201 }
14202 }
14203 }
14204 } // Remaining cases are all treated as empty.
14205
14206
14207 return deleteRemainingChildren(returnFiber, currentFirstChild);
14208 }
14209
14210 return reconcileChildFibers;
14211 }
14212
14213 var reconcileChildFibers = ChildReconciler(true);
14214 var mountChildFibers = ChildReconciler(false);
14215 function cloneChildFibers(current, workInProgress) {
14216 if (!(current === null || workInProgress.child === current.child)) {
14217 {
14218 throw Error( "Resuming work not yet implemented." );
14219 }
14220 }
14221
14222 if (workInProgress.child === null) {
14223 return;
14224 }
14225
14226 var currentChild = workInProgress.child;
14227 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps);
14228 workInProgress.child = newChild;
14229 newChild.return = workInProgress;
14230
14231 while (currentChild.sibling !== null) {
14232 currentChild = currentChild.sibling;
14233 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps);
14234 newChild.return = workInProgress;
14235 }
14236
14237 newChild.sibling = null;
14238 } // Reset a workInProgress child set to prepare it for a second pass.
14239
14240 function resetChildFibers(workInProgress, lanes) {
14241 var child = workInProgress.child;
14242
14243 while (child !== null) {
14244 resetWorkInProgress(child, lanes);
14245 child = child.sibling;
14246 }
14247 }
14248
14249 var NO_CONTEXT = {};
14250 var contextStackCursor$1 = createCursor(NO_CONTEXT);
14251 var contextFiberStackCursor = createCursor(NO_CONTEXT);
14252 var rootInstanceStackCursor = createCursor(NO_CONTEXT);
14253
14254 function requiredContext(c) {
14255 if (!(c !== NO_CONTEXT)) {
14256 {
14257 throw Error( "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." );
14258 }
14259 }
14260
14261 return c;
14262 }
14263
14264 function getRootHostContainer() {
14265 var rootInstance = requiredContext(rootInstanceStackCursor.current);
14266 return rootInstance;
14267 }
14268
14269 function pushHostContainer(fiber, nextRootInstance) {
14270 // Push current root instance onto the stack;
14271 // This allows us to reset root when portals are popped.
14272 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
14273 // This enables us to pop only Fibers that provide unique contexts.
14274
14275 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
14276 // However, we can't just call getRootHostContext() and push it because
14277 // we'd have a different number of entries on the stack depending on
14278 // whether getRootHostContext() throws somewhere in renderer code or not.
14279 // So we push an empty value first. This lets us safely unwind on errors.
14280
14281 push(contextStackCursor$1, NO_CONTEXT, fiber);
14282 var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it.
14283
14284 pop(contextStackCursor$1, fiber);
14285 push(contextStackCursor$1, nextRootContext, fiber);
14286 }
14287
14288 function popHostContainer(fiber) {
14289 pop(contextStackCursor$1, fiber);
14290 pop(contextFiberStackCursor, fiber);
14291 pop(rootInstanceStackCursor, fiber);
14292 }
14293
14294 function getHostContext() {
14295 var context = requiredContext(contextStackCursor$1.current);
14296 return context;
14297 }
14298
14299 function pushHostContext(fiber) {
14300 var rootInstance = requiredContext(rootInstanceStackCursor.current);
14301 var context = requiredContext(contextStackCursor$1.current);
14302 var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique.
14303
14304 if (context === nextContext) {
14305 return;
14306 } // Track the context and the Fiber that provided it.
14307 // This enables us to pop only Fibers that provide unique contexts.
14308
14309
14310 push(contextFiberStackCursor, fiber, fiber);
14311 push(contextStackCursor$1, nextContext, fiber);
14312 }
14313
14314 function popHostContext(fiber) {
14315 // Do not pop unless this Fiber provided the current context.
14316 // pushHostContext() only pushes Fibers that provide unique contexts.
14317 if (contextFiberStackCursor.current !== fiber) {
14318 return;
14319 }
14320
14321 pop(contextStackCursor$1, fiber);
14322 pop(contextFiberStackCursor, fiber);
14323 }
14324
14325 var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is
14326 // inherited deeply down the subtree. The upper bits only affect
14327 // this immediate suspense boundary and gets reset each new
14328 // boundary or suspense list.
14329
14330 var SubtreeSuspenseContextMask = 1; // Subtree Flags:
14331 // InvisibleParentSuspenseContext indicates that one of our parent Suspense
14332 // boundaries is not currently showing visible main content.
14333 // Either because it is already showing a fallback or is not mounted at all.
14334 // We can use this to determine if it is desirable to trigger a fallback at
14335 // the parent. If not, then we might need to trigger undesirable boundaries
14336 // and/or suspend the commit to avoid hiding the parent content.
14337
14338 var InvisibleParentSuspenseContext = 1; // Shallow Flags:
14339 // ForceSuspenseFallback can be used by SuspenseList to force newly added
14340 // items into their fallback state during one of the render passes.
14341
14342 var ForceSuspenseFallback = 2;
14343 var suspenseStackCursor = createCursor(DefaultSuspenseContext);
14344 function hasSuspenseContext(parentContext, flag) {
14345 return (parentContext & flag) !== 0;
14346 }
14347 function setDefaultShallowSuspenseContext(parentContext) {
14348 return parentContext & SubtreeSuspenseContextMask;
14349 }
14350 function setShallowSuspenseContext(parentContext, shallowContext) {
14351 return parentContext & SubtreeSuspenseContextMask | shallowContext;
14352 }
14353 function addSubtreeSuspenseContext(parentContext, subtreeContext) {
14354 return parentContext | subtreeContext;
14355 }
14356 function pushSuspenseContext(fiber, newContext) {
14357 push(suspenseStackCursor, newContext, fiber);
14358 }
14359 function popSuspenseContext(fiber) {
14360 pop(suspenseStackCursor, fiber);
14361 }
14362
14363 function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
14364 // If it was the primary children that just suspended, capture and render the
14365 // fallback. Otherwise, don't capture and bubble to the next boundary.
14366 var nextState = workInProgress.memoizedState;
14367
14368 if (nextState !== null) {
14369 if (nextState.dehydrated !== null) {
14370 // A dehydrated boundary always captures.
14371 return true;
14372 }
14373
14374 return false;
14375 }
14376
14377 var props = workInProgress.memoizedProps; // In order to capture, the Suspense component must have a fallback prop.
14378
14379 if (props.fallback === undefined) {
14380 return false;
14381 } // Regular boundaries always capture.
14382
14383
14384 if (props.unstable_avoidThisFallback !== true) {
14385 return true;
14386 } // If it's a boundary we should avoid, then we prefer to bubble up to the
14387 // parent boundary if it is currently invisible.
14388
14389
14390 if (hasInvisibleParent) {
14391 return false;
14392 } // If the parent is not able to handle it, we must handle it.
14393
14394
14395 return true;
14396 }
14397 function findFirstSuspended(row) {
14398 var node = row;
14399
14400 while (node !== null) {
14401 if (node.tag === SuspenseComponent) {
14402 var state = node.memoizedState;
14403
14404 if (state !== null) {
14405 var dehydrated = state.dehydrated;
14406
14407 if (dehydrated === null || isSuspenseInstancePending(dehydrated) || isSuspenseInstanceFallback(dehydrated)) {
14408 return node;
14409 }
14410 }
14411 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't
14412 // keep track of whether it suspended or not.
14413 node.memoizedProps.revealOrder !== undefined) {
14414 var didSuspend = (node.flags & DidCapture) !== NoFlags;
14415
14416 if (didSuspend) {
14417 return node;
14418 }
14419 } else if (node.child !== null) {
14420 node.child.return = node;
14421 node = node.child;
14422 continue;
14423 }
14424
14425 if (node === row) {
14426 return null;
14427 }
14428
14429 while (node.sibling === null) {
14430 if (node.return === null || node.return === row) {
14431 return null;
14432 }
14433
14434 node = node.return;
14435 }
14436
14437 node.sibling.return = node.return;
14438 node = node.sibling;
14439 }
14440
14441 return null;
14442 }
14443
14444 var NoFlags$1 =
14445 /* */
14446 0; // Represents whether effect should fire.
14447
14448 var HasEffect =
14449 /* */
14450 1; // Represents the phase in which the effect (not the clean-up) fires.
14451
14452 var Layout =
14453 /* */
14454 2;
14455 var Passive$1 =
14456 /* */
14457 4;
14458
14459 // This may have been an insertion or a hydration.
14460
14461 var hydrationParentFiber = null;
14462 var nextHydratableInstance = null;
14463 var isHydrating = false;
14464
14465 function enterHydrationState(fiber) {
14466
14467 var parentInstance = fiber.stateNode.containerInfo;
14468 nextHydratableInstance = getFirstHydratableChild(parentInstance);
14469 hydrationParentFiber = fiber;
14470 isHydrating = true;
14471 return true;
14472 }
14473
14474 function deleteHydratableInstance(returnFiber, instance) {
14475 {
14476 switch (returnFiber.tag) {
14477 case HostRoot:
14478 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
14479 break;
14480
14481 case HostComponent:
14482 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
14483 break;
14484 }
14485 }
14486
14487 var childToDelete = createFiberFromHostInstanceForDeletion();
14488 childToDelete.stateNode = instance;
14489 childToDelete.return = returnFiber;
14490 childToDelete.flags = Deletion; // This might seem like it belongs on progressedFirstDeletion. However,
14491 // these children are not part of the reconciliation list of children.
14492 // Even if we abort and rereconcile the children, that will try to hydrate
14493 // again and the nodes are still in the host tree so these will be
14494 // recreated.
14495
14496 if (returnFiber.lastEffect !== null) {
14497 returnFiber.lastEffect.nextEffect = childToDelete;
14498 returnFiber.lastEffect = childToDelete;
14499 } else {
14500 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
14501 }
14502 }
14503
14504 function insertNonHydratedInstance(returnFiber, fiber) {
14505 fiber.flags = fiber.flags & ~Hydrating | Placement;
14506
14507 {
14508 switch (returnFiber.tag) {
14509 case HostRoot:
14510 {
14511 var parentContainer = returnFiber.stateNode.containerInfo;
14512
14513 switch (fiber.tag) {
14514 case HostComponent:
14515 var type = fiber.type;
14516 var props = fiber.pendingProps;
14517 didNotFindHydratableContainerInstance(parentContainer, type);
14518 break;
14519
14520 case HostText:
14521 var text = fiber.pendingProps;
14522 didNotFindHydratableContainerTextInstance(parentContainer, text);
14523 break;
14524 }
14525
14526 break;
14527 }
14528
14529 case HostComponent:
14530 {
14531 var parentType = returnFiber.type;
14532 var parentProps = returnFiber.memoizedProps;
14533 var parentInstance = returnFiber.stateNode;
14534
14535 switch (fiber.tag) {
14536 case HostComponent:
14537 var _type = fiber.type;
14538 var _props = fiber.pendingProps;
14539 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type);
14540 break;
14541
14542 case HostText:
14543 var _text = fiber.pendingProps;
14544 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
14545 break;
14546
14547 case SuspenseComponent:
14548 didNotFindHydratableSuspenseInstance(parentType, parentProps);
14549 break;
14550 }
14551
14552 break;
14553 }
14554
14555 default:
14556 return;
14557 }
14558 }
14559 }
14560
14561 function tryHydrate(fiber, nextInstance) {
14562 switch (fiber.tag) {
14563 case HostComponent:
14564 {
14565 var type = fiber.type;
14566 var props = fiber.pendingProps;
14567 var instance = canHydrateInstance(nextInstance, type);
14568
14569 if (instance !== null) {
14570 fiber.stateNode = instance;
14571 return true;
14572 }
14573
14574 return false;
14575 }
14576
14577 case HostText:
14578 {
14579 var text = fiber.pendingProps;
14580 var textInstance = canHydrateTextInstance(nextInstance, text);
14581
14582 if (textInstance !== null) {
14583 fiber.stateNode = textInstance;
14584 return true;
14585 }
14586
14587 return false;
14588 }
14589
14590 case SuspenseComponent:
14591 {
14592
14593 return false;
14594 }
14595
14596 default:
14597 return false;
14598 }
14599 }
14600
14601 function tryToClaimNextHydratableInstance(fiber) {
14602 if (!isHydrating) {
14603 return;
14604 }
14605
14606 var nextInstance = nextHydratableInstance;
14607
14608 if (!nextInstance) {
14609 // Nothing to hydrate. Make it an insertion.
14610 insertNonHydratedInstance(hydrationParentFiber, fiber);
14611 isHydrating = false;
14612 hydrationParentFiber = fiber;
14613 return;
14614 }
14615
14616 var firstAttemptedInstance = nextInstance;
14617
14618 if (!tryHydrate(fiber, nextInstance)) {
14619 // If we can't hydrate this instance let's try the next one.
14620 // We use this as a heuristic. It's based on intuition and not data so it
14621 // might be flawed or unnecessary.
14622 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
14623
14624 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
14625 // Nothing to hydrate. Make it an insertion.
14626 insertNonHydratedInstance(hydrationParentFiber, fiber);
14627 isHydrating = false;
14628 hydrationParentFiber = fiber;
14629 return;
14630 } // We matched the next one, we'll now assume that the first one was
14631 // superfluous and we'll delete it. Since we can't eagerly delete it
14632 // we'll have to schedule a deletion. To do that, this node needs a dummy
14633 // fiber associated with it.
14634
14635
14636 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
14637 }
14638
14639 hydrationParentFiber = fiber;
14640 nextHydratableInstance = getFirstHydratableChild(nextInstance);
14641 }
14642
14643 function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
14644
14645 var instance = fiber.stateNode;
14646 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber); // TODO: Type this specific to this type of component.
14647
14648 fiber.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
14649 // is a new ref we mark this as an update.
14650
14651 if (updatePayload !== null) {
14652 return true;
14653 }
14654
14655 return false;
14656 }
14657
14658 function prepareToHydrateHostTextInstance(fiber) {
14659
14660 var textInstance = fiber.stateNode;
14661 var textContent = fiber.memoizedProps;
14662 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
14663
14664 {
14665 if (shouldUpdate) {
14666 // We assume that prepareToHydrateHostTextInstance is called in a context where the
14667 // hydration parent is the parent host component of this host text.
14668 var returnFiber = hydrationParentFiber;
14669
14670 if (returnFiber !== null) {
14671 switch (returnFiber.tag) {
14672 case HostRoot:
14673 {
14674 var parentContainer = returnFiber.stateNode.containerInfo;
14675 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
14676 break;
14677 }
14678
14679 case HostComponent:
14680 {
14681 var parentType = returnFiber.type;
14682 var parentProps = returnFiber.memoizedProps;
14683 var parentInstance = returnFiber.stateNode;
14684 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
14685 break;
14686 }
14687 }
14688 }
14689 }
14690 }
14691
14692 return shouldUpdate;
14693 }
14694
14695 function skipPastDehydratedSuspenseInstance(fiber) {
14696
14697 var suspenseState = fiber.memoizedState;
14698 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
14699
14700 if (!suspenseInstance) {
14701 {
14702 throw Error( "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." );
14703 }
14704 }
14705
14706 return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
14707 }
14708
14709 function popToNextHostParent(fiber) {
14710 var parent = fiber.return;
14711
14712 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== SuspenseComponent) {
14713 parent = parent.return;
14714 }
14715
14716 hydrationParentFiber = parent;
14717 }
14718
14719 function popHydrationState(fiber) {
14720
14721 if (fiber !== hydrationParentFiber) {
14722 // We're deeper than the current hydration context, inside an inserted
14723 // tree.
14724 return false;
14725 }
14726
14727 if (!isHydrating) {
14728 // If we're not currently hydrating but we're in a hydration context, then
14729 // we were an insertion and now need to pop up reenter hydration of our
14730 // siblings.
14731 popToNextHostParent(fiber);
14732 isHydrating = true;
14733 return false;
14734 }
14735
14736 var type = fiber.type; // If we have any remaining hydratable nodes, we need to delete them now.
14737 // We only do this deeper than head and body since they tend to have random
14738 // other nodes in them. We also ignore components with pure text content in
14739 // side of them.
14740 // TODO: Better heuristic.
14741
14742 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
14743 var nextInstance = nextHydratableInstance;
14744
14745 while (nextInstance) {
14746 deleteHydratableInstance(fiber, nextInstance);
14747 nextInstance = getNextHydratableSibling(nextInstance);
14748 }
14749 }
14750
14751 popToNextHostParent(fiber);
14752
14753 if (fiber.tag === SuspenseComponent) {
14754 nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber);
14755 } else {
14756 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
14757 }
14758
14759 return true;
14760 }
14761
14762 function resetHydrationState() {
14763
14764 hydrationParentFiber = null;
14765 nextHydratableInstance = null;
14766 isHydrating = false;
14767 }
14768
14769 function getIsHydrating() {
14770 return isHydrating;
14771 }
14772
14773 // and should be reset before starting a new render.
14774 // This tracks which mutable sources need to be reset after a render.
14775
14776 var workInProgressSources = [];
14777 var rendererSigil$1;
14778
14779 {
14780 // Used to detect multiple renderers using the same mutable source.
14781 rendererSigil$1 = {};
14782 }
14783
14784 function markSourceAsDirty(mutableSource) {
14785 workInProgressSources.push(mutableSource);
14786 }
14787 function resetWorkInProgressVersions() {
14788 for (var i = 0; i < workInProgressSources.length; i++) {
14789 var mutableSource = workInProgressSources[i];
14790
14791 {
14792 mutableSource._workInProgressVersionPrimary = null;
14793 }
14794 }
14795
14796 workInProgressSources.length = 0;
14797 }
14798 function getWorkInProgressVersion(mutableSource) {
14799 {
14800 return mutableSource._workInProgressVersionPrimary;
14801 }
14802 }
14803 function setWorkInProgressVersion(mutableSource, version) {
14804 {
14805 mutableSource._workInProgressVersionPrimary = version;
14806 }
14807
14808 workInProgressSources.push(mutableSource);
14809 }
14810 function warnAboutMultipleRenderersDEV(mutableSource) {
14811 {
14812 {
14813 if (mutableSource._currentPrimaryRenderer == null) {
14814 mutableSource._currentPrimaryRenderer = rendererSigil$1;
14815 } else if (mutableSource._currentPrimaryRenderer !== rendererSigil$1) {
14816 error('Detected multiple renderers concurrently rendering the ' + 'same mutable source. This is currently unsupported.');
14817 }
14818 }
14819 }
14820 } // Eager reads the version of a mutable source and stores it on the root.
14821
14822 var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher,
14823 ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig;
14824 var didWarnAboutMismatchedHooksForComponent;
14825 var didWarnAboutUseOpaqueIdentifier;
14826
14827 {
14828 didWarnAboutUseOpaqueIdentifier = {};
14829 didWarnAboutMismatchedHooksForComponent = new Set();
14830 }
14831
14832 // These are set right before calling the component.
14833 var renderLanes = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from
14834 // the work-in-progress hook.
14835
14836 var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
14837 // current hook list is the list that belongs to the current fiber. The
14838 // work-in-progress hook list is a new list that will be added to the
14839 // work-in-progress fiber.
14840
14841 var currentHook = null;
14842 var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This
14843 // does not get reset if we do another render pass; only when we're completely
14844 // finished evaluating this component. This is an optimization so we know
14845 // whether we need to clear render phase updates after a throw.
14846
14847 var didScheduleRenderPhaseUpdate = false; // Where an update was scheduled only during the current render pass. This
14848 // gets reset after each attempt.
14849 // TODO: Maybe there's some way to consolidate this with
14850 // `didScheduleRenderPhaseUpdate`. Or with `numberOfReRenders`.
14851
14852 var didScheduleRenderPhaseUpdateDuringThisPass = false;
14853 var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook
14854
14855 var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.
14856 // The list stores the order of hooks used during the initial render (mount).
14857 // Subsequent renders (updates) reference this list.
14858
14859 var hookTypesDev = null;
14860 var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore
14861 // the dependencies for Hooks that need them (e.g. useEffect or useMemo).
14862 // When true, such Hooks will always be "remounted". Only used during hot reload.
14863
14864 var ignorePreviousDependencies = false;
14865
14866 function mountHookTypesDev() {
14867 {
14868 var hookName = currentHookNameInDev;
14869
14870 if (hookTypesDev === null) {
14871 hookTypesDev = [hookName];
14872 } else {
14873 hookTypesDev.push(hookName);
14874 }
14875 }
14876 }
14877
14878 function updateHookTypesDev() {
14879 {
14880 var hookName = currentHookNameInDev;
14881
14882 if (hookTypesDev !== null) {
14883 hookTypesUpdateIndexDev++;
14884
14885 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
14886 warnOnHookMismatchInDev(hookName);
14887 }
14888 }
14889 }
14890 }
14891
14892 function checkDepsAreArrayDev(deps) {
14893 {
14894 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
14895 // Verify deps, but only on mount to avoid extra checks.
14896 // It's unlikely their type would change as usually you define them inline.
14897 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);
14898 }
14899 }
14900 }
14901
14902 function warnOnHookMismatchInDev(currentHookName) {
14903 {
14904 var componentName = getComponentName(currentlyRenderingFiber$1.type);
14905
14906 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
14907 didWarnAboutMismatchedHooksForComponent.add(componentName);
14908
14909 if (hookTypesDev !== null) {
14910 var table = '';
14911 var secondColumnStart = 30;
14912
14913 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
14914 var oldHookName = hookTypesDev[i];
14915 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
14916 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up
14917 // lol @ IE not supporting String#repeat
14918
14919 while (row.length < secondColumnStart) {
14920 row += ' ';
14921 }
14922
14923 row += newHookName + '\n';
14924 table += row;
14925 }
14926
14927 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);
14928 }
14929 }
14930 }
14931 }
14932
14933 function throwInvalidHookError() {
14934 {
14935 {
14936 throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem." );
14937 }
14938 }
14939 }
14940
14941 function areHookInputsEqual(nextDeps, prevDeps) {
14942 {
14943 if (ignorePreviousDependencies) {
14944 // Only true when this component is being hot reloaded.
14945 return false;
14946 }
14947 }
14948
14949 if (prevDeps === null) {
14950 {
14951 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);
14952 }
14953
14954 return false;
14955 }
14956
14957 {
14958 // Don't bother comparing lengths in prod because these arrays should be
14959 // passed inline.
14960 if (nextDeps.length !== prevDeps.length) {
14961 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(', ') + "]");
14962 }
14963 }
14964
14965 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
14966 if (objectIs(nextDeps[i], prevDeps[i])) {
14967 continue;
14968 }
14969
14970 return false;
14971 }
14972
14973 return true;
14974 }
14975
14976 function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderLanes) {
14977 renderLanes = nextRenderLanes;
14978 currentlyRenderingFiber$1 = workInProgress;
14979
14980 {
14981 hookTypesDev = current !== null ? current._debugHookTypes : null;
14982 hookTypesUpdateIndexDev = -1; // Used for hot reloading:
14983
14984 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
14985 }
14986
14987 workInProgress.memoizedState = null;
14988 workInProgress.updateQueue = null;
14989 workInProgress.lanes = NoLanes; // The following should have already been reset
14990 // currentHook = null;
14991 // workInProgressHook = null;
14992 // didScheduleRenderPhaseUpdate = false;
14993 // TODO Warn if no hooks are used at all during mount, then some are used during update.
14994 // Currently we will identify the update render as a mount because memoizedState === null.
14995 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
14996 // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.
14997 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
14998 // so memoizedState would be null during updates and mounts.
14999
15000 {
15001 if (current !== null && current.memoizedState !== null) {
15002 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
15003 } else if (hookTypesDev !== null) {
15004 // This dispatcher handles an edge case where a component is updating,
15005 // but no stateful hooks have been used.
15006 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
15007 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
15008 // This dispatcher does that.
15009 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
15010 } else {
15011 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
15012 }
15013 }
15014
15015 var children = Component(props, secondArg); // Check if there was a render phase update
15016
15017 if (didScheduleRenderPhaseUpdateDuringThisPass) {
15018 // Keep rendering in a loop for as long as render phase updates continue to
15019 // be scheduled. Use a counter to prevent infinite loops.
15020 var numberOfReRenders = 0;
15021
15022 do {
15023 didScheduleRenderPhaseUpdateDuringThisPass = false;
15024
15025 if (!(numberOfReRenders < RE_RENDER_LIMIT)) {
15026 {
15027 throw Error( "Too many re-renders. React limits the number of renders to prevent an infinite loop." );
15028 }
15029 }
15030
15031 numberOfReRenders += 1;
15032
15033 {
15034 // Even when hot reloading, allow dependencies to stabilize
15035 // after first render to prevent infinite render phase updates.
15036 ignorePreviousDependencies = false;
15037 } // Start over from the beginning of the list
15038
15039
15040 currentHook = null;
15041 workInProgressHook = null;
15042 workInProgress.updateQueue = null;
15043
15044 {
15045 // Also validate hook order for cascading updates.
15046 hookTypesUpdateIndexDev = -1;
15047 }
15048
15049 ReactCurrentDispatcher$1.current = HooksDispatcherOnRerenderInDEV ;
15050 children = Component(props, secondArg);
15051 } while (didScheduleRenderPhaseUpdateDuringThisPass);
15052 } // We can assume the previous dispatcher is always this one, since we set it
15053 // at the beginning of the render phase and there's no re-entrancy.
15054
15055
15056 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
15057
15058 {
15059 workInProgress._debugHookTypes = hookTypesDev;
15060 } // This check uses currentHook so that it works the same in DEV and prod bundles.
15061 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
15062
15063
15064 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
15065 renderLanes = NoLanes;
15066 currentlyRenderingFiber$1 = null;
15067 currentHook = null;
15068 workInProgressHook = null;
15069
15070 {
15071 currentHookNameInDev = null;
15072 hookTypesDev = null;
15073 hookTypesUpdateIndexDev = -1;
15074 }
15075
15076 didScheduleRenderPhaseUpdate = false;
15077
15078 if (!!didRenderTooFewHooks) {
15079 {
15080 throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." );
15081 }
15082 }
15083
15084 return children;
15085 }
15086 function bailoutHooks(current, workInProgress, lanes) {
15087 workInProgress.updateQueue = current.updateQueue;
15088 workInProgress.flags &= ~(Passive | Update);
15089 current.lanes = removeLanes(current.lanes, lanes);
15090 }
15091 function resetHooksAfterThrow() {
15092 // We can assume the previous dispatcher is always this one, since we set it
15093 // at the beginning of the render phase and there's no re-entrancy.
15094 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
15095
15096 if (didScheduleRenderPhaseUpdate) {
15097 // There were render phase updates. These are only valid for this render
15098 // phase, which we are now aborting. Remove the updates from the queues so
15099 // they do not persist to the next render. Do not remove updates from hooks
15100 // that weren't processed.
15101 //
15102 // Only reset the updates from the queue if it has a clone. If it does
15103 // not have a clone, that means it wasn't processed, and the updates were
15104 // scheduled before we entered the render phase.
15105 var hook = currentlyRenderingFiber$1.memoizedState;
15106
15107 while (hook !== null) {
15108 var queue = hook.queue;
15109
15110 if (queue !== null) {
15111 queue.pending = null;
15112 }
15113
15114 hook = hook.next;
15115 }
15116
15117 didScheduleRenderPhaseUpdate = false;
15118 }
15119
15120 renderLanes = NoLanes;
15121 currentlyRenderingFiber$1 = null;
15122 currentHook = null;
15123 workInProgressHook = null;
15124
15125 {
15126 hookTypesDev = null;
15127 hookTypesUpdateIndexDev = -1;
15128 currentHookNameInDev = null;
15129 isUpdatingOpaqueValueInRenderPhase = false;
15130 }
15131
15132 didScheduleRenderPhaseUpdateDuringThisPass = false;
15133 }
15134
15135 function mountWorkInProgressHook() {
15136 var hook = {
15137 memoizedState: null,
15138 baseState: null,
15139 baseQueue: null,
15140 queue: null,
15141 next: null
15142 };
15143
15144 if (workInProgressHook === null) {
15145 // This is the first hook in the list
15146 currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;
15147 } else {
15148 // Append to the end of the list
15149 workInProgressHook = workInProgressHook.next = hook;
15150 }
15151
15152 return workInProgressHook;
15153 }
15154
15155 function updateWorkInProgressHook() {
15156 // This function is used both for updates and for re-renders triggered by a
15157 // render phase update. It assumes there is either a current hook we can
15158 // clone, or a work-in-progress hook from a previous render pass that we can
15159 // use as a base. When we reach the end of the base list, we must switch to
15160 // the dispatcher used for mounts.
15161 var nextCurrentHook;
15162
15163 if (currentHook === null) {
15164 var current = currentlyRenderingFiber$1.alternate;
15165
15166 if (current !== null) {
15167 nextCurrentHook = current.memoizedState;
15168 } else {
15169 nextCurrentHook = null;
15170 }
15171 } else {
15172 nextCurrentHook = currentHook.next;
15173 }
15174
15175 var nextWorkInProgressHook;
15176
15177 if (workInProgressHook === null) {
15178 nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState;
15179 } else {
15180 nextWorkInProgressHook = workInProgressHook.next;
15181 }
15182
15183 if (nextWorkInProgressHook !== null) {
15184 // There's already a work-in-progress. Reuse it.
15185 workInProgressHook = nextWorkInProgressHook;
15186 nextWorkInProgressHook = workInProgressHook.next;
15187 currentHook = nextCurrentHook;
15188 } else {
15189 // Clone from the current hook.
15190 if (!(nextCurrentHook !== null)) {
15191 {
15192 throw Error( "Rendered more hooks than during the previous render." );
15193 }
15194 }
15195
15196 currentHook = nextCurrentHook;
15197 var newHook = {
15198 memoizedState: currentHook.memoizedState,
15199 baseState: currentHook.baseState,
15200 baseQueue: currentHook.baseQueue,
15201 queue: currentHook.queue,
15202 next: null
15203 };
15204
15205 if (workInProgressHook === null) {
15206 // This is the first hook in the list.
15207 currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook;
15208 } else {
15209 // Append to the end of the list.
15210 workInProgressHook = workInProgressHook.next = newHook;
15211 }
15212 }
15213
15214 return workInProgressHook;
15215 }
15216
15217 function createFunctionComponentUpdateQueue() {
15218 return {
15219 lastEffect: null
15220 };
15221 }
15222
15223 function basicStateReducer(state, action) {
15224 // $FlowFixMe: Flow doesn't like mixed types
15225 return typeof action === 'function' ? action(state) : action;
15226 }
15227
15228 function mountReducer(reducer, initialArg, init) {
15229 var hook = mountWorkInProgressHook();
15230 var initialState;
15231
15232 if (init !== undefined) {
15233 initialState = init(initialArg);
15234 } else {
15235 initialState = initialArg;
15236 }
15237
15238 hook.memoizedState = hook.baseState = initialState;
15239 var queue = hook.queue = {
15240 pending: null,
15241 dispatch: null,
15242 lastRenderedReducer: reducer,
15243 lastRenderedState: initialState
15244 };
15245 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
15246 return [hook.memoizedState, dispatch];
15247 }
15248
15249 function updateReducer(reducer, initialArg, init) {
15250 var hook = updateWorkInProgressHook();
15251 var queue = hook.queue;
15252
15253 if (!(queue !== null)) {
15254 {
15255 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );
15256 }
15257 }
15258
15259 queue.lastRenderedReducer = reducer;
15260 var current = currentHook; // The last rebase update that is NOT part of the base state.
15261
15262 var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet.
15263
15264 var pendingQueue = queue.pending;
15265
15266 if (pendingQueue !== null) {
15267 // We have new updates that haven't been processed yet.
15268 // We'll add them to the base queue.
15269 if (baseQueue !== null) {
15270 // Merge the pending queue and the base queue.
15271 var baseFirst = baseQueue.next;
15272 var pendingFirst = pendingQueue.next;
15273 baseQueue.next = pendingFirst;
15274 pendingQueue.next = baseFirst;
15275 }
15276
15277 {
15278 if (current.baseQueue !== baseQueue) {
15279 // Internal invariant that should never happen, but feasibly could in
15280 // the future if we implement resuming, or some form of that.
15281 error('Internal error: Expected work-in-progress queue to be a clone. ' + 'This is a bug in React.');
15282 }
15283 }
15284
15285 current.baseQueue = baseQueue = pendingQueue;
15286 queue.pending = null;
15287 }
15288
15289 if (baseQueue !== null) {
15290 // We have a queue to process.
15291 var first = baseQueue.next;
15292 var newState = current.baseState;
15293 var newBaseState = null;
15294 var newBaseQueueFirst = null;
15295 var newBaseQueueLast = null;
15296 var update = first;
15297
15298 do {
15299 var updateLane = update.lane;
15300
15301 if (!isSubsetOfLanes(renderLanes, updateLane)) {
15302 // Priority is insufficient. Skip this update. If this is the first
15303 // skipped update, the previous update/state is the new base
15304 // update/state.
15305 var clone = {
15306 lane: updateLane,
15307 action: update.action,
15308 eagerReducer: update.eagerReducer,
15309 eagerState: update.eagerState,
15310 next: null
15311 };
15312
15313 if (newBaseQueueLast === null) {
15314 newBaseQueueFirst = newBaseQueueLast = clone;
15315 newBaseState = newState;
15316 } else {
15317 newBaseQueueLast = newBaseQueueLast.next = clone;
15318 } // Update the remaining priority in the queue.
15319 // TODO: Don't need to accumulate this. Instead, we can remove
15320 // renderLanes from the original lanes.
15321
15322
15323 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, updateLane);
15324 markSkippedUpdateLanes(updateLane);
15325 } else {
15326 // This update does have sufficient priority.
15327 if (newBaseQueueLast !== null) {
15328 var _clone = {
15329 // This update is going to be committed so we never want uncommit
15330 // it. Using NoLane works because 0 is a subset of all bitmasks, so
15331 // this will never be skipped by the check above.
15332 lane: NoLane,
15333 action: update.action,
15334 eagerReducer: update.eagerReducer,
15335 eagerState: update.eagerState,
15336 next: null
15337 };
15338 newBaseQueueLast = newBaseQueueLast.next = _clone;
15339 } // Process this update.
15340
15341
15342 if (update.eagerReducer === reducer) {
15343 // If this update was processed eagerly, and its reducer matches the
15344 // current reducer, we can use the eagerly computed state.
15345 newState = update.eagerState;
15346 } else {
15347 var action = update.action;
15348 newState = reducer(newState, action);
15349 }
15350 }
15351
15352 update = update.next;
15353 } while (update !== null && update !== first);
15354
15355 if (newBaseQueueLast === null) {
15356 newBaseState = newState;
15357 } else {
15358 newBaseQueueLast.next = newBaseQueueFirst;
15359 } // Mark that the fiber performed work, but only if the new state is
15360 // different from the current state.
15361
15362
15363 if (!objectIs(newState, hook.memoizedState)) {
15364 markWorkInProgressReceivedUpdate();
15365 }
15366
15367 hook.memoizedState = newState;
15368 hook.baseState = newBaseState;
15369 hook.baseQueue = newBaseQueueLast;
15370 queue.lastRenderedState = newState;
15371 }
15372
15373 var dispatch = queue.dispatch;
15374 return [hook.memoizedState, dispatch];
15375 }
15376
15377 function rerenderReducer(reducer, initialArg, init) {
15378 var hook = updateWorkInProgressHook();
15379 var queue = hook.queue;
15380
15381 if (!(queue !== null)) {
15382 {
15383 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );
15384 }
15385 }
15386
15387 queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous
15388 // work-in-progress hook.
15389
15390 var dispatch = queue.dispatch;
15391 var lastRenderPhaseUpdate = queue.pending;
15392 var newState = hook.memoizedState;
15393
15394 if (lastRenderPhaseUpdate !== null) {
15395 // The queue doesn't persist past this render pass.
15396 queue.pending = null;
15397 var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;
15398 var update = firstRenderPhaseUpdate;
15399
15400 do {
15401 // Process this render phase update. We don't have to check the
15402 // priority because it will always be the same as the current
15403 // render's.
15404 var action = update.action;
15405 newState = reducer(newState, action);
15406 update = update.next;
15407 } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is
15408 // different from the current state.
15409
15410
15411 if (!objectIs(newState, hook.memoizedState)) {
15412 markWorkInProgressReceivedUpdate();
15413 }
15414
15415 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to
15416 // the base state unless the queue is empty.
15417 // TODO: Not sure if this is the desired semantics, but it's what we
15418 // do for gDSFP. I can't remember why.
15419
15420 if (hook.baseQueue === null) {
15421 hook.baseState = newState;
15422 }
15423
15424 queue.lastRenderedState = newState;
15425 }
15426
15427 return [newState, dispatch];
15428 }
15429
15430 function readFromUnsubcribedMutableSource(root, source, getSnapshot) {
15431 {
15432 warnAboutMultipleRenderersDEV(source);
15433 }
15434
15435 var getVersion = source._getVersion;
15436 var version = getVersion(source._source); // Is it safe for this component to read from this source during the current render?
15437
15438 var isSafeToReadFromSource = false; // Check the version first.
15439 // If this render has already been started with a specific version,
15440 // we can use it alone to determine if we can safely read from the source.
15441
15442 var currentRenderVersion = getWorkInProgressVersion(source);
15443
15444 if (currentRenderVersion !== null) {
15445 // It's safe to read if the store hasn't been mutated since the last time
15446 // we read something.
15447 isSafeToReadFromSource = currentRenderVersion === version;
15448 } else {
15449 // If there's no version, then this is the first time we've read from the
15450 // source during the current render pass, so we need to do a bit more work.
15451 // What we need to determine is if there are any hooks that already
15452 // subscribed to the source, and if so, whether there are any pending
15453 // mutations that haven't been synchronized yet.
15454 //
15455 // If there are no pending mutations, then `root.mutableReadLanes` will be
15456 // empty, and we know we can safely read.
15457 //
15458 // If there *are* pending mutations, we may still be able to safely read
15459 // if the currently rendering lanes are inclusive of the pending mutation
15460 // lanes, since that guarantees that the value we're about to read from
15461 // the source is consistent with the values that we read during the most
15462 // recent mutation.
15463 isSafeToReadFromSource = isSubsetOfLanes(renderLanes, root.mutableReadLanes);
15464
15465 if (isSafeToReadFromSource) {
15466 // If it's safe to read from this source during the current render,
15467 // store the version in case other components read from it.
15468 // A changed version number will let those components know to throw and restart the render.
15469 setWorkInProgressVersion(source, version);
15470 }
15471 }
15472
15473 if (isSafeToReadFromSource) {
15474 var snapshot = getSnapshot(source._source);
15475
15476 {
15477 if (typeof snapshot === 'function') {
15478 error('Mutable source should not return a function as the snapshot value. ' + 'Functions may close over mutable values and cause tearing.');
15479 }
15480 }
15481
15482 return snapshot;
15483 } else {
15484 // This handles the special case of a mutable source being shared between renderers.
15485 // In that case, if the source is mutated between the first and second renderer,
15486 // The second renderer don't know that it needs to reset the WIP version during unwind,
15487 // (because the hook only marks sources as dirty if it's written to their WIP version).
15488 // That would cause this tear check to throw again and eventually be visible to the user.
15489 // We can avoid this infinite loop by explicitly marking the source as dirty.
15490 //
15491 // This can lead to tearing in the first renderer when it resumes,
15492 // but there's nothing we can do about that (short of throwing here and refusing to continue the render).
15493 markSourceAsDirty(source);
15494
15495 {
15496 {
15497 throw Error( "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." );
15498 }
15499 }
15500 }
15501 }
15502
15503 function useMutableSource(hook, source, getSnapshot, subscribe) {
15504 var root = getWorkInProgressRoot();
15505
15506 if (!(root !== null)) {
15507 {
15508 throw Error( "Expected a work-in-progress root. This is a bug in React. Please file an issue." );
15509 }
15510 }
15511
15512 var getVersion = source._getVersion;
15513 var version = getVersion(source._source);
15514 var dispatcher = ReactCurrentDispatcher$1.current; // eslint-disable-next-line prefer-const
15515
15516 var _dispatcher$useState = dispatcher.useState(function () {
15517 return readFromUnsubcribedMutableSource(root, source, getSnapshot);
15518 }),
15519 currentSnapshot = _dispatcher$useState[0],
15520 setSnapshot = _dispatcher$useState[1];
15521
15522 var snapshot = currentSnapshot; // Grab a handle to the state hook as well.
15523 // We use it to clear the pending update queue if we have a new source.
15524
15525 var stateHook = workInProgressHook;
15526 var memoizedState = hook.memoizedState;
15527 var refs = memoizedState.refs;
15528 var prevGetSnapshot = refs.getSnapshot;
15529 var prevSource = memoizedState.source;
15530 var prevSubscribe = memoizedState.subscribe;
15531 var fiber = currentlyRenderingFiber$1;
15532 hook.memoizedState = {
15533 refs: refs,
15534 source: source,
15535 subscribe: subscribe
15536 }; // Sync the values needed by our subscription handler after each commit.
15537
15538 dispatcher.useEffect(function () {
15539 refs.getSnapshot = getSnapshot; // Normally the dispatch function for a state hook never changes,
15540 // but this hook recreates the queue in certain cases to avoid updates from stale sources.
15541 // handleChange() below needs to reference the dispatch function without re-subscribing,
15542 // so we use a ref to ensure that it always has the latest version.
15543
15544 refs.setSnapshot = setSnapshot; // Check for a possible change between when we last rendered now.
15545
15546 var maybeNewVersion = getVersion(source._source);
15547
15548 if (!objectIs(version, maybeNewVersion)) {
15549 var maybeNewSnapshot = getSnapshot(source._source);
15550
15551 {
15552 if (typeof maybeNewSnapshot === 'function') {
15553 error('Mutable source should not return a function as the snapshot value. ' + 'Functions may close over mutable values and cause tearing.');
15554 }
15555 }
15556
15557 if (!objectIs(snapshot, maybeNewSnapshot)) {
15558 setSnapshot(maybeNewSnapshot);
15559 var lane = requestUpdateLane(fiber);
15560 markRootMutableRead(root, lane);
15561 } // If the source mutated between render and now,
15562 // there may be state updates already scheduled from the old source.
15563 // Entangle the updates so that they render in the same batch.
15564
15565
15566 markRootEntangled(root, root.mutableReadLanes);
15567 }
15568 }, [getSnapshot, source, subscribe]); // If we got a new source or subscribe function, re-subscribe in a passive effect.
15569
15570 dispatcher.useEffect(function () {
15571 var handleChange = function () {
15572 var latestGetSnapshot = refs.getSnapshot;
15573 var latestSetSnapshot = refs.setSnapshot;
15574
15575 try {
15576 latestSetSnapshot(latestGetSnapshot(source._source)); // Record a pending mutable source update with the same expiration time.
15577
15578 var lane = requestUpdateLane(fiber);
15579 markRootMutableRead(root, lane);
15580 } catch (error) {
15581 // A selector might throw after a source mutation.
15582 // e.g. it might try to read from a part of the store that no longer exists.
15583 // In this case we should still schedule an update with React.
15584 // Worst case the selector will throw again and then an error boundary will handle it.
15585 latestSetSnapshot(function () {
15586 throw error;
15587 });
15588 }
15589 };
15590
15591 var unsubscribe = subscribe(source._source, handleChange);
15592
15593 {
15594 if (typeof unsubscribe !== 'function') {
15595 error('Mutable source subscribe function must return an unsubscribe function.');
15596 }
15597 }
15598
15599 return unsubscribe;
15600 }, [source, subscribe]); // If any of the inputs to useMutableSource change, reading is potentially unsafe.
15601 //
15602 // If either the source or the subscription have changed we can't can't trust the update queue.
15603 // Maybe the source changed in a way that the old subscription ignored but the new one depends on.
15604 //
15605 // If the getSnapshot function changed, we also shouldn't rely on the update queue.
15606 // It's possible that the underlying source was mutated between the when the last "change" event fired,
15607 // and when the current render (with the new getSnapshot function) is processed.
15608 //
15609 // In both cases, we need to throw away pending updates (since they are no longer relevant)
15610 // and treat reading from the source as we do in the mount case.
15611
15612 if (!objectIs(prevGetSnapshot, getSnapshot) || !objectIs(prevSource, source) || !objectIs(prevSubscribe, subscribe)) {
15613 // Create a new queue and setState method,
15614 // So if there are interleaved updates, they get pushed to the older queue.
15615 // When this becomes current, the previous queue and dispatch method will be discarded,
15616 // including any interleaving updates that occur.
15617 var newQueue = {
15618 pending: null,
15619 dispatch: null,
15620 lastRenderedReducer: basicStateReducer,
15621 lastRenderedState: snapshot
15622 };
15623 newQueue.dispatch = setSnapshot = dispatchAction.bind(null, currentlyRenderingFiber$1, newQueue);
15624 stateHook.queue = newQueue;
15625 stateHook.baseQueue = null;
15626 snapshot = readFromUnsubcribedMutableSource(root, source, getSnapshot);
15627 stateHook.memoizedState = stateHook.baseState = snapshot;
15628 }
15629
15630 return snapshot;
15631 }
15632
15633 function mountMutableSource(source, getSnapshot, subscribe) {
15634 var hook = mountWorkInProgressHook();
15635 hook.memoizedState = {
15636 refs: {
15637 getSnapshot: getSnapshot,
15638 setSnapshot: null
15639 },
15640 source: source,
15641 subscribe: subscribe
15642 };
15643 return useMutableSource(hook, source, getSnapshot, subscribe);
15644 }
15645
15646 function updateMutableSource(source, getSnapshot, subscribe) {
15647 var hook = updateWorkInProgressHook();
15648 return useMutableSource(hook, source, getSnapshot, subscribe);
15649 }
15650
15651 function mountState(initialState) {
15652 var hook = mountWorkInProgressHook();
15653
15654 if (typeof initialState === 'function') {
15655 // $FlowFixMe: Flow doesn't like mixed types
15656 initialState = initialState();
15657 }
15658
15659 hook.memoizedState = hook.baseState = initialState;
15660 var queue = hook.queue = {
15661 pending: null,
15662 dispatch: null,
15663 lastRenderedReducer: basicStateReducer,
15664 lastRenderedState: initialState
15665 };
15666 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
15667 return [hook.memoizedState, dispatch];
15668 }
15669
15670 function updateState(initialState) {
15671 return updateReducer(basicStateReducer);
15672 }
15673
15674 function rerenderState(initialState) {
15675 return rerenderReducer(basicStateReducer);
15676 }
15677
15678 function pushEffect(tag, create, destroy, deps) {
15679 var effect = {
15680 tag: tag,
15681 create: create,
15682 destroy: destroy,
15683 deps: deps,
15684 // Circular
15685 next: null
15686 };
15687 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
15688
15689 if (componentUpdateQueue === null) {
15690 componentUpdateQueue = createFunctionComponentUpdateQueue();
15691 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
15692 componentUpdateQueue.lastEffect = effect.next = effect;
15693 } else {
15694 var lastEffect = componentUpdateQueue.lastEffect;
15695
15696 if (lastEffect === null) {
15697 componentUpdateQueue.lastEffect = effect.next = effect;
15698 } else {
15699 var firstEffect = lastEffect.next;
15700 lastEffect.next = effect;
15701 effect.next = firstEffect;
15702 componentUpdateQueue.lastEffect = effect;
15703 }
15704 }
15705
15706 return effect;
15707 }
15708
15709 function mountRef(initialValue) {
15710 var hook = mountWorkInProgressHook();
15711 var ref = {
15712 current: initialValue
15713 };
15714
15715 {
15716 Object.seal(ref);
15717 }
15718
15719 hook.memoizedState = ref;
15720 return ref;
15721 }
15722
15723 function updateRef(initialValue) {
15724 var hook = updateWorkInProgressHook();
15725 return hook.memoizedState;
15726 }
15727
15728 function mountEffectImpl(fiberFlags, hookFlags, create, deps) {
15729 var hook = mountWorkInProgressHook();
15730 var nextDeps = deps === undefined ? null : deps;
15731 currentlyRenderingFiber$1.flags |= fiberFlags;
15732 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, undefined, nextDeps);
15733 }
15734
15735 function updateEffectImpl(fiberFlags, hookFlags, create, deps) {
15736 var hook = updateWorkInProgressHook();
15737 var nextDeps = deps === undefined ? null : deps;
15738 var destroy = undefined;
15739
15740 if (currentHook !== null) {
15741 var prevEffect = currentHook.memoizedState;
15742 destroy = prevEffect.destroy;
15743
15744 if (nextDeps !== null) {
15745 var prevDeps = prevEffect.deps;
15746
15747 if (areHookInputsEqual(nextDeps, prevDeps)) {
15748 pushEffect(hookFlags, create, destroy, nextDeps);
15749 return;
15750 }
15751 }
15752 }
15753
15754 currentlyRenderingFiber$1.flags |= fiberFlags;
15755 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, destroy, nextDeps);
15756 }
15757
15758 function mountEffect(create, deps) {
15759 {
15760 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15761 if ('undefined' !== typeof jest) {
15762 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
15763 }
15764 }
15765
15766 return mountEffectImpl(Update | Passive, Passive$1, create, deps);
15767 }
15768
15769 function updateEffect(create, deps) {
15770 {
15771 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15772 if ('undefined' !== typeof jest) {
15773 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
15774 }
15775 }
15776
15777 return updateEffectImpl(Update | Passive, Passive$1, create, deps);
15778 }
15779
15780 function mountLayoutEffect(create, deps) {
15781 return mountEffectImpl(Update, Layout, create, deps);
15782 }
15783
15784 function updateLayoutEffect(create, deps) {
15785 return updateEffectImpl(Update, Layout, create, deps);
15786 }
15787
15788 function imperativeHandleEffect(create, ref) {
15789 if (typeof ref === 'function') {
15790 var refCallback = ref;
15791
15792 var _inst = create();
15793
15794 refCallback(_inst);
15795 return function () {
15796 refCallback(null);
15797 };
15798 } else if (ref !== null && ref !== undefined) {
15799 var refObject = ref;
15800
15801 {
15802 if (!refObject.hasOwnProperty('current')) {
15803 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(', ') + '}');
15804 }
15805 }
15806
15807 var _inst2 = create();
15808
15809 refObject.current = _inst2;
15810 return function () {
15811 refObject.current = null;
15812 };
15813 }
15814 }
15815
15816 function mountImperativeHandle(ref, create, deps) {
15817 {
15818 if (typeof create !== 'function') {
15819 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
15820 }
15821 } // TODO: If deps are provided, should we skip comparing the ref itself?
15822
15823
15824 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
15825 return mountEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
15826 }
15827
15828 function updateImperativeHandle(ref, create, deps) {
15829 {
15830 if (typeof create !== 'function') {
15831 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
15832 }
15833 } // TODO: If deps are provided, should we skip comparing the ref itself?
15834
15835
15836 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
15837 return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
15838 }
15839
15840 function mountDebugValue(value, formatterFn) {// This hook is normally a no-op.
15841 // The react-debug-hooks package injects its own implementation
15842 // so that e.g. DevTools can display custom hook values.
15843 }
15844
15845 var updateDebugValue = mountDebugValue;
15846
15847 function mountCallback(callback, deps) {
15848 var hook = mountWorkInProgressHook();
15849 var nextDeps = deps === undefined ? null : deps;
15850 hook.memoizedState = [callback, nextDeps];
15851 return callback;
15852 }
15853
15854 function updateCallback(callback, deps) {
15855 var hook = updateWorkInProgressHook();
15856 var nextDeps = deps === undefined ? null : deps;
15857 var prevState = hook.memoizedState;
15858
15859 if (prevState !== null) {
15860 if (nextDeps !== null) {
15861 var prevDeps = prevState[1];
15862
15863 if (areHookInputsEqual(nextDeps, prevDeps)) {
15864 return prevState[0];
15865 }
15866 }
15867 }
15868
15869 hook.memoizedState = [callback, nextDeps];
15870 return callback;
15871 }
15872
15873 function mountMemo(nextCreate, deps) {
15874 var hook = mountWorkInProgressHook();
15875 var nextDeps = deps === undefined ? null : deps;
15876 var nextValue = nextCreate();
15877 hook.memoizedState = [nextValue, nextDeps];
15878 return nextValue;
15879 }
15880
15881 function updateMemo(nextCreate, deps) {
15882 var hook = updateWorkInProgressHook();
15883 var nextDeps = deps === undefined ? null : deps;
15884 var prevState = hook.memoizedState;
15885
15886 if (prevState !== null) {
15887 // Assume these are defined. If they're not, areHookInputsEqual will warn.
15888 if (nextDeps !== null) {
15889 var prevDeps = prevState[1];
15890
15891 if (areHookInputsEqual(nextDeps, prevDeps)) {
15892 return prevState[0];
15893 }
15894 }
15895 }
15896
15897 var nextValue = nextCreate();
15898 hook.memoizedState = [nextValue, nextDeps];
15899 return nextValue;
15900 }
15901
15902 function mountDeferredValue(value) {
15903 var _mountState = mountState(value),
15904 prevValue = _mountState[0],
15905 setValue = _mountState[1];
15906
15907 mountEffect(function () {
15908 var prevTransition = ReactCurrentBatchConfig$1.transition;
15909 ReactCurrentBatchConfig$1.transition = 1;
15910
15911 try {
15912 setValue(value);
15913 } finally {
15914 ReactCurrentBatchConfig$1.transition = prevTransition;
15915 }
15916 }, [value]);
15917 return prevValue;
15918 }
15919
15920 function updateDeferredValue(value) {
15921 var _updateState = updateState(),
15922 prevValue = _updateState[0],
15923 setValue = _updateState[1];
15924
15925 updateEffect(function () {
15926 var prevTransition = ReactCurrentBatchConfig$1.transition;
15927 ReactCurrentBatchConfig$1.transition = 1;
15928
15929 try {
15930 setValue(value);
15931 } finally {
15932 ReactCurrentBatchConfig$1.transition = prevTransition;
15933 }
15934 }, [value]);
15935 return prevValue;
15936 }
15937
15938 function rerenderDeferredValue(value) {
15939 var _rerenderState = rerenderState(),
15940 prevValue = _rerenderState[0],
15941 setValue = _rerenderState[1];
15942
15943 updateEffect(function () {
15944 var prevTransition = ReactCurrentBatchConfig$1.transition;
15945 ReactCurrentBatchConfig$1.transition = 1;
15946
15947 try {
15948 setValue(value);
15949 } finally {
15950 ReactCurrentBatchConfig$1.transition = prevTransition;
15951 }
15952 }, [value]);
15953 return prevValue;
15954 }
15955
15956 function startTransition(setPending, callback) {
15957 var priorityLevel = getCurrentPriorityLevel();
15958
15959 {
15960 runWithPriority$1(priorityLevel < UserBlockingPriority$2 ? UserBlockingPriority$2 : priorityLevel, function () {
15961 setPending(true);
15962 });
15963 runWithPriority$1(priorityLevel > NormalPriority$1 ? NormalPriority$1 : priorityLevel, function () {
15964 var prevTransition = ReactCurrentBatchConfig$1.transition;
15965 ReactCurrentBatchConfig$1.transition = 1;
15966
15967 try {
15968 setPending(false);
15969 callback();
15970 } finally {
15971 ReactCurrentBatchConfig$1.transition = prevTransition;
15972 }
15973 });
15974 }
15975 }
15976
15977 function mountTransition() {
15978 var _mountState2 = mountState(false),
15979 isPending = _mountState2[0],
15980 setPending = _mountState2[1]; // The `start` method can be stored on a ref, since `setPending`
15981 // never changes.
15982
15983
15984 var start = startTransition.bind(null, setPending);
15985 mountRef(start);
15986 return [start, isPending];
15987 }
15988
15989 function updateTransition() {
15990 var _updateState2 = updateState(),
15991 isPending = _updateState2[0];
15992
15993 var startRef = updateRef();
15994 var start = startRef.current;
15995 return [start, isPending];
15996 }
15997
15998 function rerenderTransition() {
15999 var _rerenderState2 = rerenderState(),
16000 isPending = _rerenderState2[0];
16001
16002 var startRef = updateRef();
16003 var start = startRef.current;
16004 return [start, isPending];
16005 }
16006
16007 var isUpdatingOpaqueValueInRenderPhase = false;
16008 function getIsUpdatingOpaqueValueInRenderPhaseInDEV() {
16009 {
16010 return isUpdatingOpaqueValueInRenderPhase;
16011 }
16012 }
16013
16014 function warnOnOpaqueIdentifierAccessInDEV(fiber) {
16015 {
16016 // TODO: Should warn in effects and callbacks, too
16017 var name = getComponentName(fiber.type) || 'Unknown';
16018
16019 if (getIsRendering() && !didWarnAboutUseOpaqueIdentifier[name]) {
16020 error('The object passed back from useOpaqueIdentifier is meant to be ' + 'passed through to attributes only. Do not read the ' + 'value directly.');
16021
16022 didWarnAboutUseOpaqueIdentifier[name] = true;
16023 }
16024 }
16025 }
16026
16027 function mountOpaqueIdentifier() {
16028 var makeId = makeClientIdInDEV.bind(null, warnOnOpaqueIdentifierAccessInDEV.bind(null, currentlyRenderingFiber$1)) ;
16029
16030 if (getIsHydrating()) {
16031 var didUpgrade = false;
16032 var fiber = currentlyRenderingFiber$1;
16033
16034 var readValue = function () {
16035 if (!didUpgrade) {
16036 // Only upgrade once. This works even inside the render phase because
16037 // the update is added to a shared queue, which outlasts the
16038 // in-progress render.
16039 didUpgrade = true;
16040
16041 {
16042 isUpdatingOpaqueValueInRenderPhase = true;
16043 setId(makeId());
16044 isUpdatingOpaqueValueInRenderPhase = false;
16045 warnOnOpaqueIdentifierAccessInDEV(fiber);
16046 }
16047 }
16048
16049 {
16050 {
16051 throw Error( "The object passed back from useOpaqueIdentifier is meant to be passed through to attributes only. Do not read the value directly." );
16052 }
16053 }
16054 };
16055
16056 var id = makeOpaqueHydratingObject(readValue);
16057 var setId = mountState(id)[1];
16058
16059 if ((currentlyRenderingFiber$1.mode & BlockingMode) === NoMode) {
16060 currentlyRenderingFiber$1.flags |= Update | Passive;
16061 pushEffect(HasEffect | Passive$1, function () {
16062 setId(makeId());
16063 }, undefined, null);
16064 }
16065
16066 return id;
16067 } else {
16068 var _id = makeId();
16069
16070 mountState(_id);
16071 return _id;
16072 }
16073 }
16074
16075 function updateOpaqueIdentifier() {
16076 var id = updateState()[0];
16077 return id;
16078 }
16079
16080 function rerenderOpaqueIdentifier() {
16081 var id = rerenderState()[0];
16082 return id;
16083 }
16084
16085 function dispatchAction(fiber, queue, action) {
16086 {
16087 if (typeof arguments[3] === 'function') {
16088 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().');
16089 }
16090 }
16091
16092 var eventTime = requestEventTime();
16093 var lane = requestUpdateLane(fiber);
16094 var update = {
16095 lane: lane,
16096 action: action,
16097 eagerReducer: null,
16098 eagerState: null,
16099 next: null
16100 }; // Append the update to the end of the list.
16101
16102 var pending = queue.pending;
16103
16104 if (pending === null) {
16105 // This is the first update. Create a circular list.
16106 update.next = update;
16107 } else {
16108 update.next = pending.next;
16109 pending.next = update;
16110 }
16111
16112 queue.pending = update;
16113 var alternate = fiber.alternate;
16114
16115 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
16116 // This is a render phase update. Stash it in a lazily-created map of
16117 // queue -> linked list of updates. After this render pass, we'll restart
16118 // and apply the stashed updates on top of the work-in-progress hook.
16119 didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true;
16120 } else {
16121 if (fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes)) {
16122 // The queue is currently empty, which means we can eagerly compute the
16123 // next state before entering the render phase. If the new state is the
16124 // same as the current state, we may be able to bail out entirely.
16125 var lastRenderedReducer = queue.lastRenderedReducer;
16126
16127 if (lastRenderedReducer !== null) {
16128 var prevDispatcher;
16129
16130 {
16131 prevDispatcher = ReactCurrentDispatcher$1.current;
16132 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16133 }
16134
16135 try {
16136 var currentState = queue.lastRenderedState;
16137 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute
16138 // it, on the update object. If the reducer hasn't changed by the
16139 // time we enter the render phase, then the eager state can be used
16140 // without calling the reducer again.
16141
16142 update.eagerReducer = lastRenderedReducer;
16143 update.eagerState = eagerState;
16144
16145 if (objectIs(eagerState, currentState)) {
16146 // Fast path. We can bail out without scheduling React to re-render.
16147 // It's still possible that we'll need to rebase this update later,
16148 // if the component re-renders for a different reason and by that
16149 // time the reducer has changed.
16150 return;
16151 }
16152 } catch (error) {// Suppress the error. It will throw again in the render phase.
16153 } finally {
16154 {
16155 ReactCurrentDispatcher$1.current = prevDispatcher;
16156 }
16157 }
16158 }
16159 }
16160
16161 {
16162 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
16163 if ('undefined' !== typeof jest) {
16164 warnIfNotScopedWithMatchingAct(fiber);
16165 warnIfNotCurrentlyActingUpdatesInDev(fiber);
16166 }
16167 }
16168
16169 scheduleUpdateOnFiber(fiber, lane, eventTime);
16170 }
16171 }
16172
16173 var ContextOnlyDispatcher = {
16174 readContext: readContext,
16175 useCallback: throwInvalidHookError,
16176 useContext: throwInvalidHookError,
16177 useEffect: throwInvalidHookError,
16178 useImperativeHandle: throwInvalidHookError,
16179 useLayoutEffect: throwInvalidHookError,
16180 useMemo: throwInvalidHookError,
16181 useReducer: throwInvalidHookError,
16182 useRef: throwInvalidHookError,
16183 useState: throwInvalidHookError,
16184 useDebugValue: throwInvalidHookError,
16185 useDeferredValue: throwInvalidHookError,
16186 useTransition: throwInvalidHookError,
16187 useMutableSource: throwInvalidHookError,
16188 useOpaqueIdentifier: throwInvalidHookError,
16189 unstable_isNewReconciler: enableNewReconciler
16190 };
16191 var HooksDispatcherOnMountInDEV = null;
16192 var HooksDispatcherOnMountWithHookTypesInDEV = null;
16193 var HooksDispatcherOnUpdateInDEV = null;
16194 var HooksDispatcherOnRerenderInDEV = null;
16195 var InvalidNestedHooksDispatcherOnMountInDEV = null;
16196 var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
16197 var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
16198
16199 {
16200 var warnInvalidContextAccess = function () {
16201 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().');
16202 };
16203
16204 var warnInvalidHookAccess = function () {
16205 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');
16206 };
16207
16208 HooksDispatcherOnMountInDEV = {
16209 readContext: function (context, observedBits) {
16210 return readContext(context, observedBits);
16211 },
16212 useCallback: function (callback, deps) {
16213 currentHookNameInDev = 'useCallback';
16214 mountHookTypesDev();
16215 checkDepsAreArrayDev(deps);
16216 return mountCallback(callback, deps);
16217 },
16218 useContext: function (context, observedBits) {
16219 currentHookNameInDev = 'useContext';
16220 mountHookTypesDev();
16221 return readContext(context, observedBits);
16222 },
16223 useEffect: function (create, deps) {
16224 currentHookNameInDev = 'useEffect';
16225 mountHookTypesDev();
16226 checkDepsAreArrayDev(deps);
16227 return mountEffect(create, deps);
16228 },
16229 useImperativeHandle: function (ref, create, deps) {
16230 currentHookNameInDev = 'useImperativeHandle';
16231 mountHookTypesDev();
16232 checkDepsAreArrayDev(deps);
16233 return mountImperativeHandle(ref, create, deps);
16234 },
16235 useLayoutEffect: function (create, deps) {
16236 currentHookNameInDev = 'useLayoutEffect';
16237 mountHookTypesDev();
16238 checkDepsAreArrayDev(deps);
16239 return mountLayoutEffect(create, deps);
16240 },
16241 useMemo: function (create, deps) {
16242 currentHookNameInDev = 'useMemo';
16243 mountHookTypesDev();
16244 checkDepsAreArrayDev(deps);
16245 var prevDispatcher = ReactCurrentDispatcher$1.current;
16246 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16247
16248 try {
16249 return mountMemo(create, deps);
16250 } finally {
16251 ReactCurrentDispatcher$1.current = prevDispatcher;
16252 }
16253 },
16254 useReducer: function (reducer, initialArg, init) {
16255 currentHookNameInDev = 'useReducer';
16256 mountHookTypesDev();
16257 var prevDispatcher = ReactCurrentDispatcher$1.current;
16258 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16259
16260 try {
16261 return mountReducer(reducer, initialArg, init);
16262 } finally {
16263 ReactCurrentDispatcher$1.current = prevDispatcher;
16264 }
16265 },
16266 useRef: function (initialValue) {
16267 currentHookNameInDev = 'useRef';
16268 mountHookTypesDev();
16269 return mountRef(initialValue);
16270 },
16271 useState: function (initialState) {
16272 currentHookNameInDev = 'useState';
16273 mountHookTypesDev();
16274 var prevDispatcher = ReactCurrentDispatcher$1.current;
16275 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16276
16277 try {
16278 return mountState(initialState);
16279 } finally {
16280 ReactCurrentDispatcher$1.current = prevDispatcher;
16281 }
16282 },
16283 useDebugValue: function (value, formatterFn) {
16284 currentHookNameInDev = 'useDebugValue';
16285 mountHookTypesDev();
16286 return mountDebugValue();
16287 },
16288 useDeferredValue: function (value) {
16289 currentHookNameInDev = 'useDeferredValue';
16290 mountHookTypesDev();
16291 return mountDeferredValue(value);
16292 },
16293 useTransition: function () {
16294 currentHookNameInDev = 'useTransition';
16295 mountHookTypesDev();
16296 return mountTransition();
16297 },
16298 useMutableSource: function (source, getSnapshot, subscribe) {
16299 currentHookNameInDev = 'useMutableSource';
16300 mountHookTypesDev();
16301 return mountMutableSource(source, getSnapshot, subscribe);
16302 },
16303 useOpaqueIdentifier: function () {
16304 currentHookNameInDev = 'useOpaqueIdentifier';
16305 mountHookTypesDev();
16306 return mountOpaqueIdentifier();
16307 },
16308 unstable_isNewReconciler: enableNewReconciler
16309 };
16310 HooksDispatcherOnMountWithHookTypesInDEV = {
16311 readContext: function (context, observedBits) {
16312 return readContext(context, observedBits);
16313 },
16314 useCallback: function (callback, deps) {
16315 currentHookNameInDev = 'useCallback';
16316 updateHookTypesDev();
16317 return mountCallback(callback, deps);
16318 },
16319 useContext: function (context, observedBits) {
16320 currentHookNameInDev = 'useContext';
16321 updateHookTypesDev();
16322 return readContext(context, observedBits);
16323 },
16324 useEffect: function (create, deps) {
16325 currentHookNameInDev = 'useEffect';
16326 updateHookTypesDev();
16327 return mountEffect(create, deps);
16328 },
16329 useImperativeHandle: function (ref, create, deps) {
16330 currentHookNameInDev = 'useImperativeHandle';
16331 updateHookTypesDev();
16332 return mountImperativeHandle(ref, create, deps);
16333 },
16334 useLayoutEffect: function (create, deps) {
16335 currentHookNameInDev = 'useLayoutEffect';
16336 updateHookTypesDev();
16337 return mountLayoutEffect(create, deps);
16338 },
16339 useMemo: function (create, deps) {
16340 currentHookNameInDev = 'useMemo';
16341 updateHookTypesDev();
16342 var prevDispatcher = ReactCurrentDispatcher$1.current;
16343 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16344
16345 try {
16346 return mountMemo(create, deps);
16347 } finally {
16348 ReactCurrentDispatcher$1.current = prevDispatcher;
16349 }
16350 },
16351 useReducer: function (reducer, initialArg, init) {
16352 currentHookNameInDev = 'useReducer';
16353 updateHookTypesDev();
16354 var prevDispatcher = ReactCurrentDispatcher$1.current;
16355 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16356
16357 try {
16358 return mountReducer(reducer, initialArg, init);
16359 } finally {
16360 ReactCurrentDispatcher$1.current = prevDispatcher;
16361 }
16362 },
16363 useRef: function (initialValue) {
16364 currentHookNameInDev = 'useRef';
16365 updateHookTypesDev();
16366 return mountRef(initialValue);
16367 },
16368 useState: function (initialState) {
16369 currentHookNameInDev = 'useState';
16370 updateHookTypesDev();
16371 var prevDispatcher = ReactCurrentDispatcher$1.current;
16372 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16373
16374 try {
16375 return mountState(initialState);
16376 } finally {
16377 ReactCurrentDispatcher$1.current = prevDispatcher;
16378 }
16379 },
16380 useDebugValue: function (value, formatterFn) {
16381 currentHookNameInDev = 'useDebugValue';
16382 updateHookTypesDev();
16383 return mountDebugValue();
16384 },
16385 useDeferredValue: function (value) {
16386 currentHookNameInDev = 'useDeferredValue';
16387 updateHookTypesDev();
16388 return mountDeferredValue(value);
16389 },
16390 useTransition: function () {
16391 currentHookNameInDev = 'useTransition';
16392 updateHookTypesDev();
16393 return mountTransition();
16394 },
16395 useMutableSource: function (source, getSnapshot, subscribe) {
16396 currentHookNameInDev = 'useMutableSource';
16397 updateHookTypesDev();
16398 return mountMutableSource(source, getSnapshot, subscribe);
16399 },
16400 useOpaqueIdentifier: function () {
16401 currentHookNameInDev = 'useOpaqueIdentifier';
16402 updateHookTypesDev();
16403 return mountOpaqueIdentifier();
16404 },
16405 unstable_isNewReconciler: enableNewReconciler
16406 };
16407 HooksDispatcherOnUpdateInDEV = {
16408 readContext: function (context, observedBits) {
16409 return readContext(context, observedBits);
16410 },
16411 useCallback: function (callback, deps) {
16412 currentHookNameInDev = 'useCallback';
16413 updateHookTypesDev();
16414 return updateCallback(callback, deps);
16415 },
16416 useContext: function (context, observedBits) {
16417 currentHookNameInDev = 'useContext';
16418 updateHookTypesDev();
16419 return readContext(context, observedBits);
16420 },
16421 useEffect: function (create, deps) {
16422 currentHookNameInDev = 'useEffect';
16423 updateHookTypesDev();
16424 return updateEffect(create, deps);
16425 },
16426 useImperativeHandle: function (ref, create, deps) {
16427 currentHookNameInDev = 'useImperativeHandle';
16428 updateHookTypesDev();
16429 return updateImperativeHandle(ref, create, deps);
16430 },
16431 useLayoutEffect: function (create, deps) {
16432 currentHookNameInDev = 'useLayoutEffect';
16433 updateHookTypesDev();
16434 return updateLayoutEffect(create, deps);
16435 },
16436 useMemo: function (create, deps) {
16437 currentHookNameInDev = 'useMemo';
16438 updateHookTypesDev();
16439 var prevDispatcher = ReactCurrentDispatcher$1.current;
16440 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16441
16442 try {
16443 return updateMemo(create, deps);
16444 } finally {
16445 ReactCurrentDispatcher$1.current = prevDispatcher;
16446 }
16447 },
16448 useReducer: function (reducer, initialArg, init) {
16449 currentHookNameInDev = 'useReducer';
16450 updateHookTypesDev();
16451 var prevDispatcher = ReactCurrentDispatcher$1.current;
16452 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16453
16454 try {
16455 return updateReducer(reducer, initialArg, init);
16456 } finally {
16457 ReactCurrentDispatcher$1.current = prevDispatcher;
16458 }
16459 },
16460 useRef: function (initialValue) {
16461 currentHookNameInDev = 'useRef';
16462 updateHookTypesDev();
16463 return updateRef();
16464 },
16465 useState: function (initialState) {
16466 currentHookNameInDev = 'useState';
16467 updateHookTypesDev();
16468 var prevDispatcher = ReactCurrentDispatcher$1.current;
16469 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16470
16471 try {
16472 return updateState(initialState);
16473 } finally {
16474 ReactCurrentDispatcher$1.current = prevDispatcher;
16475 }
16476 },
16477 useDebugValue: function (value, formatterFn) {
16478 currentHookNameInDev = 'useDebugValue';
16479 updateHookTypesDev();
16480 return updateDebugValue();
16481 },
16482 useDeferredValue: function (value) {
16483 currentHookNameInDev = 'useDeferredValue';
16484 updateHookTypesDev();
16485 return updateDeferredValue(value);
16486 },
16487 useTransition: function () {
16488 currentHookNameInDev = 'useTransition';
16489 updateHookTypesDev();
16490 return updateTransition();
16491 },
16492 useMutableSource: function (source, getSnapshot, subscribe) {
16493 currentHookNameInDev = 'useMutableSource';
16494 updateHookTypesDev();
16495 return updateMutableSource(source, getSnapshot, subscribe);
16496 },
16497 useOpaqueIdentifier: function () {
16498 currentHookNameInDev = 'useOpaqueIdentifier';
16499 updateHookTypesDev();
16500 return updateOpaqueIdentifier();
16501 },
16502 unstable_isNewReconciler: enableNewReconciler
16503 };
16504 HooksDispatcherOnRerenderInDEV = {
16505 readContext: function (context, observedBits) {
16506 return readContext(context, observedBits);
16507 },
16508 useCallback: function (callback, deps) {
16509 currentHookNameInDev = 'useCallback';
16510 updateHookTypesDev();
16511 return updateCallback(callback, deps);
16512 },
16513 useContext: function (context, observedBits) {
16514 currentHookNameInDev = 'useContext';
16515 updateHookTypesDev();
16516 return readContext(context, observedBits);
16517 },
16518 useEffect: function (create, deps) {
16519 currentHookNameInDev = 'useEffect';
16520 updateHookTypesDev();
16521 return updateEffect(create, deps);
16522 },
16523 useImperativeHandle: function (ref, create, deps) {
16524 currentHookNameInDev = 'useImperativeHandle';
16525 updateHookTypesDev();
16526 return updateImperativeHandle(ref, create, deps);
16527 },
16528 useLayoutEffect: function (create, deps) {
16529 currentHookNameInDev = 'useLayoutEffect';
16530 updateHookTypesDev();
16531 return updateLayoutEffect(create, deps);
16532 },
16533 useMemo: function (create, deps) {
16534 currentHookNameInDev = 'useMemo';
16535 updateHookTypesDev();
16536 var prevDispatcher = ReactCurrentDispatcher$1.current;
16537 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
16538
16539 try {
16540 return updateMemo(create, deps);
16541 } finally {
16542 ReactCurrentDispatcher$1.current = prevDispatcher;
16543 }
16544 },
16545 useReducer: function (reducer, initialArg, init) {
16546 currentHookNameInDev = 'useReducer';
16547 updateHookTypesDev();
16548 var prevDispatcher = ReactCurrentDispatcher$1.current;
16549 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
16550
16551 try {
16552 return rerenderReducer(reducer, initialArg, init);
16553 } finally {
16554 ReactCurrentDispatcher$1.current = prevDispatcher;
16555 }
16556 },
16557 useRef: function (initialValue) {
16558 currentHookNameInDev = 'useRef';
16559 updateHookTypesDev();
16560 return updateRef();
16561 },
16562 useState: function (initialState) {
16563 currentHookNameInDev = 'useState';
16564 updateHookTypesDev();
16565 var prevDispatcher = ReactCurrentDispatcher$1.current;
16566 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
16567
16568 try {
16569 return rerenderState(initialState);
16570 } finally {
16571 ReactCurrentDispatcher$1.current = prevDispatcher;
16572 }
16573 },
16574 useDebugValue: function (value, formatterFn) {
16575 currentHookNameInDev = 'useDebugValue';
16576 updateHookTypesDev();
16577 return updateDebugValue();
16578 },
16579 useDeferredValue: function (value) {
16580 currentHookNameInDev = 'useDeferredValue';
16581 updateHookTypesDev();
16582 return rerenderDeferredValue(value);
16583 },
16584 useTransition: function () {
16585 currentHookNameInDev = 'useTransition';
16586 updateHookTypesDev();
16587 return rerenderTransition();
16588 },
16589 useMutableSource: function (source, getSnapshot, subscribe) {
16590 currentHookNameInDev = 'useMutableSource';
16591 updateHookTypesDev();
16592 return updateMutableSource(source, getSnapshot, subscribe);
16593 },
16594 useOpaqueIdentifier: function () {
16595 currentHookNameInDev = 'useOpaqueIdentifier';
16596 updateHookTypesDev();
16597 return rerenderOpaqueIdentifier();
16598 },
16599 unstable_isNewReconciler: enableNewReconciler
16600 };
16601 InvalidNestedHooksDispatcherOnMountInDEV = {
16602 readContext: function (context, observedBits) {
16603 warnInvalidContextAccess();
16604 return readContext(context, observedBits);
16605 },
16606 useCallback: function (callback, deps) {
16607 currentHookNameInDev = 'useCallback';
16608 warnInvalidHookAccess();
16609 mountHookTypesDev();
16610 return mountCallback(callback, deps);
16611 },
16612 useContext: function (context, observedBits) {
16613 currentHookNameInDev = 'useContext';
16614 warnInvalidHookAccess();
16615 mountHookTypesDev();
16616 return readContext(context, observedBits);
16617 },
16618 useEffect: function (create, deps) {
16619 currentHookNameInDev = 'useEffect';
16620 warnInvalidHookAccess();
16621 mountHookTypesDev();
16622 return mountEffect(create, deps);
16623 },
16624 useImperativeHandle: function (ref, create, deps) {
16625 currentHookNameInDev = 'useImperativeHandle';
16626 warnInvalidHookAccess();
16627 mountHookTypesDev();
16628 return mountImperativeHandle(ref, create, deps);
16629 },
16630 useLayoutEffect: function (create, deps) {
16631 currentHookNameInDev = 'useLayoutEffect';
16632 warnInvalidHookAccess();
16633 mountHookTypesDev();
16634 return mountLayoutEffect(create, deps);
16635 },
16636 useMemo: function (create, deps) {
16637 currentHookNameInDev = 'useMemo';
16638 warnInvalidHookAccess();
16639 mountHookTypesDev();
16640 var prevDispatcher = ReactCurrentDispatcher$1.current;
16641 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16642
16643 try {
16644 return mountMemo(create, deps);
16645 } finally {
16646 ReactCurrentDispatcher$1.current = prevDispatcher;
16647 }
16648 },
16649 useReducer: function (reducer, initialArg, init) {
16650 currentHookNameInDev = 'useReducer';
16651 warnInvalidHookAccess();
16652 mountHookTypesDev();
16653 var prevDispatcher = ReactCurrentDispatcher$1.current;
16654 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16655
16656 try {
16657 return mountReducer(reducer, initialArg, init);
16658 } finally {
16659 ReactCurrentDispatcher$1.current = prevDispatcher;
16660 }
16661 },
16662 useRef: function (initialValue) {
16663 currentHookNameInDev = 'useRef';
16664 warnInvalidHookAccess();
16665 mountHookTypesDev();
16666 return mountRef(initialValue);
16667 },
16668 useState: function (initialState) {
16669 currentHookNameInDev = 'useState';
16670 warnInvalidHookAccess();
16671 mountHookTypesDev();
16672 var prevDispatcher = ReactCurrentDispatcher$1.current;
16673 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16674
16675 try {
16676 return mountState(initialState);
16677 } finally {
16678 ReactCurrentDispatcher$1.current = prevDispatcher;
16679 }
16680 },
16681 useDebugValue: function (value, formatterFn) {
16682 currentHookNameInDev = 'useDebugValue';
16683 warnInvalidHookAccess();
16684 mountHookTypesDev();
16685 return mountDebugValue();
16686 },
16687 useDeferredValue: function (value) {
16688 currentHookNameInDev = 'useDeferredValue';
16689 warnInvalidHookAccess();
16690 mountHookTypesDev();
16691 return mountDeferredValue(value);
16692 },
16693 useTransition: function () {
16694 currentHookNameInDev = 'useTransition';
16695 warnInvalidHookAccess();
16696 mountHookTypesDev();
16697 return mountTransition();
16698 },
16699 useMutableSource: function (source, getSnapshot, subscribe) {
16700 currentHookNameInDev = 'useMutableSource';
16701 warnInvalidHookAccess();
16702 mountHookTypesDev();
16703 return mountMutableSource(source, getSnapshot, subscribe);
16704 },
16705 useOpaqueIdentifier: function () {
16706 currentHookNameInDev = 'useOpaqueIdentifier';
16707 warnInvalidHookAccess();
16708 mountHookTypesDev();
16709 return mountOpaqueIdentifier();
16710 },
16711 unstable_isNewReconciler: enableNewReconciler
16712 };
16713 InvalidNestedHooksDispatcherOnUpdateInDEV = {
16714 readContext: function (context, observedBits) {
16715 warnInvalidContextAccess();
16716 return readContext(context, observedBits);
16717 },
16718 useCallback: function (callback, deps) {
16719 currentHookNameInDev = 'useCallback';
16720 warnInvalidHookAccess();
16721 updateHookTypesDev();
16722 return updateCallback(callback, deps);
16723 },
16724 useContext: function (context, observedBits) {
16725 currentHookNameInDev = 'useContext';
16726 warnInvalidHookAccess();
16727 updateHookTypesDev();
16728 return readContext(context, observedBits);
16729 },
16730 useEffect: function (create, deps) {
16731 currentHookNameInDev = 'useEffect';
16732 warnInvalidHookAccess();
16733 updateHookTypesDev();
16734 return updateEffect(create, deps);
16735 },
16736 useImperativeHandle: function (ref, create, deps) {
16737 currentHookNameInDev = 'useImperativeHandle';
16738 warnInvalidHookAccess();
16739 updateHookTypesDev();
16740 return updateImperativeHandle(ref, create, deps);
16741 },
16742 useLayoutEffect: function (create, deps) {
16743 currentHookNameInDev = 'useLayoutEffect';
16744 warnInvalidHookAccess();
16745 updateHookTypesDev();
16746 return updateLayoutEffect(create, deps);
16747 },
16748 useMemo: function (create, deps) {
16749 currentHookNameInDev = 'useMemo';
16750 warnInvalidHookAccess();
16751 updateHookTypesDev();
16752 var prevDispatcher = ReactCurrentDispatcher$1.current;
16753 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16754
16755 try {
16756 return updateMemo(create, deps);
16757 } finally {
16758 ReactCurrentDispatcher$1.current = prevDispatcher;
16759 }
16760 },
16761 useReducer: function (reducer, initialArg, init) {
16762 currentHookNameInDev = 'useReducer';
16763 warnInvalidHookAccess();
16764 updateHookTypesDev();
16765 var prevDispatcher = ReactCurrentDispatcher$1.current;
16766 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16767
16768 try {
16769 return updateReducer(reducer, initialArg, init);
16770 } finally {
16771 ReactCurrentDispatcher$1.current = prevDispatcher;
16772 }
16773 },
16774 useRef: function (initialValue) {
16775 currentHookNameInDev = 'useRef';
16776 warnInvalidHookAccess();
16777 updateHookTypesDev();
16778 return updateRef();
16779 },
16780 useState: function (initialState) {
16781 currentHookNameInDev = 'useState';
16782 warnInvalidHookAccess();
16783 updateHookTypesDev();
16784 var prevDispatcher = ReactCurrentDispatcher$1.current;
16785 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16786
16787 try {
16788 return updateState(initialState);
16789 } finally {
16790 ReactCurrentDispatcher$1.current = prevDispatcher;
16791 }
16792 },
16793 useDebugValue: function (value, formatterFn) {
16794 currentHookNameInDev = 'useDebugValue';
16795 warnInvalidHookAccess();
16796 updateHookTypesDev();
16797 return updateDebugValue();
16798 },
16799 useDeferredValue: function (value) {
16800 currentHookNameInDev = 'useDeferredValue';
16801 warnInvalidHookAccess();
16802 updateHookTypesDev();
16803 return updateDeferredValue(value);
16804 },
16805 useTransition: function () {
16806 currentHookNameInDev = 'useTransition';
16807 warnInvalidHookAccess();
16808 updateHookTypesDev();
16809 return updateTransition();
16810 },
16811 useMutableSource: function (source, getSnapshot, subscribe) {
16812 currentHookNameInDev = 'useMutableSource';
16813 warnInvalidHookAccess();
16814 updateHookTypesDev();
16815 return updateMutableSource(source, getSnapshot, subscribe);
16816 },
16817 useOpaqueIdentifier: function () {
16818 currentHookNameInDev = 'useOpaqueIdentifier';
16819 warnInvalidHookAccess();
16820 updateHookTypesDev();
16821 return updateOpaqueIdentifier();
16822 },
16823 unstable_isNewReconciler: enableNewReconciler
16824 };
16825 InvalidNestedHooksDispatcherOnRerenderInDEV = {
16826 readContext: function (context, observedBits) {
16827 warnInvalidContextAccess();
16828 return readContext(context, observedBits);
16829 },
16830 useCallback: function (callback, deps) {
16831 currentHookNameInDev = 'useCallback';
16832 warnInvalidHookAccess();
16833 updateHookTypesDev();
16834 return updateCallback(callback, deps);
16835 },
16836 useContext: function (context, observedBits) {
16837 currentHookNameInDev = 'useContext';
16838 warnInvalidHookAccess();
16839 updateHookTypesDev();
16840 return readContext(context, observedBits);
16841 },
16842 useEffect: function (create, deps) {
16843 currentHookNameInDev = 'useEffect';
16844 warnInvalidHookAccess();
16845 updateHookTypesDev();
16846 return updateEffect(create, deps);
16847 },
16848 useImperativeHandle: function (ref, create, deps) {
16849 currentHookNameInDev = 'useImperativeHandle';
16850 warnInvalidHookAccess();
16851 updateHookTypesDev();
16852 return updateImperativeHandle(ref, create, deps);
16853 },
16854 useLayoutEffect: function (create, deps) {
16855 currentHookNameInDev = 'useLayoutEffect';
16856 warnInvalidHookAccess();
16857 updateHookTypesDev();
16858 return updateLayoutEffect(create, deps);
16859 },
16860 useMemo: function (create, deps) {
16861 currentHookNameInDev = 'useMemo';
16862 warnInvalidHookAccess();
16863 updateHookTypesDev();
16864 var prevDispatcher = ReactCurrentDispatcher$1.current;
16865 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16866
16867 try {
16868 return updateMemo(create, deps);
16869 } finally {
16870 ReactCurrentDispatcher$1.current = prevDispatcher;
16871 }
16872 },
16873 useReducer: function (reducer, initialArg, init) {
16874 currentHookNameInDev = 'useReducer';
16875 warnInvalidHookAccess();
16876 updateHookTypesDev();
16877 var prevDispatcher = ReactCurrentDispatcher$1.current;
16878 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16879
16880 try {
16881 return rerenderReducer(reducer, initialArg, init);
16882 } finally {
16883 ReactCurrentDispatcher$1.current = prevDispatcher;
16884 }
16885 },
16886 useRef: function (initialValue) {
16887 currentHookNameInDev = 'useRef';
16888 warnInvalidHookAccess();
16889 updateHookTypesDev();
16890 return updateRef();
16891 },
16892 useState: function (initialState) {
16893 currentHookNameInDev = 'useState';
16894 warnInvalidHookAccess();
16895 updateHookTypesDev();
16896 var prevDispatcher = ReactCurrentDispatcher$1.current;
16897 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16898
16899 try {
16900 return rerenderState(initialState);
16901 } finally {
16902 ReactCurrentDispatcher$1.current = prevDispatcher;
16903 }
16904 },
16905 useDebugValue: function (value, formatterFn) {
16906 currentHookNameInDev = 'useDebugValue';
16907 warnInvalidHookAccess();
16908 updateHookTypesDev();
16909 return updateDebugValue();
16910 },
16911 useDeferredValue: function (value) {
16912 currentHookNameInDev = 'useDeferredValue';
16913 warnInvalidHookAccess();
16914 updateHookTypesDev();
16915 return rerenderDeferredValue(value);
16916 },
16917 useTransition: function () {
16918 currentHookNameInDev = 'useTransition';
16919 warnInvalidHookAccess();
16920 updateHookTypesDev();
16921 return rerenderTransition();
16922 },
16923 useMutableSource: function (source, getSnapshot, subscribe) {
16924 currentHookNameInDev = 'useMutableSource';
16925 warnInvalidHookAccess();
16926 updateHookTypesDev();
16927 return updateMutableSource(source, getSnapshot, subscribe);
16928 },
16929 useOpaqueIdentifier: function () {
16930 currentHookNameInDev = 'useOpaqueIdentifier';
16931 warnInvalidHookAccess();
16932 updateHookTypesDev();
16933 return rerenderOpaqueIdentifier();
16934 },
16935 unstable_isNewReconciler: enableNewReconciler
16936 };
16937 }
16938
16939 var now$1 = unstable_now;
16940 var commitTime = 0;
16941 var profilerStartTime = -1;
16942
16943 function getCommitTime() {
16944 return commitTime;
16945 }
16946
16947 function recordCommitTime() {
16948
16949 commitTime = now$1();
16950 }
16951
16952 function startProfilerTimer(fiber) {
16953
16954 profilerStartTime = now$1();
16955
16956 if (fiber.actualStartTime < 0) {
16957 fiber.actualStartTime = now$1();
16958 }
16959 }
16960
16961 function stopProfilerTimerIfRunning(fiber) {
16962
16963 profilerStartTime = -1;
16964 }
16965
16966 function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
16967
16968 if (profilerStartTime >= 0) {
16969 var elapsedTime = now$1() - profilerStartTime;
16970 fiber.actualDuration += elapsedTime;
16971
16972 if (overrideBaseTime) {
16973 fiber.selfBaseDuration = elapsedTime;
16974 }
16975
16976 profilerStartTime = -1;
16977 }
16978 }
16979
16980 function transferActualDuration(fiber) {
16981 // Transfer time spent rendering these children so we don't lose it
16982 // after we rerender. This is used as a helper in special cases
16983 // where we should count the work of multiple passes.
16984 var child = fiber.child;
16985
16986 while (child) {
16987 fiber.actualDuration += child.actualDuration;
16988 child = child.sibling;
16989 }
16990 }
16991
16992 var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
16993 var didReceiveUpdate = false;
16994 var didWarnAboutBadClass;
16995 var didWarnAboutModulePatternComponent;
16996 var didWarnAboutContextTypeOnFunctionComponent;
16997 var didWarnAboutGetDerivedStateOnFunctionComponent;
16998 var didWarnAboutFunctionRefs;
16999 var didWarnAboutReassigningProps;
17000 var didWarnAboutRevealOrder;
17001 var didWarnAboutTailOptions;
17002
17003 {
17004 didWarnAboutBadClass = {};
17005 didWarnAboutModulePatternComponent = {};
17006 didWarnAboutContextTypeOnFunctionComponent = {};
17007 didWarnAboutGetDerivedStateOnFunctionComponent = {};
17008 didWarnAboutFunctionRefs = {};
17009 didWarnAboutReassigningProps = false;
17010 didWarnAboutRevealOrder = {};
17011 didWarnAboutTailOptions = {};
17012 }
17013
17014 function reconcileChildren(current, workInProgress, nextChildren, renderLanes) {
17015 if (current === null) {
17016 // If this is a fresh new component that hasn't been rendered yet, we
17017 // won't update its child set by applying minimal side-effects. Instead,
17018 // we will add them all to the child before it gets rendered. That means
17019 // we can optimize this reconciliation pass by not tracking side-effects.
17020 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderLanes);
17021 } else {
17022 // If the current child is the same as the work in progress, it means that
17023 // we haven't yet started any work on these children. Therefore, we use
17024 // the clone algorithm to create a copy of all the current children.
17025 // If we had any progressed work already, that is invalid at this point so
17026 // let's throw it out.
17027 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderLanes);
17028 }
17029 }
17030
17031 function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes) {
17032 // This function is fork of reconcileChildren. It's used in cases where we
17033 // want to reconcile without matching against the existing set. This has the
17034 // effect of all current children being unmounted; even if the type and key
17035 // are the same, the old child is unmounted and a new child is created.
17036 //
17037 // To do this, we're going to go through the reconcile algorithm twice. In
17038 // the first pass, we schedule a deletion for all the current children by
17039 // passing null.
17040 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderLanes); // In the second pass, we mount the new children. The trick here is that we
17041 // pass null in place of where we usually pass the current child set. This has
17042 // the effect of remounting all children regardless of whether their
17043 // identities match.
17044
17045 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes);
17046 }
17047
17048 function updateForwardRef(current, workInProgress, Component, nextProps, renderLanes) {
17049 // TODO: current can be non-null here even if the component
17050 // hasn't yet mounted. This happens after the first render suspends.
17051 // We'll need to figure out if this is fine or can cause issues.
17052 {
17053 if (workInProgress.type !== workInProgress.elementType) {
17054 // Lazy component props can't be validated in createElement
17055 // because they're only guaranteed to be resolved here.
17056 var innerPropTypes = Component.propTypes;
17057
17058 if (innerPropTypes) {
17059 checkPropTypes(innerPropTypes, nextProps, // Resolved props
17060 'prop', getComponentName(Component));
17061 }
17062 }
17063 }
17064
17065 var render = Component.render;
17066 var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent
17067
17068 var nextChildren;
17069 prepareToReadContext(workInProgress, renderLanes);
17070
17071 {
17072 ReactCurrentOwner$1.current = workInProgress;
17073 setIsRendering(true);
17074 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes);
17075
17076 if ( workInProgress.mode & StrictMode) {
17077 disableLogs();
17078
17079 try {
17080 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes);
17081 } finally {
17082 reenableLogs();
17083 }
17084 }
17085
17086 setIsRendering(false);
17087 }
17088
17089 if (current !== null && !didReceiveUpdate) {
17090 bailoutHooks(current, workInProgress, renderLanes);
17091 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
17092 } // React DevTools reads this flag.
17093
17094
17095 workInProgress.flags |= PerformedWork;
17096 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
17097 return workInProgress.child;
17098 }
17099
17100 function updateMemoComponent(current, workInProgress, Component, nextProps, updateLanes, renderLanes) {
17101 if (current === null) {
17102 var type = Component.type;
17103
17104 if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either.
17105 Component.defaultProps === undefined) {
17106 var resolvedType = type;
17107
17108 {
17109 resolvedType = resolveFunctionForHotReloading(type);
17110 } // If this is a plain function component without default props,
17111 // and with only the default shallow comparison, we upgrade it
17112 // to a SimpleMemoComponent to allow fast path updates.
17113
17114
17115 workInProgress.tag = SimpleMemoComponent;
17116 workInProgress.type = resolvedType;
17117
17118 {
17119 validateFunctionComponentInDev(workInProgress, type);
17120 }
17121
17122 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, updateLanes, renderLanes);
17123 }
17124
17125 {
17126 var innerPropTypes = type.propTypes;
17127
17128 if (innerPropTypes) {
17129 // Inner memo component props aren't currently validated in createElement.
17130 // We could move it there, but we'd still need this for lazy code path.
17131 checkPropTypes(innerPropTypes, nextProps, // Resolved props
17132 'prop', getComponentName(type));
17133 }
17134 }
17135
17136 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, workInProgress, workInProgress.mode, renderLanes);
17137 child.ref = workInProgress.ref;
17138 child.return = workInProgress;
17139 workInProgress.child = child;
17140 return child;
17141 }
17142
17143 {
17144 var _type = Component.type;
17145 var _innerPropTypes = _type.propTypes;
17146
17147 if (_innerPropTypes) {
17148 // Inner memo component props aren't currently validated in createElement.
17149 // We could move it there, but we'd still need this for lazy code path.
17150 checkPropTypes(_innerPropTypes, nextProps, // Resolved props
17151 'prop', getComponentName(_type));
17152 }
17153 }
17154
17155 var currentChild = current.child; // This is always exactly one child
17156
17157 if (!includesSomeLane(updateLanes, renderLanes)) {
17158 // This will be the props with resolved defaultProps,
17159 // unlike current.memoizedProps which will be the unresolved ones.
17160 var prevProps = currentChild.memoizedProps; // Default to shallow comparison
17161
17162 var compare = Component.compare;
17163 compare = compare !== null ? compare : shallowEqual;
17164
17165 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
17166 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
17167 }
17168 } // React DevTools reads this flag.
17169
17170
17171 workInProgress.flags |= PerformedWork;
17172 var newChild = createWorkInProgress(currentChild, nextProps);
17173 newChild.ref = workInProgress.ref;
17174 newChild.return = workInProgress;
17175 workInProgress.child = newChild;
17176 return newChild;
17177 }
17178
17179 function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, updateLanes, renderLanes) {
17180 // TODO: current can be non-null here even if the component
17181 // hasn't yet mounted. This happens when the inner render suspends.
17182 // We'll need to figure out if this is fine or can cause issues.
17183 {
17184 if (workInProgress.type !== workInProgress.elementType) {
17185 // Lazy component props can't be validated in createElement
17186 // because they're only guaranteed to be resolved here.
17187 var outerMemoType = workInProgress.elementType;
17188
17189 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
17190 // We warn when you define propTypes on lazy()
17191 // so let's just skip over it to find memo() outer wrapper.
17192 // Inner props for memo are validated later.
17193 var lazyComponent = outerMemoType;
17194 var payload = lazyComponent._payload;
17195 var init = lazyComponent._init;
17196
17197 try {
17198 outerMemoType = init(payload);
17199 } catch (x) {
17200 outerMemoType = null;
17201 } // Inner propTypes will be validated in the function component path.
17202
17203
17204 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
17205
17206 if (outerPropTypes) {
17207 checkPropTypes(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
17208 'prop', getComponentName(outerMemoType));
17209 }
17210 }
17211 }
17212 }
17213
17214 if (current !== null) {
17215 var prevProps = current.memoizedProps;
17216
17217 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload.
17218 workInProgress.type === current.type )) {
17219 didReceiveUpdate = false;
17220
17221 if (!includesSomeLane(renderLanes, updateLanes)) {
17222 // The pending lanes were cleared at the beginning of beginWork. We're
17223 // about to bail out, but there might be other lanes that weren't
17224 // included in the current render. Usually, the priority level of the
17225 // remaining updates is accumlated during the evaluation of the
17226 // component (i.e. when processing the update queue). But since since
17227 // we're bailing out early *without* evaluating the component, we need
17228 // to account for it here, too. Reset to the value of the current fiber.
17229 // NOTE: This only applies to SimpleMemoComponent, not MemoComponent,
17230 // because a MemoComponent fiber does not have hooks or an update queue;
17231 // rather, it wraps around an inner component, which may or may not
17232 // contains hooks.
17233 // TODO: Move the reset at in beginWork out of the common path so that
17234 // this is no longer necessary.
17235 workInProgress.lanes = current.lanes;
17236 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
17237 } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) {
17238 // This is a special case that only exists for legacy mode.
17239 // See https://github.com/facebook/react/pull/19216.
17240 didReceiveUpdate = true;
17241 }
17242 }
17243 }
17244
17245 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes);
17246 }
17247
17248 function updateOffscreenComponent(current, workInProgress, renderLanes) {
17249 var nextProps = workInProgress.pendingProps;
17250 var nextChildren = nextProps.children;
17251 var prevState = current !== null ? current.memoizedState : null;
17252
17253 if (nextProps.mode === 'hidden' || nextProps.mode === 'unstable-defer-without-hiding') {
17254 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
17255 // In legacy sync mode, don't defer the subtree. Render it now.
17256 // TODO: Figure out what we should do in Blocking mode.
17257 var nextState = {
17258 baseLanes: NoLanes
17259 };
17260 workInProgress.memoizedState = nextState;
17261 pushRenderLanes(workInProgress, renderLanes);
17262 } else if (!includesSomeLane(renderLanes, OffscreenLane)) {
17263 var nextBaseLanes;
17264
17265 if (prevState !== null) {
17266 var prevBaseLanes = prevState.baseLanes;
17267 nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes);
17268 } else {
17269 nextBaseLanes = renderLanes;
17270 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
17271
17272
17273 {
17274 markSpawnedWork(OffscreenLane);
17275 }
17276
17277 workInProgress.lanes = workInProgress.childLanes = laneToLanes(OffscreenLane);
17278 var _nextState = {
17279 baseLanes: nextBaseLanes
17280 };
17281 workInProgress.memoizedState = _nextState; // We're about to bail out, but we need to push this to the stack anyway
17282 // to avoid a push/pop misalignment.
17283
17284 pushRenderLanes(workInProgress, nextBaseLanes);
17285 return null;
17286 } else {
17287 // Rendering at offscreen, so we can clear the base lanes.
17288 var _nextState2 = {
17289 baseLanes: NoLanes
17290 };
17291 workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out.
17292
17293 var subtreeRenderLanes = prevState !== null ? prevState.baseLanes : renderLanes;
17294 pushRenderLanes(workInProgress, subtreeRenderLanes);
17295 }
17296 } else {
17297 var _subtreeRenderLanes;
17298
17299 if (prevState !== null) {
17300 _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); // Since we're not hidden anymore, reset the state
17301
17302 workInProgress.memoizedState = null;
17303 } else {
17304 // We weren't previously hidden, and we still aren't, so there's nothing
17305 // special to do. Need to push to the stack regardless, though, to avoid
17306 // a push/pop misalignment.
17307 _subtreeRenderLanes = renderLanes;
17308 }
17309
17310 pushRenderLanes(workInProgress, _subtreeRenderLanes);
17311 }
17312
17313 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
17314 return workInProgress.child;
17315 } // Note: These happen to have identical begin phases, for now. We shouldn't hold
17316 // ourselves to this constraint, though. If the behavior diverges, we should
17317 // fork the function.
17318
17319
17320 var updateLegacyHiddenComponent = updateOffscreenComponent;
17321
17322 function updateFragment(current, workInProgress, renderLanes) {
17323 var nextChildren = workInProgress.pendingProps;
17324 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
17325 return workInProgress.child;
17326 }
17327
17328 function updateMode(current, workInProgress, renderLanes) {
17329 var nextChildren = workInProgress.pendingProps.children;
17330 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
17331 return workInProgress.child;
17332 }
17333
17334 function updateProfiler(current, workInProgress, renderLanes) {
17335 {
17336 workInProgress.flags |= Update; // Reset effect durations for the next eventual effect phase.
17337 // These are reset during render to allow the DevTools commit hook a chance to read them,
17338
17339 var stateNode = workInProgress.stateNode;
17340 stateNode.effectDuration = 0;
17341 stateNode.passiveEffectDuration = 0;
17342 }
17343
17344 var nextProps = workInProgress.pendingProps;
17345 var nextChildren = nextProps.children;
17346 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
17347 return workInProgress.child;
17348 }
17349
17350 function markRef(current, workInProgress) {
17351 var ref = workInProgress.ref;
17352
17353 if (current === null && ref !== null || current !== null && current.ref !== ref) {
17354 // Schedule a Ref effect
17355 workInProgress.flags |= Ref;
17356 }
17357 }
17358
17359 function updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes) {
17360 {
17361 if (workInProgress.type !== workInProgress.elementType) {
17362 // Lazy component props can't be validated in createElement
17363 // because they're only guaranteed to be resolved here.
17364 var innerPropTypes = Component.propTypes;
17365
17366 if (innerPropTypes) {
17367 checkPropTypes(innerPropTypes, nextProps, // Resolved props
17368 'prop', getComponentName(Component));
17369 }
17370 }
17371 }
17372
17373 var context;
17374
17375 {
17376 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
17377 context = getMaskedContext(workInProgress, unmaskedContext);
17378 }
17379
17380 var nextChildren;
17381 prepareToReadContext(workInProgress, renderLanes);
17382
17383 {
17384 ReactCurrentOwner$1.current = workInProgress;
17385 setIsRendering(true);
17386 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes);
17387
17388 if ( workInProgress.mode & StrictMode) {
17389 disableLogs();
17390
17391 try {
17392 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes);
17393 } finally {
17394 reenableLogs();
17395 }
17396 }
17397
17398 setIsRendering(false);
17399 }
17400
17401 if (current !== null && !didReceiveUpdate) {
17402 bailoutHooks(current, workInProgress, renderLanes);
17403 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
17404 } // React DevTools reads this flag.
17405
17406
17407 workInProgress.flags |= PerformedWork;
17408 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
17409 return workInProgress.child;
17410 }
17411
17412 function updateClassComponent(current, workInProgress, Component, nextProps, renderLanes) {
17413 {
17414 if (workInProgress.type !== workInProgress.elementType) {
17415 // Lazy component props can't be validated in createElement
17416 // because they're only guaranteed to be resolved here.
17417 var innerPropTypes = Component.propTypes;
17418
17419 if (innerPropTypes) {
17420 checkPropTypes(innerPropTypes, nextProps, // Resolved props
17421 'prop', getComponentName(Component));
17422 }
17423 }
17424 } // Push context providers early to prevent context stack mismatches.
17425 // During mounting we don't know the child context yet as the instance doesn't exist.
17426 // We will invalidate the child context in finishClassComponent() right after rendering.
17427
17428
17429 var hasContext;
17430
17431 if (isContextProvider(Component)) {
17432 hasContext = true;
17433 pushContextProvider(workInProgress);
17434 } else {
17435 hasContext = false;
17436 }
17437
17438 prepareToReadContext(workInProgress, renderLanes);
17439 var instance = workInProgress.stateNode;
17440 var shouldUpdate;
17441
17442 if (instance === null) {
17443 if (current !== null) {
17444 // A class component without an instance only mounts if it suspended
17445 // inside a non-concurrent tree, in an inconsistent state. We want to
17446 // treat it like a new mount, even though an empty version of it already
17447 // committed. Disconnect the alternate pointers.
17448 current.alternate = null;
17449 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
17450
17451 workInProgress.flags |= Placement;
17452 } // In the initial pass we might need to construct the instance.
17453
17454
17455 constructClassInstance(workInProgress, Component, nextProps);
17456 mountClassInstance(workInProgress, Component, nextProps, renderLanes);
17457 shouldUpdate = true;
17458 } else if (current === null) {
17459 // In a resume, we'll already have an instance we can reuse.
17460 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderLanes);
17461 } else {
17462 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderLanes);
17463 }
17464
17465 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes);
17466
17467 {
17468 var inst = workInProgress.stateNode;
17469
17470 if (shouldUpdate && inst.props !== nextProps) {
17471 if (!didWarnAboutReassigningProps) {
17472 error('It looks like %s is reassigning its own `this.props` while rendering. ' + 'This is not supported and can lead to confusing bugs.', getComponentName(workInProgress.type) || 'a component');
17473 }
17474
17475 didWarnAboutReassigningProps = true;
17476 }
17477 }
17478
17479 return nextUnitOfWork;
17480 }
17481
17482 function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes) {
17483 // Refs should update even if shouldComponentUpdate returns false
17484 markRef(current, workInProgress);
17485 var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags;
17486
17487 if (!shouldUpdate && !didCaptureError) {
17488 // Context providers should defer to sCU for rendering
17489 if (hasContext) {
17490 invalidateContextProvider(workInProgress, Component, false);
17491 }
17492
17493 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
17494 }
17495
17496 var instance = workInProgress.stateNode; // Rerender
17497
17498 ReactCurrentOwner$1.current = workInProgress;
17499 var nextChildren;
17500
17501 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
17502 // If we captured an error, but getDerivedStateFromError is not defined,
17503 // unmount all the children. componentDidCatch will schedule an update to
17504 // re-render a fallback. This is temporary until we migrate everyone to
17505 // the new API.
17506 // TODO: Warn in a future release.
17507 nextChildren = null;
17508
17509 {
17510 stopProfilerTimerIfRunning();
17511 }
17512 } else {
17513 {
17514 setIsRendering(true);
17515 nextChildren = instance.render();
17516
17517 if ( workInProgress.mode & StrictMode) {
17518 disableLogs();
17519
17520 try {
17521 instance.render();
17522 } finally {
17523 reenableLogs();
17524 }
17525 }
17526
17527 setIsRendering(false);
17528 }
17529 } // React DevTools reads this flag.
17530
17531
17532 workInProgress.flags |= PerformedWork;
17533
17534 if (current !== null && didCaptureError) {
17535 // If we're recovering from an error, reconcile without reusing any of
17536 // the existing children. Conceptually, the normal children and the children
17537 // that are shown on error are two different sets, so we shouldn't reuse
17538 // normal children even if their identities match.
17539 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes);
17540 } else {
17541 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
17542 } // Memoize state using the values we just used to render.
17543 // TODO: Restructure so we never read values from the instance.
17544
17545
17546 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.
17547
17548 if (hasContext) {
17549 invalidateContextProvider(workInProgress, Component, true);
17550 }
17551
17552 return workInProgress.child;
17553 }
17554
17555 function pushHostRootContext(workInProgress) {
17556 var root = workInProgress.stateNode;
17557
17558 if (root.pendingContext) {
17559 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
17560 } else if (root.context) {
17561 // Should always be set
17562 pushTopLevelContextObject(workInProgress, root.context, false);
17563 }
17564
17565 pushHostContainer(workInProgress, root.containerInfo);
17566 }
17567
17568 function updateHostRoot(current, workInProgress, renderLanes) {
17569 pushHostRootContext(workInProgress);
17570 var updateQueue = workInProgress.updateQueue;
17571
17572 if (!(current !== null && updateQueue !== null)) {
17573 {
17574 throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." );
17575 }
17576 }
17577
17578 var nextProps = workInProgress.pendingProps;
17579 var prevState = workInProgress.memoizedState;
17580 var prevChildren = prevState !== null ? prevState.element : null;
17581 cloneUpdateQueue(current, workInProgress);
17582 processUpdateQueue(workInProgress, nextProps, null, renderLanes);
17583 var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property
17584 // being called "element".
17585
17586 var nextChildren = nextState.element;
17587
17588 if (nextChildren === prevChildren) {
17589 resetHydrationState();
17590 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
17591 }
17592
17593 var root = workInProgress.stateNode;
17594
17595 if (root.hydrate && enterHydrationState(workInProgress)) {
17596 // If we don't have any current children this might be the first pass.
17597 // We always try to hydrate. If this isn't a hydration pass there won't
17598 // be any children to hydrate which is effectively the same thing as
17599 // not hydrating.
17600 {
17601 var mutableSourceEagerHydrationData = root.mutableSourceEagerHydrationData;
17602
17603 if (mutableSourceEagerHydrationData != null) {
17604 for (var i = 0; i < mutableSourceEagerHydrationData.length; i += 2) {
17605 var mutableSource = mutableSourceEagerHydrationData[i];
17606 var version = mutableSourceEagerHydrationData[i + 1];
17607 setWorkInProgressVersion(mutableSource, version);
17608 }
17609 }
17610 }
17611
17612 var child = mountChildFibers(workInProgress, null, nextChildren, renderLanes);
17613 workInProgress.child = child;
17614 var node = child;
17615
17616 while (node) {
17617 // Mark each child as hydrating. This is a fast path to know whether this
17618 // tree is part of a hydrating tree. This is used to determine if a child
17619 // node has fully mounted yet, and for scheduling event replaying.
17620 // Conceptually this is similar to Placement in that a new subtree is
17621 // inserted into the React tree here. It just happens to not need DOM
17622 // mutations because it already exists.
17623 node.flags = node.flags & ~Placement | Hydrating;
17624 node = node.sibling;
17625 }
17626 } else {
17627 // Otherwise reset hydration state in case we aborted and resumed another
17628 // root.
17629 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
17630 resetHydrationState();
17631 }
17632
17633 return workInProgress.child;
17634 }
17635
17636 function updateHostComponent(current, workInProgress, renderLanes) {
17637 pushHostContext(workInProgress);
17638
17639 if (current === null) {
17640 tryToClaimNextHydratableInstance(workInProgress);
17641 }
17642
17643 var type = workInProgress.type;
17644 var nextProps = workInProgress.pendingProps;
17645 var prevProps = current !== null ? current.memoizedProps : null;
17646 var nextChildren = nextProps.children;
17647 var isDirectTextChild = shouldSetTextContent(type, nextProps);
17648
17649 if (isDirectTextChild) {
17650 // We special case a direct text child of a host node. This is a common
17651 // case. We won't handle it as a reified child. We will instead handle
17652 // this in the host environment that also has access to this prop. That
17653 // avoids allocating another HostText fiber and traversing it.
17654 nextChildren = null;
17655 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
17656 // If we're switching from a direct text child to a normal child, or to
17657 // empty, we need to schedule the text content to be reset.
17658 workInProgress.flags |= ContentReset;
17659 }
17660
17661 markRef(current, workInProgress);
17662 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
17663 return workInProgress.child;
17664 }
17665
17666 function updateHostText(current, workInProgress) {
17667 if (current === null) {
17668 tryToClaimNextHydratableInstance(workInProgress);
17669 } // Nothing to do here. This is terminal. We'll do the completion step
17670 // immediately after.
17671
17672
17673 return null;
17674 }
17675
17676 function mountLazyComponent(_current, workInProgress, elementType, updateLanes, renderLanes) {
17677 if (_current !== null) {
17678 // A lazy component only mounts if it suspended inside a non-
17679 // concurrent tree, in an inconsistent state. We want to treat it like
17680 // a new mount, even though an empty version of it already committed.
17681 // Disconnect the alternate pointers.
17682 _current.alternate = null;
17683 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
17684
17685 workInProgress.flags |= Placement;
17686 }
17687
17688 var props = workInProgress.pendingProps;
17689 var lazyComponent = elementType;
17690 var payload = lazyComponent._payload;
17691 var init = lazyComponent._init;
17692 var Component = init(payload); // Store the unwrapped component in the type.
17693
17694 workInProgress.type = Component;
17695 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
17696 var resolvedProps = resolveDefaultProps(Component, props);
17697 var child;
17698
17699 switch (resolvedTag) {
17700 case FunctionComponent:
17701 {
17702 {
17703 validateFunctionComponentInDev(workInProgress, Component);
17704 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
17705 }
17706
17707 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderLanes);
17708 return child;
17709 }
17710
17711 case ClassComponent:
17712 {
17713 {
17714 workInProgress.type = Component = resolveClassForHotReloading(Component);
17715 }
17716
17717 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderLanes);
17718 return child;
17719 }
17720
17721 case ForwardRef:
17722 {
17723 {
17724 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
17725 }
17726
17727 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderLanes);
17728 return child;
17729 }
17730
17731 case MemoComponent:
17732 {
17733 {
17734 if (workInProgress.type !== workInProgress.elementType) {
17735 var outerPropTypes = Component.propTypes;
17736
17737 if (outerPropTypes) {
17738 checkPropTypes(outerPropTypes, resolvedProps, // Resolved for outer only
17739 'prop', getComponentName(Component));
17740 }
17741 }
17742 }
17743
17744 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
17745 updateLanes, renderLanes);
17746 return child;
17747 }
17748 }
17749
17750 var hint = '';
17751
17752 {
17753 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
17754 hint = ' Did you wrap a component in React.lazy() more than once?';
17755 }
17756 } // This message intentionally doesn't mention ForwardRef or MemoComponent
17757 // because the fact that it's a separate type of work is an
17758 // implementation detail.
17759
17760
17761 {
17762 {
17763 throw Error( "Element type is invalid. Received a promise that resolves to: " + Component + ". Lazy element type must resolve to a class or function." + hint );
17764 }
17765 }
17766 }
17767
17768 function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderLanes) {
17769 if (_current !== null) {
17770 // An incomplete component only mounts if it suspended inside a non-
17771 // concurrent tree, in an inconsistent state. We want to treat it like
17772 // a new mount, even though an empty version of it already committed.
17773 // Disconnect the alternate pointers.
17774 _current.alternate = null;
17775 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
17776
17777 workInProgress.flags |= Placement;
17778 } // Promote the fiber to a class and try rendering again.
17779
17780
17781 workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent`
17782 // Push context providers early to prevent context stack mismatches.
17783 // During mounting we don't know the child context yet as the instance doesn't exist.
17784 // We will invalidate the child context in finishClassComponent() right after rendering.
17785
17786 var hasContext;
17787
17788 if (isContextProvider(Component)) {
17789 hasContext = true;
17790 pushContextProvider(workInProgress);
17791 } else {
17792 hasContext = false;
17793 }
17794
17795 prepareToReadContext(workInProgress, renderLanes);
17796 constructClassInstance(workInProgress, Component, nextProps);
17797 mountClassInstance(workInProgress, Component, nextProps, renderLanes);
17798 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes);
17799 }
17800
17801 function mountIndeterminateComponent(_current, workInProgress, Component, renderLanes) {
17802 if (_current !== null) {
17803 // An indeterminate component only mounts if it suspended inside a non-
17804 // concurrent tree, in an inconsistent state. We want to treat it like
17805 // a new mount, even though an empty version of it already committed.
17806 // Disconnect the alternate pointers.
17807 _current.alternate = null;
17808 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
17809
17810 workInProgress.flags |= Placement;
17811 }
17812
17813 var props = workInProgress.pendingProps;
17814 var context;
17815
17816 {
17817 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
17818 context = getMaskedContext(workInProgress, unmaskedContext);
17819 }
17820
17821 prepareToReadContext(workInProgress, renderLanes);
17822 var value;
17823
17824 {
17825 if (Component.prototype && typeof Component.prototype.render === 'function') {
17826 var componentName = getComponentName(Component) || 'Unknown';
17827
17828 if (!didWarnAboutBadClass[componentName]) {
17829 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);
17830
17831 didWarnAboutBadClass[componentName] = true;
17832 }
17833 }
17834
17835 if (workInProgress.mode & StrictMode) {
17836 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
17837 }
17838
17839 setIsRendering(true);
17840 ReactCurrentOwner$1.current = workInProgress;
17841 value = renderWithHooks(null, workInProgress, Component, props, context, renderLanes);
17842 setIsRendering(false);
17843 } // React DevTools reads this flag.
17844
17845
17846 workInProgress.flags |= PerformedWork;
17847
17848 {
17849 // Support for module components is deprecated and is removed behind a flag.
17850 // Whether or not it would crash later, we want to show a good message in DEV first.
17851 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
17852 var _componentName = getComponentName(Component) || 'Unknown';
17853
17854 if (!didWarnAboutModulePatternComponent[_componentName]) {
17855 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);
17856
17857 didWarnAboutModulePatternComponent[_componentName] = true;
17858 }
17859 }
17860 }
17861
17862 if ( // Run these checks in production only if the flag is off.
17863 // Eventually we'll delete this branch altogether.
17864 typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
17865 {
17866 var _componentName2 = getComponentName(Component) || 'Unknown';
17867
17868 if (!didWarnAboutModulePatternComponent[_componentName2]) {
17869 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);
17870
17871 didWarnAboutModulePatternComponent[_componentName2] = true;
17872 }
17873 } // Proceed under the assumption that this is a class instance
17874
17875
17876 workInProgress.tag = ClassComponent; // Throw out any hooks that were used.
17877
17878 workInProgress.memoizedState = null;
17879 workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches.
17880 // During mounting we don't know the child context yet as the instance doesn't exist.
17881 // We will invalidate the child context in finishClassComponent() right after rendering.
17882
17883 var hasContext = false;
17884
17885 if (isContextProvider(Component)) {
17886 hasContext = true;
17887 pushContextProvider(workInProgress);
17888 } else {
17889 hasContext = false;
17890 }
17891
17892 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
17893 initializeUpdateQueue(workInProgress);
17894 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
17895
17896 if (typeof getDerivedStateFromProps === 'function') {
17897 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
17898 }
17899
17900 adoptClassInstance(workInProgress, value);
17901 mountClassInstance(workInProgress, Component, props, renderLanes);
17902 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes);
17903 } else {
17904 // Proceed under the assumption that this is a function component
17905 workInProgress.tag = FunctionComponent;
17906
17907 {
17908
17909 if ( workInProgress.mode & StrictMode) {
17910 disableLogs();
17911
17912 try {
17913 value = renderWithHooks(null, workInProgress, Component, props, context, renderLanes);
17914 } finally {
17915 reenableLogs();
17916 }
17917 }
17918 }
17919
17920 reconcileChildren(null, workInProgress, value, renderLanes);
17921
17922 {
17923 validateFunctionComponentInDev(workInProgress, Component);
17924 }
17925
17926 return workInProgress.child;
17927 }
17928 }
17929
17930 function validateFunctionComponentInDev(workInProgress, Component) {
17931 {
17932 if (Component) {
17933 if (Component.childContextTypes) {
17934 error('%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component');
17935 }
17936 }
17937
17938 if (workInProgress.ref !== null) {
17939 var info = '';
17940 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
17941
17942 if (ownerName) {
17943 info += '\n\nCheck the render method of `' + ownerName + '`.';
17944 }
17945
17946 var warningKey = ownerName || workInProgress._debugID || '';
17947 var debugSource = workInProgress._debugSource;
17948
17949 if (debugSource) {
17950 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
17951 }
17952
17953 if (!didWarnAboutFunctionRefs[warningKey]) {
17954 didWarnAboutFunctionRefs[warningKey] = true;
17955
17956 error('Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
17957 }
17958 }
17959
17960 if (typeof Component.getDerivedStateFromProps === 'function') {
17961 var _componentName3 = getComponentName(Component) || 'Unknown';
17962
17963 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) {
17964 error('%s: Function components do not support getDerivedStateFromProps.', _componentName3);
17965
17966 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true;
17967 }
17968 }
17969
17970 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
17971 var _componentName4 = getComponentName(Component) || 'Unknown';
17972
17973 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) {
17974 error('%s: Function components do not support contextType.', _componentName4);
17975
17976 didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true;
17977 }
17978 }
17979 }
17980 }
17981
17982 var SUSPENDED_MARKER = {
17983 dehydrated: null,
17984 retryLane: NoLane
17985 };
17986
17987 function mountSuspenseOffscreenState(renderLanes) {
17988 return {
17989 baseLanes: renderLanes
17990 };
17991 }
17992
17993 function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) {
17994 return {
17995 baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes)
17996 };
17997 } // TODO: Probably should inline this back
17998
17999
18000 function shouldRemainOnFallback(suspenseContext, current, workInProgress, renderLanes) {
18001 // If we're already showing a fallback, there are cases where we need to
18002 // remain on that fallback regardless of whether the content has resolved.
18003 // For example, SuspenseList coordinates when nested content appears.
18004 if (current !== null) {
18005 var suspenseState = current.memoizedState;
18006
18007 if (suspenseState === null) {
18008 // Currently showing content. Don't hide it, even if ForceSuspenseFallack
18009 // is true. More precise name might be "ForceRemainSuspenseFallback".
18010 // Note: This is a factoring smell. Can't remain on a fallback if there's
18011 // no fallback to remain on.
18012 return false;
18013 }
18014 } // Not currently showing content. Consult the Suspense context.
18015
18016
18017 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
18018 }
18019
18020 function getRemainingWorkInPrimaryTree(current, renderLanes) {
18021 // TODO: Should not remove render lanes that were pinged during this render
18022 return removeLanes(current.childLanes, renderLanes);
18023 }
18024
18025 function updateSuspenseComponent(current, workInProgress, renderLanes) {
18026 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
18027
18028 {
18029 if (shouldSuspend(workInProgress)) {
18030 workInProgress.flags |= DidCapture;
18031 }
18032 }
18033
18034 var suspenseContext = suspenseStackCursor.current;
18035 var showFallback = false;
18036 var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags;
18037
18038 if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) {
18039 // Something in this boundary's subtree already suspended. Switch to
18040 // rendering the fallback children.
18041 showFallback = true;
18042 workInProgress.flags &= ~DidCapture;
18043 } else {
18044 // Attempting the main content
18045 if (current === null || current.memoizedState !== null) {
18046 // This is a new mount or this boundary is already showing a fallback state.
18047 // Mark this subtree context as having at least one invisible parent that could
18048 // handle the fallback state.
18049 // Boundaries without fallbacks or should be avoided are not considered since
18050 // they cannot handle preferred fallback states.
18051 if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) {
18052 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
18053 }
18054 }
18055 }
18056
18057 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
18058 pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense
18059 // boundary's children. This involves some custom reconcilation logic. Two
18060 // main reasons this is so complicated.
18061 //
18062 // First, Legacy Mode has different semantics for backwards compatibility. The
18063 // primary tree will commit in an inconsistent state, so when we do the
18064 // second pass to render the fallback, we do some exceedingly, uh, clever
18065 // hacks to make that not totally break. Like transferring effects and
18066 // deletions from hidden tree. In Concurrent Mode, it's much simpler,
18067 // because we bailout on the primary tree completely and leave it in its old
18068 // state, no effects. Same as what we do for Offscreen (except that
18069 // Offscreen doesn't have the first render pass).
18070 //
18071 // Second is hydration. During hydration, the Suspense fiber has a slightly
18072 // different layout, where the child points to a dehydrated fragment, which
18073 // contains the DOM rendered by the server.
18074 //
18075 // Third, even if you set all that aside, Suspense is like error boundaries in
18076 // that we first we try to render one tree, and if that fails, we render again
18077 // and switch to a different tree. Like a try/catch block. So we have to track
18078 // which branch we're currently rendering. Ideally we would model this using
18079 // a stack.
18080
18081 if (current === null) {
18082 // Initial mount
18083 // If we're currently hydrating, try to hydrate this boundary.
18084 // But only if this has a fallback.
18085 if (nextProps.fallback !== undefined) {
18086 tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component.
18087 }
18088
18089 var nextPrimaryChildren = nextProps.children;
18090 var nextFallbackChildren = nextProps.fallback;
18091
18092 if (showFallback) {
18093 var fallbackFragment = mountSuspenseFallbackChildren(workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes);
18094 var primaryChildFragment = workInProgress.child;
18095 primaryChildFragment.memoizedState = mountSuspenseOffscreenState(renderLanes);
18096 workInProgress.memoizedState = SUSPENDED_MARKER;
18097 return fallbackFragment;
18098 } else if (typeof nextProps.unstable_expectedLoadTime === 'number') {
18099 // This is a CPU-bound tree. Skip this tree and show a placeholder to
18100 // unblock the surrounding content. Then immediately retry after the
18101 // initial commit.
18102 var _fallbackFragment = mountSuspenseFallbackChildren(workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes);
18103
18104 var _primaryChildFragment = workInProgress.child;
18105 _primaryChildFragment.memoizedState = mountSuspenseOffscreenState(renderLanes);
18106 workInProgress.memoizedState = SUSPENDED_MARKER; // Since nothing actually suspended, there will nothing to ping this to
18107 // get it started back up to attempt the next item. While in terms of
18108 // priority this work has the same priority as this current render, it's
18109 // not part of the same transition once the transition has committed. If
18110 // it's sync, we still want to yield so that it can be painted.
18111 // Conceptually, this is really the same as pinging. We can use any
18112 // RetryLane even if it's the one currently rendering since we're leaving
18113 // it behind on this node.
18114
18115 workInProgress.lanes = SomeRetryLane;
18116
18117 {
18118 markSpawnedWork(SomeRetryLane);
18119 }
18120
18121 return _fallbackFragment;
18122 } else {
18123 return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren, renderLanes);
18124 }
18125 } else {
18126 // This is an update.
18127 // If the current fiber has a SuspenseState, that means it's already showing
18128 // a fallback.
18129 var prevState = current.memoizedState;
18130
18131 if (prevState !== null) {
18132
18133 if (showFallback) {
18134 var _nextFallbackChildren2 = nextProps.fallback;
18135 var _nextPrimaryChildren2 = nextProps.children;
18136
18137 var _fallbackChildFragment = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren2, _nextFallbackChildren2, renderLanes);
18138
18139 var _primaryChildFragment3 = workInProgress.child;
18140 var prevOffscreenState = current.child.memoizedState;
18141 _primaryChildFragment3.memoizedState = prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(prevOffscreenState, renderLanes);
18142 _primaryChildFragment3.childLanes = getRemainingWorkInPrimaryTree(current, renderLanes);
18143 workInProgress.memoizedState = SUSPENDED_MARKER;
18144 return _fallbackChildFragment;
18145 } else {
18146 var _nextPrimaryChildren3 = nextProps.children;
18147
18148 var _primaryChildFragment4 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren3, renderLanes);
18149
18150 workInProgress.memoizedState = null;
18151 return _primaryChildFragment4;
18152 }
18153 } else {
18154 // The current tree is not already showing a fallback.
18155 if (showFallback) {
18156 // Timed out.
18157 var _nextFallbackChildren3 = nextProps.fallback;
18158 var _nextPrimaryChildren4 = nextProps.children;
18159
18160 var _fallbackChildFragment2 = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren4, _nextFallbackChildren3, renderLanes);
18161
18162 var _primaryChildFragment5 = workInProgress.child;
18163 var _prevOffscreenState = current.child.memoizedState;
18164 _primaryChildFragment5.memoizedState = _prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(_prevOffscreenState, renderLanes);
18165 _primaryChildFragment5.childLanes = getRemainingWorkInPrimaryTree(current, renderLanes); // Skip the primary children, and continue working on the
18166 // fallback children.
18167
18168 workInProgress.memoizedState = SUSPENDED_MARKER;
18169 return _fallbackChildFragment2;
18170 } else {
18171 // Still haven't timed out. Continue rendering the children, like we
18172 // normally do.
18173 var _nextPrimaryChildren5 = nextProps.children;
18174
18175 var _primaryChildFragment6 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren5, renderLanes);
18176
18177 workInProgress.memoizedState = null;
18178 return _primaryChildFragment6;
18179 }
18180 }
18181 }
18182 }
18183
18184 function mountSuspensePrimaryChildren(workInProgress, primaryChildren, renderLanes) {
18185 var mode = workInProgress.mode;
18186 var primaryChildProps = {
18187 mode: 'visible',
18188 children: primaryChildren
18189 };
18190 var primaryChildFragment = createFiberFromOffscreen(primaryChildProps, mode, renderLanes, null);
18191 primaryChildFragment.return = workInProgress;
18192 workInProgress.child = primaryChildFragment;
18193 return primaryChildFragment;
18194 }
18195
18196 function mountSuspenseFallbackChildren(workInProgress, primaryChildren, fallbackChildren, renderLanes) {
18197 var mode = workInProgress.mode;
18198 var progressedPrimaryFragment = workInProgress.child;
18199 var primaryChildProps = {
18200 mode: 'hidden',
18201 children: primaryChildren
18202 };
18203 var primaryChildFragment;
18204 var fallbackChildFragment;
18205
18206 if ((mode & BlockingMode) === NoMode && progressedPrimaryFragment !== null) {
18207 // In legacy mode, we commit the primary tree as if it successfully
18208 // completed, even though it's in an inconsistent state.
18209 primaryChildFragment = progressedPrimaryFragment;
18210 primaryChildFragment.childLanes = NoLanes;
18211 primaryChildFragment.pendingProps = primaryChildProps;
18212
18213 if ( workInProgress.mode & ProfileMode) {
18214 // Reset the durations from the first pass so they aren't included in the
18215 // final amounts. This seems counterintuitive, since we're intentionally
18216 // not measuring part of the render phase, but this makes it match what we
18217 // do in Concurrent Mode.
18218 primaryChildFragment.actualDuration = 0;
18219 primaryChildFragment.actualStartTime = -1;
18220 primaryChildFragment.selfBaseDuration = 0;
18221 primaryChildFragment.treeBaseDuration = 0;
18222 }
18223
18224 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null);
18225 } else {
18226 primaryChildFragment = createFiberFromOffscreen(primaryChildProps, mode, NoLanes, null);
18227 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null);
18228 }
18229
18230 primaryChildFragment.return = workInProgress;
18231 fallbackChildFragment.return = workInProgress;
18232 primaryChildFragment.sibling = fallbackChildFragment;
18233 workInProgress.child = primaryChildFragment;
18234 return fallbackChildFragment;
18235 }
18236
18237 function createWorkInProgressOffscreenFiber(current, offscreenProps) {
18238 // The props argument to `createWorkInProgress` is `any` typed, so we use this
18239 // wrapper function to constrain it.
18240 return createWorkInProgress(current, offscreenProps);
18241 }
18242
18243 function updateSuspensePrimaryChildren(current, workInProgress, primaryChildren, renderLanes) {
18244 var currentPrimaryChildFragment = current.child;
18245 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
18246 var primaryChildFragment = createWorkInProgressOffscreenFiber(currentPrimaryChildFragment, {
18247 mode: 'visible',
18248 children: primaryChildren
18249 });
18250
18251 if ((workInProgress.mode & BlockingMode) === NoMode) {
18252 primaryChildFragment.lanes = renderLanes;
18253 }
18254
18255 primaryChildFragment.return = workInProgress;
18256 primaryChildFragment.sibling = null;
18257
18258 if (currentFallbackChildFragment !== null) {
18259 // Delete the fallback child fragment
18260 currentFallbackChildFragment.nextEffect = null;
18261 currentFallbackChildFragment.flags = Deletion;
18262 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChildFragment;
18263 }
18264
18265 workInProgress.child = primaryChildFragment;
18266 return primaryChildFragment;
18267 }
18268
18269 function updateSuspenseFallbackChildren(current, workInProgress, primaryChildren, fallbackChildren, renderLanes) {
18270 var mode = workInProgress.mode;
18271 var currentPrimaryChildFragment = current.child;
18272 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
18273 var primaryChildProps = {
18274 mode: 'hidden',
18275 children: primaryChildren
18276 };
18277 var primaryChildFragment;
18278
18279 if ( // In legacy mode, we commit the primary tree as if it successfully
18280 // completed, even though it's in an inconsistent state.
18281 (mode & BlockingMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was
18282 // already cloned. In legacy mode, the only case where this isn't true is
18283 // when DevTools forces us to display a fallback; we skip the first render
18284 // pass entirely and go straight to rendering the fallback. (In Concurrent
18285 // Mode, SuspenseList can also trigger this scenario, but this is a legacy-
18286 // only codepath.)
18287 workInProgress.child !== currentPrimaryChildFragment) {
18288 var progressedPrimaryFragment = workInProgress.child;
18289 primaryChildFragment = progressedPrimaryFragment;
18290 primaryChildFragment.childLanes = NoLanes;
18291 primaryChildFragment.pendingProps = primaryChildProps;
18292
18293 if ( workInProgress.mode & ProfileMode) {
18294 // Reset the durations from the first pass so they aren't included in the
18295 // final amounts. This seems counterintuitive, since we're intentionally
18296 // not measuring part of the render phase, but this makes it match what we
18297 // do in Concurrent Mode.
18298 primaryChildFragment.actualDuration = 0;
18299 primaryChildFragment.actualStartTime = -1;
18300 primaryChildFragment.selfBaseDuration = currentPrimaryChildFragment.selfBaseDuration;
18301 primaryChildFragment.treeBaseDuration = currentPrimaryChildFragment.treeBaseDuration;
18302 } // The fallback fiber was added as a deletion effect during the first pass.
18303 // However, since we're going to remain on the fallback, we no longer want
18304 // to delete it. So we need to remove it from the list. Deletions are stored
18305 // on the same list as effects. We want to keep the effects from the primary
18306 // tree. So we copy the primary child fragment's effect list, which does not
18307 // include the fallback deletion effect.
18308
18309
18310 var progressedLastEffect = primaryChildFragment.lastEffect;
18311
18312 if (progressedLastEffect !== null) {
18313 workInProgress.firstEffect = primaryChildFragment.firstEffect;
18314 workInProgress.lastEffect = progressedLastEffect;
18315 progressedLastEffect.nextEffect = null;
18316 } else {
18317 // TODO: Reset this somewhere else? Lol legacy mode is so weird.
18318 workInProgress.firstEffect = workInProgress.lastEffect = null;
18319 }
18320 } else {
18321 primaryChildFragment = createWorkInProgressOffscreenFiber(currentPrimaryChildFragment, primaryChildProps);
18322 }
18323
18324 var fallbackChildFragment;
18325
18326 if (currentFallbackChildFragment !== null) {
18327 fallbackChildFragment = createWorkInProgress(currentFallbackChildFragment, fallbackChildren);
18328 } else {
18329 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null); // Needs a placement effect because the parent (the Suspense boundary) already
18330 // mounted but this is a new fiber.
18331
18332 fallbackChildFragment.flags |= Placement;
18333 }
18334
18335 fallbackChildFragment.return = workInProgress;
18336 primaryChildFragment.return = workInProgress;
18337 primaryChildFragment.sibling = fallbackChildFragment;
18338 workInProgress.child = primaryChildFragment;
18339 return fallbackChildFragment;
18340 }
18341
18342 function scheduleWorkOnFiber(fiber, renderLanes) {
18343 fiber.lanes = mergeLanes(fiber.lanes, renderLanes);
18344 var alternate = fiber.alternate;
18345
18346 if (alternate !== null) {
18347 alternate.lanes = mergeLanes(alternate.lanes, renderLanes);
18348 }
18349
18350 scheduleWorkOnParentPath(fiber.return, renderLanes);
18351 }
18352
18353 function propagateSuspenseContextChange(workInProgress, firstChild, renderLanes) {
18354 // Mark any Suspense boundaries with fallbacks as having work to do.
18355 // If they were previously forced into fallbacks, they may now be able
18356 // to unblock.
18357 var node = firstChild;
18358
18359 while (node !== null) {
18360 if (node.tag === SuspenseComponent) {
18361 var state = node.memoizedState;
18362
18363 if (state !== null) {
18364 scheduleWorkOnFiber(node, renderLanes);
18365 }
18366 } else if (node.tag === SuspenseListComponent) {
18367 // If the tail is hidden there might not be an Suspense boundaries
18368 // to schedule work on. In this case we have to schedule it on the
18369 // list itself.
18370 // We don't have to traverse to the children of the list since
18371 // the list will propagate the change when it rerenders.
18372 scheduleWorkOnFiber(node, renderLanes);
18373 } else if (node.child !== null) {
18374 node.child.return = node;
18375 node = node.child;
18376 continue;
18377 }
18378
18379 if (node === workInProgress) {
18380 return;
18381 }
18382
18383 while (node.sibling === null) {
18384 if (node.return === null || node.return === workInProgress) {
18385 return;
18386 }
18387
18388 node = node.return;
18389 }
18390
18391 node.sibling.return = node.return;
18392 node = node.sibling;
18393 }
18394 }
18395
18396 function findLastContentRow(firstChild) {
18397 // This is going to find the last row among these children that is already
18398 // showing content on the screen, as opposed to being in fallback state or
18399 // new. If a row has multiple Suspense boundaries, any of them being in the
18400 // fallback state, counts as the whole row being in a fallback state.
18401 // Note that the "rows" will be workInProgress, but any nested children
18402 // will still be current since we haven't rendered them yet. The mounted
18403 // order may not be the same as the new order. We use the new order.
18404 var row = firstChild;
18405 var lastContentRow = null;
18406
18407 while (row !== null) {
18408 var currentRow = row.alternate; // New rows can't be content rows.
18409
18410 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
18411 lastContentRow = row;
18412 }
18413
18414 row = row.sibling;
18415 }
18416
18417 return lastContentRow;
18418 }
18419
18420 function validateRevealOrder(revealOrder) {
18421 {
18422 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
18423 didWarnAboutRevealOrder[revealOrder] = true;
18424
18425 if (typeof revealOrder === 'string') {
18426 switch (revealOrder.toLowerCase()) {
18427 case 'together':
18428 case 'forwards':
18429 case 'backwards':
18430 {
18431 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
18432
18433 break;
18434 }
18435
18436 case 'forward':
18437 case 'backward':
18438 {
18439 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());
18440
18441 break;
18442 }
18443
18444 default:
18445 error('"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
18446
18447 break;
18448 }
18449 } else {
18450 error('%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
18451 }
18452 }
18453 }
18454 }
18455
18456 function validateTailOptions(tailMode, revealOrder) {
18457 {
18458 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
18459 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
18460 didWarnAboutTailOptions[tailMode] = true;
18461
18462 error('"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
18463 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
18464 didWarnAboutTailOptions[tailMode] = true;
18465
18466 error('<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
18467 }
18468 }
18469 }
18470 }
18471
18472 function validateSuspenseListNestedChild(childSlot, index) {
18473 {
18474 var isArray = Array.isArray(childSlot);
18475 var isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function';
18476
18477 if (isArray || isIterable) {
18478 var type = isArray ? 'array' : 'iterable';
18479
18480 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);
18481
18482 return false;
18483 }
18484 }
18485
18486 return true;
18487 }
18488
18489 function validateSuspenseListChildren(children, revealOrder) {
18490 {
18491 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
18492 if (Array.isArray(children)) {
18493 for (var i = 0; i < children.length; i++) {
18494 if (!validateSuspenseListNestedChild(children[i], i)) {
18495 return;
18496 }
18497 }
18498 } else {
18499 var iteratorFn = getIteratorFn(children);
18500
18501 if (typeof iteratorFn === 'function') {
18502 var childrenIterator = iteratorFn.call(children);
18503
18504 if (childrenIterator) {
18505 var step = childrenIterator.next();
18506 var _i = 0;
18507
18508 for (; !step.done; step = childrenIterator.next()) {
18509 if (!validateSuspenseListNestedChild(step.value, _i)) {
18510 return;
18511 }
18512
18513 _i++;
18514 }
18515 }
18516 } else {
18517 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);
18518 }
18519 }
18520 }
18521 }
18522 }
18523
18524 function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode, lastEffectBeforeRendering) {
18525 var renderState = workInProgress.memoizedState;
18526
18527 if (renderState === null) {
18528 workInProgress.memoizedState = {
18529 isBackwards: isBackwards,
18530 rendering: null,
18531 renderingStartTime: 0,
18532 last: lastContentRow,
18533 tail: tail,
18534 tailMode: tailMode,
18535 lastEffect: lastEffectBeforeRendering
18536 };
18537 } else {
18538 // We can reuse the existing object from previous renders.
18539 renderState.isBackwards = isBackwards;
18540 renderState.rendering = null;
18541 renderState.renderingStartTime = 0;
18542 renderState.last = lastContentRow;
18543 renderState.tail = tail;
18544 renderState.tailMode = tailMode;
18545 renderState.lastEffect = lastEffectBeforeRendering;
18546 }
18547 } // This can end up rendering this component multiple passes.
18548 // The first pass splits the children fibers into two sets. A head and tail.
18549 // We first render the head. If anything is in fallback state, we do another
18550 // pass through beginWork to rerender all children (including the tail) with
18551 // the force suspend context. If the first render didn't have anything in
18552 // in fallback state. Then we render each row in the tail one-by-one.
18553 // That happens in the completeWork phase without going back to beginWork.
18554
18555
18556 function updateSuspenseListComponent(current, workInProgress, renderLanes) {
18557 var nextProps = workInProgress.pendingProps;
18558 var revealOrder = nextProps.revealOrder;
18559 var tailMode = nextProps.tail;
18560 var newChildren = nextProps.children;
18561 validateRevealOrder(revealOrder);
18562 validateTailOptions(tailMode, revealOrder);
18563 validateSuspenseListChildren(newChildren, revealOrder);
18564 reconcileChildren(current, workInProgress, newChildren, renderLanes);
18565 var suspenseContext = suspenseStackCursor.current;
18566 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
18567
18568 if (shouldForceFallback) {
18569 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
18570 workInProgress.flags |= DidCapture;
18571 } else {
18572 var didSuspendBefore = current !== null && (current.flags & DidCapture) !== NoFlags;
18573
18574 if (didSuspendBefore) {
18575 // If we previously forced a fallback, we need to schedule work
18576 // on any nested boundaries to let them know to try to render
18577 // again. This is the same as context updating.
18578 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderLanes);
18579 }
18580
18581 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
18582 }
18583
18584 pushSuspenseContext(workInProgress, suspenseContext);
18585
18586 if ((workInProgress.mode & BlockingMode) === NoMode) {
18587 // In legacy mode, SuspenseList doesn't work so we just
18588 // use make it a noop by treating it as the default revealOrder.
18589 workInProgress.memoizedState = null;
18590 } else {
18591 switch (revealOrder) {
18592 case 'forwards':
18593 {
18594 var lastContentRow = findLastContentRow(workInProgress.child);
18595 var tail;
18596
18597 if (lastContentRow === null) {
18598 // The whole list is part of the tail.
18599 // TODO: We could fast path by just rendering the tail now.
18600 tail = workInProgress.child;
18601 workInProgress.child = null;
18602 } else {
18603 // Disconnect the tail rows after the content row.
18604 // We're going to render them separately later.
18605 tail = lastContentRow.sibling;
18606 lastContentRow.sibling = null;
18607 }
18608
18609 initSuspenseListRenderState(workInProgress, false, // isBackwards
18610 tail, lastContentRow, tailMode, workInProgress.lastEffect);
18611 break;
18612 }
18613
18614 case 'backwards':
18615 {
18616 // We're going to find the first row that has existing content.
18617 // At the same time we're going to reverse the list of everything
18618 // we pass in the meantime. That's going to be our tail in reverse
18619 // order.
18620 var _tail = null;
18621 var row = workInProgress.child;
18622 workInProgress.child = null;
18623
18624 while (row !== null) {
18625 var currentRow = row.alternate; // New rows can't be content rows.
18626
18627 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
18628 // This is the beginning of the main content.
18629 workInProgress.child = row;
18630 break;
18631 }
18632
18633 var nextRow = row.sibling;
18634 row.sibling = _tail;
18635 _tail = row;
18636 row = nextRow;
18637 } // TODO: If workInProgress.child is null, we can continue on the tail immediately.
18638
18639
18640 initSuspenseListRenderState(workInProgress, true, // isBackwards
18641 _tail, null, // last
18642 tailMode, workInProgress.lastEffect);
18643 break;
18644 }
18645
18646 case 'together':
18647 {
18648 initSuspenseListRenderState(workInProgress, false, // isBackwards
18649 null, // tail
18650 null, // last
18651 undefined, workInProgress.lastEffect);
18652 break;
18653 }
18654
18655 default:
18656 {
18657 // The default reveal order is the same as not having
18658 // a boundary.
18659 workInProgress.memoizedState = null;
18660 }
18661 }
18662 }
18663
18664 return workInProgress.child;
18665 }
18666
18667 function updatePortalComponent(current, workInProgress, renderLanes) {
18668 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
18669 var nextChildren = workInProgress.pendingProps;
18670
18671 if (current === null) {
18672 // Portals are special because we don't append the children during mount
18673 // but at commit. Therefore we need to track insertions which the normal
18674 // flow doesn't do during mount. This doesn't happen at the root because
18675 // the root always starts with a "current" with a null child.
18676 // TODO: Consider unifying this with how the root works.
18677 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes);
18678 } else {
18679 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
18680 }
18681
18682 return workInProgress.child;
18683 }
18684
18685 var hasWarnedAboutUsingNoValuePropOnContextProvider = false;
18686
18687 function updateContextProvider(current, workInProgress, renderLanes) {
18688 var providerType = workInProgress.type;
18689 var context = providerType._context;
18690 var newProps = workInProgress.pendingProps;
18691 var oldProps = workInProgress.memoizedProps;
18692 var newValue = newProps.value;
18693
18694 {
18695 if (!('value' in newProps)) {
18696 if (!hasWarnedAboutUsingNoValuePropOnContextProvider) {
18697 hasWarnedAboutUsingNoValuePropOnContextProvider = true;
18698
18699 error('The `value` prop is required for the `<Context.Provider>`. Did you misspell it or forget to pass it?');
18700 }
18701 }
18702
18703 var providerPropTypes = workInProgress.type.propTypes;
18704
18705 if (providerPropTypes) {
18706 checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider');
18707 }
18708 }
18709
18710 pushProvider(workInProgress, newValue);
18711
18712 if (oldProps !== null) {
18713 var oldValue = oldProps.value;
18714 var changedBits = calculateChangedBits(context, newValue, oldValue);
18715
18716 if (changedBits === 0) {
18717 // No change. Bailout early if children are the same.
18718 if (oldProps.children === newProps.children && !hasContextChanged()) {
18719 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
18720 }
18721 } else {
18722 // The context value changed. Search for matching consumers and schedule
18723 // them to update.
18724 propagateContextChange(workInProgress, context, changedBits, renderLanes);
18725 }
18726 }
18727
18728 var newChildren = newProps.children;
18729 reconcileChildren(current, workInProgress, newChildren, renderLanes);
18730 return workInProgress.child;
18731 }
18732
18733 var hasWarnedAboutUsingContextAsConsumer = false;
18734
18735 function updateContextConsumer(current, workInProgress, renderLanes) {
18736 var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In
18737 // DEV mode, we create a separate object for Context.Consumer that acts
18738 // like a proxy to Context. This proxy object adds unnecessary code in PROD
18739 // so we use the old behaviour (Context.Consumer references Context) to
18740 // reduce size and overhead. The separate object references context via
18741 // a property called "_context", which also gives us the ability to check
18742 // in DEV mode if this property exists or not and warn if it does not.
18743
18744 {
18745 if (context._context === undefined) {
18746 // This may be because it's a Context (rather than a Consumer).
18747 // Or it may be because it's older React where they're the same thing.
18748 // We only want to warn if we're sure it's a new React.
18749 if (context !== context.Consumer) {
18750 if (!hasWarnedAboutUsingContextAsConsumer) {
18751 hasWarnedAboutUsingContextAsConsumer = true;
18752
18753 error('Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
18754 }
18755 }
18756 } else {
18757 context = context._context;
18758 }
18759 }
18760
18761 var newProps = workInProgress.pendingProps;
18762 var render = newProps.children;
18763
18764 {
18765 if (typeof render !== 'function') {
18766 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.');
18767 }
18768 }
18769
18770 prepareToReadContext(workInProgress, renderLanes);
18771 var newValue = readContext(context, newProps.unstable_observedBits);
18772 var newChildren;
18773
18774 {
18775 ReactCurrentOwner$1.current = workInProgress;
18776 setIsRendering(true);
18777 newChildren = render(newValue);
18778 setIsRendering(false);
18779 } // React DevTools reads this flag.
18780
18781
18782 workInProgress.flags |= PerformedWork;
18783 reconcileChildren(current, workInProgress, newChildren, renderLanes);
18784 return workInProgress.child;
18785 }
18786
18787 function markWorkInProgressReceivedUpdate() {
18788 didReceiveUpdate = true;
18789 }
18790
18791 function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) {
18792 if (current !== null) {
18793 // Reuse previous dependencies
18794 workInProgress.dependencies = current.dependencies;
18795 }
18796
18797 {
18798 // Don't update "base" render times for bailouts.
18799 stopProfilerTimerIfRunning();
18800 }
18801
18802 markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work.
18803
18804 if (!includesSomeLane(renderLanes, workInProgress.childLanes)) {
18805 // The children don't have any work either. We can skip them.
18806 // TODO: Once we add back resuming, we should check if the children are
18807 // a work-in-progress set. If so, we need to transfer their effects.
18808 return null;
18809 } else {
18810 // This fiber doesn't have work, but its subtree does. Clone the child
18811 // fibers and continue.
18812 cloneChildFibers(current, workInProgress);
18813 return workInProgress.child;
18814 }
18815 }
18816
18817 function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
18818 {
18819 var returnFiber = oldWorkInProgress.return;
18820
18821 if (returnFiber === null) {
18822 throw new Error('Cannot swap the root fiber.');
18823 } // Disconnect from the old current.
18824 // It will get deleted.
18825
18826
18827 current.alternate = null;
18828 oldWorkInProgress.alternate = null; // Connect to the new tree.
18829
18830 newWorkInProgress.index = oldWorkInProgress.index;
18831 newWorkInProgress.sibling = oldWorkInProgress.sibling;
18832 newWorkInProgress.return = oldWorkInProgress.return;
18833 newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it.
18834
18835 if (oldWorkInProgress === returnFiber.child) {
18836 returnFiber.child = newWorkInProgress;
18837 } else {
18838 var prevSibling = returnFiber.child;
18839
18840 if (prevSibling === null) {
18841 throw new Error('Expected parent to have a child.');
18842 }
18843
18844 while (prevSibling.sibling !== oldWorkInProgress) {
18845 prevSibling = prevSibling.sibling;
18846
18847 if (prevSibling === null) {
18848 throw new Error('Expected to find the previous sibling.');
18849 }
18850 }
18851
18852 prevSibling.sibling = newWorkInProgress;
18853 } // Delete the old fiber and place the new one.
18854 // Since the old fiber is disconnected, we have to schedule it manually.
18855
18856
18857 var last = returnFiber.lastEffect;
18858
18859 if (last !== null) {
18860 last.nextEffect = current;
18861 returnFiber.lastEffect = current;
18862 } else {
18863 returnFiber.firstEffect = returnFiber.lastEffect = current;
18864 }
18865
18866 current.nextEffect = null;
18867 current.flags = Deletion;
18868 newWorkInProgress.flags |= Placement; // Restart work from the new fiber.
18869
18870 return newWorkInProgress;
18871 }
18872 }
18873
18874 function beginWork(current, workInProgress, renderLanes) {
18875 var updateLanes = workInProgress.lanes;
18876
18877 {
18878 if (workInProgress._debugNeedsRemount && current !== null) {
18879 // This will restart the begin phase with a new fiber.
18880 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.lanes));
18881 }
18882 }
18883
18884 if (current !== null) {
18885 var oldProps = current.memoizedProps;
18886 var newProps = workInProgress.pendingProps;
18887
18888 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:
18889 workInProgress.type !== current.type )) {
18890 // If props or context changed, mark the fiber as having performed work.
18891 // This may be unset if the props are determined to be equal later (memo).
18892 didReceiveUpdate = true;
18893 } else if (!includesSomeLane(renderLanes, updateLanes)) {
18894 didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering
18895 // the begin phase. There's still some bookkeeping we that needs to be done
18896 // in this optimized path, mostly pushing stuff onto the stack.
18897
18898 switch (workInProgress.tag) {
18899 case HostRoot:
18900 pushHostRootContext(workInProgress);
18901 resetHydrationState();
18902 break;
18903
18904 case HostComponent:
18905 pushHostContext(workInProgress);
18906 break;
18907
18908 case ClassComponent:
18909 {
18910 var Component = workInProgress.type;
18911
18912 if (isContextProvider(Component)) {
18913 pushContextProvider(workInProgress);
18914 }
18915
18916 break;
18917 }
18918
18919 case HostPortal:
18920 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
18921 break;
18922
18923 case ContextProvider:
18924 {
18925 var newValue = workInProgress.memoizedProps.value;
18926 pushProvider(workInProgress, newValue);
18927 break;
18928 }
18929
18930 case Profiler:
18931 {
18932 // Profiler should only call onRender when one of its descendants actually rendered.
18933 var hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes);
18934
18935 if (hasChildWork) {
18936 workInProgress.flags |= Update;
18937 } // Reset effect durations for the next eventual effect phase.
18938 // These are reset during render to allow the DevTools commit hook a chance to read them,
18939
18940
18941 var stateNode = workInProgress.stateNode;
18942 stateNode.effectDuration = 0;
18943 stateNode.passiveEffectDuration = 0;
18944 }
18945
18946 break;
18947
18948 case SuspenseComponent:
18949 {
18950 var state = workInProgress.memoizedState;
18951
18952 if (state !== null) {
18953 // whether to retry the primary children, or to skip over it and
18954 // go straight to the fallback. Check the priority of the primary
18955 // child fragment.
18956
18957
18958 var primaryChildFragment = workInProgress.child;
18959 var primaryChildLanes = primaryChildFragment.childLanes;
18960
18961 if (includesSomeLane(renderLanes, primaryChildLanes)) {
18962 // The primary children have pending work. Use the normal path
18963 // to attempt to render the primary children again.
18964 return updateSuspenseComponent(current, workInProgress, renderLanes);
18965 } else {
18966 // The primary child fragment does not have pending work marked
18967 // on it
18968 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient
18969 // priority. Bailout.
18970
18971 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
18972
18973 if (child !== null) {
18974 // The fallback children have pending work. Skip over the
18975 // primary children and work on the fallback.
18976 return child.sibling;
18977 } else {
18978 return null;
18979 }
18980 }
18981 } else {
18982 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
18983 }
18984
18985 break;
18986 }
18987
18988 case SuspenseListComponent:
18989 {
18990 var didSuspendBefore = (current.flags & DidCapture) !== NoFlags;
18991
18992 var _hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes);
18993
18994 if (didSuspendBefore) {
18995 if (_hasChildWork) {
18996 // If something was in fallback state last time, and we have all the
18997 // same children then we're still in progressive loading state.
18998 // Something might get unblocked by state updates or retries in the
18999 // tree which will affect the tail. So we need to use the normal
19000 // path to compute the correct tail.
19001 return updateSuspenseListComponent(current, workInProgress, renderLanes);
19002 } // If none of the children had any work, that means that none of
19003 // them got retried so they'll still be blocked in the same way
19004 // as before. We can fast bail out.
19005
19006
19007 workInProgress.flags |= DidCapture;
19008 } // If nothing suspended before and we're rendering the same children,
19009 // then the tail doesn't matter. Anything new that suspends will work
19010 // in the "together" mode, so we can continue from the state we had.
19011
19012
19013 var renderState = workInProgress.memoizedState;
19014
19015 if (renderState !== null) {
19016 // Reset to the "together" mode in case we've started a different
19017 // update in the past but didn't complete it.
19018 renderState.rendering = null;
19019 renderState.tail = null;
19020 renderState.lastEffect = null;
19021 }
19022
19023 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
19024
19025 if (_hasChildWork) {
19026 break;
19027 } else {
19028 // If none of the children had any work, that means that none of
19029 // them got retried so they'll still be blocked in the same way
19030 // as before. We can fast bail out.
19031 return null;
19032 }
19033 }
19034
19035 case OffscreenComponent:
19036 case LegacyHiddenComponent:
19037 {
19038 // Need to check if the tree still needs to be deferred. This is
19039 // almost identical to the logic used in the normal update path,
19040 // so we'll just enter that. The only difference is we'll bail out
19041 // at the next level instead of this one, because the child props
19042 // have not changed. Which is fine.
19043 // TODO: Probably should refactor `beginWork` to split the bailout
19044 // path from the normal path. I'm tempted to do a labeled break here
19045 // but I won't :)
19046 workInProgress.lanes = NoLanes;
19047 return updateOffscreenComponent(current, workInProgress, renderLanes);
19048 }
19049 }
19050
19051 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
19052 } else {
19053 if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) {
19054 // This is a special case that only exists for legacy mode.
19055 // See https://github.com/facebook/react/pull/19216.
19056 didReceiveUpdate = true;
19057 } else {
19058 // An update was scheduled on this fiber, but there are no new props
19059 // nor legacy context. Set this to false. If an update queue or context
19060 // consumer produces a changed value, it will set this to true. Otherwise,
19061 // the component will assume the children have not changed and bail out.
19062 didReceiveUpdate = false;
19063 }
19064 }
19065 } else {
19066 didReceiveUpdate = false;
19067 } // Before entering the begin phase, clear pending update priority.
19068 // TODO: This assumes that we're about to evaluate the component and process
19069 // the update queue. However, there's an exception: SimpleMemoComponent
19070 // sometimes bails out later in the begin phase. This indicates that we should
19071 // move this assignment out of the common path and into each branch.
19072
19073
19074 workInProgress.lanes = NoLanes;
19075
19076 switch (workInProgress.tag) {
19077 case IndeterminateComponent:
19078 {
19079 return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderLanes);
19080 }
19081
19082 case LazyComponent:
19083 {
19084 var elementType = workInProgress.elementType;
19085 return mountLazyComponent(current, workInProgress, elementType, updateLanes, renderLanes);
19086 }
19087
19088 case FunctionComponent:
19089 {
19090 var _Component = workInProgress.type;
19091 var unresolvedProps = workInProgress.pendingProps;
19092 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
19093 return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderLanes);
19094 }
19095
19096 case ClassComponent:
19097 {
19098 var _Component2 = workInProgress.type;
19099 var _unresolvedProps = workInProgress.pendingProps;
19100
19101 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
19102
19103 return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderLanes);
19104 }
19105
19106 case HostRoot:
19107 return updateHostRoot(current, workInProgress, renderLanes);
19108
19109 case HostComponent:
19110 return updateHostComponent(current, workInProgress, renderLanes);
19111
19112 case HostText:
19113 return updateHostText(current, workInProgress);
19114
19115 case SuspenseComponent:
19116 return updateSuspenseComponent(current, workInProgress, renderLanes);
19117
19118 case HostPortal:
19119 return updatePortalComponent(current, workInProgress, renderLanes);
19120
19121 case ForwardRef:
19122 {
19123 var type = workInProgress.type;
19124 var _unresolvedProps2 = workInProgress.pendingProps;
19125
19126 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
19127
19128 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderLanes);
19129 }
19130
19131 case Fragment:
19132 return updateFragment(current, workInProgress, renderLanes);
19133
19134 case Mode:
19135 return updateMode(current, workInProgress, renderLanes);
19136
19137 case Profiler:
19138 return updateProfiler(current, workInProgress, renderLanes);
19139
19140 case ContextProvider:
19141 return updateContextProvider(current, workInProgress, renderLanes);
19142
19143 case ContextConsumer:
19144 return updateContextConsumer(current, workInProgress, renderLanes);
19145
19146 case MemoComponent:
19147 {
19148 var _type2 = workInProgress.type;
19149 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.
19150
19151 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
19152
19153 {
19154 if (workInProgress.type !== workInProgress.elementType) {
19155 var outerPropTypes = _type2.propTypes;
19156
19157 if (outerPropTypes) {
19158 checkPropTypes(outerPropTypes, _resolvedProps3, // Resolved for outer only
19159 'prop', getComponentName(_type2));
19160 }
19161 }
19162 }
19163
19164 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
19165 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, updateLanes, renderLanes);
19166 }
19167
19168 case SimpleMemoComponent:
19169 {
19170 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, updateLanes, renderLanes);
19171 }
19172
19173 case IncompleteClassComponent:
19174 {
19175 var _Component3 = workInProgress.type;
19176 var _unresolvedProps4 = workInProgress.pendingProps;
19177
19178 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
19179
19180 return mountIncompleteClassComponent(current, workInProgress, _Component3, _resolvedProps4, renderLanes);
19181 }
19182
19183 case SuspenseListComponent:
19184 {
19185 return updateSuspenseListComponent(current, workInProgress, renderLanes);
19186 }
19187
19188 case FundamentalComponent:
19189 {
19190
19191 break;
19192 }
19193
19194 case ScopeComponent:
19195 {
19196
19197 break;
19198 }
19199
19200 case Block:
19201 {
19202
19203 break;
19204 }
19205
19206 case OffscreenComponent:
19207 {
19208 return updateOffscreenComponent(current, workInProgress, renderLanes);
19209 }
19210
19211 case LegacyHiddenComponent:
19212 {
19213 return updateLegacyHiddenComponent(current, workInProgress, renderLanes);
19214 }
19215 }
19216
19217 {
19218 {
19219 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." );
19220 }
19221 }
19222 }
19223
19224 function markUpdate(workInProgress) {
19225 // Tag the fiber with an update effect. This turns a Placement into
19226 // a PlacementAndUpdate.
19227 workInProgress.flags |= Update;
19228 }
19229
19230 function markRef$1(workInProgress) {
19231 workInProgress.flags |= Ref;
19232 }
19233
19234 var appendAllChildren;
19235 var updateHostContainer;
19236 var updateHostComponent$1;
19237 var updateHostText$1;
19238
19239 {
19240 // Mutation mode
19241 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
19242 // We only have the top Fiber that was created but we need recurse down its
19243 // children to find all the terminal nodes.
19244 var node = workInProgress.child;
19245
19246 while (node !== null) {
19247 if (node.tag === HostComponent || node.tag === HostText) {
19248 appendInitialChild(parent, node.stateNode);
19249 } else if (node.tag === HostPortal) ; else if (node.child !== null) {
19250 node.child.return = node;
19251 node = node.child;
19252 continue;
19253 }
19254
19255 if (node === workInProgress) {
19256 return;
19257 }
19258
19259 while (node.sibling === null) {
19260 if (node.return === null || node.return === workInProgress) {
19261 return;
19262 }
19263
19264 node = node.return;
19265 }
19266
19267 node.sibling.return = node.return;
19268 node = node.sibling;
19269 }
19270 };
19271
19272 updateHostContainer = function (workInProgress) {// Noop
19273 };
19274
19275 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
19276 // If we have an alternate, that means this is an update and we need to
19277 // schedule a side-effect to do the updates.
19278 var oldProps = current.memoizedProps;
19279
19280 if (oldProps === newProps) {
19281 // In mutation mode, this is sufficient for a bailout because
19282 // we won't touch this node even if children changed.
19283 return;
19284 } // If we get updated because one of our children updated, we don't
19285 // have newProps so we'll have to reuse them.
19286 // TODO: Split the update API as separate for the props vs. children.
19287 // Even better would be if children weren't special cased at all tho.
19288
19289
19290 var instance = workInProgress.stateNode;
19291 var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host
19292 // component is hitting the resume path. Figure out why. Possibly
19293 // related to `hidden`.
19294
19295 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext); // TODO: Type this specific to this type of component.
19296
19297 workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
19298 // is a new ref we mark this as an update. All the work is done in commitWork.
19299
19300 if (updatePayload) {
19301 markUpdate(workInProgress);
19302 }
19303 };
19304
19305 updateHostText$1 = function (current, workInProgress, oldText, newText) {
19306 // If the text differs, mark it as an update. All the work in done in commitWork.
19307 if (oldText !== newText) {
19308 markUpdate(workInProgress);
19309 }
19310 };
19311 }
19312
19313 function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
19314 if (getIsHydrating()) {
19315 // If we're hydrating, we should consume as many items as we can
19316 // so we don't leave any behind.
19317 return;
19318 }
19319
19320 switch (renderState.tailMode) {
19321 case 'hidden':
19322 {
19323 // Any insertions at the end of the tail list after this point
19324 // should be invisible. If there are already mounted boundaries
19325 // anything before them are not considered for collapsing.
19326 // Therefore we need to go through the whole tail to find if
19327 // there are any.
19328 var tailNode = renderState.tail;
19329 var lastTailNode = null;
19330
19331 while (tailNode !== null) {
19332 if (tailNode.alternate !== null) {
19333 lastTailNode = tailNode;
19334 }
19335
19336 tailNode = tailNode.sibling;
19337 } // Next we're simply going to delete all insertions after the
19338 // last rendered item.
19339
19340
19341 if (lastTailNode === null) {
19342 // All remaining items in the tail are insertions.
19343 renderState.tail = null;
19344 } else {
19345 // Detach the insertion after the last node that was already
19346 // inserted.
19347 lastTailNode.sibling = null;
19348 }
19349
19350 break;
19351 }
19352
19353 case 'collapsed':
19354 {
19355 // Any insertions at the end of the tail list after this point
19356 // should be invisible. If there are already mounted boundaries
19357 // anything before them are not considered for collapsing.
19358 // Therefore we need to go through the whole tail to find if
19359 // there are any.
19360 var _tailNode = renderState.tail;
19361 var _lastTailNode = null;
19362
19363 while (_tailNode !== null) {
19364 if (_tailNode.alternate !== null) {
19365 _lastTailNode = _tailNode;
19366 }
19367
19368 _tailNode = _tailNode.sibling;
19369 } // Next we're simply going to delete all insertions after the
19370 // last rendered item.
19371
19372
19373 if (_lastTailNode === null) {
19374 // All remaining items in the tail are insertions.
19375 if (!hasRenderedATailFallback && renderState.tail !== null) {
19376 // We suspended during the head. We want to show at least one
19377 // row at the tail. So we'll keep on and cut off the rest.
19378 renderState.tail.sibling = null;
19379 } else {
19380 renderState.tail = null;
19381 }
19382 } else {
19383 // Detach the insertion after the last node that was already
19384 // inserted.
19385 _lastTailNode.sibling = null;
19386 }
19387
19388 break;
19389 }
19390 }
19391 }
19392
19393 function completeWork(current, workInProgress, renderLanes) {
19394 var newProps = workInProgress.pendingProps;
19395
19396 switch (workInProgress.tag) {
19397 case IndeterminateComponent:
19398 case LazyComponent:
19399 case SimpleMemoComponent:
19400 case FunctionComponent:
19401 case ForwardRef:
19402 case Fragment:
19403 case Mode:
19404 case Profiler:
19405 case ContextConsumer:
19406 case MemoComponent:
19407 return null;
19408
19409 case ClassComponent:
19410 {
19411 var Component = workInProgress.type;
19412
19413 if (isContextProvider(Component)) {
19414 popContext(workInProgress);
19415 }
19416
19417 return null;
19418 }
19419
19420 case HostRoot:
19421 {
19422 popHostContainer(workInProgress);
19423 popTopLevelContextObject(workInProgress);
19424 resetWorkInProgressVersions();
19425 var fiberRoot = workInProgress.stateNode;
19426
19427 if (fiberRoot.pendingContext) {
19428 fiberRoot.context = fiberRoot.pendingContext;
19429 fiberRoot.pendingContext = null;
19430 }
19431
19432 if (current === null || current.child === null) {
19433 // If we hydrated, pop so that we can delete any remaining children
19434 // that weren't hydrated.
19435 var wasHydrated = popHydrationState(workInProgress);
19436
19437 if (wasHydrated) {
19438 // If we hydrated, then we'll need to schedule an update for
19439 // the commit side-effects on the root.
19440 markUpdate(workInProgress);
19441 } else if (!fiberRoot.hydrate) {
19442 // Schedule an effect to clear this container at the start of the next commit.
19443 // This handles the case of React rendering into a container with previous children.
19444 // It's also safe to do for updates too, because current.child would only be null
19445 // if the previous render was null (so the the container would already be empty).
19446 workInProgress.flags |= Snapshot;
19447 }
19448 }
19449
19450 updateHostContainer(workInProgress);
19451 return null;
19452 }
19453
19454 case HostComponent:
19455 {
19456 popHostContext(workInProgress);
19457 var rootContainerInstance = getRootHostContainer();
19458 var type = workInProgress.type;
19459
19460 if (current !== null && workInProgress.stateNode != null) {
19461 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
19462
19463 if (current.ref !== workInProgress.ref) {
19464 markRef$1(workInProgress);
19465 }
19466 } else {
19467 if (!newProps) {
19468 if (!(workInProgress.stateNode !== null)) {
19469 {
19470 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." );
19471 }
19472 } // This can happen when we abort work.
19473
19474
19475 return null;
19476 }
19477
19478 var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context
19479 // "stack" as the parent. Then append children as we go in beginWork
19480 // or completeWork depending on whether we want to add them top->down or
19481 // bottom->up. Top->down is faster in IE11.
19482
19483 var _wasHydrated = popHydrationState(workInProgress);
19484
19485 if (_wasHydrated) {
19486 // TODO: Move this and createInstance step into the beginPhase
19487 // to consolidate.
19488 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
19489 // If changes to the hydrated node need to be applied at the
19490 // commit-phase we mark this as such.
19491 markUpdate(workInProgress);
19492 }
19493 } else {
19494 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
19495 appendAllChildren(instance, workInProgress, false, false);
19496 workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount.
19497 // (eg DOM renderer supports auto-focus for certain elements).
19498 // Make sure such renderers get scheduled for later work.
19499
19500 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance)) {
19501 markUpdate(workInProgress);
19502 }
19503 }
19504
19505 if (workInProgress.ref !== null) {
19506 // If there is a ref on a host node we need to schedule a callback
19507 markRef$1(workInProgress);
19508 }
19509 }
19510
19511 return null;
19512 }
19513
19514 case HostText:
19515 {
19516 var newText = newProps;
19517
19518 if (current && workInProgress.stateNode != null) {
19519 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need
19520 // to schedule a side-effect to do the updates.
19521
19522 updateHostText$1(current, workInProgress, oldText, newText);
19523 } else {
19524 if (typeof newText !== 'string') {
19525 if (!(workInProgress.stateNode !== null)) {
19526 {
19527 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." );
19528 }
19529 } // This can happen when we abort work.
19530
19531 }
19532
19533 var _rootContainerInstance = getRootHostContainer();
19534
19535 var _currentHostContext = getHostContext();
19536
19537 var _wasHydrated2 = popHydrationState(workInProgress);
19538
19539 if (_wasHydrated2) {
19540 if (prepareToHydrateHostTextInstance(workInProgress)) {
19541 markUpdate(workInProgress);
19542 }
19543 } else {
19544 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
19545 }
19546 }
19547
19548 return null;
19549 }
19550
19551 case SuspenseComponent:
19552 {
19553 popSuspenseContext(workInProgress);
19554 var nextState = workInProgress.memoizedState;
19555
19556 if ((workInProgress.flags & DidCapture) !== NoFlags) {
19557 // Something suspended. Re-render with the fallback children.
19558 workInProgress.lanes = renderLanes; // Do not reset the effect list.
19559
19560 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
19561 transferActualDuration(workInProgress);
19562 }
19563
19564 return workInProgress;
19565 }
19566
19567 var nextDidTimeout = nextState !== null;
19568 var prevDidTimeout = false;
19569
19570 if (current === null) {
19571 if (workInProgress.memoizedProps.fallback !== undefined) {
19572 popHydrationState(workInProgress);
19573 }
19574 } else {
19575 var prevState = current.memoizedState;
19576 prevDidTimeout = prevState !== null;
19577 }
19578
19579 if (nextDidTimeout && !prevDidTimeout) {
19580 // If this subtreee is running in blocking mode we can suspend,
19581 // otherwise we won't suspend.
19582 // TODO: This will still suspend a synchronous tree if anything
19583 // in the concurrent tree already suspended during this render.
19584 // This is a known bug.
19585 if ((workInProgress.mode & BlockingMode) !== NoMode) {
19586 // TODO: Move this back to throwException because this is too late
19587 // if this is a large tree which is common for initial loads. We
19588 // don't know if we should restart a render or not until we get
19589 // this marker, and this is too late.
19590 // If this render already had a ping or lower pri updates,
19591 // and this is the first time we know we're going to suspend we
19592 // should be able to immediately restart from within throwException.
19593 var hasInvisibleChildContext = current === null && workInProgress.memoizedProps.unstable_avoidThisFallback !== true;
19594
19595 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
19596 // If this was in an invisible tree or a new render, then showing
19597 // this boundary is ok.
19598 renderDidSuspend();
19599 } else {
19600 // Otherwise, we're going to have to hide content so we should
19601 // suspend for longer if possible.
19602 renderDidSuspendDelayIfPossible();
19603 }
19604 }
19605 }
19606
19607 {
19608 // TODO: Only schedule updates if these values are non equal, i.e. it changed.
19609 if (nextDidTimeout || prevDidTimeout) {
19610 // If this boundary just timed out, schedule an effect to attach a
19611 // retry listener to the promise. This flag is also used to hide the
19612 // primary children. In mutation mode, we also need the flag to
19613 // *unhide* children that were previously hidden, so check if this
19614 // is currently timed out, too.
19615 workInProgress.flags |= Update;
19616 }
19617 }
19618
19619 return null;
19620 }
19621
19622 case HostPortal:
19623 popHostContainer(workInProgress);
19624 updateHostContainer(workInProgress);
19625
19626 if (current === null) {
19627 preparePortalMount(workInProgress.stateNode.containerInfo);
19628 }
19629
19630 return null;
19631
19632 case ContextProvider:
19633 // Pop provider fiber
19634 popProvider(workInProgress);
19635 return null;
19636
19637 case IncompleteClassComponent:
19638 {
19639 // Same as class component case. I put it down here so that the tags are
19640 // sequential to ensure this switch is compiled to a jump table.
19641 var _Component = workInProgress.type;
19642
19643 if (isContextProvider(_Component)) {
19644 popContext(workInProgress);
19645 }
19646
19647 return null;
19648 }
19649
19650 case SuspenseListComponent:
19651 {
19652 popSuspenseContext(workInProgress);
19653 var renderState = workInProgress.memoizedState;
19654
19655 if (renderState === null) {
19656 // We're running in the default, "independent" mode.
19657 // We don't do anything in this mode.
19658 return null;
19659 }
19660
19661 var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags;
19662 var renderedTail = renderState.rendering;
19663
19664 if (renderedTail === null) {
19665 // We just rendered the head.
19666 if (!didSuspendAlready) {
19667 // This is the first pass. We need to figure out if anything is still
19668 // suspended in the rendered set.
19669 // If new content unsuspended, but there's still some content that
19670 // didn't. Then we need to do a second pass that forces everything
19671 // to keep showing their fallbacks.
19672 // We might be suspended if something in this render pass suspended, or
19673 // something in the previous committed pass suspended. Otherwise,
19674 // there's no chance so we can skip the expensive call to
19675 // findFirstSuspended.
19676 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.flags & DidCapture) === NoFlags);
19677
19678 if (!cannotBeSuspended) {
19679 var row = workInProgress.child;
19680
19681 while (row !== null) {
19682 var suspended = findFirstSuspended(row);
19683
19684 if (suspended !== null) {
19685 didSuspendAlready = true;
19686 workInProgress.flags |= DidCapture;
19687 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as
19688 // part of the second pass. In that case nothing will subscribe to
19689 // its thennables. Instead, we'll transfer its thennables to the
19690 // SuspenseList so that it can retry if they resolve.
19691 // There might be multiple of these in the list but since we're
19692 // going to wait for all of them anyway, it doesn't really matter
19693 // which ones gets to ping. In theory we could get clever and keep
19694 // track of how many dependencies remain but it gets tricky because
19695 // in the meantime, we can add/remove/change items and dependencies.
19696 // We might bail out of the loop before finding any but that
19697 // doesn't matter since that means that the other boundaries that
19698 // we did find already has their listeners attached.
19699
19700 var newThennables = suspended.updateQueue;
19701
19702 if (newThennables !== null) {
19703 workInProgress.updateQueue = newThennables;
19704 workInProgress.flags |= Update;
19705 } // Rerender the whole list, but this time, we'll force fallbacks
19706 // to stay in place.
19707 // Reset the effect list before doing the second pass since that's now invalid.
19708
19709
19710 if (renderState.lastEffect === null) {
19711 workInProgress.firstEffect = null;
19712 }
19713
19714 workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state.
19715
19716 resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately
19717 // rerender the children.
19718
19719 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));
19720 return workInProgress.child;
19721 }
19722
19723 row = row.sibling;
19724 }
19725 }
19726
19727 if (renderState.tail !== null && now() > getRenderTargetTime()) {
19728 // We have already passed our CPU deadline but we still have rows
19729 // left in the tail. We'll just give up further attempts to render
19730 // the main content and only render fallbacks.
19731 workInProgress.flags |= DidCapture;
19732 didSuspendAlready = true;
19733 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
19734 // to get it started back up to attempt the next item. While in terms
19735 // of priority this work has the same priority as this current render,
19736 // it's not part of the same transition once the transition has
19737 // committed. If it's sync, we still want to yield so that it can be
19738 // painted. Conceptually, this is really the same as pinging.
19739 // We can use any RetryLane even if it's the one currently rendering
19740 // since we're leaving it behind on this node.
19741
19742 workInProgress.lanes = SomeRetryLane;
19743
19744 {
19745 markSpawnedWork(SomeRetryLane);
19746 }
19747 }
19748 } else {
19749 cutOffTailIfNeeded(renderState, false);
19750 } // Next we're going to render the tail.
19751
19752 } else {
19753 // Append the rendered row to the child list.
19754 if (!didSuspendAlready) {
19755 var _suspended = findFirstSuspended(renderedTail);
19756
19757 if (_suspended !== null) {
19758 workInProgress.flags |= DidCapture;
19759 didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't
19760 // get lost if this row ends up dropped during a second pass.
19761
19762 var _newThennables = _suspended.updateQueue;
19763
19764 if (_newThennables !== null) {
19765 workInProgress.updateQueue = _newThennables;
19766 workInProgress.flags |= Update;
19767 }
19768
19769 cutOffTailIfNeeded(renderState, true); // This might have been modified.
19770
19771 if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate && !getIsHydrating() // We don't cut it if we're hydrating.
19772 ) {
19773 // We need to delete the row we just rendered.
19774 // Reset the effect list to what it was before we rendered this
19775 // child. The nested children have already appended themselves.
19776 var lastEffect = workInProgress.lastEffect = renderState.lastEffect; // Remove any effects that were appended after this point.
19777
19778 if (lastEffect !== null) {
19779 lastEffect.nextEffect = null;
19780 } // We're done.
19781
19782
19783 return null;
19784 }
19785 } else if ( // The time it took to render last row is greater than the remaining
19786 // time we have to render. So rendering one more row would likely
19787 // exceed it.
19788 now() * 2 - renderState.renderingStartTime > getRenderTargetTime() && renderLanes !== OffscreenLane) {
19789 // We have now passed our CPU deadline and we'll just give up further
19790 // attempts to render the main content and only render fallbacks.
19791 // The assumption is that this is usually faster.
19792 workInProgress.flags |= DidCapture;
19793 didSuspendAlready = true;
19794 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
19795 // to get it started back up to attempt the next item. While in terms
19796 // of priority this work has the same priority as this current render,
19797 // it's not part of the same transition once the transition has
19798 // committed. If it's sync, we still want to yield so that it can be
19799 // painted. Conceptually, this is really the same as pinging.
19800 // We can use any RetryLane even if it's the one currently rendering
19801 // since we're leaving it behind on this node.
19802
19803 workInProgress.lanes = SomeRetryLane;
19804
19805 {
19806 markSpawnedWork(SomeRetryLane);
19807 }
19808 }
19809 }
19810
19811 if (renderState.isBackwards) {
19812 // The effect list of the backwards tail will have been added
19813 // to the end. This breaks the guarantee that life-cycles fire in
19814 // sibling order but that isn't a strong guarantee promised by React.
19815 // Especially since these might also just pop in during future commits.
19816 // Append to the beginning of the list.
19817 renderedTail.sibling = workInProgress.child;
19818 workInProgress.child = renderedTail;
19819 } else {
19820 var previousSibling = renderState.last;
19821
19822 if (previousSibling !== null) {
19823 previousSibling.sibling = renderedTail;
19824 } else {
19825 workInProgress.child = renderedTail;
19826 }
19827
19828 renderState.last = renderedTail;
19829 }
19830 }
19831
19832 if (renderState.tail !== null) {
19833 // We still have tail rows to render.
19834 // Pop a row.
19835 var next = renderState.tail;
19836 renderState.rendering = next;
19837 renderState.tail = next.sibling;
19838 renderState.lastEffect = workInProgress.lastEffect;
19839 renderState.renderingStartTime = now();
19840 next.sibling = null; // Restore the context.
19841 // TODO: We can probably just avoid popping it instead and only
19842 // setting it the first time we go from not suspended to suspended.
19843
19844 var suspenseContext = suspenseStackCursor.current;
19845
19846 if (didSuspendAlready) {
19847 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
19848 } else {
19849 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
19850 }
19851
19852 pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.
19853
19854 return next;
19855 }
19856
19857 return null;
19858 }
19859
19860 case FundamentalComponent:
19861 {
19862
19863 break;
19864 }
19865
19866 case ScopeComponent:
19867 {
19868
19869 break;
19870 }
19871
19872 case Block:
19873
19874 break;
19875
19876 case OffscreenComponent:
19877 case LegacyHiddenComponent:
19878 {
19879 popRenderLanes(workInProgress);
19880
19881 if (current !== null) {
19882 var _nextState = workInProgress.memoizedState;
19883 var _prevState = current.memoizedState;
19884 var prevIsHidden = _prevState !== null;
19885 var nextIsHidden = _nextState !== null;
19886
19887 if (prevIsHidden !== nextIsHidden && newProps.mode !== 'unstable-defer-without-hiding') {
19888 workInProgress.flags |= Update;
19889 }
19890 }
19891
19892 return null;
19893 }
19894 }
19895
19896 {
19897 {
19898 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." );
19899 }
19900 }
19901 }
19902
19903 function unwindWork(workInProgress, renderLanes) {
19904 switch (workInProgress.tag) {
19905 case ClassComponent:
19906 {
19907 var Component = workInProgress.type;
19908
19909 if (isContextProvider(Component)) {
19910 popContext(workInProgress);
19911 }
19912
19913 var flags = workInProgress.flags;
19914
19915 if (flags & ShouldCapture) {
19916 workInProgress.flags = flags & ~ShouldCapture | DidCapture;
19917
19918 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
19919 transferActualDuration(workInProgress);
19920 }
19921
19922 return workInProgress;
19923 }
19924
19925 return null;
19926 }
19927
19928 case HostRoot:
19929 {
19930 popHostContainer(workInProgress);
19931 popTopLevelContextObject(workInProgress);
19932 resetWorkInProgressVersions();
19933 var _flags = workInProgress.flags;
19934
19935 if (!((_flags & DidCapture) === NoFlags)) {
19936 {
19937 throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." );
19938 }
19939 }
19940
19941 workInProgress.flags = _flags & ~ShouldCapture | DidCapture;
19942 return workInProgress;
19943 }
19944
19945 case HostComponent:
19946 {
19947 // TODO: popHydrationState
19948 popHostContext(workInProgress);
19949 return null;
19950 }
19951
19952 case SuspenseComponent:
19953 {
19954 popSuspenseContext(workInProgress);
19955
19956 var _flags2 = workInProgress.flags;
19957
19958 if (_flags2 & ShouldCapture) {
19959 workInProgress.flags = _flags2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
19960
19961 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
19962 transferActualDuration(workInProgress);
19963 }
19964
19965 return workInProgress;
19966 }
19967
19968 return null;
19969 }
19970
19971 case SuspenseListComponent:
19972 {
19973 popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been
19974 // caught by a nested boundary. If not, it should bubble through.
19975
19976 return null;
19977 }
19978
19979 case HostPortal:
19980 popHostContainer(workInProgress);
19981 return null;
19982
19983 case ContextProvider:
19984 popProvider(workInProgress);
19985 return null;
19986
19987 case OffscreenComponent:
19988 case LegacyHiddenComponent:
19989 popRenderLanes(workInProgress);
19990 return null;
19991
19992 default:
19993 return null;
19994 }
19995 }
19996
19997 function unwindInterruptedWork(interruptedWork) {
19998 switch (interruptedWork.tag) {
19999 case ClassComponent:
20000 {
20001 var childContextTypes = interruptedWork.type.childContextTypes;
20002
20003 if (childContextTypes !== null && childContextTypes !== undefined) {
20004 popContext(interruptedWork);
20005 }
20006
20007 break;
20008 }
20009
20010 case HostRoot:
20011 {
20012 popHostContainer(interruptedWork);
20013 popTopLevelContextObject(interruptedWork);
20014 resetWorkInProgressVersions();
20015 break;
20016 }
20017
20018 case HostComponent:
20019 {
20020 popHostContext(interruptedWork);
20021 break;
20022 }
20023
20024 case HostPortal:
20025 popHostContainer(interruptedWork);
20026 break;
20027
20028 case SuspenseComponent:
20029 popSuspenseContext(interruptedWork);
20030 break;
20031
20032 case SuspenseListComponent:
20033 popSuspenseContext(interruptedWork);
20034 break;
20035
20036 case ContextProvider:
20037 popProvider(interruptedWork);
20038 break;
20039
20040 case OffscreenComponent:
20041 case LegacyHiddenComponent:
20042 popRenderLanes(interruptedWork);
20043 break;
20044 }
20045 }
20046
20047 function createCapturedValue(value, source) {
20048 // If the value is an error, call this function immediately after it is thrown
20049 // so the stack is accurate.
20050 return {
20051 value: value,
20052 source: source,
20053 stack: getStackByFiberInDevAndProd(source)
20054 };
20055 }
20056
20057 // This module is forked in different environments.
20058 // By default, return `true` to log errors to the console.
20059 // Forks can return `false` if this isn't desirable.
20060 function showErrorDialog(boundary, errorInfo) {
20061 return true;
20062 }
20063
20064 function logCapturedError(boundary, errorInfo) {
20065 try {
20066 var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging.
20067 // This enables renderers like ReactNative to better manage redbox behavior.
20068
20069 if (logError === false) {
20070 return;
20071 }
20072
20073 var error = errorInfo.value;
20074
20075 if (true) {
20076 var source = errorInfo.source;
20077 var stack = errorInfo.stack;
20078 var componentStack = stack !== null ? stack : ''; // Browsers support silencing uncaught errors by calling
20079 // `preventDefault()` in window `error` handler.
20080 // We record this information as an expando on the error.
20081
20082 if (error != null && error._suppressLogging) {
20083 if (boundary.tag === ClassComponent) {
20084 // The error is recoverable and was silenced.
20085 // Ignore it and don't print the stack addendum.
20086 // This is handy for testing error boundaries without noise.
20087 return;
20088 } // The error is fatal. Since the silencing might have
20089 // been accidental, we'll surface it anyway.
20090 // However, the browser would have silenced the original error
20091 // so we'll print it first, and then print the stack addendum.
20092
20093
20094 console['error'](error); // Don't transform to our wrapper
20095 // For a more detailed description of this block, see:
20096 // https://github.com/facebook/react/pull/13384
20097 }
20098
20099 var componentName = source ? getComponentName(source.type) : null;
20100 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:';
20101 var errorBoundaryMessage;
20102 var errorBoundaryName = getComponentName(boundary.type);
20103
20104 if (errorBoundaryName) {
20105 errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + ".");
20106 } else {
20107 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.';
20108 }
20109
20110 var combinedMessage = componentNameMessage + "\n" + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack.
20111 // We don't include the original error message and JS stack because the browser
20112 // has already printed it. Even if the application swallows the error, it is still
20113 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
20114
20115 console['error'](combinedMessage); // Don't transform to our wrapper
20116 } else {
20117 // In production, we print the error directly.
20118 // This will include the message, the JS stack, and anything the browser wants to show.
20119 // We pass the error object instead of custom message so that the browser displays the error natively.
20120 console['error'](error); // Don't transform to our wrapper
20121 }
20122 } catch (e) {
20123 // This method must not throw, or React internal state will get messed up.
20124 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
20125 // we want to report this error outside of the normal stack as a last resort.
20126 // https://github.com/facebook/react/issues/13188
20127 setTimeout(function () {
20128 throw e;
20129 });
20130 }
20131 }
20132
20133 var PossiblyWeakMap$1 = typeof WeakMap === 'function' ? WeakMap : Map;
20134
20135 function createRootErrorUpdate(fiber, errorInfo, lane) {
20136 var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null.
20137
20138 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property
20139 // being called "element".
20140
20141 update.payload = {
20142 element: null
20143 };
20144 var error = errorInfo.value;
20145
20146 update.callback = function () {
20147 onUncaughtError(error);
20148 logCapturedError(fiber, errorInfo);
20149 };
20150
20151 return update;
20152 }
20153
20154 function createClassErrorUpdate(fiber, errorInfo, lane) {
20155 var update = createUpdate(NoTimestamp, lane);
20156 update.tag = CaptureUpdate;
20157 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
20158
20159 if (typeof getDerivedStateFromError === 'function') {
20160 var error$1 = errorInfo.value;
20161
20162 update.payload = function () {
20163 logCapturedError(fiber, errorInfo);
20164 return getDerivedStateFromError(error$1);
20165 };
20166 }
20167
20168 var inst = fiber.stateNode;
20169
20170 if (inst !== null && typeof inst.componentDidCatch === 'function') {
20171 update.callback = function callback() {
20172 {
20173 markFailedErrorBoundaryForHotReloading(fiber);
20174 }
20175
20176 if (typeof getDerivedStateFromError !== 'function') {
20177 // To preserve the preexisting retry behavior of error boundaries,
20178 // we keep track of which ones already failed during this batch.
20179 // This gets reset before we yield back to the browser.
20180 // TODO: Warn in strict mode if getDerivedStateFromError is
20181 // not defined.
20182 markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined
20183
20184 logCapturedError(fiber, errorInfo);
20185 }
20186
20187 var error$1 = errorInfo.value;
20188 var stack = errorInfo.stack;
20189 this.componentDidCatch(error$1, {
20190 componentStack: stack !== null ? stack : ''
20191 });
20192
20193 {
20194 if (typeof getDerivedStateFromError !== 'function') {
20195 // If componentDidCatch is the only error boundary method defined,
20196 // then it needs to call setState to recover from errors.
20197 // If no state update is scheduled then the boundary will swallow the error.
20198 if (!includesSomeLane(fiber.lanes, SyncLane)) {
20199 error('%s: Error boundaries should implement getDerivedStateFromError(). ' + 'In that method, return a state update to display an error message or fallback UI.', getComponentName(fiber.type) || 'Unknown');
20200 }
20201 }
20202 }
20203 };
20204 } else {
20205 update.callback = function () {
20206 markFailedErrorBoundaryForHotReloading(fiber);
20207 };
20208 }
20209
20210 return update;
20211 }
20212
20213 function attachPingListener(root, wakeable, lanes) {
20214 // Attach a listener to the promise to "ping" the root and retry. But only if
20215 // one does not already exist for the lanes we're currently rendering (which
20216 // acts like a "thread ID" here).
20217 var pingCache = root.pingCache;
20218 var threadIDs;
20219
20220 if (pingCache === null) {
20221 pingCache = root.pingCache = new PossiblyWeakMap$1();
20222 threadIDs = new Set();
20223 pingCache.set(wakeable, threadIDs);
20224 } else {
20225 threadIDs = pingCache.get(wakeable);
20226
20227 if (threadIDs === undefined) {
20228 threadIDs = new Set();
20229 pingCache.set(wakeable, threadIDs);
20230 }
20231 }
20232
20233 if (!threadIDs.has(lanes)) {
20234 // Memoize using the thread ID to prevent redundant listeners.
20235 threadIDs.add(lanes);
20236 var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes);
20237 wakeable.then(ping, ping);
20238 }
20239 }
20240
20241 function throwException(root, returnFiber, sourceFiber, value, rootRenderLanes) {
20242 // The source fiber did not complete.
20243 sourceFiber.flags |= Incomplete; // Its effect list is no longer valid.
20244
20245 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
20246
20247 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
20248 // This is a wakeable.
20249 var wakeable = value;
20250
20251 if ((sourceFiber.mode & BlockingMode) === NoMode) {
20252 // Reset the memoizedState to what it was before we attempted
20253 // to render it.
20254 var currentSource = sourceFiber.alternate;
20255
20256 if (currentSource) {
20257 sourceFiber.updateQueue = currentSource.updateQueue;
20258 sourceFiber.memoizedState = currentSource.memoizedState;
20259 sourceFiber.lanes = currentSource.lanes;
20260 } else {
20261 sourceFiber.updateQueue = null;
20262 sourceFiber.memoizedState = null;
20263 }
20264 }
20265
20266 var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext); // Schedule the nearest Suspense to re-render the timed out view.
20267
20268 var _workInProgress = returnFiber;
20269
20270 do {
20271 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) {
20272 // Found the nearest boundary.
20273 // Stash the promise on the boundary fiber. If the boundary times out, we'll
20274 // attach another listener to flip the boundary back to its normal state.
20275 var wakeables = _workInProgress.updateQueue;
20276
20277 if (wakeables === null) {
20278 var updateQueue = new Set();
20279 updateQueue.add(wakeable);
20280 _workInProgress.updateQueue = updateQueue;
20281 } else {
20282 wakeables.add(wakeable);
20283 } // If the boundary is outside of blocking mode, we should *not*
20284 // suspend the commit. Pretend as if the suspended component rendered
20285 // null and keep rendering. In the commit phase, we'll schedule a
20286 // subsequent synchronous update to re-render the Suspense.
20287 //
20288 // Note: It doesn't matter whether the component that suspended was
20289 // inside a blocking mode tree. If the Suspense is outside of it, we
20290 // should *not* suspend the commit.
20291
20292
20293 if ((_workInProgress.mode & BlockingMode) === NoMode) {
20294 _workInProgress.flags |= DidCapture;
20295 sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete.
20296 // But we shouldn't call any lifecycle methods or callbacks. Remove
20297 // all lifecycle effect tags.
20298
20299 sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete);
20300
20301 if (sourceFiber.tag === ClassComponent) {
20302 var currentSourceFiber = sourceFiber.alternate;
20303
20304 if (currentSourceFiber === null) {
20305 // This is a new mount. Change the tag so it's not mistaken for a
20306 // completed class component. For example, we should not call
20307 // componentWillUnmount if it is deleted.
20308 sourceFiber.tag = IncompleteClassComponent;
20309 } else {
20310 // When we try rendering again, we should not reuse the current fiber,
20311 // since it's known to be in an inconsistent state. Use a force update to
20312 // prevent a bail out.
20313 var update = createUpdate(NoTimestamp, SyncLane);
20314 update.tag = ForceUpdate;
20315 enqueueUpdate(sourceFiber, update);
20316 }
20317 } // The source fiber did not complete. Mark it with Sync priority to
20318 // indicate that it still has pending work.
20319
20320
20321 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane); // Exit without suspending.
20322
20323 return;
20324 } // Confirmed that the boundary is in a concurrent mode tree. Continue
20325 // with the normal suspend path.
20326 //
20327 // After this we'll use a set of heuristics to determine whether this
20328 // render pass will run to completion or restart or "suspend" the commit.
20329 // The actual logic for this is spread out in different places.
20330 //
20331 // This first principle is that if we're going to suspend when we complete
20332 // a root, then we should also restart if we get an update or ping that
20333 // might unsuspend it, and vice versa. The only reason to suspend is
20334 // because you think you might want to restart before committing. However,
20335 // it doesn't make sense to restart only while in the period we're suspended.
20336 //
20337 // Restarting too aggressively is also not good because it starves out any
20338 // intermediate loading state. So we use heuristics to determine when.
20339 // Suspense Heuristics
20340 //
20341 // If nothing threw a Promise or all the same fallbacks are already showing,
20342 // then don't suspend/restart.
20343 //
20344 // If this is an initial render of a new tree of Suspense boundaries and
20345 // those trigger a fallback, then don't suspend/restart. We want to ensure
20346 // that we can show the initial loading state as quickly as possible.
20347 //
20348 // If we hit a "Delayed" case, such as when we'd switch from content back into
20349 // a fallback, then we should always suspend/restart. Transitions apply
20350 // to this case. If none is defined, JND is used instead.
20351 //
20352 // If we're already showing a fallback and it gets "retried", allowing us to show
20353 // another level, but there's still an inner boundary that would show a fallback,
20354 // then we suspend/restart for 500ms since the last time we showed a fallback
20355 // anywhere in the tree. This effectively throttles progressive loading into a
20356 // consistent train of commits. This also gives us an opportunity to restart to
20357 // get to the completed state slightly earlier.
20358 //
20359 // If there's ambiguity due to batching it's resolved in preference of:
20360 // 1) "delayed", 2) "initial render", 3) "retry".
20361 //
20362 // We want to ensure that a "busy" state doesn't get force committed. We want to
20363 // ensure that new initial loading states can commit as soon as possible.
20364
20365
20366 attachPingListener(root, wakeable, rootRenderLanes);
20367 _workInProgress.flags |= ShouldCapture;
20368 _workInProgress.lanes = rootRenderLanes;
20369 return;
20370 } // This boundary already captured during this render. Continue to the next
20371 // boundary.
20372
20373
20374 _workInProgress = _workInProgress.return;
20375 } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode.
20376 // TODO: Use invariant so the message is stripped in prod?
20377
20378
20379 value = new Error((getComponentName(sourceFiber.type) || 'A React component') + ' suspended while rendering, but no fallback UI was specified.\n' + '\n' + 'Add a <Suspense fallback=...> component higher in the tree to ' + 'provide a loading indicator or placeholder to display.');
20380 } // We didn't find a boundary that could handle this type of exception. Start
20381 // over and traverse parent path again, this time treating the exception
20382 // as an error.
20383
20384
20385 renderDidError();
20386 value = createCapturedValue(value, sourceFiber);
20387 var workInProgress = returnFiber;
20388
20389 do {
20390 switch (workInProgress.tag) {
20391 case HostRoot:
20392 {
20393 var _errorInfo = value;
20394 workInProgress.flags |= ShouldCapture;
20395 var lane = pickArbitraryLane(rootRenderLanes);
20396 workInProgress.lanes = mergeLanes(workInProgress.lanes, lane);
20397
20398 var _update = createRootErrorUpdate(workInProgress, _errorInfo, lane);
20399
20400 enqueueCapturedUpdate(workInProgress, _update);
20401 return;
20402 }
20403
20404 case ClassComponent:
20405 // Capture and retry
20406 var errorInfo = value;
20407 var ctor = workInProgress.type;
20408 var instance = workInProgress.stateNode;
20409
20410 if ((workInProgress.flags & DidCapture) === NoFlags && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
20411 workInProgress.flags |= ShouldCapture;
20412
20413 var _lane = pickArbitraryLane(rootRenderLanes);
20414
20415 workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state
20416
20417 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, _lane);
20418
20419 enqueueCapturedUpdate(workInProgress, _update2);
20420 return;
20421 }
20422
20423 break;
20424 }
20425
20426 workInProgress = workInProgress.return;
20427 } while (workInProgress !== null);
20428 }
20429
20430 var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
20431
20432 {
20433 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
20434 }
20435
20436 var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
20437
20438 var callComponentWillUnmountWithTimer = function (current, instance) {
20439 instance.props = current.memoizedProps;
20440 instance.state = current.memoizedState;
20441
20442 {
20443 instance.componentWillUnmount();
20444 }
20445 }; // Capture errors so they don't interrupt unmounting.
20446
20447
20448 function safelyCallComponentWillUnmount(current, instance) {
20449 {
20450 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance);
20451
20452 if (hasCaughtError()) {
20453 var unmountError = clearCaughtError();
20454 captureCommitPhaseError(current, unmountError);
20455 }
20456 }
20457 }
20458
20459 function safelyDetachRef(current) {
20460 var ref = current.ref;
20461
20462 if (ref !== null) {
20463 if (typeof ref === 'function') {
20464 {
20465 invokeGuardedCallback(null, ref, null, null);
20466
20467 if (hasCaughtError()) {
20468 var refError = clearCaughtError();
20469 captureCommitPhaseError(current, refError);
20470 }
20471 }
20472 } else {
20473 ref.current = null;
20474 }
20475 }
20476 }
20477
20478 function safelyCallDestroy(current, destroy) {
20479 {
20480 invokeGuardedCallback(null, destroy, null);
20481
20482 if (hasCaughtError()) {
20483 var error = clearCaughtError();
20484 captureCommitPhaseError(current, error);
20485 }
20486 }
20487 }
20488
20489 function commitBeforeMutationLifeCycles(current, finishedWork) {
20490 switch (finishedWork.tag) {
20491 case FunctionComponent:
20492 case ForwardRef:
20493 case SimpleMemoComponent:
20494 case Block:
20495 {
20496 return;
20497 }
20498
20499 case ClassComponent:
20500 {
20501 if (finishedWork.flags & Snapshot) {
20502 if (current !== null) {
20503 var prevProps = current.memoizedProps;
20504 var prevState = current.memoizedState;
20505 var instance = finishedWork.stateNode; // We could update instance props and state here,
20506 // but instead we rely on them being set during last render.
20507 // TODO: revisit this when we implement resuming.
20508
20509 {
20510 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
20511 if (instance.props !== finishedWork.memoizedProps) {
20512 error('Expected %s props to match memoized props before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
20513 }
20514
20515 if (instance.state !== finishedWork.memoizedState) {
20516 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.', getComponentName(finishedWork.type) || 'instance');
20517 }
20518 }
20519 }
20520
20521 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
20522
20523 {
20524 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
20525
20526 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
20527 didWarnSet.add(finishedWork.type);
20528
20529 error('%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
20530 }
20531 }
20532
20533 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
20534 }
20535 }
20536
20537 return;
20538 }
20539
20540 case HostRoot:
20541 {
20542 {
20543 if (finishedWork.flags & Snapshot) {
20544 var root = finishedWork.stateNode;
20545 clearContainer(root.containerInfo);
20546 }
20547 }
20548
20549 return;
20550 }
20551
20552 case HostComponent:
20553 case HostText:
20554 case HostPortal:
20555 case IncompleteClassComponent:
20556 // Nothing to do for these component types
20557 return;
20558 }
20559
20560 {
20561 {
20562 throw Error( "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." );
20563 }
20564 }
20565 }
20566
20567 function commitHookEffectListUnmount(tag, finishedWork) {
20568 var updateQueue = finishedWork.updateQueue;
20569 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
20570
20571 if (lastEffect !== null) {
20572 var firstEffect = lastEffect.next;
20573 var effect = firstEffect;
20574
20575 do {
20576 if ((effect.tag & tag) === tag) {
20577 // Unmount
20578 var destroy = effect.destroy;
20579 effect.destroy = undefined;
20580
20581 if (destroy !== undefined) {
20582 destroy();
20583 }
20584 }
20585
20586 effect = effect.next;
20587 } while (effect !== firstEffect);
20588 }
20589 }
20590
20591 function commitHookEffectListMount(tag, finishedWork) {
20592 var updateQueue = finishedWork.updateQueue;
20593 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
20594
20595 if (lastEffect !== null) {
20596 var firstEffect = lastEffect.next;
20597 var effect = firstEffect;
20598
20599 do {
20600 if ((effect.tag & tag) === tag) {
20601 // Mount
20602 var create = effect.create;
20603 effect.destroy = create();
20604
20605 {
20606 var destroy = effect.destroy;
20607
20608 if (destroy !== undefined && typeof destroy !== 'function') {
20609 var addendum = void 0;
20610
20611 if (destroy === null) {
20612 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
20613 } else if (typeof destroy.then === 'function') {
20614 addendum = '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' + 'Instead, write the async function inside your effect ' + 'and call it immediately:\n\n' + 'useEffect(() => {\n' + ' async function fetchData() {\n' + ' // You can await here\n' + ' const response = await MyAPI.getData(someId);\n' + ' // ...\n' + ' }\n' + ' fetchData();\n' + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + 'Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching';
20615 } else {
20616 addendum = ' You returned: ' + destroy;
20617 }
20618
20619 error('An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s', addendum);
20620 }
20621 }
20622 }
20623
20624 effect = effect.next;
20625 } while (effect !== firstEffect);
20626 }
20627 }
20628
20629 function schedulePassiveEffects(finishedWork) {
20630 var updateQueue = finishedWork.updateQueue;
20631 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
20632
20633 if (lastEffect !== null) {
20634 var firstEffect = lastEffect.next;
20635 var effect = firstEffect;
20636
20637 do {
20638 var _effect = effect,
20639 next = _effect.next,
20640 tag = _effect.tag;
20641
20642 if ((tag & Passive$1) !== NoFlags$1 && (tag & HasEffect) !== NoFlags$1) {
20643 enqueuePendingPassiveHookEffectUnmount(finishedWork, effect);
20644 enqueuePendingPassiveHookEffectMount(finishedWork, effect);
20645 }
20646
20647 effect = next;
20648 } while (effect !== firstEffect);
20649 }
20650 }
20651
20652 function commitLifeCycles(finishedRoot, current, finishedWork, committedLanes) {
20653 switch (finishedWork.tag) {
20654 case FunctionComponent:
20655 case ForwardRef:
20656 case SimpleMemoComponent:
20657 case Block:
20658 {
20659 // At this point layout effects have already been destroyed (during mutation phase).
20660 // This is done to prevent sibling component effects from interfering with each other,
20661 // e.g. a destroy function in one component should never override a ref set
20662 // by a create function in another component during the same commit.
20663 {
20664 commitHookEffectListMount(Layout | HasEffect, finishedWork);
20665 }
20666
20667 schedulePassiveEffects(finishedWork);
20668 return;
20669 }
20670
20671 case ClassComponent:
20672 {
20673 var instance = finishedWork.stateNode;
20674
20675 if (finishedWork.flags & Update) {
20676 if (current === null) {
20677 // We could update instance props and state here,
20678 // but instead we rely on them being set during last render.
20679 // TODO: revisit this when we implement resuming.
20680 {
20681 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
20682 if (instance.props !== finishedWork.memoizedProps) {
20683 error('Expected %s props to match memoized props before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
20684 }
20685
20686 if (instance.state !== finishedWork.memoizedState) {
20687 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.', getComponentName(finishedWork.type) || 'instance');
20688 }
20689 }
20690 }
20691
20692 {
20693 instance.componentDidMount();
20694 }
20695 } else {
20696 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
20697 var prevState = current.memoizedState; // We could update instance props and state here,
20698 // but instead we rely on them being set during last render.
20699 // TODO: revisit this when we implement resuming.
20700
20701 {
20702 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
20703 if (instance.props !== finishedWork.memoizedProps) {
20704 error('Expected %s props to match memoized props before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
20705 }
20706
20707 if (instance.state !== finishedWork.memoizedState) {
20708 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.', getComponentName(finishedWork.type) || 'instance');
20709 }
20710 }
20711 }
20712
20713 {
20714 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
20715 }
20716 }
20717 } // TODO: I think this is now always non-null by the time it reaches the
20718 // commit phase. Consider removing the type check.
20719
20720
20721 var updateQueue = finishedWork.updateQueue;
20722
20723 if (updateQueue !== null) {
20724 {
20725 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
20726 if (instance.props !== finishedWork.memoizedProps) {
20727 error('Expected %s props to match memoized props before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
20728 }
20729
20730 if (instance.state !== finishedWork.memoizedState) {
20731 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.', getComponentName(finishedWork.type) || 'instance');
20732 }
20733 }
20734 } // We could update instance props and state here,
20735 // but instead we rely on them being set during last render.
20736 // TODO: revisit this when we implement resuming.
20737
20738
20739 commitUpdateQueue(finishedWork, updateQueue, instance);
20740 }
20741
20742 return;
20743 }
20744
20745 case HostRoot:
20746 {
20747 // TODO: I think this is now always non-null by the time it reaches the
20748 // commit phase. Consider removing the type check.
20749 var _updateQueue = finishedWork.updateQueue;
20750
20751 if (_updateQueue !== null) {
20752 var _instance = null;
20753
20754 if (finishedWork.child !== null) {
20755 switch (finishedWork.child.tag) {
20756 case HostComponent:
20757 _instance = getPublicInstance(finishedWork.child.stateNode);
20758 break;
20759
20760 case ClassComponent:
20761 _instance = finishedWork.child.stateNode;
20762 break;
20763 }
20764 }
20765
20766 commitUpdateQueue(finishedWork, _updateQueue, _instance);
20767 }
20768
20769 return;
20770 }
20771
20772 case HostComponent:
20773 {
20774 var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted
20775 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
20776 // These effects should only be committed when components are first mounted,
20777 // aka when there is no current/alternate.
20778
20779 if (current === null && finishedWork.flags & Update) {
20780 var type = finishedWork.type;
20781 var props = finishedWork.memoizedProps;
20782 commitMount(_instance2, type, props);
20783 }
20784
20785 return;
20786 }
20787
20788 case HostText:
20789 {
20790 // We have no life-cycles associated with text.
20791 return;
20792 }
20793
20794 case HostPortal:
20795 {
20796 // We have no life-cycles associated with portals.
20797 return;
20798 }
20799
20800 case Profiler:
20801 {
20802 {
20803 var _finishedWork$memoize2 = finishedWork.memoizedProps,
20804 onCommit = _finishedWork$memoize2.onCommit,
20805 onRender = _finishedWork$memoize2.onRender;
20806 var effectDuration = finishedWork.stateNode.effectDuration;
20807 var commitTime = getCommitTime();
20808
20809 if (typeof onRender === 'function') {
20810 {
20811 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, commitTime, finishedRoot.memoizedInteractions);
20812 }
20813 }
20814 }
20815
20816 return;
20817 }
20818
20819 case SuspenseComponent:
20820 {
20821 commitSuspenseHydrationCallbacks(finishedRoot, finishedWork);
20822 return;
20823 }
20824
20825 case SuspenseListComponent:
20826 case IncompleteClassComponent:
20827 case FundamentalComponent:
20828 case ScopeComponent:
20829 case OffscreenComponent:
20830 case LegacyHiddenComponent:
20831 return;
20832 }
20833
20834 {
20835 {
20836 throw Error( "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." );
20837 }
20838 }
20839 }
20840
20841 function hideOrUnhideAllChildren(finishedWork, isHidden) {
20842 {
20843 // We only have the top Fiber that was inserted but we need to recurse down its
20844 // children to find all the terminal nodes.
20845 var node = finishedWork;
20846
20847 while (true) {
20848 if (node.tag === HostComponent) {
20849 var instance = node.stateNode;
20850
20851 if (isHidden) {
20852 hideInstance(instance);
20853 } else {
20854 unhideInstance(node.stateNode, node.memoizedProps);
20855 }
20856 } else if (node.tag === HostText) {
20857 var _instance3 = node.stateNode;
20858
20859 if (isHidden) {
20860 hideTextInstance(_instance3);
20861 } else {
20862 unhideTextInstance(_instance3, node.memoizedProps);
20863 }
20864 } else if ((node.tag === OffscreenComponent || node.tag === LegacyHiddenComponent) && node.memoizedState !== null && node !== finishedWork) ; else if (node.child !== null) {
20865 node.child.return = node;
20866 node = node.child;
20867 continue;
20868 }
20869
20870 if (node === finishedWork) {
20871 return;
20872 }
20873
20874 while (node.sibling === null) {
20875 if (node.return === null || node.return === finishedWork) {
20876 return;
20877 }
20878
20879 node = node.return;
20880 }
20881
20882 node.sibling.return = node.return;
20883 node = node.sibling;
20884 }
20885 }
20886 }
20887
20888 function commitAttachRef(finishedWork) {
20889 var ref = finishedWork.ref;
20890
20891 if (ref !== null) {
20892 var instance = finishedWork.stateNode;
20893 var instanceToUse;
20894
20895 switch (finishedWork.tag) {
20896 case HostComponent:
20897 instanceToUse = getPublicInstance(instance);
20898 break;
20899
20900 default:
20901 instanceToUse = instance;
20902 } // Moved outside to ensure DCE works with this flag
20903
20904 if (typeof ref === 'function') {
20905 ref(instanceToUse);
20906 } else {
20907 {
20908 if (!ref.hasOwnProperty('current')) {
20909 error('Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().', getComponentName(finishedWork.type));
20910 }
20911 }
20912
20913 ref.current = instanceToUse;
20914 }
20915 }
20916 }
20917
20918 function commitDetachRef(current) {
20919 var currentRef = current.ref;
20920
20921 if (currentRef !== null) {
20922 if (typeof currentRef === 'function') {
20923 currentRef(null);
20924 } else {
20925 currentRef.current = null;
20926 }
20927 }
20928 } // User-originating errors (lifecycles and refs) should not interrupt
20929 // deletion, so don't let them throw. Host-originating errors should
20930 // interrupt deletion, so it's okay
20931
20932
20933 function commitUnmount(finishedRoot, current, renderPriorityLevel) {
20934 onCommitUnmount(current);
20935
20936 switch (current.tag) {
20937 case FunctionComponent:
20938 case ForwardRef:
20939 case MemoComponent:
20940 case SimpleMemoComponent:
20941 case Block:
20942 {
20943 var updateQueue = current.updateQueue;
20944
20945 if (updateQueue !== null) {
20946 var lastEffect = updateQueue.lastEffect;
20947
20948 if (lastEffect !== null) {
20949 var firstEffect = lastEffect.next;
20950 var effect = firstEffect;
20951
20952 do {
20953 var _effect2 = effect,
20954 destroy = _effect2.destroy,
20955 tag = _effect2.tag;
20956
20957 if (destroy !== undefined) {
20958 if ((tag & Passive$1) !== NoFlags$1) {
20959 enqueuePendingPassiveHookEffectUnmount(current, effect);
20960 } else {
20961 {
20962 safelyCallDestroy(current, destroy);
20963 }
20964 }
20965 }
20966
20967 effect = effect.next;
20968 } while (effect !== firstEffect);
20969 }
20970 }
20971
20972 return;
20973 }
20974
20975 case ClassComponent:
20976 {
20977 safelyDetachRef(current);
20978 var instance = current.stateNode;
20979
20980 if (typeof instance.componentWillUnmount === 'function') {
20981 safelyCallComponentWillUnmount(current, instance);
20982 }
20983
20984 return;
20985 }
20986
20987 case HostComponent:
20988 {
20989 safelyDetachRef(current);
20990 return;
20991 }
20992
20993 case HostPortal:
20994 {
20995 // TODO: this is recursive.
20996 // We are also not using this parent because
20997 // the portal will get pushed immediately.
20998 {
20999 unmountHostComponents(finishedRoot, current);
21000 }
21001
21002 return;
21003 }
21004
21005 case FundamentalComponent:
21006 {
21007
21008 return;
21009 }
21010
21011 case DehydratedFragment:
21012 {
21013
21014 return;
21015 }
21016
21017 case ScopeComponent:
21018 {
21019
21020 return;
21021 }
21022 }
21023 }
21024
21025 function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) {
21026 // While we're inside a removed host node we don't want to call
21027 // removeChild on the inner nodes because they're removed by the top
21028 // call anyway. We also want to call componentWillUnmount on all
21029 // composites before this host node is removed from the tree. Therefore
21030 // we do an inner loop while we're still inside the host node.
21031 var node = root;
21032
21033 while (true) {
21034 commitUnmount(finishedRoot, node); // Visit children because they may contain more composite or host nodes.
21035 // Skip portals because commitUnmount() currently visits them recursively.
21036
21037 if (node.child !== null && ( // If we use mutation we drill down into portals using commitUnmount above.
21038 // If we don't use mutation we drill down into portals here instead.
21039 node.tag !== HostPortal)) {
21040 node.child.return = node;
21041 node = node.child;
21042 continue;
21043 }
21044
21045 if (node === root) {
21046 return;
21047 }
21048
21049 while (node.sibling === null) {
21050 if (node.return === null || node.return === root) {
21051 return;
21052 }
21053
21054 node = node.return;
21055 }
21056
21057 node.sibling.return = node.return;
21058 node = node.sibling;
21059 }
21060 }
21061
21062 function detachFiberMutation(fiber) {
21063 // Cut off the return pointers to disconnect it from the tree. Ideally, we
21064 // should clear the child pointer of the parent alternate to let this
21065 // get GC:ed but we don't know which for sure which parent is the current
21066 // one so we'll settle for GC:ing the subtree of this child. This child
21067 // itself will be GC:ed when the parent updates the next time.
21068 // Note: we cannot null out sibling here, otherwise it can cause issues
21069 // with findDOMNode and how it requires the sibling field to carry out
21070 // traversal in a later effect. See PR #16820. We now clear the sibling
21071 // field after effects, see: detachFiberAfterEffects.
21072 //
21073 // Don't disconnect stateNode now; it will be detached in detachFiberAfterEffects.
21074 // It may be required if the current component is an error boundary,
21075 // and one of its descendants throws while unmounting a passive effect.
21076 fiber.alternate = null;
21077 fiber.child = null;
21078 fiber.dependencies = null;
21079 fiber.firstEffect = null;
21080 fiber.lastEffect = null;
21081 fiber.memoizedProps = null;
21082 fiber.memoizedState = null;
21083 fiber.pendingProps = null;
21084 fiber.return = null;
21085 fiber.updateQueue = null;
21086
21087 {
21088 fiber._debugOwner = null;
21089 }
21090 }
21091
21092 function getHostParentFiber(fiber) {
21093 var parent = fiber.return;
21094
21095 while (parent !== null) {
21096 if (isHostParent(parent)) {
21097 return parent;
21098 }
21099
21100 parent = parent.return;
21101 }
21102
21103 {
21104 {
21105 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." );
21106 }
21107 }
21108 }
21109
21110 function isHostParent(fiber) {
21111 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
21112 }
21113
21114 function getHostSibling(fiber) {
21115 // We're going to search forward into the tree until we find a sibling host
21116 // node. Unfortunately, if multiple insertions are done in a row we have to
21117 // search past them. This leads to exponential search for the next sibling.
21118 // TODO: Find a more efficient way to do this.
21119 var node = fiber;
21120
21121 siblings: while (true) {
21122 // If we didn't find anything, let's try the next sibling.
21123 while (node.sibling === null) {
21124 if (node.return === null || isHostParent(node.return)) {
21125 // If we pop out of the root or hit the parent the fiber we are the
21126 // last sibling.
21127 return null;
21128 }
21129
21130 node = node.return;
21131 }
21132
21133 node.sibling.return = node.return;
21134 node = node.sibling;
21135
21136 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) {
21137 // If it is not host node and, we might have a host node inside it.
21138 // Try to search down until we find one.
21139 if (node.flags & Placement) {
21140 // If we don't have a child, try the siblings instead.
21141 continue siblings;
21142 } // If we don't have a child, try the siblings instead.
21143 // We also skip portals because they are not part of this host tree.
21144
21145
21146 if (node.child === null || node.tag === HostPortal) {
21147 continue siblings;
21148 } else {
21149 node.child.return = node;
21150 node = node.child;
21151 }
21152 } // Check if this host node is stable or about to be placed.
21153
21154
21155 if (!(node.flags & Placement)) {
21156 // Found it!
21157 return node.stateNode;
21158 }
21159 }
21160 }
21161
21162 function commitPlacement(finishedWork) {
21163
21164
21165 var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together.
21166
21167 var parent;
21168 var isContainer;
21169 var parentStateNode = parentFiber.stateNode;
21170
21171 switch (parentFiber.tag) {
21172 case HostComponent:
21173 parent = parentStateNode;
21174 isContainer = false;
21175 break;
21176
21177 case HostRoot:
21178 parent = parentStateNode.containerInfo;
21179 isContainer = true;
21180 break;
21181
21182 case HostPortal:
21183 parent = parentStateNode.containerInfo;
21184 isContainer = true;
21185 break;
21186
21187 case FundamentalComponent:
21188
21189 // eslint-disable-next-line-no-fallthrough
21190
21191 default:
21192 {
21193 {
21194 throw Error( "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." );
21195 }
21196 }
21197
21198 }
21199
21200 if (parentFiber.flags & ContentReset) {
21201 // Reset the text content of the parent before doing any insertions
21202 resetTextContent(parent); // Clear ContentReset from the effect tag
21203
21204 parentFiber.flags &= ~ContentReset;
21205 }
21206
21207 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
21208 // children to find all the terminal nodes.
21209
21210 if (isContainer) {
21211 insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent);
21212 } else {
21213 insertOrAppendPlacementNode(finishedWork, before, parent);
21214 }
21215 }
21216
21217 function insertOrAppendPlacementNodeIntoContainer(node, before, parent) {
21218 var tag = node.tag;
21219 var isHost = tag === HostComponent || tag === HostText;
21220
21221 if (isHost || enableFundamentalAPI ) {
21222 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
21223
21224 if (before) {
21225 insertInContainerBefore(parent, stateNode, before);
21226 } else {
21227 appendChildToContainer(parent, stateNode);
21228 }
21229 } else if (tag === HostPortal) ; else {
21230 var child = node.child;
21231
21232 if (child !== null) {
21233 insertOrAppendPlacementNodeIntoContainer(child, before, parent);
21234 var sibling = child.sibling;
21235
21236 while (sibling !== null) {
21237 insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);
21238 sibling = sibling.sibling;
21239 }
21240 }
21241 }
21242 }
21243
21244 function insertOrAppendPlacementNode(node, before, parent) {
21245 var tag = node.tag;
21246 var isHost = tag === HostComponent || tag === HostText;
21247
21248 if (isHost || enableFundamentalAPI ) {
21249 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
21250
21251 if (before) {
21252 insertBefore(parent, stateNode, before);
21253 } else {
21254 appendChild(parent, stateNode);
21255 }
21256 } else if (tag === HostPortal) ; else {
21257 var child = node.child;
21258
21259 if (child !== null) {
21260 insertOrAppendPlacementNode(child, before, parent);
21261 var sibling = child.sibling;
21262
21263 while (sibling !== null) {
21264 insertOrAppendPlacementNode(sibling, before, parent);
21265 sibling = sibling.sibling;
21266 }
21267 }
21268 }
21269 }
21270
21271 function unmountHostComponents(finishedRoot, current, renderPriorityLevel) {
21272 // We only have the top Fiber that was deleted but we need to recurse down its
21273 // children to find all the terminal nodes.
21274 var node = current; // Each iteration, currentParent is populated with node's host parent if not
21275 // currentParentIsValid.
21276
21277 var currentParentIsValid = false; // Note: these two variables *must* always be updated together.
21278
21279 var currentParent;
21280 var currentParentIsContainer;
21281
21282 while (true) {
21283 if (!currentParentIsValid) {
21284 var parent = node.return;
21285
21286 findParent: while (true) {
21287 if (!(parent !== null)) {
21288 {
21289 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." );
21290 }
21291 }
21292
21293 var parentStateNode = parent.stateNode;
21294
21295 switch (parent.tag) {
21296 case HostComponent:
21297 currentParent = parentStateNode;
21298 currentParentIsContainer = false;
21299 break findParent;
21300
21301 case HostRoot:
21302 currentParent = parentStateNode.containerInfo;
21303 currentParentIsContainer = true;
21304 break findParent;
21305
21306 case HostPortal:
21307 currentParent = parentStateNode.containerInfo;
21308 currentParentIsContainer = true;
21309 break findParent;
21310
21311 }
21312
21313 parent = parent.return;
21314 }
21315
21316 currentParentIsValid = true;
21317 }
21318
21319 if (node.tag === HostComponent || node.tag === HostText) {
21320 commitNestedUnmounts(finishedRoot, node); // After all the children have unmounted, it is now safe to remove the
21321 // node from the tree.
21322
21323 if (currentParentIsContainer) {
21324 removeChildFromContainer(currentParent, node.stateNode);
21325 } else {
21326 removeChild(currentParent, node.stateNode);
21327 } // Don't visit children because we already visited them.
21328
21329 } else if (node.tag === HostPortal) {
21330 if (node.child !== null) {
21331 // When we go into a portal, it becomes the parent to remove from.
21332 // We will reassign it back when we pop the portal on the way up.
21333 currentParent = node.stateNode.containerInfo;
21334 currentParentIsContainer = true; // Visit children because portals might contain host components.
21335
21336 node.child.return = node;
21337 node = node.child;
21338 continue;
21339 }
21340 } else {
21341 commitUnmount(finishedRoot, node); // Visit children because we may find more host components below.
21342
21343 if (node.child !== null) {
21344 node.child.return = node;
21345 node = node.child;
21346 continue;
21347 }
21348 }
21349
21350 if (node === current) {
21351 return;
21352 }
21353
21354 while (node.sibling === null) {
21355 if (node.return === null || node.return === current) {
21356 return;
21357 }
21358
21359 node = node.return;
21360
21361 if (node.tag === HostPortal) {
21362 // When we go out of the portal, we need to restore the parent.
21363 // Since we don't keep a stack of them, we will search for it.
21364 currentParentIsValid = false;
21365 }
21366 }
21367
21368 node.sibling.return = node.return;
21369 node = node.sibling;
21370 }
21371 }
21372
21373 function commitDeletion(finishedRoot, current, renderPriorityLevel) {
21374 {
21375 // Recursively delete all host nodes from the parent.
21376 // Detach refs and call componentWillUnmount() on the whole subtree.
21377 unmountHostComponents(finishedRoot, current);
21378 }
21379
21380 var alternate = current.alternate;
21381 detachFiberMutation(current);
21382
21383 if (alternate !== null) {
21384 detachFiberMutation(alternate);
21385 }
21386 }
21387
21388 function commitWork(current, finishedWork) {
21389
21390 switch (finishedWork.tag) {
21391 case FunctionComponent:
21392 case ForwardRef:
21393 case MemoComponent:
21394 case SimpleMemoComponent:
21395 case Block:
21396 {
21397 // Layout effects are destroyed during the mutation phase so that all
21398 // destroy functions for all fibers are called before any create functions.
21399 // This prevents sibling component effects from interfering with each other,
21400 // e.g. a destroy function in one component should never override a ref set
21401 // by a create function in another component during the same commit.
21402 {
21403 commitHookEffectListUnmount(Layout | HasEffect, finishedWork);
21404 }
21405
21406 return;
21407 }
21408
21409 case ClassComponent:
21410 {
21411 return;
21412 }
21413
21414 case HostComponent:
21415 {
21416 var instance = finishedWork.stateNode;
21417
21418 if (instance != null) {
21419 // Commit the work prepared earlier.
21420 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
21421 // as the newProps. The updatePayload will contain the real change in
21422 // this case.
21423
21424 var oldProps = current !== null ? current.memoizedProps : newProps;
21425 var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components.
21426
21427 var updatePayload = finishedWork.updateQueue;
21428 finishedWork.updateQueue = null;
21429
21430 if (updatePayload !== null) {
21431 commitUpdate(instance, updatePayload, type, oldProps, newProps);
21432 }
21433 }
21434
21435 return;
21436 }
21437
21438 case HostText:
21439 {
21440 if (!(finishedWork.stateNode !== null)) {
21441 {
21442 throw Error( "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." );
21443 }
21444 }
21445
21446 var textInstance = finishedWork.stateNode;
21447 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
21448 // as the newProps. The updatePayload will contain the real change in
21449 // this case.
21450
21451 var oldText = current !== null ? current.memoizedProps : newText;
21452 commitTextUpdate(textInstance, oldText, newText);
21453 return;
21454 }
21455
21456 case HostRoot:
21457 {
21458 {
21459 var _root = finishedWork.stateNode;
21460
21461 if (_root.hydrate) {
21462 // We've just hydrated. No need to hydrate again.
21463 _root.hydrate = false;
21464 commitHydratedContainer(_root.containerInfo);
21465 }
21466 }
21467
21468 return;
21469 }
21470
21471 case Profiler:
21472 {
21473 return;
21474 }
21475
21476 case SuspenseComponent:
21477 {
21478 commitSuspenseComponent(finishedWork);
21479 attachSuspenseRetryListeners(finishedWork);
21480 return;
21481 }
21482
21483 case SuspenseListComponent:
21484 {
21485 attachSuspenseRetryListeners(finishedWork);
21486 return;
21487 }
21488
21489 case IncompleteClassComponent:
21490 {
21491 return;
21492 }
21493
21494 case FundamentalComponent:
21495 {
21496
21497 break;
21498 }
21499
21500 case ScopeComponent:
21501 {
21502
21503 break;
21504 }
21505
21506 case OffscreenComponent:
21507 case LegacyHiddenComponent:
21508 {
21509 var newState = finishedWork.memoizedState;
21510 var isHidden = newState !== null;
21511 hideOrUnhideAllChildren(finishedWork, isHidden);
21512 return;
21513 }
21514 }
21515
21516 {
21517 {
21518 throw Error( "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." );
21519 }
21520 }
21521 }
21522
21523 function commitSuspenseComponent(finishedWork) {
21524 var newState = finishedWork.memoizedState;
21525
21526 if (newState !== null) {
21527 markCommitTimeOfFallback();
21528
21529 {
21530 // Hide the Offscreen component that contains the primary children. TODO:
21531 // Ideally, this effect would have been scheduled on the Offscreen fiber
21532 // itself. That's how unhiding works: the Offscreen component schedules an
21533 // effect on itself. However, in this case, the component didn't complete,
21534 // so the fiber was never added to the effect list in the normal path. We
21535 // could have appended it to the effect list in the Suspense component's
21536 // second pass, but doing it this way is less complicated. This would be
21537 // simpler if we got rid of the effect list and traversed the tree, like
21538 // we're planning to do.
21539 var primaryChildParent = finishedWork.child;
21540 hideOrUnhideAllChildren(primaryChildParent, true);
21541 }
21542 }
21543 }
21544
21545 function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) {
21546
21547 var newState = finishedWork.memoizedState;
21548
21549 if (newState === null) {
21550 var current = finishedWork.alternate;
21551
21552 if (current !== null) {
21553 var prevState = current.memoizedState;
21554
21555 if (prevState !== null) {
21556 var suspenseInstance = prevState.dehydrated;
21557
21558 if (suspenseInstance !== null) {
21559 commitHydratedSuspenseInstance(suspenseInstance);
21560 }
21561 }
21562 }
21563 }
21564 }
21565
21566 function attachSuspenseRetryListeners(finishedWork) {
21567 // If this boundary just timed out, then it will have a set of wakeables.
21568 // For each wakeable, attach a listener so that when it resolves, React
21569 // attempts to re-render the boundary in the primary (pre-timeout) state.
21570 var wakeables = finishedWork.updateQueue;
21571
21572 if (wakeables !== null) {
21573 finishedWork.updateQueue = null;
21574 var retryCache = finishedWork.stateNode;
21575
21576 if (retryCache === null) {
21577 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
21578 }
21579
21580 wakeables.forEach(function (wakeable) {
21581 // Memoize using the boundary fiber to prevent redundant listeners.
21582 var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable);
21583
21584 if (!retryCache.has(wakeable)) {
21585 {
21586 if (wakeable.__reactDoNotTraceInteractions !== true) {
21587 retry = unstable_wrap(retry);
21588 }
21589 }
21590
21591 retryCache.add(wakeable);
21592 wakeable.then(retry, retry);
21593 }
21594 });
21595 }
21596 } // This function detects when a Suspense boundary goes from visible to hidden.
21597 // It returns false if the boundary is already hidden.
21598 // TODO: Use an effect tag.
21599
21600
21601 function isSuspenseBoundaryBeingHidden(current, finishedWork) {
21602 if (current !== null) {
21603 var oldState = current.memoizedState;
21604
21605 if (oldState === null || oldState.dehydrated !== null) {
21606 var newState = finishedWork.memoizedState;
21607 return newState !== null && newState.dehydrated === null;
21608 }
21609 }
21610
21611 return false;
21612 }
21613
21614 function commitResetTextContent(current) {
21615
21616 resetTextContent(current.stateNode);
21617 }
21618
21619 var COMPONENT_TYPE = 0;
21620 var HAS_PSEUDO_CLASS_TYPE = 1;
21621 var ROLE_TYPE = 2;
21622 var TEST_NAME_TYPE = 3;
21623 var TEXT_TYPE = 4;
21624
21625 if (typeof Symbol === 'function' && Symbol.for) {
21626 var symbolFor$1 = Symbol.for;
21627 COMPONENT_TYPE = symbolFor$1('selector.component');
21628 HAS_PSEUDO_CLASS_TYPE = symbolFor$1('selector.has_pseudo_class');
21629 ROLE_TYPE = symbolFor$1('selector.role');
21630 TEST_NAME_TYPE = symbolFor$1('selector.test_id');
21631 TEXT_TYPE = symbolFor$1('selector.text');
21632 }
21633 var commitHooks = [];
21634 function onCommitRoot$1() {
21635 {
21636 commitHooks.forEach(function (commitHook) {
21637 return commitHook();
21638 });
21639 }
21640 }
21641
21642 var ceil = Math.ceil;
21643 var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher,
21644 ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner,
21645 IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing;
21646 var NoContext =
21647 /* */
21648 0;
21649 var BatchedContext =
21650 /* */
21651 1;
21652 var EventContext =
21653 /* */
21654 2;
21655 var DiscreteEventContext =
21656 /* */
21657 4;
21658 var LegacyUnbatchedContext =
21659 /* */
21660 8;
21661 var RenderContext =
21662 /* */
21663 16;
21664 var CommitContext =
21665 /* */
21666 32;
21667 var RetryAfterError =
21668 /* */
21669 64;
21670 var RootIncomplete = 0;
21671 var RootFatalErrored = 1;
21672 var RootErrored = 2;
21673 var RootSuspended = 3;
21674 var RootSuspendedWithDelay = 4;
21675 var RootCompleted = 5; // Describes where we are in the React execution stack
21676
21677 var executionContext = NoContext; // The root we're working on
21678
21679 var workInProgressRoot = null; // The fiber we're working on
21680
21681 var workInProgress = null; // The lanes we're rendering
21682
21683 var workInProgressRootRenderLanes = NoLanes; // Stack that allows components to change the render lanes for its subtree
21684 // This is a superset of the lanes we started working on at the root. The only
21685 // case where it's different from `workInProgressRootRenderLanes` is when we
21686 // enter a subtree that is hidden and needs to be unhidden: Suspense and
21687 // Offscreen component.
21688 //
21689 // Most things in the work loop should deal with workInProgressRootRenderLanes.
21690 // Most things in begin/complete phases should deal with subtreeRenderLanes.
21691
21692 var subtreeRenderLanes = NoLanes;
21693 var subtreeRenderLanesCursor = createCursor(NoLanes); // Whether to root completed, errored, suspended, etc.
21694
21695 var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown
21696
21697 var workInProgressRootFatalError = null; // "Included" lanes refer to lanes that were worked on during this render. It's
21698 // slightly different than `renderLanes` because `renderLanes` can change as you
21699 // enter and exit an Offscreen tree. This value is the combination of all render
21700 // lanes for the entire render phase.
21701
21702 var workInProgressRootIncludedLanes = NoLanes; // The work left over by components that were visited during this render. Only
21703 // includes unprocessed updates, not work in bailed out children.
21704
21705 var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an interleaved event) during this render.
21706
21707 var workInProgressRootUpdatedLanes = NoLanes; // Lanes that were pinged (in an interleaved event) during this render.
21708
21709 var workInProgressRootPingedLanes = NoLanes;
21710 var mostRecentlyUpdatedRoot = null; // The most recent time we committed a fallback. This lets us ensure a train
21711 // model where we don't commit new loading states in too quick succession.
21712
21713 var globalMostRecentFallbackTime = 0;
21714 var FALLBACK_THROTTLE_MS = 500; // The absolute time for when we should start giving up on rendering
21715 // more and prefer CPU suspense heuristics instead.
21716
21717 var workInProgressRootRenderTargetTime = Infinity; // How long a render is supposed to take before we start following CPU
21718 // suspense heuristics and opt out of rendering more content.
21719
21720 var RENDER_TIMEOUT_MS = 500;
21721
21722 function resetRenderTimer() {
21723 workInProgressRootRenderTargetTime = now() + RENDER_TIMEOUT_MS;
21724 }
21725
21726 function getRenderTargetTime() {
21727 return workInProgressRootRenderTargetTime;
21728 }
21729 var nextEffect = null;
21730 var hasUncaughtError = false;
21731 var firstUncaughtError = null;
21732 var legacyErrorBoundariesThatAlreadyFailed = null;
21733 var rootDoesHavePassiveEffects = false;
21734 var rootWithPendingPassiveEffects = null;
21735 var pendingPassiveEffectsRenderPriority = NoPriority$1;
21736 var pendingPassiveEffectsLanes = NoLanes;
21737 var pendingPassiveHookEffectsMount = [];
21738 var pendingPassiveHookEffectsUnmount = [];
21739 var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates
21740
21741 var NESTED_UPDATE_LIMIT = 50;
21742 var nestedUpdateCount = 0;
21743 var rootWithNestedUpdates = null;
21744 var NESTED_PASSIVE_UPDATE_LIMIT = 50;
21745 var nestedPassiveUpdateCount = 0; // Marks the need to reschedule pending interactions at these lanes
21746 // during the commit phase. This enables them to be traced across components
21747 // that spawn new work during render. E.g. hidden boundaries, suspended SSR
21748 // hydration or SuspenseList.
21749 // TODO: Can use a bitmask instead of an array
21750
21751 var spawnedWorkDuringRender = null; // If two updates are scheduled within the same event, we should treat their
21752 // event times as simultaneous, even if the actual clock time has advanced
21753 // between the first and second call.
21754
21755 var currentEventTime = NoTimestamp;
21756 var currentEventWipLanes = NoLanes;
21757 var currentEventPendingLanes = NoLanes; // Dev only flag that tracks if passive effects are currently being flushed.
21758 // We warn about state updates for unmounted components differently in this case.
21759
21760 var isFlushingPassiveEffects = false;
21761 var focusedInstanceHandle = null;
21762 var shouldFireAfterActiveInstanceBlur = false;
21763 function getWorkInProgressRoot() {
21764 return workInProgressRoot;
21765 }
21766 function requestEventTime() {
21767 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
21768 // We're inside React, so it's fine to read the actual time.
21769 return now();
21770 } // We're not inside React, so we may be in the middle of a browser event.
21771
21772
21773 if (currentEventTime !== NoTimestamp) {
21774 // Use the same start time for all updates until we enter React again.
21775 return currentEventTime;
21776 } // This is the first update since React yielded. Compute a new start time.
21777
21778
21779 currentEventTime = now();
21780 return currentEventTime;
21781 }
21782 function requestUpdateLane(fiber) {
21783 // Special cases
21784 var mode = fiber.mode;
21785
21786 if ((mode & BlockingMode) === NoMode) {
21787 return SyncLane;
21788 } else if ((mode & ConcurrentMode) === NoMode) {
21789 return getCurrentPriorityLevel() === ImmediatePriority$1 ? SyncLane : SyncBatchedLane;
21790 } // The algorithm for assigning an update to a lane should be stable for all
21791 // updates at the same priority within the same event. To do this, the inputs
21792 // to the algorithm must be the same. For example, we use the `renderLanes`
21793 // to avoid choosing a lane that is already in the middle of rendering.
21794 //
21795 // However, the "included" lanes could be mutated in between updates in the
21796 // same event, like if you perform an update inside `flushSync`. Or any other
21797 // code path that might call `prepareFreshStack`.
21798 //
21799 // The trick we use is to cache the first of each of these inputs within an
21800 // event. Then reset the cached values once we can be sure the event is over.
21801 // Our heuristic for that is whenever we enter a concurrent work loop.
21802 //
21803 // We'll do the same for `currentEventPendingLanes` below.
21804
21805
21806 if (currentEventWipLanes === NoLanes) {
21807 currentEventWipLanes = workInProgressRootIncludedLanes;
21808 }
21809
21810 var isTransition = requestCurrentTransition() !== NoTransition;
21811
21812 if (isTransition) {
21813 if (currentEventPendingLanes !== NoLanes) {
21814 currentEventPendingLanes = mostRecentlyUpdatedRoot !== null ? mostRecentlyUpdatedRoot.pendingLanes : NoLanes;
21815 }
21816
21817 return findTransitionLane(currentEventWipLanes, currentEventPendingLanes);
21818 } // TODO: Remove this dependency on the Scheduler priority.
21819 // To do that, we're replacing it with an update lane priority.
21820
21821
21822 var schedulerPriority = getCurrentPriorityLevel(); // The old behavior was using the priority level of the Scheduler.
21823 // This couples React to the Scheduler internals, so we're replacing it
21824 // with the currentUpdateLanePriority above. As an example of how this
21825 // could be problematic, if we're not inside `Scheduler.runWithPriority`,
21826 // then we'll get the priority of the current running Scheduler task,
21827 // which is probably not what we want.
21828
21829 var lane;
21830
21831 if ( // TODO: Temporary. We're removing the concept of discrete updates.
21832 (executionContext & DiscreteEventContext) !== NoContext && schedulerPriority === UserBlockingPriority$2) {
21833 lane = findUpdateLane(InputDiscreteLanePriority, currentEventWipLanes);
21834 } else {
21835 var schedulerLanePriority = schedulerPriorityToLanePriority(schedulerPriority);
21836
21837 lane = findUpdateLane(schedulerLanePriority, currentEventWipLanes);
21838 }
21839
21840 return lane;
21841 }
21842
21843 function requestRetryLane(fiber) {
21844 // This is a fork of `requestUpdateLane` designed specifically for Suspense
21845 // "retries" — a special update that attempts to flip a Suspense boundary
21846 // from its placeholder state to its primary/resolved state.
21847 // Special cases
21848 var mode = fiber.mode;
21849
21850 if ((mode & BlockingMode) === NoMode) {
21851 return SyncLane;
21852 } else if ((mode & ConcurrentMode) === NoMode) {
21853 return getCurrentPriorityLevel() === ImmediatePriority$1 ? SyncLane : SyncBatchedLane;
21854 } // See `requestUpdateLane` for explanation of `currentEventWipLanes`
21855
21856
21857 if (currentEventWipLanes === NoLanes) {
21858 currentEventWipLanes = workInProgressRootIncludedLanes;
21859 }
21860
21861 return findRetryLane(currentEventWipLanes);
21862 }
21863
21864 function scheduleUpdateOnFiber(fiber, lane, eventTime) {
21865 checkForNestedUpdates();
21866 warnAboutRenderPhaseUpdatesInDEV(fiber);
21867 var root = markUpdateLaneFromFiberToRoot(fiber, lane);
21868
21869 if (root === null) {
21870 warnAboutUpdateOnUnmountedFiberInDEV(fiber);
21871 return null;
21872 } // Mark that the root has a pending update.
21873
21874
21875 markRootUpdated(root, lane, eventTime);
21876
21877 if (root === workInProgressRoot) {
21878 // Received an update to a tree that's in the middle of rendering. Mark
21879 // that there was an interleaved update work on this root. Unless the
21880 // `deferRenderPhaseUpdateToNextBatch` flag is off and this is a render
21881 // phase update. In that case, we don't treat render phase updates as if
21882 // they were interleaved, for backwards compat reasons.
21883 {
21884 workInProgressRootUpdatedLanes = mergeLanes(workInProgressRootUpdatedLanes, lane);
21885 }
21886
21887 if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
21888 // The root already suspended with a delay, which means this render
21889 // definitely won't finish. Since we have a new update, let's mark it as
21890 // suspended now, right before marking the incoming update. This has the
21891 // effect of interrupting the current render and switching to the update.
21892 // TODO: Make sure this doesn't override pings that happen while we've
21893 // already started rendering.
21894 markRootSuspended$1(root, workInProgressRootRenderLanes);
21895 }
21896 } // TODO: requestUpdateLanePriority also reads the priority. Pass the
21897 // priority as an argument to that function and this one.
21898
21899
21900 var priorityLevel = getCurrentPriorityLevel();
21901
21902 if (lane === SyncLane) {
21903 if ( // Check if we're inside unbatchedUpdates
21904 (executionContext & LegacyUnbatchedContext) !== NoContext && // Check if we're not already rendering
21905 (executionContext & (RenderContext | CommitContext)) === NoContext) {
21906 // Register pending interactions on the root to avoid losing traced interaction data.
21907 schedulePendingInteractions(root, lane); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed
21908 // root inside of batchedUpdates should be synchronous, but layout updates
21909 // should be deferred until the end of the batch.
21910
21911 performSyncWorkOnRoot(root);
21912 } else {
21913 ensureRootIsScheduled(root, eventTime);
21914 schedulePendingInteractions(root, lane);
21915
21916 if (executionContext === NoContext) {
21917 // Flush the synchronous work now, unless we're already working or inside
21918 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
21919 // scheduleCallbackForFiber to preserve the ability to schedule a callback
21920 // without immediately flushing it. We only do this for user-initiated
21921 // updates, to preserve historical behavior of legacy mode.
21922 resetRenderTimer();
21923 flushSyncCallbackQueue();
21924 }
21925 }
21926 } else {
21927 // Schedule a discrete update but only if it's not Sync.
21928 if ((executionContext & DiscreteEventContext) !== NoContext && ( // Only updates at user-blocking priority or greater are considered
21929 // discrete, even inside a discrete event.
21930 priorityLevel === UserBlockingPriority$2 || priorityLevel === ImmediatePriority$1)) {
21931 // This is the result of a discrete event. Track the lowest priority
21932 // discrete update per root so we can flush them early, if needed.
21933 if (rootsWithPendingDiscreteUpdates === null) {
21934 rootsWithPendingDiscreteUpdates = new Set([root]);
21935 } else {
21936 rootsWithPendingDiscreteUpdates.add(root);
21937 }
21938 } // Schedule other updates after in case the callback is sync.
21939
21940
21941 ensureRootIsScheduled(root, eventTime);
21942 schedulePendingInteractions(root, lane);
21943 } // We use this when assigning a lane for a transition inside
21944 // `requestUpdateLane`. We assume it's the same as the root being updated,
21945 // since in the common case of a single root app it probably is. If it's not
21946 // the same root, then it's not a huge deal, we just might batch more stuff
21947 // together more than necessary.
21948
21949
21950 mostRecentlyUpdatedRoot = root;
21951 } // This is split into a separate function so we can mark a fiber with pending
21952 // work without treating it as a typical update that originates from an event;
21953 // e.g. retrying a Suspense boundary isn't an update, but it does schedule work
21954 // on a fiber.
21955
21956 function markUpdateLaneFromFiberToRoot(sourceFiber, lane) {
21957 // Update the source fiber's lanes
21958 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, lane);
21959 var alternate = sourceFiber.alternate;
21960
21961 if (alternate !== null) {
21962 alternate.lanes = mergeLanes(alternate.lanes, lane);
21963 }
21964
21965 {
21966 if (alternate === null && (sourceFiber.flags & (Placement | Hydrating)) !== NoFlags) {
21967 warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);
21968 }
21969 } // Walk the parent path to the root and update the child expiration time.
21970
21971
21972 var node = sourceFiber;
21973 var parent = sourceFiber.return;
21974
21975 while (parent !== null) {
21976 parent.childLanes = mergeLanes(parent.childLanes, lane);
21977 alternate = parent.alternate;
21978
21979 if (alternate !== null) {
21980 alternate.childLanes = mergeLanes(alternate.childLanes, lane);
21981 } else {
21982 {
21983 if ((parent.flags & (Placement | Hydrating)) !== NoFlags) {
21984 warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);
21985 }
21986 }
21987 }
21988
21989 node = parent;
21990 parent = parent.return;
21991 }
21992
21993 if (node.tag === HostRoot) {
21994 var root = node.stateNode;
21995 return root;
21996 } else {
21997 return null;
21998 }
21999 } // Use this function to schedule a task for a root. There's only one task per
22000 // root; if a task was already scheduled, we'll check to make sure the priority
22001 // of the existing task is the same as the priority of the next level that the
22002 // root has work on. This function is called on every update, and right before
22003 // exiting a task.
22004
22005
22006 function ensureRootIsScheduled(root, currentTime) {
22007 var existingCallbackNode = root.callbackNode; // Check if any lanes are being starved by other work. If so, mark them as
22008 // expired so we know to work on those next.
22009
22010 markStarvedLanesAsExpired(root, currentTime); // Determine the next lanes to work on, and their priority.
22011
22012 var nextLanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes); // This returns the priority level computed during the `getNextLanes` call.
22013
22014 var newCallbackPriority = returnNextLanesPriority();
22015
22016 if (nextLanes === NoLanes) {
22017 // Special case: There's nothing to work on.
22018 if (existingCallbackNode !== null) {
22019 cancelCallback(existingCallbackNode);
22020 root.callbackNode = null;
22021 root.callbackPriority = NoLanePriority;
22022 }
22023
22024 return;
22025 } // Check if there's an existing task. We may be able to reuse it.
22026
22027
22028 if (existingCallbackNode !== null) {
22029 var existingCallbackPriority = root.callbackPriority;
22030
22031 if (existingCallbackPriority === newCallbackPriority) {
22032 // The priority hasn't changed. We can reuse the existing task. Exit.
22033 return;
22034 } // The priority changed. Cancel the existing callback. We'll schedule a new
22035 // one below.
22036
22037
22038 cancelCallback(existingCallbackNode);
22039 } // Schedule a new callback.
22040
22041
22042 var newCallbackNode;
22043
22044 if (newCallbackPriority === SyncLanePriority) {
22045 // Special case: Sync React callbacks are scheduled on a special
22046 // internal queue
22047 newCallbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
22048 } else if (newCallbackPriority === SyncBatchedLanePriority) {
22049 newCallbackNode = scheduleCallback(ImmediatePriority$1, performSyncWorkOnRoot.bind(null, root));
22050 } else {
22051 var schedulerPriorityLevel = lanePriorityToSchedulerPriority(newCallbackPriority);
22052 newCallbackNode = scheduleCallback(schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root));
22053 }
22054
22055 root.callbackPriority = newCallbackPriority;
22056 root.callbackNode = newCallbackNode;
22057 } // This is the entry point for every concurrent task, i.e. anything that
22058 // goes through Scheduler.
22059
22060
22061 function performConcurrentWorkOnRoot(root) {
22062 // Since we know we're in a React event, we can clear the current
22063 // event time. The next update will compute a new event time.
22064 currentEventTime = NoTimestamp;
22065 currentEventWipLanes = NoLanes;
22066 currentEventPendingLanes = NoLanes;
22067
22068 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
22069 {
22070 throw Error( "Should not already be working." );
22071 }
22072 } // Flush any pending passive effects before deciding which lanes to work on,
22073 // in case they schedule additional work.
22074
22075
22076 var originalCallbackNode = root.callbackNode;
22077 var didFlushPassiveEffects = flushPassiveEffects();
22078
22079 if (didFlushPassiveEffects) {
22080 // Something in the passive effect phase may have canceled the current task.
22081 // Check if the task node for this root was changed.
22082 if (root.callbackNode !== originalCallbackNode) {
22083 // The current task was canceled. Exit. We don't need to call
22084 // `ensureRootIsScheduled` because the check above implies either that
22085 // there's a new task, or that there's no remaining work on this root.
22086 return null;
22087 }
22088 } // Determine the next expiration time to work on, using the fields stored
22089 // on the root.
22090
22091
22092 var lanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);
22093
22094 if (lanes === NoLanes) {
22095 // Defensive coding. This is never expected to happen.
22096 return null;
22097 }
22098
22099 var exitStatus = renderRootConcurrent(root, lanes);
22100
22101 if (includesSomeLane(workInProgressRootIncludedLanes, workInProgressRootUpdatedLanes)) {
22102 // The render included lanes that were updated during the render phase.
22103 // For example, when unhiding a hidden tree, we include all the lanes
22104 // that were previously skipped when the tree was hidden. That set of
22105 // lanes is a superset of the lanes we started rendering with.
22106 //
22107 // So we'll throw out the current work and restart.
22108 prepareFreshStack(root, NoLanes);
22109 } else if (exitStatus !== RootIncomplete) {
22110 if (exitStatus === RootErrored) {
22111 executionContext |= RetryAfterError; // If an error occurred during hydration,
22112 // discard server response and fall back to client side render.
22113
22114 if (root.hydrate) {
22115 root.hydrate = false;
22116 clearContainer(root.containerInfo);
22117 } // If something threw an error, try rendering one more time. We'll render
22118 // synchronously to block concurrent data mutations, and we'll includes
22119 // all pending updates are included. If it still fails after the second
22120 // attempt, we'll give up and commit the resulting tree.
22121
22122
22123 lanes = getLanesToRetrySynchronouslyOnError(root);
22124
22125 if (lanes !== NoLanes) {
22126 exitStatus = renderRootSync(root, lanes);
22127 }
22128 }
22129
22130 if (exitStatus === RootFatalErrored) {
22131 var fatalError = workInProgressRootFatalError;
22132 prepareFreshStack(root, NoLanes);
22133 markRootSuspended$1(root, lanes);
22134 ensureRootIsScheduled(root, now());
22135 throw fatalError;
22136 } // We now have a consistent tree. The next step is either to commit it,
22137 // or, if something suspended, wait to commit it after a timeout.
22138
22139
22140 var finishedWork = root.current.alternate;
22141 root.finishedWork = finishedWork;
22142 root.finishedLanes = lanes;
22143 finishConcurrentRender(root, exitStatus, lanes);
22144 }
22145
22146 ensureRootIsScheduled(root, now());
22147
22148 if (root.callbackNode === originalCallbackNode) {
22149 // The task node scheduled for this root is the same one that's
22150 // currently executed. Need to return a continuation.
22151 return performConcurrentWorkOnRoot.bind(null, root);
22152 }
22153
22154 return null;
22155 }
22156
22157 function finishConcurrentRender(root, exitStatus, lanes) {
22158 switch (exitStatus) {
22159 case RootIncomplete:
22160 case RootFatalErrored:
22161 {
22162 {
22163 {
22164 throw Error( "Root did not complete. This is a bug in React." );
22165 }
22166 }
22167 }
22168 // Flow knows about invariant, so it complains if I add a break
22169 // statement, but eslint doesn't know about invariant, so it complains
22170 // if I do. eslint-disable-next-line no-fallthrough
22171
22172 case RootErrored:
22173 {
22174 // We should have already attempted to retry this tree. If we reached
22175 // this point, it errored again. Commit it.
22176 commitRoot(root);
22177 break;
22178 }
22179
22180 case RootSuspended:
22181 {
22182 markRootSuspended$1(root, lanes); // We have an acceptable loading state. We need to figure out if we
22183 // should immediately commit it or wait a bit.
22184
22185 if (includesOnlyRetries(lanes) && // do not delay if we're inside an act() scope
22186 !shouldForceFlushFallbacksInDEV()) {
22187 // This render only included retries, no updates. Throttle committing
22188 // retries so that we don't show too many loading states too quickly.
22189 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.
22190
22191 if (msUntilTimeout > 10) {
22192 var nextLanes = getNextLanes(root, NoLanes);
22193
22194 if (nextLanes !== NoLanes) {
22195 // There's additional work on this root.
22196 break;
22197 }
22198
22199 var suspendedLanes = root.suspendedLanes;
22200
22201 if (!isSubsetOfLanes(suspendedLanes, lanes)) {
22202 // We should prefer to render the fallback of at the last
22203 // suspended level. Ping the last suspended level to try
22204 // rendering it again.
22205 // FIXME: What if the suspended lanes are Idle? Should not restart.
22206 var eventTime = requestEventTime();
22207 markRootPinged(root, suspendedLanes);
22208 break;
22209 } // The render is suspended, it hasn't timed out, and there's no
22210 // lower priority work to do. Instead of committing the fallback
22211 // immediately, wait for more data to arrive.
22212
22213
22214 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);
22215 break;
22216 }
22217 } // The work expired. Commit immediately.
22218
22219
22220 commitRoot(root);
22221 break;
22222 }
22223
22224 case RootSuspendedWithDelay:
22225 {
22226 markRootSuspended$1(root, lanes);
22227
22228 if (includesOnlyTransitions(lanes)) {
22229 // This is a transition, so we should exit without committing a
22230 // placeholder and without scheduling a timeout. Delay indefinitely
22231 // until we receive more data.
22232 break;
22233 }
22234
22235 if (!shouldForceFlushFallbacksInDEV()) {
22236 // This is not a transition, but we did trigger an avoided state.
22237 // Schedule a placeholder to display after a short delay, using the Just
22238 // Noticeable Difference.
22239 // TODO: Is the JND optimization worth the added complexity? If this is
22240 // the only reason we track the event time, then probably not.
22241 // Consider removing.
22242 var mostRecentEventTime = getMostRecentEventTime(root, lanes);
22243 var eventTimeMs = mostRecentEventTime;
22244 var timeElapsedMs = now() - eventTimeMs;
22245
22246 var _msUntilTimeout = jnd(timeElapsedMs) - timeElapsedMs; // Don't bother with a very short suspense time.
22247
22248
22249 if (_msUntilTimeout > 10) {
22250 // Instead of committing the fallback immediately, wait for more data
22251 // to arrive.
22252 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);
22253 break;
22254 }
22255 } // Commit the placeholder.
22256
22257
22258 commitRoot(root);
22259 break;
22260 }
22261
22262 case RootCompleted:
22263 {
22264 // The work completed. Ready to commit.
22265 commitRoot(root);
22266 break;
22267 }
22268
22269 default:
22270 {
22271 {
22272 {
22273 throw Error( "Unknown root exit status." );
22274 }
22275 }
22276 }
22277 }
22278 }
22279
22280 function markRootSuspended$1(root, suspendedLanes) {
22281 // When suspending, we should always exclude lanes that were pinged or (more
22282 // rarely, since we try to avoid it) updated during the render phase.
22283 // TODO: Lol maybe there's a better way to factor this besides this
22284 // obnoxiously named function :)
22285 suspendedLanes = removeLanes(suspendedLanes, workInProgressRootPingedLanes);
22286 suspendedLanes = removeLanes(suspendedLanes, workInProgressRootUpdatedLanes);
22287 markRootSuspended(root, suspendedLanes);
22288 } // This is the entry point for synchronous tasks that don't go
22289 // through Scheduler
22290
22291
22292 function performSyncWorkOnRoot(root) {
22293 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
22294 {
22295 throw Error( "Should not already be working." );
22296 }
22297 }
22298
22299 flushPassiveEffects();
22300 var lanes;
22301 var exitStatus;
22302
22303 if (root === workInProgressRoot && includesSomeLane(root.expiredLanes, workInProgressRootRenderLanes)) {
22304 // There's a partial tree, and at least one of its lanes has expired. Finish
22305 // rendering it before rendering the rest of the expired work.
22306 lanes = workInProgressRootRenderLanes;
22307 exitStatus = renderRootSync(root, lanes);
22308
22309 if (includesSomeLane(workInProgressRootIncludedLanes, workInProgressRootUpdatedLanes)) {
22310 // The render included lanes that were updated during the render phase.
22311 // For example, when unhiding a hidden tree, we include all the lanes
22312 // that were previously skipped when the tree was hidden. That set of
22313 // lanes is a superset of the lanes we started rendering with.
22314 //
22315 // Note that this only happens when part of the tree is rendered
22316 // concurrently. If the whole tree is rendered synchronously, then there
22317 // are no interleaved events.
22318 lanes = getNextLanes(root, lanes);
22319 exitStatus = renderRootSync(root, lanes);
22320 }
22321 } else {
22322 lanes = getNextLanes(root, NoLanes);
22323 exitStatus = renderRootSync(root, lanes);
22324 }
22325
22326 if (root.tag !== LegacyRoot && exitStatus === RootErrored) {
22327 executionContext |= RetryAfterError; // If an error occurred during hydration,
22328 // discard server response and fall back to client side render.
22329
22330 if (root.hydrate) {
22331 root.hydrate = false;
22332 clearContainer(root.containerInfo);
22333 } // If something threw an error, try rendering one more time. We'll render
22334 // synchronously to block concurrent data mutations, and we'll includes
22335 // all pending updates are included. If it still fails after the second
22336 // attempt, we'll give up and commit the resulting tree.
22337
22338
22339 lanes = getLanesToRetrySynchronouslyOnError(root);
22340
22341 if (lanes !== NoLanes) {
22342 exitStatus = renderRootSync(root, lanes);
22343 }
22344 }
22345
22346 if (exitStatus === RootFatalErrored) {
22347 var fatalError = workInProgressRootFatalError;
22348 prepareFreshStack(root, NoLanes);
22349 markRootSuspended$1(root, lanes);
22350 ensureRootIsScheduled(root, now());
22351 throw fatalError;
22352 } // We now have a consistent tree. Because this is a sync render, we
22353 // will commit it even if something suspended.
22354
22355
22356 var finishedWork = root.current.alternate;
22357 root.finishedWork = finishedWork;
22358 root.finishedLanes = lanes;
22359 commitRoot(root); // Before exiting, make sure there's a callback scheduled for the next
22360 // pending level.
22361
22362 ensureRootIsScheduled(root, now());
22363 return null;
22364 }
22365 function flushDiscreteUpdates() {
22366 // TODO: Should be able to flush inside batchedUpdates, but not inside `act`.
22367 // However, `act` uses `batchedUpdates`, so there's no way to distinguish
22368 // those two cases. Need to fix this before exposing flushDiscreteUpdates
22369 // as a public API.
22370 if ((executionContext & (BatchedContext | RenderContext | CommitContext)) !== NoContext) {
22371 {
22372 if ((executionContext & RenderContext) !== NoContext) {
22373 error('unstable_flushDiscreteUpdates: Cannot flush updates when React is ' + 'already rendering.');
22374 }
22375 } // We're already rendering, so we can't synchronously flush pending work.
22376 // This is probably a nested event dispatch triggered by a lifecycle/effect,
22377 // like `el.focus()`. Exit.
22378
22379
22380 return;
22381 }
22382
22383 flushPendingDiscreteUpdates(); // If the discrete updates scheduled passive effects, flush them now so that
22384 // they fire before the next serial event.
22385
22386 flushPassiveEffects();
22387 }
22388
22389 function flushPendingDiscreteUpdates() {
22390 if (rootsWithPendingDiscreteUpdates !== null) {
22391 // For each root with pending discrete updates, schedule a callback to
22392 // immediately flush them.
22393 var roots = rootsWithPendingDiscreteUpdates;
22394 rootsWithPendingDiscreteUpdates = null;
22395 roots.forEach(function (root) {
22396 markDiscreteUpdatesExpired(root);
22397 ensureRootIsScheduled(root, now());
22398 });
22399 } // Now flush the immediate queue.
22400
22401
22402 flushSyncCallbackQueue();
22403 }
22404
22405 function batchedUpdates$1(fn, a) {
22406 var prevExecutionContext = executionContext;
22407 executionContext |= BatchedContext;
22408
22409 try {
22410 return fn(a);
22411 } finally {
22412 executionContext = prevExecutionContext;
22413
22414 if (executionContext === NoContext) {
22415 // Flush the immediate callbacks that were scheduled during this batch
22416 resetRenderTimer();
22417 flushSyncCallbackQueue();
22418 }
22419 }
22420 }
22421 function batchedEventUpdates$1(fn, a) {
22422 var prevExecutionContext = executionContext;
22423 executionContext |= EventContext;
22424
22425 try {
22426 return fn(a);
22427 } finally {
22428 executionContext = prevExecutionContext;
22429
22430 if (executionContext === NoContext) {
22431 // Flush the immediate callbacks that were scheduled during this batch
22432 resetRenderTimer();
22433 flushSyncCallbackQueue();
22434 }
22435 }
22436 }
22437 function discreteUpdates$1(fn, a, b, c, d) {
22438 var prevExecutionContext = executionContext;
22439 executionContext |= DiscreteEventContext;
22440
22441 {
22442 try {
22443 return runWithPriority$1(UserBlockingPriority$2, fn.bind(null, a, b, c, d));
22444 } finally {
22445 executionContext = prevExecutionContext;
22446
22447 if (executionContext === NoContext) {
22448 // Flush the immediate callbacks that were scheduled during this batch
22449 resetRenderTimer();
22450 flushSyncCallbackQueue();
22451 }
22452 }
22453 }
22454 }
22455 function unbatchedUpdates(fn, a) {
22456 var prevExecutionContext = executionContext;
22457 executionContext &= ~BatchedContext;
22458 executionContext |= LegacyUnbatchedContext;
22459
22460 try {
22461 return fn(a);
22462 } finally {
22463 executionContext = prevExecutionContext;
22464
22465 if (executionContext === NoContext) {
22466 // Flush the immediate callbacks that were scheduled during this batch
22467 resetRenderTimer();
22468 flushSyncCallbackQueue();
22469 }
22470 }
22471 }
22472 function flushSync(fn, a) {
22473 var prevExecutionContext = executionContext;
22474
22475 if ((prevExecutionContext & (RenderContext | CommitContext)) !== NoContext) {
22476 {
22477 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.');
22478 }
22479
22480 return fn(a);
22481 }
22482
22483 executionContext |= BatchedContext;
22484
22485 {
22486 try {
22487 if (fn) {
22488 return runWithPriority$1(ImmediatePriority$1, fn.bind(null, a));
22489 } else {
22490 return undefined;
22491 }
22492 } finally {
22493 executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.
22494 // Note that this will happen even if batchedUpdates is higher up
22495 // the stack.
22496
22497 flushSyncCallbackQueue();
22498 }
22499 }
22500 }
22501 function pushRenderLanes(fiber, lanes) {
22502 push(subtreeRenderLanesCursor, subtreeRenderLanes, fiber);
22503 subtreeRenderLanes = mergeLanes(subtreeRenderLanes, lanes);
22504 workInProgressRootIncludedLanes = mergeLanes(workInProgressRootIncludedLanes, lanes);
22505 }
22506 function popRenderLanes(fiber) {
22507 subtreeRenderLanes = subtreeRenderLanesCursor.current;
22508 pop(subtreeRenderLanesCursor, fiber);
22509 }
22510
22511 function prepareFreshStack(root, lanes) {
22512 root.finishedWork = null;
22513 root.finishedLanes = NoLanes;
22514 var timeoutHandle = root.timeoutHandle;
22515
22516 if (timeoutHandle !== noTimeout) {
22517 // The root previous suspended and scheduled a timeout to commit a fallback
22518 // state. Now that we have additional work, cancel the timeout.
22519 root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
22520
22521 cancelTimeout(timeoutHandle);
22522 }
22523
22524 if (workInProgress !== null) {
22525 var interruptedWork = workInProgress.return;
22526
22527 while (interruptedWork !== null) {
22528 unwindInterruptedWork(interruptedWork);
22529 interruptedWork = interruptedWork.return;
22530 }
22531 }
22532
22533 workInProgressRoot = root;
22534 workInProgress = createWorkInProgress(root.current, null);
22535 workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes;
22536 workInProgressRootExitStatus = RootIncomplete;
22537 workInProgressRootFatalError = null;
22538 workInProgressRootSkippedLanes = NoLanes;
22539 workInProgressRootUpdatedLanes = NoLanes;
22540 workInProgressRootPingedLanes = NoLanes;
22541
22542 {
22543 spawnedWorkDuringRender = null;
22544 }
22545
22546 {
22547 ReactStrictModeWarnings.discardPendingWarnings();
22548 }
22549 }
22550
22551 function handleError(root, thrownValue) {
22552 do {
22553 var erroredWork = workInProgress;
22554
22555 try {
22556 // Reset module-level state that was set during the render phase.
22557 resetContextDependencies();
22558 resetHooksAfterThrow();
22559 resetCurrentFiber(); // TODO: I found and added this missing line while investigating a
22560 // separate issue. Write a regression test using string refs.
22561
22562 ReactCurrentOwner$2.current = null;
22563
22564 if (erroredWork === null || erroredWork.return === null) {
22565 // Expected to be working on a non-root fiber. This is a fatal error
22566 // because there's no ancestor that can handle it; the root is
22567 // supposed to capture all errors that weren't caught by an error
22568 // boundary.
22569 workInProgressRootExitStatus = RootFatalErrored;
22570 workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next
22571 // sibling, or the parent if there are no siblings. But since the root
22572 // has no siblings nor a parent, we set it to null. Usually this is
22573 // handled by `completeUnitOfWork` or `unwindWork`, but since we're
22574 // intentionally not calling those, we need set it here.
22575 // TODO: Consider calling `unwindWork` to pop the contexts.
22576
22577 workInProgress = null;
22578 return;
22579 }
22580
22581 if (enableProfilerTimer && erroredWork.mode & ProfileMode) {
22582 // Record the time spent rendering before an error was thrown. This
22583 // avoids inaccurate Profiler durations in the case of a
22584 // suspended render.
22585 stopProfilerTimerIfRunningAndRecordDelta(erroredWork, true);
22586 }
22587
22588 throwException(root, erroredWork.return, erroredWork, thrownValue, workInProgressRootRenderLanes);
22589 completeUnitOfWork(erroredWork);
22590 } catch (yetAnotherThrownValue) {
22591 // Something in the return path also threw.
22592 thrownValue = yetAnotherThrownValue;
22593
22594 if (workInProgress === erroredWork && erroredWork !== null) {
22595 // If this boundary has already errored, then we had trouble processing
22596 // the error. Bubble it to the next boundary.
22597 erroredWork = erroredWork.return;
22598 workInProgress = erroredWork;
22599 } else {
22600 erroredWork = workInProgress;
22601 }
22602
22603 continue;
22604 } // Return to the normal work loop.
22605
22606
22607 return;
22608 } while (true);
22609 }
22610
22611 function pushDispatcher() {
22612 var prevDispatcher = ReactCurrentDispatcher$2.current;
22613 ReactCurrentDispatcher$2.current = ContextOnlyDispatcher;
22614
22615 if (prevDispatcher === null) {
22616 // The React isomorphic package does not include a default dispatcher.
22617 // Instead the first renderer will lazily attach one, in order to give
22618 // nicer error messages.
22619 return ContextOnlyDispatcher;
22620 } else {
22621 return prevDispatcher;
22622 }
22623 }
22624
22625 function popDispatcher(prevDispatcher) {
22626 ReactCurrentDispatcher$2.current = prevDispatcher;
22627 }
22628
22629 function pushInteractions(root) {
22630 {
22631 var prevInteractions = __interactionsRef.current;
22632 __interactionsRef.current = root.memoizedInteractions;
22633 return prevInteractions;
22634 }
22635 }
22636
22637 function popInteractions(prevInteractions) {
22638 {
22639 __interactionsRef.current = prevInteractions;
22640 }
22641 }
22642
22643 function markCommitTimeOfFallback() {
22644 globalMostRecentFallbackTime = now();
22645 }
22646 function markSkippedUpdateLanes(lane) {
22647 workInProgressRootSkippedLanes = mergeLanes(lane, workInProgressRootSkippedLanes);
22648 }
22649 function renderDidSuspend() {
22650 if (workInProgressRootExitStatus === RootIncomplete) {
22651 workInProgressRootExitStatus = RootSuspended;
22652 }
22653 }
22654 function renderDidSuspendDelayIfPossible() {
22655 if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {
22656 workInProgressRootExitStatus = RootSuspendedWithDelay;
22657 } // Check if there are updates that we skipped tree that might have unblocked
22658 // this render.
22659
22660
22661 if (workInProgressRoot !== null && (includesNonIdleWork(workInProgressRootSkippedLanes) || includesNonIdleWork(workInProgressRootUpdatedLanes))) {
22662 // Mark the current render as suspended so that we switch to working on
22663 // the updates that were skipped. Usually we only suspend at the end of
22664 // the render phase.
22665 // TODO: We should probably always mark the root as suspended immediately
22666 // (inside this function), since by suspending at the end of the render
22667 // phase introduces a potential mistake where we suspend lanes that were
22668 // pinged or updated while we were rendering.
22669 markRootSuspended$1(workInProgressRoot, workInProgressRootRenderLanes);
22670 }
22671 }
22672 function renderDidError() {
22673 if (workInProgressRootExitStatus !== RootCompleted) {
22674 workInProgressRootExitStatus = RootErrored;
22675 }
22676 } // Called during render to determine if anything has suspended.
22677 // Returns false if we're not sure.
22678
22679 function renderHasNotSuspendedYet() {
22680 // If something errored or completed, we can't really be sure,
22681 // so those are false.
22682 return workInProgressRootExitStatus === RootIncomplete;
22683 }
22684
22685 function renderRootSync(root, lanes) {
22686 var prevExecutionContext = executionContext;
22687 executionContext |= RenderContext;
22688 var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack
22689 // and prepare a fresh one. Otherwise we'll continue where we left off.
22690
22691 if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {
22692 prepareFreshStack(root, lanes);
22693 startWorkOnPendingInteractions(root, lanes);
22694 }
22695
22696 var prevInteractions = pushInteractions(root);
22697
22698 do {
22699 try {
22700 workLoopSync();
22701 break;
22702 } catch (thrownValue) {
22703 handleError(root, thrownValue);
22704 }
22705 } while (true);
22706
22707 resetContextDependencies();
22708
22709 {
22710 popInteractions(prevInteractions);
22711 }
22712
22713 executionContext = prevExecutionContext;
22714 popDispatcher(prevDispatcher);
22715
22716 if (workInProgress !== null) {
22717 // This is a sync render, so we should have finished the whole tree.
22718 {
22719 {
22720 throw Error( "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." );
22721 }
22722 }
22723 }
22724
22725
22726 workInProgressRoot = null;
22727 workInProgressRootRenderLanes = NoLanes;
22728 return workInProgressRootExitStatus;
22729 } // The work loop is an extremely hot path. Tell Closure not to inline it.
22730
22731 /** @noinline */
22732
22733
22734 function workLoopSync() {
22735 // Already timed out, so perform work without checking if we need to yield.
22736 while (workInProgress !== null) {
22737 performUnitOfWork(workInProgress);
22738 }
22739 }
22740
22741 function renderRootConcurrent(root, lanes) {
22742 var prevExecutionContext = executionContext;
22743 executionContext |= RenderContext;
22744 var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack
22745 // and prepare a fresh one. Otherwise we'll continue where we left off.
22746
22747 if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {
22748 resetRenderTimer();
22749 prepareFreshStack(root, lanes);
22750 startWorkOnPendingInteractions(root, lanes);
22751 }
22752
22753 var prevInteractions = pushInteractions(root);
22754
22755 do {
22756 try {
22757 workLoopConcurrent();
22758 break;
22759 } catch (thrownValue) {
22760 handleError(root, thrownValue);
22761 }
22762 } while (true);
22763
22764 resetContextDependencies();
22765
22766 {
22767 popInteractions(prevInteractions);
22768 }
22769
22770 popDispatcher(prevDispatcher);
22771 executionContext = prevExecutionContext;
22772
22773
22774 if (workInProgress !== null) {
22775
22776 return RootIncomplete;
22777 } else {
22778
22779
22780 workInProgressRoot = null;
22781 workInProgressRootRenderLanes = NoLanes; // Return the final exit status.
22782
22783 return workInProgressRootExitStatus;
22784 }
22785 }
22786 /** @noinline */
22787
22788
22789 function workLoopConcurrent() {
22790 // Perform work until Scheduler asks us to yield
22791 while (workInProgress !== null && !shouldYield()) {
22792 performUnitOfWork(workInProgress);
22793 }
22794 }
22795
22796 function performUnitOfWork(unitOfWork) {
22797 // The current, flushed, state of this fiber is the alternate. Ideally
22798 // nothing should rely on this, but relying on it here means that we don't
22799 // need an additional field on the work in progress.
22800 var current = unitOfWork.alternate;
22801 setCurrentFiber(unitOfWork);
22802 var next;
22803
22804 if ( (unitOfWork.mode & ProfileMode) !== NoMode) {
22805 startProfilerTimer(unitOfWork);
22806 next = beginWork$1(current, unitOfWork, subtreeRenderLanes);
22807 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
22808 } else {
22809 next = beginWork$1(current, unitOfWork, subtreeRenderLanes);
22810 }
22811
22812 resetCurrentFiber();
22813 unitOfWork.memoizedProps = unitOfWork.pendingProps;
22814
22815 if (next === null) {
22816 // If this doesn't spawn new work, complete the current work.
22817 completeUnitOfWork(unitOfWork);
22818 } else {
22819 workInProgress = next;
22820 }
22821
22822 ReactCurrentOwner$2.current = null;
22823 }
22824
22825 function completeUnitOfWork(unitOfWork) {
22826 // Attempt to complete the current unit of work, then move to the next
22827 // sibling. If there are no more siblings, return to the parent fiber.
22828 var completedWork = unitOfWork;
22829
22830 do {
22831 // The current, flushed, state of this fiber is the alternate. Ideally
22832 // nothing should rely on this, but relying on it here means that we don't
22833 // need an additional field on the work in progress.
22834 var current = completedWork.alternate;
22835 var returnFiber = completedWork.return; // Check if the work completed or if something threw.
22836
22837 if ((completedWork.flags & Incomplete) === NoFlags) {
22838 setCurrentFiber(completedWork);
22839 var next = void 0;
22840
22841 if ( (completedWork.mode & ProfileMode) === NoMode) {
22842 next = completeWork(current, completedWork, subtreeRenderLanes);
22843 } else {
22844 startProfilerTimer(completedWork);
22845 next = completeWork(current, completedWork, subtreeRenderLanes); // Update render duration assuming we didn't error.
22846
22847 stopProfilerTimerIfRunningAndRecordDelta(completedWork, false);
22848 }
22849
22850 resetCurrentFiber();
22851
22852 if (next !== null) {
22853 // Completing this fiber spawned new work. Work on that next.
22854 workInProgress = next;
22855 return;
22856 }
22857
22858 resetChildLanes(completedWork);
22859
22860 if (returnFiber !== null && // Do not append effects to parents if a sibling failed to complete
22861 (returnFiber.flags & Incomplete) === NoFlags) {
22862 // Append all the effects of the subtree and this fiber onto the effect
22863 // list of the parent. The completion order of the children affects the
22864 // side-effect order.
22865 if (returnFiber.firstEffect === null) {
22866 returnFiber.firstEffect = completedWork.firstEffect;
22867 }
22868
22869 if (completedWork.lastEffect !== null) {
22870 if (returnFiber.lastEffect !== null) {
22871 returnFiber.lastEffect.nextEffect = completedWork.firstEffect;
22872 }
22873
22874 returnFiber.lastEffect = completedWork.lastEffect;
22875 } // If this fiber had side-effects, we append it AFTER the children's
22876 // side-effects. We can perform certain side-effects earlier if needed,
22877 // by doing multiple passes over the effect list. We don't want to
22878 // schedule our own side-effect on our own list because if end up
22879 // reusing children we'll schedule this effect onto itself since we're
22880 // at the end.
22881
22882
22883 var flags = completedWork.flags; // Skip both NoWork and PerformedWork tags when creating the effect
22884 // list. PerformedWork effect is read by React DevTools but shouldn't be
22885 // committed.
22886
22887 if (flags > PerformedWork) {
22888 if (returnFiber.lastEffect !== null) {
22889 returnFiber.lastEffect.nextEffect = completedWork;
22890 } else {
22891 returnFiber.firstEffect = completedWork;
22892 }
22893
22894 returnFiber.lastEffect = completedWork;
22895 }
22896 }
22897 } else {
22898 // This fiber did not complete because something threw. Pop values off
22899 // the stack without entering the complete phase. If this is a boundary,
22900 // capture values if possible.
22901 var _next = unwindWork(completedWork); // Because this fiber did not complete, don't reset its expiration time.
22902
22903
22904 if (_next !== null) {
22905 // If completing this work spawned new work, do that next. We'll come
22906 // back here again.
22907 // Since we're restarting, remove anything that is not a host effect
22908 // from the effect tag.
22909 _next.flags &= HostEffectMask;
22910 workInProgress = _next;
22911 return;
22912 }
22913
22914 if ( (completedWork.mode & ProfileMode) !== NoMode) {
22915 // Record the render duration for the fiber that errored.
22916 stopProfilerTimerIfRunningAndRecordDelta(completedWork, false); // Include the time spent working on failed children before continuing.
22917
22918 var actualDuration = completedWork.actualDuration;
22919 var child = completedWork.child;
22920
22921 while (child !== null) {
22922 actualDuration += child.actualDuration;
22923 child = child.sibling;
22924 }
22925
22926 completedWork.actualDuration = actualDuration;
22927 }
22928
22929 if (returnFiber !== null) {
22930 // Mark the parent fiber as incomplete and clear its effect list.
22931 returnFiber.firstEffect = returnFiber.lastEffect = null;
22932 returnFiber.flags |= Incomplete;
22933 }
22934 }
22935
22936 var siblingFiber = completedWork.sibling;
22937
22938 if (siblingFiber !== null) {
22939 // If there is more work to do in this returnFiber, do that next.
22940 workInProgress = siblingFiber;
22941 return;
22942 } // Otherwise, return to the parent
22943
22944
22945 completedWork = returnFiber; // Update the next thing we're working on in case something throws.
22946
22947 workInProgress = completedWork;
22948 } while (completedWork !== null); // We've reached the root.
22949
22950
22951 if (workInProgressRootExitStatus === RootIncomplete) {
22952 workInProgressRootExitStatus = RootCompleted;
22953 }
22954 }
22955
22956 function resetChildLanes(completedWork) {
22957 if ( // TODO: Move this check out of the hot path by moving `resetChildLanes`
22958 // to switch statement in `completeWork`.
22959 (completedWork.tag === LegacyHiddenComponent || completedWork.tag === OffscreenComponent) && completedWork.memoizedState !== null && !includesSomeLane(subtreeRenderLanes, OffscreenLane) && (completedWork.mode & ConcurrentMode) !== NoLanes) {
22960 // The children of this component are hidden. Don't bubble their
22961 // expiration times.
22962 return;
22963 }
22964
22965 var newChildLanes = NoLanes; // Bubble up the earliest expiration time.
22966
22967 if ( (completedWork.mode & ProfileMode) !== NoMode) {
22968 // In profiling mode, resetChildExpirationTime is also used to reset
22969 // profiler durations.
22970 var actualDuration = completedWork.actualDuration;
22971 var treeBaseDuration = completedWork.selfBaseDuration; // When a fiber is cloned, its actualDuration is reset to 0. This value will
22972 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
22973 // When work is done, it should bubble to the parent's actualDuration. If
22974 // the fiber has not been cloned though, (meaning no work was done), then
22975 // this value will reflect the amount of time spent working on a previous
22976 // render. In that case it should not bubble. We determine whether it was
22977 // cloned by comparing the child pointer.
22978
22979 var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;
22980 var child = completedWork.child;
22981
22982 while (child !== null) {
22983 newChildLanes = mergeLanes(newChildLanes, mergeLanes(child.lanes, child.childLanes));
22984
22985 if (shouldBubbleActualDurations) {
22986 actualDuration += child.actualDuration;
22987 }
22988
22989 treeBaseDuration += child.treeBaseDuration;
22990 child = child.sibling;
22991 }
22992
22993 var isTimedOutSuspense = completedWork.tag === SuspenseComponent && completedWork.memoizedState !== null;
22994
22995 if (isTimedOutSuspense) {
22996 // Don't count time spent in a timed out Suspense subtree as part of the base duration.
22997 var primaryChildFragment = completedWork.child;
22998
22999 if (primaryChildFragment !== null) {
23000 treeBaseDuration -= primaryChildFragment.treeBaseDuration;
23001 }
23002 }
23003
23004 completedWork.actualDuration = actualDuration;
23005 completedWork.treeBaseDuration = treeBaseDuration;
23006 } else {
23007 var _child = completedWork.child;
23008
23009 while (_child !== null) {
23010 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child.lanes, _child.childLanes));
23011 _child = _child.sibling;
23012 }
23013 }
23014
23015 completedWork.childLanes = newChildLanes;
23016 }
23017
23018 function commitRoot(root) {
23019 var renderPriorityLevel = getCurrentPriorityLevel();
23020 runWithPriority$1(ImmediatePriority$1, commitRootImpl.bind(null, root, renderPriorityLevel));
23021 return null;
23022 }
23023
23024 function commitRootImpl(root, renderPriorityLevel) {
23025 do {
23026 // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which
23027 // means `flushPassiveEffects` will sometimes result in additional
23028 // passive effects. So we need to keep flushing in a loop until there are
23029 // no more pending effects.
23030 // TODO: Might be better if `flushPassiveEffects` did not automatically
23031 // flush synchronous work at the end, to avoid factoring hazards like this.
23032 flushPassiveEffects();
23033 } while (rootWithPendingPassiveEffects !== null);
23034
23035 flushRenderPhaseStrictModeWarningsInDEV();
23036
23037 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
23038 {
23039 throw Error( "Should not already be working." );
23040 }
23041 }
23042
23043 var finishedWork = root.finishedWork;
23044 var lanes = root.finishedLanes;
23045
23046 if (finishedWork === null) {
23047
23048 return null;
23049 }
23050
23051 root.finishedWork = null;
23052 root.finishedLanes = NoLanes;
23053
23054 if (!(finishedWork !== root.current)) {
23055 {
23056 throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." );
23057 }
23058 } // commitRoot never returns a continuation; it always finishes synchronously.
23059 // So we can clear these now to allow a new callback to be scheduled.
23060
23061
23062 root.callbackNode = null; // Update the first and last pending times on this root. The new first
23063 // pending time is whatever is left on the root fiber.
23064
23065 var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes);
23066 markRootFinished(root, remainingLanes); // Clear already finished discrete updates in case that a later call of
23067 // `flushDiscreteUpdates` starts a useless render pass which may cancels
23068 // a scheduled timeout.
23069
23070 if (rootsWithPendingDiscreteUpdates !== null) {
23071 if (!hasDiscreteLanes(remainingLanes) && rootsWithPendingDiscreteUpdates.has(root)) {
23072 rootsWithPendingDiscreteUpdates.delete(root);
23073 }
23074 }
23075
23076 if (root === workInProgressRoot) {
23077 // We can reset these now that they are finished.
23078 workInProgressRoot = null;
23079 workInProgress = null;
23080 workInProgressRootRenderLanes = NoLanes;
23081 } // Get the list of effects.
23082
23083
23084 var firstEffect;
23085
23086 if (finishedWork.flags > PerformedWork) {
23087 // A fiber's effect list consists only of its children, not itself. So if
23088 // the root has an effect, we need to add it to the end of the list. The
23089 // resulting list is the set that would belong to the root's parent, if it
23090 // had one; that is, all the effects in the tree including the root.
23091 if (finishedWork.lastEffect !== null) {
23092 finishedWork.lastEffect.nextEffect = finishedWork;
23093 firstEffect = finishedWork.firstEffect;
23094 } else {
23095 firstEffect = finishedWork;
23096 }
23097 } else {
23098 // There is no effect on the root.
23099 firstEffect = finishedWork.firstEffect;
23100 }
23101
23102 if (firstEffect !== null) {
23103
23104 var prevExecutionContext = executionContext;
23105 executionContext |= CommitContext;
23106 var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles
23107
23108 ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass
23109 // of the effect list for each phase: all mutation effects come before all
23110 // layout effects, and so on.
23111 // The first phase a "before mutation" phase. We use this phase to read the
23112 // state of the host tree right before we mutate it. This is where
23113 // getSnapshotBeforeUpdate is called.
23114
23115 focusedInstanceHandle = prepareForCommit(root.containerInfo);
23116 shouldFireAfterActiveInstanceBlur = false;
23117 nextEffect = firstEffect;
23118
23119 do {
23120 {
23121 invokeGuardedCallback(null, commitBeforeMutationEffects, null);
23122
23123 if (hasCaughtError()) {
23124 if (!(nextEffect !== null)) {
23125 {
23126 throw Error( "Should be working on an effect." );
23127 }
23128 }
23129
23130 var error = clearCaughtError();
23131 captureCommitPhaseError(nextEffect, error);
23132 nextEffect = nextEffect.nextEffect;
23133 }
23134 }
23135 } while (nextEffect !== null); // We no longer need to track the active instance fiber
23136
23137
23138 focusedInstanceHandle = null;
23139
23140 {
23141 // Mark the current commit time to be shared by all Profilers in this
23142 // batch. This enables them to be grouped later.
23143 recordCommitTime();
23144 } // The next phase is the mutation phase, where we mutate the host tree.
23145
23146
23147 nextEffect = firstEffect;
23148
23149 do {
23150 {
23151 invokeGuardedCallback(null, commitMutationEffects, null, root, renderPriorityLevel);
23152
23153 if (hasCaughtError()) {
23154 if (!(nextEffect !== null)) {
23155 {
23156 throw Error( "Should be working on an effect." );
23157 }
23158 }
23159
23160 var _error = clearCaughtError();
23161
23162 captureCommitPhaseError(nextEffect, _error);
23163 nextEffect = nextEffect.nextEffect;
23164 }
23165 }
23166 } while (nextEffect !== null);
23167
23168 resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after
23169 // the mutation phase, so that the previous tree is still current during
23170 // componentWillUnmount, but before the layout phase, so that the finished
23171 // work is current during componentDidMount/Update.
23172
23173 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
23174 // the host tree after it's been mutated. The idiomatic use case for this is
23175 // layout, but class component lifecycles also fire here for legacy reasons.
23176
23177 nextEffect = firstEffect;
23178
23179 do {
23180 {
23181 invokeGuardedCallback(null, commitLayoutEffects, null, root, lanes);
23182
23183 if (hasCaughtError()) {
23184 if (!(nextEffect !== null)) {
23185 {
23186 throw Error( "Should be working on an effect." );
23187 }
23188 }
23189
23190 var _error2 = clearCaughtError();
23191
23192 captureCommitPhaseError(nextEffect, _error2);
23193 nextEffect = nextEffect.nextEffect;
23194 }
23195 }
23196 } while (nextEffect !== null);
23197
23198 nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an
23199 // opportunity to paint.
23200
23201 requestPaint();
23202
23203 {
23204 popInteractions(prevInteractions);
23205 }
23206
23207 executionContext = prevExecutionContext;
23208 } else {
23209 // No effects.
23210 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were
23211 // no effects.
23212 // TODO: Maybe there's a better way to report this.
23213
23214 {
23215 recordCommitTime();
23216 }
23217 }
23218
23219 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
23220
23221 if (rootDoesHavePassiveEffects) {
23222 // This commit has passive effects. Stash a reference to them. But don't
23223 // schedule a callback until after flushing layout work.
23224 rootDoesHavePassiveEffects = false;
23225 rootWithPendingPassiveEffects = root;
23226 pendingPassiveEffectsLanes = lanes;
23227 pendingPassiveEffectsRenderPriority = renderPriorityLevel;
23228 } else {
23229 // We are done with the effect chain at this point so let's clear the
23230 // nextEffect pointers to assist with GC. If we have passive effects, we'll
23231 // clear this in flushPassiveEffects.
23232 nextEffect = firstEffect;
23233
23234 while (nextEffect !== null) {
23235 var nextNextEffect = nextEffect.nextEffect;
23236 nextEffect.nextEffect = null;
23237
23238 if (nextEffect.flags & Deletion) {
23239 detachFiberAfterEffects(nextEffect);
23240 }
23241
23242 nextEffect = nextNextEffect;
23243 }
23244 } // Read this again, since an effect might have updated it
23245
23246
23247 remainingLanes = root.pendingLanes; // Check if there's remaining work on this root
23248
23249 if (remainingLanes !== NoLanes) {
23250 {
23251 if (spawnedWorkDuringRender !== null) {
23252 var expirationTimes = spawnedWorkDuringRender;
23253 spawnedWorkDuringRender = null;
23254
23255 for (var i = 0; i < expirationTimes.length; i++) {
23256 scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);
23257 }
23258 }
23259
23260 schedulePendingInteractions(root, remainingLanes);
23261 }
23262 } else {
23263 // If there's no remaining work, we can clear the set of already failed
23264 // error boundaries.
23265 legacyErrorBoundariesThatAlreadyFailed = null;
23266 }
23267
23268 {
23269 if (!rootDidHavePassiveEffects) {
23270 // If there are no passive effects, then we can complete the pending interactions.
23271 // Otherwise, we'll wait until after the passive effects are flushed.
23272 // Wait to do this until after remaining work has been scheduled,
23273 // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.
23274 finishPendingInteractions(root, lanes);
23275 }
23276 }
23277
23278 if (remainingLanes === SyncLane) {
23279 // Count the number of times the root synchronously re-renders without
23280 // finishing. If there are too many, it indicates an infinite update loop.
23281 if (root === rootWithNestedUpdates) {
23282 nestedUpdateCount++;
23283 } else {
23284 nestedUpdateCount = 0;
23285 rootWithNestedUpdates = root;
23286 }
23287 } else {
23288 nestedUpdateCount = 0;
23289 }
23290
23291 onCommitRoot(finishedWork.stateNode, renderPriorityLevel);
23292
23293 {
23294 onCommitRoot$1();
23295 } // Always call this before exiting `commitRoot`, to ensure that any
23296 // additional work on this root is scheduled.
23297
23298
23299 ensureRootIsScheduled(root, now());
23300
23301 if (hasUncaughtError) {
23302 hasUncaughtError = false;
23303 var _error3 = firstUncaughtError;
23304 firstUncaughtError = null;
23305 throw _error3;
23306 }
23307
23308 if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
23309 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
23310 // synchronously, but layout updates should be deferred until the end
23311 // of the batch.
23312
23313
23314 return null;
23315 } // If layout work was scheduled, flush it now.
23316
23317
23318 flushSyncCallbackQueue();
23319
23320 return null;
23321 }
23322
23323 function commitBeforeMutationEffects() {
23324 while (nextEffect !== null) {
23325 var current = nextEffect.alternate;
23326
23327 if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) {
23328 if ((nextEffect.flags & Deletion) !== NoFlags) {
23329 if (doesFiberContain(nextEffect, focusedInstanceHandle)) {
23330 shouldFireAfterActiveInstanceBlur = true;
23331 }
23332 } else {
23333 // TODO: Move this out of the hot path using a dedicated effect tag.
23334 if (nextEffect.tag === SuspenseComponent && isSuspenseBoundaryBeingHidden(current, nextEffect) && doesFiberContain(nextEffect, focusedInstanceHandle)) {
23335 shouldFireAfterActiveInstanceBlur = true;
23336 }
23337 }
23338 }
23339
23340 var flags = nextEffect.flags;
23341
23342 if ((flags & Snapshot) !== NoFlags) {
23343 setCurrentFiber(nextEffect);
23344 commitBeforeMutationLifeCycles(current, nextEffect);
23345 resetCurrentFiber();
23346 }
23347
23348 if ((flags & Passive) !== NoFlags) {
23349 // If there are passive effects, schedule a callback to flush at
23350 // the earliest opportunity.
23351 if (!rootDoesHavePassiveEffects) {
23352 rootDoesHavePassiveEffects = true;
23353 scheduleCallback(NormalPriority$1, function () {
23354 flushPassiveEffects();
23355 return null;
23356 });
23357 }
23358 }
23359
23360 nextEffect = nextEffect.nextEffect;
23361 }
23362 }
23363
23364 function commitMutationEffects(root, renderPriorityLevel) {
23365 // TODO: Should probably move the bulk of this function to commitWork.
23366 while (nextEffect !== null) {
23367 setCurrentFiber(nextEffect);
23368 var flags = nextEffect.flags;
23369
23370 if (flags & ContentReset) {
23371 commitResetTextContent(nextEffect);
23372 }
23373
23374 if (flags & Ref) {
23375 var current = nextEffect.alternate;
23376
23377 if (current !== null) {
23378 commitDetachRef(current);
23379 }
23380 } // The following switch statement is only concerned about placement,
23381 // updates, and deletions. To avoid needing to add a case for every possible
23382 // bitmap value, we remove the secondary effects from the effect tag and
23383 // switch on that value.
23384
23385
23386 var primaryFlags = flags & (Placement | Update | Deletion | Hydrating);
23387
23388 switch (primaryFlags) {
23389 case Placement:
23390 {
23391 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
23392 // inserted, before any life-cycles like componentDidMount gets called.
23393 // TODO: findDOMNode doesn't rely on this any more but isMounted does
23394 // and isMounted is deprecated anyway so we should be able to kill this.
23395
23396 nextEffect.flags &= ~Placement;
23397 break;
23398 }
23399
23400 case PlacementAndUpdate:
23401 {
23402 // Placement
23403 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
23404 // inserted, before any life-cycles like componentDidMount gets called.
23405
23406 nextEffect.flags &= ~Placement; // Update
23407
23408 var _current = nextEffect.alternate;
23409 commitWork(_current, nextEffect);
23410 break;
23411 }
23412
23413 case Hydrating:
23414 {
23415 nextEffect.flags &= ~Hydrating;
23416 break;
23417 }
23418
23419 case HydratingAndUpdate:
23420 {
23421 nextEffect.flags &= ~Hydrating; // Update
23422
23423 var _current2 = nextEffect.alternate;
23424 commitWork(_current2, nextEffect);
23425 break;
23426 }
23427
23428 case Update:
23429 {
23430 var _current3 = nextEffect.alternate;
23431 commitWork(_current3, nextEffect);
23432 break;
23433 }
23434
23435 case Deletion:
23436 {
23437 commitDeletion(root, nextEffect);
23438 break;
23439 }
23440 }
23441
23442 resetCurrentFiber();
23443 nextEffect = nextEffect.nextEffect;
23444 }
23445 }
23446
23447 function commitLayoutEffects(root, committedLanes) {
23448
23449
23450 while (nextEffect !== null) {
23451 setCurrentFiber(nextEffect);
23452 var flags = nextEffect.flags;
23453
23454 if (flags & (Update | Callback)) {
23455 var current = nextEffect.alternate;
23456 commitLifeCycles(root, current, nextEffect);
23457 }
23458
23459 {
23460 if (flags & Ref) {
23461 commitAttachRef(nextEffect);
23462 }
23463 }
23464
23465 resetCurrentFiber();
23466 nextEffect = nextEffect.nextEffect;
23467 }
23468 }
23469
23470 function flushPassiveEffects() {
23471 // Returns whether passive effects were flushed.
23472 if (pendingPassiveEffectsRenderPriority !== NoPriority$1) {
23473 var priorityLevel = pendingPassiveEffectsRenderPriority > NormalPriority$1 ? NormalPriority$1 : pendingPassiveEffectsRenderPriority;
23474 pendingPassiveEffectsRenderPriority = NoPriority$1;
23475
23476 {
23477 return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl);
23478 }
23479 }
23480
23481 return false;
23482 }
23483 function enqueuePendingPassiveHookEffectMount(fiber, effect) {
23484 pendingPassiveHookEffectsMount.push(effect, fiber);
23485
23486 if (!rootDoesHavePassiveEffects) {
23487 rootDoesHavePassiveEffects = true;
23488 scheduleCallback(NormalPriority$1, function () {
23489 flushPassiveEffects();
23490 return null;
23491 });
23492 }
23493 }
23494 function enqueuePendingPassiveHookEffectUnmount(fiber, effect) {
23495 pendingPassiveHookEffectsUnmount.push(effect, fiber);
23496
23497 {
23498 fiber.flags |= PassiveUnmountPendingDev;
23499 var alternate = fiber.alternate;
23500
23501 if (alternate !== null) {
23502 alternate.flags |= PassiveUnmountPendingDev;
23503 }
23504 }
23505
23506 if (!rootDoesHavePassiveEffects) {
23507 rootDoesHavePassiveEffects = true;
23508 scheduleCallback(NormalPriority$1, function () {
23509 flushPassiveEffects();
23510 return null;
23511 });
23512 }
23513 }
23514
23515 function invokePassiveEffectCreate(effect) {
23516 var create = effect.create;
23517 effect.destroy = create();
23518 }
23519
23520 function flushPassiveEffectsImpl() {
23521 if (rootWithPendingPassiveEffects === null) {
23522 return false;
23523 }
23524
23525 var root = rootWithPendingPassiveEffects;
23526 var lanes = pendingPassiveEffectsLanes;
23527 rootWithPendingPassiveEffects = null;
23528 pendingPassiveEffectsLanes = NoLanes;
23529
23530 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
23531 {
23532 throw Error( "Cannot flush passive effects while already rendering." );
23533 }
23534 }
23535
23536 {
23537 isFlushingPassiveEffects = true;
23538 }
23539
23540 var prevExecutionContext = executionContext;
23541 executionContext |= CommitContext;
23542 var prevInteractions = pushInteractions(root); // It's important that ALL pending passive effect destroy functions are called
23543 // before ANY passive effect create functions are called.
23544 // Otherwise effects in sibling components might interfere with each other.
23545 // e.g. a destroy function in one component may unintentionally override a ref
23546 // value set by a create function in another component.
23547 // Layout effects have the same constraint.
23548 // First pass: Destroy stale passive effects.
23549
23550 var unmountEffects = pendingPassiveHookEffectsUnmount;
23551 pendingPassiveHookEffectsUnmount = [];
23552
23553 for (var i = 0; i < unmountEffects.length; i += 2) {
23554 var _effect = unmountEffects[i];
23555 var fiber = unmountEffects[i + 1];
23556 var destroy = _effect.destroy;
23557 _effect.destroy = undefined;
23558
23559 {
23560 fiber.flags &= ~PassiveUnmountPendingDev;
23561 var alternate = fiber.alternate;
23562
23563 if (alternate !== null) {
23564 alternate.flags &= ~PassiveUnmountPendingDev;
23565 }
23566 }
23567
23568 if (typeof destroy === 'function') {
23569 {
23570 setCurrentFiber(fiber);
23571
23572 {
23573 invokeGuardedCallback(null, destroy, null);
23574 }
23575
23576 if (hasCaughtError()) {
23577 if (!(fiber !== null)) {
23578 {
23579 throw Error( "Should be working on an effect." );
23580 }
23581 }
23582
23583 var error = clearCaughtError();
23584 captureCommitPhaseError(fiber, error);
23585 }
23586
23587 resetCurrentFiber();
23588 }
23589 }
23590 } // Second pass: Create new passive effects.
23591
23592
23593 var mountEffects = pendingPassiveHookEffectsMount;
23594 pendingPassiveHookEffectsMount = [];
23595
23596 for (var _i = 0; _i < mountEffects.length; _i += 2) {
23597 var _effect2 = mountEffects[_i];
23598 var _fiber = mountEffects[_i + 1];
23599
23600 {
23601 setCurrentFiber(_fiber);
23602
23603 {
23604 invokeGuardedCallback(null, invokePassiveEffectCreate, null, _effect2);
23605 }
23606
23607 if (hasCaughtError()) {
23608 if (!(_fiber !== null)) {
23609 {
23610 throw Error( "Should be working on an effect." );
23611 }
23612 }
23613
23614 var _error4 = clearCaughtError();
23615
23616 captureCommitPhaseError(_fiber, _error4);
23617 }
23618
23619 resetCurrentFiber();
23620 }
23621 } // Note: This currently assumes there are no passive effects on the root fiber
23622 // because the root is not part of its own effect list.
23623 // This could change in the future.
23624
23625
23626 var effect = root.current.firstEffect;
23627
23628 while (effect !== null) {
23629 var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC
23630
23631 effect.nextEffect = null;
23632
23633 if (effect.flags & Deletion) {
23634 detachFiberAfterEffects(effect);
23635 }
23636
23637 effect = nextNextEffect;
23638 }
23639
23640 {
23641 popInteractions(prevInteractions);
23642 finishPendingInteractions(root, lanes);
23643 }
23644
23645 {
23646 isFlushingPassiveEffects = false;
23647 }
23648
23649 executionContext = prevExecutionContext;
23650 flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this
23651 // exceeds the limit, we'll fire a warning.
23652
23653 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
23654 return true;
23655 }
23656
23657 function isAlreadyFailedLegacyErrorBoundary(instance) {
23658 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
23659 }
23660 function markLegacyErrorBoundaryAsFailed(instance) {
23661 if (legacyErrorBoundariesThatAlreadyFailed === null) {
23662 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
23663 } else {
23664 legacyErrorBoundariesThatAlreadyFailed.add(instance);
23665 }
23666 }
23667
23668 function prepareToThrowUncaughtError(error) {
23669 if (!hasUncaughtError) {
23670 hasUncaughtError = true;
23671 firstUncaughtError = error;
23672 }
23673 }
23674
23675 var onUncaughtError = prepareToThrowUncaughtError;
23676
23677 function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
23678 var errorInfo = createCapturedValue(error, sourceFiber);
23679 var update = createRootErrorUpdate(rootFiber, errorInfo, SyncLane);
23680 enqueueUpdate(rootFiber, update);
23681 var eventTime = requestEventTime();
23682 var root = markUpdateLaneFromFiberToRoot(rootFiber, SyncLane);
23683
23684 if (root !== null) {
23685 markRootUpdated(root, SyncLane, eventTime);
23686 ensureRootIsScheduled(root, eventTime);
23687 schedulePendingInteractions(root, SyncLane);
23688 }
23689 }
23690
23691 function captureCommitPhaseError(sourceFiber, error) {
23692 if (sourceFiber.tag === HostRoot) {
23693 // Error was thrown at the root. There is no parent, so the root
23694 // itself should capture it.
23695 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);
23696 return;
23697 }
23698
23699 var fiber = sourceFiber.return;
23700
23701 while (fiber !== null) {
23702 if (fiber.tag === HostRoot) {
23703 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);
23704 return;
23705 } else if (fiber.tag === ClassComponent) {
23706 var ctor = fiber.type;
23707 var instance = fiber.stateNode;
23708
23709 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
23710 var errorInfo = createCapturedValue(error, sourceFiber);
23711 var update = createClassErrorUpdate(fiber, errorInfo, SyncLane);
23712 enqueueUpdate(fiber, update);
23713 var eventTime = requestEventTime();
23714 var root = markUpdateLaneFromFiberToRoot(fiber, SyncLane);
23715
23716 if (root !== null) {
23717 markRootUpdated(root, SyncLane, eventTime);
23718 ensureRootIsScheduled(root, eventTime);
23719 schedulePendingInteractions(root, SyncLane);
23720 } else {
23721 // This component has already been unmounted.
23722 // We can't schedule any follow up work for the root because the fiber is already unmounted,
23723 // but we can still call the log-only boundary so the error isn't swallowed.
23724 //
23725 // TODO This is only a temporary bandaid for the old reconciler fork.
23726 // We can delete this special case once the new fork is merged.
23727 if (typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
23728 try {
23729 instance.componentDidCatch(error, errorInfo);
23730 } catch (errorToIgnore) {// TODO Ignore this error? Rethrow it?
23731 // This is kind of an edge case.
23732 }
23733 }
23734 }
23735
23736 return;
23737 }
23738 }
23739
23740 fiber = fiber.return;
23741 }
23742 }
23743 function pingSuspendedRoot(root, wakeable, pingedLanes) {
23744 var pingCache = root.pingCache;
23745
23746 if (pingCache !== null) {
23747 // The wakeable resolved, so we no longer need to memoize, because it will
23748 // never be thrown again.
23749 pingCache.delete(wakeable);
23750 }
23751
23752 var eventTime = requestEventTime();
23753 markRootPinged(root, pingedLanes);
23754
23755 if (workInProgressRoot === root && isSubsetOfLanes(workInProgressRootRenderLanes, pingedLanes)) {
23756 // Received a ping at the same priority level at which we're currently
23757 // rendering. We might want to restart this render. This should mirror
23758 // the logic of whether or not a root suspends once it completes.
23759 // TODO: If we're rendering sync either due to Sync, Batched or expired,
23760 // we should probably never restart.
23761 // If we're suspended with delay, or if it's a retry, we'll always suspend
23762 // so we can always restart.
23763 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && includesOnlyRetries(workInProgressRootRenderLanes) && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
23764 // Restart from the root.
23765 prepareFreshStack(root, NoLanes);
23766 } else {
23767 // Even though we can't restart right now, we might get an
23768 // opportunity later. So we mark this render as having a ping.
23769 workInProgressRootPingedLanes = mergeLanes(workInProgressRootPingedLanes, pingedLanes);
23770 }
23771 }
23772
23773 ensureRootIsScheduled(root, eventTime);
23774 schedulePendingInteractions(root, pingedLanes);
23775 }
23776
23777 function retryTimedOutBoundary(boundaryFiber, retryLane) {
23778 // The boundary fiber (a Suspense component or SuspenseList component)
23779 // previously was rendered in its fallback state. One of the promises that
23780 // suspended it has resolved, which means at least part of the tree was
23781 // likely unblocked. Try rendering again, at a new expiration time.
23782 if (retryLane === NoLane) {
23783 retryLane = requestRetryLane(boundaryFiber);
23784 } // TODO: Special case idle priority?
23785
23786
23787 var eventTime = requestEventTime();
23788 var root = markUpdateLaneFromFiberToRoot(boundaryFiber, retryLane);
23789
23790 if (root !== null) {
23791 markRootUpdated(root, retryLane, eventTime);
23792 ensureRootIsScheduled(root, eventTime);
23793 schedulePendingInteractions(root, retryLane);
23794 }
23795 }
23796 function resolveRetryWakeable(boundaryFiber, wakeable) {
23797 var retryLane = NoLane; // Default
23798
23799 var retryCache;
23800
23801 {
23802 retryCache = boundaryFiber.stateNode;
23803 }
23804
23805 if (retryCache !== null) {
23806 // The wakeable resolved, so we no longer need to memoize, because it will
23807 // never be thrown again.
23808 retryCache.delete(wakeable);
23809 }
23810
23811 retryTimedOutBoundary(boundaryFiber, retryLane);
23812 } // Computes the next Just Noticeable Difference (JND) boundary.
23813 // The theory is that a person can't tell the difference between small differences in time.
23814 // Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
23815 // difference in the experience. However, waiting for longer might mean that we can avoid
23816 // showing an intermediate loading state. The longer we have already waited, the harder it
23817 // is to tell small differences in time. Therefore, the longer we've already waited,
23818 // the longer we can wait additionally. At some point we have to give up though.
23819 // We pick a train model where the next boundary commits at a consistent schedule.
23820 // These particular numbers are vague estimates. We expect to adjust them based on research.
23821
23822 function jnd(timeElapsed) {
23823 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
23824 }
23825
23826 function checkForNestedUpdates() {
23827 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
23828 nestedUpdateCount = 0;
23829 rootWithNestedUpdates = null;
23830
23831 {
23832 {
23833 throw Error( "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." );
23834 }
23835 }
23836 }
23837
23838 {
23839 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
23840 nestedPassiveUpdateCount = 0;
23841
23842 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.');
23843 }
23844 }
23845 }
23846
23847 function flushRenderPhaseStrictModeWarningsInDEV() {
23848 {
23849 ReactStrictModeWarnings.flushLegacyContextWarning();
23850
23851 {
23852 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
23853 }
23854 }
23855 }
23856
23857 var didWarnStateUpdateForNotYetMountedComponent = null;
23858
23859 function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) {
23860 {
23861 if ((executionContext & RenderContext) !== NoContext) {
23862 // We let the other warning about render phase updates deal with this one.
23863 return;
23864 }
23865
23866 if (!(fiber.mode & (BlockingMode | ConcurrentMode))) {
23867 return;
23868 }
23869
23870 var tag = fiber.tag;
23871
23872 if (tag !== IndeterminateComponent && tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent && tag !== Block) {
23873 // Only warn for user-defined components, not internal ones like Suspense.
23874 return;
23875 } // We show the whole stack but dedupe on the top component's name because
23876 // the problematic code almost always lies inside that component.
23877
23878
23879 var componentName = getComponentName(fiber.type) || 'ReactComponent';
23880
23881 if (didWarnStateUpdateForNotYetMountedComponent !== null) {
23882 if (didWarnStateUpdateForNotYetMountedComponent.has(componentName)) {
23883 return;
23884 }
23885
23886 didWarnStateUpdateForNotYetMountedComponent.add(componentName);
23887 } else {
23888 didWarnStateUpdateForNotYetMountedComponent = new Set([componentName]);
23889 }
23890
23891 var previousFiber = current;
23892
23893 try {
23894 setCurrentFiber(fiber);
23895
23896 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.');
23897 } finally {
23898 if (previousFiber) {
23899 setCurrentFiber(fiber);
23900 } else {
23901 resetCurrentFiber();
23902 }
23903 }
23904 }
23905 }
23906
23907 var didWarnStateUpdateForUnmountedComponent = null;
23908
23909 function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
23910 {
23911 var tag = fiber.tag;
23912
23913 if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent && tag !== Block) {
23914 // Only warn for user-defined components, not internal ones like Suspense.
23915 return;
23916 } // If there are pending passive effects unmounts for this Fiber,
23917 // we can assume that they would have prevented this update.
23918
23919
23920 if ((fiber.flags & PassiveUnmountPendingDev) !== NoFlags) {
23921 return;
23922 } // We show the whole stack but dedupe on the top component's name because
23923 // the problematic code almost always lies inside that component.
23924
23925
23926 var componentName = getComponentName(fiber.type) || 'ReactComponent';
23927
23928 if (didWarnStateUpdateForUnmountedComponent !== null) {
23929 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {
23930 return;
23931 }
23932
23933 didWarnStateUpdateForUnmountedComponent.add(componentName);
23934 } else {
23935 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);
23936 }
23937
23938 if (isFlushingPassiveEffects) ; else {
23939 var previousFiber = current;
23940
23941 try {
23942 setCurrentFiber(fiber);
23943
23944 error("Can't perform a React state update on an unmounted component. This " + 'is a no-op, but it indicates a memory leak in your application. To ' + 'fix, cancel all subscriptions and asynchronous tasks in %s.', tag === ClassComponent ? 'the componentWillUnmount method' : 'a useEffect cleanup function');
23945 } finally {
23946 if (previousFiber) {
23947 setCurrentFiber(fiber);
23948 } else {
23949 resetCurrentFiber();
23950 }
23951 }
23952 }
23953 }
23954 }
23955
23956 var beginWork$1;
23957
23958 {
23959 var dummyFiber = null;
23960
23961 beginWork$1 = function (current, unitOfWork, lanes) {
23962 // If a component throws an error, we replay it again in a synchronously
23963 // dispatched event, so that the debugger will treat it as an uncaught
23964 // error See ReactErrorUtils for more information.
23965 // Before entering the begin phase, copy the work-in-progress onto a dummy
23966 // fiber. If beginWork throws, we'll use this to reset the state.
23967 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
23968
23969 try {
23970 return beginWork(current, unitOfWork, lanes);
23971 } catch (originalError) {
23972 if (originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {
23973 // Don't replay promises. Treat everything else like an error.
23974 throw originalError;
23975 } // Keep this code in sync with handleError; any changes here must have
23976 // corresponding changes there.
23977
23978
23979 resetContextDependencies();
23980 resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the
23981 // same fiber again.
23982 // Unwind the failed stack frame
23983
23984 unwindInterruptedWork(unitOfWork); // Restore the original properties of the fiber.
23985
23986 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
23987
23988 if ( unitOfWork.mode & ProfileMode) {
23989 // Reset the profiler timer.
23990 startProfilerTimer(unitOfWork);
23991 } // Run beginWork again.
23992
23993
23994 invokeGuardedCallback(null, beginWork, null, current, unitOfWork, lanes);
23995
23996 if (hasCaughtError()) {
23997 var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`.
23998 // Rethrow this error instead of the original one.
23999
24000 throw replayError;
24001 } else {
24002 // This branch is reachable if the render phase is impure.
24003 throw originalError;
24004 }
24005 }
24006 };
24007 }
24008
24009 var didWarnAboutUpdateInRender = false;
24010 var didWarnAboutUpdateInRenderForAnotherComponent;
24011
24012 {
24013 didWarnAboutUpdateInRenderForAnotherComponent = new Set();
24014 }
24015
24016 function warnAboutRenderPhaseUpdatesInDEV(fiber) {
24017 {
24018 if (isRendering && (executionContext & RenderContext) !== NoContext && !getIsUpdatingOpaqueValueInRenderPhaseInDEV()) {
24019 switch (fiber.tag) {
24020 case FunctionComponent:
24021 case ForwardRef:
24022 case SimpleMemoComponent:
24023 {
24024 var renderingComponentName = workInProgress && getComponentName(workInProgress.type) || 'Unknown'; // Dedupe by the rendering component because it's the one that needs to be fixed.
24025
24026 var dedupeKey = renderingComponentName;
24027
24028 if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) {
24029 didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey);
24030 var setStateComponentName = getComponentName(fiber.type) || 'Unknown';
24031
24032 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);
24033 }
24034
24035 break;
24036 }
24037
24038 case ClassComponent:
24039 {
24040 if (!didWarnAboutUpdateInRender) {
24041 error('Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure ' + 'function of props and state.');
24042
24043 didWarnAboutUpdateInRender = true;
24044 }
24045
24046 break;
24047 }
24048 }
24049 }
24050 }
24051 } // a 'shared' variable that changes when act() opens/closes in tests.
24052
24053
24054 var IsThisRendererActing = {
24055 current: false
24056 };
24057 function warnIfNotScopedWithMatchingAct(fiber) {
24058 {
24059 if ( IsSomeRendererActing.current === true && IsThisRendererActing.current !== true) {
24060 var previousFiber = current;
24061
24062 try {
24063 setCurrentFiber(fiber);
24064
24065 error("It looks like you're using the wrong act() around your test interactions.\n" + 'Be sure to use the matching version of act() corresponding to your renderer:\n\n' + '// for react-dom:\n' + // Break up imports to avoid accidentally parsing them as dependencies.
24066 'import {act} fr' + "om 'react-dom/test-utils';\n" + '// ...\n' + 'act(() => ...);\n\n' + '// for react-test-renderer:\n' + // Break up imports to avoid accidentally parsing them as dependencies.
24067 'import TestRenderer fr' + "om react-test-renderer';\n" + 'const {act} = TestRenderer;\n' + '// ...\n' + 'act(() => ...);');
24068 } finally {
24069 if (previousFiber) {
24070 setCurrentFiber(fiber);
24071 } else {
24072 resetCurrentFiber();
24073 }
24074 }
24075 }
24076 }
24077 }
24078 function warnIfNotCurrentlyActingEffectsInDEV(fiber) {
24079 {
24080 if ( (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
24081 error('An update to %s ran an effect, but was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://reactjs.org/link/wrap-tests-with-act', getComponentName(fiber.type));
24082 }
24083 }
24084 }
24085
24086 function warnIfNotCurrentlyActingUpdatesInDEV(fiber) {
24087 {
24088 if ( executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
24089 var previousFiber = current;
24090
24091 try {
24092 setCurrentFiber(fiber);
24093
24094 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', getComponentName(fiber.type));
24095 } finally {
24096 if (previousFiber) {
24097 setCurrentFiber(fiber);
24098 } else {
24099 resetCurrentFiber();
24100 }
24101 }
24102 }
24103 }
24104 }
24105
24106 var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; // In tests, we want to enforce a mocked scheduler.
24107
24108 var didWarnAboutUnmockedScheduler = false; // TODO Before we release concurrent mode, revisit this and decide whether a mocked
24109 // scheduler is the actual recommendation. The alternative could be a testing build,
24110 // a new lib, or whatever; we dunno just yet. This message is for early adopters
24111 // to get their tests right.
24112
24113 function warnIfUnmockedScheduler(fiber) {
24114 {
24115 if (didWarnAboutUnmockedScheduler === false && unstable_flushAllWithoutAsserting === undefined) {
24116 if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) {
24117 didWarnAboutUnmockedScheduler = true;
24118
24119 error('In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + 'to guarantee consistent behaviour across tests and browsers. ' + 'For example, with jest: \n' + // Break up requires to avoid accidentally parsing them as dependencies.
24120 "jest.mock('scheduler', () => require" + "('scheduler/unstable_mock'));\n\n" + 'For more info, visit https://reactjs.org/link/mock-scheduler');
24121 }
24122 }
24123 }
24124 }
24125
24126 function computeThreadID(root, lane) {
24127 // Interaction threads are unique per root and expiration time.
24128 // NOTE: Intentionally unsound cast. All that matters is that it's a number
24129 // and it represents a batch of work. Could make a helper function instead,
24130 // but meh this is fine for now.
24131 return lane * 1000 + root.interactionThreadID;
24132 }
24133
24134 function markSpawnedWork(lane) {
24135
24136 if (spawnedWorkDuringRender === null) {
24137 spawnedWorkDuringRender = [lane];
24138 } else {
24139 spawnedWorkDuringRender.push(lane);
24140 }
24141 }
24142
24143 function scheduleInteractions(root, lane, interactions) {
24144
24145 if (interactions.size > 0) {
24146 var pendingInteractionMap = root.pendingInteractionMap;
24147 var pendingInteractions = pendingInteractionMap.get(lane);
24148
24149 if (pendingInteractions != null) {
24150 interactions.forEach(function (interaction) {
24151 if (!pendingInteractions.has(interaction)) {
24152 // Update the pending async work count for previously unscheduled interaction.
24153 interaction.__count++;
24154 }
24155
24156 pendingInteractions.add(interaction);
24157 });
24158 } else {
24159 pendingInteractionMap.set(lane, new Set(interactions)); // Update the pending async work count for the current interactions.
24160
24161 interactions.forEach(function (interaction) {
24162 interaction.__count++;
24163 });
24164 }
24165
24166 var subscriber = __subscriberRef.current;
24167
24168 if (subscriber !== null) {
24169 var threadID = computeThreadID(root, lane);
24170 subscriber.onWorkScheduled(interactions, threadID);
24171 }
24172 }
24173 }
24174
24175 function schedulePendingInteractions(root, lane) {
24176
24177 scheduleInteractions(root, lane, __interactionsRef.current);
24178 }
24179
24180 function startWorkOnPendingInteractions(root, lanes) {
24181 // we can accurately attribute time spent working on it, And so that cascading
24182 // work triggered during the render phase will be associated with it.
24183
24184
24185 var interactions = new Set();
24186 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledLane) {
24187 if (includesSomeLane(lanes, scheduledLane)) {
24188 scheduledInteractions.forEach(function (interaction) {
24189 return interactions.add(interaction);
24190 });
24191 }
24192 }); // Store the current set of interactions on the FiberRoot for a few reasons:
24193 // We can re-use it in hot functions like performConcurrentWorkOnRoot()
24194 // without having to recalculate it. We will also use it in commitWork() to
24195 // pass to any Profiler onRender() hooks. This also provides DevTools with a
24196 // way to access it when the onCommitRoot() hook is called.
24197
24198 root.memoizedInteractions = interactions;
24199
24200 if (interactions.size > 0) {
24201 var subscriber = __subscriberRef.current;
24202
24203 if (subscriber !== null) {
24204 var threadID = computeThreadID(root, lanes);
24205
24206 try {
24207 subscriber.onWorkStarted(interactions, threadID);
24208 } catch (error) {
24209 // If the subscriber throws, rethrow it in a separate task
24210 scheduleCallback(ImmediatePriority$1, function () {
24211 throw error;
24212 });
24213 }
24214 }
24215 }
24216 }
24217
24218 function finishPendingInteractions(root, committedLanes) {
24219
24220 var remainingLanesAfterCommit = root.pendingLanes;
24221 var subscriber;
24222
24223 try {
24224 subscriber = __subscriberRef.current;
24225
24226 if (subscriber !== null && root.memoizedInteractions.size > 0) {
24227 // FIXME: More than one lane can finish in a single commit.
24228 var threadID = computeThreadID(root, committedLanes);
24229 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
24230 }
24231 } catch (error) {
24232 // If the subscriber throws, rethrow it in a separate task
24233 scheduleCallback(ImmediatePriority$1, function () {
24234 throw error;
24235 });
24236 } finally {
24237 // Clear completed interactions from the pending Map.
24238 // Unless the render was suspended or cascading work was scheduled,
24239 // In which case– leave pending interactions until the subsequent render.
24240 var pendingInteractionMap = root.pendingInteractionMap;
24241 pendingInteractionMap.forEach(function (scheduledInteractions, lane) {
24242 // Only decrement the pending interaction count if we're done.
24243 // If there's still work at the current priority,
24244 // That indicates that we are waiting for suspense data.
24245 if (!includesSomeLane(remainingLanesAfterCommit, lane)) {
24246 pendingInteractionMap.delete(lane);
24247 scheduledInteractions.forEach(function (interaction) {
24248 interaction.__count--;
24249
24250 if (subscriber !== null && interaction.__count === 0) {
24251 try {
24252 subscriber.onInteractionScheduledWorkCompleted(interaction);
24253 } catch (error) {
24254 // If the subscriber throws, rethrow it in a separate task
24255 scheduleCallback(ImmediatePriority$1, function () {
24256 throw error;
24257 });
24258 }
24259 }
24260 });
24261 }
24262 });
24263 }
24264 } // `act` testing API
24265
24266 function shouldForceFlushFallbacksInDEV() {
24267 // Never force flush in production. This function should get stripped out.
24268 return actingUpdatesScopeDepth > 0;
24269 }
24270 // so we can tell if any async act() calls try to run in parallel.
24271
24272
24273 var actingUpdatesScopeDepth = 0;
24274
24275 function detachFiberAfterEffects(fiber) {
24276 fiber.sibling = null;
24277 fiber.stateNode = null;
24278 }
24279
24280 var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.
24281
24282 var failedBoundaries = null;
24283 var setRefreshHandler = function (handler) {
24284 {
24285 resolveFamily = handler;
24286 }
24287 };
24288 function resolveFunctionForHotReloading(type) {
24289 {
24290 if (resolveFamily === null) {
24291 // Hot reloading is disabled.
24292 return type;
24293 }
24294
24295 var family = resolveFamily(type);
24296
24297 if (family === undefined) {
24298 return type;
24299 } // Use the latest known implementation.
24300
24301
24302 return family.current;
24303 }
24304 }
24305 function resolveClassForHotReloading(type) {
24306 // No implementation differences.
24307 return resolveFunctionForHotReloading(type);
24308 }
24309 function resolveForwardRefForHotReloading(type) {
24310 {
24311 if (resolveFamily === null) {
24312 // Hot reloading is disabled.
24313 return type;
24314 }
24315
24316 var family = resolveFamily(type);
24317
24318 if (family === undefined) {
24319 // Check if we're dealing with a real forwardRef. Don't want to crash early.
24320 if (type !== null && type !== undefined && typeof type.render === 'function') {
24321 // ForwardRef is special because its resolved .type is an object,
24322 // but it's possible that we only have its inner render function in the map.
24323 // If that inner render function is different, we'll build a new forwardRef type.
24324 var currentRender = resolveFunctionForHotReloading(type.render);
24325
24326 if (type.render !== currentRender) {
24327 var syntheticType = {
24328 $$typeof: REACT_FORWARD_REF_TYPE,
24329 render: currentRender
24330 };
24331
24332 if (type.displayName !== undefined) {
24333 syntheticType.displayName = type.displayName;
24334 }
24335
24336 return syntheticType;
24337 }
24338 }
24339
24340 return type;
24341 } // Use the latest known implementation.
24342
24343
24344 return family.current;
24345 }
24346 }
24347 function isCompatibleFamilyForHotReloading(fiber, element) {
24348 {
24349 if (resolveFamily === null) {
24350 // Hot reloading is disabled.
24351 return false;
24352 }
24353
24354 var prevType = fiber.elementType;
24355 var nextType = element.type; // If we got here, we know types aren't === equal.
24356
24357 var needsCompareFamilies = false;
24358 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
24359
24360 switch (fiber.tag) {
24361 case ClassComponent:
24362 {
24363 if (typeof nextType === 'function') {
24364 needsCompareFamilies = true;
24365 }
24366
24367 break;
24368 }
24369
24370 case FunctionComponent:
24371 {
24372 if (typeof nextType === 'function') {
24373 needsCompareFamilies = true;
24374 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
24375 // We don't know the inner type yet.
24376 // We're going to assume that the lazy inner type is stable,
24377 // and so it is sufficient to avoid reconciling it away.
24378 // We're not going to unwrap or actually use the new lazy type.
24379 needsCompareFamilies = true;
24380 }
24381
24382 break;
24383 }
24384
24385 case ForwardRef:
24386 {
24387 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
24388 needsCompareFamilies = true;
24389 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
24390 needsCompareFamilies = true;
24391 }
24392
24393 break;
24394 }
24395
24396 case MemoComponent:
24397 case SimpleMemoComponent:
24398 {
24399 if ($$typeofNextType === REACT_MEMO_TYPE) {
24400 // TODO: if it was but can no longer be simple,
24401 // we shouldn't set this.
24402 needsCompareFamilies = true;
24403 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
24404 needsCompareFamilies = true;
24405 }
24406
24407 break;
24408 }
24409
24410 default:
24411 return false;
24412 } // Check if both types have a family and it's the same one.
24413
24414
24415 if (needsCompareFamilies) {
24416 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
24417 // This means both of them need to be registered to preserve state.
24418 // If we unwrapped and compared the inner types for wrappers instead,
24419 // then we would risk falsely saying two separate memo(Foo)
24420 // calls are equivalent because they wrap the same Foo function.
24421 var prevFamily = resolveFamily(prevType);
24422
24423 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
24424 return true;
24425 }
24426 }
24427
24428 return false;
24429 }
24430 }
24431 function markFailedErrorBoundaryForHotReloading(fiber) {
24432 {
24433 if (resolveFamily === null) {
24434 // Hot reloading is disabled.
24435 return;
24436 }
24437
24438 if (typeof WeakSet !== 'function') {
24439 return;
24440 }
24441
24442 if (failedBoundaries === null) {
24443 failedBoundaries = new WeakSet();
24444 }
24445
24446 failedBoundaries.add(fiber);
24447 }
24448 }
24449 var scheduleRefresh = function (root, update) {
24450 {
24451 if (resolveFamily === null) {
24452 // Hot reloading is disabled.
24453 return;
24454 }
24455
24456 var staleFamilies = update.staleFamilies,
24457 updatedFamilies = update.updatedFamilies;
24458 flushPassiveEffects();
24459 flushSync(function () {
24460 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);
24461 });
24462 }
24463 };
24464 var scheduleRoot = function (root, element) {
24465 {
24466 if (root.context !== emptyContextObject) {
24467 // Super edge case: root has a legacy _renderSubtree context
24468 // but we don't know the parentComponent so we can't pass it.
24469 // Just ignore. We'll delete this with _renderSubtree code path later.
24470 return;
24471 }
24472
24473 flushPassiveEffects();
24474 flushSync(function () {
24475 updateContainer(element, root, null, null);
24476 });
24477 }
24478 };
24479
24480 function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
24481 {
24482 var alternate = fiber.alternate,
24483 child = fiber.child,
24484 sibling = fiber.sibling,
24485 tag = fiber.tag,
24486 type = fiber.type;
24487 var candidateType = null;
24488
24489 switch (tag) {
24490 case FunctionComponent:
24491 case SimpleMemoComponent:
24492 case ClassComponent:
24493 candidateType = type;
24494 break;
24495
24496 case ForwardRef:
24497 candidateType = type.render;
24498 break;
24499 }
24500
24501 if (resolveFamily === null) {
24502 throw new Error('Expected resolveFamily to be set during hot reload.');
24503 }
24504
24505 var needsRender = false;
24506 var needsRemount = false;
24507
24508 if (candidateType !== null) {
24509 var family = resolveFamily(candidateType);
24510
24511 if (family !== undefined) {
24512 if (staleFamilies.has(family)) {
24513 needsRemount = true;
24514 } else if (updatedFamilies.has(family)) {
24515 if (tag === ClassComponent) {
24516 needsRemount = true;
24517 } else {
24518 needsRender = true;
24519 }
24520 }
24521 }
24522 }
24523
24524 if (failedBoundaries !== null) {
24525 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
24526 needsRemount = true;
24527 }
24528 }
24529
24530 if (needsRemount) {
24531 fiber._debugNeedsRemount = true;
24532 }
24533
24534 if (needsRemount || needsRender) {
24535 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
24536 }
24537
24538 if (child !== null && !needsRemount) {
24539 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
24540 }
24541
24542 if (sibling !== null) {
24543 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
24544 }
24545 }
24546 }
24547
24548 var findHostInstancesForRefresh = function (root, families) {
24549 {
24550 var hostInstances = new Set();
24551 var types = new Set(families.map(function (family) {
24552 return family.current;
24553 }));
24554 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
24555 return hostInstances;
24556 }
24557 };
24558
24559 function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
24560 {
24561 var child = fiber.child,
24562 sibling = fiber.sibling,
24563 tag = fiber.tag,
24564 type = fiber.type;
24565 var candidateType = null;
24566
24567 switch (tag) {
24568 case FunctionComponent:
24569 case SimpleMemoComponent:
24570 case ClassComponent:
24571 candidateType = type;
24572 break;
24573
24574 case ForwardRef:
24575 candidateType = type.render;
24576 break;
24577 }
24578
24579 var didMatch = false;
24580
24581 if (candidateType !== null) {
24582 if (types.has(candidateType)) {
24583 didMatch = true;
24584 }
24585 }
24586
24587 if (didMatch) {
24588 // We have a match. This only drills down to the closest host components.
24589 // There's no need to search deeper because for the purpose of giving
24590 // visual feedback, "flashing" outermost parent rectangles is sufficient.
24591 findHostInstancesForFiberShallowly(fiber, hostInstances);
24592 } else {
24593 // If there's no match, maybe there will be one further down in the child tree.
24594 if (child !== null) {
24595 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
24596 }
24597 }
24598
24599 if (sibling !== null) {
24600 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
24601 }
24602 }
24603 }
24604
24605 function findHostInstancesForFiberShallowly(fiber, hostInstances) {
24606 {
24607 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
24608
24609 if (foundHostInstances) {
24610 return;
24611 } // If we didn't find any host children, fallback to closest host parent.
24612
24613
24614 var node = fiber;
24615
24616 while (true) {
24617 switch (node.tag) {
24618 case HostComponent:
24619 hostInstances.add(node.stateNode);
24620 return;
24621
24622 case HostPortal:
24623 hostInstances.add(node.stateNode.containerInfo);
24624 return;
24625
24626 case HostRoot:
24627 hostInstances.add(node.stateNode.containerInfo);
24628 return;
24629 }
24630
24631 if (node.return === null) {
24632 throw new Error('Expected to reach root first.');
24633 }
24634
24635 node = node.return;
24636 }
24637 }
24638 }
24639
24640 function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
24641 {
24642 var node = fiber;
24643 var foundHostInstances = false;
24644
24645 while (true) {
24646 if (node.tag === HostComponent) {
24647 // We got a match.
24648 foundHostInstances = true;
24649 hostInstances.add(node.stateNode); // There may still be more, so keep searching.
24650 } else if (node.child !== null) {
24651 node.child.return = node;
24652 node = node.child;
24653 continue;
24654 }
24655
24656 if (node === fiber) {
24657 return foundHostInstances;
24658 }
24659
24660 while (node.sibling === null) {
24661 if (node.return === null || node.return === fiber) {
24662 return foundHostInstances;
24663 }
24664
24665 node = node.return;
24666 }
24667
24668 node.sibling.return = node.return;
24669 node = node.sibling;
24670 }
24671 }
24672
24673 return false;
24674 }
24675
24676 var hasBadMapPolyfill;
24677
24678 {
24679 hasBadMapPolyfill = false;
24680
24681 try {
24682 var nonExtensibleObject = Object.preventExtensions({});
24683 /* eslint-disable no-new */
24684
24685 new Map([[nonExtensibleObject, null]]);
24686 new Set([nonExtensibleObject]);
24687 /* eslint-enable no-new */
24688 } catch (e) {
24689 // TODO: Consider warning about bad polyfills
24690 hasBadMapPolyfill = true;
24691 }
24692 }
24693
24694 var debugCounter = 1;
24695
24696 function FiberNode(tag, pendingProps, key, mode) {
24697 // Instance
24698 this.tag = tag;
24699 this.key = key;
24700 this.elementType = null;
24701 this.type = null;
24702 this.stateNode = null; // Fiber
24703
24704 this.return = null;
24705 this.child = null;
24706 this.sibling = null;
24707 this.index = 0;
24708 this.ref = null;
24709 this.pendingProps = pendingProps;
24710 this.memoizedProps = null;
24711 this.updateQueue = null;
24712 this.memoizedState = null;
24713 this.dependencies = null;
24714 this.mode = mode; // Effects
24715
24716 this.flags = NoFlags;
24717 this.nextEffect = null;
24718 this.firstEffect = null;
24719 this.lastEffect = null;
24720 this.lanes = NoLanes;
24721 this.childLanes = NoLanes;
24722 this.alternate = null;
24723
24724 {
24725 // Note: The following is done to avoid a v8 performance cliff.
24726 //
24727 // Initializing the fields below to smis and later updating them with
24728 // double values will cause Fibers to end up having separate shapes.
24729 // This behavior/bug has something to do with Object.preventExtension().
24730 // Fortunately this only impacts DEV builds.
24731 // Unfortunately it makes React unusably slow for some applications.
24732 // To work around this, initialize the fields below with doubles.
24733 //
24734 // Learn more about this here:
24735 // https://github.com/facebook/react/issues/14365
24736 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
24737 this.actualDuration = Number.NaN;
24738 this.actualStartTime = Number.NaN;
24739 this.selfBaseDuration = Number.NaN;
24740 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
24741 // This won't trigger the performance cliff mentioned above,
24742 // and it simplifies other profiler code (including DevTools).
24743
24744 this.actualDuration = 0;
24745 this.actualStartTime = -1;
24746 this.selfBaseDuration = 0;
24747 this.treeBaseDuration = 0;
24748 }
24749
24750 {
24751 // This isn't directly used but is handy for debugging internals:
24752 this._debugID = debugCounter++;
24753 this._debugSource = null;
24754 this._debugOwner = null;
24755 this._debugNeedsRemount = false;
24756 this._debugHookTypes = null;
24757
24758 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
24759 Object.preventExtensions(this);
24760 }
24761 }
24762 } // This is a constructor function, rather than a POJO constructor, still
24763 // please ensure we do the following:
24764 // 1) Nobody should add any instance methods on this. Instance methods can be
24765 // more difficult to predict when they get optimized and they are almost
24766 // never inlined properly in static compilers.
24767 // 2) Nobody should rely on `instanceof Fiber` for type testing. We should
24768 // always know when it is a fiber.
24769 // 3) We might want to experiment with using numeric keys since they are easier
24770 // to optimize in a non-JIT environment.
24771 // 4) We can easily go from a constructor to a createFiber object literal if that
24772 // is faster.
24773 // 5) It should be easy to port this to a C struct and keep a C implementation
24774 // compatible.
24775
24776
24777 var createFiber = function (tag, pendingProps, key, mode) {
24778 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
24779 return new FiberNode(tag, pendingProps, key, mode);
24780 };
24781
24782 function shouldConstruct$1(Component) {
24783 var prototype = Component.prototype;
24784 return !!(prototype && prototype.isReactComponent);
24785 }
24786
24787 function isSimpleFunctionComponent(type) {
24788 return typeof type === 'function' && !shouldConstruct$1(type) && type.defaultProps === undefined;
24789 }
24790 function resolveLazyComponentTag(Component) {
24791 if (typeof Component === 'function') {
24792 return shouldConstruct$1(Component) ? ClassComponent : FunctionComponent;
24793 } else if (Component !== undefined && Component !== null) {
24794 var $$typeof = Component.$$typeof;
24795
24796 if ($$typeof === REACT_FORWARD_REF_TYPE) {
24797 return ForwardRef;
24798 }
24799
24800 if ($$typeof === REACT_MEMO_TYPE) {
24801 return MemoComponent;
24802 }
24803 }
24804
24805 return IndeterminateComponent;
24806 } // This is used to create an alternate fiber to do work on.
24807
24808 function createWorkInProgress(current, pendingProps) {
24809 var workInProgress = current.alternate;
24810
24811 if (workInProgress === null) {
24812 // We use a double buffering pooling technique because we know that we'll
24813 // only ever need at most two versions of a tree. We pool the "other" unused
24814 // node that we're free to reuse. This is lazily created to avoid allocating
24815 // extra objects for things that are never updated. It also allow us to
24816 // reclaim the extra memory if needed.
24817 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
24818 workInProgress.elementType = current.elementType;
24819 workInProgress.type = current.type;
24820 workInProgress.stateNode = current.stateNode;
24821
24822 {
24823 // DEV-only fields
24824 workInProgress._debugID = current._debugID;
24825 workInProgress._debugSource = current._debugSource;
24826 workInProgress._debugOwner = current._debugOwner;
24827 workInProgress._debugHookTypes = current._debugHookTypes;
24828 }
24829
24830 workInProgress.alternate = current;
24831 current.alternate = workInProgress;
24832 } else {
24833 workInProgress.pendingProps = pendingProps; // Needed because Blocks store data on type.
24834
24835 workInProgress.type = current.type; // We already have an alternate.
24836 // Reset the effect tag.
24837
24838 workInProgress.flags = NoFlags; // The effect list is no longer valid.
24839
24840 workInProgress.nextEffect = null;
24841 workInProgress.firstEffect = null;
24842 workInProgress.lastEffect = null;
24843
24844 {
24845 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
24846 // This prevents time from endlessly accumulating in new commits.
24847 // This has the downside of resetting values for different priority renders,
24848 // But works for yielding (the common case) and should support resuming.
24849 workInProgress.actualDuration = 0;
24850 workInProgress.actualStartTime = -1;
24851 }
24852 }
24853
24854 workInProgress.childLanes = current.childLanes;
24855 workInProgress.lanes = current.lanes;
24856 workInProgress.child = current.child;
24857 workInProgress.memoizedProps = current.memoizedProps;
24858 workInProgress.memoizedState = current.memoizedState;
24859 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
24860 // it cannot be shared with the current fiber.
24861
24862 var currentDependencies = current.dependencies;
24863 workInProgress.dependencies = currentDependencies === null ? null : {
24864 lanes: currentDependencies.lanes,
24865 firstContext: currentDependencies.firstContext
24866 }; // These will be overridden during the parent's reconciliation
24867
24868 workInProgress.sibling = current.sibling;
24869 workInProgress.index = current.index;
24870 workInProgress.ref = current.ref;
24871
24872 {
24873 workInProgress.selfBaseDuration = current.selfBaseDuration;
24874 workInProgress.treeBaseDuration = current.treeBaseDuration;
24875 }
24876
24877 {
24878 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
24879
24880 switch (workInProgress.tag) {
24881 case IndeterminateComponent:
24882 case FunctionComponent:
24883 case SimpleMemoComponent:
24884 workInProgress.type = resolveFunctionForHotReloading(current.type);
24885 break;
24886
24887 case ClassComponent:
24888 workInProgress.type = resolveClassForHotReloading(current.type);
24889 break;
24890
24891 case ForwardRef:
24892 workInProgress.type = resolveForwardRefForHotReloading(current.type);
24893 break;
24894 }
24895 }
24896
24897 return workInProgress;
24898 } // Used to reuse a Fiber for a second pass.
24899
24900 function resetWorkInProgress(workInProgress, renderLanes) {
24901 // This resets the Fiber to what createFiber or createWorkInProgress would
24902 // have set the values to before during the first pass. Ideally this wouldn't
24903 // be necessary but unfortunately many code paths reads from the workInProgress
24904 // when they should be reading from current and writing to workInProgress.
24905 // We assume pendingProps, index, key, ref, return are still untouched to
24906 // avoid doing another reconciliation.
24907 // Reset the effect tag but keep any Placement tags, since that's something
24908 // that child fiber is setting, not the reconciliation.
24909 workInProgress.flags &= Placement; // The effect list is no longer valid.
24910
24911 workInProgress.nextEffect = null;
24912 workInProgress.firstEffect = null;
24913 workInProgress.lastEffect = null;
24914 var current = workInProgress.alternate;
24915
24916 if (current === null) {
24917 // Reset to createFiber's initial values.
24918 workInProgress.childLanes = NoLanes;
24919 workInProgress.lanes = renderLanes;
24920 workInProgress.child = null;
24921 workInProgress.memoizedProps = null;
24922 workInProgress.memoizedState = null;
24923 workInProgress.updateQueue = null;
24924 workInProgress.dependencies = null;
24925 workInProgress.stateNode = null;
24926
24927 {
24928 // Note: We don't reset the actualTime counts. It's useful to accumulate
24929 // actual time across multiple render passes.
24930 workInProgress.selfBaseDuration = 0;
24931 workInProgress.treeBaseDuration = 0;
24932 }
24933 } else {
24934 // Reset to the cloned values that createWorkInProgress would've.
24935 workInProgress.childLanes = current.childLanes;
24936 workInProgress.lanes = current.lanes;
24937 workInProgress.child = current.child;
24938 workInProgress.memoizedProps = current.memoizedProps;
24939 workInProgress.memoizedState = current.memoizedState;
24940 workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type.
24941
24942 workInProgress.type = current.type; // Clone the dependencies object. This is mutated during the render phase, so
24943 // it cannot be shared with the current fiber.
24944
24945 var currentDependencies = current.dependencies;
24946 workInProgress.dependencies = currentDependencies === null ? null : {
24947 lanes: currentDependencies.lanes,
24948 firstContext: currentDependencies.firstContext
24949 };
24950
24951 {
24952 // Note: We don't reset the actualTime counts. It's useful to accumulate
24953 // actual time across multiple render passes.
24954 workInProgress.selfBaseDuration = current.selfBaseDuration;
24955 workInProgress.treeBaseDuration = current.treeBaseDuration;
24956 }
24957 }
24958
24959 return workInProgress;
24960 }
24961 function createHostRootFiber(tag) {
24962 var mode;
24963
24964 if (tag === ConcurrentRoot) {
24965 mode = ConcurrentMode | BlockingMode | StrictMode;
24966 } else if (tag === BlockingRoot) {
24967 mode = BlockingMode | StrictMode;
24968 } else {
24969 mode = NoMode;
24970 }
24971
24972 if ( isDevToolsPresent) {
24973 // Always collect profile timings when DevTools are present.
24974 // This enables DevTools to start capturing timing at any point–
24975 // Without some nodes in the tree having empty base times.
24976 mode |= ProfileMode;
24977 }
24978
24979 return createFiber(HostRoot, null, null, mode);
24980 }
24981 function createFiberFromTypeAndProps(type, // React$ElementType
24982 key, pendingProps, owner, mode, lanes) {
24983 var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
24984
24985 var resolvedType = type;
24986
24987 if (typeof type === 'function') {
24988 if (shouldConstruct$1(type)) {
24989 fiberTag = ClassComponent;
24990
24991 {
24992 resolvedType = resolveClassForHotReloading(resolvedType);
24993 }
24994 } else {
24995 {
24996 resolvedType = resolveFunctionForHotReloading(resolvedType);
24997 }
24998 }
24999 } else if (typeof type === 'string') {
25000 fiberTag = HostComponent;
25001 } else {
25002 getTag: switch (type) {
25003 case REACT_FRAGMENT_TYPE:
25004 return createFiberFromFragment(pendingProps.children, mode, lanes, key);
25005
25006 case REACT_DEBUG_TRACING_MODE_TYPE:
25007 fiberTag = Mode;
25008 mode |= DebugTracingMode;
25009 break;
25010
25011 case REACT_STRICT_MODE_TYPE:
25012 fiberTag = Mode;
25013 mode |= StrictMode;
25014 break;
25015
25016 case REACT_PROFILER_TYPE:
25017 return createFiberFromProfiler(pendingProps, mode, lanes, key);
25018
25019 case REACT_SUSPENSE_TYPE:
25020 return createFiberFromSuspense(pendingProps, mode, lanes, key);
25021
25022 case REACT_SUSPENSE_LIST_TYPE:
25023 return createFiberFromSuspenseList(pendingProps, mode, lanes, key);
25024
25025 case REACT_OFFSCREEN_TYPE:
25026 return createFiberFromOffscreen(pendingProps, mode, lanes, key);
25027
25028 case REACT_LEGACY_HIDDEN_TYPE:
25029 return createFiberFromLegacyHidden(pendingProps, mode, lanes, key);
25030
25031 case REACT_SCOPE_TYPE:
25032
25033 // eslint-disable-next-line no-fallthrough
25034
25035 default:
25036 {
25037 if (typeof type === 'object' && type !== null) {
25038 switch (type.$$typeof) {
25039 case REACT_PROVIDER_TYPE:
25040 fiberTag = ContextProvider;
25041 break getTag;
25042
25043 case REACT_CONTEXT_TYPE:
25044 // This is a consumer
25045 fiberTag = ContextConsumer;
25046 break getTag;
25047
25048 case REACT_FORWARD_REF_TYPE:
25049 fiberTag = ForwardRef;
25050
25051 {
25052 resolvedType = resolveForwardRefForHotReloading(resolvedType);
25053 }
25054
25055 break getTag;
25056
25057 case REACT_MEMO_TYPE:
25058 fiberTag = MemoComponent;
25059 break getTag;
25060
25061 case REACT_LAZY_TYPE:
25062 fiberTag = LazyComponent;
25063 resolvedType = null;
25064 break getTag;
25065
25066 case REACT_BLOCK_TYPE:
25067 fiberTag = Block;
25068 break getTag;
25069 }
25070 }
25071
25072 var info = '';
25073
25074 {
25075 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
25076 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.';
25077 }
25078
25079 var ownerName = owner ? getComponentName(owner.type) : null;
25080
25081 if (ownerName) {
25082 info += '\n\nCheck the render method of `' + ownerName + '`.';
25083 }
25084 }
25085
25086 {
25087 {
25088 throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + (type == null ? type : typeof type) + "." + info );
25089 }
25090 }
25091 }
25092 }
25093 }
25094
25095 var fiber = createFiber(fiberTag, pendingProps, key, mode);
25096 fiber.elementType = type;
25097 fiber.type = resolvedType;
25098 fiber.lanes = lanes;
25099
25100 {
25101 fiber._debugOwner = owner;
25102 }
25103
25104 return fiber;
25105 }
25106 function createFiberFromElement(element, mode, lanes) {
25107 var owner = null;
25108
25109 {
25110 owner = element._owner;
25111 }
25112
25113 var type = element.type;
25114 var key = element.key;
25115 var pendingProps = element.props;
25116 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, lanes);
25117
25118 {
25119 fiber._debugSource = element._source;
25120 fiber._debugOwner = element._owner;
25121 }
25122
25123 return fiber;
25124 }
25125 function createFiberFromFragment(elements, mode, lanes, key) {
25126 var fiber = createFiber(Fragment, elements, key, mode);
25127 fiber.lanes = lanes;
25128 return fiber;
25129 }
25130
25131 function createFiberFromProfiler(pendingProps, mode, lanes, key) {
25132 {
25133 if (typeof pendingProps.id !== 'string') {
25134 error('Profiler must specify an "id" as a prop');
25135 }
25136 }
25137
25138 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); // TODO: The Profiler fiber shouldn't have a type. It has a tag.
25139
25140 fiber.elementType = REACT_PROFILER_TYPE;
25141 fiber.type = REACT_PROFILER_TYPE;
25142 fiber.lanes = lanes;
25143
25144 {
25145 fiber.stateNode = {
25146 effectDuration: 0,
25147 passiveEffectDuration: 0
25148 };
25149 }
25150
25151 return fiber;
25152 }
25153
25154 function createFiberFromSuspense(pendingProps, mode, lanes, key) {
25155 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
25156 // This needs to be fixed in getComponentName so that it relies on the tag
25157 // instead.
25158
25159 fiber.type = REACT_SUSPENSE_TYPE;
25160 fiber.elementType = REACT_SUSPENSE_TYPE;
25161 fiber.lanes = lanes;
25162 return fiber;
25163 }
25164 function createFiberFromSuspenseList(pendingProps, mode, lanes, key) {
25165 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
25166
25167 {
25168 // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag.
25169 // This needs to be fixed in getComponentName so that it relies on the tag
25170 // instead.
25171 fiber.type = REACT_SUSPENSE_LIST_TYPE;
25172 }
25173
25174 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
25175 fiber.lanes = lanes;
25176 return fiber;
25177 }
25178 function createFiberFromOffscreen(pendingProps, mode, lanes, key) {
25179 var fiber = createFiber(OffscreenComponent, pendingProps, key, mode); // TODO: The OffscreenComponent fiber shouldn't have a type. It has a tag.
25180 // This needs to be fixed in getComponentName so that it relies on the tag
25181 // instead.
25182
25183 {
25184 fiber.type = REACT_OFFSCREEN_TYPE;
25185 }
25186
25187 fiber.elementType = REACT_OFFSCREEN_TYPE;
25188 fiber.lanes = lanes;
25189 return fiber;
25190 }
25191 function createFiberFromLegacyHidden(pendingProps, mode, lanes, key) {
25192 var fiber = createFiber(LegacyHiddenComponent, pendingProps, key, mode); // TODO: The LegacyHidden fiber shouldn't have a type. It has a tag.
25193 // This needs to be fixed in getComponentName so that it relies on the tag
25194 // instead.
25195
25196 {
25197 fiber.type = REACT_LEGACY_HIDDEN_TYPE;
25198 }
25199
25200 fiber.elementType = REACT_LEGACY_HIDDEN_TYPE;
25201 fiber.lanes = lanes;
25202 return fiber;
25203 }
25204 function createFiberFromText(content, mode, lanes) {
25205 var fiber = createFiber(HostText, content, null, mode);
25206 fiber.lanes = lanes;
25207 return fiber;
25208 }
25209 function createFiberFromHostInstanceForDeletion() {
25210 var fiber = createFiber(HostComponent, null, null, NoMode); // TODO: These should not need a type.
25211
25212 fiber.elementType = 'DELETED';
25213 fiber.type = 'DELETED';
25214 return fiber;
25215 }
25216 function createFiberFromPortal(portal, mode, lanes) {
25217 var pendingProps = portal.children !== null ? portal.children : [];
25218 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
25219 fiber.lanes = lanes;
25220 fiber.stateNode = {
25221 containerInfo: portal.containerInfo,
25222 pendingChildren: null,
25223 // Used by persistent updates
25224 implementation: portal.implementation
25225 };
25226 return fiber;
25227 } // Used for stashing WIP properties to replay failed work in DEV.
25228
25229 function assignFiberPropertiesInDEV(target, source) {
25230 if (target === null) {
25231 // This Fiber's initial properties will always be overwritten.
25232 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
25233 target = createFiber(IndeterminateComponent, null, null, NoMode);
25234 } // This is intentionally written as a list of all properties.
25235 // We tried to use Object.assign() instead but this is called in
25236 // the hottest path, and Object.assign() was too slow:
25237 // https://github.com/facebook/react/issues/12502
25238 // This code is DEV-only so size is not a concern.
25239
25240
25241 target.tag = source.tag;
25242 target.key = source.key;
25243 target.elementType = source.elementType;
25244 target.type = source.type;
25245 target.stateNode = source.stateNode;
25246 target.return = source.return;
25247 target.child = source.child;
25248 target.sibling = source.sibling;
25249 target.index = source.index;
25250 target.ref = source.ref;
25251 target.pendingProps = source.pendingProps;
25252 target.memoizedProps = source.memoizedProps;
25253 target.updateQueue = source.updateQueue;
25254 target.memoizedState = source.memoizedState;
25255 target.dependencies = source.dependencies;
25256 target.mode = source.mode;
25257 target.flags = source.flags;
25258 target.nextEffect = source.nextEffect;
25259 target.firstEffect = source.firstEffect;
25260 target.lastEffect = source.lastEffect;
25261 target.lanes = source.lanes;
25262 target.childLanes = source.childLanes;
25263 target.alternate = source.alternate;
25264
25265 {
25266 target.actualDuration = source.actualDuration;
25267 target.actualStartTime = source.actualStartTime;
25268 target.selfBaseDuration = source.selfBaseDuration;
25269 target.treeBaseDuration = source.treeBaseDuration;
25270 }
25271
25272 target._debugID = source._debugID;
25273 target._debugSource = source._debugSource;
25274 target._debugOwner = source._debugOwner;
25275 target._debugNeedsRemount = source._debugNeedsRemount;
25276 target._debugHookTypes = source._debugHookTypes;
25277 return target;
25278 }
25279
25280 function FiberRootNode(containerInfo, tag, hydrate) {
25281 this.tag = tag;
25282 this.containerInfo = containerInfo;
25283 this.pendingChildren = null;
25284 this.current = null;
25285 this.pingCache = null;
25286 this.finishedWork = null;
25287 this.timeoutHandle = noTimeout;
25288 this.context = null;
25289 this.pendingContext = null;
25290 this.hydrate = hydrate;
25291 this.callbackNode = null;
25292 this.callbackPriority = NoLanePriority;
25293 this.eventTimes = createLaneMap(NoLanes);
25294 this.expirationTimes = createLaneMap(NoTimestamp);
25295 this.pendingLanes = NoLanes;
25296 this.suspendedLanes = NoLanes;
25297 this.pingedLanes = NoLanes;
25298 this.expiredLanes = NoLanes;
25299 this.mutableReadLanes = NoLanes;
25300 this.finishedLanes = NoLanes;
25301 this.entangledLanes = NoLanes;
25302 this.entanglements = createLaneMap(NoLanes);
25303
25304 {
25305 this.mutableSourceEagerHydrationData = null;
25306 }
25307
25308 {
25309 this.interactionThreadID = unstable_getThreadID();
25310 this.memoizedInteractions = new Set();
25311 this.pendingInteractionMap = new Map();
25312 }
25313
25314 {
25315 switch (tag) {
25316 case BlockingRoot:
25317 this._debugRootType = 'createBlockingRoot()';
25318 break;
25319
25320 case ConcurrentRoot:
25321 this._debugRootType = 'createRoot()';
25322 break;
25323
25324 case LegacyRoot:
25325 this._debugRootType = 'createLegacyRoot()';
25326 break;
25327 }
25328 }
25329 }
25330
25331 function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) {
25332 var root = new FiberRootNode(containerInfo, tag, hydrate);
25333 // stateNode is any.
25334
25335
25336 var uninitializedFiber = createHostRootFiber(tag);
25337 root.current = uninitializedFiber;
25338 uninitializedFiber.stateNode = root;
25339 initializeUpdateQueue(uninitializedFiber);
25340 return root;
25341 }
25342
25343 // This ensures that the version used for server rendering matches the one
25344 // that is eventually read during hydration.
25345 // If they don't match there's a potential tear and a full deopt render is required.
25346
25347 function registerMutableSourceForHydration(root, mutableSource) {
25348 var getVersion = mutableSource._getVersion;
25349 var version = getVersion(mutableSource._source); // TODO Clear this data once all pending hydration work is finished.
25350 // Retaining it forever may interfere with GC.
25351
25352 if (root.mutableSourceEagerHydrationData == null) {
25353 root.mutableSourceEagerHydrationData = [mutableSource, version];
25354 } else {
25355 root.mutableSourceEagerHydrationData.push(mutableSource, version);
25356 }
25357 }
25358
25359 function createPortal(children, containerInfo, // TODO: figure out the API for cross-renderer implementation.
25360 implementation) {
25361 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
25362 return {
25363 // This tag allow us to uniquely identify this as a React Portal
25364 $$typeof: REACT_PORTAL_TYPE,
25365 key: key == null ? null : '' + key,
25366 children: children,
25367 containerInfo: containerInfo,
25368 implementation: implementation
25369 };
25370 }
25371
25372 var didWarnAboutNestedUpdates;
25373 var didWarnAboutFindNodeInStrictMode;
25374
25375 {
25376 didWarnAboutNestedUpdates = false;
25377 didWarnAboutFindNodeInStrictMode = {};
25378 }
25379
25380 function getContextForSubtree(parentComponent) {
25381 if (!parentComponent) {
25382 return emptyContextObject;
25383 }
25384
25385 var fiber = get(parentComponent);
25386 var parentContext = findCurrentUnmaskedContext(fiber);
25387
25388 if (fiber.tag === ClassComponent) {
25389 var Component = fiber.type;
25390
25391 if (isContextProvider(Component)) {
25392 return processChildContext(fiber, Component, parentContext);
25393 }
25394 }
25395
25396 return parentContext;
25397 }
25398
25399 function findHostInstanceWithWarning(component, methodName) {
25400 {
25401 var fiber = get(component);
25402
25403 if (fiber === undefined) {
25404 if (typeof component.render === 'function') {
25405 {
25406 {
25407 throw Error( "Unable to find node on an unmounted component." );
25408 }
25409 }
25410 } else {
25411 {
25412 {
25413 throw Error( "Argument appears to not be a ReactComponent. Keys: " + Object.keys(component) );
25414 }
25415 }
25416 }
25417 }
25418
25419 var hostFiber = findCurrentHostFiber(fiber);
25420
25421 if (hostFiber === null) {
25422 return null;
25423 }
25424
25425 if (hostFiber.mode & StrictMode) {
25426 var componentName = getComponentName(fiber.type) || 'Component';
25427
25428 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
25429 didWarnAboutFindNodeInStrictMode[componentName] = true;
25430 var previousFiber = current;
25431
25432 try {
25433 setCurrentFiber(hostFiber);
25434
25435 if (fiber.mode & StrictMode) {
25436 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);
25437 } else {
25438 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);
25439 }
25440 } finally {
25441 // Ideally this should reset to previous but this shouldn't be called in
25442 // render and there's another warning for that anyway.
25443 if (previousFiber) {
25444 setCurrentFiber(previousFiber);
25445 } else {
25446 resetCurrentFiber();
25447 }
25448 }
25449 }
25450 }
25451
25452 return hostFiber.stateNode;
25453 }
25454 }
25455
25456 function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) {
25457 return createFiberRoot(containerInfo, tag, hydrate);
25458 }
25459 function updateContainer(element, container, parentComponent, callback) {
25460 {
25461 onScheduleRoot(container, element);
25462 }
25463
25464 var current$1 = container.current;
25465 var eventTime = requestEventTime();
25466
25467 {
25468 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
25469 if ('undefined' !== typeof jest) {
25470 warnIfUnmockedScheduler(current$1);
25471 warnIfNotScopedWithMatchingAct(current$1);
25472 }
25473 }
25474
25475 var lane = requestUpdateLane(current$1);
25476
25477 var context = getContextForSubtree(parentComponent);
25478
25479 if (container.context === null) {
25480 container.context = context;
25481 } else {
25482 container.pendingContext = context;
25483 }
25484
25485 {
25486 if (isRendering && current !== null && !didWarnAboutNestedUpdates) {
25487 didWarnAboutNestedUpdates = true;
25488
25489 error('Render methods should be a pure function of props and state; ' + 'triggering nested component updates from render is not allowed. ' + 'If necessary, trigger nested updates in componentDidUpdate.\n\n' + 'Check the render method of %s.', getComponentName(current.type) || 'Unknown');
25490 }
25491 }
25492
25493 var update = createUpdate(eventTime, lane); // Caution: React DevTools currently depends on this property
25494 // being called "element".
25495
25496 update.payload = {
25497 element: element
25498 };
25499 callback = callback === undefined ? null : callback;
25500
25501 if (callback !== null) {
25502 {
25503 if (typeof callback !== 'function') {
25504 error('render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
25505 }
25506 }
25507
25508 update.callback = callback;
25509 }
25510
25511 enqueueUpdate(current$1, update);
25512 scheduleUpdateOnFiber(current$1, lane, eventTime);
25513 return lane;
25514 }
25515 function getPublicRootInstance(container) {
25516 var containerFiber = container.current;
25517
25518 if (!containerFiber.child) {
25519 return null;
25520 }
25521
25522 switch (containerFiber.child.tag) {
25523 case HostComponent:
25524 return getPublicInstance(containerFiber.child.stateNode);
25525
25526 default:
25527 return containerFiber.child.stateNode;
25528 }
25529 }
25530
25531 function markRetryLaneImpl(fiber, retryLane) {
25532 var suspenseState = fiber.memoizedState;
25533
25534 if (suspenseState !== null && suspenseState.dehydrated !== null) {
25535 suspenseState.retryLane = higherPriorityLane(suspenseState.retryLane, retryLane);
25536 }
25537 } // Increases the priority of thennables when they resolve within this boundary.
25538
25539
25540 function markRetryLaneIfNotHydrated(fiber, retryLane) {
25541 markRetryLaneImpl(fiber, retryLane);
25542 var alternate = fiber.alternate;
25543
25544 if (alternate) {
25545 markRetryLaneImpl(alternate, retryLane);
25546 }
25547 }
25548
25549 function attemptUserBlockingHydration$1(fiber) {
25550 if (fiber.tag !== SuspenseComponent) {
25551 // We ignore HostRoots here because we can't increase
25552 // their priority and they should not suspend on I/O,
25553 // since you have to wrap anything that might suspend in
25554 // Suspense.
25555 return;
25556 }
25557
25558 var eventTime = requestEventTime();
25559 var lane = InputDiscreteHydrationLane;
25560 scheduleUpdateOnFiber(fiber, lane, eventTime);
25561 markRetryLaneIfNotHydrated(fiber, lane);
25562 }
25563 function attemptContinuousHydration$1(fiber) {
25564 if (fiber.tag !== SuspenseComponent) {
25565 // We ignore HostRoots here because we can't increase
25566 // their priority and they should not suspend on I/O,
25567 // since you have to wrap anything that might suspend in
25568 // Suspense.
25569 return;
25570 }
25571
25572 var eventTime = requestEventTime();
25573 var lane = SelectiveHydrationLane;
25574 scheduleUpdateOnFiber(fiber, lane, eventTime);
25575 markRetryLaneIfNotHydrated(fiber, lane);
25576 }
25577 function attemptHydrationAtCurrentPriority$1(fiber) {
25578 if (fiber.tag !== SuspenseComponent) {
25579 // We ignore HostRoots here because we can't increase
25580 // their priority other than synchronously flush it.
25581 return;
25582 }
25583
25584 var eventTime = requestEventTime();
25585 var lane = requestUpdateLane(fiber);
25586 scheduleUpdateOnFiber(fiber, lane, eventTime);
25587 markRetryLaneIfNotHydrated(fiber, lane);
25588 }
25589 function runWithPriority$2(priority, fn) {
25590
25591 try {
25592 setCurrentUpdateLanePriority(priority);
25593 return fn();
25594 } finally {
25595 }
25596 }
25597 function findHostInstanceWithNoPortals(fiber) {
25598 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
25599
25600 if (hostFiber === null) {
25601 return null;
25602 }
25603
25604 if (hostFiber.tag === FundamentalComponent) {
25605 return hostFiber.stateNode.instance;
25606 }
25607
25608 return hostFiber.stateNode;
25609 }
25610
25611 var shouldSuspendImpl = function (fiber) {
25612 return false;
25613 };
25614
25615 function shouldSuspend(fiber) {
25616 return shouldSuspendImpl(fiber);
25617 }
25618 var overrideHookState = null;
25619 var overrideHookStateDeletePath = null;
25620 var overrideHookStateRenamePath = null;
25621 var overrideProps = null;
25622 var overridePropsDeletePath = null;
25623 var overridePropsRenamePath = null;
25624 var scheduleUpdate = null;
25625 var setSuspenseHandler = null;
25626
25627 {
25628 var copyWithDeleteImpl = function (obj, path, index) {
25629 var key = path[index];
25630 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
25631
25632 if (index + 1 === path.length) {
25633 if (Array.isArray(updated)) {
25634 updated.splice(key, 1);
25635 } else {
25636 delete updated[key];
25637 }
25638
25639 return updated;
25640 } // $FlowFixMe number or string is fine here
25641
25642
25643 updated[key] = copyWithDeleteImpl(obj[key], path, index + 1);
25644 return updated;
25645 };
25646
25647 var copyWithDelete = function (obj, path) {
25648 return copyWithDeleteImpl(obj, path, 0);
25649 };
25650
25651 var copyWithRenameImpl = function (obj, oldPath, newPath, index) {
25652 var oldKey = oldPath[index];
25653 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
25654
25655 if (index + 1 === oldPath.length) {
25656 var newKey = newPath[index]; // $FlowFixMe number or string is fine here
25657
25658 updated[newKey] = updated[oldKey];
25659
25660 if (Array.isArray(updated)) {
25661 updated.splice(oldKey, 1);
25662 } else {
25663 delete updated[oldKey];
25664 }
25665 } else {
25666 // $FlowFixMe number or string is fine here
25667 updated[oldKey] = copyWithRenameImpl( // $FlowFixMe number or string is fine here
25668 obj[oldKey], oldPath, newPath, index + 1);
25669 }
25670
25671 return updated;
25672 };
25673
25674 var copyWithRename = function (obj, oldPath, newPath) {
25675 if (oldPath.length !== newPath.length) {
25676 warn('copyWithRename() expects paths of the same length');
25677
25678 return;
25679 } else {
25680 for (var i = 0; i < newPath.length - 1; i++) {
25681 if (oldPath[i] !== newPath[i]) {
25682 warn('copyWithRename() expects paths to be the same except for the deepest key');
25683
25684 return;
25685 }
25686 }
25687 }
25688
25689 return copyWithRenameImpl(obj, oldPath, newPath, 0);
25690 };
25691
25692 var copyWithSetImpl = function (obj, path, index, value) {
25693 if (index >= path.length) {
25694 return value;
25695 }
25696
25697 var key = path[index];
25698 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj); // $FlowFixMe number or string is fine here
25699
25700 updated[key] = copyWithSetImpl(obj[key], path, index + 1, value);
25701 return updated;
25702 };
25703
25704 var copyWithSet = function (obj, path, value) {
25705 return copyWithSetImpl(obj, path, 0, value);
25706 };
25707
25708 var findHook = function (fiber, id) {
25709 // For now, the "id" of stateful hooks is just the stateful hook index.
25710 // This may change in the future with e.g. nested hooks.
25711 var currentHook = fiber.memoizedState;
25712
25713 while (currentHook !== null && id > 0) {
25714 currentHook = currentHook.next;
25715 id--;
25716 }
25717
25718 return currentHook;
25719 }; // Support DevTools editable values for useState and useReducer.
25720
25721
25722 overrideHookState = function (fiber, id, path, value) {
25723 var hook = findHook(fiber, id);
25724
25725 if (hook !== null) {
25726 var newState = copyWithSet(hook.memoizedState, path, value);
25727 hook.memoizedState = newState;
25728 hook.baseState = newState; // We aren't actually adding an update to the queue,
25729 // because there is no update we can add for useReducer hooks that won't trigger an error.
25730 // (There's no appropriate action type for DevTools overrides.)
25731 // As a result though, React will see the scheduled update as a noop and bailout.
25732 // Shallow cloning props works as a workaround for now to bypass the bailout check.
25733
25734 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
25735 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
25736 }
25737 };
25738
25739 overrideHookStateDeletePath = function (fiber, id, path) {
25740 var hook = findHook(fiber, id);
25741
25742 if (hook !== null) {
25743 var newState = copyWithDelete(hook.memoizedState, path);
25744 hook.memoizedState = newState;
25745 hook.baseState = newState; // We aren't actually adding an update to the queue,
25746 // because there is no update we can add for useReducer hooks that won't trigger an error.
25747 // (There's no appropriate action type for DevTools overrides.)
25748 // As a result though, React will see the scheduled update as a noop and bailout.
25749 // Shallow cloning props works as a workaround for now to bypass the bailout check.
25750
25751 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
25752 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
25753 }
25754 };
25755
25756 overrideHookStateRenamePath = function (fiber, id, oldPath, newPath) {
25757 var hook = findHook(fiber, id);
25758
25759 if (hook !== null) {
25760 var newState = copyWithRename(hook.memoizedState, oldPath, newPath);
25761 hook.memoizedState = newState;
25762 hook.baseState = newState; // We aren't actually adding an update to the queue,
25763 // because there is no update we can add for useReducer hooks that won't trigger an error.
25764 // (There's no appropriate action type for DevTools overrides.)
25765 // As a result though, React will see the scheduled update as a noop and bailout.
25766 // Shallow cloning props works as a workaround for now to bypass the bailout check.
25767
25768 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
25769 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
25770 }
25771 }; // Support DevTools props for function components, forwardRef, memo, host components, etc.
25772
25773
25774 overrideProps = function (fiber, path, value) {
25775 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
25776
25777 if (fiber.alternate) {
25778 fiber.alternate.pendingProps = fiber.pendingProps;
25779 }
25780
25781 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
25782 };
25783
25784 overridePropsDeletePath = function (fiber, path) {
25785 fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path);
25786
25787 if (fiber.alternate) {
25788 fiber.alternate.pendingProps = fiber.pendingProps;
25789 }
25790
25791 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
25792 };
25793
25794 overridePropsRenamePath = function (fiber, oldPath, newPath) {
25795 fiber.pendingProps = copyWithRename(fiber.memoizedProps, oldPath, newPath);
25796
25797 if (fiber.alternate) {
25798 fiber.alternate.pendingProps = fiber.pendingProps;
25799 }
25800
25801 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
25802 };
25803
25804 scheduleUpdate = function (fiber) {
25805 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
25806 };
25807
25808 setSuspenseHandler = function (newShouldSuspendImpl) {
25809 shouldSuspendImpl = newShouldSuspendImpl;
25810 };
25811 }
25812
25813 function findHostInstanceByFiber(fiber) {
25814 var hostFiber = findCurrentHostFiber(fiber);
25815
25816 if (hostFiber === null) {
25817 return null;
25818 }
25819
25820 return hostFiber.stateNode;
25821 }
25822
25823 function emptyFindFiberByHostInstance(instance) {
25824 return null;
25825 }
25826
25827 function getCurrentFiberForDevTools() {
25828 return current;
25829 }
25830
25831 function injectIntoDevTools(devToolsConfig) {
25832 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
25833 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
25834 return injectInternals({
25835 bundleType: devToolsConfig.bundleType,
25836 version: devToolsConfig.version,
25837 rendererPackageName: devToolsConfig.rendererPackageName,
25838 rendererConfig: devToolsConfig.rendererConfig,
25839 overrideHookState: overrideHookState,
25840 overrideHookStateDeletePath: overrideHookStateDeletePath,
25841 overrideHookStateRenamePath: overrideHookStateRenamePath,
25842 overrideProps: overrideProps,
25843 overridePropsDeletePath: overridePropsDeletePath,
25844 overridePropsRenamePath: overridePropsRenamePath,
25845 setSuspenseHandler: setSuspenseHandler,
25846 scheduleUpdate: scheduleUpdate,
25847 currentDispatcherRef: ReactCurrentDispatcher,
25848 findHostInstanceByFiber: findHostInstanceByFiber,
25849 findFiberByHostInstance: findFiberByHostInstance || emptyFindFiberByHostInstance,
25850 // React Refresh
25851 findHostInstancesForRefresh: findHostInstancesForRefresh ,
25852 scheduleRefresh: scheduleRefresh ,
25853 scheduleRoot: scheduleRoot ,
25854 setRefreshHandler: setRefreshHandler ,
25855 // Enables DevTools to append owner stacks to error messages in DEV mode.
25856 getCurrentFiber: getCurrentFiberForDevTools
25857 });
25858 }
25859
25860 function ReactDOMRoot(container, options) {
25861 this._internalRoot = createRootImpl(container, ConcurrentRoot, options);
25862 }
25863
25864 function ReactDOMBlockingRoot(container, tag, options) {
25865 this._internalRoot = createRootImpl(container, tag, options);
25866 }
25867
25868 ReactDOMRoot.prototype.render = ReactDOMBlockingRoot.prototype.render = function (children) {
25869 var root = this._internalRoot;
25870
25871 {
25872 if (typeof arguments[1] === 'function') {
25873 error('render(...): does not support the second callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().');
25874 }
25875
25876 var container = root.containerInfo;
25877
25878 if (container.nodeType !== COMMENT_NODE) {
25879 var hostInstance = findHostInstanceWithNoPortals(root.current);
25880
25881 if (hostInstance) {
25882 if (hostInstance.parentNode !== container) {
25883 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.");
25884 }
25885 }
25886 }
25887 }
25888
25889 updateContainer(children, root, null, null);
25890 };
25891
25892 ReactDOMRoot.prototype.unmount = ReactDOMBlockingRoot.prototype.unmount = function () {
25893 {
25894 if (typeof arguments[0] === 'function') {
25895 error('unmount(...): does not support a callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().');
25896 }
25897 }
25898
25899 var root = this._internalRoot;
25900 var container = root.containerInfo;
25901 updateContainer(null, root, null, function () {
25902 unmarkContainerAsRoot(container);
25903 });
25904 };
25905
25906 function createRootImpl(container, tag, options) {
25907 // Tag is either LegacyRoot or Concurrent Root
25908 var hydrate = options != null && options.hydrate === true;
25909 var hydrationCallbacks = options != null && options.hydrationOptions || null;
25910 var mutableSources = options != null && options.hydrationOptions != null && options.hydrationOptions.mutableSources || null;
25911 var root = createContainer(container, tag, hydrate);
25912 markContainerAsRoot(root.current, container);
25913 var containerNodeType = container.nodeType;
25914
25915 {
25916 var rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container;
25917 listenToAllSupportedEvents(rootContainerElement);
25918 }
25919
25920 if (mutableSources) {
25921 for (var i = 0; i < mutableSources.length; i++) {
25922 var mutableSource = mutableSources[i];
25923 registerMutableSourceForHydration(root, mutableSource);
25924 }
25925 }
25926
25927 return root;
25928 }
25929 function createLegacyRoot(container, options) {
25930 return new ReactDOMBlockingRoot(container, LegacyRoot, options);
25931 }
25932 function isValidContainer(node) {
25933 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 '));
25934 }
25935
25936 var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
25937 var topLevelUpdateWarnings;
25938 var warnedAboutHydrateAPI = false;
25939
25940 {
25941 topLevelUpdateWarnings = function (container) {
25942 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
25943 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
25944
25945 if (hostInstance) {
25946 if (hostInstance.parentNode !== container) {
25947 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.');
25948 }
25949 }
25950 }
25951
25952 var isRootRenderedBySomeReact = !!container._reactRootContainer;
25953 var rootEl = getReactRootElementInContainer(container);
25954 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode(rootEl));
25955
25956 if (hasNonRootReactChild && !isRootRenderedBySomeReact) {
25957 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.');
25958 }
25959
25960 if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === 'BODY') {
25961 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.');
25962 }
25963 };
25964 }
25965
25966 function getReactRootElementInContainer(container) {
25967 if (!container) {
25968 return null;
25969 }
25970
25971 if (container.nodeType === DOCUMENT_NODE) {
25972 return container.documentElement;
25973 } else {
25974 return container.firstChild;
25975 }
25976 }
25977
25978 function shouldHydrateDueToLegacyHeuristic(container) {
25979 var rootElement = getReactRootElementInContainer(container);
25980 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
25981 }
25982
25983 function legacyCreateRootFromDOMContainer(container, forceHydrate) {
25984 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container); // First clear any existing content.
25985
25986 if (!shouldHydrate) {
25987 var warned = false;
25988 var rootSibling;
25989
25990 while (rootSibling = container.lastChild) {
25991 {
25992 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
25993 warned = true;
25994
25995 error('render(): Target node has markup rendered by React, but there ' + 'are unrelated nodes as well. This is most commonly caused by ' + 'white-space inserted around server-rendered markup.');
25996 }
25997 }
25998
25999 container.removeChild(rootSibling);
26000 }
26001 }
26002
26003 {
26004 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
26005 warnedAboutHydrateAPI = true;
26006
26007 warn('render(): Calling ReactDOM.render() to hydrate server-rendered markup ' + 'will stop working in React v18. Replace the ReactDOM.render() call ' + 'with ReactDOM.hydrate() if you want React to attach to the server HTML.');
26008 }
26009 }
26010
26011 return createLegacyRoot(container, shouldHydrate ? {
26012 hydrate: true
26013 } : undefined);
26014 }
26015
26016 function warnOnInvalidCallback$1(callback, callerName) {
26017 {
26018 if (callback !== null && typeof callback !== 'function') {
26019 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
26020 }
26021 }
26022 }
26023
26024 function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
26025 {
26026 topLevelUpdateWarnings(container);
26027 warnOnInvalidCallback$1(callback === undefined ? null : callback, 'render');
26028 } // TODO: Without `any` type, Flow says "Property cannot be accessed on any
26029 // member of intersection type." Whyyyyyy.
26030
26031
26032 var root = container._reactRootContainer;
26033 var fiberRoot;
26034
26035 if (!root) {
26036 // Initial mount
26037 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
26038 fiberRoot = root._internalRoot;
26039
26040 if (typeof callback === 'function') {
26041 var originalCallback = callback;
26042
26043 callback = function () {
26044 var instance = getPublicRootInstance(fiberRoot);
26045 originalCallback.call(instance);
26046 };
26047 } // Initial mount should not be batched.
26048
26049
26050 unbatchedUpdates(function () {
26051 updateContainer(children, fiberRoot, parentComponent, callback);
26052 });
26053 } else {
26054 fiberRoot = root._internalRoot;
26055
26056 if (typeof callback === 'function') {
26057 var _originalCallback = callback;
26058
26059 callback = function () {
26060 var instance = getPublicRootInstance(fiberRoot);
26061
26062 _originalCallback.call(instance);
26063 };
26064 } // Update
26065
26066
26067 updateContainer(children, fiberRoot, parentComponent, callback);
26068 }
26069
26070 return getPublicRootInstance(fiberRoot);
26071 }
26072
26073 function findDOMNode(componentOrElement) {
26074 {
26075 var owner = ReactCurrentOwner$3.current;
26076
26077 if (owner !== null && owner.stateNode !== null) {
26078 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
26079
26080 if (!warnedAboutRefsInRender) {
26081 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.', getComponentName(owner.type) || 'A component');
26082 }
26083
26084 owner.stateNode._warnedAboutRefsInRender = true;
26085 }
26086 }
26087
26088 if (componentOrElement == null) {
26089 return null;
26090 }
26091
26092 if (componentOrElement.nodeType === ELEMENT_NODE) {
26093 return componentOrElement;
26094 }
26095
26096 {
26097 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');
26098 }
26099 }
26100 function hydrate(element, container, callback) {
26101 if (!isValidContainer(container)) {
26102 {
26103 throw Error( "Target container is not a DOM element." );
26104 }
26105 }
26106
26107 {
26108 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
26109
26110 if (isModernRoot) {
26111 error('You are calling ReactDOM.hydrate() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. ' + 'Did you mean to call createRoot(container, {hydrate: true}).render(element)?');
26112 }
26113 } // TODO: throw or warn if we couldn't hydrate?
26114
26115
26116 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
26117 }
26118 function render(element, container, callback) {
26119 if (!isValidContainer(container)) {
26120 {
26121 throw Error( "Target container is not a DOM element." );
26122 }
26123 }
26124
26125 {
26126 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
26127
26128 if (isModernRoot) {
26129 error('You are calling ReactDOM.render() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. ' + 'Did you mean to call root.render(element)?');
26130 }
26131 }
26132
26133 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
26134 }
26135 function unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
26136 if (!isValidContainer(containerNode)) {
26137 {
26138 throw Error( "Target container is not a DOM element." );
26139 }
26140 }
26141
26142 if (!(parentComponent != null && has(parentComponent))) {
26143 {
26144 throw Error( "parentComponent must be a valid React Component" );
26145 }
26146 }
26147
26148 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
26149 }
26150 function unmountComponentAtNode(container) {
26151 if (!isValidContainer(container)) {
26152 {
26153 throw Error( "unmountComponentAtNode(...): Target container is not a DOM element." );
26154 }
26155 }
26156
26157 {
26158 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
26159
26160 if (isModernRoot) {
26161 error('You are calling ReactDOM.unmountComponentAtNode() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. Did you mean to call root.unmount()?');
26162 }
26163 }
26164
26165 if (container._reactRootContainer) {
26166 {
26167 var rootEl = getReactRootElementInContainer(container);
26168 var renderedByDifferentReact = rootEl && !getInstanceFromNode(rootEl);
26169
26170 if (renderedByDifferentReact) {
26171 error("unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.');
26172 }
26173 } // Unmount should not be batched.
26174
26175
26176 unbatchedUpdates(function () {
26177 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
26178 // $FlowFixMe This should probably use `delete container._reactRootContainer`
26179 container._reactRootContainer = null;
26180 unmarkContainerAsRoot(container);
26181 });
26182 }); // If you call unmountComponentAtNode twice in quick succession, you'll
26183 // get `true` twice. That's probably fine?
26184
26185 return true;
26186 } else {
26187 {
26188 var _rootEl = getReactRootElementInContainer(container);
26189
26190 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode(_rootEl)); // Check if the container itself is a React root node.
26191
26192 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
26193
26194 if (hasNonRootReactChild) {
26195 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.');
26196 }
26197 }
26198
26199 return false;
26200 }
26201 }
26202
26203 setAttemptUserBlockingHydration(attemptUserBlockingHydration$1);
26204 setAttemptContinuousHydration(attemptContinuousHydration$1);
26205 setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority$1);
26206 setAttemptHydrationAtPriority(runWithPriority$2);
26207 var didWarnAboutUnstableCreatePortal = false;
26208
26209 {
26210 if (typeof Map !== 'function' || // $FlowIssue Flow incorrectly thinks Map has no prototype
26211 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' || // $FlowIssue Flow incorrectly thinks Set has no prototype
26212 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {
26213 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');
26214 }
26215 }
26216
26217 setRestoreImplementation(restoreControlledState$3);
26218 setBatchingImplementation(batchedUpdates$1, discreteUpdates$1, flushDiscreteUpdates, batchedEventUpdates$1);
26219
26220 function createPortal$1(children, container) {
26221 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
26222
26223 if (!isValidContainer(container)) {
26224 {
26225 throw Error( "Target container is not a DOM element." );
26226 }
26227 } // TODO: pass ReactDOM portal implementation as third argument
26228 // $FlowFixMe The Flow type is opaque but there's no way to actually create it.
26229
26230
26231 return createPortal(children, container, null, key);
26232 }
26233
26234 function renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
26235
26236 return unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback);
26237 }
26238
26239 function unstable_createPortal(children, container) {
26240 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
26241
26242 {
26243 if (!didWarnAboutUnstableCreatePortal) {
26244 didWarnAboutUnstableCreatePortal = true;
26245
26246 warn('The ReactDOM.unstable_createPortal() alias has been deprecated, ' + 'and will be removed in React 18+. Update your code to use ' + 'ReactDOM.createPortal() instead. It has the exact same API, ' + 'but without the "unstable_" prefix.');
26247 }
26248 }
26249
26250 return createPortal$1(children, container, key);
26251 }
26252
26253 var Internals = {
26254 // Keep in sync with ReactTestUtils.js, and ReactTestUtilsAct.js.
26255 // This is an array for better minification.
26256 Events: [getInstanceFromNode, getNodeFromInstance, getFiberCurrentPropsFromNode, enqueueStateRestore, restoreStateIfNeeded, flushPassiveEffects, // TODO: This is related to `act`, not events. Move to separate key?
26257 IsThisRendererActing]
26258 };
26259 var foundDevTools = injectIntoDevTools({
26260 findFiberByHostInstance: getClosestInstanceFromNode,
26261 bundleType: 1 ,
26262 version: ReactVersion,
26263 rendererPackageName: 'react-dom'
26264 });
26265
26266 {
26267 if (!foundDevTools && canUseDOM && window.top === window.self) {
26268 // If we're in Chrome or Firefox, provide a download link if not installed.
26269 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
26270 var protocol = window.location.protocol; // Don't warn in exotic cases like chrome-extension://.
26271
26272 if (/^(https?|file):$/.test(protocol)) {
26273 // eslint-disable-next-line react-internal/no-production-logging
26274 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');
26275 }
26276 }
26277 }
26278 }
26279
26280 exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals;
26281 exports.createPortal = createPortal$1;
26282 exports.findDOMNode = findDOMNode;
26283 exports.flushSync = flushSync;
26284 exports.hydrate = hydrate;
26285 exports.render = render;
26286 exports.unmountComponentAtNode = unmountComponentAtNode;
26287 exports.unstable_batchedUpdates = batchedUpdates$1;
26288 exports.unstable_createPortal = unstable_createPortal;
26289 exports.unstable_renderSubtreeIntoContainer = renderSubtreeIntoContainer;
26290 exports.version = ReactVersion;
26291
26292})));