cks whether or not a given node is a `case` node (not `default` node).
 * @param {ASTNode} node A `SwitchCase` node to check.
 * @returns {boolean} `true` if the node is a `case` node (not `default` node).
 */
function isCaseNode(node) {
  return Boolean(node.test);
}

/**
 * Checks if a given node appears as the value of a PropertyDefinition node.
 * @param {ASTNode} node THe node to check.
 * @returns {boolean} `true` if the node is a PropertyDefinition value,
 *      false if not.
 */
function isProperty

code
 * path analysis.
 * @param {string} operator The operator found in the LogicalExpression node
 * @returns {boolean} `true` if the operator is "&&" or "||" or "??"
 */
function isHandledLogicalOperator(operator) {
  return operator === '&&' || operato

DefinitionValue(node) {
  const parent = node.parent;

  return (
    parent && parent.type === 'PropertyDefinition' && parent.value === node
  );
}

/**
 * Checks whether the given logical operator is taken into account for the


disable-next-line
const assert = require('./assert');
// eslint-disable-next-line
const CodePathSegment = require('./code-path-segment');

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------

/**
 * Gets whether or not a given segment is reachable.
 * @param {CodePathSegment} segment A segment to get.
 * @returns {boolean} `true` if the segment is reachable.
 */
function isReachable(segme

es `[g, h]`. This `g` is from `a`, `c`, and `e`.
 * This `h` is from `b`, `d`, and `f`.
 * @param {ForkContext} context An instance.
 * @param {number} begin The first index of the previous segments.
 * @param {number} end The last index of the previous se

nt) {
  return segment.reachable;
}

/**
 * Creates new segments from the specific range of `context.segmentsList`.
 *
 * When `context.segmentsList` is `[[a, b], [c, d], [e, f]]`, `begin` is `0`, and
 * `end` is `-1`, this creat


 MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import * as React from 'react';
import {useMemo} from 'react';
import {copy} from 'clipboard-js';
import prettyMilliseconds from 'pretty-ms';

import ContextMenuContainer from 'react-devtools-shared/src/devtools/ContextMenu/ContextMenuContainer';
import {withPermissionsCheck} from 'react-devtools-shared/src/frontend/utils/withPermissionsCheck';

import {getBatchRange} from './utils/getBatchRange';
import {m

nu/types';
import type {
  ReactEventInfo,
  ReactMeasure,
  TimelineData,
  ViewState,
} from './types';

function zoomToBatch(
  data: TimelineData,
  measure: ReactMeasure,
  viewState: ViewState,
  width: number,
) {
  const {batchUID} = measure;
  con

oveStateToRange} from './view-base/utils/scrollState';
import {MAX_ZOOM_LEVEL, MIN_ZOOM_LEVEL} from './view-base/constants';

import type {
  ContextMenuItem,
  ContextMenuRef,
} from 'react-devtools-shared/src/devtools/ContextMe


 MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import type {ReactContext} from 'shared/ReactTypes';

import * as React from 'react';
import {createContext, useMemo, useReducer} from 'react';

import type {ReactComponentMeasure, TimelineData, ViewState} from './types';

type State = {
  profilerData: TimelineData,
  searchIndex: number,
  searchRegExp: RegExp | null,
  searchResults: Array<ReactComponentMeasure>,
  searchText: string,
};

type ACTION_GO_

,
};

type Action =
  | ACTION_GO_TO_NEXT_SEARCH_RESULT
  | ACTION_GO_TO_PREVIOUS_SEARCH_RESULT
  | ACTION_SET_SEARCH_TEXT;

type Dispatch = (action: Action) => void;

const EMPTY_ARRAY: Array<ReactComponentMeasure> = [];

function reducer(state: State, ac

TO_NEXT_SEARCH_RESULT = {
  type: 'GO_TO_NEXT_SEARCH_RESULT',
};
type ACTION_GO_TO_PREVIOUS_SEARCH_RESULT = {
  type: 'GO_TO_PREVIOUS_SEARCH_RESULT',
};
type ACTION_SET_SEARCH_TEXT = {
  type: 'SET_SEARCH_TEXT',
  payload: string


low */

import type {DevToolsHookSettings} from 'react-devtools-shared/src/backend/types';
import type {ComponentFilter} from 'react-devtools-shared/src/frontend/types';

export function postMessage(event: UnknownMessageEventData): void {
  window.postMessage(event);
}

export interface UnknownMessageEvent
  extends MessageEvent<UnknownMessageEventData> {}

export type UnknownMessageEventData =
  | SettingsInjectorEventData
  | HookInstallerEventData;

export type HookInstallerEventData = {
  source: 'react

pe SettingsInjectorEventData = {
  source: 'react-devtools-settings-injector',
  payload: SettingsInjectorEventPayload,
};

export type SettingsInjectorEventPayload =
  | SettingsInjectorEventPayloadHandshake
  | SettingsInjectorEventPayloadSettings;

expo

-devtools-hook-installer',
  payload: HookInstallerEventPayload,
};

export type HookInstallerEventPayload = HookInstallerEventPayloadHandshake;

export type HookInstallerEventPayloadHandshake = {
  handshake: true,
};

export ty


        }
      `,
    },
    {
      code: normalizeIndent`
        // Valid because components can use hooks.
        function createComponentWithHook() {
          return function ComponentWithHook() {
            useHook();
          };
        }
      `,
    },
    {
      code: normalizeIndent`
        // Valid because hooks can use hooks.
        function useHookWithHook() {
          useHook();
        }
      `,
    },
    {
      code: normalizeIndent`
        // Valid because hooks can use hooks

s.
        function ComponentWithNormalFunction() {
          doSomething();
        }
      `,
    },
    {
      code: normalizeIndent`
        // Valid because functions can call functions.
        function normalFunctionWithNormalFunction() {

.
        function createHook() {
          return function useHookWithHook() {
            useHook();
          }
        }
      `,
    },
    {
      code: normalizeIndent`
        // Valid because components can call function


n state.loopContext;
  }

  let context = state.loopContext;

  while (context) {
    if (context.label === label) {
      return context;
    }
    context = context.upper;
  }

  /* c8 ignore next */
  return null;
}

/**
 * Gets a context for a `break` statement.
 * @param {CodePathState} state A state to get.
 * @param {string} label The label of a `break` statement.
 * @returns {LoopContext|SwitchContext} A context for a `break` statement.
 */
