├── lib
├── vite-env.d.ts
├── constants.ts
├── hooks
│ ├── use-subscribe.ts
│ ├── use-midi-message.ts
│ ├── use-midi-clock.ts
│ ├── use-midi-outputs.ts
│ ├── use-midi-inputs.ts
│ ├── use-midi-note.ts
│ ├── use-midi-controls.ts
│ ├── use-midi-notes.ts
│ ├── use-midi-control.ts
│ └── use-midi-output.ts
├── main.ts
├── types.ts
├── midi-emitter.ts
├── reducer.ts
└── midi-provider.tsx
├── src
├── vite-env.d.ts
├── .npmignore
├── main.tsx
├── App.css
├── MIDIInterfaceSelector.tsx
└── App.tsx
├── tsconfig-build.json
├── .gitignore
├── tsconfig.node.json
├── index.html
├── vite.config.ts
├── tsconfig.json
├── package.json
├── README.md
└── pnpm-lock.yaml
/lib/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/tsconfig-build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "include": ["lib"]
4 | }
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | *ideas.txt
3 | node_modules
4 | *.local
5 | *.log
6 | /.vscode/
7 | .DS_Store
--------------------------------------------------------------------------------
/lib/constants.ts:
--------------------------------------------------------------------------------
1 | export const MIDIConstants = {
2 | noteOn: 0x90,
3 | noteOff: 0x80,
4 | cc: 0xb0,
5 | clock: 0xf0,
6 | tick: 0x08,
7 | play: 0x0a,
8 | stop: 0x0c,
9 | }
10 |
--------------------------------------------------------------------------------
/src/.npmignore:
--------------------------------------------------------------------------------
1 | lib
2 | src
3 | *ideas.txt
4 | node_modules
5 | *.local
6 | *.log
7 | /.vscode/
8 | .DS_Store
9 | tsconfig-build.json
10 | tsconfig.json
11 | tsconfig.node.json
12 | vite.config.ts
13 | index.html
--------------------------------------------------------------------------------
/src/main.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import App from './App'
4 |
5 | ReactDOM.createRoot(document.getElementById('root')!).render(
6 |
7 |
8 |
9 | )
10 |
--------------------------------------------------------------------------------
/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "skipLibCheck": true,
5 | "module": "ESNext",
6 | "moduleResolution": "bundler",
7 | "allowSyntheticDefaultImports": true
8 | },
9 | "include": ["vite.config.ts"]
10 | }
11 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + React + TS
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/lib/hooks/use-subscribe.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useContext } from 'react'
2 | import { EventName } from '../types'
3 | import { MIDIContext } from '../midi-provider'
4 |
5 | export const useSubscribe = (event: EventName, cb: (args: any) => void) => {
6 | const { emitter } = useContext(MIDIContext)
7 | useEffect(() => {
8 | const id = emitter.subscribe(event, cb)
9 | return () => {
10 | emitter.unsubscribe('note', id)
11 | }
12 | }, [emitter, cb])
13 | }
14 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import { resolve } from 'path'
3 | import react from '@vitejs/plugin-react-swc'
4 | import dts from 'vite-plugin-dts'
5 |
6 | // https://vitejs.dev/config/
7 | export default defineConfig({
8 | plugins: [react(), dts({ include: ['lib'] })],
9 | build: {
10 | lib: {
11 | entry: resolve(__dirname, 'lib/main.ts'),
12 | fileName: 'main',
13 | formats: ['es'],
14 | },
15 | rollupOptions: {
16 | external: ['react', 'react/jsx-runtime'],
17 | },
18 | },
19 | })
20 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | *,
2 | body {
3 | background-color: #111111;
4 | color: white;
5 | font-family: monospace;
6 | }
7 |
8 | .section {
9 | margin-bottom: 4rem;
10 | /* background: b; */
11 | }
12 | .section-title {
13 | font-size: 16px;
14 | }
15 | .subsection {
16 | margin-left: 1rem;
17 | margin-top: 1rem;
18 | }
19 | .subsection.tall {
20 | height: 200px;
21 | }
22 | .subsection-title {
23 | color: rgb(83, 218, 146);
24 | }
25 | .subsection-description {
26 | margin-bottom: 0.5rem;
27 | color: #5a55a0;
28 | }
29 | .value {
30 | color: rgb(222, 114, 255);
31 | }
32 |
--------------------------------------------------------------------------------
/lib/main.ts:
--------------------------------------------------------------------------------
1 | export { MIDIProvider } from './midi-provider'
2 | export { useMIDIOutput } from './hooks/use-midi-output'
3 | export { useMIDIOutputs } from './hooks/use-midi-outputs'
4 | export { useMIDIInputs } from './hooks/use-midi-inputs'
5 | export { useMIDIControl } from './hooks/use-midi-control'
6 | export { useMIDIMessage } from './hooks/use-midi-message'
7 | export { useMIDIControls } from './hooks/use-midi-controls'
8 | export { useMIDINote } from './hooks/use-midi-note'
9 | export { useMIDINotes } from './hooks/use-midi-notes'
10 | // export { useMIDIClock } from './hooks/use-midi-clock';
11 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2020",
4 | "useDefineForClassFields": true,
5 | "lib": ["ES2020", "DOM", "DOM.Iterable"],
6 | "module": "ESNext",
7 | "skipLibCheck": true,
8 |
9 | /* Bundler mode */
10 | "moduleResolution": "bundler",
11 | "allowImportingTsExtensions": true,
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "noEmit": true,
15 | "jsx": "react-jsx",
16 |
17 | /* Linting */
18 | "strict": true,
19 | "noUnusedLocals": true,
20 | "noUnusedParameters": true,
21 | "noFallthroughCasesInSwitch": true
22 | },
23 | "include": ["src", "lib"],
24 | "references": [{ "path": "./tsconfig.node.json" }]
25 | }
26 |
--------------------------------------------------------------------------------
/lib/hooks/use-midi-message.ts:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 | import { MIDIMessage } from '../types'
3 | import { useSubscribe } from './use-subscribe'
4 |
5 | /**
6 | * Custom hook to subscribe to all MIDI messages.
7 | *
8 | * This hook listens for any MIDI messages and updates its state with the latest message received.
9 | * It is useful for components that need to react to or display information based on incoming MIDI messages.
10 | *
11 | * @returns {MIDIMessage | undefined} - The latest MIDI message received or `undefined` if no message has been received yet.
12 | *
13 | * @example
14 | * // To use this hook in a component to display the latest MIDI message
15 | * const midiMessage = useMIDIMessage();
16 | * if (midiMessage) {
17 | * console.log(`MIDI message received:`, midiMessage);
18 | * }
19 | */
20 |
21 | export const useMIDIMessage = () => {
22 | const [message, setMessage] = useState()
23 | const handleMessage = (message: MIDIMessage) => {
24 | setMessage(message)
25 | }
26 | useSubscribe('all', handleMessage)
27 |
28 | return message
29 | }
30 |
--------------------------------------------------------------------------------
/src/MIDIInterfaceSelector.tsx:
--------------------------------------------------------------------------------
1 | import { useMIDIInputs, useMIDIOutputs } from '../lib/main'
2 |
3 | export const MIDIInterfaceSelector = () => {
4 | const { inputs, selectedInputId, selectInput } = useMIDIInputs()
5 | const { outputs, selectedOutputId, selectOutput } = useMIDIOutputs()
6 | return (
7 |
8 |
MIDI Interface
9 |
10 |
Interface Selection
11 |
12 | Lists all inputs/outputs, switching when clicked.
13 |
14 |
15 | {inputs.map(({ id, name }) => (
16 |
19 | ))}
20 |
21 |
22 | {outputs.map(({ id, name }) => (
23 |
26 | ))}
27 |
28 |
29 |
30 | )
31 | }
32 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@react-midi/hooks",
3 | "version": "2.0.1",
4 | "type": "module",
5 | "main": "dist/main.js",
6 | "types": "dist/main.d.ts",
7 | "files": [
8 | "dist"
9 | ],
10 | "scripts": {
11 | "dev": "vite",
12 | "build": "tsc --p ./tsconfig-build.json && vite build",
13 | "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
14 | "preview": "vite preview",
15 | "prepublishOnly": "npm run build"
16 | },
17 | "peerDependencies": {
18 | "react": "^18.2.0"
19 | },
20 | "devDependencies": {
21 | "@types/react": "^18.2.15",
22 | "@types/react-dom": "^18.2.7",
23 | "@types/uniqid": "^5.3.2",
24 | "@types/webmidi": "^2.0.8",
25 | "@typescript-eslint/eslint-plugin": "^6.0.0",
26 | "@typescript-eslint/parser": "^6.0.0",
27 | "@vitejs/plugin-react-swc": "^3.3.2",
28 | "eslint": "^8.45.0",
29 | "eslint-plugin-react-hooks": "^4.6.0",
30 | "eslint-plugin-react-refresh": "^0.4.3",
31 | "react": "^18.2.0",
32 | "react-dom": "^18.2.0",
33 | "typescript": "^5.0.2",
34 | "vite": "^4.4.5",
35 | "vite-plugin-dts": "^3.6.0"
36 | },
37 | "dependencies": {
38 | "uniqid": "^5.4.0"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/lib/hooks/use-midi-clock.ts:
--------------------------------------------------------------------------------
1 | import { useState, useCallback } from 'react'
2 | import { MIDIConstants } from '../constants'
3 | import { useSubscribe } from './use-subscribe'
4 | type Args = {
5 | division: number
6 | }
7 |
8 | // TODO: Test and complete. This is a work in progress.
9 | export const useMIDIClock = ({ division = 1 }: Args) => {
10 | const [step, setStep] = useState(0)
11 | const [isPlaying, setIsPlaying] = useState(false)
12 | const handleClockMessage = useCallback(() => {
13 | // Keep track of count through closure. Is there a better way?
14 | let steps = 0
15 | return (type: number) => {
16 | switch (type) {
17 | case MIDIConstants.tick:
18 | steps++
19 | if (division === 1) setStep(steps)
20 | else if (steps % division === 0) setStep(Math.floor(steps / division))
21 | break
22 | case MIDIConstants.play:
23 | setIsPlaying(true)
24 | break
25 | case MIDIConstants.stop:
26 | steps = 0
27 | setIsPlaying(false)
28 | setStep(0)
29 | break
30 | default:
31 | break
32 | }
33 | }
34 | }, [division, setStep, setIsPlaying])
35 | useSubscribe('clock', handleClockMessage())
36 | return { step, isPlaying }
37 | }
38 |
--------------------------------------------------------------------------------
/lib/types.ts:
--------------------------------------------------------------------------------
1 | export type Connection = {
2 | id: string
3 | name: string
4 | manufacturer: string
5 | }
6 |
7 | export type Input = {
8 | onmidimessage: ((message: MIDIMessage) => void) | null
9 | } & Connection
10 |
11 | export type Output = {
12 | send: (message: number[], timestamp?: number) => void
13 | } & Connection
14 |
15 | export type InputsReturnValue = {
16 | input: Input | undefined
17 | inputs: Input[]
18 | selectInput: (inputId: string) => void
19 | selectedInputId: string | null
20 | }
21 |
22 | export type MIDINoteFilter = {
23 | note?: number // allow multiple?
24 | channel?: number
25 | // min/max velocity?
26 | }
27 |
28 | export type MIDIControlFilter = {
29 | cc?: number // allow multiple?
30 | channel?: number
31 | // min/max value?
32 | }
33 |
34 | export type MIDIMessage = {
35 | data: number[]
36 | }
37 |
38 | export type Message = {
39 | target: number // note or control
40 | value: number // velocity or control value
41 | channel: number
42 | }
43 |
44 | export type NoteMessage = Message & {
45 | on: boolean
46 | }
47 |
48 | export type MIDINote = {
49 | note: number
50 | velocity: number
51 | channel: number
52 | on: boolean
53 | }
54 |
55 | export type MIDIControl = {
56 | control: number
57 | value: number
58 | channel: number
59 | }
60 |
61 | export type EventName = 'all' | 'note' | 'clock' | 'control'
62 |
--------------------------------------------------------------------------------
/lib/hooks/use-midi-outputs.ts:
--------------------------------------------------------------------------------
1 | import { useCallback, useContext } from 'react'
2 | import { MIDIContext } from '../midi-provider'
3 | import { outputSelected } from '../reducer'
4 |
5 | /**
6 | * Hook to access and manage MIDI output devices within a MIDIContext.
7 | *
8 | * This hook provides an interface to interact with available MIDI outputs and select a specific output device.
9 | * It leverages the MIDIContext to maintain and update the state related to MIDI outputs, including the current selection.
10 | *
11 | * @returns {Object} An object containing:
12 | * - output: The currently selected MIDI output device, or `undefined` if no device is selected.
13 | * - outputs: An array of all available MIDI output devices.
14 | * - selectOutput: A function to select an output device by its ID.
15 | * - selectedOutputId: The ID of the currently selected output device.
16 | *
17 | * @example
18 | * // Example of using this hook in a component to list MIDI outputs and allow selection.
19 | * const { output, outputs, selectOutput, selectedOutputId } = useMIDIOutputs();
20 | *
21 | * // To select a MIDI output by ID, for example when a user clicks on an output device in the UI
22 | * selectOutput('desired-output-device-id');
23 | */
24 |
25 | export const useMIDIOutputs = () => {
26 | const { state, dispatch } = useContext(MIDIContext)
27 | const { outputs, selectedOutputId } = state
28 | const selectOutput = useCallback(
29 | (outputId: string) => {
30 | dispatch(outputSelected(outputId))
31 | },
32 | [dispatch]
33 | )
34 | return {
35 | output: outputs.find(({ id }) => id === selectedOutputId),
36 | outputs,
37 | selectOutput,
38 | selectedOutputId,
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/lib/hooks/use-midi-inputs.ts:
--------------------------------------------------------------------------------
1 | import { useCallback, useContext } from 'react'
2 | import { MIDIContext } from '../midi-provider'
3 | import { inputSelected } from '../reducer'
4 | import { InputsReturnValue } from '../types'
5 |
6 | /**
7 | * Hook to interact with MIDI input devices within a MIDIContext.
8 | *
9 | * This hook provides functionality to access the list of available MIDI input devices,
10 | * the currently selected MIDI input device, and a method to select a MIDI input device by its ID.
11 | * It leverages a MIDIContext to manage state and dispatch actions related to MIDI input selection.
12 | *
13 | * @returns {InputsReturnValue} An object containing:
14 | * - input: The currently selected MIDI input device based on the `selectedInputId`, or `undefined` if no such device is selected.
15 | * - inputs: An array of all detected MIDI input devices.
16 | * - selectInput: A function to select a MIDI input device by its ID. This updates the context state to reflect the selected device.
17 | * - selectedInputId: The ID of the currently selected MIDI input device, or `undefined` if no device is selected.
18 | *
19 | * @example
20 | * // Example of using this hook in a component to list MIDI inputs and allow selection.
21 | * const { input, inputs, selectInput, selectedInputId } = useMIDIInputs();
22 | *
23 | * // To select a MIDI input by ID, for example when a user clicks on an input device in the UI
24 | * selectInput('desired-input-device-id');
25 | */
26 |
27 | export const useMIDIInputs = (): InputsReturnValue => {
28 | const { state, dispatch } = useContext(MIDIContext)
29 | const { inputs, selectedInputId } = state
30 | const selectInput = useCallback(
31 | (inputId: string) => {
32 | dispatch(inputSelected(inputId))
33 | },
34 | [dispatch]
35 | )
36 | return {
37 | input: inputs.find(({ id }) => id === selectedInputId),
38 | inputs,
39 | selectInput,
40 | selectedInputId,
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/lib/hooks/use-midi-note.ts:
--------------------------------------------------------------------------------
1 | import { useState, useCallback } from 'react'
2 | import { MIDINote, MIDINoteFilter, NoteMessage } from '../types'
3 | import { useSubscribe } from './use-subscribe'
4 |
5 | /**
6 | * Hook to subscribe to MIDI note messages that match specified filters.
7 | *
8 | * This hook allows you to listen for MIDI note messages and updates its state
9 | * with the message details if the message matches the specified note and channel filters.
10 | * If no filters are provided, it will update the state with every note message received.
11 | *
12 | * @param {MIDINoteFilter} [filters={}] - The filters to apply to incoming MIDI note messages.
13 | * @param {number} [filters.note] - The MIDI note number to filter messages by.
14 | * @param {number} [filters.channel] - The MIDI channel number to filter messages by.
15 | *
16 | * @returns {MIDINote | undefined} - The latest MIDI note message that matches the filters,
17 | * or `undefined` if no message has matched the filters yet.
18 | *
19 | * @example
20 | * // To use this hook to listen for note C3 (MIDI note number 60) on channel 1
21 | * const midiNote = useMIDINote({ note: 60, channel: 1 });
22 | * if (midiNote) {
23 | * console.log(`Note ${midiNote.note} with velocity ${midiNote.velocity} received on channel ${midiNote.channel}`);
24 | * }
25 | */
26 |
27 | export const useMIDINote = ({
28 | note: noteFilter,
29 | channel: channelFilter,
30 | }: MIDINoteFilter = {}): MIDINote | undefined => {
31 | const [value, setValue] = useState()
32 |
33 | const handleNote = useCallback(
34 | (message: NoteMessage) => {
35 | const { target: note, value: velocity, on, channel } = message
36 | if (
37 | (!noteFilter || noteFilter === note) &&
38 | (!channelFilter || channelFilter === channel)
39 | ) {
40 | setValue({ note, on, velocity, channel })
41 | }
42 | },
43 | [noteFilter, channelFilter, setValue]
44 | )
45 | useSubscribe('note', handleNote)
46 |
47 | return value
48 | }
49 |
--------------------------------------------------------------------------------
/lib/hooks/use-midi-controls.ts:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from 'react'
2 | import { MIDIControlFilter } from '../types'
3 | import { useMIDIControl } from './use-midi-control'
4 |
5 | /**
6 | * Hook to manage state for an array of MIDI control numbers, filtered by specific criteria.
7 | *
8 | * This hook listens for MIDI control change messages that match a provided filter,
9 | * and maintains an array of values corresponding to a predefined set of control numbers (`controls`). Each control's
10 | * value in the array is updated when a matching control change message is received. This is useful for components
11 | * that need to keep track of and react to changes in multiple MIDI control values simultaneously.
12 | *
13 | * @param {number[]} controls - An array of MIDI control numbers to monitor.
14 | * @param {Exclude} [filter={}] - An object specifying additional filters for MIDI control change messages.
15 | * Excludes the 'cc' property as that is specified by the first argument.
16 | *
17 | * @returns {number[]} An array of control values corresponding to the `controls` array. Each element in the array
18 | * represents the latest value for the control number at the same index in the `controls` input array.
19 | *
20 | * @example
21 | * // To use this hook to monitor control changes for MIDI controls 7 and 10 on channel 1
22 | * const controlValues = useMIDIControls([7, 10], { channel: 1 });
23 | * // controlValues will be an array of two numbers, initially [0, 0], updated with the latest values for controls 7 and 10.
24 | */
25 |
26 | export const useMIDIControls = (
27 | controls: number[],
28 | filter: Exclude = {}
29 | ) => {
30 | const [values, setValues] = useState(controls.map(() => 0))
31 | const cc = useMIDIControl(filter)
32 |
33 | // TODO: Get this all fixed up
34 | useEffect(() => {
35 | if (cc) {
36 | const targetIndex = controls.indexOf(cc.control)
37 | if (targetIndex > -1)
38 | setValues(values.map((v, i) => (i === targetIndex ? cc.value : v)))
39 | }
40 | }, [cc])
41 |
42 | return values
43 | }
44 |
--------------------------------------------------------------------------------
/lib/hooks/use-midi-notes.ts:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from 'react'
2 | import { MIDINoteFilter, MIDINote } from '../types'
3 | import { useMIDINote } from './use-midi-note'
4 |
5 | /**
6 | * Hook to manage an array of MIDI note messages that match a given filter.
7 | *
8 | * This hook subscribes to MIDI note messages that satisfy specified filtering criteria (such as note number and channel).
9 | * It maintains an array of active (i.e., currently pressed) MIDI notes. When a note-on message is received, the note is
10 | * added to the array. When a note-off message for an active note is received, that note is removed from the array.
11 | * This allows for tracking of currently active MIDI notes that match the filter.
12 | *
13 | * @param {MIDINoteFilter} [filter={}] - An object specifying the filtering criteria for MIDI note messages.
14 | * This can include properties like `note` (to filter by MIDI note number) and `channel` (to filter by MIDI channel).
15 | *
16 | * @returns {MIDINote[]} An array of MIDI notes that are currently active (i.e., note-on messages have been received,
17 | * but corresponding note-off messages have not yet been received) and match the specified filter. Each
18 | * element in the array is an object representing a MIDI note message, including properties like the note number,
19 | * velocity, and channel.
20 | *
21 | * @example
22 | * // To use this hook to monitor active notes for MIDI channel 1
23 | * const activeNotes = useMIDINotes({ channel: 1 });
24 | * // activeNotes will be an array of objects, each representing an active MIDI note on channel 1.
25 | */
26 |
27 | export const useMIDINotes = (filter: MIDINoteFilter = {}) => {
28 | const [notes, setNotes] = useState([])
29 | const value = useMIDINote(filter)
30 | useEffect(() => {
31 | if (value) {
32 | if (value === notes[notes.length - 1]) {
33 | return
34 | }
35 | if (value.on) {
36 | setNotes([...notes, value])
37 | } else {
38 | setNotes(notes.filter((n) => n.note !== value.note))
39 | }
40 | }
41 | }, [value])
42 | return notes
43 | }
44 |
--------------------------------------------------------------------------------
/lib/midi-emitter.ts:
--------------------------------------------------------------------------------
1 | import uniqid from 'uniqid'
2 | import { MIDIMessage, Message, NoteMessage, EventName } from './types'
3 | import { MIDIConstants } from './constants'
4 |
5 | type Subscriptions = {
6 | all: { [id: string]: (args: MIDIMessage) => void }
7 | note: { [id: string]: (args: NoteMessage) => void }
8 | clock: { [id: string]: (args: number) => void }
9 | control: { [id: string]: (args: Message) => void }
10 | }
11 |
12 | export class MIDIEmitter {
13 | private subscriptions: Subscriptions = {
14 | all: {},
15 | note: {},
16 | clock: {},
17 | control: {}, // Consider splitting this up into things like 'control:36'
18 | }
19 |
20 | subscribe(eventName: EventName, callback: (args: any) => void) {
21 | const id = uniqid()
22 | this.subscriptions[eventName][id] = callback
23 | return id
24 | }
25 |
26 | unsubscribe(eventName: EventName, id: string) {
27 | delete this.subscriptions[eventName][id]
28 | }
29 |
30 | onMIDIMessage(message: MIDIMessage) {
31 | const action = message.data[0] & 0xf0 // Mask channel/least significant bits;
32 | const leastSig = message.data[0] & 0x0f // Mask action bits;
33 | const channel = leastSig + 1
34 | const { all, note, control, clock } = this.subscriptions
35 | for (const key in all) {
36 | all[key](message)
37 | }
38 |
39 | switch (action) {
40 | case MIDIConstants.cc:
41 | for (const key in control) {
42 | control[key]({
43 | target: message.data[1],
44 | value: message.data[2],
45 | channel,
46 | }) // (value, control, channel)
47 | }
48 | break
49 | case MIDIConstants.noteOn:
50 | case MIDIConstants.noteOff:
51 | for (const key in note) {
52 | note[key]({
53 | target: message.data[1], // note
54 | value: message.data[2], // velocity
55 | channel,
56 | on: action === MIDIConstants.noteOn,
57 | })
58 | }
59 | break
60 | case MIDIConstants.clock: // Transport/Clock Message
61 | for (const key in clock) {
62 | clock[key](leastSig) // (type)
63 | }
64 | break
65 | default:
66 | break
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/lib/hooks/use-midi-control.ts:
--------------------------------------------------------------------------------
1 | import { useState, useCallback } from 'react'
2 | import { Message, MIDIControlFilter, MIDIControl } from '../types'
3 | import { useSubscribe } from './use-subscribe'
4 |
5 | // Before a control message is sent, we do not have a default value for the control.
6 | type MIDIControlState = MIDIControl & { value?: number }
7 |
8 | /**
9 | * Hook to subscribe to MIDI control change messages based on specified filters.
10 | *
11 | * This hook listens for MIDI control change (CC) messages and updates its state
12 | * with the details of the message if it matches the specified control number and channel filters.
13 | * If no filters are provided, it will update the state with every control change message received.
14 | * This can be useful for components that need to react to specific control change messages.
15 | *
16 | * @param {Object} [filters={}] - The filters to apply to incoming MIDI control change messages.
17 | * @param {number} [filters.cc] - The MIDI control change number to filter messages by.
18 | * @param {number} [filters.channel] - The MIDI channel number to filter messages by.
19 | *
20 | * @returns {MIDIControlState | undefined} - The latest MIDI control change message that matches the filters,
21 | * or `undefined` if no message has matched the filters yet.
22 | *
23 | * @example
24 | * // To use this hook to listen for control change number 7 on channel 1
25 | * const midiControl = useMIDIControl({ cc: 7, channel: 1 });
26 | * if (midiControl) {
27 | * console.log(`Control change ${midiControl.control} with value ${midiControl.value} received on channel ${midiControl.channel}`);
28 | * }
29 | */
30 |
31 | export const useMIDIControl = ({
32 | cc: controlFilter,
33 | channel: channelFilter,
34 | }: MIDIControlFilter = {}) => {
35 | const [value, setValue] = useState(undefined)
36 | const handleCC = useCallback(
37 | (message: Message) => {
38 | const { target, value, channel } = message
39 | if (
40 | (!controlFilter || controlFilter === target) &&
41 | (!channelFilter || channelFilter === channel)
42 | ) {
43 | setValue({ control: target, value, channel })
44 | }
45 | },
46 | [controlFilter, channelFilter, setValue]
47 | )
48 | useSubscribe('control', handleCC)
49 | return value
50 | }
51 |
--------------------------------------------------------------------------------
/lib/reducer.ts:
--------------------------------------------------------------------------------
1 | import { Input, Output } from './types'
2 |
3 | export type ReducerState = {
4 | inputs: Input[]
5 | outputs: Output[]
6 | selectedInputId: string | null
7 | selectedOutputId: string | null
8 | }
9 |
10 | enum ActionTypes {
11 | accessReceived = 'AccessReceived',
12 | inputSelected = 'InputSelected',
13 | outputSelected = 'OutputSelected',
14 | }
15 |
16 | export const defaultState: ReducerState = {
17 | inputs: [],
18 | outputs: [],
19 | selectedInputId: null,
20 | selectedOutputId: null,
21 | }
22 |
23 | export const reducer = (
24 | state: ReducerState = defaultState,
25 | action: { type: string; payload?: any }
26 | ): ReducerState => {
27 | const { type, payload } = action
28 | switch (type) {
29 | case ActionTypes.accessReceived:
30 | // If selectedInputId is defined and the id still exists in the new connections, let it remain
31 | const inputExists = payload.inputs.some(
32 | (input: Input) => input.id === state.selectedInputId
33 | )
34 | const outputExists = payload.outputs.find(
35 | (output: Input) => output.id === state.selectedOutputId
36 | )
37 | return {
38 | ...state,
39 | inputs: payload.inputs,
40 | outputs: payload.outputs,
41 | selectedInputId: inputExists
42 | ? state.selectedInputId
43 | : payload.inputs.length
44 | ? payload.inputs[0].id
45 | : null,
46 | selectedOutputId: outputExists
47 | ? state.selectedOutputId
48 | : payload.outputs.length
49 | ? payload.outputs[0].id
50 | : null,
51 | }
52 | case ActionTypes.inputSelected:
53 | return {
54 | ...state,
55 | selectedInputId: payload.inputId,
56 | }
57 | case ActionTypes.outputSelected:
58 | return {
59 | ...state,
60 | selectedOutputId: payload.outputId,
61 | }
62 | default:
63 | return state
64 | }
65 | }
66 |
67 | export const accessReceived = (access: WebMidi.MIDIAccess) => ({
68 | type: ActionTypes.accessReceived,
69 | payload: {
70 | inputs: Array.from(access.inputs.values()),
71 | outputs: Array.from(access.outputs.values()),
72 | },
73 | })
74 |
75 | export const inputSelected = (inputId: string) => ({
76 | type: ActionTypes.inputSelected,
77 | payload: { inputId },
78 | })
79 |
80 | export const outputSelected = (outputId: string) => ({
81 | type: ActionTypes.outputSelected,
82 | payload: { outputId },
83 | })
84 |
--------------------------------------------------------------------------------
/lib/midi-provider.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useReducer, useRef } from 'react'
2 | import { MIDIEmitter } from './midi-emitter'
3 | import { reducer, accessReceived, defaultState, ReducerState } from './reducer'
4 |
5 | // TODO Don't expose the whole midi emitter, just subscribe and unsubscribe for now.
6 | export const MIDIContext = React.createContext<{
7 | state: ReducerState
8 | dispatch: React.Dispatch<{
9 | type: string
10 | payload?: any
11 | }>
12 | emitter: MIDIEmitter
13 | }>({ state: defaultState, dispatch: () => null, emitter: new MIDIEmitter() })
14 |
15 | type Props = {
16 | children?: React.ReactNode
17 | }
18 |
19 | /**
20 | * Provides a MIDI context for its child components, managing MIDI access, inputs, and state changes.
21 | *
22 | * This component encapsulates MIDI initialization and state management logic, leveraging the Web MIDI API.
23 | * It listens for MIDI access and input changes, updating the context state accordingly. This state is then
24 | * accessible to any child components through the MIDIContext. It also sets up an emitter for MIDI messages,
25 | * allowing child components to subscribe to MIDI message events.
26 | *
27 | * @param {Object} props - The component props.
28 | * @param {React.ReactNode} props.children - Child components that will have access to the MIDIContext.
29 | *
30 | * @example
31 | * // Wrap your application or component tree with MIDIProvider to provide MIDI context.
32 | *
33 | *
34 | *
35 | */
36 |
37 | export const MIDIProvider = ({ children }: Props) => {
38 | const emitter = useRef(new MIDIEmitter())
39 | const [state, dispatch] = useReducer(reducer, defaultState)
40 | const { inputs, selectedInputId } = state
41 |
42 | useEffect(() => {
43 | if (Boolean(navigator?.requestMIDIAccess)) {
44 | navigator.requestMIDIAccess().then((access: WebMidi.MIDIAccess) => {
45 | dispatch(accessReceived(access))
46 | access.onstatechange = () => {
47 | dispatch(accessReceived(access))
48 | }
49 | })
50 | }
51 | }, [dispatch])
52 |
53 | useEffect(() => {
54 | const selectedInput = inputs.find((i) => i.id === selectedInputId)
55 | if (selectedInput) {
56 | selectedInput.onmidimessage = emitter.current.onMIDIMessage.bind(
57 | emitter.current
58 | )
59 | return () => (selectedInput.onmidimessage = null)
60 | }
61 | return () => {}
62 | }, [inputs, selectedInputId])
63 |
64 | return (
65 |
66 | {children}
67 |
68 | )
69 | }
70 |
--------------------------------------------------------------------------------
/lib/hooks/use-midi-output.ts:
--------------------------------------------------------------------------------
1 | import { MIDIConstants } from '../constants'
2 | import { useMIDIOutputs } from './use-midi-outputs'
3 |
4 | type SingleNote = number
5 | type MultipleNotes = number[]
6 | export type MultipleNotesWithOptions = {
7 | note: number
8 | velocity?: number
9 | channel?: number
10 | }[]
11 |
12 | type NoteInput = SingleNote | MultipleNotes | MultipleNotesWithOptions
13 |
14 | type NoteOptions = {
15 | velocity?: number
16 | channel?: number
17 | }
18 |
19 | /**
20 | * Hook to interact with a MIDI output device.
21 | *
22 | * This hook provides methods to send MIDI messages (note on, note off, and control change) to the selected MIDI output.
23 | * It simplifies the process of sending MIDI messages by abstracting the details of constructing MIDI message arrays.
24 | *
25 | * @returns {Object} An object containing the methods to interact with the MIDI output:
26 | * - noteOn: Function to send a 'note on' message for one or more notes.
27 | * - noteOff: Function to send a 'note off' message for one or more notes.
28 | * - cc: Function to send a control change message.
29 | *
30 | * @example
31 | * // To use this hook in a component to send a 'note on' and 'note off' message
32 | * const { noteOn, noteOff, cc } = useMIDIOutput();
33 | * noteOn(60, { velocity: 127, channel: 1 }); // Send 'note on' for note 60 with velocity 127 on channel 1
34 | * noteOff(60, { channel: 1 }); // Send 'note off' for note 60 on channel 1
35 | * cc(64, 127, 1); // Send control change message with control number 64, value 127, on channel 1
36 | */
37 |
38 | export const useMIDIOutput = () => {
39 | const { output } = useMIDIOutputs()
40 | if (!output) return {}
41 |
42 | const noteOn = (noteInput: NoteInput, options?: NoteOptions) => {
43 | const messages = getNoteMessages({
44 | type: MIDIConstants.noteOn,
45 | noteInput,
46 | ...options,
47 | })
48 | output.send(messages)
49 | }
50 |
51 | const noteOff = (noteInput: NoteInput, options?: NoteOptions) => {
52 | const messages = getNoteMessages({
53 | type: MIDIConstants.noteOff,
54 | noteInput,
55 | ...options,
56 | })
57 | output.send(messages)
58 | }
59 |
60 | const cc = (value: number, control = 0x14, channel = 1) => {
61 | const ccAndChannel = MIDIConstants.cc | getChannel(channel)
62 | output.send([ccAndChannel, control, value])
63 | }
64 |
65 | return { noteOn, noteOff, cc }
66 | }
67 |
68 | type GetNoteMessagesArgs = { type: number; noteInput: NoteInput } & NoteOptions
69 | const getNoteMessages = ({
70 | type,
71 | noteInput,
72 | velocity = 127,
73 | channel = 1,
74 | }: GetNoteMessagesArgs) => {
75 | const defaultChannelData = type | getChannel(channel)
76 | if (typeof noteInput === 'number') {
77 | return [defaultChannelData, noteInput, velocity]
78 | } else {
79 | return noteInput.reduce((messages, note) => {
80 | if (typeof note === 'number') {
81 | messages.push(defaultChannelData, note, velocity)
82 | } else {
83 | messages.push(
84 | note.channel ? type | getChannel(note.channel) : defaultChannelData,
85 | note.note,
86 | note.velocity ?? velocity
87 | )
88 | }
89 | return messages
90 | }, [] as number[])
91 | }
92 | }
93 |
94 | const getChannel = (channel: number) => {
95 | if (channel < 1 || channel > 16) return 0 //Channel 1
96 | return channel - 1
97 | }
98 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # @react-midi/hooks
2 |
3 | This package provides hooks for building MIDI-capable React applications and components.
4 |
5 | ```
6 | npm install --save @react-midi/hooks
7 | ```
8 |
9 | ## ``
10 |
11 | The `MIDIProvider` component serves as the cornerstone of our MIDI integration, enabling seamless interaction with MIDI devices directly within your React application. By leveraging the Web MIDI API, `MIDIProvider` offers a comprehensive solution for managing MIDI connections, inputs, outputs, and real-time MIDI events, all within a reactively designed context.
12 |
13 | `MIDIProvider` is a prerequisite for utilizing any of the other MIDI-related hooks within our library, as they depend on the context it establishes to function correctly.
14 |
15 | ### Getting Started:
16 |
17 | To begin working with `@react-midi/hooks`, wrap your component tree with `MIDIProvider`:
18 |
19 | ```ts
20 | import { MIDIProvider } from '@react-midi/hooks'
21 |
22 | function App() {
23 | return (
24 |
25 |
26 |
27 | )
28 | }
29 | ```
30 |
31 | ## `useMIDIInputs()`:
32 |
33 | The `useMIDIInputs` hook is designed to simplify the process of accessing and managing MIDI input devices. It provides an interface for obtaining the list of available MIDI inputs, identifying the currently selected input device, and selecting an input device by its ID.
34 |
35 | ```ts
36 | const { input, inputs, selectInput, selectedInputId } = useMIDIInputs()
37 |
38 | // Example: Select a MIDI input by ID
39 | selectInput('desired-input-device-id')
40 | ```
41 |
42 | ## `useMIDIOutputs()`:
43 |
44 | The `useMIDIOutputs` hook is almost the exact same as `useMIDIInputs`, but handles MIDI outputs instead. It provides an interface for obtaining the list of available MIDI outputs, identifying the currently selected output device, and selecting an output device by its ID.
45 |
46 | ```ts
47 | const { output, outputs, selectOutput, selectedOutputId } = useMIDIOutputs()
48 |
49 | // Example: Select a MIDI output by ID
50 | selectInput('desired-output-device-id')
51 | ```
52 |
53 | ## `useMIDIOutput()`:
54 |
55 | The `useMIDIOutput` hook provides methods to send MIDI messages (note on, note off, and control change) to the selected MIDI output.
56 | It simplifies the process of sending MIDI messages by abstracting the details of constructing MIDI message arrays.
57 |
58 | ```ts
59 | // To use this hook in a component to send a 'note on' and 'note off' message
60 | const { noteOn, noteOff, cc } = useMIDIOutput()
61 | noteOn(60, { velocity: 127, channel: 1 }) // Send 'note on' for note 60 with velocity 127 on channel 1
62 | noteOff(60, { channel: 1 }) // Send 'note off' for note 60 on channel 1
63 | cc(64, 127, 1) // Send control change message with control number 64, value 127, on channel 1
64 | ```
65 |
66 | ## `useMIDINote()`:
67 |
68 | The `useMIDINote` hook allows you to listen for MIDI note messages and updates its state
69 | with the message details if the message matches the specified note and channel filters. If no filters are provided, it will update the state with every note message received.
70 |
71 | ```ts
72 | // To use this hook to listen for note C3 (MIDI note number 60) on channel 1
73 | const midiNote = useMIDINote({ note: 60, channel: 1 })
74 | if (midiNote) {
75 | console.log(
76 | `Note ${midiNote.note} with velocity ${midiNote.velocity} received on channel ${midiNote.channel}`
77 | )
78 | }
79 | ```
80 |
81 | ## `useMIDINotes()`:
82 |
83 | The `useMIDINotes` hook subscribes to MIDI note messages that satisfy specified filtering criteria (such as note number and channel).
84 | It maintains an array of active (i.e., currently pressed) MIDI notes. When a note-on message is received, the note is
85 | added to the array. When a note-off message for an active note is received, that note is removed from the array.
86 | This allows for tracking of currently active MIDI notes that match the filter.
87 |
88 | ```ts
89 | // To use this hook to monitor active notes for MIDI channel 1
90 | const activeNotes = useMIDINotes({ channel: 1 })
91 | // activeNotes will be an array of objects, each representing an active MIDI note on channel 1.
92 | ```
93 |
94 | ## `useMIDIControl()`:
95 |
96 | The `useMIDIControl` hook listens for MIDI control change (CC) messages and updates its state
97 | with the details of the message if it matches the specified control number and channel filters.
98 | If no filters are provided, it will update the state with every control change message received.
99 | This can be useful for components that need to react to specific control change messages.
100 |
101 | ```ts
102 | // To use this hook to listen for control change number 7 on channel 1
103 | const midiControl = useMIDIControl({ cc: 7, channel: 1 })
104 | if (midiControl) {
105 | console.log(
106 | `Control change ${midiControl.control} with value ${midiControl.value} received on channel ${midiControl.channel}`
107 | )
108 | }
109 | ```
110 |
111 | ## `useMIDIControls()`:
112 |
113 | The `useMIDIControls` hook listens for MIDI control change messages that match a provided filter,
114 | and maintains an array of values corresponding to a predefined set of control numbers (`controls`). Each control's
115 | value in the array is updated when a matching control change message is received. This is useful for components
116 | that need to keep track of and react to changes in multiple MIDI control values simultaneously.
117 |
118 | ```ts
119 | // To use this hook to monitor control changes for MIDI controls 7 and 10 on channel 1
120 | const controlValues = useMIDIControls([7, 10], { channel: 1 })
121 | // controlValues will be an array of two numbers, initially [0, 0], updated with the latest values for controls 7 and 10.
122 | ```
123 |
124 | ## `useMIDIMessage()`:
125 |
126 | The `useMIDIMessage` hook listens for any MIDI messages and updates its state with the latest message received.
127 | It is useful for components that need to react to or display information based on incoming MIDI messages.
128 |
129 | ```ts
130 | // To use this hook in a component to display the latest MIDI message
131 | const midiMessage = useMIDIMessage()
132 | if (midiMessage) {
133 | console.log(`MIDI message received:`, midiMessage)
134 | }
135 | ```
136 |
--------------------------------------------------------------------------------
/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { MultipleNotesWithOptions } from '../lib/hooks/use-midi-output'
3 | import {
4 | useMIDIOutput,
5 | MIDIProvider,
6 | useMIDIControl,
7 | useMIDIMessage,
8 | useMIDIControls,
9 | useMIDINote,
10 | useMIDINotes,
11 | } from '../lib/main'
12 | import './App.css'
13 | import { MIDIInterfaceSelector } from './MIDIInterfaceSelector.tsx'
14 |
15 | const MIDIBoard = () => {
16 | const { noteOn, noteOff } = useMIDIOutput()
17 | const playNotesFromNumArr = (notes: number[]) => {
18 | if (noteOn && noteOff) {
19 | noteOn(notes)
20 | window.setTimeout(() => noteOff(notes), 1000)
21 | }
22 | }
23 | const playNotesFromObjArr = (notes: MultipleNotesWithOptions) => {
24 | if (noteOn && noteOff) {
25 | noteOn(notes)
26 | window.setTimeout(() => noteOff(notes), 1000)
27 | }
28 | }
29 | return (
30 |
31 |
Output
32 |
33 |
noteOn()
34 |
35 | Triggers note on with various settings
36 |
37 |
38 |
41 |
44 |
49 |
50 |
51 |
52 |
noteOff()
53 |
54 | Triggers note off with various settings
55 |
56 |
57 |
60 |
63 |
70 |
71 |
72 |
73 |
noteOn() + noteOff()
74 |
75 | Triggers note on and schedules note off with setTimeout()
76 |
77 |
80 |
90 |
91 |
92 | )
93 | }
94 |
95 | const MIDIMonitor = () => {
96 | const message = useMIDIMessage()
97 | return (
98 |
99 |
All Input
100 |
101 |
useMIDIMessage()
102 |
103 | Listens to all midi messages coming from input.
104 |
105 | {message?.data.join(',') ?? 'No message'}
106 |
107 |
108 | )
109 | }
110 |
111 | const MIDIControlTest = () => {
112 | const allCC = useMIDIControl()
113 | const cc4 = useMIDIControl({ cc: 4 })
114 | const [cc5, cc6, cc7] = useMIDIControls([5, 6, 7])
115 | return (
116 |
117 |
MIDI CCs
118 |
119 |
useMIDIControl()
120 |
121 | Listens to all midi control messages coming from input.
122 |
123 |
124 |
125 | Channel: {allCC?.channel} Control:{' '}
126 | {allCC?.control} Value:{' '}
127 | {allCC?.value}
128 |
129 |
130 |
131 |
132 | {'useMIDIControl({ target: 4 })'}
133 |
134 |
135 | Listens to CC 4 messages coming from input.
136 |
137 |
138 |
139 | Channel: {cc4?.channel} Control:{' '}
140 | {cc4?.control} Value:{' '}
141 | {cc4?.value}
142 |
143 |
144 |
145 |
146 |
{'useMIDIControls([5, 6, 7])'}
147 |
148 | Listens to CC4 messages coming from input.
149 |
150 | CC5:
{cc5} CC6:{' '}
151 |
{cc6} CC7:{' '}
152 |
{cc7}
153 |
154 |
155 | )
156 | }
157 |
158 | const MIDINoteTest = () => {
159 | const allNote = useMIDINote()
160 | const middleC = useMIDINote({ note: 60 })
161 | const notes = useMIDINotes()
162 | return (
163 |
164 |
Notes
165 |
166 |
useMIDINote()
167 |
168 | Listens to all incoming MIDI notes on input.
169 |
170 |
171 | Channel: {allNote?.channel} Control:{' '}
172 | {allNote?.note} Velocity:{' '}
173 | {allNote?.velocity} On:{' '}
174 | {allNote?.on ? 'true' : 'false'}
175 |
176 |
177 |
178 |
{'useMIDINote({ target: 60 })'}
179 |
180 | Listens to middle C coming from input.
181 |
182 |
183 | Channel: {middleC?.channel} Note:{' '}
184 | {middleC?.note} Velocity:{' '}
185 | {middleC?.velocity} On:{' '}
186 | {middleC?.on ? 'true' : 'false'}
187 |
188 |
189 |
190 |
191 |
{'useMIDINotes()'}
192 |
193 | Listens to input and maintains a list of active notes.
194 |
195 | {notes.map((note, i) => (
196 |
197 | Note: {note.note} Velocity:{' '}
198 | {note.velocity} Channel:{' '}
199 | {note.channel}
200 |
201 | ))}
202 |
203 |
204 | )
205 | }
206 |
207 | function App() {
208 | return (
209 |
210 | @react-midi/hooks Test App
211 |
212 |
213 |
214 |
215 |
216 |
217 | )
218 | }
219 |
220 | export default App
221 |
--------------------------------------------------------------------------------
/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
7 | dependencies:
8 | uniqid:
9 | specifier: ^5.4.0
10 | version: 5.4.0
11 |
12 | devDependencies:
13 | '@types/react':
14 | specifier: ^18.2.15
15 | version: 18.2.28
16 | '@types/react-dom':
17 | specifier: ^18.2.7
18 | version: 18.2.13
19 | '@types/uniqid':
20 | specifier: ^5.3.2
21 | version: 5.3.2
22 | '@types/webmidi':
23 | specifier: ^2.0.8
24 | version: 2.0.8
25 | '@typescript-eslint/eslint-plugin':
26 | specifier: ^6.0.0
27 | version: 6.7.5(@typescript-eslint/parser@6.7.5)(eslint@8.51.0)(typescript@5.2.2)
28 | '@typescript-eslint/parser':
29 | specifier: ^6.0.0
30 | version: 6.7.5(eslint@8.51.0)(typescript@5.2.2)
31 | '@vitejs/plugin-react-swc':
32 | specifier: ^3.3.2
33 | version: 3.4.0(vite@4.4.11)
34 | eslint:
35 | specifier: ^8.45.0
36 | version: 8.51.0
37 | eslint-plugin-react-hooks:
38 | specifier: ^4.6.0
39 | version: 4.6.0(eslint@8.51.0)
40 | eslint-plugin-react-refresh:
41 | specifier: ^0.4.3
42 | version: 0.4.3(eslint@8.51.0)
43 | react:
44 | specifier: ^18.2.0
45 | version: 18.2.0
46 | react-dom:
47 | specifier: ^18.2.0
48 | version: 18.2.0(react@18.2.0)
49 | typescript:
50 | specifier: ^5.0.2
51 | version: 5.2.2
52 | vite:
53 | specifier: ^4.4.5
54 | version: 4.4.11
55 | vite-plugin-dts:
56 | specifier: ^3.6.0
57 | version: 3.6.0(typescript@5.2.2)(vite@4.4.11)
58 |
59 | packages:
60 |
61 | /@aashutoshrathi/word-wrap@1.2.6:
62 | resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==}
63 | engines: {node: '>=0.10.0'}
64 | dev: true
65 |
66 | /@babel/helper-string-parser@7.22.5:
67 | resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==}
68 | engines: {node: '>=6.9.0'}
69 | dev: true
70 |
71 | /@babel/helper-validator-identifier@7.22.20:
72 | resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==}
73 | engines: {node: '>=6.9.0'}
74 | dev: true
75 |
76 | /@babel/parser@7.23.0:
77 | resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==}
78 | engines: {node: '>=6.0.0'}
79 | hasBin: true
80 | dependencies:
81 | '@babel/types': 7.23.0
82 | dev: true
83 |
84 | /@babel/types@7.23.0:
85 | resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==}
86 | engines: {node: '>=6.9.0'}
87 | dependencies:
88 | '@babel/helper-string-parser': 7.22.5
89 | '@babel/helper-validator-identifier': 7.22.20
90 | to-fast-properties: 2.0.0
91 | dev: true
92 |
93 | /@esbuild/android-arm64@0.18.20:
94 | resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==}
95 | engines: {node: '>=12'}
96 | cpu: [arm64]
97 | os: [android]
98 | requiresBuild: true
99 | dev: true
100 | optional: true
101 |
102 | /@esbuild/android-arm@0.18.20:
103 | resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==}
104 | engines: {node: '>=12'}
105 | cpu: [arm]
106 | os: [android]
107 | requiresBuild: true
108 | dev: true
109 | optional: true
110 |
111 | /@esbuild/android-x64@0.18.20:
112 | resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==}
113 | engines: {node: '>=12'}
114 | cpu: [x64]
115 | os: [android]
116 | requiresBuild: true
117 | dev: true
118 | optional: true
119 |
120 | /@esbuild/darwin-arm64@0.18.20:
121 | resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==}
122 | engines: {node: '>=12'}
123 | cpu: [arm64]
124 | os: [darwin]
125 | requiresBuild: true
126 | dev: true
127 | optional: true
128 |
129 | /@esbuild/darwin-x64@0.18.20:
130 | resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==}
131 | engines: {node: '>=12'}
132 | cpu: [x64]
133 | os: [darwin]
134 | requiresBuild: true
135 | dev: true
136 | optional: true
137 |
138 | /@esbuild/freebsd-arm64@0.18.20:
139 | resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==}
140 | engines: {node: '>=12'}
141 | cpu: [arm64]
142 | os: [freebsd]
143 | requiresBuild: true
144 | dev: true
145 | optional: true
146 |
147 | /@esbuild/freebsd-x64@0.18.20:
148 | resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==}
149 | engines: {node: '>=12'}
150 | cpu: [x64]
151 | os: [freebsd]
152 | requiresBuild: true
153 | dev: true
154 | optional: true
155 |
156 | /@esbuild/linux-arm64@0.18.20:
157 | resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==}
158 | engines: {node: '>=12'}
159 | cpu: [arm64]
160 | os: [linux]
161 | requiresBuild: true
162 | dev: true
163 | optional: true
164 |
165 | /@esbuild/linux-arm@0.18.20:
166 | resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==}
167 | engines: {node: '>=12'}
168 | cpu: [arm]
169 | os: [linux]
170 | requiresBuild: true
171 | dev: true
172 | optional: true
173 |
174 | /@esbuild/linux-ia32@0.18.20:
175 | resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==}
176 | engines: {node: '>=12'}
177 | cpu: [ia32]
178 | os: [linux]
179 | requiresBuild: true
180 | dev: true
181 | optional: true
182 |
183 | /@esbuild/linux-loong64@0.18.20:
184 | resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==}
185 | engines: {node: '>=12'}
186 | cpu: [loong64]
187 | os: [linux]
188 | requiresBuild: true
189 | dev: true
190 | optional: true
191 |
192 | /@esbuild/linux-mips64el@0.18.20:
193 | resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==}
194 | engines: {node: '>=12'}
195 | cpu: [mips64el]
196 | os: [linux]
197 | requiresBuild: true
198 | dev: true
199 | optional: true
200 |
201 | /@esbuild/linux-ppc64@0.18.20:
202 | resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==}
203 | engines: {node: '>=12'}
204 | cpu: [ppc64]
205 | os: [linux]
206 | requiresBuild: true
207 | dev: true
208 | optional: true
209 |
210 | /@esbuild/linux-riscv64@0.18.20:
211 | resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==}
212 | engines: {node: '>=12'}
213 | cpu: [riscv64]
214 | os: [linux]
215 | requiresBuild: true
216 | dev: true
217 | optional: true
218 |
219 | /@esbuild/linux-s390x@0.18.20:
220 | resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==}
221 | engines: {node: '>=12'}
222 | cpu: [s390x]
223 | os: [linux]
224 | requiresBuild: true
225 | dev: true
226 | optional: true
227 |
228 | /@esbuild/linux-x64@0.18.20:
229 | resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==}
230 | engines: {node: '>=12'}
231 | cpu: [x64]
232 | os: [linux]
233 | requiresBuild: true
234 | dev: true
235 | optional: true
236 |
237 | /@esbuild/netbsd-x64@0.18.20:
238 | resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==}
239 | engines: {node: '>=12'}
240 | cpu: [x64]
241 | os: [netbsd]
242 | requiresBuild: true
243 | dev: true
244 | optional: true
245 |
246 | /@esbuild/openbsd-x64@0.18.20:
247 | resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==}
248 | engines: {node: '>=12'}
249 | cpu: [x64]
250 | os: [openbsd]
251 | requiresBuild: true
252 | dev: true
253 | optional: true
254 |
255 | /@esbuild/sunos-x64@0.18.20:
256 | resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==}
257 | engines: {node: '>=12'}
258 | cpu: [x64]
259 | os: [sunos]
260 | requiresBuild: true
261 | dev: true
262 | optional: true
263 |
264 | /@esbuild/win32-arm64@0.18.20:
265 | resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==}
266 | engines: {node: '>=12'}
267 | cpu: [arm64]
268 | os: [win32]
269 | requiresBuild: true
270 | dev: true
271 | optional: true
272 |
273 | /@esbuild/win32-ia32@0.18.20:
274 | resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==}
275 | engines: {node: '>=12'}
276 | cpu: [ia32]
277 | os: [win32]
278 | requiresBuild: true
279 | dev: true
280 | optional: true
281 |
282 | /@esbuild/win32-x64@0.18.20:
283 | resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==}
284 | engines: {node: '>=12'}
285 | cpu: [x64]
286 | os: [win32]
287 | requiresBuild: true
288 | dev: true
289 | optional: true
290 |
291 | /@eslint-community/eslint-utils@4.4.0(eslint@8.51.0):
292 | resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
293 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
294 | peerDependencies:
295 | eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
296 | dependencies:
297 | eslint: 8.51.0
298 | eslint-visitor-keys: 3.4.3
299 | dev: true
300 |
301 | /@eslint-community/regexpp@4.9.1:
302 | resolution: {integrity: sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==}
303 | engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
304 | dev: true
305 |
306 | /@eslint/eslintrc@2.1.2:
307 | resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==}
308 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
309 | dependencies:
310 | ajv: 6.12.6
311 | debug: 4.3.4
312 | espree: 9.6.1
313 | globals: 13.23.0
314 | ignore: 5.2.4
315 | import-fresh: 3.3.0
316 | js-yaml: 4.1.0
317 | minimatch: 3.1.2
318 | strip-json-comments: 3.1.1
319 | transitivePeerDependencies:
320 | - supports-color
321 | dev: true
322 |
323 | /@eslint/js@8.51.0:
324 | resolution: {integrity: sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==}
325 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
326 | dev: true
327 |
328 | /@humanwhocodes/config-array@0.11.11:
329 | resolution: {integrity: sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==}
330 | engines: {node: '>=10.10.0'}
331 | dependencies:
332 | '@humanwhocodes/object-schema': 1.2.1
333 | debug: 4.3.4
334 | minimatch: 3.1.2
335 | transitivePeerDependencies:
336 | - supports-color
337 | dev: true
338 |
339 | /@humanwhocodes/module-importer@1.0.1:
340 | resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
341 | engines: {node: '>=12.22'}
342 | dev: true
343 |
344 | /@humanwhocodes/object-schema@1.2.1:
345 | resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
346 | dev: true
347 |
348 | /@microsoft/api-extractor-model@7.28.2:
349 | resolution: {integrity: sha512-vkojrM2fo3q4n4oPh4uUZdjJ2DxQ2+RnDQL/xhTWSRUNPF6P4QyrvY357HBxbnltKcYu+nNNolVqc6TIGQ73Ig==}
350 | dependencies:
351 | '@microsoft/tsdoc': 0.14.2
352 | '@microsoft/tsdoc-config': 0.16.2
353 | '@rushstack/node-core-library': 3.61.0
354 | transitivePeerDependencies:
355 | - '@types/node'
356 | dev: true
357 |
358 | /@microsoft/api-extractor@7.38.0:
359 | resolution: {integrity: sha512-e1LhZYnfw+JEebuY2bzhw0imDCl1nwjSThTrQqBXl40hrVo6xm3j/1EpUr89QyzgjqmAwek2ZkIVZbrhaR+cqg==}
360 | hasBin: true
361 | dependencies:
362 | '@microsoft/api-extractor-model': 7.28.2
363 | '@microsoft/tsdoc': 0.14.2
364 | '@microsoft/tsdoc-config': 0.16.2
365 | '@rushstack/node-core-library': 3.61.0
366 | '@rushstack/rig-package': 0.5.1
367 | '@rushstack/ts-command-line': 4.16.1
368 | colors: 1.2.5
369 | lodash: 4.17.21
370 | resolve: 1.22.8
371 | semver: 7.5.4
372 | source-map: 0.6.1
373 | typescript: 5.0.4
374 | transitivePeerDependencies:
375 | - '@types/node'
376 | dev: true
377 |
378 | /@microsoft/tsdoc-config@0.16.2:
379 | resolution: {integrity: sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==}
380 | dependencies:
381 | '@microsoft/tsdoc': 0.14.2
382 | ajv: 6.12.6
383 | jju: 1.4.0
384 | resolve: 1.19.0
385 | dev: true
386 |
387 | /@microsoft/tsdoc@0.14.2:
388 | resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==}
389 | dev: true
390 |
391 | /@nodelib/fs.scandir@2.1.5:
392 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
393 | engines: {node: '>= 8'}
394 | dependencies:
395 | '@nodelib/fs.stat': 2.0.5
396 | run-parallel: 1.2.0
397 | dev: true
398 |
399 | /@nodelib/fs.stat@2.0.5:
400 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
401 | engines: {node: '>= 8'}
402 | dev: true
403 |
404 | /@nodelib/fs.walk@1.2.8:
405 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
406 | engines: {node: '>= 8'}
407 | dependencies:
408 | '@nodelib/fs.scandir': 2.1.5
409 | fastq: 1.15.0
410 | dev: true
411 |
412 | /@rollup/pluginutils@5.0.5:
413 | resolution: {integrity: sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==}
414 | engines: {node: '>=14.0.0'}
415 | peerDependencies:
416 | rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
417 | peerDependenciesMeta:
418 | rollup:
419 | optional: true
420 | dependencies:
421 | '@types/estree': 1.0.2
422 | estree-walker: 2.0.2
423 | picomatch: 2.3.1
424 | dev: true
425 |
426 | /@rushstack/node-core-library@3.61.0:
427 | resolution: {integrity: sha512-tdOjdErme+/YOu4gPed3sFS72GhtWCgNV9oDsHDnoLY5oDfwjKUc9Z+JOZZ37uAxcm/OCahDHfuu2ugqrfWAVQ==}
428 | peerDependencies:
429 | '@types/node': '*'
430 | peerDependenciesMeta:
431 | '@types/node':
432 | optional: true
433 | dependencies:
434 | colors: 1.2.5
435 | fs-extra: 7.0.1
436 | import-lazy: 4.0.0
437 | jju: 1.4.0
438 | resolve: 1.22.8
439 | semver: 7.5.4
440 | z-schema: 5.0.5
441 | dev: true
442 |
443 | /@rushstack/rig-package@0.5.1:
444 | resolution: {integrity: sha512-pXRYSe29TjRw7rqxD4WS3HN/sRSbfr+tJs4a9uuaSIBAITbUggygdhuG0VrO0EO+QqH91GhYMN4S6KRtOEmGVA==}
445 | dependencies:
446 | resolve: 1.22.8
447 | strip-json-comments: 3.1.1
448 | dev: true
449 |
450 | /@rushstack/ts-command-line@4.16.1:
451 | resolution: {integrity: sha512-+OCsD553GYVLEmz12yiFjMOzuPeCiZ3f8wTiFHL30ZVXexTyPmgjwXEhg2K2P0a2lVf+8YBy7WtPoflB2Fp8/A==}
452 | dependencies:
453 | '@types/argparse': 1.0.38
454 | argparse: 1.0.10
455 | colors: 1.2.5
456 | string-argv: 0.3.2
457 | dev: true
458 |
459 | /@swc/core-darwin-arm64@1.3.92:
460 | resolution: {integrity: sha512-v7PqZUBtIF6Q5Cp48gqUiG8zQQnEICpnfNdoiY3xjQAglCGIQCjJIDjreZBoeZQZspB27lQN4eZ43CX18+2SnA==}
461 | engines: {node: '>=10'}
462 | cpu: [arm64]
463 | os: [darwin]
464 | requiresBuild: true
465 | dev: true
466 | optional: true
467 |
468 | /@swc/core-darwin-x64@1.3.92:
469 | resolution: {integrity: sha512-Q3XIgQfXyxxxms3bPN+xGgvwk0TtG9l89IomApu+yTKzaIIlf051mS+lGngjnh9L0aUiCp6ICyjDLtutWP54fw==}
470 | engines: {node: '>=10'}
471 | cpu: [x64]
472 | os: [darwin]
473 | requiresBuild: true
474 | dev: true
475 | optional: true
476 |
477 | /@swc/core-linux-arm-gnueabihf@1.3.92:
478 | resolution: {integrity: sha512-tnOCoCpNVXC+0FCfG84PBZJyLlz0Vfj9MQhyhCvlJz9hQmvpf8nTdKH7RHrOn8VfxtUBLdVi80dXgIFgbvl7qA==}
479 | engines: {node: '>=10'}
480 | cpu: [arm]
481 | os: [linux]
482 | requiresBuild: true
483 | dev: true
484 | optional: true
485 |
486 | /@swc/core-linux-arm64-gnu@1.3.92:
487 | resolution: {integrity: sha512-lFfGhX32w8h1j74Iyz0Wv7JByXIwX11OE9UxG+oT7lG0RyXkF4zKyxP8EoxfLrDXse4Oop434p95e3UNC3IfCw==}
488 | engines: {node: '>=10'}
489 | cpu: [arm64]
490 | os: [linux]
491 | requiresBuild: true
492 | dev: true
493 | optional: true
494 |
495 | /@swc/core-linux-arm64-musl@1.3.92:
496 | resolution: {integrity: sha512-rOZtRcLj57MSAbiecMsqjzBcZDuaCZ8F6l6JDwGkQ7u1NYR57cqF0QDyU7RKS1Jq27Z/Vg21z5cwqoH5fLN+Sg==}
497 | engines: {node: '>=10'}
498 | cpu: [arm64]
499 | os: [linux]
500 | requiresBuild: true
501 | dev: true
502 | optional: true
503 |
504 | /@swc/core-linux-x64-gnu@1.3.92:
505 | resolution: {integrity: sha512-qptoMGnBL6v89x/Qpn+l1TH1Y0ed+v0qhNfAEVzZvCvzEMTFXphhlhYbDdpxbzRmCjH6GOGq7Y+xrWt9T1/ARg==}
506 | engines: {node: '>=10'}
507 | cpu: [x64]
508 | os: [linux]
509 | requiresBuild: true
510 | dev: true
511 | optional: true
512 |
513 | /@swc/core-linux-x64-musl@1.3.92:
514 | resolution: {integrity: sha512-g2KrJ43bZkCZHH4zsIV5ErojuV1OIpUHaEyW1gf7JWKaFBpWYVyubzFPvPkjcxHGLbMsEzO7w/NVfxtGMlFH/Q==}
515 | engines: {node: '>=10'}
516 | cpu: [x64]
517 | os: [linux]
518 | requiresBuild: true
519 | dev: true
520 | optional: true
521 |
522 | /@swc/core-win32-arm64-msvc@1.3.92:
523 | resolution: {integrity: sha512-3MCRGPAYDoQ8Yyd3WsCMc8eFSyKXY5kQLyg/R5zEqA0uthomo0m0F5/fxAJMZGaSdYkU1DgF73ctOWOf+Z/EzQ==}
524 | engines: {node: '>=10'}
525 | cpu: [arm64]
526 | os: [win32]
527 | requiresBuild: true
528 | dev: true
529 | optional: true
530 |
531 | /@swc/core-win32-ia32-msvc@1.3.92:
532 | resolution: {integrity: sha512-zqTBKQhgfWm73SVGS8FKhFYDovyRl1f5dTX1IwSKynO0qHkRCqJwauFJv/yevkpJWsI2pFh03xsRs9HncTQKSA==}
533 | engines: {node: '>=10'}
534 | cpu: [ia32]
535 | os: [win32]
536 | requiresBuild: true
537 | dev: true
538 | optional: true
539 |
540 | /@swc/core-win32-x64-msvc@1.3.92:
541 | resolution: {integrity: sha512-41bE66ddr9o/Fi1FBh0sHdaKdENPTuDpv1IFHxSg0dJyM/jX8LbkjnpdInYXHBxhcLVAPraVRrNsC4SaoPw2Pg==}
542 | engines: {node: '>=10'}
543 | cpu: [x64]
544 | os: [win32]
545 | requiresBuild: true
546 | dev: true
547 | optional: true
548 |
549 | /@swc/core@1.3.92:
550 | resolution: {integrity: sha512-vx0vUrf4YTEw59njOJ46Ha5i0cZTMYdRHQ7KXU29efN1MxcmJH2RajWLPlvQarOP1ab9iv9cApD7SMchDyx2vA==}
551 | engines: {node: '>=10'}
552 | requiresBuild: true
553 | peerDependencies:
554 | '@swc/helpers': ^0.5.0
555 | peerDependenciesMeta:
556 | '@swc/helpers':
557 | optional: true
558 | dependencies:
559 | '@swc/counter': 0.1.2
560 | '@swc/types': 0.1.5
561 | optionalDependencies:
562 | '@swc/core-darwin-arm64': 1.3.92
563 | '@swc/core-darwin-x64': 1.3.92
564 | '@swc/core-linux-arm-gnueabihf': 1.3.92
565 | '@swc/core-linux-arm64-gnu': 1.3.92
566 | '@swc/core-linux-arm64-musl': 1.3.92
567 | '@swc/core-linux-x64-gnu': 1.3.92
568 | '@swc/core-linux-x64-musl': 1.3.92
569 | '@swc/core-win32-arm64-msvc': 1.3.92
570 | '@swc/core-win32-ia32-msvc': 1.3.92
571 | '@swc/core-win32-x64-msvc': 1.3.92
572 | dev: true
573 |
574 | /@swc/counter@0.1.2:
575 | resolution: {integrity: sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw==}
576 | dev: true
577 |
578 | /@swc/types@0.1.5:
579 | resolution: {integrity: sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==}
580 | dev: true
581 |
582 | /@types/argparse@1.0.38:
583 | resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==}
584 | dev: true
585 |
586 | /@types/estree@1.0.2:
587 | resolution: {integrity: sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==}
588 | dev: true
589 |
590 | /@types/json-schema@7.0.13:
591 | resolution: {integrity: sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==}
592 | dev: true
593 |
594 | /@types/prop-types@15.7.8:
595 | resolution: {integrity: sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ==}
596 | dev: true
597 |
598 | /@types/react-dom@18.2.13:
599 | resolution: {integrity: sha512-eJIUv7rPP+EC45uNYp/ThhSpE16k22VJUknt5OLoH9tbXoi8bMhwLf5xRuWMywamNbWzhrSmU7IBJfPup1+3fw==}
600 | dependencies:
601 | '@types/react': 18.2.28
602 | dev: true
603 |
604 | /@types/react@18.2.28:
605 | resolution: {integrity: sha512-ad4aa/RaaJS3hyGz0BGegdnSRXQBkd1CCYDCdNjBPg90UUpLgo+WlJqb9fMYUxtehmzF3PJaTWqRZjko6BRzBg==}
606 | dependencies:
607 | '@types/prop-types': 15.7.8
608 | '@types/scheduler': 0.16.4
609 | csstype: 3.1.2
610 | dev: true
611 |
612 | /@types/scheduler@0.16.4:
613 | resolution: {integrity: sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ==}
614 | dev: true
615 |
616 | /@types/semver@7.5.3:
617 | resolution: {integrity: sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==}
618 | dev: true
619 |
620 | /@types/uniqid@5.3.2:
621 | resolution: {integrity: sha512-/NYoaZpWsnAJDsGYeMNDeG3p3fuUb4AiC7MfKxi5VSu18tXd08w6Ch0fKW94T4FeLXXZwZPoFgHA1O0rDYKyMQ==}
622 | dev: true
623 |
624 | /@types/webmidi@2.0.8:
625 | resolution: {integrity: sha512-GMwIMYwLNpevZfcBeNrwavlbqY33SVfZdvQYfIAGtUFZnDZnDcMIN9s52Ksz341ylGUszOcAKlXUfz3QBOaA+w==}
626 | dev: true
627 |
628 | /@typescript-eslint/eslint-plugin@6.7.5(@typescript-eslint/parser@6.7.5)(eslint@8.51.0)(typescript@5.2.2):
629 | resolution: {integrity: sha512-JhtAwTRhOUcP96D0Y6KYnwig/MRQbOoLGXTON2+LlyB/N35SP9j1boai2zzwXb7ypKELXMx3DVk9UTaEq1vHEw==}
630 | engines: {node: ^16.0.0 || >=18.0.0}
631 | peerDependencies:
632 | '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha
633 | eslint: ^7.0.0 || ^8.0.0
634 | typescript: '*'
635 | peerDependenciesMeta:
636 | typescript:
637 | optional: true
638 | dependencies:
639 | '@eslint-community/regexpp': 4.9.1
640 | '@typescript-eslint/parser': 6.7.5(eslint@8.51.0)(typescript@5.2.2)
641 | '@typescript-eslint/scope-manager': 6.7.5
642 | '@typescript-eslint/type-utils': 6.7.5(eslint@8.51.0)(typescript@5.2.2)
643 | '@typescript-eslint/utils': 6.7.5(eslint@8.51.0)(typescript@5.2.2)
644 | '@typescript-eslint/visitor-keys': 6.7.5
645 | debug: 4.3.4
646 | eslint: 8.51.0
647 | graphemer: 1.4.0
648 | ignore: 5.2.4
649 | natural-compare: 1.4.0
650 | semver: 7.5.4
651 | ts-api-utils: 1.0.3(typescript@5.2.2)
652 | typescript: 5.2.2
653 | transitivePeerDependencies:
654 | - supports-color
655 | dev: true
656 |
657 | /@typescript-eslint/parser@6.7.5(eslint@8.51.0)(typescript@5.2.2):
658 | resolution: {integrity: sha512-bIZVSGx2UME/lmhLcjdVc7ePBwn7CLqKarUBL4me1C5feOd663liTGjMBGVcGr+BhnSLeP4SgwdvNnnkbIdkCw==}
659 | engines: {node: ^16.0.0 || >=18.0.0}
660 | peerDependencies:
661 | eslint: ^7.0.0 || ^8.0.0
662 | typescript: '*'
663 | peerDependenciesMeta:
664 | typescript:
665 | optional: true
666 | dependencies:
667 | '@typescript-eslint/scope-manager': 6.7.5
668 | '@typescript-eslint/types': 6.7.5
669 | '@typescript-eslint/typescript-estree': 6.7.5(typescript@5.2.2)
670 | '@typescript-eslint/visitor-keys': 6.7.5
671 | debug: 4.3.4
672 | eslint: 8.51.0
673 | typescript: 5.2.2
674 | transitivePeerDependencies:
675 | - supports-color
676 | dev: true
677 |
678 | /@typescript-eslint/scope-manager@6.7.5:
679 | resolution: {integrity: sha512-GAlk3eQIwWOJeb9F7MKQ6Jbah/vx1zETSDw8likab/eFcqkjSD7BI75SDAeC5N2L0MmConMoPvTsmkrg71+B1A==}
680 | engines: {node: ^16.0.0 || >=18.0.0}
681 | dependencies:
682 | '@typescript-eslint/types': 6.7.5
683 | '@typescript-eslint/visitor-keys': 6.7.5
684 | dev: true
685 |
686 | /@typescript-eslint/type-utils@6.7.5(eslint@8.51.0)(typescript@5.2.2):
687 | resolution: {integrity: sha512-Gs0qos5wqxnQrvpYv+pf3XfcRXW6jiAn9zE/K+DlmYf6FcpxeNYN0AIETaPR7rHO4K2UY+D0CIbDP9Ut0U4m1g==}
688 | engines: {node: ^16.0.0 || >=18.0.0}
689 | peerDependencies:
690 | eslint: ^7.0.0 || ^8.0.0
691 | typescript: '*'
692 | peerDependenciesMeta:
693 | typescript:
694 | optional: true
695 | dependencies:
696 | '@typescript-eslint/typescript-estree': 6.7.5(typescript@5.2.2)
697 | '@typescript-eslint/utils': 6.7.5(eslint@8.51.0)(typescript@5.2.2)
698 | debug: 4.3.4
699 | eslint: 8.51.0
700 | ts-api-utils: 1.0.3(typescript@5.2.2)
701 | typescript: 5.2.2
702 | transitivePeerDependencies:
703 | - supports-color
704 | dev: true
705 |
706 | /@typescript-eslint/types@6.7.5:
707 | resolution: {integrity: sha512-WboQBlOXtdj1tDFPyIthpKrUb+kZf2VroLZhxKa/VlwLlLyqv/PwUNgL30BlTVZV1Wu4Asu2mMYPqarSO4L5ZQ==}
708 | engines: {node: ^16.0.0 || >=18.0.0}
709 | dev: true
710 |
711 | /@typescript-eslint/typescript-estree@6.7.5(typescript@5.2.2):
712 | resolution: {integrity: sha512-NhJiJ4KdtwBIxrKl0BqG1Ur+uw7FiOnOThcYx9DpOGJ/Abc9z2xNzLeirCG02Ig3vkvrc2qFLmYSSsaITbKjlg==}
713 | engines: {node: ^16.0.0 || >=18.0.0}
714 | peerDependencies:
715 | typescript: '*'
716 | peerDependenciesMeta:
717 | typescript:
718 | optional: true
719 | dependencies:
720 | '@typescript-eslint/types': 6.7.5
721 | '@typescript-eslint/visitor-keys': 6.7.5
722 | debug: 4.3.4
723 | globby: 11.1.0
724 | is-glob: 4.0.3
725 | semver: 7.5.4
726 | ts-api-utils: 1.0.3(typescript@5.2.2)
727 | typescript: 5.2.2
728 | transitivePeerDependencies:
729 | - supports-color
730 | dev: true
731 |
732 | /@typescript-eslint/utils@6.7.5(eslint@8.51.0)(typescript@5.2.2):
733 | resolution: {integrity: sha512-pfRRrH20thJbzPPlPc4j0UNGvH1PjPlhlCMq4Yx7EGjV7lvEeGX0U6MJYe8+SyFutWgSHsdbJ3BXzZccYggezA==}
734 | engines: {node: ^16.0.0 || >=18.0.0}
735 | peerDependencies:
736 | eslint: ^7.0.0 || ^8.0.0
737 | dependencies:
738 | '@eslint-community/eslint-utils': 4.4.0(eslint@8.51.0)
739 | '@types/json-schema': 7.0.13
740 | '@types/semver': 7.5.3
741 | '@typescript-eslint/scope-manager': 6.7.5
742 | '@typescript-eslint/types': 6.7.5
743 | '@typescript-eslint/typescript-estree': 6.7.5(typescript@5.2.2)
744 | eslint: 8.51.0
745 | semver: 7.5.4
746 | transitivePeerDependencies:
747 | - supports-color
748 | - typescript
749 | dev: true
750 |
751 | /@typescript-eslint/visitor-keys@6.7.5:
752 | resolution: {integrity: sha512-3MaWdDZtLlsexZzDSdQWsFQ9l9nL8B80Z4fImSpyllFC/KLqWQRdEcB+gGGO+N3Q2uL40EsG66wZLsohPxNXvg==}
753 | engines: {node: ^16.0.0 || >=18.0.0}
754 | dependencies:
755 | '@typescript-eslint/types': 6.7.5
756 | eslint-visitor-keys: 3.4.3
757 | dev: true
758 |
759 | /@vitejs/plugin-react-swc@3.4.0(vite@4.4.11):
760 | resolution: {integrity: sha512-m7UaA4Uvz82N/0EOVpZL4XsFIakRqrFKeSNxa1FBLSXGvWrWRBwmZb4qxk+ZIVAZcW3c3dn5YosomDgx62XWcQ==}
761 | peerDependencies:
762 | vite: ^4
763 | dependencies:
764 | '@swc/core': 1.3.92
765 | vite: 4.4.11
766 | transitivePeerDependencies:
767 | - '@swc/helpers'
768 | dev: true
769 |
770 | /@volar/language-core@1.10.4:
771 | resolution: {integrity: sha512-Na69qA6uwVIdA0rHuOc2W3pHtVQQO8hCNim7FOaKNpRJh0oAFnu5r9i7Oopo5C4cnELZkPNjTrbmpcCTiW+CMQ==}
772 | dependencies:
773 | '@volar/source-map': 1.10.4
774 | dev: true
775 |
776 | /@volar/source-map@1.10.4:
777 | resolution: {integrity: sha512-RxZdUEL+pV8p+SMqnhVjzy5zpb1QRZTlcwSk4bdcBO7yOu4rtEWqDGahVCEj4CcXour+0yJUMrMczfSCpP9Uxg==}
778 | dependencies:
779 | muggle-string: 0.3.1
780 | dev: true
781 |
782 | /@volar/typescript@1.10.4:
783 | resolution: {integrity: sha512-BCCUEBASBEMCrz7qmNSi2hBEWYsXD0doaktRKpmmhvb6XntM2sAWYu6gbyK/MluLDgluGLFiFRpWgobgzUqolg==}
784 | dependencies:
785 | '@volar/language-core': 1.10.4
786 | dev: true
787 |
788 | /@vue/compiler-core@3.3.4:
789 | resolution: {integrity: sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==}
790 | dependencies:
791 | '@babel/parser': 7.23.0
792 | '@vue/shared': 3.3.4
793 | estree-walker: 2.0.2
794 | source-map-js: 1.0.2
795 | dev: true
796 |
797 | /@vue/compiler-dom@3.3.4:
798 | resolution: {integrity: sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==}
799 | dependencies:
800 | '@vue/compiler-core': 3.3.4
801 | '@vue/shared': 3.3.4
802 | dev: true
803 |
804 | /@vue/language-core@1.8.19(typescript@5.2.2):
805 | resolution: {integrity: sha512-nt3dodGs97UM6fnxeQBazO50yYCKBK53waFWB3qMbLmR6eL3aUryZgQtZoBe1pye17Wl8fs9HysV3si6xMgndQ==}
806 | peerDependencies:
807 | typescript: '*'
808 | peerDependenciesMeta:
809 | typescript:
810 | optional: true
811 | dependencies:
812 | '@volar/language-core': 1.10.4
813 | '@volar/source-map': 1.10.4
814 | '@vue/compiler-dom': 3.3.4
815 | '@vue/reactivity': 3.3.4
816 | '@vue/shared': 3.3.4
817 | minimatch: 9.0.3
818 | muggle-string: 0.3.1
819 | typescript: 5.2.2
820 | vue-template-compiler: 2.7.14
821 | dev: true
822 |
823 | /@vue/reactivity@3.3.4:
824 | resolution: {integrity: sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==}
825 | dependencies:
826 | '@vue/shared': 3.3.4
827 | dev: true
828 |
829 | /@vue/shared@3.3.4:
830 | resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==}
831 | dev: true
832 |
833 | /@vue/typescript@1.8.19(typescript@5.2.2):
834 | resolution: {integrity: sha512-k/SHeeQROUgqsxyHQ8Cs3Zz5TnX57p7BcBDVYR2E0c61QL2DJ2G8CsaBremmNGuGE6o1R5D50IHIxFmroMz8iw==}
835 | dependencies:
836 | '@volar/typescript': 1.10.4
837 | '@vue/language-core': 1.8.19(typescript@5.2.2)
838 | transitivePeerDependencies:
839 | - typescript
840 | dev: true
841 |
842 | /acorn-jsx@5.3.2(acorn@8.10.0):
843 | resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
844 | peerDependencies:
845 | acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
846 | dependencies:
847 | acorn: 8.10.0
848 | dev: true
849 |
850 | /acorn@8.10.0:
851 | resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==}
852 | engines: {node: '>=0.4.0'}
853 | hasBin: true
854 | dev: true
855 |
856 | /ajv@6.12.6:
857 | resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
858 | dependencies:
859 | fast-deep-equal: 3.1.3
860 | fast-json-stable-stringify: 2.1.0
861 | json-schema-traverse: 0.4.1
862 | uri-js: 4.4.1
863 | dev: true
864 |
865 | /ansi-regex@5.0.1:
866 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
867 | engines: {node: '>=8'}
868 | dev: true
869 |
870 | /ansi-styles@4.3.0:
871 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
872 | engines: {node: '>=8'}
873 | dependencies:
874 | color-convert: 2.0.1
875 | dev: true
876 |
877 | /argparse@1.0.10:
878 | resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
879 | dependencies:
880 | sprintf-js: 1.0.3
881 | dev: true
882 |
883 | /argparse@2.0.1:
884 | resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
885 | dev: true
886 |
887 | /array-union@2.1.0:
888 | resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
889 | engines: {node: '>=8'}
890 | dev: true
891 |
892 | /balanced-match@1.0.2:
893 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
894 | dev: true
895 |
896 | /brace-expansion@1.1.11:
897 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
898 | dependencies:
899 | balanced-match: 1.0.2
900 | concat-map: 0.0.1
901 | dev: true
902 |
903 | /brace-expansion@2.0.1:
904 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
905 | dependencies:
906 | balanced-match: 1.0.2
907 | dev: true
908 |
909 | /braces@3.0.2:
910 | resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
911 | engines: {node: '>=8'}
912 | dependencies:
913 | fill-range: 7.0.1
914 | dev: true
915 |
916 | /callsites@3.1.0:
917 | resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
918 | engines: {node: '>=6'}
919 | dev: true
920 |
921 | /chalk@4.1.2:
922 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
923 | engines: {node: '>=10'}
924 | dependencies:
925 | ansi-styles: 4.3.0
926 | supports-color: 7.2.0
927 | dev: true
928 |
929 | /color-convert@2.0.1:
930 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
931 | engines: {node: '>=7.0.0'}
932 | dependencies:
933 | color-name: 1.1.4
934 | dev: true
935 |
936 | /color-name@1.1.4:
937 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
938 | dev: true
939 |
940 | /colors@1.2.5:
941 | resolution: {integrity: sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==}
942 | engines: {node: '>=0.1.90'}
943 | dev: true
944 |
945 | /commander@9.5.0:
946 | resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==}
947 | engines: {node: ^12.20.0 || >=14}
948 | requiresBuild: true
949 | dev: true
950 | optional: true
951 |
952 | /concat-map@0.0.1:
953 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
954 | dev: true
955 |
956 | /cross-spawn@7.0.3:
957 | resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
958 | engines: {node: '>= 8'}
959 | dependencies:
960 | path-key: 3.1.1
961 | shebang-command: 2.0.0
962 | which: 2.0.2
963 | dev: true
964 |
965 | /csstype@3.1.2:
966 | resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
967 | dev: true
968 |
969 | /de-indent@1.0.2:
970 | resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
971 | dev: true
972 |
973 | /debug@4.3.4:
974 | resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
975 | engines: {node: '>=6.0'}
976 | peerDependencies:
977 | supports-color: '*'
978 | peerDependenciesMeta:
979 | supports-color:
980 | optional: true
981 | dependencies:
982 | ms: 2.1.2
983 | dev: true
984 |
985 | /deep-is@0.1.4:
986 | resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
987 | dev: true
988 |
989 | /dir-glob@3.0.1:
990 | resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
991 | engines: {node: '>=8'}
992 | dependencies:
993 | path-type: 4.0.0
994 | dev: true
995 |
996 | /doctrine@3.0.0:
997 | resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
998 | engines: {node: '>=6.0.0'}
999 | dependencies:
1000 | esutils: 2.0.3
1001 | dev: true
1002 |
1003 | /esbuild@0.18.20:
1004 | resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==}
1005 | engines: {node: '>=12'}
1006 | hasBin: true
1007 | requiresBuild: true
1008 | optionalDependencies:
1009 | '@esbuild/android-arm': 0.18.20
1010 | '@esbuild/android-arm64': 0.18.20
1011 | '@esbuild/android-x64': 0.18.20
1012 | '@esbuild/darwin-arm64': 0.18.20
1013 | '@esbuild/darwin-x64': 0.18.20
1014 | '@esbuild/freebsd-arm64': 0.18.20
1015 | '@esbuild/freebsd-x64': 0.18.20
1016 | '@esbuild/linux-arm': 0.18.20
1017 | '@esbuild/linux-arm64': 0.18.20
1018 | '@esbuild/linux-ia32': 0.18.20
1019 | '@esbuild/linux-loong64': 0.18.20
1020 | '@esbuild/linux-mips64el': 0.18.20
1021 | '@esbuild/linux-ppc64': 0.18.20
1022 | '@esbuild/linux-riscv64': 0.18.20
1023 | '@esbuild/linux-s390x': 0.18.20
1024 | '@esbuild/linux-x64': 0.18.20
1025 | '@esbuild/netbsd-x64': 0.18.20
1026 | '@esbuild/openbsd-x64': 0.18.20
1027 | '@esbuild/sunos-x64': 0.18.20
1028 | '@esbuild/win32-arm64': 0.18.20
1029 | '@esbuild/win32-ia32': 0.18.20
1030 | '@esbuild/win32-x64': 0.18.20
1031 | dev: true
1032 |
1033 | /escape-string-regexp@4.0.0:
1034 | resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
1035 | engines: {node: '>=10'}
1036 | dev: true
1037 |
1038 | /eslint-plugin-react-hooks@4.6.0(eslint@8.51.0):
1039 | resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==}
1040 | engines: {node: '>=10'}
1041 | peerDependencies:
1042 | eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0
1043 | dependencies:
1044 | eslint: 8.51.0
1045 | dev: true
1046 |
1047 | /eslint-plugin-react-refresh@0.4.3(eslint@8.51.0):
1048 | resolution: {integrity: sha512-Hh0wv8bUNY877+sI0BlCUlsS0TYYQqvzEwJsJJPM2WF4RnTStSnSR3zdJYa2nPOJgg3UghXi54lVyMSmpCalzA==}
1049 | peerDependencies:
1050 | eslint: '>=7'
1051 | dependencies:
1052 | eslint: 8.51.0
1053 | dev: true
1054 |
1055 | /eslint-scope@7.2.2:
1056 | resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==}
1057 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
1058 | dependencies:
1059 | esrecurse: 4.3.0
1060 | estraverse: 5.3.0
1061 | dev: true
1062 |
1063 | /eslint-visitor-keys@3.4.3:
1064 | resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
1065 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
1066 | dev: true
1067 |
1068 | /eslint@8.51.0:
1069 | resolution: {integrity: sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==}
1070 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
1071 | hasBin: true
1072 | dependencies:
1073 | '@eslint-community/eslint-utils': 4.4.0(eslint@8.51.0)
1074 | '@eslint-community/regexpp': 4.9.1
1075 | '@eslint/eslintrc': 2.1.2
1076 | '@eslint/js': 8.51.0
1077 | '@humanwhocodes/config-array': 0.11.11
1078 | '@humanwhocodes/module-importer': 1.0.1
1079 | '@nodelib/fs.walk': 1.2.8
1080 | ajv: 6.12.6
1081 | chalk: 4.1.2
1082 | cross-spawn: 7.0.3
1083 | debug: 4.3.4
1084 | doctrine: 3.0.0
1085 | escape-string-regexp: 4.0.0
1086 | eslint-scope: 7.2.2
1087 | eslint-visitor-keys: 3.4.3
1088 | espree: 9.6.1
1089 | esquery: 1.5.0
1090 | esutils: 2.0.3
1091 | fast-deep-equal: 3.1.3
1092 | file-entry-cache: 6.0.1
1093 | find-up: 5.0.0
1094 | glob-parent: 6.0.2
1095 | globals: 13.23.0
1096 | graphemer: 1.4.0
1097 | ignore: 5.2.4
1098 | imurmurhash: 0.1.4
1099 | is-glob: 4.0.3
1100 | is-path-inside: 3.0.3
1101 | js-yaml: 4.1.0
1102 | json-stable-stringify-without-jsonify: 1.0.1
1103 | levn: 0.4.1
1104 | lodash.merge: 4.6.2
1105 | minimatch: 3.1.2
1106 | natural-compare: 1.4.0
1107 | optionator: 0.9.3
1108 | strip-ansi: 6.0.1
1109 | text-table: 0.2.0
1110 | transitivePeerDependencies:
1111 | - supports-color
1112 | dev: true
1113 |
1114 | /espree@9.6.1:
1115 | resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==}
1116 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
1117 | dependencies:
1118 | acorn: 8.10.0
1119 | acorn-jsx: 5.3.2(acorn@8.10.0)
1120 | eslint-visitor-keys: 3.4.3
1121 | dev: true
1122 |
1123 | /esquery@1.5.0:
1124 | resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==}
1125 | engines: {node: '>=0.10'}
1126 | dependencies:
1127 | estraverse: 5.3.0
1128 | dev: true
1129 |
1130 | /esrecurse@4.3.0:
1131 | resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
1132 | engines: {node: '>=4.0'}
1133 | dependencies:
1134 | estraverse: 5.3.0
1135 | dev: true
1136 |
1137 | /estraverse@5.3.0:
1138 | resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
1139 | engines: {node: '>=4.0'}
1140 | dev: true
1141 |
1142 | /estree-walker@2.0.2:
1143 | resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
1144 | dev: true
1145 |
1146 | /esutils@2.0.3:
1147 | resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
1148 | engines: {node: '>=0.10.0'}
1149 | dev: true
1150 |
1151 | /fast-deep-equal@3.1.3:
1152 | resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
1153 | dev: true
1154 |
1155 | /fast-glob@3.3.1:
1156 | resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==}
1157 | engines: {node: '>=8.6.0'}
1158 | dependencies:
1159 | '@nodelib/fs.stat': 2.0.5
1160 | '@nodelib/fs.walk': 1.2.8
1161 | glob-parent: 5.1.2
1162 | merge2: 1.4.1
1163 | micromatch: 4.0.5
1164 | dev: true
1165 |
1166 | /fast-json-stable-stringify@2.1.0:
1167 | resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
1168 | dev: true
1169 |
1170 | /fast-levenshtein@2.0.6:
1171 | resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
1172 | dev: true
1173 |
1174 | /fastq@1.15.0:
1175 | resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==}
1176 | dependencies:
1177 | reusify: 1.0.4
1178 | dev: true
1179 |
1180 | /file-entry-cache@6.0.1:
1181 | resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
1182 | engines: {node: ^10.12.0 || >=12.0.0}
1183 | dependencies:
1184 | flat-cache: 3.1.1
1185 | dev: true
1186 |
1187 | /fill-range@7.0.1:
1188 | resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
1189 | engines: {node: '>=8'}
1190 | dependencies:
1191 | to-regex-range: 5.0.1
1192 | dev: true
1193 |
1194 | /find-up@5.0.0:
1195 | resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
1196 | engines: {node: '>=10'}
1197 | dependencies:
1198 | locate-path: 6.0.0
1199 | path-exists: 4.0.0
1200 | dev: true
1201 |
1202 | /flat-cache@3.1.1:
1203 | resolution: {integrity: sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==}
1204 | engines: {node: '>=12.0.0'}
1205 | dependencies:
1206 | flatted: 3.2.9
1207 | keyv: 4.5.4
1208 | rimraf: 3.0.2
1209 | dev: true
1210 |
1211 | /flatted@3.2.9:
1212 | resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==}
1213 | dev: true
1214 |
1215 | /fs-extra@7.0.1:
1216 | resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==}
1217 | engines: {node: '>=6 <7 || >=8'}
1218 | dependencies:
1219 | graceful-fs: 4.2.11
1220 | jsonfile: 4.0.0
1221 | universalify: 0.1.2
1222 | dev: true
1223 |
1224 | /fs.realpath@1.0.0:
1225 | resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
1226 | dev: true
1227 |
1228 | /fsevents@2.3.3:
1229 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
1230 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
1231 | os: [darwin]
1232 | requiresBuild: true
1233 | dev: true
1234 | optional: true
1235 |
1236 | /glob-parent@5.1.2:
1237 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
1238 | engines: {node: '>= 6'}
1239 | dependencies:
1240 | is-glob: 4.0.3
1241 | dev: true
1242 |
1243 | /glob-parent@6.0.2:
1244 | resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
1245 | engines: {node: '>=10.13.0'}
1246 | dependencies:
1247 | is-glob: 4.0.3
1248 | dev: true
1249 |
1250 | /glob@7.2.3:
1251 | resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
1252 | dependencies:
1253 | fs.realpath: 1.0.0
1254 | inflight: 1.0.6
1255 | inherits: 2.0.4
1256 | minimatch: 3.1.2
1257 | once: 1.4.0
1258 | path-is-absolute: 1.0.1
1259 | dev: true
1260 |
1261 | /globals@13.23.0:
1262 | resolution: {integrity: sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==}
1263 | engines: {node: '>=8'}
1264 | dependencies:
1265 | type-fest: 0.20.2
1266 | dev: true
1267 |
1268 | /globby@11.1.0:
1269 | resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
1270 | engines: {node: '>=10'}
1271 | dependencies:
1272 | array-union: 2.1.0
1273 | dir-glob: 3.0.1
1274 | fast-glob: 3.3.1
1275 | ignore: 5.2.4
1276 | merge2: 1.4.1
1277 | slash: 3.0.0
1278 | dev: true
1279 |
1280 | /graceful-fs@4.2.11:
1281 | resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
1282 | dev: true
1283 |
1284 | /graphemer@1.4.0:
1285 | resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
1286 | dev: true
1287 |
1288 | /has-flag@4.0.0:
1289 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
1290 | engines: {node: '>=8'}
1291 | dev: true
1292 |
1293 | /has@1.0.4:
1294 | resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==}
1295 | engines: {node: '>= 0.4.0'}
1296 | dev: true
1297 |
1298 | /he@1.2.0:
1299 | resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
1300 | hasBin: true
1301 | dev: true
1302 |
1303 | /ignore@5.2.4:
1304 | resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==}
1305 | engines: {node: '>= 4'}
1306 | dev: true
1307 |
1308 | /import-fresh@3.3.0:
1309 | resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
1310 | engines: {node: '>=6'}
1311 | dependencies:
1312 | parent-module: 1.0.1
1313 | resolve-from: 4.0.0
1314 | dev: true
1315 |
1316 | /import-lazy@4.0.0:
1317 | resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==}
1318 | engines: {node: '>=8'}
1319 | dev: true
1320 |
1321 | /imurmurhash@0.1.4:
1322 | resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
1323 | engines: {node: '>=0.8.19'}
1324 | dev: true
1325 |
1326 | /inflight@1.0.6:
1327 | resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
1328 | dependencies:
1329 | once: 1.4.0
1330 | wrappy: 1.0.2
1331 | dev: true
1332 |
1333 | /inherits@2.0.4:
1334 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
1335 | dev: true
1336 |
1337 | /is-core-module@2.13.0:
1338 | resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==}
1339 | dependencies:
1340 | has: 1.0.4
1341 | dev: true
1342 |
1343 | /is-extglob@2.1.1:
1344 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
1345 | engines: {node: '>=0.10.0'}
1346 | dev: true
1347 |
1348 | /is-glob@4.0.3:
1349 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
1350 | engines: {node: '>=0.10.0'}
1351 | dependencies:
1352 | is-extglob: 2.1.1
1353 | dev: true
1354 |
1355 | /is-number@7.0.0:
1356 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
1357 | engines: {node: '>=0.12.0'}
1358 | dev: true
1359 |
1360 | /is-path-inside@3.0.3:
1361 | resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
1362 | engines: {node: '>=8'}
1363 | dev: true
1364 |
1365 | /isexe@2.0.0:
1366 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
1367 | dev: true
1368 |
1369 | /jju@1.4.0:
1370 | resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==}
1371 | dev: true
1372 |
1373 | /js-tokens@4.0.0:
1374 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
1375 | dev: true
1376 |
1377 | /js-yaml@4.1.0:
1378 | resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
1379 | hasBin: true
1380 | dependencies:
1381 | argparse: 2.0.1
1382 | dev: true
1383 |
1384 | /json-buffer@3.0.1:
1385 | resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
1386 | dev: true
1387 |
1388 | /json-schema-traverse@0.4.1:
1389 | resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
1390 | dev: true
1391 |
1392 | /json-stable-stringify-without-jsonify@1.0.1:
1393 | resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
1394 | dev: true
1395 |
1396 | /jsonfile@4.0.0:
1397 | resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==}
1398 | optionalDependencies:
1399 | graceful-fs: 4.2.11
1400 | dev: true
1401 |
1402 | /keyv@4.5.4:
1403 | resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
1404 | dependencies:
1405 | json-buffer: 3.0.1
1406 | dev: true
1407 |
1408 | /kolorist@1.8.0:
1409 | resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==}
1410 | dev: true
1411 |
1412 | /levn@0.4.1:
1413 | resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
1414 | engines: {node: '>= 0.8.0'}
1415 | dependencies:
1416 | prelude-ls: 1.2.1
1417 | type-check: 0.4.0
1418 | dev: true
1419 |
1420 | /locate-path@6.0.0:
1421 | resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
1422 | engines: {node: '>=10'}
1423 | dependencies:
1424 | p-locate: 5.0.0
1425 | dev: true
1426 |
1427 | /lodash.get@4.4.2:
1428 | resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
1429 | dev: true
1430 |
1431 | /lodash.isequal@4.5.0:
1432 | resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==}
1433 | dev: true
1434 |
1435 | /lodash.merge@4.6.2:
1436 | resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
1437 | dev: true
1438 |
1439 | /lodash@4.17.21:
1440 | resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
1441 | dev: true
1442 |
1443 | /loose-envify@1.4.0:
1444 | resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
1445 | hasBin: true
1446 | dependencies:
1447 | js-tokens: 4.0.0
1448 | dev: true
1449 |
1450 | /lru-cache@6.0.0:
1451 | resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
1452 | engines: {node: '>=10'}
1453 | dependencies:
1454 | yallist: 4.0.0
1455 | dev: true
1456 |
1457 | /merge2@1.4.1:
1458 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
1459 | engines: {node: '>= 8'}
1460 | dev: true
1461 |
1462 | /micromatch@4.0.5:
1463 | resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
1464 | engines: {node: '>=8.6'}
1465 | dependencies:
1466 | braces: 3.0.2
1467 | picomatch: 2.3.1
1468 | dev: true
1469 |
1470 | /minimatch@3.1.2:
1471 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
1472 | dependencies:
1473 | brace-expansion: 1.1.11
1474 | dev: true
1475 |
1476 | /minimatch@9.0.3:
1477 | resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==}
1478 | engines: {node: '>=16 || 14 >=14.17'}
1479 | dependencies:
1480 | brace-expansion: 2.0.1
1481 | dev: true
1482 |
1483 | /ms@2.1.2:
1484 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
1485 | dev: true
1486 |
1487 | /muggle-string@0.3.1:
1488 | resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==}
1489 | dev: true
1490 |
1491 | /nanoid@3.3.6:
1492 | resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==}
1493 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
1494 | hasBin: true
1495 | dev: true
1496 |
1497 | /natural-compare@1.4.0:
1498 | resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
1499 | dev: true
1500 |
1501 | /once@1.4.0:
1502 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
1503 | dependencies:
1504 | wrappy: 1.0.2
1505 | dev: true
1506 |
1507 | /optionator@0.9.3:
1508 | resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==}
1509 | engines: {node: '>= 0.8.0'}
1510 | dependencies:
1511 | '@aashutoshrathi/word-wrap': 1.2.6
1512 | deep-is: 0.1.4
1513 | fast-levenshtein: 2.0.6
1514 | levn: 0.4.1
1515 | prelude-ls: 1.2.1
1516 | type-check: 0.4.0
1517 | dev: true
1518 |
1519 | /p-limit@3.1.0:
1520 | resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
1521 | engines: {node: '>=10'}
1522 | dependencies:
1523 | yocto-queue: 0.1.0
1524 | dev: true
1525 |
1526 | /p-locate@5.0.0:
1527 | resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
1528 | engines: {node: '>=10'}
1529 | dependencies:
1530 | p-limit: 3.1.0
1531 | dev: true
1532 |
1533 | /parent-module@1.0.1:
1534 | resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
1535 | engines: {node: '>=6'}
1536 | dependencies:
1537 | callsites: 3.1.0
1538 | dev: true
1539 |
1540 | /path-exists@4.0.0:
1541 | resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
1542 | engines: {node: '>=8'}
1543 | dev: true
1544 |
1545 | /path-is-absolute@1.0.1:
1546 | resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
1547 | engines: {node: '>=0.10.0'}
1548 | dev: true
1549 |
1550 | /path-key@3.1.1:
1551 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
1552 | engines: {node: '>=8'}
1553 | dev: true
1554 |
1555 | /path-parse@1.0.7:
1556 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
1557 | dev: true
1558 |
1559 | /path-type@4.0.0:
1560 | resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
1561 | engines: {node: '>=8'}
1562 | dev: true
1563 |
1564 | /picocolors@1.0.0:
1565 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
1566 | dev: true
1567 |
1568 | /picomatch@2.3.1:
1569 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
1570 | engines: {node: '>=8.6'}
1571 | dev: true
1572 |
1573 | /postcss@8.4.31:
1574 | resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
1575 | engines: {node: ^10 || ^12 || >=14}
1576 | dependencies:
1577 | nanoid: 3.3.6
1578 | picocolors: 1.0.0
1579 | source-map-js: 1.0.2
1580 | dev: true
1581 |
1582 | /prelude-ls@1.2.1:
1583 | resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
1584 | engines: {node: '>= 0.8.0'}
1585 | dev: true
1586 |
1587 | /punycode@2.3.0:
1588 | resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==}
1589 | engines: {node: '>=6'}
1590 | dev: true
1591 |
1592 | /queue-microtask@1.2.3:
1593 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
1594 | dev: true
1595 |
1596 | /react-dom@18.2.0(react@18.2.0):
1597 | resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==}
1598 | peerDependencies:
1599 | react: ^18.2.0
1600 | dependencies:
1601 | loose-envify: 1.4.0
1602 | react: 18.2.0
1603 | scheduler: 0.23.0
1604 | dev: true
1605 |
1606 | /react@18.2.0:
1607 | resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
1608 | engines: {node: '>=0.10.0'}
1609 | dependencies:
1610 | loose-envify: 1.4.0
1611 | dev: true
1612 |
1613 | /resolve-from@4.0.0:
1614 | resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
1615 | engines: {node: '>=4'}
1616 | dev: true
1617 |
1618 | /resolve@1.19.0:
1619 | resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==}
1620 | dependencies:
1621 | is-core-module: 2.13.0
1622 | path-parse: 1.0.7
1623 | dev: true
1624 |
1625 | /resolve@1.22.8:
1626 | resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
1627 | hasBin: true
1628 | dependencies:
1629 | is-core-module: 2.13.0
1630 | path-parse: 1.0.7
1631 | supports-preserve-symlinks-flag: 1.0.0
1632 | dev: true
1633 |
1634 | /reusify@1.0.4:
1635 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
1636 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
1637 | dev: true
1638 |
1639 | /rimraf@3.0.2:
1640 | resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
1641 | hasBin: true
1642 | dependencies:
1643 | glob: 7.2.3
1644 | dev: true
1645 |
1646 | /rollup@3.29.4:
1647 | resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==}
1648 | engines: {node: '>=14.18.0', npm: '>=8.0.0'}
1649 | hasBin: true
1650 | optionalDependencies:
1651 | fsevents: 2.3.3
1652 | dev: true
1653 |
1654 | /run-parallel@1.2.0:
1655 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
1656 | dependencies:
1657 | queue-microtask: 1.2.3
1658 | dev: true
1659 |
1660 | /scheduler@0.23.0:
1661 | resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==}
1662 | dependencies:
1663 | loose-envify: 1.4.0
1664 | dev: true
1665 |
1666 | /semver@7.5.4:
1667 | resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==}
1668 | engines: {node: '>=10'}
1669 | hasBin: true
1670 | dependencies:
1671 | lru-cache: 6.0.0
1672 | dev: true
1673 |
1674 | /shebang-command@2.0.0:
1675 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
1676 | engines: {node: '>=8'}
1677 | dependencies:
1678 | shebang-regex: 3.0.0
1679 | dev: true
1680 |
1681 | /shebang-regex@3.0.0:
1682 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
1683 | engines: {node: '>=8'}
1684 | dev: true
1685 |
1686 | /slash@3.0.0:
1687 | resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
1688 | engines: {node: '>=8'}
1689 | dev: true
1690 |
1691 | /source-map-js@1.0.2:
1692 | resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
1693 | engines: {node: '>=0.10.0'}
1694 | dev: true
1695 |
1696 | /source-map@0.6.1:
1697 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
1698 | engines: {node: '>=0.10.0'}
1699 | dev: true
1700 |
1701 | /sprintf-js@1.0.3:
1702 | resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
1703 | dev: true
1704 |
1705 | /string-argv@0.3.2:
1706 | resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
1707 | engines: {node: '>=0.6.19'}
1708 | dev: true
1709 |
1710 | /strip-ansi@6.0.1:
1711 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
1712 | engines: {node: '>=8'}
1713 | dependencies:
1714 | ansi-regex: 5.0.1
1715 | dev: true
1716 |
1717 | /strip-json-comments@3.1.1:
1718 | resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
1719 | engines: {node: '>=8'}
1720 | dev: true
1721 |
1722 | /supports-color@7.2.0:
1723 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
1724 | engines: {node: '>=8'}
1725 | dependencies:
1726 | has-flag: 4.0.0
1727 | dev: true
1728 |
1729 | /supports-preserve-symlinks-flag@1.0.0:
1730 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
1731 | engines: {node: '>= 0.4'}
1732 | dev: true
1733 |
1734 | /text-table@0.2.0:
1735 | resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
1736 | dev: true
1737 |
1738 | /to-fast-properties@2.0.0:
1739 | resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
1740 | engines: {node: '>=4'}
1741 | dev: true
1742 |
1743 | /to-regex-range@5.0.1:
1744 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
1745 | engines: {node: '>=8.0'}
1746 | dependencies:
1747 | is-number: 7.0.0
1748 | dev: true
1749 |
1750 | /ts-api-utils@1.0.3(typescript@5.2.2):
1751 | resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==}
1752 | engines: {node: '>=16.13.0'}
1753 | peerDependencies:
1754 | typescript: '>=4.2.0'
1755 | dependencies:
1756 | typescript: 5.2.2
1757 | dev: true
1758 |
1759 | /type-check@0.4.0:
1760 | resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
1761 | engines: {node: '>= 0.8.0'}
1762 | dependencies:
1763 | prelude-ls: 1.2.1
1764 | dev: true
1765 |
1766 | /type-fest@0.20.2:
1767 | resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
1768 | engines: {node: '>=10'}
1769 | dev: true
1770 |
1771 | /typescript@5.0.4:
1772 | resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==}
1773 | engines: {node: '>=12.20'}
1774 | hasBin: true
1775 | dev: true
1776 |
1777 | /typescript@5.2.2:
1778 | resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==}
1779 | engines: {node: '>=14.17'}
1780 | hasBin: true
1781 | dev: true
1782 |
1783 | /uniqid@5.4.0:
1784 | resolution: {integrity: sha512-38JRbJ4Fj94VmnC7G/J/5n5SC7Ab46OM5iNtSstB/ko3l1b5g7ALt4qzHFgGciFkyiRNtDXtLNb+VsxtMSE77A==}
1785 | dev: false
1786 |
1787 | /universalify@0.1.2:
1788 | resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
1789 | engines: {node: '>= 4.0.0'}
1790 | dev: true
1791 |
1792 | /uri-js@4.4.1:
1793 | resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
1794 | dependencies:
1795 | punycode: 2.3.0
1796 | dev: true
1797 |
1798 | /validator@13.11.0:
1799 | resolution: {integrity: sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==}
1800 | engines: {node: '>= 0.10'}
1801 | dev: true
1802 |
1803 | /vite-plugin-dts@3.6.0(typescript@5.2.2)(vite@4.4.11):
1804 | resolution: {integrity: sha512-doxhDRFJCZD2sGjIp4V800nm8Y19GvmwckjG5vYPuiqJ7OBjc9NlW1Vp9Gkyh2aXlUs1jTDRH/lxWfcsPLOQHg==}
1805 | engines: {node: ^14.18.0 || >=16.0.0}
1806 | peerDependencies:
1807 | typescript: '*'
1808 | vite: '*'
1809 | peerDependenciesMeta:
1810 | vite:
1811 | optional: true
1812 | dependencies:
1813 | '@microsoft/api-extractor': 7.38.0
1814 | '@rollup/pluginutils': 5.0.5
1815 | '@vue/language-core': 1.8.19(typescript@5.2.2)
1816 | debug: 4.3.4
1817 | kolorist: 1.8.0
1818 | typescript: 5.2.2
1819 | vite: 4.4.11
1820 | vue-tsc: 1.8.19(typescript@5.2.2)
1821 | transitivePeerDependencies:
1822 | - '@types/node'
1823 | - rollup
1824 | - supports-color
1825 | dev: true
1826 |
1827 | /vite@4.4.11:
1828 | resolution: {integrity: sha512-ksNZJlkcU9b0lBwAGZGGaZHCMqHsc8OpgtoYhsQ4/I2v5cnpmmmqe5pM4nv/4Hn6G/2GhTdj0DhZh2e+Er1q5A==}
1829 | engines: {node: ^14.18.0 || >=16.0.0}
1830 | hasBin: true
1831 | peerDependencies:
1832 | '@types/node': '>= 14'
1833 | less: '*'
1834 | lightningcss: ^1.21.0
1835 | sass: '*'
1836 | stylus: '*'
1837 | sugarss: '*'
1838 | terser: ^5.4.0
1839 | peerDependenciesMeta:
1840 | '@types/node':
1841 | optional: true
1842 | less:
1843 | optional: true
1844 | lightningcss:
1845 | optional: true
1846 | sass:
1847 | optional: true
1848 | stylus:
1849 | optional: true
1850 | sugarss:
1851 | optional: true
1852 | terser:
1853 | optional: true
1854 | dependencies:
1855 | esbuild: 0.18.20
1856 | postcss: 8.4.31
1857 | rollup: 3.29.4
1858 | optionalDependencies:
1859 | fsevents: 2.3.3
1860 | dev: true
1861 |
1862 | /vue-template-compiler@2.7.14:
1863 | resolution: {integrity: sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==}
1864 | dependencies:
1865 | de-indent: 1.0.2
1866 | he: 1.2.0
1867 | dev: true
1868 |
1869 | /vue-tsc@1.8.19(typescript@5.2.2):
1870 | resolution: {integrity: sha512-tacMQLQ0CXAfbhRycCL5sWIy1qujXaIEtP1hIQpzHWOUuICbtTj9gJyFf91PvzG5KCNIkA5Eg7k2Fmgt28l5DQ==}
1871 | hasBin: true
1872 | peerDependencies:
1873 | typescript: '*'
1874 | dependencies:
1875 | '@vue/language-core': 1.8.19(typescript@5.2.2)
1876 | '@vue/typescript': 1.8.19(typescript@5.2.2)
1877 | semver: 7.5.4
1878 | typescript: 5.2.2
1879 | dev: true
1880 |
1881 | /which@2.0.2:
1882 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
1883 | engines: {node: '>= 8'}
1884 | hasBin: true
1885 | dependencies:
1886 | isexe: 2.0.0
1887 | dev: true
1888 |
1889 | /wrappy@1.0.2:
1890 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
1891 | dev: true
1892 |
1893 | /yallist@4.0.0:
1894 | resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
1895 | dev: true
1896 |
1897 | /yocto-queue@0.1.0:
1898 | resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
1899 | engines: {node: '>=10'}
1900 | dev: true
1901 |
1902 | /z-schema@5.0.5:
1903 | resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==}
1904 | engines: {node: '>=8.0.0'}
1905 | hasBin: true
1906 | dependencies:
1907 | lodash.get: 4.4.2
1908 | lodash.isequal: 4.5.0
1909 | validator: 13.11.0
1910 | optionalDependencies:
1911 | commander: 9.5.0
1912 | dev: true
1913 |
--------------------------------------------------------------------------------