diff --git a/backend/gradio_webrtc/__init__.py b/backend/gradio_webrtc/__init__.py
index 306a6e5..2903fed 100644
--- a/backend/gradio_webrtc/__init__.py
+++ b/backend/gradio_webrtc/__init__.py
@@ -1,3 +1,3 @@
-from .webrtc import WebRTC
+from .webrtc import WebRTC, StreamHandler
-__all__ = ["WebRTC"]
+__all__ = ["StreamHandler", "WebRTC"]
diff --git a/backend/gradio_webrtc/utils.py b/backend/gradio_webrtc/utils.py
index d08e9e9..d7f6d4f 100644
--- a/backend/gradio_webrtc/utils.py
+++ b/backend/gradio_webrtc/utils.py
@@ -15,8 +15,7 @@ AUDIO_PTIME = 0.020
def player_worker_decode(
loop,
- callable: Callable,
- stream,
+ next: Callable,
queue: asyncio.Queue,
throttle_playback: bool,
thread_quit: threading.Event,
@@ -33,22 +32,10 @@ def player_worker_decode(
frame_time = None
start_time = time.time()
- generator = None
while not thread_quit.is_set():
- if stream.latest_args == "not_set":
- continue
- if generator is None:
- generator = callable(*stream.latest_args)
- try:
- frame = next(generator)
- except Exception as exc:
- if isinstance(exc, StopIteration):
- logger.debug("Stopping audio stream")
- asyncio.run_coroutine_threadsafe(queue.put(None), loop)
- thread_quit.set()
- break
-
+ frame = next()
+ logger.debug("emitted %s", frame)
# read up to 1 second ahead
if throttle_playback:
elapsed_time = time.time() - start_time
@@ -56,7 +43,7 @@ def player_worker_decode(
time.sleep(0.1)
sample_rate, audio_array = frame
format = "s16" if audio_array.dtype == "int16" else "fltp"
- frame = av.AudioFrame.from_ndarray(audio_array, format=format, layout="mono")
+ frame = av.AudioFrame.from_ndarray(audio_array, format=format, layout="stereo")
frame.sample_rate = sample_rate
for frame in audio_resampler.resample(frame):
# fix timestamps
diff --git a/backend/gradio_webrtc/webrtc.py b/backend/gradio_webrtc/webrtc.py
index a18edbd..955a541 100644
--- a/backend/gradio_webrtc/webrtc.py
+++ b/backend/gradio_webrtc/webrtc.py
@@ -3,6 +3,7 @@
from __future__ import annotations
import asyncio
+from abc import ABC, abstractmethod
import logging
import threading
import time
@@ -10,14 +11,16 @@ import traceback
from collections.abc import Callable
from typing import TYPE_CHECKING, Any, Generator, Literal, Sequence, cast
+import anyio.to_thread
import numpy as np
from aiortc import (
AudioStreamTrack,
RTCPeerConnection,
RTCSessionDescription,
VideoStreamTrack,
+ MediaStreamTrack,
)
-from aiortc.contrib.media import MediaRelay, VideoFrame # type: ignore
+from aiortc.contrib.media import MediaRelay, AudioFrame, VideoFrame # type: ignore
from aiortc.mediastreams import MediaStreamError
from gradio import wasm_utils
from gradio.components.base import Component, server
@@ -47,7 +50,7 @@ class VideoCallback(VideoStreamTrack):
def __init__(
self,
- track,
+ track: MediaStreamTrack,
event_handler: Callable,
) -> None:
super().__init__() # don't forget this!
@@ -72,7 +75,7 @@ class VideoCallback(VideoStreamTrack):
async def recv(self):
try:
try:
- frame = await self.track.recv()
+ frame = cast(VideoFrame, await self.track.recv())
except MediaStreamError:
return
frame_array = frame.to_ndarray(format="bgr24")
@@ -100,6 +103,100 @@ class VideoCallback(VideoStreamTrack):
logger.debug(exec)
+class StreamHandler(ABC):
+ @abstractmethod
+ def receive(self, frame: tuple[int, np.ndarray] | np.ndarray) -> None:
+ pass
+
+ @abstractmethod
+ def emit(self) -> None:
+ pass
+
+
+class AudioCallback(AudioStreamTrack):
+ kind = "audio"
+
+ def __init__(
+ self,
+ track: MediaStreamTrack,
+ event_handler: StreamHandler,
+ ) -> None:
+ self.track = track
+ self.event_handler = event_handler
+ self.current_timestamp = 0
+ self.latest_args = "not_set"
+ self.queue = asyncio.Queue()
+ self.thread_quit = threading.Event()
+ self.__thread = None
+ self._start: float | None = None
+ self.has_started = False
+ super().__init__()
+
+ async def process_input_frames(self) -> None:
+ while not self.thread_quit.is_set():
+ try:
+ frame = cast(AudioFrame, await self.track.recv())
+ numpy_array = frame.to_ndarray()
+ logger.debug("numpy array shape %s", numpy_array.shape)
+ await anyio.to_thread.run_sync(
+ self.event_handler.receive, (frame.sample_rate, numpy_array)
+ )
+ except MediaStreamError:
+ break
+
+ def start(self):
+ if not self.has_started:
+ asyncio.create_task(self.process_input_frames())
+ self.__thread = threading.Thread(
+ name="audio-output-decoders",
+ target=player_worker_decode,
+ args=(
+ asyncio.get_event_loop(),
+ self.event_handler.emit,
+ self.queue,
+ True,
+ self.thread_quit,
+ ),
+ )
+ self.__thread.start()
+ self.has_started = True
+
+ async def recv(self):
+ try:
+ if self.readyState != "live":
+ raise MediaStreamError
+
+ self.start()
+ data = await self.queue.get()
+ logger.debug("data %s", data)
+ if data is None:
+ self.stop()
+ return
+
+ data_time = data.time
+
+ # control playback rate
+ if data_time is not None:
+ if self._start is None:
+ self._start = time.time() - data_time
+ else:
+ wait = self._start + data_time - time.time()
+ await asyncio.sleep(wait)
+
+ return data
+ except Exception as e:
+ logger.debug(e)
+ exec = traceback.format_exc()
+ logger.debug(exec)
+
+ def stop(self):
+ self.thread_quit.set()
+ if self.__thread is not None:
+ self.__thread.join()
+ self.__thread = None
+ super().stop()
+
+
class ServerToClientVideo(VideoStreamTrack):
"""
This works for streaming input and output
@@ -116,17 +213,6 @@ class ServerToClientVideo(VideoStreamTrack):
self.latest_args: str | list[Any] = "not_set"
self.generator: Generator[Any, None, Any] | None = None
- def add_frame_to_payload(
- self, args: list[Any], frame: np.ndarray | None
- ) -> list[Any]:
- new_args = []
- for val in args:
- if isinstance(val, str) and val == "__webrtc_value__":
- new_args.append(frame)
- else:
- new_args.append(val)
- return new_args
-
def array_to_frame(self, array: np.ndarray) -> VideoFrame:
return VideoFrame.from_ndarray(array, format="bgr24")
@@ -176,6 +262,25 @@ class ServerToClientAudio(AudioStreamTrack):
self._start: float | None = None
super().__init__()
+ def next(self) -> tuple[int, np.ndarray] | None:
+ import anyio
+
+ if self.latest_args == "not_set":
+ return
+ if self.generator is None:
+ self.generator = self.event_handler(*self.latest_args)
+ if self.generator is not None:
+ try:
+ frame = next(self.generator)
+ return frame
+ except Exception as exc:
+ if isinstance(exc, StopIteration):
+ logger.debug("Stopping audio stream")
+ asyncio.run_coroutine_threadsafe(
+ self.queue.put(None), asyncio.get_event_loop()
+ )
+ self.thread_quit.set()
+
def start(self):
if self.__thread is None:
self.__thread = threading.Thread(
@@ -183,8 +288,7 @@ class ServerToClientAudio(AudioStreamTrack):
target=player_worker_decode,
args=(
asyncio.get_event_loop(),
- self.event_handler,
- self,
+ self.next,
self.queue,
False,
self.thread_quit,
@@ -241,7 +345,7 @@ class WebRTC(Component):
pcs: set[RTCPeerConnection] = set([])
relay = MediaRelay()
connections: dict[
- str, VideoCallback | ServerToClientVideo | ServerToClientAudio
+ str, VideoCallback | ServerToClientVideo | ServerToClientAudio | AudioCallback
] = {}
EVENTS = ["tick"]
@@ -300,9 +404,6 @@ class WebRTC(Component):
streaming: when used set as an output, takes video chunks yielded from the backend and combines them into one streaming video output. Each chunk should be a video file with a .ts extension using an h.264 encoding. Mp4 files are also accepted but they will be converted to h.264 encoding.
watermark: an image file to be included as a watermark on the video. The image is not scaled and is displayed on the bottom right of the video. Valid formats for the image are: jpeg, png.
"""
- if modality == "audio" and mode == "send-receive":
- raise ValueError("Audio modality is not supported in send-receive mode")
-
self.time_limit = time_limit
self.height = height
self.width = width
@@ -358,7 +459,7 @@ class WebRTC(Component):
def stream(
self,
- fn: Callable[..., Any] | None = None,
+ fn: Callable[..., Any] | StreamHandler | None = None,
inputs: Block | Sequence[Block] | set[Block] | None = None,
outputs: Block | Sequence[Block] | set[Block] | None = None,
js: str | None = None,
@@ -384,6 +485,15 @@ class WebRTC(Component):
self.event_handler = fn
self.time_limit = time_limit
+ if (
+ self.mode == "send-receive"
+ and self.modality == "audio"
+ and not isinstance(self.event_handler, StreamHandler)
+ ):
+ raise ValueError(
+ "In the send-receive mode for audio, the event handler must be an instance of StreamHandler."
+ )
+
if self.mode == "send-receive":
if cast(list[Block], inputs)[0] != self:
raise ValueError(
@@ -439,7 +549,7 @@ class WebRTC(Component):
@server
async def offer(self, body):
logger.debug("Starting to handle offer")
- logger.debug("Offer body", body)
+ logger.debug("Offer body %s", body)
if len(self.connections) >= cast(int, self.concurrency_limit):
return {"status": "failed"}
@@ -450,7 +560,7 @@ class WebRTC(Component):
@pc.on("iceconnectionstatechange")
async def on_iceconnectionstatechange():
- logger.debug("ICE connection state change", pc.iceConnectionState)
+ logger.debug("ICE connection state change %s", pc.iceConnectionState)
if pc.iceConnectionState == "failed":
await pc.close()
self.connections.pop(body["webrtc_id"], None)
@@ -468,12 +578,19 @@ class WebRTC(Component):
@pc.on("track")
def on_track(track):
- cb = VideoCallback(
- self.relay.subscribe(track),
- event_handler=cast(Callable, self.event_handler),
- )
+ relay = MediaRelay()
+ if self.modality == "video":
+ cb = VideoCallback(
+ relay.subscribe(track),
+ event_handler=cast(Callable, self.event_handler),
+ )
+ elif self.modality == "audio":
+ cb = AudioCallback(
+ relay.subscribe(track),
+ event_handler=cast(StreamHandler, self.event_handler),
+ )
self.connections[body["webrtc_id"]] = cb
- logger.debug("Adding track to peer connection", cb)
+ logger.debug("Adding track to peer connection %s", cb)
pc.addTrack(cb)
if self.mode == "receive":
@@ -482,7 +599,7 @@ class WebRTC(Component):
elif self.modality == "audio":
cb = ServerToClientAudio(cast(Callable, self.event_handler))
- logger.debug("Adding track to peer connection", cb)
+ logger.debug("Adding track to peer connection %s", cb)
pc.addTrack(cb)
self.connections[body["webrtc_id"]] = cb
cb.on("ended", lambda: self.connections.pop(body["webrtc_id"], None))
diff --git a/demo/app.py b/demo/app.py
index 3489fab..12e3204 100644
--- a/demo/app.py
+++ b/demo/app.py
@@ -1,72 +1,63 @@
+import logging
+
+# Configure the root logger to WARNING to suppress debug messages from other libraries
+logging.basicConfig(level=logging.WARNING)
+
+# Create a console handler
+console_handler = logging.StreamHandler()
+console_handler.setLevel(logging.DEBUG)
+
+# Create a formatter
+formatter = logging.Formatter("%(name)s - %(levelname)s - %(message)s")
+console_handler.setFormatter(formatter)
+
+# Configure the logger for your specific library
+logger = logging.getLogger("gradio_webrtc")
+logger.setLevel(logging.DEBUG)
+logger.addHandler(console_handler)
+
+
import gradio as gr
-import cv2
-from huggingface_hub import hf_hub_download
-from gradio_webrtc import WebRTC
-from twilio.rest import Client
-import os
-from inference import YOLOv10
-
-model_file = hf_hub_download(
- repo_id="onnx-community/yolov10n", filename="onnx/model.onnx"
-)
-
-model = YOLOv10(model_file)
-
-account_sid = os.environ.get("TWILIO_ACCOUNT_SID")
-auth_token = os.environ.get("TWILIO_AUTH_TOKEN")
-
-if account_sid and auth_token:
- client = Client(account_sid, auth_token)
-
- token = client.tokens.create()
-
- rtc_configuration = {
- "iceServers": token.ice_servers,
- "iceTransportPolicy": "relay",
- }
-else:
- rtc_configuration = None
+import numpy as np
+from gradio_webrtc import WebRTC, StreamHandler
+from queue import Queue
+import time
-def detection(image, conf_threshold=0.3):
- image = cv2.resize(image, (model.input_width, model.input_height))
- new_image = model.detect_objects(image, conf_threshold)
- return cv2.resize(new_image, (500, 500))
+class EchoHandler(StreamHandler):
+ def __init__(self) -> None:
+ self.queue = Queue()
+
+ def receive(self, frame: tuple[int, np.ndarray] | np.ndarray) -> None:
+ self.queue.put(frame)
+
+ def emit(self) -> None:
+ return self.queue.get()
css = """.my-group {max-width: 600px !important; max-height: 600 !important;}
.my-column {display: flex !important; justify-content: center !important; align-items: center !important};"""
-with gr.Blocks(css=css) as demo:
+with gr.Blocks() as demo:
gr.HTML(
"""
- YOLOv10 Webcam Stream (Powered by WebRTC ⚡️)
+ Audio Streaming (Powered by WebRTC ⚡️)
"""
)
- gr.HTML(
- """
-
- """
- )
with gr.Column(elem_classes=["my-column"]):
with gr.Group(elem_classes=["my-group"]):
- image = WebRTC(label="Stream", rtc_configuration=rtc_configuration)
- conf_threshold = gr.Slider(
- label="Confidence Threshold",
- minimum=0.0,
- maximum=1.0,
- step=0.05,
- value=0.30,
+ audio = WebRTC(
+ label="Stream",
+ rtc_configuration=None,
+ mode="send-receive",
+ modality="audio",
)
- image.stream(
- fn=detection, inputs=[image, conf_threshold], outputs=[image], time_limit=10
- )
+ audio.stream(fn=EchoHandler(), inputs=[audio], outputs=[audio], time_limit=15)
+
if __name__ == "__main__":
demo.launch()
diff --git a/demo/audio_out.py b/demo/audio_out.py
index a66d41c..b2da4a8 100644
--- a/demo/audio_out.py
+++ b/demo/audio_out.py
@@ -6,7 +6,6 @@ import os
from pydub import AudioSegment
-
account_sid = os.environ.get("TWILIO_ACCOUNT_SID")
auth_token = os.environ.get("TWILIO_AUTH_TOKEN")
@@ -24,10 +23,16 @@ else:
import time
+
def generation(num_steps):
for _ in range(num_steps):
- segment = AudioSegment.from_file("/Users/freddy/sources/gradio/demo/audio_debugger/cantina.wav")
- yield (segment.frame_rate, np.array(segment.get_array_of_samples()).reshape(1, -1))
+ segment = AudioSegment.from_file(
+ "/Users/freddy/sources/gradio/demo/audio_debugger/cantina.wav"
+ )
+ yield (
+ segment.frame_rate,
+ np.array(segment.get_array_of_samples()).reshape(1, -1),
+ )
time.sleep(3.5)
@@ -45,8 +50,12 @@ with gr.Blocks() as demo:
)
with gr.Column(elem_classes=["my-column"]):
with gr.Group(elem_classes=["my-group"]):
- audio = WebRTC(label="Stream", rtc_configuration=rtc_configuration,
- mode="receive", modality="audio")
+ audio = WebRTC(
+ label="Stream",
+ rtc_configuration=rtc_configuration,
+ mode="receive",
+ modality="audio",
+ )
num_steps = gr.Slider(
label="Number of Steps",
minimum=1,
@@ -57,8 +66,7 @@ with gr.Blocks() as demo:
button = gr.Button("Generate")
audio.stream(
- fn=generation, inputs=[num_steps], outputs=[audio],
- trigger=button.click
+ fn=generation, inputs=[num_steps], outputs=[audio], trigger=button.click
)
diff --git a/demo/audio_out_2.py b/demo/audio_out_2.py
index ef43b6b..ec885b3 100644
--- a/demo/audio_out_2.py
+++ b/demo/audio_out_2.py
@@ -6,7 +6,6 @@ import os
from pydub import AudioSegment
-
account_sid = os.environ.get("TWILIO_ACCOUNT_SID")
auth_token = os.environ.get("TWILIO_AUTH_TOKEN")
@@ -24,10 +23,16 @@ else:
import time
+
def generation(num_steps):
for _ in range(num_steps):
- segment = AudioSegment.from_file("/Users/freddy/sources/gradio/demo/audio_debugger/cantina.wav")
- yield (segment.frame_rate, np.array(segment.get_array_of_samples()).reshape(1, -1))
+ segment = AudioSegment.from_file(
+ "/Users/freddy/sources/gradio/demo/audio_debugger/cantina.wav"
+ )
+ yield (
+ segment.frame_rate,
+ np.array(segment.get_array_of_samples()).reshape(1, -1),
+ )
time.sleep(3.5)
@@ -48,9 +53,12 @@ with gr.Blocks() as demo:
gr.Slider()
with gr.Column():
# audio = gr.Audio(interactive=False)
- audio = WebRTC(label="Stream", rtc_configuration=rtc_configuration,
- mode="receive", modality="audio")
-
+ audio = WebRTC(
+ label="Stream",
+ rtc_configuration=rtc_configuration,
+ mode="receive",
+ modality="audio",
+ )
if __name__ == "__main__":
diff --git a/demo/space.py b/demo/space.py
index a0a85f2..36a54de 100644
--- a/demo/space.py
+++ b/demo/space.py
@@ -1,26 +1,91 @@
-
import gradio as gr
import os
-_docs = {'WebRTC':
- {'description': 'Stream audio/video with WebRTC',
- 'members': {'__init__':
- {
- 'rtc_configuration': {'type': 'dict[str, Any] | None', 'default': 'None', 'description': "The configration dictionary to pass to the RTCPeerConnection constructor. If None, the default configuration is used."},
- 'height': {'type': 'int | str | None', 'default': 'None', 'description': 'The height of the component, specified in pixels if a number is passed, or in CSS units if a string is passed. This has no effect on the preprocessed video file, but will affect the displayed video.'},
- 'width': {'type': 'int | str | None', 'default': 'None', 'description': 'The width of the component, specified in pixels if a number is passed, or in CSS units if a string is passed. This has no effect on the preprocessed video file, but will affect the displayed video.'},
- 'label': {'type': 'str | None', 'default': 'None', 'description': 'the label for this component. Appears above the component and is also used as the header if there are a table of examples for this component. If None and used in a `gr.Interface`, the label will be the name of the parameter this component is assigned to.'},
- 'show_label': {'type': 'bool | None', 'default': 'None', 'description': 'if True, will display label.'}, 'container': {'type': 'bool', 'default': 'True', 'description': 'if True, will place the component in a container - providing some extra padding around the border.'},
- 'scale': {'type': 'int | None', 'default': 'None', 'description': 'relative size compared to adjacent Components. For example if Components A and B are in a Row, and A has scale=2, and B has scale=1, A will be twice as wide as B. Should be an integer. scale applies in Rows, and to top-level Components in Blocks where fill_height=True.'},
- 'min_width': {'type': 'int', 'default': '160', 'description': 'minimum pixel width, will wrap if not sufficient screen space to satisfy this value. If a certain scale value results in this Component being narrower than min_width, the min_width parameter will be respected first.'},
- 'interactive': {'type': 'bool | None', 'default': 'None', 'description': 'if True, will allow users to upload a video; if False, can only be used to display videos. If not provided, this is inferred based on whether the component is used as an input or output.'}, 'visible': {'type': 'bool', 'default': 'True', 'description': 'if False, component will be hidden.'},
- 'elem_id': {'type': 'str | None', 'default': 'None', 'description': 'an optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.'},
- 'elem_classes': {'type': 'list[str] | str | None', 'default': 'None', 'description': 'an optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.'},
- 'render': {'type': 'bool', 'default': 'True', 'description': 'if False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.'},
- 'key': {'type': 'int | str | None', 'default': 'None', 'description': 'if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.'},
- 'mirror_webcam': {'type': 'bool', 'default': 'True', 'description': 'if True webcam will be mirrored. Default is True.'},
- },
- 'events': {'tick': {'type': None, 'default': None, 'description': ''}}}, '__meta__': {'additional_interfaces': {}, 'user_fn_refs': {'WebRTC': []}}}
+_docs = {
+ "WebRTC": {
+ "description": "Stream audio/video with WebRTC",
+ "members": {
+ "__init__": {
+ "rtc_configuration": {
+ "type": "dict[str, Any] | None",
+ "default": "None",
+ "description": "The configration dictionary to pass to the RTCPeerConnection constructor. If None, the default configuration is used.",
+ },
+ "height": {
+ "type": "int | str | None",
+ "default": "None",
+ "description": "The height of the component, specified in pixels if a number is passed, or in CSS units if a string is passed. This has no effect on the preprocessed video file, but will affect the displayed video.",
+ },
+ "width": {
+ "type": "int | str | None",
+ "default": "None",
+ "description": "The width of the component, specified in pixels if a number is passed, or in CSS units if a string is passed. This has no effect on the preprocessed video file, but will affect the displayed video.",
+ },
+ "label": {
+ "type": "str | None",
+ "default": "None",
+ "description": "the label for this component. Appears above the component and is also used as the header if there are a table of examples for this component. If None and used in a `gr.Interface`, the label will be the name of the parameter this component is assigned to.",
+ },
+ "show_label": {
+ "type": "bool | None",
+ "default": "None",
+ "description": "if True, will display label.",
+ },
+ "container": {
+ "type": "bool",
+ "default": "True",
+ "description": "if True, will place the component in a container - providing some extra padding around the border.",
+ },
+ "scale": {
+ "type": "int | None",
+ "default": "None",
+ "description": "relative size compared to adjacent Components. For example if Components A and B are in a Row, and A has scale=2, and B has scale=1, A will be twice as wide as B. Should be an integer. scale applies in Rows, and to top-level Components in Blocks where fill_height=True.",
+ },
+ "min_width": {
+ "type": "int",
+ "default": "160",
+ "description": "minimum pixel width, will wrap if not sufficient screen space to satisfy this value. If a certain scale value results in this Component being narrower than min_width, the min_width parameter will be respected first.",
+ },
+ "interactive": {
+ "type": "bool | None",
+ "default": "None",
+ "description": "if True, will allow users to upload a video; if False, can only be used to display videos. If not provided, this is inferred based on whether the component is used as an input or output.",
+ },
+ "visible": {
+ "type": "bool",
+ "default": "True",
+ "description": "if False, component will be hidden.",
+ },
+ "elem_id": {
+ "type": "str | None",
+ "default": "None",
+ "description": "an optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.",
+ },
+ "elem_classes": {
+ "type": "list[str] | str | None",
+ "default": "None",
+ "description": "an optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.",
+ },
+ "render": {
+ "type": "bool",
+ "default": "True",
+ "description": "if False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.",
+ },
+ "key": {
+ "type": "int | str | None",
+ "default": "None",
+ "description": "if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.",
+ },
+ "mirror_webcam": {
+ "type": "bool",
+ "default": "True",
+ "description": "if True webcam will be mirrored. Default is True.",
+ },
+ },
+ "events": {"tick": {"type": None, "default": None, "description": ""}},
+ },
+ "__meta__": {"additional_interfaces": {}, "user_fn_refs": {"WebRTC": []}},
+ }
}
@@ -36,16 +101,19 @@ with gr.Blocks(
),
) as demo:
gr.Markdown(
-"""
+ """
Gradio WebRTC ⚡️
-""", elem_classes=["md-custom"], header_links=True)
+""",
+ elem_classes=["md-custom"],
+ header_links=True,
+ )
gr.Markdown(
-"""
+ """
## Installation
```bash
@@ -195,17 +263,24 @@ with gr.Blocks() as demo:
rtc = WebRTC(rtc_configuration=rtc_configuration, ...)
...
```
-""", elem_classes=["md-custom"], header_links=True)
+""",
+ elem_classes=["md-custom"],
+ header_links=True,
+ )
-
- gr.Markdown("""
+ gr.Markdown(
+ """
##
-""", elem_classes=["md-custom"], header_links=True)
+""",
+ elem_classes=["md-custom"],
+ header_links=True,
+ )
gr.ParamViewer(value=_docs["WebRTC"]["members"]["__init__"], linkify=[])
-
- demo.load(None, js=r"""function() {
+ demo.load(
+ None,
+ js=r"""function() {
const refs = {};
const user_fn_refs = {
WebRTC: [], };
@@ -239,6 +314,7 @@ with gr.Blocks() as demo:
})
}
-""")
+""",
+ )
demo.launch()
diff --git a/demo/video_out.py b/demo/video_out.py
index 082e193..298614d 100644
--- a/demo/video_out.py
+++ b/demo/video_out.py
@@ -24,7 +24,6 @@ else:
def generation(input_video):
cap = cv2.VideoCapture(input_video)
-
iterating = True
while iterating:
@@ -35,6 +34,7 @@ def generation(input_video):
display_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
yield display_frame
+
with gr.Blocks() as demo:
gr.HTML(
"""
@@ -47,11 +47,17 @@ with gr.Blocks() as demo:
with gr.Column():
input_video = gr.Video(sources="upload")
with gr.Column():
- output_video = WebRTC(label="Video Stream", rtc_configuration=rtc_configuration,
- mode="receive", modality="video")
+ output_video = WebRTC(
+ label="Video Stream",
+ rtc_configuration=rtc_configuration,
+ mode="receive",
+ modality="video",
+ )
output_video.stream(
- fn=generation, inputs=[input_video], outputs=[output_video],
- trigger=input_video.upload
+ fn=generation,
+ inputs=[input_video],
+ outputs=[output_video],
+ trigger=input_video.upload,
)
diff --git a/demo/video_out_stream.py b/demo/video_out_stream.py
index 1aeb4d6..49461ed 100644
--- a/demo/video_out_stream.py
+++ b/demo/video_out_stream.py
@@ -30,7 +30,6 @@ def generation():
yield frame
-
with gr.Blocks() as demo:
gr.HTML(
"""
@@ -39,12 +38,15 @@ with gr.Blocks() as demo:
"""
)
- output_video = WebRTC(label="Video Stream", rtc_configuration=rtc_configuration,
- mode="receive", modality="video")
+ output_video = WebRTC(
+ label="Video Stream",
+ rtc_configuration=rtc_configuration,
+ mode="receive",
+ modality="video",
+ )
button = gr.Button("Start", variant="primary")
output_video.stream(
- fn=generation, inputs=None, outputs=[output_video],
- trigger=button.click
+ fn=generation, inputs=None, outputs=[output_video], trigger=button.click
)
diff --git a/frontend/Index.svelte b/frontend/Index.svelte
index 4d14ea8..b3ba5db 100644
--- a/frontend/Index.svelte
+++ b/frontend/Index.svelte
@@ -7,6 +7,7 @@
import type { LoadingStatus } from "@gradio/statustracker";
import StaticVideo from "./shared/StaticVideo.svelte";
import StaticAudio from "./shared/StaticAudio.svelte";
+ import InteractiveAudio from "./shared/InteractiveAudio.svelte";
export let elem_id = "";
export let elem_classes: string[] = [];
@@ -37,8 +38,7 @@
$: console.log("value", value);
-{#if mode == "receive" && modality === "video"}
- gradio.dispatch("clear_status", loading_status)}
/>
+ {#if mode == "receive" && modality === "video"}
gradio.dispatch("tick")}
on:error={({ detail }) => gradio.dispatch("error", detail)}
/>
-
-
-{:else if mode == "receive" && modality === "audio"}
-
- gradio.dispatch("clear_status", loading_status)}
- />
+ {:else if mode == "receive" && modality === "audio"}
gradio.dispatch("tick")}
on:error={({ detail }) => gradio.dispatch("error", detail)}
/>
-
-{:else if mode === "send-receive" && modality === "video"}
-
- gradio.dispatch("clear_status", loading_status)}
- />
+ {:else if mode === "send-receive" && modality === "video"}
-
-{/if}
+ {:else if mode === "send-receive" && modality === "audio"}
+ gradio.dispatch("tick")}
+ on:error={({ detail }) => gradio.dispatch("error", detail)}
+ />
+ {/if}
+
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 6e7e181..bd606ac 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -11,15 +11,15 @@
"dependencies": {
"@ffmpeg/ffmpeg": "^0.12.10",
"@ffmpeg/util": "^0.12.1",
- "@gradio/atoms": "0.9.0",
- "@gradio/client": "1.6.0",
+ "@gradio/atoms": "0.9.2",
+ "@gradio/client": "1.7.0",
"@gradio/icons": "0.8.0",
- "@gradio/image": "0.16.0",
- "@gradio/markdown": "^0.10.0",
- "@gradio/statustracker": "0.8.0",
- "@gradio/upload": "0.13.0",
+ "@gradio/image": "0.16.4",
+ "@gradio/markdown": "^0.10.3",
+ "@gradio/statustracker": "0.9.1",
+ "@gradio/upload": "0.13.3",
"@gradio/utils": "0.7.0",
- "@gradio/wasm": "0.14.0",
+ "@gradio/wasm": "0.14.2",
"hls.js": "^1.5.16",
"mrmime": "^2.0.0"
},
@@ -49,30 +49,30 @@
}
},
"node_modules/@babel/helper-string-parser": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
- "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==",
+ "version": "7.25.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz",
+ "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==",
"dev": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
- "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
+ "version": "7.25.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz",
+ "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==",
"dev": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz",
- "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==",
+ "version": "7.25.8",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.8.tgz",
+ "integrity": "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==",
"dev": true,
"dependencies": {
- "@babel/types": "^7.25.6"
+ "@babel/types": "^7.25.8"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -82,13 +82,13 @@
}
},
"node_modules/@babel/types": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz",
- "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==",
+ "version": "7.25.8",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz",
+ "integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==",
"dev": true,
"dependencies": {
- "@babel/helper-string-parser": "^7.24.8",
- "@babel/helper-validator-identifier": "^7.24.7",
+ "@babel/helper-string-parser": "^7.25.7",
+ "@babel/helper-validator-identifier": "^7.25.7",
"to-fast-properties": "^2.0.0"
},
"engines": {
@@ -120,6 +120,20 @@
"tough-cookie": "^4.1.4"
}
},
+ "node_modules/@bundled-es-modules/tough-cookie/node_modules/tough-cookie": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz",
+ "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==",
+ "dependencies": {
+ "psl": "^1.1.33",
+ "punycode": "^2.1.1",
+ "universalify": "^0.2.0",
+ "url-parse": "^1.5.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/@esbuild/aix-ppc64": {
"version": "0.19.12",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz",
@@ -538,11 +552,12 @@
}
},
"node_modules/@gradio/atoms": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/@gradio/atoms/-/atoms-0.9.0.tgz",
- "integrity": "sha512-dIrMl4py7+1s1on52MwCeFq1p07IjbJWg3Y2vR+5FlwjQtQ3hPhP/KH+PrL94WchsUnF6aE2DV7LpjbnZvGtrQ==",
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/@gradio/atoms/-/atoms-0.9.2.tgz",
+ "integrity": "sha512-P4+XXBl7S3JfmggMaFc/Ni9si9GtKMRE74HkG6C76HKJfszhnAV2/u/sS87+fe5NffU8CgS0R47FwxUSKMsm5g==",
"dependencies": {
"@gradio/icons": "^0.8.0",
+ "@gradio/markdown": "^0.10.3",
"@gradio/utils": "^0.7.0"
},
"peerDependencies": {
@@ -550,9 +565,9 @@
}
},
"node_modules/@gradio/client": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@gradio/client/-/client-1.6.0.tgz",
- "integrity": "sha512-1258LcF45FFjGCjcn37zDZD1dRrsApTogc7fD9jlSBN8x61s0MPzz6LRCefD2DZ1Is3G+pRu7M6w6XrBNyVVmA==",
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/@gradio/client/-/client-1.7.0.tgz",
+ "integrity": "sha512-yRo7qU4zz8ZT61L1LFy+dSU5M0L6UzpMYWIdryHskvd4DbnhpXOj0LMYH/r1Snb61YBUJYIPOSzAJV1YP1Tkug==",
"dependencies": {
"@types/eventsource": "^1.1.15",
"bufferutil": "^4.0.7",
@@ -577,17 +592,17 @@
}
},
"node_modules/@gradio/image": {
- "version": "0.16.0",
- "resolved": "https://registry.npmjs.org/@gradio/image/-/image-0.16.0.tgz",
- "integrity": "sha512-FONnsxAvJPDGJ8DMFhMrdCiQkCP9m+9NoO3nh5I5mE26Q5bioN+Wdwu/IgQkJVbxo3iok8vu+R2J1jqqB0WM8A==",
+ "version": "0.16.4",
+ "resolved": "https://registry.npmjs.org/@gradio/image/-/image-0.16.4.tgz",
+ "integrity": "sha512-BKH3FHe/N/nyRww4/Gm9uSYfkFjmVQSQAZDq5ONpFNHAoOOA6+SjjWJq6yY1vM9SaAMkMQreLN0eugbOiQwwxw==",
"dependencies": {
- "@gradio/atoms": "^0.9.0",
- "@gradio/client": "^1.6.0",
+ "@gradio/atoms": "^0.9.2",
+ "@gradio/client": "^1.7.0",
"@gradio/icons": "^0.8.0",
- "@gradio/statustracker": "^0.8.0",
- "@gradio/upload": "^0.13.0",
+ "@gradio/statustracker": "^0.9.1",
+ "@gradio/upload": "^0.13.3",
"@gradio/utils": "^0.7.0",
- "@gradio/wasm": "^0.14.0",
+ "@gradio/wasm": "^0.14.2",
"cropperjs": "^1.5.12",
"lazy-brush": "^1.0.1",
"resize-observer-polyfill": "^1.5.1"
@@ -597,18 +612,18 @@
}
},
"node_modules/@gradio/markdown": {
- "version": "0.10.0",
- "resolved": "https://registry.npmjs.org/@gradio/markdown/-/markdown-0.10.0.tgz",
- "integrity": "sha512-ge2aoFWI+Fw/qQfwm1z9OwCBRBmHbOVdK9GSD/1EMURdMpTiYd9SiyaUk7OzJXFSpBxjRQEwejQQL+AjJ7X9KQ==",
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/@gradio/markdown/-/markdown-0.10.3.tgz",
+ "integrity": "sha512-qSywsn/tpnSL1kWPX3+SyeDoYke3y19mU9dxny7ZHn8gT3qdiYOY5Xgs1qcHXd7JEkJKsMkRdEMedziaFhwp1w==",
"dependencies": {
- "@gradio/atoms": "^0.9.0",
+ "@gradio/atoms": "^0.9.2",
"@gradio/icons": "^0.8.0",
- "@gradio/statustracker": "^0.8.0",
+ "@gradio/sanitize": "^0.1.1",
+ "@gradio/statustracker": "^0.9.1",
"@gradio/utils": "^0.7.0",
"@types/dompurify": "^3.0.2",
"@types/katex": "^0.16.0",
"@types/prismjs": "1.26.4",
- "amuchina": "^1.0.12",
"dom-parser": "^1.1.5",
"github-slugger": "^2.0.0",
"isomorphic-dompurify": "^2.14.0",
@@ -616,8 +631,7 @@
"marked": "^12.0.0",
"marked-gfm-heading-id": "^3.1.2",
"marked-highlight": "^2.0.1",
- "prismjs": "1.29.0",
- "sanitize-html": "^2.13.0"
+ "prismjs": "1.29.0"
},
"peerDependencies": {
"svelte": "^4.0.0"
@@ -679,12 +693,21 @@
"url": "https://opencollective.com/stylus"
}
},
- "node_modules/@gradio/statustracker": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/@gradio/statustracker/-/statustracker-0.8.0.tgz",
- "integrity": "sha512-qQqK03OWOiISJOOR8GTB+t3Ls/LonrtBiZWcTzH0FhmXlJUYGN/vRhgg0oc9ZpLuXutTbCvNcKEu+3PPKFIolA==",
+ "node_modules/@gradio/sanitize": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@gradio/sanitize/-/sanitize-0.1.1.tgz",
+ "integrity": "sha512-7OpCtsFSlAcpEQwRLrWvJVWJrvjrEL/eE4JzBc0PATm2rV5hbKbEHq42QqNubOyrvJTQN41u0B+nxQMrrGruLA==",
"dependencies": {
- "@gradio/atoms": "^0.9.0",
+ "amuchina": "^1.0.12",
+ "sanitize-html": "^2.13.0"
+ }
+ },
+ "node_modules/@gradio/statustracker": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/@gradio/statustracker/-/statustracker-0.9.1.tgz",
+ "integrity": "sha512-Iz36z1MrA22oCDgxHdUQFT8U+jkPYdGM1kbq+jaCMTbnSg9Y/+oppyBcUV7vBFUGcBgi6WV7KqxmMCK+whTfbw==",
+ "dependencies": {
+ "@gradio/atoms": "^0.9.2",
"@gradio/icons": "^0.8.0",
"@gradio/utils": "^0.7.0",
"@types/dompurify": "^3.0.2",
@@ -703,15 +726,15 @@
}
},
"node_modules/@gradio/upload": {
- "version": "0.13.0",
- "resolved": "https://registry.npmjs.org/@gradio/upload/-/upload-0.13.0.tgz",
- "integrity": "sha512-BMBlCWDxTrZ0rNYr2Gxolvlz1Zp+cEbAP1SVhL87g0y5/5A1dO1ZporBdPRcoST57P2ApvqZPpR1HyDAy+iKvA==",
+ "version": "0.13.3",
+ "resolved": "https://registry.npmjs.org/@gradio/upload/-/upload-0.13.3.tgz",
+ "integrity": "sha512-ObL0vxWTghT07yWs2U1SQ5uILAKm9riZ5ys5dhn3kJZUsA7Pi55IUxcLA8NOIn2CnGHRKhHmyy8xe0UuTJ0qMw==",
"dependencies": {
- "@gradio/atoms": "^0.9.0",
- "@gradio/client": "^1.6.0",
+ "@gradio/atoms": "^0.9.2",
+ "@gradio/client": "^1.7.0",
"@gradio/icons": "^0.8.0",
"@gradio/utils": "^0.7.0",
- "@gradio/wasm": "^0.14.0"
+ "@gradio/wasm": "^0.14.2"
},
"peerDependencies": {
"svelte": "^4.0.0"
@@ -727,9 +750,9 @@
}
},
"node_modules/@gradio/wasm": {
- "version": "0.14.0",
- "resolved": "https://registry.npmjs.org/@gradio/wasm/-/wasm-0.14.0.tgz",
- "integrity": "sha512-7APLdin+K5iriVnG79pfdl5wVb9whoVoe8i/Nio8d/zczKae+aN/HPkAqSEAgb2pJl7BqhfaQ4BzHkzr74F4NA==",
+ "version": "0.14.2",
+ "resolved": "https://registry.npmjs.org/@gradio/wasm/-/wasm-0.14.2.tgz",
+ "integrity": "sha512-oaGYQFvD5QFizoJbD/OJzURqBhWXGo/3QTXjh53cL6hlzxee4r2nREw8qHFCJ8kKAKfvuF/9cdBrJkEm9XqLeg==",
"dependencies": {
"@types/path-browserify": "^1.0.0",
"path-browserify": "^1.0.1",
@@ -785,9 +808,9 @@
}
},
"node_modules/@inquirer/figures": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.6.tgz",
- "integrity": "sha512-yfZzps3Cso2UbM7WlxKwZQh2Hs6plrbjs1QnzQDZhK2DgyCo6D8AaHps9olkNcUFlcYERMqU3uJSp1gmy3s/qQ==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.7.tgz",
+ "integrity": "sha512-m+Trk77mp54Zma6xLkLuY+mvanPxlE4A7yNKs2HBiyZ4UkVs28Mv5c/pgWrHeInx+USHeX/WEPzjrWrcJiQgjw==",
"engines": {
"node": ">=18"
}
@@ -943,9 +966,9 @@
}
},
"node_modules/@mswjs/interceptors": {
- "version": "0.35.8",
- "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.35.8.tgz",
- "integrity": "sha512-PFfqpHplKa7KMdoQdj5td03uG05VK2Ng1dG0sP4pT9h0dGSX2v9txYt/AnrzPb/vAmfyBBC0NQV7VaBEX+efgQ==",
+ "version": "0.35.9",
+ "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.35.9.tgz",
+ "integrity": "sha512-SSnyl/4ni/2ViHKkiZb8eajA/eN1DNFaHjhGiLUdZvDz6PKF4COSf/17xqSz64nOo2Ia29SA6B2KNCsyCbVmaQ==",
"dependencies": {
"@open-draft/deferred-promise": "^2.2.0",
"@open-draft/logger": "^0.3.0",
@@ -986,6 +1009,279 @@
"esbuild": "^0.14.14"
}
},
+ "node_modules/@parcel/watcher": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.4.1.tgz",
+ "integrity": "sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==",
+ "dev": true,
+ "dependencies": {
+ "detect-libc": "^1.0.3",
+ "is-glob": "^4.0.3",
+ "micromatch": "^4.0.5",
+ "node-addon-api": "^7.0.0"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "@parcel/watcher-android-arm64": "2.4.1",
+ "@parcel/watcher-darwin-arm64": "2.4.1",
+ "@parcel/watcher-darwin-x64": "2.4.1",
+ "@parcel/watcher-freebsd-x64": "2.4.1",
+ "@parcel/watcher-linux-arm-glibc": "2.4.1",
+ "@parcel/watcher-linux-arm64-glibc": "2.4.1",
+ "@parcel/watcher-linux-arm64-musl": "2.4.1",
+ "@parcel/watcher-linux-x64-glibc": "2.4.1",
+ "@parcel/watcher-linux-x64-musl": "2.4.1",
+ "@parcel/watcher-win32-arm64": "2.4.1",
+ "@parcel/watcher-win32-ia32": "2.4.1",
+ "@parcel/watcher-win32-x64": "2.4.1"
+ }
+ },
+ "node_modules/@parcel/watcher-android-arm64": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.4.1.tgz",
+ "integrity": "sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-darwin-arm64": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.4.1.tgz",
+ "integrity": "sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-darwin-x64": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.4.1.tgz",
+ "integrity": "sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-freebsd-x64": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.4.1.tgz",
+ "integrity": "sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm-glibc": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.4.1.tgz",
+ "integrity": "sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm64-glibc": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.4.1.tgz",
+ "integrity": "sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm64-musl": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.4.1.tgz",
+ "integrity": "sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-x64-glibc": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.4.1.tgz",
+ "integrity": "sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-x64-musl": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.4.1.tgz",
+ "integrity": "sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-arm64": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.4.1.tgz",
+ "integrity": "sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-ia32": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.4.1.tgz",
+ "integrity": "sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-x64": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.4.1.tgz",
+ "integrity": "sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@@ -1040,9 +1336,9 @@
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.22.4",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz",
- "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==",
+ "version": "4.24.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz",
+ "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==",
"cpu": [
"arm"
],
@@ -1053,9 +1349,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
- "version": "4.22.4",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz",
- "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==",
+ "version": "4.24.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz",
+ "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==",
"cpu": [
"arm64"
],
@@ -1066,9 +1362,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.22.4",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz",
- "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==",
+ "version": "4.24.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz",
+ "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==",
"cpu": [
"arm64"
],
@@ -1079,9 +1375,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.22.4",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz",
- "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==",
+ "version": "4.24.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz",
+ "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==",
"cpu": [
"x64"
],
@@ -1092,9 +1388,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.22.4",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz",
- "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==",
+ "version": "4.24.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz",
+ "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==",
"cpu": [
"arm"
],
@@ -1105,9 +1401,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.22.4",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz",
- "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==",
+ "version": "4.24.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz",
+ "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==",
"cpu": [
"arm"
],
@@ -1118,9 +1414,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.22.4",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz",
- "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==",
+ "version": "4.24.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz",
+ "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==",
"cpu": [
"arm64"
],
@@ -1131,9 +1427,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.22.4",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz",
- "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==",
+ "version": "4.24.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz",
+ "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==",
"cpu": [
"arm64"
],
@@ -1144,9 +1440,9 @@
]
},
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
- "version": "4.22.4",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz",
- "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==",
+ "version": "4.24.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz",
+ "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==",
"cpu": [
"ppc64"
],
@@ -1157,9 +1453,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.22.4",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz",
- "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==",
+ "version": "4.24.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz",
+ "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==",
"cpu": [
"riscv64"
],
@@ -1170,9 +1466,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.22.4",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz",
- "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==",
+ "version": "4.24.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz",
+ "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==",
"cpu": [
"s390x"
],
@@ -1183,9 +1479,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.22.4",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz",
- "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==",
+ "version": "4.24.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz",
+ "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==",
"cpu": [
"x64"
],
@@ -1196,9 +1492,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.22.4",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz",
- "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==",
+ "version": "4.24.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz",
+ "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==",
"cpu": [
"x64"
],
@@ -1209,9 +1505,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.22.4",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz",
- "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==",
+ "version": "4.24.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz",
+ "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==",
"cpu": [
"arm64"
],
@@ -1222,9 +1518,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.22.4",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz",
- "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==",
+ "version": "4.24.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz",
+ "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==",
"cpu": [
"ia32"
],
@@ -1235,9 +1531,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.22.4",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz",
- "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==",
+ "version": "4.24.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz",
+ "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==",
"cpu": [
"x64"
],
@@ -1323,9 +1619,9 @@
}
},
"node_modules/@types/node": {
- "version": "22.6.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.6.1.tgz",
- "integrity": "sha512-V48tCfcKb/e6cVUigLAaJDAILdMP0fUW6BidkPK4GpGjXcfbnoHasCZDwz3N3yVt5we2RHm4XTQCpv0KJz9zqw==",
+ "version": "22.7.6",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.6.tgz",
+ "integrity": "sha512-/d7Rnj0/ExXDMcioS78/kf1lMzYk4BZV8MZGTBKzTGZ6/406ukkbYlIsZmMPhcR5KlkunDHQLrtAVmSq7r+mSw==",
"dependencies": {
"undici-types": "~6.19.2"
}
@@ -1528,6 +1824,18 @@
"concat-map": "0.0.1"
}
},
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/buffer-crc32": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz",
@@ -1672,9 +1980,9 @@
}
},
"node_modules/code-red/node_modules/acorn": {
- "version": "8.12.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
- "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
+ "version": "8.13.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz",
+ "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==",
"bin": {
"acorn": "bin/acorn"
},
@@ -1731,12 +2039,11 @@
}
},
"node_modules/commander": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
- "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
- "dev": true,
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
+ "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
"engines": {
- "node": ">= 6"
+ "node": ">= 12"
}
},
"node_modules/concat-map": {
@@ -2548,6 +2855,18 @@
"resolved": "https://registry.npmjs.org/fetch-event-stream/-/fetch-event-stream-0.1.5.tgz",
"integrity": "sha512-V1PWovkspxQfssq/NnxoEyQo1DV+MRK/laPuPblIZmSjMN8P5u46OhlFQznSr9p/t0Sp8Uc6SbM3yCMfr0KU8g=="
},
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/foreground-child": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
@@ -2565,9 +2884,9 @@
}
},
"node_modules/form-data": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
- "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
+ "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
@@ -2899,6 +3218,15 @@
"object-assign": "^4.1.1"
}
},
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
@@ -2907,11 +3235,32 @@
"node": ">=8"
}
},
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/is-node-process": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz",
"integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw=="
},
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
"node_modules/is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
@@ -3036,17 +3385,6 @@
}
}
},
- "node_modules/jsdom/node_modules/tough-cookie": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz",
- "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==",
- "dependencies": {
- "tldts": "^6.1.32"
- },
- "engines": {
- "node": ">=16"
- }
- },
"node_modules/jstransformer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz",
@@ -3072,14 +3410,6 @@
"katex": "cli.js"
}
},
- "node_modules/katex/node_modules/commander": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
- "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
- "engines": {
- "node": ">= 12"
- }
- },
"node_modules/kleur": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
@@ -3348,9 +3678,9 @@
}
},
"node_modules/magic-string": {
- "version": "0.30.11",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz",
- "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==",
+ "version": "0.30.12",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz",
+ "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0"
}
@@ -3378,9 +3708,9 @@
}
},
"node_modules/marked-highlight": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/marked-highlight/-/marked-highlight-2.1.4.tgz",
- "integrity": "sha512-D1GOkcdzP+1dzjoColL7umojefFrASDuLeyaHS0Zr/Uo9jkr1V6vpLRCzfi1djmEaWyK0SYMFtHnpkZ+cwFT1w==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/marked-highlight/-/marked-highlight-2.2.0.tgz",
+ "integrity": "sha512-36LzwtVf7HEbbMITKU4j+iZuyWKgdXJfgYr4F5j27vs79oRPyApuBF3WkS5OsqO1+1lypWxztad7zNRM4qgXFw==",
"peerDependencies": {
"marked": ">=4 <15"
}
@@ -3408,6 +3738,19 @@
"node": ">=0.12"
}
},
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@@ -3500,9 +3843,9 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node_modules/msw": {
- "version": "2.4.9",
- "resolved": "https://registry.npmjs.org/msw/-/msw-2.4.9.tgz",
- "integrity": "sha512-1m8xccT6ipN4PTqLinPwmzhxQREuxaEJYdx4nIbggxP8aM7r1e71vE7RtOUSQoAm1LydjGfZKy7370XD/tsuYg==",
+ "version": "2.4.11",
+ "resolved": "https://registry.npmjs.org/msw/-/msw-2.4.11.tgz",
+ "integrity": "sha512-TVEw9NOPTc6ufOQLJ53234S9NBRxQbu7xFMxs+OCP43JQcNEIOKiZHxEm2nDzYIrwccoIhUxUf8wr99SukD76A==",
"hasInstallScript": true,
"dependencies": {
"@bundled-es-modules/cookie": "^2.0.0",
@@ -3517,10 +3860,10 @@
"graphql": "^16.8.1",
"headers-polyfill": "^4.0.2",
"is-node-process": "^1.2.0",
- "outvariant": "^1.4.2",
+ "outvariant": "^1.4.3",
"path-to-regexp": "^6.3.0",
"strict-event-emitter": "^0.5.1",
- "type-fest": "^4.9.0",
+ "type-fest": "^4.26.1",
"yargs": "^17.7.2"
},
"bin": {
@@ -3582,6 +3925,12 @@
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
"integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
},
+ "node_modules/node-addon-api": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
+ "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
+ "dev": true
+ },
"node_modules/node-gyp-build": {
"version": "4.8.2",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz",
@@ -3621,9 +3970,9 @@
"integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA=="
},
"node_modules/package-json-from-dist": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz",
- "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
"dev": true
},
"node_modules/parse-srcset": {
@@ -3632,11 +3981,11 @@
"integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q=="
},
"node_modules/parse5": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
- "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.0.tgz",
+ "integrity": "sha512-ZkDsAOcxsUMZ4Lz5fVciOehNcJ+Gb8gTzcA4yl3wnc273BAybYWrQ+Ks/OjCjSEpjvQkDSeZbybK9qj2VHHdGA==",
"dependencies": {
- "entities": "^4.4.0"
+ "entities": "^4.5.0"
},
"funding": {
"url": "https://github.com/inikulin/parse5?sponsor=1"
@@ -3711,9 +4060,9 @@
}
},
"node_modules/picocolors": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
- "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw=="
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
},
"node_modules/picomatch": {
"version": "2.3.1",
@@ -3934,9 +4283,9 @@
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
},
"node_modules/readdirp": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.1.tgz",
- "integrity": "sha512-GkMg9uOTpIWWKbSsgwb5fA4EavTR+SG/PMPoAY8hkhHfEEY0/vqljY+XHqtDf2cr2IJtoNRDbrrEpZUiZCkYRw==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz",
+ "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==",
"dev": true,
"engines": {
"node": ">= 14.16.0"
@@ -3995,12 +4344,12 @@
}
},
"node_modules/rollup": {
- "version": "4.22.4",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz",
- "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==",
+ "version": "4.24.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz",
+ "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==",
"dev": true,
"dependencies": {
- "@types/estree": "1.0.5"
+ "@types/estree": "1.0.6"
},
"bin": {
"rollup": "dist/bin/rollup"
@@ -4010,31 +4359,25 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.22.4",
- "@rollup/rollup-android-arm64": "4.22.4",
- "@rollup/rollup-darwin-arm64": "4.22.4",
- "@rollup/rollup-darwin-x64": "4.22.4",
- "@rollup/rollup-linux-arm-gnueabihf": "4.22.4",
- "@rollup/rollup-linux-arm-musleabihf": "4.22.4",
- "@rollup/rollup-linux-arm64-gnu": "4.22.4",
- "@rollup/rollup-linux-arm64-musl": "4.22.4",
- "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4",
- "@rollup/rollup-linux-riscv64-gnu": "4.22.4",
- "@rollup/rollup-linux-s390x-gnu": "4.22.4",
- "@rollup/rollup-linux-x64-gnu": "4.22.4",
- "@rollup/rollup-linux-x64-musl": "4.22.4",
- "@rollup/rollup-win32-arm64-msvc": "4.22.4",
- "@rollup/rollup-win32-ia32-msvc": "4.22.4",
- "@rollup/rollup-win32-x64-msvc": "4.22.4",
+ "@rollup/rollup-android-arm-eabi": "4.24.0",
+ "@rollup/rollup-android-arm64": "4.24.0",
+ "@rollup/rollup-darwin-arm64": "4.24.0",
+ "@rollup/rollup-darwin-x64": "4.24.0",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.24.0",
+ "@rollup/rollup-linux-arm-musleabihf": "4.24.0",
+ "@rollup/rollup-linux-arm64-gnu": "4.24.0",
+ "@rollup/rollup-linux-arm64-musl": "4.24.0",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0",
+ "@rollup/rollup-linux-riscv64-gnu": "4.24.0",
+ "@rollup/rollup-linux-s390x-gnu": "4.24.0",
+ "@rollup/rollup-linux-x64-gnu": "4.24.0",
+ "@rollup/rollup-linux-x64-musl": "4.24.0",
+ "@rollup/rollup-win32-arm64-msvc": "4.24.0",
+ "@rollup/rollup-win32-ia32-msvc": "4.24.0",
+ "@rollup/rollup-win32-x64-msvc": "4.24.0",
"fsevents": "~2.3.2"
}
},
- "node_modules/rollup/node_modules/@types/estree": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
- "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
- "dev": true
- },
"node_modules/rrweb-cssom": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz",
@@ -4082,11 +4425,12 @@
}
},
"node_modules/sass": {
- "version": "1.79.3",
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.79.3.tgz",
- "integrity": "sha512-m7dZxh0W9EZ3cw50Me5GOuYm/tVAJAn91SUnohLRo9cXBixGUOdvmryN+dXpwR831bhoY3Zv7rEFt85PUwTmzA==",
+ "version": "1.80.1",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.80.1.tgz",
+ "integrity": "sha512-9lBwDZ7j3y/1DKj5Ec249EVGo5CVpwnzIyIj+cqlCjKkApLnzsJ/l9SnV4YnORvW9dQwQN+gQvh/mFZ8CnDs7Q==",
"dev": true,
"dependencies": {
+ "@parcel/watcher": "^2.4.1",
"chokidar": "^4.0.0",
"immutable": "^4.0.0",
"source-map-js": ">=0.6.2 <2.0.0"
@@ -4395,6 +4739,15 @@
"balanced-match": "^1.0.0"
}
},
+ "node_modules/sucrase/node_modules/commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/sucrase/node_modules/glob": {
"version": "10.4.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
@@ -4643,9 +4996,9 @@
}
},
"node_modules/svelte/node_modules/acorn": {
- "version": "8.12.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
- "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
+ "version": "8.13.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz",
+ "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==",
"bin": {
"acorn": "bin/acorn"
},
@@ -4714,20 +5067,20 @@
}
},
"node_modules/tldts": {
- "version": "6.1.50",
- "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.50.tgz",
- "integrity": "sha512-q9GOap6q3KCsLMdOjXhWU5jVZ8/1dIib898JBRLsN+tBhENpBDcAVQbE0epADOjw11FhQQy9AcbqKGBQPUfTQA==",
+ "version": "6.1.52",
+ "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.52.tgz",
+ "integrity": "sha512-fgrDJXDjbAverY6XnIt0lNfv8A0cf7maTEaZxNykLGsLG7XP+5xhjBTrt/ieAsFjAlZ+G5nmXomLcZDkxXnDzw==",
"dependencies": {
- "tldts-core": "^6.1.50"
+ "tldts-core": "^6.1.52"
},
"bin": {
"tldts": "bin/cli.js"
}
},
"node_modules/tldts-core": {
- "version": "6.1.50",
- "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.50.tgz",
- "integrity": "sha512-na2EcZqmdA2iV9zHV7OHQDxxdciEpxrjbkp+aHmZgnZKHzoElLajP59np5/4+sare9fQBfixgvXKx8ev1d7ytw=="
+ "version": "6.1.52",
+ "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.52.tgz",
+ "integrity": "sha512-j4OxQI5rc1Ve/4m/9o2WhWSC4jGc4uVbCINdOEJRAraCi0YqTqgMcxUx7DbmuP0G3PCixoof/RZB0Q5Kh9tagw=="
},
"node_modules/to-fast-properties": {
"version": "2.0.0",
@@ -4738,6 +5091,18 @@
"node": ">=4"
}
},
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
"node_modules/token-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz",
@@ -4745,17 +5110,14 @@
"dev": true
},
"node_modules/tough-cookie": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz",
- "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz",
+ "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==",
"dependencies": {
- "psl": "^1.1.33",
- "punycode": "^2.1.1",
- "universalify": "^0.2.0",
- "url-parse": "^1.5.3"
+ "tldts": "^6.1.32"
},
"engines": {
- "node": ">=6"
+ "node": ">=16"
}
},
"node_modules/tr46": {
@@ -4776,9 +5138,9 @@
"dev": true
},
"node_modules/tslib": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
- "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz",
+ "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA=="
},
"node_modules/type": {
"version": "2.7.3",
@@ -4797,9 +5159,9 @@
}
},
"node_modules/typescript": {
- "version": "5.6.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz",
- "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==",
+ "version": "5.6.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
+ "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -4831,9 +5193,9 @@
}
},
"node_modules/vite": {
- "version": "5.4.7",
- "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.7.tgz",
- "integrity": "sha512-5l2zxqMEPVENgvzTuBpHer2awaetimj2BGkhBPdnwKbPNOlHsODU+oiazEZzLK7KhAnOrO+XGYJYn4ZlUhDtDQ==",
+ "version": "5.4.9",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.9.tgz",
+ "integrity": "sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==",
"dev": true,
"dependencies": {
"esbuild": "^0.21.3",
diff --git a/frontend/package.json b/frontend/package.json
index bde834b..ea8bc24 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -9,15 +9,15 @@
"dependencies": {
"@ffmpeg/ffmpeg": "^0.12.10",
"@ffmpeg/util": "^0.12.1",
- "@gradio/atoms": "0.9.0",
- "@gradio/client": "1.6.0",
+ "@gradio/atoms": "0.9.2",
+ "@gradio/client": "1.7.0",
"@gradio/icons": "0.8.0",
- "@gradio/image": "0.16.0",
- "@gradio/markdown": "^0.10.0",
- "@gradio/statustracker": "0.8.0",
- "@gradio/upload": "0.13.0",
+ "@gradio/image": "0.16.4",
+ "@gradio/markdown": "^0.10.3",
+ "@gradio/statustracker": "0.9.1",
+ "@gradio/upload": "0.13.3",
"@gradio/utils": "0.7.0",
- "@gradio/wasm": "0.14.0",
+ "@gradio/wasm": "0.14.2",
"hls.js": "^1.5.16",
"mrmime": "^2.0.0"
},
diff --git a/frontend/shared/AudioWave.svelte b/frontend/shared/AudioWave.svelte
index 4e94f98..8d8c19e 100644
--- a/frontend/shared/AudioWave.svelte
+++ b/frontend/shared/AudioWave.svelte
@@ -2,7 +2,7 @@
import { onMount, onDestroy } from 'svelte';
export let numBars = 16;
- export let stream_state: "open" | "closed" = "closed";
+ export let stream_state: "open" | "closed" | "waiting" = "closed";
export let audio_source: HTMLAudioElement;
let audioContext: AudioContext;
@@ -69,17 +69,12 @@
{/each}
-
- {is_muted ? '🔈' : '🔊'}
-
\ No newline at end of file
diff --git a/frontend/shared/InteractiveAudio.svelte b/frontend/shared/InteractiveAudio.svelte
new file mode 100644
index 0000000..6f7f043
--- /dev/null
+++ b/frontend/shared/InteractiveAudio.svelte
@@ -0,0 +1,244 @@
+
+
+
+
+
dispatch("stop")}
+ on:play={() => dispatch("play")}
+ />
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/shared/InteractiveVideo.svelte b/frontend/shared/InteractiveVideo.svelte
index d74480b..9239a7c 100644
--- a/frontend/shared/InteractiveVideo.svelte
+++ b/frontend/shared/InteractiveVideo.svelte
@@ -62,22 +62,6 @@