diff --git a/.eslintignore b/.eslintignore index d31cbf75..fb9accef 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,3 +2,5 @@ .yarn/ .yarnrc.yml .pnp.* + +/docs/ diff --git a/.eslintrc.json b/.eslintrc.json index 96c64314..e9f139bf 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -43,11 +43,12 @@ } ], "no-inner-declarations": "off", - "import/no-unresolved": "off" // Typescript does this better! + "import/no-unresolved": "off", // Typescript does this better! + "@typescript-eslint/no-unused-vars": "off" // Let the TS compiler do this, too }, "settings": { "import/extensions": [".js", ".jsx", ".ts", ".tsx"], - "import/external-module-folders": [".yarn"], + "import/external-module-folders": ["node_modules"], "import/parsers": { "@typescript-eslint/parser": [".ts", ".tsx"] }, diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 492152d4..3e38b99a 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -48,5 +48,8 @@ jobs: - name: Install dependencies run: yarn + - uses: browser-actions/setup-chrome@v1 + - uses: browser-actions/setup-firefox@v1 + - name: Test run: yarn test diff --git a/.husky/pre-commit b/.husky/pre-commit index 5a182ef1..d1afdbdd 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -2,3 +2,5 @@ . "$(dirname -- "$0")/_/husky.sh" yarn lint-staged +yarn demo:build +git add docs diff --git a/.prettierignore b/.prettierignore index d31cbf75..fb9accef 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,3 +2,5 @@ .yarn/ .yarnrc.yml .pnp.* + +/docs/ diff --git a/.vscode/settings.json b/.vscode/settings.json index 8939aae4..49a56e08 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,23 +3,17 @@ "**/.yarn": true, "**/.pnp.*": true }, - "typescript.tsdk": ".yarn/sdks/typescript/lib", + "typescript.tsdk": "node_modules/typescript/lib", "typescript.enablePromptUseWorkspaceTsdk": true, - "prettier.prettierPath": ".yarn/sdks/prettier/index.js", - "eslint.nodePath": ".yarn/sdks", "editor.formatOnSave": true, - "[javascript]": { + "[javascript][typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.codeActionsOnSave": { - "source.fixAll": true - } - }, - "[typescript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" } }, + "javascript.preferences.importModuleSpecifierEnding": "js", + "typescript.preferences.importModuleSpecifierEnding": "js", "[markdown]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, diff --git a/.yarnrc.yml b/.yarnrc.yml index 35595a6d..2a902b86 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -7,3 +7,5 @@ plugins: spec: "@yarnpkg/plugin-version" yarnPath: .yarn/releases/yarn-3.4.1.cjs + +nodeLinker: node-modules diff --git a/README.md b/README.md index abb78787..4d1693e6 100644 --- a/README.md +++ b/README.md @@ -31,35 +31,30 @@ yarn add @nytimes/react-prosemirror - [`useEditorEffect`](#useeditoreffect) - [`useEditorEventCallback`](#useeditoreventcallback) - [`useEditorEventListener`](#useeditoreventlistener) - - [`useEditorView`, `EditorProvider` and `LayoutGroup`](#useeditorview-editorprovider-and-layoutgroup) - - [Building NodeViews with React](#building-nodeviews-with-react) + - [Building node views with React](#building-node-views-with-react) - [API](#api) - [`ProseMirror`](#prosemirror) - - [`EditorProvider`](#editorprovider) - - [`LayoutGroup`](#layoutgroup) - - [`useLayoutGroupEffect`](#uselayoutgroupeffect) + - [`ProseMirrorDoc`](#prosemirrordoc) - [`useEditorState`](#useeditorstate) - - [`useEditorView`](#useeditorview) - [`useEditorEventCallback`](#useeditoreventcallback-1) - [`useEditorEventListener`](#useeditoreventlistener-1) - [`useEditorEffect`](#useeditoreffect-1) - - [`useNodePos`](#usenodepos) - - [`useNodeViews`](#usenodeviews) - - [`react`](#react) + - [`NodeViewComponentProps`](#nodeviewcomponentprops) + - [`widget`](#widget) ## The Problem -React is a framework for developing reactive user interfaces. To make updates -efficient, React separates updates into phases so that it can process updates in -batches. In the first phase, application code renders a virtual document. In the -second phase, the React DOM renderer finalizes the update by reconciling the -real document with the virtual document. The ProseMirror View library renders -ProseMirror documents in a single-phase update. Unlike React, it also allows -built-in editing features of the browser to modify the document under some -circumstances, deriving state updates from view updates rather than the other -way around. +To make updates efficient, React separates updates into phases so that it can +process updates in batches. In the first phase, application code renders a +virtual document. In the second phase, the React DOM renderer finalizes the +update by reconciling the real document with the virtual document. + +On the other hand, the ProseMirror View library renders ProseMirror documents in +a single-phase update. Unlike React, it also allows built-in editing features of +the browser to modify the document under some circumstances, deriving state +updates from view updates rather than the other way around. It is possible to use both React DOM and ProseMirror View, but using React DOM to render ProseMirror View components safely requires careful consideration of @@ -72,12 +67,28 @@ code that dispatches transactions may dispatch transactions based on incorrect state. Code that invokes methods of the ProseMirror view may make bad assumptions about its state that cause incorrect behavior or errors. +It's also challenging to effectively use React to define node views for +ProseMirror documents. Both ProseMirror and React expect to have full control +over their respective parts of the DOM. They both modify and destroy DOM nodes +as needed. Previous solutions (including previous iterations of this library) +have attempted to work around this power struggle by producing wrapper elements +to hand to ProseMirror, and then mounting React nodes within these (usually with +React Portals). + +This approach works, but tenuously. Having additional nodes in the document that +ProseMirror isn't strictly aware of can cause issues with its change detection +system, leading to challenging edge cases. +[Here's an example](https://github.com/nytimes/react-prosemirror/issues/42). +These extra wrapping elements also make it challenging to produce semantic +markup and introduce challenges when styling. + ## The Solution -There are two different directions to integrate ProseMirror and React: you can -render a ProseMirror EditorView inside of a React component, and you can use -React components to render ProseMirror NodeViews. This library provides tools -for accomplishing both of these goals. +This library provides an alternate implementation of ProseMirror's EditorView. +It uses React as the rendering engine, rather than ProseMirror's home-brewed DOM +update system. This allows us to provide a more comfortable integration with +ProseMirror's powerful data model, transformations, and event management +systems. ### Rendering ProseMirror Views within React @@ -87,24 +98,30 @@ build React applications that contain ProseMirror Views, even when the EditorState is lifted into React state, or a global state management system like Redux. -The simplest way to make use of these contexts is with the `` -component. The `` component can be used controlled or -uncontrolled, and takes a "mount" prop, used to specify which DOM node the -ProseMirror EditorView should be mounted on. +The simplest way to make use of these contexts is with the `` +component. The `` component can be used controlled (via the +`state` prop) or uncontrolled (via the `defaultState` prop). ```tsx import { EditorState } from "prosemirror-state"; -import { ProseMirror } from "@nytimes/react-prosemirror"; +import { + ProseMirror, + ProseMirrorDoc, + reactKeys, +} from "@nytimes/react-prosemirror"; export function ProseMirrorEditor() { - // It's important that mount is stored as state, - // rather than a ref, so that the ProseMirror component - // is re-rendered when it's set - const [mount, setMount] = useState(null); - return ( - -
+ + ); } @@ -116,59 +133,58 @@ passed as a prop. ```tsx import { EditorState } from "prosemirror-state"; import { schema } from "prosemirror-schema-basic"; -import { ProseMirror } from "@nytimes/react-prosemirror"; +import { + ProseMirror, + ProseMirrorDoc, + reactKeys, +} from "@nytimes/react-prosemirror"; export function ProseMirrorEditor() { - const [mount, setMount] = useState(null); const [editorState, setEditorState] = useState( - EditorState.create({ schema }) + EditorState.create({ schema, plugins: [reactKeys()] }) ); return ( { setEditorState((s) => s.apply(tr)); }} > -
+ ); } ``` -The ProseMirror component will take care to ensure that the EditorView is always -updated with the latest EditorState after each render cycle. Because -synchronizing the EditorView is a side effect, it _must_ happen in the effects -phase of the React render lifecycle, _after_ all of the ProseMirror component's -children have run their render functions. This means that special care must be -taken to access the EditorView from within other React components. In order to -abstract away this complexity, React ProseMirror provides two hooks: -`useEditorEffect` and `useEditorEventCallback`. Both of these hooks can be used -from any children of the ProseMirror component. +The `EditorView` interface exposes several useful methods that provide access to +the DOM or data derived from its layout, such as `coordsFromPos`. These methods +should only be accessed outside of the render cycle, to ensure that the DOM has +been updated to match the latest state. React ProseMirror provides two hooks to +enable this access pattern: `useEditorEffect` and `useEditorEventCallback`. Both +of these hooks can be used from any children of the ProseMirror component. #### `useEditorEffect` Often, it's necessary to position React components relative to specific positions in the ProseMirror document. For example, you might have some widget that needs to be positioned at the user's cursor. In order to ensure that this -positioning happens when the EditorView is in sync with the latest EditorState, -we can use `useEditorEffect`. +positioning happens when the DOM is in sync with the latest EditorState, we can +use `useEditorEffect`. ```tsx // SelectionWidget.tsx -import { useRef } from "react" -import { useEditorEffect } from "@nytimes/react-prosemirror" +import { useRef } from "react"; +import { useEditorEffect } from "@nytimes/react-prosemirror"; export function SelectionWidget() { - const ref = useRef() + const ref = useRef(); useEditorEffect((view) => { - if (!view || !ref.current) return + if (!view || !ref.current) return; - const viewClientRect = view.dom.getBoundingClientRect() - const coords = view.coordsAtPos(view.state.selection.anchor)) + const viewClientRect = view.dom.getBoundingClientRect(); + const coords = view.coordsAtPos(view.state.selection.anchor)); ref.current.style.top = coords.top - viewClientRect.top; ref.current.style.left = coords.left - viewClientRect.left; @@ -181,35 +197,40 @@ export function SelectionWidget() { position: "absolute" }} /> - ) + ); } // ProseMirrorEditor.tsx +import { + ProseMirror, + ProseMirrorDoc, + reactKeys +} from '@nytimes/react-prosemirror'; import { EditorState } from "prosemirror-state"; import { schema } from "prosemirror-schema-basic"; import { SelectionWidget } from "./SelectionWidget.tsx"; export function ProseMirrorEditor() { - const [mount, setMount] = useState(null); - const [editorState, setEditorState] = useState(EditorState.create({ schema })) + const [editorState, setEditorState] = useState( + EditorState.create({ schema, plugins: [reactKeys()] }) + ); return ( { setEditorState(s => s.apply(tr)) }} > + {/* We have to mount all components that need to access the EditorView as children of the ProseMirror component */} -
- ) + ); } ``` @@ -241,31 +262,34 @@ export function BoldButton() { } // ProseMirrorEditor.tsx +import { + ProseMirror, + ProseMirrorDoc, + reactKeys, +} from "@nytimes/react-prosemirror"; import { EditorState } from "prosemirror-state"; import { schema } from "prosemirror-schema-basic"; import { BoldButton } from "./BoldButton.tsx"; export function ProseMirrorEditor() { - const [mount, setMount] = useState(null); const [editorState, setEditorState] = useState( - EditorState.create({ schema }) + EditorState.create({ schema, plugins: [reactKeys()] }) ); return ( { setEditorState((s) => s.apply(tr)); }} > + {/* We have to mount all components that need to access the EditorView as children of the ProseMirror component */} -
); } @@ -291,109 +315,87 @@ semantics for ProseMirror's `handleDOMEvents` prop: You can use this hook to implement custom behavior in your NodeViews: ```tsx -import { useEditorEventListener } from "@nytimes/react-prosemirror"; - -function Paragraph({ node, children }) { - const nodeStart = useNodePos(); - - useEditorEventListener("keydown", (view, event) => { - if (event.code !== "ArrowDown") { - return false; - } - const nodeEnd = nodeStart + node.nodeSize; - const { selection } = view.state; - if (selection.anchor < nodeStart || selection.anchor > nodeEnd) { - return false; - } - event.preventDefault(); - alert("No down keys allowed!"); - return true; - }); +import { forwardRef, Ref } from "react"; +import { + useEditorEventListener, + NodeViewComponentProps, +} from "@nytimes/react-prosemirror"; - return

{children}

; -} +const Paragraph = forwardRef( + function Paragraph({ children, nodeProps, ...props }, ref) { + useEditorEventListener("keydown", (view, event) => { + const { pos, node } = nodeProps; + + if (event.code !== "ArrowDown") { + return false; + } + const nodeEnd = pos + node.nodeSize; + const { selection } = view.state; + if (selection.anchor < pos || selection.anchor > nodeEnd) { + return false; + } + event.preventDefault(); + alert("No down keys allowed!"); + return true; + }); + + return ( +

+ {children} +

+ ); + } +); ``` -#### `useEditorView`, `EditorProvider` and `LayoutGroup` - -Under the hood, the `ProseMirror` component essentially just composes three -separate tools: `useEditorView`, `EditorProvider`, and `LayoutGroup`. If you -find yourself in need of more control over these, they can also be used -independently. - -`useEditorView` is a relatively simple hook that takes a mount point and -`EditorProps` as arguments and returns an EditorView instance. - -`EditorProvider` is a simple React context, which should be provided the current -EditorView and EditorState. - -`LayoutGroup` _must_ be rendered as a parent of the component using -`useEditorView`. - -### Building NodeViews with React +### Building node views with React The other way to integrate React and ProseMirror is to have ProseMirror render -NodeViews using React components. This is somewhat more complex than the -previous section. This library provides a `useNodeViews` hook, a factory for -augmenting NodeView constructors with React components, and `react`, a -ProseMirror Plugin for maintaining the React component hierarchy. - -`useNodeViews` takes a map from node name to an extended NodeView constructor. -The NodeView constructor must return at least a `dom` attribute and a -`component` attribute, but can also return any other NodeView attributes. Here's -an example of its usage: +node views using React components. Because React ProseMirror renders the +ProseMirror document with React, node view components don't need to do anything +special other than fulfill the +[`NodeViewComponentProps`](#nodeviewcomponentprops) interface. ```tsx +import { forwardRef, Ref } from "react"; import { - useNodeViews, + ProseMirror, + ProseMirrorDoc, useEditorEventCallback, NodeViewComponentProps, - react, + reactKeys, } from "@nytimes/react-prosemirror"; import { EditorState } from "prosemirror-state"; import { schema } from "prosemirror-schema-basic"; // Paragraph is more or less a normal React component, taking and rendering -// its children. The actual children will be constructed by ProseMirror and -// passed in here. Take a look at the NodeViewComponentProps type to -// see what other props will be passed to NodeView components. -function Paragraph({ children }: NodeViewComponentProps) { - const onClick = useEditorEventCallback((view) => view.dispatch(whatever)); - return

{children}

; -} - -// Make sure that your ReactNodeViews are defined outside of -// your component, or are properly memoized. ProseMirror will -// teardown and rebuild all NodeViews if the nodeView prop is -// updated, leading to unbounded recursion if this object doesn't -// have a stable reference. -const reactNodeViews = { - paragraph: () => ({ - component: Paragraph, - // We render the Paragraph component itself into a div element - dom: document.createElement("div"), - // We render the paragraph node's ProseMirror contents into - // a span, which will be passed as children to the Paragraph - // component. - contentDOM: document.createElement("span"), - }), -}; - -const editorState = EditorState.create({ - schema, - // You must add the react plugin if you use - // the useNodeViews or useNodePos hook. - plugins: [react()], -}); +// its children. All node view components _must_ forward refs to their top-level +// DOM elements. All node view components _should_ spread all of the props that they +// receive onto their top-level DOM elements; this is required for node Decorations +// that apply attributes rather than wrapping nodes in an additional element. +const Paragraph = forwardRef( + function Paragraph({ children, nodeProps, ...props }, ref) { + const onClick = useEditorEventCallback((view) => + view.dispatch(view.state.tr.deleteSelection()) + ); + + return ( +

+ {children} +

+ ); + } +); function ProseMirrorEditor() { - const { nodeViews, renderNodeViews } = useNodeViews(reactNodeViews); - const [mount, setMount] = useState(null); - return ( - -
- {renderNodeViews()} + + ); } @@ -405,91 +407,81 @@ function ProseMirrorEditor() { ```tsx type ProseMirror = ( - props: { - mount: HTMLElement; - children: ReactNode; - } & DirectEditorProps & - ({ defaultState: EditorState } | { state: EditorState }) + props: DirectEditorProps & + ({ defaultState: EditorState } | { state: EditorState }) & { + children: ReactNode; + nodeViews?: { + [nodeType: string]: ForwardRefExoticComponent< + NodeViewComponentProps & RefAttributes + >; + }; + customNodeViews?: { + [nodeType: string]: NodeViewConstructor; + }; + } ) => JSX.Element; ``` -Renders the ProseMirror View onto a DOM mount. - -The `mount` prop must be an actual HTMLElement instance. The JSX element -representing the mount should be passed as a child to the ProseMirror component. +Renders the ProseMirror editor. Example usage: ```tsx -function MyProseMirrorField() { - const [mount, setMount] = useState(null); +import { EditorState } from "prosemirror-state"; +import { + ProseMirror, + ProseMirrorDoc, + reactKeys, +} from "@nytimes/react-prosemirror"; +export function ProseMirrorEditor() { return ( - -
+ + ); } ``` -### `EditorProvider` +### `ProseMirrorDoc` ```tsx -type EditorProvider = React.Provider<{ - editorView: EditorView | null; - editorState: EditorState | null; - registerEventListener( - eventType: EventType, - handler: EventHandler - ): void; - unregisterEventListener( - eventType: EventType, - handler: EventHandler - ): void; -}>; +type ProseMirrorDoc = (props: { as?: ReactElement }) => JSX.Element; ``` -Provides the EditorView, as well as the current EditorState. Should not be -consumed directly; instead see [`useEditorState`](#useeditorstate), -[`useEditorEventCallback`](#useeditorevent), and -[`useEditorEffect`](#useeditoreffect-1). +Renders the actual editable ProseMirror document. -See [ProseMirrorInner.tsx](./src/components/ProseMirrorInner.tsx) for example -usage. Note that if you are using the [`ProseMirror`](#prosemirror) component, -you don't need to use this provider directly. +This **must** be passed as a child to the `ProseMirror` component. It may be +wrapped in any other components, and other children may be passed before or +after -### `LayoutGroup` +Example usage: ```tsx -type LayoutGroup = (props: { children: React.ReactNode }) => JSX.Element; -``` - -Provides a deferral point for grouped layout effects. All effects registered -with `useLayoutGroupEffect` by children of this provider will execute _after_ -all effects registered by `useLayoutEffect` by children of this provider. - -See [ProseMirror.tsx](./src/components/ProseMirror.tsx) for example usage. Note -that if you are using the [`ProseMirror`](#prosemirror) component, you don't -need to use this context directly. - -### `useLayoutGroupEffect` +import { EditorState } from "prosemirror-state"; +import { + ProseMirror, + ProseMirrorDoc, + reactKeys, +} from "@nytimes/react-prosemirror"; -```tsx -type useLayoutGroupEffect = ( - effect: React.EffectCallback, - deps?: React.DependencyList -) => void; +export function ProseMirrorEditor() { + return ( + + + + } /> + + + + ); +} ``` -Like `useLayoutEffect`, but all effect executions are run _after_ the -`LayoutGroup` layout effects phase. - -This hook allows child components to enqueue layout effects that won't be safe -to run until after a parent component's layout effects have run. - -Note that components that use this hook must be descendants of the -[`LayoutGroup`](#layoutgroup) component. - ### `useEditorState` ```tsx @@ -498,26 +490,6 @@ type useEditorState = () => EditorState | null; Provides access to the current EditorState value. -### `useEditorView` - -```tsx -type useEditorView = ( - mount: T | null, - props: DirectEditorProps -) => EditorView | null; -``` - -Creates, mounts, and manages a ProseMirror `EditorView`. - -All state and props updates are executed in a layout effect. To ensure that the -EditorState and EditorView are never out of sync, it's important that the -EditorView produced by this hook is only accessed through the hooks exposed by -this library. - -See [ProseMirrorInner.tsx](./src/components/ProseMirrorInner.tsx) for example -usage. Note that if you are using the [`ProseMirror`](#prosemirror) component, -you don't need to use this hook directly. - ### `useEditorEventCallback` ```tsx @@ -530,7 +502,7 @@ Returns a stable function reference to be used as an event handler callback. The callback will be called with the EditorView instance as its first argument. -This hook is dependent on both the `EditorProvider.Provider` and the +This hook is dependent on both the `EditorContext.Provider` and the `LayoutGroup`. It can only be used in a component that is mounted as a child of both of these providers. @@ -597,84 +569,46 @@ export function SelectionWidget() { } ``` -### `useNodePos` - -```tsx -type useNodePos = () => number; -``` - -Returns the node's current position in the document. Takes the place of -ProseMirror's `getPos` function that gets passed to NodeView's, which is unsafe -to use in React render functions. - -This hook can only be used in React components rendered with -[`useNodeViews`](#usenodeviews). - -### `useNodeViews` +### `NodeViewComponentProps` ```tsx -/** - * Extension of ProseMirror's NodeViewConstructor type to include - * `component`, the React component to used render the NodeView. - * All properties other than `component` and `dom` are optional. - */ -type ReactNodeViewConstructor = ( - node: Node, - view: EditorView, - getPos: () => number, - decorations: readonly Decoration[], - innerDecorations: DecorationSource -) => { - dom: HTMLElement | null; - component: React.ComponentType; - contentDOM?: HTMLElement | null; - selectNode?: () => void; - deselectNode?: () => void; - setSelection?: ( - anchor: number, - head: number, - root: Document | ShadowRoot - ) => void; - stopEvent?: (event: Event) => boolean; - ignoreMutation?: (mutation: MutationRecord) => boolean; - destroy?: () => void; - update?: ( - node: Node, - decorations: readonly Decoration[], - innerDecoration: DecorationSource - ) => boolean; -}; - -type useNodeViews = (nodeViews: Record) => { - nodeViews: Record; - renderNodeViews: () => ReactElement[]; -}; +type NodeViewComponentProps = { + decorations: readonly Decoration[]; + innerDecorations: DecorationSource; + node: Node; + children?: ReactNode | ReactNode[]; + isSelected: boolean; + pos: number; +} & HTMLAttributes; ``` -Hook for creating and rendering NodeViewConstructors that are powered by React -components. To use this hook, you must also include -[`react`](#reactnodeviewplugin) in your `EditorState`. +The props that will be passed to all node view components. These props map +directly to the arguments passed to +[`NodeViewConstructor` functions](https://prosemirror.net/docs/ref/#view.NodeViewConstructor) +by the default ProseMirror EditorView implementation. -`component` can be any React component that takes `NodeViewComponentProps`. It -will be passed as props all of the arguments to the `nodeViewConstructor` except -for `editorView`. NodeView components that need access directly to the -EditorView should use the `useEditorEventCallback`, `useEditorEventListener` and -`useEditorEffect` hooks to ensure safe access. +Node view components may also be passed _any_ other valid HTML attribute props, +and should pass them through to their top-level DOM element. +[See the above example](#building-node-views-with-react) for more details. -For contentful Nodes, the NodeView component will also be passed a `children` -prop containing an empty element. ProseMirror will render content nodes into -this element. Like in ProseMirror, the existence of a `contentDOM` attribute -determines whether a NodeView is contentful (i.e. the NodeView has editable -content that should be managed by ProseMirror). +In addition to accepting these props, all node view components _must_ forward +their ref to their top-level DOM element. -### `react` +### `widget` ```tsx -type react = Plugin>; +type widget = ( + pos: number, + component: ForwardRefExoticComponent< + RefAttributes & WidgetComponentProps + >, + spec?: ReactWidgetSpec +) => Decoration(pos, pos, new ReactWidgetType(component, spec)) ``` -A ProseMirror Plugin that assists in maintaining the correct hierarchy for React -node views. +Like ProseMirror View's `Decoration.widget`, but with support for React +components. -If you use `useNodeViews` or `useNodePos`, you _must_ include this plugin in -your `EditorState`. +**Note**: The default `Decoration.widget` implementation _will not_ work with +this library. If you wish to use widget decorations, you must use this library's +`widget` method, instead. diff --git a/demo/main.css b/demo/main.css index f419ecc3..9160a694 100644 --- a/demo/main.css +++ b/demo/main.css @@ -3,7 +3,7 @@ border-radius: 0.25rem; padding: 1rem; outline: none; - min-height: 700px; + min-height: 200px; } main { diff --git a/demo/main.tsx b/demo/main.tsx index 10d94ad9..f848801a 100644 --- a/demo/main.tsx +++ b/demo/main.tsx @@ -1,115 +1,348 @@ -import { - baseKeymap, - chainCommands, - createParagraphNear, - liftEmptyBlock, - newlineInCode, - splitBlock, -} from "prosemirror-commands"; +import { baseKeymap, toggleMark } from "prosemirror-commands"; +import { gapCursor } from "prosemirror-gapcursor"; +import "prosemirror-gapcursor/style/gapcursor.css"; +import { inputRules, wrappingInputRule } from "prosemirror-inputrules"; import { keymap } from "prosemirror-keymap"; import { Schema } from "prosemirror-model"; -import { liftListItem, splitListItem } from "prosemirror-schema-list"; -import { EditorState, Transaction } from "prosemirror-state"; +import { EditorState, Plugin } from "prosemirror-state"; +import { columnResizing, tableEditing, tableNodes } from "prosemirror-tables"; +import "prosemirror-tables/style/tables.css"; +import { + Decoration, + DecorationSet, + EditorView, + NodeViewConstructor, +} from "prosemirror-view"; import "prosemirror-view/style/prosemirror.css"; -import React, { useCallback, useState } from "react"; +import React, { + ForwardedRef, + Ref, + StrictMode, + forwardRef, + useState, +} from "react"; import { createRoot } from "react-dom/client"; import { NodeViewComponentProps, ProseMirror, - useNodeViews, + ProseMirrorDoc, + WidgetViewComponentProps, + reactKeys, + widget, } from "../src/index.js"; -import { ReactNodeViewConstructor } from "../src/nodeViews/createReactNodeViewConstructor.js"; -import { react } from "../src/plugins/react.js"; import "./main.css"; const schema = new Schema({ nodes: { doc: { content: "block+" }, - paragraph: { group: "block", content: "inline*" }, - list: { group: "block", content: "list_item+" }, - list_item: { content: "paragraph+", toDOM: () => ["li", 0] }, + paragraph: { + group: "block", + content: "inline*", + toDOM() { + return ["p", 0]; + }, + }, + ...tableNodes({ + cellContent: "inline*", + cellAttributes: {}, + tableGroup: "block", + }), + footnote: { + group: "inline", + content: "text*", + inline: true, + // This makes the view treat the node as a leaf, even though it + // technically has content + atom: true, + attrs: { number: { default: 0 } }, + }, + list: { + group: "block", + content: "list_item+", + toDOM() { + return ["ul", 0]; + }, + }, + list_item: { + content: "paragraph+", + toDOM() { + return ["li", 0]; + }, + }, + image: { + group: "block", + toDOM() { + return [ + "div", + [ + "img", + { + src: "https://smoores.gitlab.io/storyteller/img/Storyteller_Logo.png", + height: 150, + width: 150, + }, + ], + ]; + }, + }, text: { group: "inline" }, }, + marks: { + em: { + toDOM() { + return ["em", 0]; + }, + }, + strong: { + toDOM() { + return ["strong", 0]; + }, + }, + }, }); const editorState = EditorState.create({ - doc: schema.topNodeType.create(null, [ - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - schema.nodes.paragraph.createAndFill()!, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - schema.nodes.list.createAndFill()!, - ]), schema, + doc: schema.nodes.doc.create({}, [ + schema.nodes.paragraph.create({}, [ + schema.text("This ", [schema.marks.em.create()]), + schema.text("is", [ + schema.marks.em.create(), + schema.marks.strong.create(), + ]), + schema.text(" the first paragraph"), + ]), + schema.nodes.paragraph.create({}, [ + schema.text("This is the second paragraph"), + schema.nodes.footnote.create({ number: 1 }, schema.text("Footnote")), + ]), + schema.nodes.paragraph.create(), + schema.nodes.image.create(), + schema.nodes.image.create(), + schema.nodes.paragraph.create( + {}, + schema.text("This is the third paragraph 🫵") + ), + schema.nodes.table.create({}, [ + schema.nodes.table_row.create({}, [ + schema.nodes.table_header.create({}, schema.text("h1")), + schema.nodes.table_header.create({}, schema.text("h2")), + ]), + schema.nodes.table_row.create({}, [ + schema.nodes.table_cell.create({}, schema.text("c1")), + schema.nodes.table_cell.create({}, schema.text("c2")), + ]), + ]), + ]), plugins: [ - keymap({ - ...baseKeymap, - Enter: chainCommands( - newlineInCode, - createParagraphNear, - liftEmptyBlock, - splitListItem(schema.nodes.list_item), - splitBlock - ), - "Shift-Enter": baseKeymap.Enter, - "Shift-Tab": liftListItem(schema.nodes.list_item), + reactKeys(), + inputRules({ + rules: [wrappingInputRule(/^\s*([-+*])\s$/, schema.nodes.list)], }), - react(), + columnResizing(), + tableEditing(), ], }); -function Paragraph({ children }: NodeViewComponentProps) { - return

{children}

; -} +const Paragraph = forwardRef(function Paragraph( + { children, nodeProps, ...props }: NodeViewComponentProps, + ref: Ref +) { + return ( +

+ {children} +

+ ); +}); -function List({ children }: NodeViewComponentProps) { - return
    {children}
; -} +const List = forwardRef(function List( + { children, nodeProps, ...props }: NodeViewComponentProps, + ref: Ref +) { + return ( +
    + {children} +
+ ); +}); -function ListItem({ children }: NodeViewComponentProps) { - return
  • {children}
  • ; -} +const ListItem = forwardRef(function ListItem( + { children, nodeProps, ...props }: NodeViewComponentProps, + ref: Ref +) { + return ( +
  • + {children} +
  • + ); +}); -const reactNodeViews: Record = { - paragraph: () => ({ - component: Paragraph, - dom: document.createElement("div"), - contentDOM: document.createElement("span"), - }), - list: () => ({ - component: List, - dom: document.createElement("div"), - contentDOM: document.createElement("div"), - }), - list_item: () => ({ - component: ListItem, - dom: document.createElement("div"), - contentDOM: document.createElement("div"), +const Footnote = forwardRef(function Footnote( + { nodeProps, ...props }: NodeViewComponentProps, + ref: Ref +) { + return ( + + + + ); +}); + +const TestWidget = forwardRef(function TestWidget( + { widget, pos, ...props }: WidgetViewComponentProps, + ref: ForwardedRef +) { + return ( + + Widget + + ); +}); + +const viewPlugin = new Plugin({ + view(view) { + const coords = view.coordsAtPos(view.state.selection.from); + const dom = document.createElement("div"); + dom.style.width = "4px"; + dom.style.height = "4px"; + dom.style.position = "absolute"; + dom.style.top = `${coords.top - 2}px`; + dom.style.left = `${coords.left - 2}px`; + dom.style.backgroundColor = "blue"; + document.body.appendChild(dom); + return { + update(view) { + const coords = view.coordsAtPos(view.state.selection.from); + dom.style.top = `${coords.top - 2}px`; + dom.style.left = `${coords.left - 2}px`; + }, + destroy() { + document.body.removeChild(dom); + }, + }; + }, +}); + +// Need to handle widgets from plugins +// in ReactEditorView; current call to super +// breaks for React widgets +const widgetPlugin = new Plugin({ + props: { + decorations(state) { + return DecorationSet.create(state.doc, [ + widget(state.selection.from, TestWidget, { + side: 0, + key: "widget-plugin-widget", + }), + ]); + }, + }, + view(view) { + const coords = view.coordsAtPos(view.state.selection.from); + const dom = document.createElement("div"); + dom.style.width = "4px"; + dom.style.height = "4px"; + dom.style.position = "absolute"; + dom.style.top = `${coords.top - 2}px`; + dom.style.left = `${coords.left - 2}px`; + dom.style.backgroundColor = "blue"; + document.body.appendChild(dom); + return { + update(view) { + const coords = view.coordsAtPos(view.state.selection.from); + dom.style.top = `${coords.top - 2}px`; + dom.style.left = `${coords.left - 2}px`; + }, + destroy() { + document.body.removeChild(dom); + }, + }; + }, +}); + +const plugins = [ + keymap({ + ...baseKeymap, + "Mod-i": toggleMark(schema.marks.em), + "Mod-b": toggleMark(schema.marks.strong), }), + viewPlugin, + gapCursor(), + // widgetPlugin, +]; + +const customNodeViews: Record = { + paragraph: () => { + const dom = document.createElement("p"); + return { + dom, + contentDOM: dom, + }; + }, }; function DemoEditor() { - const { nodeViews, renderNodeViews } = useNodeViews(reactNodeViews); - const [mount, setMount] = useState(null); const [state, setState] = useState(editorState); - - const dispatchTransaction = useCallback( - (tr: Transaction) => setState((oldState) => oldState.apply(tr)), - [] - ); + const [showReactNodeViews, setShowReactNodeViews] = useState(true); return (

    React ProseMirror Demo

    + { + return prev.apply(tr); + }); + }} + plugins={plugins} + nodeViews={ + showReactNodeViews + ? { + paragraph: Paragraph, + list: List, + list_item: ListItem, + footnote: Footnote, + } + : undefined + } + customNodeViews={showReactNodeViews ? undefined : customNodeViews} > -
    - {renderNodeViews()} + } />
    ); @@ -118,4 +351,8 @@ function DemoEditor() { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const root = createRoot(document.getElementById("root")!); -root.render(); +root.render( + + + +); diff --git a/docs/assets/index-DAGU9WLy.css b/docs/assets/index-DAGU9WLy.css new file mode 100644 index 00000000..c094ee34 --- /dev/null +++ b/docs/assets/index-DAGU9WLy.css @@ -0,0 +1 @@ +.ProseMirror-gapcursor{display:none;pointer-events:none;position:absolute}.ProseMirror-gapcursor:after{content:"";display:block;position:absolute;top:-2px;width:20px;border-top:1px solid black;animation:ProseMirror-cursor-blink 1.1s steps(2,start) infinite}@keyframes ProseMirror-cursor-blink{to{visibility:hidden}}.ProseMirror-focused .ProseMirror-gapcursor{display:block}.ProseMirror .tableWrapper{overflow-x:auto}.ProseMirror table{border-collapse:collapse;table-layout:fixed;width:100%;overflow:hidden}.ProseMirror td,.ProseMirror th{vertical-align:top;box-sizing:border-box;position:relative}.ProseMirror .column-resize-handle{position:absolute;right:-2px;top:0;bottom:0;width:4px;z-index:20;background-color:#adf;pointer-events:none}.ProseMirror.resize-cursor{cursor:ew-resize;cursor:col-resize}.ProseMirror .selectedCell:after{z-index:2;position:absolute;content:"";left:0;right:0;top:0;bottom:0;background:#c8c8ff66;pointer-events:none}.ProseMirror{position:relative}.ProseMirror{word-wrap:break-word;white-space:pre-wrap;white-space:break-spaces;-webkit-font-variant-ligatures:none;font-variant-ligatures:none;font-feature-settings:"liga" 0}.ProseMirror pre{white-space:pre-wrap}.ProseMirror li{position:relative}.ProseMirror-hideselection *::selection{background:transparent}.ProseMirror-hideselection *::-moz-selection{background:transparent}.ProseMirror-hideselection{caret-color:transparent}.ProseMirror [draggable][contenteditable=false]{-webkit-user-select:text;user-select:text}.ProseMirror-selectednode{outline:2px solid #8cf}li.ProseMirror-selectednode{outline:none}li.ProseMirror-selectednode:after{content:"";position:absolute;left:-32px;right:-2px;top:-2px;bottom:-2px;border:2px solid #8cf;pointer-events:none}img.ProseMirror-separator{display:inline!important;border:none!important;margin:0!important}.ProseMirror{border:thin solid black;border-radius:.25rem;padding:1rem;outline:none;min-height:200px}main{margin:auto;width:80%;max-width:700px} diff --git a/docs/assets/index-DM4UcNX5.js b/docs/assets/index-DM4UcNX5.js new file mode 100644 index 00000000..cb5bc1cb --- /dev/null +++ b/docs/assets/index-DM4UcNX5.js @@ -0,0 +1,53 @@ +(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))r(i);new MutationObserver(i=>{for(const o of i)if(o.type==="childList")for(const s of o.addedNodes)s.tagName==="LINK"&&s.rel==="modulepreload"&&r(s)}).observe(document,{childList:!0,subtree:!0});function t(i){const o={};return i.integrity&&(o.integrity=i.integrity),i.referrerPolicy&&(o.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?o.credentials="include":i.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function r(i){if(i.ep)return;i.ep=!0;const o=t(i);fetch(i.href,o)}})();function Z1(n){return n&&n.__esModule&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n}var om={exports:{}},Kl={},sm={exports:{}},B={};/** + * @license React + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Uo=Symbol.for("react.element"),eS=Symbol.for("react.portal"),tS=Symbol.for("react.fragment"),nS=Symbol.for("react.strict_mode"),rS=Symbol.for("react.profiler"),iS=Symbol.for("react.provider"),oS=Symbol.for("react.context"),sS=Symbol.for("react.forward_ref"),lS=Symbol.for("react.suspense"),aS=Symbol.for("react.memo"),uS=Symbol.for("react.lazy"),wd=Symbol.iterator;function cS(n){return n===null||typeof n!="object"?null:(n=wd&&n[wd]||n["@@iterator"],typeof n=="function"?n:null)}var lm={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},am=Object.assign,um={};function ci(n,e,t){this.props=n,this.context=e,this.refs=um,this.updater=t||lm}ci.prototype.isReactComponent={};ci.prototype.setState=function(n,e){if(typeof n!="object"&&typeof n!="function"&&n!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,n,e,"setState")};ci.prototype.forceUpdate=function(n){this.updater.enqueueForceUpdate(this,n,"forceUpdate")};function cm(){}cm.prototype=ci.prototype;function jc(n,e,t){this.props=n,this.context=e,this.refs=um,this.updater=t||lm}var Kc=jc.prototype=new cm;Kc.constructor=jc;am(Kc,ci.prototype);Kc.isPureReactComponent=!0;var kd=Array.isArray,fm=Object.prototype.hasOwnProperty,qc={current:null},dm={key:!0,ref:!0,__self:!0,__source:!0};function hm(n,e,t){var r,i={},o=null,s=null;if(e!=null)for(r in e.ref!==void 0&&(s=e.ref),e.key!==void 0&&(o=""+e.key),e)fm.call(e,r)&&!dm.hasOwnProperty(r)&&(i[r]=e[r]);var l=arguments.length-2;if(l===1)i.children=t;else if(1>1}};he.from=function(n){if(n instanceof he)return n;var e=[];if(n)for(var t in n)e.push(t,n[t]);return new he(e)};function mm(n,e,t){for(let r=0;;r++){if(r==n.childCount||r==e.childCount)return n.childCount==e.childCount?null:t;let i=n.child(r),o=e.child(r);if(i==o){t+=i.nodeSize;continue}if(!i.sameMarkup(o))return t;if(i.isText&&i.text!=o.text){for(let s=0;i.text[s]==o.text[s];s++)t++;return t}if(i.content.size||o.content.size){let s=mm(i.content,o.content,t+1);if(s!=null)return s}t+=i.nodeSize}}function gm(n,e,t,r){for(let i=n.childCount,o=e.childCount;;){if(i==0||o==0)return i==o?null:{a:t,b:r};let s=n.child(--i),l=e.child(--o),a=s.nodeSize;if(s==l){t-=a,r-=a;continue}if(!s.sameMarkup(l))return{a:t,b:r};if(s.isText&&s.text!=l.text){let u=0,c=Math.min(s.text.length,l.text.length);for(;ue&&r(a,i+l,o||null,s)!==!1&&a.content.size){let c=l+1;a.nodesBetween(Math.max(0,e-c),Math.min(a.content.size,t-c),r,i+c)}l=u}}descendants(e){this.nodesBetween(0,this.size,e)}textBetween(e,t,r,i){let o="",s=!0;return this.nodesBetween(e,t,(l,a)=>{let u=l.isText?l.text.slice(Math.max(e,a)-a,t-a):l.isLeaf?i?typeof i=="function"?i(l):i:l.type.spec.leafText?l.type.spec.leafText(l):"":"";l.isBlock&&(l.isLeaf&&u||l.isTextblock)&&r&&(s?s=!1:o+=r),o+=u},0),o}append(e){if(!e.size)return this;if(!this.size)return e;let t=this.lastChild,r=e.firstChild,i=this.content.slice(),o=0;for(t.isText&&t.sameMarkup(r)&&(i[i.length-1]=t.withText(t.text+r.text),o=1);oe)for(let o=0,s=0;se&&((st)&&(l.isText?l=l.cut(Math.max(0,e-s),Math.min(l.text.length,t-s)):l=l.cut(Math.max(0,e-s-1),Math.min(l.content.size,t-s-1))),r.push(l),i+=l.nodeSize),s=a}return new v(r,i)}cutByIndex(e,t){return e==t?v.empty:e==0&&t==this.content.length?this:new v(this.content.slice(e,t))}replaceChild(e,t){let r=this.content[e];if(r==t)return this;let i=this.content.slice(),o=this.size+t.nodeSize-r.nodeSize;return i[e]=t,new v(i,o)}addToStart(e){return new v([e].concat(this.content),this.size+e.nodeSize)}addToEnd(e){return new v(this.content.concat(e),this.size+e.nodeSize)}eq(e){if(this.content.length!=e.content.length)return!1;for(let t=0;tthis.size||e<0)throw new RangeError(`Position ${e} outside of fragment (${this})`);for(let r=0,i=0;;r++){let o=this.child(r),s=i+o.nodeSize;if(s>=e)return s==e||t>0?ls(r+1,s):ls(r,i);i=s}}toString(){return"<"+this.toStringInner()+">"}toStringInner(){return this.content.join(", ")}toJSON(){return this.content.length?this.content.map(e=>e.toJSON()):null}static fromJSON(e,t){if(!t)return v.empty;if(!Array.isArray(t))throw new RangeError("Invalid input for Fragment.fromJSON");return new v(t.map(e.nodeFromJSON))}static fromArray(e){if(!e.length)return v.empty;let t,r=0;for(let i=0;ithis.type.rank&&(t||(t=e.slice(0,i)),t.push(this),r=!0),t&&t.push(o)}}return t||(t=e.slice()),r||t.push(this),t}removeFromSet(e){for(let t=0;tr.type.rank-i.type.rank),t}}U.none=[];class En extends Error{}class k{constructor(e,t,r){this.content=e,this.openStart=t,this.openEnd=r}get size(){return this.content.size-this.openStart-this.openEnd}insertAt(e,t){let r=Sm(this.content,e+this.openStart,t);return r&&new k(r,this.openStart,this.openEnd)}removeBetween(e,t){return new k(ym(this.content,e+this.openStart,t+this.openStart),this.openStart,this.openEnd)}eq(e){return this.content.eq(e.content)&&this.openStart==e.openStart&&this.openEnd==e.openEnd}toString(){return this.content+"("+this.openStart+","+this.openEnd+")"}toJSON(){if(!this.content.size)return null;let e={content:this.content.toJSON()};return this.openStart>0&&(e.openStart=this.openStart),this.openEnd>0&&(e.openEnd=this.openEnd),e}static fromJSON(e,t){if(!t)return k.empty;let r=t.openStart||0,i=t.openEnd||0;if(typeof r!="number"||typeof i!="number")throw new RangeError("Invalid input for Slice.fromJSON");return new k(v.fromJSON(e,t.content),r,i)}static maxOpen(e,t=!0){let r=0,i=0;for(let o=e.firstChild;o&&!o.isLeaf&&(t||!o.type.spec.isolating);o=o.firstChild)r++;for(let o=e.lastChild;o&&!o.isLeaf&&(t||!o.type.spec.isolating);o=o.lastChild)i++;return new k(e,r,i)}}k.empty=new k(v.empty,0,0);function ym(n,e,t){let{index:r,offset:i}=n.findIndex(e),o=n.maybeChild(r),{index:s,offset:l}=n.findIndex(t);if(i==e||o.isText){if(l!=t&&!n.child(s).isText)throw new RangeError("Removing non-flat range");return n.cut(0,e).append(n.cut(t))}if(r!=s)throw new RangeError("Removing non-flat range");return n.replaceChild(r,o.copy(ym(o.content,e-i-1,t-i-1)))}function Sm(n,e,t,r){let{index:i,offset:o}=n.findIndex(e),s=n.maybeChild(i);if(o==e||s.isText)return n.cut(0,e).append(t).append(n.cut(e));let l=Sm(s.content,e-o-1,t);return l&&n.replaceChild(i,s.copy(l))}function vS(n,e,t){if(t.openStart>n.depth)throw new En("Inserted content deeper than insertion position");if(n.depth-t.openStart!=e.depth-t.openEnd)throw new En("Inconsistent open depths");return wm(n,e,t,0)}function wm(n,e,t,r){let i=n.index(r),o=n.node(r);if(i==e.index(r)&&r=0&&n.isText&&n.sameMarkup(e[t])?e[t]=n.withText(e[t].text+n.text):e.push(n)}function Gi(n,e,t,r){let i=(e||n).node(t),o=0,s=e?e.index(t):i.childCount;n&&(o=n.index(t),n.depth>t?o++:n.textOffset&&(Yn(n.nodeAfter,r),o++));for(let l=o;li&&ku(n,e,i+1),s=r.depth>i&&ku(t,r,i+1),l=[];return Gi(null,n,i,l),o&&s&&e.index(i)==t.index(i)?(km(o,s),Yn(Gn(o,vm(n,e,t,r,i+1)),l)):(o&&Yn(Gn(o,ul(n,e,i+1)),l),Gi(e,t,i,l),s&&Yn(Gn(s,ul(t,r,i+1)),l)),Gi(r,null,i,l),new v(l)}function ul(n,e,t){let r=[];if(Gi(null,n,t,r),n.depth>t){let i=ku(n,e,t+1);Yn(Gn(i,ul(n,e,t+1)),r)}return Gi(e,null,t,r),new v(r)}function xS(n,e){let t=e.depth-n.openStart,i=e.node(t).copy(n.content);for(let o=t-1;o>=0;o--)i=e.node(o).copy(v.from(i));return{start:i.resolveNoCache(n.openStart+t),end:i.resolveNoCache(i.content.size-n.openEnd-t)}}class po{constructor(e,t,r){this.pos=e,this.path=t,this.parentOffset=r,this.depth=t.length/3-1}resolveDepth(e){return e==null?this.depth:e<0?this.depth+e:e}get parent(){return this.node(this.depth)}get doc(){return this.node(0)}node(e){return this.path[this.resolveDepth(e)*3]}index(e){return this.path[this.resolveDepth(e)*3+1]}indexAfter(e){return e=this.resolveDepth(e),this.index(e)+(e==this.depth&&!this.textOffset?0:1)}start(e){return e=this.resolveDepth(e),e==0?0:this.path[e*3-1]+1}end(e){return e=this.resolveDepth(e),this.start(e)+this.node(e).content.size}before(e){if(e=this.resolveDepth(e),!e)throw new RangeError("There is no position before the top-level node");return e==this.depth+1?this.pos:this.path[e*3-1]}after(e){if(e=this.resolveDepth(e),!e)throw new RangeError("There is no position after the top-level node");return e==this.depth+1?this.pos:this.path[e*3-1]+this.path[e*3].nodeSize}get textOffset(){return this.pos-this.path[this.path.length-1]}get nodeAfter(){let e=this.parent,t=this.index(this.depth);if(t==e.childCount)return null;let r=this.pos-this.path[this.path.length-1],i=e.child(t);return r?e.child(t).cut(r):i}get nodeBefore(){let e=this.index(this.depth),t=this.pos-this.path[this.path.length-1];return t?this.parent.child(e).cut(0,t):e==0?null:this.parent.child(e-1)}posAtIndex(e,t){t=this.resolveDepth(t);let r=this.path[t*3],i=t==0?0:this.path[t*3-1]+1;for(let o=0;o0;t--)if(this.start(t)<=e&&this.end(t)>=e)return t;return 0}blockRange(e=this,t){if(e.pos=0;r--)if(e.pos<=this.end(r)&&(!t||t(this.node(r))))return new MS(this,e,r);return null}sameParent(e){return this.pos-this.parentOffset==e.pos-e.parentOffset}max(e){return e.pos>this.pos?e:this}min(e){return e.pos=0&&t<=e.content.size))throw new RangeError("Position "+t+" out of range");let r=[],i=0,o=t;for(let s=e;;){let{index:l,offset:a}=s.content.findIndex(o),u=o-a;if(r.push(s,l,i+a),!u||(s=s.child(l),s.isText))break;o=u-1,i+=a+1}return new po(t,r,o)}static resolveCached(e,t){let r=xd.get(e);if(r)for(let o=0;oe&&this.nodesBetween(e,t,o=>(r.isInSet(o.marks)&&(i=!0),!i)),i}get isBlock(){return this.type.isBlock}get isTextblock(){return this.type.isTextblock}get inlineContent(){return this.type.inlineContent}get isInline(){return this.type.isInline}get isText(){return this.type.isText}get isLeaf(){return this.type.isLeaf}get isAtom(){return this.type.isAtom}toString(){if(this.type.spec.toDebugString)return this.type.spec.toDebugString(this);let e=this.type.name;return this.content.size&&(e+="("+this.content.toStringInner()+")"),xm(this.marks,e)}contentMatchAt(e){let t=this.type.contentMatch.matchFragment(this.content,0,e);if(!t)throw new Error("Called contentMatchAt on a node with invalid content");return t}canReplace(e,t,r=v.empty,i=0,o=r.childCount){let s=this.contentMatchAt(e).matchFragment(r,i,o),l=s&&s.matchFragment(this.content,t);if(!l||!l.validEnd)return!1;for(let a=i;at.type.name)}`);this.content.forEach(t=>t.check())}toJSON(){let e={type:this.type.name};for(let t in this.attrs){e.attrs=this.attrs;break}return this.content.size&&(e.content=this.content.toJSON()),this.marks.length&&(e.marks=this.marks.map(t=>t.toJSON())),e}static fromJSON(e,t){if(!t)throw new RangeError("Invalid input for Node.fromJSON");let r;if(t.marks){if(!Array.isArray(t.marks))throw new RangeError("Invalid mark data for Node.fromJSON");r=t.marks.map(e.markFromJSON)}if(t.type=="text"){if(typeof t.text!="string")throw new RangeError("Invalid text node in JSON");return e.text(t.text,r)}let i=v.fromJSON(e,t.content),o=e.nodeType(t.type).create(t.attrs,i,r);return o.type.checkAttrs(o.attrs),o}}Tt.prototype.text=void 0;class cl extends Tt{constructor(e,t,r,i){if(super(e,t,null,i),!r)throw new RangeError("Empty text nodes are not allowed");this.text=r}toString(){return this.type.spec.toDebugString?this.type.spec.toDebugString(this):xm(this.marks,JSON.stringify(this.text))}get textContent(){return this.text}textBetween(e,t){return this.text.slice(e,t)}get nodeSize(){return this.text.length}mark(e){return e==this.marks?this:new cl(this.type,this.attrs,this.text,e)}withText(e){return e==this.text?this:new cl(this.type,this.attrs,e,this.marks)}cut(e=0,t=this.text.length){return e==0&&t==this.text.length?this:this.withText(this.text.slice(e,t))}eq(e){return this.sameMarkup(e)&&this.text==e.text}toJSON(){let e=super.toJSON();return e.text=this.text,e}}function xm(n,e){for(let t=n.length-1;t>=0;t--)e=n[t].type.name+"("+e+")";return e}class nr{constructor(e){this.validEnd=e,this.next=[],this.wrapCache=[]}static parse(e,t){let r=new OS(e,t);if(r.next==null)return nr.empty;let i=Cm(r);r.next&&r.err("Unexpected trailing text");let o=zS(IS(i));return PS(o,r),o}matchType(e){for(let t=0;tu.createAndFill()));for(let u=0;u=this.next.length)throw new RangeError(`There's no ${e}th edge in this content match`);return this.next[e]}toString(){let e=[];function t(r){e.push(r);for(let i=0;i{let o=i+(r.validEnd?"*":" ")+" ";for(let s=0;s"+e.indexOf(r.next[s].next);return o}).join(` +`)}}nr.empty=new nr(!0);class OS{constructor(e,t){this.string=e,this.nodeTypes=t,this.inline=null,this.pos=0,this.tokens=e.split(/\s*(?=\b|\W|$)/),this.tokens[this.tokens.length-1]==""&&this.tokens.pop(),this.tokens[0]==""&&this.tokens.shift()}get next(){return this.tokens[this.pos]}eat(e){return this.next==e&&(this.pos++||!0)}err(e){throw new SyntaxError(e+" (in content expression '"+this.string+"')")}}function Cm(n){let e=[];do e.push(DS(n));while(n.eat("|"));return e.length==1?e[0]:{type:"choice",exprs:e}}function DS(n){let e=[];do e.push(TS(n));while(n.next&&n.next!=")"&&n.next!="|");return e.length==1?e[0]:{type:"seq",exprs:e}}function TS(n){let e=bS(n);for(;;)if(n.eat("+"))e={type:"plus",expr:e};else if(n.eat("*"))e={type:"star",expr:e};else if(n.eat("?"))e={type:"opt",expr:e};else if(n.eat("{"))e=RS(n,e);else break;return e}function Cd(n){/\D/.test(n.next)&&n.err("Expected number, got '"+n.next+"'");let e=Number(n.next);return n.pos++,e}function RS(n,e){let t=Cd(n),r=t;return n.eat(",")&&(n.next!="}"?r=Cd(n):r=-1),n.eat("}")||n.err("Unclosed braced range"),{type:"range",min:t,max:r,expr:e}}function AS(n,e){let t=n.nodeTypes,r=t[e];if(r)return[r];let i=[];for(let o in t){let s=t[o];s.groups.indexOf(e)>-1&&i.push(s)}return i.length==0&&n.err("No node type or group '"+e+"' found"),i}function bS(n){if(n.eat("(")){let e=Cm(n);return n.eat(")")||n.err("Missing closing paren"),e}else if(/\W/.test(n.next))n.err("Unexpected token '"+n.next+"'");else{let e=AS(n,n.next).map(t=>(n.inline==null?n.inline=t.isInline:n.inline!=t.isInline&&n.err("Mixing inline and block content"),{type:"name",value:t}));return n.pos++,e.length==1?e[0]:{type:"choice",exprs:e}}}function IS(n){let e=[[]];return i(o(n,0),t()),e;function t(){return e.push([])-1}function r(s,l,a){let u={term:a,to:l};return e[s].push(u),u}function i(s,l){s.forEach(a=>a.to=l)}function o(s,l){if(s.type=="choice")return s.exprs.reduce((a,u)=>a.concat(o(u,l)),[]);if(s.type=="seq")for(let a=0;;a++){let u=o(s.exprs[a],l);if(a==s.exprs.length-1)return u;i(u,l=t())}else if(s.type=="star"){let a=t();return r(l,a),i(o(s.expr,a),a),[r(a)]}else if(s.type=="plus"){let a=t();return i(o(s.expr,l),a),i(o(s.expr,a),a),[r(a)]}else{if(s.type=="opt")return[r(l)].concat(o(s.expr,l));if(s.type=="range"){let a=l;for(let u=0;u{n[s].forEach(({term:l,to:a})=>{if(!l)return;let u;for(let c=0;c{u||i.push([l,u=[]]),u.indexOf(c)==-1&&u.push(c)})})});let o=e[r.join(",")]=new nr(r.indexOf(n.length-1)>-1);for(let s=0;s-1}allowsMarks(e){if(this.markSet==null)return!0;for(let t=0;tr[o]=new Tm(o,t,s));let i=t.spec.topNode||"doc";if(!r[i])throw new RangeError("Schema is missing its top node type ('"+i+"')");if(!r.text)throw new RangeError("Every schema needs a 'text' type");for(let o in r.text.attrs)throw new RangeError("The text node type should not have attributes");return r}};function FS(n,e,t){let r=t.split("|");return i=>{let o=i===null?"null":typeof i;if(r.indexOf(o)<0)throw new RangeError(`Expected value of type ${r} for attribute ${e} on type ${n}, got ${o}`)}}class LS{constructor(e,t,r){this.hasDefault=Object.prototype.hasOwnProperty.call(r,"default"),this.default=r.default,this.validate=typeof r.validate=="string"?FS(e,t,r.validate):r.validate}get isRequired(){return!this.hasDefault}}class Ho{constructor(e,t,r,i){this.name=e,this.rank=t,this.schema=r,this.spec=i,this.attrs=Dm(e,i.attrs),this.excluded=null;let o=Mm(this.attrs);this.instance=o?new U(this,o):null}create(e=null){return!e&&this.instance?this.instance:new U(this,Em(this.attrs,e))}static compile(e,t){let r=Object.create(null),i=0;return e.forEach((o,s)=>r[o]=new Ho(o,i++,t,s)),r}removeFromSet(e){for(var t=0;t-1}}class Rm{constructor(e){this.linebreakReplacement=null,this.cached=Object.create(null);let t=this.spec={};for(let i in e)t[i]=e[i];t.nodes=he.from(e.nodes),t.marks=he.from(e.marks||{}),this.nodes=Md.compile(this.spec.nodes,this),this.marks=Ho.compile(this.spec.marks,this);let r=Object.create(null);for(let i in this.nodes){if(i in this.marks)throw new RangeError(i+" can not be both a node and a mark");let o=this.nodes[i],s=o.spec.content||"",l=o.spec.marks;if(o.contentMatch=r[s]||(r[s]=nr.parse(s,this.nodes)),o.inlineContent=o.contentMatch.inlineContent,o.spec.linebreakReplacement){if(this.linebreakReplacement)throw new RangeError("Multiple linebreak nodes defined");if(!o.isInline||!o.isLeaf)throw new RangeError("Linebreak replacement nodes must be inline leaf nodes");this.linebreakReplacement=o}o.markSet=l=="_"?null:l?Ed(this,l.split(" ")):l==""||!o.inlineContent?[]:null}for(let i in this.marks){let o=this.marks[i],s=o.spec.excludes;o.excluded=s==null?[o]:s==""?[]:Ed(this,s.split(" "))}this.nodeFromJSON=this.nodeFromJSON.bind(this),this.markFromJSON=this.markFromJSON.bind(this),this.topNodeType=this.nodes[this.spec.topNode||"doc"],this.cached.wrappings=Object.create(null)}node(e,t=null,r,i){if(typeof e=="string")e=this.nodeType(e);else if(e instanceof Md){if(e.schema!=this)throw new RangeError("Node type from different schema used ("+e.name+")")}else throw new RangeError("Invalid node type: "+e);return e.createChecked(t,r,i)}text(e,t){let r=this.nodes.text;return new cl(r,r.defaultAttrs,e,U.setFrom(t))}mark(e,t){return typeof e=="string"&&(e=this.marks[e]),e.create(t)}nodeFromJSON(e){return Tt.fromJSON(this,e)}markFromJSON(e){return U.fromJSON(this,e)}nodeType(e){let t=this.nodes[e];if(!t)throw new RangeError("Unknown node type: "+e);return t}}function Ed(n,e){let t=[];for(let r=0;r-1)&&t.push(s=a)}if(!s)throw new SyntaxError("Unknown mark type: '"+e[r]+"'")}return t}function $S(n){return n.tag!=null}function BS(n){return n.style!=null}class mo{constructor(e,t){this.schema=e,this.rules=t,this.tags=[],this.styles=[];let r=this.matchedStyles=[];t.forEach(i=>{if($S(i))this.tags.push(i);else if(BS(i)){let o=/[^=]*/.exec(i.style)[0];r.indexOf(o)<0&&r.push(o),this.styles.push(i)}}),this.normalizeLists=!this.tags.some(i=>{if(!/^(ul|ol)\b/.test(i.tag)||!i.node)return!1;let o=e.nodes[i.node];return o.contentMatch.matchType(o)})}parse(e,t={}){let r=new Dd(this,t,!1);return r.addAll(e,U.none,t.from,t.to),r.finish()}parseSlice(e,t={}){let r=new Dd(this,t,!0);return r.addAll(e,U.none,t.from,t.to),k.maxOpen(r.finish())}matchTag(e,t,r){for(let i=r?this.tags.indexOf(r)+1:0;ie.length&&(l.charCodeAt(e.length)!=61||l.slice(e.length+1)!=t))){if(s.getAttrs){let a=s.getAttrs(t);if(a===!1)continue;s.attrs=a||void 0}return s}}}static schemaRules(e){let t=[];function r(i){let o=i.priority==null?50:i.priority,s=0;for(;s{r(s=Td(s)),s.mark||s.ignore||s.clearMark||(s.mark=i)})}for(let i in e.nodes){let o=e.nodes[i].spec.parseDOM;o&&o.forEach(s=>{r(s=Td(s)),s.node||s.ignore||s.mark||(s.node=i)})}return t}static fromSchema(e){return e.cached.domParser||(e.cached.domParser=new mo(e,mo.schemaRules(e)))}}const Am={address:!0,article:!0,aside:!0,blockquote:!0,canvas:!0,dd:!0,div:!0,dl:!0,fieldset:!0,figcaption:!0,figure:!0,footer:!0,form:!0,h1:!0,h2:!0,h3:!0,h4:!0,h5:!0,h6:!0,header:!0,hgroup:!0,hr:!0,li:!0,noscript:!0,ol:!0,output:!0,p:!0,pre:!0,section:!0,table:!0,tfoot:!0,ul:!0},VS={head:!0,noscript:!0,object:!0,script:!0,style:!0,title:!0},bm={ol:!0,ul:!0},fl=1,dl=2,Xi=4;function Od(n,e,t){return e!=null?(e?fl:0)|(e==="full"?dl:0):n&&n.whitespace=="pre"?fl|dl:t&~Xi}class as{constructor(e,t,r,i,o,s){this.type=e,this.attrs=t,this.marks=r,this.solid=i,this.options=s,this.content=[],this.activeMarks=U.none,this.match=o||(s&Xi?null:e.contentMatch)}findWrapping(e){if(!this.match){if(!this.type)return[];let t=this.type.contentMatch.fillBefore(v.from(e));if(t)this.match=this.type.contentMatch.matchFragment(t);else{let r=this.type.contentMatch,i;return(i=r.findWrapping(e.type))?(this.match=r,i):null}}return this.match.findWrapping(e.type)}finish(e){if(!(this.options&fl)){let r=this.content[this.content.length-1],i;if(r&&r.isText&&(i=/[ \t\r\n\u000c]+$/.exec(r.text))){let o=r;r.text.length==i[0].length?this.content.pop():this.content[this.content.length-1]=o.withText(o.text.slice(0,o.text.length-i[0].length))}}let t=v.from(this.content);return!e&&this.match&&(t=t.append(this.match.fillBefore(v.empty,!0))),this.type?this.type.create(this.attrs,t,this.marks):t}inlineContext(e){return this.type?this.type.inlineContent:this.content.length?this.content[0].isInline:e.parentNode&&!Am.hasOwnProperty(e.parentNode.nodeName.toLowerCase())}}class Dd{constructor(e,t,r){this.parser=e,this.options=t,this.isOpen=r,this.open=0;let i=t.topNode,o,s=Od(null,t.preserveWhitespace,0)|(r?Xi:0);i?o=new as(i.type,i.attrs,U.none,!0,t.topMatch||i.type.contentMatch,s):r?o=new as(null,null,U.none,!0,null,s):o=new as(e.schema.topNodeType,null,U.none,!0,null,s),this.nodes=[o],this.find=t.findPositions,this.needsBlock=!1}get top(){return this.nodes[this.open]}addDOM(e,t){e.nodeType==3?this.addTextNode(e,t):e.nodeType==1&&this.addElement(e,t)}addTextNode(e,t){let r=e.nodeValue,i=this.top;if(i.options&dl||i.inlineContext(e)||/[^ \t\r\n\u000c]/.test(r)){if(i.options&fl)i.options&dl?r=r.replace(/\r\n?/g,` +`):r=r.replace(/\r?\n|\r/g," ");else if(r=r.replace(/[ \t\r\n\u000c]+/g," "),/^[ \t\r\n\u000c]/.test(r)&&this.open==this.nodes.length-1){let o=i.content[i.content.length-1],s=e.previousSibling;(!o||s&&s.nodeName=="BR"||o.isText&&/[ \t\r\n\u000c]$/.test(o.text))&&(r=r.slice(1))}r&&this.insertNode(this.parser.schema.text(r),t),this.findInText(e)}else this.findInside(e)}addElement(e,t,r){let i=e.nodeName.toLowerCase(),o;bm.hasOwnProperty(i)&&this.parser.normalizeLists&&JS(e);let s=this.options.ruleFromNode&&this.options.ruleFromNode(e)||(o=this.parser.matchTag(e,this,r));if(s?s.ignore:VS.hasOwnProperty(i))this.findInside(e),this.ignoreFallback(e,t);else if(!s||s.skip||s.closeParent){s&&s.closeParent?this.open=Math.max(0,this.open-1):s&&s.skip.nodeType&&(e=s.skip);let l,a=this.top,u=this.needsBlock;if(Am.hasOwnProperty(i))a.content.length&&a.content[0].isInline&&this.open&&(this.open--,a=this.top),l=!0,a.type||(this.needsBlock=!0);else if(!e.firstChild){this.leafFallback(e,t);return}let c=s&&s.skip?t:this.readStyles(e,t);c&&this.addAll(e,c),l&&this.sync(a),this.needsBlock=u}else{let l=this.readStyles(e,t);l&&this.addElementByRule(e,s,l,s.consuming===!1?o:void 0)}}leafFallback(e,t){e.nodeName=="BR"&&this.top.type&&this.top.type.inlineContent&&this.addTextNode(e.ownerDocument.createTextNode(` +`),t)}ignoreFallback(e,t){e.nodeName=="BR"&&(!this.top.type||!this.top.type.inlineContent)&&this.findPlace(this.parser.schema.text("-"),t)}readStyles(e,t){let r=e.style;if(r&&r.length)for(let i=0;i!a.clearMark(u)):t=t.concat(this.parser.schema.marks[a.mark].create(a.attrs)),a.consuming===!1)l=a;else break}}return t}addElementByRule(e,t,r,i){let o,s;if(t.node)if(s=this.parser.schema.nodes[t.node],s.isLeaf)this.insertNode(s.create(t.attrs),r)||this.leafFallback(e,r);else{let a=this.enter(s,t.attrs||null,r,t.preserveWhitespace);a&&(o=!0,r=a)}else{let a=this.parser.schema.marks[t.mark];r=r.concat(a.create(t.attrs))}let l=this.top;if(s&&s.isLeaf)this.findInside(e);else if(i)this.addElement(e,r,i);else if(t.getContent)this.findInside(e),t.getContent(e,this.parser.schema).forEach(a=>this.insertNode(a,r));else{let a=e;typeof t.contentElement=="string"?a=e.querySelector(t.contentElement):typeof t.contentElement=="function"?a=t.contentElement(e):t.contentElement&&(a=t.contentElement),this.findAround(e,a,!0),this.addAll(a,r)}o&&this.sync(l)&&this.open--}addAll(e,t,r,i){let o=r||0;for(let s=r?e.childNodes[r]:e.firstChild,l=i==null?null:e.childNodes[i];s!=l;s=s.nextSibling,++o)this.findAtPoint(e,o),this.addDOM(s,t);this.findAtPoint(e,o)}findPlace(e,t){let r,i;for(let o=this.open;o>=0;o--){let s=this.nodes[o],l=s.findWrapping(e);if(l&&(!r||r.length>l.length)&&(r=l,i=s,!l.length)||s.solid)break}if(!r)return null;this.sync(i);for(let o=0;o(s.type?s.type.allowsMarkType(u.type):Rd(u.type,e))?(a=u.addToSet(a),!1):!0),this.nodes.push(new as(e,t,a,i,null,l)),this.open++,r}closeExtra(e=!1){let t=this.nodes.length-1;if(t>this.open){for(;t>this.open;t--)this.nodes[t-1].content.push(this.nodes[t].finish(e));this.nodes.length=this.open+1}}finish(){return this.open=0,this.closeExtra(this.isOpen),this.nodes[0].finish(this.isOpen||this.options.topOpen)}sync(e){for(let t=this.open;t>=0;t--)if(this.nodes[t]==e)return this.open=t,!0;return!1}get currentPos(){this.closeExtra();let e=0;for(let t=this.open;t>=0;t--){let r=this.nodes[t].content;for(let i=r.length-1;i>=0;i--)e+=r[i].nodeSize;t&&e++}return e}findAtPoint(e,t){if(this.find)for(let r=0;r-1)return e.split(/\s*\|\s*/).some(this.matchesContext,this);let t=e.split("/"),r=this.options.context,i=!this.isOpen&&(!r||r.parent.type==this.nodes[0].type),o=-(r?r.depth+1:0)+(i?0:1),s=(l,a)=>{for(;l>=0;l--){let u=t[l];if(u==""){if(l==t.length-1||l==0)continue;for(;a>=o;a--)if(s(l-1,a))return!0;return!1}else{let c=a>0||a==0&&i?this.nodes[a].type:r&&a>=o?r.node(a-o).type:null;if(!c||c.name!=u&&c.groups.indexOf(u)==-1)return!1;a--}}return!0};return s(t.length-1,this.open)}textblockFromContext(){let e=this.options.context;if(e)for(let t=e.depth;t>=0;t--){let r=e.node(t).contentMatchAt(e.indexAfter(t)).defaultType;if(r&&r.isTextblock&&r.defaultAttrs)return r}for(let t in this.parser.schema.nodes){let r=this.parser.schema.nodes[t];if(r.isTextblock&&r.defaultAttrs)return r}}}function JS(n){for(let e=n.firstChild,t=null;e;e=e.nextSibling){let r=e.nodeType==1?e.nodeName.toLowerCase():null;r&&bm.hasOwnProperty(r)&&t?(t.appendChild(e),e=t):r=="li"?t=e:r&&(t=null)}}function _S(n,e){return(n.matches||n.msMatchesSelector||n.webkitMatchesSelector||n.mozMatchesSelector).call(n,e)}function Td(n){let e={};for(let t in n)e[t]=n[t];return e}function Rd(n,e){let t=e.schema.nodes;for(let r in t){let i=t[r];if(!i.allowsMarkType(n))continue;let o=[],s=l=>{o.push(l);for(let a=0;a{if(o.length||s.marks.length){let l=0,a=0;for(;l=0;i--){let o=this.serializeMark(e.marks[i],e.isInline,t);o&&((o.contentDOM||o.dom).appendChild(r),r=o.dom)}return r}serializeMark(e,t,r={}){let i=this.marks[e.type.name];return i&&zs(ka(r),i(e,t),null,e.attrs)}static renderSpec(e,t,r=null,i){return zs(e,t,r,i)}static fromSchema(e){return e.cached.domSerializer||(e.cached.domSerializer=new fi(this.nodesFromSchema(e),this.marksFromSchema(e)))}static nodesFromSchema(e){let t=Ad(e.nodes);return t.text||(t.text=r=>r.text),t}static marksFromSchema(e){return Ad(e.marks)}}function Ad(n){let e={};for(let t in n){let r=n[t].spec.toDOM;r&&(e[t]=r)}return e}function ka(n){return n.document||window.document}const bd=new WeakMap;function WS(n){let e=bd.get(n);return e===void 0&&bd.set(n,e=US(n)),e}function US(n){let e=null;function t(r){if(r&&typeof r=="object")if(Array.isArray(r))if(typeof r[0]=="string")e||(e=[]),e.push(r);else for(let i=0;i-1)throw new RangeError("Using an array from an attribute object as a DOM spec. This may be an attempted cross site scripting attack.");let s=i.indexOf(" ");s>0&&(t=i.slice(0,s),i=i.slice(s+1));let l,a=t?n.createElementNS(t,i):n.createElement(i),u=e[1],c=1;if(u&&typeof u=="object"&&u.nodeType==null&&!Array.isArray(u)){c=2;for(let f in u)if(u[f]!=null){let d=f.indexOf(" ");d>0?a.setAttributeNS(f.slice(0,d),f.slice(d+1),u[f]):a.setAttribute(f,u[f])}}for(let f=c;fc)throw new RangeError("Content hole must be the only child of its parent node");return{dom:a,contentDOM:a}}else{let{dom:p,contentDOM:h}=zs(n,d,t,r);if(a.appendChild(p),h){if(l)throw new RangeError("Multiple content holes");l=h}}}return{dom:a,contentDOM:l}}const Im=65535,zm=Math.pow(2,16);function HS(n,e){return n+e*zm}function Id(n){return n&Im}function jS(n){return(n-(n&Im))/zm}const Pm=1,Fm=2,Ps=4,Lm=8;let zd=class{constructor(e,t,r){this.pos=e,this.delInfo=t,this.recover=r}get deleted(){return(this.delInfo&Lm)>0}get deletedBefore(){return(this.delInfo&(Pm|Ps))>0}get deletedAfter(){return(this.delInfo&(Fm|Ps))>0}get deletedAcross(){return(this.delInfo&Ps)>0}},Hr=class yr{constructor(e,t=!1){if(this.ranges=e,this.inverted=t,!e.length&&yr.empty)return yr.empty}recover(e){let t=0,r=Id(e);if(!this.inverted)for(let i=0;ie)break;let u=this.ranges[l+o],c=this.ranges[l+s],f=a+u;if(e<=f){let d=u?e==a?-1:e==f?1:t:t,p=a+i+(d<0?0:c);if(r)return p;let h=e==(t<0?a:f)?null:HS(l/3,e-a),m=e==a?Fm:e==f?Pm:Ps;return(t<0?e!=a:e!=f)&&(m|=Lm),new zd(p,m,h)}i+=c-u}return r?e+i:new zd(e+i,0,null)}touches(e,t){let r=0,i=Id(t),o=this.inverted?2:1,s=this.inverted?1:2;for(let l=0;le)break;let u=this.ranges[l+o],c=a+u;if(e<=c&&l==i*3)return!0;r+=this.ranges[l+s]-u}return!1}forEach(e){let t=this.inverted?2:1,r=this.inverted?1:2;for(let i=0,o=0;i!s.isAtom||!l.type.allowsMarkType(this.mark.type)?s:s.mark(this.mark.addToSet(s.marks)),i),t.openStart,t.openEnd);return $e.fromReplace(e,this.from,this.to,o)}invert(){return new Bm(this.from,this.to,this.mark)}map(e){let t=e.mapResult(this.from,1),r=e.mapResult(this.to,-1);return t.deleted&&r.deleted||t.pos>=r.pos?null:new Mi(t.pos,r.pos,this.mark)}merge(e){return e instanceof Mi&&e.mark.eq(this.mark)&&this.from<=e.to&&this.to>=e.from?new Mi(Math.min(this.from,e.from),Math.max(this.to,e.to),this.mark):null}toJSON(){return{stepType:"addMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(e,t){if(typeof t.from!="number"||typeof t.to!="number")throw new RangeError("Invalid input for AddMarkStep.fromJSON");return new Mi(t.from,t.to,e.markFromJSON(t.mark))}};Ke.jsonID("addMark",$m);let Bm=class Ei extends Ke{constructor(e,t,r){super(),this.from=e,this.to=t,this.mark=r}apply(e){let t=e.slice(this.from,this.to),r=new k(Yc(t.content,i=>i.mark(this.mark.removeFromSet(i.marks)),e),t.openStart,t.openEnd);return $e.fromReplace(e,this.from,this.to,r)}invert(){return new $m(this.from,this.to,this.mark)}map(e){let t=e.mapResult(this.from,1),r=e.mapResult(this.to,-1);return t.deleted&&r.deleted||t.pos>=r.pos?null:new Ei(t.pos,r.pos,this.mark)}merge(e){return e instanceof Ei&&e.mark.eq(this.mark)&&this.from<=e.to&&this.to>=e.from?new Ei(Math.min(this.from,e.from),Math.max(this.to,e.to),this.mark):null}toJSON(){return{stepType:"removeMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(e,t){if(typeof t.from!="number"||typeof t.to!="number")throw new RangeError("Invalid input for RemoveMarkStep.fromJSON");return new Ei(t.from,t.to,e.markFromJSON(t.mark))}};Ke.jsonID("removeMark",Bm);let Vm=class Oi extends Ke{constructor(e,t){super(),this.pos=e,this.mark=t}apply(e){let t=e.nodeAt(this.pos);if(!t)return $e.fail("No node at mark step's position");let r=t.type.create(t.attrs,null,this.mark.addToSet(t.marks));return $e.fromReplace(e,this.pos,this.pos+1,new k(v.from(r),0,t.isLeaf?0:1))}invert(e){let t=e.nodeAt(this.pos);if(t){let r=this.mark.addToSet(t.marks);if(r.length==t.marks.length){for(let i=0;ir.pos?null:new Fs(t.pos,r.pos,i,o,this.slice,this.insert,this.structure)}toJSON(){let e={stepType:"replaceAround",from:this.from,to:this.to,gapFrom:this.gapFrom,gapTo:this.gapTo,insert:this.insert};return this.slice.size&&(e.slice=this.slice.toJSON()),this.structure&&(e.structure=!0),e}static fromJSON(e,t){if(typeof t.from!="number"||typeof t.to!="number"||typeof t.gapFrom!="number"||typeof t.gapTo!="number"||typeof t.insert!="number")throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON");return new Fs(t.from,t.to,t.gapFrom,t.gapTo,k.fromJSON(e,t.slice),t.insert,!!t.structure)}};Ke.jsonID("replaceAround",hl);function xu(n,e,t){let r=n.resolve(e),i=t-e,o=r.depth;for(;i>0&&o>0&&r.indexAfter(o)==r.node(o).childCount;)o--,i--;if(i>0){let s=r.node(o).maybeChild(r.indexAfter(o));for(;i>0;){if(!s||s.isLeaf)return!0;s=s.firstChild,i--}}return!1}function KS(n,e,t){return(e==0||n.canReplace(e,n.childCount))&&(t==n.childCount||n.canReplace(0,t))}function Xc(n){let t=n.parent.content.cutByIndex(n.startIndex,n.endIndex);for(let r=n.depth;;--r){let i=n.$from.node(r),o=n.$from.index(r),s=n.$to.indexAfter(r);if(ro;u--,c--){let f=i.node(u),d=i.index(u);if(f.type.spec.isolating)return!1;let p=f.content.cutByIndex(d,f.childCount),h=r&&r[c]||f;if(h!=f&&(p=p.replaceChild(0,h.type.create(h.attrs))),!f.canReplace(d+1,f.childCount)||!h.type.validContent(p))return!1}let l=i.indexAfter(o),a=r&&r[0];return i.node(o).canReplaceWith(l,l,a?a.type:i.node(o+1).type)}function _m(n,e){let t=n.resolve(e),r=t.index();return qS(t.nodeBefore,t.nodeAfter)&&t.parent.canReplace(r,r+1)}function qS(n,e){return!!(n&&e&&!n.isLeaf&&n.canAppend(e))}function Wm(n,e,t=e,r=k.empty){if(e==t&&!r.size)return null;let i=n.resolve(e),o=n.resolve(t);return QS(i,o,r)?new Gc(e,t,r):new YS(i,o,r).fit()}function QS(n,e,t){return!t.openStart&&!t.openEnd&&n.start()==e.start()&&n.parent.canReplace(n.index(),e.index(),t.content)}let YS=class{constructor(e,t,r){this.$from=e,this.$to=t,this.unplaced=r,this.frontier=[],this.placed=v.empty;for(let i=0;i<=e.depth;i++){let o=e.node(i);this.frontier.push({type:o.type,match:o.contentMatchAt(e.indexAfter(i))})}for(let i=e.depth;i>0;i--)this.placed=v.from(e.node(i).copy(this.placed))}get depth(){return this.frontier.length-1}fit(){for(;this.unplaced.size;){let u=this.findFittable();u?this.placeNodes(u):this.openMore()||this.dropNode()}let e=this.mustMoveInline(),t=this.placed.size-this.depth-this.$from.depth,r=this.$from,i=this.close(e<0?this.$to:r.doc.resolve(e));if(!i)return null;let o=this.placed,s=r.depth,l=i.depth;for(;s&&l&&o.childCount==1;)o=o.firstChild.content,s--,l--;let a=new k(o,s,l);return e>-1?new hl(r.pos,e,this.$to.pos,this.$to.end(),a,t):a.size||r.pos!=this.$to.pos?new Gc(r.pos,i.pos,a):null}findFittable(){let e=this.unplaced.openStart;for(let t=this.unplaced.content,r=0,i=this.unplaced.openEnd;r1&&(i=0),o.type.spec.isolating&&i<=r){e=r;break}t=o.content}for(let t=1;t<=2;t++)for(let r=t==1?e:this.unplaced.openStart;r>=0;r--){let i,o=null;r?(o=xa(this.unplaced.content,r-1).firstChild,i=o.content):i=this.unplaced.content;let s=i.firstChild;for(let l=this.depth;l>=0;l--){let{type:a,match:u}=this.frontier[l],c,f=null;if(t==1&&(s?u.matchType(s.type)||(f=u.fillBefore(v.from(s),!1)):o&&a.compatibleContent(o.type)))return{sliceDepth:r,frontierDepth:l,parent:o,inject:f};if(t==2&&s&&(c=u.findWrapping(s.type)))return{sliceDepth:r,frontierDepth:l,parent:o,wrap:c};if(o&&u.matchType(o.type))break}}}openMore(){let{content:e,openStart:t,openEnd:r}=this.unplaced,i=xa(e,t);return!i.childCount||i.firstChild.isLeaf?!1:(this.unplaced=new k(e,t+1,Math.max(r,i.size+t>=e.size-r?t+1:0)),!0)}dropNode(){let{content:e,openStart:t,openEnd:r}=this.unplaced,i=xa(e,t);if(i.childCount<=1&&t>0){let o=e.size-t<=t+i.size;this.unplaced=new k(Di(e,t-1,1),t-1,o?t-1:r)}else this.unplaced=new k(Di(e,t,1),t,r)}placeNodes({sliceDepth:e,frontierDepth:t,parent:r,inject:i,wrap:o}){for(;this.depth>t;)this.closeFrontierNode();if(o)for(let m=0;m1||a==0||m.content.size)&&(f=w,c.push(Um(m.mark(d.allowedMarks(m.marks)),u==1?a:0,u==l.childCount?p:-1)))}let h=u==l.childCount;h||(p=-1),this.placed=Ti(this.placed,t,v.from(c)),this.frontier[t].match=f,h&&p<0&&r&&r.type==this.frontier[this.depth].type&&this.frontier.length>1&&this.closeFrontierNode();for(let m=0,w=l;m1&&i==this.$to.end(--r);)++i;return i}findCloseLevel(e){e:for(let t=Math.min(this.depth,e.depth);t>=0;t--){let{match:r,type:i}=this.frontier[t],o=t=0;l--){let{match:a,type:u}=this.frontier[l],c=Ca(e,l,u,a,!0);if(!c||c.childCount)continue e}return{depth:t,fit:s,move:o?e.doc.resolve(e.after(t+1)):e}}}}close(e){let t=this.findCloseLevel(e);if(!t)return null;for(;this.depth>t.depth;)this.closeFrontierNode();t.fit.childCount&&(this.placed=Ti(this.placed,t.depth,t.fit)),e=t.move;for(let r=t.depth+1;r<=e.depth;r++){let i=e.node(r),o=i.type.contentMatch.fillBefore(i.content,!0,e.index(r));this.openFrontierNode(i.type,i.attrs,o)}return e}openFrontierNode(e,t=null,r){let i=this.frontier[this.depth];i.match=i.match.matchType(e),this.placed=Ti(this.placed,this.depth,v.from(e.create(t,r))),this.frontier.push({type:e,match:e.contentMatch})}closeFrontierNode(){let t=this.frontier.pop().match.fillBefore(v.empty,!0);t.childCount&&(this.placed=Ti(this.placed,this.frontier.length,t))}};function Di(n,e,t){return e==0?n.cutByIndex(t,n.childCount):n.replaceChild(0,n.firstChild.copy(Di(n.firstChild.content,e-1,t)))}function Ti(n,e,t){return e==0?n.append(t):n.replaceChild(n.childCount-1,n.lastChild.copy(Ti(n.lastChild.content,e-1,t)))}function xa(n,e){for(let t=0;t1&&(r=r.replaceChild(0,Um(r.firstChild,e-1,r.childCount==1?t-1:0))),e>0&&(r=n.type.contentMatch.fillBefore(r).append(r),t<=0&&(r=r.append(n.type.contentMatch.matchFragment(r).fillBefore(v.empty,!0)))),n.copy(r)}function Ca(n,e,t,r,i){let o=n.node(e),s=i?n.indexAfter(e):n.index(e);if(s==o.childCount&&!t.compatibleContent(o.type))return null;let l=r.fillBefore(o.content,!0,s);return l&&!GS(t,o.content,s)?l:null}function GS(n,e,t){for(let r=t;r0}get deletedBefore(){return(this.delInfo&(Km|Bs))>0}get deletedAfter(){return(this.delInfo&(qm|Bs))>0}get deletedAcross(){return(this.delInfo&Bs)>0}},jr=class Sr{constructor(e,t=!1){if(this.ranges=e,this.inverted=t,!e.length&&Sr.empty)return Sr.empty}recover(e){let t=0,r=Pd(e);if(!this.inverted)for(let i=0;ie)break;let u=this.ranges[l+o],c=this.ranges[l+s],f=a+u;if(e<=f){let d=u?e==a?-1:e==f?1:t:t,p=a+i+(d<0?0:c);if(r)return p;let h=e==(t<0?a:f)?null:ZS(l/3,e-a),m=e==a?qm:e==f?Km:Bs;return(t<0?e!=a:e!=f)&&(m|=Qm),new Cu(p,m,h)}i+=c-u}return r?e+i:new Cu(e+i,0,null)}touches(e,t){let r=0,i=Pd(t),o=this.inverted?2:1,s=this.inverted?1:2;for(let l=0;le)break;let u=this.ranges[l+o],c=a+u;if(e<=c&&l==i*3)return!0;r+=this.ranges[l+s]-u}return!1}forEach(e){let t=this.inverted?2:1,r=this.inverted?1:2;for(let i=0,o=0;i=0;t--){let i=e.getMirror(t);this.appendMap(e.maps[t].invert(),i!=null&&i>t?r-i-1:void 0)}}invert(){let e=new Vs;return e.appendMappingInverted(this),e}map(e,t=1){if(this.mirror)return this._map(e,t,!0);for(let r=this.from;ro&&a!s.isAtom||!l.type.allowsMarkType(this.mark.type)?s:s.mark(this.mark.addToSet(s.marks)),i),t.openStart,t.openEnd);return Be.fromReplace(e,this.from,this.to,o)}invert(){return new jo(this.from,this.to,this.mark)}map(e){let t=e.mapResult(this.from,1),r=e.mapResult(this.to,-1);return t.deleted&&r.deleted||t.pos>=r.pos?null:new Ai(t.pos,r.pos,this.mark)}merge(e){return e instanceof Ai&&e.mark.eq(this.mark)&&this.from<=e.to&&this.to>=e.from?new Ai(Math.min(this.from,e.from),Math.max(this.to,e.to),this.mark):null}toJSON(){return{stepType:"addMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(e,t){if(typeof t.from!="number"||typeof t.to!="number")throw new RangeError("Invalid input for AddMarkStep.fromJSON");return new Ai(t.from,t.to,e.markFromJSON(t.mark))}};qe.jsonID("addMark",ef);let jo=class bi extends qe{constructor(e,t,r){super(),this.from=e,this.to=t,this.mark=r}apply(e){let t=e.slice(this.from,this.to),r=new k(Zc(t.content,i=>i.mark(this.mark.removeFromSet(i.marks)),e),t.openStart,t.openEnd);return Be.fromReplace(e,this.from,this.to,r)}invert(){return new ef(this.from,this.to,this.mark)}map(e){let t=e.mapResult(this.from,1),r=e.mapResult(this.to,-1);return t.deleted&&r.deleted||t.pos>=r.pos?null:new bi(t.pos,r.pos,this.mark)}merge(e){return e instanceof bi&&e.mark.eq(this.mark)&&this.from<=e.to&&this.to>=e.from?new bi(Math.min(this.from,e.from),Math.max(this.to,e.to),this.mark):null}toJSON(){return{stepType:"removeMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(e,t){if(typeof t.from!="number"||typeof t.to!="number")throw new RangeError("Invalid input for RemoveMarkStep.fromJSON");return new bi(t.from,t.to,e.markFromJSON(t.mark))}};qe.jsonID("removeMark",jo);let tf=class Ii extends qe{constructor(e,t){super(),this.pos=e,this.mark=t}apply(e){let t=e.nodeAt(this.pos);if(!t)return Be.fail("No node at mark step's position");let r=t.type.create(t.attrs,null,this.mark.addToSet(t.marks));return Be.fromReplace(e,this.pos,this.pos+1,new k(v.from(r),0,t.isLeaf?0:1))}invert(e){let t=e.nodeAt(this.pos);if(t){let r=this.mark.addToSet(t.marks);if(r.length==t.marks.length){for(let i=0;ir.pos?null:new Js(t.pos,r.pos,i,o,this.slice,this.insert,this.structure)}toJSON(){let e={stepType:"replaceAround",from:this.from,to:this.to,gapFrom:this.gapFrom,gapTo:this.gapTo,insert:this.insert};return this.slice.size&&(e.slice=this.slice.toJSON()),this.structure&&(e.structure=!0),e}static fromJSON(e,t){if(typeof t.from!="number"||typeof t.to!="number"||typeof t.gapFrom!="number"||typeof t.gapTo!="number"||typeof t.insert!="number")throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON");return new Js(t.from,t.to,t.gapFrom,t.gapTo,k.fromJSON(e,t.slice),t.insert,!!t.structure)}};qe.jsonID("replaceAround",ur);function Mu(n,e,t){let r=n.resolve(e),i=t-e,o=r.depth;for(;i>0&&o>0&&r.indexAfter(o)==r.node(o).childCount;)o--,i--;if(i>0){let s=r.node(o).maybeChild(r.indexAfter(o));for(;i>0;){if(!s||s.isLeaf)return!0;s=s.firstChild,i--}}return!1}function nw(n,e,t,r){let i=[],o=[],s,l;n.doc.nodesBetween(e,t,(a,u,c)=>{if(!a.isInline)return;let f=a.marks;if(!r.isInSet(f)&&c.type.allowsMarkType(r.type)){let d=Math.max(u,e),p=Math.min(u+a.nodeSize,t),h=r.addToSet(f);for(let m=0;mn.step(a)),o.forEach(a=>n.step(a))}function rw(n,e,t,r){let i=[],o=0;n.doc.nodesBetween(e,t,(s,l)=>{if(!s.isInline)return;o++;let a=null;if(r instanceof Ho){let u=s.marks,c;for(;c=r.isInSet(u);)(a||(a=[])).push(c),u=c.removeFromSet(u)}else r?r.isInSet(s.marks)&&(a=[r]):a=s.marks;if(a&&a.length){let u=Math.min(l+s.nodeSize,t);for(let c=0;cn.step(new jo(s.from,s.to,s.style)))}function iw(n,e,t,r=t.contentMatch){let i=n.doc.nodeAt(e),o=[],s=e+1;for(let l=0;l=0;l--)n.step(o[l])}function ow(n,e,t){let{$from:r,$to:i,depth:o}=e,s=r.before(o+1),l=i.after(o+1),a=s,u=l,c=v.empty,f=0;for(let h=o,m=!1;h>t;h--)m||r.index(h)>0?(m=!0,c=v.from(r.node(h).copy(c)),f++):a--;let d=v.empty,p=0;for(let h=o,m=!1;h>t;h--)m||i.after(h+1)=0;s--){if(r.size){let l=t[s].type.contentMatch.matchFragment(r);if(!l||!l.validEnd)throw new RangeError("Wrapper type given to Transform.wrap does not form valid content of its parent wrapper")}r=v.from(t[s].type.create(t[s].attrs,r))}let i=e.start,o=e.end;n.step(new ur(i,o,i,o,new k(r,0,0),t.length,!0))}function lw(n,e,t,r,i){if(!r.isTextblock)throw new RangeError("Type given to setBlockType should be a textblock");let o=n.steps.length;n.doc.nodesBetween(e,t,(s,l)=>{if(s.isTextblock&&!s.hasMarkup(r,i)&&aw(n.doc,n.mapping.slice(o).map(l),r)){n.clearIncompatible(n.mapping.slice(o).map(l,1),r);let a=n.mapping.slice(o),u=a.map(l,1),c=a.map(l+s.nodeSize,1);return n.step(new ur(u,c,u+1,c-1,new k(v.from(r.create(i,null,s.marks)),0,0),1,!0)),!1}})}function aw(n,e,t){let r=n.resolve(e),i=r.index();return r.parent.canReplaceWith(i,i+1,t)}function uw(n,e,t,r,i){let o=n.doc.nodeAt(e);if(!o)throw new RangeError("No node at given position");t||(t=o.type);let s=t.create(r,null,i||o.marks);if(o.isLeaf)return n.replaceWith(e,e+o.nodeSize,s);if(!t.validContent(o.content))throw new RangeError("Invalid content for node type "+t.name);n.step(new ur(e,e+o.nodeSize,e+1,e+o.nodeSize-1,new k(v.from(s),0,0),1,!0))}function cw(n,e,t=1,r){let i=n.doc.resolve(e),o=v.empty,s=v.empty;for(let l=i.depth,a=i.depth-t,u=t-1;l>a;l--,u--){o=v.from(i.node(l).copy(o));let c=r&&r[u];s=v.from(c?c.type.create(c.attrs,s):i.node(l).copy(s))}n.step(new Tn(e,e,new k(o.append(s),t,t),!0))}function fw(n,e,t){let r=new Tn(e-t,e+t,k.empty,!0);n.step(r)}function dw(n,e,t){let r=n.resolve(e);if(r.parent.canReplaceWith(r.index(),r.index(),t))return e;if(r.parentOffset==0)for(let i=r.depth-1;i>=0;i--){let o=r.index(i);if(r.node(i).canReplaceWith(o,o,t))return r.before(i+1);if(o>0)return null}if(r.parentOffset==r.parent.content.size)for(let i=r.depth-1;i>=0;i--){let o=r.indexAfter(i);if(r.node(i).canReplaceWith(o,o,t))return r.after(i+1);if(o0;i--)this.placed=v.from(e.node(i).copy(this.placed))}get depth(){return this.frontier.length-1}fit(){for(;this.unplaced.size;){let u=this.findFittable();u?this.placeNodes(u):this.openMore()||this.dropNode()}let e=this.mustMoveInline(),t=this.placed.size-this.depth-this.$from.depth,r=this.$from,i=this.close(e<0?this.$to:r.doc.resolve(e));if(!i)return null;let o=this.placed,s=r.depth,l=i.depth;for(;s&&l&&o.childCount==1;)o=o.firstChild.content,s--,l--;let a=new k(o,s,l);return e>-1?new ur(r.pos,e,this.$to.pos,this.$to.end(),a,t):a.size||r.pos!=this.$to.pos?new Tn(r.pos,i.pos,a):null}findFittable(){let e=this.unplaced.openStart;for(let t=this.unplaced.content,r=0,i=this.unplaced.openEnd;r1&&(i=0),o.type.spec.isolating&&i<=r){e=r;break}t=o.content}for(let t=1;t<=2;t++)for(let r=t==1?e:this.unplaced.openStart;r>=0;r--){let i,o=null;r?(o=Ma(this.unplaced.content,r-1).firstChild,i=o.content):i=this.unplaced.content;let s=i.firstChild;for(let l=this.depth;l>=0;l--){let{type:a,match:u}=this.frontier[l],c,f=null;if(t==1&&(s?u.matchType(s.type)||(f=u.fillBefore(v.from(s),!1)):o&&a.compatibleContent(o.type)))return{sliceDepth:r,frontierDepth:l,parent:o,inject:f};if(t==2&&s&&(c=u.findWrapping(s.type)))return{sliceDepth:r,frontierDepth:l,parent:o,wrap:c};if(o&&u.matchType(o.type))break}}}openMore(){let{content:e,openStart:t,openEnd:r}=this.unplaced,i=Ma(e,t);return!i.childCount||i.firstChild.isLeaf?!1:(this.unplaced=new k(e,t+1,Math.max(r,i.size+t>=e.size-r?t+1:0)),!0)}dropNode(){let{content:e,openStart:t,openEnd:r}=this.unplaced,i=Ma(e,t);if(i.childCount<=1&&t>0){let o=e.size-t<=t+i.size;this.unplaced=new k(zi(e,t-1,1),t-1,o?t-1:r)}else this.unplaced=new k(zi(e,t,1),t,r)}placeNodes({sliceDepth:e,frontierDepth:t,parent:r,inject:i,wrap:o}){for(;this.depth>t;)this.closeFrontierNode();if(o)for(let m=0;m1||a==0||m.content.size)&&(f=w,c.push(Gm(m.mark(d.allowedMarks(m.marks)),u==1?a:0,u==l.childCount?p:-1)))}let h=u==l.childCount;h||(p=-1),this.placed=Pi(this.placed,t,v.from(c)),this.frontier[t].match=f,h&&p<0&&r&&r.type==this.frontier[this.depth].type&&this.frontier.length>1&&this.closeFrontierNode();for(let m=0,w=l;m1&&i==this.$to.end(--r);)++i;return i}findCloseLevel(e){e:for(let t=Math.min(this.depth,e.depth);t>=0;t--){let{match:r,type:i}=this.frontier[t],o=t=0;l--){let{match:a,type:u}=this.frontier[l],c=Ea(e,l,u,a,!0);if(!c||c.childCount)continue e}return{depth:t,fit:s,move:o?e.doc.resolve(e.after(t+1)):e}}}}close(e){let t=this.findCloseLevel(e);if(!t)return null;for(;this.depth>t.depth;)this.closeFrontierNode();t.fit.childCount&&(this.placed=Pi(this.placed,t.depth,t.fit)),e=t.move;for(let r=t.depth+1;r<=e.depth;r++){let i=e.node(r),o=i.type.contentMatch.fillBefore(i.content,!0,e.index(r));this.openFrontierNode(i.type,i.attrs,o)}return e}openFrontierNode(e,t=null,r){let i=this.frontier[this.depth];i.match=i.match.matchType(e),this.placed=Pi(this.placed,this.depth,v.from(e.create(t,r))),this.frontier.push({type:e,match:e.contentMatch})}closeFrontierNode(){let t=this.frontier.pop().match.fillBefore(v.empty,!0);t.childCount&&(this.placed=Pi(this.placed,this.frontier.length,t))}};function zi(n,e,t){return e==0?n.cutByIndex(t,n.childCount):n.replaceChild(0,n.firstChild.copy(zi(n.firstChild.content,e-1,t)))}function Pi(n,e,t){return e==0?n.append(t):n.replaceChild(n.childCount-1,n.lastChild.copy(Pi(n.lastChild.content,e-1,t)))}function Ma(n,e){for(let t=0;t1&&(r=r.replaceChild(0,Gm(r.firstChild,e-1,r.childCount==1?t-1:0))),e>0&&(r=n.type.contentMatch.fillBefore(r).append(r),t<=0&&(r=r.append(n.type.contentMatch.matchFragment(r).fillBefore(v.empty,!0)))),n.copy(r)}function Ea(n,e,t,r,i){let o=n.node(e),s=i?n.indexAfter(e):n.index(e);if(s==o.childCount&&!t.compatibleContent(o.type))return null;let l=r.fillBefore(o.content,!0,s);return l&&!mw(t,o.content,s)?l:null}function mw(n,e,t){for(let r=t;r0;d--,p--){let h=i.node(d).type.spec;if(h.defining||h.definingAsContext||h.isolating)break;s.indexOf(d)>-1?l=d:i.before(d)==p&&s.splice(1,0,-d)}let a=s.indexOf(l),u=[],c=r.openStart;for(let d=r.content,p=0;;p++){let h=d.firstChild;if(u.push(h),p==r.openStart)break;d=h.content}for(let d=c-1;d>=0;d--){let p=u[d].type,h=gw(p);if(h&&i.node(a).type!=p)c=d;else if(h||!p.isTextblock)break}for(let d=r.openStart;d>=0;d--){let p=(d+c+1)%(r.openStart+1),h=u[p];if(h)for(let m=0;m=0&&(n.replace(e,t,r),!(n.steps.length>f));d--){let p=s[d];p<0||(e=i.before(p),t=o.after(p))}}function Xm(n,e,t,r,i){if(er){let o=i.contentMatchAt(0),s=o.fillBefore(n).append(n);n=s.append(o.matchFragment(s).fillBefore(v.empty,!0))}return n}function Sw(n,e,t,r){if(!r.isInline&&e==t&&n.doc.resolve(e).parent.content.size){let i=dw(n.doc,e,r.type);i!=null&&(e=t=i)}n.replaceRange(e,t,new k(v.from(r),0,0))}function ww(n,e,t){let r=n.doc.resolve(e),i=n.doc.resolve(t),o=Zm(r,i);for(let s=0;s0&&(a||r.node(l-1).canReplace(r.index(l-1),i.indexAfter(l-1))))return n.delete(r.before(l),i.after(l))}for(let s=1;s<=r.depth&&s<=i.depth;s++)if(e-r.start(s)==r.depth-s&&t>r.end(s)&&i.end(s)-t!=i.depth-s)return n.delete(r.before(s),t);n.delete(e,t)}function Zm(n,e){let t=[],r=Math.min(n.depth,e.depth);for(let i=r;i>=0;i--){let o=n.start(i);if(oe.pos+(e.depth-i)||n.node(i).type.spec.isolating||e.node(i).type.spec.isolating)break;(o==e.start(i)||i==n.depth&&i==e.depth&&n.parent.inlineContent&&e.parent.inlineContent&&i&&e.start(i-1)==o-1)&&t.push(i)}return t}let eg=class _s extends qe{constructor(e,t,r){super(),this.pos=e,this.attr=t,this.value=r}apply(e){let t=e.nodeAt(this.pos);if(!t)return Be.fail("No node at attribute step's position");let r=Object.create(null);for(let o in t.attrs)r[o]=t.attrs[o];r[this.attr]=this.value;let i=t.type.create(r,null,t.marks);return Be.fromReplace(e,this.pos,this.pos+1,new k(v.from(i),0,t.isLeaf?0:1))}getMap(){return jr.empty}invert(e){return new _s(this.pos,this.attr,e.nodeAt(this.pos).attrs[this.attr])}map(e){let t=e.mapResult(this.pos,1);return t.deletedAfter?null:new _s(t.pos,this.attr,this.value)}toJSON(){return{stepType:"attr",pos:this.pos,attr:this.attr,value:this.value}}static fromJSON(e,t){if(typeof t.pos!="number"||typeof t.attr!="string")throw new RangeError("Invalid input for AttrStep.fromJSON");return new _s(t.pos,t.attr,t.value)}};qe.jsonID("attr",eg);let Kr=class extends Error{};Kr=function n(e){let t=Error.call(this,e);return t.__proto__=n.prototype,t};Kr.prototype=Object.create(Error.prototype);Kr.prototype.constructor=Kr;Kr.prototype.name="TransformError";let kw=class{constructor(e){this.doc=e,this.steps=[],this.docs=[],this.mapping=new tw}get before(){return this.docs.length?this.docs[0]:this.doc}step(e){let t=this.maybeStep(e);if(t.failed)throw new Kr(t.failed);return this}maybeStep(e){let t=e.apply(this.doc);return t.failed||this.addStep(e,t.doc),t}get docChanged(){return this.steps.length>0}addStep(e,t){this.docs.push(this.doc),this.steps.push(e),this.mapping.appendMap(e.getMap()),this.doc=t}replace(e,t=e,r=k.empty){let i=hw(this.doc,e,t,r);return i&&this.step(i),this}replaceWith(e,t,r){return this.replace(e,t,new k(v.from(r),0,0))}delete(e,t){return this.replace(e,t,k.empty)}insert(e,t){return this.replaceWith(e,e,t)}replaceRange(e,t,r){return yw(this,e,t,r),this}replaceRangeWith(e,t,r){return Sw(this,e,t,r),this}deleteRange(e,t){return ww(this,e,t),this}lift(e,t){return ow(this,e,t),this}join(e,t=1){return fw(this,e,t),this}wrap(e,t){return sw(this,e,t),this}setBlockType(e,t=e,r,i=null){return lw(this,e,t,r,i),this}setNodeMarkup(e,t,r=null,i){return uw(this,e,t,r,i),this}setNodeAttribute(e,t,r){return this.step(new eg(e,t,r)),this}addNodeMark(e,t){return this.step(new tf(e,t)),this}removeNodeMark(e,t){if(!(t instanceof U)){let r=this.doc.nodeAt(e);if(!r)throw new RangeError("No node at position "+e);if(t=t.isInSet(r.marks),!t)return this}return this.step(new nf(e,t)),this}split(e,t=1,r){return cw(this,e,t,r),this}addMark(e,t,r){return nw(this,e,t,r),this}removeMark(e,t,r){return rw(this,e,t,r),this}clearIncompatible(e,t,r){return iw(this,e,t,r),this}};const Oa=Object.create(null);class P{constructor(e,t,r){this.$anchor=e,this.$head=t,this.ranges=r||[new tg(e.min(t),e.max(t))]}get anchor(){return this.$anchor.pos}get head(){return this.$head.pos}get from(){return this.$from.pos}get to(){return this.$to.pos}get $from(){return this.ranges[0].$from}get $to(){return this.ranges[0].$to}get empty(){let e=this.ranges;for(let t=0;t=0;o--){let s=t<0?wr(e.node(0),e.node(o),e.before(o+1),e.index(o),t,r):wr(e.node(0),e.node(o),e.after(o+1),e.index(o)+1,t,r);if(s)return s}return null}static near(e,t=1){return this.findFrom(e,t)||this.findFrom(e,-t)||new et(e.node(0))}static atStart(e){return wr(e,e,0,0,1)||new et(e)}static atEnd(e){return wr(e,e,e.content.size,e.childCount,-1)||new et(e)}static fromJSON(e,t){if(!t||!t.type)throw new RangeError("Invalid input for Selection.fromJSON");let r=Oa[t.type];if(!r)throw new RangeError(`No selection type ${t.type} defined`);return r.fromJSON(e,t)}static jsonID(e,t){if(e in Oa)throw new RangeError("Duplicate use of selection JSON ID "+e);return Oa[e]=t,t.prototype.jsonID=e,t}getBookmark(){return $.between(this.$anchor,this.$head).getBookmark()}}P.prototype.visible=!0;class tg{constructor(e,t){this.$from=e,this.$to=t}}let Fd=!1;function Ld(n){!Fd&&!n.parent.inlineContent&&(Fd=!0,console.warn("TextSelection endpoint not pointing into a node with inline content ("+n.parent.type.name+")"))}class $ extends P{constructor(e,t=e){Ld(e),Ld(t),super(e,t)}get $cursor(){return this.$anchor.pos==this.$head.pos?this.$head:null}map(e,t){let r=e.resolve(t.map(this.head));if(!r.parent.inlineContent)return P.near(r);let i=e.resolve(t.map(this.anchor));return new $(i.parent.inlineContent?i:r,r)}replace(e,t=k.empty){if(super.replace(e,t),t==k.empty){let r=this.$from.marksAcross(this.$to);r&&e.ensureMarks(r)}}eq(e){return e instanceof $&&e.anchor==this.anchor&&e.head==this.head}getBookmark(){return new ql(this.anchor,this.head)}toJSON(){return{type:"text",anchor:this.anchor,head:this.head}}static fromJSON(e,t){if(typeof t.anchor!="number"||typeof t.head!="number")throw new RangeError("Invalid input for TextSelection.fromJSON");return new $(e.resolve(t.anchor),e.resolve(t.head))}static create(e,t,r=t){let i=e.resolve(t);return new this(i,r==t?i:e.resolve(r))}static between(e,t,r){let i=e.pos-t.pos;if((!r||i)&&(r=i>=0?1:-1),!t.parent.inlineContent){let o=P.findFrom(t,r,!0)||P.findFrom(t,-r,!0);if(o)t=o.$head;else return P.near(t,r)}return e.parent.inlineContent||(i==0?e=t:(e=(P.findFrom(e,-r,!0)||P.findFrom(e,r,!0)).$anchor,e.pos0?0:1);i>0?s=0;s+=i){let l=e.child(s);if(l.isAtom){if(!o&&I.isSelectable(l))return I.create(n,t-(i<0?l.nodeSize:0))}else{let a=wr(n,l,t+i,i<0?l.childCount:0,i,o);if(a)return a}t+=l.nodeSize*i}return null}function $d(n,e,t){let r=n.steps.length-1;if(r{s==null&&(s=c)}),n.setSelection(P.near(n.doc.resolve(s),t))}const Bd=1,us=2,Vd=4;class xw extends kw{constructor(e){super(e.doc),this.curSelectionFor=0,this.updated=0,this.meta=Object.create(null),this.time=Date.now(),this.curSelection=e.selection,this.storedMarks=e.storedMarks}get selection(){return this.curSelectionFor0}setStoredMarks(e){return this.storedMarks=e,this.updated|=us,this}ensureMarks(e){return U.sameSet(this.storedMarks||this.selection.$from.marks(),e)||this.setStoredMarks(e),this}addStoredMark(e){return this.ensureMarks(e.addToSet(this.storedMarks||this.selection.$head.marks()))}removeStoredMark(e){return this.ensureMarks(e.removeFromSet(this.storedMarks||this.selection.$head.marks()))}get storedMarksSet(){return(this.updated&us)>0}addStep(e,t){super.addStep(e,t),this.updated=this.updated&~us,this.storedMarks=null}setTime(e){return this.time=e,this}replaceSelection(e){return this.selection.replace(this,e),this}replaceSelectionWith(e,t=!0){let r=this.selection;return t&&(e=e.mark(this.storedMarks||(r.empty?r.$from.marks():r.$from.marksAcross(r.$to)||U.none))),r.replaceWith(this,e),this}deleteSelection(){return this.selection.replace(this),this}insertText(e,t,r){let i=this.doc.type.schema;if(t==null)return e?this.replaceSelectionWith(i.text(e),!0):this.deleteSelection();{if(r==null&&(r=t),r=r??t,!e)return this.deleteRange(t,r);let o=this.storedMarks;if(!o){let s=this.doc.resolve(t);o=r==t?s.marks():s.marksAcross(this.doc.resolve(r))}return this.replaceRangeWith(t,r,i.text(e,o)),this.selection.empty||this.setSelection(P.near(this.selection.$to)),this}}setMeta(e,t){return this.meta[typeof e=="string"?e:e.key]=t,this}getMeta(e){return this.meta[typeof e=="string"?e:e.key]}get isGeneric(){for(let e in this.meta)return!1;return!0}scrollIntoView(){return this.updated|=Vd,this}get scrolledIntoView(){return(this.updated&Vd)>0}}function Jd(n,e){return!e||!n?n:n.bind(e)}class Fi{constructor(e,t,r){this.name=e,this.init=Jd(t.init,r),this.apply=Jd(t.apply,r)}}const Cw=[new Fi("doc",{init(n){return n.doc||n.schema.topNodeType.createAndFill()},apply(n){return n.doc}}),new Fi("selection",{init(n,e){return n.selection||P.atStart(e.doc)},apply(n){return n.selection}}),new Fi("storedMarks",{init(n){return n.storedMarks||null},apply(n,e,t,r){return r.selection.$cursor?n.storedMarks:null}}),new Fi("scrollToSelection",{init(){return 0},apply(n,e){return n.scrolledIntoView?e+1:e}})];class Da{constructor(e,t){this.schema=e,this.plugins=[],this.pluginsByKey=Object.create(null),this.fields=Cw.slice(),t&&t.forEach(r=>{if(this.pluginsByKey[r.key])throw new RangeError("Adding different instances of a keyed plugin ("+r.key+")");this.plugins.push(r),this.pluginsByKey[r.key]=r,r.spec.state&&this.fields.push(new Fi(r.key,r.spec.state,r))})}}class cn{constructor(e){this.config=e}get schema(){return this.config.schema}get plugins(){return this.config.plugins}apply(e){return this.applyTransaction(e).state}filterTransaction(e,t=-1){for(let r=0;rr.toJSON())),e&&typeof e=="object")for(let r in e){if(r=="doc"||r=="selection")throw new RangeError("The JSON fields `doc` and `selection` are reserved");let i=e[r],o=i.spec.state;o&&o.toJSON&&(t[r]=o.toJSON.call(i,this[i.key]))}return t}static fromJSON(e,t,r){if(!t)throw new RangeError("Invalid input for EditorState.fromJSON");if(!e.schema)throw new RangeError("Required config field 'schema' missing");let i=new Da(e.schema,e.plugins),o=new cn(i);return i.fields.forEach(s=>{if(s.name=="doc")o.doc=Tt.fromJSON(e.schema,t.doc);else if(s.name=="selection")o.selection=P.fromJSON(o.doc,t.selection);else if(s.name=="storedMarks")t.storedMarks&&(o.storedMarks=t.storedMarks.map(e.schema.markFromJSON));else{if(r)for(let l in r){let a=r[l],u=a.spec.state;if(a.key==s.name&&u&&u.fromJSON&&Object.prototype.hasOwnProperty.call(t,l)){o[s.name]=u.fromJSON.call(a,e,t[l],o);return}}o[s.name]=s.init(e,o)}}),o}}function ng(n,e,t){for(let r in n){let i=n[r];i instanceof Function?i=i.bind(e):r=="handleDOMEvents"&&(i=ng(i,e,{})),t[r]=i}return t}class $t{constructor(e){this.spec=e,this.props={},e.props&&ng(e.props,this,this.props),this.key=e.key?e.key.key:rg("plugin")}getState(e){return e[this.key]}}const Ta=Object.create(null);function rg(n){return n in Ta?n+"$"+ ++Ta[n]:(Ta[n]=0,n+"$")}class Ko{constructor(e="key"){this.key=rg(e)}get(e){return e.config.pluginsByKey[this.key]}getState(e){return e[this.key]}}const ig=(n,e)=>n.selection.empty?!1:(e&&e(n.tr.deleteSelection().scrollIntoView()),!0);function Nw(n,e){let{$cursor:t}=n.selection;return!t||(e?!e.endOfTextblock("backward",n):t.parentOffset>0)?null:t}const Mw=(n,e,t)=>{let r=Nw(n,t);if(!r)return!1;let i=og(r);if(!i){let s=r.blockRange(),l=s&&Xc(s);return l==null?!1:(e&&e(n.tr.lift(s,l).scrollIntoView()),!0)}let o=i.nodeBefore;if(!o.type.spec.isolating&&lg(n,i,e))return!0;if(r.parent.content.size==0&&(qr(o,"end")||I.isSelectable(o))){let s=Wm(n.doc,r.before(),r.after(),k.empty);if(s&&s.slice.size{let{$head:r,empty:i}=n.selection,o=r;if(!i)return!1;if(r.parent.isTextblock){if(t?!t.endOfTextblock("backward",n):r.parentOffset>0)return!1;o=og(r)}let s=o&&o.nodeBefore;return!s||!I.isSelectable(s)?!1:(e&&e(n.tr.setSelection(I.create(n.doc,o.pos-s.nodeSize)).scrollIntoView()),!0)};function og(n){if(!n.parent.type.spec.isolating)for(let e=n.depth-1;e>=0;e--){if(n.index(e)>0)return n.doc.resolve(n.before(e+1));if(n.node(e).type.spec.isolating)break}return null}function Ow(n,e){let{$cursor:t}=n.selection;return!t||(e?!e.endOfTextblock("forward",n):t.parentOffset{let r=Ow(n,t);if(!r)return!1;let i=sg(r);if(!i)return!1;let o=i.nodeAfter;if(lg(n,i,e))return!0;if(r.parent.content.size==0&&(qr(o,"start")||I.isSelectable(o))){let s=Wm(n.doc,r.before(),r.after(),k.empty);if(s&&s.slice.size{let{$head:r,empty:i}=n.selection,o=r;if(!i)return!1;if(r.parent.isTextblock){if(t?!t.endOfTextblock("forward",n):r.parentOffset=0;e--){let t=n.node(e);if(n.index(e)+1{let{$head:t,$anchor:r}=n.selection;return!t.parent.type.spec.code||!t.sameParent(r)?!1:(e&&e(n.tr.insertText(` +`).scrollIntoView()),!0)};function of(n){for(let e=0;e{let{$head:t,$anchor:r}=n.selection;if(!t.parent.type.spec.code||!t.sameParent(r))return!1;let i=t.node(-1),o=t.indexAfter(-1),s=of(i.contentMatchAt(o));if(!s||!i.canReplaceWith(o,o,s))return!1;if(e){let l=t.after(),a=n.tr.replaceWith(l,l,s.createAndFill());a.setSelection(P.near(a.doc.resolve(l),1)),e(a.scrollIntoView())}return!0},bw=(n,e)=>{let t=n.selection,{$from:r,$to:i}=t;if(t instanceof et||r.parent.inlineContent||i.parent.inlineContent)return!1;let o=of(i.parent.contentMatchAt(i.indexAfter()));if(!o||!o.isTextblock)return!1;if(e){let s=(!r.parentOffset&&i.index(){let{$cursor:t}=n.selection;if(!t||t.parent.content.size)return!1;if(t.depth>1&&t.after()!=t.end(-1)){let o=t.before();if(Ls(n.doc,o))return e&&e(n.tr.split(o).scrollIntoView()),!0}let r=t.blockRange(),i=r&&Xc(r);return i==null?!1:(e&&e(n.tr.lift(r,i).scrollIntoView()),!0)};function zw(n){return(e,t)=>{let{$from:r,$to:i}=e.selection;if(e.selection instanceof I&&e.selection.node.isBlock)return!r.parentOffset||!Ls(e.doc,r.pos)?!1:(t&&t(e.tr.split(r.pos).scrollIntoView()),!0);if(!r.parent.isBlock)return!1;if(t){let o=i.parentOffset==i.parent.content.size,s=e.tr;(e.selection instanceof $||e.selection instanceof et)&&s.deleteSelection();let l=r.depth==0?null:of(r.node(-1).contentMatchAt(r.indexAfter(-1))),a=o&&l?[{type:l}]:void 0,u=Ls(s.doc,s.mapping.map(r.pos),1,a);if(!a&&!u&&Ls(s.doc,s.mapping.map(r.pos),1,l?[{type:l}]:void 0)&&(l&&(a=[{type:l}]),u=!0),u&&(s.split(s.mapping.map(r.pos),1,a),!o&&!r.parentOffset&&r.parent.type!=l)){let c=s.mapping.map(r.before()),f=s.doc.resolve(c);l&&r.node(-1).canReplaceWith(f.index(),f.index()+1,l)&&s.setNodeMarkup(s.mapping.map(r.before()),l)}t(s.scrollIntoView())}return!0}}const Pw=zw(),Fw=(n,e)=>(e&&e(n.tr.setSelection(new et(n.doc))),!0);function Lw(n,e,t){let r=e.nodeBefore,i=e.nodeAfter,o=e.index();return!r||!i||!r.type.compatibleContent(i.type)?!1:!r.content.size&&e.parent.canReplace(o-1,o)?(t&&t(n.tr.delete(e.pos-r.nodeSize,e.pos).scrollIntoView()),!0):!e.parent.canReplace(o,o+1)||!(i.isTextblock||_m(n.doc,e.pos))?!1:(t&&t(n.tr.clearIncompatible(e.pos,r.type,r.contentMatchAt(r.childCount)).join(e.pos).scrollIntoView()),!0)}function lg(n,e,t){let r=e.nodeBefore,i=e.nodeAfter,o,s;if(r.type.spec.isolating||i.type.spec.isolating)return!1;if(Lw(n,e,t))return!0;let l=e.parent.canReplace(e.index(),e.index()+1);if(l&&(o=(s=r.contentMatchAt(r.childCount)).findWrapping(i.type))&&s.matchType(o[0]||i.type).validEnd){if(t){let f=e.pos+i.nodeSize,d=v.empty;for(let m=o.length-1;m>=0;m--)d=v.from(o[m].create(null,d));d=v.from(r.copy(d));let p=n.tr.step(new hl(e.pos-1,f,e.pos,f,new k(d,1,0),o.length,!0)),h=f+2*o.length;_m(p.doc,h)&&p.join(h),t(p.scrollIntoView())}return!0}let a=P.findFrom(e,1),u=a&&a.$from.blockRange(a.$to),c=u&&Xc(u);if(c!=null&&c>=e.depth)return t&&t(n.tr.lift(u,c).scrollIntoView()),!0;if(l&&qr(i,"start",!0)&&qr(r,"end")){let f=r,d=[];for(;d.push(f),!f.isTextblock;)f=f.lastChild;let p=i,h=1;for(;!p.isTextblock;p=p.firstChild)h++;if(f.canReplace(f.childCount,f.childCount,p.content)){if(t){let m=v.empty;for(let g=d.length-1;g>=0;g--)m=v.from(d[g].copy(m));let w=n.tr.step(new hl(e.pos-d.length,e.pos+i.nodeSize,e.pos+h,e.pos+i.nodeSize-h,new k(m,d.length,0),0,!0));t(w.scrollIntoView())}return!0}}return!1}function ag(n){return function(e,t){let r=e.selection,i=n<0?r.$from:r.$to,o=i.depth;for(;i.node(o).isInline;){if(!o)return!1;o--}return i.node(o).isTextblock?(t&&t(e.tr.setSelection($.create(e.doc,n<0?i.start(o):i.end(o)))),!0):!1}}const $w=ag(-1),Bw=ag(1);function Vw(n,e,t){for(let r=0;r{if(s)return!1;s=l.inlineContent&&l.type.allowsMarkType(t)}),s)return!0}return!1}function _d(n,e=null){return function(t,r){let{empty:i,$cursor:o,ranges:s}=t.selection;if(i&&!o||!Vw(t.doc,s,n))return!1;if(r)if(o)n.isInSet(t.storedMarks||o.marks())?r(t.tr.removeStoredMark(n)):r(t.tr.addStoredMark(n.create(e)));else{let l=!1,a=t.tr;for(let u=0;!l&&u",191:"?",192:"~",219:"{",220:"|",221:"}",222:'"'},Ud=typeof navigator<"u"&&/Chrome\/(\d+)/.exec(navigator.userAgent),Ww=typeof navigator<"u"&&/Mac/.test(navigator.platform),Uw=typeof navigator<"u"&&/MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent),Hw=Ww||Ud&&+Ud[1]<57;for(var me=0;me<10;me++)It[48+me]=It[96+me]=String(me);for(var me=1;me<=24;me++)It[me+111]="F"+me;for(var me=65;me<=90;me++)It[me]=String.fromCharCode(me+32),pl[me]=String.fromCharCode(me);for(var Aa in It)pl.hasOwnProperty(Aa)||(pl[Aa]=It[Aa]);function lf(n){var e=Hw&&(n.ctrlKey||n.altKey||n.metaKey)||Uw&&n.shiftKey&&n.key&&n.key.length==1||n.key=="Unidentified",t=!e&&n.key||(n.shiftKey?pl:It)[n.keyCode]||n.key||"Unidentified";return t=="Esc"&&(t="Escape"),t=="Del"&&(t="Delete"),t=="Left"&&(t="ArrowLeft"),t=="Up"&&(t="ArrowUp"),t=="Right"&&(t="ArrowRight"),t=="Down"&&(t="ArrowDown"),t}const jw=typeof navigator<"u"?/Mac|iP(hone|[oa]d)/.test(navigator.platform):!1;function Kw(n){let e=n.split(/-(?!$)/),t=e[e.length-1];t=="Space"&&(t=" ");let r,i,o,s;for(let l=0;l127)&&(o=It[r.keyCode])&&o!=i){let l=e[ba(o,r)];if(l&&l(t.state,t.dispatch,t))return!0}}return!1}}const cg=65535,fg=Math.pow(2,16);function Yw(n,e){return n+e*fg}function Hd(n){return n&cg}function Gw(n){return(n-(n&cg))/fg}const dg=1,hg=2,Ws=4,pg=8;let jd=class{constructor(e,t,r){this.pos=e,this.delInfo=t,this.recover=r}get deleted(){return(this.delInfo&pg)>0}get deletedBefore(){return(this.delInfo&(dg|Ws))>0}get deletedAfter(){return(this.delInfo&(hg|Ws))>0}get deletedAcross(){return(this.delInfo&Ws)>0}},Qr=class kr{constructor(e,t=!1){if(this.ranges=e,this.inverted=t,!e.length&&kr.empty)return kr.empty}recover(e){let t=0,r=Hd(e);if(!this.inverted)for(let i=0;ie)break;let u=this.ranges[l+o],c=this.ranges[l+s],f=a+u;if(e<=f){let d=u?e==a?-1:e==f?1:t:t,p=a+i+(d<0?0:c);if(r)return p;let h=e==(t<0?a:f)?null:Yw(l/3,e-a),m=e==a?hg:e==f?dg:Ws;return(t<0?e!=a:e!=f)&&(m|=pg),new jd(p,m,h)}i+=c-u}return r?e+i:new jd(e+i,0,null)}touches(e,t){let r=0,i=Hd(t),o=this.inverted?2:1,s=this.inverted?1:2;for(let l=0;le)break;let u=this.ranges[l+o],c=a+u;if(e<=c&&l==i*3)return!0;r+=this.ranges[l+s]-u}return!1}forEach(e){let t=this.inverted?2:1,r=this.inverted?1:2;for(let i=0,o=0;i!s.isAtom||!l.type.allowsMarkType(this.mark.type)?s:s.mark(this.mark.addToSet(s.marks)),i),t.openStart,t.openEnd);return Ve.fromReplace(e,this.from,this.to,o)}invert(){return new gg(this.from,this.to,this.mark)}map(e){let t=e.mapResult(this.from,1),r=e.mapResult(this.to,-1);return t.deleted&&r.deleted||t.pos>=r.pos?null:new $i(t.pos,r.pos,this.mark)}merge(e){return e instanceof $i&&e.mark.eq(this.mark)&&this.from<=e.to&&this.to>=e.from?new $i(Math.min(this.from,e.from),Math.max(this.to,e.to),this.mark):null}toJSON(){return{stepType:"addMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(e,t){if(typeof t.from!="number"||typeof t.to!="number")throw new RangeError("Invalid input for AddMarkStep.fromJSON");return new $i(t.from,t.to,e.markFromJSON(t.mark))}};Qe.jsonID("addMark",mg);let gg=class Bi extends Qe{constructor(e,t,r){super(),this.from=e,this.to=t,this.mark=r}apply(e){let t=e.slice(this.from,this.to),r=new k(af(t.content,i=>i.mark(this.mark.removeFromSet(i.marks)),e),t.openStart,t.openEnd);return Ve.fromReplace(e,this.from,this.to,r)}invert(){return new mg(this.from,this.to,this.mark)}map(e){let t=e.mapResult(this.from,1),r=e.mapResult(this.to,-1);return t.deleted&&r.deleted||t.pos>=r.pos?null:new Bi(t.pos,r.pos,this.mark)}merge(e){return e instanceof Bi&&e.mark.eq(this.mark)&&this.from<=e.to&&this.to>=e.from?new Bi(Math.min(this.from,e.from),Math.max(this.to,e.to),this.mark):null}toJSON(){return{stepType:"removeMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(e,t){if(typeof t.from!="number"||typeof t.to!="number")throw new RangeError("Invalid input for RemoveMarkStep.fromJSON");return new Bi(t.from,t.to,e.markFromJSON(t.mark))}};Qe.jsonID("removeMark",gg);let yg=class Vi extends Qe{constructor(e,t){super(),this.pos=e,this.mark=t}apply(e){let t=e.nodeAt(this.pos);if(!t)return Ve.fail("No node at mark step's position");let r=t.type.create(t.attrs,null,this.mark.addToSet(t.marks));return Ve.fromReplace(e,this.pos,this.pos+1,new k(v.from(r),0,t.isLeaf?0:1))}invert(e){let t=e.nodeAt(this.pos);if(t){let r=this.mark.addToSet(t.marks);if(r.length==t.marks.length){for(let i=0;ir.pos?null:new Us(t.pos,r.pos,i,o,this.slice,this.insert,this.structure)}toJSON(){let e={stepType:"replaceAround",from:this.from,to:this.to,gapFrom:this.gapFrom,gapTo:this.gapTo,insert:this.insert};return this.slice.size&&(e.slice=this.slice.toJSON()),this.structure&&(e.structure=!0),e}static fromJSON(e,t){if(typeof t.from!="number"||typeof t.to!="number"||typeof t.gapFrom!="number"||typeof t.gapTo!="number"||typeof t.insert!="number")throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON");return new Us(t.from,t.to,t.gapFrom,t.gapTo,k.fromJSON(e,t.slice),t.insert,!!t.structure)}};Qe.jsonID("replaceAround",Zw);function Ou(n,e,t){let r=n.resolve(e),i=t-e,o=r.depth;for(;i>0&&o>0&&r.indexAfter(o)==r.node(o).childCount;)o--,i--;if(i>0){let s=r.node(o).maybeChild(r.indexAfter(o));for(;i>0;){if(!s||s.isLeaf)return!0;s=s.firstChild,i--}}return!1}function ek(n,e,t){let r=n.resolve(e);if(!t.content.size)return e;let i=t.content;for(let o=0;o=0;s--){let l=s==r.depth?0:r.pos<=(r.start(s+1)+r.end(s+1))/2?-1:1,a=r.index(s)+(l>0?1:0),u=r.node(s),c=!1;if(o==1)c=u.canReplace(a,a,i);else{let f=u.contentMatchAt(a).findWrapping(i.firstChild.type);c=f&&u.canReplaceWith(a,a,f[0])}if(c)return l==0?r.pos:l<0?r.before(s+1):r.after(s+1)}return null}let tk=class Hs extends Qe{constructor(e,t,r){super(),this.pos=e,this.attr=t,this.value=r}apply(e){let t=e.nodeAt(this.pos);if(!t)return Ve.fail("No node at attribute step's position");let r=Object.create(null);for(let o in t.attrs)r[o]=t.attrs[o];r[this.attr]=this.value;let i=t.type.create(r,null,t.marks);return Ve.fromReplace(e,this.pos,this.pos+1,new k(v.from(i),0,t.isLeaf?0:1))}getMap(){return Qr.empty}invert(e){return new Hs(this.pos,this.attr,e.nodeAt(this.pos).attrs[this.attr])}map(e){let t=e.mapResult(this.pos,1);return t.deletedAfter?null:new Hs(t.pos,this.attr,this.value)}toJSON(){return{stepType:"attr",pos:this.pos,attr:this.attr,value:this.value}}static fromJSON(e,t){if(typeof t.pos!="number"||typeof t.attr!="string")throw new RangeError("Invalid input for AttrStep.fromJSON");return new Hs(t.pos,t.attr,t.value)}};Qe.jsonID("attr",tk);let yo=class extends Error{};yo=function n(e){let t=Error.call(this,e);return t.__proto__=n.prototype,t};yo.prototype=Object.create(Error.prototype);yo.prototype.constructor=yo;yo.prototype.name="TransformError";const ge=function(n){for(var e=0;;e++)if(n=n.previousSibling,!n)return e},So=function(n){let e=n.assignedSlot||n.parentNode;return e&&e.nodeType==11?e.host:e};let Du=null;const Jt=function(n,e,t){let r=Du||(Du=document.createRange());return r.setEnd(n,t??n.nodeValue.length),r.setStart(n,e||0),r},nk=function(){Du=null},rr=function(n,e,t,r){return t&&(Kd(n,e,t,r,-1)||Kd(n,e,t,r,1))},rk=/^(img|br|input|textarea|hr)$/i;function Kd(n,e,t,r,i){for(;;){if(n==t&&e==r)return!0;if(e==(i<0?0:at(n))){let o=n.parentNode;if(!o||o.nodeType!=1||qo(n)||rk.test(n.nodeName)||n.contentEditable=="false")return!1;e=ge(n)+(i<0?0:1),n=o}else if(n.nodeType==1){if(n=n.childNodes[e+(i<0?-1:0)],n.contentEditable=="false")return!1;e=i<0?at(n):0}else return!1}}function at(n){return n.nodeType==3?n.nodeValue.length:n.childNodes.length}function ik(n,e){for(;;){if(n.nodeType==3&&e)return n;if(n.nodeType==1&&e>0){if(n.contentEditable=="false")return null;n=n.childNodes[e-1],e=at(n)}else if(n.parentNode&&!qo(n))e=ge(n),n=n.parentNode;else return null}}function ok(n,e){for(;;){if(n.nodeType==3&&e2),ot=Yr||(zt?/Mac/.test(zt.platform):!1),uk=zt?/Win/.test(zt.platform):!1,wt=/Android \d/.test(Rn),Qo=!!qd&&"webkitFontSmoothing"in qd.documentElement.style,ck=Qo?+(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent)||[0,0])[1]:0;function fk(n){let e=n.defaultView&&n.defaultView.visualViewport;return e?{left:0,right:e.width,top:0,bottom:e.height}:{left:0,right:n.documentElement.clientWidth,top:0,bottom:n.documentElement.clientHeight}}function Bt(n,e){return typeof n=="number"?n:n[e]}function dk(n){let e=n.getBoundingClientRect(),t=e.width/n.offsetWidth||1,r=e.height/n.offsetHeight||1;return{left:e.left,right:e.left+n.clientWidth*t,top:e.top,bottom:e.top+n.clientHeight*r}}function Qd(n,e,t){let r=n.someProp("scrollThreshold")||0,i=n.someProp("scrollMargin")||5,o=n.dom.ownerDocument;for(let s=t||n.dom;s;s=So(s)){if(s.nodeType!=1)continue;let l=s,a=l==o.body,u=a?fk(o):dk(l),c=0,f=0;if(e.topu.bottom-Bt(r,"bottom")&&(f=e.bottom-e.top>u.bottom-u.top?e.top+Bt(i,"top")-u.top:e.bottom-u.bottom+Bt(i,"bottom")),e.leftu.right-Bt(r,"right")&&(c=e.right-u.right+Bt(i,"right")),c||f)if(a)o.defaultView.scrollBy(c,f);else{let d=l.scrollLeft,p=l.scrollTop;f&&(l.scrollTop+=f),c&&(l.scrollLeft+=c);let h=l.scrollLeft-d,m=l.scrollTop-p;e={left:e.left-h,top:e.top-m,right:e.right-h,bottom:e.bottom-m}}if(a||/^(fixed|sticky)$/.test(getComputedStyle(s).position))break}}function hk(n){let e=n.dom.getBoundingClientRect(),t=Math.max(0,e.top),r,i;for(let o=(e.left+e.right)/2,s=t+1;s=t-20){r=l,i=a.top;break}}return{refDOM:r,refTop:i,stack:vg(n.dom)}}function vg(n){let e=[],t=n.ownerDocument;for(let r=n;r&&(e.push({dom:r,top:r.scrollTop,left:r.scrollLeft}),n!=t);r=So(r));return e}function pk({refDOM:n,refTop:e,stack:t}){let r=n?n.getBoundingClientRect().top:0;xg(t,r==0?0:r-e)}function xg(n,e){for(let t=0;t=l){s=Math.max(h.bottom,s),l=Math.min(h.top,l);let m=h.left>e.left?h.left-e.left:h.right=(h.left+h.right)/2?1:0));continue}}else h.top>e.top&&!a&&h.left<=e.left&&h.right>=e.left&&(a=c,u={left:Math.max(h.left,Math.min(h.right,e.left)),top:h.top});!t&&(e.left>=h.right&&e.top>=h.top||e.left>=h.left&&e.top>=h.bottom)&&(o=f+1)}}return!t&&a&&(t=a,i=u,r=0),t&&t.nodeType==3?gk(t,i):!t||r&&t.nodeType==1?{node:n,offset:o}:Cg(t,i)}function gk(n,e){let t=n.nodeValue.length,r=document.createRange();for(let i=0;i=(o.left+o.right)/2?1:0)}}return{node:n,offset:0}}function uf(n,e){return n.left>=e.left-1&&n.left<=e.right+1&&n.top>=e.top-1&&n.top<=e.bottom+1}function yk(n,e){let t=n.parentNode;return t&&/^li$/i.test(t.nodeName)&&e.left(s.left+s.right)/2?1:-1}return n.docView.posFromDOM(r,i,o)}function wk(n,e,t,r){let i=-1;for(let o=e,s=!1;o!=n.dom;){let l=n.docView.nearestDesc(o,!0);if(!l)return null;if(l.dom.nodeType==1&&(l.node.isBlock&&l.parent||!l.contentDOM)){let a=l.dom.getBoundingClientRect();if(l.node.isBlock&&l.parent&&(!s&&a.left>r.left||a.top>r.top?i=l.posBefore:(!s&&a.right-1?i:n.docView.posFromDOM(e,t,-1)}function Ng(n,e,t){let r=n.childNodes.length;if(r&&t.tope.top&&i++}let u;Qo&&i&&r.nodeType==1&&(u=r.childNodes[i-1]).nodeType==1&&u.contentEditable=="false"&&u.getBoundingClientRect().top>=e.top&&i--,r==n.dom&&i==r.childNodes.length-1&&r.lastChild.nodeType==1&&e.top>r.lastChild.getBoundingClientRect().bottom?l=n.state.doc.content.size:(i==0||r.nodeType!=1||r.childNodes[i-1].nodeName!="BR")&&(l=wk(n,r,i,e))}l==null&&(l=Sk(n,s,e));let a=n.docView.nearestDesc(s,!0);return{pos:l,inside:a?a.posAtStart-a.border:-1}}function Yd(n){return n.top=0&&i==r.nodeValue.length?(a--,c=1):t<0?a--:u++,mi(tn(Jt(r,a,u),c),c<0)}if(!n.state.doc.resolve(e-(o||0)).parent.inlineContent){if(o==null&&i&&(t<0||i==at(r))){let a=r.childNodes[i-1];if(a.nodeType==1)return za(a.getBoundingClientRect(),!1)}if(o==null&&i=0)}if(o==null&&i&&(t<0||i==at(r))){let a=r.childNodes[i-1],u=a.nodeType==3?Jt(a,at(a)-(s?0:1)):a.nodeType==1&&(a.nodeName!="BR"||!a.nextSibling)?a:null;if(u)return mi(tn(u,1),!1)}if(o==null&&i=0)}function mi(n,e){if(n.width==0)return n;let t=e?n.left:n.right;return{top:n.top,bottom:n.bottom,left:t,right:t}}function za(n,e){if(n.height==0)return n;let t=e?n.top:n.bottom;return{top:t,bottom:t,left:n.left,right:n.right}}function Eg(n,e,t){let r=n.state,i=n.root.activeElement;r!=e&&n.updateState(e),i!=n.dom&&n.focus();try{return t()}finally{r!=e&&n.updateState(r),i!=n.dom&&i&&i.focus()}}function xk(n,e,t){let r=e.selection,i=t=="up"?r.$from:r.$to;return Eg(n,e,()=>{let{node:o}=n.docView.domFromPos(i.pos,t=="up"?-1:1);for(;;){let l=n.docView.nearestDesc(o,!0);if(!l)break;if(l.node.isBlock){o=l.contentDOM||l.dom;break}o=l.dom.parentNode}let s=Mg(n,i.pos,1);for(let l=o.firstChild;l;l=l.nextSibling){let a;if(l.nodeType==1)a=l.getClientRects();else if(l.nodeType==3)a=Jt(l,0,l.nodeValue.length).getClientRects();else continue;for(let u=0;uc.top+1&&(t=="up"?s.top-c.top>(c.bottom-s.top)*2:c.bottom-s.bottom>(s.bottom-c.top)*2))return!1}}return!0})}const Ck=/[\u0590-\u08ac]/;function Nk(n,e,t){let{$head:r}=e.selection;if(!r.parent.isTextblock)return!1;let i=r.parentOffset,o=!i,s=i==r.parent.content.size,l=n.domSelection();return l?!Ck.test(r.parent.textContent)||!l.modify?t=="left"||t=="backward"?o:s:Eg(n,e,()=>{let{focusNode:a,focusOffset:u,anchorNode:c,anchorOffset:f}=n.domSelectionRange(),d=l.caretBidiLevel;l.modify("move",t,"character");let p=r.depth?n.docView.domAfterPos(r.before()):n.dom,{focusNode:h,focusOffset:m}=n.domSelectionRange(),w=h&&!p.contains(h.nodeType==1?h:h.parentNode)||a==h&&u==m;try{l.collapse(c,f),a&&(a!=c||u!=f)&&l.extend&&l.extend(a,u)}catch{}return d!=null&&(l.caretBidiLevel=d),w}):r.pos==r.start()||r.pos==r.end()}let Gd=null,Xd=null,Zd=!1;function Mk(n,e,t){return Gd==e&&Xd==t?Zd:(Gd=e,Xd=t,Zd=t=="up"||t=="down"?xk(n,e,t):Nk(n,e,t))}const ft=0,eh=1,Hn=2,Pt=3;let Yo=class{constructor(e,t,r,i){this.parent=e,this.children=t,this.dom=r,this.contentDOM=i,this.dirty=ft,r.pmViewDesc=this}matchesWidget(e){return!1}matchesMark(e){return!1}matchesNode(e,t,r){return!1}matchesHack(e){return!1}parseRule(){return null}stopEvent(e){return!1}get size(){let e=0;for(let t=0;tge(this.contentDOM);else if(this.contentDOM&&this.contentDOM!=this.dom&&this.dom.contains(this.contentDOM))i=e.compareDocumentPosition(this.contentDOM)&2;else if(this.dom.firstChild){if(t==0)for(let o=e;;o=o.parentNode){if(o==this.dom){i=!1;break}if(o.previousSibling)break}if(i==null&&t==e.childNodes.length)for(let o=e;;o=o.parentNode){if(o==this.dom){i=!0;break}if(o.nextSibling)break}}return i??r>0?this.posAtEnd:this.posAtStart}nearestDesc(e,t=!1){for(let r=!0,i=e;i;i=i.parentNode){let o=this.getDesc(i),s;if(o&&(!t||o.node))if(r&&(s=o.nodeDOM)&&!(s.nodeType==1?s.contains(e.nodeType==1?e:e.parentNode):s==e))r=!1;else return o}}getDesc(e){let t=e.pmViewDesc;for(let r=t;r;r=r.parent)if(r==this)return t}posFromDOM(e,t,r){for(let i=e;i;i=i.parentNode){let o=this.getDesc(i);if(o)return o.localPosFromDOM(e,t,r)}return-1}descAt(e){for(let t=0,r=0;te||s instanceof Ag){i=e-o;break}o=l}if(i)return this.children[r].domFromPos(i-this.children[r].border,t);for(let o;r&&!(o=this.children[r-1]).size&&o instanceof Og&&o.side>=0;r--);if(t<=0){let o,s=!0;for(;o=r?this.children[r-1]:null,!(!o||o.dom.parentNode==this.contentDOM);r--,s=!1);return o&&t&&s&&!o.border&&!o.domAtom?o.domFromPos(o.size,t):{node:this.contentDOM,offset:o?ge(o.dom)+1:0}}else{let o,s=!0;for(;o=r=c&&t<=u-a.border&&a.node&&a.contentDOM&&this.contentDOM.contains(a.contentDOM))return a.parseRange(e,t,c);e=s;for(let f=l;f>0;f--){let d=this.children[f-1];if(d.size&&d.dom.parentNode==this.contentDOM&&!d.emptyChildAt(1)){i=ge(d.dom)+1;break}e-=d.size}i==-1&&(i=0)}if(i>-1&&(u>t||l==this.children.length-1)){t=u;for(let c=l+1;cp&&st){let p=l;l=a,a=p}let d=document.createRange();d.setEnd(a.node,a.offset),d.setStart(l.node,l.offset),u.removeAllRanges(),u.addRange(d)}}ignoreMutation(e){return!this.contentDOM&&e.type!="selection"}get contentLost(){return this.contentDOM&&this.contentDOM!=this.dom&&!this.dom.contains(this.contentDOM)}markDirty(e,t){for(let r=0,i=0;i=r:er){let l=r+o.border,a=s-o.border;if(e>=l&&t<=a){this.dirty=e==r||t==s?Hn:eh,e==l&&t==a&&(o.contentLost||o.dom.parentNode!=this.contentDOM)?o.dirty=Pt:o.markDirty(e-l,t-l);return}else o.dirty=o.dom==o.contentDOM&&o.dom.parentNode==this.contentDOM&&!o.children.length?Hn:Pt}r=s}this.dirty=Hn}markParentsDirty(){let e=1;for(let t=this.parent;t;t=t.parent,e++){let r=e==1?Hn:eh;t.dirty{if(!o)return i;if(o.parent)return o.parent.posBeforeChild(o)})),!t.type.spec.raw){if(s.nodeType!=1){let l=document.createElement("span");l.appendChild(s),s=l}s.contentEditable="false",s.classList.add("ProseMirror-widget")}super(e,[],s,null),this.widget=t,this.widget=t,o=this}matchesWidget(e){return this.dirty==ft&&e.type.eq(this.widget.type)}parseRule(){return{ignore:!0}}stopEvent(e){let t=this.widget.spec.stopEvent;return t?t(e):!1}ignoreMutation(e){return e.type!="selection"||this.widget.spec.ignoreSelection}destroy(){this.widget.type.destroy(this.dom),super.destroy()}get domAtom(){return!0}get side(){return this.widget.type.side}},Ek=class extends Yo{constructor(e,t,r,i){super(e,[],t,null),this.textDOM=r,this.text=i}get size(){return this.text.length}localPosFromDOM(e,t){return e!=this.textDOM?this.posAtStart+(t?this.size:0):this.posAtStart+t}domFromPos(e){return{node:this.textDOM,offset:e}}ignoreMutation(e){return e.type==="characterData"&&e.target.nodeValue==e.oldValue}},ml=class bu extends Yo{constructor(e,t,r,i){super(e,[],r,i),this.mark=t}static create(e,t,r,i){let o=i.nodeViews[t.type.name],s=o&&o(t,i,r);return(!s||!s.dom)&&(s=fi.renderSpec(document,t.type.spec.toDOM(t,r),null,t.attrs)),new bu(e,t,s.dom,s.contentDOM||s.dom)}parseRule(){return this.dirty&Pt||this.mark.type.spec.reparseInView?null:{mark:this.mark.type.name,attrs:this.mark.attrs,contentElement:this.contentDOM}}matchesMark(e){return this.dirty!=Pt&&this.mark.eq(e)}markDirty(e,t){if(super.markDirty(e,t),this.dirty!=ft){let r=this.parent;for(;!r.node;)r=r.parent;r.dirty0&&(o=Pu(o,0,e,r));for(let l=0;l{if(!a)return s;if(a.parent)return a.parent.posBeforeChild(a)},r,i),c=u&&u.dom,f=u&&u.contentDOM;if(t.isText){if(!c)c=document.createTextNode(t.text);else if(c.nodeType!=3)throw new RangeError("Text must be rendered as a DOM text node")}else c||({dom:c,contentDOM:f}=fi.renderSpec(document,t.type.spec.toDOM(t),null,t.attrs));!f&&!t.isText&&c.nodeName!="BR"&&(c.hasAttribute("contenteditable")||(c.contentEditable="false"),t.type.spec.draggable&&(c.draggable=!0));let d=c;return c=zg(c,r,t),u?a=new Ok(e,t,r,i,c,f||null,d,u,o,s+1):t.isText?new Tg(e,t,r,i,c,d,o):new Dg(e,t,r,i,c,f||null,d,o,s+1)}parseRule(){if(this.node.type.spec.reparseInView)return null;let e={node:this.node.type.name,attrs:this.node.attrs};if(this.node.type.whitespace=="pre"&&(e.preserveWhitespace="full"),!this.contentDOM)e.getContent=()=>this.node.content;else if(!this.contentLost)e.contentElement=this.contentDOM;else{for(let t=this.children.length-1;t>=0;t--){let r=this.children[t];if(this.dom.contains(r.dom.parentNode)){e.contentElement=r.dom.parentNode;break}}e.contentElement||(e.getContent=()=>v.empty)}return e}matchesNode(e,t,r){return this.dirty==ft&&e.eq(this.node)&&zu(t,this.outerDeco)&&r.eq(this.innerDeco)}get size(){return this.node.nodeSize}get border(){return this.node.isLeaf?0:1}updateChildren(e,t){let r=this.node.inlineContent,i=t,o=e.composing?this.localCompositionInfo(e,t):null,s=o&&o.pos>-1?o:null,l=o&&o.pos<0,a=new Tk(this,s&&s.node,e);bk(this.node,this.innerDeco,(u,c,f)=>{u.spec.marks?a.syncToMarks(u.spec.marks,r,e):u.type.side>=0&&!f&&a.syncToMarks(c==this.node.childCount?U.none:this.node.child(c).marks,r,e),a.placeWidget(u,e,i)},(u,c,f,d)=>{a.syncToMarks(u.marks,r,e);let p;a.findNodeMatch(u,c,f,d)||l&&e.state.selection.from>i&&e.state.selection.to-1&&a.updateNodeAt(u,c,f,p,e)||a.updateNextNode(u,c,f,e,d,i)||a.addNode(u,c,f,e,i),i+=u.nodeSize}),a.syncToMarks([],r,e),this.node.isTextblock&&a.addTextblockHacks(),a.destroyRest(),(a.changed||this.dirty==Hn)&&(s&&this.protectLocalComposition(e,s),bg(this.contentDOM,this.children,e),Yr&&Ik(this.dom))}localCompositionInfo(e,t){let{from:r,to:i}=e.state.selection;if(!(e.state.selection instanceof $)||rt+this.node.content.size)return null;let o=e.input.compositionNode;if(!o||!this.dom.contains(o.parentNode))return null;if(this.node.inlineContent){let s=o.nodeValue,l=zk(this.node.content,s,r-t,i-t);return l<0?null:{node:o,pos:l,text:s}}else return{node:o,pos:-1,text:""}}protectLocalComposition(e,{node:t,pos:r,text:i}){if(this.getDesc(t))return;let o=t;for(;o.parentNode!=this.contentDOM;o=o.parentNode){for(;o.previousSibling;)o.parentNode.removeChild(o.previousSibling);for(;o.nextSibling;)o.parentNode.removeChild(o.nextSibling);o.pmViewDesc&&(o.pmViewDesc=void 0)}let s=new Ek(this,o,t,i);e.input.compositionNodes.push(s),this.children=Pu(this.children,r,r+i.length,e,s)}update(e,t,r,i){return this.dirty==Pt||!e.sameMarkup(this.node)?!1:(this.updateInner(e,t,r,i),!0)}updateInner(e,t,r,i){this.updateOuterDeco(t),this.node=e,this.innerDeco=r,this.contentDOM&&this.updateChildren(i,this.posAtStart),this.dirty=ft}updateOuterDeco(e){if(zu(e,this.outerDeco))return;let t=this.nodeDOM.nodeType!=1,r=this.dom;this.dom=Ig(this.dom,this.nodeDOM,Iu(this.outerDeco,this.node,t),Iu(e,this.node,t)),this.dom!=r&&(r.pmViewDesc=void 0,this.dom.pmViewDesc=this),this.outerDeco=e}selectNode(){this.nodeDOM.nodeType==1&&this.nodeDOM.classList.add("ProseMirror-selectednode"),(this.contentDOM||!this.node.type.spec.draggable)&&(this.dom.draggable=!0)}deselectNode(){this.nodeDOM.nodeType==1&&(this.nodeDOM.classList.remove("ProseMirror-selectednode"),(this.contentDOM||!this.node.type.spec.draggable)&&this.dom.removeAttribute("draggable"))}get domAtom(){return this.node.isAtom}};function th(n,e,t,r,i){zg(r,e,n);let o=new Fr(void 0,n,e,t,r,r,r,i,0);return o.contentDOM&&o.updateChildren(i,0),o}let Tg=class Rg extends Fr{constructor(e,t,r,i,o,s,l){super(e,t,r,i,o,null,s,l,0)}parseRule(){let e=this.nodeDOM.parentNode;for(;e&&e!=this.dom&&!e.pmIsDeco;)e=e.parentNode;return{skip:e||!0}}update(e,t,r,i){return this.dirty==Pt||this.dirty!=ft&&!this.inParent()||!e.sameMarkup(this.node)?!1:(this.updateOuterDeco(t),(this.dirty!=ft||e.text!=this.node.text)&&e.text!=this.nodeDOM.nodeValue&&(this.nodeDOM.nodeValue=e.text,i.trackWrites==this.nodeDOM&&(i.trackWrites=null)),this.node=e,this.dirty=ft,!0)}inParent(){let e=this.parent.contentDOM;for(let t=this.nodeDOM;t;t=t.parentNode)if(t==e)return!0;return!1}domFromPos(e){return{node:this.nodeDOM,offset:e}}localPosFromDOM(e,t,r){return e==this.nodeDOM?this.posAtStart+Math.min(t,this.node.text.length):super.localPosFromDOM(e,t,r)}ignoreMutation(e){return e.type!="characterData"&&e.type!="selection"}slice(e,t,r){let i=this.node.cut(e,t),o=document.createTextNode(i.text);return new Rg(this.parent,i,this.outerDeco,this.innerDeco,o,o,r)}markDirty(e,t){super.markDirty(e,t),this.dom!=this.nodeDOM&&(e==0||t==this.nodeDOM.nodeValue.length)&&(this.dirty=Pt)}get domAtom(){return!1}isText(e){return this.node.text==e}},Ag=class extends Yo{parseRule(){return{ignore:!0}}matchesHack(e){return this.dirty==ft&&this.dom.nodeName==e}get domAtom(){return!0}get ignoreForCoords(){return this.dom.nodeName=="IMG"}};class Ok extends Fr{constructor(e,t,r,i,o,s,l,a,u,c){super(e,t,r,i,o,s,l,u,c),this.spec=a}update(e,t,r,i){if(this.dirty==Pt)return!1;if(this.spec.update){let o=this.spec.update(e,t,r);return o&&this.updateInner(e,t,r,i),o}else return!this.contentDOM&&!e.isLeaf?!1:super.update(e,t,r,i)}selectNode(){this.spec.selectNode?this.spec.selectNode():super.selectNode()}deselectNode(){this.spec.deselectNode?this.spec.deselectNode():super.deselectNode()}setSelection(e,t,r,i){this.spec.setSelection?this.spec.setSelection(e,t,r):super.setSelection(e,t,r,i)}destroy(){this.spec.destroy&&this.spec.destroy(),super.destroy()}stopEvent(e){return this.spec.stopEvent?this.spec.stopEvent(e):!1}ignoreMutation(e){return this.spec.ignoreMutation?this.spec.ignoreMutation(e):super.ignoreMutation(e)}}function bg(n,e,t){let r=n.firstChild,i=!1;for(let o=0;o>1,s=Math.min(o,e.length);for(;i-1)l>this.index&&(this.changed=!0,this.destroyBetween(this.index,l)),this.top=this.top.children[this.index];else{let a=ml.create(this.top,e[o],t,r);this.top.children.splice(this.index,0,a),this.top=a,this.changed=!0}this.index=0,o++}}findNodeMatch(e,t,r,i){let o=-1,s;if(i>=this.preMatch.index&&(s=this.preMatch.matches[i-this.preMatch.index]).parent==this.top&&s.matchesNode(e,t,r))o=this.top.children.indexOf(s,this.index);else for(let l=this.index,a=Math.min(this.top.children.length,l+5);l0;){let l;for(;;)if(r){let u=t.children[r-1];if(u instanceof ml)t=u,r=u.children.length;else{l=u,r--;break}}else{if(t==e)break e;r=t.parent.children.indexOf(t),t=t.parent}let a=l.node;if(a){if(a!=n.child(i-1))break;--i,o.set(l,i),s.push(l)}}return{index:i,matched:o,matches:s.reverse()}}function Ak(n,e){return n.type.side-e.type.side}function bk(n,e,t,r){let i=e.locals(n),o=0;if(i.length==0){for(let u=0;uo;)l.push(i[s++]);let h=o+d.nodeSize;if(d.isText){let w=h;s!w.inline):l.slice();r(d,m,e.forChild(o,d),p),o=h}}function Ik(n){if(n.nodeName=="UL"||n.nodeName=="OL"){let e=n.style.cssText;n.style.cssText=e+"; list-style: square !important",window.getComputedStyle(n).listStyle,n.style.cssText=e}}function zk(n,e,t,r){for(let i=0,o=0;i=t){if(o>=r&&a.slice(r-e.length-l,r-l)==e)return r-e.length;let u=l=0&&u+e.length+l>=t)return l+u;if(t==r&&a.length>=r+e.length-l&&a.slice(r-l,r-l+e.length)==e)return r}}return-1}function Pu(n,e,t,r,i){let o=[];for(let s=0,l=0;s=t||c<=e?o.push(a):(ut&&o.push(a.slice(t-u,a.size,r)))}return o}function cf(n,e=null){let t=n.domSelectionRange(),r=n.state.doc;if(!t.focusNode)return null;let i=n.docView.nearestDesc(t.focusNode),o=i&&i.size==0,s=n.docView.posFromDOM(t.focusNode,t.focusOffset,1);if(s<0)return null;let l=r.resolve(s),a,u;if(Ql(t)){for(a=l;i&&!i.node;)i=i.parent;let c=i.node;if(i&&c.isAtom&&I.isSelectable(c)&&i.parent&&!(c.isInline&&sk(t.focusNode,t.focusOffset,i.dom))){let f=i.posBefore;u=new I(s==f?l:r.resolve(f))}}else{let c=n.docView.posFromDOM(t.anchorNode,t.anchorOffset,1);if(c<0)return null;a=r.resolve(c)}if(!u){let c=e=="pointer"||n.state.selection.head{(t.anchorNode!=r||t.anchorOffset!=i)&&(e.removeEventListener("selectionchange",n.input.hideSelectionGuard),setTimeout(()=>{(!Pg(n)||n.state.selection.visible)&&n.dom.classList.remove("ProseMirror-hideselection")},20))})}function Fk(n){let e=n.domSelection(),t=document.createRange();if(!e)return;let r=n.cursorWrapper.dom,i=r.nodeName=="IMG";i?t.setStart(r.parentNode,ge(r)+1):t.setStart(r,0),t.collapse(!0),e.removeAllRanges(),e.addRange(t),!i&&!n.state.selection.visible&&We&&gn<=11&&(r.disabled=!0,r.disabled=!1)}function Fg(n,e){if(e instanceof I){let t=n.docView.descAt(e.from);t!=n.lastSelectedViewDesc&&(sh(n),t&&t.selectNode(),n.lastSelectedViewDesc=t)}else sh(n)}function sh(n){n.lastSelectedViewDesc&&(n.lastSelectedViewDesc.parent&&n.lastSelectedViewDesc.deselectNode(),n.lastSelectedViewDesc=void 0)}function ff(n,e,t,r){return n.someProp("createSelectionBetween",i=>i(n,e,t))||$.between(e,t,r)}function lh(n){return n.editable&&!n.hasFocus()?!1:Lg(n)}function Lg(n){let e=n.domSelectionRange();if(!e.anchorNode)return!1;try{return n.dom.contains(e.anchorNode.nodeType==3?e.anchorNode.parentNode:e.anchorNode)&&(n.editable||n.dom.contains(e.focusNode.nodeType==3?e.focusNode.parentNode:e.focusNode))}catch{return!1}}function Lk(n){let e=n.docView.domFromPos(n.state.selection.anchor,0),t=n.domSelectionRange();return rr(e.node,e.offset,t.anchorNode,t.anchorOffset)}function Fu(n,e){let{$anchor:t,$head:r}=n.selection,i=e>0?t.max(r):t.min(r),o=i.parent.inlineContent?i.depth?n.doc.resolve(e>0?i.after():i.before()):null:i;return o&&P.findFrom(o,e)}function nn(n,e){return n.dispatch(n.state.tr.setSelection(e).scrollIntoView()),!0}function ah(n,e,t){let r=n.state.selection;if(r instanceof $)if(t.indexOf("s")>-1){let{$head:i}=r,o=i.textOffset?null:e<0?i.nodeBefore:i.nodeAfter;if(!o||o.isText||!o.isLeaf)return!1;let s=n.state.doc.resolve(i.pos+o.nodeSize*(e<0?-1:1));return nn(n,new $(r.$anchor,s))}else if(r.empty){if(n.endOfTextblock(e>0?"forward":"backward")){let i=Fu(n.state,e);return i&&i instanceof I?nn(n,i):!1}else if(!(ot&&t.indexOf("m")>-1)){let i=r.$head,o=i.textOffset?null:e<0?i.nodeBefore:i.nodeAfter,s;if(!o||o.isText)return!1;let l=e<0?i.pos-o.nodeSize:i.pos;return o.isAtom||(s=n.docView.descAt(l))&&!s.contentDOM?I.isSelectable(o)?nn(n,new I(e<0?n.state.doc.resolve(i.pos-o.nodeSize):i)):Qo?nn(n,new $(n.state.doc.resolve(e<0?l:l+o.nodeSize))):!1:!1}}else return!1;else{if(r instanceof I&&r.node.isInline)return nn(n,new $(e>0?r.$to:r.$from));{let i=Fu(n.state,e);return i?nn(n,i):!1}}}function gl(n){return n.nodeType==3?n.nodeValue.length:n.childNodes.length}function eo(n,e){let t=n.pmViewDesc;return t&&t.size==0&&(e<0||n.nextSibling||n.nodeName!="BR")}function mr(n,e){return e<0?$k(n):Bk(n)}function $k(n){let e=n.domSelectionRange(),t=e.focusNode,r=e.focusOffset;if(!t)return;let i,o,s=!1;for(Ct&&t.nodeType==1&&r0){if(t.nodeType!=1)break;{let l=t.childNodes[r-1];if(eo(l,-1))i=t,o=--r;else if(l.nodeType==3)t=l,r=t.nodeValue.length;else break}}else{if($g(t))break;{let l=t.previousSibling;for(;l&&eo(l,-1);)i=t.parentNode,o=ge(l),l=l.previousSibling;if(l)t=l,r=gl(t);else{if(t=t.parentNode,t==n.dom)break;r=0}}}s?Lu(n,t,r):i&&Lu(n,i,o)}function Bk(n){let e=n.domSelectionRange(),t=e.focusNode,r=e.focusOffset;if(!t)return;let i=gl(t),o,s;for(;;)if(r{n.state==i&&Kt(n)},50)}function uh(n,e){let t=n.state.doc.resolve(e);if(!(Me||uk)&&t.parent.inlineContent){let i=n.coordsAtPos(e);if(e>t.start()){let o=n.coordsAtPos(e-1),s=(o.top+o.bottom)/2;if(s>i.top&&s1)return o.lefti.top&&s1)return o.left>i.left?"ltr":"rtl"}}return getComputedStyle(n.dom).direction=="rtl"?"rtl":"ltr"}function ch(n,e,t){let r=n.state.selection;if(r instanceof $&&!r.empty||t.indexOf("s")>-1||ot&&t.indexOf("m")>-1)return!1;let{$from:i,$to:o}=r;if(!i.parent.inlineContent||n.endOfTextblock(e<0?"up":"down")){let s=Fu(n.state,e);if(s&&s instanceof I)return nn(n,s)}if(!i.parent.inlineContent){let s=e<0?i:o,l=r instanceof et?P.near(s,e):P.findFrom(s,e);return l?nn(n,l):!1}return!1}function fh(n,e){if(!(n.state.selection instanceof $))return!0;let{$head:t,$anchor:r,empty:i}=n.state.selection;if(!t.sameParent(r))return!0;if(!i)return!1;if(n.endOfTextblock(e>0?"forward":"backward"))return!0;let o=!t.textOffset&&(e<0?t.nodeBefore:t.nodeAfter);if(o&&!o.isText){let s=n.state.tr;return e<0?s.delete(t.pos-o.nodeSize,t.pos):s.delete(t.pos,t.pos+o.nodeSize),n.dispatch(s),!0}return!1}function dh(n,e,t){n.domObserver.stop(),e.contentEditable=t,n.domObserver.start()}function _k(n){if(!be||n.state.selection.$head.parentOffset>0)return!1;let{focusNode:e,focusOffset:t}=n.domSelectionRange();if(e&&e.nodeType==1&&t==0&&e.firstChild&&e.firstChild.contentEditable=="false"){let r=e.firstChild;dh(n,r,"true"),setTimeout(()=>dh(n,r,"false"),20)}return!1}function Wk(n){let e="";return n.ctrlKey&&(e+="c"),n.metaKey&&(e+="m"),n.altKey&&(e+="a"),n.shiftKey&&(e+="s"),e}function Uk(n,e){let t=e.keyCode,r=Wk(e);if(t==8||ot&&t==72&&r=="c")return fh(n,-1)||mr(n,-1);if(t==46&&!e.shiftKey||ot&&t==68&&r=="c")return fh(n,1)||mr(n,1);if(t==13||t==27)return!0;if(t==37||ot&&t==66&&r=="c"){let i=t==37?uh(n,n.state.selection.from)=="ltr"?-1:1:-1;return ah(n,i,r)||mr(n,i)}else if(t==39||ot&&t==70&&r=="c"){let i=t==39?uh(n,n.state.selection.from)=="ltr"?1:-1:1;return ah(n,i,r)||mr(n,i)}else{if(t==38||ot&&t==80&&r=="c")return ch(n,-1,r)||mr(n,-1);if(t==40||ot&&t==78&&r=="c")return _k(n)||ch(n,1,r)||mr(n,1);if(r==(ot?"m":"c")&&(t==66||t==73||t==89||t==90))return!0}return!1}function Bg(n,e){n.someProp("transformCopied",p=>{e=p(e,n)});let t=[],{content:r,openStart:i,openEnd:o}=e;for(;i>1&&o>1&&r.childCount==1&&r.firstChild.childCount==1;){i--,o--;let p=r.firstChild;t.push(p.type.name,p.attrs!=p.type.defaultAttrs?p.attrs:null),r=p.content}let s=n.someProp("clipboardSerializer")||fi.fromSchema(n.state.schema),l=Hg(),a=l.createElement("div");a.appendChild(s.serializeFragment(r,{document:l}));let u=a.firstChild,c,f=0;for(;u&&u.nodeType==1&&(c=Ug[u.nodeName.toLowerCase()]);){for(let p=c.length-1;p>=0;p--){let h=l.createElement(c[p]);for(;a.firstChild;)h.appendChild(a.firstChild);a.appendChild(h),f++}u=a.firstChild}u&&u.nodeType==1&&u.setAttribute("data-pm-slice",`${i} ${o}${f?` -${f}`:""} ${JSON.stringify(t)}`);let d=n.someProp("clipboardTextSerializer",p=>p(e,n))||e.content.textBetween(0,e.content.size,` + +`);return{dom:a,text:d,slice:e}}function Vg(n,e,t,r,i){let o=i.parent.type.spec.code,s,l;if(!t&&!e)return null;let a=e&&(r||o||!t);if(a){if(n.someProp("transformPastedText",d=>{e=d(e,o||r,n)}),o)return e?new k(v.from(n.state.schema.text(e.replace(/\r\n?/g,` +`))),0,0):k.empty;let f=n.someProp("clipboardTextParser",d=>d(e,i,r,n));if(f)l=f;else{let d=i.marks(),{schema:p}=n.state,h=fi.fromSchema(p);s=document.createElement("div"),e.split(/(?:\r\n?|\n)+/).forEach(m=>{let w=s.appendChild(document.createElement("p"));m&&w.appendChild(h.serializeNode(p.text(m,d)))})}}else n.someProp("transformPastedHTML",f=>{t=f(t,n)}),s=qk(t),Qo&&Qk(s);let u=s&&s.querySelector("[data-pm-slice]"),c=u&&/^(\d+) (\d+)(?: -(\d+))? (.*)/.exec(u.getAttribute("data-pm-slice")||"");if(c&&c[3])for(let f=+c[3];f>0;f--){let d=s.firstChild;for(;d&&d.nodeType!=1;)d=d.nextSibling;if(!d)break;s=d}if(l||(l=(n.someProp("clipboardParser")||n.someProp("domParser")||mo.fromSchema(n.state.schema)).parseSlice(s,{preserveWhitespace:!!(a||c),context:i,ruleFromNode(d){return d.nodeName=="BR"&&!d.nextSibling&&d.parentNode&&!Hk.test(d.parentNode.nodeName)?{ignore:!0}:null}})),c)l=Yk(hh(l,+c[1],+c[2]),c[4]);else if(l=k.maxOpen(jk(l.content,i),!0),l.openStart||l.openEnd){let f=0,d=0;for(let p=l.content.firstChild;f{l=f(l,n)}),l}const Hk=/^(a|abbr|acronym|b|cite|code|del|em|i|ins|kbd|label|output|q|ruby|s|samp|span|strong|sub|sup|time|u|tt|var)$/i;function jk(n,e){if(n.childCount<2)return n;for(let t=e.depth;t>=0;t--){let i=e.node(t).contentMatchAt(e.index(t)),o,s=[];if(n.forEach(l=>{if(!s)return;let a=i.findWrapping(l.type),u;if(!a)return s=null;if(u=s.length&&o.length&&_g(a,o,l,s[s.length-1],0))s[s.length-1]=u;else{s.length&&(s[s.length-1]=Wg(s[s.length-1],o.length));let c=Jg(l,a);s.push(c),i=i.matchType(c.type),o=a}}),s)return v.from(s)}return n}function Jg(n,e,t=0){for(let r=e.length-1;r>=t;r--)n=e[r].create(null,v.from(n));return n}function _g(n,e,t,r,i){if(i1&&(o=0),i=t&&(l=e<0?s.contentMatchAt(0).fillBefore(l,o<=i).append(l):l.append(s.contentMatchAt(s.childCount).fillBefore(v.empty,!0))),n.replaceChild(e<0?0:n.childCount-1,s.copy(l))}function hh(n,e,t){return et}).createHTML(n):n}function qk(n){let e=/^(\s*]*>)*/.exec(n);e&&(n=n.slice(e[0].length));let t=Hg().createElement("div"),r=/<([a-z][^>\s]+)/i.exec(n),i;if((i=r&&Ug[r[1].toLowerCase()])&&(n=i.map(o=>"<"+o+">").join("")+n+i.map(o=>"").reverse().join("")),t.innerHTML=Kk(n),i)for(let o=0;o=0;l-=2){let a=t.nodes[r[l]];if(!a||a.hasRequiredAttrs())break;i=v.from(a.create(r[l+1],i)),o++,s++}return new k(i,o,s)}const Ie={},ze={},Gk={touchstart:!0,touchmove:!0};class Xk{constructor(){this.shiftKey=!1,this.mouseDown=null,this.lastKeyCode=null,this.lastKeyCodeTime=0,this.lastClick={time:0,x:0,y:0,type:""},this.lastSelectionOrigin=null,this.lastSelectionTime=0,this.lastIOSEnter=0,this.lastIOSEnterFallbackTimeout=-1,this.lastFocus=0,this.lastTouch=0,this.lastAndroidDelete=0,this.composing=!1,this.compositionNode=null,this.composingTimeout=-1,this.compositionNodes=[],this.compositionEndedAt=-2e8,this.compositionID=1,this.compositionPendingChanges=0,this.domChangeCount=0,this.eventHandlers=Object.create(null),this.hideSelectionGuard=null}}function Zk(n){for(let e in Ie){let t=Ie[e];n.dom.addEventListener(e,n.input.eventHandlers[e]=r=>{tv(n,r)&&!df(n,r)&&(n.editable||!(r.type in ze))&&t(n,r)},Gk[e]?{passive:!0}:void 0)}be&&n.dom.addEventListener("input",()=>null),Bu(n)}function fn(n,e){n.input.lastSelectionOrigin=e,n.input.lastSelectionTime=Date.now()}function ev(n){n.domObserver.stop();for(let e in n.input.eventHandlers)n.dom.removeEventListener(e,n.input.eventHandlers[e]);clearTimeout(n.input.composingTimeout),clearTimeout(n.input.lastIOSEnterFallbackTimeout)}function Bu(n){n.someProp("handleDOMEvents",e=>{for(let t in e)n.input.eventHandlers[t]||n.dom.addEventListener(t,n.input.eventHandlers[t]=r=>df(n,r))})}function df(n,e){return n.someProp("handleDOMEvents",t=>{let r=t[e.type];return r?r(n,e)||e.defaultPrevented:!1})}function tv(n,e){if(!e.bubbles)return!0;if(e.defaultPrevented)return!1;for(let t=e.target;t!=n.dom;t=t.parentNode)if(!t||t.nodeType==11||t.pmViewDesc&&t.pmViewDesc.stopEvent(e))return!1;return!0}function nv(n,e){!df(n,e)&&Ie[e.type]&&(n.editable||!(e.type in ze))&&Ie[e.type](n,e)}ze.keydown=(n,e)=>{let t=e;if(n.input.shiftKey=t.keyCode==16||t.shiftKey,!Kg(n,t)&&(n.input.lastKeyCode=t.keyCode,n.input.lastKeyCodeTime=Date.now(),!(wt&&Me&&t.keyCode==13)))if(n.domObserver.selectionChanged(n.domSelectionRange())?n.domObserver.flush():t.keyCode!=229&&n.domObserver.forceFlush(),Yr&&t.keyCode==13&&!t.ctrlKey&&!t.altKey&&!t.metaKey){let r=Date.now();n.input.lastIOSEnter=r,n.input.lastIOSEnterFallbackTimeout=setTimeout(()=>{n.input.lastIOSEnter==r&&(n.someProp("handleKeyDown",i=>i(n,Wn(13,"Enter"))),n.input.lastIOSEnter=0)},200)}else n.someProp("handleKeyDown",r=>r(n,t))||Uk(n,t)?t.preventDefault():fn(n,"key")};ze.keyup=(n,e)=>{e.keyCode==16&&(n.input.shiftKey=!1)};ze.keypress=(n,e)=>{let t=e;if(Kg(n,t)||!t.charCode||t.ctrlKey&&!t.altKey||ot&&t.metaKey)return;if(n.someProp("handleKeyPress",i=>i(n,t))){t.preventDefault();return}let r=n.state.selection;if(!(r instanceof $)||!r.$from.sameParent(r.$to)){let i=String.fromCharCode(t.charCode);!/[\r\n]/.test(i)&&!n.someProp("handleTextInput",o=>o(n,r.$from.pos,r.$to.pos,i))&&n.dispatch(n.state.tr.insertText(i).scrollIntoView()),t.preventDefault()}};function Yl(n){return{left:n.clientX,top:n.clientY}}function rv(n,e){let t=e.x-n.clientX,r=e.y-n.clientY;return t*t+r*r<100}function hf(n,e,t,r,i){if(r==-1)return!1;let o=n.state.doc.resolve(r);for(let s=o.depth+1;s>0;s--)if(n.someProp(e,l=>s>o.depth?l(n,t,o.nodeAfter,o.before(s),i,!0):l(n,t,o.node(s),o.before(s),i,!1)))return!0;return!1}function Lr(n,e,t){if(n.focused||n.focus(),n.state.selection.eq(e))return;let r=n.state.tr.setSelection(e);r.setMeta("pointer",!0),n.dispatch(r)}function iv(n,e){if(e==-1)return!1;let t=n.state.doc.resolve(e),r=t.nodeAfter;return r&&r.isAtom&&I.isSelectable(r)?(Lr(n,new I(t)),!0):!1}function ov(n,e){if(e==-1)return!1;let t=n.state.selection,r,i;t instanceof I&&(r=t.node);let o=n.state.doc.resolve(e);for(let s=o.depth+1;s>0;s--){let l=s>o.depth?o.nodeAfter:o.node(s);if(I.isSelectable(l)){r&&t.$from.depth>0&&s>=t.$from.depth&&o.before(t.$from.depth+1)==t.$from.pos?i=o.before(t.$from.depth):i=o.before(s);break}}return i!=null?(Lr(n,I.create(n.state.doc,i)),!0):!1}function sv(n,e,t,r,i){return hf(n,"handleClickOn",e,t,r)||n.someProp("handleClick",o=>o(n,e,r))||(i?ov(n,t):iv(n,t))}function lv(n,e,t,r){return hf(n,"handleDoubleClickOn",e,t,r)||n.someProp("handleDoubleClick",i=>i(n,e,r))}function av(n,e,t,r){return hf(n,"handleTripleClickOn",e,t,r)||n.someProp("handleTripleClick",i=>i(n,e,r))||uv(n,t,r)}function uv(n,e,t){if(t.button!=0)return!1;let r=n.state.doc;if(e==-1)return r.inlineContent?(Lr(n,$.create(r,0,r.content.size)),!0):!1;let i=r.resolve(e);for(let o=i.depth+1;o>0;o--){let s=o>i.depth?i.nodeAfter:i.node(o),l=i.before(o);if(s.inlineContent)Lr(n,$.create(r,l+1,l+1+s.content.size));else if(I.isSelectable(s))Lr(n,I.create(r,l));else continue;return!0}}function pf(n){return yl(n)}const jg=ot?"metaKey":"ctrlKey";Ie.mousedown=(n,e)=>{let t=e;n.input.shiftKey=t.shiftKey;let r=pf(n),i=Date.now(),o="singleClick";i-n.input.lastClick.time<500&&rv(t,n.input.lastClick)&&!t[jg]&&(n.input.lastClick.type=="singleClick"?o="doubleClick":n.input.lastClick.type=="doubleClick"&&(o="tripleClick")),n.input.lastClick={time:i,x:t.clientX,y:t.clientY,type:o};let s=n.posAtCoords(Yl(t));s&&(o=="singleClick"?(n.input.mouseDown&&n.input.mouseDown.done(),n.input.mouseDown=new cv(n,s,t,!!r)):(o=="doubleClick"?lv:av)(n,s.pos,s.inside,t)?t.preventDefault():fn(n,"pointer"))};class cv{constructor(e,t,r,i){this.view=e,this.pos=t,this.event=r,this.flushed=i,this.delayedSelectionSync=!1,this.mightDrag=null,this.startDoc=e.state.doc,this.selectNode=!!r[jg],this.allowDefault=r.shiftKey;let o,s;if(t.inside>-1)o=e.state.doc.nodeAt(t.inside),s=t.inside;else{let c=e.state.doc.resolve(t.pos);o=c.parent,s=c.depth?c.before():0}const l=i?null:r.target,a=l?e.docView.nearestDesc(l,!0):null;this.target=a&&a.dom.nodeType==1?a.dom:null;let{selection:u}=e.state;(r.button==0&&o.type.spec.draggable&&o.type.spec.selectable!==!1||u instanceof I&&u.from<=s&&u.to>s)&&(this.mightDrag={node:o,pos:s,addAttr:!!(this.target&&!this.target.draggable),setUneditable:!!(this.target&&Ct&&!this.target.hasAttribute("contentEditable"))}),this.target&&this.mightDrag&&(this.mightDrag.addAttr||this.mightDrag.setUneditable)&&(this.view.domObserver.stop(),this.mightDrag.addAttr&&(this.target.draggable=!0),this.mightDrag.setUneditable&&setTimeout(()=>{this.view.input.mouseDown==this&&this.target.setAttribute("contentEditable","false")},20),this.view.domObserver.start()),e.root.addEventListener("mouseup",this.up=this.up.bind(this)),e.root.addEventListener("mousemove",this.move=this.move.bind(this)),fn(e,"pointer")}done(){this.view.root.removeEventListener("mouseup",this.up),this.view.root.removeEventListener("mousemove",this.move),this.mightDrag&&this.target&&(this.view.domObserver.stop(),this.mightDrag.addAttr&&this.target.removeAttribute("draggable"),this.mightDrag.setUneditable&&this.target.removeAttribute("contentEditable"),this.view.domObserver.start()),this.delayedSelectionSync&&setTimeout(()=>Kt(this.view)),this.view.input.mouseDown=null}up(e){if(this.done(),!this.view.dom.contains(e.target))return;let t=this.pos;this.view.state.doc!=this.startDoc&&(t=this.view.posAtCoords(Yl(e))),this.updateAllowDefault(e),this.allowDefault||!t?fn(this.view,"pointer"):sv(this.view,t.pos,t.inside,e,this.selectNode)?e.preventDefault():e.button==0&&(this.flushed||be&&this.mightDrag&&!this.mightDrag.node.isAtom||Me&&!this.view.state.selection.visible&&Math.min(Math.abs(t.pos-this.view.state.selection.from),Math.abs(t.pos-this.view.state.selection.to))<=2)?(Lr(this.view,P.near(this.view.state.doc.resolve(t.pos))),e.preventDefault()):fn(this.view,"pointer")}move(e){this.updateAllowDefault(e),fn(this.view,"pointer"),e.buttons==0&&this.done()}updateAllowDefault(e){!this.allowDefault&&(Math.abs(this.event.x-e.clientX)>4||Math.abs(this.event.y-e.clientY)>4)&&(this.allowDefault=!0)}}Ie.touchstart=n=>{n.input.lastTouch=Date.now(),pf(n),fn(n,"pointer")};Ie.touchmove=n=>{n.input.lastTouch=Date.now(),fn(n,"pointer")};Ie.contextmenu=n=>pf(n);function Kg(n,e){return n.composing?!0:be&&Math.abs(e.timeStamp-n.input.compositionEndedAt)<500?(n.input.compositionEndedAt=-2e8,!0):!1}const fv=wt?5e3:-1;ze.compositionstart=ze.compositionupdate=n=>{if(!n.composing){n.domObserver.flush();let{state:e}=n,t=e.selection.$to;if(e.selection instanceof $&&(e.storedMarks||!t.textOffset&&t.parentOffset&&t.nodeBefore.marks.some(r=>r.type.spec.inclusive===!1)))n.markCursor=n.state.storedMarks||t.marks(),yl(n,!0),n.markCursor=null;else if(yl(n,!e.selection.empty),Ct&&e.selection.empty&&t.parentOffset&&!t.textOffset&&t.nodeBefore.marks.length){let r=n.domSelectionRange();for(let i=r.focusNode,o=r.focusOffset;i&&i.nodeType==1&&o!=0;){let s=o<0?i.lastChild:i.childNodes[o-1];if(!s)break;if(s.nodeType==3){let l=n.domSelection();l&&l.collapse(s,s.nodeValue.length);break}else i=s,o=-1}}n.input.composing=!0}qg(n,fv)};ze.compositionend=(n,e)=>{n.composing&&(n.input.composing=!1,n.input.compositionEndedAt=e.timeStamp,n.input.compositionPendingChanges=n.domObserver.pendingRecords().length?n.input.compositionID:0,n.input.compositionNode=null,n.input.compositionPendingChanges&&Promise.resolve().then(()=>n.domObserver.flush()),n.input.compositionID++,qg(n,20))};function qg(n,e){clearTimeout(n.input.composingTimeout),e>-1&&(n.input.composingTimeout=setTimeout(()=>yl(n),e))}function Qg(n){for(n.composing&&(n.input.composing=!1,n.input.compositionEndedAt=hv());n.input.compositionNodes.length>0;)n.input.compositionNodes.pop().markParentsDirty()}function dv(n){let e=n.domSelectionRange();if(!e.focusNode)return null;let t=ik(e.focusNode,e.focusOffset),r=ok(e.focusNode,e.focusOffset);if(t&&r&&t!=r){let i=r.pmViewDesc,o=n.domObserver.lastChangedTextNode;if(t==o||r==o)return o;if(!i||!i.isText(r.nodeValue))return r;if(n.input.compositionNode==r){let s=t.pmViewDesc;if(!(!s||!s.isText(t.nodeValue)))return r}}return t||r}function hv(){let n=document.createEvent("Event");return n.initEvent("event",!0,!0),n.timeStamp}function yl(n,e=!1){if(!(wt&&n.domObserver.flushingSoon>=0)){if(n.domObserver.forceFlush(),Qg(n),e||n.docView&&n.docView.dirty){let t=cf(n);return t&&!t.eq(n.state.selection)?n.dispatch(n.state.tr.setSelection(t)):(n.markCursor||e)&&!n.state.selection.empty?n.dispatch(n.state.tr.deleteSelection()):n.updateState(n.state),!0}return!1}}function pv(n,e){if(!n.dom.parentNode)return;let t=n.dom.parentNode.appendChild(document.createElement("div"));t.appendChild(e),t.style.cssText="position: fixed; left: -10000px; top: 10px";let r=getSelection(),i=document.createRange();i.selectNodeContents(e),n.dom.blur(),r.removeAllRanges(),r.addRange(i),setTimeout(()=>{t.parentNode&&t.parentNode.removeChild(t),n.focus()},50)}const wo=We&&gn<15||Yr&&ck<604;Ie.copy=ze.cut=(n,e)=>{let t=e,r=n.state.selection,i=t.type=="cut";if(r.empty)return;let o=wo?null:t.clipboardData,s=r.content(),{dom:l,text:a}=Bg(n,s);o?(t.preventDefault(),o.clearData(),o.setData("text/html",l.innerHTML),o.setData("text/plain",a)):pv(n,l),i&&n.dispatch(n.state.tr.deleteSelection().scrollIntoView().setMeta("uiEvent","cut"))};function mv(n){return n.openStart==0&&n.openEnd==0&&n.content.childCount==1?n.content.firstChild:null}function gv(n,e){if(!n.dom.parentNode)return;let t=n.input.shiftKey||n.state.selection.$from.parent.type.spec.code,r=n.dom.parentNode.appendChild(document.createElement(t?"textarea":"div"));t||(r.contentEditable="true"),r.style.cssText="position: fixed; left: -10000px; top: 10px",r.focus();let i=n.input.shiftKey&&n.input.lastKeyCode!=45;setTimeout(()=>{n.focus(),r.parentNode&&r.parentNode.removeChild(r),t?ko(n,r.value,null,i,e):ko(n,r.textContent,r.innerHTML,i,e)},50)}function ko(n,e,t,r,i){let o=Vg(n,e,t,r,n.state.selection.$from);if(n.someProp("handlePaste",a=>a(n,i,o||k.empty)))return!0;if(!o)return!1;let s=mv(o),l=s?n.state.tr.replaceSelectionWith(s,r):n.state.tr.replaceSelection(o);return n.dispatch(l.scrollIntoView().setMeta("paste",!0).setMeta("uiEvent","paste")),!0}function Yg(n){let e=n.getData("text/plain")||n.getData("Text");if(e)return e;let t=n.getData("text/uri-list");return t?t.replace(/\r?\n/g," "):""}ze.paste=(n,e)=>{let t=e;if(n.composing&&!wt)return;let r=wo?null:t.clipboardData,i=n.input.shiftKey&&n.input.lastKeyCode!=45;r&&ko(n,Yg(r),r.getData("text/html"),i,t)?t.preventDefault():gv(n,t)};class Gg{constructor(e,t,r){this.slice=e,this.move=t,this.node=r}}const Xg=ot?"altKey":"ctrlKey";Ie.dragstart=(n,e)=>{let t=e,r=n.input.mouseDown;if(r&&r.done(),!t.dataTransfer)return;let i=n.state.selection,o=i.empty?null:n.posAtCoords(Yl(t)),s;if(!(o&&o.pos>=i.from&&o.pos<=(i instanceof I?i.to-1:i.to))){if(r&&r.mightDrag)s=I.create(n.state.doc,r.mightDrag.pos);else if(t.target&&t.target.nodeType==1){let f=n.docView.nearestDesc(t.target,!0);f&&f.node.type.spec.draggable&&f!=n.docView&&(s=I.create(n.state.doc,f.posBefore))}}let l=(s||n.state.selection).content(),{dom:a,text:u,slice:c}=Bg(n,l);(!t.dataTransfer.files.length||!Me||kg>120)&&t.dataTransfer.clearData(),t.dataTransfer.setData(wo?"Text":"text/html",a.innerHTML),t.dataTransfer.effectAllowed="copyMove",wo||t.dataTransfer.setData("text/plain",u),n.dragging=new Gg(c,!t[Xg],s)};Ie.dragend=n=>{let e=n.dragging;window.setTimeout(()=>{n.dragging==e&&(n.dragging=null)},50)};ze.dragover=ze.dragenter=(n,e)=>e.preventDefault();ze.drop=(n,e)=>{let t=e,r=n.dragging;if(n.dragging=null,!t.dataTransfer)return;let i=n.posAtCoords(Yl(t));if(!i)return;let o=n.state.doc.resolve(i.pos),s=r&&r.slice;s?n.someProp("transformPasted",h=>{s=h(s,n)}):s=Vg(n,Yg(t.dataTransfer),wo?null:t.dataTransfer.getData("text/html"),!1,o);let l=!!(r&&!t[Xg]);if(n.someProp("handleDrop",h=>h(n,t,s||k.empty,l))){t.preventDefault();return}if(!s)return;t.preventDefault();let a=s?ek(n.state.doc,o.pos,s):o.pos;a==null&&(a=o.pos);let u=n.state.tr;if(l){let{node:h}=r;h?h.replace(u):u.deleteSelection()}let c=u.mapping.map(a),f=s.openStart==0&&s.openEnd==0&&s.content.childCount==1,d=u.doc;if(f?u.replaceRangeWith(c,c,s.content.firstChild):u.replaceRange(c,c,s),u.doc.eq(d))return;let p=u.doc.resolve(c);if(f&&I.isSelectable(s.content.firstChild)&&p.nodeAfter&&p.nodeAfter.sameMarkup(s.content.firstChild))u.setSelection(new I(p));else{let h=u.mapping.map(a);u.mapping.maps[u.mapping.maps.length-1].forEach((m,w,g,y)=>h=y),u.setSelection(ff(n,p,u.doc.resolve(h)))}n.focus(),n.dispatch(u.setMeta("uiEvent","drop"))};Ie.focus=n=>{n.input.lastFocus=Date.now(),n.focused||(n.domObserver.stop(),n.dom.classList.add("ProseMirror-focused"),n.domObserver.start(),n.focused=!0,setTimeout(()=>{n.docView&&n.hasFocus()&&!n.domObserver.currentSelection.eq(n.domSelectionRange())&&Kt(n)},20))};Ie.blur=(n,e)=>{let t=e;n.focused&&(n.domObserver.stop(),n.dom.classList.remove("ProseMirror-focused"),n.domObserver.start(),t.relatedTarget&&n.dom.contains(t.relatedTarget)&&n.domObserver.currentSelection.clear(),n.focused=!1)};Ie.beforeinput=(n,e)=>{if(Me&&wt&&e.inputType=="deleteContentBackward"){n.domObserver.flushSoon();let{domChangeCount:r}=n.input;setTimeout(()=>{if(n.input.domChangeCount!=r||(n.dom.blur(),n.focus(),n.someProp("handleKeyDown",o=>o(n,Wn(8,"Backspace")))))return;let{$cursor:i}=n.state.selection;i&&i.pos>0&&n.dispatch(n.state.tr.delete(i.pos-1,i.pos).scrollIntoView())},50)}};for(let n in ze)Ie[n]=ze[n];function vo(n,e){if(n==e)return!0;for(let t in n)if(n[t]!==e[t])return!1;for(let t in e)if(!(t in n))return!1;return!0}class Sl{constructor(e,t){this.toDOM=e,this.spec=t||Xn,this.side=this.spec.side||0}map(e,t,r,i){let{pos:o,deleted:s}=e.mapResult(t.from+i,this.side<0?-1:1);return s?null:new ye(o-r,o-r,this)}valid(){return!0}eq(e){return this==e||e instanceof Sl&&(this.spec.key&&this.spec.key==e.spec.key||this.toDOM==e.toDOM&&vo(this.spec,e.spec))}destroy(e){this.spec.destroy&&this.spec.destroy(e)}}class yn{constructor(e,t){this.attrs=e,this.spec=t||Xn}map(e,t,r,i){let o=e.map(t.from+i,this.spec.inclusiveStart?-1:1)-r,s=e.map(t.to+i,this.spec.inclusiveEnd?1:-1)-r;return o>=s?null:new ye(o,s,this)}valid(e,t){return t.from=e&&(!o||o(l.spec))&&r.push(l.copy(l.from+i,l.to+i))}for(let s=0;se){let l=this.children[s]+1;this.children[s+2].findInner(e-l,t-l,r,i+l,o)}}map(e,t,r){return this==Ce||e.maps.length==0?this:this.mapInner(e,t,0,0,r||Xn)}mapInner(e,t,r,i,o){let s;for(let l=0;l{let u=a+r,c;if(c=ty(t,l,u)){for(i||(i=this.children.slice());ol&&f.to=e){this.children[l]==e&&(r=this.children[l+2]);break}let o=e+1,s=o+t.content.size;for(let l=0;lo&&a.type instanceof yn){let u=Math.max(o,a.from)-o,c=Math.min(s,a.to)-o;ui.map(e,t,Xn));return xr.from(r)}forChild(e,t){if(t.isLeaf)return _.empty;let r=[];for(let i=0;it instanceof _)?e:e.reduce((t,r)=>t.concat(r instanceof _?r:r.members),[]))}}forEachSet(e){for(let t=0;t{let w=m-h-(p-d);for(let g=0;gy+c-f)continue;let S=l[g]+c-f;p>=S?l[g+1]=d<=S?-2:-1:d>=c&&w&&(l[g]+=w,l[g+1]+=w)}f+=w}),c=t.maps[u].map(c,-1)}let a=!1;for(let u=0;u=r.content.size){a=!0;continue}let d=t.map(n[u+1]+o,-1),p=d-i,{index:h,offset:m}=r.content.findIndex(f),w=r.maybeChild(h);if(w&&m==f&&m+w.nodeSize==p){let g=l[u+2].mapInner(t,w,c+1,n[u]+o+1,s);g!=Ce?(l[u]=f,l[u+1]=p,l[u+2]=g):(l[u+1]=-2,a=!0)}else a=!0}if(a){let u=Sv(l,n,e,t,i,o,s),c=wl(u,r,0,s);e=c.local;for(let f=0;ft&&s.to{let u=ty(n,l,a+t);if(u){o=!0;let c=wl(u,l,t+a+1,r);c!=Ce&&i.push(a,a+l.nodeSize,c)}});let s=ey(o?ny(n):n,-t).sort(Zn);for(let l=0;l0;)e++;n.splice(e,0,t)}function Fa(n){let e=[];return n.someProp("decorations",t=>{let r=t(n.state);r&&r!=Ce&&e.push(r)}),n.cursorWrapper&&e.push(_.create(n.state.doc,[n.cursorWrapper.deco])),Zg.from(e)}const wv={childList:!0,characterData:!0,characterDataOldValue:!0,attributes:!0,attributeOldValue:!0,subtree:!0},kv=We&&gn<=11;let vv=class{constructor(){this.anchorNode=null,this.anchorOffset=0,this.focusNode=null,this.focusOffset=0}set(e){this.anchorNode=e.anchorNode,this.anchorOffset=e.anchorOffset,this.focusNode=e.focusNode,this.focusOffset=e.focusOffset}clear(){this.anchorNode=this.focusNode=null}eq(e){return e.anchorNode==this.anchorNode&&e.anchorOffset==this.anchorOffset&&e.focusNode==this.focusNode&&e.focusOffset==this.focusOffset}};class xv{constructor(e,t){this.view=e,this.handleDOMChange=t,this.queue=[],this.flushingSoon=-1,this.observer=null,this.currentSelection=new vv,this.onCharData=null,this.suppressingSelectionUpdates=!1,this.lastChangedTextNode=null,this.observer=window.MutationObserver&&new window.MutationObserver(r=>{for(let i=0;ii.type=="childList"&&i.removedNodes.length||i.type=="characterData"&&i.oldValue.length>i.target.nodeValue.length)?this.flushSoon():this.flush()}),kv&&(this.onCharData=r=>{this.queue.push({target:r.target,type:"characterData",oldValue:r.prevValue}),this.flushSoon()}),this.onSelectionChange=this.onSelectionChange.bind(this)}flushSoon(){this.flushingSoon<0&&(this.flushingSoon=window.setTimeout(()=>{this.flushingSoon=-1,this.flush()},20))}forceFlush(){this.flushingSoon>-1&&(window.clearTimeout(this.flushingSoon),this.flushingSoon=-1,this.flush())}start(){this.observer&&(this.observer.takeRecords(),this.observer.observe(this.view.dom,wv)),this.onCharData&&this.view.dom.addEventListener("DOMCharacterDataModified",this.onCharData),this.connectSelection()}stop(){if(this.observer){let e=this.observer.takeRecords();if(e.length){for(let t=0;tthis.flush(),20)}this.observer.disconnect()}this.onCharData&&this.view.dom.removeEventListener("DOMCharacterDataModified",this.onCharData),this.disconnectSelection()}connectSelection(){this.view.dom.ownerDocument.addEventListener("selectionchange",this.onSelectionChange)}disconnectSelection(){this.view.dom.ownerDocument.removeEventListener("selectionchange",this.onSelectionChange)}suppressSelectionUpdates(){this.suppressingSelectionUpdates=!0,setTimeout(()=>this.suppressingSelectionUpdates=!1,50)}onSelectionChange(){if(lh(this.view)){if(this.suppressingSelectionUpdates)return Kt(this.view);if(We&&gn<=11&&!this.view.state.selection.empty){let e=this.view.domSelectionRange();if(e.focusNode&&rr(e.focusNode,e.focusOffset,e.anchorNode,e.anchorOffset))return this.flushSoon()}this.flush()}}setCurSelection(){this.currentSelection.set(this.view.domSelectionRange())}ignoreSelectionChange(e){if(!e.focusNode)return!0;let t=new Set,r;for(let o=e.focusNode;o;o=So(o))t.add(o);for(let o=e.anchorNode;o;o=So(o))if(t.has(o)){r=o;break}let i=r&&this.view.docView.nearestDesc(r);if(i&&i.ignoreMutation({type:"selection",target:r.nodeType==3?r.parentNode:r}))return this.setCurSelection(),!0}pendingRecords(){if(this.observer)for(let e of this.observer.takeRecords())this.queue.push(e);return this.queue}selectionChanged(e){return!this.suppressingSelectionUpdates&&!this.currentSelection.eq(e)&&lh(this.view)&&!this.ignoreSelectionChange(e)}flush(){let{view:e}=this;if(!e.docView||this.flushingSoon>-1)return;let t=this.pendingRecords();t.length&&(this.queue=[]);let r=e.domSelectionRange(),i=this.selectionChanged(r),o=-1,s=-1,l=!1,a=[];if(e.editable)for(let c=0;cf.nodeName=="BR");if(c.length==2){let[f,d]=c;f.parentNode&&f.parentNode.parentNode==d.parentNode?d.remove():f.remove()}else{let{focusNode:f}=this.currentSelection;for(let d of c){let p=d.parentNode;p&&p.nodeName=="LI"&&(!f||Mv(e,f)!=p)&&d.remove()}}}let u=null;o<0&&i&&e.input.lastFocus>Date.now()-200&&Math.max(e.input.lastTouch,e.input.lastClick.time)-1||i)&&(o>-1&&(e.docView.markDirty(o,s),Cv(e)),this.handleDOMChange(o,s,l,a),e.docView&&e.docView.dirty?e.updateState(e.state):this.currentSelection.eq(r)||Kt(e),this.currentSelection.set(r))}registerMutation(e,t){if(t.indexOf(e.target)>-1)return null;let r=this.view.docView.nearestDesc(e.target);if(e.type=="attributes"&&(r==this.view.docView||e.attributeName=="contenteditable"||e.attributeName=="style"&&!e.oldValue&&!e.target.getAttribute("style"))||!r||r.ignoreMutation(e))return null;if(e.type=="childList"){for(let c=0;ci;w--){let g=r.childNodes[w-1],y=g.pmViewDesc;if(g.nodeName=="BR"&&!y){o=w;break}if(!y||y.size)break}let f=n.state.doc,d=n.someProp("domParser")||mo.fromSchema(n.state.schema),p=f.resolve(s),h=null,m=d.parse(r,{topNode:p.parent,topMatch:p.parent.contentMatchAt(p.index()),topOpen:!0,from:i,to:o,preserveWhitespace:p.parent.type.whitespace=="pre"?"full":!0,findPositions:u,ruleFromNode:Ov,context:p});if(u&&u[0].pos!=null){let w=u[0].pos,g=u[1]&&u[1].pos;g==null&&(g=w),h={anchor:w+s,head:g+s}}return{doc:m,sel:h,from:s,to:l}}function Ov(n){let e=n.pmViewDesc;if(e)return e.parseRule();if(n.nodeName=="BR"&&n.parentNode){if(be&&/^(ul|ol)$/i.test(n.parentNode.nodeName)){let t=document.createElement("div");return t.appendChild(document.createElement("li")),{skip:t}}else if(n.parentNode.lastChild==n||be&&/^(tr|table)$/i.test(n.parentNode.nodeName))return{ignore:!0}}else if(n.nodeName=="IMG"&&n.getAttribute("mark-placeholder"))return{ignore:!0};return null}const Dv=/^(a|abbr|acronym|b|bd[io]|big|br|button|cite|code|data(list)?|del|dfn|em|i|ins|kbd|label|map|mark|meter|output|q|ruby|s|samp|small|span|strong|su[bp]|time|u|tt|var)$/i;function Tv(n,e,t,r,i){let o=n.input.compositionPendingChanges||(n.composing?n.input.compositionID:0);if(n.input.compositionPendingChanges=0,e<0){let b=n.input.lastSelectionTime>Date.now()-50?n.input.lastSelectionOrigin:null,z=cf(n,b);if(z&&!n.state.selection.eq(z)){if(Me&&wt&&n.input.lastKeyCode===13&&Date.now()-100W(n,Wn(13,"Enter"))))return;let se=n.state.tr.setSelection(z);b=="pointer"?se.setMeta("pointer",!0):b=="key"&&se.scrollIntoView(),o&&se.setMeta("composition",o),n.dispatch(se)}return}let s=n.state.doc.resolve(e),l=s.sharedDepth(t);e=s.before(l+1),t=n.state.doc.resolve(t).after(l+1);let a=n.state.selection,u=Ev(n,e,t),c=n.state.doc,f=c.slice(u.from,u.to),d,p;n.input.lastKeyCode===8&&Date.now()-100Date.now()-225||wt)&&i.some(b=>b.nodeType==1&&!Dv.test(b.nodeName))&&(!h||h.endA>=h.endB)&&n.someProp("handleKeyDown",b=>b(n,Wn(13,"Enter")))){n.input.lastIOSEnter=0;return}if(!h)if(r&&a instanceof $&&!a.empty&&a.$head.sameParent(a.$anchor)&&!n.composing&&!(u.sel&&u.sel.anchor!=u.sel.head))h={start:a.from,endA:a.to,endB:a.to};else{if(u.sel){let b=wh(n,n.state.doc,u.sel);if(b&&!b.eq(n.state.selection)){let z=n.state.tr.setSelection(b);o&&z.setMeta("composition",o),n.dispatch(z)}}return}n.state.selection.fromn.state.selection.from&&h.start<=n.state.selection.from+2&&n.state.selection.from>=u.from?h.start=n.state.selection.from:h.endA=n.state.selection.to-2&&n.state.selection.to<=u.to&&(h.endB+=n.state.selection.to-h.endA,h.endA=n.state.selection.to)),We&&gn<=11&&h.endB==h.start+1&&h.endA==h.start&&h.start>u.from&&u.doc.textBetween(h.start-u.from-1,h.start-u.from+1)=="  "&&(h.start--,h.endA--,h.endB--);let m=u.doc.resolveNoCache(h.start-u.from),w=u.doc.resolveNoCache(h.endB-u.from),g=c.resolve(h.start),y=m.sameParent(w)&&m.parent.inlineContent&&g.end()>=h.endA,S;if((Yr&&n.input.lastIOSEnter>Date.now()-225&&(!y||i.some(b=>b.nodeName=="DIV"||b.nodeName=="P"))||!y&&m.posb(n,Wn(13,"Enter")))){n.input.lastIOSEnter=0;return}if(n.state.selection.anchor>h.start&&Av(c,h.start,h.endA,m,w)&&n.someProp("handleKeyDown",b=>b(n,Wn(8,"Backspace")))){wt&&Me&&n.domObserver.suppressSelectionUpdates();return}Me&&wt&&h.endB==h.start&&(n.input.lastAndroidDelete=Date.now()),wt&&!y&&m.start()!=w.start()&&w.parentOffset==0&&m.depth==w.depth&&u.sel&&u.sel.anchor==u.sel.head&&u.sel.head==h.endA&&(h.endB-=2,w=u.doc.resolveNoCache(h.endB-u.from),setTimeout(()=>{n.someProp("handleKeyDown",function(b){return b(n,Wn(13,"Enter"))})},20));let x=h.start,M=h.endA,E,O,T;if(y){if(m.pos==w.pos)We&&gn<=11&&m.parentOffset==0&&(n.domObserver.suppressSelectionUpdates(),setTimeout(()=>Kt(n),20)),E=n.state.tr.delete(x,M),O=c.resolve(h.start).marksAcross(c.resolve(h.endA));else if(h.endA==h.endB&&(T=Rv(m.parent.content.cut(m.parentOffset,w.parentOffset),g.parent.content.cut(g.parentOffset,h.endA-g.start()))))E=n.state.tr,T.type=="add"?E.addMark(x,M,T.mark):E.removeMark(x,M,T.mark);else if(m.parent.child(m.index()).isText&&m.index()==w.index()-(w.textOffset?0:1)){let b=m.parent.textBetween(m.parentOffset,w.parentOffset);if(n.someProp("handleTextInput",z=>z(n,x,M,b)))return;E=n.state.tr.insertText(b,x,M)}}if(E||(E=n.state.tr.replace(x,M,u.doc.slice(h.start-u.from,h.endB-u.from))),u.sel){let b=wh(n,E.doc,u.sel);b&&!(Me&&wt&&n.composing&&b.empty&&(h.start!=h.endB||n.input.lastAndroidDeletee.content.size?null:ff(n,e.resolve(t.anchor),e.resolve(t.head))}function Rv(n,e){let t=n.firstChild.marks,r=e.firstChild.marks,i=t,o=r,s,l,a;for(let c=0;cc.mark(l.addToSet(c.marks));else if(i.length==0&&o.length==1)l=o[0],s="remove",a=c=>c.mark(l.removeFromSet(c.marks));else return null;let u=[];for(let c=0;ct||La(s,!0,!1)0&&(e||n.indexAfter(r)==n.node(r).childCount);)r--,i++,e=!1;if(t){let o=n.node(r).maybeChild(n.indexAfter(r));for(;o&&!o.isLeaf;)o=o.firstChild,i++}return i}function bv(n,e,t,r,i){let o=n.findDiffStart(e,t);if(o==null)return null;let{a:s,b:l}=n.findDiffEnd(e,t+n.size,t+e.size);if(i=="end"){let a=Math.max(0,o-Math.min(s,l));r-=s+a-o}if(s=s?o-r:0;o-=a,o&&o=l?o-r:0;o-=a,o&&o=56320&&e<=57343&&t>=55296&&t<=56319}class Iv{constructor(e,t){this._root=null,this.focused=!1,this.trackWrites=null,this.mounted=!1,this.markCursor=null,this.cursorWrapper=null,this.lastSelectedViewDesc=void 0,this.input=new Xk,this.prevDirectPlugins=[],this.pluginViews=[],this.requiresGeckoHackNode=!1,this.dragging=null,this._props=t,this.state=t.state,this.directPlugins=t.plugins||[],this.directPlugins.forEach(Mh),this.dispatch=this.dispatch.bind(this),this.dom=e&&e.mount||document.createElement("div"),e&&(e.appendChild?e.appendChild(this.dom):typeof e=="function"?e(this.dom):e.mount&&(this.mounted=!0)),this.editable=Ch(this),xh(this),this.nodeViews=Nh(this),this.docView=th(this.state.doc,vh(this),Fa(this),this.dom,this),this.domObserver=new xv(this,(r,i,o,s)=>Tv(this,r,i,o,s)),this.domObserver.start(),Zk(this),this.updatePluginViews()}get composing(){return this.input.composing}get props(){if(this._props.state!=this.state){let e=this._props;this._props={};for(let t in e)this._props[t]=e[t];this._props.state=this.state}return this._props}update(e){e.handleDOMEvents!=this._props.handleDOMEvents&&Bu(this);let t=this._props;this._props=e,e.plugins&&(e.plugins.forEach(Mh),this.directPlugins=e.plugins),this.updateStateInner(e.state,t)}setProps(e){let t={};for(let r in this._props)t[r]=this._props[r];t.state=this.state;for(let r in e)t[r]=e[r];this.update(t)}updateState(e){this.updateStateInner(e,this._props)}updateStateInner(e,t){var r;let i=this.state,o=!1,s=!1;e.storedMarks&&this.composing&&(Qg(this),s=!0),this.state=e;let l=i.plugins!=e.plugins||this._props.plugins!=t.plugins;if(l||this._props.plugins!=t.plugins||this._props.nodeViews!=t.nodeViews){let p=Nh(this);Pv(p,this.nodeViews)&&(this.nodeViews=p,o=!0)}(l||t.handleDOMEvents!=this._props.handleDOMEvents)&&Bu(this),this.editable=Ch(this),xh(this);let a=Fa(this),u=vh(this),c=i.plugins!=e.plugins&&!i.doc.eq(e.doc)?"reset":e.scrollToSelection>i.scrollToSelection?"to selection":"preserve",f=o||!this.docView.matchesNode(e.doc,u,a);(f||!e.selection.eq(i.selection))&&(s=!0);let d=c=="preserve"&&s&&this.dom.style.overflowAnchor==null&&hk(this);if(s){this.domObserver.stop();let p=f&&(We||Me)&&!this.composing&&!i.selection.empty&&!e.selection.empty&&zv(i.selection,e.selection);if(f){let h=Me?this.trackWrites=this.domSelectionRange().focusNode:null;this.composing&&(this.input.compositionNode=dv(this)),(o||!this.docView.update(e.doc,u,a,this))&&(this.docView.updateOuterDeco(u),this.docView.destroy(),this.docView=th(e.doc,u,a,this.dom,this)),h&&!this.trackWrites&&(p=!0)}p||!(this.input.mouseDown&&this.domObserver.currentSelection.eq(this.domSelectionRange())&&Lk(this))?Kt(this,p):(Fg(this,e.selection),this.domObserver.setCurSelection()),this.domObserver.start()}this.updatePluginViews(i),!((r=this.dragging)===null||r===void 0)&&r.node&&!i.doc.eq(e.doc)&&this.updateDraggedNode(this.dragging,i),c=="reset"?this.dom.scrollTop=0:c=="to selection"?this.scrollToSelection():d&&pk(d)}scrollToSelection(){let e=this.domSelectionRange().focusNode;if(!this.someProp("handleScrollToSelection",t=>t(this)))if(this.state.selection instanceof I){let t=this.docView.domAfterPos(this.state.selection.from);t.nodeType==1&&Qd(this,t.getBoundingClientRect(),e)}else Qd(this,this.coordsAtPos(this.state.selection.head,1),e)}destroyPluginViews(){let e;for(;e=this.pluginViews.pop();)e.destroy&&e.destroy()}updatePluginViews(e){if(!e||e.plugins!=this.state.plugins||this.directPlugins!=this.prevDirectPlugins){this.prevDirectPlugins=this.directPlugins,this.destroyPluginViews();for(let t=0;t0&&this.state.doc.nodeAt(o))==r.node&&(i=o)}this.dragging=new Gg(e.slice,e.move,i<0?void 0:I.create(this.state.doc,i))}someProp(e,t){let r=this._props&&this._props[e],i;if(r!=null&&(i=t?t(r):r))return i;for(let s=0;st.ownerDocument.getSelection()),this._root=t}return e||document}updateRoot(){this._root=null}posAtCoords(e){return kk(this,e)}coordsAtPos(e,t=1){return Mg(this,e,t)}domAtPos(e,t=0){return this.docView.domFromPos(e,t)}nodeDOM(e){let t=this.docView.descAt(e);return t?t.nodeDOM:null}posAtDOM(e,t,r=-1){let i=this.docView.posFromDOM(e,t,r);if(i==null)throw new RangeError("DOM position not inside the editor");return i}endOfTextblock(e,t){return Mk(this,t||this.state,e)}pasteHTML(e,t){return ko(this,"",e,!1,t||new ClipboardEvent("paste"))}pasteText(e,t){return ko(this,e,null,!0,t||new ClipboardEvent("paste"))}destroy(){this.docView&&(ev(this),this.destroyPluginViews(),this.mounted?(this.docView.update(this.state.doc,[],Fa(this),this),this.dom.textContent=""):this.dom.parentNode&&this.dom.parentNode.removeChild(this.dom),this.docView.destroy(),this.docView=null,nk())}get isDestroyed(){return this.docView==null}dispatchEvent(e){return nv(this,e)}dispatch(e){let t=this._props.dispatchTransaction;t?t.call(this,e):this.updateState(this.state.apply(e))}domSelectionRange(){let e=this.domSelection();return e?be&&this.root.nodeType===11&&lk(this.dom.ownerDocument)==this.dom&&Nv(this,e)||e:{focusNode:null,focusOffset:0,anchorNode:null,anchorOffset:0}}domSelection(){return this.root.getSelection()}}function vh(n){let e=Object.create(null);return e.class="ProseMirror",e.contenteditable=String(n.editable),n.someProp("attributes",t=>{if(typeof t=="function"&&(t=t(n.state)),t)for(let r in t)r=="class"?e.class+=" "+t[r]:r=="style"?e.style=(e.style?e.style+";":"")+t[r]:!e[r]&&r!="contenteditable"&&r!="nodeName"&&(e[r]=String(t[r]))}),e.translate||(e.translate="no"),[ye.node(0,n.state.doc.content.size,e)]}function xh(n){if(n.markCursor){let e=document.createElement("img");e.className="ProseMirror-separator",e.setAttribute("mark-placeholder","true"),e.setAttribute("alt",""),n.cursorWrapper={dom:e,deco:ye.widget(n.state.selection.from,e,{raw:!0,marks:n.markCursor})}}else n.cursorWrapper=null}function Ch(n){return!n.someProp("editable",e=>e(n.state)===!1)}function zv(n,e){let t=Math.min(n.$anchor.sharedDepth(n.head),e.$anchor.sharedDepth(e.head));return n.$anchor.start(t)!=e.$anchor.start(t)}function Nh(n){let e=Object.create(null);function t(r){for(let i in r)Object.prototype.hasOwnProperty.call(e,i)||(e[i]=r[i])}return n.someProp("nodeViews",t),n.someProp("markViews",t),e}function Pv(n,e){let t=0,r=0;for(let i in n){if(n[i]!=e[i])return!0;t++}for(let i in e)r++;return t!=r}function Mh(n){if(n.spec.state||n.spec.filterTransaction||n.spec.appendTransaction)throw new RangeError("Plugins passed directly to the view must not have a state component")}class ee extends P{constructor(e){super(e,e)}map(e,t){let r=e.resolve(t.map(this.head));return ee.valid(r)?new ee(r):P.near(r)}content(){return k.empty}eq(e){return e instanceof ee&&e.head==this.head}toJSON(){return{type:"gapcursor",pos:this.head}}static fromJSON(e,t){if(typeof t.pos!="number")throw new RangeError("Invalid input for GapCursor.fromJSON");return new ee(e.resolve(t.pos))}getBookmark(){return new yf(this.anchor)}static valid(e){let t=e.parent;if(t.isTextblock||!Fv(e)||!Lv(e))return!1;let r=t.type.spec.allowGapCursor;if(r!=null)return r;let i=t.contentMatchAt(e.index()).defaultType;return i&&i.isTextblock}static findGapCursorFrom(e,t,r=!1){e:for(;;){if(!r&&ee.valid(e))return e;let i=e.pos,o=null;for(let s=e.depth;;s--){let l=e.node(s);if(t>0?e.indexAfter(s)0){o=l.child(t>0?e.indexAfter(s):e.index(s)-1);break}else if(s==0)return null;i+=t;let a=e.doc.resolve(i);if(ee.valid(a))return a}for(;;){let s=t>0?o.firstChild:o.lastChild;if(!s){if(o.isAtom&&!o.isText&&!I.isSelectable(o)){e=e.doc.resolve(i+o.nodeSize*t),r=!1;continue e}break}o=s,i+=t;let l=e.doc.resolve(i);if(ee.valid(l))return l}return null}}}ee.prototype.visible=!1;ee.findFrom=ee.findGapCursorFrom;P.jsonID("gapcursor",ee);class yf{constructor(e){this.pos=e}map(e){return new yf(e.map(this.pos))}resolve(e){let t=e.resolve(this.pos);return ee.valid(t)?new ee(t):P.near(t)}}function Fv(n){for(let e=n.depth;e>=0;e--){let t=n.index(e),r=n.node(e);if(t==0){if(r.type.spec.isolating)return!0;continue}for(let i=r.child(t-1);;i=i.lastChild){if(i.childCount==0&&!i.inlineContent||i.isAtom||i.type.spec.isolating)return!0;if(i.inlineContent)return!1}}return!0}function Lv(n){for(let e=n.depth;e>=0;e--){let t=n.indexAfter(e),r=n.node(e);if(t==r.childCount){if(r.type.spec.isolating)return!0;continue}for(let i=r.child(t);;i=i.firstChild){if(i.childCount==0&&!i.inlineContent||i.isAtom||i.type.spec.isolating)return!0;if(i.inlineContent)return!1}}return!0}function $v(){return new $t({props:{decorations:_v,createSelectionBetween(n,e,t){return e.pos==t.pos&&ee.valid(t)?new ee(t):null},handleClick:Vv,handleKeyDown:Bv,handleDOMEvents:{beforeinput:Jv}}})}const Bv=Qw({ArrowLeft:cs("horiz",-1),ArrowRight:cs("horiz",1),ArrowUp:cs("vert",-1),ArrowDown:cs("vert",1)});function cs(n,e){const t=n=="vert"?e>0?"down":"up":e>0?"right":"left";return function(r,i,o){let s=r.selection,l=e>0?s.$to:s.$from,a=s.empty;if(s instanceof $){if(!o.endOfTextblock(t)||l.depth==0)return!1;a=!1,l=r.doc.resolve(e>0?l.after():l.before())}let u=ee.findGapCursorFrom(l,e,a);return u?(i&&i(r.tr.setSelection(new ee(u))),!0):!1}}function Vv(n,e,t){if(!n||!n.editable)return!1;let r=n.state.doc.resolve(e);if(!ee.valid(r))return!1;let i=n.posAtCoords({left:t.clientX,top:t.clientY});return i&&i.inside>-1&&I.isSelectable(n.state.doc.nodeAt(i.inside))?!1:(n.dispatch(n.state.tr.setSelection(new ee(r))),!0)}function Jv(n,e){if(e.inputType!="insertCompositionText"||!(n.state.selection instanceof ee))return!1;let{$from:t}=n.state.selection,r=t.parent.contentMatchAt(t.index()).findWrapping(n.state.schema.nodes.text);if(!r)return!1;let i=v.empty;for(let s=r.length-1;s>=0;s--)i=v.from(r[s].createAndFill(null,i));let o=n.state.tr.replace(t.pos,t.pos,new k(i,0,0));return o.setSelection($.near(o.doc.resolve(t.pos+1))),n.dispatch(o),!1}function _v(n){if(!(n.selection instanceof ee))return null;let e=document.createElement("div");return e.className="ProseMirror-gapcursor",_.create(n.doc,[ye.widget(n.selection.head,e,{key:"gapcursor"})])}const ry=65535,iy=Math.pow(2,16);function Wv(n,e){return n+e*iy}function Eh(n){return n&ry}function Uv(n){return(n-(n&ry))/iy}const oy=1,sy=2,js=4,ly=8;let Oh=class{constructor(e,t,r){this.pos=e,this.delInfo=t,this.recover=r}get deleted(){return(this.delInfo&ly)>0}get deletedBefore(){return(this.delInfo&(oy|js))>0}get deletedAfter(){return(this.delInfo&(sy|js))>0}get deletedAcross(){return(this.delInfo&js)>0}},Gr=class Cr{constructor(e,t=!1){if(this.ranges=e,this.inverted=t,!e.length&&Cr.empty)return Cr.empty}recover(e){let t=0,r=Eh(e);if(!this.inverted)for(let i=0;ie)break;let u=this.ranges[l+o],c=this.ranges[l+s],f=a+u;if(e<=f){let d=u?e==a?-1:e==f?1:t:t,p=a+i+(d<0?0:c);if(r)return p;let h=e==(t<0?a:f)?null:Wv(l/3,e-a),m=e==a?sy:e==f?oy:js;return(t<0?e!=a:e!=f)&&(m|=ly),new Oh(p,m,h)}i+=c-u}return r?e+i:new Oh(e+i,0,null)}touches(e,t){let r=0,i=Eh(t),o=this.inverted?2:1,s=this.inverted?1:2;for(let l=0;le)break;let u=this.ranges[l+o],c=a+u;if(e<=c&&l==i*3)return!0;r+=this.ranges[l+s]-u}return!1}forEach(e){let t=this.inverted?2:1,r=this.inverted?1:2;for(let i=0,o=0;i!s.isAtom||!l.type.allowsMarkType(this.mark.type)?s:s.mark(this.mark.addToSet(s.marks)),i),t.openStart,t.openEnd);return Je.fromReplace(e,this.from,this.to,o)}invert(){return new uy(this.from,this.to,this.mark)}map(e){let t=e.mapResult(this.from,1),r=e.mapResult(this.to,-1);return t.deleted&&r.deleted||t.pos>=r.pos?null:new _i(t.pos,r.pos,this.mark)}merge(e){return e instanceof _i&&e.mark.eq(this.mark)&&this.from<=e.to&&this.to>=e.from?new _i(Math.min(this.from,e.from),Math.max(this.to,e.to),this.mark):null}toJSON(){return{stepType:"addMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(e,t){if(typeof t.from!="number"||typeof t.to!="number")throw new RangeError("Invalid input for AddMarkStep.fromJSON");return new _i(t.from,t.to,e.markFromJSON(t.mark))}};Ye.jsonID("addMark",ay);let uy=class Wi extends Ye{constructor(e,t,r){super(),this.from=e,this.to=t,this.mark=r}apply(e){let t=e.slice(this.from,this.to),r=new k(Sf(t.content,i=>i.mark(this.mark.removeFromSet(i.marks)),e),t.openStart,t.openEnd);return Je.fromReplace(e,this.from,this.to,r)}invert(){return new ay(this.from,this.to,this.mark)}map(e){let t=e.mapResult(this.from,1),r=e.mapResult(this.to,-1);return t.deleted&&r.deleted||t.pos>=r.pos?null:new Wi(t.pos,r.pos,this.mark)}merge(e){return e instanceof Wi&&e.mark.eq(this.mark)&&this.from<=e.to&&this.to>=e.from?new Wi(Math.min(this.from,e.from),Math.max(this.to,e.to),this.mark):null}toJSON(){return{stepType:"removeMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(e,t){if(typeof t.from!="number"||typeof t.to!="number")throw new RangeError("Invalid input for RemoveMarkStep.fromJSON");return new Wi(t.from,t.to,e.markFromJSON(t.mark))}};Ye.jsonID("removeMark",uy);let cy=class Ui extends Ye{constructor(e,t){super(),this.pos=e,this.mark=t}apply(e){let t=e.nodeAt(this.pos);if(!t)return Je.fail("No node at mark step's position");let r=t.type.create(t.attrs,null,this.mark.addToSet(t.marks));return Je.fromReplace(e,this.pos,this.pos+1,new k(v.from(r),0,t.isLeaf?0:1))}invert(e){let t=e.nodeAt(this.pos);if(t){let r=this.mark.addToSet(t.marks);if(r.length==t.marks.length){for(let i=0;ir.pos?null:new Ks(t.pos,r.pos,i,o,this.slice,this.insert,this.structure)}toJSON(){let e={stepType:"replaceAround",from:this.from,to:this.to,gapFrom:this.gapFrom,gapTo:this.gapTo,insert:this.insert};return this.slice.size&&(e.slice=this.slice.toJSON()),this.structure&&(e.structure=!0),e}static fromJSON(e,t){if(typeof t.from!="number"||typeof t.to!="number"||typeof t.gapFrom!="number"||typeof t.gapTo!="number"||typeof t.insert!="number")throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON");return new Ks(t.from,t.to,t.gapFrom,t.gapTo,k.fromJSON(e,t.slice),t.insert,!!t.structure)}};Ye.jsonID("replaceAround",jv);function Ju(n,e,t){let r=n.resolve(e),i=t-e,o=r.depth;for(;i>0&&o>0&&r.indexAfter(o)==r.node(o).childCount;)o--,i--;if(i>0){let s=r.node(o).maybeChild(r.indexAfter(o));for(;i>0;){if(!s||s.isLeaf)return!0;s=s.firstChild,i--}}return!1}function Kv(n,e,t=null,r=n){let i=qv(n,e),o=i&&Qv(r,e);return o?i.map(Dh).concat({type:e,attrs:t}).concat(o.map(Dh)):null}function Dh(n){return{type:n,attrs:null}}function qv(n,e){let{parent:t,startIndex:r,endIndex:i}=n,o=t.contentMatchAt(r).findWrapping(e);if(!o)return null;let s=o.length?o[0]:e;return t.canReplaceWith(r,i,s)?o:null}function Qv(n,e){let{parent:t,startIndex:r,endIndex:i}=n,o=t.child(r),s=e.contentMatch.findWrapping(o.type);if(!s)return null;let a=(s.length?s[s.length-1]:e).contentMatch;for(let u=r;a&&u0&&(o=t[0].slice(s-l,s)+o,r=i)}return e.tr.insertText(o,r,i)}}const ex=500;function tx({rules:n}){let e=new $t({state:{init(){return null},apply(t,r){let i=t.getMeta(this);return i||(t.selectionSet||t.docChanged?null:r)}},props:{handleTextInput(t,r,i,o){return Th(t,r,i,o,n,e)},handleDOMEvents:{compositionend:t=>{setTimeout(()=>{let{$cursor:r}=t.state.selection;r&&Th(t,r.pos,r.pos,"",n,e)})}}},isInputRules:!0});return e}function Th(n,e,t,r,i,o){if(n.composing)return!1;let s=n.state,l=s.doc.resolve(e),a=l.parent.textBetween(Math.max(0,l.parentOffset-ex),l.parentOffset,null,"")+r;for(let u=0;u{let a=t instanceof Function?t(o):t,u=i.tr.delete(s,l),c=u.doc.resolve(s),f=c.blockRange(),d=f&&Kv(f,e,a);if(!d)return null;u.wrap(f,d);let p=u.doc.resolve(s-1).nodeBefore;return p&&p.type==e&&Yv(u.doc,s-1)&&!r&&u.join(s-1),u})}const rx=typeof navigator<"u"?/Mac|iP(hone|[oa]d)/.test(navigator.platform):!1;function ix(n){let e=n.split(/-(?!$)/),t=e[e.length-1];t=="Space"&&(t=" ");let r,i,o,s;for(let l=0;l127)&&(o=It[r.keyCode])&&o!=i){let l=e[Ba(o,r)];if(l&&l(t.state,t.dispatch,t))return!0}}return!1}}const ax=typeof navigator<"u"?/Mac|iP(hone|[oa]d)/.test(navigator.platform):!1;function ux(n){let e=n.split(/-(?!$)/),t=e[e.length-1];t=="Space"&&(t=" ");let r,i,o,s;for(let l=0;l127)&&(o=It[r.keyCode])&&o!=i){let l=e[Va(o,r)];if(l&&l(t.state,t.dispatch,t))return!0}}return!1}}const dy=65535,hy=Math.pow(2,16);function dx(n,e){return n+e*hy}function Rh(n){return n&dy}function hx(n){return(n-(n&dy))/hy}const py=1,my=2,Qs=4,gy=8;class _u{constructor(e,t,r){this.pos=e,this.delInfo=t,this.recover=r}get deleted(){return(this.delInfo&gy)>0}get deletedBefore(){return(this.delInfo&(py|Qs))>0}get deletedAfter(){return(this.delInfo&(my|Qs))>0}get deletedAcross(){return(this.delInfo&Qs)>0}}class Xe{constructor(e,t=!1){if(this.ranges=e,this.inverted=t,!e.length&&Xe.empty)return Xe.empty}recover(e){let t=0,r=Rh(e);if(!this.inverted)for(let i=0;ie)break;let u=this.ranges[l+o],c=this.ranges[l+s],f=a+u;if(e<=f){let d=u?e==a?-1:e==f?1:t:t,p=a+i+(d<0?0:c);if(r)return p;let h=e==(t<0?a:f)?null:dx(l/3,e-a),m=e==a?my:e==f?py:Qs;return(t<0?e!=a:e!=f)&&(m|=gy),new _u(p,m,h)}i+=c-u}return r?e+i:new _u(e+i,0,null)}touches(e,t){let r=0,i=Rh(t),o=this.inverted?2:1,s=this.inverted?1:2;for(let l=0;le)break;let u=this.ranges[l+o],c=a+u;if(e<=c&&l==i*3)return!0;r+=this.ranges[l+s]-u}return!1}forEach(e){let t=this.inverted?2:1,r=this.inverted?1:2;for(let i=0,o=0;i=0;t--){let i=e.getMirror(t);this.appendMap(e.maps[t].invert(),i!=null&&i>t?r-i-1:void 0)}}invert(){let e=new to;return e.appendMappingInverted(this),e}map(e,t=1){if(this.mirror)return this._map(e,t,!0);for(let r=this.from;ro&&a!s.isAtom||!l.type.allowsMarkType(this.mark.type)?s:s.mark(this.mark.addToSet(s.marks)),i),t.openStart,t.openEnd);return oe.fromReplace(e,this.from,this.to,o)}invert(){return new Dt(this.from,this.to,this.mark)}map(e){let t=e.mapResult(this.from,1),r=e.mapResult(this.to,-1);return t.deleted&&r.deleted||t.pos>=r.pos?null:new dn(t.pos,r.pos,this.mark)}merge(e){return e instanceof dn&&e.mark.eq(this.mark)&&this.from<=e.to&&this.to>=e.from?new dn(Math.min(this.from,e.from),Math.max(this.to,e.to),this.mark):null}toJSON(){return{stepType:"addMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(e,t){if(typeof t.from!="number"||typeof t.to!="number")throw new RangeError("Invalid input for AddMarkStep.fromJSON");return new dn(t.from,t.to,e.markFromJSON(t.mark))}}De.jsonID("addMark",dn);class Dt extends De{constructor(e,t,r){super(),this.from=e,this.to=t,this.mark=r}apply(e){let t=e.slice(this.from,this.to),r=new k(wf(t.content,i=>i.mark(this.mark.removeFromSet(i.marks)),e),t.openStart,t.openEnd);return oe.fromReplace(e,this.from,this.to,r)}invert(){return new dn(this.from,this.to,this.mark)}map(e){let t=e.mapResult(this.from,1),r=e.mapResult(this.to,-1);return t.deleted&&r.deleted||t.pos>=r.pos?null:new Dt(t.pos,r.pos,this.mark)}merge(e){return e instanceof Dt&&e.mark.eq(this.mark)&&this.from<=e.to&&this.to>=e.from?new Dt(Math.min(this.from,e.from),Math.max(this.to,e.to),this.mark):null}toJSON(){return{stepType:"removeMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(e,t){if(typeof t.from!="number"||typeof t.to!="number")throw new RangeError("Invalid input for RemoveMarkStep.fromJSON");return new Dt(t.from,t.to,e.markFromJSON(t.mark))}}De.jsonID("removeMark",Dt);class hn extends De{constructor(e,t){super(),this.pos=e,this.mark=t}apply(e){let t=e.nodeAt(this.pos);if(!t)return oe.fail("No node at mark step's position");let r=t.type.create(t.attrs,null,this.mark.addToSet(t.marks));return oe.fromReplace(e,this.pos,this.pos+1,new k(v.from(r),0,t.isLeaf?0:1))}invert(e){let t=e.nodeAt(this.pos);if(t){let r=this.mark.addToSet(t.marks);if(r.length==t.marks.length){for(let i=0;ir.pos?null:new Rt(t.pos,r.pos,i,o,this.slice,this.insert,this.structure)}toJSON(){let e={stepType:"replaceAround",from:this.from,to:this.to,gapFrom:this.gapFrom,gapTo:this.gapTo,insert:this.insert};return this.slice.size&&(e.slice=this.slice.toJSON()),this.structure&&(e.structure=!0),e}static fromJSON(e,t){if(typeof t.from!="number"||typeof t.to!="number"||typeof t.gapFrom!="number"||typeof t.gapTo!="number"||typeof t.insert!="number")throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON");return new Rt(t.from,t.to,t.gapFrom,t.gapTo,k.fromJSON(e,t.slice),t.insert,!!t.structure)}}De.jsonID("replaceAround",Rt);function Wu(n,e,t){let r=n.resolve(e),i=t-e,o=r.depth;for(;i>0&&o>0&&r.indexAfter(o)==r.node(o).childCount;)o--,i--;if(i>0){let s=r.node(o).maybeChild(r.indexAfter(o));for(;i>0;){if(!s||s.isLeaf)return!0;s=s.firstChild,i--}}return!1}function px(n,e,t,r){let i=[],o=[],s,l;n.doc.nodesBetween(e,t,(a,u,c)=>{if(!a.isInline)return;let f=a.marks;if(!r.isInSet(f)&&c.type.allowsMarkType(r.type)){let d=Math.max(u,e),p=Math.min(u+a.nodeSize,t),h=r.addToSet(f);for(let m=0;mn.step(a)),o.forEach(a=>n.step(a))}function mx(n,e,t,r){let i=[],o=0;n.doc.nodesBetween(e,t,(s,l)=>{if(!s.isInline)return;o++;let a=null;if(r instanceof Ho){let u=s.marks,c;for(;c=r.isInSet(u);)(a||(a=[])).push(c),u=c.removeFromSet(u)}else r?r.isInSet(s.marks)&&(a=[r]):a=s.marks;if(a&&a.length){let u=Math.min(l+s.nodeSize,t);for(let c=0;cn.step(new Dt(s.from,s.to,s.style)))}function gx(n,e,t,r=t.contentMatch){let i=n.doc.nodeAt(e),o=[],s=e+1;for(let l=0;l=0;l--)n.step(o[l])}function yx(n,e,t){let{$from:r,$to:i,depth:o}=e,s=r.before(o+1),l=i.after(o+1),a=s,u=l,c=v.empty,f=0;for(let h=o,m=!1;h>t;h--)m||r.index(h)>0?(m=!0,c=v.from(r.node(h).copy(c)),f++):a--;let d=v.empty,p=0;for(let h=o,m=!1;h>t;h--)m||i.after(h+1)=0;s--){if(r.size){let l=t[s].type.contentMatch.matchFragment(r);if(!l||!l.validEnd)throw new RangeError("Wrapper type given to Transform.wrap does not form valid content of its parent wrapper")}r=v.from(t[s].type.create(t[s].attrs,r))}let i=e.start,o=e.end;n.step(new Rt(i,o,i,o,new k(r,0,0),t.length,!0))}function wx(n,e,t,r,i){if(!r.isTextblock)throw new RangeError("Type given to setBlockType should be a textblock");let o=n.steps.length;n.doc.nodesBetween(e,t,(s,l)=>{if(s.isTextblock&&!s.hasMarkup(r,i)&&kx(n.doc,n.mapping.slice(o).map(l),r)){n.clearIncompatible(n.mapping.slice(o).map(l,1),r);let a=n.mapping.slice(o),u=a.map(l,1),c=a.map(l+s.nodeSize,1);return n.step(new Rt(u,c,u+1,c-1,new k(v.from(r.create(i,null,s.marks)),0,0),1,!0)),!1}})}function kx(n,e,t){let r=n.resolve(e),i=r.index();return r.parent.canReplaceWith(i,i+1,t)}function vx(n,e,t,r,i){let o=n.doc.nodeAt(e);if(!o)throw new RangeError("No node at given position");t||(t=o.type);let s=t.create(r,null,i||o.marks);if(o.isLeaf)return n.replaceWith(e,e+o.nodeSize,s);if(!t.validContent(o.content))throw new RangeError("Invalid content for node type "+t.name);n.step(new Rt(e,e+o.nodeSize,e+1,e+o.nodeSize-1,new k(v.from(s),0,0),1,!0))}function xx(n,e,t=1,r){let i=n.doc.resolve(e),o=v.empty,s=v.empty;for(let l=i.depth,a=i.depth-t,u=t-1;l>a;l--,u--){o=v.from(i.node(l).copy(o));let c=r&&r[u];s=v.from(c?c.type.create(c.attrs,s):i.node(l).copy(s))}n.step(new Re(e,e,new k(o.append(s),t,t),!0))}function Cx(n,e,t){let r=new Re(e-t,e+t,k.empty,!0);n.step(r)}function Nx(n,e,t){let r=n.resolve(e);if(r.parent.canReplaceWith(r.index(),r.index(),t))return e;if(r.parentOffset==0)for(let i=r.depth-1;i>=0;i--){let o=r.index(i);if(r.node(i).canReplaceWith(o,o,t))return r.before(i+1);if(o>0)return null}if(r.parentOffset==r.parent.content.size)for(let i=r.depth-1;i>=0;i--){let o=r.indexAfter(i);if(r.node(i).canReplaceWith(o,o,t))return r.after(i+1);if(o0;i--)this.placed=v.from(e.node(i).copy(this.placed))}get depth(){return this.frontier.length-1}fit(){for(;this.unplaced.size;){let u=this.findFittable();u?this.placeNodes(u):this.openMore()||this.dropNode()}let e=this.mustMoveInline(),t=this.placed.size-this.depth-this.$from.depth,r=this.$from,i=this.close(e<0?this.$to:r.doc.resolve(e));if(!i)return null;let o=this.placed,s=r.depth,l=i.depth;for(;s&&l&&o.childCount==1;)o=o.firstChild.content,s--,l--;let a=new k(o,s,l);return e>-1?new Rt(r.pos,e,this.$to.pos,this.$to.end(),a,t):a.size||r.pos!=this.$to.pos?new Re(r.pos,i.pos,a):null}findFittable(){let e=this.unplaced.openStart;for(let t=this.unplaced.content,r=0,i=this.unplaced.openEnd;r1&&(i=0),o.type.spec.isolating&&i<=r){e=r;break}t=o.content}for(let t=1;t<=2;t++)for(let r=t==1?e:this.unplaced.openStart;r>=0;r--){let i,o=null;r?(o=_a(this.unplaced.content,r-1).firstChild,i=o.content):i=this.unplaced.content;let s=i.firstChild;for(let l=this.depth;l>=0;l--){let{type:a,match:u}=this.frontier[l],c,f=null;if(t==1&&(s?u.matchType(s.type)||(f=u.fillBefore(v.from(s),!1)):o&&a.compatibleContent(o.type)))return{sliceDepth:r,frontierDepth:l,parent:o,inject:f};if(t==2&&s&&(c=u.findWrapping(s.type)))return{sliceDepth:r,frontierDepth:l,parent:o,wrap:c};if(o&&u.matchType(o.type))break}}}openMore(){let{content:e,openStart:t,openEnd:r}=this.unplaced,i=_a(e,t);return!i.childCount||i.firstChild.isLeaf?!1:(this.unplaced=new k(e,t+1,Math.max(r,i.size+t>=e.size-r?t+1:0)),!0)}dropNode(){let{content:e,openStart:t,openEnd:r}=this.unplaced,i=_a(e,t);if(i.childCount<=1&&t>0){let o=e.size-t<=t+i.size;this.unplaced=new k(Hi(e,t-1,1),t-1,o?t-1:r)}else this.unplaced=new k(Hi(e,t,1),t,r)}placeNodes({sliceDepth:e,frontierDepth:t,parent:r,inject:i,wrap:o}){for(;this.depth>t;)this.closeFrontierNode();if(o)for(let m=0;m1||a==0||m.content.size)&&(f=w,c.push(Sy(m.mark(d.allowedMarks(m.marks)),u==1?a:0,u==l.childCount?p:-1)))}let h=u==l.childCount;h||(p=-1),this.placed=ji(this.placed,t,v.from(c)),this.frontier[t].match=f,h&&p<0&&r&&r.type==this.frontier[this.depth].type&&this.frontier.length>1&&this.closeFrontierNode();for(let m=0,w=l;m1&&i==this.$to.end(--r);)++i;return i}findCloseLevel(e){e:for(let t=Math.min(this.depth,e.depth);t>=0;t--){let{match:r,type:i}=this.frontier[t],o=t=0;l--){let{match:a,type:u}=this.frontier[l],c=Wa(e,l,u,a,!0);if(!c||c.childCount)continue e}return{depth:t,fit:s,move:o?e.doc.resolve(e.after(t+1)):e}}}}close(e){let t=this.findCloseLevel(e);if(!t)return null;for(;this.depth>t.depth;)this.closeFrontierNode();t.fit.childCount&&(this.placed=ji(this.placed,t.depth,t.fit)),e=t.move;for(let r=t.depth+1;r<=e.depth;r++){let i=e.node(r),o=i.type.contentMatch.fillBefore(i.content,!0,e.index(r));this.openFrontierNode(i.type,i.attrs,o)}return e}openFrontierNode(e,t=null,r){let i=this.frontier[this.depth];i.match=i.match.matchType(e),this.placed=ji(this.placed,this.depth,v.from(e.create(t,r))),this.frontier.push({type:e,match:e.contentMatch})}closeFrontierNode(){let t=this.frontier.pop().match.fillBefore(v.empty,!0);t.childCount&&(this.placed=ji(this.placed,this.frontier.length,t))}}function Hi(n,e,t){return e==0?n.cutByIndex(t,n.childCount):n.replaceChild(0,n.firstChild.copy(Hi(n.firstChild.content,e-1,t)))}function ji(n,e,t){return e==0?n.append(t):n.replaceChild(n.childCount-1,n.lastChild.copy(ji(n.lastChild.content,e-1,t)))}function _a(n,e){for(let t=0;t1&&(r=r.replaceChild(0,Sy(r.firstChild,e-1,r.childCount==1?t-1:0))),e>0&&(r=n.type.contentMatch.fillBefore(r).append(r),t<=0&&(r=r.append(n.type.contentMatch.matchFragment(r).fillBefore(v.empty,!0)))),n.copy(r)}function Wa(n,e,t,r,i){let o=n.node(e),s=i?n.indexAfter(e):n.index(e);if(s==o.childCount&&!t.compatibleContent(o.type))return null;let l=r.fillBefore(o.content,!0,s);return l&&!Ox(t,o.content,s)?l:null}function Ox(n,e,t){for(let r=t;r0;d--,p--){let h=i.node(d).type.spec;if(h.defining||h.definingAsContext||h.isolating)break;s.indexOf(d)>-1?l=d:i.before(d)==p&&s.splice(1,0,-d)}let a=s.indexOf(l),u=[],c=r.openStart;for(let d=r.content,p=0;;p++){let h=d.firstChild;if(u.push(h),p==r.openStart)break;d=h.content}for(let d=c-1;d>=0;d--){let p=u[d],h=Dx(p.type);if(h&&!p.sameMarkup(i.node(Math.abs(l)-1)))c=d;else if(h||!p.type.isTextblock)break}for(let d=r.openStart;d>=0;d--){let p=(d+c+1)%(r.openStart+1),h=u[p];if(h)for(let m=0;m=0&&(n.replace(e,t,r),!(n.steps.length>f));d--){let p=s[d];p<0||(e=i.before(p),t=o.after(p))}}function wy(n,e,t,r,i){if(er){let o=i.contentMatchAt(0),s=o.fillBefore(n).append(n);n=s.append(o.matchFragment(s).fillBefore(v.empty,!0))}return n}function Rx(n,e,t,r){if(!r.isInline&&e==t&&n.doc.resolve(e).parent.content.size){let i=Nx(n.doc,e,r.type);i!=null&&(e=t=i)}n.replaceRange(e,t,new k(v.from(r),0,0))}function Ax(n,e,t){let r=n.doc.resolve(e),i=n.doc.resolve(t),o=ky(r,i);for(let s=0;s0&&(a||r.node(l-1).canReplace(r.index(l-1),i.indexAfter(l-1))))return n.delete(r.before(l),i.after(l))}for(let s=1;s<=r.depth&&s<=i.depth;s++)if(e-r.start(s)==r.depth-s&&t>r.end(s)&&i.end(s)-t!=i.depth-s)return n.delete(r.before(s),t);n.delete(e,t)}function ky(n,e){let t=[],r=Math.min(n.depth,e.depth);for(let i=r;i>=0;i--){let o=n.start(i);if(oe.pos+(e.depth-i)||n.node(i).type.spec.isolating||e.node(i).type.spec.isolating)break;(o==e.start(i)||i==n.depth&&i==e.depth&&n.parent.inlineContent&&e.parent.inlineContent&&i&&e.start(i-1)==o-1)&&t.push(i)}return t}class $r extends De{constructor(e,t,r){super(),this.pos=e,this.attr=t,this.value=r}apply(e){let t=e.nodeAt(this.pos);if(!t)return oe.fail("No node at attribute step's position");let r=Object.create(null);for(let o in t.attrs)r[o]=t.attrs[o];r[this.attr]=this.value;let i=t.type.create(r,null,t.marks);return oe.fromReplace(e,this.pos,this.pos+1,new k(v.from(i),0,t.isLeaf?0:1))}getMap(){return Xe.empty}invert(e){return new $r(this.pos,this.attr,e.nodeAt(this.pos).attrs[this.attr])}map(e){let t=e.mapResult(this.pos,1);return t.deletedAfter?null:new $r(t.pos,this.attr,this.value)}toJSON(){return{stepType:"attr",pos:this.pos,attr:this.attr,value:this.value}}static fromJSON(e,t){if(typeof t.pos!="number"||typeof t.attr!="string")throw new RangeError("Invalid input for AttrStep.fromJSON");return new $r(t.pos,t.attr,t.value)}}De.jsonID("attr",$r);class Co extends De{constructor(e,t){super(),this.attr=e,this.value=t}apply(e){let t=Object.create(null);for(let i in e.attrs)t[i]=e.attrs[i];t[this.attr]=this.value;let r=e.type.create(t,e.content,e.marks);return oe.ok(r)}getMap(){return Xe.empty}invert(e){return new Co(this.attr,e.attrs[this.attr])}map(e){return this}toJSON(){return{stepType:"docAttr",attr:this.attr,value:this.value}}static fromJSON(e,t){if(typeof t.attr!="string")throw new RangeError("Invalid input for DocAttrStep.fromJSON");return new Co(t.attr,t.value)}}De.jsonID("docAttr",Co);let Zr=class extends Error{};Zr=function n(e){let t=Error.call(this,e);return t.__proto__=n.prototype,t};Zr.prototype=Object.create(Error.prototype);Zr.prototype.constructor=Zr;Zr.prototype.name="TransformError";class bx{constructor(e){this.doc=e,this.steps=[],this.docs=[],this.mapping=new to}get before(){return this.docs.length?this.docs[0]:this.doc}step(e){let t=this.maybeStep(e);if(t.failed)throw new Zr(t.failed);return this}maybeStep(e){let t=e.apply(this.doc);return t.failed||this.addStep(e,t.doc),t}get docChanged(){return this.steps.length>0}addStep(e,t){this.docs.push(this.doc),this.steps.push(e),this.mapping.appendMap(e.getMap()),this.doc=t}replace(e,t=e,r=k.empty){let i=Mx(this.doc,e,t,r);return i&&this.step(i),this}replaceWith(e,t,r){return this.replace(e,t,new k(v.from(r),0,0))}delete(e,t){return this.replace(e,t,k.empty)}insert(e,t){return this.replaceWith(e,e,t)}replaceRange(e,t,r){return Tx(this,e,t,r),this}replaceRangeWith(e,t,r){return Rx(this,e,t,r),this}deleteRange(e,t){return Ax(this,e,t),this}lift(e,t){return yx(this,e,t),this}join(e,t=1){return Cx(this,e,t),this}wrap(e,t){return Sx(this,e,t),this}setBlockType(e,t=e,r,i=null){return wx(this,e,t,r,i),this}setNodeMarkup(e,t,r=null,i){return vx(this,e,t,r,i),this}setNodeAttribute(e,t,r){return this.step(new $r(e,t,r)),this}setDocAttribute(e,t){return this.step(new Co(e,t)),this}addNodeMark(e,t){return this.step(new hn(e,t)),this}removeNodeMark(e,t){if(!(t instanceof U)){let r=this.doc.nodeAt(e);if(!r)throw new RangeError("No node at position "+e);if(t=t.isInSet(r.marks),!t)return this}return this.step(new Xr(e,t)),this}split(e,t=1,r){return xx(this,e,t,r),this}addMark(e,t,r){return px(this,e,t,r),this}removeMark(e,t,r){return mx(this,e,t,r),this}clearIncompatible(e,t,r){return gx(this,e,t,r),this}}var Uu,Hu;if(typeof WeakMap<"u"){let n=new WeakMap;Uu=e=>n.get(e),Hu=(e,t)=>(n.set(e,t),t)}else{const n=[];let t=0;Uu=r=>{for(let i=0;i(t==10&&(t=0),n[t++]=r,n[t++]=i)}var re=class{constructor(n,e,t,r){this.width=n,this.height=e,this.map=t,this.problems=r}findCell(n){for(let e=0;e=t){(o||(o=[])).push({type:"overlong_rowspan",pos:c,n:g-S});break}const x=i+S*e;for(let M=0;Mr&&(o+=u.attrs.colspan)}}for(let s=0;s1&&(t=!0)}e==-1?e=o:e!=o&&(e=Math.max(e,o))}return e}function Px(n,e,t){n.problems||(n.problems=[]);const r={};for(let i=0;iNumber(s)):null,i=Number(n.getAttribute("colspan")||1),o={colspan:i,rowspan:Number(n.getAttribute("rowspan")||1),colwidth:r&&r.length==i?r:null};for(const s in e){const l=e[s].getFromDOM,a=l&&l(n);a!=null&&(o[s]=a)}return o}function bh(n,e){const t={};n.attrs.colspan!=1&&(t.colspan=n.attrs.colspan),n.attrs.rowspan!=1&&(t.rowspan=n.attrs.rowspan),n.attrs.colwidth&&(t["data-colwidth"]=n.attrs.colwidth.join(","));for(const r in e){const i=e[r].setDOMAttr;i&&i(n.attrs[r],t)}return t}function Lx(n){const e=n.cellAttributes||{},t={colspan:{default:1},rowspan:{default:1},colwidth:{default:null}};for(const r in e)t[r]={default:e[r].default};return{table:{content:"table_row+",tableRole:"table",isolating:!0,group:n.tableGroup,parseDOM:[{tag:"table"}],toDOM(){return["table",["tbody",0]]}},table_row:{content:"(table_cell | table_header)*",tableRole:"row",parseDOM:[{tag:"tr"}],toDOM(){return["tr",0]}},table_cell:{content:n.cellContent,attrs:t,tableRole:"cell",isolating:!0,parseDOM:[{tag:"td",getAttrs:r=>Ah(r,e)}],toDOM(r){return["td",bh(r,e),0]}},table_header:{content:n.cellContent,attrs:t,tableRole:"header_cell",isolating:!0,parseDOM:[{tag:"th",getAttrs:r=>Ah(r,e)}],toDOM(r){return["th",bh(r,e),0]}}}}function Ft(n){let e=n.cached.tableNodeTypes;if(!e){e=n.cached.tableNodeTypes={};for(const t in n.nodes){const r=n.nodes[t],i=r.spec.tableRole;i&&(e[i]=r)}}return e}var ln=new Ko("selectingCells");function Go(n){for(let e=n.depth-1;e>0;e--)if(n.node(e).type.spec.tableRole=="row")return n.node(0).resolve(n.before(e+1));return null}function kf(n){const e=n.selection.$head;for(let t=e.depth;t>0;t--)if(e.node(t).type.spec.tableRole=="row")return!0;return!1}function vy(n){const e=n.selection;if("$anchorCell"in e&&e.$anchorCell)return e.$anchorCell.pos>e.$headCell.pos?e.$anchorCell:e.$headCell;if("node"in e&&e.node&&e.node.type.spec.tableRole=="cell")return e.$anchor;const t=Go(e.$head)||$x(e.$head);if(t)return t;throw new RangeError(`No cell found around position ${e.head}`)}function $x(n){for(let e=n.nodeAfter,t=n.pos;e;e=e.firstChild,t++){const r=e.type.spec.tableRole;if(r=="cell"||r=="header_cell")return n.doc.resolve(t)}for(let e=n.nodeBefore,t=n.pos;e;e=e.lastChild,t--){const r=e.type.spec.tableRole;if(r=="cell"||r=="header_cell")return n.doc.resolve(t-e.nodeSize)}}function ju(n){return n.parent.type.spec.tableRole=="row"&&!!n.nodeAfter}function vf(n,e){return n.depth==e.depth&&n.pos>=e.start(-1)&&n.pos<=e.end(-1)}function xy(n,e,t){const r=n.node(-1),i=re.get(r),o=n.start(-1),s=i.nextCell(n.pos-o,e,t);return s==null?null:n.node(0).resolve(o+s)}function ei(n,e,t=1){const r={...n,colspan:n.colspan-t};return r.colwidth&&(r.colwidth=r.colwidth.slice(),r.colwidth.splice(e,t),r.colwidth.some(i=>i>0)||(r.colwidth=null)),r}var fe=class Vt extends P{constructor(e,t=e){const r=e.node(-1),i=re.get(r),o=e.start(-1),s=i.rectBetween(e.pos-o,t.pos-o),l=e.node(0),a=i.cellsInRect(s).filter(c=>c!=t.pos-o);a.unshift(t.pos-o);const u=a.map(c=>{const f=r.nodeAt(c);if(!f)throw RangeError(`No cell with offset ${c} found`);const d=o+c+1;return new tg(l.resolve(d),l.resolve(d+f.content.size))});super(u[0].$from,u[0].$to,u),this.$anchorCell=e,this.$headCell=t}map(e,t){const r=e.resolve(t.map(this.$anchorCell.pos)),i=e.resolve(t.map(this.$headCell.pos));if(ju(r)&&ju(i)&&vf(r,i)){const o=this.$anchorCell.node(-1)!=r.node(-1);return o&&this.isRowSelection()?Vt.rowSelection(r,i):o&&this.isColSelection()?Vt.colSelection(r,i):new Vt(r,i)}return $.between(r,i)}content(){const e=this.$anchorCell.node(-1),t=re.get(e),r=this.$anchorCell.start(-1),i=t.rectBetween(this.$anchorCell.pos-r,this.$headCell.pos-r),o={},s=[];for(let a=i.top;a0||w>0){let g=h.attrs;if(m>0&&(g=ei(g,0,m)),w>0&&(g=ei(g,g.colspan-w,w)),p.lefti.bottom){const g={...h.attrs,rowspan:Math.min(p.bottom,i.bottom)-Math.max(p.top,i.top)};p.top0)return!1;const r=e+this.$anchorCell.nodeAfter.attrs.rowspan,i=t+this.$headCell.nodeAfter.attrs.rowspan;return Math.max(r,i)==this.$headCell.node(-1).childCount}static colSelection(e,t=e){const r=e.node(-1),i=re.get(r),o=e.start(-1),s=i.findCell(e.pos-o),l=i.findCell(t.pos-o),a=e.node(0);return s.top<=l.top?(s.top>0&&(e=a.resolve(o+i.map[s.left])),l.bottom0&&(t=a.resolve(o+i.map[l.left])),s.bottom0)return!1;const s=i+this.$anchorCell.nodeAfter.attrs.colspan,l=o+this.$headCell.nodeAfter.attrs.colspan;return Math.max(s,l)==t.width}eq(e){return e instanceof Vt&&e.$anchorCell.pos==this.$anchorCell.pos&&e.$headCell.pos==this.$headCell.pos}static rowSelection(e,t=e){const r=e.node(-1),i=re.get(r),o=e.start(-1),s=i.findCell(e.pos-o),l=i.findCell(t.pos-o),a=e.node(0);return s.left<=l.left?(s.left>0&&(e=a.resolve(o+i.map[s.top*i.width])),l.right0&&(t=a.resolve(o+i.map[l.top*i.width])),s.right{e.push(ye.node(r,r+t.nodeSize,{class:"selectedCell"}))}),_.create(n.doc,e)}function Jx({$from:n,$to:e}){if(n.pos==e.pos||n.pos=0&&!(n.after(i+1)=0&&!(e.before(o+1)>e.start(o));o--,r--);return t==r&&/row|table/.test(n.node(i).type.spec.tableRole)}function _x({$from:n,$to:e}){let t,r;for(let i=n.depth;i>0;i--){const o=n.node(i);if(o.type.spec.tableRole==="cell"||o.type.spec.tableRole==="header_cell"){t=o;break}}for(let i=e.depth;i>0;i--){const o=e.node(i);if(o.type.spec.tableRole==="cell"||o.type.spec.tableRole==="header_cell"){r=o;break}}return t!==r&&e.parentOffset===0}function Wx(n,e,t){const r=(e||n).selection,i=(e||n).doc;let o,s;if(r instanceof I&&(s=r.node.type.spec.tableRole)){if(s=="cell"||s=="header_cell")o=fe.create(i,r.from);else if(s=="row"){const l=i.resolve(r.from+1);o=fe.rowSelection(l,l)}else if(!t){const l=re.get(r.node),a=r.from+1,u=a+l.map[l.width*l.height-1];o=fe.create(i,a+1,u)}}else r instanceof $&&Jx(r)?o=$.create(i,r.from):r instanceof $&&_x(r)&&(o=$.create(i,r.$from.start(),r.$from.end()));return o&&(e||(e=n.tr)).setSelection(o),e}var Ux=new Ko("fix-tables");function Ny(n,e,t,r){const i=n.childCount,o=e.childCount;e:for(let s=0,l=0;s{i.type.spec.tableRole=="table"&&(t=jx(n,i,o,t))};return e?e.doc!=n.doc&&Ny(e.doc,n.doc,0,r):n.doc.descendants(r),t}function jx(n,e,t,r){const i=re.get(e);if(!i.problems)return r;r||(r=n.tr);const o=[];for(let a=0;a0){let p="cell";c.firstChild&&(p=c.firstChild.type.spec.tableRole);const h=[];for(let w=0;w0&&r>0||e.child(0).type.spec.tableRole=="table");)t--,r--,e=e.child(0).content;const i=e.child(0),o=i.type.spec.tableRole,s=i.type.schema,l=[];if(o=="row")for(let a=0;a=0;s--){const{rowspan:l,colspan:a}=o.child(s).attrs;for(let u=i;u=e.length&&e.push(v.empty),t[i]r&&(d=d.type.createChecked(ei(d.attrs,d.attrs.colspan,c+d.attrs.colspan-r),d.content)),u.push(d),c+=d.attrs.colspan;for(let p=1;pi&&(f=f.type.create({...f.attrs,rowspan:Math.max(1,i-f.attrs.rowspan)},f.content)),a.push(f)}o.push(v.from(a))}t=o,e=i}return{width:n,height:e,rows:t}}function Yx(n,e,t,r,i,o,s){const l=n.doc.type.schema,a=Ft(l);let u,c;if(i>e.width)for(let f=0,d=0;fe.height){const f=[];for(let h=0,m=(e.height-1)*e.width;h=e.width?!1:t.nodeAt(e.map[m+h]).type==a.header_cell;f.push(w?c||(c=a.header_cell.createAndFill()):u||(u=a.cell.createAndFill()))}const d=a.row.create(null,v.from(f)),p=[];for(let h=e.height;h{if(!i)return!1;const o=t.selection;if(o instanceof fe)return Ys(t,r,P.near(o.$headCell,e));if(n!="horiz"&&!o.empty)return!1;const s=My(i,n,e);if(s==null)return!1;if(n=="horiz")return Ys(t,r,P.near(t.doc.resolve(o.head+e),e));{const l=t.doc.resolve(s),a=xy(l,n,e);let u;return a?u=P.near(a,1):e<0?u=P.near(t.doc.resolve(l.before(-1)),-1):u=P.near(t.doc.resolve(l.after(-1)),1),Ys(t,r,u)}}}function ds(n,e){return(t,r,i)=>{if(!i)return!1;const o=t.selection;let s;if(o instanceof fe)s=o;else{const a=My(i,n,e);if(a==null)return!1;s=new fe(t.doc.resolve(a))}const l=xy(s.$headCell,n,e);return l?Ys(t,r,new fe(s.$anchorCell,l)):!1}}function hs(n,e){const t=n.selection;if(!(t instanceof fe))return!1;if(e){const r=n.tr,i=Ft(n.schema).cell.createAndFill().content;t.forEachCell((o,s)=>{o.content.eq(i)||r.replace(r.mapping.map(s+1),r.mapping.map(s+o.nodeSize-1),new k(i,0,0))}),r.docChanged&&e(r)}return!0}function Xx(n,e){const t=n.state.doc,r=Go(t.resolve(e));return r?(n.dispatch(n.state.tr.setSelection(new fe(r))),!0):!1}function Zx(n,e,t){if(!kf(n.state))return!1;let r=Kx(t);const i=n.state.selection;if(i instanceof fe){r||(r={width:1,height:1,rows:[v.from(Ku(Ft(n.state.schema).cell,t))]});const o=i.$anchorCell.node(-1),s=i.$anchorCell.start(-1),l=re.get(o).rectBetween(i.$anchorCell.pos-s,i.$headCell.pos-s);return r=Qx(r,l.right-l.left,l.bottom-l.top),Ph(n.state,n.dispatch,s,l,r),!0}else if(r){const o=vy(n.state),s=o.start(-1);return Ph(n.state,n.dispatch,s,re.get(o.node(-1)).findCell(o.pos-s),r),!0}else return!1}function eC(n,e){var t;if(e.ctrlKey||e.metaKey)return;const r=Fh(n,e.target);let i;if(e.shiftKey&&n.state.selection instanceof fe)o(n.state.selection.$anchorCell,e),e.preventDefault();else if(e.shiftKey&&r&&(i=Go(n.state.selection.$anchor))!=null&&((t=Ua(n,e))==null?void 0:t.pos)!=i.pos)o(i,e),e.preventDefault();else if(!r)return;function o(a,u){let c=Ua(n,u);const f=ln.getState(n.state)==null;if(!c||!vf(a,c))if(f)c=a;else return;const d=new fe(a,c);if(f||!n.state.selection.eq(d)){const p=n.state.tr.setSelection(d);f&&p.setMeta(ln,a.pos),n.dispatch(p)}}function s(){n.root.removeEventListener("mouseup",s),n.root.removeEventListener("dragstart",s),n.root.removeEventListener("mousemove",l),ln.getState(n.state)!=null&&n.dispatch(n.state.tr.setMeta(ln,-1))}function l(a){const u=a,c=ln.getState(n.state);let f;if(c!=null)f=n.state.doc.resolve(c);else if(Fh(n,u.target)!=r&&(f=Ua(n,e),!f))return s();f&&o(f,u)}n.root.addEventListener("mouseup",s),n.root.addEventListener("dragstart",s),n.root.addEventListener("mousemove",l)}function My(n,e,t){if(!(n.state.selection instanceof $))return null;const{$head:r}=n.state.selection;for(let i=r.depth-1;i>=0;i--){const o=r.node(i);if((t<0?r.index(i):r.indexAfter(i))!=(t<0?0:o.childCount))return null;if(o.type.spec.tableRole=="cell"||o.type.spec.tableRole=="header_cell"){const l=r.before(i),a=e=="vert"?t>0?"down":"up":t>0?"right":"left";return n.endOfTextblock(a)?l:null}}return null}function Fh(n,e){for(;e&&e!=n.dom;e=e.parentNode)if(e.nodeName=="TD"||e.nodeName=="TH")return e;return null}function Ua(n,e){const t=n.posAtCoords({left:e.clientX,top:e.clientY});return t&&t?Go(n.state.doc.resolve(t.pos)):null}var tC=class{constructor(n,e){this.node=n,this.cellMinWidth=e,this.dom=document.createElement("div"),this.dom.className="tableWrapper",this.table=this.dom.appendChild(document.createElement("table")),this.colgroup=this.table.appendChild(document.createElement("colgroup")),qu(n,this.colgroup,this.table,e),this.contentDOM=this.table.appendChild(document.createElement("tbody"))}update(n){return n.type!=this.node.type?!1:(this.node=n,qu(n,this.colgroup,this.table,this.cellMinWidth),!0)}ignoreMutation(n){return n.type=="attributes"&&(n.target==this.table||this.colgroup.contains(n.target))}};function qu(n,e,t,r,i,o){var s;let l=0,a=!0,u=e.firstChild;const c=n.firstChild;if(c){for(let f=0,d=0;fnew t(l,e,a),new rC(-1,!1)},apply(o,s){return s.apply(o)}},props:{attributes:o=>{const s=ut.getState(o);return s&&s.activeHandle>-1?{class:"resize-cursor"}:{}},handleDOMEvents:{mousemove:(o,s)=>{iC(o,s,n,e,r)},mouseleave:o=>{oC(o)},mousedown:(o,s)=>{sC(o,s,e)}},decorations:o=>{const s=ut.getState(o);if(s&&s.activeHandle>-1)return dC(o,s.activeHandle)},nodeViews:{}}});return i}var rC=class Gs{constructor(e,t){this.activeHandle=e,this.dragging=t}apply(e){const t=this,r=e.getMeta(ut);if(r&&r.setHandle!=null)return new Gs(r.setHandle,!1);if(r&&r.setDragging!==void 0)return new Gs(t.activeHandle,r.setDragging);if(t.activeHandle>-1&&e.docChanged){let i=e.mapping.map(t.activeHandle,-1);return ju(e.doc.resolve(i))||(i=-1),new Gs(i,t.dragging)}return t}};function iC(n,e,t,r,i){const o=ut.getState(n.state);if(o&&!o.dragging){const s=aC(e.target);let l=-1;if(s){const{left:a,right:u}=s.getBoundingClientRect();e.clientX-a<=t?l=Lh(n,e,"left",t):u-e.clientX<=t&&(l=Lh(n,e,"right",t))}if(l!=o.activeHandle){if(!i&&l!==-1){const a=n.state.doc.resolve(l),u=a.node(-1),c=re.get(u),f=a.start(-1);if(c.colCount(a.pos-f)+a.nodeAfter.attrs.colspan-1==c.width-1)return}Ey(n,l)}}}function oC(n){const e=ut.getState(n.state);e&&e.activeHandle>-1&&!e.dragging&&Ey(n,-1)}function sC(n,e,t){var r;const i=(r=n.dom.ownerDocument.defaultView)!=null?r:window,o=ut.getState(n.state);if(!o||o.activeHandle==-1||o.dragging)return!1;const s=n.state.doc.nodeAt(o.activeHandle),l=lC(n,o.activeHandle,s.attrs);n.dispatch(n.state.tr.setMeta(ut,{setDragging:{startX:e.clientX,startWidth:l}}));function a(c){i.removeEventListener("mouseup",a),i.removeEventListener("mousemove",u);const f=ut.getState(n.state);f!=null&&f.dragging&&(uC(n,f.activeHandle,$h(f.dragging,c,t)),n.dispatch(n.state.tr.setMeta(ut,{setDragging:null})))}function u(c){if(!c.which)return a(c);const f=ut.getState(n.state);if(f&&f.dragging){const d=$h(f.dragging,c,t);cC(n,f.activeHandle,d,t)}}return i.addEventListener("mouseup",a),i.addEventListener("mousemove",u),e.preventDefault(),!0}function lC(n,e,{colspan:t,colwidth:r}){const i=r&&r[r.length-1];if(i)return i;const o=n.domAtPos(e);let l=o.node.childNodes[o.offset].offsetWidth,a=t;if(r)for(let u=0;ui.table.nodeAt(a));for(let a=0;a{const h=p+o.tableStart,m=s.doc.nodeAt(h);m&&s.setNodeMarkup(h,d,m.attrs)}),r(s)}return!0}}xf("row",{useDeprecatedLogic:!0});xf("column",{useDeprecatedLogic:!0});xf("cell",{useDeprecatedLogic:!0});function pC({allowTableNodeSelection:n=!1}={}){return new $t({key:ln,state:{init(){return null},apply(e,t){const r=e.getMeta(ln);if(r!=null)return r==-1?null:r;if(t==null||!e.docChanged)return t;const{deleted:i,pos:o}=e.mapping.mapResult(t);return i?null:o}},props:{decorations:Vx,handleDOMEvents:{mousedown:eC},createSelectionBetween(e){return ln.getState(e.state)!=null?e.state.selection:null},handleTripleClick:Xx,handleKeyDown:Gx,handlePaste:Zx},appendTransaction(e,t,r){return Wx(r,Hx(r,t),n)}})}var Dy={exports:{}},rt={},Ty={exports:{}},Ry={};/** + * @license React + * scheduler.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */(function(n){function e(R,F){var L=R.length;R.push(F);e:for(;0>>1,ue=R[te];if(0>>1;tei(ya,L))Fni(is,ya)?(R[te]=is,R[Fn]=L,te=Fn):(R[te]=ya,R[Pn]=L,te=Pn);else if(Fni(is,L))R[te]=is,R[Fn]=L,te=Fn;else break e}}return F}function i(R,F){var L=R.sortIndex-F.sortIndex;return L!==0?L:R.id-F.id}if(typeof performance=="object"&&typeof performance.now=="function"){var o=performance;n.unstable_now=function(){return o.now()}}else{var s=Date,l=s.now();n.unstable_now=function(){return s.now()-l}}var a=[],u=[],c=1,f=null,d=3,p=!1,h=!1,m=!1,w=typeof setTimeout=="function"?setTimeout:null,g=typeof clearTimeout=="function"?clearTimeout:null,y=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function S(R){for(var F=t(u);F!==null;){if(F.callback===null)r(u);else if(F.startTime<=R)r(u),F.sortIndex=F.expirationTime,e(a,F);else break;F=t(u)}}function x(R){if(m=!1,S(R),!h)if(t(a)!==null)h=!0,ma(M);else{var F=t(u);F!==null&&ga(x,F.startTime-R)}}function M(R,F){h=!1,m&&(m=!1,g(T),T=-1),p=!0;var L=d;try{for(S(F),f=t(a);f!==null&&(!(f.expirationTime>F)||R&&!se());){var te=f.callback;if(typeof te=="function"){f.callback=null,d=f.priorityLevel;var ue=te(f.expirationTime<=F);F=n.unstable_now(),typeof ue=="function"?f.callback=ue:f===t(a)&&r(a),S(F)}else r(a);f=t(a)}if(f!==null)var rs=!0;else{var Pn=t(u);Pn!==null&&ga(x,Pn.startTime-F),rs=!1}return rs}finally{f=null,d=L,p=!1}}var E=!1,O=null,T=-1,b=5,z=-1;function se(){return!(n.unstable_now()-zR||125te?(R.sortIndex=L,e(u,R),t(a)===null&&R===t(u)&&(m?(g(T),T=-1):m=!0,ga(x,L-te))):(R.sortIndex=ue,e(a,R),h||p||(h=!0,ma(M))),R},n.unstable_shouldYield=se,n.unstable_wrapCallback=function(R){var F=d;return function(){var L=d;d=F;try{return R.apply(this,arguments)}finally{d=L}}}})(Ry);Ty.exports=Ry;var mC=Ty.exports;/** + * @license React + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Ay=C,nt=mC;function N(n){for(var e="https://reactjs.org/docs/error-decoder.html?invariant="+n,t=1;t"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),Qu=Object.prototype.hasOwnProperty,gC=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,Vh={},Jh={};function yC(n){return Qu.call(Jh,n)?!0:Qu.call(Vh,n)?!1:gC.test(n)?Jh[n]=!0:(Vh[n]=!0,!1)}function SC(n,e,t,r){if(t!==null&&t.type===0)return!1;switch(typeof e){case"function":case"symbol":return!0;case"boolean":return r?!1:t!==null?!t.acceptsBooleans:(n=n.toLowerCase().slice(0,5),n!=="data-"&&n!=="aria-");default:return!1}}function wC(n,e,t,r){if(e===null||typeof e>"u"||SC(n,e,t,r))return!0;if(r)return!1;if(t!==null)switch(t.type){case 3:return!e;case 4:return e===!1;case 5:return isNaN(e);case 6:return isNaN(e)||1>e}return!1}function Fe(n,e,t,r,i,o,s){this.acceptsBooleans=e===2||e===3||e===4,this.attributeName=r,this.attributeNamespace=i,this.mustUseProperty=t,this.propertyName=n,this.type=e,this.sanitizeURL=o,this.removeEmptyString=s}var we={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(n){we[n]=new Fe(n,0,!1,n,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(n){var e=n[0];we[e]=new Fe(e,1,!1,n[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(n){we[n]=new Fe(n,2,!1,n.toLowerCase(),null,!1,!1)});["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(n){we[n]=new Fe(n,2,!1,n,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(n){we[n]=new Fe(n,3,!1,n.toLowerCase(),null,!1,!1)});["checked","multiple","muted","selected"].forEach(function(n){we[n]=new Fe(n,3,!0,n,null,!1,!1)});["capture","download"].forEach(function(n){we[n]=new Fe(n,4,!1,n,null,!1,!1)});["cols","rows","size","span"].forEach(function(n){we[n]=new Fe(n,6,!1,n,null,!1,!1)});["rowSpan","start"].forEach(function(n){we[n]=new Fe(n,5,!1,n.toLowerCase(),null,!1,!1)});var Cf=/[\-:]([a-z])/g;function Nf(n){return n[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(n){var e=n.replace(Cf,Nf);we[e]=new Fe(e,1,!1,n,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(n){var e=n.replace(Cf,Nf);we[e]=new Fe(e,1,!1,n,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(n){var e=n.replace(Cf,Nf);we[e]=new Fe(e,1,!1,n,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(n){we[n]=new Fe(n,1,!1,n.toLowerCase(),null,!1,!1)});we.xlinkHref=new Fe("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(n){we[n]=new Fe(n,1,!1,n.toLowerCase(),null,!0,!0)});function Mf(n,e,t,r){var i=we.hasOwnProperty(e)?we[e]:null;(i!==null?i.type!==0:r||!(2l||i[s]!==o[l]){var a=` +`+i[s].replace(" at new "," at ");return n.displayName&&a.includes("")&&(a=a.replace("",n.displayName)),a}while(1<=s&&0<=l);break}}}finally{ja=!1,Error.prepareStackTrace=t}return(n=n?n.displayName||n.name:"")?Ki(n):""}function kC(n){switch(n.tag){case 5:return Ki(n.type);case 16:return Ki("Lazy");case 13:return Ki("Suspense");case 19:return Ki("SuspenseList");case 0:case 2:case 15:return n=Ka(n.type,!1),n;case 11:return n=Ka(n.type.render,!1),n;case 1:return n=Ka(n.type,!0),n;default:return""}}function Zu(n){if(n==null)return null;if(typeof n=="function")return n.displayName||n.name||null;if(typeof n=="string")return n;switch(n){case Mr:return"Fragment";case Nr:return"Portal";case Yu:return"Profiler";case Ef:return"StrictMode";case Gu:return"Suspense";case Xu:return"SuspenseList"}if(typeof n=="object")switch(n.$$typeof){case zy:return(n.displayName||"Context")+".Consumer";case Iy:return(n._context.displayName||"Context")+".Provider";case Of:var e=n.render;return n=n.displayName,n||(n=e.displayName||e.name||"",n=n!==""?"ForwardRef("+n+")":"ForwardRef"),n;case Df:return e=n.displayName||null,e!==null?e:Zu(n.type)||"Memo";case rn:e=n._payload,n=n._init;try{return Zu(n(e))}catch{}}return null}function vC(n){var e=n.type;switch(n.tag){case 24:return"Cache";case 9:return(e.displayName||"Context")+".Consumer";case 10:return(e._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return n=e.render,n=n.displayName||n.name||"",e.displayName||(n!==""?"ForwardRef("+n+")":"ForwardRef");case 7:return"Fragment";case 5:return e;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return Zu(e);case 8:return e===Ef?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e}return null}function On(n){switch(typeof n){case"boolean":case"number":case"string":case"undefined":return n;case"object":return n;default:return""}}function Fy(n){var e=n.type;return(n=n.nodeName)&&n.toLowerCase()==="input"&&(e==="checkbox"||e==="radio")}function xC(n){var e=Fy(n)?"checked":"value",t=Object.getOwnPropertyDescriptor(n.constructor.prototype,e),r=""+n[e];if(!n.hasOwnProperty(e)&&typeof t<"u"&&typeof t.get=="function"&&typeof t.set=="function"){var i=t.get,o=t.set;return Object.defineProperty(n,e,{configurable:!0,get:function(){return i.call(this)},set:function(s){r=""+s,o.call(this,s)}}),Object.defineProperty(n,e,{enumerable:t.enumerable}),{getValue:function(){return r},setValue:function(s){r=""+s},stopTracking:function(){n._valueTracker=null,delete n[e]}}}}function ms(n){n._valueTracker||(n._valueTracker=xC(n))}function Ly(n){if(!n)return!1;var e=n._valueTracker;if(!e)return!0;var t=e.getValue(),r="";return n&&(r=Fy(n)?n.checked?"true":"false":n.value),n=r,n!==t?(e.setValue(n),!0):!1}function kl(n){if(n=n||(typeof document<"u"?document:void 0),typeof n>"u")return null;try{return n.activeElement||n.body}catch{return n.body}}function ec(n,e){var t=e.checked;return X({},e,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:t??n._wrapperState.initialChecked})}function Wh(n,e){var t=e.defaultValue==null?"":e.defaultValue,r=e.checked!=null?e.checked:e.defaultChecked;t=On(e.value!=null?e.value:t),n._wrapperState={initialChecked:r,initialValue:t,controlled:e.type==="checkbox"||e.type==="radio"?e.checked!=null:e.value!=null}}function $y(n,e){e=e.checked,e!=null&&Mf(n,"checked",e,!1)}function tc(n,e){$y(n,e);var t=On(e.value),r=e.type;if(t!=null)r==="number"?(t===0&&n.value===""||n.value!=t)&&(n.value=""+t):n.value!==""+t&&(n.value=""+t);else if(r==="submit"||r==="reset"){n.removeAttribute("value");return}e.hasOwnProperty("value")?nc(n,e.type,t):e.hasOwnProperty("defaultValue")&&nc(n,e.type,On(e.defaultValue)),e.checked==null&&e.defaultChecked!=null&&(n.defaultChecked=!!e.defaultChecked)}function Uh(n,e,t){if(e.hasOwnProperty("value")||e.hasOwnProperty("defaultValue")){var r=e.type;if(!(r!=="submit"&&r!=="reset"||e.value!==void 0&&e.value!==null))return;e=""+n._wrapperState.initialValue,t||e===n.value||(n.value=e),n.defaultValue=e}t=n.name,t!==""&&(n.name=""),n.defaultChecked=!!n._wrapperState.initialChecked,t!==""&&(n.name=t)}function nc(n,e,t){(e!=="number"||kl(n.ownerDocument)!==n)&&(t==null?n.defaultValue=""+n._wrapperState.initialValue:n.defaultValue!==""+t&&(n.defaultValue=""+t))}var qi=Array.isArray;function Br(n,e,t,r){if(n=n.options,e){e={};for(var i=0;i"+e.valueOf().toString()+"",e=gs.firstChild;n.firstChild;)n.removeChild(n.firstChild);for(;e.firstChild;)n.appendChild(e.firstChild)}});function Mo(n,e){if(e){var t=n.firstChild;if(t&&t===n.lastChild&&t.nodeType===3){t.nodeValue=e;return}}n.textContent=e}var no={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},CC=["Webkit","ms","Moz","O"];Object.keys(no).forEach(function(n){CC.forEach(function(e){e=e+n.charAt(0).toUpperCase()+n.substring(1),no[e]=no[n]})});function _y(n,e,t){return e==null||typeof e=="boolean"||e===""?"":t||typeof e!="number"||e===0||no.hasOwnProperty(n)&&no[n]?(""+e).trim():e+"px"}function Wy(n,e){n=n.style;for(var t in e)if(e.hasOwnProperty(t)){var r=t.indexOf("--")===0,i=_y(t,e[t],r);t==="float"&&(t="cssFloat"),r?n.setProperty(t,i):n[t]=i}}var NC=X({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function oc(n,e){if(e){if(NC[n]&&(e.children!=null||e.dangerouslySetInnerHTML!=null))throw Error(N(137,n));if(e.dangerouslySetInnerHTML!=null){if(e.children!=null)throw Error(N(60));if(typeof e.dangerouslySetInnerHTML!="object"||!("__html"in e.dangerouslySetInnerHTML))throw Error(N(61))}if(e.style!=null&&typeof e.style!="object")throw Error(N(62))}}function sc(n,e){if(n.indexOf("-")===-1)return typeof e.is=="string";switch(n){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var lc=null;function Tf(n){return n=n.target||n.srcElement||window,n.correspondingUseElement&&(n=n.correspondingUseElement),n.nodeType===3?n.parentNode:n}var ac=null,Vr=null,Jr=null;function Kh(n){if(n=es(n)){if(typeof ac!="function")throw Error(N(280));var e=n.stateNode;e&&(e=ta(e),ac(n.stateNode,n.type,e))}}function Uy(n){Vr?Jr?Jr.push(n):Jr=[n]:Vr=n}function Hy(){if(Vr){var n=Vr,e=Jr;if(Jr=Vr=null,Kh(n),e)for(n=0;n>>=0,n===0?32:31-(PC(n)/FC|0)|0}var ys=64,Ss=4194304;function Qi(n){switch(n&-n){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return n&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return n&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return n}}function Nl(n,e){var t=n.pendingLanes;if(t===0)return 0;var r=0,i=n.suspendedLanes,o=n.pingedLanes,s=t&268435455;if(s!==0){var l=s&~i;l!==0?r=Qi(l):(o&=s,o!==0&&(r=Qi(o)))}else s=t&~i,s!==0?r=Qi(s):o!==0&&(r=Qi(o));if(r===0)return 0;if(e!==0&&e!==r&&!(e&i)&&(i=r&-r,o=e&-e,i>=o||i===16&&(o&4194240)!==0))return e;if(r&4&&(r|=t&16),e=n.entangledLanes,e!==0)for(n=n.entanglements,e&=r;0t;t++)e.push(n);return e}function Xo(n,e,t){n.pendingLanes|=e,e!==536870912&&(n.suspendedLanes=0,n.pingedLanes=0),n=n.eventTimes,e=31-vt(e),n[e]=t}function VC(n,e){var t=n.pendingLanes&~e;n.pendingLanes=e,n.suspendedLanes=0,n.pingedLanes=0,n.expiredLanes&=e,n.mutableReadLanes&=e,n.entangledLanes&=e,e=n.entanglements;var r=n.eventTimes;for(n=n.expirationTimes;0=io),np=" ",rp=!1;function f0(n,e){switch(n){case"keyup":return pN.indexOf(e.keyCode)!==-1;case"keydown":return e.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function d0(n){return n=n.detail,typeof n=="object"&&"data"in n?n.data:null}var Er=!1;function gN(n,e){switch(n){case"compositionend":return d0(e);case"keypress":return e.which!==32?null:(rp=!0,np);case"textInput":return n=e.data,n===np&&rp?null:n;default:return null}}function yN(n,e){if(Er)return n==="compositionend"||!Lf&&f0(n,e)?(n=u0(),Zs=zf=pn=null,Er=!1,n):null;switch(n){case"paste":return null;case"keypress":if(!(e.ctrlKey||e.altKey||e.metaKey)||e.ctrlKey&&e.altKey){if(e.char&&1=e)return{node:t,offset:e-n};n=r}e:{for(;t;){if(t.nextSibling){t=t.nextSibling;break e}t=t.parentNode}t=void 0}t=lp(t)}}function g0(n,e){return n&&e?n===e?!0:n&&n.nodeType===3?!1:e&&e.nodeType===3?g0(n,e.parentNode):"contains"in n?n.contains(e):n.compareDocumentPosition?!!(n.compareDocumentPosition(e)&16):!1:!1}function y0(){for(var n=window,e=kl();e instanceof n.HTMLIFrameElement;){try{var t=typeof e.contentWindow.location.href=="string"}catch{t=!1}if(t)n=e.contentWindow;else break;e=kl(n.document)}return e}function $f(n){var e=n&&n.nodeName&&n.nodeName.toLowerCase();return e&&(e==="input"&&(n.type==="text"||n.type==="search"||n.type==="tel"||n.type==="url"||n.type==="password")||e==="textarea"||n.contentEditable==="true")}function EN(n){var e=y0(),t=n.focusedElem,r=n.selectionRange;if(e!==t&&t&&t.ownerDocument&&g0(t.ownerDocument.documentElement,t)){if(r!==null&&$f(t)){if(e=r.start,n=r.end,n===void 0&&(n=e),"selectionStart"in t)t.selectionStart=e,t.selectionEnd=Math.min(n,t.value.length);else if(n=(e=t.ownerDocument||document)&&e.defaultView||window,n.getSelection){n=n.getSelection();var i=t.textContent.length,o=Math.min(r.start,i);r=r.end===void 0?o:Math.min(r.end,i),!n.extend&&o>r&&(i=r,r=o,o=i),i=ap(t,o);var s=ap(t,r);i&&s&&(n.rangeCount!==1||n.anchorNode!==i.node||n.anchorOffset!==i.offset||n.focusNode!==s.node||n.focusOffset!==s.offset)&&(e=e.createRange(),e.setStart(i.node,i.offset),n.removeAllRanges(),o>r?(n.addRange(e),n.extend(s.node,s.offset)):(e.setEnd(s.node,s.offset),n.addRange(e)))}}for(e=[],n=t;n=n.parentNode;)n.nodeType===1&&e.push({element:n,left:n.scrollLeft,top:n.scrollTop});for(typeof t.focus=="function"&&t.focus(),t=0;t=document.documentMode,Or=null,pc=null,so=null,mc=!1;function up(n,e,t){var r=t.window===t?t.document:t.nodeType===9?t:t.ownerDocument;mc||Or==null||Or!==kl(r)||(r=Or,"selectionStart"in r&&$f(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),so&&Ao(so,r)||(so=r,r=Ol(pc,"onSelect"),0Rr||(n.current=vc[Rr],vc[Rr]=null,Rr--)}function j(n,e){Rr++,vc[Rr]=n.current,n.current=e}var Dn={},Oe=bn(Dn),Ue=bn(!1),ir=Dn;function ni(n,e){var t=n.type.contextTypes;if(!t)return Dn;var r=n.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===e)return r.__reactInternalMemoizedMaskedChildContext;var i={},o;for(o in t)i[o]=e[o];return r&&(n=n.stateNode,n.__reactInternalMemoizedUnmaskedChildContext=e,n.__reactInternalMemoizedMaskedChildContext=i),i}function He(n){return n=n.childContextTypes,n!=null}function Tl(){q(Ue),q(Oe)}function gp(n,e,t){if(Oe.current!==Dn)throw Error(N(168));j(Oe,e),j(Ue,t)}function E0(n,e,t){var r=n.stateNode;if(e=e.childContextTypes,typeof r.getChildContext!="function")return t;r=r.getChildContext();for(var i in r)if(!(i in e))throw Error(N(108,vC(n)||"Unknown",i));return X({},t,r)}function Rl(n){return n=(n=n.stateNode)&&n.__reactInternalMemoizedMergedChildContext||Dn,ir=Oe.current,j(Oe,n),j(Ue,Ue.current),!0}function yp(n,e,t){var r=n.stateNode;if(!r)throw Error(N(169));t?(n=E0(n,e,ir),r.__reactInternalMemoizedMergedChildContext=n,q(Ue),q(Oe),j(Oe,n)):q(Ue),j(Ue,t)}var Ut=null,na=!1,lu=!1;function O0(n){Ut===null?Ut=[n]:Ut.push(n)}function $N(n){na=!0,O0(n)}function In(){if(!lu&&Ut!==null){lu=!0;var n=0,e=H;try{var t=Ut;for(H=1;n>=s,i-=s,Ht=1<<32-vt(e)+i|t<T?(b=O,O=null):b=O.sibling;var z=d(g,O,S[T],x);if(z===null){O===null&&(O=b);break}n&&O&&z.alternate===null&&e(g,O),y=o(z,y,T),E===null?M=z:E.sibling=z,E=z,O=b}if(T===S.length)return t(g,O),Q&&Jn(g,T),M;if(O===null){for(;TT?(b=O,O=null):b=O.sibling;var se=d(g,O,z.value,x);if(se===null){O===null&&(O=b);break}n&&O&&se.alternate===null&&e(g,O),y=o(se,y,T),E===null?M=se:E.sibling=se,E=se,O=b}if(z.done)return t(g,O),Q&&Jn(g,T),M;if(O===null){for(;!z.done;T++,z=S.next())z=f(g,z.value,x),z!==null&&(y=o(z,y,T),E===null?M=z:E.sibling=z,E=z);return Q&&Jn(g,T),M}for(O=r(g,O);!z.done;T++,z=S.next())z=p(O,g,T,z.value,x),z!==null&&(n&&z.alternate!==null&&O.delete(z.key===null?T:z.key),y=o(z,y,T),E===null?M=z:E.sibling=z,E=z);return n&&O.forEach(function(W){return e(g,W)}),Q&&Jn(g,T),M}function w(g,y,S,x){if(typeof S=="object"&&S!==null&&S.type===Mr&&S.key===null&&(S=S.props.children),typeof S=="object"&&S!==null){switch(S.$$typeof){case ps:e:{for(var M=S.key,E=y;E!==null;){if(E.key===M){if(M=S.type,M===Mr){if(E.tag===7){t(g,E.sibling),y=i(E,S.props.children),y.return=g,g=y;break e}}else if(E.elementType===M||typeof M=="object"&&M!==null&&M.$$typeof===rn&&Np(M)===E.type){t(g,E.sibling),y=i(E,S.props),y.ref=vi(g,E,S),y.return=g,g=y;break e}t(g,E);break}else e(g,E);E=E.sibling}S.type===Mr?(y=tr(S.props.children,g.mode,x,S.key),y.return=g,g=y):(x=ll(S.type,S.key,S.props,null,g.mode,x),x.ref=vi(g,y,S),x.return=g,g=x)}return s(g);case Nr:e:{for(E=S.key;y!==null;){if(y.key===E)if(y.tag===4&&y.stateNode.containerInfo===S.containerInfo&&y.stateNode.implementation===S.implementation){t(g,y.sibling),y=i(y,S.children||[]),y.return=g,g=y;break e}else{t(g,y);break}else e(g,y);y=y.sibling}y=mu(S,g.mode,x),y.return=g,g=y}return s(g);case rn:return E=S._init,w(g,y,E(S._payload),x)}if(qi(S))return h(g,y,S,x);if(gi(S))return m(g,y,S,x);Ms(g,S)}return typeof S=="string"&&S!==""||typeof S=="number"?(S=""+S,y!==null&&y.tag===6?(t(g,y.sibling),y=i(y,S),y.return=g,g=y):(t(g,y),y=pu(S,g.mode,x),y.return=g,g=y),s(g)):t(g,y)}return w}var ii=P0(!0),F0=P0(!1),ts={},bt=bn(ts),Po=bn(ts),Fo=bn(ts);function Qn(n){if(n===ts)throw Error(N(174));return n}function Kf(n,e){switch(j(Fo,e),j(Po,n),j(bt,ts),n=e.nodeType,n){case 9:case 11:e=(e=e.documentElement)?e.namespaceURI:ic(null,"");break;default:n=n===8?e.parentNode:e,e=n.namespaceURI||null,n=n.tagName,e=ic(e,n)}q(bt),j(bt,e)}function oi(){q(bt),q(Po),q(Fo)}function L0(n){Qn(Fo.current);var e=Qn(bt.current),t=ic(e,n.type);e!==t&&(j(Po,n),j(bt,t))}function qf(n){Po.current===n&&(q(bt),q(Po))}var Y=bn(0);function Fl(n){for(var e=n;e!==null;){if(e.tag===13){var t=e.memoizedState;if(t!==null&&(t=t.dehydrated,t===null||t.data==="$?"||t.data==="$!"))return e}else if(e.tag===19&&e.memoizedProps.revealOrder!==void 0){if(e.flags&128)return e}else if(e.child!==null){e.child.return=e,e=e.child;continue}if(e===n)break;for(;e.sibling===null;){if(e.return===null||e.return===n)return null;e=e.return}e.sibling.return=e.return,e=e.sibling}return null}var au=[];function Qf(){for(var n=0;nt?t:4,n(!0);var r=uu.transition;uu.transition={};try{n(!1),e()}finally{H=t,uu.transition=r}}function Z0(){return pt().memoizedState}function _N(n,e,t){var r=Nn(n);if(t={lane:r,action:t,hasEagerState:!1,eagerState:null,next:null},e1(n))t1(e,t);else if(t=A0(n,e,t,r),t!==null){var i=Ae();xt(t,n,r,i),n1(t,e,r)}}function WN(n,e,t){var r=Nn(n),i={lane:r,action:t,hasEagerState:!1,eagerState:null,next:null};if(e1(n))t1(e,i);else{var o=n.alternate;if(n.lanes===0&&(o===null||o.lanes===0)&&(o=e.lastRenderedReducer,o!==null))try{var s=e.lastRenderedState,l=o(s,t);if(i.hasEagerState=!0,i.eagerState=l,Nt(l,s)){var a=e.interleaved;a===null?(i.next=i,Hf(e)):(i.next=a.next,a.next=i),e.interleaved=i;return}}catch{}finally{}t=A0(n,e,i,r),t!==null&&(i=Ae(),xt(t,n,r,i),n1(t,e,r))}}function e1(n){var e=n.alternate;return n===G||e!==null&&e===G}function t1(n,e){lo=Ll=!0;var t=n.pending;t===null?e.next=e:(e.next=t.next,t.next=e),n.pending=e}function n1(n,e,t){if(t&4194240){var r=e.lanes;r&=n.pendingLanes,t|=r,e.lanes=t,Af(n,t)}}var $l={readContext:ht,useCallback:ve,useContext:ve,useEffect:ve,useImperativeHandle:ve,useInsertionEffect:ve,useLayoutEffect:ve,useMemo:ve,useReducer:ve,useRef:ve,useState:ve,useDebugValue:ve,useDeferredValue:ve,useTransition:ve,useMutableSource:ve,useSyncExternalStore:ve,useId:ve,unstable_isNewReconciler:!1},UN={readContext:ht,useCallback:function(n,e){return Et().memoizedState=[n,e===void 0?null:e],n},useContext:ht,useEffect:Ep,useImperativeHandle:function(n,e,t){return t=t!=null?t.concat([n]):null,rl(4194308,4,q0.bind(null,e,n),t)},useLayoutEffect:function(n,e){return rl(4194308,4,n,e)},useInsertionEffect:function(n,e){return rl(4,2,n,e)},useMemo:function(n,e){var t=Et();return e=e===void 0?null:e,n=n(),t.memoizedState=[n,e],n},useReducer:function(n,e,t){var r=Et();return e=t!==void 0?t(e):e,r.memoizedState=r.baseState=e,n={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:n,lastRenderedState:e},r.queue=n,n=n.dispatch=_N.bind(null,G,n),[r.memoizedState,n]},useRef:function(n){var e=Et();return n={current:n},e.memoizedState=n},useState:Mp,useDebugValue:ed,useDeferredValue:function(n){return Et().memoizedState=n},useTransition:function(){var n=Mp(!1),e=n[0];return n=JN.bind(null,n[1]),Et().memoizedState=n,[e,n]},useMutableSource:function(){},useSyncExternalStore:function(n,e,t){var r=G,i=Et();if(Q){if(t===void 0)throw Error(N(407));t=t()}else{if(t=e(),de===null)throw Error(N(349));sr&30||V0(r,e,t)}i.memoizedState=t;var o={value:t,getSnapshot:e};return i.queue=o,Ep(_0.bind(null,r,o,n),[n]),r.flags|=2048,Bo(9,J0.bind(null,r,o,t,e),void 0,null),t},useId:function(){var n=Et(),e=de.identifierPrefix;if(Q){var t=jt,r=Ht;t=(r&~(1<<32-vt(r)-1)).toString(32)+t,e=":"+e+"R"+t,t=Lo++,0<\/script>",n=n.removeChild(n.firstChild)):typeof r.is=="string"?n=s.createElement(t,{is:r.is}):(n=s.createElement(t),t==="select"&&(s=n,r.multiple?s.multiple=!0:r.size&&(s.size=r.size))):n=s.createElementNS(n,t),n[Ot]=e,n[zo]=r,f1(n,e,!1,!1),e.stateNode=n;e:{switch(s=sc(t,r),t){case"dialog":K("cancel",n),K("close",n),i=r;break;case"iframe":case"object":case"embed":K("load",n),i=r;break;case"video":case"audio":for(i=0;ili&&(e.flags|=128,r=!0,xi(o,!1),e.lanes=4194304)}else{if(!r)if(n=Fl(s),n!==null){if(e.flags|=128,r=!0,t=n.updateQueue,t!==null&&(e.updateQueue=t,e.flags|=4),xi(o,!0),o.tail===null&&o.tailMode==="hidden"&&!s.alternate&&!Q)return xe(e),null}else 2*ne()-o.renderingStartTime>li&&t!==1073741824&&(e.flags|=128,r=!0,xi(o,!1),e.lanes=4194304);o.isBackwards?(s.sibling=e.child,e.child=s):(t=o.last,t!==null?t.sibling=s:e.child=s,o.last=s)}return o.tail!==null?(e=o.tail,o.rendering=e,o.tail=e.sibling,o.renderingStartTime=ne(),e.sibling=null,t=Y.current,j(Y,r?t&1|2:t&1),e):(xe(e),null);case 22:case 23:return sd(),r=e.memoizedState!==null,n!==null&&n.memoizedState!==null!==r&&(e.flags|=8192),r&&e.mode&1?Ge&1073741824&&(xe(e),e.subtreeFlags&6&&(e.flags|=8192)):xe(e),null;case 24:return null;case 25:return null}throw Error(N(156,e.tag))}function XN(n,e){switch(Vf(e),e.tag){case 1:return He(e.type)&&Tl(),n=e.flags,n&65536?(e.flags=n&-65537|128,e):null;case 3:return oi(),q(Ue),q(Oe),Qf(),n=e.flags,n&65536&&!(n&128)?(e.flags=n&-65537|128,e):null;case 5:return qf(e),null;case 13:if(q(Y),n=e.memoizedState,n!==null&&n.dehydrated!==null){if(e.alternate===null)throw Error(N(340));ri()}return n=e.flags,n&65536?(e.flags=n&-65537|128,e):null;case 19:return q(Y),null;case 4:return oi(),null;case 10:return Uf(e.type._context),null;case 22:case 23:return sd(),null;case 24:return null;default:return null}}var Os=!1,Ne=!1,ZN=typeof WeakSet=="function"?WeakSet:Set,D=null;function zr(n,e){var t=n.ref;if(t!==null)if(typeof t=="function")try{t(null)}catch(r){Z(n,e,r)}else t.current=null}function Ic(n,e,t){try{t()}catch(r){Z(n,e,r)}}var Pp=!1;function eM(n,e){if(gc=Ml,n=y0(),$f(n)){if("selectionStart"in n)var t={start:n.selectionStart,end:n.selectionEnd};else e:{t=(t=n.ownerDocument)&&t.defaultView||window;var r=t.getSelection&&t.getSelection();if(r&&r.rangeCount!==0){t=r.anchorNode;var i=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{t.nodeType,o.nodeType}catch{t=null;break e}var s=0,l=-1,a=-1,u=0,c=0,f=n,d=null;t:for(;;){for(var p;f!==t||i!==0&&f.nodeType!==3||(l=s+i),f!==o||r!==0&&f.nodeType!==3||(a=s+r),f.nodeType===3&&(s+=f.nodeValue.length),(p=f.firstChild)!==null;)d=f,f=p;for(;;){if(f===n)break t;if(d===t&&++u===i&&(l=s),d===o&&++c===r&&(a=s),(p=f.nextSibling)!==null)break;f=d,d=f.parentNode}f=p}t=l===-1||a===-1?null:{start:l,end:a}}else t=null}t=t||{start:0,end:0}}else t=null;for(yc={focusedElem:n,selectionRange:t},Ml=!1,D=e;D!==null;)if(e=D,n=e.child,(e.subtreeFlags&1028)!==0&&n!==null)n.return=e,D=n;else for(;D!==null;){e=D;try{var h=e.alternate;if(e.flags&1024)switch(e.tag){case 0:case 11:case 15:break;case 1:if(h!==null){var m=h.memoizedProps,w=h.memoizedState,g=e.stateNode,y=g.getSnapshotBeforeUpdate(e.elementType===e.type?m:yt(e.type,m),w);g.__reactInternalSnapshotBeforeUpdate=y}break;case 3:var S=e.stateNode.containerInfo;S.nodeType===1?S.textContent="":S.nodeType===9&&S.documentElement&&S.removeChild(S.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(N(163))}}catch(x){Z(e,e.return,x)}if(n=e.sibling,n!==null){n.return=e.return,D=n;break}D=e.return}return h=Pp,Pp=!1,h}function ao(n,e,t){var r=e.updateQueue;if(r=r!==null?r.lastEffect:null,r!==null){var i=r=r.next;do{if((i.tag&n)===n){var o=i.destroy;i.destroy=void 0,o!==void 0&&Ic(e,t,o)}i=i.next}while(i!==r)}}function oa(n,e){if(e=e.updateQueue,e=e!==null?e.lastEffect:null,e!==null){var t=e=e.next;do{if((t.tag&n)===n){var r=t.create;t.destroy=r()}t=t.next}while(t!==e)}}function zc(n){var e=n.ref;if(e!==null){var t=n.stateNode;switch(n.tag){case 5:n=t;break;default:n=t}typeof e=="function"?e(n):e.current=n}}function p1(n){var e=n.alternate;e!==null&&(n.alternate=null,p1(e)),n.child=null,n.deletions=null,n.sibling=null,n.tag===5&&(e=n.stateNode,e!==null&&(delete e[Ot],delete e[zo],delete e[kc],delete e[FN],delete e[LN])),n.stateNode=null,n.return=null,n.dependencies=null,n.memoizedProps=null,n.memoizedState=null,n.pendingProps=null,n.stateNode=null,n.updateQueue=null}function m1(n){return n.tag===5||n.tag===3||n.tag===4}function Fp(n){e:for(;;){for(;n.sibling===null;){if(n.return===null||m1(n.return))return null;n=n.return}for(n.sibling.return=n.return,n=n.sibling;n.tag!==5&&n.tag!==6&&n.tag!==18;){if(n.flags&2||n.child===null||n.tag===4)continue e;n.child.return=n,n=n.child}if(!(n.flags&2))return n.stateNode}}function Pc(n,e,t){var r=n.tag;if(r===5||r===6)n=n.stateNode,e?t.nodeType===8?t.parentNode.insertBefore(n,e):t.insertBefore(n,e):(t.nodeType===8?(e=t.parentNode,e.insertBefore(n,t)):(e=t,e.appendChild(n)),t=t._reactRootContainer,t!=null||e.onclick!==null||(e.onclick=Dl));else if(r!==4&&(n=n.child,n!==null))for(Pc(n,e,t),n=n.sibling;n!==null;)Pc(n,e,t),n=n.sibling}function Fc(n,e,t){var r=n.tag;if(r===5||r===6)n=n.stateNode,e?t.insertBefore(n,e):t.appendChild(n);else if(r!==4&&(n=n.child,n!==null))for(Fc(n,e,t),n=n.sibling;n!==null;)Fc(n,e,t),n=n.sibling}var pe=null,St=!1;function en(n,e,t){for(t=t.child;t!==null;)g1(n,e,t),t=t.sibling}function g1(n,e,t){if(At&&typeof At.onCommitFiberUnmount=="function")try{At.onCommitFiberUnmount(Gl,t)}catch{}switch(t.tag){case 5:Ne||zr(t,e);case 6:var r=pe,i=St;pe=null,en(n,e,t),pe=r,St=i,pe!==null&&(St?(n=pe,t=t.stateNode,n.nodeType===8?n.parentNode.removeChild(t):n.removeChild(t)):pe.removeChild(t.stateNode));break;case 18:pe!==null&&(St?(n=pe,t=t.stateNode,n.nodeType===8?su(n.parentNode,t):n.nodeType===1&&su(n,t),To(n)):su(pe,t.stateNode));break;case 4:r=pe,i=St,pe=t.stateNode.containerInfo,St=!0,en(n,e,t),pe=r,St=i;break;case 0:case 11:case 14:case 15:if(!Ne&&(r=t.updateQueue,r!==null&&(r=r.lastEffect,r!==null))){i=r=r.next;do{var o=i,s=o.destroy;o=o.tag,s!==void 0&&(o&2||o&4)&&Ic(t,e,s),i=i.next}while(i!==r)}en(n,e,t);break;case 1:if(!Ne&&(zr(t,e),r=t.stateNode,typeof r.componentWillUnmount=="function"))try{r.props=t.memoizedProps,r.state=t.memoizedState,r.componentWillUnmount()}catch(l){Z(t,e,l)}en(n,e,t);break;case 21:en(n,e,t);break;case 22:t.mode&1?(Ne=(r=Ne)||t.memoizedState!==null,en(n,e,t),Ne=r):en(n,e,t);break;default:en(n,e,t)}}function Lp(n){var e=n.updateQueue;if(e!==null){n.updateQueue=null;var t=n.stateNode;t===null&&(t=n.stateNode=new ZN),e.forEach(function(r){var i=uM.bind(null,n,r);t.has(r)||(t.add(r),r.then(i,i))})}}function gt(n,e){var t=e.deletions;if(t!==null)for(var r=0;ri&&(i=s),r&=~o}if(r=i,r=ne()-r,r=(120>r?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*nM(r/1960))-r,10n?16:n,mn===null)var r=!1;else{if(n=mn,mn=null,Jl=0,V&6)throw Error(N(331));var i=V;for(V|=4,D=n.current;D!==null;){var o=D,s=o.child;if(D.flags&16){var l=o.deletions;if(l!==null){for(var a=0;ane()-id?er(n,0):rd|=t),je(n,e)}function N1(n,e){e===0&&(n.mode&1?(e=Ss,Ss<<=1,!(Ss&130023424)&&(Ss=4194304)):e=1);var t=Ae();n=Gt(n,e),n!==null&&(Xo(n,e,t),je(n,t))}function aM(n){var e=n.memoizedState,t=0;e!==null&&(t=e.retryLane),N1(n,t)}function uM(n,e){var t=0;switch(n.tag){case 13:var r=n.stateNode,i=n.memoizedState;i!==null&&(t=i.retryLane);break;case 19:r=n.stateNode;break;default:throw Error(N(314))}r!==null&&r.delete(e),N1(n,t)}var M1;M1=function(n,e,t){if(n!==null)if(n.memoizedProps!==e.pendingProps||Ue.current)_e=!0;else{if(!(n.lanes&t)&&!(e.flags&128))return _e=!1,YN(n,e,t);_e=!!(n.flags&131072)}else _e=!1,Q&&e.flags&1048576&&D0(e,bl,e.index);switch(e.lanes=0,e.tag){case 2:var r=e.type;il(n,e),n=e.pendingProps;var i=ni(e,Oe.current);Wr(e,t),i=Gf(null,e,r,n,i,t);var o=Xf();return e.flags|=1,typeof i=="object"&&i!==null&&typeof i.render=="function"&&i.$$typeof===void 0?(e.tag=1,e.memoizedState=null,e.updateQueue=null,He(r)?(o=!0,Rl(e)):o=!1,e.memoizedState=i.state!==null&&i.state!==void 0?i.state:null,jf(e),i.updater=ra,e.stateNode=i,i._reactInternals=e,Ec(e,r,n,t),e=Tc(null,e,r,!0,o,t)):(e.tag=0,Q&&o&&Bf(e),Te(null,e,i,t),e=e.child),e;case 16:r=e.elementType;e:{switch(il(n,e),n=e.pendingProps,i=r._init,r=i(r._payload),e.type=r,i=e.tag=fM(r),n=yt(r,n),i){case 0:e=Dc(null,e,r,n,t);break e;case 1:e=bp(null,e,r,n,t);break e;case 11:e=Rp(null,e,r,n,t);break e;case 14:e=Ap(null,e,r,yt(r.type,n),t);break e}throw Error(N(306,r,""))}return e;case 0:return r=e.type,i=e.pendingProps,i=e.elementType===r?i:yt(r,i),Dc(n,e,r,i,t);case 1:return r=e.type,i=e.pendingProps,i=e.elementType===r?i:yt(r,i),bp(n,e,r,i,t);case 3:e:{if(a1(e),n===null)throw Error(N(387));r=e.pendingProps,o=e.memoizedState,i=o.element,b0(n,e),Pl(e,r,null,t);var s=e.memoizedState;if(r=s.element,o.isDehydrated)if(o={element:r,isDehydrated:!1,cache:s.cache,pendingSuspenseBoundaries:s.pendingSuspenseBoundaries,transitions:s.transitions},e.updateQueue.baseState=o,e.memoizedState=o,e.flags&256){i=si(Error(N(423)),e),e=Ip(n,e,r,t,i);break e}else if(r!==i){i=si(Error(N(424)),e),e=Ip(n,e,r,t,i);break e}else for(Ze=vn(e.stateNode.containerInfo.firstChild),tt=e,Q=!0,kt=null,t=F0(e,null,r,t),e.child=t;t;)t.flags=t.flags&-3|4096,t=t.sibling;else{if(ri(),r===i){e=Xt(n,e,t);break e}Te(n,e,r,t)}e=e.child}return e;case 5:return L0(e),n===null&&Cc(e),r=e.type,i=e.pendingProps,o=n!==null?n.memoizedProps:null,s=i.children,Sc(r,i)?s=null:o!==null&&Sc(r,o)&&(e.flags|=32),l1(n,e),Te(n,e,s,t),e.child;case 6:return n===null&&Cc(e),null;case 13:return u1(n,e,t);case 4:return Kf(e,e.stateNode.containerInfo),r=e.pendingProps,n===null?e.child=ii(e,null,r,t):Te(n,e,r,t),e.child;case 11:return r=e.type,i=e.pendingProps,i=e.elementType===r?i:yt(r,i),Rp(n,e,r,i,t);case 7:return Te(n,e,e.pendingProps,t),e.child;case 8:return Te(n,e,e.pendingProps.children,t),e.child;case 12:return Te(n,e,e.pendingProps.children,t),e.child;case 10:e:{if(r=e.type._context,i=e.pendingProps,o=e.memoizedProps,s=i.value,j(Il,r._currentValue),r._currentValue=s,o!==null)if(Nt(o.value,s)){if(o.children===i.children&&!Ue.current){e=Xt(n,e,t);break e}}else for(o=e.child,o!==null&&(o.return=e);o!==null;){var l=o.dependencies;if(l!==null){s=o.child;for(var a=l.firstContext;a!==null;){if(a.context===r){if(o.tag===1){a=qt(-1,t&-t),a.tag=2;var u=o.updateQueue;if(u!==null){u=u.shared;var c=u.pending;c===null?a.next=a:(a.next=c.next,c.next=a),u.pending=a}}o.lanes|=t,a=o.alternate,a!==null&&(a.lanes|=t),Nc(o.return,t,e),l.lanes|=t;break}a=a.next}}else if(o.tag===10)s=o.type===e.type?null:o.child;else if(o.tag===18){if(s=o.return,s===null)throw Error(N(341));s.lanes|=t,l=s.alternate,l!==null&&(l.lanes|=t),Nc(s,t,e),s=o.sibling}else s=o.child;if(s!==null)s.return=o;else for(s=o;s!==null;){if(s===e){s=null;break}if(o=s.sibling,o!==null){o.return=s.return,s=o;break}s=s.return}o=s}Te(n,e,i.children,t),e=e.child}return e;case 9:return i=e.type,r=e.pendingProps.children,Wr(e,t),i=ht(i),r=r(i),e.flags|=1,Te(n,e,r,t),e.child;case 14:return r=e.type,i=yt(r,e.pendingProps),i=yt(r.type,i),Ap(n,e,r,i,t);case 15:return o1(n,e,e.type,e.pendingProps,t);case 17:return r=e.type,i=e.pendingProps,i=e.elementType===r?i:yt(r,i),il(n,e),e.tag=1,He(r)?(n=!0,Rl(e)):n=!1,Wr(e,t),z0(e,r,i),Ec(e,r,i,t),Tc(null,e,r,!0,n,t);case 19:return c1(n,e,t);case 22:return s1(n,e,t)}throw Error(N(156,e.tag))};function E1(n,e){return Xy(n,e)}function cM(n,e,t,r){this.tag=n,this.key=t,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=e,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function ct(n,e,t,r){return new cM(n,e,t,r)}function ad(n){return n=n.prototype,!(!n||!n.isReactComponent)}function fM(n){if(typeof n=="function")return ad(n)?1:0;if(n!=null){if(n=n.$$typeof,n===Of)return 11;if(n===Df)return 14}return 2}function Mn(n,e){var t=n.alternate;return t===null?(t=ct(n.tag,e,n.key,n.mode),t.elementType=n.elementType,t.type=n.type,t.stateNode=n.stateNode,t.alternate=n,n.alternate=t):(t.pendingProps=e,t.type=n.type,t.flags=0,t.subtreeFlags=0,t.deletions=null),t.flags=n.flags&14680064,t.childLanes=n.childLanes,t.lanes=n.lanes,t.child=n.child,t.memoizedProps=n.memoizedProps,t.memoizedState=n.memoizedState,t.updateQueue=n.updateQueue,e=n.dependencies,t.dependencies=e===null?null:{lanes:e.lanes,firstContext:e.firstContext},t.sibling=n.sibling,t.index=n.index,t.ref=n.ref,t}function ll(n,e,t,r,i,o){var s=2;if(r=n,typeof n=="function")ad(n)&&(s=1);else if(typeof n=="string")s=5;else e:switch(n){case Mr:return tr(t.children,i,o,e);case Ef:s=8,i|=8;break;case Yu:return n=ct(12,t,e,i|2),n.elementType=Yu,n.lanes=o,n;case Gu:return n=ct(13,t,e,i),n.elementType=Gu,n.lanes=o,n;case Xu:return n=ct(19,t,e,i),n.elementType=Xu,n.lanes=o,n;case Py:return la(t,i,o,e);default:if(typeof n=="object"&&n!==null)switch(n.$$typeof){case Iy:s=10;break e;case zy:s=9;break e;case Of:s=11;break e;case Df:s=14;break e;case rn:s=16,r=null;break e}throw Error(N(130,n==null?n:typeof n,""))}return e=ct(s,t,e,i),e.elementType=n,e.type=r,e.lanes=o,e}function tr(n,e,t,r){return n=ct(7,n,r,e),n.lanes=t,n}function la(n,e,t,r){return n=ct(22,n,r,e),n.elementType=Py,n.lanes=t,n.stateNode={isHidden:!1},n}function pu(n,e,t){return n=ct(6,n,null,e),n.lanes=t,n}function mu(n,e,t){return e=ct(4,n.children!==null?n.children:[],n.key,e),e.lanes=t,e.stateNode={containerInfo:n.containerInfo,pendingChildren:null,implementation:n.implementation},e}function dM(n,e,t,r,i){this.tag=e,this.containerInfo=n,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Qa(0),this.expirationTimes=Qa(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Qa(0),this.identifierPrefix=r,this.onRecoverableError=i,this.mutableSourceEagerHydrationData=null}function ud(n,e,t,r,i,o,s,l,a){return n=new dM(n,e,t,l,a),e===1?(e=1,o===!0&&(e|=8)):e=0,o=ct(3,null,null,e),n.current=o,o.stateNode=n,o.memoizedState={element:r,isDehydrated:t,cache:null,transitions:null,pendingSuspenseBoundaries:null},jf(o),n}function hM(n,e,t){var r=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(R1)}catch(n){console.error(n)}}R1(),Dy.exports=rt;var ai=Dy.exports,A1,Hp=ai;A1=Hp.createRoot,Hp.hydrateRoot;const pi=C.createContext(null),b1=C.createContext(null);function SM(n){const e=Object.create(null);return e.class="ProseMirror",e.contenteditable=String(n.editable),n.someProp("attributes",t=>{if(typeof t=="function"&&(t=t(n.state)),t)for(const r in t)r=="class"?e.class+=" "+t[r]:r=="style"?e.style=(e.style?e.style+";":"")+t[r]:!e[r]&&r!="contenteditable"&&r!="nodeName"&&(e[r]=String(t[r]))}),e.translate||(e.translate="no"),[ye.node(0,n.state.doc.content.size,e)]}const wM=[],kM={},Jc=_.empty;class Un{constructor(e){this.members=e}map(e,t){const r=this.members.map(i=>i.map(e,t,kM));return Un.from(r)}forChild(e,t){if(t.isLeaf)return _.empty;let r=[];for(let i=0;it instanceof _)?e:e.reduce((t,r)=>t.concat(r instanceof _?r:r.members),[]))}}forEachSet(e){for(let t=0;t0;)e++;n.splice(e,0,t)}function xM(n,e){const t=[];return n.someProp("decorations",r=>{const i=r(n.state);i&&i!=Jc&&t.push(i)}),e&&t.push(_.create(n.state.doc,[e])),Un.from(t)}const hd=function(n){for(let e=0;;e++)if(n=n.previousSibling,!n)return e},Kp=function(n){const e=n.assignedSlot||n.parentNode;return e&&e.nodeType==11?e.host:e},CM=function(n,e,t,r){return t&&(qp(n,e,t,r,-1)||qp(n,e,t,r,1))},NM=/^(img|br|input|textarea|hr)$/i;function qp(n,e,t,r,i){for(;;){if(n==t&&e==r)return!0;if(e==(i<0?0:Ul(n))){const o=n.parentNode;if(!o||o.nodeType!=1||EM(n)||NM.test(n.nodeName)||n.contentEditable=="false")return!1;e=hd(n)+(i<0?0:1),n=o}else if(n.nodeType==1){if(n=n.childNodes[e+(i<0?-1:0)],n.contentEditable=="false")return!1;e=i<0?Ul(n):0}else return!1}}function Ul(n){return n.nodeType==3?n.nodeValue.length:n.childNodes.length}function MM(n,e,t){for(let r=e==0,i=e==Ul(n);r||i;){if(n==t)return!0;const o=hd(n);if(n=n.parentNode,!n)return!1;r=r&&o==0,i=i&&o==Ul(n)}return!1}function EM(n){let e;for(let t=n;t&&!(e=t.pmViewDesc);t=t.parentNode);return e&&e.node&&e.node.isBlock&&(e.dom==n||e.contentDOM==n)}const z1=function(n){return n.focusNode&&CM(n.focusNode,n.focusOffset,n.anchorNode,n.anchorOffset)},P1=C.createContext(null);function OM(n,e){const t=C.useContext(P1);C.useLayoutEffect(()=>t(n),e)}function F1(n,e){const{view:t}=C.useContext(pi);OM(()=>{if(t)return n(t)},e&&[t,...e])}const DM=C.forwardRef(function({widget:e,pos:t,...r},i){const[o,s]=C.useState(!0),l=C.useRef(null);return C.useImperativeHandle(i,()=>l.current,[]),F1(a=>{if(!a||!l.current)return;a.domObserver.disconnectSelection();const u=a.domSelection(),c=document.createRange(),f=l.current;f.nodeName=="IMG"&&f.parentNode?c.setEnd(f.parentNode,hd(f)+1):c.setEnd(f,0),c.collapse(!1),u.removeAllRanges(),u.addRange(c),s(!1),a.domObserver.connectSelection()},[]),o?A.jsx("img",{ref:l,className:"ProseMirror-separator","mark-placeholder":"true",alt:"",...r}):null});function TM(n,e){if(n==e)return!0;for(const t in n)if(n[t]!==e[t])return!1;for(const t in e)if(!(t in n))return!1;return!0}const RM={side:0};class Jo{constructor(e,t){this.Component=e,this.spec=t??RM,this.side=this.spec.side??0}map(e,t,r,i){const{pos:o,deleted:s}=e.mapResult(t.from+i,this.side<0?-1:1);return s?null:new ye(o-r,o-r,this)}valid(){return!0}eq(e){return this==e||e instanceof Jo&&(this.spec.key&&this.spec.key==e.spec.key||this.Component==e.Component&&TM(this.spec,e.spec))}destroy(){}}function L1(n,e,t){return new ye(n,n,new Jo(e,t))}function gu(){return Math.floor(Math.random()*16777215).toString(16)}const _o=new Ko("@nytimes/react-prosemirror/reactKeys");function AM(){let n=!1;return new $t({key:_o,state:{init(e,t){const r={posToKey:new Map,keyToPos:new Map};return t.doc.descendants((i,o)=>{const s=gu();return r.posToKey.set(o,s),r.keyToPos.set(s,o),!0}),r},apply(e,t,r,i){if(!e.docChanged||n)return t;const o=e.getMeta(_o),s=(o==null?void 0:o.type)==="bustKey"&&o.payload.key,l={posToKey:new Map,keyToPos:new Map},a=Array.from(t.posToKey.entries()).sort(([u],[c])=>u-c);for(const[u,c]of a){const{pos:f,deleted:d}=e.mapping.mapResult(u);if(d)continue;let p=c;s===c&&(p=gu()),l.posToKey.set(f,p),l.keyToPos.set(p,f)}return i.doc.descendants((u,c)=>{if(l.posToKey.has(c))return!0;const f=gu();return l.posToKey.set(c,f),l.keyToPos.set(f,c),!0}),l}},props:{handleDOMEvents:{compositionstart:()=>{n=!0},compositionend:()=>{n=!1}}}})}function yu(n,e,t={}){var s;if(e===null)return!1;const r=t.from??n.state.selection.from,i=t.to??n.state.selection.to;if(n.someProp("handleTextInput",l=>l(n,r,i,e)))return!0;const{tr:o}=n.state;if(t.marks&&o.ensureMarks(t.marks),o.insertText(e,r,i),t.bust){const l=n.state.doc.resolve(r),a=l.sharedDepth(i),u=l.start(a),c=(s=_o.getState(n.state))==null?void 0:s.posToKey.get(u-1);o.setMeta(_o,{type:"bustKey",payload:{key:c}})}return n.dispatch(o),!0}function bM(n){let e=null,t=null;return new $t({props:{handleDOMEvents:{compositionstart(r){var s;const{state:i}=r;r.dispatch(i.tr.deleteSelection());const o=i.selection.$from;return i.selection.empty&&(i.storedMarks||!o.textOffset&&o.parentOffset&&((s=o.nodeBefore)!=null&&s.marks.some(l=>l.type.spec.inclusive===!1)))&&n(L1(i.selection.from,DM,{key:"cursor-wrapper",marks:i.storedMarks??o.marks()})),t=i.storedMarks??o.marks(),r.input.composing=!0,!0},compositionupdate(){return!0},compositionend(r){if(r.input.composing=!1,e!==null)return yu(r,e,{bust:!0,marks:t}),e=null,t=null,n(null),!0},beforeinput(r,i){var o,s;switch(i.preventDefault(),i.inputType){case"insertCompositionText":{if(i.data===null)break;e=i.data;break}case"insertReplacementText":{const l=i.getTargetRanges();(s=(o=i.dataTransfer)==null?void 0:o.items[0])==null||s.getAsString(a=>{for(const u of l){const c=r.posAtDOM(u.startContainer,u.startOffset,1),f=r.posAtDOM(u.endContainer,u.endOffset,1);yu(r,a,{from:c,to:f})}});break}case"insertText":{yu(r,i.data);break}case"deleteWordBackward":case"deleteContentBackward":case"deleteWordForward":case"deleteContentForward":case"deleteContent":{const l=i.getTargetRanges(),{tr:a}=r.state;for(const u of l){const c=r.posAtDOM(u.startContainer,u.startOffset),f=r.posAtDOM(u.endContainer,u.endOffset),{doc:d}=r.state,p=d.resolve(c).marksAcross(d.resolve(f));a.delete(c,f).setStoredMarks(p)}r.dispatch(a);break}}return!0}}}})}const Lt=typeof navigator<"u"?navigator:null,Qp=typeof document<"u"?document:null,zn=Lt&&Lt.userAgent||"",_c=/Edge\/(\d+)/.exec(zn),$1=/MSIE \d/.exec(zn),Wc=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(zn),da=!!($1||Wc||_c),IM=$1?document.documentMode:Wc?+Wc[1]:_c?+_c[1]:0,B1=!da&&/gecko\/(\d+)/i.test(zn),zM=B1&&+(/Firefox\/(\d+)/.exec(zn)||[0,0])[1],Uc=!da&&/Chrome\/(\d+)/.exec(zn),PM=!!Uc,FM=Uc?+Uc[1]:0,V1=!da&&!!Lt&&/Apple Computer/.test(Lt.vendor),J1=V1&&(/Mobile\/\w+/.test(zn)||!!Lt&&Lt.maxTouchPoints>2),LM=J1||(Lt?/Mac/.test(Lt.platform):!1),$M=Lt?/Win/.test(Lt.platform):!1,BM=/Android \d/.test(zn),_1=!!Qp&&"webkitFontSmoothing"in Qp.documentElement.style,VM=_1?+(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent)||[0,0])[1]:0,Ee={ie:da,ie_version:IM,gecko:B1,gecko_version:zM,chrome:PM,chrome_version:FM,safari:V1,ios:J1,mac:LM,windows:$M,android:BM,webkit:_1,webkit_version:VM};function Su(n){return n.editable&&!n.hasFocus()?!1:JM(n)}function JM(n){var t,r;const e=n.domSelectionRange();if(!e.anchorNode)return!1;try{return n.dom.contains(e.anchorNode.nodeType==3?e.anchorNode.parentNode:e.anchorNode)&&(n.editable||n.dom.contains(((t=e.focusNode)==null?void 0:t.nodeType)==3?(r=e.focusNode)==null?void 0:r.parentNode:e.focusNode))}catch{return!1}}function _M(n,e,t,r){return n.someProp("createSelectionBetween",i=>i(n,e,t))||$.between(e,t,r)}function Yp(n,e=null){const t=n.domSelectionRange(),r=n.state.doc;if(!t.focusNode)return null;let i=n.docView.nearestDesc(t.focusNode);const o=i&&i.size==0;let s=n.docView.posFromDOM(t.focusNode,t.focusOffset,1);if(s<0)return null;let l=r.resolve(s),a,u;if(z1(t)){for(a=s;i&&!i.node;)i=i.parent;const f=i.node;if(i&&f.isAtom&&I.isSelectable(f)&&i.parent&&!(f.isInline&&MM(t.focusNode,t.focusOffset,i.dom))){const d=i.posBefore;u=new I(s==d?l:r.resolve(d))}}else{if(t instanceof n.dom.ownerDocument.defaultView.Selection&&t.rangeCount>1){let f=s,d=s;for(let p=0;p{(r.anchorNode!=i||r.anchorOffset!=o)&&(t.removeEventListener("selectionchange",e.input.hideSelectionGuard),setTimeout(()=>{(!W1(e)||e.state.selection.visible)&&e.dom.classList.remove("ProseMirror-hideselection")},20))})}const nm=Ee.safari||Ee.chrome&&Ee.chrome_version<63;function Rs(n,e=!1){const t=n,r=t.state.selection;if(HM(t,r),!!W1(t)){if(!e&&t.input.mouseDown&&t.input.mouseDown.allowDefault&&Ee.chrome){const i=t.domSelectionRange(),o=t.domObserver.currentSelection;if(i.anchorNode&&o.anchorNode&&Hl(i.anchorNode,i.anchorOffset,o.anchorNode,o.anchorOffset)){t.input.mouseDown.delayedSelectionSync=!0,t.domObserver.setCurSelection();return}}if(t.domObserver.disconnectSelection(),t.cursorWrapper)KM(t);else{const{anchor:i,head:o}=r;let s,l;nm&&!(r instanceof $)&&(r.$from.parent.inlineContent||(s=em(t,r.from)),!r.empty&&!r.$from.parent.inlineContent&&(l=em(t,r.to))),t.docView.setSelection(i,o,t.root,e),nm&&(s&&tm(s),l&&tm(l)),r.visible?t.dom.classList.remove("ProseMirror-hideselection"):(t.dom.classList.add("ProseMirror-hideselection"),"onselectionchange"in document&&qM(t))}t.domObserver.setCurSelection(),t.domObserver.connectSelection()}}class QM{constructor(){this.anchorNode=null,this.anchorOffset=0,this.focusNode=null,this.focusOffset=0}set(e){this.anchorNode=e.anchorNode,this.anchorOffset=e.anchorOffset,this.focusNode=e.focusNode,this.focusOffset=e.focusOffset}clear(){this.anchorNode=this.focusNode=null}eq(e){return e.anchorNode==this.anchorNode&&e.anchorOffset==this.anchorOffset&&e.focusNode==this.focusNode&&e.focusOffset==this.focusOffset}}class YM{constructor(e){this.view=e,this.flushingSoon=-1,this.currentSelection=new QM,this.suppressingSelectionUpdates=!1,this.view=e,this.onSelectionChange=this.onSelectionChange.bind(this)}connectSelection(){this.view.dom.ownerDocument.addEventListener("selectionchange",this.onSelectionChange)}disconnectSelection(){this.view.dom.ownerDocument.removeEventListener("selectionchange",this.onSelectionChange)}stop(){this.disconnectSelection()}start(){this.connectSelection()}suppressSelectionUpdates(){this.suppressingSelectionUpdates=!0,setTimeout(()=>this.suppressingSelectionUpdates=!1,50)}setCurSelection(){this.currentSelection.set(this.view.domSelectionRange())}ignoreSelectionChange(e){if(!e.focusNode)return!0;const t=new Set;let r;for(let o=e.focusNode;o;o=Kp(o))t.add(o);for(let o=e.anchorNode;o;o=Kp(o))if(t.has(o)){r=o;break}const i=r&&this.view.docView.nearestDesc(r);if(i&&i.ignoreMutation({type:"selection",target:(r==null?void 0:r.nodeType)==3?r==null?void 0:r.parentNode:r}))return this.setCurSelection(),!0}registerMutation(){}flushSoon(){this.flushingSoon<0&&(this.flushingSoon=window.setTimeout(()=>{this.flushingSoon=-1,this.flush()},20))}updateSelection(){const{view:e}=this,t=e.input.compositionPendingChanges||(e.composing?e.input.compositionID:0);e.input.compositionPendingChanges=0;const r=e.input.lastSelectionTime>Date.now()-50?e.input.lastSelectionOrigin:null,i=Yp(e,r);if(i&&!e.state.selection.eq(i)){const o=e.state.tr.setSelection(i);r=="pointer"?o.setMeta("pointer",!0):r=="key"&&o.scrollIntoView(),t&&o.setMeta("composition",t),e.dispatch(o)}}selectionToDOM(){const{view:e}=this;Rs(e);const t=e.domSelectionRange();this.currentSelection.set(t)}flush(){const{view:e}=this;if(!e.docView||this.flushingSoon>-1)return;const t=e.domSelectionRange(),r=!this.suppressingSelectionUpdates&&!this.currentSelection.eq(t)&&Su(e)&&!this.ignoreSelectionChange(t);let i=null;r&&e.input.lastFocus>Date.now()-200&&Math.max(e.input.lastTouch,e.input.lastClick.time)-1&&(window.clearTimeout(this.flushingSoon),this.flushingSoon=-1,this.flush())}onSelectionChange(){if(Su(this.view)&&!this.view.composing){if(this.suppressingSelectionUpdates)return Rs(this.view);if(Ee.ie&&Ee.ie_version<=11&&!this.view.state.selection.empty){const e=this.view.domSelectionRange();if(e.focusNode&&Hl(e.focusNode,e.focusOffset,e.anchorNode,e.anchorOffset))return this.flushSoon()}this.flush()}}}const ui=0,rm=1,As=2,Wo=3;class ns{constructor(e,t,r,i){this.parent=e,this.children=t,this.dom=r,this.contentDOM=i,this.dirty=ui,r.pmViewDesc=this}matchesWidget(e){return!1}matchesMark(e){return!1}matchesNode(e,t,r){return!1}matchesHack(e){return!1}parseRule(){return null}stopEvent(e){return!1}get size(){let e=0;for(let t=0;tsn(this.contentDOM);else if(this.contentDOM&&this.contentDOM!=this.dom&&this.dom.contains(this.contentDOM))i=e.compareDocumentPosition(this.contentDOM)&2;else if(this.dom.firstChild){if(t==0)for(let o=e;;o=o.parentNode){if(o==this.dom){i=!1;break}if(o.previousSibling)break}if(i==null&&t==e.childNodes.length)for(let o=e;;o=o.parentNode){if(o==this.dom){i=!0;break}if(o.nextSibling)break}}return i??r>0?this.posAtEnd:this.posAtStart}nearestDesc(e,t=!1){for(let r=!0,i=e;i;i=i.parentNode){const o=this.getDesc(i);let s;if(o&&(!t||o.node))if(r&&(s=o.nodeDOM)&&!(s.nodeType==1?s.contains(e.nodeType==1?e:e.parentNode):s==e))r=!1;else return o}}getDesc(e){const t=e.pmViewDesc;for(let r=t;r;r=r.parent)if(r==this)return t}posFromDOM(e,t,r){for(let i=e;i;i=i.parentNode){const o=this.getDesc(i);if(o)return o.localPosFromDOM(e,t,r)}return-1}descAt(e){for(let t=0,r=0;te||s instanceof gd){i=e-o;break}o=l}if(i)return this.children[r].domFromPos(i-this.children[r].border,t);for(let o;r&&!(o=this.children[r-1]).size&&o instanceof pd&&o.side>=0;r--);if(t<=0){let o,s=!0;for(;o=r?this.children[r-1]:null,!(!o||o.dom.parentNode==this.contentDOM);r--,s=!1);return o&&t&&s&&!o.border&&!o.domAtom?o.domFromPos(o.size,t):{node:this.contentDOM,offset:o?sn(o.dom)+1:0}}else{let o,s=!0;for(;o=r=c&&t<=u-a.border&&a.node&&a.contentDOM&&this.contentDOM.contains(a.contentDOM))return a.parseRange(e,t,c);e=s;for(let f=l;f>0;f--){const d=this.children[f-1];if(d.size&&d.dom.parentNode==this.contentDOM&&!d.emptyChildAt(1)){i=sn(d.dom)+1;break}e-=d.size}i==-1&&(i=0)}if(i>-1&&(u>t||l==this.children.length-1)){t=u;for(let c=l+1;ch&&st){const h=l;l=a,a=h}const p=document.createRange();p.setEnd(a.node,a.offset),p.setStart(l.node,l.offset),u.removeAllRanges(),u.addRange(p)}}ignoreMutation(e){return!this.contentDOM&&e.type!="selection"}get contentLost(){return this.contentDOM&&this.contentDOM!=this.dom&&!this.dom.contains(this.contentDOM)}markDirty(e,t){for(let r=0,i=0;i=r:er){const l=r+o.border,a=s-o.border;if(e>=l&&t<=a){this.dirty=e==r||t==s?As:rm,e==l&&t==a&&(o.contentLost||o.dom.parentNode!=this.contentDOM)?o.dirty=Wo:o.markDirty(e-l,t-l);return}else o.dirty=o.dom==o.contentDOM&&o.dom.parentNode==this.contentDOM&&!o.children.length?As:Wo}r=s}this.dirty=As}markParentsDirty(){let e=1;for(let t=this.parent;t;t=t.parent,e++){const r=e==1?As:rm;t.dirtythis.node.content;else if(!this.contentLost)e.contentElement=this.contentDOM;else{for(let t=this.children.length-1;t>=0;t--){const r=this.children[t];if(this.dom.contains(r.dom.parentNode)){e.contentElement=r.dom.parentNode;break}}e.contentElement||(e.getContent=()=>v.empty)}return e}matchesNode(e,t,r){return this.dirty==ui&&e.eq(this.node)&&ZM(t,this.outerDeco)&&r.eq(this.innerDeco)}get size(){return this.node.nodeSize}get border(){return this.node.isLeaf?0:1}update(e,t,r,i){return!0}selectNode(){this.nodeDOM.nodeType==1&&this.nodeDOM.classList.add("ProseMirror-selectednode"),(this.contentDOM||!this.node.type.spec.draggable)&&(this.dom.draggable=!0)}deselectNode(){this.nodeDOM.nodeType==1&&(this.nodeDOM.classList.remove("ProseMirror-selectednode"),(this.contentDOM||!this.node.type.spec.draggable)&&this.dom.removeAttribute("draggable"))}get domAtom(){return this.node.isAtom}}class XM extends md{constructor(e,t,r,i,o,s,l){super(e,t,r,i,o,s,null,l,()=>!1)}parseRule(){let e=this.nodeDOM.parentNode;for(;e&&e!=this.dom&&!e.pmIsDeco;)e=e.parentNode;return{skip:e||!0}}update(e,t,r,i){return!0}inParent(){const e=this.parent.contentDOM;for(let t=this.nodeDOM;t;t=t.parentNode)if(t==e)return!0;return!1}domFromPos(e){return{node:this.nodeDOM,offset:e}}localPosFromDOM(e,t,r){return e==this.nodeDOM?this.posAtStart+Math.min(t,this.node.text.length):super.localPosFromDOM(e,t,r)}ignoreMutation(e){return e.type!="characterData"&&e.type!="selection"}markDirty(e,t){super.markDirty(e,t),this.dom!=this.nodeDOM&&(e==0||t==this.nodeDOM.nodeValue.length)&&(this.dirty=Wo)}get domAtom(){return!1}}class gd extends ns{parseRule(){return{ignore:!0}}matchesHack(e){return this.dirty==ui&&this.dom.nodeName==e}get domAtom(){return!0}get ignoreForCoords(){return this.dom.nodeName=="IMG"}}function ZM(n,e){if(n.length!=e.length)return!1;for(let t=0;t{u=!!a.call(this,s,l)}),u||l.defaultPrevented)return!0}return!1};e[r]=o}return new $t({key:new Ko("@nytimes/react-prosemirror/componentEventListeners"),props:{handleDOMEvents:e}})}function tE(){const[n,e]=C.useState(new Map),t=C.useCallback((o,s)=>{const l=n.get(o)??[];l.unshift(s),n.has(o)||(n.set(o,l),e(new Map(n)))},[n]),r=C.useCallback((o,s)=>{const l=n.get(o);l==null||l.splice(l.indexOf(s),1)},[n]),i=C.useMemo(()=>eE(n),[n]);return{registerEventListener:t,unregisterEventListener:r,componentEventListenersPlugin:i}}function U1(){const[,n]=C.useReducer(e=>e+1,0);return n}function nE(n){const e=Object.create(null);function t(r){for(const i in r)Object.prototype.hasOwnProperty.call(e,i)||(e[i]=r[i])}return n.someProp("nodeViews",t),n.someProp("markViews",t),e}function rE(n,e){let t=0,r=0;for(const i in n){if(n[i]!=e[i])return!0;t++}for(const i in e)r++;return t!=r}function iE(n,e){for(const t of Object.keys(n))if(n[t]!==e[t])return!0;return!1}function im(n){return!n.someProp("editable",e=>e(n.state)===!1)}class oE extends Iv{constructor(e,t){super(e,{state:cn.create({schema:t.state.schema,plugins:t.state.plugins}),plugins:t.plugins}),this.shouldUpdatePluginViews=!1,this.shouldUpdatePluginViews=!0,this._props=t,this.oldProps={state:t.state},this.state=t.state,this.domObserver.stop(),this.domObserver=new YM(this),this.domObserver.start(),this.editable=im(this),this.docView.dom.replaceChildren(),this.docView=t.docView}get needsRedraw(){if(this.oldProps.state.plugins===this._props.state.plugins&&this._props.plugins===this.oldProps.plugins)return!1;const e=nE(this);return rE(this.nodeViews,e)}pureSetProps(e){this._props={...this._props,...e},this.state=this._props.state,this.editable=im(this)}runPendingEffects(){if(iE(this.props,this.oldProps)){const e=this.props;this._props=this.oldProps,this.state=this._props.state,this.update(e)}}update(e){super.update(e),this.oldProps=e}updatePluginViews(e){this.shouldUpdatePluginViews&&super.updatePluginViews(e)}destroy(){this.dom=document.createElement("div"),super.destroy()}}const sE=new Rm({nodes:{doc:{content:"text*"},text:{inline:!0}}}),lE=cn.create({schema:sE});function aE(n,e){const[t,r]=C.useState(null),[i,o]=C.useState(null),s=U1(),l=e.defaultState??lE,[a,u]=C.useState(l),c=e.state??a,{componentEventListenersPlugin:f,registerEventListener:d,unregisterEventListener:p}=tE(),h=C.useCallback(x=>{ai.flushSync(()=>{o(x)})},[]),m=C.useMemo(()=>[...e.plugins??[],f,bM(h)],[e.plugins,f,h]),w=C.useCallback(function(M){ai.flushSync(()=>{e.state||u(E=>E.apply(M)),e.dispatchTransaction&&e.dispatchTransaction.call(this,M)})},[e.dispatchTransaction,e.state]),g=document.createElement("div"),y=C.useRef(new md(void 0,[],c.doc,[],_.empty,g,null,g,()=>!1)),S={...e,state:c,plugins:m,dispatchTransaction:w,docView:y.current};return C.useLayoutEffect(()=>()=>{t==null||t.destroy()},[t]),C.useLayoutEffect(()=>{if(t&&t.dom!==n&&r(null),!!n&&!t){const x=new oE({mount:n},S);r(x),x.dom.addEventListener("compositionend",s);return}}),C.useLayoutEffect(()=>{if(t!=null&&t.needsRedraw){r(null);return}else t==null||t.domObserver.selectionToDOM(),t==null||t.runPendingEffects()}),t==null||t.pureSetProps(S),C.useMemo(()=>({view:t,state:c,registerEventListener:d,unregisterEventListener:p,cursorWrapper:i,docViewDescRef:y}),[t,c,d,p,i])}function uE({children:n}){const e=C.useRef(new Set).current,t=C.useRef(new Set).current,r=C.useRef(!1),i=U1(),o=C.useRef(!0),s=C.useCallback(()=>{o.current||(i(),o.current=!0)},[i]),l=C.useCallback(a=>{let u;const c=()=>{u=a()};return e.add(c),s(),()=>{e.delete(c),u&&(r.current?(t.add(u),s()):u())}},[e,t,s]);return C.useLayoutEffect(()=>(o.current=!1,e.forEach(a=>a()),e.clear(),()=>{t.forEach(a=>a()),t.clear()})),C.useLayoutEffect(()=>(r.current=!0,()=>{r.current=!1}),[]),A.jsx(P1.Provider,{value:l,children:n})}const mt=C.createContext([]);function H1(n,e,t,r,i,o,s){const{view:l}=C.useContext(pi),[a,u]=C.useState(!0),c=C.useRef(o),f=C.useRef(()=>!1),d=C.useCallback(m=>{f.current=m},[]),p=C.useContext(mt),h=[];return C.useLayoutEffect(()=>{var w;if(!n||!t.current)return;const m=h[0];c.current?(c.current.parent=void 0,c.current.children=h,c.current.node=n,c.current.outerDeco=i,c.current.innerDeco=r,c.current.dom=(e==null?void 0:e.current)??t.current,c.current.dom.pmViewDesc=c.current,c.current.contentDOM=(s==null?void 0:s.current)??c.current.contentDOM??(m==null?void 0:m.dom.parentElement)??null,c.current.nodeDOM=t.current):c.current=new md(void 0,h,n,i,r,(e==null?void 0:e.current)??t.current,(m==null?void 0:m.dom.parentElement)??null,t.current,g=>!!f.current(g)),u(c.current.contentDOM!==null),p.push(c.current);for(const g of h)if(g.parent=c.current,g instanceof jl){const y=(w=c.current.contentDOM)==null?void 0:w.firstChild;if(!y)throw new Error("Started a composition but couldn't find the text node it belongs to.");let S=y;for(;S.firstChild;)S=S.firstChild;if(!S||!(S instanceof Text))throw new Error("Started a composition but couldn't find the text node it belongs to.");g.dom=y,g.textDOM=S,g.text=S.data,g.textDOM.pmViewDesc=g,l==null||l.input.compositionNodes.push(g)}return()=>{var g,y,S,x;((g=c.current)==null?void 0:g.children[0])instanceof jl&&!(l!=null&&l.composing)&&((x=(y=c.current)==null?void 0:y.children[0].dom.parentNode)==null||x.removeChild((S=c.current)==null?void 0:S.children[0].dom))}}),{hasContentDOM:a,childDescriptors:h,setStopEvent:d}}function cE(n,e){return n.type.side-e.type.side}function fE(n,e,t,r){const i=e.locals(n);let o=0;if(i.length==0){for(let u=0;uo;)l.push(i[s++]);let d=o+c.nodeSize;if(c.isText){let h=d;s!h.inline):l.slice();r(c,p,e.forChild(o,c),o,f),o=d}}function ha(){const{state:n}=C.useContext(pi);return n}function j1(){const n=ha();return _o.getState(n)}var K1={exports:{}};/*! + Copyright (c) 2018 Jed Watson. + Licensed under the MIT License (MIT), see + http://jedwatson.github.io/classnames +*/(function(n){(function(){var e={}.hasOwnProperty;function t(){for(var r=[],i=0;i{var t;return((t=e[1])==null?void 0:t.toUpperCase())??""})}function mE(n){const e=new CSSStyleSheet;e.insertRule(`* { ${n} }`);const r=e.cssRules[0].style,i={};for(let o=0;o0&&(e.step=r);break}case"disabled":{e.disabled=r!=null;break}case"rows":{const i=parseInt(r,10);Number.isNaN(i)||(e.rows=r);break}default:{e[t]=r;break}}return e}const yd=C.forwardRef(function({outputSpec:e,children:t,...r},i){if(typeof e=="string")return A.jsx(A.Fragment,{children:e});if(!Array.isArray(e))throw new Error("@nytimes/react-prosemirror only supports strings and arrays in toDOM");const s=e[0].replace(" ",":"),l=e[1];let a={ref:i,...r},u=1;l&&typeof l=="object"&&l.nodeType==null&&!Array.isArray(l)&&(u=2,a=q1(Q1(l),a));const c=[];for(let f=u;fu)throw new RangeError("Content hole must be the only child of its parent node");return C.createElement(s,a,t)}c.push(A.jsx(yd,{ref:void 0,outputSpec:d,children:t}))}return C.createElement(s,a,...c)}),Y1=C.forwardRef(function({mark:e,children:t},r){var a,u;const i=C.useContext(mt),o=[],s=C.useRef(null);C.useImperativeHandle(r,()=>s.current,[]);const l=(u=(a=e.type.spec).toDOM)==null?void 0:u.call(a,e,!0);if(!l)throw new Error(`Mark spec for ${e.type.name} is missing toDOM`);return C.useLayoutEffect(()=>{if(!s.current)return;const c=o[0],f=new GM(void 0,o,e,s.current,(c==null?void 0:c.dom.parentElement)??s.current);i.push(f);for(const d of o)d.parent=f}),A.jsx(yd,{ref:s,outputSpec:l,children:A.jsx(mt.Provider,{value:o,children:t})})});function gE({widget:n,pos:e}){const t=C.useContext(mt),r=C.useRef(null),i=C.useRef(e);return i.current=e,F1(o=>{if(!r.current)return;const s=n.type.toDOM;let l=typeof s=="function"?s(o,()=>i.current):s;if(!n.type.spec.raw){if(l.nodeType!=1){const a=document.createElement("span");a.appendChild(l),l=a}l.contentEditable="false",l.classList.add("ProseMirror-widget")}r.current.firstElementChild!==l&&r.current.replaceChildren(l)}),C.useLayoutEffect(()=>{if(!r.current)return;const o=new pd(void 0,n,r.current);t.push(o)}),A.jsx("span",{ref:r})}const yE=C.createContext(null);function G1({outerDeco:n,pos:e,node:t,innerDeco:r,...i}){var z,se;const o=C.useRef(null),s=C.useRef(null),l=C.useRef(null),a=C.useRef(t),u=C.useRef(n),c=C.useRef(r),f=C.useRef(e);f.current=e;const d=C.useRef(null),p=C.useRef(null),h=ha(),{nodeViews:m}=C.useContext(b1),{view:w}=C.useContext(pi);let g=null;const y=m[t.type.name],S=w==null?void 0:w.someProp("nodeViews",W=>W==null?void 0:W[t.type.name]);C.useLayoutEffect(()=>{if(!p.current||!d.current)return;const{dom:W}=p.current;return s.current=d.current,d.current.appendChild(W),()=>{var ke,hr;(hr=(ke=p.current)==null?void 0:ke.destroy)==null||hr.call(ke)}},[]),C.useLayoutEffect(()=>{if(!S||!p.current)return;const{destroy:W,update:ke}=p.current;if(((ke==null?void 0:ke.call(p.current,t,n,r))??!0)||(W==null||W.call(p.current),!d.current))return;a.current=t,u.current=n,c.current=r,p.current=S(a.current,w,()=>f.current,u.current,c.current);const{dom:pa}=p.current;s.current=d.current,d.current.appendChild(pa)},[S,w,r,t,n]);const{hasContentDOM:x,childDescriptors:M,setStopEvent:E}=H1(t,o,s,r,n,void 0,l),O={...i,...!x&&{contentEditable:!1}};if(y)g=A.jsx(y,{...O,ref:s,nodeProps:{node:t,pos:e,decorations:n,innerDecorations:r,isSelected:h.selection instanceof I&&h.selection.node===t},children:A.jsx(ho,{pos:e,node:t,innerDecorations:r})});else if(S){p.current||(p.current=S(a.current,w,()=>f.current,u.current,c.current));const{contentDOM:W}=p.current;l.current=W??null,g=C.createElement(t.isInline?"span":"div",{ref:d,contentEditable:!!W,suppressContentEditableWarning:!0},W&&ai.createPortal(A.jsx(ho,{pos:e,node:t,innerDecorations:r}),W))}else{const W=(se=(z=t.type.spec).toDOM)==null?void 0:se.call(z,t);W&&(g=A.jsx(yd,{...O,ref:s,outputSpec:W,children:A.jsx(ho,{pos:e,node:t,innerDecorations:r})}))}if(!g)throw new Error(`Node spec for ${t.type.name} is missing toDOM`);const T=C.cloneElement(n.reduce(Sd,g),n.some(W=>W.type.attrs.nodeName)?{ref:o}:void 0),b=t.marks.reduce((W,ke)=>A.jsx(Y1,{mark:ke,children:W}),T);return A.jsx(yE.Provider,{value:E,children:A.jsx(mt.Provider,{value:M,children:C.cloneElement(b,t.marks.length||n.some(W=>W.type.attrs.nodeName)?{ref:o}:void 0)})})}function SE(){const n=C.useContext(mt),e=C.useRef(null),[t,r]=C.useState(!1);return C.useLayoutEffect(()=>{var s;const i=n[n.length-1];if((Ee.safari||Ee.chrome)&&((s=i==null?void 0:i.dom)==null?void 0:s.contentEditable)=="false"){r(!0);return}if(!e.current)return;const o=new gd(void 0,[],e.current,null);n.push(o)}),t?A.jsx("img",{ref:e,className:"ProseMirror-separator"}):null}class wE extends C.Component{constructor(){super(...arguments),this.viewDescRef=null,this.renderRef=null}updateEffect(){const{view:e,decorations:t,siblingDescriptors:r,node:i}=this.props,o=ai.findDOMNode(this);if(!o){if(!(e!=null&&e.composing))return;this.viewDescRef=new jl(void 0,document.createElement("div"),document.createTextNode(i.text??""),i.text??"");return}let s=o;for(;s.firstChild;)s=s.firstChild;!this.viewDescRef||this.viewDescRef instanceof jl?this.viewDescRef=new XM(void 0,[],i,t,_.empty,o,s):(this.viewDescRef.parent=void 0,this.viewDescRef.children=[],this.viewDescRef.node=i,this.viewDescRef.outerDeco=t,this.viewDescRef.innerDeco=_.empty,this.viewDescRef.dom=o,this.viewDescRef.dom.pmViewDesc=this.viewDescRef,this.viewDescRef.nodeDOM=s),r.push(this.viewDescRef)}componentDidMount(){this.updateEffect()}componentDidUpdate(){this.updateEffect()}render(){const{view:e,pos:t,node:r,decorations:i}=this.props;return e!=null&&e.composing&&e.state.selection.from>=t&&e.state.selection.from<=t+r.nodeSize?this.renderRef:(this.renderRef=i.reduce(Sd,r.text),this.renderRef)}}function kE(){const n=C.useContext(mt),e=C.useRef(null);return C.useLayoutEffect(()=>{if(!e.current)return;const t=new gd(void 0,[],e.current,null);n.push(t)}),A.jsx("br",{ref:e,className:"ProseMirror-trailingBreak"})}function vE({widget:n,pos:e}){const t=C.useContext(mt),r=C.useRef(null);C.useLayoutEffect(()=>{if(!r.current)return;const o=new pd(void 0,n,r.current);t.push(o)});const{Component:i}=n.type;return i&&A.jsx(i,{ref:r,widget:n,pos:e,contentEditable:!1})}function Sd(n,e){const{nodeName:t,...r}=e.type.attrs,i=Q1(r);return t||typeof n=="string"?C.createElement(t??"span",i,n):C.cloneElement(n,q1(n.props,i))}function Hc({innerPos:n,childViews:e}){const{view:t}=C.useContext(pi),r=ha(),i=j1(),o=e.reduce((s,l)=>{var c;const a=s[s.length-1];if(!a)return[[l]];const u=a[a.length-1];return u?!l.marks.length&&!u.marks.length||l.marks.length&&u.marks.length&&((c=l.marks[0])!=null&&c.eq(u.marks[0]))?[...s.slice(0,s.length-1),[...a.slice(0,a.length),l]]:[...s,[l]]:[...s.slice(0,s.length),[l]]},[]);return A.jsx(A.Fragment,{children:o.map(s=>{const l=s[0];if(!l)return null;const a=l.marks[0];return a?A.jsx(Y1,{mark:a,children:A.jsx(Hc,{innerPos:n,childViews:s.map(u=>({...u,marks:u.marks.slice(1)}))},fo(r==null?void 0:r.doc,n,l,i==null?void 0:i.posToKey))},fo(r==null?void 0:r.doc,n,l,i==null?void 0:i.posToKey)):s.map(u=>{const c=n+u.offset,f=u.type==="widget"?A.jsx(vE,{widget:u.widget,pos:c}):u.type==="native-widget"?A.jsx(gE,{widget:u.widget,pos:c}):u.node.isText?A.jsx(mt.Consumer,{children:d=>A.jsx(wE,{view:t,node:u.node,pos:c,siblingDescriptors:d,decorations:u.outerDeco})}):A.jsx(G1,{node:u.node,pos:c,outerDeco:u.outerDeco,innerDeco:u.innerDeco});return C.cloneElement(f,{key:fo(r.doc,n,u,i==null?void 0:i.posToKey)})})})})}function fo(n,e,t,r){const i=e+t.offset,o=r==null?void 0:r.get(i);if(t.type==="widget"||t.type==="native-widget")return t.widget.type.spec.key?t.widget.type.spec.key:(console.warn(`Widget at position ${i} doesn't have a key specified. This has negative performance implications.`),`${o}-${t.index}`);if(o)return o;if(!n)return i;const s=n.resolve(i).start()-1,l=r==null?void 0:r.get(s);return l?`${l}-${t.offset}`:i}function xE(n){const e=n[n.length-1];if((e==null?void 0:e.type)!=="widget"&&(e==null?void 0:e.type)!=="native-widget"||e.widget.type.side>=0)return;let t=null;for(let i=n.length-2;i>=0;i--){const o=n[i];if((o==null?void 0:o.type)==="node"){t=o;break}}if(!t||!t.node.isInline)return;const r=t.marks;e.marks=e.marks.reduce((i,o)=>o.addToSet(i),r)}function CE(n){const e=n[n.length-1];if((e==null?void 0:e.type)!=="node"||!e.node.isInline)return;const t=e.marks;for(let r=n.length-2;r>=0;r--){const i=n[r];if((i==null?void 0:i.type)!=="widget"&&(i==null?void 0:i.type)!=="native-widget"||i.widget.type.side<0)break;i.marks=i.marks.reduce((o,s)=>s.addToSet(o),t)}}function NE(n,e,t,r){return n.length?n.every(i=>i.type!=="node"||i.node.isInline)?[A.jsx(Hc,{childViews:n,innerPos:e},fo(t,e,n[0],r))]:n.map(i=>{if(i.type==="node"){const o=e+i.offset,s=(r==null?void 0:r.get(o))??o;return A.jsx(G1,{outerDeco:i.outerDeco,node:i.node,innerDeco:i.innerDeco,pos:o},s)}else return A.jsx(Hc,{childViews:[i],innerPos:e},fo(t,e,i,r))}):[]}function ho({pos:n,node:e,innerDecorations:t}){const r=ha(),i=j1();if(!e)return null;const o=n+1,s=[];fE(e,t,(u,c,f,d)=>{const p=u.type.spec.marks??[];c?s.push({type:"native-widget",widget:u,marks:p,offset:f,index:d}):s.push({type:"widget",widget:u,marks:p,offset:f,index:d}),xE(s)},(u,c,f,d)=>{s.push({type:"node",node:u,marks:u.marks,innerDeco:f,outerDeco:c,offset:d}),CE(s)});const l=NE(s,o,r.doc,i==null?void 0:i.posToKey),a=s[s.length-1];return(!a||a.type!=="node"||a.node.isInline&&!a.node.isText||/\n$/.test(a.node.text))&&l.push(A.jsx(SE,{},"trailing-hack-img"),A.jsx(kE,{},"trailing-hack-br")),A.jsx(A.Fragment,{children:l})}const ME=C.forwardRef(function({className:e,node:t,innerDeco:r,outerDeco:i,as:o,viewDesc:s,...l},a){const u=C.useRef(null);C.useImperativeHandle(a,()=>u.current,[]);const{childDescriptors:c}=H1(t,u,u,r,i,s),f={...l,ref:u,className:e,suppressContentEditableWarning:!0},d=o?C.cloneElement(o,f,A.jsx(mt.Provider,{value:c,children:A.jsx(ho,{pos:-1,node:t,innerDecorations:r})})):C.createElement("div",f,A.jsx(mt.Provider,{value:c,children:A.jsx(ho,{pos:-1,node:t,innerDecorations:r})}));if(!t)return d;const p=i.filter(m=>!m.inline);return p.length?p.reduce(Sd,d):d}),X1=C.createContext(null);function EE({as:n,...e},t){const r=C.useRef(null),{setMount:i,...o}=C.useContext(X1);return C.useImperativeHandle(t,()=>r.current,[]),A.jsx(mt.Provider,{value:[],children:A.jsx(ME,{ref:s=>{r.current=s,i(s)},...e,...o,as:n})})}const OE=C.forwardRef(EE);function DE({className:n,children:e,nodeViews:t={},customNodeViews:r,...i}){var c;const[o,s]=C.useState(null),l=aE(o,{...i,nodeViews:r}),a=l.view?xM(l.view,l.cursorWrapper):_.empty,u=l.view?SM(l.view):[];return A.jsx(pi.Provider,{value:l,children:A.jsx(b1.Provider,{value:{nodeViews:t},children:A.jsx(X1.Provider,{value:{className:n,setMount:s,node:(c=l.view)==null?void 0:c.state.doc,innerDeco:a,outerDeco:u,viewDesc:l.docViewDescRef.current},children:e})})})}function TE(n){return A.jsx(uE,{children:A.jsx(DE,{...n})})}const J=new Rm({nodes:{doc:{content:"block+"},paragraph:{group:"block",content:"inline*",toDOM(){return["p",0]}},...Lx({cellContent:"inline*",cellAttributes:{},tableGroup:"block"}),footnote:{group:"inline",content:"text*",inline:!0,atom:!0,attrs:{number:{default:0}}},list:{group:"block",content:"list_item+",toDOM(){return["ul",0]}},list_item:{content:"paragraph+",toDOM(){return["li",0]}},image:{group:"block",toDOM(){return["div",["img",{src:"https://smoores.gitlab.io/storyteller/img/Storyteller_Logo.png",height:150,width:150}]]}},text:{group:"inline"}},marks:{em:{toDOM(){return["em",0]}},strong:{toDOM(){return["strong",0]}}}}),RE=cn.create({schema:J,doc:J.nodes.doc.create({},[J.nodes.paragraph.create({},[J.text("This ",[J.marks.em.create()]),J.text("is",[J.marks.em.create(),J.marks.strong.create()]),J.text(" the first paragraph")]),J.nodes.paragraph.create({},[J.text("This is the second paragraph"),J.nodes.footnote.create({number:1},J.text("Footnote"))]),J.nodes.paragraph.create(),J.nodes.image.create(),J.nodes.image.create(),J.nodes.paragraph.create({},J.text("This is the third paragraph 🫵")),J.nodes.table.create({},[J.nodes.table_row.create({},[J.nodes.table_header.create({},J.text("h1")),J.nodes.table_header.create({},J.text("h2"))]),J.nodes.table_row.create({},[J.nodes.table_cell.create({},J.text("c1")),J.nodes.table_cell.create({},J.text("c2"))])])]),plugins:[AM(),tx({rules:[nx(/^\s*([-+*])\s$/,J.nodes.list)]}),nC(),pC()]}),AE=C.forwardRef(function({children:e,nodeProps:t,...r},i){return A.jsx("p",{ref:i,...r,children:e})}),bE=C.forwardRef(function({children:e,nodeProps:t,...r},i){return A.jsx("ul",{ref:i,...r,children:e})}),IE=C.forwardRef(function({children:e,nodeProps:t,...r},i){return A.jsx("li",{ref:i,...r,children:e})}),zE=C.forwardRef(function({nodeProps:e,...t},r){return A.jsx("span",{ref:r,...t,suppressContentEditableWarning:!0,contentEditable:"false",children:A.jsx("button",{children:e.node.attrs.number})})}),PE=C.forwardRef(function({widget:e,pos:t,...r},i){return A.jsx("span",{...r,ref:i,style:{display:"block",backgroundColor:"blue",width:"4px",height:"4px",position:"absolute",transform:"translateX(-2px)"},children:"Widget"})}),FE=new $t({view(n){const e=n.coordsAtPos(n.state.selection.from),t=document.createElement("div");return t.style.width="4px",t.style.height="4px",t.style.position="absolute",t.style.top=`${e.top-2}px`,t.style.left=`${e.left-2}px`,t.style.backgroundColor="blue",document.body.appendChild(t),{update(r){const i=r.coordsAtPos(r.state.selection.from);t.style.top=`${i.top-2}px`,t.style.left=`${i.left-2}px`},destroy(){document.body.removeChild(t)}}}});new $t({props:{decorations(n){return _.create(n.doc,[L1(n.selection.from,PE,{side:0,key:"widget-plugin-widget"})])}},view(n){const e=n.coordsAtPos(n.state.selection.from),t=document.createElement("div");return t.style.width="4px",t.style.height="4px",t.style.position="absolute",t.style.top=`${e.top-2}px`,t.style.left=`${e.left-2}px`,t.style.backgroundColor="blue",document.body.appendChild(t),{update(r){const i=r.coordsAtPos(r.state.selection.from);t.style.top=`${i.top-2}px`,t.style.left=`${i.left-2}px`},destroy(){document.body.removeChild(t)}}}});const LE=[sx({..._w,"Mod-i":_d(J.marks.em),"Mod-b":_d(J.marks.strong)}),FE,$v()],$E={paragraph:()=>{const n=document.createElement("p");return{dom:n,contentDOM:n}}};function BE(){const[n,e]=C.useState(RE),[t,r]=C.useState(!0);return A.jsxs("main",{children:[A.jsx("h1",{children:"React ProseMirror Demo"}),A.jsxs("button",{onClick:()=>{t?r(i=>!i):window.location.reload()},children:["Switch to"," ",t?"ProseMirror node views":"React node views (requires reload)"]}),A.jsx(TE,{className:"ProseMirror",state:n,dispatchTransaction:function(i){e(o=>o.apply(i))},plugins:LE,nodeViews:t?{paragraph:AE,list:bE,list_item:IE,footnote:zE}:void 0,customNodeViews:t?void 0:$E,children:A.jsx(OE,{as:A.jsx("article",{})})},`${t}`)]})}const VE=A1(document.getElementById("root"));VE.render(A.jsx(C.StrictMode,{children:A.jsx(BE,{})})); diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 00000000..91c36751 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,14 @@ + + + + + + + React-ProseMirror Demo + + + + +
    + + diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..04feec69 --- /dev/null +++ b/flake.lock @@ -0,0 +1,26 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1698849552, + "narHash": "sha256-2pSykdb+Fe9+rGA1NIG/xXFfCmJu4QG8GbG5oJMyLKI=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "7f8c9b338ff8388d893e9d6c2928870613a073ed", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000..a3955a14 --- /dev/null +++ b/flake.nix @@ -0,0 +1,37 @@ +{ + description = "Example JavaScript development environment for Zero to Nix"; + + # Flake inputs + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs"; # also valid: "nixpkgs" + }; + + # Flake outputs + outputs = { self, nixpkgs }: + let + # Systems supported + allSystems = [ + "x86_64-linux" # 64-bit Intel/AMD Linux + "aarch64-linux" # 64-bit ARM Linux + "x86_64-darwin" # 64-bit Intel macOS + "aarch64-darwin" # 64-bit ARM macOS + ]; + + # Helper to provide system-specific attributes + forAllSystems = f: nixpkgs.lib.genAttrs allSystems (system: f { + pkgs = import nixpkgs { inherit system; }; + }); + in + { + # Development environment output + devShells = forAllSystems ({ pkgs }: { + default = pkgs.mkShell { + # The Nix packages provided in the environment + packages = with pkgs; [ + nodejs-18_x # Node.js 18, plus npm, npx, and corepack + yarn + ]; + }; + }); + }; +} diff --git a/jest.config.cjs b/jest.config.cjs index c8c7e293..930e52bf 100644 --- a/jest.config.cjs +++ b/jest.config.cjs @@ -3,6 +3,7 @@ module.exports = { rootDir: "src", testEnvironment: "jsdom", extensionsToTreatAsEsm: [".ts", ".tsx"], + testPathIgnorePatterns: ["src/components/__tests__/ProseMirror.*.test.tsx"], moduleNameMapper: { "(.+)\\.js": "$1", }, diff --git a/package.json b/package.json index 0999ec43..233fd60d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nytimes/react-prosemirror", - "version": "0.4.2", + "version": "0.7.0-next.10", "license": "Apache-2.0", "type": "module", "main": "dist/cjs/index.js", @@ -30,27 +30,35 @@ "check": "concurrently -P 'npm:check:* {@}' --", "clean": "rimraf \"./dist/!(cjs/package.json)\"", "demo": "yarn vite", + "demo:build": "yarn vite build --outDir docs --base=/react-prosemirror/", "dev": "yarn build -- --watch", "fix:format": "prettier --write .", "fix:lint": "eslint --cache --fix .", "fix:toc": "markdown-toc --bullets='-' -i README.md", "fix": "concurrently -P 'npm:fix:* {@}' --", "prepack": "yarn build", - "test": "jest" + "test:wdio": "wdio run ./wdio.conf.ts", + "test:unit": "jest", + "test": "yarn test:unit && yarn test:wdio" }, "devDependencies": { + "@jest/globals": "^29.6.2", "@swc/cli": "^0.1.61", "@swc/core": "^1.3.32", "@swc/jest": "^0.2.24", - "@testing-library/dom": "^9.0.0", - "@testing-library/react": "^13.4.0", + "@testing-library/dom": "^10.4.0", + "@testing-library/react": "^16.0.1", "@testing-library/user-event": "^14.4.3", "@types/jest": "^27.0.0", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "@typescript-eslint/eslint-plugin": "^5.51.0", "@typescript-eslint/parser": "^5.51.0", - "@vitejs/plugin-react": "^3.1.0", + "@vitejs/plugin-react": "^4.3.1", + "@wdio/browser-runner": "^9.0.9", + "@wdio/cli": "^9.0.9", + "@wdio/mocha-framework": "^9.0.8", + "@wdio/types": "^9.0.8", "@yarnpkg/sdks": "^3.0.0-rc.38", "concurrently": "^7.6.0", "eslint": "^8.33.0", @@ -60,32 +68,44 @@ "eslint-plugin-jest": "^27.2.1", "eslint-plugin-react": "^7.32.2", "eslint-plugin-react-hooks": "^4.6.0", + "expect": "^29.7.0", "husky": "^8.0.3", - "jest": "^29.0.0", - "jest-environment-jsdom": "^29.4.1", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", "lint-staged": "^13.1.0", "markdown-toc": "^1.2.0", "prettier": "^2.8.3", "prosemirror-commands": "^1.5.0", + "prosemirror-gapcursor": "^1.3.2", + "prosemirror-inputrules": "^1.4.0", "prosemirror-keymap": "^1.2.1", - "prosemirror-model": "^1.18.3", + "prosemirror-model": "^1.22.3", "prosemirror-schema-list": "^1.2.2", - "prosemirror-state": "^1.4.2", - "prosemirror-view": "^1.29.1", + "prosemirror-state": "^1.4.3", + "prosemirror-tables": "^1.3.7", + "prosemirror-test-builder": "^1.1.1", + "prosemirror-transform": "^1.8.0", + "prosemirror-view": "^1.34.2", "react": "^18.2.0", "react-dom": "^18.2.0", "rimraf": "^3.0.2", + "tsx": "^4.19.1", "typescript": "^4.9.5", - "vite": "^4.1.5" + "vite": "^5.4.5", + "webdriverio": "^9.0.9" }, "peerDependencies": { + "prosemirror-model": "^1.0.0", "prosemirror-state": "^1.0.0", - "prosemirror-view": "^1.0.0", + "prosemirror-view": "1.34.2", "react": ">=17", "react-dom": ">=17" }, "packageManager": "yarn@3.4.1", "engines": { "node": ">=16.9" + }, + "dependencies": { + "classnames": "^2.3.2" } } diff --git a/src/browser.ts b/src/browser.ts new file mode 100644 index 00000000..83c65573 --- /dev/null +++ b/src/browser.ts @@ -0,0 +1,53 @@ +const nav = typeof navigator != "undefined" ? navigator : null; +const doc = typeof document != "undefined" ? document : null; +const agent = (nav && nav.userAgent) || ""; + +const ie_edge = /Edge\/(\d+)/.exec(agent); +const ie_upto10 = /MSIE \d/.exec(agent); +const ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(agent); + +const ie = !!(ie_upto10 || ie_11up || ie_edge); +const ie_version = ie_upto10 + ? // eslint-disable-next-line @typescript-eslint/no-explicit-any + (document as any).documentMode + : ie_11up + ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + +ie_11up[1]! + : ie_edge + ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + +ie_edge[1]! + : 0; +const gecko = !ie && /gecko\/(\d+)/i.test(agent); +const gecko_version = gecko && +(/Firefox\/(\d+)/.exec(agent) || [0, 0])[1]; + +const _chrome = !ie && /Chrome\/(\d+)/.exec(agent); +const chrome = !!_chrome; +// eslint-disable-next-line @typescript-eslint/no-non-null-assertion +const chrome_version = _chrome ? +_chrome[1]! : 0; +const safari = !ie && !!nav && /Apple Computer/.test(nav.vendor); +// Is true for both iOS and iPadOS for convenience +const ios = + safari && (/Mobile\/\w+/.test(agent) || (!!nav && nav.maxTouchPoints > 2)); +const mac = ios || (nav ? /Mac/.test(nav.platform) : false); +const windows = nav ? /Win/.test(nav.platform) : false; +const android = /Android \d/.test(agent); +const webkit = !!doc && "webkitFontSmoothing" in doc.documentElement.style; +const webkit_version = webkit + ? +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1] + : 0; + +export const browser = { + ie, + ie_version, + gecko, + gecko_version, + chrome, + chrome_version, + safari, + ios, + mac, + windows, + android, + webkit, + webkit_version, +}; diff --git a/src/components/ChildNodeViews.tsx b/src/components/ChildNodeViews.tsx new file mode 100644 index 00000000..411fb23d --- /dev/null +++ b/src/components/ChildNodeViews.tsx @@ -0,0 +1,414 @@ +import { Mark, Node } from "prosemirror-model"; +import { Decoration, DecorationSource } from "prosemirror-view"; +import React, { + ReactNode, + cloneElement, + createElement, + useContext, +} from "react"; + +import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"; +import { EditorContext } from "../contexts/EditorContext.js"; +import { ReactWidgetDecoration } from "../decorations/ReactWidgetType.js"; +import { iterDeco } from "../decorations/iterDeco.js"; +import { useEditorState } from "../hooks/useEditorState.js"; +import { useReactKeys } from "../hooks/useReactKeys.js"; +import { htmlAttrsToReactProps, mergeReactProps } from "../props.js"; + +import { MarkView } from "./MarkView.js"; +import { NativeWidgetView } from "./NativeWidgetView.js"; +import { NodeView } from "./NodeView.js"; +import { SeparatorHackView } from "./SeparatorHackView.js"; +import { TextNodeView } from "./TextNodeView.js"; +import { TrailingHackView } from "./TrailingHackView.js"; +import { WidgetView } from "./WidgetView.js"; + +export function wrapInDeco(reactNode: JSX.Element | string, deco: Decoration) { + const { + nodeName, + ...attrs + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } = (deco as any).type.attrs; + + const props = htmlAttrsToReactProps(attrs); + + // We auto-wrap text nodes in spans so that we can apply attributes + // and styles, but we want to avoid double-wrapping the same + // text node + if (nodeName || typeof reactNode === "string") { + return createElement(nodeName ?? "span", props, reactNode); + } + + return cloneElement(reactNode, mergeReactProps(reactNode.props, props)); +} + +type ChildWidget = { + type: "widget"; + widget: ReactWidgetDecoration; + marks: readonly Mark[]; + offset: number; + index: number; +}; + +type ChildNativeWidget = { + type: "native-widget"; + widget: Decoration; + marks: readonly Mark[]; + offset: number; + index: number; +}; + +type ChildNode = { + type: "node"; + node: Node; + marks: readonly Mark[]; + innerDeco: DecorationSource; + outerDeco: readonly Decoration[]; + offset: number; +}; + +type ChildTrailingHack = { + type: "trailinghack"; + offset: 0; +}; + +type Child = ChildNode | ChildWidget | ChildNativeWidget; + +type SharedMarksProps = { + innerPos: number; + childViews: Child[]; +}; + +function InlineView({ innerPos, childViews }: SharedMarksProps) { + const { view } = useContext(EditorContext); + const editorState = useEditorState(); + const reactKeys = useReactKeys(); + + const partitioned = childViews.reduce((acc, child) => { + const lastPartition = acc[acc.length - 1]; + if (!lastPartition) { + return [[child]]; + } + const lastChild = lastPartition[lastPartition.length - 1]; + if (!lastChild) { + return [...acc.slice(0, acc.length), [child]]; + } + + if ( + (!child.marks.length && !lastChild.marks.length) || + (child.marks.length && + lastChild.marks.length && + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + child.marks[0]?.eq(lastChild.marks[0]!)) + ) { + return [ + ...acc.slice(0, acc.length - 1), + [...lastPartition.slice(0, lastPartition.length), child], + ]; + } + + return [...acc, [child]]; + }, [] as Child[][]); + + return ( + <> + {partitioned.map((childViews) => { + const firstChild = childViews[0]; + if (!firstChild) return null; + + const firstMark = firstChild.marks[0]; + if (!firstMark) { + return childViews.map((child) => { + const childPos = innerPos + child.offset; + + const childElement = + child.type === "widget" ? ( + + ) : child.type === "native-widget" ? ( + + ) : child.node.isText ? ( + + {(siblingDescriptors) => ( + + )} + + ) : ( + + ); + + return cloneElement(childElement, { + key: createKey( + editorState.doc, + innerPos, + child, + reactKeys?.posToKey + ), + }); + }); + } + + return ( + + ({ + ...child, + marks: child.marks.slice(1), + }))} + /> + + ); + })} + + ); +} + +function createKey( + doc: Node | undefined, + innerPos: number, + child: Child | ChildTrailingHack, + posToKey: Map | undefined +) { + const pos = innerPos + child.offset; + const key = posToKey?.get(pos); + + if (child.type === "widget" || child.type === "native-widget") { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if ((child.widget as any).type.spec.key) + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return (child.widget as any).type.spec.key; + + // eslint-disable-next-line no-console + console.warn( + `Widget at position ${pos} doesn't have a key specified. This has negative performance implications.` + ); + return `${key}-${child.index}`; + } + + if (key) return key; + + if (!doc) return pos; + + const parentPos = doc.resolve(pos).start() - 1; + + const parentKey = posToKey?.get(parentPos); + + if (parentKey) return `${parentKey}-${child.offset}`; + + return pos; +} + +function adjustWidgetMarksForward(children: Child[]) { + const lastChild = children[children.length - 1]; + if ( + (lastChild?.type !== "widget" && lastChild?.type !== "native-widget") || + // Using internal Decoration property, "type" + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (lastChild.widget as any).type.side >= 0 + ) + return; + + let lastNodeChild: ChildNode | null = null; + for (let i = children.length - 2; i >= 0; i--) { + const child = children[i]; + if (child?.type === "node") { + lastNodeChild = child; + break; + } + } + + if (!lastNodeChild || !lastNodeChild.node.isInline) return; + + const marksToSpread = lastNodeChild.marks; + + lastChild.marks = lastChild.marks.reduce( + (acc, mark) => mark.addToSet(acc), + marksToSpread + ); +} + +function adjustWidgetMarksBack(children: Child[]) { + const lastChild = children[children.length - 1]; + if (lastChild?.type !== "node" || !lastChild.node.isInline) return; + + const marksToSpread = lastChild.marks; + for (let i = children.length - 2; i >= 0; i--) { + const child = children[i]; + if ( + (child?.type !== "widget" && child?.type !== "native-widget") || + // Using internal Decoration property, "type" + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (child.widget as any).type.side < 0 + ) + break; + + child.marks = child.marks.reduce( + (acc, mark) => mark.addToSet(acc), + marksToSpread + ); + } +} + +function createChildElements( + children: Child[], + innerPos: number, + doc: Node | undefined, + posToKey: Map | undefined +): ReactNode[] { + if (!children.length) return []; + + if (children.every((child) => child.type !== "node" || child.node.isInline)) { + return [ + , + ]; + } + + return children.map((child) => { + if (child.type === "node") { + const pos = innerPos + child.offset; + const key = posToKey?.get(pos) ?? pos; + return ( + + ); + } else { + return ( + + ); + } + }); +} + +export function ChildNodeViews({ + pos, + node, + innerDecorations, +}: { + pos: number; + node: Node | undefined; + innerDecorations: DecorationSource; +}) { + const editorState = useEditorState(); + const reactKeys = useReactKeys(); + + if (!node) return null; + const innerPos = pos + 1; + + const children: Child[] = []; + + iterDeco( + node, + innerDecorations, + (widget, isNative, offset, index) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const widgetMarks = ((widget as any).type.spec.marks as Mark[]) ?? []; + if (isNative) { + children.push({ + type: "native-widget", + widget: widget, + marks: widgetMarks, + offset, + index, + }); + } else { + children.push({ + type: "widget", + widget: widget as ReactWidgetDecoration, + marks: widgetMarks, + offset, + index, + }); + } + adjustWidgetMarksForward(children); + }, + (childNode, outerDeco, innerDeco, offset) => { + children.push({ + type: "node", + node: childNode, + marks: childNode.marks, + innerDeco, + outerDeco, + offset, + }); + adjustWidgetMarksBack(children); + } + ); + + const childElements = createChildElements( + children, + innerPos, + editorState.doc, + reactKeys?.posToKey + ); + + const lastChild = children[children.length - 1]; + + if ( + !lastChild || + lastChild.type !== "node" || + (lastChild.node.isInline && !lastChild.node.isText) || + // RegExp.test actually handles undefined just fine + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + /\n$/.test(lastChild.node.text!) + ) { + childElements.push( + , + + ); + } + + return <>{childElements}; +} diff --git a/src/components/CursorWrapper.tsx b/src/components/CursorWrapper.tsx new file mode 100644 index 00000000..1ff0a104 --- /dev/null +++ b/src/components/CursorWrapper.tsx @@ -0,0 +1,64 @@ +import React, { + forwardRef, + useImperativeHandle, + useRef, + useState, +} from "react"; + +import { domIndex } from "../dom.js"; +import { useEditorEffect } from "../hooks/useEditorEffect.js"; + +import { WidgetViewComponentProps } from "./WidgetViewComponentProps.js"; + +export const CursorWrapper = forwardRef< + HTMLImageElement, + WidgetViewComponentProps +>(function CursorWrapper({ widget, pos, ...props }, ref) { + const [shouldRender, setShouldRender] = useState(true); + const innerRef = useRef(null); + + useImperativeHandle( + ref, + () => { + return innerRef.current; + }, + [] + ); + + useEditorEffect((view) => { + if (!view || !innerRef.current) return; + + // @ts-expect-error Internal property - domObserver + view.domObserver.disconnectSelection(); + // @ts-expect-error Internal property - domSelection + const domSel = view.domSelection(); + const range = document.createRange(); + const node = innerRef.current; + const img = node.nodeName == "IMG"; + + if (img && node.parentNode) { + range.setEnd(node.parentNode, domIndex(node) + 1); + } else { + range.setEnd(node, 0); + } + + range.collapse(false); + domSel.removeAllRanges(); + domSel.addRange(range); + + setShouldRender(false); + // @ts-expect-error Internal property - domObserver + view.domObserver.connectSelection(); + }, []); + + return shouldRender ? ( + + ) : null; +}); diff --git a/src/components/DocNodeView.tsx b/src/components/DocNodeView.tsx new file mode 100644 index 00000000..a99dd331 --- /dev/null +++ b/src/components/DocNodeView.tsx @@ -0,0 +1,97 @@ +// TODO: I must be missing something, but I do not know why +// this linting rule is only broken in this file +/* eslint-disable react/prop-types */ +import { Node } from "prosemirror-model"; +import { Decoration, DecorationSource } from "prosemirror-view"; +import React, { + DetailedHTMLProps, + ForwardedRef, + HTMLAttributes, + ReactElement, + cloneElement, + createElement, + forwardRef, + useImperativeHandle, + useRef, +} from "react"; + +import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"; +import { useNodeViewDescriptor } from "../hooks/useNodeViewDescriptor.js"; +import { NodeViewDesc } from "../viewdesc.js"; + +import { ChildNodeViews, wrapInDeco } from "./ChildNodeViews.js"; + +export type DocNodeViewProps = { + className?: string; + node: Node | undefined; + innerDeco: DecorationSource; + outerDeco: Decoration[]; + as?: ReactElement; + viewDesc?: NodeViewDesc; +} & Omit, HTMLDivElement>, "ref">; + +export const DocNodeView = forwardRef(function DocNodeView( + { + className, + node, + innerDeco, + outerDeco, + as, + viewDesc, + ...elementProps + }: DocNodeViewProps, + ref: ForwardedRef +) { + const innerRef = useRef(null); + + useImperativeHandle( + ref, + () => { + return innerRef.current; + }, + [] + ); + + const { childDescriptors } = useNodeViewDescriptor( + node, + innerRef, + innerRef, + innerDeco, + outerDeco, + viewDesc + ); + + const props = { + ...elementProps, + ref: innerRef, + className, + suppressContentEditableWarning: true, + }; + + const element = as + ? cloneElement( + as, + props, + + + + ) + : createElement( + "div", + props, + + + + ); + + if (!node) return element; + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const nodeDecorations = outerDeco.filter((deco) => !(deco as any).inline); + if (!nodeDecorations.length) { + return element; + } + + const wrapped = nodeDecorations.reduce(wrapInDeco, element); + return wrapped; +}); diff --git a/src/components/LayoutGroup.tsx b/src/components/LayoutGroup.tsx new file mode 100644 index 00000000..1ed07c58 --- /dev/null +++ b/src/components/LayoutGroup.tsx @@ -0,0 +1,80 @@ +import React, { useCallback, useLayoutEffect, useRef } from "react"; +import type { EffectCallback } from "react"; + +import { LayoutGroupContext } from "../contexts/LayoutGroupContext.js"; +import { useForceUpdate } from "../hooks/useForceUpdate.js"; + +export interface LayoutGroupProps { + children: React.ReactNode; +} + +/** + * Provides a boundary for grouping layout effects. + * + * Descendant components can invoke the `useLayoutGroupEffect` hook to register + * effects that run after all descendants within the group have processed their + * regular layout effects. + */ +export function LayoutGroup({ children }: LayoutGroupProps) { + const createQueue = useRef(new Set<() => void>()).current; + const destroyQueue = useRef(new Set<() => void>()).current; + const isMounted = useRef(false); + + const forceUpdate = useForceUpdate(); + const isUpdatePending = useRef(true); + + const ensureFlush = useCallback(() => { + if (!isUpdatePending.current) { + forceUpdate(); + isUpdatePending.current = true; + } + }, [forceUpdate]); + + const register = useCallback( + (effect: EffectCallback) => { + let destroy: ReturnType; + const create = () => { + destroy = effect(); + }; + + createQueue.add(create); + ensureFlush(); + + return () => { + createQueue.delete(create); + if (destroy) { + if (isMounted.current) { + destroyQueue.add(destroy); + ensureFlush(); + } else { + destroy(); + } + } + }; + }, + [createQueue, destroyQueue, ensureFlush] + ); + + useLayoutEffect(() => { + isUpdatePending.current = false; + createQueue.forEach((create) => create()); + createQueue.clear(); + return () => { + destroyQueue.forEach((destroy) => destroy()); + destroyQueue.clear(); + }; + }); + + useLayoutEffect(() => { + isMounted.current = true; + return () => { + isMounted.current = false; + }; + }, []); + + return ( + + {children} + + ); +} diff --git a/src/components/MarkView.tsx b/src/components/MarkView.tsx new file mode 100644 index 00000000..fb40834e --- /dev/null +++ b/src/components/MarkView.tsx @@ -0,0 +1,67 @@ +import { Mark } from "prosemirror-model"; +import React, { + ReactNode, + forwardRef, + useContext, + useImperativeHandle, + useLayoutEffect, + useRef, +} from "react"; + +import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"; +import { MarkViewDesc, ViewDesc } from "../viewdesc.js"; + +import { OutputSpec } from "./OutputSpec.js"; + +type Props = { + mark: Mark; + children: ReactNode; +}; + +export const MarkView = forwardRef(function MarkView( + { mark, children }: Props, + ref +) { + const siblingDescriptors = useContext(ChildDescriptorsContext); + const childDescriptors: ViewDesc[] = []; + const domRef = useRef(null); + + useImperativeHandle( + ref, + () => { + return domRef.current; + }, + [] + ); + + const outputSpec = mark.type.spec.toDOM?.(mark, true); + if (!outputSpec) + throw new Error(`Mark spec for ${mark.type.name} is missing toDOM`); + + useLayoutEffect(() => { + if (!domRef.current) return; + + const firstChildDesc = childDescriptors[0]; + + const desc = new MarkViewDesc( + undefined, + childDescriptors, + mark, + domRef.current, + firstChildDesc?.dom.parentElement ?? domRef.current + ); + siblingDescriptors.push(desc); + + for (const childDesc of childDescriptors) { + childDesc.parent = desc; + } + }); + + return ( + + + {children} + + + ); +}); diff --git a/src/components/NativeWidgetView.tsx b/src/components/NativeWidgetView.tsx new file mode 100644 index 00000000..97c40327 --- /dev/null +++ b/src/components/NativeWidgetView.tsx @@ -0,0 +1,51 @@ +import { Decoration, EditorView } from "prosemirror-view"; +import React, { useContext, useLayoutEffect, useRef } from "react"; + +import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"; +import { useEditorEffect } from "../hooks/useEditorEffect.js"; +import { WidgetViewDesc } from "../viewdesc.js"; + +type Props = { + widget: Decoration; + pos: number; +}; + +export function NativeWidgetView({ widget, pos }: Props) { + const siblingDescriptors = useContext(ChildDescriptorsContext); + const rootDomRef = useRef(null); + const posRef = useRef(pos); + posRef.current = pos; + + useEditorEffect((view) => { + if (!rootDomRef.current) return; + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const toDOM = (widget as any).type.toDOM as + | HTMLElement + | ((view: EditorView, getPos: () => number) => HTMLElement); + let dom = + typeof toDOM === "function" ? toDOM(view, () => posRef.current) : toDOM; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if (!(widget as any).type.spec.raw) { + if (dom.nodeType != 1) { + const wrap = document.createElement("span"); + wrap.appendChild(dom); + dom = wrap; + } + dom.contentEditable = "false"; + dom.classList.add("ProseMirror-widget"); + } + if (rootDomRef.current.firstElementChild === dom) return; + + rootDomRef.current.replaceChildren(dom); + }); + + useLayoutEffect(() => { + if (!rootDomRef.current) return; + + const desc = new WidgetViewDesc(undefined, widget, rootDomRef.current); + siblingDescriptors.push(desc); + }); + + return ; +} diff --git a/src/components/NodeView.tsx b/src/components/NodeView.tsx new file mode 100644 index 00000000..ddd772b2 --- /dev/null +++ b/src/components/NodeView.tsx @@ -0,0 +1,235 @@ +import { DOMOutputSpec, Node } from "prosemirror-model"; +import { NodeSelection } from "prosemirror-state"; +import { + Decoration, + DecorationSource, + NodeView as NodeViewT, +} from "prosemirror-view"; +import React, { + ForwardRefExoticComponent, + RefAttributes, + cloneElement, + createElement, + useContext, + useLayoutEffect, + useRef, +} from "react"; +import { createPortal } from "react-dom"; + +import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"; +import { EditorContext } from "../contexts/EditorContext.js"; +import { NodeViewContext } from "../contexts/NodeViewContext.js"; +import { StopEventContext } from "../contexts/StopEventContext.js"; +import { useEditorState } from "../hooks/useEditorState.js"; +import { useNodeViewDescriptor } from "../hooks/useNodeViewDescriptor.js"; + +import { ChildNodeViews, wrapInDeco } from "./ChildNodeViews.js"; +import { MarkView } from "./MarkView.js"; +import { NodeViewComponentProps } from "./NodeViewComponentProps.js"; +import { OutputSpec } from "./OutputSpec.js"; + +type NodeViewProps = { + outerDeco: readonly Decoration[]; + pos: number; + node: Node; + innerDeco: DecorationSource; +}; + +export function NodeView({ + outerDeco, + pos, + node, + innerDeco, + ...props +}: NodeViewProps) { + const domRef = useRef(null); + const nodeDomRef = useRef(null); + const contentDomRef = useRef(null); + // this is ill-conceived; should revisit + const initialNode = useRef(node); + const initialOuterDeco = useRef(outerDeco); + const initialInnerDeco = useRef(innerDeco); + const posRef = useRef(pos); + posRef.current = pos; + const customNodeViewRootRef = useRef(null); + const customNodeViewRef = useRef(null); + + const state = useEditorState(); + const { nodeViews } = useContext(NodeViewContext); + const { view } = useContext(EditorContext); + + let element: JSX.Element | null = null; + + const Component: + | ForwardRefExoticComponent< + NodeViewComponentProps & RefAttributes + > + | undefined = nodeViews[node.type.name]; + + // TODO: Would be great to pull all of the custom node view stuff into + // a hook + const customNodeView = view?.someProp( + "nodeViews", + (nodeViews) => nodeViews?.[node.type.name] + ); + + useLayoutEffect(() => { + if (!customNodeViewRef.current || !customNodeViewRootRef.current) return; + + const { dom } = customNodeViewRef.current; + nodeDomRef.current = customNodeViewRootRef.current; + customNodeViewRootRef.current.appendChild(dom); + return () => { + customNodeViewRef.current?.destroy?.(); + }; + }, []); + + useLayoutEffect(() => { + if (!customNodeView || !customNodeViewRef.current) return; + + const { destroy, update } = customNodeViewRef.current; + + const updated = + update?.call(customNodeViewRef.current, node, outerDeco, innerDeco) ?? + true; + if (updated) return; + + destroy?.call(customNodeViewRef.current); + + if (!customNodeViewRootRef.current) return; + + initialNode.current = node; + initialOuterDeco.current = outerDeco; + initialInnerDeco.current = innerDeco; + + customNodeViewRef.current = customNodeView( + initialNode.current, + // customNodeView will only be set if view is set, and we can only reach + // this line if customNodeView is set + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + view!, + () => posRef.current, + initialOuterDeco.current, + initialInnerDeco.current + ); + const { dom } = customNodeViewRef.current; + nodeDomRef.current = customNodeViewRootRef.current; + customNodeViewRootRef.current.appendChild(dom); + }, [customNodeView, view, innerDeco, node, outerDeco]); + + const { hasContentDOM, childDescriptors, setStopEvent } = + useNodeViewDescriptor( + node, + domRef, + nodeDomRef, + innerDeco, + outerDeco, + undefined, + contentDomRef + ); + + const finalProps = { + ...props, + ...(!hasContentDOM && { + contentEditable: false, + }), + }; + + if (Component) { + element = ( + + + + ); + } else if (customNodeView) { + if (!customNodeViewRef.current) { + customNodeViewRef.current = customNodeView( + initialNode.current, + // customNodeView will only be set if view is set, and we can only reach + // this line if customNodeView is set + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + view!, + () => posRef.current, + initialOuterDeco.current, + initialInnerDeco.current + ); + } + const { contentDOM } = customNodeViewRef.current; + contentDomRef.current = contentDOM ?? null; + element = createElement( + node.isInline ? "span" : "div", + { + ref: customNodeViewRootRef, + contentEditable: !!contentDOM, + suppressContentEditableWarning: true, + }, + contentDOM && + createPortal( + , + contentDOM + ) + ); + } else { + const outputSpec: DOMOutputSpec | undefined = node.type.spec.toDOM?.(node); + + if (outputSpec) { + element = ( + + + + ); + } + } + + if (!element) { + throw new Error(`Node spec for ${node.type.name} is missing toDOM`); + } + + const decoratedElement = cloneElement( + outerDeco.reduce(wrapInDeco, element), + // eslint-disable-next-line @typescript-eslint/no-explicit-any + outerDeco.some((d) => (d as any).type.attrs.nodeName) + ? { ref: domRef } + : // If all of the node decorations were attr-only, then + // we've already passed the domRef to the NodeView component + // as a prop + undefined + ); + + // TODO: Should we only be wrapping non-inline elements? Inline elements have + // already been wrapped in ChildNodeViews/InlineView? + const markedElement = node.marks.reduce( + (element, mark) => {element}, + decoratedElement + ); + + return ( + + + {cloneElement( + markedElement, + node.marks.length || + // eslint-disable-next-line @typescript-eslint/no-explicit-any + outerDeco.some((d) => (d as any).type.attrs.nodeName) + ? { ref: domRef } + : // If all of the node decorations were attr-only, then + // we've already passed the domRef to the NodeView component + // as a prop + undefined + )} + + + ); +} diff --git a/src/components/NodeViewComponentProps.tsx b/src/components/NodeViewComponentProps.tsx new file mode 100644 index 00000000..2e3df52b --- /dev/null +++ b/src/components/NodeViewComponentProps.tsx @@ -0,0 +1,14 @@ +import { Node } from "prosemirror-model"; +import { Decoration, DecorationSource } from "prosemirror-view"; +import { HTMLAttributes, ReactNode } from "react"; + +export type NodeViewComponentProps = { + nodeProps: { + decorations: readonly Decoration[]; + innerDecorations: DecorationSource; + node: Node; + children?: ReactNode | ReactNode[]; + isSelected: boolean; + pos: number; + }; +} & HTMLAttributes; diff --git a/src/components/OutputSpec.tsx b/src/components/OutputSpec.tsx new file mode 100644 index 00000000..4d8c536a --- /dev/null +++ b/src/components/OutputSpec.tsx @@ -0,0 +1,64 @@ +import { DOMOutputSpec } from "prosemirror-model"; +import React, { HTMLProps, ReactNode, createElement, forwardRef } from "react"; + +import { htmlAttrsToReactProps, mergeReactProps } from "../props.js"; + +type Props = HTMLProps & { + outputSpec: DOMOutputSpec; + children?: ReactNode; +}; + +const ForwardedOutputSpec = forwardRef(function OutputSpec( + { outputSpec, children, ...propOverrides }: Props, + ref +) { + if (typeof outputSpec === "string") { + return <>{outputSpec}; + } + + if (!Array.isArray(outputSpec)) { + throw new Error( + "@nytimes/react-prosemirror only supports strings and arrays in toDOM" + ); + } + + const tagSpec = outputSpec[0] as string; + const tagName = tagSpec.replace(" ", ":"); + const attrs = outputSpec[1]; + + let props: HTMLProps = { + ref, + ...propOverrides, + }; + let start = 1; + if ( + attrs && + typeof attrs === "object" && + attrs.nodeType == null && + !Array.isArray(attrs) + ) { + start = 2; + props = mergeReactProps(htmlAttrsToReactProps(attrs), props); + } + + const content: ReactNode[] = []; + for (let i = start; i < outputSpec.length; i++) { + const child = outputSpec[i] as DOMOutputSpec | 0; + if (child === 0) { + if (i < outputSpec.length - 1 || i > start) { + throw new RangeError( + "Content hole must be the only child of its parent node" + ); + } + return createElement(tagName, props, children); + } + content.push( + + {children} + + ); + } + return createElement(tagName, props, ...content); +}); + +export { ForwardedOutputSpec as OutputSpec }; diff --git a/src/components/ProseMirror.tsx b/src/components/ProseMirror.tsx index 0f65e908..020a00fe 100644 --- a/src/components/ProseMirror.tsx +++ b/src/components/ProseMirror.tsx @@ -1,31 +1,84 @@ -import React from "react"; - -import { LayoutGroup } from "../contexts/LayoutGroup.js"; - -import { ProseMirrorInner, ProseMirrorProps } from "./ProseMirrorInner.js"; - -/** - * Renders the ProseMirror View onto a DOM mount. - * - * The `mount` prop must be an actual HTMLElement instance. The - * JSX element representing the mount should be passed as a child - * to the ProseMirror component. - * - * e.g. - * - * ``` - * function MyProseMirrorField() { - * const [mount, setMount] = useState(null); - * - * return ( - * - *
    - * - * ); - * } - * ``` - */ -export function ProseMirror(props: ProseMirrorProps) { +import { DecorationSet, NodeViewConstructor } from "prosemirror-view"; +import React, { + ForwardRefExoticComponent, + ReactNode, + RefAttributes, + useState, +} from "react"; + +import { EditorContext } from "../contexts/EditorContext.js"; +import { NodeViewContext } from "../contexts/NodeViewContext.js"; +import { computeDocDeco } from "../decorations/computeDocDeco.js"; +import { viewDecorations } from "../decorations/viewDecorations.js"; +import { UseEditorOptions, useEditor } from "../hooks/useEditor.js"; + +import { LayoutGroup } from "./LayoutGroup.js"; +import { NodeViewComponentProps } from "./NodeViewComponentProps.js"; +import { DocNodeViewContext } from "./ProseMirrorDoc.js"; + +export type Props = Omit & { + className?: string; + children?: ReactNode; + nodeViews?: { + [nodeType: string]: ForwardRefExoticComponent< + // We need to allow refs to any type of HTMLElement, but there's + // no way to express that that still allows consumers to correctly + // type their own refs. This is sufficient to ensure that there's + // a ref of _some_ kind, which is enough. + // eslint-disable-next-line @typescript-eslint/no-explicit-any + NodeViewComponentProps & RefAttributes + >; + }; + customNodeViews?: { + [nodeType: string]: NodeViewConstructor; + }; +}; + +function ProseMirrorInner({ + className, + children, + nodeViews = {}, + customNodeViews, + ...props +}: Props) { + const [mount, setMount] = useState(null); + + const editor = useEditor(mount, { + ...props, + nodeViews: customNodeViews, + }); + + const innerDecos = editor.view + ? viewDecorations(editor.view, editor.cursorWrapper) + : (DecorationSet.empty as unknown as DecorationSet); + + const outerDecos = editor.view ? computeDocDeco(editor.view) : []; + + return ( + + + + {children} + + + + ); +} + +export function ProseMirror(props: Props) { return ( diff --git a/src/components/ProseMirrorDoc.tsx b/src/components/ProseMirrorDoc.tsx new file mode 100644 index 00000000..d8e18365 --- /dev/null +++ b/src/components/ProseMirrorDoc.tsx @@ -0,0 +1,61 @@ +import React, { + DetailedHTMLProps, + ForwardedRef, + HTMLAttributes, + ReactElement, + createContext, + forwardRef, + useContext, + useImperativeHandle, + useRef, +} from "react"; + +import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"; + +import { DocNodeView, DocNodeViewProps } from "./DocNodeView.js"; + +type DocNodeViewContextValue = Omit & { + setMount: (mount: HTMLElement | null) => void; +}; + +export const DocNodeViewContext = createContext( + null as unknown as DocNodeViewContextValue +); + +type Props = { + as?: ReactElement; +} & Omit, HTMLDivElement>, "ref">; + +function ProseMirrorDoc( + { as, ...props }: Props, + ref: ForwardedRef +) { + const innerRef = useRef(null); + const { setMount, ...docProps } = useContext(DocNodeViewContext); + + useImperativeHandle( + ref, + () => { + return innerRef.current; + }, + [] + ); + + return ( + + { + innerRef.current = el; + setMount(el); + }} + {...props} + {...docProps} + as={as} + /> + + ); +} + +const ForwardedProseMirrorDoc = forwardRef(ProseMirrorDoc); + +export { ForwardedProseMirrorDoc as ProseMirrorDoc }; diff --git a/src/components/ProseMirrorInner.tsx b/src/components/ProseMirrorInner.tsx deleted file mode 100644 index 95144f51..00000000 --- a/src/components/ProseMirrorInner.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React, { useMemo } from "react"; -import type { ReactNode } from "react"; - -import { EditorProvider } from "../contexts/EditorContext.js"; -import { useComponentEventListeners } from "../hooks/useComponentEventListeners.js"; -import { EditorProps, useEditorView } from "../hooks/useEditorView.js"; - -export type ProseMirrorProps = EditorProps & { - mount: HTMLElement | null; - children?: ReactNode | null; -}; - -/** - * Renders the ProseMirror View onto a DOM mount. - * - * The `mount` prop must be an actual HTMLElement instance. The - * JSX element representing the mount should be passed as a child - * to the ProseMirror component. - * - * e.g. - * - * ``` - * function MyProseMirrorField() { - * const [mount, setMount] = useState(null); - * - * return ( - * - *
    - * - * ); - * } - * ``` - */ -export function ProseMirrorInner({ - children, - mount, - ...editorProps -}: ProseMirrorProps) { - const { - componentEventListenersPlugin, - registerEventListener, - unregisterEventListener, - } = useComponentEventListeners(); - - const plugins = useMemo( - () => [...(editorProps.plugins ?? []), componentEventListenersPlugin], - [editorProps.plugins, componentEventListenersPlugin] - ); - - const editorView = useEditorView(mount, { - ...editorProps, - plugins, - }); - - const editorState = - "state" in editorProps ? editorProps.state : editorView?.state ?? null; - - const editorContextValue = useMemo( - () => ({ - editorView, - editorState, - registerEventListener, - unregisterEventListener, - }), - [editorState, editorView, registerEventListener, unregisterEventListener] - ); - - return ( - - {children ?? null} - - ); -} diff --git a/src/components/SeparatorHackView.tsx b/src/components/SeparatorHackView.tsx new file mode 100644 index 00000000..b61caf63 --- /dev/null +++ b/src/components/SeparatorHackView.tsx @@ -0,0 +1,34 @@ +import React, { useContext, useLayoutEffect, useRef, useState } from "react"; + +import { browser } from "../browser.js"; +import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"; +import { TrailingHackViewDesc } from "../viewdesc.js"; + +export function SeparatorHackView() { + const siblingDescriptors = useContext(ChildDescriptorsContext); + const ref = useRef(null); + const [shouldRender, setShouldRender] = useState(false); + + // There's no risk of an infinite loop here, because + // we call setShouldRender conditionally + // eslint-disable-next-line react-hooks/exhaustive-deps + useLayoutEffect(() => { + const lastSibling = siblingDescriptors[siblingDescriptors.length - 1]; + if ( + (browser.safari || browser.chrome) && + (lastSibling?.dom as HTMLElement)?.contentEditable == "false" + ) { + setShouldRender(true); + return; + } + + if (!ref.current) return; + + const desc = new TrailingHackViewDesc(undefined, [], ref.current, null); + siblingDescriptors.push(desc); + }); + + return shouldRender ? ( + + ) : null; +} diff --git a/src/components/TextNodeView.tsx b/src/components/TextNodeView.tsx new file mode 100644 index 00000000..e8c2c67e --- /dev/null +++ b/src/components/TextNodeView.tsx @@ -0,0 +1,110 @@ +import { Node } from "prosemirror-model"; +import { Decoration, DecorationSet, EditorView } from "prosemirror-view"; +import { Component } from "react"; +import { findDOMNode } from "react-dom"; + +import { CompositionViewDesc, TextViewDesc, ViewDesc } from "../viewdesc.js"; + +import { wrapInDeco } from "./ChildNodeViews.js"; + +type Props = { + view: EditorView | null; + node: Node; + pos: number; + siblingDescriptors: ViewDesc[]; + decorations: readonly Decoration[]; +}; + +export class TextNodeView extends Component { + private viewDescRef: null | TextViewDesc | CompositionViewDesc = null; + private renderRef: null | JSX.Element = null; + + updateEffect() { + const { view, decorations, siblingDescriptors, node } = this.props; + // There simply is no other way to ref a text node + // eslint-disable-next-line react/no-find-dom-node + const dom = findDOMNode(this); + + // We only need to explicitly create a CompositionViewDesc + // when a composition was started that produces a new text node. + // Otherwise we just rely on re-rendering the renderRef + if (!dom) { + if (!view?.composing) return; + + this.viewDescRef = new CompositionViewDesc( + undefined, + // These are just placeholders/dummies. We can't + // actually find the correct DOM nodes from here, + // so we let our parent do it. + // Passing a valid element here just so that the + // ViewDesc constructor doesn't blow up. + document.createElement("div"), + document.createTextNode(node.text ?? ""), + node.text ?? "" + ); + + return; + } + + let textNode = dom; + while (textNode.firstChild) { + textNode = textNode.firstChild as Element | Text; + } + + if (!this.viewDescRef || this.viewDescRef instanceof CompositionViewDesc) { + this.viewDescRef = new TextViewDesc( + undefined, + [], + node, + decorations, + DecorationSet.empty, + dom, + textNode + ); + } else { + this.viewDescRef.parent = undefined; + this.viewDescRef.children = []; + this.viewDescRef.node = node; + this.viewDescRef.outerDeco = decorations; + this.viewDescRef.innerDeco = DecorationSet.empty; + this.viewDescRef.dom = dom; + // @ts-expect-error We have our own ViewDesc implementations + this.viewDescRef.dom.pmViewDesc = this.viewDescRef; + this.viewDescRef.nodeDOM = textNode; + } + + siblingDescriptors.push(this.viewDescRef); + } + + componentDidMount(): void { + this.updateEffect(); + } + + componentDidUpdate(): void { + this.updateEffect(); + } + + render() { + const { view, pos, node, decorations } = this.props; + + // During a composition, it's crucial that we don't try to + // update the DOM that the user is working in. If there's + // an active composition and the selection is in this node, + // we freeze the DOM of this element so that it doesn't + // interrupt the composition + if ( + view?.composing && + view.state.selection.from >= pos && + view.state.selection.from <= pos + node.nodeSize + ) { + return this.renderRef; + } + + this.renderRef = decorations.reduce( + wrapInDeco, + node.text as unknown as JSX.Element + ); + + return this.renderRef; + } +} diff --git a/src/components/TrailingHackView.tsx b/src/components/TrailingHackView.tsx new file mode 100644 index 00000000..49c305f6 --- /dev/null +++ b/src/components/TrailingHackView.tsx @@ -0,0 +1,18 @@ +import React, { useContext, useLayoutEffect, useRef } from "react"; + +import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"; +import { TrailingHackViewDesc } from "../viewdesc.js"; + +export function TrailingHackView() { + const siblingDescriptors = useContext(ChildDescriptorsContext); + const ref = useRef<(HTMLBRElement & HTMLImageElement) | null>(null); + + useLayoutEffect(() => { + if (!ref.current) return; + + const desc = new TrailingHackViewDesc(undefined, [], ref.current, null); + siblingDescriptors.push(desc); + }); + + return
    ; +} diff --git a/src/components/WidgetView.tsx b/src/components/WidgetView.tsx new file mode 100644 index 00000000..72c05038 --- /dev/null +++ b/src/components/WidgetView.tsx @@ -0,0 +1,35 @@ +import React, { useContext, useLayoutEffect, useRef } from "react"; + +import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"; +import { ReactWidgetDecoration } from "../decorations/ReactWidgetType.js"; +import { WidgetViewDesc } from "../viewdesc.js"; + +type Props = { + widget: ReactWidgetDecoration; + pos: number; +}; + +export function WidgetView({ widget, pos }: Props) { + const siblingDescriptors = useContext(ChildDescriptorsContext); + const domRef = useRef(null); + + useLayoutEffect(() => { + if (!domRef.current) return; + + const desc = new WidgetViewDesc(undefined, widget, domRef.current); + siblingDescriptors.push(desc); + }); + + const { Component } = widget.type; + + return ( + Component && ( + + ) + ); +} diff --git a/src/components/WidgetViewComponentProps.ts b/src/components/WidgetViewComponentProps.ts new file mode 100644 index 00000000..0ae5ecd1 --- /dev/null +++ b/src/components/WidgetViewComponentProps.ts @@ -0,0 +1,8 @@ +import { HTMLAttributes } from "react"; + +import { ReactWidgetDecoration } from "../decorations/ReactWidgetType.js"; + +export type WidgetViewComponentProps = { + widget: ReactWidgetDecoration; + pos: number; +} & HTMLAttributes; diff --git a/src/components/__tests__/ProseMirror.composition.test.tsx b/src/components/__tests__/ProseMirror.composition.test.tsx new file mode 100644 index 00000000..d0f8ecd6 --- /dev/null +++ b/src/components/__tests__/ProseMirror.composition.test.tsx @@ -0,0 +1,432 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import { doc, em, p, strong } from "prosemirror-test-builder"; +// @ts-expect-error This is an internal export +import { EditorView, __endComposition } from "prosemirror-view"; + +import { + findTextNode, + tempEditor, +} from "../../testing/editorViewTestHelpers.js"; + +function endComposition(view: EditorView, forceUpdate?: boolean) { + __endComposition(view, forceUpdate); +} + +function event(pm: EditorView, type: string) { + pm.dom.dispatchEvent(new CompositionEvent(type)); +} + +function edit(node: Text, text = "", from = node.nodeValue!.length, to = from) { + const val = node.nodeValue!; + node.nodeValue = val.slice(0, from) + text + val.slice(to); + document.getSelection()!.collapse(node, from + text.length); + return node; +} + +function hasCompositionNode(_pm: EditorView) { + let { focusNode } = document.getSelection()!; + while (focusNode && !focusNode.pmViewDesc) focusNode = focusNode.parentNode; + return ( + focusNode && focusNode.pmViewDesc!.constructor.name == "CompositionViewDesc" + ); +} + +function compose( + pm: EditorView, + start: () => Text, + update: ((node: Text) => void)[], + options: any = {} +) { + event(pm, "compositionstart"); + expect(pm.composing).toBeTruthy(); + let node: Text; + const sel = document.getSelection()!; + for (let i = -1; i < update.length; i++) { + if (i < 0) node = start(); + else update[i]!(node!); + const { focusNode, focusOffset } = sel; + // @ts-expect-error Internal property + pm.domObserver.flush(); + + if (options.cancel && i == update.length - 1) { + expect(hasCompositionNode(pm)).toBeFalsy(); + } else { + expect( + node!.parentNode! && pm.dom.contains(node!.parentNode!) + ).toBeTruthy(); + expect(sel.focusNode === focusNode).toBeTruthy(); + expect(sel.focusOffset === focusOffset).toBeTruthy(); + if (options.node) expect(hasCompositionNode(pm)).toBeTruthy(); + } + } + event(pm, "compositionend"); + if (options.end) { + options.end(node!); + // @ts-expect-error Internal property + pm.domObserver.flush(); + } + endComposition(pm); + expect(pm.composing).toBeFalsy(); + expect(hasCompositionNode(pm)).toBeFalsy(); +} + +// function wordDeco(state: EditorState) { +// const re = /\w+/g, +// deco: Decoration[] = []; +// state.doc.descendants((node, pos) => { +// if (node.isText) +// for (let m; (m = re.exec(node.text!)); ) +// deco.push( +// Decoration.inline(pos + m.index, pos + m.index + m[0].length, { +// class: "word", +// }) +// ); +// }); +// return DecorationSet.create(state.doc, deco); +// } + +// const wordHighlighter = new Plugin({ +// props: { decorations: wordDeco }, +// }); + +// const Widget = forwardRef(function Widget( +// { widget, pos, ...props }: WidgetViewComponentProps, +// ref: Ref +// ) { +// return ( +// +// × +// +// ); +// }); + +// function widgets(positions: number[], sides: number[]) { +// return new Plugin({ +// state: { +// init(state) { +// const deco = positions.map((p, i) => +// widget(p, Widget, { side: sides[i] }) +// ); +// return DecorationSet.create(state.doc!, deco); +// }, +// apply(tr, deco) { +// return deco.map(tr.mapping, tr.doc); +// }, +// }, +// props: { +// decorations(this: Plugin, state) { +// return this.getState(state); +// }, +// }, +// }); +// } + +// These unfortunately aren't working at the moment, though +// composition seems to be working generally. +describe.skip("EditorView composition", () => { + it("supports composition in an empty block", () => { + const { view: pm } = tempEditor({ doc: doc(p("")) }); + compose( + pm, + () => edit(pm.dom.firstChild!.appendChild(document.createTextNode("a"))), + [(n) => edit(n, "b"), (n) => edit(n, "c")], + { node: true } + ); + expect(pm.state.doc).toEqualNode(doc(p("abc"))); + }); + + it("supports composition at end of block", () => { + const { view: pm } = tempEditor({ doc: doc(p("foo")) }); + compose(pm, () => edit(findTextNode(pm.dom, "foo")!), [ + (n) => edit(n, "!"), + (n) => edit(n, "?"), + ]); + expect(pm.state.doc).toEqualNode(doc(p("foo!?"))); + }); + + it("supports composition at end of block in a new node", () => { + const { view: pm } = tempEditor({ doc: doc(p("foo")) }); + compose( + pm, + () => edit(pm.dom.firstChild!.appendChild(document.createTextNode("!"))), + [(n) => edit(n, "?")], + // $$FORK: We don't use composition view descriptors except for in initially empty nodes + { node: false } + ); + expect(pm.state.doc).toEqualNode(doc(p("foo!?"))); + }); + + it("supports composition at start of block in a new node", () => { + const { view: pm } = tempEditor({ doc: doc(p("foo")) }); + compose( + pm, + () => { + const p = pm.dom.firstChild!; + return edit(p.insertBefore(document.createTextNode("!"), p.firstChild)); + }, + [(n) => edit(n, "?")], + // $$FORK: We don't use composition view descriptors except for in initially empty nodes + { node: false } + ); + expect(pm.state.doc).toEqualNode(doc(p("!?foo"))); + }); + + it("supports composition inside existing text", () => { + const { view: pm } = tempEditor({ doc: doc(p("foo")) }); + compose(pm, () => edit(findTextNode(pm.dom, "foo")!), [ + (n) => edit(n, "x", 1), + (n) => edit(n, "y", 2), + (n) => edit(n, "z", 3), + ]); + expect(pm.state.doc).toEqualNode(doc(p("fxyzoo"))); + }); + + // TODO: Offset out of bound + // eslint-disable-next-line jest/no-disabled-tests + it.skip("can deal with Android-style newline-after-composition", () => { + const { view: pm } = tempEditor({ doc: doc(p("abcdef")) }); + compose( + pm, + () => edit(findTextNode(pm.dom, "abcdef")!), + [(n) => edit(n, "x", 3), (n) => edit(n, "y", 4)], + { + end: (n: Text) => { + const line = pm.dom.appendChild(document.createElement("div")); + line.textContent = "def"; + n.nodeValue = "abcxy"; + document.getSelection()!.collapse(line, 0); + }, + } + ); + expect(pm.state.doc).toEqualNode(doc(p("abcxy"), p("def"))); + }); + + it("handles replacement of existing words", () => { + const { view: pm } = tempEditor({ doc: doc(p("one two three")) }); + compose( + pm, + () => edit(findTextNode(pm.dom, "one two three")!, "five", 4, 7), + [(n) => edit(n, "seven", 4, 8), (n) => edit(n, "zero", 4, 9)] + ); + expect(pm.state.doc).toEqualNode(doc(p("one zero three"))); + }); + + it("handles composition inside marks", () => { + const { view: pm } = tempEditor({ doc: doc(p("one ", em("two"))) }); + compose(pm, () => edit(findTextNode(pm.dom, "two")!, "o"), [ + (n) => edit(n, "o"), + (n) => edit(n, "w"), + ]); + expect(pm.state.doc).toEqualNode(doc(p("one ", em("twooow")))); + }); + + it.skip("handles composition in a mark that has multiple children", () => { + const { view: pm } = tempEditor({ + doc: doc(p("one ", em("two", strong(" three")))), + }); + compose(pm, () => edit(findTextNode(pm.dom, "two")!, "o"), [ + (n) => edit(n, "o"), + (n) => edit(n, "w"), + ]); + expect(pm.state.doc).toEqualNode( + doc(p("one ", em("twooow", strong(" three")))) + ); + }); + + // it("supports composition in a cursor wrapper", () => { + // const { view: pm } = tempEditor({ doc: doc(p("")) }); + // pm.dispatch(pm.state.tr.addStoredMark(schema.marks.em.create())); + // compose( + // pm, + // () => + // edit(pm.dom.firstChild!.appendChild(document.createTextNode("")), "a"), + // [(n) => edit(n, "b"), (n) => edit(n, "c")], + // { node: true } + // ); + // ist(pm.state.doc, doc(p(em("abc"))), eq); + // }); + + // it("handles composition in a multi-child mark with a cursor wrapper", () => { + // const { view: pm } = requireFocus( + // tempEditor({ doc: doc(p("one ", em("two", strong(" three")))) }) + // ); + // pm.dispatch(pm.state.tr.addStoredMark(schema.marks.code.create())); + // const emNode = pm.dom.querySelector("em")!; + // compose( + // pm, + // () => + // edit( + // emNode.insertBefore( + // document.createTextNode(""), + // emNode.querySelector("strong") + // ), + // "o" + // ), + // [(n) => edit(n, "o"), (n) => edit(n, "w")], + // { node: true } + // ); + // ist( + // pm.state.doc, + // doc(p("one ", em("two", code("oow"), strong(" three")))), + // eq + // ); + // }); + + // it("doesn't get interrupted by changes in decorations", () => { + // const { view: pm } = requireFocus( + // tempEditor({ doc: doc(p("foo ...")), plugins: [wordHighlighter] }) + // ); + // compose(pm, () => edit(findTextNode(pm.dom, " ...")!), [ + // (n) => edit(n, "hi", 1, 4), + // ]); + // ist(pm.state.doc, doc(p("foo hi")), eq); + // }); + + // it("works inside highlighted text", () => { + // const { view: pm } = requireFocus( + // tempEditor({ doc: doc(p("one two")), plugins: [wordHighlighter] }) + // ); + // compose(pm, () => edit(findTextNode(pm.dom, "one")!, "x"), [ + // (n) => edit(n, "y"), + // (n) => edit(n, "."), + // ]); + // ist(pm.state.doc, doc(p("onexy. two")), eq); + // }); + + // it("can handle compositions spanning multiple nodes", () => { + // const { view: pm } = requireFocus( + // tempEditor({ doc: doc(p("one two")), plugins: [wordHighlighter] }) + // ); + // compose( + // pm, + // () => edit(findTextNode(pm.dom, "two")!, "a"), + // [(n) => edit(n, "b"), (n) => edit(n, "c")], + // { + // end: (n: Text) => { + // n.parentNode!.previousSibling!.remove(); + // n.parentNode!.previousSibling!.remove(); + // return edit(n, "xyzone ", 0); + // }, + // } + // ); + // ist(pm.state.doc, doc(p("xyzone twoabc")), eq); + // }); + + // it("doesn't overwrite widgets next to the composition", () => { + // const { view: pm } = requireFocus( + // tempEditor({ doc: doc(p("")), plugins: [widgets([1, 1], [-1, 1])] }) + // ); + // compose( + // pm, + // () => { + // const p = pm.dom.firstChild!; + // return edit(p.insertBefore(document.createTextNode("a"), p.lastChild)); + // }, + // [(n) => edit(n, "b", 0, 1)], + // { + // end: () => { + // ist(pm.dom.querySelectorAll("var").length, 2); + // }, + // } + // ); + // ist(pm.state.doc, doc(p("b")), eq); + // }); + + // it("cancels composition when a change fully overlaps with it", () => { + // const { view: pm } = requireFocus( + // tempEditor({ doc: doc(p("one"), p("two"), p("three")) }) + // ); + // compose( + // pm, + // () => edit(findTextNode(pm.dom, "two")!, "x"), + // [() => pm.dispatch(pm.state.tr.insertText("---", 3, 13))], + // { cancel: true } + // ); + // ist(pm.state.doc, doc(p("on---hree")), eq); + // }); + + // it("cancels composition when a change partially overlaps with it", () => { + // const { view: pm } = requireFocus( + // tempEditor({ doc: doc(p("one"), p("two"), p("three")) }) + // ); + // compose( + // pm, + // () => edit(findTextNode(pm.dom, "two")!, "x", 0), + // [() => pm.dispatch(pm.state.tr.insertText("---", 7, 15))], + // { cancel: true } + // ); + // ist(pm.state.doc, doc(p("one"), p("x---ee")), eq); + // }); + + // it("cancels composition when a change happens inside of it", () => { + // const { view: pm } = requireFocus( + // tempEditor({ doc: doc(p("one"), p("two"), p("three")) }) + // ); + // compose( + // pm, + // () => edit(findTextNode(pm.dom, "two")!, "x", 0), + // [() => pm.dispatch(pm.state.tr.insertText("!", 7, 8))], + // { cancel: true } + // ); + // ist(pm.state.doc, doc(p("one"), p("x!wo"), p("three")), eq); + // }); + + // it("doesn't cancel composition when a change happens elsewhere", () => { + // const { view: pm } = requireFocus( + // tempEditor({ doc: doc(p("one"), p("two"), p("three")) }) + // ); + // compose(pm, () => edit(findTextNode(pm.dom, "two")!, "x", 0), [ + // (n) => edit(n, "y", 1), + // () => pm.dispatch(pm.state.tr.insertText("!", 2, 3)), + // (n) => edit(n, "z", 2), + // ]); + // ist(pm.state.doc, doc(p("o!e"), p("xyztwo"), p("three")), eq); + // }); + + // it("handles compositions rapidly following each other", () => { + // const { view: pm } = tempEditor({ doc: doc(p("one"), p("two")) }); + // event(pm, "compositionstart"); + // const one = findTextNode(pm.dom, "one")!; + // edit(one, "!"); + // pm.domObserver.flush(); + // event(pm, "compositionend"); + // one.nodeValue = "one!!"; + // const L2 = pm.dom.lastChild; + // event(pm, "compositionstart"); + // const two = findTextNode(pm.dom, "two")!; + // ist(pm.dom.lastChild, L2); + // edit(two, "."); + // pm.domObserver.flush(); + // ist(document.getSelection()!.focusNode, two); + // ist(document.getSelection()!.focusOffset, 4); + // ist(pm.composing); + // event(pm, "compositionend"); + // pm.domObserver.flush(); + // ist(pm.state.doc, doc(p("one!!"), p("two.")), eq); + // }); + + // function crossParagraph(first = false) { + // const { view: pm } = requireFocus( + // tempEditor({ doc: doc(p("one two"), p("three"), p("four five")) }) + // ); + // compose( + // pm, + // () => { + // for (let i = 0; i < 2; i++) + // pm.dom.removeChild(first ? pm.dom.lastChild! : pm.dom.firstChild!); + // const target = pm.dom.firstChild!.firstChild as Text; + // target.nodeValue = "one A five"; + // document.getSelection()!.collapse(target, 4); + // return target; + // }, + // [(n) => edit(n, "B", 4, 5), (n) => edit(n, "C", 4, 5)] + // ); + // ist(pm.state.doc, doc(p("one C five")), eq); + // } + + // it("can handle cross-paragraph compositions", () => crossParagraph(true)); + + // it("can handle cross-paragraph compositions (keeping the last paragraph)", () => + // crossParagraph(false)); +}); diff --git a/src/components/__tests__/ProseMirror.domchange.test.tsx b/src/components/__tests__/ProseMirror.domchange.test.tsx new file mode 100644 index 00000000..ad3d9429 --- /dev/null +++ b/src/components/__tests__/ProseMirror.domchange.test.tsx @@ -0,0 +1,304 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import { screen } from "@testing-library/react"; +import { EditorState, TextSelection } from "prosemirror-state"; +import { + a, + blockquote, + doc, + em, + p, + pre, + strong, +} from "prosemirror-test-builder"; +import { Step } from "prosemirror-transform"; +import { Key } from "webdriverio"; + +import { tempEditor } from "../../testing/editorViewTestHelpers.js"; + +describe("DOM change", () => { + it("notices when text is added", async () => { + const { view } = tempEditor({ doc: doc(p("hello")) }); + + view.focus(); + await browser.keys([Key.Shift, "l"]); + + expect(view.state.doc).toEqualNode(doc(p("heLllo"))); + }); + + it("notices when text is removed", async () => { + const { view } = tempEditor({ doc: doc(p("hello")) }); + + view.focus(); + await browser.keys(Key.Backspace); + await browser.keys(Key.Backspace); + + expect(view.state.doc).toEqualNode(doc(p("heo"))); + }); + + it("respects stored marks", async () => { + const { view } = tempEditor({ doc: doc(p("hello")) }); + view.dispatch( + view.state.tr.addStoredMark(view.state.schema.marks.em!.create()) + ); + view.focus(); + await browser.keys("o"); + + expect(view.state.doc).toEqualNode(doc(p("hello", em("o")))); + }); + + it("support inserting repeated text", async () => { + const { view } = tempEditor({ doc: doc(p("hello")) }); + view.focus(); + await browser.keys("h"); + await browser.keys("e"); + await browser.keys("l"); + + expect(view.state.doc).toEqualNode(doc(p("helhello"))); + }); + + it("detects an enter press", async () => { + let enterPressed = false; + const { view } = tempEditor({ + doc: doc(blockquote(p("foo"), p(""))), + handleKeyDown: (_, event) => { + if (event.key === "Enter") return (enterPressed = true); + return false; + }, + }); + + view.focus(); + await browser.keys(Key.Enter); + + expect(enterPressed).toBeTruthy(); + }); + + it("detects a simple backspace press", async () => { + let backspacePressed = false; + + const { view } = tempEditor({ + doc: doc(blockquote(p("foo"), p(""))), + handleKeyDown: (_, event) => { + if (event.key === "Backspace") return (backspacePressed = true); + return false; + }, + }); + + view.focus(); + await browser.keys(Key.Backspace); + + expect(backspacePressed).toBeTruthy(); + }); + + it("correctly adjusts the selection", async () => { + const { view } = tempEditor({ doc: doc(p("abc")) }); + view.focus(); + await browser.keys("d"); + + expect(view.state.doc).toEqualNode(doc(p("abcd"))); + expect(view.state.selection.anchor).toBe(5); + expect(view.state.selection.head).toBe(5); + }); + + // todoit("can read a simple composition", () => { + // let view = tempEditor({ doc: doc(p("hello")) }); + // findTextNode(view.dom, "hello")!.nodeValue = "hellox"; + // flush(view); + // ist(view.state.doc, doc(p("hellox")), eq); + // }); + + // $$FORK: We _do_ repaint text nodes when they're typed into. + // Unlike prosemirror-view, we prevent user inputs from modifying + // the dom until after we've turned them into transactions. + // This test instead ensures that we only modify the character data, + // rather than replacing entire nodes. + it("does not replace a text node when it's typed into", async () => { + const { view } = tempEditor({ + doc: doc(p("foo")), + }); + + let mutated = false; + const observer = new MutationObserver(() => (mutated = true)); + observer.observe(view.dom, { + subtree: true, + characterData: false, + childList: true, + }); + + view.focus(); + await browser.keys("j"); + + expect(view.state.doc).toEqualNode(doc(p("fojo"))); + expect(mutated).toBeFalsy(); + observer.disconnect(); + }); + + it("understands text typed into an empty paragraph", async () => { + const { view } = tempEditor({ doc: doc(p("")) }); + view.focus(); + await browser.keys("i"); + + expect(view.state.doc).toEqualNode(doc(p("i"))); + }); + + it("fixes text changes when input is ignored", async () => { + const { view } = tempEditor({ + doc: doc(p("foo")), + controlled: true, + dispatchTransaction() { + // intentionally do nothing + }, + }); + view.focus(); + await browser.keys("i"); + expect(view.dom.textContent).toBe("foo"); + }); + + it("aborts when an incompatible state is set", async () => { + const { view } = tempEditor({ doc: doc(p("abcde")) }); + + view.dispatchEvent({ type: "input" } as Event); + view.focus(); + await browser.keys("x"); + + view.updateState(EditorState.create({ doc: doc(p("uvw")) })); + expect(view.state.doc).toEqualNode(doc(p("uvw"))); + }); + + it("preserves marks on deletion", async () => { + const { view } = tempEditor({ doc: doc(p("one", em("x"))) }); + + view.focus(); + await browser.keys(Key.Backspace); + view.dispatchEvent({ type: "input" } as Event); + view.dispatch(view.state.tr.insertText("y")); + + expect(view.state.doc).toEqualNode(doc(p("one", em("y")))); + }); + + it("works when a node's contentDOM is deleted", async () => { + const { view } = tempEditor({ doc: doc(p("one"), pre("two")) }); + view.focus(); + await browser.keys(Key.Backspace); + await browser.keys(Key.Backspace); + await browser.keys(Key.Backspace); + view.dispatchEvent({ type: "input" } as Event); + expect(view.state.doc).toEqualNode(doc(p("one"), pre())); + expect(view.state.selection.head).toBe(6); + }); + + it("doesn't redraw content with marks when typing in front", async () => { + const { view } = tempEditor({ + doc: doc(p("foo", em("bar"), strong("baz"))), + }); + const bar = await screen.findByText("bar"); + const foo = await screen.findByText("foo"); + view.focus(); + await browser.keys("r"); + + expect(view.state.doc).toEqualNode( + doc(p("froo", em("bar"), strong("baz"))) + ); + expect(bar.parentNode).toBeTruthy(); + expect(view.dom.contains(bar.parentNode)).toBeTruthy(); + expect(foo.parentNode).toBeTruthy(); + expect(view.dom.contains(foo.parentNode)).toBeTruthy(); + }); + + it("doesn't redraw content with marks when typing inside mark", async () => { + const { view } = tempEditor({ + doc: doc(p("foo", em("bar"), strong("baz"))), + }); + const bar = await screen.findByText("bar"); + const foo = await screen.findByText("foo"); + view.focus(); + await browser.keys("a"); + + expect(view.state.doc).toEqualNode( + doc(p("foo", em("baar"), strong("baz"))) + ); + expect(bar.parentNode).toBeTruthy(); + expect(view.dom.contains(bar.parentNode)).toBeTruthy(); + expect(foo.parentNode).toBeTruthy(); + expect(view.dom.contains(foo.parentNode)).toBeTruthy(); + }); + + it("maps input to coordsAtPos through pending changes", async () => { + const { view } = tempEditor({ doc: doc(p("foo")) }); + view.dispatchEvent({ type: "input" } as Event); + view.dispatch(view.state.tr.insertText("more text")); + + expect(view.coordsAtPos(13)).toBeTruthy(); + }); + + it("notices text added to a cursor wrapper at the start of a mark", async () => { + const { view } = tempEditor({ + doc: doc(p(strong(a("foo"), "bar"))), + }); + view.focus(); + await browser.keys("xy"); + + expect(view.state.doc).toEqualNode(doc(p(strong(a("foo"), "xybar")))); + }); + + it("removes cursor wrapper text when the wrapper otherwise remains valid", async () => { + const { view } = tempEditor({ + doc: doc(p(a(strong("foo"), "bar"))), + }); + view.focus(); + await browser.keys("q"); + + expect(view.state.doc).toEqualNode(doc(p(a(strong("fooq"), "bar")))); + const found = screen.queryByText("\ufeffq"); + expect(found).toBeNull(); + }); + + it("creates a correct step for an ambiguous selection-deletion", async () => { + let steps: Step[]; + const { view } = tempEditor({ + doc: doc(p("lalala")), + dispatchTransaction(tr) { + steps = tr.steps; + view.updateState(view.state.apply(tr)); + }, + }); + + (view as any).input.lastKeyCode = 8; + (view as any).input.lastKeyCodeTime = Date.now(); + view.focus(); + await browser.keys(Key.Backspace); + + expect(steps!).toHaveLength(1); + expect((steps![0] as any).from).toBe(3); + expect((steps![0] as any).to).toBe(5); + }); + + it("creates a step that covers the entire selection for partially-matching replacement", async () => { + let steps: Step[]; + const { view } = tempEditor({ + doc: doc(p("one two three")), + dispatchTransaction(tr) { + steps = tr.steps; + view.updateState(view.state.apply(tr)); + }, + }); + + view.focus(); + await browser.keys("t"); + expect(steps!).toHaveLength(1); + expect((steps![0] as any).from).toBe(5); + expect((steps![0] as any).to).toBe(8); + expect((steps![0] as any).slice.content.toString()).toBe('<"t">'); + + view.dispatch( + view.state.tr.setSelection(TextSelection.create(view.state.doc, 7, 12)) + ); + view.focus(); + await browser.keys("e"); + + expect(steps!).toHaveLength(1); + expect((steps![0] as any).from).toBe(7); + expect((steps![0] as any).to).toBe(12); + expect((steps![0] as any).slice.content.toString()).toBe('<"e">'); + }); +}); diff --git a/src/components/__tests__/ProseMirror.draw-decoration.test.tsx b/src/components/__tests__/ProseMirror.draw-decoration.test.tsx new file mode 100644 index 00000000..dfa9e043 --- /dev/null +++ b/src/components/__tests__/ProseMirror.draw-decoration.test.tsx @@ -0,0 +1,875 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ + +// TODO: figure out whether it's possible to support native +// widgets. Right now, I'm not sure how we'd do it without +// wrapping them in another element, which would re-introduce +// all of the issues we had before with node views. +// +// For now, we've updated the factory in this file to use +// our React widgets. + +import { Schema } from "prosemirror-model"; +import { Plugin, TextSelection } from "prosemirror-state"; +import { + blockquote, + doc, + em, + h1, + hr, + img, + p, + schema, + strong, +} from "prosemirror-test-builder"; +import { + Decoration, + DecorationSet, + DecorationSource, + EditorView, +} from "prosemirror-view"; +import React, { LegacyRef, forwardRef, useEffect } from "react"; + +import { widget } from "../../decorations/ReactWidgetType.js"; +import { useEditorEffect } from "../../hooks/useEditorEffect.js"; +import { tempEditor } from "../../testing/editorViewTestHelpers.js"; +import { NodeViewComponentProps } from "../NodeViewComponentProps.js"; +import { WidgetViewComponentProps } from "../WidgetViewComponentProps.js"; + +const Widget = forwardRef(function Widget(props, ref) { + return ( + + ); +}); + +function make(str: string | Decoration): Decoration { + if (typeof str != "string") return str; + const match = /^(\d+)(?:-(\d+))?-(.+)$/.exec(str)!; + if (match[3] == "widget") { + return widget(+match[1]!, Widget, { key: str }); + } + return Decoration.inline(+match[1]!, +match[2]!, { class: match[3] }); +} + +function decoPlugin(decos: readonly (string | Decoration)[]) { + return new Plugin({ + state: { + init(config) { + return config.doc + ? DecorationSet.create(config.doc, decos.map(make)) + : DecorationSet.empty; + }, + apply(tr, set, state) { + if (tr.docChanged) set = set.map(tr.mapping, tr.doc); + const change = tr.getMeta("updateDecorations"); + if (change) { + if (change.remove) set = set.remove(change.remove); + if (change.add) set = set.add(state.doc, change.add); + } + return set; + }, + }, + props: { + decorations(this: Plugin, state) { + return this.getState(state); + }, + }, + }); +} + +function updateDeco( + view: EditorView, + add: readonly Decoration[] | null, + remove?: readonly Decoration[] +) { + view.dispatch(view.state.tr.setMeta("updateDecorations", { add, remove })); +} + +describe("Decoration drawing", () => { + it("draws inline decorations", async () => { + const { view } = tempEditor({ + doc: doc(p("foobar")), + plugins: [decoPlugin(["2-5-foo"])], + }); + const found = view.dom.querySelector(".foo")!; + expect(found).not.toBeNull(); + expect(found.textContent).toBe("oob"); + }); + + it("draws wrapping decorations", async () => { + const { view } = tempEditor({ + doc: doc(p("foo")), + plugins: [decoPlugin([Decoration.inline(1, 5, { nodeName: "i" })])], + }); + const found = view.dom.querySelector("i"); + expect(found && found.innerHTML).toBe("foo"); + }); + + it("draws node decorations", async () => { + const { view } = tempEditor({ + doc: doc(p("foo"), p("bar")), + plugins: [decoPlugin([Decoration.node(5, 10, { class: "cls" })])], + }); + const found = view.dom.querySelectorAll(".cls"); + expect(found).toHaveLength(1); + expect(found[0]!.nodeName).toBe("P"); + expect(found[0]!.previousSibling!.nodeName).toBe("P"); + }); + + it("can update multi-level wrapping decorations", async () => { + const d2 = Decoration.inline(1, 5, { nodeName: "i", class: "b" }); + const { view } = tempEditor({ + doc: doc(p("hello")), + plugins: [ + decoPlugin([ + Decoration.inline(1, 5, { nodeName: "i", class: "a" }), + d2, + ]), + ], + }); + expect(view.dom.querySelectorAll("i")).toHaveLength(2); + updateDeco( + view, + [Decoration.inline(1, 5, { nodeName: "i", class: "c" })], + [d2] + ); + const iNodes = view.dom.querySelectorAll("i"); + expect(iNodes).toHaveLength(2); + expect( + Array.prototype.map + .call(iNodes, (n) => n.className) + .sort() + .join() + ).toBe("a,c"); + }); + + it("draws overlapping inline decorations", async () => { + const { view } = tempEditor({ + doc: doc(p("abcdef")), + plugins: [decoPlugin(["3-5-foo", "4-6-bar", "1-7-baz"])], + }); + const baz = view.dom.querySelectorAll(".baz") as any as HTMLElement[]; + expect(baz).toHaveLength(5); + expect(Array.prototype.map.call(baz, (x) => x.textContent).join("-")).toBe( + "ab-c-d-e-f" + ); + function classes(n: HTMLElement) { + return n.className.split(" ").sort().join(" "); + } + expect(classes(baz[1]!)).toBe("baz foo"); + expect(classes(baz[2]!)).toBe("bar baz foo"); + expect(classes(baz[3]!)).toBe("bar baz"); + }); + + it("draws multiple widgets", async () => { + const { view } = tempEditor({ + doc: doc(p("foobar")), + plugins: [decoPlugin(["1-widget", "4-widget", "7-widget"])], + }); + const found = view.dom.querySelectorAll("button") as any as HTMLElement[]; + expect(found).toHaveLength(3); + expect(found[0]!.nextSibling!.textContent).toBe("foo"); + expect(found[1]!.nextSibling!.textContent).toBe("bar"); + expect(found[2]!.previousSibling!.textContent).toBe("bar"); + }); + + it("orders widgets by their side option", async () => { + const { view } = tempEditor({ + doc: doc(p("foobar")), + plugins: [ + decoPlugin([ + widget( + 4, + forwardRef(function B( + props, + ref + ) { + return ( + + B + + ); + }), + { key: "widget-b" } + ), + widget( + 4, + forwardRef(function A( + props, + ref + ) { + return ( + + A + + ); + }), + { side: -100, key: "widget-a" } + ), + widget( + 4, + forwardRef(function C( + props, + ref + ) { + return ( + + C + + ); + }), + { side: 2, key: "widget-c" } + ), + ]), + ], + }); + expect(view.dom.textContent).toBe("fooABCbar"); + }); + + it("draws a widget in an empty node", async () => { + const { view } = tempEditor({ + doc: doc(p()), + plugins: [decoPlugin(["1-widget"])], + }); + expect(view.dom.querySelectorAll("button")).toHaveLength(1); + }); + + it("draws widgets on node boundaries", async () => { + const { view } = tempEditor({ + doc: doc(p("foo", em("bar"))), + plugins: [decoPlugin(["4-widget"])], + }); + expect(view.dom.querySelectorAll("button")).toHaveLength(1); + }); + + it("draws decorations from multiple plugins", async () => { + const { view } = tempEditor({ + doc: doc(p("foo", em("bar"))), + plugins: [decoPlugin(["2-widget"]), decoPlugin(["6-widget"])], + }); + expect(view.dom.querySelectorAll("button")).toHaveLength(2); + }); + + it("calls widget destroy methods", async () => { + let destroyed = false; + const DestroyableWidget = forwardRef( + function DestroyableWidget(props, ref) { + useEffect(() => { + destroyed = true; + }); + return ( + + ); + } + ); + const { view } = tempEditor({ + doc: doc(p("abc")), + plugins: [ + decoPlugin([ + widget(2, DestroyableWidget, { key: "destroyable-widget" }), + ]), + ], + }); + view.dispatch(view.state.tr.delete(1, 4)); + expect(destroyed).toBeTruthy(); + }); + + it("draws inline decorations spanning multiple parents", async () => { + const { view } = tempEditor({ + doc: doc(p("long first ", em("p"), "aragraph"), p("two")), + plugins: [decoPlugin(["7-25-foo"])], + }); + const foos = view.dom.querySelectorAll(".foo"); + expect(foos).toHaveLength(4); + expect(foos[0]!.textContent).toBe("irst "); + expect(foos[1]!.textContent).toBe("p"); + expect(foos[2]!.textContent).toBe("aragraph"); + expect(foos[3]!.textContent).toBe("tw"); + }); + + it("draws inline decorations across empty paragraphs", async () => { + const { view } = tempEditor({ + doc: doc(p("first"), p(), p("second")), + plugins: [decoPlugin(["3-12-foo"])], + }); + const foos = view.dom.querySelectorAll(".foo"); + expect(foos).toHaveLength(2); + expect(foos[0]!.textContent).toBe("rst"); + expect(foos[1]!.textContent).toBe("se"); + }); + + it("can handle inline decorations ending at the start or end of a node", async () => { + const { view } = tempEditor({ + doc: doc(p(), p()), + plugins: [decoPlugin(["1-3-foo"])], + }); + expect(view.dom.querySelector(".foo")).toBeNull(); + }); + + it("can draw decorations with multiple classes", async () => { + const { view } = tempEditor({ + doc: doc(p("foo")), + plugins: [decoPlugin(["1-4-foo bar"])], + }); + expect(view.dom.querySelectorAll(".foo")).toHaveLength(1); + expect(view.dom.querySelectorAll(".bar")).toHaveLength(1); + }); + + it("supports overlapping inline decorations", async () => { + const { view } = tempEditor({ + doc: doc(p("foobar")), + plugins: [decoPlugin(["1-3-foo", "2-5-bar"])], + }); + const foos = view.dom.querySelectorAll(".foo"); + const bars = view.dom.querySelectorAll(".bar"); + expect(foos).toHaveLength(2); + expect(bars).toHaveLength(2); + expect(foos[0]!.textContent).toBe("f"); + expect(foos[1]!.textContent).toBe("o"); + expect(bars[0]!.textContent).toBe("o"); + expect(bars[1]!.textContent).toBe("ob"); + }); + + it("doesn't redraw when irrelevant decorations change", async () => { + const { view } = tempEditor({ + doc: doc(p("foo"), p("baz")), + plugins: [decoPlugin(["7-8-foo"])], + }); + const para2 = view.dom.lastChild; + updateDeco(view, [make("2-3-bar")]); + expect(view.dom.lastChild).toBe(para2); + expect(view.dom.querySelector(".bar")).not.toBeNull(); + }); + + it("doesn't redraw when irrelevant content changes", async () => { + const { view } = tempEditor({ + doc: doc(p("foo"), p("baz")), + plugins: [decoPlugin(["7-8-foo"])], + }); + const para2 = view.dom.lastChild; + view.dispatch(view.state.tr.delete(2, 3)); + view.dispatch(view.state.tr.delete(2, 3)); + expect(view.dom.lastChild).toBe(para2); + }); + + it("can add a widget on a node boundary", async () => { + const { view } = tempEditor({ + doc: doc(p("foo", em("bar"))), + plugins: [decoPlugin([])], + }); + updateDeco(view, [make("4-widget")]); + expect(view.dom.querySelectorAll("button")).toHaveLength(1); + }); + + it("can remove a widget on a node boundary", async () => { + const dec = make("4-widget"); + const { view } = tempEditor({ + doc: doc(p("foo", em("bar"))), + plugins: [decoPlugin([dec])], + }); + updateDeco(view, null, [dec]); + expect(view.dom.querySelector("button")).toBeNull(); + }); + + it("can remove the class from a text node", async () => { + const dec = make("1-4-foo"); + const { view } = tempEditor({ + doc: doc(p("abc")), + plugins: [decoPlugin([dec])], + }); + expect(view.dom.querySelector(".foo")).not.toBeNull(); + updateDeco(view, null, [dec]); + expect(view.dom.querySelector(".foo")).toBeNull(); + }); + + it("can remove the class from part of a text node", async () => { + const dec = make("2-4-foo"); + const { view } = tempEditor({ + doc: doc(p("abcd")), + plugins: [decoPlugin([dec])], + }); + expect(view.dom.querySelector(".foo")).not.toBeNull(); + updateDeco(view, null, [dec]); + expect(view.dom.querySelector(".foo")).toBeNull(); + expect((view.dom.firstChild as HTMLElement).innerHTML).toBe("abcd"); + }); + + it("can change the class for part of a text node", async () => { + const dec = make("2-4-foo"); + const { view } = tempEditor({ + doc: doc(p("abcd")), + plugins: [decoPlugin([dec])], + }); + expect(view.dom.querySelector(".foo")).not.toBeNull(); + updateDeco(view, [make("2-4-bar")], [dec]); + expect(view.dom.querySelector(".foo")).toBeNull(); + expect(view.dom.querySelector(".bar")).not.toBeNull(); + }); + + it("draws a widget added in the middle of a text node", async () => { + const { view } = tempEditor({ + doc: doc(p("foo")), + plugins: [decoPlugin([])], + }); + updateDeco(view, [make("3-widget")]); + expect((view.dom.firstChild as HTMLElement).textContent).toBe("foωo"); + }); + + it("can update a text node around a widget", async () => { + const { view } = tempEditor({ + doc: doc(p("bar")), + plugins: [decoPlugin(["3-widget"])], + }); + view.dispatch(view.state.tr.delete(1, 2)); + expect(view.dom.querySelectorAll("button")).toHaveLength(1); + expect((view.dom.firstChild as HTMLElement).textContent).toBe("aωr"); + }); + + it("can update a text node with an inline decoration", async () => { + const { view } = tempEditor({ + doc: doc(p("bar")), + plugins: [decoPlugin(["1-3-foo"])], + }); + view.dispatch(view.state.tr.delete(1, 2)); + const foo = view.dom.querySelector(".foo") as HTMLElement; + expect(foo).not.toBeNull(); + expect(foo.textContent).toBe("a"); + expect(foo.nextSibling!.textContent).toBe("r"); + }); + + it("correctly redraws a partially decorated node when a widget is added", async () => { + const { view } = tempEditor({ + doc: doc(p("one", em("two"))), + plugins: [decoPlugin(["1-6-foo"])], + }); + updateDeco(view, [make("6-widget")]); + const foos = view.dom.querySelectorAll(".foo"); + expect(foos).toHaveLength(2); + expect(foos[0]!.textContent).toBe("one"); + expect(foos[1]!.textContent).toBe("tw"); + }); + + it("correctly redraws when skipping split text node", async () => { + const { view } = tempEditor({ + doc: doc(p("foo")), + plugins: [decoPlugin(["3-widget", "3-4-foo"])], + }); + updateDeco(view, [make("4-widget")]); + expect(view.dom.querySelectorAll("button")).toHaveLength(2); + }); + + it("drops removed node decorations from the view", async () => { + const deco = Decoration.node(1, 6, { class: "cls" }); + const { view } = tempEditor({ + doc: doc(blockquote(p("foo"), p("bar"))), + plugins: [decoPlugin([deco])], + }); + updateDeco(view, null, [deco]); + expect(view.dom.querySelector(".cls")).toBeNull(); + }); + + it("can update a node's attributes without replacing the node", async () => { + const deco = Decoration.node(0, 5, { title: "title", class: "foo" }); + const { view } = tempEditor({ + doc: doc(p("foo")), + plugins: [decoPlugin([deco])], + }); + const para = view.dom.querySelector("p") as HTMLElement; + updateDeco(view, [Decoration.node(0, 5, { class: "foo bar" })], [deco]); + expect(view.dom.querySelector("p")).toBe(para); + expect(para.className).toBe("foo bar"); + expect(para.title).toBeFalsy(); + }); + + it("can add and remove CSS custom properties from a node", async () => { + const deco = Decoration.node(0, 5, { style: "--my-custom-property:36px" }); + const { view } = tempEditor({ + doc: doc(p("foo")), + plugins: [decoPlugin([deco])], + }); + expect( + view.dom + .querySelector("p")! + .style.getPropertyValue("--my-custom-property") + ).toBe("36px"); + updateDeco(view, null, [deco]); + expect( + view.dom + .querySelector("p")! + .style.getPropertyValue("--my-custom-property") + ).toBe(""); + }); + + it("updates decorated nodes even if a widget is added before them", async () => { + const { view } = tempEditor({ + doc: doc(p("a"), p("b")), + plugins: [decoPlugin([])], + }); + const lastP = view.dom.querySelectorAll("p")[1]; + updateDeco(view, [ + make("3-widget"), + Decoration.node(3, 6, { style: "color: red" }), + ]); + expect(lastP!.style.color).toBe("red"); + }); + + it("doesn't redraw nodes when a widget before them is replaced", async () => { + const w0 = make("3-widget"); + const { view } = tempEditor({ + doc: doc(h1("a"), p("b")), + plugins: [decoPlugin([w0])], + }); + const initialP = view.dom.querySelector("p"); + view.dispatch( + view.state.tr + .setMeta("updateDecorations", { + add: [make("3-widget")], + remove: [w0], + }) + .insertText("c", 5) + ); + expect(view.dom.querySelector("p")).toBe(initialP); + }); + + it("can add and remove inline style", async () => { + const deco = Decoration.inline(1, 6, { + style: "color: rgba(0,10,200,.4); text-decoration: underline", + }); + const { view } = tempEditor({ + doc: doc(p("al", img(), "lo")), + plugins: [decoPlugin([deco])], + }); + expect(view.dom.querySelector("img")!.style.color).toMatch(/rgba/); + expect( + (view.dom.querySelector("img")!.previousSibling as HTMLElement).style + .textDecoration + ).toBe("underline"); + updateDeco(view, null, [deco]); + expect(view.dom.querySelector("img")!.style.color).toBe(""); + expect(view.dom.querySelector("img")!.style.textDecoration).toBe(""); + }); + + it("passes decorations to a node view", async () => { + let current = ""; + const { view } = tempEditor({ + doc: doc(p("foo"), hr()), + plugins: [decoPlugin([])], + nodeViews: { + horizontal_rule: forwardRef( + function HR({ nodeProps, children, ...props }, ref) { + current = nodeProps.decorations.map((d) => d.spec.name).join(); + return
    } {...props} />; + } + ), + }, + }); + const a = Decoration.node(5, 6, {}, { name: "a" }); + updateDeco(view, [a], []); + expect(current).toBe("a"); + updateDeco( + view, + [ + Decoration.node(5, 6, {}, { name: "b" }), + Decoration.node(5, 6, {}, { name: "c" }), + ], + [a] + ); + expect(current).toBe("b,c"); + }); + + it("draws the specified marks around a widget", async () => { + const { view } = tempEditor({ + doc: doc(p("foobar")), + plugins: [ + decoPlugin([ + widget( + 4, + forwardRef(function Img( + props, + ref + ) { + return ( + } /> + ); + }), + { + marks: [schema.mark("em")], + key: "img-widget", + } + ), + ]), + ], + }); + expect(view.dom.querySelector("em img")).not.toBeNull(); + }); + + it("draws widgets inside the marks for their side", async () => { + const { view } = tempEditor({ + doc: doc(p(em("foo"), strong("bar"))), + plugins: [ + decoPlugin([ + widget( + 4, + forwardRef(function Img( + props, + ref + ) { + return ( + } /> + ); + }), + { side: -1, key: "img-widget" } + ), + ]), + decoPlugin([ + widget( + 4, + forwardRef(function BR( + props, + ref + ) { + return
    } />; + }), + { key: "br-widget" } + ), + ]), + decoPlugin([ + widget( + 7, + forwardRef( + function Span(props, ref) { + return ; + } + ), + { side: 1, key: "span-widget" } + ), + ]), + ], + }); + expect(view.dom.querySelector("em img")).not.toBeNull(); + expect(view.dom.querySelector("strong img")).toBeNull(); + expect(view.dom.querySelector("strong br")).not.toBeNull(); + expect(view.dom.querySelector("em br")).toBeNull(); + expect(view.dom.querySelector("strong span")).toBeNull(); + }); + + it("draws decorations inside node views", async () => { + const { view } = tempEditor({ + doc: doc(p("foo")), + nodeViews: { + paragraph: forwardRef( + function Paragraph({ nodeProps, children, ...props }, ref) { + return ( +

    } {...props}> + {children} +

    + ); + } + ), + }, + plugins: [ + decoPlugin([ + widget( + 2, + forwardRef(function Img( + props, + ref + ) { + return ( + } /> + ); + }), + { key: "img-widget" } + ), + ]), + ], + }); + expect(view.dom.querySelector("img")).not.toBeNull(); + }); + + it("can delay widget drawing to render time", async () => { + const { view } = tempEditor({ + doc: doc(p("hi")), + decorations(state) { + return DecorationSet.create(state.doc, [ + widget( + 3, + forwardRef(function Span( + props, + ref + ) { + useEditorEffect((view) => { + expect(view.state).toBe(state); + }); + return ( + + ! + + ); + }), + { key: "span-widget" } + ), + ]); + }, + }); + expect(view.dom.textContent).toBe("hi!"); + }); + + it("supports widgets querying their own position", async () => { + tempEditor({ + doc: doc(p("hi")), + decorations(state) { + return DecorationSet.create(state.doc, [ + widget( + 3, + forwardRef( + function Widget( + { pos, ...props }: WidgetViewComponentProps, + ref + ) { + expect(pos).toBe(3); + return ( + + ); + } + ), + { key: "button-widget" } + ), + ]); + }, + }); + }); + + it("doesn't redraw widgets with matching keys", async () => { + const { view } = tempEditor({ + doc: doc(p("hi")), + decorations(state) { + return DecorationSet.create(state.doc, [ + widget(2, Widget, { key: "myButton" }), + ]); + }, + }); + const widgetDOM = view.dom.querySelector("button"); + view.dispatch(view.state.tr.insertText("!", 2, 2)); + expect(view.dom.querySelector("button")).toBe(widgetDOM); + }); + + it("doesn't redraw widgets with identical specs", async () => { + const { view } = tempEditor({ + doc: doc(p("hi")), + decorations(state) { + return DecorationSet.create(state.doc, [ + widget(2, Widget, { side: 1, key: "widget" }), + ]); + }, + }); + const widgetDOM = view.dom.querySelector("button"); + view.dispatch(view.state.tr.insertText("!", 2, 2)); + expect(view.dom.querySelector("button")).toBe(widgetDOM); + }); + + it("doesn't get confused by split text nodes", async () => { + const { view } = tempEditor({ + doc: doc(p("abab")), + decorations(state) { + return state.selection.from <= 1 + ? null + : DecorationSet.create(view.state.doc, [ + Decoration.inline(1, 2, { class: "foo" }), + Decoration.inline(3, 4, { class: "foo" }), + ]); + }, + }); + view.dispatch( + view.state.tr.setSelection(TextSelection.create(view.state.doc, 5)) + ); + expect(view.dom.textContent).toBe("abab"); + }); + + it("only draws inline decorations on the innermost level", async () => { + const s = new Schema({ + nodes: { + doc: { content: "(text | thing)*" }, + text: {}, + thing: { + inline: true, + content: "text*", + toDOM: () => ["strong", 0], + parseDOM: [{ tag: "strong" }], + }, + }, + }); + const { view } = tempEditor({ + doc: s.node("doc", null, [ + s.text("abc"), + s.node("thing", null, [s.text("def")]), + s.text("ghi"), + ]) as ReturnType, + decorations: (s) => + DecorationSet.create(s.doc, [ + Decoration.inline(1, 10, { class: "dec" }), + ]), + }); + const styled = view.dom.querySelectorAll(".dec"); + expect(styled).toHaveLength(3); + expect(Array.prototype.map.call(styled, (n) => n.textContent).join()).toBe( + "bc,def,gh" + ); + expect(styled[1]!.parentNode!.nodeName).toBe("STRONG"); + }); + + it("can handle nodeName decoration overlapping with classes", async () => { + const { view } = tempEditor({ + doc: doc(p("one two three")), + plugins: [ + decoPlugin([ + Decoration.inline(2, 13, { class: "foo" }), + Decoration.inline(5, 8, { nodeName: "em" }), + ]), + ], + }); + expect((view.dom.firstChild as HTMLElement).innerHTML).toBe( + 'one two three' + ); + }); + + it("can handle combining decorations from parent editors in child editors", async () => { + let decosFromFirstEditor: DecorationSource | undefined; + let { view } = tempEditor({ + doc: doc(p("one two three")), + plugins: [ + decoPlugin([Decoration.inline(2, 13, { class: "foo" })]), + decoPlugin([Decoration.inline(2, 13, { class: "bar" })]), + ], + nodeViews: { + paragraph: forwardRef( + function Paragraph( + { nodeProps, children, ...props }: NodeViewComponentProps, + ref + ) { + decosFromFirstEditor = nodeProps.innerDecorations; + return ( +

    } {...props}> + {children} +

    + ); + } + ), + }, + }); + + ({ view } = tempEditor({ + doc: doc(p("one two three")), + plugins: [decoPlugin([Decoration.inline(1, 12, { class: "baz" })])], + decorations: () => decosFromFirstEditor, + })); + + expect(view.dom.querySelectorAll(".foo")).toHaveLength(1); + expect(view.dom.querySelectorAll(".bar")).toHaveLength(1); + expect(view.dom.querySelectorAll(".baz")).toHaveLength(1); + }); +}); diff --git a/src/components/__tests__/ProseMirror.draw.test.tsx b/src/components/__tests__/ProseMirror.draw.test.tsx new file mode 100644 index 00000000..f2e700f3 --- /dev/null +++ b/src/components/__tests__/ProseMirror.draw.test.tsx @@ -0,0 +1,239 @@ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import { Schema } from "prosemirror-model"; +import { Plugin } from "prosemirror-state"; +import { doc, h1, hr, p, pre, schema, strong } from "prosemirror-test-builder"; +import React, { forwardRef } from "react"; + +import { tempEditor } from "../../testing/editorViewTestHelpers.js"; +import { NodeViewComponentProps } from "../NodeViewComponentProps.js"; + +describe("EditorView draw", () => { + it("updates the DOM", async () => { + const { view } = tempEditor({ doc: doc(p("foo")) }); + view.dispatch(view.state.tr.insertText("bar")); + expect(view.dom.textContent).toBe("barfoo"); + }); + + it("doesn't redraw nodes after changes", async () => { + const { view } = tempEditor({ doc: doc(h1("foo
    "), p("bar")) }); + const oldP = view.dom.querySelector("p"); + + view.dispatch(view.state.tr.insertText("!")); + expect(view.dom.querySelector("p")).toBe(oldP); + }); + + it("doesn't redraw nodes before changes", async () => { + const { view } = tempEditor({ doc: doc(p("foo"), h1("bar")) }); + const oldP = view.dom.querySelector("p"); + + view.dispatch(view.state.tr.insertText("!", 2)); + expect(view.dom.querySelector("p")).toBe(oldP); + }); + + it("doesn't redraw nodes between changes", async () => { + const { view } = tempEditor({ + doc: doc(p("foo"), h1("bar"), pre("baz")), + }); + const oldP = view.dom.querySelector("p"); + const oldPre = view.dom.querySelector("pre"); + + view.dispatch(view.state.tr.insertText("!", 2)); + expect(view.dom.querySelector("p")).toBe(oldP); + expect(view.dom.querySelector("pre")).toBe(oldPre); + }); + + it("doesn't redraw siblings of a split node", async () => { + const { view } = tempEditor({ + doc: doc(p("foo"), h1("bar"), pre("baz")), + }); + const oldP = view.dom.querySelector("p"); + const oldPre = view.dom.querySelector("pre"); + + view.dispatch(view.state.tr.split(8)); + expect(view.dom.querySelector("p")).toBe(oldP); + expect(view.dom.querySelector("pre")).toBe(oldPre); + }); + + it("doesn't redraw siblings of a joined node", async () => { + const { view } = tempEditor({ + doc: doc(p("foo"), h1("bar"), h1("x"), pre("baz")), + }); + const oldP = view.dom.querySelector("p"); + const oldPre = view.dom.querySelector("pre"); + + view.dispatch(view.state.tr.join(10)); + expect(view.dom.querySelector("p")).toBe(oldP); + expect(view.dom.querySelector("pre")).toBe(oldPre); + }); + + it("doesn't redraw after a big deletion", async () => { + const { view } = tempEditor({ + doc: doc(p(), p(), p(), p(), p(), p(), p(), p(), h1("!"), p(), p()), + }); + const oldH = view.dom.querySelector("h1"); + + view.dispatch(view.state.tr.delete(2, 14)); + expect(view.dom.querySelector("h1")).toBe(oldH); + }); + + it("adds classes from the attributes prop", async () => { + const { view, rerender } = tempEditor({ + doc: doc(p()), + attributes: { class: "foo bar" }, + }); + expect(view.dom.classList.contains("foo")).toBeTruthy(); + expect(view.dom.classList.contains("bar")).toBeTruthy(); + expect(view.dom.classList.contains("ProseMirror")).toBeTruthy(); + rerender({ attributes: { class: "baz" } }); + expect(!view.dom.classList.contains("foo")).toBeTruthy(); + expect(view.dom.classList.contains("baz")).toBeTruthy(); + }); + + it("adds style from the attributes prop", async () => { + const { view } = tempEditor({ + doc: doc(p()), + attributes: { style: "border: 1px solid red;" }, + plugins: [ + new Plugin({ props: { attributes: { style: "background: red;" } } }), + new Plugin({ props: { attributes: { style: "color: red;" } } }), + ], + }); + expect(view.dom.style.border).toBe("1px solid red"); + expect(view.dom.style.backgroundColor).toBe("red"); + expect(view.dom.style.color).toBe("red"); + }); + + it("can set other attributes", async () => { + const { view, rerender } = tempEditor({ + doc: doc(p()), + attributes: { spellcheck: "false", "aria-label": "hello" }, + }); + expect(view.dom.spellcheck).toBe(false); + expect(view.dom.getAttribute("aria-label")).toBe("hello"); + rerender({ + attributes: { style: "background-color: yellow" }, + }); + expect(view.dom.hasAttribute("aria-label")).toBe(false); + expect(view.dom.style.backgroundColor).toBe("yellow"); + }); + + it("can't set the contenteditable attribute", async () => { + const { view } = tempEditor({ + doc: doc(p()), + attributes: { contenteditable: "false" }, + }); + expect(view.dom.contentEditable).toBe("true"); + }); + + it("understands the editable prop", async () => { + const { view, rerender } = tempEditor({ + doc: doc(p()), + editable: () => false, + }); + expect(view.dom.contentEditable).toBe("false"); + rerender({ editable: () => true }); + expect(view.dom.contentEditable).toBe("true"); + }); + + it("doesn't redraw following paragraphs when a paragraph is split", async () => { + const { view } = tempEditor({ doc: doc(p("abcde"), p("fg")) }); + const lastPara = view.dom.lastChild; + view.dispatch(view.state.tr.split(3)); + expect(view.dom.lastChild).toBe(lastPara); + }); + + it("doesn't greedily match nodes that have another match", async () => { + const { view } = tempEditor({ doc: doc(p("a"), p("b"), p()) }); + const secondPara = view.dom.querySelectorAll("p")[1]; + view.dispatch(view.state.tr.split(2)); + expect(view.dom.querySelectorAll("p")[2]).toBe(secondPara); + }); + + it("creates and destroys plugin views", async () => { + const events: string[] = []; + class PluginView { + update() { + events.push("update"); + } + destroy() { + events.push("destroy"); + } + } + const plugin = new Plugin({ + view() { + events.push("create"); + return new PluginView(); + }, + }); + const { view, unmount } = tempEditor({ plugins: [plugin] }); + view.dispatch(view.state.tr.insertText("u")); + unmount(); + expect(events.join(" ")).toBe("create update destroy"); + }); + + it("redraws changed node views", async () => { + const { view, rerender } = tempEditor({ doc: doc(p("foo"), hr()) }); + expect(view.dom.querySelector("hr")).toBeTruthy(); + rerender({ + nodeViews: { + horizontal_rule: forwardRef( + function HorizontalRule({ nodeProps, ...props }, ref) { + return ; + } + ), + }, + }); + expect(!view.dom.querySelector("hr")).toBeTruthy(); + expect(view.dom.querySelector("var")).toBeTruthy(); + }); + + it("doesn't get confused by merged nodes", async () => { + const { view } = tempEditor({ + doc: doc(p(strong("one"), " two ", strong("three"))), + }); + view.dispatch(view.state.tr.removeMark(1, 4, schema.marks.strong)); + expect(view.dom.querySelectorAll("strong")).toHaveLength(1); + }); + + it("doesn't redraw too much when marks are present", async () => { + const s = new Schema({ + nodes: { + doc: { content: "paragraph+", marks: "m" }, + text: { group: "inline" }, + paragraph: schema.spec.nodes.get("paragraph")!, + }, + marks: { + m: { + toDOM: () => ["div", { class: "m" }, 0], + parseDOM: [{ tag: "div.m" }], + }, + }, + }); + const paragraphs = []; + for (let i = 1; i <= 10; i++) + paragraphs.push( + s.node("paragraph", null, [s.text("para " + i)], [s.mark("m")]) + ); + const { view } = tempEditor({ + // @ts-expect-error this is fine + doc: s.node("doc", null, paragraphs), + }); + const initialChildren = Array.from(view.dom.querySelectorAll("p")); + const newParagraphs = []; + for (let i = -6; i < 0; i++) + newParagraphs.push( + s.node("paragraph", null, [s.text("para " + i)], [s.mark("m")]) + ); + view.dispatch(view.state.tr.replaceWith(0, 8, newParagraphs)); + const currentChildren = Array.from(view.dom.querySelectorAll("p")); + let sameAtEnd = 0; + while ( + sameAtEnd < currentChildren.length && + sameAtEnd < initialChildren.length && + currentChildren[currentChildren.length - sameAtEnd - 1] == + initialChildren[initialChildren.length - sameAtEnd - 1] + ) + sameAtEnd++; + expect(sameAtEnd).toBe(9); + }); +}); diff --git a/src/components/__tests__/ProseMirror.node-view.test.tsx b/src/components/__tests__/ProseMirror.node-view.test.tsx new file mode 100644 index 00000000..954c92ca --- /dev/null +++ b/src/components/__tests__/ProseMirror.node-view.test.tsx @@ -0,0 +1,316 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import { act, screen } from "@testing-library/react"; +import { Plugin } from "prosemirror-state"; +import { blockquote, br, doc, p } from "prosemirror-test-builder"; +import { Decoration, DecorationSet } from "prosemirror-view"; +import React, { LegacyRef, forwardRef, useEffect } from "react"; + +import { useStopEvent } from "../../hooks/useStopEvent.js"; +import { tempEditor } from "../../testing/editorViewTestHelpers.js"; +import { NodeViewComponentProps } from "../NodeViewComponentProps.js"; + +describe("nodeViews prop", () => { + it("can replace a node's representation", async () => { + const { view } = tempEditor({ + doc: doc(p("foo", br())), + nodeViews: { + hard_break: forwardRef(function Var( + props: NodeViewComponentProps, + ref + ) { + return {props.children}; + }), + }, + }); + expect(view.dom.querySelector("var")).not.toBeNull(); + }); + + it("can override drawing of a node's content", async () => { + const { view } = tempEditor({ + doc: doc(p("foo")), + nodeViews: { + paragraph: forwardRef(function Paragraph( + props: NodeViewComponentProps, + ref + ) { + return ( +

    }> + {props.nodeProps.node.textContent.toUpperCase()} +

    + ); + }), + }, + }); + expect(view.dom.querySelector("p")!.textContent).toBe("FOO"); + act(() => { + view.dispatch(view.state.tr.insertText("a")); + }); + expect(view.dom.querySelector("p")!.textContent).toBe("AFOO"); + }); + + // React makes this more or less trivial; the render + // method of the component _is_ the update (and create) + // method + // eslint-disable-next-line jest/no-disabled-tests + it.skip("can register its own update method", async () => { + const { view } = tempEditor({ + doc: doc(p("foo")), + nodeViews: { + paragraph: forwardRef(function Paragraph( + props: NodeViewComponentProps, + ref + ) { + return ( +

    }> + {props.nodeProps.node.textContent.toUpperCase()} +

    + ); + }), + }, + }); + const para = view.dom.querySelector("p")!; + view.dispatch(view.state.tr.insertText("a")); + expect(view.dom.querySelector("p")).toBe(para); + expect(para.textContent).toBe("AFOO"); + }); + + it("allows decoration updates for node views with an update method", async () => { + const { view, rerender } = tempEditor({ + doc: doc(p("foo")), + nodeViews: { + paragraph: forwardRef(function Paragraph( + { children, nodeProps, ...props }: NodeViewComponentProps, + ref + ) { + return ( +

    } {...props}> + {children} +

    + ); + }), + }, + }); + + rerender({ + decorations(state) { + return DecorationSet.create(state.doc, [ + Decoration.inline(2, 3, { someattr: "ok" }), + Decoration.node(0, 5, { otherattr: "ok" }), + ]); + }, + }); + + expect(view.dom.querySelector("[someattr]")).not.toBeNull(); + expect(view.dom.querySelector("[otherattr]")).not.toBeNull(); + }); + + it("can provide a contentDOM property", async () => { + const { view } = tempEditor({ + doc: doc(p("foo")), + nodeViews: { + paragraph: forwardRef(function Paragraph( + props: NodeViewComponentProps, + ref + ) { + return ( + // ContentDOM is inferred from where props.children is rendered +

    }>{props.children}

    + ); + }), + }, + }); + const para = view.dom.querySelector("p")!; + act(() => { + view.dispatch(view.state.tr.insertText("a")); + }); + expect(view.dom.querySelector("p")).toBe(para); + expect(para.textContent).toBe("afoo"); + }); + + it("has its destroy method called", async () => { + let destroyed = false; + const { view } = tempEditor({ + doc: doc(p("foo", br())), + nodeViews: { + hard_break: forwardRef(function BR( + _props: NodeViewComponentProps, + ref + ) { + // React implements "destroy methods" with effect + // hooks + useEffect(() => { + return () => { + destroyed = true; + }; + }, []); + return
    } />; + }), + }, + }); + expect(destroyed).toBeFalsy(); + act(() => { + view.dispatch(view.state.tr.delete(3, 5)); + }); + expect(destroyed).toBeTruthy(); + }); + + it("can query its own position", async () => { + let pos: number | undefined; + const { view } = tempEditor({ + doc: doc(blockquote(p("abc"), p("foo", br()))), + nodeViews: { + hard_break: forwardRef(function BR(props: NodeViewComponentProps, ref) { + pos = props.nodeProps.pos; + return
    } />; + }), + }, + }); + expect(pos).toBe(10); + act(() => { + view.dispatch(view.state.tr.insertText("a")); + }); + expect(pos).toBe(11); + }); + + it("has access to outer decorations", async () => { + const plugin = new Plugin({ + state: { + init() { + return null; + }, + apply(tr, prev) { + return tr.getMeta("setDeco") || prev; + }, + }, + props: { + decorations(this: Plugin, state) { + const deco = this.getState(state); + return ( + deco && + DecorationSet.create(state.doc, [ + Decoration.inline(0, state.doc.content.size, {}, { + name: deco, + } as any), + ]) + ); + }, + }, + }); + const { view } = tempEditor({ + doc: doc(p("foo", br())), + plugins: [plugin], + nodeViews: { + hard_break: forwardRef(function Var( + props: NodeViewComponentProps, + ref + ) { + return ( + + {props.nodeProps.decorations.length + ? props.nodeProps.decorations[0]!.spec.name + : "[]"} + + ); + }), + }, + }); + expect(view.dom.querySelector("var")!.textContent).toBe("[]"); + act(() => { + view.dispatch(view.state.tr.setMeta("setDeco", "foo")); + }); + expect(view.dom.querySelector("var")!.textContent).toBe("foo"); + act(() => { + view.dispatch(view.state.tr.setMeta("setDeco", "bar")); + }); + expect(view.dom.querySelector("var")!.textContent).toBe("bar"); + }); + + it("provides access to inner decorations in the constructor", async () => { + tempEditor({ + doc: doc(p("foo")), + nodeViews: { + paragraph: forwardRef(function Paragraph( + props: NodeViewComponentProps, + ref + ) { + expect( + (props.nodeProps.innerDecorations as DecorationSet) + .find() + .map((d) => `${d.from}-${d.to}`) + .join() + ).toBe("1-2"); + return ( +

    }>{props.children}

    + ); + }), + }, + decorations(state) { + return DecorationSet.create(state.doc, [ + Decoration.inline(2, 3, { someattr: "ok" }), + Decoration.node(0, 5, { otherattr: "ok" }), + ]); + }, + }); + }); + + it("provides access to inner decorations in the update method", async () => { + let innerDecos: string[] = []; + const { rerender } = tempEditor({ + doc: doc(p("foo")), + nodeViews: { + paragraph: forwardRef(function Paragraph( + props: NodeViewComponentProps, + ref + ) { + innerDecos = (props.nodeProps.innerDecorations as DecorationSet) + .find() + .map((d) => `${d.from}-${d.to}`); + return ( +

    }>{props.children}

    + ); + }), + }, + }); + + rerender({ + decorations(state) { + return DecorationSet.create(state.doc, [ + Decoration.inline(2, 3, { someattr: "ok" }), + Decoration.node(0, 5, { otherattr: "ok" }), + ]); + }, + }); + + expect(innerDecos.join()).toBe("1-2"); + }); + + it("can provide a stopEvent hook", async () => { + tempEditor({ + doc: doc(p("input value")), + nodeViews: { + paragraph: forwardRef( + function ParagraphInput({ nodeProps, children, ...props }, ref) { + useStopEvent(() => { + return true; + }); + return ( + + ); + } + ), + }, + }); + + const input = screen.getByDisplayValue("input value"); + input.focus(); + await browser.keys("z"); + + expect(await $(input).getValue()).toBe("input valuez"); + }); +}); diff --git a/src/components/__tests__/ProseMirror.selection.test.tsx b/src/components/__tests__/ProseMirror.selection.test.tsx new file mode 100644 index 00000000..75f087d8 --- /dev/null +++ b/src/components/__tests__/ProseMirror.selection.test.tsx @@ -0,0 +1,500 @@ +/* eslint-disable jest/no-disabled-tests */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import { act, screen } from "@testing-library/react"; +import { Node as PMNode } from "prosemirror-model"; +import { NodeSelection, Selection } from "prosemirror-state"; +import { + blockquote, + br, + code, + code_block, + doc, + em, + hr, + img as img_, + li, + p, + strong, + ul, +} from "prosemirror-test-builder"; +import { Decoration, DecorationSet, EditorView } from "prosemirror-view"; + +import { tempEditor } from "../../testing/editorViewTestHelpers.js"; + +const img = img_({ + src: "data:image/gif;base64,R0lGODlhBQAFAIABAAAAAP///yH5BAEKAAEALAAAAAAFAAUAAAIEjI+pWAA7", +}); + +async function findTextNode(_: HTMLElement, text: string) { + const parent = await screen.findByText(text); + return parent.firstChild!; +} + +function allPositions(doc: PMNode) { + const found: number[] = []; + function scan(node: PMNode, start: number) { + if (node.isTextblock) { + for (let i = 0; i <= node.content.size; i++) found.push(start + i); + } else { + node.forEach((child, offset) => scan(child, start + offset + 1)); + } + } + scan(doc, 0); + return found; +} + +function setDOMSel(node: Node, offset: number) { + const range = document.createRange(); + range.setEnd(node, offset); + range.setStart(node, offset); + const sel = window.getSelection()!; + sel.removeAllRanges(); + sel.addRange(range); +} + +function getSel() { + const sel = window.getSelection()!; + let node = sel.focusNode, + offset = sel.focusOffset; + while (node && node.nodeType != 3) { + const after = offset < node.childNodes.length && node.childNodes[offset]; + const before = offset > 0 && node.childNodes[offset - 1]; + if (after) { + node = after; + offset = 0; + } else if (before) { + node = before; + offset = + node.nodeType == 3 ? node.nodeValue!.length : node.childNodes.length; + } else break; + } + return { node: node, offset: offset }; +} + +function setSel(view: EditorView, sel: number | Selection) { + const selection = + typeof sel == "number" ? Selection.near(view.state.doc.resolve(sel)) : sel; + act(() => { + view.dispatch(view.state.tr.setSelection(selection)); + }); +} + +function event(code: number) { + const event = document.createEvent("Event"); + event.initEvent("keydown", true, true); + (event as any).keyCode = code; + return event; +} +const LEFT = 37, + RIGHT = 39, + UP = 38, + DOWN = 40; + +describe("ProseMirror", () => { + it("can read the DOM selection", async () => { + const { view } = tempEditor({ + doc: doc(p("one"), hr(), blockquote(p("two"))), + }); + function test(node: Node, offset: number, expected: number) { + setDOMSel(node, offset); + view.dom.focus(); + act(() => { + (view as any).domObserver.flush(); + }); + const sel = view.state.selection; + expect(sel.head == null ? sel.from : sel.head).toBe(expected); + } + const one = await findTextNode(view.dom, "one")!; + const two = await findTextNode(view.dom, "two")!; + test(one, 0, 1); + test(one, 1, 2); + test(one, 3, 4); + test(one.parentNode!, 0, 1); + test(one.parentNode!, 1, 4); + test(two, 0, 8); + test(two, 3, 11); + test(two.parentNode!, 1, 11); + test(view.dom, 1, 4); + test(view.dom, 2, 8); + test(view.dom, 3, 11); + }); + + it("syncs the DOM selection with the editor selection", async () => { + const { view } = tempEditor({ + doc: doc(p("one"), hr(), blockquote(p("two"))), + }); + function test(pos: number, node: Node, offset: number) { + setSel(view, pos); + const sel = getSel(); + expect(sel.node).toBe(node); + expect(sel.offset).toBe(offset); + } + const one = await findTextNode(view.dom, "one")!; + const two = await findTextNode(view.dom, "two")!; + view.focus(); + test(1, one, 0); + test(2, one, 1); + test(4, one, 3); + test(8, two, 0); + test(10, two, 2); + }); + + it("returns sensible screen coordinates", async () => { + const { view } = tempEditor({ doc: doc(p("one"), p("two")) }); + + const p00 = view.coordsAtPos(1); + const p01 = view.coordsAtPos(2); + const p03 = view.coordsAtPos(4); + const p10 = view.coordsAtPos(6); + const p13 = view.coordsAtPos(9); + + expect(p00.bottom).toBeGreaterThan(p00.top); + expect(p13.bottom).toBeGreaterThan(p13.top); + + expect(p00.top).toEqual(p01.top); + expect(p01.top).toEqual(p03.top); + expect(p00.bottom).toEqual(p03.bottom); + expect(p10.top).toEqual(p13.top); + + expect(p01.left).toBeGreaterThan(p00.left); + expect(p03.left).toBeGreaterThan(p01.left); + expect(p10.top).toBeGreaterThan(p00.top); + expect(p13.left).toBeGreaterThan(p10.left); + }); + + it("returns proper coordinates in code blocks", async () => { + const { view } = tempEditor({ doc: doc(code_block("a\nb\n")) }), + p = []; + for (let i = 1; i <= 5; i++) p.push(view.coordsAtPos(i)); + const [p0, p1, p2, p3, p4] = p; + expect(p0!.top).toBe(p1!.top); + expect(p0!.left).toBeLessThan(p1!.left); + expect(p2!.top).toBeGreaterThan(p1!.top); + expect(p2!.top).toBe(p3!.top); + expect(p2!.left).toBeLessThan(p3!.left); + expect(p2!.left).toBe(p0!.left); + expect(p4!.top).toBeGreaterThan(p3!.top); + // This one shows a small (0.01 pixel) difference in Firefox for + // some reason. + expect(Math.round(p4!.left)).toBe(Math.round(p2!.left)); + }); + + // TODO: This test fails on the position between the img and the br (it returns + // the position before the img, instead of after). + it.skip("produces sensible screen coordinates in corner cases", async () => { + const { view } = tempEditor({ + doc: doc( + p("one", em("two", strong("three"), img), br(), code("foo")), + p() + ), + }); + return new Promise((ok) => { + setTimeout(() => { + allPositions(view.state.doc).forEach((pos) => { + const coords = view.coordsAtPos(pos); + const found = view.posAtCoords({ + top: coords.top + 1, + left: coords.left, + })!.pos; + expect(found).toBe(pos); + setSel(view, pos); + }); + ok(null); + }, 20); + }); + }); + + it("doesn't return zero-height rectangles after leaves", async () => { + const { view } = tempEditor({ doc: doc(p(img)) }); + const coords = view.coordsAtPos(2, 1); + expect(coords.bottom - coords.top).toBeGreaterThan(5); + }); + + it("produces horizontal rectangles for positions between blocks", async () => { + const { view } = tempEditor({ + doc: doc(p("ha"), hr(), blockquote(p("ba"))), + }); + const a = view.coordsAtPos(0); + expect(a.top).toBe(a.bottom); + expect(a.top).toBe( + (view.dom.firstChild as HTMLElement).getBoundingClientRect().top + ); + expect(a.left).toBeLessThan(a.right); + const b = view.coordsAtPos(4); + expect(b.top).toBe(b.bottom); + expect(b.top).toBeGreaterThan(a.top); + expect(b.left).toBeLessThan(b.right); + const c = view.coordsAtPos(5); + expect(c.top).toBe(c.bottom); + expect(c.top).toBeGreaterThan(b.top); + const d = view.coordsAtPos(6); + expect(d.top).toBe(d.bottom); + expect(d.left).toBeLessThan(d.right); + expect(d.top).toBeLessThan(view.dom.getBoundingClientRect().bottom); + }); + + it("produces sensible screen coordinates around line breaks", async () => { + const { view } = tempEditor({ + doc: doc(p("one two three four five-six-seven-eight")), + }); + function afterSpace(pos: number) { + return pos > 0 && view.state.doc.textBetween(pos - 1, pos) == " "; + } + view.dom.style.width = "4em"; + let prevBefore: + | { left: number; top: number; right: number; bottom: number } + | undefined; + let prevAfter: + | { left: number; top: number; right: number; bottom: number } + | undefined; + allPositions(view.state.doc).forEach((pos) => { + const coords = view.coordsAtPos(pos, 1); + if (prevAfter) + // eslint-disable-next-line jest/no-conditional-expect + expect( + prevAfter.top < coords.top || + (prevAfter.top == coords.top && prevAfter.left < coords.left) + ).toBeTruthy(); + prevAfter = coords; + const found = view.posAtCoords({ + top: coords.top + 1, + left: coords.left, + })!.pos; + expect(found).toBe(pos); + const coordsBefore = view.coordsAtPos(pos, -1); + if (prevBefore) + // eslint-disable-next-line jest/no-conditional-expect + expect( + prevBefore.top < coordsBefore.top || + (prevBefore.top == coordsBefore.top && + (prevBefore.left < coordsBefore.left || + (afterSpace(pos) && prevBefore.left == coordsBefore.left))) + ).toBeTruthy(); + prevBefore = coordsBefore; + }); + }); + + it("can find coordinates on node boundaries", async () => { + const { view } = tempEditor({ + doc: doc(p("one ", em("two"), " ", em(strong("three")))), + }); + let prev: { left: number; top: number; right: number; bottom: number }; + allPositions(view.state.doc).forEach((pos) => { + const coords = view.coordsAtPos(pos, 1); + if (prev) + // eslint-disable-next-line jest/no-conditional-expect + expect( + prev.top < coords.top || + (Math.abs(prev.top - coords.top) < 4 && prev.left < coords.left) + ).toBeTruthy(); + prev = coords; + }); + }); + + it("finds proper coordinates in RTL text", async () => { + const { view } = tempEditor({ doc: doc(p("مرآة نثرية")) }); + view.dom.style.direction = "rtl"; + let prev: { left: number; top: number; right: number; bottom: number }; + allPositions(view.state.doc).forEach((pos) => { + const coords = view.coordsAtPos(pos, 1); + if (prev) + // eslint-disable-next-line jest/no-conditional-expect + expect( + prev.top < coords.top || + (Math.abs(prev.top - coords.top) < 4 && prev.left > coords.left) + ).toBeTruthy(); + prev = coords; + }); + }); + + it("can go back and forth between screen coordsa and document positions", async () => { + const { view } = tempEditor({ + doc: doc(p("one"), blockquote(p("two"), p("three"))), + }); + [1, 2, 4, 7, 14, 15].forEach((pos) => { + const coords = view.coordsAtPos(pos); + const found = view.posAtCoords({ + top: coords.top + 1, + left: coords.left, + })!.pos; + expect(found).toBe(pos); + }); + }); + + it("returns correct screen coordinates for wrapped lines", async () => { + const { view } = tempEditor({}); + const top = view.coordsAtPos(1); + let pos = 1, + end: + | { left: number; top: number; right: number; bottom: number } + | undefined; + for (let i = 0; i < 100; i++) { + view.dispatch(view.state.tr.insertText("a bc de fg h")); + pos += 12; + end = view.coordsAtPos(pos)!; + if (end.bottom > top.bottom + 4) break; + } + expect( + view.posAtCoords({ left: end!.left + 50, top: end!.top + 5 })!.pos + ).toBe(pos); + }); + + it("makes arrow motion go through selectable inline nodes", async () => { + const { view } = tempEditor({ doc: doc(p("foo
    ", img, "bar")) }); + act(() => { + view.dispatchEvent(event(RIGHT)); + }); + expect(view.state.selection.from).toBe(4); + act(() => { + view.dispatchEvent(event(RIGHT)); + }); + expect(view.state.selection.head).toBe(5); + expect(view.state.selection.anchor).toBe(5); + act(() => { + view.dispatchEvent(event(LEFT)); + }); + expect(view.state.selection.from).toBe(4); + act(() => { + view.dispatchEvent(event(LEFT)); + }); + expect(view.state.selection.head).toBe(4); + expect(view.state.selection.anchor).toBe(4); + }); + + it("makes arrow motion go through selectable block nodes", async () => { + const { view } = tempEditor({ + doc: doc(p("hello"), hr(), ul(li(p("there")))), + }); + act(() => { + view.dispatchEvent(event(DOWN)); + }); + expect(view.state.selection.from).toBe(7); + setSel(view, 11); + act(() => { + view.dispatchEvent(event(UP)); + }); + expect(view.state.selection.from).toBe(7); + }); + + it("supports arrow motion through adjacent blocks", async () => { + const { view } = tempEditor({ + doc: doc(blockquote(p("hello")), hr(), hr(), p("there")), + }); + act(() => { + view.dispatchEvent(event(DOWN)); + }); + expect(view.state.selection.from).toBe(9); + act(() => { + view.dispatchEvent(event(DOWN)); + }); + expect(view.state.selection.from).toBe(10); + setSel(view, 14); + act(() => { + view.dispatchEvent(event(UP)); + }); + expect(view.state.selection.from).toBe(10); + act(() => { + view.dispatchEvent(event(UP)); + }); + expect(view.state.selection.from).toBe(9); + }); + + it("support horizontal motion through blocks", async () => { + const { view } = tempEditor({ + doc: doc(p("foo"), hr(), hr(), p("bar")), + }); + act(() => { + view.dispatchEvent(event(RIGHT)); + }); + expect(view.state.selection.from).toBe(5); + act(() => { + view.dispatchEvent(event(RIGHT)); + }); + expect(view.state.selection.from).toBe(6); + act(() => { + view.dispatchEvent(event(RIGHT)); + }); + expect(view.state.selection.head).toBe(8); + act(() => { + view.dispatchEvent(event(LEFT)); + }); + expect(view.state.selection.from).toBe(6); + act(() => { + view.dispatchEvent(event(LEFT)); + }); + expect(view.state.selection.from).toBe(5); + act(() => { + view.dispatchEvent(event(LEFT)); + }); + expect(view.state.selection.head).toBe(4); + }); + + it("allows moving directly from an inline node to a block node", async () => { + const { view } = tempEditor({ + doc: doc(p("foo", img), hr(), p(img, "bar")), + }); + setSel(view, NodeSelection.create(view.state.doc, 4)); + act(() => { + view.dispatchEvent(event(DOWN)); + }); + expect(view.state.selection.from).toBe(6); + setSel(view, NodeSelection.create(view.state.doc, 8)); + act(() => { + view.dispatchEvent(event(UP)); + }); + expect(view.state.selection.from).toBe(6); + }); + + it("updates the selection even if the DOM parameters look unchanged", async () => { + const { view, rerender } = tempEditor({ doc: doc(p("foobar")) }); + view.focus(); + const decos = DecorationSet.create(view.state.doc, [ + Decoration.inline(1, 4, { color: "green" }), + ]); + rerender({ + decorations() { + return decos; + }, + }); + rerender({ decorations: undefined }); + rerender({ + decorations() { + return decos; + }, + }); + const range = document.createRange(); + range.setEnd( + document.getSelection()!.anchorNode!, + document.getSelection()!.anchorOffset + ); + range.setStart(view.dom, 0); + expect(range.toString()).toBe("foobar"); + }); + + it("sets selection even if Selection.extend throws DOMException", async () => { + const originalExtend = window.Selection.prototype.extend; + window.Selection.prototype.extend = () => { + // declare global: DOMException + throw new DOMException("failed"); + }; + try { + const { view } = tempEditor({ + doc: doc(p("foo", img), hr(), p(img, "bar")), + }); + setSel(view, NodeSelection.create(view.state.doc, 4)); + act(() => { + view.dispatchEvent(event(DOWN)); + }); + expect(view.state.selection.from).toBe(6); + } finally { + window.Selection.prototype.extend = originalExtend; + } + }); + + it("doesn't put the cursor after BR hack nodes", async () => { + const { view } = tempEditor({ doc: doc(p()) }); + view.focus(); + expect(getSelection()!.focusOffset).toBe(0); + }); +}); diff --git a/src/components/__tests__/ProseMirror.test.tsx b/src/components/__tests__/ProseMirror.test.tsx index f3c0e8e2..fdfc5ad0 100644 --- a/src/components/__tests__/ProseMirror.test.tsx +++ b/src/components/__tests__/ProseMirror.test.tsx @@ -1,24 +1,30 @@ -import { act, render, screen } from "@testing-library/react"; -import userEvent from "@testing-library/user-event"; +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import { render, screen } from "@testing-library/react"; import { Schema } from "prosemirror-model"; -import { EditorState } from "prosemirror-state"; +import { EditorState, Plugin } from "prosemirror-state"; +import { + doc, + em, + hr, + li, + p, + schema, + strong, + ul, +} from "prosemirror-test-builder"; import { EditorView } from "prosemirror-view"; -import React, { useEffect, useState } from "react"; +import React, { forwardRef, useEffect, useState } from "react"; -import { useNodeViews } from "../../hooks/useNodeViews.js"; -import { NodeViewComponentProps } from "../../nodeViews/createReactNodeViewConstructor.js"; -import { react } from "../../plugins/react.js"; -import { - setupProseMirrorView, - teardownProseMirrorView, -} from "../../testing/setupProseMirrorView.js"; +import { useEditorEffect } from "../../hooks/useEditorEffect.js"; +import { useStopEvent } from "../../hooks/useStopEvent.js"; +import { reactKeys } from "../../plugins/reactKeys.js"; +import { tempEditor } from "../../testing/editorViewTestHelpers.js"; +import { NodeViewComponentProps } from "../NodeViewComponentProps.js"; import { ProseMirror } from "../ProseMirror.js"; +import { ProseMirrorDoc } from "../ProseMirrorDoc.js"; describe("ProseMirror", () => { - beforeAll(() => { - setupProseMirrorView(); - }); - it("renders a contenteditable", async () => { const schema = new Schema({ nodes: { @@ -29,19 +35,29 @@ describe("ProseMirror", () => { const editorState = EditorState.create({ schema }); function TestEditor() { - const [mount, setMount] = useState(null); - return ( - -
    + + ); } - const user = userEvent.setup(); render(); const editor = screen.getByTestId("editor"); - await user.type(editor, "Hello, world!"); + editor.focus(); + await browser.keys("H"); + await browser.keys("e"); + await browser.keys("l"); + await browser.keys("l"); + await browser.keys("o"); + await browser.keys(","); + await browser.keys(" "); + await browser.keys("w"); + await browser.keys("o"); + await browser.keys("r"); + await browser.keys("l"); + await browser.keys("d"); + await browser.keys("!"); expect(editor.textContent).toBe("Hello, world!"); }); @@ -56,7 +72,6 @@ describe("ProseMirror", () => { let outerEditorState = EditorState.create({ schema }); function TestEditor() { const [editorState, setEditorState] = useState(outerEditorState); - const [mount, setMount] = useState(null); useEffect(() => { outerEditorState = editorState; @@ -64,21 +79,30 @@ describe("ProseMirror", () => { return ( - act(() => setEditorState(editorState.apply(tr))) - } + dispatchTransaction={(tr) => setEditorState(editorState.apply(tr))} > -
    + ); } - const user = userEvent.setup(); render(); const editor = screen.getByTestId("editor"); - await user.type(editor, "Hello, world!"); + editor.focus(); + await browser.keys("H"); + await browser.keys("e"); + await browser.keys("l"); + await browser.keys("l"); + await browser.keys("o"); + await browser.keys(","); + await browser.keys(" "); + await browser.keys("w"); + await browser.keys("o"); + await browser.keys("r"); + await browser.keys("l"); + await browser.keys("d"); + await browser.keys("!"); expect(outerEditorState.doc.textContent).toBe("Hello, world!"); }); @@ -87,52 +111,56 @@ describe("ProseMirror", () => { const schema = new Schema({ nodes: { text: {}, - paragraph: { content: "text*" }, + paragraph: { + content: "text*", + toDOM() { + return ["p", 0]; + }, + }, doc: { content: "paragraph+" }, }, }); - const editorState = EditorState.create({ schema, plugins: [react()] }); + const editorState = EditorState.create({ schema }); - function Paragraph({ children }: NodeViewComponentProps) { - return

    {children}

    ; - } + const Paragraph = forwardRef( + function Paragraph({ children }, ref) { + return ( +

    + {children} +

    + ); + } + ); const reactNodeViews = { - paragraph: () => ({ - component: Paragraph, - dom: document.createElement("div"), - contentDOM: document.createElement("span"), - }), + paragraph: Paragraph, }; function TestEditor() { - const { nodeViews, renderNodeViews } = useNodeViews(reactNodeViews); - const [mount, setMount] = useState(null); - return ( - this.updateState(this.state.apply(tr))); - }} - nodeViews={nodeViews} - > -
    - {renderNodeViews()} + + ); } - const user = userEvent.setup(); render(); const editor = screen.getByTestId("editor"); - await user.type(editor, "Hello, world!"); + editor.focus(); + await browser.keys("H"); + await browser.keys("e"); + await browser.keys("l"); + await browser.keys("l"); + await browser.keys("o"); + await browser.keys(","); + await browser.keys(" "); + await browser.keys("w"); + await browser.keys("o"); + await browser.keys("r"); + await browser.keys("l"); + await browser.keys("d"); + await browser.keys("!"); expect(editor.textContent).toBe("Hello, world!"); // Ensure that ProseMirror really rendered our Paragraph @@ -140,7 +168,206 @@ describe("ProseMirror", () => { expect(screen.getAllByTestId("paragraph").length).toBeGreaterThanOrEqual(1); }); - afterAll(() => { - teardownProseMirrorView(); + it("reflects the current state in .props", async () => { + const { view } = tempEditor({ + doc: doc(p()), + }); + + expect(view.state).toBe(view.props.state); + }); + + it("calls handleScrollToSelection when appropriate", async () => { + let scrolled = 0; + + const { view } = tempEditor({ + doc: doc(p()), + handleScrollToSelection: () => { + scrolled++; + return false; + }, + }); + + view.dispatch(view.state.tr.scrollIntoView()); + + expect(scrolled).toBe(1); + }); + + it("can be queried for the DOM position at a doc position", async () => { + const { view } = tempEditor({ doc: doc(ul(li(p(strong("foo"))))) }); + + const inText = view.domAtPos(4); + expect(inText.offset).toBe(1); + expect(inText.node.nodeValue).toBe("foo"); + const beforeLI = view.domAtPos(1); + expect(beforeLI.offset).toBe(0); + expect(beforeLI.node.nodeName).toBe("UL"); + const afterP = view.domAtPos(7); + expect(afterP.offset).toBe(1); + expect(afterP.node.nodeName).toBe("LI"); + }); + + it("can bias DOM position queries to enter nodes", async () => { + const { view } = tempEditor({ + doc: doc(p(em(strong("a"), "b"), "c")), + }); + + function get(pos: number, bias: number) { + const r = view.domAtPos(pos, bias); + return ( + (r.node.nodeType == 1 ? r.node.nodeName : r.node.nodeValue) + + "@" + + r.offset + ); + } + + expect(get(1, 0)).toBe("P@0"); + expect(get(1, -1)).toBe("P@0"); + expect(get(1, 1)).toBe("a@0"); + expect(get(2, -1)).toBe("a@1"); + expect(get(2, 0)).toBe("EM@1"); + expect(get(2, 1)).toBe("b@0"); + expect(get(3, -1)).toBe("b@1"); + expect(get(3, 0)).toBe("P@1"); + expect(get(3, 1)).toBe("c@0"); + expect(get(4, -1)).toBe("c@1"); + expect(get(4, 0)).toBe("P@2"); + expect(get(4, 1)).toBe("P@2"); + }); + + it("can be queried for a node's DOM representation", async () => { + const { view } = tempEditor({ + doc: doc(p("foo"), hr()), + }); + + expect(view.nodeDOM(0)!.nodeName).toBe("P"); + expect(view.nodeDOM(5)!.nodeName).toBe("HR"); + expect(view.nodeDOM(3)).toBeNull(); + }); + + it("can map DOM positions to doc positions", async () => { + const { view } = tempEditor({ + doc: doc(p("foo"), hr()), + }); + + expect(view.posAtDOM(view.dom.firstChild!.firstChild!, 2)).toBe(3); + expect(view.posAtDOM(view.dom, 1)).toBe(5); + expect(view.posAtDOM(view.dom, 2)).toBe(6); + expect(view.posAtDOM(view.dom.lastChild!, 0, -1)).toBe(5); + expect(view.posAtDOM(view.dom.lastChild!, 0, 1)).toBe(6); + }); + + it("binds this to itself in dispatchTransaction prop", async () => { + let thisBinding: any; + + const { view } = tempEditor({ + doc: doc(p("foo"), hr()), + dispatchTransaction() { + // eslint-disable-next-line @typescript-eslint/no-this-alias + thisBinding = this; + }, + }); + + view.dispatch(view.state.tr.insertText("x")); + expect(view).toBe(thisBinding); + }); + + it("replaces the EditorView when ProseMirror would redraw", async () => { + const viewPlugin = () => + new Plugin({ + props: { + nodeViews: { + horizontal_rule() { + const dom = document.createElement("hr"); + return { + dom, + }; + }, + }, + }, + }); + + const startDoc = doc(p()); + const firstState = EditorState.create({ + doc: startDoc, + schema, + plugins: [viewPlugin(), reactKeys()], + }); + + let firstView: EditorView | null = null; + let secondView: EditorView | null = null; + + function Test() { + useEditorEffect((v) => { + if (firstView === null) { + firstView = v; + } else { + secondView = v; + } + }); + + return null; + } + + const Paragraph = forwardRef( + function Paragraph({ nodeProps, children, ...props }, ref) { + return ( +

    + {children} +

    + ); + } + ); + + const { rerender } = render( + + + + + ); + + expect(() => screen.getByTestId("node-view")).not.toThrow(); + + const secondState = EditorState.create({ + doc: startDoc, + schema, + plugins: [viewPlugin(), reactKeys()], + }); + + rerender( + + + + + ); + + expect(() => screen.getByTestId("node-view")).not.toThrow(); + + expect(firstView).not.toBeNull(); + expect(secondView).not.toBeNull(); + expect(firstView === secondView).toBeFalsy(); + }); + + it("supports focusing interactive controls", async () => { + tempEditor({ + doc: doc(hr()), + nodeViews: { + horizontal_rule: forwardRef( + function Button({ nodeProps, ...props }, ref) { + useStopEvent(() => { + return true; + }); + return ( + + ); + } + ), + }, + }); + + const button = screen.getByText("Click me"); + await $("#button").click(); + expect(document.activeElement === button).toBeTruthy(); }); }); diff --git a/src/contexts/ChildDescriptorsContext.ts b/src/contexts/ChildDescriptorsContext.ts new file mode 100644 index 00000000..b6f71b15 --- /dev/null +++ b/src/contexts/ChildDescriptorsContext.ts @@ -0,0 +1,5 @@ +import { createContext } from "react"; + +import { ViewDesc } from "../viewdesc.js"; + +export const ChildDescriptorsContext = createContext([]); diff --git a/src/contexts/EditorContext.ts b/src/contexts/EditorContext.ts index 2941872f..1534b07e 100644 --- a/src/contexts/EditorContext.ts +++ b/src/contexts/EditorContext.ts @@ -4,9 +4,9 @@ import { createContext } from "react"; import type { EventHandler } from "../plugins/componentEventListeners"; -interface EditorContextValue { - editorView: EditorView | null; - editorState: EditorState | null; +export interface EditorContextValue { + view: EditorView | null; + state: EditorState; registerEventListener( eventType: EventType, handler: EventHandler @@ -26,5 +26,3 @@ interface EditorContextValue { export const EditorContext = createContext( null as unknown as EditorContextValue ); - -export const EditorProvider = EditorContext.Provider; diff --git a/src/contexts/LayoutGroup.tsx b/src/contexts/LayoutGroup.tsx deleted file mode 100644 index 2244df27..00000000 --- a/src/contexts/LayoutGroup.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import React, { - createContext, - useCallback, - useContext, - useLayoutEffect, - useRef, -} from "react"; -import type { DependencyList, EffectCallback } from "react"; - -import { useForceUpdate } from "../hooks/useForceUpdate.js"; - -/** - * Like `useLayoutEffect`, but all effect executions are run - * *after* the `DeferredLayoutEffectsProvider` layout effects - * phase. - * - * This hook allows child components to enqueue layout effects - * that won't be safe to run until after a parent component's - * layout effects have run. - * - */ -const useLayoutGroupEffectsRegistry = () => { - const createQueue = useRef(new Set<() => void>()).current; - const destroyQueue = useRef(new Set<() => void>()).current; - - const forceUpdate = useForceUpdate(); - const isUpdatePending = useRef(true); - - const ensureFlush = useCallback(() => { - if (!isUpdatePending.current) { - forceUpdate(); - isUpdatePending.current = true; - } - }, [forceUpdate]); - - const register = useCallback( - (effect: EffectCallback) => { - let destroy: ReturnType; - const create = () => { - destroy = effect(); - }; - - createQueue.add(create); - ensureFlush(); - - return () => { - createQueue.delete(create); - if (destroy) { - destroyQueue.add(destroy); - ensureFlush(); - } - }; - }, - [createQueue, destroyQueue, ensureFlush] - ); - - useLayoutEffect(() => { - isUpdatePending.current = false; - createQueue.forEach((create) => create()); - createQueue.clear(); - return () => { - destroyQueue.forEach((destroy) => destroy()); - destroyQueue.clear(); - }; - }); - - return register; -}; - -type Destructor = () => void; -type Register = (e: EffectCallback) => Destructor; - -const LayoutGroupContext = createContext(null as unknown as Register); - -interface DeferredLayoutEffectsContextProviderProps { - children: React.ReactNode; -} - -/** - * Provides a deferral point for deferred layout effects. - * All effects registered with `useDeferredLayoutEffect` - * by children of this provider will execute *after* all - * effects registered by `useLayoutEffect` by children of - * this provider. - */ -export function LayoutGroup({ - children, -}: DeferredLayoutEffectsContextProviderProps) { - const register = useLayoutGroupEffectsRegistry(); - return ( - - {children} - - ); -} - -/** - * Like `useLayoutEffect`, but all effect executions are run - * *after* the `DeferredLayoutEffectsProvider` layout effects - * phase. - * - * This hook allows child components to enqueue layout effects - * that won't be safe to run until after a parent component's - * layout effects have run. - */ -export function useLayoutGroupEffect( - effect: EffectCallback, - deps?: DependencyList -) { - const register = useContext(LayoutGroupContext); - // The rule for hooks wants to statically verify the deps, - // but the dependencies are up to the caller, not this implementation. - // eslint-disable-next-line react-hooks/exhaustive-deps - useLayoutEffect(() => register(effect), deps); -} diff --git a/src/contexts/LayoutGroupContext.tsx b/src/contexts/LayoutGroupContext.tsx new file mode 100644 index 00000000..e3f93fb1 --- /dev/null +++ b/src/contexts/LayoutGroupContext.tsx @@ -0,0 +1,10 @@ +import { createContext } from "react"; +import type { EffectCallback } from "react"; + +export interface LayoutGroupContextValue { + (effect: EffectCallback): ReturnType; +} + +export const LayoutGroupContext = createContext( + null as unknown as LayoutGroupContextValue +); diff --git a/src/contexts/NodeViewContext.tsx b/src/contexts/NodeViewContext.tsx new file mode 100644 index 00000000..44a72f09 --- /dev/null +++ b/src/contexts/NodeViewContext.tsx @@ -0,0 +1,16 @@ +import { ForwardRefExoticComponent, RefAttributes, createContext } from "react"; + +import { NodeViewComponentProps } from "../components/NodeViewComponentProps.js"; + +export type NodeViewContextValue = { + nodeViews: Record< + string, + ForwardRefExoticComponent< + NodeViewComponentProps & RefAttributes + > + >; +}; + +export const NodeViewContext = createContext( + null as unknown as NodeViewContextValue +); diff --git a/src/contexts/PortalRegistryContext.ts b/src/contexts/PortalRegistryContext.ts deleted file mode 100644 index 93c4abca..00000000 --- a/src/contexts/PortalRegistryContext.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ReactPortal, createContext } from "react"; - -import { NodeKey } from "../plugins/react.js"; - -export type RegisteredPortal = { - getPos: () => number; - portal: ReactPortal; -}; - -export type PortalRegistry = Record; - -/** - * A map of node view keys to portals. - * - * Each node view registers a portal under its parent's - * key. Each can then retrieve the list of portals under their - * key, allowing portals to be rendered with the appropriate - * hierarchy. - */ -export const PortalRegistryContext = createContext( - null as unknown as PortalRegistry -); diff --git a/src/contexts/StopEventContext.ts b/src/contexts/StopEventContext.ts new file mode 100644 index 00000000..f3d668a9 --- /dev/null +++ b/src/contexts/StopEventContext.ts @@ -0,0 +1,9 @@ +import { createContext } from "react"; + +type StopEventContextValue = ( + stopEvent: (event: Event) => boolean | undefined +) => void; + +export const StopEventContext = createContext( + null as unknown as StopEventContextValue +); diff --git a/src/contexts/__tests__/DeferredLayoutEffects.test.tsx b/src/contexts/__tests__/DeferredLayoutEffects.test.tsx index afc8dd2e..32f05aaa 100644 --- a/src/contexts/__tests__/DeferredLayoutEffects.test.tsx +++ b/src/contexts/__tests__/DeferredLayoutEffects.test.tsx @@ -1,7 +1,8 @@ import { act, render, screen } from "@testing-library/react"; import React, { useLayoutEffect, useState } from "react"; -import { LayoutGroup, useLayoutGroupEffect } from "../LayoutGroup.js"; +import { LayoutGroup } from "../../components/LayoutGroup.js"; +import { useLayoutGroupEffect } from "../../hooks/useLayoutGroupEffect.js"; describe("DeferredLayoutEffects", () => { jest.useFakeTimers("modern"); diff --git a/src/decorations/ReactWidgetType.ts b/src/decorations/ReactWidgetType.ts new file mode 100644 index 00000000..5fbf2ab8 --- /dev/null +++ b/src/decorations/ReactWidgetType.ts @@ -0,0 +1,108 @@ +import { Mark } from "prosemirror-model"; +import { Mappable } from "prosemirror-transform"; +import { Decoration } from "prosemirror-view"; +import { ForwardRefExoticComponent, RefAttributes } from "react"; + +import { WidgetViewComponentProps } from "../components/WidgetViewComponentProps.js"; +import { DOMNode } from "../dom.js"; + +function compareObjs( + a: { [prop: string]: unknown }, + b: { [prop: string]: unknown } +) { + if (a == b) return true; + for (const p in a) if (a[p] !== b[p]) return false; + for (const p in b) if (!(p in a)) return false; + return true; +} + +export interface DecorationType { + spec: unknown; + map( + mapping: Mappable, + span: Decoration, + offset: number, + oldOffset: number + ): Decoration | null; + valid(node: Node, span: Decoration): boolean; + eq(other: DecorationType): boolean; + destroy(dom: DOMNode): void; +} + +export type DecorationWithType = Decoration & { + type: DecorationType; +}; + +type ReactWidgetSpec = { + side?: number; + marks?: readonly Mark[]; + stopEvent?: (event: Event) => boolean; + ignoreSelection?: boolean; + key?: string; +}; + +const noSpec = { side: 0 }; + +export class ReactWidgetType implements DecorationType { + side: number; + spec: ReactWidgetSpec; + + constructor( + public Component: ForwardRefExoticComponent< + RefAttributes & WidgetViewComponentProps + >, + spec?: ReactWidgetSpec + ) { + this.spec = spec ?? noSpec; + this.side = this.spec.side ?? 0; + } + + map( + mapping: Mappable, + span: Decoration, + offset: number, + oldOffset: number + ): Decoration | null { + const { pos, deleted } = mapping.mapResult( + span.from + oldOffset, + this.side < 0 ? -1 : 1 + ); + // @ts-expect-error The Decoration constructor is private/internal, but + // we need to use it for our custom widget implementation here. + return deleted ? null : new Decoration(pos - offset, pos - offset, this); + } + + valid(): boolean { + return true; + } + + eq(other: DecorationType): boolean { + return ( + this == other || + (other instanceof ReactWidgetType && + ((this.spec.key && this.spec.key == other.spec.key) || + (this.Component == other.Component && + compareObjs(this.spec, other.spec)))) + ); + } + destroy(): void { + // Can be implemented with React effect hooks + } +} + +export function widget( + pos: number, + component: ForwardRefExoticComponent< + RefAttributes & WidgetViewComponentProps + >, + spec?: ReactWidgetSpec +) { + // @ts-expect-error The Decoration constructor is private/internal, but + // we need to use it for our custom widget implementation here. + return new Decoration(pos, pos, new ReactWidgetType(component, spec)); +} + +export interface ReactWidgetDecoration extends Decoration { + type: ReactWidgetType; + inline: false; +} diff --git a/src/decorations/computeDocDeco.ts b/src/decorations/computeDocDeco.ts new file mode 100644 index 00000000..82eb5ef0 --- /dev/null +++ b/src/decorations/computeDocDeco.ts @@ -0,0 +1,26 @@ +import { Decoration, EditorView } from "prosemirror-view"; + +export function computeDocDeco(view: EditorView) { + const attrs = Object.create(null); + attrs.class = "ProseMirror"; + attrs.contenteditable = String(view.editable); + + view.someProp("attributes", (value) => { + if (typeof value == "function") value = value(view.state); + if (value) + for (const attr in value) { + if (attr == "class") attrs.class += " " + value[attr]; + else if (attr == "style") + attrs.style = (attrs.style ? attrs.style + ";" : "") + value[attr]; + else if ( + !attrs[attr] && + attr != "contenteditable" && + attr != "nodeName" + ) + attrs[attr] = String(value[attr]); + } + }); + if (!attrs.translate) attrs.translate = "no"; + + return [Decoration.node(0, view.state.doc.content.size, attrs)]; +} diff --git a/src/decorations/internalTypes.ts b/src/decorations/internalTypes.ts new file mode 100644 index 00000000..8614028c --- /dev/null +++ b/src/decorations/internalTypes.ts @@ -0,0 +1,25 @@ +import { Node } from "prosemirror-model"; +import { Mapping } from "prosemirror-transform"; +import { Decoration, DecorationSet, DecorationSource } from "prosemirror-view"; + +export interface InternalDecorationSource { + /// Map the set of decorations in response to a change in the + /// document. + map: (mapping: Mapping, node: Node) => DecorationSource; + /// @internal + locals(node: Node): readonly Decoration[]; + /// @internal + forChild(offset: number, child: Node): DecorationSource; + /// @internal + eq(other: DecorationSource): boolean; + + forEachSet(f: (set: DecorationSet) => void): void; +} + +export interface InternalDecorationSet extends InternalDecorationSource { + localsInner(node: Node): readonly Decoration[]; +} + +export interface InternalDecoration extends Decoration { + copy(from: number, to: number): Decoration; +} diff --git a/src/decorations/iterDeco.ts b/src/decorations/iterDeco.ts new file mode 100644 index 00000000..3037a5eb --- /dev/null +++ b/src/decorations/iterDeco.ts @@ -0,0 +1,138 @@ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import { Node } from "prosemirror-model"; +import { Decoration, DecorationSource } from "prosemirror-view"; + +import { ReactWidgetType } from "./ReactWidgetType.js"; +import { InternalDecorationSource } from "./internalTypes.js"; + +function compareSide(a: Decoration, b: Decoration) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return (a as any).type.side - (b as any).type.side; +} + +// This function abstracts iterating over the nodes and decorations in +// a fragment. Calls `onNode` for each node, with its local and child +// decorations. Splits text nodes when there is a decoration starting +// or ending inside of them. Calls `onWidget` for each widget. +export function iterDeco( + parent: Node, + deco: DecorationSource, + // Callbacks have been slightly modified to pass + // the offset, so that we can pass the position as + // a prop to components + onWidget: ( + widget: Decoration, + isNative: boolean, + offset: number, + index: number, + insideNode: boolean + ) => void, + onNode: ( + node: Node, + outerDeco: readonly Decoration[], + innerDeco: DecorationSource, + offset: number, + index: number + ) => void +) { + const locals = (deco as InternalDecorationSource).locals(parent); + let offset = 0; + // Simple, cheap variant for when there are no local decorations + if (locals.length == 0) { + for (let i = 0; i < parent.childCount; i++) { + const child = parent.child(i); + onNode( + child, + locals, + (deco as InternalDecorationSource).forChild(offset, child), + offset, + i + ); + offset += child.nodeSize; + } + return; + } + + let decoIndex = 0; + const active = []; + let restNode = null; + for (let parentIndex = 0; ; ) { + if (decoIndex < locals.length && locals[decoIndex]!.to == offset) { + const widget = locals[decoIndex++]!; + let widgets; + while (decoIndex < locals.length && locals[decoIndex]!.to == offset) + (widgets || (widgets = [widget])).push(locals[decoIndex++]!); + if (widgets) { + widgets.sort(compareSide); + for (let i = 0; i < widgets.length; i++) + onWidget( + widgets[i]!, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + !((widgets[i]! as any).type instanceof ReactWidgetType), + offset, + parentIndex + i, + !!restNode + ); + } else { + onWidget( + widget, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + !((widget as any).type instanceof ReactWidgetType), + offset, + parentIndex, + !!restNode + ); + } + } + + let child, index; + if (restNode) { + index = -1; + child = restNode; + restNode = null; + } else if (parentIndex < parent.childCount) { + index = parentIndex; + child = parent.child(parentIndex++); + } else { + break; + } + + for (let i = 0; i < active.length; i++) + if (active[i]!.to <= offset) active.splice(i--, 1); + while ( + decoIndex < locals.length && + locals[decoIndex]!.from <= offset && + locals[decoIndex]!.to > offset + ) + active.push(locals[decoIndex++]!); + + let end = offset + child.nodeSize; + if (child.isText) { + let cutAt = end; + if (decoIndex < locals.length && locals[decoIndex]!.from < cutAt) + cutAt = locals[decoIndex]!.from; + for (let i = 0; i < active.length; i++) + if (active[i]!.to < cutAt) cutAt = active[i]!.to; + if (cutAt < end) { + restNode = child.cut(cutAt - offset); + child = child.cut(0, cutAt - offset); + end = cutAt; + index = -1; + } + } + + const outerDeco = + child.isInline && !child.isLeaf + ? // eslint-disable-next-line @typescript-eslint/no-explicit-any + active.filter((d) => !(d as any).inline) + : active.slice(); + onNode( + child, + outerDeco, + (deco as InternalDecorationSource).forChild(offset, child), + offset, + index + ); + offset = end; + } +} diff --git a/src/decorations/viewDecorations.tsx b/src/decorations/viewDecorations.tsx new file mode 100644 index 00000000..4e2f3159 --- /dev/null +++ b/src/decorations/viewDecorations.tsx @@ -0,0 +1,200 @@ +import { Node } from "prosemirror-model"; +import { Mapping } from "prosemirror-transform"; +import { + Decoration, + DecorationSet, + DecorationSource, + EditorView, +} from "prosemirror-view"; + +import { + InternalDecoration, + InternalDecorationSet, + InternalDecorationSource, +} from "./internalTypes.js"; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const none: readonly any[] = [], + noSpec = {}; + +const empty = DecorationSet.empty; + +// An abstraction that allows the code dealing with decorations to +// treat multiple DecorationSet objects as if it were a single object +// with (a subset of) the same interface. +class DecorationGroup implements DecorationSource { + constructor(readonly members: readonly DecorationSet[]) {} + + map(mapping: Mapping, doc: Node) { + const mappedDecos = this.members.map((member) => + member.map(mapping, doc, noSpec) + ); + return DecorationGroup.from(mappedDecos); + } + + forChild(offset: number, child: Node) { + if (child.isLeaf) return DecorationSet.empty; + let found: DecorationSet[] = []; + for (let i = 0; i < this.members.length; i++) { + const result = ( + this.members[i] as unknown as InternalDecorationSource + ).forChild(offset, child); + if (result == empty) continue; + if (result instanceof DecorationGroup) + found = found.concat(result.members); + else found.push(result as unknown as DecorationSet); + } + return DecorationGroup.from(found); + } + + eq(other: DecorationGroup) { + if ( + !(other instanceof DecorationGroup) || + other.members.length != this.members.length + ) + return false; + for (let i = 0; i < this.members.length; i++) + if ( + !(this.members[i] as unknown as InternalDecorationSource).eq( + other.members[i] as DecorationSource + ) + ) + return false; + return true; + } + + locals(node: Node) { + let result: Decoration[] | undefined, + sorted = true; + for (let i = 0; i < this.members.length; i++) { + const locals = ( + this.members[i] as unknown as InternalDecorationSet + ).localsInner(node); + if (!locals.length) continue; + if (!result) { + result = locals as Decoration[]; + } else { + if (sorted) { + result = result.slice(); + sorted = false; + } + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + for (let j = 0; j < locals.length; j++) result.push(locals[j]!); + } + } + return result ? removeOverlap(sorted ? result : result.sort(byPos)) : none; + } + + // Create a group for the given array of decoration sets, or return + // a single set when possible. + static from(members: readonly DecorationSource[]): DecorationSource { + switch (members.length) { + case 0: + return empty; + case 1: + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return members[0]!; + default: + return new DecorationGroup( + members.every((m) => m instanceof DecorationSet) + ? (members as DecorationSet[]) + : members.reduce( + (r, m) => + r.concat( + m instanceof DecorationSet + ? m + : (m as DecorationGroup).members + ), + [] as DecorationSet[] + ) + ); + } + } + + forEachSet(f: (set: DecorationSet) => void) { + for (let i = 0; i < this.members.length; i++) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + this.members[i]!.forEachSet(f); + } +} + +// Used to sort decorations so that ones with a low start position +// come first, and within a set with the same start position, those +// with an smaller end position come first. +function byPos(a: Decoration, b: Decoration) { + return a.from - b.from || a.to - b.to; +} + +// Scan a sorted array of decorations for partially overlapping spans, +// and split those so that only fully overlapping spans are left (to +// make subsequent rendering easier). Will return the input array if +// no partially overlapping spans are found (the common case). +function removeOverlap(spans: readonly Decoration[]): Decoration[] { + let working: Decoration[] = spans as Decoration[]; + for (let i = 0; i < working.length - 1; i++) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const span = working[i]!; + if (span.from != span.to) + for (let j = i + 1; j < working.length; j++) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const next = working[j]!; + if (next.from == span.from) { + if (next.to != span.to) { + if (working == spans) working = spans.slice(); + // Followed by a partially overlapping larger span. Split that + // span. + working[j] = (next as InternalDecoration).copy(next.from, span.to); + insertAhead( + working, + j + 1, + (next as InternalDecoration).copy(span.to, next.to) + ); + } + continue; + } else { + if (next.from < span.to) { + if (working == spans) working = spans.slice(); + // The end of this one overlaps with a subsequent span. Split + // this one. + working[i] = (span as InternalDecoration).copy( + span.from, + next.from + ); + insertAhead( + working, + j, + (span as InternalDecoration).copy(next.from, span.to) + ); + } + break; + } + } + } + return working; +} + +function insertAhead(array: Decoration[], i: number, deco: Decoration) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + while (i < array.length && byPos(deco, array[i]!) > 0) i++; + array.splice(i, 0, deco); +} + +export function viewDecorations( + view: EditorView, + cursorWrapper: Decoration | null +): DecorationSource { + const found: DecorationSource[] = []; + view.someProp("decorations", (f) => { + const result = f(view.state); + if (result && result != empty) found.push(result); + }); + // We don't have access to types for view.cursorWrapper here + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if (cursorWrapper) { + found.push( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + DecorationSet.create(view.state.doc, [cursorWrapper]) + ); + } + return DecorationGroup.from(found); +} diff --git a/src/dom.ts b/src/dom.ts new file mode 100644 index 00000000..48935441 --- /dev/null +++ b/src/dom.ts @@ -0,0 +1,175 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +export type DOMNode = InstanceType; +export type DOMSelection = InstanceType; +export type DOMSelectionRange = { + focusNode: DOMNode | null; + focusOffset: number; + anchorNode: DOMNode | null; + anchorOffset: number; +}; + +export const domIndex = function (node: Node) { + for (let index = 0; ; index++) { + node = node.previousSibling!; + if (!node) return index; + } +}; + +export const parentNode = function (node: Node): Node | null { + const parent = (node as HTMLSlotElement).assignedSlot || node.parentNode; + return parent && parent.nodeType == 11 ? (parent as ShadowRoot).host : parent; +}; + +let reusedRange: Range | null = null; + +// Note that this will always return the same range, because DOM range +// objects are every expensive, and keep slowing down subsequent DOM +// updates, for some reason. +export const textRange = function (node: Text, from?: number, to?: number) { + const range = reusedRange || (reusedRange = document.createRange()); + range.setEnd(node, to == null ? node.nodeValue!.length : to); + range.setStart(node, from || 0); + return range; +}; + +// Scans forward and backward through DOM positions equivalent to the +// given one to see if the two are in the same place (i.e. after a +// text node vs at the end of that text node) +export const isEquivalentPosition = function ( + node: Node, + off: number, + targetNode: Node, + targetOff: number +) { + return ( + targetNode && + (scanFor(node, off, targetNode, targetOff, -1) || + scanFor(node, off, targetNode, targetOff, 1)) + ); +}; + +const atomElements = /^(img|br|input|textarea|hr)$/i; + +function scanFor( + node: Node, + off: number, + targetNode: Node, + targetOff: number, + dir: number +) { + for (;;) { + if (node == targetNode && off == targetOff) return true; + if (off == (dir < 0 ? 0 : nodeSize(node))) { + const parent = node.parentNode; + if ( + !parent || + parent.nodeType != 1 || + hasBlockDesc(node) || + atomElements.test(node.nodeName) || + (node as HTMLElement).contentEditable == "false" + ) + return false; + off = domIndex(node) + (dir < 0 ? 0 : 1); + node = parent; + } else if (node.nodeType == 1) { + node = node.childNodes[off + (dir < 0 ? -1 : 0)]!; + if ((node as HTMLElement).contentEditable == "false") return false; + off = dir < 0 ? nodeSize(node) : 0; + } else { + return false; + } + } +} + +export function nodeSize(node: Node) { + return node.nodeType == 3 ? node.nodeValue!.length : node.childNodes.length; +} + +export function isOnEdge(node: Node, offset: number, parent: Node) { + for ( + let atStart = offset == 0, atEnd = offset == nodeSize(node); + atStart || atEnd; + + ) { + if (node == parent) return true; + const index = domIndex(node); + node = node.parentNode!; + if (!node) return false; + atStart = atStart && index == 0; + atEnd = atEnd && index == nodeSize(node); + } + return false; +} + +export function hasBlockDesc(dom: Node) { + let desc; + for (let cur: Node | null = dom; cur; cur = cur.parentNode) + if ((desc = cur.pmViewDesc)) break; + return ( + desc && + desc.node && + desc.node.isBlock && + (desc.dom == dom || desc.contentDOM == dom) + ); +} + +// Work around Chrome issue https://bugs.chromium.org/p/chromium/issues/detail?id=447523 +// (isCollapsed inappropriately returns true in shadow dom) +export const selectionCollapsed = function (domSel: DOMSelectionRange) { + return ( + domSel.focusNode && + isEquivalentPosition( + domSel.focusNode, + domSel.focusOffset, + domSel.anchorNode!, + domSel.anchorOffset + ) + ); +}; + +export function keyEvent(keyCode: number, key: string) { + const event = document.createEvent("Event") as KeyboardEvent; + event.initEvent("keydown", true, true); + (event as any).keyCode = keyCode; + (event as any).key = (event as any).code = key; + return event; +} + +export function deepActiveElement(doc: Document) { + let elt = doc.activeElement; + while (elt && elt.shadowRoot) elt = elt.shadowRoot.activeElement; + return elt; +} + +export function caretFromPoint( + doc: Document, + x: number, + y: number +): { node: Node; offset: number } | undefined { + if ((doc as any).caretPositionFromPoint) { + try { + // Firefox throws for this call in hard-to-predict circumstances (#994) + const pos = (doc as any).caretPositionFromPoint(x, y); + // Clip the offset, because Chrome will return a text offset + // into nodes, which can't be treated as a regular DOM + // offset + if (pos) + return { + node: pos.offsetNode, + offset: Math.min(nodeSize(pos.offsetNode), pos.offset), + }; + } catch (_) { + // pass + } + } + if (doc.caretRangeFromPoint) { + const range = doc.caretRangeFromPoint(x, y); + if (range) + return { + node: range.startContainer, + offset: Math.min(nodeSize(range.startContainer), range.startOffset), + }; + } + return; +} diff --git a/src/hooks/__tests__/useEditorViewLayoutEffect.test.tsx b/src/hooks/__tests__/useEditorViewLayoutEffect.test.tsx index 03b8611e..de8991be 100644 --- a/src/hooks/__tests__/useEditorViewLayoutEffect.test.tsx +++ b/src/hooks/__tests__/useEditorViewLayoutEffect.test.tsx @@ -4,8 +4,8 @@ import type { EditorState } from "prosemirror-state"; import type { EditorView } from "prosemirror-view"; import React from "react"; +import { LayoutGroup } from "../../components/LayoutGroup.js"; import { EditorContext } from "../../contexts/EditorContext.js"; -import { LayoutGroup } from "../../contexts/LayoutGroup.js"; import { useEditorEffect } from "../useEditorEffect.js"; function TestComponent({ @@ -31,8 +31,8 @@ describe("useEditorViewLayoutEffect", () => { { { { { { - it("should render node views", () => { - function List({ children }: NodeViewComponentProps) { - return ( - <> - list -
      {children}
    - - ); - } - - function ListItem({ children }: NodeViewComponentProps) { - return ( - <> - list item -
  • {children}
  • - - ); - } - - const reactNodeViews = { - list: () => ({ - component: List, - dom: document.createElement("div"), - contentDOM: document.createElement("div"), - }), - list_item: () => ({ - component: ListItem, - dom: document.createElement("div"), - contentDOM: document.createElement("div"), - }), - }; - - function TestEditor() { - const { nodeViews, renderNodeViews } = useNodeViews(reactNodeViews); - const [mount, setMount] = useState(null); - - return ( - -
    - {renderNodeViews()} - - ); - } - - render(); - - expect(screen.getByText("list")).toBeTruthy(); - expect(screen.getByText("list item")).toBeTruthy(); - }); - - it("should render child node views as children of their parents", () => { - const TestContext = createContext("default"); - - function List({ children }: NodeViewComponentProps) { - return ( - -
      {children}
    -
    - ); - } - - function ListItem({ children }: NodeViewComponentProps) { - const testContextValue = useContext(TestContext); - - return ( - <> - {testContextValue} -
  • {children}
  • - - ); - } - - const reactNodeViews = { - list: () => ({ - component: List, - dom: document.createElement("div"), - contentDOM: document.createElement("div"), - }), - list_item: () => ({ - component: ListItem, - dom: document.createElement("div"), - contentDOM: document.createElement("div"), - }), - }; - - function TestEditor() { - const { nodeViews, renderNodeViews } = useNodeViews(reactNodeViews); - const [mount, setMount] = useState(null); - - return ( - -
    - {renderNodeViews()} - - ); - } - - render(); - - expect(screen.getByText("overriden")).toBeTruthy(); - }); -}); diff --git a/src/hooks/useComponentEventListeners.tsx b/src/hooks/useComponentEventListeners.tsx index b63e723e..ca167528 100644 --- a/src/hooks/useComponentEventListeners.tsx +++ b/src/hooks/useComponentEventListeners.tsx @@ -15,7 +15,7 @@ import { * along with any other plugins. * * - `registerEventListener` and `unregisterEventListener` should be - * passed to `EditorProvider`. + * passed to `EditorContext.Provider`. * * @privateRemarks * diff --git a/src/hooks/useEditor.ts b/src/hooks/useEditor.ts new file mode 100644 index 00000000..097f90b2 --- /dev/null +++ b/src/hooks/useEditor.ts @@ -0,0 +1,370 @@ +import { Schema } from "prosemirror-model"; +import { EditorState, Plugin, Transaction } from "prosemirror-state"; +import { + Decoration, + DecorationSet, + DirectEditorProps, + EditorProps, + EditorView, + MarkViewConstructor, + NodeViewConstructor, +} from "prosemirror-view"; +import { useCallback, useLayoutEffect, useMemo, useRef, useState } from "react"; +import { flushSync } from "react-dom"; + +import { DOMNode } from "../dom.js"; +import { beforeInputPlugin } from "../plugins/beforeInputPlugin.js"; +import { SelectionDOMObserver } from "../selection/SelectionDOMObserver.js"; +import { NodeViewDesc } from "../viewdesc.js"; + +import { useComponentEventListeners } from "./useComponentEventListeners.js"; +import { useForceUpdate } from "./useForceUpdate.js"; + +type NodeViewSet = { + [name: string]: NodeViewConstructor | MarkViewConstructor; +}; + +function buildNodeViews(view: ReactEditorView) { + const result: NodeViewSet = Object.create(null); + function add(obj: NodeViewSet) { + for (const prop in obj) + if (!Object.prototype.hasOwnProperty.call(result, prop)) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + result[prop] = obj[prop]!; + } + view.someProp("nodeViews", add); + view.someProp("markViews", add); + return result; +} + +function changedNodeViews(a: NodeViewSet, b: NodeViewSet) { + let nA = 0, + nB = 0; + for (const prop in a) { + if (a[prop] != b[prop]) return true; + nA++; + } + for (const _ in b) nB++; + return nA != nB; +} + +function changedProps(a: DirectEditorProps, b: DirectEditorProps) { + for (const prop of Object.keys(a) as (keyof DirectEditorProps)[]) { + if (a[prop] !== b[prop]) return true; + } + return false; +} + +function getEditable(view: ReactEditorView) { + return !view.someProp("editable", (value) => value(view.state) === false); +} + +// @ts-expect-error We're making use of knowledge of internal methods here +export class ReactEditorView extends EditorView { + private shouldUpdatePluginViews = false; + + private oldProps: DirectEditorProps; + + private _props: DirectEditorProps; + + constructor( + place: + | null + | DOMNode + | ((editor: HTMLElement) => void) + | { mount: HTMLElement }, + props: DirectEditorProps & { docView: NodeViewDesc } + ) { + // Call the superclass constructor with an empty + // document and limited props. We'll set everything + // else ourselves. + super(place, { + state: EditorState.create({ + schema: props.state.schema, + plugins: props.state.plugins, + }), + plugins: props.plugins, + }); + + this.shouldUpdatePluginViews = true; + + this._props = props; + this.oldProps = { state: props.state }; + this.state = props.state; + + // @ts-expect-error We're making use of knowledge of internal attributes here + this.domObserver.stop(); + // @ts-expect-error We're making use of knowledge of internal attributes here + this.domObserver = new SelectionDOMObserver(this); + // @ts-expect-error We're making use of knowledge of internal attributes here + this.domObserver.start(); + + this.editable = getEditable(this); + + // Destroy the DOM created by the default + // ProseMirror ViewDesc implementation; we + // have a NodeViewDesc from React instead. + // @ts-expect-error We're making use of knowledge of internal attributes here + this.docView.dom.replaceChildren(); + // @ts-expect-error We're making use of knowledge of internal attributes here + this.docView = props.docView; + } + + /** + * Whether the EditorView's updateStateInner method thinks that the + * docView needs to be blown away and redrawn. + * + * @privateremarks + * + * When ProseMirror View detects that the EditorState has been reconfigured + * to provide new custom node views, it calls an internal function that + * we can't override in order to recreate the entire editor DOM. + * + * This property mimics that check, so that we can replace the EditorView + * with another of our own, preventing ProseMirror View from taking over + * DOM management responsibility. + */ + get needsRedraw() { + if ( + this.oldProps.state.plugins === this._props.state.plugins && + this._props.plugins === this.oldProps.plugins + ) { + return false; + } + + const newNodeViews = buildNodeViews(this); + // @ts-expect-error Internal property + return changedNodeViews(this.nodeViews, newNodeViews); + } + + /** + * Like setProps, but without executing any side effects. + * Safe to use in a component render method. + */ + pureSetProps(props: Partial) { + // this.oldProps = this.props; + this._props = { + ...this._props, + ...props, + }; + this.state = this._props.state; + + this.editable = getEditable(this); + } + + /** + * Triggers any side effects that have been queued by previous + * calls to pureSetProps. + */ + runPendingEffects() { + if (changedProps(this.props, this.oldProps)) { + const newProps = this.props; + this._props = this.oldProps; + this.state = this._props.state; + this.update(newProps); + } + } + + update(props: DirectEditorProps) { + super.update(props); + // Ensure that side effects aren't re-triggered until + // pureSetProps is called again + this.oldProps = props; + } + + updatePluginViews(prevState?: EditorState) { + if (this.shouldUpdatePluginViews) { + // @ts-expect-error We're making use of knowledge of internal methods here + super.updatePluginViews(prevState); + } + } + + // We want to trigger the default EditorView cleanup, but without + // the actual view.dom cleanup (which React will have already handled). + // So we give the EditorView a dummy DOM element and ask it to clean up + destroy() { + // @ts-expect-error we're intentionally overwriting this property + // to prevent side effects + this.dom = document.createElement("div"); + super.destroy(); + } +} + +export interface UseEditorOptions extends EditorProps { + defaultState?: EditorState; + state?: EditorState; + plugins?: Plugin[]; + dispatchTransaction?(this: EditorView, tr: Transaction): void; +} + +const EMPTY_SCHEMA = new Schema({ + nodes: { + doc: { content: "text*" }, + text: { inline: true }, + }, +}); + +const EMPTY_STATE = EditorState.create({ + schema: EMPTY_SCHEMA, +}); + +let didWarnValueDefaultValue = false; + +/** + * Creates, mounts, and manages a ProseMirror `EditorView`. + * + * All state and props updates are executed in a layout effect. + * To ensure that the EditorState and EditorView are never out of + * sync, it's important that the EditorView produced by this hook + * is only accessed through the `useEditorViewEvent` and + * `useEditorViewLayoutEffect` hooks. + */ +export function useEditor( + mount: T | null, + options: UseEditorOptions +) { + if (process.env.NODE_ENV !== "production") { + if ( + options.defaultState !== undefined && + options.state !== undefined && + !didWarnValueDefaultValue + ) { + console.error( + "A component contains a ProseMirror editor with both value and defaultValue props. " + + "ProseMirror editors must be either controlled or uncontrolled " + + "(specify either the state prop, or the defaultState prop, but not both). " + + "Decide between using a controlled or uncontrolled ProseMirror editor " + + "and remove one of these props. More info: " + + "https://reactjs.org/link/controlled-components" + ); + didWarnValueDefaultValue = true; + } + } + const [view, setView] = useState(null); + const [cursorWrapper, _setCursorWrapper] = useState(null); + const forceUpdate = useForceUpdate(); + + const defaultState = options.defaultState ?? EMPTY_STATE; + const [_state, setState] = useState(defaultState); + const state = options.state ?? _state; + + const { + componentEventListenersPlugin, + registerEventListener, + unregisterEventListener, + } = useComponentEventListeners(); + + const setCursorWrapper = useCallback((deco: Decoration | null) => { + flushSync(() => { + _setCursorWrapper(deco); + }); + }, []); + + const plugins = useMemo( + () => [ + ...(options.plugins ?? []), + componentEventListenersPlugin, + beforeInputPlugin(setCursorWrapper), + ], + [options.plugins, componentEventListenersPlugin, setCursorWrapper] + ); + + const dispatchTransaction = useCallback( + function dispatchTransaction(this: EditorView, tr: Transaction) { + flushSync(() => { + if (!options.state) { + setState((s) => s.apply(tr)); + } + + if (options.dispatchTransaction) { + options.dispatchTransaction.call(this, tr); + } + }); + }, + [options.dispatchTransaction, options.state] + ); + + const tempDom = document.createElement("div"); + + const docViewDescRef = useRef( + new NodeViewDesc( + undefined, + [], + state.doc, + [], + DecorationSet.empty, + tempDom, + null, + tempDom, + () => false + ) + ); + + const directEditorProps = { + ...options, + state, + plugins, + dispatchTransaction, + docView: docViewDescRef.current, + }; + + useLayoutEffect(() => { + return () => { + view?.destroy(); + }; + }, [view]); + + // This rule is concerned about infinite updates due to the + // call to setView. These calls are deliberately conditional, + // so this is not a concern. + // eslint-disable-next-line react-hooks/exhaustive-deps + useLayoutEffect(() => { + if (view && view.dom !== mount) { + setView(null); + } + + if (!mount) { + return; + } + + if (!view) { + const newView = new ReactEditorView({ mount }, directEditorProps); + setView(newView); + newView.dom.addEventListener("compositionend", forceUpdate); + return; + } + }); + + // This rule is concerned about infinite updates due to the + // call to setView. These calls are deliberately conditional, + // so this is not a concern. + // eslint-disable-next-line react-hooks/exhaustive-deps + useLayoutEffect(() => { + // If ProseMirror View is about to redraw the entire document's + // DOM, clear the EditorView and reconstruct another, instead. + // This only happens when a newly instantiated EditorState has + // been provided. + if (view?.needsRedraw) { + setView(null); + return; + } else { + // @ts-expect-error Internal property - domObserver + view?.domObserver.selectionToDOM(); + view?.runPendingEffects(); + } + }); + + view?.pureSetProps(directEditorProps); + + return useMemo( + () => ({ + view: view as EditorView | null, + state: state, + registerEventListener, + unregisterEventListener, + cursorWrapper, + docViewDescRef, + }), + [view, state, registerEventListener, unregisterEventListener, cursorWrapper] + ); +} diff --git a/src/hooks/useEditorEffect.ts b/src/hooks/useEditorEffect.ts index 2ea2932a..5d97d971 100644 --- a/src/hooks/useEditorEffect.ts +++ b/src/hooks/useEditorEffect.ts @@ -3,7 +3,8 @@ import { useContext } from "react"; import type { DependencyList } from "react"; import { EditorContext } from "../contexts/EditorContext.js"; -import { useLayoutGroupEffect } from "../contexts/LayoutGroup.js"; + +import { useLayoutGroupEffect } from "./useLayoutGroupEffect.js"; /** * Registers a layout effect to run after the EditorView has @@ -20,10 +21,10 @@ import { useLayoutGroupEffect } from "../contexts/LayoutGroup.js"; * EditorView lives in an ancestor component. */ export function useEditorEffect( - effect: (editorView: EditorView | null) => void | (() => void), + effect: (editorView: EditorView) => void | (() => void), dependencies?: DependencyList ) { - const { editorView } = useContext(EditorContext); + const { view } = useContext(EditorContext); // The rules of hooks want `effect` to be included in the // dependency list, but dependency issues for `effect` will @@ -33,11 +34,15 @@ export function useEditorEffect( // every time it changes, because it will most likely // be defined inline and run on every re-render. useLayoutGroupEffect( - () => effect(editorView), + () => { + if (view) { + return effect(view); + } + }, // The rules of hooks want to be able to statically // verify the dependencies for the effect, but this will // have already happened at the call-site. // eslint-disable-next-line react-hooks/exhaustive-deps - dependencies && [editorView, ...dependencies] + dependencies && [view, ...dependencies] ); } diff --git a/src/hooks/useEditorEventCallback.ts b/src/hooks/useEditorEventCallback.ts index 96982ce6..53f681f1 100644 --- a/src/hooks/useEditorEventCallback.ts +++ b/src/hooks/useEditorEventCallback.ts @@ -19,17 +19,22 @@ import { useEditorEffect } from "./useEditorEffect.js"; * providers. */ export function useEditorEventCallback( - callback: (view: EditorView | null, ...args: T) => R + callback: (view: EditorView, ...args: T) => R ) { const ref = useRef(callback); - const { editorView } = useContext(EditorContext); + const { view } = useContext(EditorContext); useEditorEffect(() => { ref.current = callback; }, [callback]); return useCallback( - (...args: T) => ref.current(editorView, ...args), - [editorView] + (...args: T) => { + if (view) { + return ref.current(view, ...args); + } + return; + }, + [view] ); } diff --git a/src/hooks/useEditorState.ts b/src/hooks/useEditorState.ts index 469bc727..0202491f 100644 --- a/src/hooks/useEditorState.ts +++ b/src/hooks/useEditorState.ts @@ -6,8 +6,8 @@ import { EditorContext } from "../contexts/EditorContext.js"; /** * Provides access to the current EditorState value. */ -export function useEditorState(): EditorState | null { - const { editorState } = useContext(EditorContext); +export function useEditorState(): EditorState { + const { state: editorState } = useContext(EditorContext); return editorState; } diff --git a/src/hooks/useEditorView.ts b/src/hooks/useEditorView.ts deleted file mode 100644 index adba099e..00000000 --- a/src/hooks/useEditorView.ts +++ /dev/null @@ -1,128 +0,0 @@ -import type { EditorState, Transaction } from "prosemirror-state"; -import { EditorView } from "prosemirror-view"; -import type { DirectEditorProps } from "prosemirror-view"; -import { useLayoutEffect, useState } from "react"; -import { flushSync } from "react-dom"; - -import { useForceUpdate } from "./useForceUpdate.js"; - -function withFlushedUpdates( - fn: (this: This, ...args: T) => void -): (...args: T) => void { - return function (this: This, ...args: T) { - flushSync(() => { - fn.call(this, ...args); - }); - }; -} - -function defaultDispatchTransaction(this: EditorView, tr: Transaction) { - this.updateState(this.state.apply(tr)); -} - -type EditorStateProps = - | { - state: EditorState; - } - | { - defaultState: EditorState; - }; - -export type EditorProps = Omit & EditorStateProps; - -function withFlushedDispatch( - props: EditorProps, - forceUpdate: () => void -): EditorProps & { - dispatchTransaction: EditorView["dispatch"]; -} { - return { - ...props, - ...{ - dispatchTransaction: function dispatchTransaction( - this: EditorView, - tr: Transaction - ) { - const flushedDispatch = withFlushedUpdates( - props.dispatchTransaction ?? defaultDispatchTransaction - ); - flushedDispatch.call(this, tr); - if (!("state" in props)) forceUpdate(); - }, - }, - }; -} - -/** - * Creates, mounts, and manages a ProseMirror `EditorView`. - * - * All state and props updates are executed in a layout effect. - * To ensure that the EditorState and EditorView are never out of - * sync, it's important that the EditorView produced by this hook - * is only accessed through the `useEditorViewEvent` and - * `useEditorViewLayoutEffect` hooks. - */ -export function useEditorView( - mount: T | null, - props: EditorProps -): EditorView | null { - const [view, setView] = useState(null); - const forceUpdate = useForceUpdate(); - - const editorProps = withFlushedDispatch(props, forceUpdate); - - const stateProp = "state" in editorProps ? editorProps.state : undefined; - - const state = - "defaultState" in editorProps - ? editorProps.defaultState - : editorProps.state; - - const nonStateProps = Object.fromEntries( - Object.entries(editorProps).filter( - ([propName]) => propName !== "state" && propName !== "defaultState" - ) - ); - - useLayoutEffect(() => { - return () => { - if (view) { - view.destroy(); - } - }; - }, [view]); - - useLayoutEffect(() => { - if (view && view.dom !== mount) { - setView(null); - return; - } - - if (!mount) { - return; - } - - if (!view) { - setView( - new EditorView( - { mount }, - { - ...editorProps, - state, - } - ) - ); - return; - } - }, [editorProps, mount, state, view]); - - useLayoutEffect(() => { - view?.setProps(nonStateProps); - }, [view, nonStateProps]); - - useLayoutEffect(() => { - if (stateProp) view?.setProps({ state: stateProp }); - }, [view, stateProp]); - - return view; -} diff --git a/src/hooks/useLayoutGroupEffect.ts b/src/hooks/useLayoutGroupEffect.ts new file mode 100644 index 00000000..eca6d756 --- /dev/null +++ b/src/hooks/useLayoutGroupEffect.ts @@ -0,0 +1,16 @@ +import { useContext, useLayoutEffect } from "react"; +import type { DependencyList, EffectCallback } from "react"; + +import { LayoutGroupContext } from "../contexts/LayoutGroupContext.js"; + +/** Registers a layout effect to run at the nearest `LayoutGroup` boundary. */ +export function useLayoutGroupEffect( + effect: EffectCallback, + deps?: DependencyList +) { + const register = useContext(LayoutGroupContext); + // The rule for hooks wants to statically verify the deps, + // but the dependencies are up to the caller, not this implementation. + // eslint-disable-next-line react-hooks/exhaustive-deps + useLayoutEffect(() => register(effect), deps); +} diff --git a/src/hooks/useNodePos.tsx b/src/hooks/useNodePos.tsx deleted file mode 100644 index 0783e72a..00000000 --- a/src/hooks/useNodePos.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React, { ReactNode, createContext, useContext } from "react"; - -import { NodeKey, reactPluginKey } from "../plugins/react.js"; - -import { useEditorState } from "./useEditorState.js"; - -type Props = { - nodeKey: NodeKey; - children: ReactNode; -}; - -const NodePosContext = createContext(null as unknown as number); - -export function NodePosProvider({ nodeKey, children }: Props) { - const editorState = useEditorState(); - if (!editorState) return <>{children}; - const pluginState = reactPluginKey.getState(editorState); - if (!pluginState) return <>{children}; - return ( - - {children} - - ); -} - -export function useNodePos() { - return useContext(NodePosContext); -} diff --git a/src/hooks/useNodeViewDescriptor.ts b/src/hooks/useNodeViewDescriptor.ts new file mode 100644 index 00000000..c497927f --- /dev/null +++ b/src/hooks/useNodeViewDescriptor.ts @@ -0,0 +1,125 @@ +import { Node } from "prosemirror-model"; +import { Decoration, DecorationSource } from "prosemirror-view"; +import { + MutableRefObject, + useCallback, + useContext, + useLayoutEffect, + useRef, + useState, +} from "react"; + +import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"; +import { EditorContext } from "../contexts/EditorContext.js"; +import { CompositionViewDesc, NodeViewDesc, ViewDesc } from "../viewdesc.js"; + +export function useNodeViewDescriptor( + node: Node | undefined, + domRef: undefined | MutableRefObject, + nodeDomRef: MutableRefObject, + innerDecorations: DecorationSource, + outerDecorations: readonly Decoration[], + viewDesc?: NodeViewDesc, + contentDOMRef?: MutableRefObject +) { + const { view } = useContext(EditorContext); + const [hasContentDOM, setHasContentDOM] = useState(true); + const nodeViewDescRef = useRef(viewDesc); + const stopEvent = useRef<(event: Event) => boolean | undefined>(() => false); + const setStopEvent = useCallback( + (newStopEvent: (event: Event) => boolean | undefined) => { + stopEvent.current = newStopEvent; + }, + [] + ); + const siblingDescriptors = useContext(ChildDescriptorsContext); + const childDescriptors: ViewDesc[] = []; + + useLayoutEffect(() => { + if (!node || !nodeDomRef.current) return; + + const firstChildDesc = childDescriptors[0]; + + if (!nodeViewDescRef.current) { + nodeViewDescRef.current = new NodeViewDesc( + undefined, + childDescriptors, + node, + outerDecorations, + innerDecorations, + domRef?.current ?? nodeDomRef.current, + firstChildDesc?.dom.parentElement ?? null, + nodeDomRef.current, + (event) => !!stopEvent.current(event) + ); + } else { + nodeViewDescRef.current.parent = undefined; + nodeViewDescRef.current.children = childDescriptors; + nodeViewDescRef.current.node = node; + nodeViewDescRef.current.outerDeco = outerDecorations; + nodeViewDescRef.current.innerDeco = innerDecorations; + nodeViewDescRef.current.dom = domRef?.current ?? nodeDomRef.current; + // @ts-expect-error We have our own ViewDesc implementations + nodeViewDescRef.current.dom.pmViewDesc = nodeViewDescRef.current; + nodeViewDescRef.current.contentDOM = + // If there's already a contentDOM, we can just + // keep it; it won't have changed. This is especially + // important during compositions, where the + // firstChildDesc might not have a correct dom node set yet. + contentDOMRef?.current ?? + nodeViewDescRef.current.contentDOM ?? + firstChildDesc?.dom.parentElement ?? + null; + nodeViewDescRef.current.nodeDOM = nodeDomRef.current; + } + setHasContentDOM(nodeViewDescRef.current.contentDOM !== null); + siblingDescriptors.push(nodeViewDescRef.current); + + for (const childDesc of childDescriptors) { + childDesc.parent = nodeViewDescRef.current; + + // Because TextNodeViews can't locate the DOM nodes + // for compositions, we need to override them here + if (childDesc instanceof CompositionViewDesc) { + const compositionTopDOM = + nodeViewDescRef.current.contentDOM?.firstChild; + if (!compositionTopDOM) + throw new Error( + `Started a composition but couldn't find the text node it belongs to.` + ); + + let textDOM = compositionTopDOM; + while (textDOM.firstChild) { + textDOM = textDOM.firstChild as Element | Text; + } + + if (!textDOM || !(textDOM instanceof Text)) + throw new Error( + `Started a composition but couldn't find the text node it belongs to.` + ); + + childDesc.dom = compositionTopDOM; + childDesc.textDOM = textDOM; + childDesc.text = textDOM.data; + // @ts-expect-error ??? + childDesc.textDOM.pmViewDesc = childDesc; + + // @ts-expect-error ??? + view?.input.compositionNodes.push(childDesc); + } + } + + return () => { + if ( + nodeViewDescRef.current?.children[0] instanceof CompositionViewDesc && + !view?.composing + ) { + nodeViewDescRef.current?.children[0].dom.parentNode?.removeChild( + nodeViewDescRef.current?.children[0].dom + ); + } + }; + }); + + return { hasContentDOM, childDescriptors, setStopEvent }; +} diff --git a/src/hooks/useNodeViews.tsx b/src/hooks/useNodeViews.tsx deleted file mode 100644 index 7a42a0ae..00000000 --- a/src/hooks/useNodeViews.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import { EditorView } from "prosemirror-view"; -import React, { ReactPortal, useCallback, useMemo, useState } from "react"; - -import { - PortalRegistry, - PortalRegistryContext, -} from "../contexts/PortalRegistryContext.js"; -import { - ReactNodeViewConstructor, - RegisterPortal, - createReactNodeViewConstructor, - findNodeKeyUp, -} from "../nodeViews/createReactNodeViewConstructor.js"; -import { ROOT_NODE_KEY } from "../plugins/react.js"; - -import { useEditorEffect } from "./useEditorEffect.js"; - -type Props = { - portals: PortalRegistry; -}; - -function NodeViews({ portals }: Props) { - const rootRegisteredPortals = portals[ROOT_NODE_KEY]; - const [rootPortals, setRootPortals] = useState( - rootRegisteredPortals?.map(({ portal }) => portal) - ); - - // `getPos` is technically derived from the EditorView - // state, so it's not safe to call until after the EditorView - // has been updated - useEditorEffect(() => { - setRootPortals( - rootRegisteredPortals - ?.sort((a, b) => a.getPos() - b.getPos()) - .map(({ portal }) => portal) - ); - }, [rootRegisteredPortals]); - - return ( - - {rootPortals} - - ); -} - -export function useNodeViews( - nodeViews: Record -) { - const [portals, setPortals] = useState({} as PortalRegistry); - - const registerPortal: RegisterPortal = useCallback( - (view: EditorView, getPos: () => number, portal: ReactPortal) => { - const nearestAncestorKey = findNodeKeyUp(view, getPos()); - - setPortals((oldPortals) => { - const oldChildPortals = oldPortals[nearestAncestorKey] ?? []; - const newChildPortals = oldChildPortals.concat({ getPos, portal }); - return { - ...oldPortals, - [nearestAncestorKey]: newChildPortals, - }; - }); - - return () => { - setPortals((oldPortals) => { - const oldChildPortals = oldPortals[nearestAncestorKey] ?? []; - const newChildPortals = oldChildPortals.filter( - ({ portal: p }) => p !== portal - ); - return { - ...oldPortals, - [nearestAncestorKey]: newChildPortals, - }; - }); - }; - }, - [] - ); - - const reactNodeViews = useMemo(() => { - const nodeViewEntries = Object.entries(nodeViews); - const reactNodeViewEntries = nodeViewEntries.map(([name, constructor]) => [ - name, - createReactNodeViewConstructor(constructor, registerPortal), - ]); - return Object.fromEntries(reactNodeViewEntries); - }, [nodeViews, registerPortal]); - - return { - nodeViews: reactNodeViews, - renderNodeViews: () => , - }; -} diff --git a/src/hooks/useReactKeys.ts b/src/hooks/useReactKeys.ts new file mode 100644 index 00000000..cb5b7fdd --- /dev/null +++ b/src/hooks/useReactKeys.ts @@ -0,0 +1,8 @@ +import { reactKeysPluginKey } from "../plugins/reactKeys.js"; + +import { useEditorState } from "./useEditorState.js"; + +export function useReactKeys() { + const state = useEditorState(); + return reactKeysPluginKey.getState(state); +} diff --git a/src/hooks/useStopEvent.ts b/src/hooks/useStopEvent.ts new file mode 100644 index 00000000..dd8852cc --- /dev/null +++ b/src/hooks/useStopEvent.ts @@ -0,0 +1,17 @@ +import { EditorView } from "prosemirror-view"; +import { useContext } from "react"; + +import { StopEventContext } from "../contexts/StopEventContext.js"; + +import { useEditorEffect } from "./useEditorEffect.js"; +import { useEditorEventCallback } from "./useEditorEventCallback.js"; + +export function useStopEvent( + stopEvent: (view: EditorView, event: Event) => boolean +) { + const register = useContext(StopEventContext); + const stopEventMemo = useEditorEventCallback(stopEvent); + useEditorEffect(() => { + register(stopEventMemo); + }, [register, stopEventMemo]); +} diff --git a/src/index.ts b/src/index.ts index a9cb4981..8b4f9bda 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,19 +1,14 @@ "use client"; export { ProseMirror } from "./components/ProseMirror.js"; -export { EditorProvider } from "./contexts/EditorContext.js"; -export { LayoutGroup, useLayoutGroupEffect } from "./contexts/LayoutGroup.js"; +export { ProseMirrorDoc } from "./components/ProseMirrorDoc.js"; export { useEditorEffect } from "./hooks/useEditorEffect.js"; export { useEditorEventCallback } from "./hooks/useEditorEventCallback.js"; export { useEditorEventListener } from "./hooks/useEditorEventListener.js"; export { useEditorState } from "./hooks/useEditorState.js"; -export { useEditorView } from "./hooks/useEditorView.js"; -export { useNodeViews } from "./hooks/useNodeViews.js"; -export { useNodePos } from "./hooks/useNodePos.js"; -export { react } from "./plugins/react.js"; +export { useStopEvent } from "./hooks/useStopEvent.js"; +export { reactKeys } from "./plugins/reactKeys.js"; +export { widget } from "./decorations/ReactWidgetType.js"; -export type { - NodeViewComponentProps, - ReactNodeView, - ReactNodeViewConstructor, -} from "./nodeViews/createReactNodeViewConstructor.js"; +export type { NodeViewComponentProps } from "./components/NodeViewComponentProps.js"; +export type { WidgetViewComponentProps } from "./components/WidgetViewComponentProps.js"; diff --git a/src/nodeViews/createReactNodeViewConstructor.tsx b/src/nodeViews/createReactNodeViewConstructor.tsx deleted file mode 100644 index ddfed5a5..00000000 --- a/src/nodeViews/createReactNodeViewConstructor.tsx +++ /dev/null @@ -1,358 +0,0 @@ -import type { Node } from "prosemirror-model"; -import type { - Decoration, - DecorationSource, - EditorView, - NodeView, - NodeViewConstructor, -} from "prosemirror-view"; -import React, { - Dispatch, - ReactPortal, - SetStateAction, - forwardRef, - useContext, - useImperativeHandle, - useState, -} from "react"; -import type { ComponentType, ReactNode } from "react"; -import { createPortal } from "react-dom"; - -import { PortalRegistryContext } from "../contexts/PortalRegistryContext.js"; -import { useEditorEffect } from "../hooks/useEditorEffect.js"; -import { NodePosProvider } from "../hooks/useNodePos.js"; -import { - NodeKey, - ROOT_NODE_KEY, - createNodeKey, - reactPluginKey, -} from "../plugins/react.js"; - -import { phrasingContentTags } from "./phrasingContentTags.js"; - -export interface NodeViewComponentProps { - decorations: readonly Decoration[]; - node: Node; - children: ReactNode; - isSelected: boolean; -} - -interface NodeViewWrapperState { - node: Node; - decorations: readonly Decoration[]; - isSelected: boolean; -} - -interface NodeViewWrapperProps { - initialState: NodeViewWrapperState; -} - -interface NodeViewWrapperRef { - node: Node; - contentDOMWrapper: HTMLElement | null; - contentDOMParent: HTMLElement | null; - setNode: Dispatch>; - setDecorations: Dispatch>; - setIsSelected: Dispatch>; -} - -export type UnregisterElement = () => void; - -export type RegisterPortal = ( - view: EditorView, - getPos: () => number, - portal: ReactPortal -) => UnregisterElement; - -type _ReactNodeView = NodeView & { - component: ComponentType; -}; - -// We use a mapped type to improve LSP information for this type. -// The language server will actually spell out the properties and -// corresponding types of the mapped type, rather than repeating -// the ugly Omit<...> & { component: ... } type above. -export type ReactNodeView = { - [Property in keyof _ReactNodeView]: _ReactNodeView[Property]; -}; - -export type ReactNodeViewConstructor = ( - ...args: Parameters -) => ReactNodeView; - -/** - * Identifies a node view constructor as having been created - * by @nytimes/react-prosemirror - */ -export const REACT_NODE_VIEW = Symbol("react node view"); - -/** - * Searches upward for the nearest node with a node key, - * returning the first node key it finds associated with - * a React node view. - * - * Returns the root key if no ancestor nodes have node keys. - */ -export function findNodeKeyUp(editorView: EditorView, pos: number): NodeKey { - const pluginState = reactPluginKey.getState(editorView.state); - if (!pluginState) return ROOT_NODE_KEY; - - const $pos = editorView.state.doc.resolve(pos); - - for (let d = $pos.depth; d > 0; d--) { - const ancestorNodeTypeName = $pos.node(d).type.name; - const ancestorNodeView = editorView.props.nodeViews?.[ - ancestorNodeTypeName - ] as (NodeViewConstructor & { [REACT_NODE_VIEW]?: true }) | undefined; - - if (!ancestorNodeView?.[REACT_NODE_VIEW]) continue; - - const ancestorPos = $pos.before(d); - const ancestorKey = pluginState.posToKey.get(ancestorPos); - - if (ancestorKey) return ancestorKey; - } - - return ROOT_NODE_KEY; -} - -/** - * Factory function for creating nodeViewConstructors that - * render as React components. - * - * `ReactComponent` can be any React component that takes - * `NodeViewComponentProps`. It will be passed all of the - * arguments to the `nodeViewConstructor` except for - * `editorView`. NodeView components that need access - * directly to the EditorView should use the - * `useEditorViewEvent` and `useEditorViewLayoutEffect` - * hooks to ensure safe access. - * - * For contentful Nodes, the NodeView component will also - * be passed a `children` prop containing an empty element. - * ProseMirror will render content nodes into this element. - */ -export function createReactNodeViewConstructor( - reactNodeViewConstructor: ReactNodeViewConstructor, - registerPortal: RegisterPortal -) { - function nodeViewConstructor( - node: Node, - editorView: EditorView, - getPos: () => number, - decorations: readonly Decoration[], - innerDecorations: DecorationSource - ): NodeView { - const reactNodeView = reactNodeViewConstructor( - node, - editorView, - getPos, - decorations, - innerDecorations - ); - - let componentRef: NodeViewWrapperRef | null = null; - - const { dom, contentDOM, component: ReactComponent } = reactNodeView; - - // Use a span if the provided contentDOM is in the "phrasing" content - // category. Otherwise use a div. This is our best attempt at not - // breaking the intended content model, for now. - // - // https://developer.mozilla.org/en-US/docs/Web/HTML/Content_categories#phrasing_content - const ContentDOMWrapper = - contentDOM && - (phrasingContentTags.includes(contentDOM.tagName.toLocaleLowerCase()) - ? "span" - : "div"); - - const reactPluginState = reactPluginKey.getState(editorView.state); - if (!reactPluginState) - throw new Error( - "Can't find the react() ProseMirror plugin, required for useNodeViews(). Was it added to the EditorState.plugins?" - ); - const nodeKey = reactPluginState.posToKey.get(getPos()) ?? createNodeKey(); - - /** - * Wrapper component to provide some imperative handles for updating - * and re-rendering its child. Takes and renders an arbitrary ElementType - * that expects NodeViewComponentProps as props. - */ - const NodeViewWrapper = forwardRef< - NodeViewWrapperRef, - NodeViewWrapperProps - >(function NodeViewWrapper({ initialState }: NodeViewWrapperProps, ref) { - const [node, setNode] = useState(initialState.node); - const [decorations, setDecorations] = useState( - initialState.decorations - ); - const [isSelected, setIsSelected] = useState( - initialState.isSelected - ); - - const portalRegistry = useContext(PortalRegistryContext); - const childRegisteredPortals = portalRegistry[nodeKey]; - const [childPortals, setChildPortals] = useState( - childRegisteredPortals?.map(({ portal }) => portal) - ); - - // `getPos` is technically derived from the EditorView - // state, so it's not safe to call until after the EditorView - // has been updated - useEditorEffect(() => { - setChildPortals( - childRegisteredPortals - ?.sort((a, b) => a.getPos() - b.getPos()) - .map(({ portal }) => portal) - ); - }, [childRegisteredPortals]); - - const [contentDOMWrapper, setContentDOMWrapper] = - useState(null); - - const [contentDOMParent, setContentDOMParent] = - useState(null); - - useImperativeHandle( - ref, - () => ({ - node, - contentDOMWrapper: contentDOMWrapper, - contentDOMParent: contentDOMParent, - setNode, - setDecorations, - setIsSelected, - }), - [node, contentDOMWrapper, contentDOMParent] - ); - return ( - - - {childPortals} - {ContentDOMWrapper && ( - { - setContentDOMWrapper(nextContentDOMWrapper); - // we preserve a reference to the contentDOMWrapper' - // parent so that later we can reassemble the DOM hierarchy - // React expects when cleaning up the ContentDOMWrapper element - if (nextContentDOMWrapper?.parentNode) { - setContentDOMParent( - nextContentDOMWrapper.parentNode as HTMLElement - ); - } - }} - /> - )} - - - ); - }); - - NodeViewWrapper.displayName = `NodeView(${ - ReactComponent.displayName ?? ReactComponent.name - })`; - - const element = ( - { - componentRef = c; - - if (!componentRef || componentRef.node.isLeaf) return; - - const contentDOMWrapper = componentRef.contentDOMWrapper; - if ( - !contentDOMWrapper || - !(contentDOMWrapper instanceof HTMLElement) - ) { - return; - } - - // We always set contentDOM when !node.isLeaf, which is checked above - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - contentDOMWrapper.appendChild(contentDOM!); - - // Synchronize the ProseMirror selection to the DOM, because mounting the - // component changes the DOM outside of a ProseMirror update. - const { node } = componentRef; - const pos = getPos(); - const end = pos + node.nodeSize; - const { from, to } = editorView.state.selection; - if (editorView.hasFocus() && pos < from && to < end) { - // This call seems like it should be a no-op, given the editor already has - // focus, but it causes ProseMirror to synchronize the DOM selection with - // its state again, placing the DOM selection in a reasonable place within - // the node. - editorView.focus(); - } - }} - /> - ); - - const portal = createPortal(element, dom as HTMLElement, nodeKey); - - const unregisterPortal = registerPortal(editorView, getPos, portal); - - return { - ignoreMutation(record: MutationRecord) { - return !contentDOM?.contains(record.target); - }, - ...reactNodeView, - selectNode() { - componentRef?.setIsSelected(true); - reactNodeView.selectNode?.(); - }, - deselectNode() { - componentRef?.setIsSelected(false); - reactNodeView.deselectNode?.(); - }, - update( - node: Node, - decorations: readonly Decoration[], - innerDecorations: DecorationSource - ) { - // If this node view's parent has been removed from the registry, we - // need to rebuild it and its children with new registry keys - const positionRegistry = reactPluginKey.getState(editorView.state); - if ( - positionRegistry && - nodeKey !== positionRegistry.posToKey.get(getPos()) - ) { - return false; - } - - if ( - reactNodeView.update?.(node, decorations, innerDecorations) === false - ) { - return false; - } - if (node.type === componentRef?.node.type) { - componentRef?.setNode(node); - componentRef?.setDecorations(decorations); - return true; - } - return false; - }, - destroy() { - // React expects the contentDOMParent to be a child of the - // DOM element where the portal was mounted, but in some situations - // contenteditable may have already detached the contentDOMParent - // from the DOM. Here we attempt to reassemble the DOM that React - // expects when cleaning up the portal. - if (componentRef?.contentDOMParent) { - this.dom.appendChild(componentRef.contentDOMParent); - } - unregisterPortal(); - reactNodeView.destroy?.(); - }, - }; - } - - return Object.assign(nodeViewConstructor, { [REACT_NODE_VIEW]: true }); -} diff --git a/src/nodeViews/phrasingContentTags.ts b/src/nodeViews/phrasingContentTags.ts deleted file mode 100644 index d67223f8..00000000 --- a/src/nodeViews/phrasingContentTags.ts +++ /dev/null @@ -1,49 +0,0 @@ -export const phrasingContentTags = [ - "abbr", - "audio", - "b", - "bdo", - "br", - "button", - "canvas", - "cite", - "code", - "data", - "datalist", - "dfn", - "em", - "embed", - "i", - "iframe", - "img", - "input", - "kbd", - "keygen", - "label", - "mark", - "math", - "meter", - "noscript", - "object", - "output", - "picture", - "progress", - "q", - "ruby", - "s", - "samp", - "script", - "select", - "small", - "span", - "strong", - "sub", - "sup", - "svg", - "textarea", - "time", - "u", - "var", - "video", - "wbr", -]; diff --git a/src/plugins/__tests__/react.test.ts b/src/plugins/__tests__/reactKeys.test.ts similarity index 75% rename from src/plugins/__tests__/react.test.ts rename to src/plugins/__tests__/reactKeys.test.ts index 617ab433..5b37529a 100644 --- a/src/plugins/__tests__/react.test.ts +++ b/src/plugins/__tests__/reactKeys.test.ts @@ -2,7 +2,7 @@ import { Schema } from "prosemirror-model"; import { EditorState } from "prosemirror-state"; -import { react, reactPluginKey } from "../react.js"; +import { reactKeys, reactKeysPluginKey } from "../reactKeys.js"; const schema = new Schema({ nodes: { @@ -22,29 +22,29 @@ describe("reactNodeViewPlugin", () => { schema.nodes.paragraph.create(), schema.nodes.paragraph.create(), ]), - plugins: [react()], + plugins: [reactKeys()], }); - const pluginState = reactPluginKey.getState(editorState)!; + const pluginState = reactKeysPluginKey.getState(editorState)!; expect(pluginState.posToKey.size).toBe(3); }); it("should maintain key stability when possible", () => { const initialEditorState = EditorState.create({ doc: schema.topNodeType.create(null, [ - schema.nodes.paragraph.create(), + schema.nodes.paragraph.create({}, schema.text("Hello")), schema.nodes.paragraph.create(), schema.nodes.paragraph.create(), ]), - plugins: [react()], + plugins: [reactKeys()], }); - const initialPluginState = reactPluginKey.getState(initialEditorState)!; + const initialPluginState = reactKeysPluginKey.getState(initialEditorState)!; const nextEditorState = initialEditorState.apply( - initialEditorState.tr.insertText("Hello, world!", 1) + initialEditorState.tr.insertText(", world!", 6) ); - const nextPluginState = reactPluginKey.getState(nextEditorState)!; + const nextPluginState = reactKeysPluginKey.getState(nextEditorState)!; expect(Array.from(initialPluginState.keyToPos.keys())).toEqual( Array.from(nextPluginState.keyToPos.keys()) @@ -58,15 +58,15 @@ describe("reactNodeViewPlugin", () => { schema.nodes.paragraph.create(), schema.nodes.paragraph.create(), ]), - plugins: [react()], + plugins: [reactKeys()], }); - const initialPluginState = reactPluginKey.getState(initialEditorState)!; + const initialPluginState = reactKeysPluginKey.getState(initialEditorState)!; const nextEditorState = initialEditorState.apply( initialEditorState.tr.insert(0, schema.nodes.list.createAndFill()!) ); - const nextPluginState = reactPluginKey.getState(nextEditorState)!; + const nextPluginState = reactKeysPluginKey.getState(nextEditorState)!; // Adds new keys for new nodes expect(nextPluginState.keyToPos.size).toBe(5); diff --git a/src/plugins/beforeInputPlugin.ts b/src/plugins/beforeInputPlugin.ts new file mode 100644 index 00000000..34009695 --- /dev/null +++ b/src/plugins/beforeInputPlugin.ts @@ -0,0 +1,181 @@ +import { Mark } from "prosemirror-model"; +import { Plugin } from "prosemirror-state"; +import { Decoration, EditorView } from "prosemirror-view"; + +import { CursorWrapper } from "../components/CursorWrapper.js"; +import { widget } from "../decorations/ReactWidgetType.js"; + +import { reactKeysPluginKey } from "./reactKeys.js"; + +function insertText( + view: EditorView, + eventData: string | null, + options: { + from?: number; + to?: number; + bust?: boolean; + marks?: readonly Mark[] | null; + } = {} +) { + if (eventData === null) return false; + + const from = options.from ?? view.state.selection.from; + const to = options.to ?? view.state.selection.to; + + if (view.someProp("handleTextInput", (f) => f(view, from, to, eventData))) { + return true; + } + + const { tr } = view.state; + if (options.marks) tr.ensureMarks(options.marks); + + tr.insertText(eventData, from, to); + + if (options.bust) { + const $from = view.state.doc.resolve(from); + const sharedAncestorDepth = $from.sharedDepth(to); + const sharedAncestorPos = $from.start(sharedAncestorDepth); + + const parentKey = reactKeysPluginKey + .getState(view.state) + ?.posToKey.get(sharedAncestorPos - 1); + + tr.setMeta(reactKeysPluginKey, { + type: "bustKey", + payload: { key: parentKey }, + }); + } + + view.dispatch(tr); + return true; +} + +export function beforeInputPlugin( + setCursorWrapper: (deco: Decoration | null) => void +) { + let compositionText: string | null = null; + let compositionMarks: readonly Mark[] | null = null; + return new Plugin({ + props: { + handleDOMEvents: { + compositionstart(view) { + const { state } = view; + + view.dispatch(state.tr.deleteSelection()); + + const $pos = state.selection.$from; + + if ( + state.selection.empty && + (state.storedMarks || + (!$pos.textOffset && + $pos.parentOffset && + $pos.nodeBefore?.marks.some( + (m) => m.type.spec.inclusive === false + ))) + ) { + setCursorWrapper( + widget(state.selection.from, CursorWrapper, { + key: "cursor-wrapper", + marks: state.storedMarks ?? $pos.marks(), + }) + ); + } + compositionMarks = state.storedMarks ?? $pos.marks(); + + // @ts-expect-error Internal property - input + view.input.composing = true; + return true; + }, + compositionupdate() { + return true; + }, + compositionend(view) { + // @ts-expect-error Internal property - input + view.input.composing = false; + if (compositionText === null) return; + + insertText(view, compositionText, { + // TODO: Rather than busting the reactKey cache here, + // which is pretty blunt and doesn't work for + // multi-node replacements, we should attempt to + // snapshot the selected DOM during compositionstart + // and restore it before we end the composition. + // This should allow React to successfully clean up + // and insert the newly composed text, without requiring + // any remounts + bust: true, + marks: compositionMarks, + }); + + compositionText = null; + compositionMarks = null; + setCursorWrapper(null); + return true; + }, + beforeinput(view, event) { + event.preventDefault(); + switch (event.inputType) { + case "insertCompositionText": { + if (event.data === null) break; + + compositionText = event.data; + break; + } + case "insertReplacementText": { + const ranges = event.getTargetRanges(); + event.dataTransfer?.items[0]?.getAsString((data) => { + for (const range of ranges) { + const from = view.posAtDOM( + range.startContainer, + range.startOffset, + 1 + ); + const to = view.posAtDOM( + range.endContainer, + range.endOffset, + 1 + ); + insertText(view, data, { from, to }); + } + }); + break; + } + case "insertText": { + insertText(view, event.data); + break; + } + case "deleteWordBackward": + case "deleteContentBackward": + case "deleteWordForward": + case "deleteContentForward": + case "deleteContent": { + const targetRanges = event.getTargetRanges(); + const { tr } = view.state; + for (const range of targetRanges) { + const start = view.posAtDOM( + range.startContainer, + range.startOffset + ); + const end = view.posAtDOM(range.endContainer, range.endOffset); + const { doc } = view.state; + + const storedMarks = doc + .resolve(start) + .marksAcross(doc.resolve(end)); + + tr.delete(start, end).setStoredMarks(storedMarks); + } + view.dispatch(tr); + break; + } + default: { + break; + } + } + return true; + }, + }, + }, + }); +} diff --git a/src/plugins/react.ts b/src/plugins/react.ts deleted file mode 100644 index e0a5300e..00000000 --- a/src/plugins/react.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Plugin, PluginKey } from "prosemirror-state"; - -/** - * This is a stand-in for the doc node itself, which doesn't have a - * unique position to map to. - */ -export const ROOT_NODE_KEY = Symbol("@nytimes/react-prosemirror/root-node-key"); - -export type NodeKey = string | typeof ROOT_NODE_KEY; - -/** - * Identifies a node view constructor as having been created - * by @nytimes/react-prosemirror - */ -export const REACT_NODE_VIEW = Symbol("react node view"); - -export function createNodeKey() { - return Math.floor(Math.random() * 0xffffff).toString(16); -} - -export type ReactPluginState = { - posToKey: Map; - keyToPos: Map; -}; - -export const reactPluginKey = new PluginKey( - "@nytimes/react-prosemirror/react" -); - -/** - * Tracks a unique key for each (non-text) node in the - * document, identified by its current position. Keys are - * (mostly) stable across transaction applications. The - * key for a given node can be accessed by that node's - * current position in the document, and vice versa. - */ -export function react() { - return new Plugin({ - key: reactPluginKey, - state: { - init(_, state) { - const next = { - posToKey: new Map(), - keyToPos: new Map(), - }; - state.doc.descendants((node, pos) => { - if (node.isText) return false; - - const key = createNodeKey(); - - next.posToKey.set(pos, key); - next.keyToPos.set(key, pos); - return true; - }); - return next; - }, - /** - * Keeps node keys (mostly) stable across transactions. - * - * To accomplish this, we map each node position backwards - * through the transaction to identify its previous position, - * and thereby retrieve its previous key. - */ - apply(tr, value, _, newState) { - if (!tr.docChanged) return value; - - const next = { - posToKey: new Map(), - keyToPos: new Map(), - }; - const nextKeys = new Set(); - newState.doc.descendants((node, pos) => { - if (node.isText) return false; - - const prevPos = tr.mapping.invert().map(pos); - const prevKey = value.posToKey.get(prevPos) ?? createNodeKey(); - // If this transaction adds a new node, there will be multiple - // nodes that map back to the same initial position. In this case, - // create new keys for new nodes. - const key = nextKeys.has(prevKey) ? createNodeKey() : prevKey; - next.posToKey.set(pos, key); - next.keyToPos.set(key, pos); - nextKeys.add(key); - return true; - }); - return next; - }, - }, - }); -} diff --git a/src/plugins/reactKeys.ts b/src/plugins/reactKeys.ts new file mode 100644 index 00000000..dc2e53c8 --- /dev/null +++ b/src/plugins/reactKeys.ts @@ -0,0 +1,95 @@ +import { Node } from "prosemirror-model"; +import { Plugin, PluginKey } from "prosemirror-state"; + +export function createNodeKey() { + const key = Math.floor(Math.random() * 0xffffff).toString(16); + return key; +} + +export const reactKeysPluginKey = new PluginKey<{ + posToKey: Map; + keyToPos: Map; + posToNode: Map; +}>("@nytimes/react-prosemirror/reactKeys"); + +/** + * Tracks a unique key for each (non-text) node in the + * document, identified by its current position. Keys are + * (mostly) stable across transaction applications. The + * key for a given node can be accessed by that node's + * current position in the document, and vice versa. + */ +export function reactKeys() { + let composing = false; + return new Plugin({ + key: reactKeysPluginKey, + state: { + init(_, state) { + const next = { + posToKey: new Map(), + keyToPos: new Map(), + }; + state.doc.descendants((_, pos) => { + const key = createNodeKey(); + + next.posToKey.set(pos, key); + next.keyToPos.set(key, pos); + return true; + }); + return next; + }, + /** + * Keeps node keys (mostly) stable across transactions. + * + * To accomplish this, we map each node position backwards + * through the transaction to identify its previous position, + * and thereby retrieve its previous key. + */ + apply(tr, value, _, newState) { + if (!tr.docChanged || composing) return value; + const meta = tr.getMeta(reactKeysPluginKey); + const keyToBust = meta?.type === "bustKey" && meta.payload.key; + + const next = { + posToKey: new Map(), + keyToPos: new Map(), + }; + const posToKeyEntries = Array.from(value.posToKey.entries()).sort( + ([a], [b]) => a - b + ); + for (const [pos, key] of posToKeyEntries) { + const { pos: newPos, deleted } = tr.mapping.mapResult(pos); + if (deleted) continue; + + let newKey = key; + + if (keyToBust === key) { + newKey = createNodeKey(); + } + + next.posToKey.set(newPos, newKey); + next.keyToPos.set(newKey, newPos); + } + newState.doc.descendants((_, pos) => { + if (next.posToKey.has(pos)) return true; + + const key = createNodeKey(); + next.posToKey.set(pos, key); + next.keyToPos.set(key, pos); + return true; + }); + return next; + }, + }, + props: { + handleDOMEvents: { + compositionstart: () => { + composing = true; + }, + compositionend: () => { + composing = false; + }, + }, + }, + }); +} diff --git a/src/props.ts b/src/props.ts new file mode 100644 index 00000000..be81ec70 --- /dev/null +++ b/src/props.ts @@ -0,0 +1,238 @@ +import cx from "classnames"; +import { HTMLProps } from "react"; + +export function kebabCaseToCamelCase(str: string) { + return str.replaceAll(/-[a-z]/g, (g) => g[1]?.toUpperCase() ?? ""); +} + +/** + * Converts a CSS style string to an object + * that can be passed to a React component's + * `style` prop. + */ +export function cssToStyles(css: string) { + const stylesheet = new CSSStyleSheet(); + stylesheet.insertRule(`* { ${css} }`); + + const insertedRule = stylesheet.cssRules[0] as CSSStyleRule; + const declaration = insertedRule.style; + const styles: Record = {}; + + for (let i = 0; i < declaration.length; i++) { + const property = declaration.item(i); + const value = declaration.getPropertyValue(property); + const camelCasePropertyName = property.startsWith("--") + ? property + : kebabCaseToCamelCase(property); + styles[camelCasePropertyName] = value; + } + + return styles; +} + +/** + * Merges two sets of React props. Class names + * will be concatenated and style objects + * will be merged. + */ +export function mergeReactProps( + a: HTMLProps, + b: HTMLProps +) { + return { + ...a, + ...b, + className: cx(a.className, b.className), + style: { + ...a.style, + ...b.style, + }, + }; +} + +/** + * Given a record of HTML attributes, returns tho + * equivalent React props. + */ +export function htmlAttrsToReactProps( + attrs: Record +): HTMLProps { + const props: Record = {}; + for (const [attrName, attrValue] of Object.entries(attrs)) { + switch (attrName.toLowerCase()) { + case "class": { + props.className = attrValue; + break; + } + case "style": { + props.style = cssToStyles(attrValue); + break; + } + case "autocapitalize": { + props.autoCapitalize = attrValue; + break; + } + case "contenteditable": { + if (attrValue === "" || attrValue === "true") { + props.contentEditable = true; + break; + } + if (attrValue === "false") { + props.contentEditable = false; + break; + } + if (attrValue === "plaintext-only") { + props.contentEditable = "plaintext-only"; + break; + } + props.contentEditable = null; + break; + } + case "draggable": { + props.draggable = attrValue != null; + break; + } + case "enterkeyhint": { + props.enterKeyHint = attrValue; + break; + } + case "for": { + props.htmlFor = attrValue; + break; + } + case "hidden": { + props.hidden = attrValue; + break; + } + case "inputmode": { + props.inputMode = attrValue; + break; + } + case "itemprop": { + props.itemProp = attrValue; + break; + } + case "spellcheck": { + if (attrValue === "" || attrValue === "true") { + props.spellCheck = true; + break; + } + if (attrValue === "false") { + props.spellCheck = false; + break; + } + props.spellCheck = null; + break; + } + case "tabindex": { + const numValue = parseInt(attrValue, 10); + if (!Number.isNaN(numValue)) { + props.tabIndex = numValue; + } + break; + } + case "autocomplete": { + props.autoComplete = attrValue; + break; + } + case "autofocus": { + props.autoFocus = attrValue != null; + break; + } + case "formaction": { + props.formAction = attrValue; + break; + } + case "formenctype": { + props.formEnctype = attrValue; + break; + } + case "formmethod": { + props.formMethod = attrValue; + break; + } + case "formnovalidate": { + props.formNoValidate = attrValue; + break; + } + case "formtarget": { + props.formTarget = attrValue; + break; + } + case "maxlength": { + const numValue = parseInt(attrValue, 10); + if (!Number.isNaN(numValue)) { + props.maxLength = attrValue; + } + break; + } + case "minlength": { + const numValue = parseInt(attrValue, 10); + if (!Number.isNaN(numValue)) { + props.minLength = attrValue; + } + break; + } + case "max": { + const numValue = parseInt(attrValue, 10); + if (!Number.isNaN(numValue)) { + props.max = attrValue; + } + break; + } + case "min": { + const numValue = parseInt(attrValue, 10); + if (!Number.isNaN(numValue)) { + props.min = attrValue; + } + break; + } + case "multiple": { + props.multiple = attrValue != null; + break; + } + case "readonly": { + props.readOnly = attrValue != null; + break; + } + case "required": { + props.required = attrValue != null; + break; + } + case "size": { + const numValue = parseInt(attrValue, 10); + if (!Number.isNaN(numValue)) { + props.size = attrValue; + } + break; + } + case "step": { + if (attrValue === "any") { + props.step = attrValue; + break; + } + const numValue = parseInt(attrValue, 10); + if (!Number.isNaN(numValue) && numValue > 0) { + props.step = attrValue; + } + break; + } + case "disabled": { + props.disabled = attrValue != null; + break; + } + case "rows": { + const numValue = parseInt(attrValue, 10); + if (!Number.isNaN(numValue)) { + props.rows = attrValue; + } + break; + } + default: { + props[attrName] = attrValue; + break; + } + } + } + return props; +} diff --git a/src/selection/SelectionDOMObserver.ts b/src/selection/SelectionDOMObserver.ts new file mode 100644 index 00000000..5d8bc9e2 --- /dev/null +++ b/src/selection/SelectionDOMObserver.ts @@ -0,0 +1,248 @@ +import { Selection } from "prosemirror-state"; +import { EditorView } from "prosemirror-view"; + +import { browser } from "../browser.js"; +import { + DOMNode, + DOMSelectionRange, + parentNode, + selectionCollapsed, +} from "../dom.js"; + +import { hasFocusAndSelection } from "./hasFocusAndSelection.js"; +import { selectionFromDOM } from "./selectionFromDOM.js"; +import { isEquivalentPosition, selectionToDOM } from "./selectionToDOM.js"; + +class SelectionState { + anchorNode: Node | null = null; + anchorOffset = 0; + focusNode: Node | null = null; + focusOffset = 0; + + set(sel: DOMSelectionRange) { + this.anchorNode = sel.anchorNode; + this.anchorOffset = sel.anchorOffset; + this.focusNode = sel.focusNode; + this.focusOffset = sel.focusOffset; + } + + clear() { + this.anchorNode = this.focusNode = null; + } + + eq(sel: DOMSelectionRange) { + return ( + sel.anchorNode == this.anchorNode && + sel.anchorOffset == this.anchorOffset && + sel.focusNode == this.focusNode && + sel.focusOffset == this.focusOffset + ); + } +} + +export class SelectionDOMObserver { + flushingSoon = -1; + currentSelection = new SelectionState(); + suppressingSelectionUpdates = false; + + constructor(readonly view: EditorView) { + this.view = view; + this.onSelectionChange = this.onSelectionChange.bind(this); + } + + connectSelection() { + this.view.dom.ownerDocument.addEventListener( + "selectionchange", + this.onSelectionChange + ); + } + + disconnectSelection() { + this.view.dom.ownerDocument.removeEventListener( + "selectionchange", + this.onSelectionChange + ); + } + + stop() { + this.disconnectSelection(); + } + + start() { + this.connectSelection(); + } + + suppressSelectionUpdates() { + this.suppressingSelectionUpdates = true; + setTimeout(() => (this.suppressingSelectionUpdates = false), 50); + } + + setCurSelection() { + // @ts-expect-error Internal method + this.currentSelection.set(this.view.domSelectionRange()); + } + + ignoreSelectionChange(sel: DOMSelectionRange) { + if (!sel.focusNode) return true; + const ancestors: Set = new Set(); + let container: DOMNode | undefined; + for ( + let scan: DOMNode | null = sel.focusNode; + scan; + scan = parentNode(scan) + ) + ancestors.add(scan); + for (let scan = sel.anchorNode; scan; scan = parentNode(scan)) + if (ancestors.has(scan)) { + container = scan; + break; + } + // @ts-expect-error Internal property (docView) + const desc = container && this.view.docView.nearestDesc(container); + if ( + desc && + desc.ignoreMutation({ + type: "selection", + target: container?.nodeType == 3 ? container?.parentNode : container, + }) + ) { + this.setCurSelection(); + return true; + } + return; + } + + registerMutation() { + // pass + } + + flushSoon() { + if (this.flushingSoon < 0) + this.flushingSoon = window.setTimeout(() => { + this.flushingSoon = -1; + this.flush(); + }, 20); + } + + updateSelection() { + const { view } = this; + const compositionID = + // @ts-expect-error Internal property (input) + view.input.compositionPendingChanges || + // @ts-expect-error Internal property (input) + (view.composing ? view.input.compositionID : 0); + // @ts-expect-error Internal property (input) + view.input.compositionPendingChanges = 0; + + const origin = + // @ts-expect-error Internal property (input) + view.input.lastSelectionTime > Date.now() - 50 + ? // @ts-expect-error Internal property (input) + view.input.lastSelectionOrigin + : null; + const newSel = selectionFromDOM(view, origin); + if (newSel && !view.state.selection.eq(newSel)) { + const tr = view.state.tr.setSelection(newSel); + if (origin == "pointer") tr.setMeta("pointer", true); + else if (origin == "key") tr.scrollIntoView(); + if (compositionID) tr.setMeta("composition", compositionID); + view.dispatch(tr); + } + } + + selectionToDOM() { + const { view } = this; + selectionToDOM(view); + // @ts-expect-error Internal property (domSelectionRange) + const sel = view.domSelectionRange(); + this.currentSelection.set(sel); + } + + flush() { + const { view } = this; + // @ts-expect-error Internal property (docView) + if (!view.docView || this.flushingSoon > -1) return; + + // @ts-expect-error Internal property (domSelectionRange) + const sel = view.domSelectionRange(); + const newSel = + !this.suppressingSelectionUpdates && + !this.currentSelection.eq(sel) && + hasFocusAndSelection(view) && + !this.ignoreSelectionChange(sel); + + let readSel: Selection | null = null; + // If it looks like the browser has reset the selection to the + // start of the document after focus, restore the selection from + // the state + if ( + newSel && + // @ts-expect-error Internal property (input) + view.input.lastFocus > Date.now() - 200 && + // @ts-expect-error Internal property (input) + Math.max(view.input.lastTouch, view.input.lastClick.time) < + Date.now() - 300 && + selectionCollapsed(sel) && + (readSel = selectionFromDOM(view)) && + readSel.eq(Selection.near(view.state.doc.resolve(0), 1)) + ) { + // @ts-expect-error Internal property (input) + view.input.lastFocus = 0; + selectionToDOM(view); + this.currentSelection.set(sel); + // @ts-expect-error Internal property (scrollToSelection) + view.scrollToSelection(); + } else if (newSel) { + this.updateSelection(); + if (!this.currentSelection.eq(sel)) selectionToDOM(view); + this.currentSelection.set(sel); + } + } + + selectionChanged(sel: DOMSelectionRange) { + return ( + !this.suppressingSelectionUpdates && + !this.currentSelection.eq(sel) && + hasFocusAndSelection(this.view) && + !this.ignoreSelectionChange(sel) + ); + } + + forceFlush() { + if (this.flushingSoon > -1) { + window.clearTimeout(this.flushingSoon); + this.flushingSoon = -1; + this.flush(); + } + } + + onSelectionChange() { + if (!hasFocusAndSelection(this.view)) return; + if (this.view.composing) return; + if (this.suppressingSelectionUpdates) return selectionToDOM(this.view); + // Deletions on IE11 fire their events in the wrong order, giving + // us a selection change event before the DOM changes are + // reported. + if ( + browser.ie && + browser.ie_version <= 11 && + !this.view.state.selection.empty + ) { + // @ts-expect-error Internal method + const sel = this.view.domSelectionRange(); + // Selection.isCollapsed isn't reliable on IE + if ( + sel.focusNode && + isEquivalentPosition( + sel.focusNode, + sel.focusOffset, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + sel.anchorNode!, + sel.anchorOffset + ) + ) + return this.flushSoon(); + } + this.flush(); + } +} diff --git a/src/selection/hasFocusAndSelection.ts b/src/selection/hasFocusAndSelection.ts new file mode 100644 index 00000000..b73ed80a --- /dev/null +++ b/src/selection/hasFocusAndSelection.ts @@ -0,0 +1,32 @@ +import { EditorView } from "prosemirror-view"; + +export function hasFocusAndSelection(view: EditorView) { + if (view.editable && !view.hasFocus()) return false; + return hasSelection(view); +} + +export function hasSelection(view: EditorView) { + // @ts-expect-error Internal method + const sel = view.domSelectionRange(); + if (!sel.anchorNode) return false; + try { + // Firefox will raise 'permission denied' errors when accessing + // properties of `sel.anchorNode` when it's in a generated CSS + // element. + return ( + view.dom.contains( + sel.anchorNode.nodeType == 3 + ? sel.anchorNode.parentNode + : sel.anchorNode + ) && + (view.editable || + view.dom.contains( + sel.focusNode?.nodeType == 3 + ? sel.focusNode?.parentNode + : sel.focusNode + )) + ); + } catch (_) { + return false; + } +} diff --git a/src/selection/selectionFromDOM.ts b/src/selection/selectionFromDOM.ts new file mode 100644 index 00000000..a3db372c --- /dev/null +++ b/src/selection/selectionFromDOM.ts @@ -0,0 +1,101 @@ +import { ResolvedPos } from "prosemirror-model"; +import { NodeSelection, TextSelection } from "prosemirror-state"; +import { EditorView } from "prosemirror-view"; + +import { isOnEdge, selectionCollapsed } from "../dom.js"; +import { NodeViewDesc } from "../viewdesc.js"; + +export function selectionBetween( + view: EditorView, + $anchor: ResolvedPos, + $head: ResolvedPos, + bias?: number +) { + return ( + view.someProp("createSelectionBetween", (f) => f(view, $anchor, $head)) || + TextSelection.between($anchor, $head, bias) + ); +} + +export function selectionFromDOM( + view: EditorView, + origin: string | null = null +) { + // @ts-expect-error Internal method + const domSel = view.domSelectionRange(), + doc = view.state.doc; + if (!domSel.focusNode) return null; + // @ts-expect-error Internal method + let nearestDesc = view.docView.nearestDesc(domSel.focusNode); + const inWidget = nearestDesc && nearestDesc.size == 0; + // @ts-expect-error Internal method + let head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset, 1); + if (head < 0) return null; + let $head = doc.resolve(head), + anchor, + selection; + if (selectionCollapsed(domSel)) { + anchor = head; + while (nearestDesc && !nearestDesc.node) nearestDesc = nearestDesc.parent; + const nearestDescNode = (nearestDesc as NodeViewDesc).node; + if ( + nearestDesc && + nearestDescNode.isAtom && + NodeSelection.isSelectable(nearestDescNode) && + nearestDesc.parent && + !( + nearestDescNode.isInline && + isOnEdge(domSel.focusNode, domSel.focusOffset, nearestDesc.dom) + ) + ) { + const pos = nearestDesc.posBefore; + selection = new NodeSelection(head == pos ? $head : doc.resolve(pos)); + } + } else { + if ( + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + domSel instanceof view.dom.ownerDocument.defaultView!.Selection && + domSel.rangeCount > 1 + ) { + let min = head, + max = head; + for (let i = 0; i < domSel.rangeCount; i++) { + const range = domSel.getRangeAt(i); + min = Math.min( + min, + // @ts-expect-error Internal method + view.docView.posFromDOM(range.startContainer, range.startOffset, 1) + ); + max = Math.max( + max, + // @ts-expect-error Internal method + view.docView.posFromDOM(range.endContainer, range.endOffset, -1) + ); + } + if (min < 0) return null; + [anchor, head] = + max == view.state.selection.anchor ? [max, min] : [min, max]; + $head = doc.resolve(head); + } else { + // @ts-expect-error Internal method + anchor = view.docView.posFromDOM( + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + domSel.anchorNode!, + domSel.anchorOffset, + 1 + ); + } + if (anchor < 0) return null; + } + const $anchor = doc.resolve(anchor); + + if (!selection) { + const bias = + origin == "pointer" || + (view.state.selection.head < $head.pos && !inWidget) + ? 1 + : -1; + selection = selectionBetween(view, $anchor, $head, bias); + } + return selection; +} diff --git a/src/selection/selectionToDOM.ts b/src/selection/selectionToDOM.ts new file mode 100644 index 00000000..5a47b932 --- /dev/null +++ b/src/selection/selectionToDOM.ts @@ -0,0 +1,323 @@ +import { NodeSelection, Selection, TextSelection } from "prosemirror-state"; +import { Decoration, EditorView } from "prosemirror-view"; + +import { browser } from "../browser.js"; +import { DOMNode, DOMSelection } from "../dom.js"; +import { NodeViewDesc, ViewDesc } from "../viewdesc.js"; + +// Scans forward and backward through DOM positions equivalent to the +// given one to see if the two are in the same place (i.e. after a +// text node vs at the end of that text node) +export const isEquivalentPosition = function ( + node: Node, + off: number, + targetNode: Node, + targetOff: number +) { + return ( + targetNode && + (scanFor(node, off, targetNode, targetOff, -1) || + scanFor(node, off, targetNode, targetOff, 1)) + ); +}; + +export function hasBlockDesc(dom: Node) { + let desc; + for (let cur: Node | null = dom; cur; cur = cur.parentNode) + if ((desc = cur.pmViewDesc)) break; + return ( + desc && + desc.node && + desc.node.isBlock && + (desc.dom == dom || desc.contentDOM == dom) + ); +} + +const atomElements = /^(img|br|input|textarea|hr)$/i; + +function scanFor( + node: Node, + off: number, + targetNode: Node, + targetOff: number, + dir: number +) { + for (;;) { + if (node == targetNode && off == targetOff) return true; + if (off == (dir < 0 ? 0 : nodeSize(node))) { + const parent = node.parentNode; + if ( + !parent || + parent.nodeType != 1 || + hasBlockDesc(node) || + atomElements.test(node.nodeName) || + (node as HTMLElement).contentEditable == "false" + ) + return false; + off = domIndex(node) + (dir < 0 ? 0 : 1); + node = parent; + } else if (node.nodeType == 1) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + node = node.childNodes[off + (dir < 0 ? -1 : 0)]!; + if ((node as HTMLElement).contentEditable == "false") return false; + off = dir < 0 ? nodeSize(node) : 0; + } else { + return false; + } + } +} + +export const domIndex = function (node: Node) { + let n: Node | null = node; + for (let index = 0; ; index++) { + n = n.previousSibling; + if (!n) return index; + } +}; + +export function nodeSize(node: Node) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return node.nodeType == 3 ? node.nodeValue!.length : node.childNodes.length; +} + +interface InternalView extends EditorView { + docView: ViewDesc; + lastSelectedViewDesc: ViewDesc | undefined; + domSelectionRange(): { + focusNode: DOMNode | null; + focusOffset: number; + anchorNode: DOMNode | null; + anchorOffset: number; + }; + domSelection(): DOMSelection; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + domObserver: any; + cursorWrapper: { dom: DOMNode; deco: Decoration } | null; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + input: any; +} + +export function syncNodeSelection(view: EditorView, sel: Selection) { + const v = view as InternalView; + if (sel instanceof NodeSelection) { + const desc = v.docView.descAt(sel.from); + if (desc != v.lastSelectedViewDesc) { + clearNodeSelection(v); + if (desc) (desc as NodeViewDesc).selectNode(); + v.lastSelectedViewDesc = desc; + } + } else { + clearNodeSelection(v); + } +} + +// Clear all DOM statefulness of the last node selection. +function clearNodeSelection(view: EditorView) { + const v = view as InternalView; + if (v.lastSelectedViewDesc) { + if (v.lastSelectedViewDesc.parent) + (v.lastSelectedViewDesc as NodeViewDesc).deselectNode(); + v.lastSelectedViewDesc = undefined; + } +} + +export function hasSelection(view: EditorView) { + const v = view as InternalView; + const sel = v.domSelectionRange(); + if (!sel.anchorNode) return false; + try { + // Firefox will raise 'permission denied' errors when accessing + // properties of `sel.anchorNode` when it's in a generated CSS + // element. + return ( + v.dom.contains( + sel.anchorNode.nodeType == 3 + ? sel.anchorNode.parentNode + : sel.anchorNode + ) && + (v.editable || + v.dom.contains( + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + sel.focusNode!.nodeType == 3 + ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + sel.focusNode!.parentNode + : sel.focusNode + )) + ); + } catch (_) { + return false; + } +} + +function editorOwnsSelection(view: EditorView) { + return view.editable + ? view.hasFocus() + : hasSelection(view) && + document.activeElement && + document.activeElement.contains(view.dom); +} + +function selectCursorWrapper(view: EditorView) { + const v = view as InternalView; + const domSel = v.domSelection(), + range = document.createRange(); + if (!domSel) return; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const node = v.cursorWrapper!.dom, + img = node.nodeName == "IMG"; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + if (img) range.setStart(node.parentNode!, domIndex(node) + 1); + else range.setStart(node, 0); + range.collapse(true); + domSel.removeAllRanges(); + domSel.addRange(range); + // Kludge to kill 'control selection' in IE11 when selecting an + // invisible cursor wrapper, since that would result in those weird + // resize handles and a selection that considers the absolutely + // positioned wrapper, rather than the root editable node, the + // focused element. + if ( + !img && + !v.state.selection.visible && + browser.ie && + browser.ie_version <= 11 + ) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (node as any).disabled = true; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (node as any).disabled = false; + } +} + +function temporarilyEditableNear(view: EditorView, pos: number) { + const v = view as InternalView; + const { node, offset } = v.docView.domFromPos(pos, 0); + const after = + offset < node.childNodes.length ? node.childNodes[offset] : null; + const before = offset ? node.childNodes[offset - 1] : null; + if ( + browser.safari && + after && + (after as HTMLElement).contentEditable == "false" + ) + return setEditable(after as HTMLElement); + if ( + (!after || (after as HTMLElement).contentEditable == "false") && + (!before || (before as HTMLElement).contentEditable == "false") + ) { + if (after) return setEditable(after as HTMLElement); + else if (before) return setEditable(before as HTMLElement); + } + return; +} + +function setEditable(element: HTMLElement) { + element.contentEditable = "true"; + if (browser.safari && element.draggable) { + element.draggable = false; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (element as any).wasDraggable = true; + } + return element; +} + +function resetEditable(element: HTMLElement) { + element.contentEditable = "false"; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if ((element as any).wasDraggable) { + element.draggable = true; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (element as any).wasDraggable = null; + } +} + +function removeClassOnSelectionChange(view: EditorView) { + const v = view as InternalView; + const doc = v.dom.ownerDocument; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + doc.removeEventListener("selectionchange", v.input.hideSelectionGuard!); + const domSel = v.domSelectionRange(); + const node = domSel.anchorNode, + offset = domSel.anchorOffset; + doc.addEventListener( + "selectionchange", + (v.input.hideSelectionGuard = () => { + if (domSel.anchorNode != node || domSel.anchorOffset != offset) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + doc.removeEventListener("selectionchange", v.input.hideSelectionGuard!); + setTimeout(() => { + if (!editorOwnsSelection(v) || v.state.selection.visible) + v.dom.classList.remove("ProseMirror-hideselection"); + }, 20); + } + }) + ); +} + +const brokenSelectBetweenUneditable = + browser.safari || (browser.chrome && browser.chrome_version < 63); + +export function selectionToDOM(view: EditorView, force = false) { + const v = view as InternalView; + const sel = v.state.selection; + syncNodeSelection(v, sel); + + if (!editorOwnsSelection(v)) return; + + // The delayed drag selection causes issues with Cell Selections + // in Safari. And the drag selection delay is to workarond issues + // which only present in Chrome. + if ( + !force && + v.input.mouseDown && + v.input.mouseDown.allowDefault && + browser.chrome + ) { + const domSel = v.domSelectionRange(), + curSel = v.domObserver.currentSelection; + if ( + domSel.anchorNode && + curSel.anchorNode && + isEquivalentPosition( + domSel.anchorNode, + domSel.anchorOffset, + curSel.anchorNode, + curSel.anchorOffset + ) + ) { + v.input.mouseDown.delayedSelectionSync = true; + v.domObserver.setCurSelection(); + return; + } + } + + v.domObserver.disconnectSelection(); + + if (v.cursorWrapper) { + selectCursorWrapper(v); + } else { + const { anchor, head } = sel; + let resetEditableFrom; + let resetEditableTo; + if (brokenSelectBetweenUneditable && !(sel instanceof TextSelection)) { + if (!sel.$from.parent.inlineContent) + resetEditableFrom = temporarilyEditableNear(v, sel.from); + if (!sel.empty && !sel.$from.parent.inlineContent) + resetEditableTo = temporarilyEditableNear(v, sel.to); + } + v.docView.setSelection(anchor, head, v.root, force); + if (brokenSelectBetweenUneditable) { + if (resetEditableFrom) resetEditable(resetEditableFrom); + if (resetEditableTo) resetEditable(resetEditableTo); + } + if (sel.visible) { + v.dom.classList.remove("ProseMirror-hideselection"); + } else { + v.dom.classList.add("ProseMirror-hideselection"); + if ("onselectionchange" in document) removeClassOnSelectionChange(v); + } + } + + v.domObserver.setCurSelection(); + v.domObserver.connectSelection(); +} diff --git a/src/testing/editorViewTestHelpers.tsx b/src/testing/editorViewTestHelpers.tsx new file mode 100644 index 00000000..75d16716 --- /dev/null +++ b/src/testing/editorViewTestHelpers.tsx @@ -0,0 +1,134 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { render } from "@testing-library/react"; +import { MatcherFunction, expect } from "expect"; +import { Node } from "prosemirror-model"; +import { EditorState, TextSelection } from "prosemirror-state"; +import { doc, eq, p, schema } from "prosemirror-test-builder"; +import { EditorView, EditorView as EditorViewT } from "prosemirror-view"; +import React from "react"; + +import { Props, ProseMirror } from "../components/ProseMirror.js"; +import { ProseMirrorDoc } from "../components/ProseMirrorDoc.js"; +import { DOMNode } from "../dom.js"; +import { useEditorEffect } from "../hooks/useEditorEffect.js"; +import { reactKeys } from "../plugins/reactKeys.js"; + +const toEqualNode: MatcherFunction<[actual: unknown, expect: unknown]> = + function (actual, expected) { + if (!(actual instanceof Node && expected instanceof Node)) { + throw new Error("Must be comparing nodes"); + } + + const pass = eq(actual, expected); + + return { + message: () => + // `this` context will have correct typings + `expected ${this.utils.printReceived(actual)} ${ + pass ? "not " : "" + }to equal ${this.utils.printExpected(expected)}`, + pass, + }; + }; + +expect.extend({ toEqualNode }); + +declare module "expect" { + interface AsymmetricMatchers { + toEqualNode(actual: Node): void; + } + interface Matchers { + toEqualNode(actual: Node): R; + } +} + +export function tempEditor({ + doc: startDoc, + selection, + controlled, + plugins, + ...props +}: { + doc?: ReturnType; + selection?: Selection; + controlled?: boolean; +} & Omit): { + view: EditorViewT; + rerender: (props?: Omit) => void; + unmount: () => void; +} { + startDoc = startDoc ?? doc(p()); + const state = EditorState.create({ + doc: startDoc, + schema, + selection: + selection ?? startDoc.tag?.a + ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + TextSelection.create(startDoc, startDoc.tag.a!, startDoc.tag?.b) + : undefined, + plugins: [...(plugins ?? []), reactKeys()], + }); + + let view: EditorView | null = null; + + function Test() { + useEditorEffect((v) => { + view = v; + }); + + return null; + } + + const { rerender, unmount } = render( + + + + + ); + + function rerenderEditor({ + ...newProps + }: Omit = {}) { + rerender( + + + + + ); + return view; + } + + // We need two renders for the hasContentDOM state to settle + rerenderEditor(); + + return { + view: view as unknown as EditorView, + rerender: rerenderEditor, + unmount, + }; +} + +function findTextNodeInner(node: DOMNode, text: string): Text | undefined { + if (node.nodeType == 3) { + if (node.nodeValue == text) return node as Text; + } else if (node.nodeType == 1) { + for (let ch = node.firstChild; ch; ch = ch.nextSibling) { + const found = findTextNodeInner(ch, text); + if (found) return found; + } + } + return undefined; +} + +export function findTextNode(node: DOMNode, text: string): Text { + const found = findTextNodeInner(node, text); + if (found) return found; + + throw new Error("Unable to find matching text node"); +} diff --git a/src/testing/setupProseMirrorView.ts b/src/testing/setupProseMirrorView.ts index bc648471..00a1ea5b 100644 --- a/src/testing/setupProseMirrorView.ts +++ b/src/testing/setupProseMirrorView.ts @@ -1,7 +1,32 @@ let oldElementFromPoint: undefined | ((x: number, y: number) => Element | null); let oldGetClientRects: undefined | (() => DOMRectList); +let oldGetBoundingClientRect: undefined | (() => DOMRect); const mockElementFromPoint = () => globalThis.document.body; +const mockGetBoundingClientRect = (): DOMRect => { + return { + bottom: 0, + height: 0, + left: 0, + right: 0, + top: 0, + width: 0, + x: 0, + y: 0, + toJSON() { + return { + bottom: 0, + height: 0, + left: 0, + right: 0, + top: 0, + width: 0, + x: 0, + y: 0, + }; + }, + }; +}; const mockGetClientRects = () => { const list = [ { @@ -41,6 +66,9 @@ export function setupProseMirrorView() { oldGetClientRects = Range.prototype.getClientRects; Range.prototype.getClientRects = mockGetClientRects; + + oldGetBoundingClientRect = Range.prototype.getBoundingClientRect; + Range.prototype.getBoundingClientRect = mockGetBoundingClientRect; } export function teardownProseMirrorView() { @@ -48,4 +76,6 @@ export function teardownProseMirrorView() { Document.prototype.elementFromPoint = oldElementFromPoint; // @ts-expect-error jsdom actually doesn't implement these, so they might be undefined Range.prototype.getClientRects = oldGetClientRects; + // @ts-expect-error jsdom actually doesn't implement these, so they might be undefined + Range.prototype.getBoundingClientRect = oldGetBoundingClientRect; } diff --git a/src/viewdesc.ts b/src/viewdesc.ts new file mode 100644 index 00000000..e2c3e741 --- /dev/null +++ b/src/viewdesc.ts @@ -0,0 +1,949 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import { Fragment, Mark, Node, TagParseRule } from "prosemirror-model"; +import { Decoration, DecorationSource, EditorView } from "prosemirror-view"; + +import { browser } from "./browser.js"; +import { InternalDecorationSource } from "./decorations/internalTypes.js"; +import { DOMNode } from "./dom.js"; +import { domIndex, isEquivalentPosition } from "./selection/selectionToDOM.js"; + +// View descriptions are data structures that describe the DOM that is +// used to represent the editor's content. They are used for: +// +// - Incremental redrawing when the document changes +// +// - Figuring out what part of the document a given DOM position +// corresponds to +// +// - Wiring in custom implementations of the editing interface for a +// given node +// +// They form a doubly-linked mutable tree, starting at `view.docView`. + +const NOT_DIRTY = 0, + CHILD_DIRTY = 1, + CONTENT_DIRTY = 2, + NODE_DIRTY = 3; + +// Superclass for the various kinds of descriptions. Defines their +// basic structure and shared methods. +export class ViewDesc { + dirty = NOT_DIRTY; + node!: Node | null; + + constructor( + public parent: ViewDesc | undefined, + public children: ViewDesc[], + public dom: DOMNode, + // This is the node that holds the child views. It may be null for + // descs that don't have children. + public contentDOM: HTMLElement | null + ) { + // An expando property on the DOM node provides a link back to its + // description. + // @ts-expect-error We're using custom view implementations here but + // we match the API so this is relatively safe. + dom.pmViewDesc = this; + } + + // Used to check whether a given description corresponds to a + // widget/mark/node. + matchesWidget(_widget: Decoration) { + return false; + } + matchesMark(_mark: Mark) { + return false; + } + matchesNode( + _node: Node, + _outerDeco: readonly Decoration[], + _innerDeco: DecorationSource + ) { + return false; + } + // @ts-expect-error ... + matchesHack(nodeName: string) { + return false; + } + + // When parsing in-editor content (in domchange.js), we allow + // descriptions to determine the parse rules that should be used to + // parse them. + parseRule(): Omit | null { + return null; + } + + // Used by the editor's event handler to ignore events that come + // from certain descs. + // @ts-expect-error ... + stopEvent(event: Event) { + return false; + } + + // The size of the content represented by this desc. + get size() { + let size = 0; + for (let i = 0; i < this.children.length; i++) + // @ts-expect-error ... + size += this.children[i].size; + return size; + } + + // For block nodes, this represents the space taken up by their + // start/end tokens. + get border() { + return 0; + } + + destroy() { + // pass + } + + posBeforeChild(child: ViewDesc): number { + for (let i = 0, pos = this.posAtStart; ; i++) { + const cur = this.children[i]; + if (cur == child) return pos; + // @ts-expect-error ... + pos += cur.size; + } + } + + get posBefore() { + return this.parent!.posBeforeChild(this); + } + + get posAtStart() { + return this.parent ? this.parent.posBeforeChild(this) + this.border : 0; + } + + get posAfter() { + return this.posBefore + this.size; + } + + get posAtEnd() { + return this.posAtStart + this.size - 2 * this.border; + } + + localPosFromDOM(dom: DOMNode, offset: number, bias: number): number { + // If the DOM position is in the content, use the child desc after + // it to figure out a position. + if ( + this.contentDOM && + this.contentDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode) + ) { + if (bias < 0) { + let domBefore, desc: ViewDesc | undefined; + if (dom == this.contentDOM) { + domBefore = dom.childNodes[offset - 1]; + } else { + while (dom.parentNode != this.contentDOM) dom = dom.parentNode!; + domBefore = dom.previousSibling; + } + while ( + domBefore && + !( + (desc = domBefore.pmViewDesc as ViewDesc | undefined) && + desc.parent == this + ) + ) + domBefore = domBefore.previousSibling; + return domBefore + ? this.posBeforeChild(desc!) + desc!.size + : this.posAtStart; + } else { + let domAfter, desc: ViewDesc | undefined; + if (dom == this.contentDOM) { + domAfter = dom.childNodes[offset]; + } else { + while (dom.parentNode != this.contentDOM) dom = dom.parentNode!; + domAfter = dom.nextSibling; + } + while ( + domAfter && + !( + (desc = domAfter.pmViewDesc as ViewDesc | undefined) && + desc.parent == this + ) + ) + domAfter = domAfter.nextSibling; + + return domAfter ? this.posBeforeChild(desc!) : this.posAtEnd; + } + } + // Otherwise, use various heuristics, falling back on the bias + // parameter, to determine whether to return the position at the + // start or at the end of this view desc. + let atEnd; + if (dom == this.dom && this.contentDOM) { + atEnd = offset > domIndex(this.contentDOM); + } else if ( + this.contentDOM && + this.contentDOM != this.dom && + this.dom.contains(this.contentDOM) + ) { + atEnd = dom.compareDocumentPosition(this.contentDOM) & 2; + } else if (this.dom.firstChild) { + if (offset == 0) + for (let search = dom; ; search = search.parentNode!) { + if (search == this.dom) { + atEnd = false; + break; + } + if (search.previousSibling) break; + } + if (atEnd == null && offset == dom.childNodes.length) + for (let search = dom; ; search = search.parentNode!) { + if (search == this.dom) { + atEnd = true; + break; + } + if (search.nextSibling) break; + } + } + return (atEnd == null ? bias > 0 : atEnd) ? this.posAtEnd : this.posAtStart; + } + + // Scan up the dom finding the first desc that is a descendant of + // this one. + nearestDesc(dom: DOMNode): ViewDesc | undefined; + nearestDesc(dom: DOMNode, onlyNodes: true): NodeViewDesc | undefined; + nearestDesc( + dom: DOMNode, + onlyNodes = false + ): ViewDesc | NodeViewDesc | undefined { + for ( + let first = true, cur: DOMNode | null = dom; + cur; + cur = cur.parentNode + ) { + const desc = this.getDesc(cur); + let nodeDOM; + if (desc && (!onlyNodes || desc.node)) { + // If dom is outside of this desc's nodeDOM, don't count it. + if ( + first && + (nodeDOM = (desc as NodeViewDesc).nodeDOM) && + !(nodeDOM.nodeType == 1 + ? nodeDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode) + : nodeDOM == dom) + ) + first = false; + else return desc as ViewDesc | NodeViewDesc | undefined; + } + } + return; + } + + getDesc(dom: DOMNode) { + const desc = dom.pmViewDesc as ViewDesc | undefined; + for (let cur: ViewDesc | undefined = desc; cur; cur = cur.parent) + if (cur == this) return desc; + return; + } + + posFromDOM(dom: DOMNode, offset: number, bias: number) { + for (let scan: DOMNode | null = dom; scan; scan = scan.parentNode) { + const desc = this.getDesc(scan); + if (desc) return desc.localPosFromDOM(dom, offset, bias); + } + return -1; + } + + // Find the desc for the node after the given pos, if any. (When a + // parent node overrode rendering, there might not be one.) + descAt(pos: number): ViewDesc | undefined { + for (let i = 0, offset = 0; i < this.children.length; i++) { + let child = this.children[i]!; + const end = offset + child.size; + if (offset == pos && end != offset) { + while (!child.border && child.children.length) + child = child.children[0]!; + return child; + } + if (pos < end) return child.descAt(pos - offset - child.border); + offset = end; + } + return; + } + + domFromPos( + pos: number, + side: number + ): { node: DOMNode; offset: number; atom?: number } { + if (!this.contentDOM) return { node: this.dom, offset: 0, atom: pos + 1 }; + // First find the position in the child array + let i = 0, + offset = 0; + for (let curPos = 0; i < this.children.length; i++) { + const child = this.children[i]!, + end = curPos + child.size; + if (end > pos || child instanceof TrailingHackViewDesc) { + offset = pos - curPos; + break; + } + curPos = end; + } + // If this points into the middle of a child, call through + if (offset) + return this.children[i]!.domFromPos( + offset - this.children[i]!.border, + side + ); + // Go back if there were any zero-length widgets with side >= 0 before this point + for ( + let prev; + i && + !(prev = this.children[i - 1]!).size && + prev instanceof WidgetViewDesc && + prev.side >= 0; + i-- + ) { + // ... + } + // Scan towards the first useable node + if (side <= 0) { + let prev, + enter = true; + for (; ; i--, enter = false) { + prev = i ? this.children[i - 1] : null; + if (!prev || prev.dom.parentNode == this.contentDOM) break; + } + if (prev && side && enter && !prev.border && !prev.domAtom) + return prev.domFromPos(prev.size, side); + return { + node: this.contentDOM, + offset: prev ? domIndex(prev.dom) + 1 : 0, + }; + } else { + let next, + enter = true; + for (; ; i++, enter = false) { + next = i < this.children.length ? this.children[i] : null; + if (!next || next.dom.parentNode == this.contentDOM) break; + } + if (next && enter && !next.border && !next.domAtom) + return next.domFromPos(0, side); + return { + node: this.contentDOM, + offset: next ? domIndex(next.dom) : this.contentDOM.childNodes.length, + }; + } + } + + // Used to find a DOM range in a single parent for a given changed + // range. + parseRange( + from: number, + to: number, + base = 0 + ): { + node: DOMNode; + from: number; + to: number; + fromOffset: number; + toOffset: number; + } { + if (this.children.length == 0) + return { + node: this.contentDOM!, + from, + to, + fromOffset: 0, + + toOffset: this.contentDOM!.childNodes.length, + }; + + let fromOffset = -1, + toOffset = -1; + for (let offset = base, i = 0; ; i++) { + const child = this.children[i]!, + end = offset + child.size; + if (fromOffset == -1 && from <= end) { + const childBase = offset + child.border; + // FIXME maybe descend mark views to parse a narrower range? + if ( + from >= childBase && + to <= end - child.border && + child.node && + child.contentDOM && + this.contentDOM!.contains(child.contentDOM) + ) + return child.parseRange(from, to, childBase); + + from = offset; + for (let j = i; j > 0; j--) { + const prev = this.children[j - 1]!; + if ( + prev.size && + prev.dom.parentNode == this.contentDOM && + !prev.emptyChildAt(1) + ) { + fromOffset = domIndex(prev.dom) + 1; + break; + } + from -= prev.size; + } + if (fromOffset == -1) fromOffset = 0; + } + if (fromOffset > -1 && (end > to || i == this.children.length - 1)) { + to = end; + for (let j = i + 1; j < this.children.length; j++) { + const next = this.children[j]!; + if ( + next.size && + next.dom.parentNode == this.contentDOM && + !next.emptyChildAt(-1) + ) { + toOffset = domIndex(next.dom); + break; + } + to += next.size; + } + + if (toOffset == -1) toOffset = this.contentDOM!.childNodes.length; + break; + } + offset = end; + } + + return { node: this.contentDOM!, from, to, fromOffset, toOffset }; + } + + emptyChildAt(side: number): boolean { + if (this.border || !this.contentDOM || !this.children.length) return false; + const child = this.children[side < 0 ? 0 : this.children.length - 1]; + // @ts-expect-error ... + return child.size == 0 || child.emptyChildAt(side); + } + + domAfterPos(pos: number): DOMNode { + const { node, offset } = this.domFromPos(pos, 0); + if (node.nodeType != 1 || offset == node.childNodes.length) + throw new RangeError("No node after pos " + pos); + // @ts-expect-error ... + return node.childNodes[offset]; + } + + // View descs are responsible for setting any selection that falls + // entirely inside of them, so that custom implementations can do + // custom things with the selection. Note that this falls apart when + // a selection starts in such a node and ends in another, in which + // case we just use whatever domFromPos produces as a best effort. + setSelection( + anchor: number, + head: number, + root: Document | ShadowRoot, + force = false + ): void { + // If the selection falls entirely in a child, give it to that child + const from = Math.min(anchor, head), + to = Math.max(anchor, head); + for (let i = 0, offset = 0; i < this.children.length; i++) { + const child = this.children[i]!, + end = offset + child.size; + if (from > offset && to < end) + return child.setSelection( + anchor - offset - child.border, + head - offset - child.border, + root, + force + ); + offset = end; + } + + let anchorDOM = this.domFromPos(anchor, anchor ? -1 : 1); + let headDOM = + head == anchor ? anchorDOM : this.domFromPos(head, head ? -1 : 1); + + const domSel = (root as Document).getSelection()!; + + let brKludge = false; + // On Firefox, using Selection.collapse to put the cursor after a + // BR node for some reason doesn't always work (#1073). On Safari, + // the cursor sometimes inexplicable visually lags behind its + // reported position in such situations (#1092). + if ((browser.gecko || browser.safari) && anchor == head) { + const { node, offset } = anchorDOM; + if (node.nodeType == 3) { + brKludge = !!(offset && node.nodeValue?.[offset - 1] == "\n"); + // Issue #1128 + + if (brKludge && offset == node.nodeValue!.length) { + for ( + let scan: DOMNode | null = node, after; + scan; + scan = scan.parentNode + ) { + if ((after = scan.nextSibling)) { + if (after.nodeName == "BR") + anchorDOM = headDOM = { + node: after.parentNode!, + offset: domIndex(after) + 1, + }; + break; + } + const desc = scan.pmViewDesc; + if (desc && desc.node && desc.node.isBlock) break; + } + } + } else { + const prev = node.childNodes[offset - 1]; + // @ts-expect-error ... + brKludge = + prev && + (prev.nodeName == "BR" || + (prev as HTMLElement).contentEditable == "false"); + } + } + // Firefox can act strangely when the selection is in front of an + // uneditable node. See #1163 and https://bugzilla.mozilla.org/show_bug.cgi?id=1709536 + if ( + browser.gecko && + domSel.focusNode && + domSel.focusNode != headDOM.node && + domSel.focusNode.nodeType == 1 + ) { + const after = domSel.focusNode.childNodes[domSel.focusOffset]; + if (after && (after as HTMLElement).contentEditable == "false") + force = true; + } + + if ( + !(force || (brKludge && browser.safari)) && + isEquivalentPosition( + anchorDOM.node, + anchorDOM.offset, + domSel.anchorNode!, + domSel.anchorOffset + ) && + isEquivalentPosition( + headDOM.node, + headDOM.offset, + domSel.focusNode!, + domSel.focusOffset + ) + ) + return; + + // Selection.extend can be used to create an 'inverted' selection + // (one where the focus is before the anchor), but not all + // browsers support it yet. + let domSelExtended = false; + if ((domSel.extend || anchor == head) && !brKludge) { + domSel.collapse(anchorDOM.node, anchorDOM.offset); + try { + if (anchor != head) domSel.extend(headDOM.node, headDOM.offset); + domSelExtended = true; + } catch (_) { + // In some cases with Chrome the selection is empty after calling + // collapse, even when it should be valid. This appears to be a bug, but + // it is difficult to isolate. If this happens fallback to the old path + // without using extend. + // Similarly, this could crash on Safari if the editor is hidden, and + // there was no selection. + } + } + if (!domSelExtended) { + if (anchor > head) { + const tmp = anchorDOM; + anchorDOM = headDOM; + headDOM = tmp; + } + const range = document.createRange(); + range.setEnd(headDOM.node, headDOM.offset); + range.setStart(anchorDOM.node, anchorDOM.offset); + domSel.removeAllRanges(); + domSel.addRange(range); + } + } + + ignoreMutation(mutation: MutationRecord): boolean { + return !this.contentDOM && (mutation.type as any) != "selection"; + } + + get contentLost() { + return ( + this.contentDOM && + this.contentDOM != this.dom && + !this.dom.contains(this.contentDOM) + ); + } + + // Remove a subtree of the element tree that has been touched + // by a DOM change, so that the next update will redraw it. + markDirty(from: number, to: number) { + for (let offset = 0, i = 0; i < this.children.length; i++) { + const child = this.children[i]!, + end = offset + child.size; + if ( + offset == end ? from <= end && to >= offset : from < end && to > offset + ) { + const startInside = offset + child.border, + endInside = end - child.border; + if (from >= startInside && to <= endInside) { + this.dirty = + from == offset || to == end ? CONTENT_DIRTY : CHILD_DIRTY; + if ( + from == startInside && + to == endInside && + (child.contentLost || child.dom.parentNode != this.contentDOM) + ) + child.dirty = NODE_DIRTY; + else child.markDirty(from - startInside, to - startInside); + return; + } else { + child.dirty = + child.dom == child.contentDOM && + child.dom.parentNode == this.contentDOM && + !child.children.length + ? CONTENT_DIRTY + : NODE_DIRTY; + } + } + offset = end; + } + this.dirty = CONTENT_DIRTY; + } + + markParentsDirty() { + let level = 1; + for (let node = this.parent; node; node = node.parent, level++) { + const dirty = level == 1 ? CONTENT_DIRTY : CHILD_DIRTY; + if (node.dirty < dirty) node.dirty = dirty; + } + } + + get domAtom() { + return false; + } + + get ignoreForCoords() { + return false; + } +} + +// A widget desc represents a widget decoration, which is a DOM node +// drawn between the document nodes. +export class WidgetViewDesc extends ViewDesc { + constructor( + parent: ViewDesc | undefined, + readonly widget: Decoration, + dom: DOMNode + ) { + super(parent, [], dom, null); + this.widget = widget; + } + + matchesWidget(widget: Decoration) { + return ( + this.dirty == NOT_DIRTY && + (widget as any).type.eq((this.widget as any).type) + ); + } + + parseRule() { + return { ignore: true }; + } + + stopEvent(event: Event) { + const stop = this.widget.spec.stopEvent; + return stop ? stop(event) : false; + } + + ignoreMutation(mutation: MutationRecord) { + return ( + (mutation.type as any) != "selection" || this.widget.spec.ignoreSelection + ); + } + + get domAtom() { + return true; + } + + get side() { + return (this.widget as any).type.side as number; + } +} + +export class CompositionViewDesc extends ViewDesc { + constructor( + parent: ViewDesc | undefined, + dom: DOMNode, + public textDOM: Text, + public text: string + ) { + super(parent, [], dom, null); + } + + get size() { + return this.text.length; + } + + localPosFromDOM(dom: DOMNode, offset: number) { + if (dom != this.textDOM) return this.posAtStart + (offset ? this.size : 0); + return this.posAtStart + offset; + } + + domFromPos(pos: number) { + return { node: this.textDOM, offset: pos }; + } + + ignoreMutation(mut: MutationRecord) { + return mut.type === "characterData" && mut.target.nodeValue == mut.oldValue; + } +} + +// A mark desc represents a mark. May have multiple children, +// depending on how the mark is split. Note that marks are drawn using +// a fixed nesting order, for simplicity and predictability, so in +// some cases they will be split more often than would appear +// necessary. +export class MarkViewDesc extends ViewDesc { + constructor( + parent: ViewDesc | undefined, + children: ViewDesc[], + readonly mark: Mark, + dom: DOMNode, + contentDOM: HTMLElement + ) { + super(parent, children, dom, contentDOM); + } + + parseRule() { + if (this.dirty & NODE_DIRTY || this.mark.type.spec.reparseInView) + return null; + return { + mark: this.mark.type.name, + attrs: this.mark.attrs, + contentElement: this.contentDOM!, + }; + } + + matchesMark(mark: Mark) { + return this.dirty != NODE_DIRTY && this.mark.eq(mark); + } + + markDirty(from: number, to: number) { + super.markDirty(from, to); + // Move dirty info to nearest node view + if (this.dirty != NOT_DIRTY) { + let parent = this.parent!; + while (!parent.node) parent = parent.parent!; + if (parent.dirty < this.dirty) parent.dirty = this.dirty; + this.dirty = NOT_DIRTY; + } + } +} + +// Node view descs are the main, most common type of view desc, and +// correspond to an actual node in the document. Unlike mark descs, +// they populate their child array themselves. +export class NodeViewDesc extends ViewDesc { + constructor( + parent: ViewDesc | undefined, + children: ViewDesc[], + public node: Node, + public outerDeco: readonly Decoration[], + public innerDeco: DecorationSource, + dom: DOMNode, + contentDOM: HTMLElement | null, + public nodeDOM: DOMNode, + public stopEvent: (event: Event) => boolean + ) { + super(parent, children, dom, contentDOM); + } + + updateOuterDeco() { + // pass + } + + parseRule() { + // Experimental kludge to allow opt-in re-parsing of nodes + if (this.node.type.spec.reparseInView) return null; + // FIXME the assumption that this can always return the current + // attrs means that if the user somehow manages to change the + // attrs in the dom, that won't be picked up. Not entirely sure + // whether this is a problem + const rule: Omit = { + node: this.node.type.name, + attrs: this.node.attrs, + }; + if (this.node.type.whitespace == "pre") rule.preserveWhitespace = "full"; + if (!this.contentDOM) { + rule.getContent = () => this.node.content; + } else if (!this.contentLost) { + rule.contentElement = this.contentDOM; + } else { + // Chrome likes to randomly recreate parent nodes when + // backspacing things. When that happens, this tries to find the + // new parent. + for (let i = this.children.length - 1; i >= 0; i--) { + const child = this.children[i]; + // @ts-expect-error ... + if (this.dom.contains(child.dom.parentNode)) { + // @ts-expect-error ... + rule.contentElement = child.dom.parentNode as HTMLElement; + break; + } + } + if (!rule.contentElement) rule.getContent = () => Fragment.empty; + } + return rule; + } + + matchesNode( + node: Node, + outerDeco: readonly Decoration[], + innerDeco: DecorationSource + ) { + return ( + this.dirty == NOT_DIRTY && + node.eq(this.node) && + sameOuterDeco(outerDeco, this.outerDeco) && + (innerDeco as InternalDecorationSource).eq(this.innerDeco) + ); + } + + get size() { + return this.node.nodeSize; + } + + get border() { + return this.node.isLeaf ? 0 : 1; + } + + // If this desc must be updated to match the given node decoration, + // do so and return true. + update( + _node: Node, + _outerDeco: readonly Decoration[], + _innerDeco: DecorationSource, + _view: EditorView + ) { + return true; + } + + // Mark this node as being the selected node. + selectNode() { + if (this.nodeDOM.nodeType == 1) + (this.nodeDOM as HTMLElement).classList.add("ProseMirror-selectednode"); + if (this.contentDOM || !this.node.type.spec.draggable) + (this.dom as HTMLElement).draggable = true; + } + + // Remove selected node marking from this node. + deselectNode() { + if (this.nodeDOM.nodeType == 1) { + (this.nodeDOM as HTMLElement).classList.remove( + "ProseMirror-selectednode" + ); + if (this.contentDOM || !this.node.type.spec.draggable) + (this.dom as HTMLElement).removeAttribute("draggable"); + } + } + + get domAtom() { + return this.node.isAtom; + } +} + +export class TextViewDesc extends NodeViewDesc { + constructor( + parent: ViewDesc | undefined, + children: ViewDesc[], + node: Node, + outerDeco: readonly Decoration[], + innerDeco: DecorationSource, + dom: DOMNode, + nodeDOM: DOMNode + ) { + super( + parent, + children, + node, + outerDeco, + innerDeco, + dom, + null, + nodeDOM, + () => false + ); + } + + parseRule() { + let skip = this.nodeDOM.parentNode; + while (skip && skip != this.dom && !(skip as any).pmIsDeco) + skip = skip.parentNode; + return { skip: (skip || true) as any }; + } + + update( + _node: Node, + _outerDeco: readonly Decoration[], + _innerDeco: DecorationSource, + _view: EditorView + ) { + return true; + } + + inParent() { + const parentDOM = this.parent!.contentDOM; + for (let n: DOMNode | null = this.nodeDOM; n; n = n.parentNode) + if (n == parentDOM) return true; + return false; + } + + domFromPos(pos: number) { + return { node: this.nodeDOM, offset: pos }; + } + + localPosFromDOM(dom: DOMNode, offset: number, bias: number) { + if (dom == this.nodeDOM) + return this.posAtStart + Math.min(offset, this.node.text!.length); + return super.localPosFromDOM(dom, offset, bias); + } + + ignoreMutation(mutation: MutationRecord) { + return ( + mutation.type != "characterData" && (mutation.type as any) != "selection" + ); + } + + markDirty(from: number, to: number) { + super.markDirty(from, to); + if ( + this.dom != this.nodeDOM && + (from == 0 || to == this.nodeDOM.nodeValue!.length) + ) + this.dirty = NODE_DIRTY; + } + + get domAtom() { + return false; + } +} + +// A dummy desc used to tag trailing BR or IMG nodes created to work +// around contentEditable terribleness. +export class TrailingHackViewDesc extends ViewDesc { + parseRule() { + return { ignore: true }; + } + matchesHack(nodeName: string) { + return this.dirty == NOT_DIRTY && this.dom.nodeName == nodeName; + } + get domAtom() { + return true; + } + get ignoreForCoords() { + return this.dom.nodeName == "IMG"; + } +} + +function sameOuterDeco(a: readonly Decoration[], b: readonly Decoration[]) { + if (a.length != b.length) return false; + // @ts-expect-error ... + for (let i = 0; i < a.length; i++) if (!a[i].type.eq(b[i].type)) return false; + return true; +} diff --git a/tsconfig.json b/tsconfig.json index ca48256f..ff0cc6eb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -30,6 +30,7 @@ /* Incremental Build Options */ "incremental": true, /* "Classic" React JSX pragma */ - "jsx": "react" + "jsx": "react", + "types": ["node", "@wdio/globals/types", "@wdio/mocha-framework", "jest"] } } diff --git a/wdio.conf.ts b/wdio.conf.ts new file mode 100644 index 00000000..6f1ccbaa --- /dev/null +++ b/wdio.conf.ts @@ -0,0 +1,301 @@ +import "@wdio/types"; + +import viteConfig from "./vite.config.js"; + +export const config: WebdriverIO.Config = { + // + // ==================== + // Runner Configuration + // ==================== + // WebdriverIO supports running e2e tests as well as unit and component tests. + runner: ["browser", { viteConfig }], + tsConfigPath: "./tsconfig.json", + + // + // ================== + // Specify Test Files + // ================== + // Define which test specs should run. The pattern is relative to the directory + // of the configuration file being run. + // + // The specs are defined as an array of spec files (optionally using wildcards + // that will be expanded). The test for each spec file will be run in a separate + // worker process. In order to have a group of spec files run in the same worker + // process simply enclose them in an array within the specs array. + // + // The path of the spec files will be resolved relative from the directory of + // of the config file unless it's absolute. + // + specs: [ + "./src/components/__tests__/ProseMirror.*.test.tsx", + "./src/components/__tests__/ProseMirror.test.tsx", + ], + // Patterns to exclude. + exclude: [ + // 'path/to/excluded/files' + ], + // + // ============ + // Capabilities + // ============ + // Define your capabilities here. WebdriverIO can run multiple capabilities at the same + // time. Depending on the number of capabilities, WebdriverIO launches several test + // sessions. Within your capabilities you can overwrite the spec and exclude options in + // order to group specific specs to a specific capability. + // + // First, you can define how many instances should be started at the same time. Let's + // say you have 3 different capabilities (Chrome, Firefox, and Safari) and you have + // set maxInstances to 1; wdio will spawn 3 processes. Therefore, if you have 10 spec + // files and you set maxInstances to 10, all spec files will get tested at the same time + // and 30 processes will get spawned. The property handles how many capabilities + // from the same test should run tests. + // + maxInstances: 1, + // + // If you have trouble getting all important capabilities together, check out the + // Sauce Labs platform configurator - a great tool to configure your capabilities: + // https://saucelabs.com/platform/platform-configurator + // + capabilities: [ + { + browserName: "chrome", + }, + { + browserName: "firefox", + }, + ], + + // + // =================== + // Test Configurations + // =================== + // Define all options that are relevant for the WebdriverIO instance here + // + // Level of logging verbosity: trace | debug | info | warn | error | silent + logLevel: "error", + // + // Set specific log levels per logger + // loggers: + // - webdriver, webdriverio + // - @wdio/browserstack-service, @wdio/lighthouse-service, @wdio/sauce-service + // - @wdio/mocha-framework, @wdio/jasmine-framework + // - @wdio/local-runner + // - @wdio/sumologic-reporter + // - @wdio/cli, @wdio/config, @wdio/utils + // Level of logging verbosity: trace | debug | info | warn | error | silent + // logLevels: { + // webdriver: 'info', + // '@wdio/appium-service': 'info' + // }, + // + // If you only want to run your tests until a specific amount of tests have failed use + // bail (default is 0 - don't bail, run all tests). + bail: 0, + // + // Set a base URL in order to shorten url command calls. If your `url` parameter starts + // with `/`, the base url gets prepended, not including the path portion of your baseUrl. + // If your `url` parameter starts without a scheme or `/` (like `some/path`), the base url + // gets prepended directly. + // baseUrl: 'http://localhost:8080', + // + // Default timeout for all waitFor* commands. + waitforTimeout: 10000, + // + // Default timeout in milliseconds for request + // if browser driver or grid doesn't send response + connectionRetryTimeout: 120000, + // + // Default request retries count + connectionRetryCount: 3, + // + // Test runner services + // Services take over a specific job you don't want to take care of. They enhance + // your test setup with almost no effort. Unlike plugins, they don't add new + // commands. Instead, they hook themselves up into the test process. + // services: [], + // + framework: "mocha", + + // + // The number of times to retry the entire specfile when it fails as a whole + // specFileRetries: 1, + // + // Delay in seconds between the spec file retry attempts + // specFileRetriesDelay: 0, + // + // Whether or not retried spec files should be retried immediately or deferred to the end of the queue + // specFileRetriesDeferred: false, + // + // Test reporter for stdout. + // The only one supported by default is 'dot' + // see also: https://webdriver.io/docs/dot-reporter + // reporters: ['dot'], + + // Options to be passed to Mocha. + // See the full list at http://mochajs.org/ + mochaOpts: { + ui: "bdd", + timeout: 3600000, + }, + + // + // ===== + // Hooks + // ===== + // WebdriverIO provides several hooks you can use to interfere with the test process in order to enhance + // it and to build services around it. You can either apply a single function or an array of + // methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got + // resolved to continue. + /** + * Gets executed once before all workers get launched. + * @param {object} config wdio configuration object + * @param {Array.} capabilities list of capabilities details + */ + // onPrepare: function (config, capabilities) { + // }, + /** + * Gets executed before a worker process is spawned and can be used to initialize specific service + * for that worker as well as modify runtime environments in an async fashion. + * @param {string} cid capability id (e.g 0-0) + * @param {object} caps object containing capabilities for session that will be spawn in the worker + * @param {object} specs specs to be run in the worker process + * @param {object} args object that will be merged with the main configuration once worker is initialized + * @param {object} execArgv list of string arguments passed to the worker process + */ + // onWorkerStart: function (cid, caps, specs, args, execArgv) { + // }, + /** + * Gets executed just after a worker process has exited. + * @param {string} cid capability id (e.g 0-0) + * @param {number} exitCode 0 - success, 1 - fail + * @param {object} specs specs to be run in the worker process + * @param {number} retries number of retries used + */ + // onWorkerEnd: function (cid, exitCode, specs, retries) { + // }, + /** + * Gets executed just before initialising the webdriver session and test framework. It allows you + * to manipulate configurations depending on the capability or spec. + * @param {object} config wdio configuration object + * @param {Array.} capabilities list of capabilities details + * @param {Array.} specs List of spec file paths that are to be run + * @param {string} cid worker id (e.g. 0-0) + */ + // beforeSession: function (config, capabilities, specs, cid) { + // }, + /** + * Gets executed before test execution begins. At this point you can access to all global + * variables like `browser`. It is the perfect place to define custom commands. + * @param {Array.} capabilities list of capabilities details + * @param {Array.} specs List of spec file paths that are to be run + * @param {object} browser instance of created browser/device session + */ + // Use Jest's expect function + // before() { + // global.expect = expect; + // }, + /** + * Runs before a WebdriverIO command gets executed. + * @param {string} commandName hook command name + * @param {Array} args arguments that command would receive + */ + // beforeCommand: function (commandName, args) { + // }, + /** + * Hook that gets executed before the suite starts + * @param {object} suite suite details + */ + // beforeSuite: function (suite) { + // }, + /** + * Function to be executed before a test (in Mocha/Jasmine) starts. + */ + // beforeTest: function (test, context) { + // }, + /** + * Hook that gets executed _before_ a hook within the suite starts (e.g. runs before calling + * beforeEach in Mocha) + */ + // beforeHook: function (test, context, hookName) { + // }, + /** + * Hook that gets executed _after_ a hook within the suite starts (e.g. runs after calling + * afterEach in Mocha) + */ + // afterHook: function (test, context, { error, result, duration, passed, retries }, hookName) { + // }, + /** + * Function to be executed after a test (in Mocha/Jasmine only) + * @param {object} test test object + * @param {object} context scope object the test was executed with + * @param {Error} result.error error object in case the test fails, otherwise `undefined` + * @param {*} result.result return object of test function + * @param {number} result.duration duration of test + * @param {boolean} result.passed true if test has passed, otherwise false + * @param {object} result.retries information about spec related retries, e.g. `{ attempts: 0, limit: 0 }` + */ + // afterTest: function(test, context, { error, result, duration, passed, retries }) { + // }, + + /** + * Hook that gets executed after the suite has ended + * @param {object} suite suite details + */ + // afterSuite: function (suite) { + // }, + /** + * Runs after a WebdriverIO command gets executed + * @param {string} commandName hook command name + * @param {Array} args arguments that command would receive + * @param {number} result 0 - command success, 1 - command error + * @param {object} error error object if any + */ + // afterCommand: function (commandName, args, result, error) { + // }, + /** + * Gets executed after all tests are done. You still have access to all global variables from + * the test. + * @param {number} result 0 - test pass, 1 - test fail + * @param {Array.} capabilities list of capabilities details + * @param {Array.} specs List of spec file paths that ran + */ + // after: function (result, capabilities, specs) { + // }, + /** + * Gets executed right after terminating the webdriver session. + * @param {object} config wdio configuration object + * @param {Array.} capabilities list of capabilities details + * @param {Array.} specs List of spec file paths that ran + */ + // afterSession: function (config, capabilities, specs) { + // }, + /** + * Gets executed after all workers got shut down and the process is about to exit. An error + * thrown in the onComplete hook will result in the test run failing. + * @param {object} exitCode 0 - success, 1 - fail + * @param {object} config wdio configuration object + * @param {Array.} capabilities list of capabilities details + * @param {} results object containing test results + */ + // onComplete: function(exitCode, config, capabilities, results) { + // }, + /** + * Gets executed when a refresh happens. + * @param {string} oldSessionId session ID of the old session + * @param {string} newSessionId session ID of the new session + */ + // onReload: function(oldSessionId, newSessionId) { + // } + /** + * Hook that gets executed before a WebdriverIO assertion happens. + * @param {object} params information about the assertion to be executed + */ + // beforeAssertion: function(params) { + // } + /** + * Hook that gets executed after a WebdriverIO assertion happened. + * @param {object} params information about the assertion that was executed, including its results + */ + // afterAssertion: function(params) { + // } +}; diff --git a/yarn.lock b/yarn.lock index 03d8d264..d2fda0d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -33,6 +33,16 @@ __metadata: languageName: node linkType: hard +"@babel/code-frame@npm:^7.21.4, @babel/code-frame@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/code-frame@npm:7.24.7" + dependencies: + "@babel/highlight": ^7.24.7 + picocolors: ^1.0.0 + checksum: 830e62cd38775fdf84d612544251ce773d544a8e63df667728cc9e0126eeef14c6ebda79be0f0bc307e8318316b7f58c27ce86702e0a1f5c321d842eb38ffda4 + languageName: node + linkType: hard + "@babel/code-frame@npm:^7.22.13": version: 7.22.13 resolution: "@babel/code-frame@npm:7.22.13" @@ -50,6 +60,13 @@ __metadata: languageName: node linkType: hard +"@babel/compat-data@npm:^7.25.2": + version: 7.25.4 + resolution: "@babel/compat-data@npm:7.25.4" + checksum: b12a91d27c3731a4b0bdc9312a50b1911f41f7f728aaf0d4b32486e2257fd2cb2d3ea1a295e98449600c48f2c7883a3196ca77cda1cef7d97a10c2e83d037974 + languageName: node + linkType: hard + "@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3": version: 7.20.12 resolution: "@babel/core@npm:7.20.12" @@ -73,26 +90,26 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.20.12": - version: 7.21.0 - resolution: "@babel/core@npm:7.21.0" +"@babel/core@npm:^7.23.7, @babel/core@npm:^7.23.9, @babel/core@npm:^7.24.5": + version: 7.25.2 + resolution: "@babel/core@npm:7.25.2" dependencies: "@ampproject/remapping": ^2.2.0 - "@babel/code-frame": ^7.18.6 - "@babel/generator": ^7.21.0 - "@babel/helper-compilation-targets": ^7.20.7 - "@babel/helper-module-transforms": ^7.21.0 - "@babel/helpers": ^7.21.0 - "@babel/parser": ^7.21.0 - "@babel/template": ^7.20.7 - "@babel/traverse": ^7.21.0 - "@babel/types": ^7.21.0 - convert-source-map: ^1.7.0 + "@babel/code-frame": ^7.24.7 + "@babel/generator": ^7.25.0 + "@babel/helper-compilation-targets": ^7.25.2 + "@babel/helper-module-transforms": ^7.25.2 + "@babel/helpers": ^7.25.0 + "@babel/parser": ^7.25.0 + "@babel/template": ^7.25.0 + "@babel/traverse": ^7.25.2 + "@babel/types": ^7.25.2 + convert-source-map: ^2.0.0 debug: ^4.1.0 gensync: ^1.0.0-beta.2 - json5: ^2.2.2 - semver: ^6.3.0 - checksum: 357f4dd3638861ceebf6d95ff49ad8b902065ee8b7b352621deed5666c2a6d702a48ca7254dba23ecae2a0afb67d20f90db7dd645c3b75e35e72ad9776c671aa + json5: ^2.2.3 + semver: ^6.3.1 + checksum: 9a1ef604a7eb62195f70f9370cec45472a08114e3934e3eaaedee8fd754edf0730e62347c7b4b5e67d743ce57b5bb8cf3b92459482ca94d06e06246ef021390a languageName: node linkType: hard @@ -107,18 +124,6 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.21.0": - version: 7.21.1 - resolution: "@babel/generator@npm:7.21.1" - dependencies: - "@babel/types": ^7.21.0 - "@jridgewell/gen-mapping": ^0.3.2 - "@jridgewell/trace-mapping": ^0.3.17 - jsesc: ^2.5.1 - checksum: 69085a211ff91a7a608ee3f86e6fcb9cf5e724b756d792a713b0c328a671cd3e423e1ef1b12533f366baba0616caffe0a7ba9d328727eab484de5961badbef00 - languageName: node - linkType: hard - "@babel/generator@npm:^7.23.0": version: 7.23.0 resolution: "@babel/generator@npm:7.23.0" @@ -131,6 +136,18 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^7.25.0, @babel/generator@npm:^7.25.6": + version: 7.25.6 + resolution: "@babel/generator@npm:7.25.6" + dependencies: + "@babel/types": ^7.25.6 + "@jridgewell/gen-mapping": ^0.3.5 + "@jridgewell/trace-mapping": ^0.3.25 + jsesc: ^2.5.1 + checksum: b55975cd664f5602304d868bb34f4ee3bed6f5c7ce8132cd92ff27a46a53a119def28a182d91992e86f75db904f63094a81247703c4dc96e4db0c03fd04bcd68 + languageName: node + linkType: hard + "@babel/helper-compilation-targets@npm:^7.20.7": version: 7.20.7 resolution: "@babel/helper-compilation-targets@npm:7.20.7" @@ -146,6 +163,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-compilation-targets@npm:^7.25.2": + version: 7.25.2 + resolution: "@babel/helper-compilation-targets@npm:7.25.2" + dependencies: + "@babel/compat-data": ^7.25.2 + "@babel/helper-validator-option": ^7.24.8 + browserslist: ^4.23.1 + lru-cache: ^5.1.1 + semver: ^6.3.1 + checksum: aed33c5496cb9db4b5e2d44e26bf8bc474074cc7f7bb5ebe1d4a20fdeb362cb3ba9e1596ca18c7484bcd6e5c3a155ab975e420d520c0ae60df81f9de04d0fd16 + languageName: node + linkType: hard + "@babel/helper-environment-visitor@npm:^7.18.9": version: 7.18.9 resolution: "@babel/helper-environment-visitor@npm:7.18.9" @@ -188,6 +218,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-imports@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-module-imports@npm:7.24.7" + dependencies: + "@babel/traverse": ^7.24.7 + "@babel/types": ^7.24.7 + checksum: 8ac15d96d262b8940bc469052a048e06430bba1296369be695fabdf6799f201dd0b00151762b56012a218464e706bc033f27c07f6cec20c6f8f5fd6543c67054 + languageName: node + linkType: hard + "@babel/helper-module-transforms@npm:^7.20.11": version: 7.20.11 resolution: "@babel/helper-module-transforms@npm:7.20.11" @@ -204,29 +244,34 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.21.0": - version: 7.21.2 - resolution: "@babel/helper-module-transforms@npm:7.21.2" +"@babel/helper-module-transforms@npm:^7.25.2": + version: 7.25.2 + resolution: "@babel/helper-module-transforms@npm:7.25.2" dependencies: - "@babel/helper-environment-visitor": ^7.18.9 - "@babel/helper-module-imports": ^7.18.6 - "@babel/helper-simple-access": ^7.20.2 - "@babel/helper-split-export-declaration": ^7.18.6 - "@babel/helper-validator-identifier": ^7.19.1 - "@babel/template": ^7.20.7 - "@babel/traverse": ^7.21.2 - "@babel/types": ^7.21.2 - checksum: 8a1c129a4f90bdf97d8b6e7861732c9580f48f877aaaafbc376ce2482febebcb8daaa1de8bc91676d12886487603f8c62a44f9e90ee76d6cac7f9225b26a49e1 + "@babel/helper-module-imports": ^7.24.7 + "@babel/helper-simple-access": ^7.24.7 + "@babel/helper-validator-identifier": ^7.24.7 + "@babel/traverse": ^7.25.2 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 282d4e3308df6746289e46e9c39a0870819630af5f84d632559171e4fae6045684d771a65f62df3d569e88ccf81dc2def78b8338a449ae3a94bb421aa14fc367 languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.19.0, @babel/helper-plugin-utils@npm:^7.20.2, @babel/helper-plugin-utils@npm:^7.8.0": +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.19.0, @babel/helper-plugin-utils@npm:^7.8.0": version: 7.20.2 resolution: "@babel/helper-plugin-utils@npm:7.20.2" checksum: f6cae53b7fdb1bf3abd50fa61b10b4470985b400cc794d92635da1e7077bb19729f626adc0741b69403d9b6e411cddddb9c0157a709cc7c4eeb41e663be5d74b languageName: node linkType: hard +"@babel/helper-plugin-utils@npm:^7.24.7": + version: 7.24.8 + resolution: "@babel/helper-plugin-utils@npm:7.24.8" + checksum: 73b1a83ba8bcee21dc94de2eb7323207391715e4369fd55844bb15cf13e3df6f3d13a40786d990e6370bf0f571d94fc31f70dec96c1d1002058258c35ca3767a + languageName: node + linkType: hard + "@babel/helper-simple-access@npm:^7.20.2": version: 7.20.2 resolution: "@babel/helper-simple-access@npm:7.20.2" @@ -236,6 +281,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-simple-access@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-simple-access@npm:7.24.7" + dependencies: + "@babel/traverse": ^7.24.7 + "@babel/types": ^7.24.7 + checksum: ddbf55f9dea1900213f2a1a8500fabfd21c5a20f44dcfa957e4b0d8638c730f88751c77f678644f754f1a1dc73f4eb8b766c300deb45a9daad000e4247957819 + languageName: node + linkType: hard + "@babel/helper-split-export-declaration@npm:^7.18.6": version: 7.18.6 resolution: "@babel/helper-split-export-declaration@npm:7.18.6" @@ -268,6 +323,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-string-parser@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-string-parser@npm:7.24.8" + checksum: 39b03c5119216883878655b149148dc4d2e284791e969b19467a9411fccaa33f7a713add98f4db5ed519535f70ad273cdadfd2eb54d47ebbdeac5083351328ce + languageName: node + linkType: hard + "@babel/helper-validator-identifier@npm:^7.18.6, @babel/helper-validator-identifier@npm:^7.19.1": version: 7.19.1 resolution: "@babel/helper-validator-identifier@npm:7.19.1" @@ -282,6 +344,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-validator-identifier@npm:7.24.7" + checksum: 6799ab117cefc0ecd35cd0b40ead320c621a298ecac88686a14cffceaac89d80cdb3c178f969861bf5fa5e4f766648f9161ea0752ecfe080d8e89e3147270257 + languageName: node + linkType: hard + "@babel/helper-validator-option@npm:^7.18.6": version: 7.18.6 resolution: "@babel/helper-validator-option@npm:7.18.6" @@ -289,6 +358,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-option@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-validator-option@npm:7.24.8" + checksum: a52442dfa74be6719c0608fee3225bd0493c4057459f3014681ea1a4643cd38b68ff477fe867c4b356da7330d085f247f0724d300582fa4ab9a02efaf34d107c + languageName: node + linkType: hard + "@babel/helpers@npm:^7.20.7": version: 7.20.13 resolution: "@babel/helpers@npm:7.20.13" @@ -300,14 +376,13 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.21.0": - version: 7.21.0 - resolution: "@babel/helpers@npm:7.21.0" +"@babel/helpers@npm:^7.25.0": + version: 7.25.6 + resolution: "@babel/helpers@npm:7.25.6" dependencies: - "@babel/template": ^7.20.7 - "@babel/traverse": ^7.21.0 - "@babel/types": ^7.21.0 - checksum: 9370dad2bb665c551869a08ac87c8bdafad53dbcdce1f5c5d498f51811456a3c005d9857562715151a0f00b2e912ac8d89f56574f837b5689f5f5072221cdf54 + "@babel/template": ^7.25.0 + "@babel/types": ^7.25.6 + checksum: 5a548999db82049a5f7ac6de57576b4ed0d386ce07d058151698836ed411eae6230db12535487caeebb68a2ffc964491e8aead62364a5132ab0ae20e8b68e19f languageName: node linkType: hard @@ -333,6 +408,18 @@ __metadata: languageName: node linkType: hard +"@babel/highlight@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/highlight@npm:7.24.7" + dependencies: + "@babel/helper-validator-identifier": ^7.24.7 + chalk: ^2.4.2 + js-tokens: ^4.0.0 + picocolors: ^1.0.0 + checksum: 5cd3a89f143671c4ac129960024ba678b669e6fc673ce078030f5175002d1d3d52bc10b22c5b916a6faf644b5028e9a4bd2bb264d053d9b05b6a98690f1d46f1 + languageName: node + linkType: hard + "@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7": version: 7.20.15 resolution: "@babel/parser@npm:7.20.15" @@ -342,21 +429,23 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.21.0": - version: 7.21.2 - resolution: "@babel/parser@npm:7.21.2" +"@babel/parser@npm:^7.22.15, @babel/parser@npm:^7.23.0": + version: 7.23.0 + resolution: "@babel/parser@npm:7.23.0" bin: parser: ./bin/babel-parser.js - checksum: e2b89de2c63d4cdd2cafeaea34f389bba729727eec7a8728f736bc472a59396059e3e9fe322c9bed8fd126d201fb609712949dc8783f4cae4806acd9a73da6ff + checksum: 453fdf8b9e2c2b7d7b02139e0ce003d1af21947bbc03eb350fb248ee335c9b85e4ab41697ddbdd97079698de825a265e45a0846bb2ed47a2c7c1df833f42a354 languageName: node linkType: hard -"@babel/parser@npm:^7.22.15, @babel/parser@npm:^7.23.0": - version: 7.23.0 - resolution: "@babel/parser@npm:7.23.0" +"@babel/parser@npm:^7.23.9, @babel/parser@npm:^7.25.0, @babel/parser@npm:^7.25.6": + version: 7.25.6 + resolution: "@babel/parser@npm:7.25.6" + dependencies: + "@babel/types": ^7.25.6 bin: parser: ./bin/babel-parser.js - checksum: 453fdf8b9e2c2b7d7b02139e0ce003d1af21947bbc03eb350fb248ee335c9b85e4ab41697ddbdd97079698de825a265e45a0846bb2ed47a2c7c1df833f42a354 + checksum: 85b237ded09ee43cc984493c35f3b1ff8a83e8dbbb8026b8132e692db6567acc5a1659ec928e4baa25499ddd840d7dae9dee3062be7108fe23ec5f94a8066b1e languageName: node linkType: hard @@ -514,25 +603,25 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-self@npm:^7.18.6": - version: 7.21.0 - resolution: "@babel/plugin-transform-react-jsx-self@npm:7.21.0" +"@babel/plugin-transform-react-jsx-self@npm:^7.24.5": + version: 7.24.7 + resolution: "@babel/plugin-transform-react-jsx-self@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.20.2 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 696f74c04a265409ccd46e333ff762e6011d394e6972128b5d97db4c1647289141bc7ebd45ab2bab99b60932f9793e8f89ee9432d3bde19962de2100456f6147 + checksum: 2d72c33664e614031b8a03fc2d4cfd185e99efb1d681cbde4b0b4ab379864b31d83ee923509892f6d94b2c5893c309f0217d33bcda3e470ed42297f958138381 languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-source@npm:^7.19.6": - version: 7.19.6 - resolution: "@babel/plugin-transform-react-jsx-source@npm:7.19.6" +"@babel/plugin-transform-react-jsx-source@npm:^7.24.1": + version: 7.24.7 + resolution: "@babel/plugin-transform-react-jsx-source@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.19.0 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 1e9e29a4efc5b79840bd4f68e404f5ab7765ce48c7bd22f12f2b185f9c782c66933bdf54a1b21879e4e56e6b50b4e88aca82789ecb1f61123af6dfa9ab16c555 + checksum: c9afcb2259dd124a2de76f8a578589c18bd2f24dbcf78fe02b53c5cbc20c493c4618369604720e4e699b52be10ba0751b97140e1ef8bc8f0de0a935280e9d5b7 languageName: node linkType: hard @@ -545,6 +634,13 @@ __metadata: languageName: node linkType: hard +"@babel/standalone@npm:^7.23.8": + version: 7.25.6 + resolution: "@babel/standalone@npm:7.25.6" + checksum: d02f023d8c0fa10d2aaac98ad64ea43818b86a6a51a85c4e626507b4ff99ac9199dd3a483788b0b0a3e1d73d23a91a29c78c160e5a2af94cb9e3d59730f05ea0 + languageName: node + linkType: hard + "@babel/template@npm:^7.20.7, @babel/template@npm:^7.3.3": version: 7.20.7 resolution: "@babel/template@npm:7.20.7" @@ -567,7 +663,18 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.20.10, @babel/traverse@npm:^7.20.12, @babel/traverse@npm:^7.20.13, @babel/traverse@npm:^7.21.0, @babel/traverse@npm:^7.21.2, @babel/traverse@npm:^7.7.2": +"@babel/template@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/template@npm:7.25.0" + dependencies: + "@babel/code-frame": ^7.24.7 + "@babel/parser": ^7.25.0 + "@babel/types": ^7.25.0 + checksum: 3f2db568718756d0daf2a16927b78f00c425046b654cd30b450006f2e84bdccaf0cbe6dc04994aa1f5f6a4398da2f11f3640a4d3ee31722e43539c4c919c817b + languageName: node + linkType: hard + +"@babel/traverse@npm:^7.20.10, @babel/traverse@npm:^7.20.12, @babel/traverse@npm:^7.20.13": version: 7.23.2 resolution: "@babel/traverse@npm:7.23.2" dependencies: @@ -585,25 +692,29 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.6, @babel/types@npm:^7.20.2, @babel/types@npm:^7.20.7, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.8.3": - version: 7.20.7 - resolution: "@babel/types@npm:7.20.7" +"@babel/traverse@npm:^7.24.7, @babel/traverse@npm:^7.25.2": + version: 7.25.6 + resolution: "@babel/traverse@npm:7.25.6" dependencies: - "@babel/helper-string-parser": ^7.19.4 - "@babel/helper-validator-identifier": ^7.19.1 - to-fast-properties: ^2.0.0 - checksum: b39af241f0b72bba67fd6d0d23914f6faec8c0eba8015c181cbd5ea92e59fc91a52a1ab490d3520c7dbd19ddb9ebb76c476308f6388764f16d8201e37fae6811 + "@babel/code-frame": ^7.24.7 + "@babel/generator": ^7.25.6 + "@babel/parser": ^7.25.6 + "@babel/template": ^7.25.0 + "@babel/types": ^7.25.6 + debug: ^4.3.1 + globals: ^11.1.0 + checksum: 11ee47269aa4356f2d6633a05b9af73405b5ed72c09378daf644289b686ef852035a6ac9aa410f601991993c6bbf72006795b5478283b78eb1ca77874ada7737 languageName: node linkType: hard -"@babel/types@npm:^7.21.0, @babel/types@npm:^7.21.2": - version: 7.21.2 - resolution: "@babel/types@npm:7.21.2" +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.6, @babel/types@npm:^7.20.2, @babel/types@npm:^7.20.7, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.8.3": + version: 7.20.7 + resolution: "@babel/types@npm:7.20.7" dependencies: "@babel/helper-string-parser": ^7.19.4 "@babel/helper-validator-identifier": ^7.19.1 to-fast-properties: ^2.0.0 - checksum: a45a52acde139e575502c6de42c994bdbe262bafcb92ae9381fb54cdf1a3672149086843fda655c7683ce9806e998fd002bbe878fa44984498d0fdc7935ce7ff + checksum: b39af241f0b72bba67fd6d0d23914f6faec8c0eba8015c181cbd5ea92e59fc91a52a1ab490d3520c7dbd19ddb9ebb76c476308f6388764f16d8201e37fae6811 languageName: node linkType: hard @@ -618,6 +729,17 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.23.6, @babel/types@npm:^7.24.7, @babel/types@npm:^7.25.0, @babel/types@npm:^7.25.2, @babel/types@npm:^7.25.6": + version: 7.25.6 + resolution: "@babel/types@npm:7.25.6" + dependencies: + "@babel/helper-string-parser": ^7.24.8 + "@babel/helper-validator-identifier": ^7.24.7 + to-fast-properties: ^2.0.0 + checksum: 9b2f84ff3f874ad05b0b9bf06862c56f478b65781801f82296b4cc01bee39e79c20a7c0a06959fed0ee582c8267e1cb21638318655c5e070b0287242a844d1c9 + languageName: node + linkType: hard + "@bcoe/v8-coverage@npm:^0.2.3": version: 0.2.3 resolution: "@bcoe/v8-coverage@npm:0.2.3" @@ -625,156 +747,338 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/android-arm64@npm:0.17.19" +"@esbuild/aix-ppc64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/aix-ppc64@npm:0.21.5" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/aix-ppc64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/aix-ppc64@npm:0.23.1" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/android-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-arm64@npm:0.21.5" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/android-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-arm64@npm:0.23.1" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@esbuild/android-arm@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/android-arm@npm:0.17.19" +"@esbuild/android-arm@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-arm@npm:0.21.5" conditions: os=android & cpu=arm languageName: node linkType: hard -"@esbuild/android-x64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/android-x64@npm:0.17.19" +"@esbuild/android-arm@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-arm@npm:0.23.1" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@esbuild/android-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-x64@npm:0.21.5" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/android-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-x64@npm:0.23.1" conditions: os=android & cpu=x64 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/darwin-arm64@npm:0.17.19" +"@esbuild/darwin-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/darwin-arm64@npm:0.21.5" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/darwin-x64@npm:0.17.19" +"@esbuild/darwin-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/darwin-arm64@npm:0.23.1" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/darwin-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/darwin-x64@npm:0.21.5" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/darwin-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/darwin-x64@npm:0.23.1" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/freebsd-arm64@npm:0.17.19" +"@esbuild/freebsd-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/freebsd-arm64@npm:0.21.5" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/freebsd-x64@npm:0.17.19" +"@esbuild/freebsd-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/freebsd-arm64@npm:0.23.1" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/freebsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/freebsd-x64@npm:0.21.5" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/freebsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/freebsd-x64@npm:0.23.1" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/linux-arm64@npm:0.17.19" +"@esbuild/linux-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-arm64@npm:0.21.5" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/linux-arm@npm:0.17.19" +"@esbuild/linux-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-arm64@npm:0.23.1" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/linux-arm@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-arm@npm:0.21.5" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@esbuild/linux-arm@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-arm@npm:0.23.1" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/linux-ia32@npm:0.17.19" +"@esbuild/linux-ia32@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-ia32@npm:0.21.5" conditions: os=linux & cpu=ia32 languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/linux-loong64@npm:0.17.19" +"@esbuild/linux-ia32@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-ia32@npm:0.23.1" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.14.54": + version: 0.14.54 + resolution: "@esbuild/linux-loong64@npm:0.14.54" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-loong64@npm:0.21.5" conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/linux-mips64el@npm:0.17.19" +"@esbuild/linux-loong64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-loong64@npm:0.23.1" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-mips64el@npm:0.21.5" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-mips64el@npm:0.23.1" conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/linux-ppc64@npm:0.17.19" +"@esbuild/linux-ppc64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-ppc64@npm:0.21.5" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/linux-riscv64@npm:0.17.19" +"@esbuild/linux-ppc64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-ppc64@npm:0.23.1" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-riscv64@npm:0.21.5" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-riscv64@npm:0.23.1" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/linux-s390x@npm:0.17.19" +"@esbuild/linux-s390x@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-s390x@npm:0.21.5" conditions: os=linux & cpu=s390x languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/linux-x64@npm:0.17.19" +"@esbuild/linux-s390x@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-s390x@npm:0.23.1" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-x64@npm:0.21.5" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-x64@npm:0.23.1" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/netbsd-x64@npm:0.17.19" +"@esbuild/netbsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/netbsd-x64@npm:0.21.5" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/openbsd-x64@npm:0.17.19" +"@esbuild/netbsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/netbsd-x64@npm:0.23.1" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/openbsd-arm64@npm:0.23.1" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/openbsd-x64@npm:0.21.5" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/openbsd-x64@npm:0.23.1" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/sunos-x64@npm:0.17.19" +"@esbuild/sunos-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/sunos-x64@npm:0.21.5" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/sunos-x64@npm:0.23.1" conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/win32-arm64@npm:0.17.19" +"@esbuild/win32-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-arm64@npm:0.21.5" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-arm64@npm:0.23.1" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/win32-ia32@npm:0.17.19" +"@esbuild/win32-ia32@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-ia32@npm:0.21.5" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-ia32@npm:0.23.1" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/win32-x64@npm:0.17.19" +"@esbuild/win32-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-x64@npm:0.21.5" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-x64@npm:0.23.1" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -828,157 +1132,403 @@ __metadata: languageName: node linkType: hard -"@istanbuljs/load-nyc-config@npm:^1.0.0": - version: 1.1.0 - resolution: "@istanbuljs/load-nyc-config@npm:1.1.0" +"@inquirer/checkbox@npm:^2.5.0": + version: 2.5.0 + resolution: "@inquirer/checkbox@npm:2.5.0" dependencies: - camelcase: ^5.3.1 - find-up: ^4.1.0 - get-package-type: ^0.1.0 - js-yaml: ^3.13.1 - resolve-from: ^5.0.0 - checksum: d578da5e2e804d5c93228450a1380e1a3c691de4953acc162f387b717258512a3e07b83510a936d9fab03eac90817473917e24f5d16297af3867f59328d58568 + "@inquirer/core": ^9.1.0 + "@inquirer/figures": ^1.0.5 + "@inquirer/type": ^1.5.3 + ansi-escapes: ^4.3.2 + yoctocolors-cjs: ^2.1.2 + checksum: 4f1df42fe9eb725787803b11daf11d9bda30c31c68ff170d494b089d86bcf3858a7a98f0b6edd172d20479548bcfb241a7142f5f0880d536eac8c6cb7739489e languageName: node linkType: hard -"@istanbuljs/schema@npm:^0.1.2": - version: 0.1.3 - resolution: "@istanbuljs/schema@npm:0.1.3" - checksum: 5282759d961d61350f33d9118d16bcaed914ebf8061a52f4fa474b2cb08720c9c81d165e13b82f2e5a8a212cc5af482f0c6fc1ac27b9e067e5394c9a6ed186c9 +"@inquirer/confirm@npm:^3.2.0": + version: 3.2.0 + resolution: "@inquirer/confirm@npm:3.2.0" + dependencies: + "@inquirer/core": ^9.1.0 + "@inquirer/type": ^1.5.3 + checksum: 6b032a26c64075dc14769558720b17f09bc6784a223bbf2c85ec42e491be6ce4c4b83518433c47e05d7e8836ba680ab1b2f6b9c553410d4326582308a1fd2259 languageName: node linkType: hard -"@jest/console@npm:^29.4.1": - version: 29.4.1 - resolution: "@jest/console@npm:29.4.1" +"@inquirer/core@npm:^9.1.0": + version: 9.2.1 + resolution: "@inquirer/core@npm:9.2.1" dependencies: - "@jest/types": ^29.4.1 - "@types/node": "*" - chalk: ^4.0.0 - jest-message-util: ^29.4.1 - jest-util: ^29.4.1 - slash: ^3.0.0 - checksum: 5b061e4fec29016d42ab1dbbc0fd8386cfa28f921deb6880ff1a82203c7df0776827c2819f2fe1feb8872c8a5cf6d0a04aaf008e80c239813357ccf8790332e9 + "@inquirer/figures": ^1.0.6 + "@inquirer/type": ^2.0.0 + "@types/mute-stream": ^0.0.4 + "@types/node": ^22.5.5 + "@types/wrap-ansi": ^3.0.0 + ansi-escapes: ^4.3.2 + cli-width: ^4.1.0 + mute-stream: ^1.0.0 + signal-exit: ^4.1.0 + strip-ansi: ^6.0.1 + wrap-ansi: ^6.2.0 + yoctocolors-cjs: ^2.1.2 + checksum: 681339aac03b6998e7fee1c5a0a15951e9268b7be20fd7532f180b408893f9e7203020a57d40dc78352d281f19b66222df83c68f73a125f6e1beadfa0df3920c languageName: node linkType: hard -"@jest/core@npm:^29.4.1": - version: 29.4.1 - resolution: "@jest/core@npm:29.4.1" +"@inquirer/editor@npm:^2.2.0": + version: 2.2.0 + resolution: "@inquirer/editor@npm:2.2.0" dependencies: - "@jest/console": ^29.4.1 - "@jest/reporters": ^29.4.1 - "@jest/test-result": ^29.4.1 - "@jest/transform": ^29.4.1 - "@jest/types": ^29.4.1 - "@types/node": "*" - ansi-escapes: ^4.2.1 - chalk: ^4.0.0 - ci-info: ^3.2.0 - exit: ^0.1.2 - graceful-fs: ^4.2.9 - jest-changed-files: ^29.4.0 - jest-config: ^29.4.1 - jest-haste-map: ^29.4.1 - jest-message-util: ^29.4.1 - jest-regex-util: ^29.2.0 - jest-resolve: ^29.4.1 - jest-resolve-dependencies: ^29.4.1 - jest-runner: ^29.4.1 - jest-runtime: ^29.4.1 - jest-snapshot: ^29.4.1 - jest-util: ^29.4.1 - jest-validate: ^29.4.1 - jest-watcher: ^29.4.1 - micromatch: ^4.0.4 - pretty-format: ^29.4.1 - slash: ^3.0.0 - strip-ansi: ^6.0.0 - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - checksum: 70bf65187bdc14825512bbb5afda6f578cca62cda70d8fc2bf08377d916785cfa5da3f3b6aabda42e535c1353fc9a1073b8370f49b2d49ad8fca798119219c3e + "@inquirer/core": ^9.1.0 + "@inquirer/type": ^1.5.3 + external-editor: ^3.1.0 + checksum: 6f238050613b4db8d4d76eafe1a3531c211a016866826bf55f1187c89d29439e69ef9fc7a4f86b26f2a4a45260184bd8200056d25c79a540014abe66581c7b81 languageName: node linkType: hard -"@jest/create-cache-key-function@npm:^27.4.2": - version: 27.5.1 - resolution: "@jest/create-cache-key-function@npm:27.5.1" +"@inquirer/expand@npm:^2.3.0": + version: 2.3.0 + resolution: "@inquirer/expand@npm:2.3.0" dependencies: - "@jest/types": ^27.5.1 - checksum: a6c3a8c769aca6f66f5dc80f1c77e66980b4f213a6b2a15a92ba3595f032848a1261c06c9c798dcf2b672b1ffbefad5085af89d130548741c85ddbe0cf4284e7 + "@inquirer/core": ^9.1.0 + "@inquirer/type": ^1.5.3 + yoctocolors-cjs: ^2.1.2 + checksum: fdc9b2d0a509e9c0120fda8e1c044593b1f4b68038fd13e19fc35cc305f1e132fddd482bc1b44966cbcab06d579d130cabbb5cac50d917549d16d7e66fad4e74 + languageName: node + linkType: hard + +"@inquirer/figures@npm:^1.0.5, @inquirer/figures@npm:^1.0.6": + version: 1.0.6 + resolution: "@inquirer/figures@npm:1.0.6" + checksum: dd5d53834d1a2b214b98e28c6acf512fca208dc9ffccb1f54f15c87a90ac503aa544b64dd9c899f5bbc3d6f9f300bc7b659bb0d69b728007f9ca091e7c414f2d languageName: node linkType: hard -"@jest/environment@npm:^29.4.1": - version: 29.4.1 - resolution: "@jest/environment@npm:29.4.1" +"@inquirer/input@npm:^2.3.0": + version: 2.3.0 + resolution: "@inquirer/input@npm:2.3.0" dependencies: - "@jest/fake-timers": ^29.4.1 - "@jest/types": ^29.4.1 - "@types/node": "*" - jest-mock: ^29.4.1 - checksum: f6fed37d2e4aede2930f0a030432b72efeed6d3ea2eee165c1e64afd9fb3af8cf827e306c800cdb3f7bbd106bc5b2405cdec98b91a85695e3f62b1e228cb8d09 + "@inquirer/core": ^9.1.0 + "@inquirer/type": ^1.5.3 + checksum: 5c5833050eb231e81beac3b70999c6a7b66b59809b0e60889dd0df012084ed2b28235da8025391ff26f41f4e913d89ead82f4fd92e18a9bdde5f2465416080ae languageName: node linkType: hard -"@jest/expect-utils@npm:^29.4.1": - version: 29.4.1 - resolution: "@jest/expect-utils@npm:29.4.1" +"@inquirer/number@npm:^1.1.0": + version: 1.1.0 + resolution: "@inquirer/number@npm:1.1.0" dependencies: - jest-get-type: ^29.2.0 - checksum: 865b4ee79d43e2457efb8ce3f58108f2fe141ce620350fe21d0baaf7e2f00b9b67f6e9c1c89760b1008c100e844fb03a6dda264418ed378243956904d9a88c69 + "@inquirer/core": ^9.1.0 + "@inquirer/type": ^1.5.3 + checksum: 5f56fd32490b35f6fe53032db19bcad5f5000c3ed88e27e58f0d9dfe4f858808d7b9447b5a3a1d85216b2a4293f2d97c51624abf87d06ac26da45b50485b61db languageName: node linkType: hard -"@jest/expect@npm:^29.4.1": - version: 29.4.1 - resolution: "@jest/expect@npm:29.4.1" +"@inquirer/password@npm:^2.2.0": + version: 2.2.0 + resolution: "@inquirer/password@npm:2.2.0" dependencies: - expect: ^29.4.1 - jest-snapshot: ^29.4.1 - checksum: 5e9979822a83847f2671e6ed8482e1afc6553ea6579527fdcc6f31ac4f54975e74f1410b9ca133e80ad30dfc38510a9e731ffe70e9eecea61abad487095d969a + "@inquirer/core": ^9.1.0 + "@inquirer/type": ^1.5.3 + ansi-escapes: ^4.3.2 + checksum: 85a15957a667fcfcbfbd36b1acaf31d5c23473f229cb03ade37adfffa2016cfe75d81b0c59cf697e42bfe7dd2fa4f8e400b7eeafbda711fb2785456520a939f8 languageName: node linkType: hard -"@jest/fake-timers@npm:^29.4.1": - version: 29.4.1 - resolution: "@jest/fake-timers@npm:29.4.1" +"@inquirer/prompts@npm:^5.5.0": + version: 5.5.0 + resolution: "@inquirer/prompts@npm:5.5.0" dependencies: - "@jest/types": ^29.4.1 - "@sinonjs/fake-timers": ^10.0.2 - "@types/node": "*" - jest-message-util: ^29.4.1 - jest-mock: ^29.4.1 - jest-util: ^29.4.1 - checksum: 6e1f404054cae54291c1aba7e6b16d7895e2f14b2a1814a0133f9859d6bf49b8e91ce5b3ee15517013bcc6061b63e7a9aeebabd32a68f27a1a15a6dfb15644d1 + "@inquirer/checkbox": ^2.5.0 + "@inquirer/confirm": ^3.2.0 + "@inquirer/editor": ^2.2.0 + "@inquirer/expand": ^2.3.0 + "@inquirer/input": ^2.3.0 + "@inquirer/number": ^1.1.0 + "@inquirer/password": ^2.2.0 + "@inquirer/rawlist": ^2.3.0 + "@inquirer/search": ^1.1.0 + "@inquirer/select": ^2.5.0 + checksum: 647312c644284223483ec67fa476fee7bcc099793fb6773e44f325554c91f7db7a124dd81f0b5a9ad22b07c9e807c9f276b34ee4614c99921a9644b9e831d4e9 languageName: node linkType: hard -"@jest/globals@npm:^29.4.1": - version: 29.4.1 - resolution: "@jest/globals@npm:29.4.1" +"@inquirer/rawlist@npm:^2.3.0": + version: 2.3.0 + resolution: "@inquirer/rawlist@npm:2.3.0" dependencies: - "@jest/environment": ^29.4.1 - "@jest/expect": ^29.4.1 - "@jest/types": ^29.4.1 - jest-mock: ^29.4.1 - checksum: 492af8f7c1a97c88464951dfe30fdfcc1566138658df87ab4cdd3b0e20245022637ee4636270af35346391fc4dcd18130d21b643c7e317355087b7cece392476 + "@inquirer/core": ^9.1.0 + "@inquirer/type": ^1.5.3 + yoctocolors-cjs: ^2.1.2 + checksum: 48635c5f62527dde46209d168da53e364c33ea7f795c23d9a5ee7e0836159404adc4f68e7a743a0a9a9c4c90fc1f96668b6ff869c3232f1a3b585d3afcf0b702 languageName: node linkType: hard -"@jest/reporters@npm:^29.4.1": - version: 29.4.1 - resolution: "@jest/reporters@npm:29.4.1" +"@inquirer/search@npm:^1.1.0": + version: 1.1.0 + resolution: "@inquirer/search@npm:1.1.0" + dependencies: + "@inquirer/core": ^9.1.0 + "@inquirer/figures": ^1.0.5 + "@inquirer/type": ^1.5.3 + yoctocolors-cjs: ^2.1.2 + checksum: 1304adf79f181941c4bc41e7a400e68e3d9281819d523b0efb04f928f96ab0f28cdf800236c6847757a02a958ee3b0047d94079aba04a0aececfd9968f656c01 + languageName: node + linkType: hard + +"@inquirer/select@npm:^2.5.0": + version: 2.5.0 + resolution: "@inquirer/select@npm:2.5.0" + dependencies: + "@inquirer/core": ^9.1.0 + "@inquirer/figures": ^1.0.5 + "@inquirer/type": ^1.5.3 + ansi-escapes: ^4.3.2 + yoctocolors-cjs: ^2.1.2 + checksum: fc7aa1a70d69f61ad2270ebfb83c059ba8d6bc749a90ae759a538acfa0ae158621f9653625f3fa7ac81072674f19013898e16598ce71a3dd2476897304832598 + languageName: node + linkType: hard + +"@inquirer/type@npm:^1.5.3": + version: 1.5.5 + resolution: "@inquirer/type@npm:1.5.5" + dependencies: + mute-stream: ^1.0.0 + checksum: 6cada82bb14519f3c71f455b08dc03c1064046fe0469aa5fce44c7ebf88a3a3d67a0cf852b0a7339476fec3b02874167f46d2c5b0964218d00273ab27ff861c5 + languageName: node + linkType: hard + +"@inquirer/type@npm:^2.0.0": + version: 2.0.0 + resolution: "@inquirer/type@npm:2.0.0" + dependencies: + mute-stream: ^1.0.0 + checksum: 0f78f84c182ef3879109a651c7b4afdc7480bc5365948cbdad7e0aa5b9713ef052761b6914b8c76c3ffeef5a8f61ef1d6d44c6c3914800e17506ecb1a8e99844 + languageName: node + linkType: hard + +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: ^5.1.2 + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: ^7.0.1 + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: ^8.1.0 + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: 4a473b9b32a7d4d3cfb7a614226e555091ff0c5a29a1734c28c72a182c2f6699b26fc6b5c2131dfd841e86b185aea714c72201d7c98c2fba5f17709333a67aeb + languageName: node + linkType: hard + +"@istanbuljs/load-nyc-config@npm:^1.0.0, @istanbuljs/load-nyc-config@npm:^1.1.0": + version: 1.1.0 + resolution: "@istanbuljs/load-nyc-config@npm:1.1.0" + dependencies: + camelcase: ^5.3.1 + find-up: ^4.1.0 + get-package-type: ^0.1.0 + js-yaml: ^3.13.1 + resolve-from: ^5.0.0 + checksum: d578da5e2e804d5c93228450a1380e1a3c691de4953acc162f387b717258512a3e07b83510a936d9fab03eac90817473917e24f5d16297af3867f59328d58568 + languageName: node + linkType: hard + +"@istanbuljs/schema@npm:^0.1.2, @istanbuljs/schema@npm:^0.1.3": + version: 0.1.3 + resolution: "@istanbuljs/schema@npm:0.1.3" + checksum: 5282759d961d61350f33d9118d16bcaed914ebf8061a52f4fa474b2cb08720c9c81d165e13b82f2e5a8a212cc5af482f0c6fc1ac27b9e067e5394c9a6ed186c9 + languageName: node + linkType: hard + +"@jest/console@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/console@npm:29.7.0" + dependencies: + "@jest/types": ^29.6.3 + "@types/node": "*" + chalk: ^4.0.0 + jest-message-util: ^29.7.0 + jest-util: ^29.7.0 + slash: ^3.0.0 + checksum: 0e3624e32c5a8e7361e889db70b170876401b7d70f509a2538c31d5cd50deb0c1ae4b92dc63fe18a0902e0a48c590c21d53787a0df41a52b34fa7cab96c384d6 + languageName: node + linkType: hard + +"@jest/core@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/core@npm:29.7.0" + dependencies: + "@jest/console": ^29.7.0 + "@jest/reporters": ^29.7.0 + "@jest/test-result": ^29.7.0 + "@jest/transform": ^29.7.0 + "@jest/types": ^29.6.3 + "@types/node": "*" + ansi-escapes: ^4.2.1 + chalk: ^4.0.0 + ci-info: ^3.2.0 + exit: ^0.1.2 + graceful-fs: ^4.2.9 + jest-changed-files: ^29.7.0 + jest-config: ^29.7.0 + jest-haste-map: ^29.7.0 + jest-message-util: ^29.7.0 + jest-regex-util: ^29.6.3 + jest-resolve: ^29.7.0 + jest-resolve-dependencies: ^29.7.0 + jest-runner: ^29.7.0 + jest-runtime: ^29.7.0 + jest-snapshot: ^29.7.0 + jest-util: ^29.7.0 + jest-validate: ^29.7.0 + jest-watcher: ^29.7.0 + micromatch: ^4.0.4 + pretty-format: ^29.7.0 + slash: ^3.0.0 + strip-ansi: ^6.0.0 + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + checksum: af759c9781cfc914553320446ce4e47775ae42779e73621c438feb1e4231a5d4862f84b1d8565926f2d1aab29b3ec3dcfdc84db28608bdf5f29867124ebcfc0d + languageName: node + linkType: hard + +"@jest/create-cache-key-function@npm:^27.4.2": + version: 27.5.1 + resolution: "@jest/create-cache-key-function@npm:27.5.1" + dependencies: + "@jest/types": ^27.5.1 + checksum: a6c3a8c769aca6f66f5dc80f1c77e66980b4f213a6b2a15a92ba3595f032848a1261c06c9c798dcf2b672b1ffbefad5085af89d130548741c85ddbe0cf4284e7 + languageName: node + linkType: hard + +"@jest/environment@npm:^29.6.2": + version: 29.6.2 + resolution: "@jest/environment@npm:29.6.2" + dependencies: + "@jest/fake-timers": ^29.6.2 + "@jest/types": ^29.6.1 + "@types/node": "*" + jest-mock: ^29.6.2 + checksum: c7de0e4c0d9166e02d0eb166574e05ec460e1db3b69d6476e63244edd52d7c917e6876af55fe723ff3086f52c0b1869dec60654054735a7a48c9d4ac43af2a25 + languageName: node + linkType: hard + +"@jest/environment@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/environment@npm:29.7.0" + dependencies: + "@jest/fake-timers": ^29.7.0 + "@jest/types": ^29.6.3 + "@types/node": "*" + jest-mock: ^29.7.0 + checksum: 6fb398143b2543d4b9b8d1c6dbce83fa5247f84f550330604be744e24c2bd2178bb893657d62d1b97cf2f24baf85c450223f8237cccb71192c36a38ea2272934 + languageName: node + linkType: hard + +"@jest/expect-utils@npm:^29.6.2": + version: 29.6.2 + resolution: "@jest/expect-utils@npm:29.6.2" + dependencies: + jest-get-type: ^29.4.3 + checksum: 0decf2009aa3735f9df469e78ce1721c2815e4278439887e0cf0321ca8979541a22515d114a59b2445a6cd70a074b09dc9c00b5e7b3b3feac5174b9c4a78b2e1 + languageName: node + linkType: hard + +"@jest/expect-utils@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/expect-utils@npm:29.7.0" + dependencies: + jest-get-type: ^29.6.3 + checksum: 75eb177f3d00b6331bcaa057e07c0ccb0733a1d0a1943e1d8db346779039cb7f103789f16e502f888a3096fb58c2300c38d1f3748b36a7fa762eb6f6d1b160ed + languageName: node + linkType: hard + +"@jest/expect@npm:^29.6.2": + version: 29.6.2 + resolution: "@jest/expect@npm:29.6.2" + dependencies: + expect: ^29.6.2 + jest-snapshot: ^29.6.2 + checksum: bd2d88a4e7c5420079c239afef341ec53dc7e353816cd13acbb42631a31fd321fe58677bb43a4dba851028f4c7e31da7980314e9094cd5b348896cb6cd3d42b2 + languageName: node + linkType: hard + +"@jest/expect@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/expect@npm:29.7.0" + dependencies: + expect: ^29.7.0 + jest-snapshot: ^29.7.0 + checksum: a01cb85fd9401bab3370618f4b9013b90c93536562222d920e702a0b575d239d74cecfe98010aaec7ad464f67cf534a353d92d181646a4b792acaa7e912ae55e + languageName: node + linkType: hard + +"@jest/fake-timers@npm:^29.6.2": + version: 29.6.2 + resolution: "@jest/fake-timers@npm:29.6.2" + dependencies: + "@jest/types": ^29.6.1 + "@sinonjs/fake-timers": ^10.0.2 + "@types/node": "*" + jest-message-util: ^29.6.2 + jest-mock: ^29.6.2 + jest-util: ^29.6.2 + checksum: 1abcda02f22d2ba32e178b7ab80a9180235a6c75ec9faef33324627b19a70dad64889a9ea49b8f07230e14a6e683b9120542c6d1d6b2ecaf937f4efde32dad88 + languageName: node + linkType: hard + +"@jest/fake-timers@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/fake-timers@npm:29.7.0" + dependencies: + "@jest/types": ^29.6.3 + "@sinonjs/fake-timers": ^10.0.2 + "@types/node": "*" + jest-message-util: ^29.7.0 + jest-mock: ^29.7.0 + jest-util: ^29.7.0 + checksum: caf2bbd11f71c9241b458d1b5a66cbe95debc5a15d96442444b5d5c7ba774f523c76627c6931cca5e10e76f0d08761f6f1f01a608898f4751a0eee54fc3d8d00 + languageName: node + linkType: hard + +"@jest/globals@npm:^29.6.2": + version: 29.6.2 + resolution: "@jest/globals@npm:29.6.2" + dependencies: + "@jest/environment": ^29.6.2 + "@jest/expect": ^29.6.2 + "@jest/types": ^29.6.1 + jest-mock: ^29.6.2 + checksum: aa4a54f19cc025205bc696546940e1fe9c752c2d4d825852088aa76d44677ebba1ec66fabb78e615480cff23a06a70b5a3f893ab5163d901cdfa0d2267870b10 + languageName: node + linkType: hard + +"@jest/globals@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/globals@npm:29.7.0" + dependencies: + "@jest/environment": ^29.7.0 + "@jest/expect": ^29.7.0 + "@jest/types": ^29.6.3 + jest-mock: ^29.7.0 + checksum: 97dbb9459135693ad3a422e65ca1c250f03d82b2a77f6207e7fa0edd2c9d2015fbe4346f3dc9ebff1678b9d8da74754d4d440b7837497f8927059c0642a22123 + languageName: node + linkType: hard + +"@jest/reporters@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/reporters@npm:29.7.0" dependencies: "@bcoe/v8-coverage": ^0.2.3 - "@jest/console": ^29.4.1 - "@jest/test-result": ^29.4.1 - "@jest/transform": ^29.4.1 - "@jest/types": ^29.4.1 - "@jridgewell/trace-mapping": ^0.3.15 + "@jest/console": ^29.7.0 + "@jest/test-result": ^29.7.0 + "@jest/transform": ^29.7.0 + "@jest/types": ^29.6.3 + "@jridgewell/trace-mapping": ^0.3.18 "@types/node": "*" chalk: ^4.0.0 collect-v8-coverage: ^1.0.0 @@ -986,13 +1536,13 @@ __metadata: glob: ^7.1.3 graceful-fs: ^4.2.9 istanbul-lib-coverage: ^3.0.0 - istanbul-lib-instrument: ^5.1.0 + istanbul-lib-instrument: ^6.0.0 istanbul-lib-report: ^3.0.0 istanbul-lib-source-maps: ^4.0.0 istanbul-reports: ^3.1.3 - jest-message-util: ^29.4.1 - jest-util: ^29.4.1 - jest-worker: ^29.4.1 + jest-message-util: ^29.7.0 + jest-util: ^29.7.0 + jest-worker: ^29.7.0 slash: ^3.0.0 string-length: ^4.0.1 strip-ansi: ^6.0.0 @@ -1002,74 +1552,106 @@ __metadata: peerDependenciesMeta: node-notifier: optional: true - checksum: fb70886e90eeb45e1df7c4196e1768285d5f1db4c01edd6eeed33619971d8c33031a9a3705004f14dff9c3460f5d605a9dac9779c5a91c73e4f7a4b303ff25ff + checksum: 7eadabd62cc344f629024b8a268ecc8367dba756152b761bdcb7b7e570a3864fc51b2a9810cd310d85e0a0173ef002ba4528d5ea0329fbf66ee2a3ada9c40455 + languageName: node + linkType: hard + +"@jest/schemas@npm:^29.6.0": + version: 29.6.0 + resolution: "@jest/schemas@npm:29.6.0" + dependencies: + "@sinclair/typebox": ^0.27.8 + checksum: c00511c69cf89138a7d974404d3a5060af375b5a52b9c87215d91873129b382ca11c1ff25bd6d605951404bb381ddce5f8091004a61e76457da35db1f5c51365 languageName: node linkType: hard -"@jest/schemas@npm:^29.4.0": - version: 29.4.0 - resolution: "@jest/schemas@npm:29.4.0" +"@jest/schemas@npm:^29.6.3": + version: 29.6.3 + resolution: "@jest/schemas@npm:29.6.3" dependencies: - "@sinclair/typebox": ^0.25.16 - checksum: 005c90b7b641af029133fa390c0c8a75b63edf651da6253d7c472a8f15ddd18aa139edcd4236e57f974006e39c67217925768115484dbd7bfed2eba224de8b7d + "@sinclair/typebox": ^0.27.8 + checksum: 910040425f0fc93cd13e68c750b7885590b8839066dfa0cd78e7def07bbb708ad869381f725945d66f2284de5663bbecf63e8fdd856e2ae6e261ba30b1687e93 languageName: node linkType: hard -"@jest/source-map@npm:^29.2.0": - version: 29.2.0 - resolution: "@jest/source-map@npm:29.2.0" +"@jest/source-map@npm:^29.6.3": + version: 29.6.3 + resolution: "@jest/source-map@npm:29.6.3" dependencies: - "@jridgewell/trace-mapping": ^0.3.15 + "@jridgewell/trace-mapping": ^0.3.18 callsites: ^3.0.0 graceful-fs: ^4.2.9 - checksum: 09f76ab63d15dcf44b3035a79412164f43be34ec189575930f1a00c87e36ea0211ebd6a4fbe2253c2516e19b49b131f348ddbb86223ca7b6bbac9a6bc76ec96e + checksum: bcc5a8697d471396c0003b0bfa09722c3cd879ad697eb9c431e6164e2ea7008238a01a07193dfe3cbb48b1d258eb7251f6efcea36f64e1ebc464ea3c03ae2deb languageName: node linkType: hard -"@jest/test-result@npm:^29.4.1": - version: 29.4.1 - resolution: "@jest/test-result@npm:29.4.1" +"@jest/test-result@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/test-result@npm:29.7.0" dependencies: - "@jest/console": ^29.4.1 - "@jest/types": ^29.4.1 + "@jest/console": ^29.7.0 + "@jest/types": ^29.6.3 "@types/istanbul-lib-coverage": ^2.0.0 collect-v8-coverage: ^1.0.0 - checksum: 8909e5033bf52b85840da8bbc7ded98d52a86f63f2708d6c976f204e007739ada8fc2f985394a8950e40b1e17508bd8e26db4fa328a5fb37c411fe534bb192ec + checksum: 67b6317d526e335212e5da0e768e3b8ab8a53df110361b80761353ad23b6aea4432b7c5665bdeb87658ea373b90fb1afe02ed3611ef6c858c7fba377505057fa + languageName: node + linkType: hard + +"@jest/test-sequencer@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/test-sequencer@npm:29.7.0" + dependencies: + "@jest/test-result": ^29.7.0 + graceful-fs: ^4.2.9 + jest-haste-map: ^29.7.0 + slash: ^3.0.0 + checksum: 73f43599017946be85c0b6357993b038f875b796e2f0950487a82f4ebcb115fa12131932dd9904026b4ad8be131fe6e28bd8d0aa93b1563705185f9804bff8bd languageName: node linkType: hard -"@jest/test-sequencer@npm:^29.4.1": - version: 29.4.1 - resolution: "@jest/test-sequencer@npm:29.4.1" +"@jest/transform@npm:^29.6.2": + version: 29.6.2 + resolution: "@jest/transform@npm:29.6.2" dependencies: - "@jest/test-result": ^29.4.1 + "@babel/core": ^7.11.6 + "@jest/types": ^29.6.1 + "@jridgewell/trace-mapping": ^0.3.18 + babel-plugin-istanbul: ^6.1.1 + chalk: ^4.0.0 + convert-source-map: ^2.0.0 + fast-json-stable-stringify: ^2.1.0 graceful-fs: ^4.2.9 - jest-haste-map: ^29.4.1 + jest-haste-map: ^29.6.2 + jest-regex-util: ^29.4.3 + jest-util: ^29.6.2 + micromatch: ^4.0.4 + pirates: ^4.0.4 slash: ^3.0.0 - checksum: ddf26b780579b239076d5eaf445ff17b8cf1d363c2cfdd3842f281c597d2ef1ee42e93f3cd2ac52803a88de0107a6059d72007ecc51bcd535406c17941ef33be + write-file-atomic: ^4.0.2 + checksum: ffb8c3c344cd48bedadec295d9c436737eccc39c1f0868aa9753b76397b33b2e5b121058af6f287ba6f2036181137e37df1212334bfa9d9a712986a4518cdc18 languageName: node linkType: hard -"@jest/transform@npm:^29.4.1": - version: 29.4.1 - resolution: "@jest/transform@npm:29.4.1" +"@jest/transform@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/transform@npm:29.7.0" dependencies: "@babel/core": ^7.11.6 - "@jest/types": ^29.4.1 - "@jridgewell/trace-mapping": ^0.3.15 + "@jest/types": ^29.6.3 + "@jridgewell/trace-mapping": ^0.3.18 babel-plugin-istanbul: ^6.1.1 chalk: ^4.0.0 convert-source-map: ^2.0.0 fast-json-stable-stringify: ^2.1.0 graceful-fs: ^4.2.9 - jest-haste-map: ^29.4.1 - jest-regex-util: ^29.2.0 - jest-util: ^29.4.1 + jest-haste-map: ^29.7.0 + jest-regex-util: ^29.6.3 + jest-util: ^29.7.0 micromatch: ^4.0.4 pirates: ^4.0.4 slash: ^3.0.0 - write-file-atomic: ^5.0.0 - checksum: ae8aa3ec32d869fbaa45f9513455ae96447de829effc3855d720ff12218f7d5b1b4e782cccf1ad38a9e85d6a762c53148259065075200844c997fe6a6252604e + write-file-atomic: ^4.0.2 + checksum: 0f8ac9f413903b3cb6d240102db848f2a354f63971ab885833799a9964999dd51c388162106a807f810071f864302cdd8e3f0c241c29ce02d85a36f18f3f40ab languageName: node linkType: hard @@ -1086,17 +1668,31 @@ __metadata: languageName: node linkType: hard -"@jest/types@npm:^29.4.1": - version: 29.4.1 - resolution: "@jest/types@npm:29.4.1" +"@jest/types@npm:^29.6.1": + version: 29.6.1 + resolution: "@jest/types@npm:29.6.1" + dependencies: + "@jest/schemas": ^29.6.0 + "@types/istanbul-lib-coverage": ^2.0.0 + "@types/istanbul-reports": ^3.0.0 + "@types/node": "*" + "@types/yargs": ^17.0.8 + chalk: ^4.0.0 + checksum: 89fc1ccf71a84fe0da643e0675b1cfe6a6f19ea72e935b2ab1dbdb56ec547e94433fb59b3536d3832a6e156c077865b7176fe9dae707dab9c3d2f9405ba6233c + languageName: node + linkType: hard + +"@jest/types@npm:^29.6.3": + version: 29.6.3 + resolution: "@jest/types@npm:29.6.3" dependencies: - "@jest/schemas": ^29.4.0 + "@jest/schemas": ^29.6.3 "@types/istanbul-lib-coverage": ^2.0.0 "@types/istanbul-reports": ^3.0.0 "@types/node": "*" "@types/yargs": ^17.0.8 chalk: ^4.0.0 - checksum: 0aa0b6a210b3474289e5dcaa8e7abb2238dba8d0baf2eb5a3f080fb95e9a39e71e8abc96811d4ef7011f5d993755bb54515e9d827d7ebc2a2d4d9579d84f5a04 + checksum: a0bcf15dbb0eca6bdd8ce61a3fb055349d40268622a7670a3b2eb3c3dbafe9eb26af59938366d520b86907b9505b0f9b29b85cec11579a9e580694b87cd90fcc languageName: node linkType: hard @@ -1121,6 +1717,17 @@ __metadata: languageName: node linkType: hard +"@jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.5 + resolution: "@jridgewell/gen-mapping@npm:0.3.5" + dependencies: + "@jridgewell/set-array": ^1.2.1 + "@jridgewell/sourcemap-codec": ^1.4.10 + "@jridgewell/trace-mapping": ^0.3.24 + checksum: ff7a1764ebd76a5e129c8890aa3e2f46045109dabde62b0b6c6a250152227647178ff2069ea234753a690d8f3c4ac8b5e7b267bbee272bffb7f3b0a370ab6e52 + languageName: node + linkType: hard + "@jridgewell/resolve-uri@npm:3.1.0": version: 3.1.0 resolution: "@jridgewell/resolve-uri@npm:3.1.0" @@ -1128,6 +1735,13 @@ __metadata: languageName: node linkType: hard +"@jridgewell/resolve-uri@npm:^3.1.0": + version: 3.1.1 + resolution: "@jridgewell/resolve-uri@npm:3.1.1" + checksum: f5b441fe7900eab4f9155b3b93f9800a916257f4e8563afbcd3b5a5337b55e52bd8ae6735453b1b745457d9f6cdb16d74cd6220bbdd98cf153239e13f6cbb653 + languageName: node + linkType: hard + "@jridgewell/set-array@npm:^1.0.0, @jridgewell/set-array@npm:^1.0.1": version: 1.1.2 resolution: "@jridgewell/set-array@npm:1.1.2" @@ -1135,14 +1749,35 @@ __metadata: languageName: node linkType: hard -"@jridgewell/sourcemap-codec@npm:1.4.14, @jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.13": +"@jridgewell/set-array@npm:^1.2.1": + version: 1.2.1 + resolution: "@jridgewell/set-array@npm:1.2.1" + checksum: 832e513a85a588f8ed4f27d1279420d8547743cc37fcad5a5a76fc74bb895b013dfe614d0eed9cb860048e6546b798f8f2652020b4b2ba0561b05caa8c654b10 + languageName: node + linkType: hard + +"@jridgewell/sourcemap-codec@npm:1.4.14, @jridgewell/sourcemap-codec@npm:^1.4.10": version: 1.4.14 resolution: "@jridgewell/sourcemap-codec@npm:1.4.14" checksum: 61100637b6d173d3ba786a5dff019e1a74b1f394f323c1fee337ff390239f053b87266c7a948777f4b1ee68c01a8ad0ab61e5ff4abb5a012a0b091bec391ab97 languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.15, @jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.9": +"@jridgewell/sourcemap-codec@npm:^1.4.14": + version: 1.4.15 + resolution: "@jridgewell/sourcemap-codec@npm:1.4.15" + checksum: b881c7e503db3fc7f3c1f35a1dd2655a188cc51a3612d76efc8a6eb74728bef5606e6758ee77423e564092b4a518aba569bbb21c9bac5ab7a35b0c6ae7e344c8 + languageName: node + linkType: hard + +"@jridgewell/sourcemap-codec@npm:^1.5.0": + version: 1.5.0 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.0" + checksum: 05df4f2538b3b0f998ea4c1cd34574d0feba216fa5d4ccaef0187d12abf82eafe6021cec8b49f9bb4d90f2ba4582ccc581e72986a5fcf4176ae0cfeb04cf52ec + languageName: node + linkType: hard + +"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.9": version: 0.3.17 resolution: "@jridgewell/trace-mapping@npm:0.3.17" dependencies: @@ -1152,6 +1787,33 @@ __metadata: languageName: node linkType: hard +"@jridgewell/trace-mapping@npm:^0.3.18": + version: 0.3.19 + resolution: "@jridgewell/trace-mapping@npm:0.3.19" + dependencies: + "@jridgewell/resolve-uri": ^3.1.0 + "@jridgewell/sourcemap-codec": ^1.4.14 + checksum: 956a6f0f6fec060fb48c6bf1f5ec2064e13cd38c8be3873877d4b92b4a27ba58289a34071752671262a3e3c202abcc3fa2aac64d8447b4b0fa1ba3c9047f1c20 + languageName: node + linkType: hard + +"@jridgewell/trace-mapping@npm:^0.3.23, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": + version: 0.3.25 + resolution: "@jridgewell/trace-mapping@npm:0.3.25" + dependencies: + "@jridgewell/resolve-uri": ^3.1.0 + "@jridgewell/sourcemap-codec": ^1.4.14 + checksum: 9d3c40d225e139987b50c48988f8717a54a8c994d8a948ee42e1412e08988761d0754d7d10b803061cc3aebf35f92a5dbbab493bd0e1a9ef9e89a2130e83ba34 + languageName: node + linkType: hard + +"@jspm/core@npm:^2.0.1": + version: 2.0.1 + resolution: "@jspm/core@npm:2.0.1" + checksum: 611f37cadd8a76662309e89afb68bf5936d0fed16aacc8886fef0f0af94a9f7e1241ce6c619b650fa1064631374f6fcadad99be04c9cf504a47f5361746b8d7f + languageName: node + linkType: hard + "@mole-inc/bin-wrapper@npm:^8.0.1": version: 8.0.1 resolution: "@mole-inc/bin-wrapper@npm:8.0.1" @@ -1215,23 +1877,77 @@ __metadata: languageName: node linkType: hard +"@nuxt/kit@npm:^3.12.4": + version: 3.13.2 + resolution: "@nuxt/kit@npm:3.13.2" + dependencies: + "@nuxt/schema": 3.13.2 + c12: ^1.11.2 + consola: ^3.2.3 + defu: ^6.1.4 + destr: ^2.0.3 + globby: ^14.0.2 + hash-sum: ^2.0.0 + ignore: ^5.3.2 + jiti: ^1.21.6 + klona: ^2.0.6 + knitwork: ^1.1.0 + mlly: ^1.7.1 + pathe: ^1.1.2 + pkg-types: ^1.2.0 + scule: ^1.3.0 + semver: ^7.6.3 + ufo: ^1.5.4 + unctx: ^2.3.1 + unimport: ^3.12.0 + untyped: ^1.4.2 + checksum: c81a943e1e1aaec5852a098438147eaf61acc485bdb5061ec12d7b60907ff700bbea9df975417e4543054f50f834fc075f52d3a9d6cc42f739590c28860f4a8c + languageName: node + linkType: hard + +"@nuxt/schema@npm:3.13.2": + version: 3.13.2 + resolution: "@nuxt/schema@npm:3.13.2" + dependencies: + compatx: ^0.1.8 + consola: ^3.2.3 + defu: ^6.1.4 + hookable: ^5.5.3 + pathe: ^1.1.2 + pkg-types: ^1.2.0 + scule: ^1.3.0 + std-env: ^3.7.0 + ufo: ^1.5.4 + uncrypto: ^0.1.3 + unimport: ^3.12.0 + untyped: ^1.4.2 + checksum: 3d2e61a7125d714ce6efc27c3dedc20aa4ebe5ec6a18e62fb03fde1e38d9676f24e6dcc64cf98f111908eb14f1a8f299d707569dab5e998b0ce7cae8ca6e9257 + languageName: node + linkType: hard + "@nytimes/react-prosemirror@workspace:.": version: 0.0.0-use.local resolution: "@nytimes/react-prosemirror@workspace:." dependencies: + "@jest/globals": ^29.6.2 "@swc/cli": ^0.1.61 "@swc/core": ^1.3.32 "@swc/jest": ^0.2.24 - "@testing-library/dom": ^9.0.0 - "@testing-library/react": ^13.4.0 + "@testing-library/dom": ^10.4.0 + "@testing-library/react": ^16.0.1 "@testing-library/user-event": ^14.4.3 "@types/jest": ^27.0.0 "@types/react": ^18.0.0 "@types/react-dom": ^18.0.0 "@typescript-eslint/eslint-plugin": ^5.51.0 "@typescript-eslint/parser": ^5.51.0 - "@vitejs/plugin-react": ^3.1.0 + "@vitejs/plugin-react": ^4.3.1 + "@wdio/browser-runner": ^9.0.9 + "@wdio/cli": ^9.0.9 + "@wdio/mocha-framework": ^9.0.8 + "@wdio/types": ^9.0.8 "@yarnpkg/sdks": ^3.0.0-rc.38 + classnames: ^2.3.2 concurrently: ^7.6.0 eslint: ^8.33.0 eslint-config-prettier: ^8.6.0 @@ -1240,31 +1956,56 @@ __metadata: eslint-plugin-jest: ^27.2.1 eslint-plugin-react: ^7.32.2 eslint-plugin-react-hooks: ^4.6.0 + expect: ^29.7.0 husky: ^8.0.3 - jest: ^29.0.0 - jest-environment-jsdom: ^29.4.1 + jest: ^29.7.0 + jest-environment-jsdom: ^29.7.0 lint-staged: ^13.1.0 markdown-toc: ^1.2.0 prettier: ^2.8.3 prosemirror-commands: ^1.5.0 + prosemirror-gapcursor: ^1.3.2 + prosemirror-inputrules: ^1.4.0 prosemirror-keymap: ^1.2.1 - prosemirror-model: ^1.18.3 + prosemirror-model: ^1.22.3 prosemirror-schema-list: ^1.2.2 - prosemirror-state: ^1.4.2 - prosemirror-view: ^1.29.1 + prosemirror-state: ^1.4.3 + prosemirror-tables: ^1.3.7 + prosemirror-test-builder: ^1.1.1 + prosemirror-transform: ^1.8.0 + prosemirror-view: ^1.34.2 react: ^18.2.0 react-dom: ^18.2.0 rimraf: ^3.0.2 + tsx: ^4.19.1 typescript: ^4.9.5 - vite: ^4.1.5 + vite: ^5.4.5 + webdriverio: ^9.0.9 peerDependencies: + prosemirror-model: ^1.0.0 prosemirror-state: ^1.0.0 - prosemirror-view: ^1.0.0 + prosemirror-view: 1.34.2 react: ">=17" react-dom: ">=17" languageName: unknown linkType: soft +"@originjs/vite-plugin-commonjs@npm:^1.0.3": + version: 1.0.3 + resolution: "@originjs/vite-plugin-commonjs@npm:1.0.3" + dependencies: + esbuild: ^0.14.14 + checksum: e4cd22a73e2be726fc78f794942333b8c6ede20c7b57edebe3d7bf52119532ef3206142f36498fbb22fb34fc706d30cd5efb10d1d84bf8d11be09ed7b90b8aaf + languageName: node + linkType: hard + +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 6ad6a00fc4f2f2cfc6bff76fb1d88b8ee20bc0601e18ebb01b6d4be583733a860239a521a7fbca73b612e66705078809483549d2b18f370eb346c5155c8e4a0f + languageName: node + linkType: hard + "@pkgr/utils@npm:^2.3.1": version: 2.3.1 resolution: "@pkgr/utils@npm:2.3.1" @@ -1279,10 +2020,184 @@ __metadata: languageName: node linkType: hard -"@sinclair/typebox@npm:^0.25.16": - version: 0.25.21 - resolution: "@sinclair/typebox@npm:0.25.21" - checksum: 763af1163fe4eabee9b914d4e4548a39fbba3287d2b3b1ff043c1da3c5a321e99d50a3ca94eb182988131e00b006a6f019799cde8da2f61e2f118b30b0276a00 +"@promptbook/utils@npm:0.70.0-1": + version: 0.70.0-1 + resolution: "@promptbook/utils@npm:0.70.0-1" + dependencies: + spacetrim: 0.11.39 + checksum: 837f302bc570445449137c57d4580a544c21acab44fb191902ad50bf6aaec29ef8327e9054803379177c539e7cbce1488bd7213da2f8e50a714ab62546e93175 + languageName: node + linkType: hard + +"@puppeteer/browsers@npm:^2.2.0": + version: 2.4.0 + resolution: "@puppeteer/browsers@npm:2.4.0" + dependencies: + debug: ^4.3.6 + extract-zip: ^2.0.1 + progress: ^2.0.3 + proxy-agent: ^6.4.0 + semver: ^7.6.3 + tar-fs: ^3.0.6 + unbzip2-stream: ^1.4.3 + yargs: ^17.7.2 + bin: + browsers: lib/cjs/main-cli.js + checksum: c5f9890f1bf355783574c00b42e8a9bf9e4788d0dce76cc4cd50fcf80b5e5f99ae2b4325edd5350d4fb289f7dfa89f67edf8bc2da9abd53eba1f815caae97beb + languageName: node + linkType: hard + +"@rollup/plugin-virtual@npm:^3.0.2": + version: 3.0.2 + resolution: "@rollup/plugin-virtual@npm:3.0.2" + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + checksum: 962bc9efece57a07c328a3d093bd1a62b9b4396a88640ac79cfc04181e06b31c4b37726ca27ded71178ace27db9b0085b43c4de823378773bb44cb233ea1340e + languageName: node + linkType: hard + +"@rollup/pluginutils@npm:^5.0.2, @rollup/pluginutils@npm:^5.1.0": + version: 5.1.0 + resolution: "@rollup/pluginutils@npm:5.1.0" + dependencies: + "@types/estree": ^1.0.0 + estree-walker: ^2.0.2 + picomatch: ^2.3.1 + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + checksum: 3cc5a6d91452a6eabbfd1ae79b4dd1f1e809d2eecda6e175deb784e75b0911f47e9ecce73f8dd315d6a8b3f362582c91d3c0f66908b6ced69345b3cbe28f8ce8 + languageName: node + linkType: hard + +"@rollup/rollup-android-arm-eabi@npm:4.21.3": + version: 4.21.3 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.21.3" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@rollup/rollup-android-arm64@npm:4.21.3": + version: 4.21.3 + resolution: "@rollup/rollup-android-arm64@npm:4.21.3" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-arm64@npm:4.21.3": + version: 4.21.3 + resolution: "@rollup/rollup-darwin-arm64@npm:4.21.3" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-x64@npm:4.21.3": + version: 4.21.3 + resolution: "@rollup/rollup-darwin-x64@npm:4.21.3" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-gnueabihf@npm:4.21.3": + version: 4.21.3 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.21.3" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-musleabihf@npm:4.21.3": + version: 4.21.3 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.21.3" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-gnu@npm:4.21.3": + version: 4.21.3 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.21.3" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-musl@npm:4.21.3": + version: 4.21.3 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.21.3" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.21.3": + version: 4.21.3 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.21.3" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-gnu@npm:4.21.3": + version: 4.21.3 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.21.3" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-s390x-gnu@npm:4.21.3": + version: 4.21.3 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.21.3" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-gnu@npm:4.21.3": + version: 4.21.3 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.21.3" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-musl@npm:4.21.3": + version: 4.21.3 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.21.3" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-win32-arm64-msvc@npm:4.21.3": + version: 4.21.3 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.21.3" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-ia32-msvc@npm:4.21.3": + version: 4.21.3 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.21.3" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@rollup/rollup-win32-x64-msvc@npm:4.21.3": + version: 4.21.3 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.21.3" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@sec-ant/readable-stream@npm:^0.4.1": + version: 0.4.1 + resolution: "@sec-ant/readable-stream@npm:0.4.1" + checksum: eb56f72a70995f725269f1c1c206d6dbeb090e88413b1302a456c600041175a7a484c2f0172454f7bed65a8ab95ffed7647d8ad03e6c23b1e3bbc9845f78cd17 + languageName: node + linkType: hard + +"@sinclair/typebox@npm:^0.27.8": + version: 0.27.8 + resolution: "@sinclair/typebox@npm:0.27.8" + checksum: 00bd7362a3439021aa1ea51b0e0d0a0e8ca1351a3d54c606b115fdcc49b51b16db6e5f43b4fe7a28c38688523e22a94d49dd31168868b655f0d4d50f032d07a1 languageName: node linkType: hard @@ -1293,6 +2208,20 @@ __metadata: languageName: node linkType: hard +"@sindresorhus/merge-streams@npm:^2.1.0": + version: 2.3.0 + resolution: "@sindresorhus/merge-streams@npm:2.3.0" + checksum: e989d53dee68d7e49b4ac02ae49178d561c461144cea83f66fa91ff012d981ad0ad2340cbd13f2fdb57989197f5c987ca22a74eb56478626f04e79df84291159 + languageName: node + linkType: hard + +"@sindresorhus/merge-streams@npm:^4.0.0": + version: 4.0.0 + resolution: "@sindresorhus/merge-streams@npm:4.0.0" + checksum: 5759d31dfd822999bbe3ddcf72d4b15dc3d99ea51dd5b3210888f3348234eaff0f44bc999bef6b3c328daeb34e862a63b2c4abe5590acec541f93bc6fa016c9d + languageName: node + linkType: hard + "@sinonjs/commons@npm:^2.0.0": version: 2.0.0 resolution: "@sinonjs/commons@npm:2.0.0" @@ -1311,6 +2240,15 @@ __metadata: languageName: node linkType: hard +"@stencil/core@npm:^4.20.0": + version: 4.21.0 + resolution: "@stencil/core@npm:4.21.0" + bin: + stencil: bin/stencil + checksum: 7f69f4ccfd473b2032569763b70d1e56e7d330cb7b81ff48194e93436de8b4d4f767560e39630aa717f8484071139dcddf8c9f8bbd33be06239f66207d43aa57 + languageName: node + linkType: hard + "@swc/cli@npm:^0.1.61": version: 0.1.61 resolution: "@swc/cli@npm:0.1.61" @@ -1342,6 +2280,13 @@ __metadata: languageName: node linkType: hard +"@swc/core-darwin-arm64@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-darwin-arm64@npm:1.7.26" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@swc/core-darwin-x64@npm:1.3.32": version: 1.3.32 resolution: "@swc/core-darwin-x64@npm:1.3.32" @@ -1349,6 +2294,13 @@ __metadata: languageName: node linkType: hard +"@swc/core-darwin-x64@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-darwin-x64@npm:1.7.26" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@swc/core-linux-arm-gnueabihf@npm:1.3.32": version: 1.3.32 resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.32" @@ -1356,6 +2308,13 @@ __metadata: languageName: node linkType: hard +"@swc/core-linux-arm-gnueabihf@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.7.26" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@swc/core-linux-arm64-gnu@npm:1.3.32": version: 1.3.32 resolution: "@swc/core-linux-arm64-gnu@npm:1.3.32" @@ -1363,6 +2322,13 @@ __metadata: languageName: node linkType: hard +"@swc/core-linux-arm64-gnu@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-linux-arm64-gnu@npm:1.7.26" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + "@swc/core-linux-arm64-musl@npm:1.3.32": version: 1.3.32 resolution: "@swc/core-linux-arm64-musl@npm:1.3.32" @@ -1370,6 +2336,13 @@ __metadata: languageName: node linkType: hard +"@swc/core-linux-arm64-musl@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-linux-arm64-musl@npm:1.7.26" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + "@swc/core-linux-x64-gnu@npm:1.3.32": version: 1.3.32 resolution: "@swc/core-linux-x64-gnu@npm:1.3.32" @@ -1377,6 +2350,13 @@ __metadata: languageName: node linkType: hard +"@swc/core-linux-x64-gnu@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-linux-x64-gnu@npm:1.7.26" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + "@swc/core-linux-x64-musl@npm:1.3.32": version: 1.3.32 resolution: "@swc/core-linux-x64-musl@npm:1.3.32" @@ -1384,6 +2364,13 @@ __metadata: languageName: node linkType: hard +"@swc/core-linux-x64-musl@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-linux-x64-musl@npm:1.7.26" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + "@swc/core-win32-arm64-msvc@npm:1.3.32": version: 1.3.32 resolution: "@swc/core-win32-arm64-msvc@npm:1.3.32" @@ -1391,6 +2378,13 @@ __metadata: languageName: node linkType: hard +"@swc/core-win32-arm64-msvc@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-win32-arm64-msvc@npm:1.7.26" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@swc/core-win32-ia32-msvc@npm:1.3.32": version: 1.3.32 resolution: "@swc/core-win32-ia32-msvc@npm:1.3.32" @@ -1398,6 +2392,13 @@ __metadata: languageName: node linkType: hard +"@swc/core-win32-ia32-msvc@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-win32-ia32-msvc@npm:1.7.26" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@swc/core-win32-x64-msvc@npm:1.3.32": version: 1.3.32 resolution: "@swc/core-win32-x64-msvc@npm:1.3.32" @@ -1405,6 +2406,13 @@ __metadata: languageName: node linkType: hard +"@swc/core-win32-x64-msvc@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-win32-x64-msvc@npm:1.7.26" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@swc/core@npm:^1.3.32": version: 1.3.32 resolution: "@swc/core@npm:1.3.32" @@ -1444,6 +2452,59 @@ __metadata: languageName: node linkType: hard +"@swc/core@npm:^1.7.0": + version: 1.7.26 + resolution: "@swc/core@npm:1.7.26" + dependencies: + "@swc/core-darwin-arm64": 1.7.26 + "@swc/core-darwin-x64": 1.7.26 + "@swc/core-linux-arm-gnueabihf": 1.7.26 + "@swc/core-linux-arm64-gnu": 1.7.26 + "@swc/core-linux-arm64-musl": 1.7.26 + "@swc/core-linux-x64-gnu": 1.7.26 + "@swc/core-linux-x64-musl": 1.7.26 + "@swc/core-win32-arm64-msvc": 1.7.26 + "@swc/core-win32-ia32-msvc": 1.7.26 + "@swc/core-win32-x64-msvc": 1.7.26 + "@swc/counter": ^0.1.3 + "@swc/types": ^0.1.12 + peerDependencies: + "@swc/helpers": "*" + dependenciesMeta: + "@swc/core-darwin-arm64": + optional: true + "@swc/core-darwin-x64": + optional: true + "@swc/core-linux-arm-gnueabihf": + optional: true + "@swc/core-linux-arm64-gnu": + optional: true + "@swc/core-linux-arm64-musl": + optional: true + "@swc/core-linux-x64-gnu": + optional: true + "@swc/core-linux-x64-musl": + optional: true + "@swc/core-win32-arm64-msvc": + optional: true + "@swc/core-win32-ia32-msvc": + optional: true + "@swc/core-win32-x64-msvc": + optional: true + peerDependenciesMeta: + "@swc/helpers": + optional: true + checksum: 8249f2af001f2b5b312ccace4e3a8575bf286bb0f67f029eb58ef8b144f73e37f766800859161ef87c0993e586055238c000ab17dddf9d3760edcfa63ffd22e6 + languageName: node + linkType: hard + +"@swc/counter@npm:^0.1.3": + version: 0.1.3 + resolution: "@swc/counter@npm:0.1.3" + checksum: df8f9cfba9904d3d60f511664c70d23bb323b3a0803ec9890f60133954173047ba9bdeabce28cd70ba89ccd3fd6c71c7b0bd58be85f611e1ffbe5d5c18616598 + languageName: node + linkType: hard + "@swc/jest@npm:^0.2.24": version: 0.2.24 resolution: "@swc/jest@npm:0.2.24" @@ -1456,6 +2517,15 @@ __metadata: languageName: node linkType: hard +"@swc/types@npm:^0.1.12": + version: 0.1.12 + resolution: "@swc/types@npm:0.1.12" + dependencies: + "@swc/counter": ^0.1.3 + checksum: cf7f89e46f859864075d7965582baea9c5f98830f45b1046251568c9bdf1ca484b1bf37f6d3c32b7c82ecf8cd5df89d22f05268c391819c44e49911bb1a8e71a + languageName: node + linkType: hard + "@szmarczak/http-timer@npm:^4.0.5": version: 4.0.6 resolution: "@szmarczak/http-timer@npm:4.0.6" @@ -1465,49 +2535,39 @@ __metadata: languageName: node linkType: hard -"@testing-library/dom@npm:^8.5.0": - version: 8.20.0 - resolution: "@testing-library/dom@npm:8.20.0" +"@testing-library/dom@npm:^10.4.0": + version: 10.4.0 + resolution: "@testing-library/dom@npm:10.4.0" dependencies: "@babel/code-frame": ^7.10.4 "@babel/runtime": ^7.12.5 "@types/aria-query": ^5.0.1 - aria-query: ^5.0.0 + aria-query: 5.3.0 chalk: ^4.1.0 dom-accessibility-api: ^0.5.9 - lz-string: ^1.4.4 + lz-string: ^1.5.0 pretty-format: ^27.0.2 - checksum: 1e599129a2fe91959ce80900a0a4897232b89e2a8e22c1f5950c36d39c97629ea86b4986b60b173b5525a05de33fde1e35836ea597b03de78cc51b122835c6f0 + checksum: bb128b90be0c8cd78c5f5e67aa45f53de614cc048a2b50b230e736ec710805ac6c73375af354b83c74d710b3928d52b83a273a4cb89de4eb3efe49e91e706837 languageName: node linkType: hard -"@testing-library/dom@npm:^9.0.0": - version: 9.0.0 - resolution: "@testing-library/dom@npm:9.0.0" - dependencies: - "@babel/code-frame": ^7.10.4 - "@babel/runtime": ^7.12.5 - "@types/aria-query": ^5.0.1 - aria-query: ^5.0.0 - chalk: ^4.1.0 - dom-accessibility-api: ^0.5.9 - lz-string: ^1.4.4 - pretty-format: ^27.0.2 - checksum: 5381bf9438f0ee35f795e7f9b203564aa455e7cd838b6677084c82dd56396779c38cc49ddffed4e57a8bcc3c62b4bc96ea684bb4b24d13655152db745327b2cd - languageName: node - linkType: hard - -"@testing-library/react@npm:^13.4.0": - version: 13.4.0 - resolution: "@testing-library/react@npm:13.4.0" +"@testing-library/react@npm:^16.0.1": + version: 16.0.1 + resolution: "@testing-library/react@npm:16.0.1" dependencies: "@babel/runtime": ^7.12.5 - "@testing-library/dom": ^8.5.0 - "@types/react-dom": ^18.0.0 peerDependencies: + "@testing-library/dom": ^10.0.0 + "@types/react": ^18.0.0 + "@types/react-dom": ^18.0.0 react: ^18.0.0 react-dom: ^18.0.0 - checksum: 51ec548c1fdb1271089a5c63e0908f0166f2c7fcd9cacd3108ebbe0ce64cb4351812d885892020dc37608418cfb15698514856502b3cab0e5cc58d6cc1bd4a3e + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 1837db473ea018cf2b5d0cbfffb7a30d0d759e5a7f23aad431441c77bcc3d2533250cd003a61878fd908267df47404cedcb5914f12d79e413002c659652b37fd languageName: node linkType: hard @@ -1534,6 +2594,13 @@ __metadata: languageName: node linkType: hard +"@tootallnate/quickjs-emscripten@npm:^0.23.0": + version: 0.23.0 + resolution: "@tootallnate/quickjs-emscripten@npm:0.23.0" + checksum: c350a2947ffb80b22e14ff35099fd582d1340d65723384a0fd0515e905e2534459ad2f301a43279a37308a27c99273c932e64649abd57d0bb3ca8c557150eccc + languageName: node + linkType: hard + "@types/aria-query@npm:^5.0.1": version: 5.0.1 resolution: "@types/aria-query@npm:5.0.1" @@ -1554,6 +2621,19 @@ __metadata: languageName: node linkType: hard +"@types/babel__core@npm:^7.20.5": + version: 7.20.5 + resolution: "@types/babel__core@npm:7.20.5" + dependencies: + "@babel/parser": ^7.20.7 + "@babel/types": ^7.20.7 + "@types/babel__generator": "*" + "@types/babel__template": "*" + "@types/babel__traverse": "*" + checksum: a3226f7930b635ee7a5e72c8d51a357e799d19cbf9d445710fa39ab13804f79ab1a54b72ea7d8e504659c7dfc50675db974b526142c754398d7413aa4bc30845 + languageName: node + linkType: hard + "@types/babel__generator@npm:*": version: 7.6.4 resolution: "@types/babel__generator@npm:7.6.4" @@ -1601,6 +2681,13 @@ __metadata: languageName: node linkType: hard +"@types/estree@npm:1.0.5, @types/estree@npm:^1.0.0": + version: 1.0.5 + resolution: "@types/estree@npm:1.0.5" + checksum: dd8b5bed28e6213b7acd0fb665a84e693554d850b0df423ac8076cc3ad5823a6bc26b0251d080bdc545af83179ede51dd3f6fa78cad2c46ed1f29624ddf3e41a + languageName: node + linkType: hard + "@types/graceful-fs@npm:^4.1.3": version: 4.1.6 resolution: "@types/graceful-fs@npm:4.1.6" @@ -1633,6 +2720,16 @@ __metadata: languageName: node linkType: hard +"@types/istanbul-lib-source-maps@npm:^4.0.4": + version: 4.0.4 + resolution: "@types/istanbul-lib-source-maps@npm:4.0.4" + dependencies: + "@types/istanbul-lib-coverage": "*" + source-map: ^0.6.1 + checksum: ad9ea59894ec929051b5588cf4b1608498013928483a6d7bc903655c13bb6f338b220281aec76b2d9d43cbc5620f51ff30d94701ca0cb1d8970d27a7e6427079 + languageName: node + linkType: hard + "@types/istanbul-reports@npm:^3.0.0": version: 3.0.1 resolution: "@types/istanbul-reports@npm:3.0.1" @@ -1686,6 +2783,22 @@ __metadata: languageName: node linkType: hard +"@types/mocha@npm:^10.0.6": + version: 10.0.8 + resolution: "@types/mocha@npm:10.0.8" + checksum: d64faa9f1ed249441944a6ae3f01d72c756b54d8bcf8e2edccb09c0d084cec6d8a0cd8b717df517812f045ade20b4b8768e06aa8633bd2485a41ec37f06be710 + languageName: node + linkType: hard + +"@types/mute-stream@npm:^0.0.4": + version: 0.0.4 + resolution: "@types/mute-stream@npm:0.0.4" + dependencies: + "@types/node": "*" + checksum: af8d83ad7b68ea05d9357985daf81b6c9b73af4feacb2f5c2693c7fd3e13e5135ef1bd083ce8d5bdc8e97acd28563b61bb32dec4e4508a8067fcd31b8a098632 + languageName: node + linkType: hard + "@types/node@npm:*": version: 18.11.19 resolution: "@types/node@npm:18.11.19" @@ -1693,10 +2806,28 @@ __metadata: languageName: node linkType: hard -"@types/prettier@npm:^2.1.5": - version: 2.7.2 - resolution: "@types/prettier@npm:2.7.2" - checksum: b47d76a5252265f8d25dd2fe2a5a61dc43ba0e6a96ffdd00c594cb4fd74c1982c2e346497e3472805d97915407a09423804cc2110a0b8e1b22cffcab246479b7 +"@types/node@npm:^20.1.0, @types/node@npm:^20.1.1, @types/node@npm:^20.11.28, @types/node@npm:^20.11.30": + version: 20.16.5 + resolution: "@types/node@npm:20.16.5" + dependencies: + undici-types: ~6.19.2 + checksum: f38b7bd8c4993dcf38943afa2ffdd7dfd18fc94f8f3f28d0c1045a10d39871a6cc1b8f8d3bf0c7ed848457d0e1d283482f6ca125579c13fed1b7575d23e8e8f5 + languageName: node + linkType: hard + +"@types/node@npm:^22.5.5": + version: 22.5.5 + resolution: "@types/node@npm:22.5.5" + dependencies: + undici-types: ~6.19.2 + checksum: 1f788966ff7df07add0af3481fb68c7fe5091cc72a265c671432abb443788ddacca4ca6378af64fe100c20f857c4d80170d358e66c070171fcea0d4adb1b45b1 + languageName: node + linkType: hard + +"@types/normalize-package-data@npm:^2.4.1": + version: 2.4.4 + resolution: "@types/normalize-package-data@npm:2.4.4" + checksum: 65dff72b543997b7be8b0265eca7ace0e34b75c3e5fee31de11179d08fa7124a7a5587265d53d0409532ecb7f7fba662c2012807963e1f9b059653ec2c83ee05 languageName: node linkType: hard @@ -1761,6 +2892,13 @@ __metadata: languageName: node linkType: hard +"@types/sinonjs__fake-timers@npm:^8.1.5": + version: 8.1.5 + resolution: "@types/sinonjs__fake-timers@npm:8.1.5" + checksum: 7e3c08f6c13df44f3ea7d9a5155ddf77e3f7314c156fa1c5a829a4f3763bafe2f75b1283b887f06e6b4296996a2f299b70f64ff82625f9af5885436e2524d10c + languageName: node + linkType: hard + "@types/stack-utils@npm:^2.0.0": version: 2.0.1 resolution: "@types/stack-utils@npm:2.0.1" @@ -1782,6 +2920,29 @@ __metadata: languageName: node linkType: hard +"@types/which@npm:^2.0.1": + version: 2.0.2 + resolution: "@types/which@npm:2.0.2" + checksum: 8626a3c2f6db676c449142e1082e33ea0c9d88b8a2bd796366b944891e6da0088b2aa83d3fa9c79e6696f7381a851fc76d43bd353eb6c4d98a7775b4ae0a96a5 + languageName: node + linkType: hard + +"@types/wrap-ansi@npm:^3.0.0": + version: 3.0.0 + resolution: "@types/wrap-ansi@npm:3.0.0" + checksum: 492f0610093b5802f45ca292777679bb9b381f1f32ae939956dd9e00bf81dba7cc99979687620a2817d9a7d8b59928207698166c47a0861c6a2e5c30d4aaf1e9 + languageName: node + linkType: hard + +"@types/ws@npm:^8.5.3": + version: 8.5.12 + resolution: "@types/ws@npm:8.5.12" + dependencies: + "@types/node": "*" + checksum: ddefb6ad1671f70ce73b38a5f47f471d4d493864fca7c51f002a86e5993d031294201c5dced6d5018fb8905ad46888d65c7f20dd54fc165910b69f42fba9a6d0 + languageName: node + linkType: hard + "@types/yargs-parser@npm:*": version: 21.0.0 resolution: "@types/yargs-parser@npm:21.0.0" @@ -1807,6 +2968,15 @@ __metadata: languageName: node linkType: hard +"@types/yauzl@npm:^2.9.1": + version: 2.10.3 + resolution: "@types/yauzl@npm:2.10.3" + dependencies: + "@types/node": "*" + checksum: 5ee966ea7bd6b2802f31ad4281c92c4c0b6dfa593c378a2582c58541fa113bec3d70eb0696b34ad95e8e6861a884cba6c3e351285816693ed176222f840a8c08 + languageName: node + linkType: hard + "@typescript-eslint/eslint-plugin@npm:^5.51.0": version: 5.51.0 resolution: "@typescript-eslint/eslint-plugin@npm:5.51.0" @@ -1918,28 +3088,300 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:5.51.0": - version: 5.51.0 - resolution: "@typescript-eslint/visitor-keys@npm:5.51.0" +"@typescript-eslint/visitor-keys@npm:5.51.0": + version: 5.51.0 + resolution: "@typescript-eslint/visitor-keys@npm:5.51.0" + dependencies: + "@typescript-eslint/types": 5.51.0 + eslint-visitor-keys: ^3.3.0 + checksum: b49710f3c6b3b62a846a163afffd81be5eb2b1f44e25bec51ff3c9f4c3b579d74aa4cbd3753b4fc09ea3dbc64a7062f9c658c08d22bb2740a599cb703d876220 + languageName: node + linkType: hard + +"@vitejs/plugin-react@npm:^4.3.1": + version: 4.3.1 + resolution: "@vitejs/plugin-react@npm:4.3.1" + dependencies: + "@babel/core": ^7.24.5 + "@babel/plugin-transform-react-jsx-self": ^7.24.5 + "@babel/plugin-transform-react-jsx-source": ^7.24.1 + "@types/babel__core": ^7.20.5 + react-refresh: ^0.14.2 + peerDependencies: + vite: ^4.2.0 || ^5.0.0 + checksum: 57872e0193c7e545c5ef4852cbe1adf17a6b35406a2aba4b3acce06c173a9dabbf6ff4c72701abc11bb3cbe24a056f5054f39018f7034c9aa57133a3a7770237 + languageName: node + linkType: hard + +"@vitest/pretty-format@npm:2.1.1": + version: 2.1.1 + resolution: "@vitest/pretty-format@npm:2.1.1" + dependencies: + tinyrainbow: ^1.2.0 + checksum: acc327b4d097719adf01762c22fa6aa59536cef916b7f1e1cbb91179f513ac056aaf023ba07fd86966a241c3157ee8a9c99b52f6899ee61bc1028c7f0117ca14 + languageName: node + linkType: hard + +"@vitest/snapshot@npm:^1.2.1": + version: 1.6.0 + resolution: "@vitest/snapshot@npm:1.6.0" + dependencies: + magic-string: ^0.30.5 + pathe: ^1.1.1 + pretty-format: ^29.7.0 + checksum: c4249fbf3ce310de86a19529a0a5c10b1bde4d8d8a678029c632335969b86cbdbf51cedc20d5e9c9328afee834d13cec1b8de5d0fd58139bf8e2dd8dcd0797f4 + languageName: node + linkType: hard + +"@vitest/snapshot@npm:^2.0.5": + version: 2.1.1 + resolution: "@vitest/snapshot@npm:2.1.1" + dependencies: + "@vitest/pretty-format": 2.1.1 + magic-string: ^0.30.11 + pathe: ^1.1.2 + checksum: d913fa14430d02e38d9c6a14326658be4ce871c8df82f9aa2f33f7c7ac6ab1a341a7b43585d72e8e159482578567865beffe561da218a18ee10110ce9008e0e5 + languageName: node + linkType: hard + +"@vitest/spy@npm:^2.0.4": + version: 2.1.1 + resolution: "@vitest/spy@npm:2.1.1" + dependencies: + tinyspy: ^3.0.0 + checksum: 87d680dc905b80ced10a5ae8a019772b6b31b7cd928a21ae7043cd06b163ff39eee37dbb3a8033d80e1496200b2990aa13600fccae9b3bf234a65485a4f3f71b + languageName: node + linkType: hard + +"@wdio/browser-runner@npm:^9.0.9": + version: 9.0.9 + resolution: "@wdio/browser-runner@npm:9.0.9" + dependencies: + "@nuxt/kit": ^3.12.4 + "@originjs/vite-plugin-commonjs": ^1.0.3 + "@stencil/core": ^4.20.0 + "@types/istanbul-lib-source-maps": ^4.0.4 + "@vitest/spy": ^2.0.4 + "@wdio/globals": 9.0.9 + "@wdio/local-runner": 9.0.9 + "@wdio/logger": 9.0.8 + "@wdio/mocha-framework": 9.0.8 + "@wdio/protocols": 9.0.8 + "@wdio/runner": 9.0.9 + "@wdio/types": 9.0.8 + "@wdio/utils": 9.0.8 + deepmerge-ts: ^7.0.3 + expect: ^29.7.0 + expect-webdriverio: ^5.0.1 + get-port: ^7.1.0 + import-meta-resolve: ^4.0.0 + istanbul-lib-coverage: ^3.2.2 + istanbul-lib-report: ^3.0.1 + istanbul-lib-source-maps: ^5.0.4 + istanbul-reports: ^3.1.7 + mlly: ^1.6.1 + modern-node-polyfills: ^1.0.0 + recast: ^0.23.6 + safe-stringify: ^1.1.0 + source-map-support: ^0.5.21 + unimport: ^3.10.0 + vite: ~5.4.0 + vite-plugin-istanbul: ^6.0.0 + vite-plugin-top-level-await: ^1.4.1 + webdriver: 9.0.8 + webdriverio: 9.0.9 + dependenciesMeta: + "@nuxt/kit": + optional: true + "@stencil/core": + optional: true + unimport: + optional: true + checksum: be979a08cf91d8b3de4c3a1f4661c73bb2beb0a5cda4e7e3914dfa4b2eadb92c5fddea23a67c768deabcaf418411bc2390dd5468240e274e44d0c90205dae676 + languageName: node + linkType: hard + +"@wdio/cli@npm:^9.0.9": + version: 9.0.9 + resolution: "@wdio/cli@npm:9.0.9" + dependencies: + "@types/node": ^20.1.1 + "@vitest/snapshot": ^1.2.1 + "@wdio/config": 9.0.8 + "@wdio/globals": 9.0.9 + "@wdio/logger": 9.0.8 + "@wdio/protocols": 9.0.8 + "@wdio/types": 9.0.8 + "@wdio/utils": 9.0.8 + async-exit-hook: ^2.0.1 + chalk: ^5.2.0 + chokidar: ^3.5.3 + cli-spinners: ^3.0.0 + dotenv: ^16.3.1 + ejs: ^3.1.9 + execa: ^9.2.0 + import-meta-resolve: ^4.0.0 + inquirer: ^10.1.8 + lodash.flattendeep: ^4.4.0 + lodash.pickby: ^4.6.0 + lodash.union: ^4.6.0 + read-pkg-up: ^10.0.0 + recursive-readdir: ^2.2.3 + tsx: ^4.7.2 + webdriverio: 9.0.9 + yargs: ^17.7.2 + bin: + wdio: ./bin/wdio.js + checksum: 71fdba5e837a27a74117012cbf7623064b98f21688599fccda366b11935404d4bc7c4a193e550366673a9e6c5bbdeb8b0af12435b27a058dcd5e4031811752aa + languageName: node + linkType: hard + +"@wdio/config@npm:9.0.8": + version: 9.0.8 + resolution: "@wdio/config@npm:9.0.8" + dependencies: + "@wdio/logger": 9.0.8 + "@wdio/types": 9.0.8 + "@wdio/utils": 9.0.8 + decamelize: ^6.0.0 + deepmerge-ts: ^7.0.3 + glob: ^10.2.2 + import-meta-resolve: ^4.0.0 + checksum: 4e613e02bb0c2a0c5a6400366efcbc5d54f1e7e2289aec96cec115719d578c63ea44de461382572238c28f125853901ff562d4841adb1fa68955fd50bc12587d + languageName: node + linkType: hard + +"@wdio/globals@npm:9.0.9": + version: 9.0.9 + resolution: "@wdio/globals@npm:9.0.9" + dependencies: + expect-webdriverio: ^5.0.1 + webdriverio: 9.0.9 + dependenciesMeta: + expect-webdriverio: + optional: true + webdriverio: + optional: true + checksum: 07da508593408d777866d65d911aa61d17717ea41fa1ac9978007672899fdfcccf2202cfee82fbabd469b095d23b81312600d026a21f43bd1626c801bc6ee126 + languageName: node + linkType: hard + +"@wdio/local-runner@npm:9.0.9": + version: 9.0.9 + resolution: "@wdio/local-runner@npm:9.0.9" + dependencies: + "@types/node": ^20.1.0 + "@wdio/logger": 9.0.8 + "@wdio/repl": 9.0.8 + "@wdio/runner": 9.0.9 + "@wdio/types": 9.0.8 + async-exit-hook: ^2.0.1 + split2: ^4.1.0 + stream-buffers: ^3.0.2 + checksum: a1db011a535cbd7b7e882a2b3066744f7131c65bddb56cb2f1ce1fe3212b88788d66232a4dd17bc4054cdb9ceb3b2741002b374c9f2f53f8ea5e4b1266137f43 + languageName: node + linkType: hard + +"@wdio/logger@npm:9.0.8, @wdio/logger@npm:^9.0.0": + version: 9.0.8 + resolution: "@wdio/logger@npm:9.0.8" + dependencies: + chalk: ^5.1.2 + loglevel: ^1.6.0 + loglevel-plugin-prefix: ^0.8.4 + strip-ansi: ^7.1.0 + checksum: ab62da85785344284fdf2be229bc07f6c11351e5b7eec773cac0d59c845fb0a0fcbf17ed628c28df3fb7d27b7e493b6c21128f3c789b2f0de4db5f619f4b4e1f + languageName: node + linkType: hard + +"@wdio/logger@npm:^8.38.0": + version: 8.38.0 + resolution: "@wdio/logger@npm:8.38.0" + dependencies: + chalk: ^5.1.2 + loglevel: ^1.6.0 + loglevel-plugin-prefix: ^0.8.4 + strip-ansi: ^7.1.0 + checksum: 3cb5b0e23c95317170c5b7a76f46eb37f5416ffacbcdfbea9cd6fa5dbc3571ed0ab82f98c7d56f8b7b11eb61912eae0eefe7cfae21fb70630bfd892a084f4a9f + languageName: node + linkType: hard + +"@wdio/mocha-framework@npm:9.0.8, @wdio/mocha-framework@npm:^9.0.8": + version: 9.0.8 + resolution: "@wdio/mocha-framework@npm:9.0.8" + dependencies: + "@types/mocha": ^10.0.6 + "@types/node": ^20.11.28 + "@wdio/logger": 9.0.8 + "@wdio/types": 9.0.8 + "@wdio/utils": 9.0.8 + mocha: ^10.3.0 + checksum: 1284c6d44f26f84979a00b232306edafefbc90a32c9c8c999e2567ecff54cbdaa90c50fd4789c58b6c84b1741477ba362e14ecf668158b11aef7c5b5fd3176a2 + languageName: node + linkType: hard + +"@wdio/protocols@npm:9.0.8": + version: 9.0.8 + resolution: "@wdio/protocols@npm:9.0.8" + checksum: 8019def62e6994abde8f538c928dd812ce12c641e027e3c11e0b592bc36269d3bd743e3b88b1247f51ff2d71225f5ad20187da16629bb74f50a8b804c9510f38 + languageName: node + linkType: hard + +"@wdio/repl@npm:9.0.8": + version: 9.0.8 + resolution: "@wdio/repl@npm:9.0.8" dependencies: - "@typescript-eslint/types": 5.51.0 - eslint-visitor-keys: ^3.3.0 - checksum: b49710f3c6b3b62a846a163afffd81be5eb2b1f44e25bec51ff3c9f4c3b579d74aa4cbd3753b4fc09ea3dbc64a7062f9c658c08d22bb2740a599cb703d876220 + "@types/node": ^20.1.0 + checksum: 29e395239edf967bd5cbb156e7e88f1d4640116c27959e2353717c8d0a0784aae54ef4e2d7e4cac7a1c94540cf4fa4d5dcd6eebb71626d195f16d26f335d588f languageName: node linkType: hard -"@vitejs/plugin-react@npm:^3.1.0": - version: 3.1.0 - resolution: "@vitejs/plugin-react@npm:3.1.0" +"@wdio/runner@npm:9.0.9": + version: 9.0.9 + resolution: "@wdio/runner@npm:9.0.9" dependencies: - "@babel/core": ^7.20.12 - "@babel/plugin-transform-react-jsx-self": ^7.18.6 - "@babel/plugin-transform-react-jsx-source": ^7.19.6 - magic-string: ^0.27.0 - react-refresh: ^0.14.0 - peerDependencies: - vite: ^4.1.0-beta.0 - checksum: 450fac79e67cba9e1581c860f78e687b44108ab4117663ef20db279316e03cd8e87f94fef376e27cc5e200bd52813dcc09b70ea570c7c7cc291fcd47eb260fbc + "@types/node": ^20.11.28 + "@wdio/config": 9.0.8 + "@wdio/globals": 9.0.9 + "@wdio/logger": 9.0.8 + "@wdio/types": 9.0.8 + "@wdio/utils": 9.0.8 + deepmerge-ts: ^7.0.3 + expect-webdriverio: ^5.0.1 + gaze: ^1.1.3 + webdriver: 9.0.8 + webdriverio: 9.0.9 + checksum: 7885c0e7ca7db5e3a2bbbb0cc3c1592a99a65d01f32c8b990f44f1ce48de9629d117b1c80d9eca3b1b2233a5aaa177bbba6e9339c69c0abdde7dcfab5e2ab142 + languageName: node + linkType: hard + +"@wdio/types@npm:9.0.8, @wdio/types@npm:^9.0.8": + version: 9.0.8 + resolution: "@wdio/types@npm:9.0.8" + dependencies: + "@types/node": ^20.1.0 + checksum: d5ba8e18d34ad64d3b728aa0a1171ee4105364b6819455a4c061775dc94b66d5b055dc54eadb2d16471cfd116a14f5520110489f522a0c06d84c28b38055e921 + languageName: node + linkType: hard + +"@wdio/utils@npm:9.0.8": + version: 9.0.8 + resolution: "@wdio/utils@npm:9.0.8" + dependencies: + "@puppeteer/browsers": ^2.2.0 + "@wdio/logger": 9.0.8 + "@wdio/types": 9.0.8 + decamelize: ^6.0.0 + deepmerge-ts: ^7.0.3 + edgedriver: ^5.6.1 + geckodriver: ^4.3.3 + get-port: ^7.0.0 + import-meta-resolve: ^4.0.0 + locate-app: ^2.2.24 + safaridriver: ^0.1.2 + split2: ^4.2.0 + wait-port: ^1.1.0 + checksum: 414d61ccf82c1a0bc958c5360fcc93eb5bc265af97f3a93b30d230bf3586a118c091e3217e1b0ffca49fa42227c5095f8b598b02351bd7aeb994518982027aec languageName: node linkType: hard @@ -2044,6 +3486,13 @@ __metadata: languageName: node linkType: hard +"@zip.js/zip.js@npm:^2.7.48": + version: 2.7.52 + resolution: "@zip.js/zip.js@npm:2.7.52" + checksum: aecc9925bfaeb3fc46b2bb91f9de7161dcf87bb72037d22f3628d9609878b3efc4e149d767ad6fb91e19d2f21adb83303c128ba707190a44b823c6e384fecc85 + languageName: node + linkType: hard + "abab@npm:^2.0.6": version: 2.0.6 resolution: "abab@npm:2.0.6" @@ -2058,6 +3507,15 @@ __metadata: languageName: node linkType: hard +"abort-controller@npm:^3.0.0": + version: 3.0.0 + resolution: "abort-controller@npm:3.0.0" + dependencies: + event-target-shim: ^5.0.0 + checksum: 170bdba9b47b7e65906a28c8ce4f38a7a369d78e2271706f020849c1bfe0ee2067d4261df8bbb66eb84f79208fd5b710df759d64191db58cfba7ce8ef9c54b75 + languageName: node + linkType: hard + "acorn-globals@npm:^7.0.0": version: 7.0.1 resolution: "acorn-globals@npm:7.0.1" @@ -2093,6 +3551,15 @@ __metadata: languageName: node linkType: hard +"acorn@npm:^8.11.3, acorn@npm:^8.12.0, acorn@npm:^8.12.1, acorn@npm:^8.8.2": + version: 8.12.1 + resolution: "acorn@npm:8.12.1" + bin: + acorn: bin/acorn + checksum: 677880034aee5bdf7434cc2d25b641d7bedb0b5ef47868a78dadabedccf58e1c5457526d9d8249cd253f2df087e081c3fe7d903b448d8e19e5131a3065b83c07 + languageName: node + linkType: hard + "agent-base@npm:6, agent-base@npm:^6.0.2": version: 6.0.2 resolution: "agent-base@npm:6.0.2" @@ -2102,6 +3569,15 @@ __metadata: languageName: node linkType: hard +"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.1": + version: 7.1.1 + resolution: "agent-base@npm:7.1.1" + dependencies: + debug: ^4.3.4 + checksum: 51c158769c5c051482f9ca2e6e1ec085ac72b5a418a9b31b4e82fe6c0a6699adb94c1c42d246699a587b3335215037091c79e0de512c516f73b6ea844202f037 + languageName: node + linkType: hard + "agentkeepalive@npm:^4.2.1": version: 4.2.1 resolution: "agentkeepalive@npm:4.2.1" @@ -2135,7 +3611,14 @@ __metadata: languageName: node linkType: hard -"ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.0": +"ansi-colors@npm:^4.1.3": + version: 4.1.3 + resolution: "ansi-colors@npm:4.1.3" + checksum: a9c2ec842038a1fabc7db9ece7d3177e2fe1c5dc6f0c51ecfbf5f39911427b89c00b5dc6b8bd95f82a26e9b16aaae2e83d45f060e98070ce4d1333038edceb0e + languageName: node + linkType: hard + +"ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.0, ansi-escapes@npm:^4.3.2": version: 4.3.2 resolution: "ansi-escapes@npm:4.3.2" dependencies: @@ -2192,7 +3675,7 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^6.0.0": +"ansi-styles@npm:^6.0.0, ansi-styles@npm:^6.1.0": version: 6.2.1 resolution: "ansi-styles@npm:6.2.1" checksum: ef940f2f0ced1a6347398da88a91da7930c33ecac3c77b72c5905f8b8fe402c52e6fde304ff5347f616e27a742da3f1dc76de98f6866c69251ad0b07a66776d9 @@ -2206,7 +3689,7 @@ __metadata: languageName: node linkType: hard -"anymatch@npm:^3.0.3": +"anymatch@npm:^3.0.3, anymatch@npm:~3.1.2": version: 3.1.3 resolution: "anymatch@npm:3.1.3" dependencies: @@ -2230,6 +3713,36 @@ __metadata: languageName: node linkType: hard +"archiver-utils@npm:^5.0.0, archiver-utils@npm:^5.0.2": + version: 5.0.2 + resolution: "archiver-utils@npm:5.0.2" + dependencies: + glob: ^10.0.0 + graceful-fs: ^4.2.0 + is-stream: ^2.0.1 + lazystream: ^1.0.0 + lodash: ^4.17.15 + normalize-path: ^3.0.0 + readable-stream: ^4.0.0 + checksum: 7dc4f3001dc373bd0fa7671ebf08edf6f815cbc539c78b5478a2eaa67e52e3fc0e92f562cdef2ba016c4dcb5468d3d069eb89535c6844da4a5bb0baf08ad5720 + languageName: node + linkType: hard + +"archiver@npm:^7.0.1": + version: 7.0.1 + resolution: "archiver@npm:7.0.1" + dependencies: + archiver-utils: ^5.0.2 + async: ^3.2.4 + buffer-crc32: ^1.0.0 + readable-stream: ^4.0.0 + readdir-glob: ^1.1.2 + tar-stream: ^3.0.0 + zip-stream: ^6.0.1 + checksum: f93bcc00f919e0bbb6bf38fddf111d6e4d1ed34721b73cc073edd37278303a7a9f67aa4abd6fd2beb80f6c88af77f2eb4f60276343f67605e3aea404e5ad93ea + languageName: node + linkType: hard + "are-we-there-yet@npm:^3.0.0": version: 3.0.1 resolution: "are-we-there-yet@npm:3.0.1" @@ -2256,12 +3769,19 @@ __metadata: languageName: node linkType: hard -"aria-query@npm:^5.0.0": - version: 5.1.3 - resolution: "aria-query@npm:5.1.3" +"aria-query@npm:5.3.0": + version: 5.3.0 + resolution: "aria-query@npm:5.3.0" dependencies: - deep-equal: ^2.0.5 - checksum: 929ff95f02857b650fb4cbcd2f41072eee2f46159a6605ea03bf63aa572e35ffdff43d69e815ddc462e16e07de8faba3978afc2813650b4448ee18c9895d982b + dequal: ^2.0.3 + checksum: 305bd73c76756117b59aba121d08f413c7ff5e80fa1b98e217a3443fcddb9a232ee790e24e432b59ae7625aebcf4c47cb01c2cac872994f0b426f5bdfcd96ba9 + languageName: node + linkType: hard + +"aria-query@npm:^5.3.0": + version: 5.3.1 + resolution: "aria-query@npm:5.3.1" + checksum: 8f7ece335efadd80217901005dfb71130eab45b38d71ec5ba63b3a51c1028abc018618b86db3dcd9222995538e7b10d7c505051fb8ba7a02ec0a4e77499c9a9c languageName: node linkType: hard @@ -2322,6 +3842,24 @@ __metadata: languageName: node linkType: hard +"ast-types@npm:^0.13.4": + version: 0.13.4 + resolution: "ast-types@npm:0.13.4" + dependencies: + tslib: ^2.0.1 + checksum: 5a51f7b70588ecced3601845a0e203279ca2f5fdc184416a0a1640c93ec0a267241d6090a328e78eebb8de81f8754754e0a4f1558ba2a3d638f8ccbd0b1f0eff + languageName: node + linkType: hard + +"ast-types@npm:^0.16.1": + version: 0.16.1 + resolution: "ast-types@npm:0.16.1" + dependencies: + tslib: ^2.0.1 + checksum: 21c186da9fdb1d8087b1b7dabbc4059f91aa5a1e593a9776b4393cc1eaa857e741b2dda678d20e34b16727b78fef3ab59cf8f0c75ed1ba649c78fe194e5c114b + languageName: node + linkType: hard + "astral-regex@npm:^2.0.0": version: 2.0.0 resolution: "astral-regex@npm:2.0.0" @@ -2329,6 +3867,20 @@ __metadata: languageName: node linkType: hard +"async-exit-hook@npm:^2.0.1": + version: 2.0.1 + resolution: "async-exit-hook@npm:2.0.1" + checksum: b72cbdd19ea90fa33a3a57b0dbff83e4bf2f4e4acd70b2b3847a588f9f16a45d38590ee13f285375dd919c224f60fa58dc3d315a87678d3aa24ff686d1c0200a + languageName: node + linkType: hard + +"async@npm:^3.2.3, async@npm:^3.2.4": + version: 3.2.6 + resolution: "async@npm:3.2.6" + checksum: ee6eb8cd8a0ab1b58bd2a3ed6c415e93e773573a91d31df9d5ef559baafa9dab37d3b096fa7993e84585cac3697b2af6ddb9086f45d3ac8cae821bb2aab65682 + languageName: node + linkType: hard + "asynckit@npm:^0.4.0": version: 0.4.0 resolution: "asynckit@npm:0.4.0" @@ -2352,20 +3904,27 @@ __metadata: languageName: node linkType: hard -"babel-jest@npm:^29.4.1": - version: 29.4.1 - resolution: "babel-jest@npm:29.4.1" +"b4a@npm:^1.6.4, b4a@npm:^1.6.6": + version: 1.6.6 + resolution: "b4a@npm:1.6.6" + checksum: c46a27e3ac9c84426ae728f0fc46a6ae7703a7bc03e771fa0bef4827fd7cf3bb976d1a3d5afff54606248372ab8fdf595bd0114406690edf37f14d120630cf7f + languageName: node + linkType: hard + +"babel-jest@npm:^29.7.0": + version: 29.7.0 + resolution: "babel-jest@npm:29.7.0" dependencies: - "@jest/transform": ^29.4.1 + "@jest/transform": ^29.7.0 "@types/babel__core": ^7.1.14 babel-plugin-istanbul: ^6.1.1 - babel-preset-jest: ^29.4.0 + babel-preset-jest: ^29.6.3 chalk: ^4.0.0 graceful-fs: ^4.2.9 slash: ^3.0.0 peerDependencies: "@babel/core": ^7.8.0 - checksum: 4a2971ee50d0e467ccc9ca3557c2e721aaac1a165c34cd82fd056be8fc0bce258247b3c960059ecf05beddafe06b37dceeb8b8c32fa7393b8a42d2055a70559f + checksum: ee6f8e0495afee07cac5e4ee167be705c711a8cc8a737e05a587a131fdae2b3c8f9aa55dfd4d9c03009ac2d27f2de63d8ba96d3e8460da4d00e8af19ef9a83f7 languageName: node linkType: hard @@ -2382,15 +3941,15 @@ __metadata: languageName: node linkType: hard -"babel-plugin-jest-hoist@npm:^29.4.0": - version: 29.4.0 - resolution: "babel-plugin-jest-hoist@npm:29.4.0" +"babel-plugin-jest-hoist@npm:^29.6.3": + version: 29.6.3 + resolution: "babel-plugin-jest-hoist@npm:29.6.3" dependencies: "@babel/template": ^7.3.3 "@babel/types": ^7.3.3 "@types/babel__core": ^7.1.14 "@types/babel__traverse": ^7.0.6 - checksum: c18369a9aa5e29f8d1c00b19f513f6c291df8d531c344ef7951e7e3d3b95ae5dd029817510544ceb668a96e156f05ee73eadb228428956b9239f1714d99fecb6 + checksum: 51250f22815a7318f17214a9d44650ba89551e6d4f47a2dc259128428324b52f5a73979d010cefd921fd5a720d8c1d55ad74ff601cd94c7bd44d5f6292fde2d1 languageName: node linkType: hard @@ -2416,15 +3975,15 @@ __metadata: languageName: node linkType: hard -"babel-preset-jest@npm:^29.4.0": - version: 29.4.0 - resolution: "babel-preset-jest@npm:29.4.0" +"babel-preset-jest@npm:^29.6.3": + version: 29.6.3 + resolution: "babel-preset-jest@npm:29.6.3" dependencies: - babel-plugin-jest-hoist: ^29.4.0 + babel-plugin-jest-hoist: ^29.6.3 babel-preset-current-node-syntax: ^1.0.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: 38baf965731059ec13cf4038d2a6ec3ac528ba45ce45f4e41710f17fa0cdcba404ff74689cdc9a929c64b2547d6ea9f8d5c41ca4db7770a85f82b7de3fb25024 + checksum: aa4ff2a8a728d9d698ed521e3461a109a1e66202b13d3494e41eea30729a5e7cc03b3a2d56c594423a135429c37bf63a9fa8b0b9ce275298be3095a88c69f6fb languageName: node linkType: hard @@ -2435,6 +3994,64 @@ __metadata: languageName: node linkType: hard +"bare-events@npm:^2.0.0, bare-events@npm:^2.2.0": + version: 2.4.2 + resolution: "bare-events@npm:2.4.2" + checksum: 6cd2b10dd32a3410787e120c091b6082fbc2df0c45ed723a7ae51d0e2f55d2a4037e1daff21dae90b671d36582f9f8d50df337875c281d10adb60df81b8cd861 + languageName: node + linkType: hard + +"bare-fs@npm:^2.1.1": + version: 2.3.5 + resolution: "bare-fs@npm:2.3.5" + dependencies: + bare-events: ^2.0.0 + bare-path: ^2.0.0 + bare-stream: ^2.0.0 + checksum: 071b1dff94a213eaf0b41693953959bf10af2deade597a56ff206a5d833579d56bc8530aa4614bb88bf39fd6d52f2404f7c36af4695109ffa756a13837ac3d91 + languageName: node + linkType: hard + +"bare-os@npm:^2.1.0": + version: 2.4.4 + resolution: "bare-os@npm:2.4.4" + checksum: e90088a7dc0307c020350a28df8ec5564cae5a4b7a213d8509d70831d7064308e2ed31de801b68f474cb004ad3a0a66bd28c38374d270484d9025ee71af20396 + languageName: node + linkType: hard + +"bare-path@npm:^2.0.0, bare-path@npm:^2.1.0": + version: 2.1.3 + resolution: "bare-path@npm:2.1.3" + dependencies: + bare-os: ^2.1.0 + checksum: 20301aeb05b735852a396515464908e51e896922c3bb353ef2a09ff54e81ced94e6ad857bb0a36d2ce659c42bd43dd5c3d5643edd8faaf910ee9950c4e137b88 + languageName: node + linkType: hard + +"bare-stream@npm:^2.0.0": + version: 2.3.0 + resolution: "bare-stream@npm:2.3.0" + dependencies: + b4a: ^1.6.6 + streamx: ^2.20.0 + checksum: 17de9dbd5a6d70863b6e55f0acdfe1cb5d2b05f22d87e79986372cc796095eb4882a868ee6ba3dc543243085d27f618b4b81ef2bf384bc1c690dd3a557b6e30d + languageName: node + linkType: hard + +"base64-js@npm:^1.3.1": + version: 1.5.1 + resolution: "base64-js@npm:1.5.1" + checksum: 669632eb3745404c2f822a18fc3a0122d2f9a7a13f7fb8b5823ee19d1d2ff9ee5b52c53367176ea4ad093c332fd5ab4bd0ebae5a8e27917a4105a4cfc86b1005 + languageName: node + linkType: hard + +"basic-ftp@npm:^5.0.2": + version: 5.0.5 + resolution: "basic-ftp@npm:5.0.5" + checksum: bc82d1c1c61cd838eaca96d68ece888bacf07546642fb6b9b8328ed410756f5935f8cf43a42cb44bb343e0565e28e908adc54c298bd2f1a6e0976871fb11fec6 + languageName: node + linkType: hard + "bin-check@npm:^4.1.0": version: 4.1.0 resolution: "bin-check@npm:4.1.0" @@ -2466,6 +4083,20 @@ __metadata: languageName: node linkType: hard +"binary-extensions@npm:^2.0.0": + version: 2.3.0 + resolution: "binary-extensions@npm:2.3.0" + checksum: bcad01494e8a9283abf18c1b967af65ee79b0c6a9e6fcfafebfe91dbe6e0fc7272bafb73389e198b310516ae04f7ad17d79aacf6cb4c0d5d5202a7e2e52c7d98 + languageName: node + linkType: hard + +"boolbase@npm:^1.0.0": + version: 1.0.0 + resolution: "boolbase@npm:1.0.0" + checksum: 3e25c80ef626c3a3487c73dbfc70ac322ec830666c9ad915d11b701142fab25ec1e63eff2c450c74347acfd2de854ccde865cd79ef4db1683f7c7b046ea43bb0 + languageName: node + linkType: hard + "brace-expansion@npm:^1.1.7": version: 1.1.11 resolution: "brace-expansion@npm:1.1.11" @@ -2494,6 +4125,22 @@ __metadata: languageName: node linkType: hard +"braces@npm:~3.0.2": + version: 3.0.3 + resolution: "braces@npm:3.0.3" + dependencies: + fill-range: ^7.1.1 + checksum: b95aa0b3bd909f6cd1720ffcf031aeaf46154dd88b4da01f9a1d3f7ea866a79eba76a6d01cbc3c422b2ee5cdc39a4f02491058d5df0d7bf6e6a162a832df1f69 + languageName: node + linkType: hard + +"browser-stdout@npm:^1.3.1": + version: 1.3.1 + resolution: "browser-stdout@npm:1.3.1" + checksum: b717b19b25952dd6af483e368f9bcd6b14b87740c3d226c2977a65e84666ffd67000bddea7d911f111a9b6ddc822b234de42d52ab6507bce4119a4cc003ef7b3 + languageName: node + linkType: hard + "browserslist@npm:^4.21.3": version: 4.21.5 resolution: "browserslist@npm:4.21.5" @@ -2508,6 +4155,20 @@ __metadata: languageName: node linkType: hard +"browserslist@npm:^4.23.1": + version: 4.23.3 + resolution: "browserslist@npm:4.23.3" + dependencies: + caniuse-lite: ^1.0.30001646 + electron-to-chromium: ^1.5.4 + node-releases: ^2.0.18 + update-browserslist-db: ^1.1.0 + bin: + browserslist: cli.js + checksum: 7906064f9970aeb941310b2fcb8b4ace4a1b50aa657c986677c6f1553a8cabcc94ee9c5922f715baffbedaa0e6cf0831b6fed7b059dde6873a4bfadcbe069c7e + languageName: node + linkType: hard + "bser@npm:2.1.1": version: 2.1.1 resolution: "bser@npm:2.1.1" @@ -2517,6 +4178,20 @@ __metadata: languageName: node linkType: hard +"buffer-crc32@npm:^1.0.0": + version: 1.0.0 + resolution: "buffer-crc32@npm:1.0.0" + checksum: bc114c0e02fe621249e0b5093c70e6f12d4c2b1d8ddaf3b1b7bbe3333466700100e6b1ebdc12c050d0db845bc582c4fce8c293da487cc483f97eea027c480b23 + languageName: node + linkType: hard + +"buffer-crc32@npm:~0.2.3": + version: 0.2.13 + resolution: "buffer-crc32@npm:0.2.13" + checksum: 06252347ae6daca3453b94e4b2f1d3754a3b146a111d81c68924c22d91889a40623264e95e67955b1cb4a68cbedf317abeabb5140a9766ed248973096db5ce1c + languageName: node + linkType: hard + "buffer-from@npm:^1.0.0": version: 1.1.2 resolution: "buffer-from@npm:1.1.2" @@ -2524,6 +4199,51 @@ __metadata: languageName: node linkType: hard +"buffer@npm:^5.2.1": + version: 5.7.1 + resolution: "buffer@npm:5.7.1" + dependencies: + base64-js: ^1.3.1 + ieee754: ^1.1.13 + checksum: e2cf8429e1c4c7b8cbd30834ac09bd61da46ce35f5c22a78e6c2f04497d6d25541b16881e30a019c6fd3154150650ccee27a308eff3e26229d788bbdeb08ab84 + languageName: node + linkType: hard + +"buffer@npm:^6.0.3": + version: 6.0.3 + resolution: "buffer@npm:6.0.3" + dependencies: + base64-js: ^1.3.1 + ieee754: ^1.2.1 + checksum: 5ad23293d9a731e4318e420025800b42bf0d264004c0286c8cc010af7a270c7a0f6522e84f54b9ad65cbd6db20b8badbfd8d2ebf4f80fa03dab093b89e68c3f9 + languageName: node + linkType: hard + +"c12@npm:^1.11.2": + version: 1.11.2 + resolution: "c12@npm:1.11.2" + dependencies: + chokidar: ^3.6.0 + confbox: ^0.1.7 + defu: ^6.1.4 + dotenv: ^16.4.5 + giget: ^1.2.3 + jiti: ^1.21.6 + mlly: ^1.7.1 + ohash: ^1.1.3 + pathe: ^1.1.2 + perfect-debounce: ^1.0.0 + pkg-types: ^1.2.0 + rc9: ^2.1.2 + peerDependencies: + magicast: ^0.3.4 + peerDependenciesMeta: + magicast: + optional: true + checksum: 167ae62cdac6dd327d0ca9d1e781cbc8d685f96ad734416fa52279618cf4154bfd56d76be644e05ac07bc2b40cdc67f49f174a21ef58a4256e1b341e9e59ab97 + languageName: node + linkType: hard + "cacache@npm:^16.1.0": version: 16.1.3 resolution: "cacache@npm:16.1.3" @@ -2596,7 +4316,7 @@ __metadata: languageName: node linkType: hard -"camelcase@npm:^6.2.0": +"camelcase@npm:^6.0.0, camelcase@npm:^6.2.0": version: 6.3.0 resolution: "camelcase@npm:6.3.0" checksum: 8c96818a9076434998511251dcb2761a94817ea17dbdc37f47ac080bd088fc62c7369429a19e2178b993497132c8cbcf5cc1f44ba963e76782ba469c0474938d @@ -2610,6 +4330,13 @@ __metadata: languageName: node linkType: hard +"caniuse-lite@npm:^1.0.30001646": + version: 1.0.30001660 + resolution: "caniuse-lite@npm:1.0.30001660" + checksum: 8b2c5de2f5facd31980426afbba68238270984acfe8c1ae925b8b6480448eea2fae292f815674617e9170c730c8a238d7cc0db919f184dc0e3cd9bec18f5e5ad + languageName: node + linkType: hard + "chalk@npm:^2.0.0, chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" @@ -2631,7 +4358,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^4.0.0, chalk@npm:^4.1.0": +"chalk@npm:^4.0.0, chalk@npm:^4.0.2, chalk@npm:^4.1.0, chalk@npm:^4.1.2": version: 4.1.2 resolution: "chalk@npm:4.1.2" dependencies: @@ -2641,6 +4368,13 @@ __metadata: languageName: node linkType: hard +"chalk@npm:^5.1.2, chalk@npm:^5.2.0": + version: 5.3.0 + resolution: "chalk@npm:5.3.0" + checksum: 623922e077b7d1e9dedaea6f8b9e9352921f8ae3afe739132e0e00c275971bdd331268183b2628cf4ab1727c45ea1f28d7e24ac23ce1db1eb653c414ca8a5a80 + languageName: node + linkType: hard + "char-regex@npm:^1.0.2": version: 1.0.2 resolution: "char-regex@npm:1.0.2" @@ -2648,6 +4382,65 @@ __metadata: languageName: node linkType: hard +"chardet@npm:^0.7.0": + version: 0.7.0 + resolution: "chardet@npm:0.7.0" + checksum: 6fd5da1f5d18ff5712c1e0aed41da200d7c51c28f11b36ee3c7b483f3696dabc08927fc6b227735eb8f0e1215c9a8abd8154637f3eff8cada5959df7f58b024d + languageName: node + linkType: hard + +"cheerio-select@npm:^2.1.0": + version: 2.1.0 + resolution: "cheerio-select@npm:2.1.0" + dependencies: + boolbase: ^1.0.0 + css-select: ^5.1.0 + css-what: ^6.1.0 + domelementtype: ^2.3.0 + domhandler: ^5.0.3 + domutils: ^3.0.1 + checksum: 843d6d479922f28a6c5342c935aff1347491156814de63c585a6eb73baf7bb4185c1b4383a1195dca0f12e3946d737c7763bcef0b9544c515d905c5c44c5308b + languageName: node + linkType: hard + +"cheerio@npm:^1.0.0-rc.12": + version: 1.0.0 + resolution: "cheerio@npm:1.0.0" + dependencies: + cheerio-select: ^2.1.0 + dom-serializer: ^2.0.0 + domhandler: ^5.0.3 + domutils: ^3.1.0 + encoding-sniffer: ^0.2.0 + htmlparser2: ^9.1.0 + parse5: ^7.1.2 + parse5-htmlparser2-tree-adapter: ^7.0.0 + parse5-parser-stream: ^7.1.2 + undici: ^6.19.5 + whatwg-mimetype: ^4.0.0 + checksum: ade4344811dcad5b5d78392506ef6bab1900c13a65222c869e745a38370d287f4b94838ac6d752883a84d937edb62b5bd0deaf70e6f38054acbfe3da4881574a + languageName: node + linkType: hard + +"chokidar@npm:^3.5.3, chokidar@npm:^3.6.0": + version: 3.6.0 + resolution: "chokidar@npm:3.6.0" + dependencies: + anymatch: ~3.1.2 + braces: ~3.0.2 + fsevents: ~2.3.2 + glob-parent: ~5.1.2 + is-binary-path: ~2.1.0 + is-glob: ~4.0.1 + normalize-path: ~3.0.0 + readdirp: ~3.6.0 + dependenciesMeta: + fsevents: + optional: true + checksum: d2f29f499705dcd4f6f3bbed79a9ce2388cf530460122eed3b9c48efeab7a4e28739c6551fd15bec9245c6b9eeca7a32baa64694d64d9b6faeb74ddb8c4a413d + languageName: node + linkType: hard + "chownr@npm:^2.0.0": version: 2.0.0 resolution: "chownr@npm:2.0.0" @@ -2662,6 +4455,15 @@ __metadata: languageName: node linkType: hard +"citty@npm:^0.1.6": + version: 0.1.6 + resolution: "citty@npm:0.1.6" + dependencies: + consola: ^3.2.3 + checksum: 3fbcaaea92d328deddb5aba7d629d9076d4f1aa0338f59db7ea647a8f51eedc14b7f6218c87ad03c9e3c126213ba87d13d7774f9c30d64209f4b074aa83bd6ab + languageName: node + linkType: hard + "cjs-module-lexer@npm:^1.0.0": version: 1.2.2 resolution: "cjs-module-lexer@npm:1.2.2" @@ -2669,6 +4471,13 @@ __metadata: languageName: node linkType: hard +"classnames@npm:^2.3.2": + version: 2.3.2 + resolution: "classnames@npm:2.3.2" + checksum: 2c62199789618d95545c872787137262e741f9db13328e216b093eea91c85ef2bfb152c1f9e63027204e2559a006a92eb74147d46c800a9f96297ae1d9f96f4e + languageName: node + linkType: hard + "clean-stack@npm:^2.0.0": version: 2.2.0 resolution: "clean-stack@npm:2.2.0" @@ -2685,6 +4494,13 @@ __metadata: languageName: node linkType: hard +"cli-spinners@npm:^3.0.0": + version: 3.2.0 + resolution: "cli-spinners@npm:3.2.0" + checksum: c81430db85384819fe6d6ce3643f76f6c9382121aaee0375f3830f645c68d2ca2ab7cc286e23855764ae9672f5ca3f4e82e3a2e30d7f89122df45d60f5e0939e + languageName: node + linkType: hard + "cli-truncate@npm:^2.1.0": version: 2.1.0 resolution: "cli-truncate@npm:2.1.0" @@ -2705,6 +4521,13 @@ __metadata: languageName: node linkType: hard +"cli-width@npm:^4.1.0": + version: 4.1.0 + resolution: "cli-width@npm:4.1.0" + checksum: 0a79cff2dbf89ef530bcd54c713703ba94461457b11e5634bd024c78796ed21401e32349c004995954e06f442d82609287e7aabf6a5f02c919a1cf3b9b6854ff + languageName: node + linkType: hard + "clipanion@npm:^3.2.0-rc.10": version: 3.2.0-rc.16 resolution: "clipanion@npm:3.2.0-rc.16" @@ -2716,6 +4539,17 @@ __metadata: languageName: node linkType: hard +"cliui@npm:^7.0.2": + version: 7.0.4 + resolution: "cliui@npm:7.0.4" + dependencies: + string-width: ^4.2.0 + strip-ansi: ^6.0.0 + wrap-ansi: ^7.0.0 + checksum: ce2e8f578a4813806788ac399b9e866297740eecd4ad1823c27fd344d78b22c5f8597d548adbcc46f0573e43e21e751f39446c5a5e804a12aace402b7a315d7f + languageName: node + linkType: hard + "cliui@npm:^8.0.1": version: 8.0.1 resolution: "cliui@npm:8.0.1" @@ -2824,7 +4658,7 @@ __metadata: languageName: node linkType: hard -"commander@npm:^9.4.1": +"commander@npm:^9.3.0, commander@npm:^9.4.1": version: 9.5.0 resolution: "commander@npm:9.5.0" checksum: c7a3e27aa59e913b54a1bafd366b88650bc41d6651f0cbe258d4ff09d43d6a7394232a4dadd0bf518b3e696fdf595db1028a0d82c785b88bd61f8a440cecfade @@ -2843,6 +4677,26 @@ __metadata: languageName: node linkType: hard +"compatx@npm:^0.1.8": + version: 0.1.8 + resolution: "compatx@npm:0.1.8" + checksum: 0fb09f486f600906f08cd35c2ec4c95eb80767dc6d0a8a0dcd75ec2c488e5701ae18e713f95f876ed67ed3d88918846191f577e4c04a553dd8e3ae565a3e594c + languageName: node + linkType: hard + +"compress-commons@npm:^6.0.2": + version: 6.0.2 + resolution: "compress-commons@npm:6.0.2" + dependencies: + crc-32: ^1.2.0 + crc32-stream: ^6.0.0 + is-stream: ^2.0.1 + normalize-path: ^3.0.0 + readable-stream: ^4.0.0 + checksum: 37d79a54f91344ecde352588e0a128f28ce619b085acd4f887defd76978a0640e3454a42c7dcadb0191bb3f971724ae4b1f9d6ef9620034aa0427382099ac946 + languageName: node + linkType: hard + "concat-map@npm:0.0.1": version: 0.0.1 resolution: "concat-map@npm:0.0.1" @@ -2891,6 +4745,20 @@ __metadata: languageName: node linkType: hard +"confbox@npm:^0.1.7": + version: 0.1.7 + resolution: "confbox@npm:0.1.7" + checksum: bde836c26f5154a348b0c0a757f8a0138929e5737e0553be3c4f07a056abca618b861aa63ac3b22d344789b56be99a1382928933e08cd500df00213bf4d8fb43 + languageName: node + linkType: hard + +"consola@npm:^3.2.3": + version: 3.2.3 + resolution: "consola@npm:3.2.3" + checksum: 32ec70e177dd2385c42e38078958cc7397be91db21af90c6f9faa0b16168b49b1c61d689338604bbb2d64370b9347a35f42a9197663a913d3a405bb0ce728499 + languageName: node + linkType: hard + "console-control-strings@npm:^1.1.0": version: 1.1.0 resolution: "console-control-strings@npm:1.1.0" @@ -2928,7 +4796,43 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:7.0.3, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": +"crc-32@npm:^1.2.0": + version: 1.2.2 + resolution: "crc-32@npm:1.2.2" + bin: + crc32: bin/crc32.njs + checksum: ad2d0ad0cbd465b75dcaeeff0600f8195b686816ab5f3ba4c6e052a07f728c3e70df2e3ca9fd3d4484dc4ba70586e161ca5a2334ec8bf5a41bf022a6103ff243 + languageName: node + linkType: hard + +"crc32-stream@npm:^6.0.0": + version: 6.0.0 + resolution: "crc32-stream@npm:6.0.0" + dependencies: + crc-32: ^1.2.0 + readable-stream: ^4.0.0 + checksum: e6edc2f81bc387daef6d18b2ac18c2ffcb01b554d3b5c7d8d29b177505aafffba574658fdd23922767e8dab1183d1962026c98c17e17fb272794c33293ef607c + languageName: node + linkType: hard + +"create-jest@npm:^29.7.0": + version: 29.7.0 + resolution: "create-jest@npm:29.7.0" + dependencies: + "@jest/types": ^29.6.3 + chalk: ^4.0.0 + exit: ^0.1.2 + graceful-fs: ^4.2.9 + jest-config: ^29.7.0 + jest-util: ^29.7.0 + prompts: ^2.0.1 + bin: + create-jest: bin/create-jest.js + checksum: 1427d49458adcd88547ef6fa39041e1fe9033a661293aa8d2c3aa1b4967cb5bf4f0c00436c7a61816558f28ba2ba81a94d5c962e8022ea9a883978fc8e1f2945 + languageName: node + linkType: hard + +"cross-spawn@npm:7.0.3, cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": version: 7.0.3 resolution: "cross-spawn@npm:7.0.3" dependencies: @@ -2939,14 +4843,48 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^5.0.1": - version: 5.1.0 - resolution: "cross-spawn@npm:5.1.0" - dependencies: - lru-cache: ^4.0.1 - shebang-command: ^1.2.0 - which: ^1.2.9 - checksum: 726939c9954fc70c20e538923feaaa33bebc253247d13021737c3c7f68cdc3e0a57f720c0fe75057c0387995349f3f12e20e9bfdbf12274db28019c7ea4ec166 +"cross-spawn@npm:^5.0.1": + version: 5.1.0 + resolution: "cross-spawn@npm:5.1.0" + dependencies: + lru-cache: ^4.0.1 + shebang-command: ^1.2.0 + which: ^1.2.9 + checksum: 726939c9954fc70c20e538923feaaa33bebc253247d13021737c3c7f68cdc3e0a57f720c0fe75057c0387995349f3f12e20e9bfdbf12274db28019c7ea4ec166 + languageName: node + linkType: hard + +"css-select@npm:^5.1.0": + version: 5.1.0 + resolution: "css-select@npm:5.1.0" + dependencies: + boolbase: ^1.0.0 + css-what: ^6.1.0 + domhandler: ^5.0.2 + domutils: ^3.0.1 + nth-check: ^2.0.1 + checksum: 2772c049b188d3b8a8159907192e926e11824aea525b8282981f72ba3f349cf9ecd523fdf7734875ee2cb772246c22117fc062da105b6d59afe8dcd5c99c9bda + languageName: node + linkType: hard + +"css-shorthand-properties@npm:^1.1.1": + version: 1.1.1 + resolution: "css-shorthand-properties@npm:1.1.1" + checksum: 014b48e9fda528da7155cdf41e4ad9a0079ace4890e853d1d3ce4e41c2bb38c19e627d0be93dafe8b202c3a9fe83a6120b684e1405ee79b69ea8e248bd8833e9 + languageName: node + linkType: hard + +"css-value@npm:^0.0.1": + version: 0.0.1 + resolution: "css-value@npm:0.0.1" + checksum: 976a5832d1e5e5dc041903395a2842a382c7a0b150026f0f81671046f8125d4b86c7a9eed014a047c7a2111bc56d807d0e8d2e08b6e028798054593a9afc6b4d + languageName: node + linkType: hard + +"css-what@npm:^6.1.0": + version: 6.1.0 + resolution: "css-what@npm:6.1.0" + checksum: b975e547e1e90b79625918f84e67db5d33d896e6de846c9b584094e529f0c63e2ab85ee33b9daffd05bff3a146a1916bec664e18bb76dd5f66cbff9fc13b2bbe languageName: node linkType: hard @@ -2980,6 +4918,20 @@ __metadata: languageName: node linkType: hard +"data-uri-to-buffer@npm:^4.0.0": + version: 4.0.1 + resolution: "data-uri-to-buffer@npm:4.0.1" + checksum: 0d0790b67ffec5302f204c2ccca4494f70b4e2d940fea3d36b09f0bb2b8539c2e86690429eb1f1dc4bcc9e4df0644193073e63d9ee48ac9fce79ec1506e4aa4c + languageName: node + linkType: hard + +"data-uri-to-buffer@npm:^6.0.2": + version: 6.0.2 + resolution: "data-uri-to-buffer@npm:6.0.2" + checksum: 8b6927c33f9b54037f442856be0aa20e5fd49fa6c9c8ceece408dc306445d593ad72d207d57037c529ce65f413b421da800c6827b1dbefb607b8056f17123a61 + languageName: node + linkType: hard + "data-urls@npm:^3.0.2": version: 3.0.2 resolution: "data-urls@npm:3.0.2" @@ -3019,6 +4971,32 @@ __metadata: languageName: node linkType: hard +"debug@npm:^4.3.1, debug@npm:^4.3.5, debug@npm:^4.3.6": + version: 4.3.7 + resolution: "debug@npm:4.3.7" + dependencies: + ms: ^2.1.3 + peerDependenciesMeta: + supports-color: + optional: true + checksum: 822d74e209cd910ef0802d261b150314bbcf36c582ccdbb3e70f0894823c17e49a50d3e66d96b633524263975ca16b6a833f3e3b7e030c157169a5fabac63160 + languageName: node + linkType: hard + +"decamelize@npm:^4.0.0": + version: 4.0.0 + resolution: "decamelize@npm:4.0.0" + checksum: b7d09b82652c39eead4d6678bb578e3bebd848add894b76d0f6b395bc45b2d692fb88d977e7cfb93c4ed6c119b05a1347cef261174916c2e75c0a8ca57da1809 + languageName: node + linkType: hard + +"decamelize@npm:^6.0.0": + version: 6.0.0 + resolution: "decamelize@npm:6.0.0" + checksum: 0066bc30798ec11e01adf0c19ad975caef86545d4bb6f70cfb90b7eb8e3cbf7974cf774ac2e6ea2586e4e07b1f654bfecc4e772c42128a79a89f8584fc546753 + languageName: node + linkType: hard + "decimal.js@npm:^10.4.2": version: 10.4.3 resolution: "decimal.js@npm:10.4.3" @@ -3035,35 +5013,15 @@ __metadata: languageName: node linkType: hard -"dedent@npm:^0.7.0": - version: 0.7.0 - resolution: "dedent@npm:0.7.0" - checksum: 87de191050d9a40dd70cad01159a0bcf05ecb59750951242070b6abf9569088684880d00ba92a955b4058804f16eeaf91d604f283929b4f614d181cd7ae633d2 - languageName: node - linkType: hard - -"deep-equal@npm:^2.0.5": - version: 2.2.0 - resolution: "deep-equal@npm:2.2.0" - dependencies: - call-bind: ^1.0.2 - es-get-iterator: ^1.1.2 - get-intrinsic: ^1.1.3 - is-arguments: ^1.1.1 - is-array-buffer: ^3.0.1 - is-date-object: ^1.0.5 - is-regex: ^1.1.4 - is-shared-array-buffer: ^1.0.2 - isarray: ^2.0.5 - object-is: ^1.1.5 - object-keys: ^1.1.1 - object.assign: ^4.1.4 - regexp.prototype.flags: ^1.4.3 - side-channel: ^1.0.4 - which-boxed-primitive: ^1.0.2 - which-collection: ^1.0.1 - which-typed-array: ^1.1.9 - checksum: 46a34509d2766d6c6dc5aec4756089cf0cc137e46787e91f08f1ee0bb570d874f19f0493146907df0cf18aed4a7b4b50f6f62c899240a76c323f057528b122e3 +"dedent@npm:^1.0.0": + version: 1.5.3 + resolution: "dedent@npm:1.5.3" + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + checksum: 045b595557b2a8ea2eb9b0b4623d764e9a87326486fe2b61191b4342ed93dc01245644d8a09f3108a50c0ee7965f1eedd92e4a3a503ed89ea8e810566ea27f9a languageName: node linkType: hard @@ -3074,6 +5032,13 @@ __metadata: languageName: node linkType: hard +"deepmerge-ts@npm:^7.0.3": + version: 7.1.0 + resolution: "deepmerge-ts@npm:7.1.0" + checksum: 8c36d7e88b12248e138ba0f959c03e5b6d008842acbc7bb3c43a0513b4b942f936352b8910ac75bcbe1fc61d3975b4e0ab5b13b2492f0ede06f95553c637479e + languageName: node + linkType: hard + "deepmerge@npm:^4.2.2": version: 4.3.0 resolution: "deepmerge@npm:4.3.0" @@ -3105,6 +5070,24 @@ __metadata: languageName: node linkType: hard +"defu@npm:^6.1.4": + version: 6.1.4 + resolution: "defu@npm:6.1.4" + checksum: 40e3af6338f195ac1564f53d1887fa2d0429ac7e8c081204bc4d29191180059d3952b5f4e08fe5df8d59eb873aa26e9c88b56d4fac699673d4a372c93620b229 + languageName: node + linkType: hard + +"degenerator@npm:^5.0.0": + version: 5.0.1 + resolution: "degenerator@npm:5.0.1" + dependencies: + ast-types: ^0.13.4 + escodegen: ^2.1.0 + esprima: ^4.0.1 + checksum: a64fa39cdf6c2edd75188157d32338ee9de7193d7dbb2aeb4acb1eb30fa4a15ed80ba8dae9bd4d7b085472cf174a5baf81adb761aaa8e326771392c922084152 + languageName: node + linkType: hard + "delayed-stream@npm:~1.0.0": version: 1.0.0 resolution: "delayed-stream@npm:1.0.0" @@ -3126,6 +5109,20 @@ __metadata: languageName: node linkType: hard +"dequal@npm:^2.0.3": + version: 2.0.3 + resolution: "dequal@npm:2.0.3" + checksum: 8679b850e1a3d0ebbc46ee780d5df7b478c23f335887464023a631d1b9af051ad4a6595a44220f9ff8ff95a8ddccf019b5ad778a976fd7bbf77383d36f412f90 + languageName: node + linkType: hard + +"destr@npm:^2.0.3": + version: 2.0.3 + resolution: "destr@npm:2.0.3" + checksum: 4521b145ba6118919a561f7d979d623793695a516d1b9df704de81932601bf9cf21c47278e1cb93a309c88a14f4fd1f18680bb49ebef8b2546cc7f415e7ae48e + languageName: node + linkType: hard + "detect-newline@npm:^3.0.0": version: 3.1.0 resolution: "detect-newline@npm:3.1.0" @@ -3147,10 +5144,17 @@ __metadata: languageName: node linkType: hard -"diff-sequences@npm:^29.3.1": - version: 29.3.1 - resolution: "diff-sequences@npm:29.3.1" - checksum: 8edab8c383355022e470779a099852d595dd856f9f5bd7af24f177e74138a668932268b4c4fd54096eed643861575c3652d4ecbbb1a9d710488286aed3ffa443 +"diff-sequences@npm:^29.4.3": + version: 29.4.3 + resolution: "diff-sequences@npm:29.4.3" + checksum: 28b265e04fdddcf7f9f814effe102cc95a9dec0564a579b5aed140edb24fc345c611ca52d76d725a3cab55d3888b915b5e8a4702e0f6058968a90fa5f41fcde7 + languageName: node + linkType: hard + +"diff-sequences@npm:^29.6.3": + version: 29.6.3 + resolution: "diff-sequences@npm:29.6.3" + checksum: f4914158e1f2276343d98ff5b31fc004e7304f5470bf0f1adb2ac6955d85a531a6458d33e87667f98f6ae52ebd3891bb47d420bb48a5bd8b7a27ee25b20e33aa languageName: node linkType: hard @@ -3161,6 +5165,13 @@ __metadata: languageName: node linkType: hard +"diff@npm:^5.2.0": + version: 5.2.0 + resolution: "diff@npm:5.2.0" + checksum: 12b63ca9c36c72bafa3effa77121f0581b4015df18bc16bac1f8e263597735649f1a173c26f7eba17fb4162b073fee61788abe49610e6c70a2641fe1895443fd + languageName: node + linkType: hard + "dir-glob@npm:^3.0.1": version: 3.0.1 resolution: "dir-glob@npm:3.0.1" @@ -3195,6 +5206,24 @@ __metadata: languageName: node linkType: hard +"dom-serializer@npm:^2.0.0": + version: 2.0.0 + resolution: "dom-serializer@npm:2.0.0" + dependencies: + domelementtype: ^2.3.0 + domhandler: ^5.0.2 + entities: ^4.2.0 + checksum: cd1810544fd8cdfbd51fa2c0c1128ec3a13ba92f14e61b7650b5de421b88205fd2e3f0cc6ace82f13334114addb90ed1c2f23074a51770a8e9c1273acbc7f3e6 + languageName: node + linkType: hard + +"domelementtype@npm:^2.3.0": + version: 2.3.0 + resolution: "domelementtype@npm:2.3.0" + checksum: ee837a318ff702622f383409d1f5b25dd1024b692ef64d3096ff702e26339f8e345820f29a68bcdcea8cfee3531776b3382651232fbeae95612d6f0a75efb4f6 + languageName: node + linkType: hard + "domexception@npm:^4.0.0": version: 4.0.0 resolution: "domexception@npm:4.0.0" @@ -3204,6 +5233,33 @@ __metadata: languageName: node linkType: hard +"domhandler@npm:^5.0.2, domhandler@npm:^5.0.3": + version: 5.0.3 + resolution: "domhandler@npm:5.0.3" + dependencies: + domelementtype: ^2.3.0 + checksum: 0f58f4a6af63e6f3a4320aa446d28b5790a009018707bce2859dcb1d21144c7876482b5188395a188dfa974238c019e0a1e610d2fc269a12b2c192ea2b0b131c + languageName: node + linkType: hard + +"domutils@npm:^3.0.1, domutils@npm:^3.1.0": + version: 3.1.0 + resolution: "domutils@npm:3.1.0" + dependencies: + dom-serializer: ^2.0.0 + domelementtype: ^2.3.0 + domhandler: ^5.0.3 + checksum: e5757456ddd173caa411cfc02c2bb64133c65546d2c4081381a3bafc8a57411a41eed70494551aa58030be9e58574fcc489828bebd673863d39924fb4878f416 + languageName: node + linkType: hard + +"dotenv@npm:^16.3.1, dotenv@npm:^16.4.5": + version: 16.4.5 + resolution: "dotenv@npm:16.4.5" + checksum: 301a12c3d44fd49888b74eb9ccf9f07a1f5df43f489e7fcb89647a2edcd84c42d6bc349dc8df099cd18f07c35c7b04685c1a4f3e6a6a9e6b30f8d48c15b7f49c + languageName: node + linkType: hard + "eastasianwidth@npm:^0.2.0": version: 0.2.0 resolution: "eastasianwidth@npm:0.2.0" @@ -3211,6 +5267,44 @@ __metadata: languageName: node linkType: hard +"edge-paths@npm:^3.0.5": + version: 3.0.5 + resolution: "edge-paths@npm:3.0.5" + dependencies: + "@types/which": ^2.0.1 + which: ^2.0.2 + checksum: 76ea4380ad2e9c259b76493c33c335cb9043ab450f8fc8b26b8123c0b2d78325e1e824220ffc9380fa50d9ac8d82d9bf25af14a637f627eb2f7d9fd099421069 + languageName: node + linkType: hard + +"edgedriver@npm:^5.6.1": + version: 5.6.1 + resolution: "edgedriver@npm:5.6.1" + dependencies: + "@wdio/logger": ^8.38.0 + "@zip.js/zip.js": ^2.7.48 + decamelize: ^6.0.0 + edge-paths: ^3.0.5 + fast-xml-parser: ^4.4.1 + node-fetch: ^3.3.2 + which: ^4.0.0 + bin: + edgedriver: bin/edgedriver.js + checksum: af6f00162785bc23742e9f2960d58a6e67d9adab6e66c16e92dfabd2951b243ef2d883d8a51389d271113c968fba756c3a35dcb1f6ed75f86eae4715e36161ff + languageName: node + linkType: hard + +"ejs@npm:^3.1.9": + version: 3.1.10 + resolution: "ejs@npm:3.1.10" + dependencies: + jake: ^10.8.5 + bin: + ejs: bin/cli.js + checksum: ce90637e9c7538663ae023b8a7a380b2ef7cc4096de70be85abf5a3b9641912dde65353211d05e24d56b1f242d71185c6d00e02cb8860701d571786d92c71f05 + languageName: node + linkType: hard + "electron-to-chromium@npm:^1.4.284": version: 1.4.286 resolution: "electron-to-chromium@npm:1.4.286" @@ -3218,6 +5312,13 @@ __metadata: languageName: node linkType: hard +"electron-to-chromium@npm:^1.5.4": + version: 1.5.23 + resolution: "electron-to-chromium@npm:1.5.23" + checksum: bc80f540120ffcc762caa199fb79fafb83aad97b2548e89222e61b31e7b7c58b7b10755b495d5ab3a245972a8790b4786ce9c1e2210e49a1231e012c42d44f73 + languageName: node + linkType: hard + "emittery@npm:^0.13.1": version: 0.13.1 resolution: "emittery@npm:0.13.1" @@ -3239,6 +5340,16 @@ __metadata: languageName: node linkType: hard +"encoding-sniffer@npm:^0.2.0": + version: 0.2.0 + resolution: "encoding-sniffer@npm:0.2.0" + dependencies: + iconv-lite: ^0.6.3 + whatwg-encoding: ^3.1.1 + checksum: 05ad76b674066e62abc80427eb9e89ecf5ed50f4d20c392f7465992d309215687e3ae1ae8b5d5694fb258f4517c759694c3b413d6c724e1024e1cf98750390eb + languageName: node + linkType: hard + "encoding@npm:^0.1.13": version: 0.1.13 resolution: "encoding@npm:0.1.13" @@ -3267,6 +5378,13 @@ __metadata: languageName: node linkType: hard +"entities@npm:^4.2.0, entities@npm:^4.5.0": + version: 4.5.0 + resolution: "entities@npm:4.5.0" + checksum: 853f8ebd5b425d350bffa97dd6958143179a5938352ccae092c62d1267c4e392a039be1bae7d51b6e4ffad25f51f9617531fedf5237f15df302ccfb452cbf2d7 + languageName: node + linkType: hard + "entities@npm:^4.4.0": version: 4.4.0 resolution: "entities@npm:4.4.0" @@ -3288,7 +5406,7 @@ __metadata: languageName: node linkType: hard -"error-ex@npm:^1.3.1": +"error-ex@npm:^1.3.1, error-ex@npm:^1.3.2": version: 1.3.2 resolution: "error-ex@npm:1.3.2" dependencies: @@ -3297,122 +5415,403 @@ __metadata: languageName: node linkType: hard -"es-abstract@npm:^1.19.0, es-abstract@npm:^1.20.4": - version: 1.21.1 - resolution: "es-abstract@npm:1.21.1" - dependencies: - available-typed-arrays: ^1.0.5 - call-bind: ^1.0.2 - es-set-tostringtag: ^2.0.1 - es-to-primitive: ^1.2.1 - function-bind: ^1.1.1 - function.prototype.name: ^1.1.5 - get-intrinsic: ^1.1.3 - get-symbol-description: ^1.0.0 - globalthis: ^1.0.3 - gopd: ^1.0.1 - has: ^1.0.3 - has-property-descriptors: ^1.0.0 - has-proto: ^1.0.1 - has-symbols: ^1.0.3 - internal-slot: ^1.0.4 - is-array-buffer: ^3.0.1 - is-callable: ^1.2.7 - is-negative-zero: ^2.0.2 - is-regex: ^1.1.4 - is-shared-array-buffer: ^1.0.2 - is-string: ^1.0.7 - is-typed-array: ^1.1.10 - is-weakref: ^1.0.2 - object-inspect: ^1.12.2 - object-keys: ^1.1.1 - object.assign: ^4.1.4 - regexp.prototype.flags: ^1.4.3 - safe-regex-test: ^1.0.0 - string.prototype.trimend: ^1.0.6 - string.prototype.trimstart: ^1.0.6 - typed-array-length: ^1.0.4 - unbox-primitive: ^1.0.2 - which-typed-array: ^1.1.9 - checksum: 23ff60d42d17a55d150e7bcedbdb065d4077a8b98c436e0e2e1ef4dd532a6d78a56028673de0bd8ed464a43c46ba781c50d9af429b6a17e44dbd14c7d7fb7926 +"es-abstract@npm:^1.19.0, es-abstract@npm:^1.20.4": + version: 1.21.1 + resolution: "es-abstract@npm:1.21.1" + dependencies: + available-typed-arrays: ^1.0.5 + call-bind: ^1.0.2 + es-set-tostringtag: ^2.0.1 + es-to-primitive: ^1.2.1 + function-bind: ^1.1.1 + function.prototype.name: ^1.1.5 + get-intrinsic: ^1.1.3 + get-symbol-description: ^1.0.0 + globalthis: ^1.0.3 + gopd: ^1.0.1 + has: ^1.0.3 + has-property-descriptors: ^1.0.0 + has-proto: ^1.0.1 + has-symbols: ^1.0.3 + internal-slot: ^1.0.4 + is-array-buffer: ^3.0.1 + is-callable: ^1.2.7 + is-negative-zero: ^2.0.2 + is-regex: ^1.1.4 + is-shared-array-buffer: ^1.0.2 + is-string: ^1.0.7 + is-typed-array: ^1.1.10 + is-weakref: ^1.0.2 + object-inspect: ^1.12.2 + object-keys: ^1.1.1 + object.assign: ^4.1.4 + regexp.prototype.flags: ^1.4.3 + safe-regex-test: ^1.0.0 + string.prototype.trimend: ^1.0.6 + string.prototype.trimstart: ^1.0.6 + typed-array-length: ^1.0.4 + unbox-primitive: ^1.0.2 + which-typed-array: ^1.1.9 + checksum: 23ff60d42d17a55d150e7bcedbdb065d4077a8b98c436e0e2e1ef4dd532a6d78a56028673de0bd8ed464a43c46ba781c50d9af429b6a17e44dbd14c7d7fb7926 + languageName: node + linkType: hard + +"es-set-tostringtag@npm:^2.0.1": + version: 2.0.1 + resolution: "es-set-tostringtag@npm:2.0.1" + dependencies: + get-intrinsic: ^1.1.3 + has: ^1.0.3 + has-tostringtag: ^1.0.0 + checksum: ec416a12948cefb4b2a5932e62093a7cf36ddc3efd58d6c58ca7ae7064475ace556434b869b0bbeb0c365f1032a8ccd577211101234b69837ad83ad204fff884 + languageName: node + linkType: hard + +"es-shim-unscopables@npm:^1.0.0": + version: 1.0.0 + resolution: "es-shim-unscopables@npm:1.0.0" + dependencies: + has: ^1.0.3 + checksum: 83e95cadbb6ee44d3644dfad60dcad7929edbc42c85e66c3e99aefd68a3a5c5665f2686885cddb47dfeabfd77bd5ea5a7060f2092a955a729bbd8834f0d86fa1 + languageName: node + linkType: hard + +"es-to-primitive@npm:^1.2.1": + version: 1.2.1 + resolution: "es-to-primitive@npm:1.2.1" + dependencies: + is-callable: ^1.1.4 + is-date-object: ^1.0.1 + is-symbol: ^1.0.2 + checksum: 4ead6671a2c1402619bdd77f3503991232ca15e17e46222b0a41a5d81aebc8740a77822f5b3c965008e631153e9ef0580540007744521e72de8e33599fca2eed + languageName: node + linkType: hard + +"esbuild-android-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-android-64@npm:0.14.54" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"esbuild-android-arm64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-android-arm64@npm:0.14.54" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"esbuild-darwin-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-darwin-64@npm:0.14.54" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"esbuild-darwin-arm64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-darwin-arm64@npm:0.14.54" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"esbuild-freebsd-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-freebsd-64@npm:0.14.54" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"esbuild-freebsd-arm64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-freebsd-arm64@npm:0.14.54" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"esbuild-linux-32@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-32@npm:0.14.54" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"esbuild-linux-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-64@npm:0.14.54" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"esbuild-linux-arm64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-arm64@npm:0.14.54" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"esbuild-linux-arm@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-arm@npm:0.14.54" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"esbuild-linux-mips64le@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-mips64le@npm:0.14.54" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"esbuild-linux-ppc64le@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-ppc64le@npm:0.14.54" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"esbuild-linux-riscv64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-riscv64@npm:0.14.54" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"esbuild-linux-s390x@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-s390x@npm:0.14.54" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"esbuild-netbsd-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-netbsd-64@npm:0.14.54" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"esbuild-openbsd-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-openbsd-64@npm:0.14.54" + conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"es-get-iterator@npm:^1.1.2": - version: 1.1.3 - resolution: "es-get-iterator@npm:1.1.3" - dependencies: - call-bind: ^1.0.2 - get-intrinsic: ^1.1.3 - has-symbols: ^1.0.3 - is-arguments: ^1.1.1 - is-map: ^2.0.2 - is-set: ^2.0.2 - is-string: ^1.0.7 - isarray: ^2.0.5 - stop-iteration-iterator: ^1.0.0 - checksum: 8fa118da42667a01a7c7529f8a8cca514feeff243feec1ce0bb73baaa3514560bd09d2b3438873cf8a5aaec5d52da248131de153b28e2638a061b6e4df13267d +"esbuild-sunos-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-sunos-64@npm:0.14.54" + conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"es-set-tostringtag@npm:^2.0.1": - version: 2.0.1 - resolution: "es-set-tostringtag@npm:2.0.1" - dependencies: - get-intrinsic: ^1.1.3 - has: ^1.0.3 - has-tostringtag: ^1.0.0 - checksum: ec416a12948cefb4b2a5932e62093a7cf36ddc3efd58d6c58ca7ae7064475ace556434b869b0bbeb0c365f1032a8ccd577211101234b69837ad83ad204fff884 +"esbuild-windows-32@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-windows-32@npm:0.14.54" + conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"es-shim-unscopables@npm:^1.0.0": - version: 1.0.0 - resolution: "es-shim-unscopables@npm:1.0.0" - dependencies: - has: ^1.0.3 - checksum: 83e95cadbb6ee44d3644dfad60dcad7929edbc42c85e66c3e99aefd68a3a5c5665f2686885cddb47dfeabfd77bd5ea5a7060f2092a955a729bbd8834f0d86fa1 +"esbuild-windows-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-windows-64@npm:0.14.54" + conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"es-to-primitive@npm:^1.2.1": - version: 1.2.1 - resolution: "es-to-primitive@npm:1.2.1" - dependencies: - is-callable: ^1.1.4 - is-date-object: ^1.0.1 - is-symbol: ^1.0.2 - checksum: 4ead6671a2c1402619bdd77f3503991232ca15e17e46222b0a41a5d81aebc8740a77822f5b3c965008e631153e9ef0580540007744521e72de8e33599fca2eed +"esbuild-windows-arm64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-windows-arm64@npm:0.14.54" + conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"esbuild@npm:^0.17.5": - version: 0.17.19 - resolution: "esbuild@npm:0.17.19" - dependencies: - "@esbuild/android-arm": 0.17.19 - "@esbuild/android-arm64": 0.17.19 - "@esbuild/android-x64": 0.17.19 - "@esbuild/darwin-arm64": 0.17.19 - "@esbuild/darwin-x64": 0.17.19 - "@esbuild/freebsd-arm64": 0.17.19 - "@esbuild/freebsd-x64": 0.17.19 - "@esbuild/linux-arm": 0.17.19 - "@esbuild/linux-arm64": 0.17.19 - "@esbuild/linux-ia32": 0.17.19 - "@esbuild/linux-loong64": 0.17.19 - "@esbuild/linux-mips64el": 0.17.19 - "@esbuild/linux-ppc64": 0.17.19 - "@esbuild/linux-riscv64": 0.17.19 - "@esbuild/linux-s390x": 0.17.19 - "@esbuild/linux-x64": 0.17.19 - "@esbuild/netbsd-x64": 0.17.19 - "@esbuild/openbsd-x64": 0.17.19 - "@esbuild/sunos-x64": 0.17.19 - "@esbuild/win32-arm64": 0.17.19 - "@esbuild/win32-ia32": 0.17.19 - "@esbuild/win32-x64": 0.17.19 +"esbuild@npm:^0.14.14": + version: 0.14.54 + resolution: "esbuild@npm:0.14.54" + dependencies: + "@esbuild/linux-loong64": 0.14.54 + esbuild-android-64: 0.14.54 + esbuild-android-arm64: 0.14.54 + esbuild-darwin-64: 0.14.54 + esbuild-darwin-arm64: 0.14.54 + esbuild-freebsd-64: 0.14.54 + esbuild-freebsd-arm64: 0.14.54 + esbuild-linux-32: 0.14.54 + esbuild-linux-64: 0.14.54 + esbuild-linux-arm: 0.14.54 + esbuild-linux-arm64: 0.14.54 + esbuild-linux-mips64le: 0.14.54 + esbuild-linux-ppc64le: 0.14.54 + esbuild-linux-riscv64: 0.14.54 + esbuild-linux-s390x: 0.14.54 + esbuild-netbsd-64: 0.14.54 + esbuild-openbsd-64: 0.14.54 + esbuild-sunos-64: 0.14.54 + esbuild-windows-32: 0.14.54 + esbuild-windows-64: 0.14.54 + esbuild-windows-arm64: 0.14.54 + dependenciesMeta: + "@esbuild/linux-loong64": + optional: true + esbuild-android-64: + optional: true + esbuild-android-arm64: + optional: true + esbuild-darwin-64: + optional: true + esbuild-darwin-arm64: + optional: true + esbuild-freebsd-64: + optional: true + esbuild-freebsd-arm64: + optional: true + esbuild-linux-32: + optional: true + esbuild-linux-64: + optional: true + esbuild-linux-arm: + optional: true + esbuild-linux-arm64: + optional: true + esbuild-linux-mips64le: + optional: true + esbuild-linux-ppc64le: + optional: true + esbuild-linux-riscv64: + optional: true + esbuild-linux-s390x: + optional: true + esbuild-netbsd-64: + optional: true + esbuild-openbsd-64: + optional: true + esbuild-sunos-64: + optional: true + esbuild-windows-32: + optional: true + esbuild-windows-64: + optional: true + esbuild-windows-arm64: + optional: true + bin: + esbuild: bin/esbuild + checksum: 49e360b1185c797f5ca3a7f5f0a75121494d97ddf691f65ed1796e6257d318f928342a97f559bb8eced6a90cf604dd22db4a30e0dbbf15edd9dbf22459b639af + languageName: node + linkType: hard + +"esbuild@npm:^0.21.3": + version: 0.21.5 + resolution: "esbuild@npm:0.21.5" + dependencies: + "@esbuild/aix-ppc64": 0.21.5 + "@esbuild/android-arm": 0.21.5 + "@esbuild/android-arm64": 0.21.5 + "@esbuild/android-x64": 0.21.5 + "@esbuild/darwin-arm64": 0.21.5 + "@esbuild/darwin-x64": 0.21.5 + "@esbuild/freebsd-arm64": 0.21.5 + "@esbuild/freebsd-x64": 0.21.5 + "@esbuild/linux-arm": 0.21.5 + "@esbuild/linux-arm64": 0.21.5 + "@esbuild/linux-ia32": 0.21.5 + "@esbuild/linux-loong64": 0.21.5 + "@esbuild/linux-mips64el": 0.21.5 + "@esbuild/linux-ppc64": 0.21.5 + "@esbuild/linux-riscv64": 0.21.5 + "@esbuild/linux-s390x": 0.21.5 + "@esbuild/linux-x64": 0.21.5 + "@esbuild/netbsd-x64": 0.21.5 + "@esbuild/openbsd-x64": 0.21.5 + "@esbuild/sunos-x64": 0.21.5 + "@esbuild/win32-arm64": 0.21.5 + "@esbuild/win32-ia32": 0.21.5 + "@esbuild/win32-x64": 0.21.5 + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 2911c7b50b23a9df59a7d6d4cdd3a4f85855787f374dce751148dbb13305e0ce7e880dde1608c2ab7a927fc6cec3587b80995f7fc87a64b455f8b70b55fd8ec1 + languageName: node + linkType: hard + +"esbuild@npm:~0.23.0": + version: 0.23.1 + resolution: "esbuild@npm:0.23.1" + dependencies: + "@esbuild/aix-ppc64": 0.23.1 + "@esbuild/android-arm": 0.23.1 + "@esbuild/android-arm64": 0.23.1 + "@esbuild/android-x64": 0.23.1 + "@esbuild/darwin-arm64": 0.23.1 + "@esbuild/darwin-x64": 0.23.1 + "@esbuild/freebsd-arm64": 0.23.1 + "@esbuild/freebsd-x64": 0.23.1 + "@esbuild/linux-arm": 0.23.1 + "@esbuild/linux-arm64": 0.23.1 + "@esbuild/linux-ia32": 0.23.1 + "@esbuild/linux-loong64": 0.23.1 + "@esbuild/linux-mips64el": 0.23.1 + "@esbuild/linux-ppc64": 0.23.1 + "@esbuild/linux-riscv64": 0.23.1 + "@esbuild/linux-s390x": 0.23.1 + "@esbuild/linux-x64": 0.23.1 + "@esbuild/netbsd-x64": 0.23.1 + "@esbuild/openbsd-arm64": 0.23.1 + "@esbuild/openbsd-x64": 0.23.1 + "@esbuild/sunos-x64": 0.23.1 + "@esbuild/win32-arm64": 0.23.1 + "@esbuild/win32-ia32": 0.23.1 + "@esbuild/win32-x64": 0.23.1 dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true "@esbuild/android-arm": optional: true "@esbuild/android-arm64": @@ -3447,6 +5846,8 @@ __metadata: optional: true "@esbuild/netbsd-x64": optional: true + "@esbuild/openbsd-arm64": + optional: true "@esbuild/openbsd-x64": optional: true "@esbuild/sunos-x64": @@ -3459,7 +5860,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: ac11b1a5a6008e4e37ccffbd6c2c054746fc58d0ed4a2f9ee643bd030cfcea9a33a235087bc777def8420f2eaafb3486e76adb7bdb7241a9143b43a69a10afd8 + checksum: 0413c3b9257327fb598427688b7186ea335bf1693746fe5713cc93c95854d6388b8ed4ad643fddf5b5ace093f7dcd9038dd58e087bf2da1f04dfb4c5571660af languageName: node linkType: hard @@ -3470,6 +5871,13 @@ __metadata: languageName: node linkType: hard +"escalade@npm:^3.1.2": + version: 3.2.0 + resolution: "escalade@npm:3.2.0" + checksum: 47b029c83de01b0d17ad99ed766347b974b0d628e848de404018f3abee728e987da0d2d370ad4574aa3d5b5bfc368754fd085d69a30f8e75903486ec4b5b709e + languageName: node + linkType: hard + "escape-string-regexp@npm:^1.0.5": version: 1.0.5 resolution: "escape-string-regexp@npm:1.0.5" @@ -3517,6 +5925,24 @@ __metadata: languageName: node linkType: hard +"escodegen@npm:^2.1.0": + version: 2.1.0 + resolution: "escodegen@npm:2.1.0" + dependencies: + esprima: ^4.0.1 + estraverse: ^5.2.0 + esutils: ^2.0.2 + source-map: ~0.6.1 + dependenciesMeta: + source-map: + optional: true + bin: + escodegen: bin/escodegen.js + esgenerate: bin/esgenerate.js + checksum: 096696407e161305cd05aebb95134ad176708bc5cb13d0dcc89a5fcbb959b8ed757e7f2591a5f8036f8f4952d4a724de0df14cd419e29212729fa6df5ce16bf6 + languageName: node + linkType: hard + "eslint-config-prettier@npm:^8.6.0": version: 8.6.0 resolution: "eslint-config-prettier@npm:8.6.0" @@ -3690,6 +6116,13 @@ __metadata: languageName: node linkType: hard +"eslint-visitor-keys@npm:^4.0.0": + version: 4.0.0 + resolution: "eslint-visitor-keys@npm:4.0.0" + checksum: 5c09f89cf29d87cdbfbac38802a880d3c2e65f8cb61c689888346758f1e24a4c7f6caefeac9474dfa52058a99920623599bdb00516976a30134abeba91275aa2 + languageName: node + linkType: hard + "eslint@npm:^8.33.0": version: 8.33.0 resolution: "eslint@npm:8.33.0" @@ -3739,6 +6172,17 @@ __metadata: languageName: node linkType: hard +"espree@npm:^10.0.1": + version: 10.1.0 + resolution: "espree@npm:10.1.0" + dependencies: + acorn: ^8.12.0 + acorn-jsx: ^5.3.2 + eslint-visitor-keys: ^4.0.0 + checksum: a4708ab987f6c03734b8738b1588e9f31b2e305e869ca4677c60d82294eb05f7099b6687eb39eeb0913bb2d49bdf0bd0f31c511599ea7ee171281f871a9c897e + languageName: node + linkType: hard + "espree@npm:^9.4.0": version: 9.4.1 resolution: "espree@npm:9.4.1" @@ -3750,7 +6194,7 @@ __metadata: languageName: node linkType: hard -"esprima@npm:^4.0.0, esprima@npm:^4.0.1": +"esprima@npm:^4.0.0, esprima@npm:^4.0.1, esprima@npm:~4.0.0": version: 4.0.1 resolution: "esprima@npm:4.0.1" bin: @@ -3792,6 +6236,22 @@ __metadata: languageName: node linkType: hard +"estree-walker@npm:^2.0.2": + version: 2.0.2 + resolution: "estree-walker@npm:2.0.2" + checksum: 6151e6f9828abe2259e57f5fd3761335bb0d2ebd76dc1a01048ccee22fabcfef3c0859300f6d83ff0d1927849368775ec5a6d265dde2f6de5a1be1721cd94efc + languageName: node + linkType: hard + +"estree-walker@npm:^3.0.3": + version: 3.0.3 + resolution: "estree-walker@npm:3.0.3" + dependencies: + "@types/estree": ^1.0.0 + checksum: a65728d5727b71de172c5df323385755a16c0fdab8234dc756c3854cfee343261ddfbb72a809a5660fac8c75d960bb3e21aa898c2d7e9b19bb298482ca58a3af + languageName: node + linkType: hard + "esutils@npm:^2.0.2": version: 2.0.3 resolution: "esutils@npm:2.0.3" @@ -3799,6 +6259,20 @@ __metadata: languageName: node linkType: hard +"event-target-shim@npm:^5.0.0": + version: 5.0.1 + resolution: "event-target-shim@npm:5.0.1" + checksum: 1ffe3bb22a6d51bdeb6bf6f7cf97d2ff4a74b017ad12284cc9e6a279e727dc30a5de6bb613e5596ff4dc3e517841339ad09a7eec44266eccb1aa201a30448166 + languageName: node + linkType: hard + +"events@npm:^3.3.0": + version: 3.3.0 + resolution: "events@npm:3.3.0" + checksum: f6f487ad2198aa41d878fa31452f1a3c00958f46e9019286ff4787c84aac329332ab45c9cdc8c445928fc6d7ded294b9e005a7fce9426488518017831b272780 + languageName: node + linkType: hard + "execa@npm:^0.7.0": version: 0.7.0 resolution: "execa@npm:0.7.0" @@ -3848,6 +6322,43 @@ __metadata: languageName: node linkType: hard +"execa@npm:^8.0.1": + version: 8.0.1 + resolution: "execa@npm:8.0.1" + dependencies: + cross-spawn: ^7.0.3 + get-stream: ^8.0.1 + human-signals: ^5.0.0 + is-stream: ^3.0.0 + merge-stream: ^2.0.0 + npm-run-path: ^5.1.0 + onetime: ^6.0.0 + signal-exit: ^4.1.0 + strip-final-newline: ^3.0.0 + checksum: cac1bf86589d1d9b73bdc5dda65c52012d1a9619c44c526891956745f7b366ca2603d29fe3f7460bacc2b48c6eab5d6a4f7afe0534b31473d3708d1265545e1f + languageName: node + linkType: hard + +"execa@npm:^9.2.0": + version: 9.3.1 + resolution: "execa@npm:9.3.1" + dependencies: + "@sindresorhus/merge-streams": ^4.0.0 + cross-spawn: ^7.0.3 + figures: ^6.1.0 + get-stream: ^9.0.0 + human-signals: ^8.0.0 + is-plain-obj: ^4.1.0 + is-stream: ^4.0.1 + npm-run-path: ^5.2.0 + pretty-ms: ^9.0.0 + signal-exit: ^4.1.0 + strip-final-newline: ^4.0.0 + yoctocolors: ^2.0.0 + checksum: 8a7529de3c99a7039eb7b9063afb423332c1b8255002e0414983454f06efb915225ac79011db0a0b55f3144086d409a1daf47e1066b7cd09eba596dae87dba49 + languageName: node + linkType: hard + "executable@npm:^4.1.0": version: 4.1.1 resolution: "executable@npm:4.1.1" @@ -3873,16 +6384,53 @@ __metadata: languageName: node linkType: hard -"expect@npm:^29.4.1": - version: 29.4.1 - resolution: "expect@npm:29.4.1" +"expect-webdriverio@npm:^5.0.1": + version: 5.0.2 + resolution: "expect-webdriverio@npm:5.0.2" + dependencies: + "@vitest/snapshot": ^2.0.5 + expect: ^29.7.0 + jest-matcher-utils: ^29.7.0 + lodash.isequal: ^4.5.0 + peerDependencies: + "@wdio/globals": ^9.0.0 + "@wdio/logger": ^9.0.0 + webdriverio: ^9.0.0 + peerDependenciesMeta: + "@wdio/globals": + optional: false + "@wdio/logger": + optional: false + webdriverio: + optional: false + checksum: a1d29497bebe85c66b49e7b6af8472f1d655ffcfbd57ace6fd9eef69df63d8bace0ce73aa865a98b274a5a4d85b9c1489a7a7a0cdc65f25df13cfef5ac67a63d + languageName: node + linkType: hard + +"expect@npm:^29.6.2": + version: 29.6.2 + resolution: "expect@npm:29.6.2" + dependencies: + "@jest/expect-utils": ^29.6.2 + "@types/node": "*" + jest-get-type: ^29.4.3 + jest-matcher-utils: ^29.6.2 + jest-message-util: ^29.6.2 + jest-util: ^29.6.2 + checksum: 71f7b0c560e58bf6d27e0fded261d4bdb7ef81552a6bb4bd1ee09ce7a1f7dca67fbf83cf9b07a6645a88ef52e65085a0dcbe17f6c063b53ff7c2f0f3ea4ef69e + languageName: node + linkType: hard + +"expect@npm:^29.7.0": + version: 29.7.0 + resolution: "expect@npm:29.7.0" dependencies: - "@jest/expect-utils": ^29.4.1 - jest-get-type: ^29.2.0 - jest-matcher-utils: ^29.4.1 - jest-message-util: ^29.4.1 - jest-util: ^29.4.1 - checksum: 5918f69371557bbceb01bc163cd0ac03e8cbbc5de761892a9c27ef17a1f9e94dc91edd8298b4eaca18b71ba4a9d521c74b072f0a46950b13d6b61123b0431836 + "@jest/expect-utils": ^29.7.0 + jest-get-type: ^29.6.3 + jest-matcher-utils: ^29.7.0 + jest-message-util: ^29.7.0 + jest-util: ^29.7.0 + checksum: 9257f10288e149b81254a0fda8ffe8d54a7061cd61d7515779998b012579d2b8c22354b0eb901daf0145f347403da582f75f359f4810c007182ad3fb318b5c0c languageName: node linkType: hard @@ -3914,6 +6462,41 @@ __metadata: languageName: node linkType: hard +"external-editor@npm:^3.1.0": + version: 3.1.0 + resolution: "external-editor@npm:3.1.0" + dependencies: + chardet: ^0.7.0 + iconv-lite: ^0.4.24 + tmp: ^0.0.33 + checksum: 1c2a616a73f1b3435ce04030261bed0e22d4737e14b090bb48e58865da92529c9f2b05b893de650738d55e692d071819b45e1669259b2b354bc3154d27a698c7 + languageName: node + linkType: hard + +"extract-zip@npm:^2.0.1": + version: 2.0.1 + resolution: "extract-zip@npm:2.0.1" + dependencies: + "@types/yauzl": ^2.9.1 + debug: ^4.1.1 + get-stream: ^5.1.0 + yauzl: ^2.10.0 + dependenciesMeta: + "@types/yauzl": + optional: true + bin: + extract-zip: cli.js + checksum: 8cbda9debdd6d6980819cc69734d874ddd71051c9fe5bde1ef307ebcedfe949ba57b004894b585f758b7c9eeeea0e3d87f2dda89b7d25320459c2c9643ebb635 + languageName: node + linkType: hard + +"fast-deep-equal@npm:^2.0.1": + version: 2.0.1 + resolution: "fast-deep-equal@npm:2.0.1" + checksum: b701835a87985e0ec4925bdf1f0c1e7eb56309b5d12d534d5b4b69d95a54d65bb16861c081781ead55f73f12d6c60ba668713391ee7fbf6b0567026f579b7b0b + languageName: node + linkType: hard + "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -3921,16 +6504,36 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.2, fast-glob@npm:^3.2.5, fast-glob@npm:^3.2.9": - version: 3.2.12 - resolution: "fast-glob@npm:3.2.12" +"fast-fifo@npm:^1.2.0, fast-fifo@npm:^1.3.2": + version: 1.3.2 + resolution: "fast-fifo@npm:1.3.2" + checksum: 6bfcba3e4df5af7be3332703b69a7898a8ed7020837ec4395bb341bd96cc3a6d86c3f6071dd98da289618cf2234c70d84b2a6f09a33dd6f988b1ff60d8e54275 + languageName: node + linkType: hard + +"fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.2, fast-glob@npm:^3.2.5, fast-glob@npm:^3.2.9": + version: 3.2.12 + resolution: "fast-glob@npm:3.2.12" + dependencies: + "@nodelib/fs.stat": ^2.0.2 + "@nodelib/fs.walk": ^1.2.3 + glob-parent: ^5.1.2 + merge2: ^1.3.0 + micromatch: ^4.0.4 + checksum: 0b1990f6ce831c7e28c4d505edcdaad8e27e88ab9fa65eedadb730438cfc7cde4910d6c975d6b7b8dc8a73da4773702ebcfcd6e3518e73938bb1383badfe01c2 + languageName: node + linkType: hard + +"fast-glob@npm:^3.3.2": + version: 3.3.2 + resolution: "fast-glob@npm:3.3.2" dependencies: "@nodelib/fs.stat": ^2.0.2 "@nodelib/fs.walk": ^1.2.3 glob-parent: ^5.1.2 merge2: ^1.3.0 micromatch: ^4.0.4 - checksum: 0b1990f6ce831c7e28c4d505edcdaad8e27e88ab9fa65eedadb730438cfc7cde4910d6c975d6b7b8dc8a73da4773702ebcfcd6e3518e73938bb1383badfe01c2 + checksum: 900e4979f4dbc3313840078419245621259f349950411ca2fa445a2f9a1a6d98c3b5e7e0660c5ccd563aa61abe133a21765c6c0dec8e57da1ba71d8000b05ec1 languageName: node linkType: hard @@ -3948,6 +6551,17 @@ __metadata: languageName: node linkType: hard +"fast-xml-parser@npm:^4.4.1": + version: 4.5.0 + resolution: "fast-xml-parser@npm:4.5.0" + dependencies: + strnum: ^1.0.5 + bin: + fxparser: src/cli/cli.js + checksum: 696dc98da46f0f48eb26dfe1640a53043ea64f2420056374e62abbb5e620f092f8df3c3ff3195505a2eefab2057db3bf0ebaac63557f277934f6cce4e7da027c + languageName: node + linkType: hard + "fastq@npm:^1.6.0": version: 1.15.0 resolution: "fastq@npm:1.15.0" @@ -3966,6 +6580,34 @@ __metadata: languageName: node linkType: hard +"fd-slicer@npm:~1.1.0": + version: 1.1.0 + resolution: "fd-slicer@npm:1.1.0" + dependencies: + pend: ~1.2.0 + checksum: c8585fd5713f4476eb8261150900d2cb7f6ff2d87f8feb306ccc8a1122efd152f1783bdb2b8dc891395744583436bfd8081d8e63ece0ec8687eeefea394d4ff2 + languageName: node + linkType: hard + +"fetch-blob@npm:^3.1.2, fetch-blob@npm:^3.1.4": + version: 3.2.0 + resolution: "fetch-blob@npm:3.2.0" + dependencies: + node-domexception: ^1.0.0 + web-streams-polyfill: ^3.0.3 + checksum: f19bc28a2a0b9626e69fd7cf3a05798706db7f6c7548da657cbf5026a570945f5eeaedff52007ea35c8bcd3d237c58a20bf1543bc568ab2422411d762dd3d5bf + languageName: node + linkType: hard + +"figures@npm:^6.1.0": + version: 6.1.0 + resolution: "figures@npm:6.1.0" + dependencies: + is-unicode-supported: ^2.0.0 + checksum: 35c81239d4fa40b75c2c7c010833b0bc8861c27187e4c9388fca1d9731103ec9989b70ee3b664ef426ddd9abe02ec5f4fd973424aa8c6fd3ea5d3bf57a2d01b4 + languageName: node + linkType: hard + "file-entry-cache@npm:^6.0.1": version: 6.0.1 resolution: "file-entry-cache@npm:6.0.1" @@ -3986,6 +6628,15 @@ __metadata: languageName: node linkType: hard +"filelist@npm:^1.0.4": + version: 1.0.4 + resolution: "filelist@npm:1.0.4" + dependencies: + minimatch: ^5.0.1 + checksum: a303573b0821e17f2d5e9783688ab6fbfce5d52aaac842790ae85e704a6f5e4e3538660a63183d6453834dedf1e0f19a9dadcebfa3e926c72397694ea11f5160 + languageName: node + linkType: hard + "filename-reserved-regex@npm:^3.0.0": version: 3.0.0 resolution: "filename-reserved-regex@npm:3.0.0" @@ -4026,6 +6677,15 @@ __metadata: languageName: node linkType: hard +"fill-range@npm:^7.1.1": + version: 7.1.1 + resolution: "fill-range@npm:7.1.1" + dependencies: + to-regex-range: ^5.0.1 + checksum: b4abfbca3839a3d55e4ae5ec62e131e2e356bf4859ce8480c64c4876100f4df292a63e5bb1618e1d7460282ca2b305653064f01654474aa35c68000980f17798 + languageName: node + linkType: hard + "find-up@npm:^4.0.0, find-up@npm:^4.1.0": version: 4.1.0 resolution: "find-up@npm:4.1.0" @@ -4046,6 +6706,16 @@ __metadata: languageName: node linkType: hard +"find-up@npm:^6.3.0": + version: 6.3.0 + resolution: "find-up@npm:6.3.0" + dependencies: + locate-path: ^7.1.0 + path-exists: ^5.0.0 + checksum: 9a21b7f9244a420e54c6df95b4f6fc3941efd3c3e5476f8274eb452f6a85706e7a6a90de71353ee4f091fcb4593271a6f92810a324ec542650398f928783c280 + languageName: node + linkType: hard + "find-versions@npm:^5.0.0": version: 5.1.0 resolution: "find-versions@npm:5.1.0" @@ -4065,6 +6735,15 @@ __metadata: languageName: node linkType: hard +"flat@npm:^5.0.2": + version: 5.0.2 + resolution: "flat@npm:5.0.2" + bin: + flat: cli.js + checksum: 12a1536ac746db74881316a181499a78ef953632ddd28050b7a3a43c62ef5462e3357c8c29d76072bb635f147f7a9a1f0c02efef6b4be28f8db62ceb3d5c7f5d + languageName: node + linkType: hard + "flatted@npm:^3.1.0": version: 3.2.7 resolution: "flatted@npm:3.2.7" @@ -4088,6 +6767,16 @@ __metadata: languageName: node linkType: hard +"foreground-child@npm:^3.1.0": + version: 3.3.0 + resolution: "foreground-child@npm:3.3.0" + dependencies: + cross-spawn: ^7.0.0 + signal-exit: ^4.0.1 + checksum: 1989698488f725b05b26bc9afc8a08f08ec41807cd7b92ad85d96004ddf8243fd3e79486b8348c64a3011ae5cc2c9f0936af989e1f28339805d8bc178a75b451 + languageName: node + linkType: hard + "form-data@npm:^4.0.0": version: 4.0.0 resolution: "form-data@npm:4.0.0" @@ -4099,6 +6788,26 @@ __metadata: languageName: node linkType: hard +"formdata-polyfill@npm:^4.0.10": + version: 4.0.10 + resolution: "formdata-polyfill@npm:4.0.10" + dependencies: + fetch-blob: ^3.1.2 + checksum: 82a34df292afadd82b43d4a740ce387bc08541e0a534358425193017bf9fb3567875dc5f69564984b1da979979b70703aa73dee715a17b6c229752ae736dd9db + languageName: node + linkType: hard + +"fs-extra@npm:^11.2.0": + version: 11.2.0 + resolution: "fs-extra@npm:11.2.0" + dependencies: + graceful-fs: ^4.2.0 + jsonfile: ^6.0.1 + universalify: ^2.0.0 + checksum: b12e42fa40ba47104202f57b8480dd098aa931c2724565e5e70779ab87605665594e76ee5fb00545f772ab9ace167fe06d2ab009c416dc8c842c5ae6df7aa7e8 + languageName: node + linkType: hard + "fs-minipass@npm:^2.0.0, fs-minipass@npm:^2.1.0": version: 2.1.0 resolution: "fs-minipass@npm:2.1.0" @@ -4125,6 +6834,16 @@ __metadata: languageName: node linkType: hard +"fsevents@npm:~2.3.3": + version: 2.3.3 + resolution: "fsevents@npm:2.3.3" + dependencies: + node-gyp: latest + checksum: 11e6ea6fea15e42461fc55b4b0e4a0a3c654faa567f1877dbd353f39156f69def97a69936d1746619d656c4b93de2238bf731f6085a03a50cabf287c9d024317 + conditions: os=darwin + languageName: node + linkType: hard + "fsevents@patch:fsevents@^2.3.2#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin": version: 2.3.2 resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=df0bf1" @@ -4134,6 +6853,15 @@ __metadata: languageName: node linkType: hard +"fsevents@patch:fsevents@~2.3.3#~builtin": + version: 2.3.3 + resolution: "fsevents@patch:fsevents@npm%3A2.3.3#~builtin::version=2.3.3&hash=df0bf1" + dependencies: + node-gyp: latest + conditions: os=darwin + languageName: node + linkType: hard + "function-bind@npm:^1.1.1": version: 1.1.1 resolution: "function-bind@npm:1.1.1" @@ -4176,6 +6904,33 @@ __metadata: languageName: node linkType: hard +"gaze@npm:^1.1.3": + version: 1.1.3 + resolution: "gaze@npm:1.1.3" + dependencies: + globule: ^1.0.0 + checksum: d5fd375a029c07346154806a076bde21290598179d01ffbe7bc3e54092fa65814180bd27fc2b577582737733eec77cdbb7a572a4e73dff934dde60317223cde6 + languageName: node + linkType: hard + +"geckodriver@npm:^4.3.3": + version: 4.4.4 + resolution: "geckodriver@npm:4.4.4" + dependencies: + "@wdio/logger": ^9.0.0 + "@zip.js/zip.js": ^2.7.48 + decamelize: ^6.0.0 + http-proxy-agent: ^7.0.2 + https-proxy-agent: ^7.0.5 + node-fetch: ^3.3.2 + tar-fs: ^3.0.6 + which: ^4.0.0 + bin: + geckodriver: bin/geckodriver.js + checksum: 75eabdd5c597747c03c0889069ea04d169b8c1ed7c0ad26fd0136e001f8b7b5fd406e405392ee765d7de663472e6c46f7bc9995a7c79cdbcf7f44af9f80f6582 + languageName: node + linkType: hard + "gensync@npm:^1.0.0-beta.2": version: 1.0.0-beta.2 resolution: "gensync@npm:1.0.0-beta.2" @@ -4208,6 +6963,13 @@ __metadata: languageName: node linkType: hard +"get-port@npm:^7.0.0, get-port@npm:^7.1.0": + version: 7.1.0 + resolution: "get-port@npm:7.1.0" + checksum: f4d23b43026124007663a899578cc87ff37bfcf645c5c72651e9810ebafc759857784e409fb8e0ada9b90e5c5db089b0ae2f5f6b49fba1ce2e0aff86094ab17d + languageName: node + linkType: hard + "get-stream@npm:^3.0.0": version: 3.0.0 resolution: "get-stream@npm:3.0.0" @@ -4231,6 +6993,23 @@ __metadata: languageName: node linkType: hard +"get-stream@npm:^8.0.1": + version: 8.0.1 + resolution: "get-stream@npm:8.0.1" + checksum: 01e3d3cf29e1393f05f44d2f00445c5f9ec3d1c49e8179b31795484b9c117f4c695e5e07b88b50785d5c8248a788c85d9913a79266fc77e3ef11f78f10f1b974 + languageName: node + linkType: hard + +"get-stream@npm:^9.0.0": + version: 9.0.1 + resolution: "get-stream@npm:9.0.1" + dependencies: + "@sec-ant/readable-stream": ^0.4.1 + is-stream: ^4.0.1 + checksum: 631df71d7bd60a7f373094d3c352e2ce412b82d30b1b0ec562e5a4aced976173a4cc0dabef019050e1aceaffb1f0e086349ab3d14377b0b7280510bd75bd3e1e + languageName: node + linkType: hard + "get-symbol-description@npm:^1.0.0": version: 1.0.0 resolution: "get-symbol-description@npm:1.0.0" @@ -4248,7 +7027,46 @@ __metadata: languageName: node linkType: hard -"glob-parent@npm:^5.1.2": +"get-tsconfig@npm:^4.7.5": + version: 4.8.1 + resolution: "get-tsconfig@npm:4.8.1" + dependencies: + resolve-pkg-maps: ^1.0.0 + checksum: 12df01672e691d2ff6db8cf7fed1ddfef90ed94a5f3d822c63c147a26742026d582acd86afcd6f65db67d809625d17dd7f9d34f4d3f38f69bc2f48e19b2bdd5b + languageName: node + linkType: hard + +"get-uri@npm:^6.0.1": + version: 6.0.3 + resolution: "get-uri@npm:6.0.3" + dependencies: + basic-ftp: ^5.0.2 + data-uri-to-buffer: ^6.0.2 + debug: ^4.3.4 + fs-extra: ^11.2.0 + checksum: 3eda448a59fa1ba82ad4f252e58490fec586b644f2dc9c98ba3ab20e801ecc8a1bc1784829c474c9d188edb633d4dfd81c33894ca6117a33a16e8e013b41b40f + languageName: node + linkType: hard + +"giget@npm:^1.2.3": + version: 1.2.3 + resolution: "giget@npm:1.2.3" + dependencies: + citty: ^0.1.6 + consola: ^3.2.3 + defu: ^6.1.4 + node-fetch-native: ^1.6.3 + nypm: ^0.3.8 + ohash: ^1.1.3 + pathe: ^1.1.2 + tar: ^6.2.0 + bin: + giget: dist/cli.mjs + checksum: ec6e9126cb210377b952c090338dee5df0f58f724666318a14a505f1d2c961b91fd1b364b86a038b24a21a5ef44702c9d6841f8726b09aeb88a74720b6b682dd + languageName: node + linkType: hard + +"glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2": version: 5.1.2 resolution: "glob-parent@npm:5.1.2" dependencies: @@ -4266,6 +7084,22 @@ __metadata: languageName: node linkType: hard +"glob@npm:^10.0.0, glob@npm:^10.2.2": + version: 10.4.5 + resolution: "glob@npm:10.4.5" + dependencies: + foreground-child: ^3.1.0 + jackspeak: ^3.1.2 + minimatch: ^9.0.4 + minipass: ^7.1.2 + package-json-from-dist: ^1.0.0 + path-scurry: ^1.11.1 + bin: + glob: dist/esm/bin.mjs + checksum: 0bc725de5e4862f9f387fd0f2b274baf16850dcd2714502ccf471ee401803997983e2c05590cb65f9675a3c6f2a58e7a53f9e365704108c6ad3cbf1d60934c4a + languageName: node + linkType: hard + "glob@npm:^7.1.3, glob@npm:^7.1.4": version: 7.2.3 resolution: "glob@npm:7.2.3" @@ -4280,7 +7114,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^8.0.1": +"glob@npm:^8.0.1, glob@npm:^8.1.0": version: 8.1.0 resolution: "glob@npm:8.1.0" dependencies: @@ -4293,6 +7127,20 @@ __metadata: languageName: node linkType: hard +"glob@npm:~7.1.1": + version: 7.1.7 + resolution: "glob@npm:7.1.7" + dependencies: + fs.realpath: ^1.0.0 + inflight: ^1.0.4 + inherits: 2 + minimatch: ^3.0.4 + once: ^1.3.0 + path-is-absolute: ^1.0.0 + checksum: b61f48973bbdcf5159997b0874a2165db572b368b931135832599875919c237fc05c12984e38fe828e69aa8a921eb0e8a4997266211c517c9cfaae8a93988bb8 + languageName: node + linkType: hard + "globals@npm:^11.1.0": version: 11.12.0 resolution: "globals@npm:11.12.0" @@ -4352,6 +7200,20 @@ __metadata: languageName: node linkType: hard +"globby@npm:^14.0.2": + version: 14.0.2 + resolution: "globby@npm:14.0.2" + dependencies: + "@sindresorhus/merge-streams": ^2.1.0 + fast-glob: ^3.3.2 + ignore: ^5.2.4 + path-type: ^5.0.0 + slash: ^5.1.0 + unicorn-magic: ^0.1.0 + checksum: 2cee79efefca4383a825fc2fcbdb37e5706728f2d39d4b63851927c128fff62e6334ef7d4d467949d411409ad62767dc2d214e0f837a0f6d4b7290b6711d485c + languageName: node + linkType: hard + "globrex@npm:^0.1.2": version: 0.1.2 resolution: "globrex@npm:0.1.2" @@ -4359,6 +7221,17 @@ __metadata: languageName: node linkType: hard +"globule@npm:^1.0.0": + version: 1.3.4 + resolution: "globule@npm:1.3.4" + dependencies: + glob: ~7.1.1 + lodash: ^4.17.21 + minimatch: ~3.0.2 + checksum: 258b6865c77d54fbd4c91dd6931d99baf81b1485fdf4bd2c053b1a10eab015163cb646e6c96812d5c8b027fb07adfc0b7c7fb13bbbb571f3c12ea60bd7fda2f5 + languageName: node + linkType: hard + "gopd@npm:^1.0.1": version: 1.0.1 resolution: "gopd@npm:1.0.1" @@ -4387,6 +7260,13 @@ __metadata: languageName: node linkType: hard +"graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: ac85f94da92d8eb6b7f5a8b20ce65e43d66761c55ce85ac96df6865308390da45a8d3f0296dd3a663de65d30ba497bd46c696cc1e248c72b13d6d567138a4fc7 + languageName: node + linkType: hard + "graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": version: 4.2.10 resolution: "graceful-fs@npm:4.2.10" @@ -4501,6 +7381,38 @@ __metadata: languageName: node linkType: hard +"hash-sum@npm:^2.0.0": + version: 2.0.0 + resolution: "hash-sum@npm:2.0.0" + checksum: efeeacf09ecbd467202865403c3a1991fa15d4f4903c1148ecbe13223fdbf9ec6d7dc661e17e5ce6e776cd70d67b6ee4c82e0171318962435be45c1155175f3f + languageName: node + linkType: hard + +"he@npm:^1.2.0": + version: 1.2.0 + resolution: "he@npm:1.2.0" + bin: + he: bin/he + checksum: 3d4d6babccccd79c5c5a3f929a68af33360d6445587d628087f39a965079d84f18ce9c3d3f917ee1e3978916fc833bb8b29377c3b403f919426f91bc6965e7a7 + languageName: node + linkType: hard + +"hookable@npm:^5.5.3": + version: 5.5.3 + resolution: "hookable@npm:5.5.3" + checksum: df659977888398649b6ef8c4470719e7e8384a1d939a6587e332e86fd55b3881806e2f8aaebaabdb4f218f74b83b98f2110e143df225e16d62a39dc271e7e288 + languageName: node + linkType: hard + +"hosted-git-info@npm:^7.0.0": + version: 7.0.2 + resolution: "hosted-git-info@npm:7.0.2" + dependencies: + lru-cache: ^10.0.1 + checksum: 467cf908a56556417b18e86ae3b8dee03c2360ef1d51e61c4028fe87f6f309b6ff038589c94b5666af207da9d972d5107698906aabeb78aca134641962a5c6f8 + languageName: node + linkType: hard + "html-encoding-sniffer@npm:^3.0.0": version: 3.0.0 resolution: "html-encoding-sniffer@npm:3.0.0" @@ -4517,6 +7429,25 @@ __metadata: languageName: node linkType: hard +"htmlfy@npm:^0.2.1": + version: 0.2.1 + resolution: "htmlfy@npm:0.2.1" + checksum: 539000ef53c16dc65500a3281b0ad71680680a68a141a256cbe6bc447a374c6ffe0fbdd25c3fd1986a25d92e66f76747f92f26dabeb35cabe980b65afbc8ab8b + languageName: node + linkType: hard + +"htmlparser2@npm:^9.1.0": + version: 9.1.0 + resolution: "htmlparser2@npm:9.1.0" + dependencies: + domelementtype: ^2.3.0 + domhandler: ^5.0.3 + domutils: ^3.1.0 + entities: ^4.5.0 + checksum: e5f8d5193967e4a500226f37bdf2c0f858cecb39dde14d0439f24bf2c461a4342778740d988fbaba652b0e4cb6052f7f2e99e69fc1a329a86c629032bb76e7c8 + languageName: node + linkType: hard + "http-cache-semantics@npm:^4.0.0, http-cache-semantics@npm:^4.1.0": version: 4.1.1 resolution: "http-cache-semantics@npm:4.1.1" @@ -4535,6 +7466,16 @@ __metadata: languageName: node linkType: hard +"http-proxy-agent@npm:^7.0.0, http-proxy-agent@npm:^7.0.1, http-proxy-agent@npm:^7.0.2": + version: 7.0.2 + resolution: "http-proxy-agent@npm:7.0.2" + dependencies: + agent-base: ^7.1.0 + debug: ^4.3.4 + checksum: 670858c8f8f3146db5889e1fa117630910101db601fff7d5a8aa637da0abedf68c899f03d3451cac2f83bcc4c3d2dabf339b3aa00ff8080571cceb02c3ce02f3 + languageName: node + linkType: hard + "http2-wrapper@npm:^1.0.0-beta.5.2": version: 1.0.3 resolution: "http2-wrapper@npm:1.0.3" @@ -4555,6 +7496,16 @@ __metadata: languageName: node linkType: hard +"https-proxy-agent@npm:^7.0.3, https-proxy-agent@npm:^7.0.5": + version: 7.0.5 + resolution: "https-proxy-agent@npm:7.0.5" + dependencies: + agent-base: ^7.0.2 + debug: 4 + checksum: 2e1a28960f13b041a50702ee74f240add8e75146a5c37fc98f1960f0496710f6918b3a9fe1e5aba41e50f58e6df48d107edd9c405c5f0d73ac260dabf2210857 + languageName: node + linkType: hard + "human-signals@npm:^2.1.0": version: 2.1.0 resolution: "human-signals@npm:2.1.0" @@ -4569,6 +7520,20 @@ __metadata: languageName: node linkType: hard +"human-signals@npm:^5.0.0": + version: 5.0.0 + resolution: "human-signals@npm:5.0.0" + checksum: 6504560d5ed91444f16bea3bd9dfc66110a339442084e56c3e7fa7bbdf3f406426d6563d662bdce67064b165eac31eeabfc0857ed170aaa612cf14ec9f9a464c + languageName: node + linkType: hard + +"human-signals@npm:^8.0.0": + version: 8.0.0 + resolution: "human-signals@npm:8.0.0" + checksum: ccaca470e8b5509d89cd9af82e88fc497a4b4b9149b7964bcd9dd1463f9d9676fb5488f50cd1bc0f12ed8875a7c1c5e7019cbe238992b444919e8cf056688eba + languageName: node + linkType: hard + "humanize-ms@npm:^1.2.1": version: 1.2.1 resolution: "humanize-ms@npm:1.2.1" @@ -4587,7 +7552,7 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2": +"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": version: 0.6.3 resolution: "iconv-lite@npm:0.6.3" dependencies: @@ -4596,7 +7561,16 @@ __metadata: languageName: node linkType: hard -"ieee754@npm:^1.2.1": +"iconv-lite@npm:^0.4.24": + version: 0.4.24 + resolution: "iconv-lite@npm:0.4.24" + dependencies: + safer-buffer: ">= 2.1.2 < 3" + checksum: bd9f120f5a5b306f0bc0b9ae1edeb1577161503f5f8252a20f1a9e56ef8775c9959fd01c55f2d3a39d9a8abaf3e30c1abeb1895f367dcbbe0a8fd1c9ca01c4f6 + languageName: node + linkType: hard + +"ieee754@npm:^1.1.13, ieee754@npm:^1.2.1": version: 1.2.1 resolution: "ieee754@npm:1.2.1" checksum: 5144c0c9815e54ada181d80a0b810221a253562422e7c6c3a60b1901154184f49326ec239d618c416c1c5945a2e197107aee8d986a3dd836b53dffefd99b5e7e @@ -4610,6 +7584,20 @@ __metadata: languageName: node linkType: hard +"ignore@npm:^5.2.4, ignore@npm:^5.3.2": + version: 5.3.2 + resolution: "ignore@npm:5.3.2" + checksum: 2acfd32a573260ea522ea0bfeff880af426d68f6831f973129e2ba7363f422923cf53aab62f8369cbf4667c7b25b6f8a3761b34ecdb284ea18e87a5262a865be + languageName: node + linkType: hard + +"immediate@npm:~3.0.5": + version: 3.0.6 + resolution: "immediate@npm:3.0.6" + checksum: f9b3486477555997657f70318cc8d3416159f208bec4cca3ff3442fd266bc23f50f0c9bd8547e1371a6b5e82b821ec9a7044a4f7b944798b25aa3cc6d5e63e62 + languageName: node + linkType: hard + "import-fresh@npm:^3.0.0, import-fresh@npm:^3.2.1": version: 3.3.0 resolution: "import-fresh@npm:3.3.0" @@ -4632,6 +7620,13 @@ __metadata: languageName: node linkType: hard +"import-meta-resolve@npm:^4.0.0": + version: 4.1.0 + resolution: "import-meta-resolve@npm:4.1.0" + checksum: 6497af27bf3ee384ad4efd4e0ec3facf9a114863f35a7b35f248659f32faa5e1ae07baa74d603069f35734ae3718a78b3f66926f98dc9a62e261e7df37854a62 + languageName: node + linkType: hard + "imurmurhash@npm:^0.1.4": version: 0.1.4 resolution: "imurmurhash@npm:0.1.4" @@ -4670,6 +7665,22 @@ __metadata: languageName: node linkType: hard +"inquirer@npm:^10.1.8": + version: 10.2.2 + resolution: "inquirer@npm:10.2.2" + dependencies: + "@inquirer/core": ^9.1.0 + "@inquirer/prompts": ^5.5.0 + "@inquirer/type": ^1.5.3 + "@types/mute-stream": ^0.0.4 + ansi-escapes: ^4.3.2 + mute-stream: ^1.0.0 + run-async: ^3.0.0 + rxjs: ^7.8.1 + checksum: 41e09d818f9545d52698f69f6c832f6a2ea2cf40e7b0e056147aadd8ea4b76d489a2a10e34b0593cd1f43989def3114c086502166c2a0bdab353ea5c43f4173b + languageName: node + linkType: hard + "internal-slot@npm:^1.0.3, internal-slot@npm:^1.0.4": version: 1.0.4 resolution: "internal-slot@npm:1.0.4" @@ -4681,6 +7692,16 @@ __metadata: languageName: node linkType: hard +"ip-address@npm:^9.0.5": + version: 9.0.5 + resolution: "ip-address@npm:9.0.5" + dependencies: + jsbn: 1.1.0 + sprintf-js: ^1.1.3 + checksum: aa15f12cfd0ef5e38349744e3654bae649a34c3b10c77a674a167e99925d1549486c5b14730eebce9fea26f6db9d5e42097b00aa4f9f612e68c79121c71652dc + languageName: node + linkType: hard + "ip@npm:^2.0.0": version: 2.0.0 resolution: "ip@npm:2.0.0" @@ -4688,16 +7709,6 @@ __metadata: languageName: node linkType: hard -"is-arguments@npm:^1.1.1": - version: 1.1.1 - resolution: "is-arguments@npm:1.1.1" - dependencies: - call-bind: ^1.0.2 - has-tostringtag: ^1.0.0 - checksum: 7f02700ec2171b691ef3e4d0e3e6c0ba408e8434368504bb593d0d7c891c0dbfda6d19d30808b904a6cb1929bca648c061ba438c39f296c2a8ca083229c49f27 - languageName: node - linkType: hard - "is-array-buffer@npm:^3.0.1": version: 3.0.1 resolution: "is-array-buffer@npm:3.0.1" @@ -4725,6 +7736,15 @@ __metadata: languageName: node linkType: hard +"is-binary-path@npm:~2.1.0": + version: 2.1.0 + resolution: "is-binary-path@npm:2.1.0" + dependencies: + binary-extensions: ^2.0.0 + checksum: 84192eb88cff70d320426f35ecd63c3d6d495da9d805b19bc65b518984b7c0760280e57dbf119b7e9be6b161784a5a673ab2c6abe83abb5198a432232ad5b35c + languageName: node + linkType: hard + "is-boolean-object@npm:^1.1.0": version: 1.1.2 resolution: "is-boolean-object@npm:1.1.2" @@ -4758,7 +7778,7 @@ __metadata: languageName: node linkType: hard -"is-date-object@npm:^1.0.1, is-date-object@npm:^1.0.5": +"is-date-object@npm:^1.0.1": version: 1.0.5 resolution: "is-date-object@npm:1.0.5" dependencies: @@ -4820,7 +7840,7 @@ __metadata: languageName: node linkType: hard -"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3": +"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1": version: 4.0.3 resolution: "is-glob@npm:4.0.3" dependencies: @@ -4836,13 +7856,6 @@ __metadata: languageName: node linkType: hard -"is-map@npm:^2.0.1, is-map@npm:^2.0.2": - version: 2.0.2 - resolution: "is-map@npm:2.0.2" - checksum: ace3d0ecd667bbdefdb1852de601268f67f2db725624b1958f279316e13fecb8fa7df91fd60f690d7417b4ec180712f5a7ee967008e27c65cfd475cc84337728 - languageName: node - linkType: hard - "is-negative-zero@npm:^2.0.2": version: 2.0.2 resolution: "is-negative-zero@npm:2.0.2" @@ -4896,6 +7909,20 @@ __metadata: languageName: node linkType: hard +"is-plain-obj@npm:^2.1.0": + version: 2.1.0 + resolution: "is-plain-obj@npm:2.1.0" + checksum: cec9100678b0a9fe0248a81743041ed990c2d4c99f893d935545cfbc42876cbe86d207f3b895700c690ad2fa520e568c44afc1605044b535a7820c1d40e38daa + languageName: node + linkType: hard + +"is-plain-obj@npm:^4.1.0": + version: 4.1.0 + resolution: "is-plain-obj@npm:4.1.0" + checksum: 6dc45da70d04a81f35c9310971e78a6a3c7a63547ef782e3a07ee3674695081b6ca4e977fbb8efc48dae3375e0b34558d2bcd722aec9bddfa2d7db5b041be8ce + languageName: node + linkType: hard + "is-plain-object@npm:^2.0.4": version: 2.0.4 resolution: "is-plain-object@npm:2.0.4" @@ -4922,13 +7949,6 @@ __metadata: languageName: node linkType: hard -"is-set@npm:^2.0.1, is-set@npm:^2.0.2": - version: 2.0.2 - resolution: "is-set@npm:2.0.2" - checksum: b64343faf45e9387b97a6fd32be632ee7b269bd8183701f3b3f5b71a7cf00d04450ed8669d0bd08753e08b968beda96fca73a10fd0ff56a32603f64deba55a57 - languageName: node - linkType: hard - "is-shared-array-buffer@npm:^1.0.2": version: 1.0.2 resolution: "is-shared-array-buffer@npm:1.0.2" @@ -4945,7 +7965,7 @@ __metadata: languageName: node linkType: hard -"is-stream@npm:^2.0.0": +"is-stream@npm:^2.0.0, is-stream@npm:^2.0.1": version: 2.0.1 resolution: "is-stream@npm:2.0.1" checksum: b8e05ccdf96ac330ea83c12450304d4a591f9958c11fd17bed240af8d5ffe08aedafa4c0f4cfccd4d28dc9d4d129daca1023633d5c11601a6cbc77521f6fae66 @@ -4959,6 +7979,13 @@ __metadata: languageName: node linkType: hard +"is-stream@npm:^4.0.1": + version: 4.0.1 + resolution: "is-stream@npm:4.0.1" + checksum: cbea3f1fc271b21ceb228819d0c12a0965a02b57f39423925f99530b4eb86935235f258f06310b67cd02b2d10b49e9a0998f5ececf110ab7d3760bae4055ad23 + languageName: node + linkType: hard + "is-string@npm:^1.0.5, is-string@npm:^1.0.7": version: 1.0.7 resolution: "is-string@npm:1.0.7" @@ -4990,10 +8017,17 @@ __metadata: languageName: node linkType: hard -"is-weakmap@npm:^2.0.1": - version: 2.0.1 - resolution: "is-weakmap@npm:2.0.1" - checksum: 1222bb7e90c32bdb949226e66d26cb7bce12e1e28e3e1b40bfa6b390ba3e08192a8664a703dff2a00a84825f4e022f9cd58c4599ff9981ab72b1d69479f4f7f6 +"is-unicode-supported@npm:^0.1.0": + version: 0.1.0 + resolution: "is-unicode-supported@npm:0.1.0" + checksum: a2aab86ee7712f5c2f999180daaba5f361bdad1efadc9610ff5b8ab5495b86e4f627839d085c6530363c6d6d4ecbde340fb8e54bdb83da4ba8e0865ed5513c52 + languageName: node + linkType: hard + +"is-unicode-supported@npm:^2.0.0": + version: 2.1.0 + resolution: "is-unicode-supported@npm:2.1.0" + checksum: f254e3da6b0ab1a57a94f7273a7798dd35d1d45b227759f600d0fa9d5649f9c07fa8d3c8a6360b0e376adf916d151ec24fc9a50c5295c58bae7ca54a76a063f9 languageName: node linkType: hard @@ -5006,16 +8040,6 @@ __metadata: languageName: node linkType: hard -"is-weakset@npm:^2.0.1": - version: 2.0.2 - resolution: "is-weakset@npm:2.0.2" - dependencies: - call-bind: ^1.0.2 - get-intrinsic: ^1.1.1 - checksum: 5d8698d1fa599a0635d7ca85be9c26d547b317ed8fd83fc75f03efbe75d50001b5eececb1e9971de85fcde84f69ae6f8346bc92d20d55d46201d328e4c74a367 - languageName: node - linkType: hard - "is-wsl@npm:^2.2.0": version: 2.2.0 resolution: "is-wsl@npm:2.2.0" @@ -5026,16 +8050,9 @@ __metadata: linkType: hard "isarray@npm:1.0.0, isarray@npm:~1.0.0": - version: 1.0.0 - resolution: "isarray@npm:1.0.0" - checksum: f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab - languageName: node - linkType: hard - -"isarray@npm:^2.0.5": - version: 2.0.5 - resolution: "isarray@npm:2.0.5" - checksum: bd5bbe4104438c4196ba58a54650116007fa0262eccef13a4c55b2e09a5b36b59f1e75b9fcc49883dd9d4953892e6fc007eef9e9155648ceea036e184b0f930a + version: 1.0.0 + resolution: "isarray@npm:1.0.0" + checksum: f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab languageName: node linkType: hard @@ -5046,6 +8063,13 @@ __metadata: languageName: node linkType: hard +"isexe@npm:^3.1.1": + version: 3.1.1 + resolution: "isexe@npm:3.1.1" + checksum: 7fe1931ee4e88eb5aa524cd3ceb8c882537bc3a81b02e438b240e47012eef49c86904d0f0e593ea7c3a9996d18d0f1f3be8d3eaa92333977b0c3a9d353d5563e + languageName: node + linkType: hard + "isobject@npm:^2.0.0": version: 2.1.0 resolution: "isobject@npm:2.1.0" @@ -5069,7 +8093,14 @@ __metadata: languageName: node linkType: hard -"istanbul-lib-instrument@npm:^5.0.4, istanbul-lib-instrument@npm:^5.1.0": +"istanbul-lib-coverage@npm:^3.2.2": + version: 3.2.2 + resolution: "istanbul-lib-coverage@npm:3.2.2" + checksum: 2367407a8d13982d8f7a859a35e7f8dd5d8f75aae4bb5484ede3a9ea1b426dc245aff28b976a2af48ee759fdd9be374ce2bd2669b644f31e76c5f46a2e29a831 + languageName: node + linkType: hard + +"istanbul-lib-instrument@npm:^5.0.4": version: 5.2.1 resolution: "istanbul-lib-instrument@npm:5.2.1" dependencies: @@ -5082,6 +8113,19 @@ __metadata: languageName: node linkType: hard +"istanbul-lib-instrument@npm:^6.0.0, istanbul-lib-instrument@npm:^6.0.2": + version: 6.0.3 + resolution: "istanbul-lib-instrument@npm:6.0.3" + dependencies: + "@babel/core": ^7.23.9 + "@babel/parser": ^7.23.9 + "@istanbuljs/schema": ^0.1.3 + istanbul-lib-coverage: ^3.2.0 + semver: ^7.5.4 + checksum: 74104c60c65c4fa0e97cc76f039226c356123893929f067bfad5f86fe839e08f5d680354a68fead3bc9c1e2f3fa6f3f53cded70778e821d911e851d349f3545a + languageName: node + linkType: hard + "istanbul-lib-report@npm:^3.0.0": version: 3.0.0 resolution: "istanbul-lib-report@npm:3.0.0" @@ -5093,6 +8137,17 @@ __metadata: languageName: node linkType: hard +"istanbul-lib-report@npm:^3.0.1": + version: 3.0.1 + resolution: "istanbul-lib-report@npm:3.0.1" + dependencies: + istanbul-lib-coverage: ^3.0.0 + make-dir: ^4.0.0 + supports-color: ^7.1.0 + checksum: fd17a1b879e7faf9bb1dc8f80b2a16e9f5b7b8498fe6ed580a618c34df0bfe53d2abd35bf8a0a00e628fb7405462576427c7df20bbe4148d19c14b431c974b21 + languageName: node + linkType: hard + "istanbul-lib-source-maps@npm:^4.0.0": version: 4.0.1 resolution: "istanbul-lib-source-maps@npm:4.0.1" @@ -5104,6 +8159,17 @@ __metadata: languageName: node linkType: hard +"istanbul-lib-source-maps@npm:^5.0.4": + version: 5.0.6 + resolution: "istanbul-lib-source-maps@npm:5.0.6" + dependencies: + "@jridgewell/trace-mapping": ^0.3.23 + debug: ^4.1.1 + istanbul-lib-coverage: ^3.0.0 + checksum: 8dd6f2c1e2ecaacabeef8dc9ab52c4ed0a6036310002cf7f46ea6f3a5fb041da8076f5350e6a6be4c60cd4f231c51c73e042044afaf44820d857d92ecfb8ab6c + languageName: node + linkType: hard + "istanbul-reports@npm:^3.1.3": version: 3.1.5 resolution: "istanbul-reports@npm:3.1.5" @@ -5114,58 +8180,96 @@ __metadata: languageName: node linkType: hard -"jest-changed-files@npm:^29.4.0": - version: 29.4.0 - resolution: "jest-changed-files@npm:29.4.0" +"istanbul-reports@npm:^3.1.7": + version: 3.1.7 + resolution: "istanbul-reports@npm:3.1.7" + dependencies: + html-escaper: ^2.0.0 + istanbul-lib-report: ^3.0.0 + checksum: 2072db6e07bfbb4d0eb30e2700250636182398c1af811aea5032acb219d2080f7586923c09fa194029efd6b92361afb3dcbe1ebcc3ee6651d13340f7c6c4ed95 + languageName: node + linkType: hard + +"jackspeak@npm:^3.1.2": + version: 3.4.3 + resolution: "jackspeak@npm:3.4.3" + dependencies: + "@isaacs/cliui": ^8.0.2 + "@pkgjs/parseargs": ^0.11.0 + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: be31027fc72e7cc726206b9f560395604b82e0fddb46c4cbf9f97d049bcef607491a5afc0699612eaa4213ca5be8fd3e1e7cd187b3040988b65c9489838a7c00 + languageName: node + linkType: hard + +"jake@npm:^10.8.5": + version: 10.9.2 + resolution: "jake@npm:10.9.2" + dependencies: + async: ^3.2.3 + chalk: ^4.0.2 + filelist: ^1.0.4 + minimatch: ^3.1.2 + bin: + jake: bin/cli.js + checksum: f2dc4a086b4f58446d02cb9be913c39710d9ea570218d7681bb861f7eeaecab7b458256c946aeaa7e548c5e0686cc293e6435501e4047174a3b6a504dcbfcaae + languageName: node + linkType: hard + +"jest-changed-files@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-changed-files@npm:29.7.0" dependencies: execa: ^5.0.0 + jest-util: ^29.7.0 p-limit: ^3.1.0 - checksum: d8883b32b8b28f4f63cbbe32ff75283401a11647303bd74e2c522981457a88b9146b77974759023c74215a0a55c1b1d0fc3070fe3cde9d4f33aaa1c76aede4eb + checksum: 963e203893c396c5dfc75e00a49426688efea7361b0f0e040035809cecd2d46b3c01c02be2d9e8d38b1138357d2de7719ea5b5be21f66c10f2e9685a5a73bb99 languageName: node linkType: hard -"jest-circus@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-circus@npm:29.4.1" +"jest-circus@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-circus@npm:29.7.0" dependencies: - "@jest/environment": ^29.4.1 - "@jest/expect": ^29.4.1 - "@jest/test-result": ^29.4.1 - "@jest/types": ^29.4.1 + "@jest/environment": ^29.7.0 + "@jest/expect": ^29.7.0 + "@jest/test-result": ^29.7.0 + "@jest/types": ^29.6.3 "@types/node": "*" chalk: ^4.0.0 co: ^4.6.0 - dedent: ^0.7.0 + dedent: ^1.0.0 is-generator-fn: ^2.0.0 - jest-each: ^29.4.1 - jest-matcher-utils: ^29.4.1 - jest-message-util: ^29.4.1 - jest-runtime: ^29.4.1 - jest-snapshot: ^29.4.1 - jest-util: ^29.4.1 + jest-each: ^29.7.0 + jest-matcher-utils: ^29.7.0 + jest-message-util: ^29.7.0 + jest-runtime: ^29.7.0 + jest-snapshot: ^29.7.0 + jest-util: ^29.7.0 p-limit: ^3.1.0 - pretty-format: ^29.4.1 + pretty-format: ^29.7.0 + pure-rand: ^6.0.0 slash: ^3.0.0 stack-utils: ^2.0.3 - checksum: e1aff95668c2e17397e65b201d472a430d0713e9a75650b0a73ba7aed71f5eb0c2065c0f593dc2f422dcb817db1ec41b6eb888a3a8c01dbaf5eaeec7429a83d5 + checksum: 349437148924a5a109c9b8aad6d393a9591b4dac1918fc97d81b7fc515bc905af9918495055071404af1fab4e48e4b04ac3593477b1d5dcf48c4e71b527c70a7 languageName: node linkType: hard -"jest-cli@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-cli@npm:29.4.1" +"jest-cli@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-cli@npm:29.7.0" dependencies: - "@jest/core": ^29.4.1 - "@jest/test-result": ^29.4.1 - "@jest/types": ^29.4.1 + "@jest/core": ^29.7.0 + "@jest/test-result": ^29.7.0 + "@jest/types": ^29.6.3 chalk: ^4.0.0 + create-jest: ^29.7.0 exit: ^0.1.2 - graceful-fs: ^4.2.9 import-local: ^3.0.2 - jest-config: ^29.4.1 - jest-util: ^29.4.1 - jest-validate: ^29.4.1 - prompts: ^2.0.1 + jest-config: ^29.7.0 + jest-util: ^29.7.0 + jest-validate: ^29.7.0 yargs: ^17.3.1 peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -5174,34 +8278,34 @@ __metadata: optional: true bin: jest: bin/jest.js - checksum: 12318e61d51288f4c43ad38f776df8e31264f31458d4b810583945b137ddf9ebbcdd2018cef9987e973f56cf716892649bff650d8b80cae8d868a35c4f0f3f93 + checksum: 664901277a3f5007ea4870632ed6e7889db9da35b2434e7cb488443e6bf5513889b344b7fddf15112135495b9875892b156faeb2d7391ddb9e2a849dcb7b6c36 languageName: node linkType: hard -"jest-config@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-config@npm:29.4.1" +"jest-config@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-config@npm:29.7.0" dependencies: "@babel/core": ^7.11.6 - "@jest/test-sequencer": ^29.4.1 - "@jest/types": ^29.4.1 - babel-jest: ^29.4.1 + "@jest/test-sequencer": ^29.7.0 + "@jest/types": ^29.6.3 + babel-jest: ^29.7.0 chalk: ^4.0.0 ci-info: ^3.2.0 deepmerge: ^4.2.2 glob: ^7.1.3 graceful-fs: ^4.2.9 - jest-circus: ^29.4.1 - jest-environment-node: ^29.4.1 - jest-get-type: ^29.2.0 - jest-regex-util: ^29.2.0 - jest-resolve: ^29.4.1 - jest-runner: ^29.4.1 - jest-util: ^29.4.1 - jest-validate: ^29.4.1 + jest-circus: ^29.7.0 + jest-environment-node: ^29.7.0 + jest-get-type: ^29.6.3 + jest-regex-util: ^29.6.3 + jest-resolve: ^29.7.0 + jest-runner: ^29.7.0 + jest-util: ^29.7.0 + jest-validate: ^29.7.0 micromatch: ^4.0.4 parse-json: ^5.2.0 - pretty-format: ^29.4.1 + pretty-format: ^29.7.0 slash: ^3.0.0 strip-json-comments: ^3.1.1 peerDependencies: @@ -5212,7 +8316,7 @@ __metadata: optional: true ts-node: optional: true - checksum: 7ca9c46b25cdf1bd1dd77edeb9ae1a9669e47e6d3af7097bb21b43883415e8311ef97d7b17da5d8eaae695d89e368cfd427a98836391ffec2bdb683b3f4fa060 + checksum: 4cabf8f894c180cac80b7df1038912a3fc88f96f2622de33832f4b3314f83e22b08fb751da570c0ab2b7988f21604bdabade95e3c0c041068ac578c085cf7dff languageName: node linkType: hard @@ -5228,72 +8332,84 @@ __metadata: languageName: node linkType: hard -"jest-diff@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-diff@npm:29.4.1" +"jest-diff@npm:^29.6.2": + version: 29.6.2 + resolution: "jest-diff@npm:29.6.2" + dependencies: + chalk: ^4.0.0 + diff-sequences: ^29.4.3 + jest-get-type: ^29.4.3 + pretty-format: ^29.6.2 + checksum: 0effd66a0c23f8c139ebf7ca99ed30b479b86fff66f19ad4869f130aaf7ae6a24ca1533f697b7e4930cbe2ddffc85387723fcca673501c653fb77a38f538e959 + languageName: node + linkType: hard + +"jest-diff@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-diff@npm:29.7.0" dependencies: chalk: ^4.0.0 - diff-sequences: ^29.3.1 - jest-get-type: ^29.2.0 - pretty-format: ^29.4.1 - checksum: 359af2d11a75bbb3c91e3def8cfd0ede00afc6fb5d69d9495f2af5f6e18f692adb940d8338a186159f75afe48088d82bce14e2cc272cad9a5c2148bf0bc7f6bf + diff-sequences: ^29.6.3 + jest-get-type: ^29.6.3 + pretty-format: ^29.7.0 + checksum: 08e24a9dd43bfba1ef07a6374e5af138f53137b79ec3d5cc71a2303515335898888fa5409959172e1e05de966c9e714368d15e8994b0af7441f0721ee8e1bb77 languageName: node linkType: hard -"jest-docblock@npm:^29.2.0": - version: 29.2.0 - resolution: "jest-docblock@npm:29.2.0" +"jest-docblock@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-docblock@npm:29.7.0" dependencies: detect-newline: ^3.0.0 - checksum: b3f1227b7d73fc9e4952180303475cf337b36fa65c7f730ac92f0580f1c08439983262fee21cf3dba11429aa251b4eee1e3bc74796c5777116b400d78f9d2bbe + checksum: 66390c3e9451f8d96c5da62f577a1dad701180cfa9b071c5025acab2f94d7a3efc2515cfa1654ebe707213241541ce9c5530232cdc8017c91ed64eea1bd3b192 languageName: node linkType: hard -"jest-each@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-each@npm:29.4.1" +"jest-each@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-each@npm:29.7.0" dependencies: - "@jest/types": ^29.4.1 + "@jest/types": ^29.6.3 chalk: ^4.0.0 - jest-get-type: ^29.2.0 - jest-util: ^29.4.1 - pretty-format: ^29.4.1 - checksum: af44c12c747c4b76534b34f7135176c645ff740b59b20a29a3c6c97590ddb4216e7a2e076a43e98a0132350b4af5af3d8e5334bdd7753bf999a5ee240b7360b8 + jest-get-type: ^29.6.3 + jest-util: ^29.7.0 + pretty-format: ^29.7.0 + checksum: e88f99f0184000fc8813f2a0aa79e29deeb63700a3b9b7928b8a418d7d93cd24933608591dbbdea732b473eb2021c72991b5cc51a17966842841c6e28e6f691c languageName: node linkType: hard -"jest-environment-jsdom@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-environment-jsdom@npm:29.4.1" +"jest-environment-jsdom@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-environment-jsdom@npm:29.7.0" dependencies: - "@jest/environment": ^29.4.1 - "@jest/fake-timers": ^29.4.1 - "@jest/types": ^29.4.1 + "@jest/environment": ^29.7.0 + "@jest/fake-timers": ^29.7.0 + "@jest/types": ^29.6.3 "@types/jsdom": ^20.0.0 "@types/node": "*" - jest-mock: ^29.4.1 - jest-util: ^29.4.1 + jest-mock: ^29.7.0 + jest-util: ^29.7.0 jsdom: ^20.0.0 peerDependencies: canvas: ^2.5.0 peerDependenciesMeta: canvas: optional: true - checksum: ad0d3e2926f847ed711f11a622b3c4990bcdb3b150e013a1bc7789e5da6efb4c4554d2208e42d543cfb4732d971478330f75549f927002566f6d50963a17e133 + checksum: 559aac134c196fccc1dfc794d8fc87377e9f78e894bb13012b0831d88dec0abd7ece99abec69da564b8073803be4f04a9eb4f4d1bb80e29eec0cb252c254deb8 languageName: node linkType: hard -"jest-environment-node@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-environment-node@npm:29.4.1" +"jest-environment-node@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-environment-node@npm:29.7.0" dependencies: - "@jest/environment": ^29.4.1 - "@jest/fake-timers": ^29.4.1 - "@jest/types": ^29.4.1 + "@jest/environment": ^29.7.0 + "@jest/fake-timers": ^29.7.0 + "@jest/types": ^29.6.3 "@types/node": "*" - jest-mock: ^29.4.1 - jest-util: ^29.4.1 - checksum: 1de024edbc8a281b2c54d379d649a2d63e153049848c257be4118eaa5136cc4943a32f3ce44841ca2356e18850ab51f833cb94509f268e25ebcd32c6bfac27a3 + jest-mock: ^29.7.0 + jest-util: ^29.7.0 + checksum: 501a9966292cbe0ca3f40057a37587cb6def25e1e0c5e39ac6c650fe78d3c70a2428304341d084ac0cced5041483acef41c477abac47e9a290d5545fd2f15646 languageName: node linkType: hard @@ -5304,43 +8420,73 @@ __metadata: languageName: node linkType: hard -"jest-get-type@npm:^29.2.0": - version: 29.2.0 - resolution: "jest-get-type@npm:29.2.0" - checksum: e396fd880a30d08940ed8a8e43cd4595db1b8ff09649018eb358ca701811137556bae82626af73459e3c0f8c5e972ed1e57fd3b1537b13a260893dac60a90942 +"jest-get-type@npm:^29.4.3": + version: 29.4.3 + resolution: "jest-get-type@npm:29.4.3" + checksum: 6ac7f2dde1c65e292e4355b6c63b3a4897d7e92cb4c8afcf6d397f2682f8080e094c8b0b68205a74d269882ec06bf696a9de6cd3e1b7333531e5ed7b112605ce + languageName: node + linkType: hard + +"jest-get-type@npm:^29.6.3": + version: 29.6.3 + resolution: "jest-get-type@npm:29.6.3" + checksum: 88ac9102d4679d768accae29f1e75f592b760b44277df288ad76ce5bf038c3f5ce3719dea8aa0f035dac30e9eb034b848ce716b9183ad7cc222d029f03e92205 + languageName: node + linkType: hard + +"jest-haste-map@npm:^29.6.2": + version: 29.6.2 + resolution: "jest-haste-map@npm:29.6.2" + dependencies: + "@jest/types": ^29.6.1 + "@types/graceful-fs": ^4.1.3 + "@types/node": "*" + anymatch: ^3.0.3 + fb-watchman: ^2.0.0 + fsevents: ^2.3.2 + graceful-fs: ^4.2.9 + jest-regex-util: ^29.4.3 + jest-util: ^29.6.2 + jest-worker: ^29.6.2 + micromatch: ^4.0.4 + walker: ^1.0.8 + dependenciesMeta: + fsevents: + optional: true + checksum: 726233972030eb2e5bce6c9468e497310436b455c88b40e744bd053e20a6f3ff19aec340edcbd89537c629ed5cf8916506bc895d690cc39a0862c74dcd95b7b8 languageName: node linkType: hard -"jest-haste-map@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-haste-map@npm:29.4.1" +"jest-haste-map@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-haste-map@npm:29.7.0" dependencies: - "@jest/types": ^29.4.1 + "@jest/types": ^29.6.3 "@types/graceful-fs": ^4.1.3 "@types/node": "*" anymatch: ^3.0.3 fb-watchman: ^2.0.0 fsevents: ^2.3.2 graceful-fs: ^4.2.9 - jest-regex-util: ^29.2.0 - jest-util: ^29.4.1 - jest-worker: ^29.4.1 + jest-regex-util: ^29.6.3 + jest-util: ^29.7.0 + jest-worker: ^29.7.0 micromatch: ^4.0.4 walker: ^1.0.8 dependenciesMeta: fsevents: optional: true - checksum: f9815172f0b5d89b723558c5544db4915e03806590b6b686dabb91811b201f3eac07e7211f021a19fc6f9fa6cb90836efac92970ec16385ea18285d91ba8ffc3 + checksum: c2c8f2d3e792a963940fbdfa563ce14ef9e14d4d86da645b96d3cd346b8d35c5ce0b992ee08593939b5f718cf0a1f5a90011a056548a1dbf58397d4356786f01 languageName: node linkType: hard -"jest-leak-detector@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-leak-detector@npm:29.4.1" +"jest-leak-detector@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-leak-detector@npm:29.7.0" dependencies: - jest-get-type: ^29.2.0 - pretty-format: ^29.4.1 - checksum: 94f8091e52e163a4e50420112988d8386117dfa92bd21738d9a367dc5e1f87d3e645bee2db4fc7fc25a1d495934761bb7a64750d61a7e7b6477b8f1f54da317c + jest-get-type: ^29.6.3 + pretty-format: ^29.7.0 + checksum: e3950e3ddd71e1d0c22924c51a300a1c2db6cf69ec1e51f95ccf424bcc070f78664813bef7aed4b16b96dfbdeea53fe358f8aeaaea84346ae15c3735758f1605 languageName: node linkType: hard @@ -5356,43 +8502,83 @@ __metadata: languageName: node linkType: hard -"jest-matcher-utils@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-matcher-utils@npm:29.4.1" +"jest-matcher-utils@npm:^29.6.2": + version: 29.6.2 + resolution: "jest-matcher-utils@npm:29.6.2" + dependencies: + chalk: ^4.0.0 + jest-diff: ^29.6.2 + jest-get-type: ^29.4.3 + pretty-format: ^29.6.2 + checksum: 3e1b65dd30d05f75fe56dc45fbe4135aec2ff96a3d1e21afbf6a66f3a45a7e29cd0fd37cf80b9564e0381d6205833f77ccaf766c6f7e1aad6b7924d117be504e + languageName: node + linkType: hard + +"jest-matcher-utils@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-matcher-utils@npm:29.7.0" + dependencies: + chalk: ^4.0.0 + jest-diff: ^29.7.0 + jest-get-type: ^29.6.3 + pretty-format: ^29.7.0 + checksum: d7259e5f995d915e8a37a8fd494cb7d6af24cd2a287b200f831717ba0d015190375f9f5dc35393b8ba2aae9b2ebd60984635269c7f8cff7d85b077543b7744cd + languageName: node + linkType: hard + +"jest-message-util@npm:^29.6.2": + version: 29.6.2 + resolution: "jest-message-util@npm:29.6.2" dependencies: + "@babel/code-frame": ^7.12.13 + "@jest/types": ^29.6.1 + "@types/stack-utils": ^2.0.0 chalk: ^4.0.0 - jest-diff: ^29.4.1 - jest-get-type: ^29.2.0 - pretty-format: ^29.4.1 - checksum: ea84dbcae82241cb28e94ff586660aeec51196d9245413dc516ce3aa78140b3ea728b1168b242281b59ad513b0148b9f12d674729bd043a894a3ba9d6ec164f4 + graceful-fs: ^4.2.9 + micromatch: ^4.0.4 + pretty-format: ^29.6.2 + slash: ^3.0.0 + stack-utils: ^2.0.3 + checksum: e8e3c8d2301e2ca4038ed6df8cbba7fedc6949d1ede4c0e3f1f44f53afb56d77eb35983fa460140d0eadeab99a5f3ae04b703fe77cd7b316b40b361228b5aa1a languageName: node linkType: hard -"jest-message-util@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-message-util@npm:29.4.1" +"jest-message-util@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-message-util@npm:29.7.0" dependencies: "@babel/code-frame": ^7.12.13 - "@jest/types": ^29.4.1 + "@jest/types": ^29.6.3 "@types/stack-utils": ^2.0.0 chalk: ^4.0.0 graceful-fs: ^4.2.9 micromatch: ^4.0.4 - pretty-format: ^29.4.1 + pretty-format: ^29.7.0 slash: ^3.0.0 stack-utils: ^2.0.3 - checksum: 7d49823401b6d42f0d2d63dd9c0f11d2f64783416f82a68634190abee46e600e25bb0b380c746726acc56e854687bb03a76e26e617fcdda78e8c6316423b694f + checksum: a9d025b1c6726a2ff17d54cc694de088b0489456c69106be6b615db7a51b7beb66788bea7a59991a019d924fbf20f67d085a445aedb9a4d6760363f4d7d09930 + languageName: node + linkType: hard + +"jest-mock@npm:^29.6.2": + version: 29.6.2 + resolution: "jest-mock@npm:29.6.2" + dependencies: + "@jest/types": ^29.6.1 + "@types/node": "*" + jest-util: ^29.6.2 + checksum: 0bacb5d58441462c0e531ec4d2f7377eecbe21f664d8a460e72f94ba61d22635028931678e7a0f1c3e3f5894973db8e409432f7db4c01283456c8fdbd85f5b3b languageName: node linkType: hard -"jest-mock@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-mock@npm:29.4.1" +"jest-mock@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-mock@npm:29.7.0" dependencies: - "@jest/types": ^29.4.1 + "@jest/types": ^29.6.3 "@types/node": "*" - jest-util: ^29.4.1 - checksum: 7f595a71886a64eda21b9fc2660e86a02f0efe6685496c675e6be921d5609fe9ac5fe97e8c7d1cae811974967439e8daa12c1779e731bdd777c47326f173e4a2 + jest-util: ^29.7.0 + checksum: 81ba9b68689a60be1482212878973700347cb72833c5e5af09895882b9eb5c4e02843a1bbdf23f94c52d42708bab53a30c45a3482952c9eec173d1eaac5b86c5 languageName: node linkType: hard @@ -5408,196 +8594,252 @@ __metadata: languageName: node linkType: hard -"jest-regex-util@npm:^29.2.0": - version: 29.2.0 - resolution: "jest-regex-util@npm:29.2.0" - checksum: 7c533e51c51230dac20c0d7395b19b8366cb022f7c6e08e6bcf2921626840ff90424af4c9b4689f02f0addfc9b071c4cd5f8f7a989298a4c8e0f9c94418ca1c3 +"jest-regex-util@npm:^29.4.3": + version: 29.4.3 + resolution: "jest-regex-util@npm:29.4.3" + checksum: 96fc7fc28cd4dd73a63c13a526202c4bd8b351d4e5b68b1a2a2c88da3308c2a16e26feaa593083eb0bac38cca1aa9dd05025412e7de013ba963fb8e66af22b8a + languageName: node + linkType: hard + +"jest-regex-util@npm:^29.6.3": + version: 29.6.3 + resolution: "jest-regex-util@npm:29.6.3" + checksum: 0518beeb9bf1228261695e54f0feaad3606df26a19764bc19541e0fc6e2a3737191904607fb72f3f2ce85d9c16b28df79b7b1ec9443aa08c3ef0e9efda6f8f2a languageName: node linkType: hard -"jest-resolve-dependencies@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-resolve-dependencies@npm:29.4.1" +"jest-resolve-dependencies@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-resolve-dependencies@npm:29.7.0" dependencies: - jest-regex-util: ^29.2.0 - jest-snapshot: ^29.4.1 - checksum: 561e588abc1aae3d44a46b53eaeee1bc86419407c2e9b97afb7b3fc6ea2df06ef1523e9561bfc8d790c7a48a40031c3b1e1f38281850d23b0a07351553f7e85e + jest-regex-util: ^29.6.3 + jest-snapshot: ^29.7.0 + checksum: aeb75d8150aaae60ca2bb345a0d198f23496494677cd6aefa26fc005faf354061f073982175daaf32b4b9d86b26ca928586344516e3e6969aa614cb13b883984 languageName: node linkType: hard -"jest-resolve@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-resolve@npm:29.4.1" +"jest-resolve@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-resolve@npm:29.7.0" dependencies: chalk: ^4.0.0 graceful-fs: ^4.2.9 - jest-haste-map: ^29.4.1 + jest-haste-map: ^29.7.0 jest-pnp-resolver: ^1.2.2 - jest-util: ^29.4.1 - jest-validate: ^29.4.1 + jest-util: ^29.7.0 + jest-validate: ^29.7.0 resolve: ^1.20.0 resolve.exports: ^2.0.0 slash: ^3.0.0 - checksum: 1e19c0156937366b3edc867d38ca4c6c8193067605921544a5f5d2019a96c01be5fb9b385bb61a3600eacaceb7a3333f42dbed4cb699403d8575d476a9d4c5d5 + checksum: 0ca218e10731aa17920526ec39deaec59ab9b966237905ffc4545444481112cd422f01581230eceb7e82d86f44a543d520a71391ec66e1b4ef1a578bd5c73487 languageName: node linkType: hard -"jest-runner@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-runner@npm:29.4.1" +"jest-runner@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-runner@npm:29.7.0" dependencies: - "@jest/console": ^29.4.1 - "@jest/environment": ^29.4.1 - "@jest/test-result": ^29.4.1 - "@jest/transform": ^29.4.1 - "@jest/types": ^29.4.1 + "@jest/console": ^29.7.0 + "@jest/environment": ^29.7.0 + "@jest/test-result": ^29.7.0 + "@jest/transform": ^29.7.0 + "@jest/types": ^29.6.3 "@types/node": "*" chalk: ^4.0.0 emittery: ^0.13.1 graceful-fs: ^4.2.9 - jest-docblock: ^29.2.0 - jest-environment-node: ^29.4.1 - jest-haste-map: ^29.4.1 - jest-leak-detector: ^29.4.1 - jest-message-util: ^29.4.1 - jest-resolve: ^29.4.1 - jest-runtime: ^29.4.1 - jest-util: ^29.4.1 - jest-watcher: ^29.4.1 - jest-worker: ^29.4.1 + jest-docblock: ^29.7.0 + jest-environment-node: ^29.7.0 + jest-haste-map: ^29.7.0 + jest-leak-detector: ^29.7.0 + jest-message-util: ^29.7.0 + jest-resolve: ^29.7.0 + jest-runtime: ^29.7.0 + jest-util: ^29.7.0 + jest-watcher: ^29.7.0 + jest-worker: ^29.7.0 p-limit: ^3.1.0 source-map-support: 0.5.13 - checksum: b6651d8ac16c9f3ce502b58c97e59b062e83b3b7a9bee91812fbbcf141098ef1456902be6598d7980727a0c22457290cb548913dea5bd25ceaca4e1822f733bf + checksum: f0405778ea64812bf9b5c50b598850d94ccf95d7ba21f090c64827b41decd680ee19fcbb494007cdd7f5d0d8906bfc9eceddd8fa583e753e736ecd462d4682fb languageName: node linkType: hard -"jest-runtime@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-runtime@npm:29.4.1" +"jest-runtime@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-runtime@npm:29.7.0" dependencies: - "@jest/environment": ^29.4.1 - "@jest/fake-timers": ^29.4.1 - "@jest/globals": ^29.4.1 - "@jest/source-map": ^29.2.0 - "@jest/test-result": ^29.4.1 - "@jest/transform": ^29.4.1 - "@jest/types": ^29.4.1 + "@jest/environment": ^29.7.0 + "@jest/fake-timers": ^29.7.0 + "@jest/globals": ^29.7.0 + "@jest/source-map": ^29.6.3 + "@jest/test-result": ^29.7.0 + "@jest/transform": ^29.7.0 + "@jest/types": ^29.6.3 "@types/node": "*" chalk: ^4.0.0 cjs-module-lexer: ^1.0.0 collect-v8-coverage: ^1.0.0 glob: ^7.1.3 graceful-fs: ^4.2.9 - jest-haste-map: ^29.4.1 - jest-message-util: ^29.4.1 - jest-mock: ^29.4.1 - jest-regex-util: ^29.2.0 - jest-resolve: ^29.4.1 - jest-snapshot: ^29.4.1 - jest-util: ^29.4.1 - semver: ^7.3.5 + jest-haste-map: ^29.7.0 + jest-message-util: ^29.7.0 + jest-mock: ^29.7.0 + jest-regex-util: ^29.6.3 + jest-resolve: ^29.7.0 + jest-snapshot: ^29.7.0 + jest-util: ^29.7.0 slash: ^3.0.0 strip-bom: ^4.0.0 - checksum: 6c5fcc350ef019bbc0c0601e41c236f4f666c6cee2eef5048fd07a48cc579133d68c852a0d68d9ebbc9b4e115a4f1d0ab5641f3d204944f312fbcb11b73cef8f + checksum: d19f113d013e80691e07047f68e1e3448ef024ff2c6b586ce4f90cd7d4c62a2cd1d460110491019719f3c59bfebe16f0e201ed005ef9f80e2cf798c374eed54e languageName: node linkType: hard -"jest-snapshot@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-snapshot@npm:29.4.1" +"jest-snapshot@npm:^29.6.2": + version: 29.6.2 + resolution: "jest-snapshot@npm:29.6.2" dependencies: "@babel/core": ^7.11.6 "@babel/generator": ^7.7.2 "@babel/plugin-syntax-jsx": ^7.7.2 "@babel/plugin-syntax-typescript": ^7.7.2 - "@babel/traverse": ^7.7.2 "@babel/types": ^7.3.3 - "@jest/expect-utils": ^29.4.1 - "@jest/transform": ^29.4.1 - "@jest/types": ^29.4.1 - "@types/babel__traverse": ^7.0.6 - "@types/prettier": ^2.1.5 + "@jest/expect-utils": ^29.6.2 + "@jest/transform": ^29.6.2 + "@jest/types": ^29.6.1 babel-preset-current-node-syntax: ^1.0.0 chalk: ^4.0.0 - expect: ^29.4.1 + expect: ^29.6.2 graceful-fs: ^4.2.9 - jest-diff: ^29.4.1 - jest-get-type: ^29.2.0 - jest-haste-map: ^29.4.1 - jest-matcher-utils: ^29.4.1 - jest-message-util: ^29.4.1 - jest-util: ^29.4.1 + jest-diff: ^29.6.2 + jest-get-type: ^29.4.3 + jest-matcher-utils: ^29.6.2 + jest-message-util: ^29.6.2 + jest-util: ^29.6.2 natural-compare: ^1.4.0 - pretty-format: ^29.4.1 - semver: ^7.3.5 - checksum: 0d309d4a5edd985be1a9e2d64a78f588f5d98b8add709cdf72c6ce77508329dccdb0de3f0be45223f67535691f3eb6430c13fdfb7dfcca7a81d4a210de2fa736 + pretty-format: ^29.6.2 + semver: ^7.5.3 + checksum: c1c70a9dbce7fca62ed73ac38234b4ee643e8b667acf71b4417ab67776c1188bb08b8ad450e56a2889ad182903ffd416386fa8082a477724ccf8d8c29a4c6906 + languageName: node + linkType: hard + +"jest-snapshot@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-snapshot@npm:29.7.0" + dependencies: + "@babel/core": ^7.11.6 + "@babel/generator": ^7.7.2 + "@babel/plugin-syntax-jsx": ^7.7.2 + "@babel/plugin-syntax-typescript": ^7.7.2 + "@babel/types": ^7.3.3 + "@jest/expect-utils": ^29.7.0 + "@jest/transform": ^29.7.0 + "@jest/types": ^29.6.3 + babel-preset-current-node-syntax: ^1.0.0 + chalk: ^4.0.0 + expect: ^29.7.0 + graceful-fs: ^4.2.9 + jest-diff: ^29.7.0 + jest-get-type: ^29.6.3 + jest-matcher-utils: ^29.7.0 + jest-message-util: ^29.7.0 + jest-util: ^29.7.0 + natural-compare: ^1.4.0 + pretty-format: ^29.7.0 + semver: ^7.5.3 + checksum: 86821c3ad0b6899521ce75ee1ae7b01b17e6dfeff9166f2cf17f012e0c5d8c798f30f9e4f8f7f5bed01ea7b55a6bc159f5eda778311162cbfa48785447c237ad + languageName: node + linkType: hard + +"jest-util@npm:^29.6.2": + version: 29.6.2 + resolution: "jest-util@npm:29.6.2" + dependencies: + "@jest/types": ^29.6.1 + "@types/node": "*" + chalk: ^4.0.0 + ci-info: ^3.2.0 + graceful-fs: ^4.2.9 + picomatch: ^2.2.3 + checksum: 8aedc0c80083d0cabd6c6c4f04dea1cbcac609fd7bc3b1fc05a3999291bd6e63dd52b0c806f9378d5cae28eff5a6191709a4987861001293f8d03e53984adca4 languageName: node linkType: hard -"jest-util@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-util@npm:29.4.1" +"jest-util@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-util@npm:29.7.0" dependencies: - "@jest/types": ^29.4.1 + "@jest/types": ^29.6.3 "@types/node": "*" chalk: ^4.0.0 ci-info: ^3.2.0 graceful-fs: ^4.2.9 picomatch: ^2.2.3 - checksum: 10a0e6c448ace1386f728ee3b7669f67878bb0c2e668a902d11140cc3f75c89a18f4142a37a24ccb587ede20dad86d497b3e8df4f26848a9be50a44779d92bc9 + checksum: 042ab4980f4ccd4d50226e01e5c7376a8556b472442ca6091a8f102488c0f22e6e8b89ea874111d2328a2080083bf3225c86f3788c52af0bd0345a00eb57a3ca languageName: node linkType: hard -"jest-validate@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-validate@npm:29.4.1" +"jest-validate@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-validate@npm:29.7.0" dependencies: - "@jest/types": ^29.4.1 + "@jest/types": ^29.6.3 camelcase: ^6.2.0 chalk: ^4.0.0 - jest-get-type: ^29.2.0 + jest-get-type: ^29.6.3 leven: ^3.1.0 - pretty-format: ^29.4.1 - checksum: f2cd98293ed961e79bc75935fbc8fc18e57bcd207175a4119baf810da38542704545afa8ca402456e34d298e44c7564570400645537c31dab9bf27e18284a650 + pretty-format: ^29.7.0 + checksum: 191fcdc980f8a0de4dbdd879fa276435d00eb157a48683af7b3b1b98b0f7d9de7ffe12689b617779097ff1ed77601b9f7126b0871bba4f776e222c40f62e9dae languageName: node linkType: hard -"jest-watcher@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-watcher@npm:29.4.1" +"jest-watcher@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-watcher@npm:29.7.0" dependencies: - "@jest/test-result": ^29.4.1 - "@jest/types": ^29.4.1 + "@jest/test-result": ^29.7.0 + "@jest/types": ^29.6.3 "@types/node": "*" ansi-escapes: ^4.2.1 chalk: ^4.0.0 emittery: ^0.13.1 - jest-util: ^29.4.1 + jest-util: ^29.7.0 string-length: ^4.0.1 - checksum: 210c4931e065367bf8fcd08a31506245610f25cf4bf566c67136afd963fdf9ff56730570e794e52d7ae2f9e6e64f6d92b9287691af14b01dd7deacac840415fb + checksum: 67e6e7fe695416deff96b93a14a561a6db69389a0667e9489f24485bb85e5b54e12f3b2ba511ec0b777eca1e727235b073e3ebcdd473d68888650489f88df92f + languageName: node + linkType: hard + +"jest-worker@npm:^29.6.2": + version: 29.6.2 + resolution: "jest-worker@npm:29.6.2" + dependencies: + "@types/node": "*" + jest-util: ^29.6.2 + merge-stream: ^2.0.0 + supports-color: ^8.0.0 + checksum: 11035564534bf181ead80b25be138c2d42372bd5626151a3e705200d47a74fd9da3ca79f8a7b15806cdc325ad73c3d21d23acceeed99d50941589ff02915ed38 languageName: node linkType: hard -"jest-worker@npm:^29.4.1": - version: 29.4.1 - resolution: "jest-worker@npm:29.4.1" +"jest-worker@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-worker@npm:29.7.0" dependencies: "@types/node": "*" - jest-util: ^29.4.1 + jest-util: ^29.7.0 merge-stream: ^2.0.0 supports-color: ^8.0.0 - checksum: c3b3eaa09d7ac88e11800a63e96a90ba27b7d609335c73842ee5f8e899e9fd6a6aa68009f54dabb6d6e561c98127def369fc86c8f528639ddfb74dd130f4be9f + checksum: 30fff60af49675273644d408b650fc2eb4b5dcafc5a0a455f238322a8f9d8a98d847baca9d51ff197b6747f54c7901daa2287799230b856a0f48287d131f8c13 languageName: node linkType: hard -"jest@npm:^29.0.0": - version: 29.4.1 - resolution: "jest@npm:29.4.1" +"jest@npm:^29.7.0": + version: 29.7.0 + resolution: "jest@npm:29.7.0" dependencies: - "@jest/core": ^29.4.1 - "@jest/types": ^29.4.1 + "@jest/core": ^29.7.0 + "@jest/types": ^29.6.3 import-local: ^3.0.2 - jest-cli: ^29.4.1 + jest-cli: ^29.7.0 peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: @@ -5605,7 +8847,16 @@ __metadata: optional: true bin: jest: bin/jest.js - checksum: b2f74b24d74e135460579a34727d5027818ab6d55a84cbb1d6e730064f8c8fec0590092c6a84334178b310b923587798b0091ab8ae40baba372530fc46dfd195 + checksum: 17ca8d67504a7dbb1998cf3c3077ec9031ba3eb512da8d71cb91bcabb2b8995c4e4b292b740cb9bf1cbff5ce3e110b3f7c777b0cefb6f41ab05445f248d0ee0b + languageName: node + linkType: hard + +"jiti@npm:^1.21.0, jiti@npm:^1.21.6": + version: 1.21.6 + resolution: "jiti@npm:1.21.6" + bin: + jiti: bin/jiti.js + checksum: 9ea4a70a7bb950794824683ed1c632e2ede26949fbd348e2ba5ec8dc5efa54dc42022d85ae229cadaa60d4b95012e80ea07d625797199b688cc22ab0e8891d32 languageName: node linkType: hard @@ -5623,6 +8874,13 @@ __metadata: languageName: node linkType: hard +"js-tokens@npm:^9.0.0": + version: 9.0.0 + resolution: "js-tokens@npm:9.0.0" + checksum: 427d0db681caab0c906cfc78a0235bbe7b41712cee83f3f14785c1de079a1b1a85693cc8f99a3f71685d0d76acaa5b9c8920850b67f93d3eeb7ef186987d186c + languageName: node + linkType: hard + "js-yaml@npm:^3.10.0, js-yaml@npm:^3.13.1, js-yaml@npm:^3.8.1": version: 3.14.1 resolution: "js-yaml@npm:3.14.1" @@ -5646,6 +8904,13 @@ __metadata: languageName: node linkType: hard +"jsbn@npm:1.1.0": + version: 1.1.0 + resolution: "jsbn@npm:1.1.0" + checksum: 944f924f2bd67ad533b3850eee47603eed0f6ae425fd1ee8c760f477e8c34a05f144c1bd4f5a5dd1963141dc79a2c55f89ccc5ab77d039e7077f3ad196b64965 + languageName: node + linkType: hard + "jsdom@npm:^20.0.0": version: 20.0.3 resolution: "jsdom@npm:20.0.3" @@ -5708,6 +8973,13 @@ __metadata: languageName: node linkType: hard +"json-parse-even-better-errors@npm:^3.0.0": + version: 3.0.2 + resolution: "json-parse-even-better-errors@npm:3.0.2" + checksum: 6f04ea6c9ccb783630a59297959247e921cc90b917b8351197ca7fd058fccc7079268fd9362be21ba876fc26aa5039369dd0a2280aae49aae425784794a94927 + languageName: node + linkType: hard + "json-schema-traverse@npm:^0.4.1": version: 0.4.1 resolution: "json-schema-traverse@npm:0.4.1" @@ -5733,7 +9005,7 @@ __metadata: languageName: node linkType: hard -"json5@npm:^2.2.2": +"json5@npm:^2.2.2, json5@npm:^2.2.3": version: 2.2.3 resolution: "json5@npm:2.2.3" bin: @@ -5749,6 +9021,19 @@ __metadata: languageName: node linkType: hard +"jsonfile@npm:^6.0.1": + version: 6.1.0 + resolution: "jsonfile@npm:6.1.0" + dependencies: + graceful-fs: ^4.1.6 + universalify: ^2.0.0 + dependenciesMeta: + graceful-fs: + optional: true + checksum: 7af3b8e1ac8fe7f1eccc6263c6ca14e1966fcbc74b618d3c78a0a2075579487547b94f72b7a1114e844a1e15bb00d440e5d1720bfc4612d790a6f285d5ea8354 + languageName: node + linkType: hard + "jsx-ast-utils@npm:^2.4.1 || ^3.0.0": version: 3.3.3 resolution: "jsx-ast-utils@npm:3.3.3" @@ -5759,6 +9044,18 @@ __metadata: languageName: node linkType: hard +"jszip@npm:^3.10.1": + version: 3.10.1 + resolution: "jszip@npm:3.10.1" + dependencies: + lie: ~3.3.0 + pako: ~1.0.2 + readable-stream: ~2.3.6 + setimmediate: ^1.0.5 + checksum: abc77bfbe33e691d4d1ac9c74c8851b5761fba6a6986630864f98d876f3fcc2d36817dfc183779f32c00157b5d53a016796677298272a714ae096dfe6b1c8b60 + languageName: node + linkType: hard + "keyv@npm:^4.0.0": version: 4.5.2 resolution: "keyv@npm:4.5.2" @@ -5791,6 +9088,20 @@ __metadata: languageName: node linkType: hard +"klona@npm:^2.0.6": + version: 2.0.6 + resolution: "klona@npm:2.0.6" + checksum: ac9ee3732e42b96feb67faae4d27cf49494e8a3bf3fa7115ce242fe04786788e0aff4741a07a45a2462e2079aa983d73d38519c85d65b70ef11447bbc3c58ce7 + languageName: node + linkType: hard + +"knitwork@npm:^1.1.0": + version: 1.1.0 + resolution: "knitwork@npm:1.1.0" + checksum: eb22cde0ec60c9be48dfb3e04a7e1d60527fc0c8725c0e0f63ac73c8974d1533b008ffa39d1ec871f0cfb223d953d27dcaf7feeedc6ba84326288eb00508bcb6 + languageName: node + linkType: hard + "lazy-cache@npm:^2.0.2": version: 2.0.2 resolution: "lazy-cache@npm:2.0.2" @@ -5800,6 +9111,15 @@ __metadata: languageName: node linkType: hard +"lazystream@npm:^1.0.0": + version: 1.0.1 + resolution: "lazystream@npm:1.0.1" + dependencies: + readable-stream: ^2.0.5 + checksum: 822c54c6b87701a6491c70d4fabc4cafcf0f87d6b656af168ee7bb3c45de9128a801cb612e6eeeefc64d298a7524a698dd49b13b0121ae50c2ae305f0dcc5310 + languageName: node + linkType: hard + "leven@npm:^3.1.0": version: 3.1.0 resolution: "leven@npm:3.1.0" @@ -5827,6 +9147,15 @@ __metadata: languageName: node linkType: hard +"lie@npm:~3.3.0": + version: 3.3.0 + resolution: "lie@npm:3.3.0" + dependencies: + immediate: ~3.0.5 + checksum: 33102302cf19766f97919a6a98d481e01393288b17a6aa1f030a3542031df42736edde8dab29ffdbf90bebeffc48c761eb1d064dc77592ca3ba3556f9fe6d2a8 + languageName: node + linkType: hard + "lilconfig@npm:2.0.6": version: 2.0.6 resolution: "lilconfig@npm:2.0.6" @@ -5841,6 +9170,13 @@ __metadata: languageName: node linkType: hard +"lines-and-columns@npm:^2.0.3": + version: 2.0.4 + resolution: "lines-and-columns@npm:2.0.4" + checksum: f5e3e207467d3e722280c962b786dc20ebceb191821dcd771d14ab3146b6744cae28cf305ee4638805bec524ac54800e15698c853fcc53243821f88df37e4975 + languageName: node + linkType: hard + "lint-staged@npm:^13.1.0": version: 13.1.0 resolution: "lint-staged@npm:13.1.0" @@ -5897,6 +9233,34 @@ __metadata: languageName: node linkType: hard +"local-pkg@npm:^0.4.3": + version: 0.4.3 + resolution: "local-pkg@npm:0.4.3" + checksum: 7825aca531dd6afa3a3712a0208697aa4a5cd009065f32e3fb732aafcc42ed11f277b5ac67229222e96f4def55197171cdf3d5522d0381b489d2e5547b407d55 + languageName: node + linkType: hard + +"local-pkg@npm:^0.5.0": + version: 0.5.0 + resolution: "local-pkg@npm:0.5.0" + dependencies: + mlly: ^1.4.2 + pkg-types: ^1.0.3 + checksum: b0a6931e588ad4f7bf4ab49faacf49e07fc4d05030f895aa055d46727a15b99300d39491cf2c3e3f05284aec65565fb760debb74c32e64109f4a101f9300d81a + languageName: node + linkType: hard + +"locate-app@npm:^2.2.24": + version: 2.4.43 + resolution: "locate-app@npm:2.4.43" + dependencies: + "@promptbook/utils": 0.70.0-1 + type-fest: 2.13.0 + userhome: 1.0.0 + checksum: b83c4c3b0406d5b116ce3f145dbc747582f147b3e99ffe72d2255270ff4a21d7a6b51fa27a9be5eb044544c91457927f6bd449719e121eb2605b006f4ffcf3e4 + languageName: node + linkType: hard + "locate-path@npm:^5.0.0": version: 5.0.0 resolution: "locate-path@npm:5.0.0" @@ -5915,6 +9279,15 @@ __metadata: languageName: node linkType: hard +"locate-path@npm:^7.1.0": + version: 7.2.0 + resolution: "locate-path@npm:7.2.0" + dependencies: + p-locate: ^6.0.0 + checksum: c1b653bdf29beaecb3d307dfb7c44d98a2a98a02ebe353c9ad055d1ac45d6ed4e1142563d222df9b9efebc2bcb7d4c792b507fad9e7150a04c29530b7db570f8 + languageName: node + linkType: hard + "lodash._reinterpolate@npm:^3.0.0": version: 3.0.0 resolution: "lodash._reinterpolate@npm:3.0.0" @@ -5922,6 +9295,27 @@ __metadata: languageName: node linkType: hard +"lodash.clonedeep@npm:^4.5.0": + version: 4.5.0 + resolution: "lodash.clonedeep@npm:4.5.0" + checksum: 92c46f094b064e876a23c97f57f81fbffd5d760bf2d8a1c61d85db6d1e488c66b0384c943abee4f6af7debf5ad4e4282e74ff83177c9e63d8ff081a4837c3489 + languageName: node + linkType: hard + +"lodash.flattendeep@npm:^4.4.0": + version: 4.4.0 + resolution: "lodash.flattendeep@npm:4.4.0" + checksum: 8521c919acac3d4bcf0aaf040c1ca9cb35d6c617e2d72e9b4d51c9a58b4366622cd6077441a18be626c3f7b28227502b3bf042903d447b056ee7e0b11d45c722 + languageName: node + linkType: hard + +"lodash.isequal@npm:^4.5.0": + version: 4.5.0 + resolution: "lodash.isequal@npm:4.5.0" + checksum: da27515dc5230eb1140ba65ff8de3613649620e8656b19a6270afe4866b7bd461d9ba2ac8a48dcc57f7adac4ee80e1de9f965d89d4d81a0ad52bb3eec2609644 + languageName: node + linkType: hard + "lodash.merge@npm:^4.6.2": version: 4.6.2 resolution: "lodash.merge@npm:4.6.2" @@ -5929,6 +9323,13 @@ __metadata: languageName: node linkType: hard +"lodash.pickby@npm:^4.6.0": + version: 4.6.0 + resolution: "lodash.pickby@npm:4.6.0" + checksum: a554d898c15bcd3218e4005b95b5146210bd862010c7d242d17106ee36aed9b9209a858ce974136ab1faadd86a82297761c206fda7f1886278bac827145c5536 + languageName: node + linkType: hard + "lodash.template@npm:^4.4.0": version: 4.5.0 resolution: "lodash.template@npm:4.5.0" @@ -5948,6 +9349,20 @@ __metadata: languageName: node linkType: hard +"lodash.union@npm:^4.6.0": + version: 4.6.0 + resolution: "lodash.union@npm:4.6.0" + checksum: 1514dc6508b2614ec071a6470f36eb7a70f69bf1abb6d55bdfdc21069635a4517783654b28504c0f025059a7598d37529766888e6d5902b8ab28b712228f7b2a + languageName: node + linkType: hard + +"lodash.zip@npm:^4.2.0": + version: 4.2.0 + resolution: "lodash.zip@npm:4.2.0" + checksum: 41fd8dc1af8b38086369d4fdc81dd725715dcda36ec463d907b9c58f25e5ebb518376b0acec39ded96a6b1790a89c387b9a6b1627306f33fabaf987c8d5eac9e + languageName: node + linkType: hard + "lodash@npm:^4.17.15, lodash@npm:^4.17.21": version: 4.17.21 resolution: "lodash@npm:4.17.21" @@ -5955,6 +9370,16 @@ __metadata: languageName: node linkType: hard +"log-symbols@npm:^4.1.0": + version: 4.1.0 + resolution: "log-symbols@npm:4.1.0" + dependencies: + chalk: ^4.1.0 + is-unicode-supported: ^0.1.0 + checksum: fce1497b3135a0198803f9f07464165e9eb83ed02ceb2273930a6f8a508951178d8cf4f0378e9d28300a2ed2bc49050995d2bd5f53ab716bb15ac84d58c6ef74 + languageName: node + linkType: hard + "log-update@npm:^4.0.0": version: 4.0.0 resolution: "log-update@npm:4.0.0" @@ -5967,6 +9392,20 @@ __metadata: languageName: node linkType: hard +"loglevel-plugin-prefix@npm:^0.8.4": + version: 0.8.4 + resolution: "loglevel-plugin-prefix@npm:0.8.4" + checksum: 5fe0632fa04263e083f87204107a06aa53e40a3537e08752539f5c0fd9a0ef112fe9ba6bdaed791502156c67a4ff7993a2b2871404615f0163f4c49649c362e4 + languageName: node + linkType: hard + +"loglevel@npm:^1.6.0": + version: 1.9.2 + resolution: "loglevel@npm:1.9.2" + checksum: 896c67b90a507bfcfc1e9a4daa7bf789a441dd70d95cd13b998d6dd46233a3bfadfb8fadb07250432bbfb53bf61e95f2520f9b11f9d3175cc460e5c251eca0af + languageName: node + linkType: hard + "loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" @@ -5985,6 +9424,13 @@ __metadata: languageName: node linkType: hard +"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": + version: 10.4.3 + resolution: "lru-cache@npm:10.4.3" + checksum: 6476138d2125387a6d20f100608c2583d415a4f64a0fecf30c9e2dda976614f09cad4baa0842447bd37dd459a7bd27f57d9d8f8ce558805abd487c583f3d774a + languageName: node + linkType: hard + "lru-cache@npm:^4.0.1": version: 4.1.5 resolution: "lru-cache@npm:4.1.5" @@ -6013,6 +9459,13 @@ __metadata: languageName: node linkType: hard +"lru-cache@npm:^7.14.1": + version: 7.18.3 + resolution: "lru-cache@npm:7.18.3" + checksum: e550d772384709deea3f141af34b6d4fa392e2e418c1498c078de0ee63670f1f46f5eee746e8ef7e69e1c895af0d4224e62ee33e66a543a14763b0f2e74c1356 + languageName: node + linkType: hard + "lru-cache@npm:^7.7.1": version: 7.14.1 resolution: "lru-cache@npm:7.14.1" @@ -6020,21 +9473,21 @@ __metadata: languageName: node linkType: hard -"lz-string@npm:^1.4.4": - version: 1.4.4 - resolution: "lz-string@npm:1.4.4" +"lz-string@npm:^1.5.0": + version: 1.5.0 + resolution: "lz-string@npm:1.5.0" bin: lz-string: bin/bin.js - checksum: 54e31238a61a84d8f664d9860a9fba7310c5b97a52c444f80543069bc084815eff40b8d4474ae1d93992fdf6c252dca37cf27f6adbeb4dbc3df2f3ac773d0e61 + checksum: 1ee98b4580246fd90dd54da6e346fb1caefcf05f677c686d9af237a157fdea3fd7c83a4bc58f858cd5b10a34d27afe0fdcbd0505a47e0590726a873dc8b8f65d languageName: node linkType: hard -"magic-string@npm:^0.27.0": - version: 0.27.0 - resolution: "magic-string@npm:0.27.0" +"magic-string@npm:^0.30.0, magic-string@npm:^0.30.11, magic-string@npm:^0.30.5": + version: 0.30.11 + resolution: "magic-string@npm:0.30.11" dependencies: - "@jridgewell/sourcemap-codec": ^1.4.13 - checksum: 273faaa50baadb7a2df6e442eac34ad611304fc08fe16e24fe2e472fd944bfcb73ffb50d2dc972dc04e92784222002af46868cb9698b1be181c81830fd95a13e + "@jridgewell/sourcemap-codec": ^1.5.0 + checksum: e041649453c9a3f31d2e731fc10e38604d50e20d3585cd48bc7713a6e2e1a3ad3012105929ca15750d59d0a3f1904405e4b95a23b7e69dc256db3c277a73a3ca languageName: node linkType: hard @@ -6047,6 +9500,15 @@ __metadata: languageName: node linkType: hard +"make-dir@npm:^4.0.0": + version: 4.0.0 + resolution: "make-dir@npm:4.0.0" + dependencies: + semver: ^7.5.3 + checksum: bf0731a2dd3aab4db6f3de1585cea0b746bb73eb5a02e3d8d72757e376e64e6ada190b1eddcde5b2f24a81b688a9897efd5018737d05e02e2a671dda9cff8a8a + languageName: node + linkType: hard + "make-fetch-happen@npm:^10.0.3": version: 10.2.1 resolution: "make-fetch-happen@npm:10.2.1" @@ -6193,7 +9655,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^5.0.1": +"minimatch@npm:^5.0.1, minimatch@npm:^5.1.0, minimatch@npm:^5.1.6": version: 5.1.6 resolution: "minimatch@npm:5.1.6" dependencies: @@ -6202,6 +9664,24 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^9.0.3, minimatch@npm:^9.0.4": + version: 9.0.5 + resolution: "minimatch@npm:9.0.5" + dependencies: + brace-expansion: ^2.0.1 + checksum: 2c035575eda1e50623c731ec6c14f65a85296268f749b9337005210bb2b34e2705f8ef1a358b188f69892286ab99dc42c8fb98a57bde55c8d81b3023c19cea28 + languageName: node + linkType: hard + +"minimatch@npm:~3.0.2": + version: 3.0.8 + resolution: "minimatch@npm:3.0.8" + dependencies: + brace-expansion: ^1.1.7 + checksum: 850cca179cad715133132693e6963b0db64ab0988c4d211415b087fc23a3e46321e2c5376a01bf5623d8782aba8bdf43c571e2e902e51fdce7175c7215c29f8b + languageName: node + linkType: hard + "minimist@npm:^1.2.0, minimist@npm:^1.2.6": version: 1.2.7 resolution: "minimist@npm:1.2.7" @@ -6276,6 +9756,20 @@ __metadata: languageName: node linkType: hard +"minipass@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass@npm:5.0.0" + checksum: 425dab288738853fded43da3314a0b5c035844d6f3097a8e3b5b29b328da8f3c1af6fc70618b32c29ff906284cf6406b6841376f21caaadd0793c1d5a6a620ea + languageName: node + linkType: hard + +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.1.2": + version: 7.1.2 + resolution: "minipass@npm:7.1.2" + checksum: 2bfd325b95c555f2b4d2814d49325691c7bee937d753814861b0b49d5edcda55cbbf22b6b6a60bb91eddac8668771f03c5ff647dcd9d0f798e9548b9cdc46ee3 + languageName: node + linkType: hard + "minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": version: 2.1.2 resolution: "minizlib@npm:2.1.2" @@ -6305,6 +9799,69 @@ __metadata: languageName: node linkType: hard +"mlly@npm:^1.4.2, mlly@npm:^1.6.1, mlly@npm:^1.7.1": + version: 1.7.1 + resolution: "mlly@npm:1.7.1" + dependencies: + acorn: ^8.11.3 + pathe: ^1.1.2 + pkg-types: ^1.1.1 + ufo: ^1.5.3 + checksum: 956a6d54119eef782f302580f63a9800654e588cd70015b4218a00069c6ef11b87984e8ffe140a4668b0100ad4022b11d1f9b11ac2c6dbafa4d8bc33ae3a08a8 + languageName: node + linkType: hard + +"mocha@npm:^10.3.0": + version: 10.7.3 + resolution: "mocha@npm:10.7.3" + dependencies: + ansi-colors: ^4.1.3 + browser-stdout: ^1.3.1 + chokidar: ^3.5.3 + debug: ^4.3.5 + diff: ^5.2.0 + escape-string-regexp: ^4.0.0 + find-up: ^5.0.0 + glob: ^8.1.0 + he: ^1.2.0 + js-yaml: ^4.1.0 + log-symbols: ^4.1.0 + minimatch: ^5.1.6 + ms: ^2.1.3 + serialize-javascript: ^6.0.2 + strip-json-comments: ^3.1.1 + supports-color: ^8.1.1 + workerpool: ^6.5.1 + yargs: ^16.2.0 + yargs-parser: ^20.2.9 + yargs-unparser: ^2.0.0 + bin: + _mocha: bin/_mocha + mocha: bin/mocha.js + checksum: 956376dd8c7cd3e4f496ab1b06b7c89673ade2fb7f78704d8fce32b491f6940550eb1e784b7eef617e37fa29257a728df8b5b2b5e34ed7e83a692652290fab3c + languageName: node + linkType: hard + +"modern-node-polyfills@npm:^1.0.0": + version: 1.0.0 + resolution: "modern-node-polyfills@npm:1.0.0" + dependencies: + "@jspm/core": ^2.0.1 + "@rollup/pluginutils": ^5.0.2 + local-pkg: ^0.4.3 + peerDependencies: + esbuild: ^0.14.0 || ^0.15.0 || ^0.16.0 || ^0.17.0 || ^0.18.0 + checksum: 2cf0c7fe4c15efa02702576e799ce20e0ff85e4db39516cc566c2c17cd45702ec56f1f1b57e40d4126f4c94f2bcff6923ed48191d2323c0f059d51c2e2b45d7b + languageName: node + linkType: hard + +"mri@npm:^1.2.0": + version: 1.2.0 + resolution: "mri@npm:1.2.0" + checksum: 83f515abbcff60150873e424894a2f65d68037e5a7fcde8a9e2b285ee9c13ac581b63cfc1e6826c4732de3aeb84902f7c1e16b7aff46cd3f897a0f757a894e85 + languageName: node + linkType: hard + "ms@npm:2.1.2": version: 2.1.2 resolution: "ms@npm:2.1.2" @@ -6312,19 +9869,26 @@ __metadata: languageName: node linkType: hard -"ms@npm:^2.0.0, ms@npm:^2.1.1": +"ms@npm:^2.0.0, ms@npm:^2.1.1, ms@npm:^2.1.3": version: 2.1.3 resolution: "ms@npm:2.1.3" checksum: aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d languageName: node linkType: hard -"nanoid@npm:^3.3.6": - version: 3.3.6 - resolution: "nanoid@npm:3.3.6" +"mute-stream@npm:^1.0.0": + version: 1.0.0 + resolution: "mute-stream@npm:1.0.0" + checksum: 36fc968b0e9c9c63029d4f9dc63911950a3bdf55c9a87f58d3a266289b67180201cade911e7699f8b2fa596b34c9db43dad37649e3f7fdd13c3bb9edb0017ee7 + languageName: node + linkType: hard + +"nanoid@npm:^3.3.7": + version: 3.3.7 + resolution: "nanoid@npm:3.3.7" bin: nanoid: bin/nanoid.cjs - checksum: 7d0eda657002738aa5206107bd0580aead6c95c460ef1bdd0b1a87a9c7ae6277ac2e9b945306aaa5b32c6dcb7feaf462d0f552e7f8b5718abfc6ead5c94a71b3 + checksum: d36c427e530713e4ac6567d488b489a36582ef89da1d6d4e3b87eded11eb10d7042a877958c6f104929809b2ab0bafa17652b076cdf84324aa75b30b722204f2 languageName: node linkType: hard @@ -6349,6 +9913,38 @@ __metadata: languageName: node linkType: hard +"netmask@npm:^2.0.2": + version: 2.0.2 + resolution: "netmask@npm:2.0.2" + checksum: c65cb8d3f7ea5669edddb3217e4c96910a60d0d9a4b52d9847ff6b28b2d0277cd8464eee0ef85133cdee32605c57940cacdd04a9a019079b091b6bba4cb0ec22 + languageName: node + linkType: hard + +"node-domexception@npm:^1.0.0": + version: 1.0.0 + resolution: "node-domexception@npm:1.0.0" + checksum: ee1d37dd2a4eb26a8a92cd6b64dfc29caec72bff5e1ed9aba80c294f57a31ba4895a60fd48347cf17dd6e766da0ae87d75657dfd1f384ebfa60462c2283f5c7f + languageName: node + linkType: hard + +"node-fetch-native@npm:^1.6.3": + version: 1.6.4 + resolution: "node-fetch-native@npm:1.6.4" + checksum: 7b159f610e037e8813750096a6616ec6771e9abf868aa6e75e5b790bfc2ba2d92cf2abcce33c18fd01f2e5e5cc72de09c78bd4381e7f8c0887f7de21bd96f045 + languageName: node + linkType: hard + +"node-fetch@npm:^3.3.2": + version: 3.3.2 + resolution: "node-fetch@npm:3.3.2" + dependencies: + data-uri-to-buffer: ^4.0.0 + fetch-blob: ^3.1.4 + formdata-polyfill: ^4.0.10 + checksum: 06a04095a2ddf05b0830a0d5302699704d59bda3102894ea64c7b9d4c865ecdff2d90fd042df7f5bc40337266961cb6183dcc808ea4f3000d024f422b462da92 + languageName: node + linkType: hard + "node-gyp@npm:latest": version: 9.3.1 resolution: "node-gyp@npm:9.3.1" @@ -6376,6 +9972,13 @@ __metadata: languageName: node linkType: hard +"node-releases@npm:^2.0.18": + version: 2.0.18 + resolution: "node-releases@npm:2.0.18" + checksum: ef55a3d853e1269a6d6279b7692cd6ff3e40bc74947945101138745bfdc9a5edabfe72cb19a31a8e45752e1910c4c65c77d931866af6357f242b172b7283f5b3 + languageName: node + linkType: hard + "node-releases@npm:^2.0.8": version: 2.0.10 resolution: "node-releases@npm:2.0.10" @@ -6394,7 +9997,18 @@ __metadata: languageName: node linkType: hard -"normalize-path@npm:^3.0.0": +"normalize-package-data@npm:^6.0.0": + version: 6.0.2 + resolution: "normalize-package-data@npm:6.0.2" + dependencies: + hosted-git-info: ^7.0.0 + semver: ^7.3.5 + validate-npm-package-license: ^3.0.4 + checksum: ea35f8de68e03fc845f545c8197857c0cd256207fdb809ca63c2b39fe76ae77765ee939eb21811fb6c3b533296abf49ebe3cd617064f98a775adaccb24ff2e03 + languageName: node + linkType: hard + +"normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0": version: 3.0.0 resolution: "normalize-path@npm:3.0.0" checksum: 88eeb4da891e10b1318c4b2476b6e2ecbeb5ff97d946815ffea7794c31a89017c70d7f34b3c2ebf23ef4e9fc9fb99f7dffe36da22011b5b5c6ffa34f4873ec20 @@ -6435,6 +10049,15 @@ __metadata: languageName: node linkType: hard +"npm-run-path@npm:^5.2.0": + version: 5.3.0 + resolution: "npm-run-path@npm:5.3.0" + dependencies: + path-key: ^4.0.0 + checksum: ae8e7a89da9594fb9c308f6555c73f618152340dcaae423e5fb3620026fefbec463618a8b761920382d666fa7a2d8d240b6fe320e8a6cdd54dc3687e2b659d25 + languageName: node + linkType: hard + "npmlog@npm:^6.0.0": version: 6.0.2 resolution: "npmlog@npm:6.0.2" @@ -6447,6 +10070,15 @@ __metadata: languageName: node linkType: hard +"nth-check@npm:^2.0.1": + version: 2.1.1 + resolution: "nth-check@npm:2.1.1" + dependencies: + boolbase: ^1.0.0 + checksum: 5afc3dafcd1573b08877ca8e6148c52abd565f1d06b1eb08caf982e3fa289a82f2cae697ffb55b5021e146d60443f1590a5d6b944844e944714a5b549675bcd3 + languageName: node + linkType: hard + "nwsapi@npm:^2.2.2": version: 2.2.2 resolution: "nwsapi@npm:2.2.2" @@ -6454,6 +10086,22 @@ __metadata: languageName: node linkType: hard +"nypm@npm:^0.3.8": + version: 0.3.11 + resolution: "nypm@npm:0.3.11" + dependencies: + citty: ^0.1.6 + consola: ^3.2.3 + execa: ^8.0.1 + pathe: ^1.1.2 + pkg-types: ^1.2.0 + ufo: ^1.5.4 + bin: + nypm: dist/cli.mjs + checksum: baad0850b2c9f3d5cbf5733c064820a5b813504bf2b7ce52e6eefd39dd876358d95614759f321fd213379e01b3604e20fabfef2e4334f707b078c15a263ffa4f + languageName: node + linkType: hard + "object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" @@ -6468,16 +10116,6 @@ __metadata: languageName: node linkType: hard -"object-is@npm:^1.1.5": - version: 1.1.5 - resolution: "object-is@npm:1.1.5" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.1.3 - checksum: 989b18c4cba258a6b74dc1d74a41805c1a1425bce29f6cabb50dcb1a6a651ea9104a1b07046739a49a5bb1bc49727bcb00efd5c55f932f6ea04ec8927a7901fe - languageName: node - linkType: hard - "object-keys@npm:^1.1.1": version: 1.1.1 resolution: "object-keys@npm:1.1.1" @@ -6549,6 +10187,13 @@ __metadata: languageName: node linkType: hard +"ohash@npm:^1.1.3": + version: 1.1.4 + resolution: "ohash@npm:1.1.4" + checksum: 8c63897941e67129ac81a15cfc2bb66a7b122200c9ee244e86d3d6b7aa7f5d9f7cb98d33dfc38b169c83b77c9babcc6f66ccbc90864d1f862f10ac8b72d80d66 + languageName: node + linkType: hard + "once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0": version: 1.4.0 resolution: "once@npm:1.4.0" @@ -6631,6 +10276,13 @@ __metadata: languageName: node linkType: hard +"os-tmpdir@npm:~1.0.2": + version: 1.0.2 + resolution: "os-tmpdir@npm:1.0.2" + checksum: 5666560f7b9f10182548bf7013883265be33620b1c1b4a4d405c25be2636f970c5488ff3e6c48de75b55d02bde037249fe5dbfbb4c0fb7714953d56aed062e6d + languageName: node + linkType: hard + "p-cancelable@npm:^2.0.0": version: 2.1.1 resolution: "p-cancelable@npm:2.1.1" @@ -6663,6 +10315,15 @@ __metadata: languageName: node linkType: hard +"p-limit@npm:^4.0.0": + version: 4.0.0 + resolution: "p-limit@npm:4.0.0" + dependencies: + yocto-queue: ^1.0.0 + checksum: 01d9d70695187788f984226e16c903475ec6a947ee7b21948d6f597bed788e3112cc7ec2e171c1d37125057a5f45f3da21d8653e04a3a793589e12e9e80e756b + languageName: node + linkType: hard + "p-locate@npm:^4.1.0": version: 4.1.0 resolution: "p-locate@npm:4.1.0" @@ -6681,6 +10342,15 @@ __metadata: languageName: node linkType: hard +"p-locate@npm:^6.0.0": + version: 6.0.0 + resolution: "p-locate@npm:6.0.0" + dependencies: + p-limit: ^4.0.0 + checksum: 2bfe5234efa5e7a4e74b30a5479a193fdd9236f8f6b4d2f3f69e3d286d9a7d7ab0c118a2a50142efcf4e41625def635bd9332d6cbf9cc65d85eb0718c579ab38 + languageName: node + linkType: hard + "p-map@npm:^4.0.0": version: 4.0.0 resolution: "p-map@npm:4.0.0" @@ -6697,6 +10367,46 @@ __metadata: languageName: node linkType: hard +"pac-proxy-agent@npm:^7.0.1": + version: 7.0.2 + resolution: "pac-proxy-agent@npm:7.0.2" + dependencies: + "@tootallnate/quickjs-emscripten": ^0.23.0 + agent-base: ^7.0.2 + debug: ^4.3.4 + get-uri: ^6.0.1 + http-proxy-agent: ^7.0.0 + https-proxy-agent: ^7.0.5 + pac-resolver: ^7.0.1 + socks-proxy-agent: ^8.0.4 + checksum: 82772aaa489a4ad6f598b75d56daf609e7ba294a05a91cfe3101b004e2df494f0a269c98452cb47aaa4a513428e248308a156e26fee67eb78a76a58e9346921e + languageName: node + linkType: hard + +"pac-resolver@npm:^7.0.1": + version: 7.0.1 + resolution: "pac-resolver@npm:7.0.1" + dependencies: + degenerator: ^5.0.0 + netmask: ^2.0.2 + checksum: 839134328781b80d49f9684eae1f5c74f50a1d4482076d44c84fc2f3ca93da66fa11245a4725a057231e06b311c20c989fd0681e662a0792d17f644d8fe62a5e + languageName: node + linkType: hard + +"package-json-from-dist@npm:^1.0.0": + version: 1.0.0 + resolution: "package-json-from-dist@npm:1.0.0" + checksum: ac706ec856a5a03f5261e4e48fa974f24feb044d51f84f8332e2af0af04fbdbdd5bbbfb9cbbe354190409bc8307c83a9e38c6672c3c8855f709afb0006a009ea + languageName: node + linkType: hard + +"pako@npm:~1.0.2": + version: 1.0.11 + resolution: "pako@npm:1.0.11" + checksum: 1be2bfa1f807608c7538afa15d6f25baa523c30ec870a3228a89579e474a4d992f4293859524e46d5d87fd30fa17c5edf34dbef0671251d9749820b488660b16 + languageName: node + linkType: hard + "parent-module@npm:^1.0.0": version: 1.0.1 resolution: "parent-module@npm:1.0.1" @@ -6718,7 +10428,46 @@ __metadata: languageName: node linkType: hard -"parse5@npm:^7.0.0, parse5@npm:^7.1.1": +"parse-json@npm:^7.0.0": + version: 7.1.1 + resolution: "parse-json@npm:7.1.1" + dependencies: + "@babel/code-frame": ^7.21.4 + error-ex: ^1.3.2 + json-parse-even-better-errors: ^3.0.0 + lines-and-columns: ^2.0.3 + type-fest: ^3.8.0 + checksum: 187275c7ac097dcfb3c7420bca2399caa4da33bcd5d5aac3604bda0e2b8eee4df61cc26aa0d79fab97f0d67bf42d41d332baa9f9f56ad27636ad785f1ae639e5 + languageName: node + linkType: hard + +"parse-ms@npm:^4.0.0": + version: 4.0.0 + resolution: "parse-ms@npm:4.0.0" + checksum: 673c801d9f957ff79962d71ed5a24850163f4181a90dd30c4e3666b3a804f53b77f1f0556792e8b2adbb5d58757907d1aa51d7d7dc75997c2a56d72937cbc8b7 + languageName: node + linkType: hard + +"parse5-htmlparser2-tree-adapter@npm:^7.0.0": + version: 7.0.0 + resolution: "parse5-htmlparser2-tree-adapter@npm:7.0.0" + dependencies: + domhandler: ^5.0.2 + parse5: ^7.0.0 + checksum: fc5d01e07733142a1baf81de5c2a9c41426c04b7ab29dd218acb80cd34a63177c90aff4a4aee66cf9f1d0aeecff1389adb7452ad6f8af0a5888e3e9ad6ef733d + languageName: node + linkType: hard + +"parse5-parser-stream@npm:^7.1.2": + version: 7.1.2 + resolution: "parse5-parser-stream@npm:7.1.2" + dependencies: + parse5: ^7.0.0 + checksum: 75b232d460bce6bd0e35012750a78ef034f40ccf550b7c6cec3122395af6b4553202ad3663ad468cf537ead5a2e13b6727670395fd0ff548faccad1dc2dc93cf + languageName: node + linkType: hard + +"parse5@npm:^7.0.0, parse5@npm:^7.1.1, parse5@npm:^7.1.2": version: 7.1.2 resolution: "parse5@npm:7.1.2" dependencies: @@ -6734,6 +10483,13 @@ __metadata: languageName: node linkType: hard +"path-exists@npm:^5.0.0": + version: 5.0.0 + resolution: "path-exists@npm:5.0.0" + checksum: 8ca842868cab09423994596eb2c5ec2a971c17d1a3cb36dbf060592c730c725cd524b9067d7d2a1e031fef9ba7bd2ac6dc5ec9fb92aa693265f7be3987045254 + languageName: node + linkType: hard + "path-is-absolute@npm:^1.0.0": version: 1.0.1 resolution: "path-is-absolute@npm:1.0.1" @@ -6769,6 +10525,16 @@ __metadata: languageName: node linkType: hard +"path-scurry@npm:^1.11.1": + version: 1.11.1 + resolution: "path-scurry@npm:1.11.1" + dependencies: + lru-cache: ^10.2.0 + minipass: ^5.0.0 || ^6.0.2 || ^7.0.0 + checksum: 890d5abcd593a7912dcce7cf7c6bf7a0b5648e3dee6caf0712c126ca0a65c7f3d7b9d769072a4d1baf370f61ce493ab5b038d59988688e0c5f3f646ee3c69023 + languageName: node + linkType: hard + "path-type@npm:^4.0.0": version: 4.0.0 resolution: "path-type@npm:4.0.0" @@ -6776,6 +10542,20 @@ __metadata: languageName: node linkType: hard +"path-type@npm:^5.0.0": + version: 5.0.0 + resolution: "path-type@npm:5.0.0" + checksum: 15ec24050e8932c2c98d085b72cfa0d6b4eeb4cbde151a0a05726d8afae85784fc5544f733d8dfc68536587d5143d29c0bd793623fad03d7e61cc00067291cd5 + languageName: node + linkType: hard + +"pathe@npm:^1.1.1, pathe@npm:^1.1.2": + version: 1.1.2 + resolution: "pathe@npm:1.1.2" + checksum: ec5f778d9790e7b9ffc3e4c1df39a5bb1ce94657a4e3ad830c1276491ca9d79f189f47609884671db173400256b005f4955f7952f52a2aeb5834ad5fb4faf134 + languageName: node + linkType: hard + "peek-readable@npm:^5.0.0": version: 5.0.0 resolution: "peek-readable@npm:5.0.0" @@ -6783,6 +10563,20 @@ __metadata: languageName: node linkType: hard +"pend@npm:~1.2.0": + version: 1.2.0 + resolution: "pend@npm:1.2.0" + checksum: 6c72f5243303d9c60bd98e6446ba7d30ae29e3d56fdb6fae8767e8ba6386f33ee284c97efe3230a0d0217e2b1723b8ab490b1bbf34fcbb2180dbc8a9de47850d + languageName: node + linkType: hard + +"perfect-debounce@npm:^1.0.0": + version: 1.0.0 + resolution: "perfect-debounce@npm:1.0.0" + checksum: 220343acf52976947958fef3599849471605316e924fe19c633ae2772576298e9d38f02cefa8db46f06607505ce7b232cbb35c9bfd477bd0329bd0a2ce37c594 + languageName: node + linkType: hard + "picocolors@npm:^1.0.0": version: 1.0.0 resolution: "picocolors@npm:1.0.0" @@ -6790,7 +10584,14 @@ __metadata: languageName: node linkType: hard -"picomatch@npm:^2.0.4, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1": +"picocolors@npm:^1.0.1, picocolors@npm:^1.1.0": + version: 1.1.0 + resolution: "picocolors@npm:1.1.0" + checksum: a64d653d3a188119ff45781dfcdaeedd7625583f45280aea33fcb032c7a0d3959f2368f9b192ad5e8aade75b74dbd954ffe3106c158509a45e4c18ab379a2acd + languageName: node + linkType: hard + +"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1": version: 2.3.1 resolution: "picomatch@npm:2.3.1" checksum: 050c865ce81119c4822c45d3c84f1ced46f93a0126febae20737bd05ca20589c564d6e9226977df859ed5e03dc73f02584a2b0faad36e896936238238b0446cf @@ -6829,14 +10630,25 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.4.23": - version: 8.4.31 - resolution: "postcss@npm:8.4.31" +"pkg-types@npm:^1.0.3, pkg-types@npm:^1.1.1, pkg-types@npm:^1.2.0": + version: 1.2.0 + resolution: "pkg-types@npm:1.2.0" dependencies: - nanoid: ^3.3.6 - picocolors: ^1.0.0 - source-map-js: ^1.0.2 - checksum: 1d8611341b073143ad90486fcdfeab49edd243377b1f51834dc4f6d028e82ce5190e4f11bb2633276864503654fb7cab28e67abdc0fbf9d1f88cad4a0ff0beea + confbox: ^0.1.7 + mlly: ^1.7.1 + pathe: ^1.1.2 + checksum: c9ea31be8c7bf0b760c075d5e39f71d90fcebee316e49688345e9095d520ed766f3bfd560227e3f3c28639399a0641a27193eef60c4802d89cb414e21240bbb5 + languageName: node + linkType: hard + +"postcss@npm:^8.4.43": + version: 8.4.47 + resolution: "postcss@npm:8.4.47" + dependencies: + nanoid: ^3.3.7 + picocolors: ^1.1.0 + source-map-js: ^1.2.1 + checksum: f78440a9d8f97431dd2ab1ab8e1de64f12f3eff38a3d8d4a33919b96c381046a314658d2de213a5fa5eb296b656de76a3ec269fdea27f16d5ab465b916a0f52c languageName: node linkType: hard @@ -6874,14 +10686,34 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:^29.4.1": - version: 29.4.1 - resolution: "pretty-format@npm:29.4.1" +"pretty-format@npm:^29.6.2": + version: 29.6.2 + resolution: "pretty-format@npm:29.6.2" dependencies: - "@jest/schemas": ^29.4.0 + "@jest/schemas": ^29.6.0 ansi-styles: ^5.0.0 react-is: ^18.0.0 - checksum: bcc8e86bcf8e7f5106c96e2ea7905912bd17ae2aac76e4e0745d2a50df4b340638ed95090ee455a1c0f78189efa05077bd655ca08bf66292e83ebd7035fc46fd + checksum: a0f972a44f959023c0df9cdfe9eed7540264d7f7ddf74667db8a5294444d5aa153fd47d20327df10ae86964e2ceec10e46ea06b1a5c9c12e02348b78c952c9fc + languageName: node + linkType: hard + +"pretty-format@npm:^29.7.0": + version: 29.7.0 + resolution: "pretty-format@npm:29.7.0" + dependencies: + "@jest/schemas": ^29.6.3 + ansi-styles: ^5.0.0 + react-is: ^18.0.0 + checksum: 032c1602383e71e9c0c02a01bbd25d6759d60e9c7cf21937dde8357aa753da348fcec5def5d1002c9678a8524d5fe099ad98861286550ef44de8808cc61e43b6 + languageName: node + linkType: hard + +"pretty-ms@npm:^9.0.0": + version: 9.1.0 + resolution: "pretty-ms@npm:9.1.0" + dependencies: + parse-ms: ^4.0.0 + checksum: 0f66507467f2005040cccdcb36f35b82674d7809f41c4432009235ed6c920787afa17f621c25b7ccb8ccd80b0840c7b71f7f4a3addb8f0eeef3a033ff1e5cf71 languageName: node linkType: hard @@ -6892,6 +10724,20 @@ __metadata: languageName: node linkType: hard +"process@npm:^0.11.10": + version: 0.11.10 + resolution: "process@npm:0.11.10" + checksum: bfcce49814f7d172a6e6a14d5fa3ac92cc3d0c3b9feb1279774708a719e19acd673995226351a082a9ae99978254e320ccda4240ddc474ba31a76c79491ca7c3 + languageName: node + linkType: hard + +"progress@npm:^2.0.3": + version: 2.0.3 + resolution: "progress@npm:2.0.3" + checksum: f67403fe7b34912148d9252cb7481266a354bd99ce82c835f79070643bb3c6583d10dbcfda4d41e04bbc1d8437e9af0fb1e1f2135727878f5308682a579429b7 + languageName: node + linkType: hard + "promise-inflight@npm:^1.0.1": version: 1.0.1 resolution: "promise-inflight@npm:1.0.1" @@ -6941,6 +10787,38 @@ __metadata: languageName: node linkType: hard +"prosemirror-gapcursor@npm:^1.3.2": + version: 1.3.2 + resolution: "prosemirror-gapcursor@npm:1.3.2" + dependencies: + prosemirror-keymap: ^1.0.0 + prosemirror-model: ^1.0.0 + prosemirror-state: ^1.0.0 + prosemirror-view: ^1.0.0 + checksum: a1a359f9cb701417f00b330d24b70aaba48ef48a906bc1a7425de1c81c3fa67b19352c432075419ec363827006799964ab47f1ca192e25a2c4fb696e6d1db3ed + languageName: node + linkType: hard + +"prosemirror-inputrules@npm:^1.4.0": + version: 1.4.0 + resolution: "prosemirror-inputrules@npm:1.4.0" + dependencies: + prosemirror-state: ^1.0.0 + prosemirror-transform: ^1.0.0 + checksum: b893eff382b585aa934e41a7bcbb02cd9ce5199bc6e939ef3f1629aeaf181320f2b52a0d088cb6432aa10c4536c3b5ea67a15e66ef24714a3b3f9e89d0f29ef4 + languageName: node + linkType: hard + +"prosemirror-keymap@npm:^1.0.0, prosemirror-keymap@npm:^1.1.2": + version: 1.2.2 + resolution: "prosemirror-keymap@npm:1.2.2" + dependencies: + prosemirror-state: ^1.0.0 + w3c-keyname: ^2.2.0 + checksum: 85fe4fc3038499b6dabd9a16581c0ee7a4358835c200f8a6a17dbe05733ea3df1f2571b0d02c071dbd51ce32e909da3ebb9227f25434587238e89f8c9ba293f9 + languageName: node + linkType: hard + "prosemirror-keymap@npm:^1.2.1": version: 1.2.1 resolution: "prosemirror-keymap@npm:1.2.1" @@ -6951,12 +10829,32 @@ __metadata: languageName: node linkType: hard -"prosemirror-model@npm:^1.0.0, prosemirror-model@npm:^1.16.0, prosemirror-model@npm:^1.18.3": - version: 1.19.0 - resolution: "prosemirror-model@npm:1.19.0" +"prosemirror-model@npm:^1.0.0, prosemirror-model@npm:^1.19.0, prosemirror-model@npm:^1.20.0, prosemirror-model@npm:^1.22.3, prosemirror-model@npm:^1.8.1": + version: 1.22.3 + resolution: "prosemirror-model@npm:1.22.3" dependencies: orderedmap: ^2.0.0 - checksum: 1ab3d3e0cbe3f56d368984f8cc8e4302e95856e00bc9804068d9648aae7a7e494be631017ad0dffe9d2f90c1044c56548b96ab9d3d1ef9e7155391be2547905f + checksum: dfc1f80fadbd4dc839af7fcbf23ff6788988e78b968e8937acf1b658987e351e7a6c880c8ff70f06d7a9ae88efff60bdb31e2daea95bf9eff6db1821001fefac + languageName: node + linkType: hard + +"prosemirror-schema-basic@npm:^1.0.0": + version: 1.2.2 + resolution: "prosemirror-schema-basic@npm:1.2.2" + dependencies: + prosemirror-model: ^1.19.0 + checksum: 1f93f8678c797c53867da2473a3f69995edaeeea4a8cd631351f30bd75da372cd32203aa44c145d93ee607fa0c80b9888dcdfa1ce68b127513c02d3260441ffb + languageName: node + linkType: hard + +"prosemirror-schema-list@npm:^1.0.0": + version: 1.3.0 + resolution: "prosemirror-schema-list@npm:1.3.0" + dependencies: + prosemirror-model: ^1.0.0 + prosemirror-state: ^1.0.0 + prosemirror-transform: ^1.7.3 + checksum: 03654e37c8e11598ade33a72cff20e5fdd4d87f129a2c83b378e8255e8003a37cdafc40fd7e7519ba6440f872127ef327d7063c7799325a40e9853ebfc83b544 languageName: node linkType: hard @@ -6971,14 +10869,38 @@ __metadata: languageName: node linkType: hard -"prosemirror-state@npm:^1.0.0, prosemirror-state@npm:^1.4.2": - version: 1.4.2 - resolution: "prosemirror-state@npm:1.4.2" +"prosemirror-state@npm:^1.0.0, prosemirror-state@npm:^1.3.1, prosemirror-state@npm:^1.4.3": + version: 1.4.3 + resolution: "prosemirror-state@npm:1.4.3" dependencies: prosemirror-model: ^1.0.0 prosemirror-transform: ^1.0.0 prosemirror-view: ^1.27.0 - checksum: a9e44df56aeb53fb99036742fbb63826380cf74cb115efffdd9f4e096bfb27dc7bf35c46d4b5fb5f260cd84e8bdc467aa5dc9540bd06f9f802de70b4873d8db4 + checksum: 28857d935c443efae185407e2b6fe4ab481840a3609dfac344ee16eeeaebf39765207c8e525bd628d72755f9257cd51a743e543c8c9d4357b7e67ab22c9dc44c + languageName: node + linkType: hard + +"prosemirror-tables@npm:^1.3.7": + version: 1.3.7 + resolution: "prosemirror-tables@npm:1.3.7" + dependencies: + prosemirror-keymap: ^1.1.2 + prosemirror-model: ^1.8.1 + prosemirror-state: ^1.3.1 + prosemirror-transform: ^1.2.1 + prosemirror-view: ^1.13.3 + checksum: fc28cd6a109a128e9eb95d1ca67c4e658982f2634af50cea95804fc7e9eeb7cc34eddf9855b7da447c53713eb281daa0e5cebc2ad042d78c917e3e9648ab294b + languageName: node + linkType: hard + +"prosemirror-test-builder@npm:^1.1.1": + version: 1.1.1 + resolution: "prosemirror-test-builder@npm:1.1.1" + dependencies: + prosemirror-model: ^1.0.0 + prosemirror-schema-basic: ^1.0.0 + prosemirror-schema-list: ^1.0.0 + checksum: 48c34257093a2d3f85dc164a126e72245c773bbdcb0975460c38ea04dc9eae3386996ca02a14e7bc9013844ea7398e256cef894383fe9d56f14d102a16436f34 languageName: node linkType: hard @@ -6991,14 +10913,55 @@ __metadata: languageName: node linkType: hard -"prosemirror-view@npm:^1.27.0, prosemirror-view@npm:^1.29.1": - version: 1.30.1 - resolution: "prosemirror-view@npm:1.30.1" +"prosemirror-transform@npm:^1.2.1, prosemirror-transform@npm:^1.8.0": + version: 1.8.0 + resolution: "prosemirror-transform@npm:1.8.0" + dependencies: + prosemirror-model: ^1.0.0 + checksum: 6d16ca4f954ad7b040a4adbb5ddfa8c8ad14b0514f15e1ecfd5e32f08eb3f8696492975b9e599b4776e991ab76df114166dcf6ec7b966a67b02b2069a28415f1 + languageName: node + linkType: hard + +"prosemirror-transform@npm:^1.7.3": + version: 1.7.3 + resolution: "prosemirror-transform@npm:1.7.3" + dependencies: + prosemirror-model: ^1.0.0 + checksum: dbafa4cee8a0ea3ff0a27eda27e3b5ff21f8b39619b09894963c68f5fb2454b67bd2206fb18fdb4176f65fb4f72f307f8a41ddbb4fa35a6feb83675902cc2889 + languageName: node + linkType: hard + +"prosemirror-view@npm:^1.0.0, prosemirror-view@npm:^1.13.3, prosemirror-view@npm:^1.27.0, prosemirror-view@npm:^1.34.2": + version: 1.34.2 + resolution: "prosemirror-view@npm:1.34.2" + dependencies: + prosemirror-model: ^1.20.0 + prosemirror-state: ^1.0.0 + prosemirror-transform: ^1.1.0 + checksum: 5895d76c3fa69117a8e67c8d0bb7f312eeed1551fff50cb0c8b8a40126f701536f16e85aae7c75e5753a7948bd9373c710092121407fbec8b1e33fe627800589 + languageName: node + linkType: hard + +"proxy-agent@npm:^6.4.0": + version: 6.4.0 + resolution: "proxy-agent@npm:6.4.0" dependencies: - prosemirror-model: ^1.16.0 - prosemirror-state: ^1.0.0 - prosemirror-transform: ^1.1.0 - checksum: 6dec0205954ae9ffba7e6864274de6fd2508f8aacec7d54a0bd448257a92bf9c93a147ecc24d4a909bca9b8fddad34627dabfb51c7742653a2b836d962290c9c + agent-base: ^7.0.2 + debug: ^4.3.4 + http-proxy-agent: ^7.0.1 + https-proxy-agent: ^7.0.3 + lru-cache: ^7.14.1 + pac-proxy-agent: ^7.0.1 + proxy-from-env: ^1.1.0 + socks-proxy-agent: ^8.0.2 + checksum: 4d3794ad5e07486298902f0a7f250d0f869fa0e92d790767ca3f793a81374ce0ab6c605f8ab8e791c4d754da96656b48d1c24cb7094bfd310a15867e4a0841d7 + languageName: node + linkType: hard + +"proxy-from-env@npm:^1.1.0": + version: 1.1.0 + resolution: "proxy-from-env@npm:1.1.0" + checksum: ed7fcc2ba0a33404958e34d95d18638249a68c430e30fcb6c478497d72739ba64ce9810a24f53a7d921d0c065e5b78e3822759800698167256b04659366ca4d4 languageName: node linkType: hard @@ -7033,6 +10996,20 @@ __metadata: languageName: node linkType: hard +"pure-rand@npm:^6.0.0": + version: 6.1.0 + resolution: "pure-rand@npm:6.1.0" + checksum: 8d53bc02bed99eca0b65b505090152ee7e9bd67dd74f8ff32ba1c883b87234067c5bf68d2614759fb217d82594d7a92919e6df80f97885e7b12b42af4bd3316a + languageName: node + linkType: hard + +"query-selector-shadow-dom@npm:^1.0.1": + version: 1.0.1 + resolution: "query-selector-shadow-dom@npm:1.0.1" + checksum: 8ab1cdd5e1927b583503b590165d66770fb91c87ac28b50a43596b755db3792c0e506250f46d0af97f0064a5cc12a1de449fd5c2cfcadf18b0880a4d8aecebbd + languageName: node + linkType: hard + "querystringify@npm:^2.1.1": version: 2.2.0 resolution: "querystringify@npm:2.2.0" @@ -7047,6 +11024,13 @@ __metadata: languageName: node linkType: hard +"queue-tick@npm:^1.0.1": + version: 1.0.1 + resolution: "queue-tick@npm:1.0.1" + checksum: 57c3292814b297f87f792fbeb99ce982813e4e54d7a8bdff65cf53d5c084113913289d4a48ec8bbc964927a74b847554f9f4579df43c969a6c8e0f026457ad01 + languageName: node + linkType: hard + "quick-lru@npm:^5.1.1": version: 5.1.1 resolution: "quick-lru@npm:5.1.1" @@ -7065,6 +11049,25 @@ __metadata: languageName: node linkType: hard +"randombytes@npm:^2.1.0": + version: 2.1.0 + resolution: "randombytes@npm:2.1.0" + dependencies: + safe-buffer: ^5.1.0 + checksum: d779499376bd4cbb435ef3ab9a957006c8682f343f14089ed5f27764e4645114196e75b7f6abf1cbd84fd247c0cb0651698444df8c9bf30e62120fbbc52269d6 + languageName: node + linkType: hard + +"rc9@npm:^2.1.2": + version: 2.1.2 + resolution: "rc9@npm:2.1.2" + dependencies: + defu: ^6.1.4 + destr: ^2.0.3 + checksum: aaa8f962a9a6a89981e2da75dad71117fe0f856bb55fecf793cd42ee0badc1cb92e6bb7cd25a9473e2d3c968ac29e507384ce52c4e76bbd63ac5649d3d7c2ab3 + languageName: node + linkType: hard + "react-dom@npm:^18.2.0": version: 18.2.0 resolution: "react-dom@npm:18.2.0" @@ -7098,10 +11101,10 @@ __metadata: languageName: node linkType: hard -"react-refresh@npm:^0.14.0": - version: 0.14.0 - resolution: "react-refresh@npm:0.14.0" - checksum: dc69fa8c993df512f42dd0f1b604978ae89bd747c0ed5ec595c0cc50d535fb2696619ccd98ae28775cc01d0a7c146a532f0f7fb81dc22e1977c242a4912312f4 +"react-refresh@npm:^0.14.2": + version: 0.14.2 + resolution: "react-refresh@npm:0.14.2" + checksum: d80db4bd40a36dab79010dc8aa317a5b931f960c0d83c4f3b81f0552cbcf7f29e115b84bb7908ec6a1eb67720fff7023084eff73ece8a7ddc694882478464382 languageName: node linkType: hard @@ -7114,6 +11117,44 @@ __metadata: languageName: node linkType: hard +"read-pkg-up@npm:^10.0.0": + version: 10.1.0 + resolution: "read-pkg-up@npm:10.1.0" + dependencies: + find-up: ^6.3.0 + read-pkg: ^8.1.0 + type-fest: ^4.2.0 + checksum: 554470d7ff54026b561f6c851c35470f5bc95a47bfb8645dc13c447d83c42c78b42d47fffdc8f86bffe731215406dab498f75cb27494e1fb3eca7fa8d00fb501 + languageName: node + linkType: hard + +"read-pkg@npm:^8.1.0": + version: 8.1.0 + resolution: "read-pkg@npm:8.1.0" + dependencies: + "@types/normalize-package-data": ^2.4.1 + normalize-package-data: ^6.0.0 + parse-json: ^7.0.0 + type-fest: ^4.2.0 + checksum: f4cd164f096e78cf3e338a55f800043524e3055f9b0b826143290002fafc951025fc3cbd6ca683ebaf7945efcfb092d31c683dd252a7871a974662985c723b67 + languageName: node + linkType: hard + +"readable-stream@npm:^2.0.5": + version: 2.3.8 + resolution: "readable-stream@npm:2.3.8" + dependencies: + core-util-is: ~1.0.0 + inherits: ~2.0.3 + isarray: ~1.0.0 + process-nextick-args: ~2.0.0 + safe-buffer: ~5.1.1 + string_decoder: ~1.1.1 + util-deprecate: ~1.0.1 + checksum: 65645467038704f0c8aaf026a72fbb588a9e2ef7a75cd57a01702ee9db1c4a1e4b03aaad36861a6a0926546a74d174149c8c207527963e0c2d3eee2f37678a42 + languageName: node + linkType: hard + "readable-stream@npm:^2.2.2, readable-stream@npm:~2.3.6": version: 2.3.7 resolution: "readable-stream@npm:2.3.7" @@ -7140,6 +11181,19 @@ __metadata: languageName: node linkType: hard +"readable-stream@npm:^4.0.0": + version: 4.5.2 + resolution: "readable-stream@npm:4.5.2" + dependencies: + abort-controller: ^3.0.0 + buffer: ^6.0.3 + events: ^3.3.0 + process: ^0.11.10 + string_decoder: ^1.3.0 + checksum: c4030ccff010b83e4f33289c535f7830190773e274b3fcb6e2541475070bdfd69c98001c3b0cb78763fc00c8b62f514d96c2b10a8bd35d5ce45203a25fa1d33a + languageName: node + linkType: hard + "readable-web-to-node-stream@npm:^3.0.2": version: 3.0.2 resolution: "readable-web-to-node-stream@npm:3.0.2" @@ -7149,6 +11203,46 @@ __metadata: languageName: node linkType: hard +"readdir-glob@npm:^1.1.2": + version: 1.1.3 + resolution: "readdir-glob@npm:1.1.3" + dependencies: + minimatch: ^5.1.0 + checksum: 1dc0f7440ff5d9378b593abe9d42f34ebaf387516615e98ab410cf3a68f840abbf9ff1032d15e0a0dbffa78f9e2c46d4fafdbaac1ca435af2efe3264e3f21874 + languageName: node + linkType: hard + +"readdirp@npm:~3.6.0": + version: 3.6.0 + resolution: "readdirp@npm:3.6.0" + dependencies: + picomatch: ^2.2.1 + checksum: 1ced032e6e45670b6d7352d71d21ce7edf7b9b928494dcaba6f11fba63180d9da6cd7061ebc34175ffda6ff529f481818c962952004d273178acd70f7059b320 + languageName: node + linkType: hard + +"recast@npm:^0.23.6": + version: 0.23.9 + resolution: "recast@npm:0.23.9" + dependencies: + ast-types: ^0.16.1 + esprima: ~4.0.0 + source-map: ~0.6.1 + tiny-invariant: ^1.3.3 + tslib: ^2.0.1 + checksum: be8e896a46b24e30fbeafcd111ff3beaf2b5532d241c199f833fe1c18e89f695b2704cf83f3006fa96a785851019031de0de50bd3e0fd7bb114be18bf2cad900 + languageName: node + linkType: hard + +"recursive-readdir@npm:^2.2.3": + version: 2.2.3 + resolution: "recursive-readdir@npm:2.2.3" + dependencies: + minimatch: ^3.0.5 + checksum: 88ec96e276237290607edc0872b4f9842837b95cfde0cdbb1e00ba9623dfdf3514d44cdd14496ab60a0c2dd180a6ef8a3f1c34599e6cf2273afac9b72a6fb2b5 + languageName: node + linkType: hard + "regenerator-runtime@npm:^0.13.11": version: 0.13.11 resolution: "regenerator-runtime@npm:0.13.11" @@ -7244,6 +11338,13 @@ __metadata: languageName: node linkType: hard +"resolve-pkg-maps@npm:^1.0.0": + version: 1.0.0 + resolution: "resolve-pkg-maps@npm:1.0.0" + checksum: 1012afc566b3fdb190a6309cc37ef3b2dcc35dff5fa6683a9d00cd25c3247edfbc4691b91078c97adc82a29b77a2660c30d791d65dab4fc78bfc473f60289977 + languageName: node + linkType: hard + "resolve.exports@npm:^2.0.0": version: 2.0.0 resolution: "resolve.exports@npm:2.0.0" @@ -7312,6 +11413,15 @@ __metadata: languageName: node linkType: hard +"resq@npm:^1.11.0": + version: 1.11.0 + resolution: "resq@npm:1.11.0" + dependencies: + fast-deep-equal: ^2.0.1 + checksum: a596c0125883246946cf6b9172557265d00334019327c09b84c9016b1e7e876e15c35c81d2f8ed315adf6b93ac035f3d993f9a8b323dcd80ffd6cf8f3eb5cc7e + languageName: node + linkType: hard + "restore-cursor@npm:^3.1.0": version: 3.1.0 resolution: "restore-cursor@npm:3.1.0" @@ -7343,6 +11453,13 @@ __metadata: languageName: node linkType: hard +"rgb2hex@npm:0.2.5": + version: 0.2.5 + resolution: "rgb2hex@npm:0.2.5" + checksum: 2c36c878bd28b24112dbf5b8d6e898ddb03dcc14e5bd0ddb1a0cc48479aac426cc4f3d1c56d22358ea7ff06154ca4dbe26bca8af303145392afa2d139a8131c4 + languageName: node + linkType: hard + "rimraf@npm:^3.0.2": version: 3.0.2 resolution: "rimraf@npm:3.0.2" @@ -7354,17 +11471,73 @@ __metadata: languageName: node linkType: hard -"rollup@npm:^3.21.0": - version: 3.23.1 - resolution: "rollup@npm:3.23.1" - dependencies: +"rollup@npm:^4.20.0": + version: 4.21.3 + resolution: "rollup@npm:4.21.3" + dependencies: + "@rollup/rollup-android-arm-eabi": 4.21.3 + "@rollup/rollup-android-arm64": 4.21.3 + "@rollup/rollup-darwin-arm64": 4.21.3 + "@rollup/rollup-darwin-x64": 4.21.3 + "@rollup/rollup-linux-arm-gnueabihf": 4.21.3 + "@rollup/rollup-linux-arm-musleabihf": 4.21.3 + "@rollup/rollup-linux-arm64-gnu": 4.21.3 + "@rollup/rollup-linux-arm64-musl": 4.21.3 + "@rollup/rollup-linux-powerpc64le-gnu": 4.21.3 + "@rollup/rollup-linux-riscv64-gnu": 4.21.3 + "@rollup/rollup-linux-s390x-gnu": 4.21.3 + "@rollup/rollup-linux-x64-gnu": 4.21.3 + "@rollup/rollup-linux-x64-musl": 4.21.3 + "@rollup/rollup-win32-arm64-msvc": 4.21.3 + "@rollup/rollup-win32-ia32-msvc": 4.21.3 + "@rollup/rollup-win32-x64-msvc": 4.21.3 + "@types/estree": 1.0.5 fsevents: ~2.3.2 dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm-musleabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-powerpc64le-gnu": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true fsevents: optional: true bin: rollup: dist/bin/rollup - checksum: 4b3b3bbfd490b41ec5473d1141fe2beb0c86f600b56378fce97e0485192818256f8cbf4d43450b097ee7042e6629fb0187488807e2d15050860718f458c44685 + checksum: 19689840d25ced3924124b012d7e0048f2b0844a0765a5dde0804ae9961af1103657c2ec3e90f7a19876ebe40b3fa2c33f53fca071d46639c57bd327b82aba22 + languageName: node + linkType: hard + +"run-async@npm:^3.0.0": + version: 3.0.0 + resolution: "run-async@npm:3.0.0" + checksum: 280c03d5a88603f48103fc6fd69f07fb0c392a1e0d319c34ec96a2516030e07ba06f79231a563c78698b882649c2fc1fda601bc84705f57d50efcd1fa506cfc0 languageName: node linkType: hard @@ -7386,7 +11559,23 @@ __metadata: languageName: node linkType: hard -"safe-buffer@npm:5.2.1, safe-buffer@npm:~5.2.0": +"rxjs@npm:^7.8.1": + version: 7.8.1 + resolution: "rxjs@npm:7.8.1" + dependencies: + tslib: ^2.1.0 + checksum: de4b53db1063e618ec2eca0f7965d9137cabe98cf6be9272efe6c86b47c17b987383df8574861bcced18ebd590764125a901d5506082be84a8b8e364bf05f119 + languageName: node + linkType: hard + +"safaridriver@npm:^0.1.2": + version: 0.1.2 + resolution: "safaridriver@npm:0.1.2" + checksum: facb384c0e1b2029cb29af14c6329c50d58f247e8a180d8d153c1a285033c4932d916e185efe1f45bab353c4a8f46439166e08483040c0b9e7c00066c0947926 + languageName: node + linkType: hard + +"safe-buffer@npm:5.2.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:~5.2.0": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491 @@ -7411,7 +11600,14 @@ __metadata: languageName: node linkType: hard -"safer-buffer@npm:>= 2.1.2 < 3.0.0": +"safe-stringify@npm:^1.1.0": + version: 1.1.1 + resolution: "safe-stringify@npm:1.1.1" + checksum: 5f06510a8adfa9fbc3045021b31e9eb8b5e68f5525d0ea75cb64ceaf7cf7c449abd562f2f5dbd1e5318b046159eaece2d834f4047ccedb941574a9186c0eeb70 + languageName: node + linkType: hard + +"safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0": version: 2.1.2 resolution: "safer-buffer@npm:2.1.2" checksum: cab8f25ae6f1434abee8d80023d7e72b598cf1327164ddab31003c51215526801e40b66c5e65d658a0af1e9d6478cadcb4c745f4bd6751f97d8644786c0978b0 @@ -7436,6 +11632,13 @@ __metadata: languageName: node linkType: hard +"scule@npm:^1.2.0, scule@npm:^1.3.0": + version: 1.3.0 + resolution: "scule@npm:1.3.0" + checksum: f2968b292e33c0eddca4a68b5c70f08dfc8479e492461c248f72873deaf77ae87c9f27dde7a342b3cb6394d2fae9665890b07a2243f79cff5cba65c9525ccf7e + languageName: node + linkType: hard + "semver-regex@npm:^4.0.5": version: 4.0.5 resolution: "semver-regex@npm:4.0.5" @@ -7452,7 +11655,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^6.0.0, semver@npm:^6.3.0": +"semver@npm:^6.0.0, semver@npm:^6.3.0, semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" bin: @@ -7472,6 +11675,44 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.5.3": + version: 7.5.4 + resolution: "semver@npm:7.5.4" + dependencies: + lru-cache: ^6.0.0 + bin: + semver: bin/semver.js + checksum: 12d8ad952fa353b0995bf180cdac205a4068b759a140e5d3c608317098b3575ac2f1e09182206bf2eb26120e1c0ed8fb92c48c592f6099680de56bb071423ca3 + languageName: node + linkType: hard + +"semver@npm:^7.5.4, semver@npm:^7.6.3": + version: 7.6.3 + resolution: "semver@npm:7.6.3" + bin: + semver: bin/semver.js + checksum: 4110ec5d015c9438f322257b1c51fe30276e5f766a3f64c09edd1d7ea7118ecbc3f379f3b69032bacf13116dc7abc4ad8ce0d7e2bd642e26b0d271b56b61a7d8 + languageName: node + linkType: hard + +"serialize-error@npm:^11.0.3": + version: 11.0.3 + resolution: "serialize-error@npm:11.0.3" + dependencies: + type-fest: ^2.12.2 + checksum: 09d1aee6186fd5ff8acc074ee8641116cdd07b12df1e95682c43d8b5d1ef657deecc2efede7f1a08f5ff3ef3d65fb60ab9c8b4b2fdde65867ad3e6d4feed34a9 + languageName: node + linkType: hard + +"serialize-javascript@npm:^6.0.2": + version: 6.0.2 + resolution: "serialize-javascript@npm:6.0.2" + dependencies: + randombytes: ^2.1.0 + checksum: c4839c6206c1d143c0f80763997a361310305751171dd95e4b57efee69b8f6edd8960a0b7fbfc45042aadff98b206d55428aee0dc276efe54f100899c7fa8ab7 + languageName: node + linkType: hard + "set-blocking@npm:^2.0.0": version: 2.0.0 resolution: "set-blocking@npm:2.0.0" @@ -7488,6 +11729,13 @@ __metadata: languageName: node linkType: hard +"setimmediate@npm:^1.0.5": + version: 1.0.5 + resolution: "setimmediate@npm:1.0.5" + checksum: c9a6f2c5b51a2dabdc0247db9c46460152ffc62ee139f3157440bd48e7c59425093f42719ac1d7931f054f153e2d26cf37dfeb8da17a794a58198a2705e527fd + languageName: node + linkType: hard + "shebang-command@npm:^1.2.0": version: 1.2.0 resolution: "shebang-command@npm:1.2.0" @@ -7545,6 +11793,13 @@ __metadata: languageName: node linkType: hard +"signal-exit@npm:^4.0.1, signal-exit@npm:^4.1.0": + version: 4.1.0 + resolution: "signal-exit@npm:4.1.0" + checksum: 64c757b498cb8629ffa5f75485340594d2f8189e9b08700e69199069c8e3070fb3e255f7ab873c05dc0b3cec412aea7402e10a5990cb6a050bd33ba062a6c549 + languageName: node + linkType: hard + "sisteransi@npm:^1.0.5": version: 1.0.5 resolution: "sisteransi@npm:1.0.5" @@ -7566,6 +11821,13 @@ __metadata: languageName: node linkType: hard +"slash@npm:^5.1.0": + version: 5.1.0 + resolution: "slash@npm:5.1.0" + checksum: 70434b34c50eb21b741d37d455110258c42d2cf18c01e6518aeb7299f3c6e626330c889c0c552b5ca2ef54a8f5a74213ab48895f0640717cacefeef6830a1ba4 + languageName: node + linkType: hard + "slice-ansi@npm:^3.0.0": version: 3.0.0 resolution: "slice-ansi@npm:3.0.0" @@ -7616,6 +11878,17 @@ __metadata: languageName: node linkType: hard +"socks-proxy-agent@npm:^8.0.2, socks-proxy-agent@npm:^8.0.4": + version: 8.0.4 + resolution: "socks-proxy-agent@npm:8.0.4" + dependencies: + agent-base: ^7.1.1 + debug: ^4.3.4 + socks: ^2.8.3 + checksum: b2ec5051d85fe49072f9a250c427e0e9571fd09d5db133819192d078fd291276e1f0f50f6dbc04329b207738b1071314cee8bdbb4b12e27de42dbcf1d4233c67 + languageName: node + linkType: hard + "socks@npm:^2.6.2": version: 2.7.1 resolution: "socks@npm:2.7.1" @@ -7626,6 +11899,16 @@ __metadata: languageName: node linkType: hard +"socks@npm:^2.8.3": + version: 2.8.3 + resolution: "socks@npm:2.8.3" + dependencies: + ip-address: ^9.0.5 + smart-buffer: ^4.2.0 + checksum: 7a6b7f6eedf7482b9e4597d9a20e09505824208006ea8f2c49b71657427f3c137ca2ae662089baa73e1971c62322d535d9d0cf1c9235cf6f55e315c18203eadd + languageName: node + linkType: hard + "sort-keys-length@npm:^1.0.0": version: 1.0.1 resolution: "sort-keys-length@npm:1.0.1" @@ -7644,10 +11927,10 @@ __metadata: languageName: node linkType: hard -"source-map-js@npm:^1.0.2": - version: 1.0.2 - resolution: "source-map-js@npm:1.0.2" - checksum: c049a7fc4deb9a7e9b481ae3d424cc793cb4845daa690bc5a05d428bf41bf231ced49b4cf0c9e77f9d42fdb3d20d6187619fc586605f5eabe995a316da8d377c +"source-map-js@npm:^1.2.1": + version: 1.2.1 + resolution: "source-map-js@npm:1.2.1" + checksum: 4eb0cd997cdf228bc253bcaff9340afeb706176e64868ecd20efbe6efea931465f43955612346d6b7318789e5265bdc419bc7669c1cebe3db0eb255f57efa76b languageName: node linkType: hard @@ -7661,6 +11944,16 @@ __metadata: languageName: node linkType: hard +"source-map-support@npm:^0.5.21": + version: 0.5.21 + resolution: "source-map-support@npm:0.5.21" + dependencies: + buffer-from: ^1.0.0 + source-map: ^0.6.0 + checksum: 43e98d700d79af1d36f859bdb7318e601dfc918c7ba2e98456118ebc4c4872b327773e5a1df09b0524e9e5063bb18f0934538eace60cca2710d1fa687645d137 + languageName: node + linkType: hard + "source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.1": version: 0.6.1 resolution: "source-map@npm:0.6.1" @@ -7668,13 +11961,20 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.7.3": +"source-map@npm:^0.7.3, source-map@npm:^0.7.4": version: 0.7.4 resolution: "source-map@npm:0.7.4" checksum: 01cc5a74b1f0e1d626a58d36ad6898ea820567e87f18dfc9d24a9843a351aaa2ec09b87422589906d6ff1deed29693e176194dc88bcae7c9a852dc74b311dbf5 languageName: node linkType: hard +"spacetrim@npm:0.11.39": + version: 0.11.39 + resolution: "spacetrim@npm:0.11.39" + checksum: 22af3d3935916e16712f4f2d097c85f352ca4b2fcb5d2f3b6645f1a0a200fe20fb161e3ea33bf71182079a1f14613a1bd880914d27f07e2e65d30151a0476821 + languageName: node + linkType: hard + "spawn-command@npm:^0.0.2-1": version: 0.0.2 resolution: "spawn-command@npm:0.0.2" @@ -7682,6 +11982,54 @@ __metadata: languageName: node linkType: hard +"spdx-correct@npm:^3.0.0": + version: 3.2.0 + resolution: "spdx-correct@npm:3.2.0" + dependencies: + spdx-expression-parse: ^3.0.0 + spdx-license-ids: ^3.0.0 + checksum: e9ae98d22f69c88e7aff5b8778dc01c361ef635580e82d29e5c60a6533cc8f4d820803e67d7432581af0cc4fb49973125076ee3b90df191d153e223c004193b2 + languageName: node + linkType: hard + +"spdx-exceptions@npm:^2.1.0": + version: 2.5.0 + resolution: "spdx-exceptions@npm:2.5.0" + checksum: bb127d6e2532de65b912f7c99fc66097cdea7d64c10d3ec9b5e96524dbbd7d20e01cba818a6ddb2ae75e62bb0c63d5e277a7e555a85cbc8ab40044984fa4ae15 + languageName: node + linkType: hard + +"spdx-expression-parse@npm:^3.0.0": + version: 3.0.1 + resolution: "spdx-expression-parse@npm:3.0.1" + dependencies: + spdx-exceptions: ^2.1.0 + spdx-license-ids: ^3.0.0 + checksum: a1c6e104a2cbada7a593eaa9f430bd5e148ef5290d4c0409899855ce8b1c39652bcc88a725259491a82601159d6dc790bedefc9016c7472f7de8de7361f8ccde + languageName: node + linkType: hard + +"spdx-license-ids@npm:^3.0.0": + version: 3.0.20 + resolution: "spdx-license-ids@npm:3.0.20" + checksum: 0c57750bedbcff48f3d0e266fbbdaf0aab54217e182f669542ffe0b5a902dce69e8cdfa126a131e1ddd39a9bef4662e357b2b41315d7240b4a28c0a7e782bb40 + languageName: node + linkType: hard + +"split2@npm:^4.1.0, split2@npm:^4.2.0": + version: 4.2.0 + resolution: "split2@npm:4.2.0" + checksum: 05d54102546549fe4d2455900699056580cca006c0275c334611420f854da30ac999230857a85fdd9914dc2109ae50f80fda43d2a445f2aa86eccdc1dfce779d + languageName: node + linkType: hard + +"sprintf-js@npm:^1.1.3": + version: 1.1.3 + resolution: "sprintf-js@npm:1.1.3" + checksum: a3fdac7b49643875b70864a9d9b469d87a40dfeaf5d34d9d0c5b1cda5fd7d065531fcb43c76357d62254c57184a7b151954156563a4d6a747015cfb41021cad0 + languageName: node + linkType: hard + "sprintf-js@npm:~1.0.2": version: 1.0.3 resolution: "sprintf-js@npm:1.0.3" @@ -7707,12 +12055,32 @@ __metadata: languageName: node linkType: hard -"stop-iteration-iterator@npm:^1.0.0": - version: 1.0.0 - resolution: "stop-iteration-iterator@npm:1.0.0" +"std-env@npm:^3.7.0": + version: 3.7.0 + resolution: "std-env@npm:3.7.0" + checksum: 4f489d13ff2ab838c9acd4ed6b786b51aa52ecacdfeaefe9275fcb220ff2ac80c6e95674723508fd29850a694569563a8caaaea738eb82ca16429b3a0b50e510 + languageName: node + linkType: hard + +"stream-buffers@npm:^3.0.2": + version: 3.0.3 + resolution: "stream-buffers@npm:3.0.3" + checksum: 3f0bdc4b1fd3ff370cef5a2103dd930b8981d42d97741eeb087a660771e27f0fc35fa8a351bb36e15bbbbce0eea00fefed60d6cdff4c6c3f527580529f183807 + languageName: node + linkType: hard + +"streamx@npm:^2.15.0, streamx@npm:^2.20.0": + version: 2.20.1 + resolution: "streamx@npm:2.20.1" dependencies: - internal-slot: ^1.0.4 - checksum: d04173690b2efa40e24ab70e5e51a3ff31d56d699550cfad084104ab3381390daccb36652b25755e420245f3b0737de66c1879eaa2a8d4fc0a78f9bf892fcb42 + bare-events: ^2.2.0 + fast-fifo: ^1.3.2 + queue-tick: ^1.0.1 + text-decoder: ^1.1.0 + dependenciesMeta: + bare-events: + optional: true + checksum: 48605ddd3abdd86d2e3ee945ec7c9317f36abb5303347a8fff6e4c7926a72c33ec7ac86b50734ccd1cf65602b6a38e247966e8199b24e5a7485d9cec8f5327bd languageName: node linkType: hard @@ -7733,7 +12101,7 @@ __metadata: languageName: node linkType: hard -"string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": version: 4.2.3 resolution: "string-width@npm:4.2.3" dependencies: @@ -7744,7 +12112,7 @@ __metadata: languageName: node linkType: hard -"string-width@npm:^5.0.0": +"string-width@npm:^5.0.0, string-width@npm:^5.0.1, string-width@npm:^5.1.2": version: 5.1.2 resolution: "string-width@npm:5.1.2" dependencies: @@ -7793,7 +12161,7 @@ __metadata: languageName: node linkType: hard -"string_decoder@npm:^1.1.1": +"string_decoder@npm:^1.1.1, string_decoder@npm:^1.3.0": version: 1.3.0 resolution: "string_decoder@npm:1.3.0" dependencies: @@ -7811,7 +12179,7 @@ __metadata: languageName: node linkType: hard -"strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": version: 6.0.1 resolution: "strip-ansi@npm:6.0.1" dependencies: @@ -7829,6 +12197,15 @@ __metadata: languageName: node linkType: hard +"strip-ansi@npm:^7.1.0": + version: 7.1.0 + resolution: "strip-ansi@npm:7.1.0" + dependencies: + ansi-regex: ^6.0.1 + checksum: 859c73fcf27869c22a4e4d8c6acfe690064659e84bef9458aa6d13719d09ca88dcfd40cbf31fd0be63518ea1a643fe070b4827d353e09533a5b0b9fd4553d64d + languageName: node + linkType: hard + "strip-bom@npm:^3.0.0": version: 3.0.0 resolution: "strip-bom@npm:3.0.0" @@ -7871,6 +12248,13 @@ __metadata: languageName: node linkType: hard +"strip-final-newline@npm:^4.0.0": + version: 4.0.0 + resolution: "strip-final-newline@npm:4.0.0" + checksum: b5fe48f695d74863153a3b3155220e6e9bf51f4447832998c8edec38e6559b3af87a9fe5ac0df95570a78a26f5fa91701358842eab3c15480e27980b154a145f + languageName: node + linkType: hard + "strip-json-comments@npm:^3.1.0, strip-json-comments@npm:^3.1.1": version: 3.1.1 resolution: "strip-json-comments@npm:3.1.1" @@ -7878,6 +12262,15 @@ __metadata: languageName: node linkType: hard +"strip-literal@npm:^2.1.0": + version: 2.1.0 + resolution: "strip-literal@npm:2.1.0" + dependencies: + js-tokens: ^9.0.0 + checksum: 37c2072634d2de11a3644fe1bcf4abd566d85e89f0d8e8b10d35d04e7bef962e7c112fbe5b805ce63e59dfacedc240356eeef57976351502966b7c64b742c6ac + languageName: node + linkType: hard + "strip-outer@npm:^2.0.0": version: 2.0.0 resolution: "strip-outer@npm:2.0.0" @@ -7885,6 +12278,13 @@ __metadata: languageName: node linkType: hard +"strnum@npm:^1.0.5": + version: 1.0.5 + resolution: "strnum@npm:1.0.5" + checksum: 651b2031db5da1bf4a77fdd2f116a8ac8055157c5420f5569f64879133825915ad461513e7202a16d7fec63c54fd822410d0962f8ca12385c4334891b9ae6dd2 + languageName: node + linkType: hard + "strtok3@npm:^7.0.0-alpha.9": version: 7.0.0 resolution: "strtok3@npm:7.0.0" @@ -7913,7 +12313,7 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^8.0.0, supports-color@npm:^8.1.0": +"supports-color@npm:^8.0.0, supports-color@npm:^8.1.0, supports-color@npm:^8.1.1": version: 8.1.1 resolution: "supports-color@npm:8.1.1" dependencies: @@ -7953,6 +12353,34 @@ __metadata: languageName: node linkType: hard +"tar-fs@npm:^3.0.6": + version: 3.0.6 + resolution: "tar-fs@npm:3.0.6" + dependencies: + bare-fs: ^2.1.1 + bare-path: ^2.1.0 + pump: ^3.0.0 + tar-stream: ^3.1.5 + dependenciesMeta: + bare-fs: + optional: true + bare-path: + optional: true + checksum: b4fa09c70f75caf05bf5cf87369cd2862f1ac5fb75c4ddf9d25d55999f7736a94b58ad679d384196cba837c5f5ff14086e060fafccef5474a16e2d3058ffa488 + languageName: node + linkType: hard + +"tar-stream@npm:^3.0.0, tar-stream@npm:^3.1.5": + version: 3.1.7 + resolution: "tar-stream@npm:3.1.7" + dependencies: + b4a: ^1.6.4 + fast-fifo: ^1.2.0 + streamx: ^2.15.0 + checksum: 6393a6c19082b17b8dcc8e7fd349352bb29b4b8bfe1075912b91b01743ba6bb4298f5ff0b499a3bbaf82121830e96a1a59d4f21a43c0df339e54b01789cb8cc6 + languageName: node + linkType: hard + "tar@npm:^6.0.5, tar@npm:^6.1.11, tar@npm:^6.1.2": version: 6.1.13 resolution: "tar@npm:6.1.13" @@ -7967,6 +12395,20 @@ __metadata: languageName: node linkType: hard +"tar@npm:^6.2.0": + version: 6.2.1 + resolution: "tar@npm:6.2.1" + dependencies: + chownr: ^2.0.0 + fs-minipass: ^2.0.0 + minipass: ^5.0.0 + minizlib: ^2.1.1 + mkdirp: ^1.0.3 + yallist: ^4.0.0 + checksum: f1322768c9741a25356c11373bce918483f40fa9a25c69c59410c8a1247632487edef5fe76c5f12ac51a6356d2f1829e96d2bc34098668a2fc34d76050ac2b6c + languageName: node + linkType: hard + "test-exclude@npm:^6.0.0": version: 6.0.0 resolution: "test-exclude@npm:6.0.0" @@ -7978,6 +12420,15 @@ __metadata: languageName: node linkType: hard +"text-decoder@npm:^1.1.0": + version: 1.2.0 + resolution: "text-decoder@npm:1.2.0" + dependencies: + b4a: ^1.6.4 + checksum: 9f4c23900b42153af0e4a902577eba37cb70cd1d5b187732b81c74c705d3206952cf1dcecf97537794374f55aac6c547ac3860f1facc9560007ca9a06b0e309d + languageName: node + linkType: hard + "text-table@npm:^0.2.0": version: 0.2.0 resolution: "text-table@npm:0.2.0" @@ -8012,6 +12463,13 @@ __metadata: languageName: node linkType: hard +"tiny-invariant@npm:^1.3.3": + version: 1.3.3 + resolution: "tiny-invariant@npm:1.3.3" + checksum: 5e185c8cc2266967984ce3b352a4e57cb89dad5a8abb0dea21468a6ecaa67cd5bb47a3b7a85d08041008644af4f667fb8b6575ba38ba5fb00b3b5068306e59fe + languageName: node + linkType: hard + "tinylogic@npm:^2.0.0": version: 2.0.0 resolution: "tinylogic@npm:2.0.0" @@ -8019,6 +12477,29 @@ __metadata: languageName: node linkType: hard +"tinyrainbow@npm:^1.2.0": + version: 1.2.0 + resolution: "tinyrainbow@npm:1.2.0" + checksum: d1e2cb5400032c0092be00e4a3da5450bea8b4fad58bfb5d3c58ca37ff5c5e252f7fcfb9af247914854af79c46014add9d1042fe044358c305a129ed55c8be35 + languageName: node + linkType: hard + +"tinyspy@npm:^3.0.0": + version: 3.0.2 + resolution: "tinyspy@npm:3.0.2" + checksum: 5db671b2ff5cd309de650c8c4761ca945459d7204afb1776db9a04fb4efa28a75f08517a8620c01ee32a577748802231ad92f7d5b194dc003ee7f987a2a06337 + languageName: node + linkType: hard + +"tmp@npm:^0.0.33": + version: 0.0.33 + resolution: "tmp@npm:0.0.33" + dependencies: + os-tmpdir: ~1.0.2 + checksum: 902d7aceb74453ea02abbf58c203f4a8fc1cead89b60b31e354f74ed5b3fb09ea817f94fb310f884a5d16987dd9fa5a735412a7c2dd088dd3d415aa819ae3a28 + languageName: node + linkType: hard + "tmpl@npm:1.0.5": version: 1.0.5 resolution: "tmpl@npm:1.0.5" @@ -8133,6 +12614,13 @@ __metadata: languageName: node linkType: hard +"tslib@npm:^2.0.1": + version: 2.7.0 + resolution: "tslib@npm:2.7.0" + checksum: 1606d5c89f88d466889def78653f3aab0f88692e80bb2066d090ca6112ae250ec1cfa9dbfaab0d17b60da15a4186e8ec4d893801c67896b277c17374e36e1d28 + languageName: node + linkType: hard + "tslib@npm:^2.1.0, tslib@npm:^2.4.0, tslib@npm:^2.5.0": version: 2.5.0 resolution: "tslib@npm:2.5.0" @@ -8151,6 +12639,22 @@ __metadata: languageName: node linkType: hard +"tsx@npm:^4.19.1, tsx@npm:^4.7.2": + version: 4.19.1 + resolution: "tsx@npm:4.19.1" + dependencies: + esbuild: ~0.23.0 + fsevents: ~2.3.3 + get-tsconfig: ^4.7.5 + dependenciesMeta: + fsevents: + optional: true + bin: + tsx: dist/cli.mjs + checksum: 31bfd2df62c1230f7c15f6e24d3790019ba7b2ad497221cb0cebcf5cf4f2c1ac971fac0d1283e3d80dc823652d2f9be946bd40ac65b640ff3f199b84a904a9c7 + languageName: node + linkType: hard + "tunnel@npm:^0.0.6": version: 0.0.6 resolution: "tunnel@npm:0.0.6" @@ -8190,6 +12694,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:2.13.0": + version: 2.13.0 + resolution: "type-fest@npm:2.13.0" + checksum: 3492384f759fdeaec7eaa07e79f70e777bf825cf8892690642fa9350818df4a8c50fd697fd1239ae7026064af4dd94e4d5eca27e781e0952ff302af0708a2e69 + languageName: node + linkType: hard + "type-fest@npm:^0.20.2": version: 0.20.2 resolution: "type-fest@npm:0.20.2" @@ -8204,6 +12715,27 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^2.12.2": + version: 2.19.0 + resolution: "type-fest@npm:2.19.0" + checksum: a4ef07ece297c9fba78fc1bd6d85dff4472fe043ede98bd4710d2615d15776902b595abf62bd78339ed6278f021235fb28a96361f8be86ed754f778973a0d278 + languageName: node + linkType: hard + +"type-fest@npm:^3.8.0": + version: 3.13.1 + resolution: "type-fest@npm:3.13.1" + checksum: c06b0901d54391dc46de3802375f5579868949d71f93b425ce564e19a428a0d411ae8d8cb0e300d330071d86152c3ea86e744c3f2860a42a79585b6ec2fdae8e + languageName: node + linkType: hard + +"type-fest@npm:^4.2.0": + version: 4.26.1 + resolution: "type-fest@npm:4.26.1" + checksum: 7188db3bca82afa62c69a8043fb7c5eb74e63c45e7e28efb986da1629d844286f7181bc5a8185f38989fffff0d6c96be66fd13529b01932d1b6ebe725181d31a + languageName: node + linkType: hard + "typed-array-length@npm:^1.0.4": version: 1.0.4 resolution: "typed-array-length@npm:1.0.4" @@ -8242,6 +12774,13 @@ __metadata: languageName: node linkType: hard +"ufo@npm:^1.5.3, ufo@npm:^1.5.4": + version: 1.5.4 + resolution: "ufo@npm:1.5.4" + checksum: f244703b7d4f9f0df4f9af23921241ab73410b591f4e5b39c23e3147f3159b139a4b1fb5903189c306129f7a16b55995dac0008e0fbae88a37c3e58cbc34d833 + languageName: node + linkType: hard + "unbox-primitive@npm:^1.0.2": version: 1.0.2 resolution: "unbox-primitive@npm:1.0.2" @@ -8254,6 +12793,77 @@ __metadata: languageName: node linkType: hard +"unbzip2-stream@npm:^1.4.3": + version: 1.4.3 + resolution: "unbzip2-stream@npm:1.4.3" + dependencies: + buffer: ^5.2.1 + through: ^2.3.8 + checksum: 0e67c4a91f4fa0fc7b4045f8b914d3498c2fc2e8c39c359977708ec85ac6d6029840e97f508675fdbdf21fcb8d276ca502043406f3682b70f075e69aae626d1d + languageName: node + linkType: hard + +"uncrypto@npm:^0.1.3": + version: 0.1.3 + resolution: "uncrypto@npm:0.1.3" + checksum: 07160e08806dd6cea16bb96c3fd54cd70fc801e02fc3c6f86980144d15c9ebbd1c55587f7280a207b3af6cd34901c0d0b77ada5a02c2f7081a033a05acf409e2 + languageName: node + linkType: hard + +"unctx@npm:^2.3.1": + version: 2.3.1 + resolution: "unctx@npm:2.3.1" + dependencies: + acorn: ^8.8.2 + estree-walker: ^3.0.3 + magic-string: ^0.30.0 + unplugin: ^1.3.1 + checksum: 96876a01b2d7dc70b44dce0e863aa654d066b04f57cdc4739ce884c13aadbfddad10df4e52de3648dae24ccd7aca454b6927b372d4912b9471c7671376f82b27 + languageName: node + linkType: hard + +"undici-types@npm:~6.19.2": + version: 6.19.8 + resolution: "undici-types@npm:6.19.8" + checksum: de51f1b447d22571cf155dfe14ff6d12c5bdaec237c765085b439c38ca8518fc360e88c70f99469162bf2e14188a7b0bcb06e1ed2dc031042b984b0bb9544017 + languageName: node + linkType: hard + +"undici@npm:^6.19.5": + version: 6.19.8 + resolution: "undici@npm:6.19.8" + checksum: 2f812769992a187d9c55809b6943059c0bb1340687a0891f769de02101342dded0b9c8874cd5af4a49daaeba8284101d74a1fbda4de04c604ba7a5f6190b9ea2 + languageName: node + linkType: hard + +"unicorn-magic@npm:^0.1.0": + version: 0.1.0 + resolution: "unicorn-magic@npm:0.1.0" + checksum: 48c5882ca3378f380318c0b4eb1d73b7e3c5b728859b060276e0a490051d4180966beeb48962d850fd0c6816543bcdfc28629dcd030bb62a286a2ae2acb5acb6 + languageName: node + linkType: hard + +"unimport@npm:^3.10.0, unimport@npm:^3.12.0": + version: 3.12.0 + resolution: "unimport@npm:3.12.0" + dependencies: + "@rollup/pluginutils": ^5.1.0 + acorn: ^8.12.1 + escape-string-regexp: ^5.0.0 + estree-walker: ^3.0.3 + fast-glob: ^3.3.2 + local-pkg: ^0.5.0 + magic-string: ^0.30.11 + mlly: ^1.7.1 + pathe: ^1.1.2 + pkg-types: ^1.2.0 + scule: ^1.3.0 + strip-literal: ^2.1.0 + unplugin: ^1.14.1 + checksum: 40df387cb9e37db090498314fabb68c58ad4f0e2becd8ca85e0a0f4e8f99337e8df14c0e704b71f4389d3f8a134e435c5befb6dd1402af1e465699dc5bba9fdf + languageName: node + linkType: hard + "unique-filename@npm:^2.0.0": version: 2.0.1 resolution: "unique-filename@npm:2.0.1" @@ -8279,6 +12889,45 @@ __metadata: languageName: node linkType: hard +"universalify@npm:^2.0.0": + version: 2.0.1 + resolution: "universalify@npm:2.0.1" + checksum: ecd8469fe0db28e7de9e5289d32bd1b6ba8f7183db34f3bfc4ca53c49891c2d6aa05f3fb3936a81285a905cc509fb641a0c3fc131ec786167eff41236ae32e60 + languageName: node + linkType: hard + +"unplugin@npm:^1.14.1, unplugin@npm:^1.3.1": + version: 1.14.1 + resolution: "unplugin@npm:1.14.1" + dependencies: + acorn: ^8.12.1 + webpack-virtual-modules: ^0.6.2 + peerDependencies: + webpack-sources: ^3 + peerDependenciesMeta: + webpack-sources: + optional: true + checksum: fa0bedf5e6e311418e30a788828221ab211700a480a397890062ba867aa1474bb06e4fe0ede16f5bd8512d25041dd1988d4108a918343030f638231de2bf7af1 + languageName: node + linkType: hard + +"untyped@npm:^1.4.2": + version: 1.4.2 + resolution: "untyped@npm:1.4.2" + dependencies: + "@babel/core": ^7.23.7 + "@babel/standalone": ^7.23.8 + "@babel/types": ^7.23.6 + defu: ^6.1.4 + jiti: ^1.21.0 + mri: ^1.2.0 + scule: ^1.2.0 + bin: + untyped: dist/cli.mjs + checksum: 3e46096c8c20cd3a25234da718825f8a8ed66f9c5e7a19a81089e195dc00c8d15a1acb30159d989772fbe94b515e4fc89e6402c970451b3ed43e93bcc9103fc8 + languageName: node + linkType: hard + "update-browserslist-db@npm:^1.0.10": version: 1.0.10 resolution: "update-browserslist-db@npm:1.0.10" @@ -8293,6 +12942,20 @@ __metadata: languageName: node linkType: hard +"update-browserslist-db@npm:^1.1.0": + version: 1.1.0 + resolution: "update-browserslist-db@npm:1.1.0" + dependencies: + escalade: ^3.1.2 + picocolors: ^1.0.1 + peerDependencies: + browserslist: ">= 4.21.0" + bin: + update-browserslist-db: cli.js + checksum: 7b74694d96f0c360f01b702e72353dc5a49df4fe6663d3ee4e5c628f061576cddf56af35a3a886238c01dd3d8f231b7a86a8ceaa31e7a9220ae31c1c1238e562 + languageName: node + linkType: hard + "uri-js@npm:^4.2.2": version: 4.4.1 resolution: "uri-js@npm:4.4.1" @@ -8312,6 +12975,20 @@ __metadata: languageName: node linkType: hard +"urlpattern-polyfill@npm:^10.0.0": + version: 10.0.0 + resolution: "urlpattern-polyfill@npm:10.0.0" + checksum: 61d890f151ea4ecf34a3dcab32c65ad1f3cda857c9d154af198260c6e5b2ad96d024593409baaa6d4428dd1ab206c14799bf37fe011117ac93a6a44913ac5aa4 + languageName: node + linkType: hard + +"userhome@npm:1.0.0": + version: 1.0.0 + resolution: "userhome@npm:1.0.0" + checksum: 78e2c4f4fcdb2349df7024bf94d11af13b8101ee9ca12f1ba8a42f8c17276046bd523e6e09e2f32b119f0216ee5043e3d874e3fd0af0d73cb2231ba1c0987334 + languageName: node + linkType: hard + "util-deprecate@npm:^1.0.1, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" @@ -8319,6 +12996,15 @@ __metadata: languageName: node linkType: hard +"uuid@npm:^10.0.0": + version: 10.0.0 + resolution: "uuid@npm:10.0.0" + bin: + uuid: dist/bin/uuid + checksum: 4b81611ade2885d2313ddd8dc865d93d8dccc13ddf901745edca8f86d99bc46d7a330d678e7532e7ebf93ce616679fb19b2e3568873ac0c14c999032acb25869 + languageName: node + linkType: hard + "v8-to-istanbul@npm:^9.0.1": version: 9.0.1 resolution: "v8-to-istanbul@npm:9.0.1" @@ -8330,18 +13016,59 @@ __metadata: languageName: node linkType: hard -"vite@npm:^4.1.5": - version: 4.3.9 - resolution: "vite@npm:4.3.9" +"validate-npm-package-license@npm:^3.0.4": + version: 3.0.4 + resolution: "validate-npm-package-license@npm:3.0.4" dependencies: - esbuild: ^0.17.5 - fsevents: ~2.3.2 - postcss: ^8.4.23 - rollup: ^3.21.0 + spdx-correct: ^3.0.0 + spdx-expression-parse: ^3.0.0 + checksum: 35703ac889d419cf2aceef63daeadbe4e77227c39ab6287eeb6c1b36a746b364f50ba22e88591f5d017bc54685d8137bc2d328d0a896e4d3fd22093c0f32a9ad + languageName: node + linkType: hard + +"vite-plugin-istanbul@npm:^6.0.0": + version: 6.0.2 + resolution: "vite-plugin-istanbul@npm:6.0.2" + dependencies: + "@istanbuljs/load-nyc-config": ^1.1.0 + espree: ^10.0.1 + istanbul-lib-instrument: ^6.0.2 + picocolors: ^1.0.0 + source-map: ^0.7.4 + test-exclude: ^6.0.0 + peerDependencies: + vite: ">=4 <=6" + checksum: fddd8367fa02159a047179c9c576c309f9a14bb970116e35fe543d40e3acc615c1671387b9de2394a5bc75d2ab0cfb7b7ebb9e29ec4ddff5411fa7bfee663e42 + languageName: node + linkType: hard + +"vite-plugin-top-level-await@npm:^1.4.1": + version: 1.4.4 + resolution: "vite-plugin-top-level-await@npm:1.4.4" + dependencies: + "@rollup/plugin-virtual": ^3.0.2 + "@swc/core": ^1.7.0 + uuid: ^10.0.0 + peerDependencies: + vite: ">=2.8" + checksum: d15cf5734ad95816a3b28b23956587a2a9ec00076440e6b69fe1efd0b0e1c13baef5385870f5437b09b848db4903fc2e39dd0c007111b35098d59bf54cfbc66c + languageName: node + linkType: hard + +"vite@npm:^5.4.5, vite@npm:~5.4.0": + version: 5.4.5 + resolution: "vite@npm:5.4.5" + dependencies: + esbuild: ^0.21.3 + fsevents: ~2.3.3 + postcss: ^8.4.43 + rollup: ^4.20.0 peerDependencies: - "@types/node": ">= 14" + "@types/node": ^18.0.0 || >=20.0.0 less: "*" + lightningcss: ^1.21.0 sass: "*" + sass-embedded: "*" stylus: "*" sugarss: "*" terser: ^5.4.0 @@ -8353,8 +13080,12 @@ __metadata: optional: true less: optional: true + lightningcss: + optional: true sass: optional: true + sass-embedded: + optional: true stylus: optional: true sugarss: @@ -8363,7 +13094,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 8c45a516278d1e0425fac00c0877336790f71484a851a318346a70e0d2aef9f3b9651deb2f9f002c791ceb920eda7d6a3cda753bdefd657321c99f448b02dd25 + checksum: 19e7aa49cd72f93d4e152f23b736ff3de4fc4bccf81d99970b3e88bf399138cf1807314fde1f5ee6251f2007292d491bad97e444fb9d4d5628be4bf6cae62a42 languageName: node linkType: hard @@ -8383,6 +13114,19 @@ __metadata: languageName: node linkType: hard +"wait-port@npm:^1.1.0": + version: 1.1.0 + resolution: "wait-port@npm:1.1.0" + dependencies: + chalk: ^4.1.2 + commander: ^9.3.0 + debug: ^4.3.4 + bin: + wait-port: bin/wait-port.js + checksum: bf7c2cd566449530e2599a00cdf4b5a8a6e8c55d370bcd4045db6eacdc7040fdf3d83ff8773bbb036ac614e0d677ade28724a4d259cd3cc555cf9b4995647bab + languageName: node + linkType: hard + "walker@npm:^1.0.8": version: 1.0.8 resolution: "walker@npm:1.0.8" @@ -8392,6 +13136,70 @@ __metadata: languageName: node linkType: hard +"web-streams-polyfill@npm:^3.0.3": + version: 3.3.3 + resolution: "web-streams-polyfill@npm:3.3.3" + checksum: 21ab5ea08a730a2ef8023736afe16713b4f2023ec1c7085c16c8e293ee17ed085dff63a0ad8722da30c99c4ccbd4ccd1b2e79c861829f7ef2963d7de7004c2cb + languageName: node + linkType: hard + +"webdriver@npm:9.0.8": + version: 9.0.8 + resolution: "webdriver@npm:9.0.8" + dependencies: + "@types/node": ^20.1.0 + "@types/ws": ^8.5.3 + "@wdio/config": 9.0.8 + "@wdio/logger": 9.0.8 + "@wdio/protocols": 9.0.8 + "@wdio/types": 9.0.8 + "@wdio/utils": 9.0.8 + deepmerge-ts: ^7.0.3 + ws: ^8.8.0 + checksum: 18b27519eb76ff0cbb0cbda272db1da3573bbb8a9fbb622f0d6ca3618e83968cc5354f72c7cbd19f1be53f051d7adf1b4954f51cfb7ceada9f2dcf1e52af7316 + languageName: node + linkType: hard + +"webdriverio@npm:9.0.9, webdriverio@npm:^9.0.9": + version: 9.0.9 + resolution: "webdriverio@npm:9.0.9" + dependencies: + "@types/node": ^20.11.30 + "@types/sinonjs__fake-timers": ^8.1.5 + "@wdio/config": 9.0.8 + "@wdio/logger": 9.0.8 + "@wdio/protocols": 9.0.8 + "@wdio/repl": 9.0.8 + "@wdio/types": 9.0.8 + "@wdio/utils": 9.0.8 + archiver: ^7.0.1 + aria-query: ^5.3.0 + cheerio: ^1.0.0-rc.12 + css-shorthand-properties: ^1.1.1 + css-value: ^0.0.1 + grapheme-splitter: ^1.0.4 + htmlfy: ^0.2.1 + import-meta-resolve: ^4.0.0 + is-plain-obj: ^4.1.0 + jszip: ^3.10.1 + lodash.clonedeep: ^4.5.0 + lodash.zip: ^4.2.0 + minimatch: ^9.0.3 + query-selector-shadow-dom: ^1.0.1 + resq: ^1.11.0 + rgb2hex: 0.2.5 + serialize-error: ^11.0.3 + urlpattern-polyfill: ^10.0.0 + webdriver: 9.0.8 + peerDependencies: + puppeteer-core: ^22.3.0 + peerDependenciesMeta: + puppeteer-core: + optional: true + checksum: e5c83ef86b84d9034fb806139f0b367b6b59dec7ff40344893550ccc4ac3a06fa78b9f183cae9c4c794bbdac42a5464f541be272968ee653f985ab2d25f30743 + languageName: node + linkType: hard + "webidl-conversions@npm:^7.0.0": version: 7.0.0 resolution: "webidl-conversions@npm:7.0.0" @@ -8399,6 +13207,13 @@ __metadata: languageName: node linkType: hard +"webpack-virtual-modules@npm:^0.6.2": + version: 0.6.2 + resolution: "webpack-virtual-modules@npm:0.6.2" + checksum: 7e8e1d63f35864c815420cc2f27da8561a1e028255040698a352717de0ba46d3b3faf16f06c1a1965217054c4c2894eb9af53a85451870e919b5707ce9c5822d + languageName: node + linkType: hard + "whatwg-encoding@npm:^2.0.0": version: 2.0.0 resolution: "whatwg-encoding@npm:2.0.0" @@ -8408,6 +13223,15 @@ __metadata: languageName: node linkType: hard +"whatwg-encoding@npm:^3.1.1": + version: 3.1.1 + resolution: "whatwg-encoding@npm:3.1.1" + dependencies: + iconv-lite: 0.6.3 + checksum: f75a61422421d991e4aec775645705beaf99a16a88294d68404866f65e92441698a4f5b9fa11dd609017b132d7b286c3c1534e2de5b3e800333856325b549e3c + languageName: node + linkType: hard + "whatwg-mimetype@npm:^3.0.0": version: 3.0.0 resolution: "whatwg-mimetype@npm:3.0.0" @@ -8415,6 +13239,13 @@ __metadata: languageName: node linkType: hard +"whatwg-mimetype@npm:^4.0.0": + version: 4.0.0 + resolution: "whatwg-mimetype@npm:4.0.0" + checksum: f97edd4b4ee7e46a379f3fb0e745de29fe8b839307cc774300fd49059fcdd560d38cb8fe21eae5575b8f39b022f23477cc66e40b0355c2851ce84760339cef30 + languageName: node + linkType: hard + "whatwg-url@npm:^11.0.0": version: 11.0.0 resolution: "whatwg-url@npm:11.0.0" @@ -8438,18 +13269,6 @@ __metadata: languageName: node linkType: hard -"which-collection@npm:^1.0.1": - version: 1.0.1 - resolution: "which-collection@npm:1.0.1" - dependencies: - is-map: ^2.0.1 - is-set: ^2.0.1 - is-weakmap: ^2.0.1 - is-weakset: ^2.0.1 - checksum: c815bbd163107ef9cb84f135e6f34453eaf4cca994e7ba85ddb0d27cea724c623fae2a473ceccfd5549c53cc65a5d82692de418166df3f858e1e5dc60818581c - languageName: node - linkType: hard - "which-typed-array@npm:^1.1.9": version: 1.1.9 resolution: "which-typed-array@npm:1.1.9" @@ -8486,6 +13305,17 @@ __metadata: languageName: node linkType: hard +"which@npm:^4.0.0": + version: 4.0.0 + resolution: "which@npm:4.0.0" + dependencies: + isexe: ^3.1.1 + bin: + node-which: bin/which.js + checksum: f17e84c042592c21e23c8195108cff18c64050b9efb8459589116999ea9da6dd1509e6a1bac3aeebefd137be00fabbb61b5c2bc0aa0f8526f32b58ee2f545651 + languageName: node + linkType: hard + "wide-align@npm:^1.1.5": version: 1.1.5 resolution: "wide-align@npm:1.1.5" @@ -8502,6 +13332,24 @@ __metadata: languageName: node linkType: hard +"workerpool@npm:^6.5.1": + version: 6.5.1 + resolution: "workerpool@npm:6.5.1" + checksum: f86d13f9139c3a57c5a5867e81905cd84134b499849405dec2ffe5b1acd30dabaa1809f6f6ee603a7c65e1e4325f21509db6b8398eaf202c8b8f5809e26a2e16 + languageName: node + linkType: hard + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: ^4.0.0 + string-width: ^4.1.0 + strip-ansi: ^6.0.0 + checksum: a790b846fd4505de962ba728a21aaeda189b8ee1c7568ca5e817d85930e06ef8d1689d49dbf0e881e8ef84436af3a88bc49115c2e2788d841ff1b8b5b51a608b + languageName: node + linkType: hard + "wrap-ansi@npm:^6.2.0": version: 6.2.0 resolution: "wrap-ansi@npm:6.2.0" @@ -8513,14 +13361,14 @@ __metadata: languageName: node linkType: hard -"wrap-ansi@npm:^7.0.0": - version: 7.0.0 - resolution: "wrap-ansi@npm:7.0.0" +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" dependencies: - ansi-styles: ^4.0.0 - string-width: ^4.1.0 - strip-ansi: ^6.0.0 - checksum: a790b846fd4505de962ba728a21aaeda189b8ee1c7568ca5e817d85930e06ef8d1689d49dbf0e881e8ef84436af3a88bc49115c2e2788d841ff1b8b5b51a608b + ansi-styles: ^6.1.0 + string-width: ^5.0.1 + strip-ansi: ^7.0.1 + checksum: 371733296dc2d616900ce15a0049dca0ef67597d6394c57347ba334393599e800bab03c41d4d45221b6bc967b8c453ec3ae4749eff3894202d16800fdfe0e238 languageName: node linkType: hard @@ -8531,13 +13379,13 @@ __metadata: languageName: node linkType: hard -"write-file-atomic@npm:^5.0.0": - version: 5.0.0 - resolution: "write-file-atomic@npm:5.0.0" +"write-file-atomic@npm:^4.0.2": + version: 4.0.2 + resolution: "write-file-atomic@npm:4.0.2" dependencies: imurmurhash: ^0.1.4 signal-exit: ^3.0.7 - checksum: 6ee16b195572386cb1c905f9d29808f77f4de2fd063d74a6f1ab6b566363832d8906a493b764ee715e57ab497271d5fc91642a913724960e8e845adf504a9837 + checksum: 5da60bd4eeeb935eec97ead3df6e28e5917a6bd317478e4a85a5285e8480b8ed96032bbcc6ecd07b236142a24f3ca871c924ec4a6575e623ec1b11bf8c1c253c languageName: node linkType: hard @@ -8556,6 +13404,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:^8.8.0": + version: 8.18.0 + resolution: "ws@npm:8.18.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 91d4d35bc99ff6df483bdf029b9ea4bfd7af1f16fc91231a96777a63d263e1eabf486e13a2353970efc534f9faa43bdbf9ee76525af22f4752cbc5ebda333975 + languageName: node + linkType: hard + "xml-name-validator@npm:^4.0.0": version: 4.0.0 resolution: "xml-name-validator@npm:4.0.0" @@ -8612,6 +13475,13 @@ __metadata: languageName: node linkType: hard +"yargs-parser@npm:^20.2.2, yargs-parser@npm:^20.2.9": + version: 20.2.9 + resolution: "yargs-parser@npm:20.2.9" + checksum: 8bb69015f2b0ff9e17b2c8e6bfe224ab463dd00ca211eece72a4cd8a906224d2703fb8a326d36fdd0e68701e201b2a60ed7cf81ce0fd9b3799f9fe7745977ae3 + languageName: node + linkType: hard + "yargs-parser@npm:^21.1.1": version: 21.1.1 resolution: "yargs-parser@npm:21.1.1" @@ -8619,6 +13489,33 @@ __metadata: languageName: node linkType: hard +"yargs-unparser@npm:^2.0.0": + version: 2.0.0 + resolution: "yargs-unparser@npm:2.0.0" + dependencies: + camelcase: ^6.0.0 + decamelize: ^4.0.0 + flat: ^5.0.2 + is-plain-obj: ^2.1.0 + checksum: 68f9a542c6927c3768c2f16c28f71b19008710abd6b8f8efbac6dcce26bbb68ab6503bed1d5994bdbc2df9a5c87c161110c1dfe04c6a3fe5c6ad1b0e15d9a8a3 + languageName: node + linkType: hard + +"yargs@npm:^16.2.0": + version: 16.2.0 + resolution: "yargs@npm:16.2.0" + dependencies: + cliui: ^7.0.2 + escalade: ^3.1.1 + get-caller-file: ^2.0.5 + require-directory: ^2.1.1 + string-width: ^4.2.0 + y18n: ^5.0.5 + yargs-parser: ^20.2.2 + checksum: b14afbb51e3251a204d81937c86a7e9d4bdbf9a2bcee38226c900d00f522969ab675703bee2a6f99f8e20103f608382936034e64d921b74df82b63c07c5e8f59 + languageName: node + linkType: hard + "yargs@npm:^17.3.1": version: 17.6.2 resolution: "yargs@npm:17.6.2" @@ -8634,9 +13531,66 @@ __metadata: languageName: node linkType: hard +"yargs@npm:^17.7.2": + version: 17.7.2 + resolution: "yargs@npm:17.7.2" + dependencies: + cliui: ^8.0.1 + escalade: ^3.1.1 + get-caller-file: ^2.0.5 + require-directory: ^2.1.1 + string-width: ^4.2.3 + y18n: ^5.0.5 + yargs-parser: ^21.1.1 + checksum: 73b572e863aa4a8cbef323dd911d79d193b772defd5a51aab0aca2d446655216f5002c42c5306033968193bdbf892a7a4c110b0d77954a7fdf563e653967b56a + languageName: node + linkType: hard + +"yauzl@npm:^2.10.0": + version: 2.10.0 + resolution: "yauzl@npm:2.10.0" + dependencies: + buffer-crc32: ~0.2.3 + fd-slicer: ~1.1.0 + checksum: 7f21fe0bbad6e2cb130044a5d1d0d5a0e5bf3d8d4f8c4e6ee12163ce798fee3de7388d22a7a0907f563ac5f9d40f8699a223d3d5c1718da90b0156da6904022b + languageName: node + linkType: hard + "yocto-queue@npm:^0.1.0": version: 0.1.0 resolution: "yocto-queue@npm:0.1.0" checksum: f77b3d8d00310def622123df93d4ee654fc6a0096182af8bd60679ddcdfb3474c56c6c7190817c84a2785648cdee9d721c0154eb45698c62176c322fb46fc700 languageName: node linkType: hard + +"yocto-queue@npm:^1.0.0": + version: 1.1.1 + resolution: "yocto-queue@npm:1.1.1" + checksum: f2e05b767ed3141e6372a80af9caa4715d60969227f38b1a4370d60bffe153c9c5b33a862905609afc9b375ec57cd40999810d20e5e10229a204e8bde7ef255c + languageName: node + linkType: hard + +"yoctocolors-cjs@npm:^2.1.2": + version: 2.1.2 + resolution: "yoctocolors-cjs@npm:2.1.2" + checksum: 1c474d4b30a8c130e679279c5c2c33a0d48eba9684ffa0252cc64846c121fb56c3f25457fef902edbe1e2d7a7872130073a9fc8e795299d75e13fa3f5f548f1b + languageName: node + linkType: hard + +"yoctocolors@npm:^2.0.0": + version: 2.1.1 + resolution: "yoctocolors@npm:2.1.1" + checksum: 563fbec88bce9716d1044bc98c96c329e1d7a7c503e6f1af68f1ff914adc3ba55ce953c871395e2efecad329f85f1632f51a99c362032940321ff80c42a6f74d + languageName: node + linkType: hard + +"zip-stream@npm:^6.0.1": + version: 6.0.1 + resolution: "zip-stream@npm:6.0.1" + dependencies: + archiver-utils: ^5.0.0 + compress-commons: ^6.0.2 + readable-stream: ^4.0.0 + checksum: aa5abd6a89590eadeba040afbc375f53337f12637e5e98330012a12d9886cde7a3ccc28bd91aafab50576035bbb1de39a9a316eecf2411c8b9009c9f94f0db27 + languageName: node + linkType: hard