UNPKG

@pixi/react

Version:

Write PixiJS applications using React declarative style.

1 lines 1.66 MB
{"version":3,"file":"pixi-react.min.mjs","sources":["../node_modules/its-fine/src/index.tsx","../node_modules/react-reconciler/cjs/react-reconciler-constants.production.js","../node_modules/react-reconciler/cjs/react-reconciler-constants.development.js","../node_modules/react-reconciler/constants.js","../src/components/Context.ts","../src/helpers/isReadOnlyProperty.ts","../src/store.ts","../src/helpers/log.ts","../src/helpers/prepareInstance.ts","../src/helpers/afterActiveInstanceBlur.ts","../src/helpers/attach.ts","../src/helpers/appendChild.ts","../src/helpers/beforeActiveInstanceBlur.ts","../src/helpers/clearContainer.ts","../src/constants/EventPropNames.ts","../src/helpers/compare.ts","../src/constants/ReactIgnoredProps.ts","../src/helpers/gentleClone.ts","../src/helpers/gentleCloneProps.ts","../src/helpers/diffProps.ts","../src/helpers/isDiffSet.ts","../src/helpers/applyProps.ts","../src/helpers/prepareUpdate.ts","../src/helpers/commitUpdate.ts","../src/constants/PixiReactIgnoredProps.ts","../src/helpers/catalogue.ts","../src/helpers/convertStringToPascalCase.ts","../src/helpers/parseComponentType.ts","../src/helpers/createInstance.ts","../node_modules/scheduler/cjs/scheduler.production.js","../node_modules/scheduler/cjs/scheduler.development.js","../node_modules/scheduler/index.js","../node_modules/react-reconciler/cjs/react-reconciler.production.js","../node_modules/react-reconciler/cjs/react-reconciler.development.js","../node_modules/react-reconciler/index.js","../src/helpers/createReconciler.ts","../src/helpers/createTextInstance.ts","../src/helpers/detachDeletedInstance.ts","../src/helpers/finalizeInitialChildren.ts","../src/constants/NO_CONTEXT.ts","../src/helpers/getChildHostContext.ts","../src/helpers/getCurrentUpdatePriority.ts","../src/helpers/getInstanceFromNode.ts","../src/helpers/getInstanceFromScope.ts","../src/helpers/getPublicInstance.ts","../src/helpers/getRootHostContext.ts","../src/helpers/hideInstance.ts","../src/helpers/hideTextInstance.ts","../src/helpers/detach.ts","../src/helpers/invariant.ts","../src/helpers/insertBefore.ts","../src/helpers/maySuspendCommit.ts","../src/helpers/preloadInstance.ts","../src/helpers/prepareForCommit.ts","../src/helpers/preparePortalMount.ts","../src/helpers/prepareScopeUpdate.ts","../src/helpers/removeChild.ts","../src/helpers/requestPostPaintCallback.ts","../src/helpers/resetAfterCommit.ts","../src/helpers/resetFormInstance.ts","../src/helpers/resolveEventTimeStamp.ts","../src/helpers/resolveEventType.ts","../src/helpers/resolveUpdatePriority.ts","../src/helpers/setCurrentUpdatePriority.ts","../src/helpers/shouldAttemptEagerTransition.ts","../src/helpers/shouldSetTextContent.ts","../src/helpers/startSuspendingCommit.ts","../src/helpers/suspendInstance.ts","../src/helpers/trackSchedulerEvent.ts","../src/helpers/unhideInstance.ts","../src/helpers/unhideTextInstance.ts","../src/helpers/waitForCommitToBeReady.ts","../src/core/reconciler.ts","../src/core/roots.ts","../src/core/createRoot.tsx","../src/helpers/unmountRoot.ts","../src/helpers/processUnmountQueue.ts","../src/helpers/queueForUnmount.ts","../src/helpers/unqueueForUnmount.ts","../src/hooks/useIsomorphicLayoutEffect.ts","../src/components/Application.tsx","../src/helpers/extend.ts","../src/hooks/useApplication.ts","../src/hooks/useExtend.ts","../src/hooks/useTick.ts"],"sourcesContent":["import * as React from 'react'\r\nimport type ReactReconciler from 'react-reconciler'\r\n\r\n/**\r\n * An SSR-friendly useLayoutEffect.\r\n *\r\n * React currently throws a warning when using useLayoutEffect on the server.\r\n * To get around it, we can conditionally useEffect on the server (no-op) and\r\n * useLayoutEffect elsewhere.\r\n *\r\n * @see https://github.com/facebook/react/issues/14927\r\n */\r\nconst useIsomorphicLayoutEffect = /* @__PURE__ */ (() =>\r\n typeof window !== 'undefined' && (window.document?.createElement || window.navigator?.product === 'ReactNative'))()\r\n ? React.useLayoutEffect\r\n : React.useEffect\r\n\r\n/**\r\n * Represents a react-internal Fiber node.\r\n */\r\nexport type Fiber<T = any> = Omit<ReactReconciler.Fiber, 'stateNode'> & { stateNode: T }\r\n\r\n/**\r\n * Represents a {@link Fiber} node selector for traversal.\r\n */\r\nexport type FiberSelector<T = any> = (\r\n /** The current {@link Fiber} node. */\r\n node: Fiber<T | null>,\r\n) => boolean | void\r\n\r\n/**\r\n * Traverses up or down a {@link Fiber}, return `true` to stop and select a node.\r\n */\r\nexport function traverseFiber<T = any>(\r\n /** Input {@link Fiber} to traverse. */\r\n fiber: Fiber | undefined,\r\n /** Whether to ascend and walk up the tree. Will walk down if `false`. */\r\n ascending: boolean,\r\n /** A {@link Fiber} node selector, returns the first match when `true` is passed. */\r\n selector: FiberSelector<T>,\r\n): Fiber<T> | undefined {\r\n if (!fiber) return\r\n if (selector(fiber) === true) return fiber\r\n\r\n let child = ascending ? fiber.return : fiber.child\r\n while (child) {\r\n const match = traverseFiber(child, ascending, selector)\r\n if (match) return match\r\n\r\n child = ascending ? null : child.sibling\r\n }\r\n}\r\n\r\n// In development, React will warn about using contexts between renderers.\r\n// Hide the warning because its-fine fixes this issue\r\n// https://github.com/facebook/react/pull/12779\r\nfunction wrapContext<T>(context: React.Context<T>): React.Context<T> {\r\n try {\r\n return Object.defineProperties(context, {\r\n _currentRenderer: {\r\n get() {\r\n return null\r\n },\r\n set() {},\r\n },\r\n _currentRenderer2: {\r\n get() {\r\n return null\r\n },\r\n set() {},\r\n },\r\n })\r\n } catch (_) {\r\n return context\r\n }\r\n}\r\n\r\nconst FiberContext = /* @__PURE__ */ wrapContext(/* @__PURE__ */ React.createContext<Fiber>(null!))\r\n\r\n/**\r\n * A react-internal {@link Fiber} provider. This component binds React children to the React Fiber tree. Call its-fine hooks within this.\r\n */\r\nexport class FiberProvider extends React.Component<{ children?: React.ReactNode }> {\r\n private _reactInternals!: Fiber\r\n\r\n render() {\r\n return <FiberContext.Provider value={this._reactInternals}>{this.props.children}</FiberContext.Provider>\r\n }\r\n}\r\n\r\n/**\r\n * Returns the current react-internal {@link Fiber}. This is an implementation detail of [react-reconciler](https://github.com/facebook/react/tree/main/packages/react-reconciler).\r\n */\r\nexport function useFiber(): Fiber<null> | undefined {\r\n const root = React.useContext(FiberContext)\r\n if (root === null) throw new Error('its-fine: useFiber must be called within a <FiberProvider />!')\r\n\r\n const id = React.useId()\r\n const fiber = React.useMemo(() => {\r\n for (const maybeFiber of [root, root?.alternate]) {\r\n if (!maybeFiber) continue\r\n const fiber = traverseFiber<null>(maybeFiber, false, (node) => {\r\n let state = node.memoizedState\r\n while (state) {\r\n if (state.memoizedState === id) return true\r\n state = state.next\r\n }\r\n })\r\n if (fiber) return fiber\r\n }\r\n }, [root, id])\r\n\r\n return fiber\r\n}\r\n\r\n/**\r\n * Represents a react-reconciler container instance.\r\n */\r\nexport interface ContainerInstance<T = any> {\r\n containerInfo: T\r\n}\r\n\r\n/**\r\n * Returns the current react-reconciler container info passed to {@link ReactReconciler.Reconciler.createContainer}.\r\n *\r\n * In react-dom, a container will point to the root DOM element; in react-three-fiber, it will point to the root Zustand store.\r\n */\r\nexport function useContainer<T = any>(): T | undefined {\r\n const fiber = useFiber()\r\n const root = React.useMemo(\r\n () => traverseFiber<ContainerInstance<T>>(fiber, true, (node) => node.stateNode?.containerInfo != null),\r\n [fiber],\r\n )\r\n\r\n return root?.stateNode.containerInfo\r\n}\r\n\r\n/**\r\n * Returns the nearest react-reconciler child instance or the node created from {@link ReactReconciler.HostConfig.createInstance}.\r\n *\r\n * In react-dom, this would be a DOM element; in react-three-fiber this would be an instance descriptor.\r\n */\r\nexport function useNearestChild<T = any>(\r\n /** An optional element type to filter to. */\r\n type?: keyof React.JSX.IntrinsicElements,\r\n): React.RefObject<T | undefined> {\r\n const fiber = useFiber()\r\n const childRef = React.useRef<T>(undefined)\r\n\r\n useIsomorphicLayoutEffect(() => {\r\n childRef.current = traverseFiber<T>(\r\n fiber,\r\n false,\r\n (node) => typeof node.type === 'string' && (type === undefined || node.type === type),\r\n )?.stateNode\r\n }, [fiber])\r\n\r\n return childRef\r\n}\r\n\r\n/**\r\n * Returns the nearest react-reconciler parent instance or the node created from {@link ReactReconciler.HostConfig.createInstance}.\r\n *\r\n * In react-dom, this would be a DOM element; in react-three-fiber this would be an instance descriptor.\r\n */\r\nexport function useNearestParent<T = any>(\r\n /** An optional element type to filter to. */\r\n type?: keyof React.JSX.IntrinsicElements,\r\n): React.RefObject<T | undefined> {\r\n const fiber = useFiber()\r\n const parentRef = React.useRef<T>(undefined)\r\n\r\n useIsomorphicLayoutEffect(() => {\r\n parentRef.current = traverseFiber<T>(\r\n fiber,\r\n true,\r\n (node) => typeof node.type === 'string' && (type === undefined || node.type === type),\r\n )?.stateNode\r\n }, [fiber])\r\n\r\n return parentRef\r\n}\r\n\r\nexport type ContextMap = Map<React.Context<any>, any> & {\r\n get<T>(context: React.Context<T>): T | undefined\r\n}\r\n\r\nconst REACT_CONTEXT_TYPE = Symbol.for('react.context')\r\n\r\nconst isContext = <T,>(type: unknown): type is React.Context<T> =>\r\n type !== null && typeof type === 'object' && '$$typeof' in type && type.$$typeof === REACT_CONTEXT_TYPE\r\n\r\n/**\r\n * Returns a map of all contexts and their values.\r\n */\r\nexport function useContextMap(): ContextMap {\r\n const fiber = useFiber()\r\n const [contextMap] = React.useState(() => new Map<React.Context<any>, any>())\r\n\r\n // Collect live context\r\n contextMap.clear()\r\n let node = fiber\r\n while (node) {\r\n const context = node.type\r\n if (isContext(context) && context !== FiberContext && !contextMap.has(context)) {\r\n contextMap.set(context, React.use(wrapContext(context)))\r\n }\r\n\r\n node = node.return!\r\n }\r\n\r\n return contextMap\r\n}\r\n\r\n/**\r\n * Represents a react-context bridge provider component.\r\n */\r\nexport type ContextBridge = React.FC<React.PropsWithChildren<{}>>\r\n\r\n/**\r\n * React Context currently cannot be shared across [React renderers](https://reactjs.org/docs/codebase-overview.html#renderers) but explicitly forwarded between providers (see [react#17275](https://github.com/facebook/react/issues/17275)). This hook returns a {@link ContextBridge} of live context providers to pierce Context across renderers.\r\n *\r\n * Pass {@link ContextBridge} as a component to a secondary renderer to enable context-sharing within its children.\r\n */\r\nexport function useContextBridge(): ContextBridge {\r\n const contextMap = useContextMap()\r\n\r\n // Flatten context and their memoized values into a `ContextBridge` provider\r\n return React.useMemo(\r\n () =>\r\n Array.from(contextMap.keys()).reduce(\r\n (Prev, context) => (props) =>\r\n (\r\n <Prev>\r\n <context.Provider {...props} value={contextMap.get(context)} />\r\n </Prev>\r\n ),\r\n (props) => <FiberProvider {...props} />,\r\n ),\r\n [contextMap],\r\n )\r\n}\r\n","/**\n * @license React\n * react-reconciler-constants.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nexports.ConcurrentRoot = 1;\nexports.ContinuousEventPriority = 8;\nexports.DefaultEventPriority = 32;\nexports.DiscreteEventPriority = 2;\nexports.IdleEventPriority = 268435456;\nexports.LegacyRoot = 0;\nexports.NoEventPriority = 0;\n","/**\n * @license React\n * react-reconciler-constants.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n ((exports.ConcurrentRoot = 1),\n (exports.ContinuousEventPriority = 8),\n (exports.DefaultEventPriority = 32),\n (exports.DiscreteEventPriority = 2),\n (exports.IdleEventPriority = 268435456),\n (exports.LegacyRoot = 0),\n (exports.NoEventPriority = 0));\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-reconciler-constants.production.js');\n} else {\n module.exports = require('./cjs/react-reconciler-constants.development.js');\n}\n","import { createContext } from 'react';\nimport { type ApplicationState } from '../typedefs/ApplicationState';\n\nexport const Context = createContext<ApplicationState>({} as ApplicationState);\n\nexport const ContextProvider = Context.Provider;\nexport const ContextConsumer = Context.Consumer;\n","export function isReadOnlyProperty(\n objectInstance: Record<string, unknown>,\n propertyKey: string,\n)\n{\n const prototype = Object.getPrototypeOf(objectInstance);\n const propertyDescriptor = Object.getOwnPropertyDescriptor(prototype, propertyKey);\n\n return !(typeof propertyDescriptor === 'undefined' || propertyDescriptor.writable || propertyDescriptor.set);\n}\n","import { DefaultEventPriority } from 'react-reconciler/constants';\nimport { type Root } from './typedefs/Root';\n\nconst store: {\n currentUpdatePriority: number,\n debug: boolean,\n unmountQueue: Set<Root>,\n} = {\n currentUpdatePriority: DefaultEventPriority,\n debug: false,\n unmountQueue: new Set(),\n};\n\nexport { store };\n","import { store } from '../store';\n\nexport type LogType = 'error' | 'info' | 'log' | 'warn';\n\nexport function log(logType: LogType, ...args: any[])\n{\n if (!store.debug)\n {\n return;\n }\n\n // eslint-disable-next-line no-console\n const logMethod = console[logType];\n\n if (!(logMethod instanceof Function))\n {\n console.warn(`Attempted to create an invalid log type: \"${logType}\"`);\n\n return;\n }\n\n logMethod('@pixi/react', ...args);\n}\n","import {\n type Container,\n type Filter,\n} from 'pixi.js';\nimport { type HostConfig } from '../typedefs/HostConfig';\nimport { type InstanceState } from '../typedefs/InstanceState';\n\n/** Create the instance with the provided sate and attach the component to it. */\nexport function prepareInstance<T extends Container | Filter | HostConfig['instance']>(\n component: T,\n state: Partial<InstanceState> = {},\n)\n{\n const instance = component as HostConfig['instance'];\n\n instance.__pixireact = Object.assign({\n filters: [],\n parent: null,\n root: null as unknown as HostConfig['containerInstance'],\n type: '',\n }, state);\n\n return instance;\n}\n","import { log } from './log';\n\n/**\n * No idea what this actually does. 🤷🏻‍♂️\n */\nexport function afterActiveInstanceBlur()\n{\n log('info', 'lifecycle::afterActiveInstanceBlur');\n}\n","import { Filter } from 'pixi.js';\nimport { type HostConfig } from '../typedefs/HostConfig';\n\nexport function attach(\n parentInstance: HostConfig['containerInstance'],\n childInstance: HostConfig['instance'],\n targetIndex?: number\n)\n{\n if (childInstance instanceof Filter)\n {\n (childInstance as unknown as HostConfig['filterInstance']).__pixireact.parent = parentInstance;\n\n if (typeof targetIndex === 'number')\n {\n parentInstance.__pixireact.filters.splice(targetIndex, 0, childInstance);\n }\n else\n {\n parentInstance.__pixireact.filters.push(childInstance);\n }\n\n parentInstance.filters = parentInstance.__pixireact.filters;\n }\n}\n","import {\n Container,\n Filter,\n} from 'pixi.js';\nimport { type HostConfig } from '../typedefs/HostConfig';\nimport { attach } from './attach';\nimport { log } from './log';\n\n/** Adds elements to our application. */\nexport function appendChild(\n parentNode: HostConfig['containerInstance'],\n childNode: HostConfig['instance'] | null,\n)\n{\n log('info', 'lifecycle::appendChild');\n\n if (!childNode)\n {\n return;\n }\n\n if (childNode instanceof Container)\n {\n parentNode.addChild(childNode);\n }\n else if (childNode instanceof Filter)\n {\n attach(parentNode, childNode);\n }\n}\n","import { log } from './log';\n\n/**\n * No idea what this actually does. 🤷🏻‍♂️\n */\nexport function beforeActiveInstanceBlur()\n{\n log('info', 'lifecycle::beforeActiveInstanceBlur');\n}\n","import { log } from './log';\n\n/** Mutate and remove all children from a container. */\nexport function clearContainer()\n{\n log('info', 'lifecycle::clearContainer');\n\n return false;\n}\n","export const PixiToReactEventPropNames = Object.freeze({\n onclick: 'onClick',\n onglobalmousemove: 'onGlobalMouseMove',\n onglobalpointermove: 'onGlobalPointerMove',\n onglobaltouchmove: 'onGlobalTouchMove',\n onmousedown: 'onMouseDown',\n onmouseenter: 'onMouseEnter',\n onmouseleave: 'onMouseLeave',\n onmousemove: 'onMouseMove',\n onmouseout: 'onMouseOut',\n onmouseover: 'onMouseOver',\n onmouseup: 'onMouseUp',\n onmouseupoutside: 'onMouseUpOutside',\n onpointercancel: 'onPointerCancel',\n onpointerdown: 'onPointerDown',\n onpointerenter: 'onPointerEnter',\n onpointerleave: 'onPointerLeave',\n onpointermove: 'onPointerMove',\n onpointerout: 'onPointerOut',\n onpointerover: 'onPointerOver',\n onpointertap: 'onPointerTap',\n onpointerup: 'onPointerUp',\n onpointerupoutside: 'onPointerUpOutside',\n onrightclick: 'onRightClick',\n onrightdown: 'onRightDown',\n onrightup: 'onRightUp',\n onrightupoutside: 'onRightUpOutside',\n ontap: 'onTap',\n ontouchcancel: 'onTouchCancel',\n ontouchend: 'onTouchEnd',\n ontouchendoutside: 'onTouchEndOutside',\n ontouchmove: 'onTouchMove',\n ontouchstart: 'onTouchStart',\n onwheel: 'onWheel',\n});\nexport const ReactToPixiEventPropNames = Object.freeze({\n onClick: 'onclick',\n onGlobalMouseMove: 'onglobalmousemove',\n onGlobalPointerMove: 'onglobalpointermove',\n onGlobalTouchMove: 'onglobaltouchmove',\n onMouseDown: 'onmousedown',\n onMouseEnter: 'onmouseenter',\n onMouseLeave: 'onmouseleave',\n onMouseMove: 'onmousemove',\n onMouseOut: 'onmouseout',\n onMouseOver: 'onmouseover',\n onMouseUp: 'onmouseup',\n onMouseUpOutside: 'onmouseupoutside',\n onPointerCancel: 'onpointercancel',\n onPointerDown: 'onpointerdown',\n onPointerEnter: 'onpointerenter',\n onPointerLeave: 'onpointerleave',\n onPointerMove: 'onpointermove',\n onPointerOut: 'onpointerout',\n onPointerOver: 'onpointerover',\n onPointerTap: 'onpointertap',\n onPointerUp: 'onpointerup',\n onPointerUpOutside: 'onpointerupoutside',\n onRightClick: 'onrightclick',\n onRightDown: 'onrightdown',\n onRightUp: 'onrightup',\n onRightUpOutside: 'onrightupoutside',\n onTap: 'ontap',\n onTouchCancel: 'ontouchcancel',\n onTouchEnd: 'ontouchend',\n onTouchEndOutside: 'ontouchendoutside',\n onTouchMove: 'ontouchmove',\n onTouchStart: 'ontouchstart',\n onWheel: 'onwheel',\n});\n","/** Whether the input is an array. */\nexport function isArray(input: any): input is []\n{\n return Array.isArray(input);\n}\n\n/** Whether the input is a boolean. */\nexport function isBoolean(input: any): input is boolean\n{\n return typeof input === 'boolean';\n}\n\n/** Whether the inputs are equal. */\nexport function isEqual(\n inputA: any,\n inputB: any,\n options: {\n arrays?: 'reference' | 'shallow',\n objects?: 'reference' | 'shallow',\n strict?: boolean,\n } = {\n arrays: 'reference',\n objects: 'reference',\n strict: true,\n })\n{\n const {\n arrays,\n objects,\n strict,\n } = options;\n\n // If input types are incompatible, or one input is undefined\n if (typeof inputA !== typeof inputB || !!inputA !== !!inputB)\n {\n return false;\n }\n\n // Atomic, just compare a against b\n if (isString(inputA) || isNumber(inputA))\n {\n return inputA === inputB;\n }\n\n const isInputAAnObject = isObject(inputA);\n\n if (isInputAAnObject && objects === 'reference')\n {\n return inputA === inputB;\n }\n\n const isInputAAnArray = isArray(inputA);\n\n if (isInputAAnArray && arrays === 'reference')\n {\n return inputA === inputB;\n }\n\n // If we're dealing with either an array or object, we'll shallow compare first to see if they match\n if ((isInputAAnArray || isInputAAnObject) && inputA === inputB)\n {\n return true;\n }\n\n // Last resort, go through keys\n let key;\n\n // Check if inputB has all the keys of inputA\n for (key in inputA)\n {\n if (!(key in inputB))\n {\n return false;\n }\n }\n\n let input = inputA;\n\n if (strict)\n {\n input = inputB;\n }\n\n // Check if values between keys match\n if (isInputAAnObject && arrays === 'shallow' && objects === 'shallow')\n {\n for (key in input)\n {\n const equalityCheckResult = isEqual(inputA[key], inputB[key], {\n strict,\n objects: 'reference',\n });\n\n if (!equalityCheckResult)\n {\n return false;\n }\n }\n }\n else\n {\n for (key in input)\n {\n if (inputA[key] !== inputB[key])\n {\n return false;\n }\n }\n }\n\n if (isUndefined(key))\n {\n if (isInputAAnArray && (inputA.length === 0) && (inputB.length === 0))\n {\n return true;\n }\n\n if (isInputAAnObject && Object.keys(inputA).length === 0 && Object.keys(inputB).length === 0)\n {\n return true;\n }\n\n if (inputA !== inputB)\n {\n return false;\n }\n }\n\n return true;\n}\n\n/** Whether the input is a function. */\nexport function isFunction(input: any): input is (...args: any) => any\n{\n return typeof input === 'function';\n}\n\n/** Whether the input is null. */\nexport function isNull(input: any): input is null\n{\n return input === null;\n}\n\n/** Whether the input is a number. */\nexport function isNumber(input: any): input is number\n{\n return typeof input === 'number';\n}\n\n/** Whether the input is an object. */\nexport function isObject(input: any): input is Record<string, unknown>\n{\n if (input !== Object(input))\n {\n return false;\n }\n\n if (isArray(input))\n {\n return false;\n }\n\n if (typeof input === 'function')\n {\n return false;\n }\n\n return true;\n}\n\n/** Whether the input is a string. */\nexport function isString(input: any): input is string\n{\n return typeof input === 'string';\n}\n\n/** Whether the input is undefined. */\nexport function isUndefined(input: any): input is undefined\n{\n // eslint-disable-next-line no-void\n return input === void 0;\n}\n","export const ReactIgnoredProps = Object.freeze([\n 'children',\n 'key',\n 'ref',\n]);\n","/** Clones an object without any of the ignored keys. */\nexport function gentleClone(\n object: Record<string, any>,\n ignoredKeys: string[] = [],\n)\n{\n const cloneBase: Record<string, any> = {};\n\n return Object.entries(object).reduce((accumulator, [key, value]) =>\n {\n if (!ignoredKeys.includes(key))\n {\n accumulator[key] = value;\n }\n\n return accumulator;\n }, cloneBase);\n}\n","import { ReactIgnoredProps } from '../constants/ReactIgnoredProps';\nimport { gentleClone } from './gentleClone';\n\n/** Clones a props object, excluding keys that are special to React and Pixi React. */\nexport function gentleCloneProps(\n props: Record<string, any>,\n additionalIgnoredProps: readonly string[] = [],\n)\n{\n return gentleClone(props, ReactIgnoredProps.concat(additionalIgnoredProps));\n}\n","import { ReactToPixiEventPropNames } from '../constants/EventPropNames';\nimport { type Change } from '../typedefs/Change';\nimport { type HostConfig } from '../typedefs/HostConfig';\nimport { isEqual } from './compare';\nimport { gentleCloneProps } from './gentleCloneProps';\n\nconst DEFAULT = '__default';\n\nexport function diffProps(\n newProps: HostConfig['props'],\n oldProps: HostConfig['props'] = {},\n remove = false,\n)\n{\n const newPropsRest = gentleCloneProps(newProps);\n const oldPropsRest = gentleCloneProps(oldProps);\n\n const entries = Object.entries(newPropsRest);\n\n const changes: Change[] = [];\n\n // Catch removed props, prepend them so they can be reset or removed\n if (remove)\n {\n const oldPropsKeys = Object.keys(oldPropsRest);\n\n let propIndex = 0;\n\n while (propIndex < oldPropsKeys.length)\n {\n const propKey = oldPropsKeys[propIndex];\n const isPropRemoved = !(propKey in newPropsRest);\n\n if (isPropRemoved)\n {\n entries.unshift([propKey, `${DEFAULT}remove`]);\n }\n\n propIndex += 1;\n }\n }\n\n entries.forEach(([key, value]) =>\n {\n // When props match bail out\n if (isEqual(value, oldPropsRest[key]))\n {\n return;\n }\n\n // Collect handlers and bail out\n if (key in ReactToPixiEventPropNames)\n {\n changes.push([key, value, true, []]);\n\n return;\n }\n\n // Split dashed props\n let entries: string[] = [];\n\n if (key.includes('-'))\n {\n entries = key.split('-');\n }\n\n changes.push([key, value, false, entries]);\n\n // Reset pierced props\n for (const prop in newPropsRest)\n {\n const value = newPropsRest[prop];\n\n if (prop.startsWith(`${key}-`))\n {\n changes.push([prop, value, false, prop.split('-')]);\n }\n }\n });\n\n return { changes };\n}\n","import { type DiffSet } from '../typedefs/DiffSet';\n\n/** Whether the input is a diff set. */\nexport function isDiffSet(input: any): input is DiffSet\n{\n const inputAsDiffSet = input as DiffSet;\n\n if (!inputAsDiffSet)\n {\n return false;\n }\n\n if (!inputAsDiffSet.changes)\n {\n return false;\n }\n\n return true;\n}\n","import {\n Container,\n Graphics,\n} from 'pixi.js';\nimport {\n type FederatedPointerEvent,\n type FederatedWheelEvent,\n} from 'pixi.js';\nimport {\n PixiToReactEventPropNames,\n ReactToPixiEventPropNames,\n} from '../constants/EventPropNames';\nimport { type DiffSet } from '../typedefs/DiffSet';\nimport { type HostConfig } from '../typedefs/HostConfig';\nimport { type InstanceState } from '../typedefs/InstanceState';\nimport {\n isNull,\n isUndefined,\n} from './compare';\nimport { diffProps } from './diffProps';\nimport { isDiffSet } from './isDiffSet';\nimport { isReadOnlyProperty } from './isReadOnlyProperty';\nimport { log } from './log';\n\nconst DEFAULT = '__default';\nconst DEFAULTS_CONTAINERS = new Map();\n\nconst PIXI_EVENT_PROP_NAME_ERROR_HAS_BEEN_SHOWN: Record<string, boolean> = {};\n\nexport type MaybeInstance = Partial<HostConfig['instance']>;\n\nfunction targetKeyReducer(accumulator: any, key: string)\n{\n if (accumulator)\n {\n const value = accumulator[key];\n\n if (!isUndefined(value) && !isNull(value))\n {\n return value;\n }\n }\n\n return accumulator;\n}\n\n/** Apply properties to Pixi.js instance. */\nexport function applyProps(\n instance: MaybeInstance,\n data: HostConfig['props'] | DiffSet,\n)\n{\n const {\n __pixireact: instanceState = {} as InstanceState,\n ...instanceProps\n } = instance;\n\n let typedData;\n\n if (isDiffSet(data))\n {\n typedData = data as DiffSet;\n }\n else\n {\n typedData = diffProps(data, instanceProps as HostConfig['props']);\n }\n\n const { changes } = typedData;\n\n let changeIndex = 0;\n\n while (changeIndex < changes.length)\n {\n const change = changes[changeIndex];\n let hasError = false;\n let key = change[0] as keyof HostConfig['instance'];\n let value = change[1];\n const isEvent = change[2];\n\n const keys = change[3];\n\n let currentInstance = instance;\n let targetProp = currentInstance[key];\n\n if ((key as string === 'draw') && (typeof value === 'function'))\n {\n if (instance instanceof Graphics)\n {\n value(instance);\n }\n else\n {\n hasError = true;\n log('warn', `The \\`draw\\` prop was used on a \\`${instanceState.type}\\` component, but it's only valid on \\`graphics\\` components.`);\n }\n }\n\n if (key in PixiToReactEventPropNames)\n {\n const typedKey = key as keyof typeof PixiToReactEventPropNames;\n\n hasError = true;\n\n if (!PIXI_EVENT_PROP_NAME_ERROR_HAS_BEEN_SHOWN[key])\n {\n PIXI_EVENT_PROP_NAME_ERROR_HAS_BEEN_SHOWN[key] = true;\n\n log('warn', `Event names must be pascal case; instead of \\`${key}\\`, you probably want \\`${PixiToReactEventPropNames[typedKey]}\\`.`);\n }\n }\n\n if (!hasError)\n {\n // Resolve dashed props\n if (keys.length)\n {\n targetProp = keys.reduce(targetKeyReducer, currentInstance);\n\n // If the target is atomic, it forces us to switch the root\n if (!(targetProp && (targetProp as unknown as Record<string, unknown>).set))\n {\n const [name, ...reverseEntries] = keys.reverse();\n\n currentInstance = reverseEntries.reverse().reduce(targetKeyReducer, currentInstance);\n\n key = name as keyof MaybeInstance;\n }\n }\n\n // https://github.com/mrdoob/three.js/issues/21209\n // HMR/fast-refresh relies on the ability to cancel out props, but pixi.js\n // has no means to do this. Hence we curate a small collection of value-classes\n // with their respective constructor/set arguments\n // For removed props, try to set default values, if possible\n if (value === `${DEFAULT}remove`)\n {\n if (currentInstance instanceof Container)\n {\n // create a blank slate of the instance and copy the particular parameter.\n let ctor = DEFAULTS_CONTAINERS.get(currentInstance.constructor);\n\n if (!ctor)\n {\n ctor = currentInstance.constructor;\n\n // eslint-disable-next-line new-cap\n ctor = new ctor();\n\n DEFAULTS_CONTAINERS.set(currentInstance.constructor, ctor);\n }\n\n value = ctor[key];\n }\n else\n {\n // instance does not have constructor, just set it to 0\n value = 0;\n }\n }\n\n // Deal with events ...\n if (isEvent && instanceState)\n {\n const typedKey = key as keyof typeof ReactToPixiEventPropNames;\n const pixiKey = ReactToPixiEventPropNames[typedKey];\n\n if (value)\n {\n currentInstance[pixiKey] = value as (event: FederatedPointerEvent | FederatedWheelEvent) => void;\n }\n else\n {\n delete currentInstance[pixiKey];\n }\n }\n else if (!isReadOnlyProperty(currentInstance as Record<string, unknown>, key))\n {\n // @ts-expect-error Typescript is grumpy because this could be setting a readonly key, but we're already handling that in the conditional above. 🤷🏻‍♂️\n currentInstance[key] = value;\n }\n }\n\n changeIndex += 1;\n }\n\n return instance;\n}\n","import { type HostConfig } from '../typedefs/HostConfig';\nimport { diffProps } from './diffProps';\nimport { log } from './log';\n\nexport function prepareUpdate(\n _instance: HostConfig['instance'],\n _type: HostConfig['type'],\n oldProps: HostConfig['props'],\n newProps: HostConfig['props'],\n)\n{\n log('info', 'lifecycle::prepareUpdate');\n\n const {\n children: newChildren,\n ...newPropsRest\n } = newProps;\n const {\n children: oldChildren,\n ...oldPropsRest\n } = oldProps;\n\n const diff = diffProps(newPropsRest, oldPropsRest, true);\n\n if (diff.changes.length)\n {\n return diff;\n }\n\n return null;\n}\n","import { applyProps } from '../helpers/applyProps';\nimport { log } from '../helpers/log';\nimport { type HostConfig } from '../typedefs/HostConfig';\nimport { prepareUpdate } from './prepareUpdate';\n\nexport function commitUpdate(\n instance: HostConfig['instance'],\n type: HostConfig['type'],\n oldProps: HostConfig['props'],\n newProps: HostConfig['props'],\n)\n{\n log('info', 'lifecycle::commitUpdate');\n\n const diff = prepareUpdate(\n instance,\n type,\n oldProps,\n newProps,\n );\n\n if (diff)\n {\n applyProps(instance, diff);\n }\n}\n","import { PixiToReactEventPropNames } from './EventPropNames';\n\nexport const PixiReactIgnoredProps = Object.freeze([\n ...Object.keys(PixiToReactEventPropNames),\n 'draw',\n]);\n","import { type HostConfig } from '../typedefs/HostConfig';\n\nexport const catalogue: {\n [name: string]: {\n new (...args: any): HostConfig['instance'],\n }\n} = {};\n","/** Converts a string to PascalCase. */\nexport function convertStringToPascalCase<S extends string>(string: S)\n{\n const firstChar = string.charAt(0);\n const rest = string.substring(1);\n\n return `${firstChar.toUpperCase()}${rest}`;\n}\n","function lowercaseFirstCharacter(_fullMatch: string, firstCharacter: string)\n{\n return firstCharacter.toLowerCase();\n}\n\nexport function parseComponentType(type: string)\n{\n let parsedType = type;\n\n if (type.startsWith('pixi'))\n {\n parsedType = type.replace(/^pixi([A-Z])/, lowercaseFirstCharacter);\n }\n\n return parsedType;\n}\n","import { ReactToPixiEventPropNames } from '../constants/EventPropNames';\nimport { PixiReactIgnoredProps } from '../constants/PixiReactIgnoredProps';\nimport { type HostConfig } from '../typedefs/HostConfig';\nimport { applyProps } from './applyProps';\nimport { catalogue } from './catalogue';\nimport { convertStringToPascalCase } from './convertStringToPascalCase';\nimport { gentleCloneProps } from './gentleCloneProps';\nimport { log } from './log';\nimport { parseComponentType } from './parseComponentType';\nimport { prepareInstance } from './prepareInstance';\n\nexport function createInstance(\n type: HostConfig['type'],\n props: HostConfig['props'],\n root: HostConfig['containerInstance'],\n)\n{\n log('info', 'lifecycle::createInstance');\n\n const parsedType = parseComponentType(type);\n\n // Convert lowercase component name to PascalCase\n const name = convertStringToPascalCase(parsedType);\n\n if (!(name in catalogue))\n {\n throw new Error(`${name} is not part of the PIXI namespace! Did you forget to extend?`);\n }\n\n // Get the class from an imported Pixi.js namespace\n const PixiComponent = catalogue[name];\n\n const pixiProps = gentleCloneProps(props, PixiReactIgnoredProps);\n\n // Clone event props\n Object.entries(props).forEach(([key, value]) =>\n {\n if (key in ReactToPixiEventPropNames)\n {\n const pixiEventName = ReactToPixiEventPropNames[key as keyof typeof ReactToPixiEventPropNames];\n\n pixiProps[pixiEventName] = value;\n }\n });\n\n const instance = prepareInstance(new PixiComponent(pixiProps), {\n root,\n type: parsedType,\n });\n\n // Set initial props\n applyProps(instance, props);\n\n return instance;\n}\n","/**\n * @license React\n * scheduler.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nfunction push(heap, node) {\n var index = heap.length;\n heap.push(node);\n a: for (; 0 < index; ) {\n var parentIndex = (index - 1) >>> 1,\n parent = heap[parentIndex];\n if (0 < compare(parent, node))\n (heap[parentIndex] = node), (heap[index] = parent), (index = parentIndex);\n else break a;\n }\n}\nfunction peek(heap) {\n return 0 === heap.length ? null : heap[0];\n}\nfunction pop(heap) {\n if (0 === heap.length) return null;\n var first = heap[0],\n last = heap.pop();\n if (last !== first) {\n heap[0] = last;\n a: for (\n var index = 0, length = heap.length, halfLength = length >>> 1;\n index < halfLength;\n\n ) {\n var leftIndex = 2 * (index + 1) - 1,\n left = heap[leftIndex],\n rightIndex = leftIndex + 1,\n right = heap[rightIndex];\n if (0 > compare(left, last))\n rightIndex < length && 0 > compare(right, left)\n ? ((heap[index] = right),\n (heap[rightIndex] = last),\n (index = rightIndex))\n : ((heap[index] = left),\n (heap[leftIndex] = last),\n (index = leftIndex));\n else if (rightIndex < length && 0 > compare(right, last))\n (heap[index] = right), (heap[rightIndex] = last), (index = rightIndex);\n else break a;\n }\n }\n return first;\n}\nfunction compare(a, b) {\n var diff = a.sortIndex - b.sortIndex;\n return 0 !== diff ? diff : a.id - b.id;\n}\nexports.unstable_now = void 0;\nif (\"object\" === typeof performance && \"function\" === typeof performance.now) {\n var localPerformance = performance;\n exports.unstable_now = function () {\n return localPerformance.now();\n };\n} else {\n var localDate = Date,\n initialTime = localDate.now();\n exports.unstable_now = function () {\n return localDate.now() - initialTime;\n };\n}\nvar taskQueue = [],\n timerQueue = [],\n taskIdCounter = 1,\n currentTask = null,\n currentPriorityLevel = 3,\n isPerformingWork = !1,\n isHostCallbackScheduled = !1,\n isHostTimeoutScheduled = !1,\n localSetTimeout = \"function\" === typeof setTimeout ? setTimeout : null,\n localClearTimeout = \"function\" === typeof clearTimeout ? clearTimeout : null,\n localSetImmediate = \"undefined\" !== typeof setImmediate ? setImmediate : null;\nfunction advanceTimers(currentTime) {\n for (var timer = peek(timerQueue); null !== timer; ) {\n if (null === timer.callback) pop(timerQueue);\n else if (timer.startTime <= currentTime)\n pop(timerQueue),\n (timer.sortIndex = timer.expirationTime),\n push(taskQueue, timer);\n else break;\n timer = peek(timerQueue);\n }\n}\nfunction handleTimeout(currentTime) {\n isHostTimeoutScheduled = !1;\n advanceTimers(currentTime);\n if (!isHostCallbackScheduled)\n if (null !== peek(taskQueue))\n (isHostCallbackScheduled = !0), requestHostCallback();\n else {\n var firstTimer = peek(timerQueue);\n null !== firstTimer &&\n requestHostTimeout(handleTimeout, firstTimer.startTime - currentTime);\n }\n}\nvar isMessageLoopRunning = !1,\n taskTimeoutID = -1,\n frameInterval = 5,\n startTime = -1;\nfunction shouldYieldToHost() {\n return exports.unstable_now() - startTime < frameInterval ? !1 : !0;\n}\nfunction performWorkUntilDeadline() {\n if (isMessageLoopRunning) {\n var currentTime = exports.unstable_now();\n startTime = currentTime;\n var hasMoreWork = !0;\n try {\n a: {\n isHostCallbackScheduled = !1;\n isHostTimeoutScheduled &&\n ((isHostTimeoutScheduled = !1),\n localClearTimeout(taskTimeoutID),\n (taskTimeoutID = -1));\n isPerformingWork = !0;\n var previousPriorityLevel = currentPriorityLevel;\n try {\n b: {\n advanceTimers(currentTime);\n for (\n currentTask = peek(taskQueue);\n null !== currentTask &&\n !(\n currentTask.expirationTime > currentTime && shouldYieldToHost()\n );\n\n ) {\n var callback = currentTask.callback;\n if (\"function\" === typeof callback) {\n currentTask.callback = null;\n currentPriorityLevel = currentTask.priorityLevel;\n var continuationCallback = callback(\n currentTask.expirationTime <= currentTime\n );\n currentTime = exports.unstable_now();\n if (\"function\" === typeof continuationCallback) {\n currentTask.callback = continuationCallback;\n advanceTimers(currentTime);\n hasMoreWork = !0;\n break b;\n }\n currentTask === peek(taskQueue) && pop(taskQueue);\n advanceTimers(currentTime);\n } else pop(taskQueue);\n currentTask = peek(taskQueue);\n }\n if (null !== currentTask) hasMoreWork = !0;\n else {\n var firstTimer = peek(timerQueue);\n null !== firstTimer &&\n requestHostTimeout(\n handleTimeout,\n firstTimer.startTime - currentTime\n );\n hasMoreWork = !1;\n }\n }\n break a;\n } finally {\n (currentTask = null),\n (currentPriorityLevel = previousPriorityLevel),\n (isPerformingWork = !1);\n }\n hasMoreWork = void 0;\n }\n } finally {\n hasMoreWork\n ? schedulePerformWorkUntilDeadline()\n : (isMessageLoopRunning = !1);\n }\n }\n}\nvar schedulePerformWorkUntilDeadline;\nif (\"function\" === typeof localSetImmediate)\n schedulePerformWorkUntilDeadline = function () {\n localSetImmediate(performWorkUntilDeadline);\n };\nelse if (\"undefined\" !== typeof MessageChannel) {\n var channel = new MessageChannel(),\n port = channel.port2;\n channel.port1.onmessage = performWorkUntilDeadline;\n schedulePerformWorkUntilDeadline = function () {\n port.postMessage(null);\n };\n} else\n schedulePerformWorkUntilDeadline = function () {\n localSetTimeout(performWorkUntilDeadline, 0);\n };\nfunction requestHostCallback() {\n isMessageLoopRunning ||\n ((isMessageLoopRunning = !0), schedulePerformWorkUntilDeadline());\n}\nfunction requestHostTimeout(callback, ms) {\n taskTimeoutID = localSetTimeout(function () {\n callback(exports.unstable_now());\n }, ms);\n}\nexports.unstable_IdlePriority = 5;\nexports.unstable_ImmediatePriority = 1;\nexports.unstable_LowPriority = 4;\nexports.unstable_NormalPriority = 3;\nexports.unstable_Profiling = null;\nexports.unstable_UserBlockingPriority = 2;\nexports.unstable_cancelCallback = function (task) {\n task.callback = null;\n};\nexports.unstable_continueExecution = function () {\n isHostCallbackScheduled ||\n isPerformingWork ||\n ((isHostCallbackScheduled = !0), requestHostCallback());\n};\nexports.unstable_forceFrameRate = function (fps) {\n 0 > fps || 125 < fps\n ? console.error(\n \"forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported\"\n )\n : (frameInterval = 0 < fps ? Math.floor(1e3 / fps) : 5);\n};\nexports.unstable_getCurrentPriorityLevel = function () {\n return currentPriorityLevel;\n};\nexports.unstable_getFirstCallbackNode = function () {\n return peek(taskQueue);\n};\nexports.unstable_next = function (eventHandler) {\n switch (currentPriorityLevel) {\n case 1:\n case 2:\n case 3:\n var priorityLevel = 3;\n break;\n default:\n priorityLevel = currentPriorityLevel;\n }\n var previousPriorityLevel = currentPriorityLevel;\n currentPriorityLevel = priorityLevel;\n try {\n return eventHandler();\n } finally {\n currentPriorityLevel = previousPriorityLevel;\n }\n};\nexports.unstable_pauseExecution = function () {};\nexports.unstable_requestPaint = function () {};\nexports.unstable_runWithPriority = function (priorityLevel, eventHandler) {\n switch (priorityLevel) {\n case 1:\n case 2:\n case 3:\n case 4:\n case 5:\n break;\n default:\n priorityLevel = 3;\n }\n var previousPriorityLevel = currentPriorityLevel;\n currentPriorityLevel = priorityLevel;\n try {\n return eventHandler();\n } finally {\n currentPriorityLevel = previousPriorityLevel;\n }\n};\nexports.unstable_scheduleCallback = function (\n priorityLevel,\n callback,\n options\n) {\n var currentTime = exports.unstable_now();\n \"object\" === typeof options && null !== options\n ? ((options = options.delay),\n (options =\n \"number\" === typeof options && 0 < options\n ? currentTime + options\n : currentTime))\n : (options = currentTime);\n switch (priorityLevel) {\n case 1:\n var timeout = -1;\n break;\n case 2:\n timeout = 250;\n break;\n case 5:\n timeout = 1073741823;\n break;\n case 4:\n timeout = 1e4;\n break;\n default:\n timeout = 5e3;\n }\n timeout = options + timeout;\n priorityLevel = {\n id: taskIdCounter++,\n callback: callback,\n priorityLevel: priorityLevel,\n startTime: options,\n expirationTime: timeout,\n sortIndex: -1\n };\n options > currentTime\n ? ((priorityLevel.sortIndex = options),\n push(timerQueue, priorityLevel),\n null === peek(taskQueue) &&\n priorityLevel === peek(timerQueue) &&\n (isHostTimeoutScheduled\n ? (localClearTimeout(taskTimeoutID), (taskTimeoutID = -1))\n : (isHostTimeoutScheduled = !0),\n requestHostTimeout(handleTimeout, options - currentTime)))\n : ((priorityLevel.sortIndex = timeout),\n push(taskQueue, priorityLevel),\n isHostCallbackScheduled ||\n isPerformingWork ||\n ((isHostCallbackScheduled = !0), requestHostCallback()));\n return priorityLevel;\n};\nexports.unstable_shouldYield = shouldYieldToHost;\nexports.unstable_wrapCallback = function (callback) {\n var parentPriorityLevel = currentPriorityLevel;\n return function () {\n var previousPriorityLevel = currentPriorityLevel;\n currentPriorityLevel = parentPriorityLevel;\n try {\n return callback.apply(this, arguments);\n } finally {\n currentPriorityLevel = previousPriorityLevel;\n }\n };\n};\n","/**\n * @license React\n * scheduler.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function performWorkUntilDeadline() {\n if (isMessageLoopRunning) {\n var currentTime = exports.unstable_now();\n startTime = currentTime;\n var hasMoreWork = !0;\n try {\n a: {\n isHostCallbackScheduled = !1;\n isHostTimeoutScheduled &&\n ((isHostTimeoutScheduled = !1),\n localClearTimeout(taskTimeoutID),\n (taskTimeoutID = -1));\n isPerformingWork = !0;\n var previousPriorityLevel = currentPriorityLevel;\n try {\n b: {\n advanceTimers(currentTime);\n for (\n currentTask = peek(taskQueue);\n null !== currentTask &&\n !(\n currentTask.expirationTime > currentTime &&\n shouldYieldToHost()\n );\n\n ) {\n var callback = currentTask.callback;\n if (\"function\" === typeof callback) {\n currentTask.callback = null;\n currentPriorityLevel = currentTask.priorityLevel;\n var continuationCallback = callback(\n currentTask.expirationTime <= currentTime\n );\n currentTime = exports.unstable_now();\n if (\"function\" === typeof continuationCallback) {\n currentTask.callback = continuationCallback;\n advanceTimers(currentTime);\n