function getBreakContext(state, label) {
  let context = st

r a `return` statement.
 * @param {CodePathState} state A state to get.
 * @returns {TryContext|CodePathState} A context for a `return` statement.
 */
function getReturnContext(state) {
  let context = state.tryContext;

  while (context) {
    if (context

ate.breakContext;

  while (context) {
    if (label ? context.label === label : context.breakable) {
      return context;
    }
    context = context.upper;
  }

  /* c8 ignore next */
  return null;
}

/**
 * Gets a context fo


iates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import * as React from 'react';
import {isInternalFacebookBuild} from 'react-devtools-feature-flags';

import styles from './TimelineNotSupported.css';

type Props = {
  isPerformanceTracksSupported: boolean,
};

function PerformanceTracksSupported() {
  return (
    <>

          Please use{' '}

        </a>{' '}
          instead of the Timeline profiler.
        </span>
      </p>
    </>
  );
}

function UnknownUnsupportedReason() {
  return (
    <>
      <p className={styles.Paragraph}>
        Timeline profiler requires a development or prof

  <a
            className={styles.Link}
            href="https://react.dev/reference/dev-tools/react-performance-tracks"
            rel="noopener noreferrer"
            target="_blank">
            React Performance tracks


iates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import {hslaColorToString, dimmedColor, ColorGenerator} from '../colors';

describe('hslaColorToString', () => {
  it('should transform colors to strings', () => {
    expect(hslaColorToString({h: 1, s: 2, l: 3, a: 4})).toEqual(
      'hsl(1deg 2% 3% / 4)',
    );
    expect(hslaColorToString({h: 3.14, s: 6.28, l: 1.68, a: 100})).toEqual(
      'hsl(3.14deg

 4,
    });
    expect(dimmedColor({h: 1, s: 2, l: 3, a: 4}, -3)).toEqual({
      h: 1,
      s: 2,
      l: 6,
      a: 4,
    });
  });
});

describe('ColorGenerator', () => {
  describe('colorForID', () => {
    it('should generate a color for an ID', (

 6.28% 1.68% / 100)',
    );
  });
});

describe('dimmedColor', () => {
  it('should dim luminosity using delta', () => {
    expect(dimmedColor({h: 1, s: 2, l: 3, a: 4}, 3)).toEqual({
      h: 1,
      s: 2,
      l: 0,
      a:


import type {Size, IntrinsicSize, Rect} from './geometry';
import type {
  Interaction,
  MouseDownInteraction,
  MouseMoveInteraction,
  MouseUpInteraction,
  WheelPlainInteraction,
  WheelWithShiftInteraction,
} from './useCanvasInteraction';
import type {ScrollState} from './utils/scrollState';
import type {ViewRefs} from './Surface';
import type {ViewState} from '../types';

import {Surface} from './Surface';
import {View} from './View';
import {rectContainsPoint} from './geometry';
import {
  clampStat

PanAndZoomView extends View {
  _contentView: View;
  _intrinsicContentWidth: number;
  _isPanning: boolean = false;
  _viewState: ViewState;

  constructor(
    surface: Surface,
    frame: Rect,
    contentView: View,
    intrinsicContentWidth: number,

e,
  moveStateToRange,
  areScrollStatesEqual,
  translateState,
  zoomState,
} from './utils/scrollState';
import {
  MAX_ZOOM_LEVEL,
  MIN_ZOOM_LEVEL,
  MOVE_WHEEL_DELTA_THRESHOLD,
} from './constants';

export class Horizontal


 MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import type {Interaction} from './useCanvasInteraction';
import type {Size} from './geometry';

import memoize from 'memoize-one';

import {View} from './View';
import {zeroPoint} from './geometry';
import {DPR} from '../content-views/constants';

export type ViewRefs = {
  activeView: View | null,
  hoveredView: View | null,
};

// hidpi canvas: https://web.dev/articles/canvas-hidipi
function configureReti

anvasContext = memoize(
  (
    canvas: HTMLCanvasElement,
    height: number,
    width: number,
    scaleCanvas: boolean = true,
  ): CanvasRenderingContext2D => {
    const context = canvas.getContext('2d', {alpha: false});
    if (scaleCanvas) {

naCanvas(
  canvas: HTMLCanvasElement,
  height: number,
  width: number,
) {
  canvas.width = width * DPR;
  canvas.height = height * DPR;
  canvas.style.width = `${width}px`;
  canvas.style.height = `${height}px`;
}

const getC


import type {Rect} from './geometry';
import type {View} from './View';

export type LayoutInfo = {view: View, frame: Rect};
export type Layout = LayoutInfo[];

/**
 * A function that takes a list of subviews, currently laid out in
 * `existingLayout`, and lays them out into `containingFrame`.
 */
export type Layouter = (
  existingLayout: Layout,
  containingFrame: Rect,
) => Layout;

function viewToLayoutInfo(view: View): LayoutInfo {
  return {view, frame: view.frame};
}

export function viewsToLayout(vi

w.setFrame(frame));
}

/**
 * A no-operation layout; does not modify the layout.
 */
export const noopLayout: Layouter = layout => layout;

/**
 * Layer views on top of each other. All views' frames will be set to `containerFrame`.
 *
 * Equivalent to comp

ews: View[]): Layout {
  return views.map(viewToLayoutInfo);
}

/**
 * Applies `layout`'s `frame`s to its corresponding `view`.
 */
export function collapseLayoutIntoViews(layout: Layout) {
  layout.forEach(({view, frame}) => vie


import type {NormalizedWheelDelta} from './utils/normalizeWheel';
import type {Point} from './geometry';

import {useEffect, useRef} from 'react';
import {normalizeWheel} from './utils/normalizeWheel';

export type ClickInteraction = {
  type: 'click',
  payload: {
    event: MouseEvent,
    location: Point,
  },
};
export type DoubleClickInteraction = {
  type: 'double-click',
  payload: {
    event: MouseEvent,
    location: Point,
  },
};
export type MouseDownInteraction = {
  type: 'mousedown',
  payloa

up',
  payload: {
    event: MouseEvent,
    location: Point,
  },
};
export type WheelPlainInteraction = {
  type: 'wheel-plain',
  payload: {
    event: WheelEvent,
    location: Point,
    delta: NormalizedWheelDelta,
  },
};
export type WheelWithShiftI

d: {
    event: MouseEvent,
    location: Point,
  },
};
export type MouseMoveInteraction = {
  type: 'mousemove',
  payload: {
    event: MouseEvent,
    location: Point,
  },
};
export type MouseUpInteraction = {
  type: 'mouse


import type {Rect} from '../geometry';
import type {Surface, ViewRefs} from '../Surface';
import type {
  Interaction,
  ClickInteraction,
  MouseDownInteraction,
  MouseMoveInteraction,
  MouseUpInteraction,
} from '../useCanvasInteraction';

import {VerticalScrollOverflowView} from './VerticalScrollOverflowView';
import {rectContainsPoint, rectEqualToRect} from '../geometry';
import {View} from '../View';
import {BORDER_SIZE, COLORS} from '../../content-views/constants';

const SCROLL_BAR_SIZE = 14;

cons

ect: Rect = HIDDEN_RECT;
  _scrollThumbRect: Rect = HIDDEN_RECT;
  _verticalScrollOverflowView: VerticalScrollOverflowView;

  constructor(
    surface: Surface,
    frame: Rect,
    verticalScrollOverflowView: VerticalScrollOverflowView,
  ) {
    super(s

t HIDDEN_RECT = {
  origin: {
    x: 0,
    y: 0,
  },
  size: {
    width: 0,
    height: 0,
  },
};

export class VerticalScrollBarView extends View {
  _contentHeight: number = 0;
  _isScrolling: boolean = false;
  _scrollBarR


iates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import type {Rect} from '../geometry';
import type {ScrollState} from '../utils/scrollState';
import type {Surface} from '../Surface';
import type {ViewState} from '../../types';

import {VerticalScrollBarView} from './VerticalScrollBarView';
import {withVerticalScrollbarLayout} from './withVerticalScrollbarLayout';
import {View} from '../View';
import {Ver

  _scrollBarView: VerticalScrollBarView;
  _verticalScrollView: VerticalScrollView;

  constructor(
    surface: Surface,
    frame: Rect,
    contentView: View,
    viewState: ViewState,
  ) {
    super(surface, frame, withVerticalScrollbarLayout);

    t

ticalScrollView} from '../VerticalScrollView';

export class VerticalScrollOverflowView extends View {
  _contentView: View;
  _isProcessingOnChange: boolean = false;
  _isScrolling: boolean = false;
  _scrollOffset: number = 0;


nt,
  Snapshot,
  SuspenseEvent,
  ThrownError,
  TimelineData,
  UserTimingMark,
} from './types';

import * as React from 'react';
import {
  formatDuration,
  formatTimestamp,
  trimString,
  getSchedulingEventLabel,
} from './utils/formatting';
import {getBatchRange} from './utils/getBatchRange';
import useSmartTooltip from './utils/useSmartTooltip';
import styles from './EventTooltip.css';

const MAX_TOOLTIP_TEXT_LENGTH = 60;

type Props = {
  canvasRef: {current: HTMLCanvasElement | null},
  data: Tim

eact commit';
    case 'render-idle':
      return 'react idle';
    case 'render':
      return 'react render';
    case 'layout-effects':
      return 'react layout effects';
    case 'passive-effects':
      return 'react passive effects';
    default:

elineData,
  height: number,
  hoveredEvent: ReactEventInfo | null,
  origin: Point,
  width: number,
};

function getReactMeasureLabel(type: ReactMeasureType): string | null {
  switch (type) {
    case 'commit':
      return 'r


iates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import type {
  FlamechartStackFrame,
  InternalModuleSourceToRanges,
} from '../../types';

import {
  CHROME_WEBSTORE_EXTENSION_ID,
  INTERNAL_EXTENSION_ID,
  LOCAL_EXTENSION_ID,
} from 'react-devtools-shared/src/constants';

export function isInternalModule(
  internalModuleSourceToRanges: InternalModuleSourceToRanges,
  flamechartStackFrame: FlamechartS

e performance.mark().
    return false;
  }

  // Internal modules are only registered if DevTools was running when the profile was captured,
  // but DevTools should also hide its own frames to avoid over-emphasizing them.
  if (
    // Handle webpack-int

tackFrame,
): boolean {
  const {locationColumn, locationLine, scriptUrl} = flamechartStackFrame;

  if (scriptUrl == null || locationColumn == null || locationLine == null) {
    // This could indicate a browser-internal API lik


iates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import {isInternalModule} from '../moduleFilters';

describe('isInternalModule', () => {
  let map;

  function createFlamechartStackFrame(scriptUrl, locationLine, locationColumn) {
    return {
      name: 'test',
      timestamp: 0,
      duration: 1,
      scriptUrl,
      locationLine,
      locationColumn,
    };
  }

  function createStackFrame(fileNa

er})`,
    };
  }

  beforeEach(() => {
    map = new Map();
    map.set('foo', [
      [createStackFrame('foo', 10, 0), createStackFrame('foo', 15, 100)],
    ]);
    map.set('bar', [
      [createStackFrame('bar', 10, 0), createStackFrame('bar', 15, 100)

me, lineNumber, columnNumber) {
    return {
      columnNumber: columnNumber,
      lineNumber: lineNumber,
      fileName: fileName,
      functionName: 'test',
      source: `    at test (${fileName}:${lineNumber}:${columnNumb


import type {Interaction} from './useCanvasInteraction';
import type {IntrinsicSize, Rect, Size} from './geometry';
import type {Layouter} from './layouter';
import type {ViewRefs} from './Surface';

import {Surface} from './Surface';
import {
  rectEqualToRect,
  intersectionOfRects,
  rectIntersectsRect,
  sizeIsEmpty,
  sizeIsValid,
  unionOfRects,
  zeroRect,
} from './geometry';
import {noopLayout, viewsToLayout, collapseLayoutIntoViews} from './layouter';

/**
 * Base view class that can be subclassed

subviews: View[] = [];

  /**
   * An injected function that lays out our subviews.
   * @private
   */
  _layouter: Layouter;

  /**
   * Whether this view needs to be drawn.
   *
   * NOTE: Do not set directly! Use `setNeedsDisplay`.
   *
   * @see setNe

 to draw custom content or manage
 * subclasses.
 */
export class View {
  _backgroundColor: string | null;

  currentCursor: string | null = null;

  surface: Surface;

  frame: Rect;
  visibleArea: Rect;

  superview: ?View;


 MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

export type Point = $ReadOnly<{x: number, y: number}>;
export type Size = $ReadOnly<{width: number, height: number}>;
export type IntrinsicSize = {
  ...Size,

  // If content is this height or less, hide the scrollbar entirely,
  // so that it doesn't take up vertical space unnecessarily (e.g. for a single row of content).
  hideScrollBarIfLessThanHeight?: number,

  // The initial height should be the hei

ft`) coordinates.
 */
type Box = [number, number, number, number];

export const zeroPoint: Point = Object.freeze({x: 0, y: 0});
export const zeroSize: Size = Object.freeze({width: 0, height: 0});
export const zeroRect: Rect = Object.freeze({
  origin: zer

ght of the content, or this, whichever is less.
  maxInitialHeight?: number,
};
export type Rect = $ReadOnly<{origin: Point, size: Size}>;

/**
 * Alternative representation of `Rect`.
 * A tuple of (`top`, `right`, `bottom`, `le


om './setExtensionIconAndPopup';

function isRestrictedBrowserPage(url) {
  if (!url) {
    return true;
  }

  const urlProtocol = new URL(url).protocol;
  return urlProtocol === 'chrome:' || urlProtocol === 'about:';
}

function checkAndHandleRestrictedPageIfSo(tab) {
  if (tab && isRestrictedBrowserPage(tab.url)) {
    setExtensionIconAndPopup('restricted', tab.id);
  }
}

// Update popup page of any existing open tabs, if they are restricted browser pages
chrome.tabs.query({}, tabs => tabs.forEach(check

.addListener(tab => checkAndHandleRestrictedPageIfSo(tab));

// Listen to URL changes on the active tab and update the DevTools icon.
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
  if (changeInfo.url && isRestrictedBrowserPage(changeInfo


nder the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import type {Rect} from '../../view-base';

export function positioningScaleFactor(
  intrinsicWidth: number,
  frame: Rect,
): number {
  return frame.size.width / intrinsicWidth;
}

export function timestampToPosition(
  timestamp: number,
  scaleFactor: number,
  frame: Rect,
): number {
  return frame.origin.x + timestamp * scaleFactor;
}

export function positionToTimestamp(
  position: number,

 return (position - frame.origin.x) / scaleFactor;
}

export function durationToWidth(duration: number, scaleFactor: number): number {
  return duration * scaleFactor;
}

export function widthToDuration(width: number, scaleFactor: number): number {
  retur


import {
  pointEqualToPoint,
  sizeEqualToSize,
  rectEqualToRect,
  sizeIsValid,
  sizeIsEmpty,
  rectIntersectsRect,
  intersectionOfRects,
  rectContainsPoint,
  unionOfRects,
} from '../geometry';

describe('pointEqualToPoint', () => {
  it('should return true when 2 points have the same values', () => {
    expect(pointEqualToPoint({x: 1, y: 1}, {x: 1, y: 1})).toBe(true);
    expect(pointEqualToPoint({x: -1, y: 2}, {x: -1, y: 2})).toBe(true);
    expect(
      pointEqualToPoint({x: 3.14159, y: 0.26535

: -1, y: 2}, {x: 0, y: 1})).toBe(false);
    expect(
      pointEqualToPoint({x: 3.1416, y: 0.26534}, {x: 3.14159, y: 0.26535}),
    ).toBe(false);
  });
});

describe('sizeEqualToSize', () => {
  it('should return true when 2 sizes have the same values',

}, {x: 3.14159, y: 0.26535}),
    ).toBe(true);
  });

  it('should return false when 2 points have different values', () => {
    expect(pointEqualToPoint({x: 1, y: 1}, {x: 1, y: 0})).toBe(false);
    expect(pointEqualToPoint({x


require('@playwright/test');
const config = require('../../playwright.config');
const semver = require('semver');

test.use(config);
test.describe('Components', () => {
  let page;

  test.beforeEach(async ({browser}) => {
    page = await browser.newPage();

    await page.goto(config.use.url, {
      waitUntil: 'domcontentloaded',
    });

    await page.waitForSelector('#iframe');

    await devToolsUtils.clickButton(page, 'TabBarButton-components');
  });

  test('Should display initial React components

t rows = findAllNodes(container, [
        createTestNameSelector('ListItem'),
      ]);
      return rows.length;
    });
    expect(appRowCount).toBe(3);

    const devToolsRowCount = await devToolsUtils.getElementCount(
      page,
      'ListItem'

', async () => {
    const appRowCount = await page.evaluate(() => {
      const {createTestNameSelector, findAllNodes} = window.REACT_DOM_APP;
      const container = document.getElementById('iframe').contentDocument;
      cons


testName => {
    const {createTestNameSelector, findAllNodes} = window.REACT_DOM_DEVTOOLS;
    const container = document.getElementById('devtools');

    const button = findAllNodes(container, [
      createTestNameSelector(testName),
    ])[0];
    button.click();
  }, buttonTestName);
}

async function getElementCount(page, displayName) {
  return await page.evaluate(listItemText => {
    const {createTestNameSelector, createTextSelector, findAllNodes} =
      window.REACT_DOM_DEVTOOLS;
    const contai

);
}

async function selectElement(
  page,
  displayName,
  waitForOwnersText,
  waitForSourceLoaded = false
) {
  await page.evaluate(listItemText => {
    const {createTestNameSelector, createTextSelector, findAllNodes} =
      window.REACT_DOM_DEVTOOLS

ner = document.getElementById('devtools');
    const rows = findAllNodes(container, [
      createTestNameSelector('ComponentTreeListItem'),
      createTextSelector(listItemText),
    ]);
    return rows.length;
  }, displayName


equire('./list-app-utils');
const devToolsUtils = require('./devtools-utils');
const {test, expect} = require('@playwright/test');
const config = require('../../playwright.config');
test.use(config);
test.describe('Profiler', () => {
  let page;

  test.beforeEach(async ({browser}) => {
    page = await browser.newPage();
    await page.goto(config.use.url, {
      waitUntil: 'domcontentloaded',
    });

    await page.waitForSelector('#iframe');

    await devToolsUtils.clickButton(page, 'TabBarButton-prof

urn await page.evaluate(() => {
        const {createTestNameSelector, findAllNodes} =
          window.REACT_DOM_DEVTOOLS;
        const container = document.getElementById('devtools');

        const input = findAllNodes(container, [
          createTest

iler');
  });

  test('should record renders and commits when active', async () => {
    // Profiling is only available in 16.5 and over
    runOnlyForReactRange('>=16.5');
    async function getSnapshotSelectorText() {
      ret


evtools-shared/src/bridge';
import {initBackend} from 'react-devtools-shared/src/backend';
import {installHook} from 'react-devtools-shared/src/hook';
import setupNativeStyleEditor from 'react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor';

import type {
  BackendBridge,
  SavedPreferencesParams,
} from 'react-devtools-shared/src/bridge';
import type {
  ComponentFilter,
  Wall,
} from 'react-devtools-shared/src/frontend/types';
import {
  getIfReloadedAndProfiling,
  getIsReloadAndP

w Promise<Array<ComponentFilter>>(resolve => {
  resolveComponentFiltersInjection = resolve;
});

function startActivation(contentWindow: any, bridge: BackendBridge) {
  const onSavedPreferences = (data: SavedPreferencesParams) => {
    // This is the only

rofileSupported,
  onReloadAndProfile,
  onReloadAndProfileFlagsReset,
} from 'react-devtools-shared/src/utils';

let resolveComponentFiltersInjection: (filters: Array<ComponentFilter>) => void;
const componentFiltersPromise = ne


t {forwardRef} from 'react';
import Bridge from 'react-devtools-shared/src/bridge';
import Store from 'react-devtools-shared/src/devtools/store';
import DevTools from 'react-devtools-shared/src/devtools/views/DevTools';
import {getSavedComponentFilters} from 'react-devtools-shared/src/utils';

import type {Wall} from 'react-devtools-shared/src/frontend/types';
import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
import type {Props} from 'react-devtools-shared/src/devtools/views/DevTools';
i

ortsTraceUpdates: true,
    supportsTimeline: true,
    ...config,
  });
}

export function createBridge(contentWindow: any, wall?: Wall): FrontendBridge {
  if (wall == null) {
    wall = {
      listen(fn) {
        // $FlowFixMe[missing-local-annot]

mport type {Config} from 'react-devtools-shared/src/devtools/store';

export function createStore(bridge: FrontendBridge, config?: Config): Store {
  return new Store(bridge, {
    checkBridgeProtocolCompatibility: true,
    supp


 Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

/* globals Event$Init */

/**
 * A bridge event class that extends the W3C Event interface and carries
 * the native event payload. This is used as a compatibility layer during
 * the migration from the legacy SyntheticEvent system to EventTarget-based
 * dispatching.
 */
export default class LegacySyntheticEvent extends Event {

    this._propagationStopped = false;
  }

  get nativeEvent(): {[string]: mixed} {
    return this._nativeEvent;
  }

  stopPropagation(): void {
    super.stopPropagation();
    this._propagationStopped = true;
  }

  stopImmediatePropagation(): void {

_nativeEvent: {[string]: mixed};
  _propagationStopped: boolean;

  constructor(
    type: string,
    options: Event$Init,
    nativeEvent: {[string]: mixed},
  ) {
    super(type, options);
    this._nativeEvent = nativeEvent;


import type {ReactPortal, ReactNodeList} from 'shared/ReactTypes';
import type {ElementRef, Element, ElementType} from 'react';
import type {FiberRoot} from 'react-reconciler/src/ReactInternalTypes';
import type {RenderRootOptions} from './ReactNativeTypes';

import './ReactFabricInjection';

import {
  batchedUpdates as batchedUpdatesImpl,
  discreteUpdates,
  createContainer,
  updateContainer,
  injectIntoDevTools,
  getPublicRootInstance,
  defaultOnUncaughtError,
  defaultOnCaughtError,
  defaultOnReco

import {LegacyRoot, ConcurrentRoot} from 'react-reconciler/src/ReactRootTags';
import {
  findHostInstance_DEPRECATED,
  findNodeHandle,
  dispatchCommand,
  sendAccessibilityEvent,
  getNodeFromInternalInstanceHandle,
  isChildPublicInstance,
} from './

verableError,
} from 'react-reconciler/src/ReactFiberReconciler';

import {createPortal as createPortalImpl} from 'react-reconciler/src/ReactPortal';
import {setBatchingImplementation} from './legacy-events/ReactGenericBatching';


 Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow strict-local
 */

import type {
  PublicInstance,
  Instance,
  Props,
  TextInstance,
} from './ReactFiberConfigFabric';
import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
import {getPublicInstance} from './ReactFiberConfigFabric';

// `node` is typed incorrectly here. The proper type should be `PublicInstance`.
// Thi

ative, node is never a text instance

  if (
    instance.canonical != null &&
    instance.canonical.internalInstanceHandle != null
  ) {
    return instance.canonical.internalInstanceHandle;
  }

  // $FlowFixMe[incompatible-return] DevTools incorrectly

s is ok in DOM because they types are interchangeable, but in React Native
// they aren't.
function getInstanceFromNode(node: Instance | TextInstance): Fiber | null {
  const instance: Instance = (node: $FlowFixMe); // In React N


import type {
  AnyNativeEvent,
  LegacyPluginModule,
} from './legacy-events/PluginModuleType';
import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
import type {ReactSyntheticEvent} from './legacy-events/ReactSyntheticEventType';
import type {
  RNTopLevelEventType,
  TopLevelType,
} from './legacy-events/TopLevelEventTypes';

import {
  registrationNameModules,
  plugins,
} from './legacy-events/EventPluginRegistry';
import {batchedUpdates} from './legacy-events/ReactGenericBatching';
impo

rom 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
import {getPublicInstance} from './ReactFiberConfigFabric';
import {enableNativeEventTargetEventDispatching} from './ReactNativeFeatureFlags';

export {getListener, registrationNameModu

rt accumulateInto from './legacy-events/accumulateInto';

import getListener from './ReactNativeGetListener';
import {runEventsInBatch} from './legacy-events/EventBatching';

import {
  RawEventEmitter,
  dispatchNativeEvent,
} f


a Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

const ReactFabricGlobalResponderHandler = {
  onChange: function (from: any, to: any, blockNativeResponder: boolean) {
    if (from && from.stateNode) {
      // equivalent to clearJSResponder
      nativeFabricUIManager.setIsJSResponder(
        from.stateNode.node,
        false,
        blockNativeResponder || false,
      );

to && to.stateNode) {
      // equivalent to setJSResponder
      nativeFabricUIManager.setIsJSResponder(
        to.stateNode.node,
        true,
        blockNativeResponder || false,
      );
    }
  },
};

export default ReactFabricGlobalResponderHandl


ight (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import './ReactNativeInjectionShared';

import {
  getFiberCurrentPropsFromNode,
  getInstanceFromNode,
  getNodeFromInstance,
} from './ReactFabricComponentTree';
import {setComponentTree} from './legacy-events/EventPluginUtils';
import ReactFabricGlobalResponderHandler from './ReactFabricGlobalResponderHandler';
impo

entPlugin from './legacy-events/ResponderEventPlugin';

setComponentTree(
  getFiberCurrentPropsFromNode,
  getInstanceFromNode,
  getNodeFromInstance,
);

ResponderEventPlugin.injection.injectGlobalResponderHandler(
  ReactFabricGlobalResponderHandler,
);


ules provided by RN:
import {
  ReactNativeViewConfigRegistry,
  deepFreezeAndThrowOnMutationInDev,
  createPublicInstance,
  createPublicTextInstance,
  createAttributePayload,
  diffAttributePayloads,
  type PublicInstance as ReactNativePublicInstance,
  type PublicTextInstance,
  type PublicRootInstance,
} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
import {
  enableFragmentRefsInstanceHandles,
  enableFragmentRefsTextNodes,
} from 'shared/ReactFeatureFlags';

const {
  create

sterEventHandler,
  unstable_DefaultEventPriority: FabricDefaultPriority,
  unstable_DiscreteEventPriority: FabricDiscretePriority,
  unstable_ContinuousEventPriority: FabricContinuousPriority,
  unstable_IdleEventPriority: FabricIdlePriority,
  unstable_g

Node,
  cloneNodeWithNewChildren,
  cloneNodeWithNewChildrenAndProps,
  cloneNodeWithNewProps,
  createChildSet: createChildNodeSet,
  appendChild: appendChildNode,
  appendChildToSet: appendChildNodeToSet,
  completeRoot,
  regi


import type {TransitionTypes} from 'react/src/ReactTransitionType';
import type {
  Instance,
  Props,
  Container,
  SuspendedState,
  GestureTimeline,
} from './ReactFiberConfigFabric';

import {allocateTag} from './ReactFiberConfigFabric';

const {
  applyViewTransitionName: fabricApplyViewTransitionName,
  createViewTransitionInstance: fabricCreateViewTransitionInstance,
  startViewTransition: fabricStartViewTransition,
  startViewTransitionReadyFinished: fabricStartViewTransitionReadyFinished,
} = nati

e<void>,
  ready: Promise<void>,
  ...
};

interface ViewTransitionPseudoElementType extends mixin$Animatable {
  _pseudo: string;
  _name: string;
}

function ViewTransitionPseudoElement(
  this: ViewTransitionPseudoElementType,
  pseudo: string,
  name:

veFabricUIManager;

export type InstanceMeasurement = {
  rect: {x: number, y: number, width: number, height: number},
  abs: boolean,
  clip: boolean,
  view: boolean,
};

export type RunningViewTransition = {
  finished: Promis


import type {
  AnyNativeEvent,
  EventTypes,
  LegacyPluginModule,
} from './legacy-events/PluginModuleType';
import type {TopLevelType} from './legacy-events/TopLevelEventTypes';
import SyntheticEvent from './legacy-events/SyntheticEvent';

// Module provided by RN:
import {ReactNativeViewConfigRegistry} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
import accumulateInto from './legacy-events/accumulateInto';
import getListener from './ReactNativeGetListener';
import forEachAccum

 the below functions were inlined from
// EventPropagator.js, as they deviated from ReactDOM's newer
// implementations.
// $FlowFixMe[missing-local-annot]
function listenerAtPhase(inst, event, propagationPhase: PropagationPhases) {
  const registrationNam

ulated from './legacy-events/forEachAccumulated';
import {HostComponent} from 'react-reconciler/src/ReactWorkTags';

const {customBubblingEventTypes, customDirectEventTypes} =
  ReactNativeViewConfigRegistry;

// Start of inline:


nder the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

// These globals are set by React Native (e.g. in setUpDOM.js, setUpTimers.js)
// and provide access to RN's feature flags. We use global functions because we
// don't have another mechanism to pass feature flags from RN to React in OSS.
// Values are lazily evaluated and cached on first access.

let _enableNativeEventTargetEventDispatching: boolean | null = null;
export function enableNativeEventTa

eEventTargetEventDispatching == null) {
    _enableNativeEventTargetEventDispatching =
      typeof RN$isNativeEventTargetEventDispatchingEnabled === 'function' &&
      RN$isNativeEventTargetEventDispatchingEnabled();
  }
  return _enableNativeEventTarget

rgetEventDispatching(): boolean {
  if (_enableNativ


import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
import type {TouchedViewDataAtPoint, InspectorData} from './ReactNativeTypes';

import {
  findCurrentHostFiber,
  findCurrentFiberUsingSlowPath,
} from 'react-reconciler/src/ReactFiberTreeReflection';
import getComponentNameFromType from 'shared/getComponentNameFromType';
import {HostComponent} from 'react-reconciler/src/ReactWorkTags';
// Module provided by RN:
import {getNodeFromPublicInstance} from 'react-native/Libraries/ReactPrivate/R

: (
  closestInstance: Fiber | null,
) => InspectorData;

if (__DEV__) {
  const emptyObject = Object.freeze({});

  // $FlowFixMe[missing-local-annot]
  const createHierarchy = function (fiberHierarchy) {
    return fiberHierarchy.map(fiber => ({
      na

eactNativePrivateInterface';
import {getNodeFromInternalInstanceHandle} from './ReactNativePublicCompat';
import {getStackByFiberInDevAndProd} from 'react-reconciler/src/ReactFiberComponentStack';

let getInspectorDataForInstance


/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';

import {getFiberCurrentPropsFromNode} from './legacy-events/EventPluginUtils';

export default function getListener(
  inst: Fiber,
  registrationName: string,
): Function | null {
  const stateNode = inst.stateNode;
  if (stateNode === nu

stener = props[registrationName];

  if (listener && typeof listener !== 'function') {
    throw new Error(
      `Expected \`${registrationName}\` listener to be a function, instead got a value of \`${typeof listener}\` type.`,
    );
  }

  return listen

ll) {
    // Work in progress (ex: onload events in incremental mode).
    return null;
  }
  const props = getFiberCurrentPropsFromNode(stateNode);
  if (props === null) {
    // Work in progress.
    return null;
  }
  const li


ight (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

/**
 * Make sure essential globals are available and are patched correctly. Please don't remove this
 * line. Bundles created by react-packager `require` it before executing any application code. This
 * ensures it exists in the dependency graph and can be `require`d.
 * TODO: require this in packager, not in React #10

jectEventPluginsByName,
} from './legacy-events/EventPluginRegistry';

import ReactNativeBridgeEventPlugin from './ReactNativeBridgeEventPlugin';
import ReactNativeEventPluginOrder from './ReactNativeEventPluginOrder';

/**
 * Inject module for resolving D

932517
 */
// Module provided by RN:
import 'react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore';

import ResponderEventPlugin from './legacy-events/ResponderEventPlugin';
import {
  injectEventPluginOrder,
  in


t {hasPointerEvent, platform} from './domEnvironment';
import * as touchStore from './touchStore';

/**
 * Converts a PointerEvent payload to a Touch
 */
function createTouch(target, payload) {
  const {
    height = defaultPointerSize,
    pageX,
    pageY,
    pointerId,
    pressure = 1,
    twist = 0,
    width = defaultPointerSize,
    x = 0,
    y = 0,
  } = payload;

  return {
    clientX: x,
    clientY: y,
    force: pressure,
    identifier: pointerId,
    pageX: pageX || x,
    pageY: pageY || y

entPayload(target, touch, payload) {
  const {
    altKey = false,
    ctrlKey = false,
    metaKey = false,
    preventDefault,
    shiftKey = false,
    timeStamp,
  } = payload;

  return {
    altKey,
    changedTouches: [touch],
    ctrlKey,
    metaK

,
    radiusX: width / 2,
    radiusY: height / 2,
    rotationAngle: twist,
    target,
    screenX: x,
    screenY: y + defaultBrowserChromeSize,
  };
}

/**
 * Converts a PointerEvent to a TouchEvent
 */
function createTouchEv


nder the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @emails react-core
 */

'use strict';

import {hasPointerEvent, setPointerEvent} from './domEnvironment';

export function describeWithPointerEvent(message, describeFn) {
  const pointerEvent = 'PointerEvent';
  const fallback = 'MouseEvent/TouchEvent';
  describe.each`
    value    | name
    ${true}  | ${pointerEvent}
    ${false} | ${fallback}
  `(`${message}: $name`, entry => {
    const hasPointerEvents =

    describeFn(hasPointerEvents);
  });
}

export function testWithPointerType(message, testFn) {
  const table = hasPointerEvent()
    ? ['mouse', 'touch', 'pen']
    : ['mouse', 'touch'];
  test.each(table)(`${message}: %s`, pointerType => {
    testFn(

 entry.value;
    setPointerEvent(hasPointerEvents);


;

/**
 * Unit test helpers
 */
describeWithPointerEvent('describeWithPointerEvent', pointerEvent => {
  test('provides boolean to tests', () => {
    expect(pointerEvent).toMatchSnapshot();
  });

  testWithPointerType('testWithPointerType', pointerType => {
    expect(pointerType).toMatchSnapshot();
  });
});

/**
 * createEventTarget
 */
describe('createEventTarget', () => {
  let node;
  beforeEach(() => {
    node = document.createElement('div');
  });

  afterEach(() => {
    node = null;
    resetAct

 "blur",
        "click",
        "focus",
        "keydown",
        "keyup",
        "scroll",
        "virtualclick",
        "contextmenu",
        "pointercancel",
        "pointerdown",
        "pointerhover",
        "pointermove",
        "pointere

ivePointers();
  });

  it('returns expected API', () => {
    const target = createEventTarget(node);
    expect(target.node).toEqual(node);
    expect(Object.keys(target)).toMatchInlineSnapshot(`
      [
        "node",


ct-core
 */

'use strict';

let React;
let ReactDOM;
let ReactIs;
let SuspenseList;

describe('ReactIs', () => {
  beforeEach(() => {
    jest.resetModules();

    React = require('react');
    ReactDOM = require('react-dom');
    ReactIs = require('react-is');

    if (gate(flags => flags.enableSuspenseList)) {
      SuspenseList = React.unstable_SuspenseList;
    }
  });

  it('should return undefined for unknown/invalid types', () => {
    expect(ReactIs.typeOf('abc')).toBe(undefined);
    expect(ReactIs

ed);
    expect(ReactIs.typeOf(NaN)).toBe(undefined);
    expect(ReactIs.typeOf(Symbol('def'))).toBe(undefined);
  });

  it('identifies valid element types', () => {
    class Component extends React.Component {
      render() {
        return React.creat

.typeOf(true)).toBe(undefined);
    expect(ReactIs.typeOf(123)).toBe(undefined);
    expect(ReactIs.typeOf({})).toBe(undefined);
    expect(ReactIs.typeOf(null)).toBe(undefined);
    expect(ReactIs.typeOf(undefined)).toBe(undefin


iliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

const electron = require('electron');
const spawn = require('cross-spawn');
const argv = process.argv.slice(2);
const pkg = require('./package.json');
const updateNotifier = require('update-notifier');

// Notify if there's an update in 7 days' interval
const notifier = updateNotifier({
  pkg,
  updateCheckInterval: 1000 * 60 * 60 * 24 * 7,
});

if (notif

ble ${notifier.update.current} -> ${notifier.update.latest}` +
    '\nTo update:' +
    '\n"npm i [-g] react-devtools" or "yarn add react-devtools"';
  notifier.notify({defer: false, message: updateMsg});
}

const result = spawn.sync(electron, [require.res

ier.update) {
  const updateMsg =
    `Update availa


contextBridge} = require('electron');
const fs = require('fs');
const internalIP = require('internal-ip');

// Expose protected methods so that render process does not need unsafe node integration
contextBridge.exposeInMainWorld('api', {
  electron: {clipboard, shell},
  ip: {address: internalIP.v4.sync},
  getDevTools() {
    let devtools;
    try {
      devtools = require('react-devtools-core/standalone').default;
    } catch (err) {
      alert(
        err.toString() +
          '\n\nDid you run `yarn`

 = {
          key: fs.readFileSync(process.env.KEY),
          cert: fs.readFileSync(process.env.CERT),
        };
        useHttps = true;
      }
    } catch (err) {
      console.error('Failed to process SSL options - ', err);
      options = undefined

 and `yarn run build` in packages/react-devtools-core?',
      );
    }
    return devtools;
  },
  readEnv() {
    let options;
    let useHttps = false;
    try {
      if (process.env.KEY && process.env.CERT) {
        options


ight (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */
import type {ReactBuildType} from 'react-devtools-shared/src/backend/types';

function reduceReactBuild(
  currentReactBuildType: null | ReactBuildType,
  nextReactBuildType: ReactBuildType,
): ReactBuildType {
  if (
    currentReactBuildType === null ||
    currentReactBuildType === 'production'
  ) {
    return nextR

f them is a non-production build, we'll display that instead of "production".
  return nextReactBuildType === 'production'
    ? currentReactBuildType
    : nextReactBuildType;
}

export function createReactRendererListener(target: {
  postMessage: Functio

eactBuildType;
  }

  // We only display the "worst" build type, so if we've already detected a non-production build,
  // we ignore any future production builds. This way if a page has multiple renderers,
  // and at least one o


import type {Size, IntrinsicSize, Rect} from './geometry';
import type {
  Interaction,
  MouseDownInteraction,
  MouseMoveInteraction,
  MouseUpInteraction,
  WheelWithShiftInteraction,
} from './useCanvasInteraction';
import type {ScrollState} from './utils/scrollState';
import type {ViewRefs} from './Surface';
import type {ViewState} from '../types';

import {Surface} from './Surface';
import {View} from './View';
import {rectContainsPoint} from './geometry';
import {
  clampState,
  areScrollStatesEqual

type OnChangeCallback = (
  scrollState: ScrollState,
  containerLength: number,
) => void;

export class VerticalScrollView extends View {
  _contentView: View;
  _isPanning: boolean;
  _mutableViewStateKey: string;
  _onChangeCallback: OnChangeCallback

,
  translateState,
} from './utils/scrollState';
import {MOVE_WHEEL_DELTA_THRESHOLD} from './constants';
import {COLORS} from '../content-views/constants';

const CARET_MARGIN = 3;
const CARET_WIDTH = 5;
const CARET_HEIGHT = 3;


ight (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import type {LayoutInfo, Layouter} from '../layouter';

/**
 * Assumes {@param layout} will only contain 2 views.
 */
export const withVerticalScrollbarLayout: Layouter = (
  layout,
  containerFrame,
) => {
  const [contentLayoutInfo, scrollbarLayoutInfo] = layout;

  const desiredContentSize = contentLayoutInfo.view.

tentLayoutInfo: LayoutInfo = {
    ...contentLayoutInfo,
    frame: {
      origin: contentLayoutInfo.view.frame.origin,
      size: {
        width: containerFrame.size.width - scrollbarWidth,
        height: containerFrame.size.height,
      },
    },

desiredSize();
  const shouldShowScrollbar =
    desiredContentSize.height > containerFrame.size.height;
  const scrollbarWidth = shouldShowScrollbar
    ? scrollbarLayoutInfo.view.desiredSize().width
    : 0;

  const laidOutCon


import type {
  Interaction,
  MouseDownInteraction,
  MouseMoveInteraction,
  MouseUpInteraction,
} from '../useCanvasInteraction';
import type {Rect, Size} from '../geometry';
import type {ViewRefs} from '../Surface';

import {BORDER_SIZE, COLORS} from '../../content-views/constants';
import {drawText} from '../../content-views/utils/text';
import {Surface} from '../Surface';
import {View} from '../View';
import {rectContainsPoint} from '../geometry';
import {noopLayout} from '../layouter';

type ResizeBa

nteractionState: ResizeBarState = 'normal';
  _label: string;

  showLabel: boolean = false;

  constructor(surface: Surface, frame: Rect, label: string) {
    super(surface, frame, noopLayout);

    this._label = label;
  }

  desiredSize(): Size {
    re

rState = 'normal' | 'hovered' | 'dragging';

const RESIZE_BAR_DOT_RADIUS = 1;
const RESIZE_BAR_DOT_SPACING = 4;
const RESIZE_BAR_HEIGHT = 8;
const RESIZE_BAR_WITH_LABEL_HEIGHT = 16;

export class ResizeBarView extends View {
  _i


 MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

// Adapted from: https://github.com/facebookarchive/fixed-data-table/blob/master/src/vendor_upstream/dom/normalizeWheel.js

export type NormalizedWheelDelta = {
  deltaX: number,
  deltaY: number,
};

// Reasonable defaults
const LINE_HEIGHT = 40;
const PAGE_HEIGHT = 800;

/**
 * Mouse wheel (and 2-finger trackpad) support on the web sucks.  It is
 * complicated, thus this doc is long and (hopefully) detail

of the
 * deltas.  This code will return an object with properties:
 *
 *   - deltaX  -- normalized distance (to pixels) - x plane
 *   - deltaY  -- " - y plane
 *
 * Wheel values are provided by the browser assuming you are using the wheel to
 * scroll a

ed enough to answer
 * your questions.
 *
 * If you need to react to the mouse wheel in a predictable way, this code is
 * like your bestest friend. * hugs *
 *
 * In your event callback, use this code to get sane interpretation


import {
  clampState,
  moveStateToRange,
  areScrollStatesEqual,
  translateState,
  zoomState,
} from '../scrollState';

describe('clampState', () => {
  it('should passthrough offset if state fits within container', () => {
    expect(
      clampState({
        state: {offset: 0, length: 50},
        minContentLength: 0,
        maxContentLength: 100,
        containerLength: 50,
      }).offset,
    ).toBeCloseTo(0, 10);
    expect(
      clampState({
        state: {offset: -20, length: 100},

      clampState({
        state: {offset: -1, length: 50},
        minContentLength: 0,
        maxContentLength: 100,
        containerLength: 50,
      }).offset,
    ).toBeCloseTo(0, 10);
    expect(
      clampState({
        state: {offset: 1, lengt

 minContentLength: 0,
        maxContentLength: 100,
        containerLength: 50,
      }).offset,
    ).toBeCloseTo(-20, 10);
  });

  it('should clamp offset if offset causes content to go out of container', () => {
    expect(


  potentialSuspenseEventsOutsideOfTransition: Array<
    [SuspenseEvent, ReactLane[]],
  >,
  requestIdToNetworkMeasureMap: Map<string, NetworkMeasure>,
  uidCounter: BatchUID,
  unresolvedSuspenseEvents: Map<string, SuspenseEvent>,
};

const NATIVE_EVENT_DURATION_THRESHOLD = 20;
const NESTED_UPDATE_DURATION_THRESHOLD = 20;

const WARNING_STRINGS = {
  LONG_EVENT_HANDLER:
    'An event handler scheduled a big update with React. Consider using the Transition API to defer some of this work.',
  NESTED_UPDATE:

ect).',
  SUSPEND_DURING_UPDATE:
    'A component suspended during an update which caused a fallback to be shown. ' +
    "Consider using the Transition API to avoid hiding components after they've been mounted.",
};

// Exported for tests
export function

    'A big nested update was scheduled during layout. ' +
    'Nested updates require React to re-render synchronously before the browser can paint. ' +
    'Consider delaying this update by moving it to a passive effect (useEff


 Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import type {SchedulingEvent} from '../types';

import prettyMilliseconds from 'pretty-ms';

export function formatTimestamp(ms: number): string {
  return (
    ms.toLocaleString(undefined, {
      minimumFractionDigits: 1,
      maximumFractionDigits: 1,
    }) + 'ms'
  );
}

export function formatDuration(ms:

…`;
  }
  return string;
}

export function getSchedulingEventLabel(event: SchedulingEvent): string | null {
  switch (event.type) {
    case 'schedule-render':
      return 'render scheduled';
    case 'schedule-state-update':
      return 'state update s

number): string {
  return prettyMilliseconds(ms, {millisecondsDecimalDigits: 1});
}

export function trimString(string: string, length: number): string {
  if (string.length > length) {
    return `${string.slice(0, length - 1)}


ight (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import memoize from 'memoize-one';

import type {
  BatchUID,
  Milliseconds,
  ReactMeasure,
  TimelineData,
} from '../types';

function unmemoizedGetBatchRange(
  batchUID: BatchUID,
  data: TimelineData,
  minStartTime?: number = 0,
): [Milliseconds, Milliseconds] {
  const measures = data.batchUIDToMeasuresMap.get

Time = lastMeasure.timestamp + lastMeasure.duration;

  if (stopTime < minStartTime) {
    return [0, 0];
  }

  let startTime = minStartTime;
  for (let index = 0; index < measures.length; index++) {
    const measure = measures[index];
    if (measure.ti

(batchUID);
  if (measures == null || measures.length === 0) {
    throw Error(`Could not find measures with batch UID "${batchUID}"`);
  }

  const lastMeasure = ((measures[measures.length - 1]: any): ReactMeasure);
  const stop


ight (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @emails react-core
 */

'use strict';

export const defaultPointerId = 1;
export const defaultPointerSize = 23;
export const defaultBrowserChromeSize = 50;

/**
 * Button property
 * This property only guarantees to indicate which buttons are pressed during events caused by pressing or
 * releasing one or multiple buttons. As suc

rt const buttonType = {
  // no change since last event
  none: -1,
  // left-mouse
  // touch contact
  // pen contact
  primary: 0,
  // right-mouse
  // pen barrel button
  secondary: 2,
  // middle mouse
  auxiliary: 1,
  // back mouse
  back: 3,
  //

h, it is not reliable for events such as 'mouseenter', 'mouseleave',
 * 'mouseover', 'mouseout' or 'mousemove'. Furthermore, the semantics differ for PointerEvent, where the value
 * for 'pointermove' will always be -1.
 */

expo


 MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @emails react-core
 */

'use strict';

import {buttonType, buttonsType} from './constants';
import * as domEvents from './domEvents';
import * as domEventSequences from './domEventSequences';
import {hasPointerEvent, setPointerEvent, platform} from './domEnvironment';
import {describeWithPointerEvent, testWithPointerType} from './testHelpers';

const createEventTarget = node => ({
  node,
  /**
   * Simple events abst

) {
    node.dispatchEvent(domEvents.focus(payload));
    node.dispatchEvent(domEvents.focusIn(payload));
    node.focus();
  },
  keydown(payload) {
    node.dispatchEvent(domEvents.keydown(payload));
  },
  keyup(payload) {
    node.dispatchEvent(domEven

raction.
   */
  blur(payload) {
    node.dispatchEvent(domEvents.blur(payload));
    node.dispatchEvent(domEvents.focusOut(payload));
  },
  click(payload) {
    node.dispatchEvent(domEvents.click(payload));
  },
  focus(payload


'use strict';

import {
  REACT_CONTEXT_TYPE,
  REACT_ELEMENT_TYPE,
  REACT_FORWARD_REF_TYPE,
  REACT_FRAGMENT_TYPE,
  REACT_LAZY_TYPE,
  REACT_MEMO_TYPE,
  REACT_PORTAL_TYPE,
  REACT_PROFILER_TYPE,
  REACT_CONSUMER_TYPE,
  REACT_STRICT_MODE_TYPE,
  REACT_SUSPENSE_TYPE,
  REACT_SUSPENSE_LIST_TYPE,
  REACT_VIEW_TRANSITION_TYPE,
  REACT_SCOPE_TYPE,
  REACT_LEGACY_HIDDEN_TYPE,
  REACT_TRACING_MARKER_TYPE,
} from 'shared/ReactSymbols';

import {
  enableScopeAPI,
  enableTransitionTracing,
  enableLegacyHidden,

= null) {
    const $$typeof = object.$$typeof;
    switch ($$typeof) {
      case REACT_ELEMENT_TYPE:
        const type = object.type;

        switch (type) {
          case REACT_FRAGMENT_TYPE:
          case REACT_PROFILER_TYPE:
          case REACT_S

  enableViewTransition,
} from 'shared/ReactFeatureFlags';

const REACT_CLIENT_REFERENCE: symbol = Symbol.for('react.client.reference');

export function typeOf(object: any): mixed {
  if (typeof object === 'object' && object !=


 Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

const {app, BrowserWindow, shell} = require('electron'); // Module to create native browser window.
const {join} = require('path');
const os = require('os');

const argv = require('minimist')(process.argv.slice(2));
const projectRoots = argv._;

let mainWindow = null;

app.on('window-all-closed', function () {
  app.quit();
});

app.on('ready'

  webPreferences: {
      contextIsolation: true, // protect against prototype pollution
      enableRemoteModule: false, // turn off remote
      sandbox: false, // allow preload script to access file system
      preload: join(__dirname, 'preload.js'), /

, function () {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    icon: join(__dirname, 'icons/icon128.png'),
    frame: false,
    //titleBarStyle: 'customButtonsOnHover',


ionString,
} = require('react-devtools-extensions/utils');
const {resolveFeatureFlags} = require('react-devtools-shared/buildUtils');

const NODE_ENV = process.env.NODE_ENV;
if (!NODE_ENV) {
  console.error('NODE_ENV not set');
  process.exit(1);
}

const __DEV__ = NODE_ENV === 'development';

const EDITOR_URL = process.env.EDITOR_URL || null;

const DEVTOOLS_VERSION = getVersionString();

const babelOptions = {
  configFile: resolve(
    __dirname,
    '..',
    'react-devtools-shared',
    'babel.config.j

ames: './src/hookNames.js',
  },
  output: {
    path: __dirname + '/dist',
    publicPath: '/dist/',
    filename: '[name].js',
    chunkFilename: '[name].chunk.js',
    library: {
      type: 'commonjs2',
    },
  },
  externals: {
    react: 'react',

s',
  ),
};

module.exports = {
  mode: __DEV__ ? 'development' : 'production',
  devtool: __DEV__ ? 'eval-cheap-source-map' : 'source-map',
  entry: {
    backend: './src/backend.js',
    frontend: './src/frontend.js',
    hookN


import type {
  ClickInteraction,
  DoubleClickInteraction,
  Interaction,
  MouseDownInteraction,
  MouseMoveInteraction,
  MouseUpInteraction,
} from '../useCanvasInteraction';
import type {Rect} from '../geometry';
import type {ViewRefs} from '../Surface';
import type {ViewState} from '../../types';

import {ResizeBarView} from './ResizeBarView';
import {Surface} from '../Surface';
import {View} from '../View';
import {rectContainsPoint} from '../geometry';
import {noopLayout} from '../layouter';
import

}>;

type LayoutState = {
  /** Resize bar's vertical position relative to resize view's frame.origin.y */
  barOffsetY: number,
};

const RESIZE_BAR_HEIGHT = 8;
const RESIZE_BAR_WITH_LABEL_HEIGHT = 16;

const HIDDEN_RECT = {
  origin: {x: 0, y: 0},
  size

{clamp} from '../utils/clamp';

type ResizingState = $ReadOnly<{
  /** Distance between top of resize bar and mouseY */
  cursorOffsetInBarFrame: number,
  /** Mouse's vertical coordinates relative to canvas */
  mouseY: number,


 MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import {clamp} from './clamp';

/**
 * Single-axis offset and length state.
 *
 * ```
 * contentStart   containerStart  containerEnd   contentEnd
 *     |<----------offset|              |             |
 *     |<-------------------length------------------->|
 * ```
 */
export type ScrollState = {
  offset: number,
  length: number,
};

function clampOffset(state: ScrollState, containerLength: number): Scroll

ScrollState,
  minContentLength: number,
  maxContentLength: number,
  containerLength: number,
}): ScrollState {
  return {
    offset: state.offset,
    length: clamp(
      Math.max(minContentLength, containerLength),
      Math.max(containerLength, max

State {
  return {
    offset: clamp(-(state.length - containerLength), 0, state.offset),
    length: state.length,
  };
}

function clampLength({
  state,
  minContentLength,
  maxContentLength,
  containerLength,
}: {
  state:


**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

// This file uses workerize to load ./importFile.worker as a webworker and instanciates it,
// exposing flow typed functions that can be used on other files.

import * as importFileModule from './importFile';
import WorkerizedImportFile from './importFile.worker';

import type {TimelineData} from '../types';

ssedData: TimelineData}
  | {status: 'INVALID_PROFILE_ERROR', error: Error}
  | {status: 'UNEXPECTED_ERROR', error: Error};

export type importFileFunction = (file: File) => ImportWorkerOutputData;

export const importFile = (file: File): Promise<ImportWor

type ImportFileModule = typeof importFileModule;

const workerizedImportFile: ImportFileModule = window.Worker
  ? WorkerizedImportFile()
  : importFileModule;

export type ImportWorkerOutputData =
  | {status: 'SUCCESS', proce


iates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import {useLayoutEffect, useRef} from 'react';

const TOOLTIP_OFFSET_BOTTOM = 10;
const TOOLTIP_OFFSET_TOP = 5;

export default function useSmartTooltip({
  canvasRef,
  mouseX,
  mouseY,
}: {
  canvasRef: {current: HTMLCanvasElement | null},
  mouseX: number,
  mouseY: number,
}): {current: HTMLElement | null} {
  const ref = useRef<HTMLElement | null>(nul

 if (target !== null) {
    const rect = target.getBoundingClientRect();
    height = rect.top + rect.height;
    width = rect.left + rect.width;
  }

  useLayoutEffect(() => {
    const element = ref.current;
    if (element !== null) {
      // Let's che

l);

  // HACK: Browser extension reports window.innerHeight of 0,
  // so we fallback to using the tooltip target element.
  let height = window.innerHeight;
  let width = window.innerWidth;
  const target = canvasRef.current;


 Each event type defines the exact object that it accepts. This ensures
 * that no arbitrary properties can be assigned to events, and the properties
 * that don't exist on specific event types (e.g., 'pointerType') are not added
 * to the respective native event.
 *
 * 2. Properties that cannot be relied on due to inconsistent browser support (e.g., 'x' and 'y') are not
 * added to the native event. Others that shouldn't be arbitrarily customized (e.g., 'screenX')
 * are automatically inferred from associa

');
  event.initCustomEvent(type, true, true);
  if (data != null) {
    Object.keys(data).forEach(key => {
      const value = data[key];
      if (key === 'timeStamp' && !value) {
        return;
      }
      Object.defineProperty(event, key, {value});

ted values.
 *
 * 3. PointerEvent and TouchEvent fields are normalized (e.g., 'rotationAngle' -> 'twist')
 */

function emptyFunction() {}

function createEvent(type, data = {}) {
  const event = document.createEvent('CustomEvent


onst fs = require('fs');
const ReactVersionSrc = fs.readFileSync(require.resolve('shared/ReactVersion'));
const reactVersion = /export default '([^']+)';/.exec(ReactVersionSrc)[1];

const config = {
  use: {
    headless: true,
    browserName: 'chromium',
    launchOptions: {
      // This bit of delay gives async React time to render
      // and DevTools operations to be sent across the bridge.
      slowMo: 100,
    },
    url: process.env.REACT_VERSION
      ? 'http://localhost:8080/e2e-regression.html

t_version: process.env.REACT_VERSION
      ? semver.coerce(process.env.REACT_VERSION).version
      : reactVersion,
    trace: 'retain-on-failure',
  },
  // Some of our e2e tests can be flaky. Retry tests to make sure the error isn't transient
  retries:

'
      : 'http://localhost:8080/e2e.html',
    reac


 MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import type {Rect} from '../../view-base';

import {rectEqualToRect} from '../../view-base';
import {COLORS, FONT_SIZE, TEXT_PADDING} from '../constants';

const cachedTextWidths = new Map<string, number>();

export function getTextWidth(
  context: CanvasRenderingContext2D,
  text: string,
): number {
  let measuredWidth = cachedTextWidths.get(text);
  if (measuredWidth == null) {
    measuredWidth = conte

 | null {
  const maxIndex = text.length - 1;

  let startIndex = 0;
  let stopIndex = maxIndex;

  let longestValidIndex = 0;
  let longestValidText = null;

  // Trimming long text could be really slow if we decrease only 1 character at a time.
  // Trim

xt.measureText(text).width;
    cachedTextWidths.set(text, measuredWidth);
  }

  return ((measuredWidth: any): number);
}

export function trimText(
  context: CanvasRenderingContext2D,
  text: string,
  width: number,
): string


ource code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import nullthrows from 'nullthrows';
import InvalidProfileError from './InvalidProfileError';

export const readInputData = (file: File): Promise<string> => {
  if (!file.name.endsWith('.json')) {
    throw new InvalidProfileError(
      'Invalid file type. Only JSON performance profiles are supported',
    );
  }

  const fileReader = new FileReader();

  return new Promise(

 {
      const result = nullthrows(fileReader.result);
      if (typeof result === 'string') {
        resolve(result);
      }
      reject(new InvalidProfileError('Input file was not read as a string'));
    };

    fileReader.onerror = () => reject(file

(resolve, reject) => {
    fileReader.onload = () =>


 Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @emails react-core
 */

'use strict';

/**
 * Change environment support for PointerEvent.
 */

function emptyFunction() {}

export function hasPointerEvent() {
  return global != null && global.PointerEvent != null;
}

export function setPointerEvent(bool) {
  const pointerCaptureFn = name => id => {
    if (typeof id !== 'number') {
      i

ptureFn('setPointerCapture')
    : undefined;
  global.HTMLElement.prototype.releasePointerCapture = bool
    ? pointerCaptureFn('releasePointerCapture')
    : undefined;
}

/**
 * Change environment host platform.
 */

const platformGetter = jest.spyOn(gl

f (__DEV__) {
        console.error('A pointerId must be passed to "%s"', name);
      }
    }
  };
  global.PointerEvent = bool ? emptyFunction : undefined;
  global.HTMLElement.prototype.setPointerCapture = bool
    ? pointerCa


 Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import 'regenerator-runtime/runtime';

import type {TimelineEvent} from '@elg/speedscope';
import type {ImportWorkerOutputData} from './index';

import preprocessData from './preprocessData';
import {readInputData} from './readInputData';
import InvalidProfileError from './InvalidProfileError';

export async func

idProfileError('No profiling data found in file.');
    }

    const processedData = await preprocessData(events);

    return {
      status: 'SUCCESS',
      processedData,
    };
  } catch (error) {
    if (error instanceof InvalidProfileError) {

tion importFile(file: File): Promise<ImportWorkerOutputData> {
  try {
    const readFile = await readInputData(file);
    const events: TimelineEvent[] = JSON.parse(readFile);
    if (events.length === 0) {
      throw new Inval


iates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @emails react-core
 */

'use strict';

/**
 * Touch events state machine.
 *
 * Keeps track of the active pointers and allows them to be reflected in touch events.
 */

const activeTouches = new Map();

export function addTouch(touch) {
  const identifier = touch.identifier;
  const target = touch.target;
  if (!activeTouches.has(target)) {
    activeTouches.set(targe

dentifier,
    );
  } else {
    activeTouches.get(target).set(identifier, touch);
  }
}

export function updateTouch(touch) {
  const identifier = touch.identifier;
  const target = touch.target;
  if (activeTouches.get(target) != null) {
    activeTouche

t, new Map());
  }
  if (activeTouches.get(target).get(identifier)) {
    // Do not allow existing touches to be overwritten
    console.error(
      'Touch with identifier %s already exists. Did not record touch start.',
      i


;

// Mock of the Native Hooks

const roots = new Map();
const allocatedTags = new Set();

function dumpSubtree(info, indent) {
  let out = '';
  out += ' '.repeat(indent) + info.viewName + ' ' + JSON.stringify(info.props);
  // eslint-disable-next-line no-for-of-loops/no-for-of-loops
  for (const child of info.children) {
    out += '\n' + dumpSubtree(child, indent + 2);
  }
  return out;
}

const RCTFabricUIManager = {
  __dumpChildSetForJestTestsOnly: function (childSet) {
    const result = [];
    // e

onst result = [];
    // eslint-disable-next-line no-for-of-loops/no-for-of-loops
    for (const [rootTag, childSet] of roots) {
      result.push(rootTag);
      // eslint-disable-next-line no-for-of-loops/no-for-of-loops
      for (const child of childSe

slint-disable-next-line no-for-of-loops/no-for-of-loops
    for (const child of childSet) {
      result.push(dumpSubtree(child, 0));
    }
    return result.join('\n');
  },
  __dumpHierarchyForJestTestsOnly: function () {
    c


ight (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow strict-local
 */

module.exports = {
  get ReactFiberErrorDialog() {
    return require('./ReactFiberErrorDialog');
  },
  get ReactNativeViewConfigRegistry() {
    return require('./ReactNativeViewConfigRegistry');
  },
  get deepFreezeAndThrowOnMutationInDev() {
    return require('./deepFreezeAndThrowOnMutationInDev');

    return require('./getNodeFromPublicInstance').default;
  },
  get createPublicInstance() {
    return require('./createPublicInstance').default;
  },
  get createPublicTextInstance() {
    return require('./createPublicTextInstance').default;
  },
  g

 },
  get RawEventEmitter() {
    return require('./RawEventEmitter').default;
  },
  get getNativeTagFromPublicInstance() {
    return require('./getNativeTagFromPublicInstance').default;
  },
  get getNodeFromPublicInstance() {


iates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 */

'use strict';

type Options = {+unsafelyIgnoreFunctions?: boolean};

/*
 * @returns {bool} true if different, false if equal
 */
function deepDiffer(
  one: any,
  two: any,
  maxDepthOrOptions: Options | number = -1,
  maybeOptions?: Options,
): boolean {
  const options =
    typeof maxDepthOrOptions === 'number' ? maybeOptions : maxDepthOrOptions;
  const maxDept

false;
  }
  if (typeof one === 'function' && typeof two === 'function') {
    // We consider all functions equal unless explicitly configured otherwise
    let unsafelyIgnoreFunctions =
      options == null ? null : options.unsafelyIgnoreFunctions;
    i

h =
    typeof maxDepthOrOptions === 'number' ? maxDepthOrOptions : -1;
  if (maxDepth === 0) {
    return true;
  }
  if (one === two) {
    // Short circuit on identical object references instead of traversing them.
    return


import type {DispatchConfig} from './ReactSyntheticEventType';
import type {
  AnyNativeEvent,
  PluginName,
  LegacyPluginModule,
} from './PluginModuleType';
import type {TopLevelType} from './TopLevelEventTypes';

type NamesToPlugins = {
  [key: PluginName]: LegacyPluginModule<AnyNativeEvent>,
};
type EventPluginOrder = null | Array<PluginName>;

/**
 * Injectable ordering of event plugins.
 */
let eventPluginOrder: EventPluginOrder = null;

/**
 * Injectable mapping from names to event plugin modules.

 until an `eventPluginOrder` is injected.
    return;
  }
  for (const pluginName in namesToPlugins) {
    const pluginModule = namesToPlugins[pluginName];
    // $FlowFixMe[incompatible-use] found when upgrading Flow
    const pluginIndex = eventPluginOrd

*/
const namesToPlugins: NamesToPlugins = {};

/**
 * Recomputes the plugin list using the injected plugins and plugin ordering.
 *
 * @private
 */
function recomputePluginOrdering(): void {
  if (!eventPluginOrder) {
    // Wait


import type {Node} from './ReactNativeTypes';
import type {ElementRef, ElementType} from 'react';
import type {PublicInstance} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';

// Modules provided by RN:
import {
  getNodeFromPublicInstance,
  getNativeTagFromPublicInstance,
  getInternalInstanceHandleFromPublicInstance,
} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';

import {
  findHostInstance,
  findHostInstanceWithWarning,
} from 'react-reconciler/src/Re

m 'react-reconciler/src/ReactCurrentFiber';

export function findHostInstance_DEPRECATED<TElementType: ElementType>(
  componentOrHandle: ?(ElementRef<TElementType> | number),
): ?PublicInstance {
  if (__DEV__) {
    const owner = currentOwner;
    if (ow

actFiberReconciler';
import {doesFiberContain} from 'react-reconciler/src/ReactFiberTreeReflection';
import getComponentNameFromType from 'shared/getComponentNameFromType';
import {
  current as currentOwner,
  isRendering,
} fro


ct-core
 */

'use strict';

describe('EventPluginRegistry', () => {
  let EventPluginRegistry;
  let createPlugin;

  beforeEach(() => {
    jest.resetModules();
    // These tests are intentionally testing the private injection interface.
    // The public API surface of this is covered by other tests so
    // if `EventPluginRegistry` is ever deleted, these tests should be
    // safe to remove too.
    EventPluginRegistry = require('react-native-renderer/src/legacy-events/EventPluginRegistry');

    crea

const TwoPlugin = createPlugin();
    const ThreePlugin = createPlugin();

    EventPluginRegistry.injectEventPluginOrder(['one', 'two', 'three']);
    EventPluginRegistry.injectEventPluginsByName({
      one: OnePlugin,
      two: TwoPlugin,
    });
    E

tePlugin = function (properties) {
      return Object.assign({extractEvents: function () {}}, properties);
    };
  });

  it('should be able to inject ordering before plugins', () => {
    const OnePlugin = createPlugin();


 MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @emails react-core
 * @jest-environment node
 */

'use strict';

let React;
let ReactFabric;
let createReactNativeComponentClass;
let act;
let View;
let Text;

describe('Fabric FragmentRefs', () => {
  beforeEach(() => {
    jest.resetModules();

    require('react-native/Libraries/ReactPrivate/InitializeNativeFabricUIManager');

    React = require('react');
    ReactFabric = require('react-native-renderer/fabric');

teReactNativeComponentClass('RCTView', () => ({
      validAttributes: {nativeID: true},
      uiViewClassName: 'RCTView',
    }));
    Text = createReactNativeComponentClass('RCTText', () => ({
      validAttributes: {nativeID: true},
      uiViewClassNam

    createReactNativeComponentClass =
      require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface')
        .ReactNativeViewConfigRegistry.register;
    ({act} = require('internal-test-utils'));
    View = crea


ay from 'shared/isArray';

import {runWithFiberInDEV} from 'react-reconciler/src/ReactCurrentFiber';

let hasError = false;
let caughtError = null;

export let getFiberCurrentPropsFromNode = null;
export let getInstanceFromNode = null;
export let getNodeFromInstance = null;

export function setComponentTree(
  getFiberCurrentPropsFromNodeImpl,
  getInstanceFromNodeImpl,
  getNodeFromInstanceImpl,
) {
  getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl;
  getInstanceFromNode = getInstanceFromNo

nstanceFromNode.',
      );
    }
  }
}

function validateEventDispatches(event) {
  if (__DEV__) {
    const dispatchListeners = event._dispatchListeners;
    const dispatchInstances = event._dispatchInstances;

    const listenersIsArr = isArray(dispatch

deImpl;
  getNodeFromInstance = getNodeFromInstanceImpl;
  if (__DEV__) {
    if (!getNodeFromInstance || !getInstanceFromNode) {
      console.error(
        'Injected ' +
          'module is missing getNodeFromInstance or getI


oo: true},
      uiViewClassName: 'RCTView',
    }));

    await act(() => {
      ReactFabric.render(<View foo="test" />, 1, null, true);
    });
    expect(nativeFabricUIManager.createNode).toBeCalled();
    expect(nativeFabricUIManager.appendChild).not.toBeCalled();
    expect(nativeFabricUIManager.completeRoot).toBeCalled();
  });

  it('should be able to create and update a native component', async () => {
    const View = createReactNativeComponentClass('RCTView', () => ({
      validAttributes: {foo:

    });

    expect(nativeFabricUIManager.createNode).toHaveBeenCalledTimes(1);

    await act(() => {
      ReactFabric.render(<View foo="bar" />, 11, null, true);
    });

    expect(nativeFabricUIManager.createNode).toHaveBeenCalledTimes(1);
    expect(

 true},
      uiViewClassName: 'RCTView',
    }));

    const firstNode = {};

    nativeFabricUIManager.createNode.mockReturnValue(firstNode);

    await act(() => {
      ReactFabric.render(<View foo="foo" />, 11, null, true);


 = 0; i < arr.length; i++) {
    if (indices.indexOf(i) === -1) {
      ret.push(arr[i]);
    }
  }
  return ret;
};

/**
 * Helper for creating touch test config data.
 * @param allTouchHandles
 */
const _touchConfig = function (
  topType,
  targetNodeHandle,
  allTouchHandles,
  changedIndices,
  eventTarget,
) {
  const allTouchObjects = allTouchHandles.map(touch);
  const changedTouchObjects = subsequence(allTouchObjects, changedIndices);
  const activeTouchObjects =
    topType === 'topTouchStart'

   ? antiSubsequence(allTouchObjects, changedIndices)
            : null;

  return {
    nativeEvent: touchEvent(
      targetNodeHandle,
      activeTouchObjects,
      changedTouchObjects,
    ),
    topLevelType: topType,
    targetInst: getInstanceFro

   ? allTouchObjects
      : topType === 'topTouchMove'
        ? allTouchObjects
        : topType === 'topTouchEnd'
          ? antiSubsequence(allTouchObjects, changedIndices)
          : topType === 'topTouchCancel'


 startLoggingProfilingEvents,
} from '../SchedulerProfiling';

type Callback = boolean => ?Callback;

type Task = {
  id: number,
  callback: Callback | null,
  priorityLevel: PriorityLevel,
  startTime: number,
  expirationTime: number,
  sortIndex: number,
  isQueued?: boolean,
};

// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
// Math.pow(2, 30) - 1
// 0b111111111111111111111111111111
var maxSigned31BitInt = 1073741823;

// Times out immediately
var IMMEDIATE_PRIORITY_TIMEOUT = -1;

min heap
var taskQueue: Array<Task> = [];
var timerQueue: Array<Task> = [];

// Incrementing id counter. Used to maintain insertion order.
var taskIdCounter = 1;

var currentTask = null;
var currentPriorityLevel: PriorityLevel = NormalPriority;

// This is

// Eventually times out
var USER_BLOCKING_PRIORITY_TIMEOUT = 250;
var NORMAL_PRIORITY_TIMEOUT = 5000;
var LOW_PRIORITY_TIMEOUT = 10000;
// Never times out
var IDLE_PRIORITY_TIMEOUT = maxSigned31BitInt;

// Tasks are stored on a


 MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow strict
 */

import * as Scheduler from './Scheduler';
import type {Callback, Task} from './Scheduler';
import type {PriorityLevel} from '../SchedulerPriorities';
import typeof * as PriorityLevels from '../SchedulerPriorities';
import typeof * as SchedulerExportsType from './Scheduler';
import typeof * as SchedulerNativeExportsType from './SchedulerNative';

// This type is supposed to reflect the actual methods

Type = {
  unstable_ImmediatePriority: PriorityLevels['ImmediatePriority'],
  unstable_UserBlockingPriority: PriorityLevels['UserBlockingPriority'],
  unstable_NormalPriority: PriorityLevels['NormalPriority'],
  unstable_IdlePriority: PriorityLevels['IdleP

and arguments currently supported by the C++ implementation:
// https://github.com/facebook/react-native/blob/main/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.cpp
type NativeScheduler


import type {PriorityLevel} from '../SchedulerPriorities';

declare class TaskController {
  constructor(options?: {priority?: string}): TaskController;
  signal: mixed;
  abort(): void;
}

type PostTaskPriorityLevel = 'user-blocking' | 'user-visible' | 'background';

type CallbackNode = {
  _controller: TaskController,
};

import {
  ImmediatePriority,
  UserBlockingPriority,
  NormalPriority,
  LowPriority,
  IdlePriority,
} from '../SchedulerPriorities';

export {
  ImmediatePriority as unstable_Immediat

ative APIs, in case a polyfill overrides them.
const perf = window.performance;
const setTimeout = window.setTimeout;

// Use experimental Chrome Scheduler postTask API.
const scheduler = global.scheduler;

const getCurrentTime: () => DOMHighResTimeStamp =

ePriority,
  UserBlockingPriority as unstable_UserBlockingPriority,
  NormalPriority as unstable_NormalPriority,
  IdlePriority as unstable_IdlePriority,
  LowPriority as unstable_LowPriority,
};

// Capture local references to n


ee.
 */

'use strict';

(function (global, factory) {
  // eslint-disable-next-line ft-flow/no-unused-expressions
  typeof exports === 'object' && typeof module !== 'undefined'
    ? (module.exports = factory(require('react')))
    : typeof define === 'function' && define.amd // eslint-disable-line no-undef
      ? define(['react'], factory) // eslint-disable-line no-undef
      : (global.Scheduler = factory(global));
})(this, function (global) {
  function unstable_now() {
    return global.React.__CLIENT_

SERS_THEY_CANNOT_UPGRADE.Scheduler.unstable_scheduleCallback.apply(
      this,
      arguments
    );
  }

  function unstable_cancelCallback() {
    return global.React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE.Scheduler.unstable_ca

INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE.Scheduler.unstable_now.apply(
      this,
      arguments
    );
  }

  function unstable_scheduleCallback() {
    return global.React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_U


, Array<any>> {
  // This initializes a cache of all primitive hooks so that the top
  // most stack frames added by calling the primitive hook can be removed.
  if (primitiveStackCache === null) {
    const cache = new Map<string, Array<any>>();
    let readHookLog;
    try {
      // Use all hooks here to add them to the hook log.
      Dispatcher.useContext(({_currentValue: null}: any));
      Dispatcher.useState(null);
      Dispatcher.useReducer((s: mixed, a: mixed) => s, null);
      Dispatcher.useRef

rtionEffect(() => {});
      Dispatcher.useEffect(() => {});
      Dispatcher.useImperativeHandle(undefined, () => null);
      Dispatcher.useDebugValue(null);
      Dispatcher.useCallback(() => {});
      Dispatcher.useTransition();
      Dispatcher.useSy

(null);
      if (typeof Dispatcher.useCacheRefresh === 'function') {
        // This type check is for Flow only.
        Dispatcher.useCacheRefresh();
      }
      Dispatcher.useLayoutEffect(() => {});
      Dispatcher.useInse


 let scheduleUpdate;
  let scheduleRetry;
  let setSuspenseHandler;
  let waitForAll;

  global.IS_REACT_ACT_ENVIRONMENT = true;

  beforeEach(() => {
    global.__REACT_DEVTOOLS_GLOBAL_HOOK__ = {
      inject: injected => {
        overrideHookState = injected.overrideHookState;
        scheduleUpdate = injected.scheduleUpdate;
        scheduleRetry = injected.scheduleRetry;
        setSuspenseHandler = injected.setSuspenseHandler;
      },
      supportsFiber: true,
      onCommitFiberRoot: () => {},

Utils = require('internal-test-utils');
    waitForAll = InternalTestUtils.waitForAll;

    act = require('internal-test-utils').act;
  });

  it('should support editing useState hooks', async () => {
    let setCountFn;

    function MyComponent() {

  onCommitFiberUnmount: () => {},
    };

    jest.resetModules();

    React = require('react');
    ReactDebugTools = require('react-debug-tools');
    ReactTestRenderer = require('react-test-renderer');

    const InternalTest


{
      const [state] = React.useState('hello world');
      return <div>{state}</div>;
    }
    const tree = ReactDebugTools.inspectHooks(Foo, {});
    expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
      [
        {
          "debugInfo": null,
          "hookSource": {
            "columnNumber": 0,
            "fileName": "**",
            "functionName": "Foo",
            "lineNumber": 0,
          },
          "id": 0,
          "isStateEditable": true,
          "name": "State",

DebugValue('custom hook label');
      return state;
    }
    function Foo(props) {
      const value = useCustom('hello world');
      return <div>{value}</div>;
    }
    const tree = ReactDebugTools.inspectHooks(Foo, {});
    if (__DEV__) {
      expec

 "subHooks": [],
          "value": "hello world",
        },
      ]
    `);
  });

  it('should inspect a simple custom hook', () => {
    function useCustom(value) {
      const [state] = React.useState(value);
      React.use


er": 0,
          },
          "id": 1,
          "isStateEditable": true,
          "name": "State",
          "subHooks": [],
          "value": "world",
        },
      ]
    `);

    await act(() => setStateB('world!'));

    childFiber = renderer.root.findByType(Foo)._currentFiber();
    tree = ReactDebugTools.inspectHooksOfFiber(childFiber);

    expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
      [
        {
          "debugInfo": null,
          "hookSource": {
            "columnNumber"

"value": "Hi",
        },
        {
          "debugInfo": null,
          "hookSource": {
            "columnNumber": 0,
            "fileName": "**",
            "functionName": "Foo",
            "lineNumber": 0,
          },
          "id": 1,

: 0,
            "fileName": "**",
            "functionName": "Foo",
            "lineNumber": 0,
          },
          "id": 0,
          "isStateEditable": true,
          "name": "State",
          "subHooks": [],


 MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @emails react-core
 * @jest-environment jsdom
 */

'use strict';

let React;
let ReactDOM;
let ReactDOMClient;
let ReactDebugTools;
let act;

function normalizeSourceLoc(tree) {
  tree.forEach(node => {
    if (node.hookSource) {
      node.hookSource.fileName = '**';
      node.hookSource.lineNumber = 0;
      node.hookSource.columnNumber = 0;
    }
    normalizeSourceLoc(node.subHooks);
  });
  return tree;
}

descr

internal-test-utils').act;
    ReactDebugTools = require('react-debug-tools');
  });

  it('should support useFormStatus hook', async () => {
    function FormStatus() {
      const status = ReactDOM.useFormStatus();
      React.useMemo(() => 'memo', []);

ibe('ReactHooksInspectionIntegration', () => {
  beforeEach(() => {
    jest.resetModules();
    React = require('react');
    ReactDOM = require('react-dom');
    ReactDOMClient = require('react-dom/client');
    act = require('


 from 'react';
import {Component} from 'react';
import {findDOMNode} from 'react-dom';
import {Link} from 'react-router-dom';
import {connect} from 'react-redux';
import {store} from '../store';

import ThemeContext from './shared/ThemeContext';
import Clock from './shared/Clock';

store.subscribe(() => {
  console.log('Counter:', store.getState());
});

class AboutSection extends Component {
  componentDidMount() {
    // The modern app is wrapped in StrictMode,
    // but the legacy bits can still use old

              This component is rendered by the nested React ({React.version}).

            <Clock />

              Counter: {this.props.counter}{' '}
              <button onClick={() => thi

APIs.
    findDOMNode(this);
  }
  render() {
    return (
      <ThemeContext.Consumer>
        {theme => (

src/legacy/Greeting.js


sable react/jsx-pascal-case */

import React from 'react';
import ReactDOM from 'react-dom';
import ThemeContext from './shared/ThemeContext';

// Note: this is a semi-private API, but it's ok to use it
// if we never inspect the values, and only pass them through.
import {__RouterContext} from 'react-router';
import {Provider} from 'react-redux';

// Pass through every context required by this tree.
// The context object is populated in src/modern/withLegacyRoot.
function Bridge({children, context}) {
  re

ort {ReactReduxContext} from 'react-redux'
          and render <ReactReduxContext.Provider value={context.reactRedux}>.
        */}
        <Provider store={context.reactRedux.store}>{children}</Provider>
      </__RouterContext.Provider>
    </ThemeConte

turn (
    <ThemeContext.Provider value={context.theme}>
      <__RouterContext.Provider value={context.router}>
        {/*
          If we used the newer react-redux@7.x in the legacy/package.json,
          we woud instead imp


from 'react';
import {connect} from 'react-redux';

import ThemeContext from './shared/ThemeContext';
import lazyLegacyRoot from './lazyLegacyRoot';

// Lazy-load a component from the bundle using legacy React.
const Greeting = lazyLegacyRoot(() => import('../legacy/Greeting'));

function AboutPage({counter, dispatch}) {
  const theme = useContext(ThemeContext);
  return (
    <>

src/modern/AboutPage.js

        This component is rendered by the outer React ({

        Counter: {counter}{' '}
        <button onClick={() => dispatch({type: 'increment'})}>+</button>

    </>
  );
}

function mapStateToProps(state) {
  return {counter: state};
}

export default connect(mapStateToProps)(A

React.version}).
      </h3>
      <Greeting />


 from 'react';
import {useState, Suspense} from 'react';
import {BrowserRouter, Switch, Route} from 'react-router-dom';

import HomePage from './HomePage';
import AboutPage from './AboutPage';
import ThemeContext from './shared/ThemeContext';

export default function App() {
  const [theme, setTheme] = useState('slategrey');

  function handleToggleClick() {
    if (theme === 'slategrey') {
      setTheme('hotpink');
    } else {
      setTheme('slategrey');
    }
  }

  return (
    <BrowserRouter>
      <

 minHeight: 300,
            }}>
            <button onClick={handleToggleClick}>Toggle Theme Context</button>
            <br />
            <Suspense fallback={<Spinner />}>
              <Switch>
                <Route path="/about">
                  <

ThemeContext.Provider value={theme}>
        <div style={{fontFamily: 'sans-serif'}}>
          <div
            style={{
              margin: 20,
              padding: 20,
              border: '1px solid black',


emo, useRef, useState, useLayoutEffect} from 'react';
import {__RouterContext} from 'react-router';
import {ReactReduxContext} from 'react-redux';

import ThemeContext from './shared/ThemeContext';

let rendererModule = {
  status: 'pending',
  promise: null,
  result: null,
};

export default function lazyLegacyRoot(getLegacyComponent) {
  let componentModule = {
    status: 'pending',
    promise: null,
    result: null,
  };

  return function Wrapper(props) {
    const createLegacyRoot = readModule(

ull);

    // Populate every contexts we want the legacy subtree to see.
    // Then in src/legacy/createLegacyRoot we will apply them.
    const theme = useContext(ThemeContext);
    const router = useContext(__RouterContext);
    const reactRedux = useCo

   rendererModule,
      () => import('../legacy/createLegacyRoot')
    ).default;
    const Component = readModule(componentModule, getLegacyComponent).default;
    const containerRef = useRef(null);
    const rootRef = useRef(n


=== void 0) {
    throw new ReferenceError(
      "this hasn't been initialised - super() hasn't been called"
    );
  }
  return self;
}
function _defineProperty(obj, key, value) {
  key = _toPropertyKey(key);
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true,
    });
  } else {
    obj[key] = value;
  }
  return obj;
}
function _toPropertyKey(t) {
  var i = _toPrimitive(t, 'string');
  return 'symbol' == typ

    throw new TypeError('@@toPrimitive must return a primitive value.');
  }
  return ('string' === r ? String : Number)(t);
}
function _inheritsLoose(subClass, superClass) {
  subClass.prototype = Object.create(superClass.prototype);
  subClass.prototype

eof i ? i : i + '';
}
function _toPrimitive(t, r) {
  if ('object' != typeof t || !t) return t;
  var e = t[Symbol.toPrimitive];
  if (void 0 !== e) {
    var i = e.call(t, r || 'default');
    if ('object' != typeof i) return i;


lClass, BabelClassWithFields} from './BabelClasses-compiled.js';
import {
  Throw,
  Component,
  DisplayName,
  NativeClass,
  FrozenClass,
} from './Components.js';

const x = React.createElement;

class ErrorBoundary extends React.Component {
  static getDerivedStateFromError(error) {
    return {
      error: error,
    };
  }

  componentDidCatch(error, errorInfo) {
    console.log(error.message, errorInfo.componentStack);
    this.setState({
      componentStack: errorInfo.componentStack,
    });
  }

s.props.children;
  }
}

export default function Example() {
  let state = React.useState(false);
  return x(
    ErrorBoundary,
    null,
    x(
      DisplayName,
      null,
      x(
        NativeClass,
        null,
        x(
          FrozenClass,

  render() {
    if (this.state && this.state.error) {
      return x(
        'div',
        null,
        x('h3', null, this.state.error.message),
        x('pre', null, this.state.componentStack)
      );
    }
    return thi


ictoryBar,
  VictoryTheme,
  VictoryScatter,
  VictoryStack,
} from 'victory';

const colors = ['#fff489', '#fa57c1', '#b166cc', '#7572ff', '#69a6f9'];

export default class Charts extends PureComponent {
  render() {
    const streamData = this.props.data;
    return (

          <VictoryChart
            theme={VictoryTheme.material}
            width={400}
            height={400}
            style={{
              parent: {
                backgroundCol

ryAxis
              style={{
                axis: {stroke: 'white'},
                tickLabels: {fill: 'white'},
              }}
              dependentAxis
            />
            <VictoryScatter
              data={streamData[0]}
              siz

or: '#222',
              },
            }}>
            <VictoryAxis
              style={{
                axis: {stroke: 'white'},
                tickLabels: {fill: 'white'},
              }}
            />
            <Victo


t';

const SPEED = 0.003 / Math.PI;
const FRAMES = 10;

export default class Clock extends PureComponent {
  faceRef = createRef();
  arcGroupRef = createRef();
  clockHandRef = createRef();
  frame = null;
  hitCounter = 0;
  rotation = 0;
  t0 = Date.now();
  arcs = [];

  animate = () => {
    const now = Date.now();
    const td = now - this.t0;
    this.rotation = (this.rotation + SPEED * td) % (2 * Math.PI);
    this.t0 = now;

    this.arcs.push({rotation: this.rotation, td});

    let lx, ly, tx, ty

;
        const bigArc = SPEED * td < Math.PI ? '0' : '1';
        const path = `M${tx} ${ty}A${r} ${r} 0 ${bigArc} 0 ${lx} ${ly}L155 155`;
        const hue = 120 - Math.min(120, td / 4);
        const colour = `hsl(${hue}, 100%, ${60 - i * (30 / FRAMES)}

;
    if (this.arcs.length > FRAMES) {
      this.arcs.forEach(({rotation, td}, i) => {
        lx = tx;
        ly = ty;
        const r = 145;
        tx = 155 + r * Math.cos(rotation);
        ty = 155 + r * Math.sin(rotation)


t';
import _ from 'lodash';
import Charts from './Charts';
import Clock from './Clock';
import './index.css';

let cachedData = new Map();

class App extends PureComponent {
  state = {
    value: '',
    strategy: 'sync',
    showDemo: true,
    showClock: false,
  };

  // Random data for the chart
  getStreamData(input) {
    if (cachedData.has(input)) {
      return cachedData.get(input);
    }
    const multiplier = input.length !== 0 ? input.length : 1;
    const complexity =
      (parseInt(window.lo

 })
    );
    cachedData.set(input, data);
    return data;
  }

  componentDidMount() {
    window.addEventListener('keydown', e => {
      if (e.key.toLowerCase() === '?') {
        e.preventDefault();
        this.setState(state => ({
          showClo

cation.search.slice(1), 10) / 100) * 25 || 25;
    const data = _.range(5).map(t =>
      _.range(complexity * multiplier).map((j, i) => {
        return {
          x: j,
          y: (t + 1) * _.random(0, 255),
        };


t,
  useEffect,
  useState,
  addTransitionType,
} from 'react';

import Chrome from './Chrome.js';
import Page from './Page.js';

const enableNavigationAPI = typeof navigation === 'object';

export default function App({assets, initialURL}) {
  const [routerState, setRouterState] = useState({
    pendingNav: () => {},
    url: initialURL,
  });
  function navigate(url) {
    if (enableNavigationAPI) {
      window.navigation.navigate(url);
    } else {
      startTransition(() => {
        setRouterState({

'navigate', event => {
        if (!event.canIntercept) {
          return;
        }
        const navigationType = event.navigationType;
        const previousIndex = window.navigation.currentEntry.index;
        const newURL = new URL(event.destination.

          url,
          pendingNav() {
            window.history.pushState({}, '', url);
          },
        });
      });
    }
  }
  useEffect(() => {
    if (enableNavigationAPI) {
      window.navigation.addEventListener(