diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..0edc7596e0d5d439f968e07dbd566f84b659bd14 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,133 @@ +# build frontend with node +FROM node:20-alpine AS frontend +RUN apk add --no-cache libc6-compat +WORKDIR /app + +ARG DUMMY_ARG=1 + +COPY streaming-react-app . +RUN \ + if [ -f yarn.lock ]; then yarn --frozen-lockfile; \ + elif [ -f package-lock.json ]; then npm ci; \ + elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i --frozen-lockfile; \ + else echo "Lockfile not found." && exit 1; \ + fi + +RUN npm run build + +# build backend on CUDA +FROM nvidia/cuda:11.8.0-cudnn8-devel-ubuntu22.04 AS backend +WORKDIR /app + +ENV DEBIAN_FRONTEND=noninteractive +ENV NODE_MAJOR=20 + +RUN apt-get update && \ + apt-get upgrade -y && \ + apt-get install -y --no-install-recommends \ + git \ + git-lfs \ + wget \ + curl \ + # python build dependencies \ + build-essential \ + libssl-dev \ + zlib1g-dev \ + libbz2-dev \ + libreadline-dev \ + libsqlite3-dev \ + libncursesw5-dev \ + xz-utils \ + tk-dev \ + libxml2-dev \ + libxmlsec1-dev \ + libffi-dev \ + liblzma-dev \ + sox libsox-fmt-all \ + # gradio dependencies \ + ffmpeg \ + # fairseq2 dependencies \ + libsndfile-dev && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + + +# RUN apt-get install zlib1g-dev &&\ +# wget https://sourceforge.net/projects/libpng/files/libpng15/1.5.30/libpng-1.5.30.tar.gz &&\ +# tar -xzvf libpng-1.5.30.tar.gz &&\ +# cd libpng-1.5.30 &&\ +# ./configure --prefix=/usr/local/libpng &&\ +# make &&\ +# make install &&\ +# echo "Contents of /usr/local/lib:" && ls /usr/local/lib && \ +# echo "Contents of /usr/local/libpng/lib:" && ls /usr/local/libpng/lib && \ +# # ls /usr/local/lib/libpng* &&\ +# ldconfig &&\ +# cd .. +# ENV LD_LIBRARY_PATH=/usr/local/libpng/lib: + +# RUN wget http://www.ijg.org/files/jpegsrc.v9a.tar.gz &&\ +# tar -xzvf jpegsrc.v9a.tar.gz &&\ +# cd jpeg-9a &&\ +# ./configure --prefix=/usr/local/libjpeg &&\ +# make &&\ +# make install +# RUN cd .. &&\ +# echo "Contents of /usr/local/lib :" && ls /usr/local && \ +# echo "Contents of /usr/local/libjpeg/lib :" && ls /usr/local/libjpeg/lib && \ +# ls /usr/local/lib/libpng* &&\ +# ldconfig +# # ENV LD_LIBRARY_PATH=/usr/local/libpng/lib: + +# RUN wget libjpeg62-turbo_2.0.6-4_amd64.deb &&\ +# tar -xzvf jpegsrc.v9a.tar.gz &&\ +# cd jpeg-9a &&\ +# ./configure --prefix=/usr/local/libjpeg &&\ +# make &&\ +# make install +# RUN cd .. &&\ +# echo "Contents of /usr/local/lib :" && ls /usr/local && \ +# echo "Contents of /usr/local/libjpeg/lib :" && ls /usr/local/libjpeg/lib && \ +# ls /usr/local/lib/libpng* &&\ +# ldconfig +# ENV LD_LIBRARY_PATH=/usr/local/libpng/lib: + +# RUN apt-get update &&\ +# apt-get -y install libjpeg62-turbo-dev &&\ +# apt-get install libjpeg8 libbodfile1 + +RUN useradd -m -u 1000 user +USER user +ENV HOME=/home/user \ + PATH=/home/user/.local/bin:$PATH +WORKDIR $HOME/app + +RUN curl https://pyenv.run | bash +ENV PATH=$HOME/.pyenv/shims:$HOME/.pyenv/bin:$PATH +ARG PYTHON_VERSION=3.10.12 +RUN pyenv install $PYTHON_VERSION && \ + pyenv global $PYTHON_VERSION && \ + pyenv rehash && \ + pip install --no-cache-dir -U pip setuptools wheel + +COPY --chown=user:user ./seamless_server ./seamless_server +# change dir since pip needs to seed whl folder +RUN cd seamless_server && \ + pip install fairseq2 &&\ +# pip install fairseq2 --pre --extra-index-url https://fair.pkg.atmeta.com/fairseq2/whl/nightly/pt2.1.1/cu118 && \ + pip install --no-cache-dir --upgrade -r requirements.txt +COPY --from=frontend /app/dist ./streaming-react-app/dist + +WORKDIR $HOME/app/seamless_server +RUN --mount=type=secret,id=HF_TOKEN,mode=0444,required=false \ + huggingface-cli login --token $(cat /run/secrets/HF_TOKEN) || echo "HF_TOKEN error" && \ + huggingface-cli download meta-private/SeamlessExpressive pretssel_melhifigan_wm-final.pt --local-dir ./models/Seamless/ || echo "HF_TOKEN error" && \ + ln -s $(readlink -f models/Seamless/pretssel_melhifigan_wm-final.pt) models/Seamless/pretssel_melhifigan_wm.pt || true; + +USER root +RUN ln -s /usr/lib/x86_64-linux-gnu/libsox.so.3 /usr/lib/x86_64-linux-gnu/libsox.so +USER user +RUN ["chmod", "+x", "./run_docker.sh"] +CMD ./run_docker.sh + + diff --git a/README.md b/README.md index aeda6b57810cd97172e2270b6fdbd870f0661a0b..c412ff78f13b639297743a581df1fa157cd6697d 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,74 @@ --- -title: Stream Trans Docker -emoji: 📊 -colorFrom: purple -colorTo: blue +title: Seamless Streaming +emoji: 📞 +colorFrom: blue +colorTo: yellow sdk: docker pinned: false +suggested_hardware: t4-small +models: + - facebook/seamless-streaming --- -Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference +# RESOURCES AWS +I use a g4 machine with 35GB of volume. You could delete the volume and create a new one and connect it to the instance when needed. Obv you'd need to re-pull the docker image. +The same is true for the elastic IP. Both the volume and the elastic IP costs me ~0.10$ per day, for an overall of ~0.22$. It does not make sense to keep them if you don't need to use it for a couple of months. + +# Seamless Streaming demo +## Running on HF spaces +You can simply duplicate the space to run it. + +## Running locally +### Install backend seamless_server dependencies + +> [!NOTE] +> Please note: we *do not* recommend running the model on CPU. CPU inference will be slow and introduce noticable delays in the simultaneous translation. + +> [!NOTE] +> The example below is for PyTorch stable (2.1.1) and variant cu118. +> Check [here](https://pytorch.org/get-started/locally/) to find the torch/torchaudio command for your variant. +> Check [here](https://github.com/facebookresearch/fairseq2#variants) to find the fairseq2 command for your variant. + +If running for the first time, create conda environment and install the desired torch version. Then install the rest of the requirements: +``` +cd seamless_server +conda create --yes --name smlss_server python=3.8 libsndfile==1.0.31 +conda activate smlss_server +conda install --yes pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia +pip install fairseq2 --pre --extra-index-url https://fair.pkg.atmeta.com/fairseq2/whl/nightly/pt2.1.1/cu118 +pip install -r requirements.txt +``` + +### Install frontend streaming-react-app dependencies +``` +conda install -c conda-forge nodejs +cd streaming-react-app +npm install --global yarn +yarn +yarn build # this will create the dist/ folder +``` + + +### Running the server + +The server can be run locally with uvicorn below. +Run the server in dev mode: + +``` +cd seamless_server +uvicorn app_pubsub:app --reload --host localhost +``` + +Run the server in prod mode: + +``` +cd seamless_server +uvicorn app_pubsub:app --host 0.0.0.0 +``` + +To enable additional logging from uvicorn pass `--log-level debug` or `--log-level trace`. + + +### Debuging + +If you enable "Server Debug Flag" when starting streaming from the client, this enables extensive debug logging and it saves audio files in /debug folder. diff --git a/docker-compose.dev.yaml b/docker-compose.dev.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/seamless_server/.DS_Store b/seamless_server/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..33e7bc8feb4b46a8c717b0df8dd4e889e0a06ec2 Binary files /dev/null and b/seamless_server/.DS_Store differ diff --git a/seamless_server/.gitignore b/seamless_server/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..a693d3474a1e1aa50070a82f640925b28ff43164 --- /dev/null +++ b/seamless_server/.gitignore @@ -0,0 +1,4 @@ +__pycache__/ +src/__pycache__/ +debug/ +.vscode/ \ No newline at end of file diff --git a/seamless_server/app_pubsub.py b/seamless_server/app_pubsub.py new file mode 100644 index 0000000000000000000000000000000000000000..c501ec284b5f1661be8e0494eeeef2d79b9a0d05 --- /dev/null +++ b/seamless_server/app_pubsub.py @@ -0,0 +1,829 @@ +from operator import itemgetter +import os +from typing import Any, Optional, Tuple, Dict, TypedDict +from urllib import parse +from uuid import uuid4 +import colorlog +import io +import logging +from pprint import pformat +import socketio +import sys +import time +import random +import string +from starlette.applications import Starlette +from starlette.routing import Mount, Route +from starlette.staticfiles import StaticFiles + + +from src.room import Room, Member +from src.simuleval_agent_directory import NoAvailableAgentException +from src.simuleval_agent_directory import SimulevalAgentDirectory +from src.simuleval_transcoder import SimulevalTranscoder +from src.transcoder_helpers import get_transcoder_output_events + +############################################### +# Constants +############################################### + +DEBUG = True + +ALL_ROOM_ID = "ALL" + +ROOM_ID_USABLE_CHARACTERS = string.ascii_uppercase +ROOM_ID_LENGTH = 4 + +ROOM_LISTENERS_SUFFIX = "_listeners" +ROOM_SPEAKERS_SUFFIX = "_speakers" + +ESCAPE_HATCH_SERVER_LOCK_RELEASE_NAME = "remove_server_lock" + +############################################### +# Configure logger +############################################### + +logger = logging.getLogger("socketio_server_pubsub") +logger.propagate = False + +handler = colorlog.StreamHandler(stream=sys.stdout) + +formatter = colorlog.ColoredFormatter( + "%(log_color)s[%(asctime)s][%(levelname)s][%(module)s]:%(reset)s %(message)s", + reset=True, + log_colors={ + "DEBUG": "cyan", + "INFO": "green", + "WARNING": "yellow", + "ERROR": "red", + "CRITICAL": "red,bg_white", + }, +) + +handler.setFormatter(formatter) +logger.addHandler(handler) + +logger.setLevel(logging.WARNING) + +print("") +print("") +print("=" * 20 + " ⭐️ Starting Server... ⭐️ " + "=" * 20) + +############################################### +# Configure socketio server +############################################### + +CLIENT_BUILD_PATH = "../streaming-react-app/dist/" +static_files = { + "/": CLIENT_BUILD_PATH, + "/assets/seamless-db6a2555.svg": { + "filename": CLIENT_BUILD_PATH + "assets/seamless-db6a2555.svg", + "content_type": "image/svg+xml", + }, +} + +# sio is the main socket.io entrypoint +sio = socketio.AsyncServer( + async_mode="asgi", + cors_allowed_origins="*", + logger=logger, + # engineio_logger=logger, +) +# sio.logger.setLevel(logging.DEBUG) +socketio_app = socketio.ASGIApp(sio) + +app_routes = [ + Mount("/ws", app=socketio_app), # Mount Socket.IO server under /app + Mount( + "/", app=StaticFiles(directory=CLIENT_BUILD_PATH, html=True) + ), # Serve static files from root +] +app = Starlette(debug=True, routes=app_routes) + +# rooms is indexed by room_id +rooms: Dict[str, Room] = {} + + +class MemberDirectoryObject(TypedDict): + room: Room + member_object: Member + + +# member_directory is indexed by client_id +# NOTE: client_id is really "client session id", meaning that it is unique to a single browser session. +# If a user opens a new tab, they will have a different client_id and can join another room, join +# the same room with different roles, etc. +# NOTE: For a long-running production server we would want to clean up members after a certain timeout +# but for this limited application we can just keep them around +member_directory: Dict[str, MemberDirectoryObject] = {} + + +class ServerLock(TypedDict): + name: str + client_id: str + member_object: Member + +MAX_SPEAKERS = os.environ.get("MAX_SPEAKERS") + +if os.environ.get("LOCK_SERVER_COMPLETELY", "0") == "1": + logger.info("LOCK_SERVER_COMPLETELY is set. Server will be locked on startup.") +if MAX_SPEAKERS is not None and int(MAX_SPEAKERS): + logger.info(f"MAX_SPEAKERS is set to: {MAX_SPEAKERS}") +dummy_server_lock_member_object = Member( + client_id="seamless_user", session_id="dummy", name="Seamless User" +) +# Normally this would be an actual transcoder, but it's fine putting True here since currently we only check for the presence of the transcoder +dummy_server_lock_member_object.transcoder = True +server_lock: Optional[ServerLock] = ( + { + "name": "Seamless User", + "client_id": "seamless_user", + "member_object": dummy_server_lock_member_object, + } + if os.environ.get("LOCK_SERVER_COMPLETELY", "0") == "1" + else None +) + +server_id = str(uuid4()) + +# Specify specific models to load (some environments have issues loading multiple models) +# See AgentWithInfo with JSON format details. +models_override = os.environ.get("MODELS_OVERRIDE") + +available_agents = SimulevalAgentDirectory() +logger.info("Building and adding agents...") +if models_override is not None: + logger.info(f"MODELS_OVERRIDE supplied from env vars: {models_override}") +available_agents.build_and_add_agents(models_override) + +agents_capabilities_for_json = available_agents.get_agents_capabilities_list_for_json() + + +############################################### +# Helpers +############################################### + + +def catch_and_log_exceptions_for_sio_event_handlers(func): + # wrapper should have the same signature as the original function + async def catch_exception_wrapper(*args, **kwargs): + try: + return await func(*args, **kwargs) + except Exception as e: + message = f"[app_pubsub] Caught exception in '{func.__name__}' event handler:\n\n{e}" + logger.exception(message, stack_info=True) + + try: + exception_data = { + "message": message, + "timeEpochMs": int(time.time() * 1000), + } + + try: + # Let's try to add as much useful metadata as possible to the server_exception event + sid = args[0] + if isinstance(sid, str) and len(sid) > 0: + session_data = await get_session_data(sid) + if session_data: + client_id = session_data.get("client_id") + member = session_data.get("member_object") + room = session_data.get("room_object") + + exception_data["room"] = str(room) + exception_data["member"] = str(member) + exception_data["clientID"] = str(client_id) + except Exception as inner_e: + # We expect there will be times when clientID or other values aren't present, so just log this as a warning + logger.warn( + f"[app_pubsub] Caught exception while trying add additional_data to server_exception:\n\n{inner_e}" + ) + + # For now let's emit this to all clients. We ultimatley may want to emit it just to the room it's happening in. + await sio.emit("server_exception", exception_data) + except Exception as inner_e: + logger.exception( + f"[app_pubsub] Caught exception while trying to emit server_exception event:\n{inner_e}" + ) + + # Re-raise the exception so it's handled normally by the server + raise e + + # Set the name of the wrapper to the name of the original function so that the socketio server can associate it with the right event + catch_exception_wrapper.__name__ = func.__name__ + return catch_exception_wrapper + + +async def emit_room_state_update(room): + await sio.emit( + "room_state_update", + room.to_json(), + room=room.room_id, + ) + + +async def emit_server_state_update(): + room_statuses = { + room_id: room.get_room_status_dict() for room_id, room in rooms.items() + } + total_active_connections = sum( + [room_status["activeConnections"] for room_status in room_statuses.values()] + ) + total_active_transcoders = sum( + [room_status["activeTranscoders"] for room_status in room_statuses.values()] + ) + logger.info( + f"[Server Status]: {total_active_connections} active connections (in rooms); {total_active_transcoders} active transcoders" + ) + logger.info(f"[Server Status]: server_lock={server_lock}") + server_lock_object_for_js = ( + { + "name": server_lock.get("name"), + "clientID": server_lock.get("client_id"), + "isActive": server_lock.get("member_object") + and server_lock.get("member_object").transcoder is not None, + } + if server_lock + else None + ) + await sio.emit( + "server_state_update", + { + "statusByRoom": room_statuses, + "totalActiveConnections": total_active_connections, + "totalActiveTranscoders": total_active_transcoders, + "agentsCapabilities": agents_capabilities_for_json, + "serverLock": server_lock_object_for_js, + }, + room=ALL_ROOM_ID, + ) + + +async def get_session_data(sid): + session = await sio.get_session(sid) + # It seems like if the session has not been set that get_session may return None, so let's provide a fallback empty dictionary here + return session or {} + + +async def set_session_data(sid, client_id, room_id, room_object, member_object): + await sio.save_session( + sid, + { + "client_id": client_id, + "room_id": room_id, + "room_object": room_object, + "member_object": member_object, + }, + ) + + +def get_random_room_id(): + return "".join(random.choices(ROOM_ID_USABLE_CHARACTERS, k=ROOM_ID_LENGTH)) + + +def get_random_unused_room_id(): + room_id = get_random_room_id() + while room_id in rooms: + room_id = get_random_room_id() + return room_id + + +############################################### +# Socket.io Basic Event Handlers +############################################### + + +@sio.on("connect") +@catch_and_log_exceptions_for_sio_event_handlers +async def connect(sid, environ): + logger.info(f"📥 [event: connected] sid={sid}") + + # TODO: Sanitize/validate query param input + query_params = dict(parse.parse_qsl(environ["QUERY_STRING"])) + client_id = query_params.get("clientID") + + logger.debug(f"query_params:\n{pformat(query_params)}") + + if client_id is None: + logger.info("No clientID provided. Disconnecting...") + await sio.disconnect(sid) + return + + # On reconnect we need to rejoin rooms and reset session data + if member_directory.get(client_id): + room = member_directory[client_id].get("room") + room_id = room.room_id + # Note: We could also get this from room.members[client_id] + member = member_directory[client_id].get("member_object") + + member.connection_status = "connected" + member.session_id = sid + + logger.info( + f"[event: connect] {member} reconnected. Attempting to re-add them to socketio rooms and reset session data." + ) + + if room is None or member is None: + logger.error( + f"[event: connect] {client_id} is reconnecting, but room or member is None. This should not happen." + ) + await sio.disconnect(sid) + return + + sio.enter_room(sid, room_id) + sio.enter_room(sid, ALL_ROOM_ID) + + if client_id in room.listeners: + sio.enter_room(sid, f"{room_id}{ROOM_LISTENERS_SUFFIX}") + if client_id in room.speakers: + sio.enter_room(sid, f"{room_id}{ROOM_SPEAKERS_SUFFIX}") + + # Save the room_id to the socketio client session + await set_session_data( + sid, + client_id=client_id, + room_id=room.room_id, + room_object=room, + member_object=member, + ) + await emit_room_state_update(room) + else: + # Save the client id to the socketio client session + await set_session_data( + sid, client_id=client_id, room_id=None, room_object=None, member_object=None + ) + + await sio.emit("server_id", server_id, to=sid) + await emit_server_state_update() + + +@sio.event +@catch_and_log_exceptions_for_sio_event_handlers +async def disconnect(sid): + global server_lock + session_data = await get_session_data(sid) + # logger.info("session_data", session_data) + + client_id = None + member = None + room = None + + if session_data: + client_id = session_data.get("client_id") + member = session_data.get("member_object") + room = session_data.get("room_object") + + logger.info( + f"[event: disconnect][{room or 'NOT_IN_ROOM'}] member: {member or 'NO_MEMBER_OBJECT'} disconnected" + ) + + # Release the lock if this is the client that holds the current server lock + if server_lock and server_lock.get("client_id") == client_id: + server_lock = None + + if member: + member.connection_status = "disconnected" + + if member.transcoder: + member.transcoder.close = True + member.transcoder = None + member.requested_output_type = None + + if room: + logger.info( + f"[event: disconnect] {member} disconnected from room {room.room_id}" + ) + await emit_room_state_update(room) + else: + logger.info( + f"[event: disconnect] {member} disconnected, but no room object present. This should not happen." + ) + else: + logger.info( + f"[event: disconnect] client_id {client_id or 'NO_CLIENT_ID'} with sid {sid} in rooms {str(sio.rooms(sid))} disconnected" + ) + + await emit_server_state_update() + + +@sio.on("*") +async def catch_all(event, sid, data): + logger.info(f"[unhandled event: {event}] sid={sid} data={data}") + + +############################################### +# Socket.io Streaming Event handlers +############################################### + + +@sio.on("join_room") +@catch_and_log_exceptions_for_sio_event_handlers +async def join_room(sid, client_id, room_id_from_client, config_dict): + global server_lock + + args = { + "sid": sid, + "client_id": client_id, + "room_id": room_id_from_client, + "config_dict": config_dict, + } + logger.info(f"[event: join_room] {args}") + session_data = await get_session_data(sid) + logger.info(f"session_data: {session_data}") + + room_id = room_id_from_client + if room_id is None: + room_id = get_random_unused_room_id() + logger.info( + f"No room_id provided. Generating a random, unused room_id: {room_id}" + ) + + # Create the room if it doesn't already exist + if room_id not in rooms: + rooms[room_id] = Room(room_id) + + room = rooms[room_id] + + member = None + + name = "[NO_NAME]" + + # If the client is reconnecting use their existing member object. Otherwise create a new one. + if client_id in room.members: + member = room.members[client_id] + logger.info(f"{member} is rejoining room {room_id}.") + else: + member_number = len(room.members) + 1 + name = f"Member {member_number}" + member = Member( + client_id=client_id, + session_id=sid, + name=name, + ) + logger.info(f"Created a new Member object: {member}") + logger.info(f"Adding {member} to room {room_id}") + room.members[client_id] = member + + # Also add them to the member directory + member_directory[client_id] = {"room": room, "member_object": member} + + # Join the socketio room, which enables broadcasting to all members of the room + sio.enter_room(sid, room_id) + # Join the room for all clients + sio.enter_room(sid, ALL_ROOM_ID) + + if "listener" in config_dict["roles"]: + sio.enter_room(sid, f"{room_id}{ROOM_LISTENERS_SUFFIX}") + if client_id not in room.listeners: + room.listeners.append(client_id) + else: + sio.leave_room(sid, f"{room_id}{ROOM_LISTENERS_SUFFIX}") + room.listeners = [ + listener_id for listener_id in room.listeners if listener_id != client_id + ] + + if "speaker" in config_dict["roles"]: + sio.enter_room(sid, f"{room_id}{ROOM_SPEAKERS_SUFFIX}") + if client_id not in room.speakers: + room.speakers.append(client_id) + else: + sio.leave_room(sid, f"{room_id}{ROOM_SPEAKERS_SUFFIX}") + # If the person is no longer a speaker they should no longer be able to lock the server + if server_lock and server_lock.get("client_id") == client_id: + logger.info( + f"🔓 Server is now unlocked from client {server_lock.get('client_id')} with name/info: {server_lock.get('name')}" + ) + server_lock = None + if member.transcoder: + member.transcoder.close = True + member.transcoder = None + room.speakers = [ + speaker_id for speaker_id in room.speakers if speaker_id != client_id + ] + + # If we currently own the server lock and are updating roles and we no longer have server lock specified, release it + if ( + server_lock is not None + and server_lock["client_id"] == client_id + and config_dict.get("lockServerName") is None + ): + logger.info(f"[join_room] Releasing server lock: {pformat(server_lock)}") + server_lock = None + + # Only speakers should be able to lock the server + if config_dict.get("lockServerName") is not None and "speaker" in config_dict.get( + "roles", {} + ): + # If something goes wrong and the server gets stuck in a locked state the client can + # force the server to remove the lock by passing the special name ESCAPE_HATCH_SERVER_LOCK_RELEASE_NAME + if ( + server_lock is not None + and config_dict.get("lockServerName") + == ESCAPE_HATCH_SERVER_LOCK_RELEASE_NAME + # If we are locking the server completely we don't want someone to be able to unlock it + and not os.environ.get("LOCK_SERVER_COMPLETELY", "0") == "1" + ): + server_lock = None + logger.info( + f"🔓 Server lock has been reset by {client_id} using the escape hatch name {ESCAPE_HATCH_SERVER_LOCK_RELEASE_NAME}" + ) + + # If the server is not locked, set a lock. If it's already locked to this client, update the lock object + if server_lock is None or server_lock.get("client_id") == client_id: + # TODO: Add some sort of timeout as a backstop in case someone leaves the browser tab open after locking the server + server_lock = { + "name": config_dict.get("lockServerName"), + "client_id": client_id, + "member_object": member, + } + logger.info( + f"🔒 Server is now locked to client {server_lock.get('client_id')} with name/info: {server_lock.get('name')}\nThis client will have priority over all others until they disconnect." + ) + # If the server is already locked to someone else, don't allow this client to lock it + elif server_lock is not None and server_lock.get("client_id") != client_id: + logger.warn( + f"⚠️ Server is already locked to client {server_lock.get('client_id')}. Ignoring request to lock to client {client_id}." + ) + # TODO: Maybe throw an error here? + + # Save the room_id to the socketio client session + await set_session_data( + sid, + client_id=client_id, + room_id=room_id, + room_object=room, + member_object=member, + ) + + await emit_room_state_update(room) + await emit_server_state_update() + + return {"roomsJoined": sio.rooms(sid), "roomID": room_id} + +def allow_speaker(room, client_id): + if MAX_SPEAKERS is not None and client_id in room.speakers: + room_statuses = {room_id: room.get_room_status_dict() for room_id, room in rooms.items()} + speakers = sum(room_status["activeTranscoders"] for room_status in room_statuses.values()) + return speakers < int(MAX_SPEAKERS) + return True + +# TODO: Add code to prevent more than one speaker from connecting/streaming at a time +@sio.event +@catch_and_log_exceptions_for_sio_event_handlers +async def configure_stream(sid, config): + session_data = await get_session_data(sid) + client_id, member, room = itemgetter("client_id", "member_object", "room_object")( + session_data + ) + + logger.debug( + f"[event: configure_stream][{room}] Received stream config from {member}\n{pformat(config)}" + ) + + if member is None or room is None: + logger.error( + f"Received stream config from {member}, but member or room is None. This should not happen." + ) + return {"status": "error", "message": "member_or_room_is_none"} + + if not allow_speaker(room, client_id): + logger.error( + f"In MAX_SPEAKERS mode we only allow one speaker at a time. Ignoring request to configure stream from client {client_id}." + ) + return {"status": "error", "message": "max_speakers"} + + # If there is a server lock WITH an active transcoder session, prevent other users from configuring and starting a stream + # If the server lock client does NOT have an active transcoder session allow this to proceed, knowing that + # this stream will be interrupted if the server lock client starts streaming + if ( + server_lock is not None + and server_lock.get("client_id") != client_id + and server_lock.get("member_object") + and server_lock.get("member_object").transcoder is not None + ): + logger.warn( + f"Server is locked to client {server_lock.get('client_id')}. Ignoring request to configure stream from client {client_id}." + ) + return {"status": "error", "message": "server_locked"} + + debug = config.get("debug") + async_processing = config.get("async_processing") + + # Currently s2s, s2t or s2s&t + model_type = config.get("model_type") + member.requested_output_type = model_type + + model_name = config.get("model_name") + + try: + agent = available_agents.get_agent_or_throw(model_name) + except NoAvailableAgentException as e: + logger.warn(f"Error while getting agent: {e}") + # await sio.emit("error", str(e), to=sid) + await sio.disconnect(sid) + return {"status": "error", "message": str(e)} + + if member.transcoder: + logger.warn( + "Member already has a transcoder configured. Closing it, and overwriting with a new transcoder..." + ) + member.transcoder.close = True + + t0 = time.time() + try: + member.transcoder = SimulevalTranscoder( + agent, + config["rate"], + debug=debug, + buffer_limit=int(config["buffer_limit"]), + ) + except Exception as e: + logger.warn(f"Got exception while initializing agents: {e}") + # await sio.emit("error", str(e), to=sid) + await sio.disconnect(sid) + return {"status": "error", "message": str(e)} + + t1 = time.time() + logger.debug(f"Booting up VAD and transcoder took {t1-t0} sec") + + # TODO: if async_processing is false, then we need to run transcoder.process_pipeline_once() whenever we receive audio, or at some other sensible interval + if async_processing: + member.transcoder.start() + + # We need to emit a room state update here since room state now includes # of active transcoders + await emit_room_state_update(room) + await emit_server_state_update() + + return {"status": "ok", "message": "server_ready"} + + +# The config here is a partial config, meaning it may not contain all the config values -- only the ones the user +# wants to change +@sio.on("set_dynamic_config") +@catch_and_log_exceptions_for_sio_event_handlers +async def set_dynamic_config( + sid, + # partial_config's type is defined in StreamingTypes.ts + partial_config, +): + session_data = await get_session_data(sid) + + member = None + + if session_data: + member = session_data.get("member_object") + + if member: + new_dynamic_config = { + **(member.transcoder_dynamic_config or {}), + **partial_config, + } + logger.info( + f"[set_dynamic_config] Setting new dynamic config:\n\n{pformat(new_dynamic_config)}\n" + ) + member.transcoder_dynamic_config = new_dynamic_config + + return {"status": "ok", "message": "dynamic_config_set"} + + +@sio.event +@catch_and_log_exceptions_for_sio_event_handlers +async def incoming_audio(sid, blob): + session_data = await get_session_data(sid) + + client_id = None + member = None + room = None + + if session_data: + client_id = session_data.get("client_id") + member = session_data.get("member_object") + room = session_data.get("room_object") + + logger.debug(f"[event: incoming_audio] from member {member}") + + # If the server is locked by someone else, kill our transcoder and ignore incoming audio + # If the server lock client does NOT have an active transcoder session allow this incoming audio pipeline to proceed, + # knowing that this stream will be interrupted if the server lock client starts streaming + if ( + server_lock is not None + and server_lock.get("client_id") != client_id + and server_lock.get("member_object") + and server_lock.get("member_object").transcoder is not None + ): + # TODO: Send an event to the client to let them know their streaming session has been killed + if member.transcoder: + member.transcoder.close = True + member.transcoder = None + # Update both room state and server state given that the number of active transcoders has changed + if room: + await emit_room_state_update(room) + await emit_server_state_update() + logger.warn( + f"[incoming_audio] Server is locked to client {server_lock.get('client_id')}. Ignoring incoming audio from client {client_id}." + ) + return + + if member is None or room is None: + logger.error( + f"[incoming_audio] Received incoming_audio from {member}, but member or room is None. This should not happen." + ) + return + + # NOTE: bytes and bytearray are very similar, but bytes is immutable, and is what is returned by socketio + if not isinstance(blob, bytes): + logger.error( + f"[incoming_audio] Received audio from {member}, but it was not of type `bytes`. type(blob) = {type(blob)}" + ) + return + + if member.transcoder is None: + logger.error( + f"[incoming_audio] Received audio from {member}, but no transcoder configured to process it (member.transcoder is None). This should not happen." + ) + return + + member.transcoder.process_incoming_bytes( + blob, dynamic_config=member.transcoder_dynamic_config + ) + + # Send back any available model output + # NOTE: In theory it would make sense remove this from the incoming_audio handler and + # handle this in a dedicated thread that checks for output and sends it right away, + # but in practice for our limited demo use cases this approach didn't add noticeable + # latency, so we're keeping it simple for now. + events = get_transcoder_output_events(member.transcoder) + logger.debug(f"[incoming_audio] transcoder output events: {len(events)}") + + if len(events) == 0: + logger.debug("[incoming_audio] No transcoder output to send") + else: + for e in events: + if e["event"] == "translation_speech" and member.requested_output_type in [ + "s2s", + "s2s&t", + ]: + logger.debug("[incoming_audio] Sending translation_speech event") + await sio.emit( + "translation_speech", e, room=f"{room.room_id}_listeners" + ) + elif e["event"] == "translation_text" and member.requested_output_type in [ + "s2t", + "s2s&t", + ]: + logger.debug("[incoming_audio] Sending translation_text event") + await sio.emit("translation_text", e, room=f"{room.room_id}_listeners") + else: + logger.error(f"[incoming_audio] Unexpected event type: {e['event']}") + + return + + +@sio.event +@catch_and_log_exceptions_for_sio_event_handlers +async def stop_stream(sid): + session_data = await get_session_data(sid) + client_id, member, room = itemgetter("client_id", "member_object", "room_object")( + session_data + ) + + logger.debug(f"[event: stop_stream][{room}] Attempting to stop stream for {member}") + + if member is None or room is None: + message = f"Received stop_stream from {member}, but member or room is None. This should not happen." + logger.error(message) + return {"status": "error", "message": message} + + # In order to stop the stream and end the transcoder thread, set close to True and unset it for the member + if member.transcoder: + member.transcoder.close = True + member.transcoder = None + else: + message = f"Received stop_stream from {member}, but member.transcoder is None. This should not happen." + logger.warn(message) + + # We need to emit a room state update here since room state now includes # of active transcoders + await emit_room_state_update(room) + # Emit a server state update now that we've changed the number of active transcoders + await emit_server_state_update() + + return {"status": "ok", "message": "Stream stopped"} + + +@sio.on("clear_transcript_for_all") +@catch_and_log_exceptions_for_sio_event_handlers +async def clear_transcript_for_all(sid): + session_data = await get_session_data(sid) + + room = session_data.get("room_object") + + if room: + await sio.emit("clear_transcript", room=f"{room.room_id}") + else: + logger.error("[clear_transcript] room is None. This should not happen.") + + +@sio.event +@catch_and_log_exceptions_for_sio_event_handlers +async def set_name(sid, name): + logger.info(f"[Event: set_name] name={name}") + await sio.save_session(sid, {"name": name}) diff --git a/seamless_server/models/.DS_Store b/seamless_server/models/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..ae96aa4c209518ce1645bb0dd0d3e74777b3d1bf Binary files /dev/null and b/seamless_server/models/.DS_Store differ diff --git a/seamless_server/models/Seamless/vad_s2st_sc_24khz_main.yaml b/seamless_server/models/Seamless/vad_s2st_sc_24khz_main.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f7dfef9be652d703d7c6c187d13113a71b0127d4 --- /dev/null +++ b/seamless_server/models/Seamless/vad_s2st_sc_24khz_main.yaml @@ -0,0 +1,25 @@ +agent_class: seamless_communication.streaming.agents.seamless_s2st.SeamlessS2STDualVocoderVADAgent +monotonic_decoder_model_name: seamless_streaming_monotonic_decoder +unity_model_name: seamless_streaming_unity +sentencepiece_model: spm_256k_nllb100.model + +task: s2st +tgt_lang: "eng" +min_unit_chunk_size: 50 +decision_threshold: 0.7 +no_early_stop: True +block_ngrams: True +vocoder_name: vocoder_v2 +expr_vocoder_name: vocoder_pretssel +gated_model_dir: . +expr_vocoder_gain: 3.0 +upstream_idx: 1 +wav2vec_yaml: wav2vec.yaml +min_starting_wait_w2vbert: 192 + +config_yaml: cfg_fbank_u2t.yaml +upstream_idx: 1 +detokenize_only: True +device: cuda:0 +max_len_a: 0 +max_len_b: 1000 diff --git a/seamless_server/models/SeamlessStreaming/vad_s2st_sc_main.yaml b/seamless_server/models/SeamlessStreaming/vad_s2st_sc_main.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1ffba98b76f9cff0c21095e160670ffc003c227c --- /dev/null +++ b/seamless_server/models/SeamlessStreaming/vad_s2st_sc_main.yaml @@ -0,0 +1,21 @@ +agent_class: seamless_communication.streaming.agents.seamless_streaming_s2st.SeamlessStreamingS2STJointVADAgent +monotonic_decoder_model_name: seamless_streaming_monotonic_decoder +unity_model_name: seamless_streaming_unity +sentencepiece_model: spm_256k_nllb100.model + +task: s2st +tgt_lang: "eng" +min_unit_chunk_size: 50 +decision_threshold: 0.7 +no_early_stop: True +block_ngrams: True +vocoder_name: vocoder_v2 +wav2vec_yaml: wav2vec.yaml +min_starting_wait_w2vbert: 192 + +config_yaml: cfg_fbank_u2t.yaml +upstream_idx: 1 +detokenize_only: True +device: cuda:0 +max_len_a: 0 +max_len_b: 1000 diff --git a/seamless_server/requirements.txt b/seamless_server/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..e3c281ae037fc6e7a24604d143f322825e090786 --- /dev/null +++ b/seamless_server/requirements.txt @@ -0,0 +1,29 @@ +# seamless_communication +git+https://github.com/facebookresearch/seamless_communication.git +# ./whl/seamless_communication-1.0.0-py3-none-any.whl +Flask==2.1.3 +Flask_Sockets==0.2.1 +g2p_en==2.1.0 +gevent==22.10.2 +gevent_websocket==0.10.1 +librosa==0.9.2 +numpy==1.24.4 +openai_whisper==20230124 +protobuf==4.24.2 +psola==0.0.1 +pydub==0.25.1 +silero==0.4.1 +soundfile==0.11.0 +stable_ts==1.4.0 +# torch # to be installed by user for desired PyTorch version +# simuleval # to be installed by seamless_communication +Werkzeug==2.0.3 +whisper==1.1.10 +colorlog==6.7.0 +python-socketio==5.9.0 +uvicorn[standard]==0.23.2 +parallel-wavegan==0.5.5 +python-jose[cryptography]==3.3.0 +starlette==0.32.0.post1 +hf_transfer==0.1.4 +huggingface_hub==0.19.4 \ No newline at end of file diff --git a/seamless_server/run_docker.sh b/seamless_server/run_docker.sh new file mode 100755 index 0000000000000000000000000000000000000000..6a73f914f986751a5361c3c853c1e5ab35cc776d --- /dev/null +++ b/seamless_server/run_docker.sh @@ -0,0 +1,5 @@ +# !/bin/bash +if [ -f models/Seamless/pretssel_melhifigan_wm.pt ] ; then + export USE_EXPRESSIVE_MODEL=1; +fi +uvicorn app_pubsub:app --host 0.0.0.0 --port 7860 \ No newline at end of file diff --git a/seamless_server/src/room.py b/seamless_server/src/room.py new file mode 100644 index 0000000000000000000000000000000000000000..2cf7fe4801bbab695c3dc28086affc224e0e1be5 --- /dev/null +++ b/seamless_server/src/room.py @@ -0,0 +1,64 @@ +# import json +import uuid + + +class Room: + def __init__(self, room_id) -> None: + self.room_id = room_id + # members is a dict from client_id to Member + self.members = {} + + # listeners and speakers are lists of client_id's + self.listeners = [] + self.speakers = [] + + def __str__(self) -> str: + return f"Room {self.room_id} ({len(self.members)} member{'s' if len(self.members) == 1 else ''})" + + def to_json(self): + varsResult = vars(self) + # Remember: result is just a shallow copy, so result.members === self.members + # Because of that, we need to jsonify self.members without writing over result.members, + # which we do here via dictionary unpacking (the ** operator) + result = { + **varsResult, + "members": {key: value.to_json() for (key, value) in self.members.items()}, + "activeTranscoders": self.get_active_transcoders(), + } + + return result + + def get_active_connections(self): + return len( + [m for m in self.members.values() if m.connection_status == "connected"] + ) + + def get_active_transcoders(self): + return len([m for m in self.members.values() if m.transcoder is not None]) + + def get_room_status_dict(self): + return { + "activeConnections": self.get_active_connections(), + "activeTranscoders": self.get_active_transcoders(), + } + + +class Member: + def __init__(self, client_id, session_id, name) -> None: + self.client_id = client_id + self.session_id = session_id + self.name = name + self.connection_status = "connected" + self.transcoder = None + self.requested_output_type = None + self.transcoder_dynamic_config = None + + def __str__(self) -> str: + return f"{self.name} (id: {self.client_id[:4]}...) ({self.connection_status})" + + def to_json(self): + self_vars = vars(self) + return { + **self_vars, + "transcoder": self.transcoder is not None, + } diff --git a/seamless_server/src/simuleval_agent_directory.py b/seamless_server/src/simuleval_agent_directory.py new file mode 100644 index 0000000000000000000000000000000000000000..6f0fc9022801d52c05f4f8823e4fb26e610e411a --- /dev/null +++ b/seamless_server/src/simuleval_agent_directory.py @@ -0,0 +1,171 @@ +# Creates a directory in which to look up available agents + +import os +from typing import List, Optional +from src.simuleval_transcoder import SimulevalTranscoder +import json +import logging + +logger = logging.getLogger("socketio_server_pubsub") + +# fmt: off +M4T_P0_LANGS = [ + "eng", + "arb", "ben", "cat", "ces", "cmn", "cym", "dan", + "deu", "est", "fin", "fra", "hin", "ind", "ita", + "jpn", "kor", "mlt", "nld", "pes", "pol", "por", + "ron", "rus", "slk", "spa", "swe", "swh", "tel", + "tgl", "tha", "tur", "ukr", "urd", "uzn", "vie", +] +# fmt: on + + +class NoAvailableAgentException(Exception): + pass + + +class AgentWithInfo: + def __init__( + self, + agent, + name: str, + modalities: List[str], + target_langs: List[str], + # Supported dynamic params are defined in StreamingTypes.ts + dynamic_params: List[str] = [], + description="", + has_expressive: Optional[bool] = None, + ): + self.agent = agent + self.has_expressive = has_expressive + self.name = name + self.description = description + self.modalities = modalities + self.target_langs = target_langs + self.dynamic_params = dynamic_params + + def get_capabilities_for_json(self): + return { + "name": self.name, + "description": self.description, + "modalities": self.modalities, + "targetLangs": self.target_langs, + "dynamicParams": self.dynamic_params, + } + + @classmethod + def load_from_json(cls, config: str): + """ + Takes in JSON array of models to load in, e.g. + [{"name": "s2s_m4t_emma-unity2_multidomain_v0.1", "description": "M4T model that supports simultaneous S2S and S2T", "modalities": ["s2t", "s2s"], "targetLangs": ["en"]}, + {"name": "s2s_m4t_expr-emma_v0.1", "description": "ES-EN expressive model that supports S2S and S2T", "modalities": ["s2t", "s2s"], "targetLangs": ["en"]}] + """ + configs = json.loads(config) + agents = [] + for config in configs: + agent = SimulevalTranscoder.build_agent(config["name"]) + agents.append( + AgentWithInfo( + agent=agent, + name=config["name"], + modalities=config["modalities"], + target_langs=config["targetLangs"], + ) + ) + return agents + + +class SimulevalAgentDirectory: + # Available models. These are the directories where the models can be found, and also serve as an ID for the model. + seamless_streaming_agent = "SeamlessStreaming" + seamless_agent = "Seamless" + + def __init__(self): + self.agents = [] + self.did_build_and_add_agents = False + + def add_agent(self, agent: AgentWithInfo): + self.agents.append(agent) + + def build_agent_if_available(self, model_id, config_name=None): + agent = None + try: + if config_name is not None: + agent = SimulevalTranscoder.build_agent( + model_id, + config_name=config_name, + ) + else: + agent = SimulevalTranscoder.build_agent( + model_id, + ) + except Exception as e: + from fairseq2.assets.error import AssetError + logger.warning("Failed to build agent %s: %s" % (model_id, e)) + if isinstance(e, AssetError): + logger.warning( + "Please download gated assets and set `gated_model_dir` in the config" + ) + raise e + + return agent + + def build_and_add_agents(self, models_override=None): + if self.did_build_and_add_agents: + return + + if models_override is not None: + agent_infos = AgentWithInfo.load_from_json(models_override) + for agent_info in agent_infos: + self.add_agent(agent_info) + else: + s2s_agent = None + if os.environ.get("USE_EXPRESSIVE_MODEL", "0") == "1": + logger.info("Building expressive model...") + s2s_agent = self.build_agent_if_available( + SimulevalAgentDirectory.seamless_agent, + config_name="vad_s2st_sc_24khz_main.yaml", + ) + has_expressive = True + else: + logger.info("Building non-expressive model...") + s2s_agent = self.build_agent_if_available( + SimulevalAgentDirectory.seamless_streaming_agent, + config_name="vad_s2st_sc_main.yaml", + ) + has_expressive = False + + if s2s_agent: + self.add_agent( + AgentWithInfo( + agent=s2s_agent, + name=SimulevalAgentDirectory.seamless_streaming_agent, + modalities=["s2t", "s2s"], + target_langs=M4T_P0_LANGS, + dynamic_params=["expressive"], + description="multilingual expressive model that supports S2S and S2T", + has_expressive=has_expressive, + ) + ) + + if len(self.agents) == 0: + logger.error( + "No agents were loaded. This likely means you are missing the actual model files specified in simuleval_agent_directory." + ) + + self.did_build_and_add_agents = True + + def get_agent(self, name): + for agent in self.agents: + if agent.name == name: + return agent + return None + + def get_agent_or_throw(self, name): + agent = self.get_agent(name) + if agent is None: + raise NoAvailableAgentException("No agent found with name= %s" % (name)) + return agent + + def get_agents_capabilities_list_for_json(self): + return [agent.get_capabilities_for_json() for agent in self.agents] diff --git a/seamless_server/src/simuleval_transcoder.py b/seamless_server/src/simuleval_transcoder.py new file mode 100644 index 0000000000000000000000000000000000000000..216a3c759fcdeccad8da50db00b51d6cf03db223 --- /dev/null +++ b/seamless_server/src/simuleval_transcoder.py @@ -0,0 +1,428 @@ +from simuleval.utils.agent import build_system_from_dir +from typing import Any, List, Optional, Tuple, Union +import numpy as np +import soundfile +import io +import asyncio +from simuleval.agents.pipeline import TreeAgentPipeline +from simuleval.agents.states import AgentStates +from simuleval.data.segments import Segment, EmptySegment, SpeechSegment +import threading +import math +import logging +import sys +from pathlib import Path +import time +from g2p_en import G2p +import torch +import traceback +import time +import random +import colorlog + +from .speech_and_text_output import SpeechAndTextOutput + +MODEL_SAMPLE_RATE = 16_000 + +logger = logging.getLogger(__name__) +# logger.propagate = False +handler = colorlog.StreamHandler(stream=sys.stdout) +formatter = colorlog.ColoredFormatter( + "%(log_color)s[%(asctime)s][%(levelname)s][%(module)s]:%(reset)s %(message)s", + reset=True, + log_colors={ + "DEBUG": "cyan", + "INFO": "green", + "WARNING": "yellow", + "ERROR": "red", + "CRITICAL": "red,bg_white", + }, +) +handler.setFormatter(formatter) +logger.addHandler(handler) +logger.setLevel(logging.WARNING) + + +class OutputSegments: + def __init__(self, segments: Union[List[Segment], Segment]): + if isinstance(segments, Segment): + segments = [segments] + self.segments: List[Segment] = [s for s in segments] + + @property + def is_empty(self): + return all(segment.is_empty for segment in self.segments) + + @property + def finished(self): + return all(segment.finished for segment in self.segments) + + def compute_length(self, g2p): + lengths = [] + for segment in self.segments: + if segment.data_type == "text": + lengths.append(len([x for x in g2p(segment.content) if x != " "])) + elif segment.data_type == "speech": + lengths.append(len(segment.content) / MODEL_SAMPLE_RATE) + elif isinstance(segment, EmptySegment): + continue + else: + logger.warning( + f"Unexpected data_type: {segment.data_type} not in 'speech', 'text'" + ) + return max(lengths) + + @classmethod + def join_output_buffer( + cls, buffer: List[List[Segment]], output: SpeechAndTextOutput + ): + num_segments = len(buffer[0]) + for i in range(num_segments): + segment_list = [ + buffer[j][i] + for j in range(len(buffer)) + if buffer[j][i].data_type is not None + ] + if len(segment_list) == 0: + continue + if len(set(segment.data_type for segment in segment_list)) != 1: + logger.warning( + f"Data type mismatch at {i}: {set(segment.data_type for segment in segment_list)}" + ) + continue + data_type = segment_list[0].data_type + if data_type == "text": + if output.text is not None: + logger.warning("Multiple text outputs, overwriting!") + output.text = " ".join([segment.content for segment in segment_list]) + elif data_type == "speech": + if output.speech_samples is not None: + logger.warning("Multiple speech outputs, overwriting!") + speech_out = [] + for segment in segment_list: + speech_out += segment.content + output.speech_samples = speech_out + output.speech_sample_rate = segment.sample_rate + elif isinstance(segment_list[0], EmptySegment): + continue + else: + logger.warning( + f"Invalid output buffer data type: {data_type}, expected 'speech' or 'text" + ) + + return output + + def __repr__(self) -> str: + repr_str = str(self.segments) + return f"{self.__class__.__name__}(\n\t{repr_str}\n)" + + +class SimulevalTranscoder: + def __init__(self, agent, sample_rate, debug, buffer_limit): + self.agent = agent.agent + self.has_expressive = agent.has_expressive + self.input_queue = asyncio.Queue() + self.output_queue = asyncio.Queue() + self.states = self.agent.build_states() + if debug: + self.get_states_root().debug = True + self.incoming_sample_rate = sample_rate + self.close = False + self.g2p = G2p() + + # buffer all outgoing translations within this amount of time + self.output_buffer_idle_ms = 5000 + self.output_buffer_size_limit = ( + buffer_limit # phonemes for text, seconds for speech + ) + self.output_buffer_cur_size = 0 + self.output_buffer: List[List[Segment]] = [] + self.speech_output_sample_rate = None + + self.last_output_ts = time.time() * 1000 + self.timeout_ms = ( + 30000 # close the transcoder thread after this amount of silence + ) + self.first_input_ts = None + self.first_output_ts = None + self.debug = debug + self.debug_ts = f"{time.time()}_{random.randint(1000, 9999)}" + if self.debug: + debug_folder = Path(__file__).resolve().parent.parent / "debug" + self.test_incoming_wav = soundfile.SoundFile( + debug_folder / f"{self.debug_ts}_test_incoming.wav", + mode="w+", + format="WAV", + subtype="PCM_16", + samplerate=self.incoming_sample_rate, + channels=1, + ) + self.get_states_root().test_input_segments_wav = soundfile.SoundFile( + debug_folder / f"{self.debug_ts}_test_input_segments.wav", + mode="w+", + format="WAV", + samplerate=MODEL_SAMPLE_RATE, + channels=1, + ) + + def get_states_root(self) -> AgentStates: + if isinstance(self.agent, TreeAgentPipeline): + # self.states is a dict + return self.states[self.agent.source_module] + else: + # self.states is a list + return self.states[0] + + def reset_states(self): + if isinstance(self.agent, TreeAgentPipeline): + states_iter = self.states.values() + else: + states_iter = self.states + for state in states_iter: + state.reset() + + def debug_log(self, *args): + if self.debug: + logger.info(*args) + + @classmethod + def build_agent(cls, model_path, config_name): + logger.info(f"Building simuleval agent: {model_path}, {config_name}") + agent = build_system_from_dir( + Path(__file__).resolve().parent.parent / f"models/{model_path}", + config_name=config_name, + ) + device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + agent.to(device, fp16=True) + logger.info( + f"Successfully built simuleval agent {model_path} on device {device}" + ) + + return agent + + def process_incoming_bytes(self, incoming_bytes, dynamic_config): + # TODO: We probably want to do some validation on dynamic_config to ensure it has what we needs + segment, sr = self._preprocess_wav(incoming_bytes) + segment = SpeechSegment( + content=segment, + sample_rate=sr, + tgt_lang=dynamic_config.get("targetLanguage"), + config=dynamic_config, + ) + if dynamic_config.get("expressive") is True and self.has_expressive is False: + logger.warning( + "Passing 'expressive' but the agent does not support expressive output!" + ) + # # segment is array([0, 0, 0, ..., 0, 0, 0], dtype=int16) + self.input_queue.put_nowait(segment) + + def get_input_segment(self): + if self.input_queue.empty(): + return None + chunk = self.input_queue.get_nowait() + self.input_queue.task_done() + return chunk + + def convert_waveform( + self, + waveform: Union[np.ndarray, torch.Tensor], + sample_rate: int, + normalize_volume: bool = False, + to_mono: bool = False, + to_sample_rate: Optional[int] = None, + ) -> Tuple[Union[np.ndarray, torch.Tensor], int]: + """convert a waveform: + - to a target sample rate + - from multi-channel to mono channel + - volume normalization + + Args: + waveform (numpy.ndarray or torch.Tensor): 2D original waveform + (channels x length) + sample_rate (int): original sample rate + normalize_volume (bool): perform volume normalization + to_mono (bool): convert to mono channel if having multiple channels + to_sample_rate (Optional[int]): target sample rate + Returns: + waveform (numpy.ndarray): converted 2D waveform (channels x length) + sample_rate (float): target sample rate + """ + try: + import torchaudio.sox_effects as ta_sox + except ImportError: + raise ImportError("Please install torchaudio: pip install torchaudio") + + effects = [] + if normalize_volume: + effects.append(["gain", "-n"]) + if to_sample_rate is not None and to_sample_rate != sample_rate: + effects.append(["rate", f"{to_sample_rate}"]) + if to_mono and waveform.shape[0] > 1: + effects.append(["channels", "1"]) + if len(effects) > 0: + is_np_input = isinstance(waveform, np.ndarray) + _waveform = torch.from_numpy(waveform) if is_np_input else waveform + converted, converted_sample_rate = ta_sox.apply_effects_tensor( + _waveform, sample_rate, effects + ) + if is_np_input: + converted = converted.numpy() + return converted, converted_sample_rate + return waveform, sample_rate + + def _preprocess_wav(self, data: Any) -> Tuple[np.ndarray, int]: + segment, sample_rate = soundfile.read( + io.BytesIO(data), + dtype="float32", + always_2d=True, + frames=-1, + start=0, + format="RAW", + subtype="PCM_16", + samplerate=self.incoming_sample_rate, + channels=1, + ) + if self.debug: + self.test_incoming_wav.seek(0, soundfile.SEEK_END) + self.test_incoming_wav.write(segment) + + segment = segment.T + segment, new_sample_rate = self.convert_waveform( + segment, + sample_rate, + normalize_volume=False, + to_mono=True, + to_sample_rate=MODEL_SAMPLE_RATE, + ) + + assert MODEL_SAMPLE_RATE == new_sample_rate + segment = segment.squeeze(axis=0) + return segment, new_sample_rate + + def process_pipeline_impl(self, input_segment): + try: + with torch.no_grad(): + output_segment = OutputSegments( + self.agent.pushpop(input_segment, self.states) + ) + if ( + self.get_states_root().first_input_ts is not None + and self.first_input_ts is None + ): + # TODO: this is hacky + self.first_input_ts = self.get_states_root().first_input_ts + + if not output_segment.is_empty: + self.output_queue.put_nowait(output_segment) + + if output_segment.finished: + self.debug_log("OUTPUT SEGMENT IS FINISHED. Resetting states.") + + self.reset_states() + + if self.debug: + # when we rebuild states, this value is reset to whatever + # is in the system dir config, which defaults debug=False. + self.get_states_root().debug = True + except Exception as e: + logger.error(f"Got exception while processing pipeline: {e}") + traceback.print_exc() + return input_segment + + def process_pipeline_loop(self): + if self.close: + return # closes the thread + + self.debug_log("processing_pipeline") + while not self.close: + input_segment = self.get_input_segment() + if input_segment is None: + if self.get_states_root().is_fresh_state: # TODO: this is hacky + time.sleep(0.3) + else: + time.sleep(0.03) + continue + self.process_pipeline_impl(input_segment) + self.debug_log("finished processing_pipeline") + + def process_pipeline_once(self): + if self.close: + return + + self.debug_log("processing pipeline once") + input_segment = self.get_input_segment() + if input_segment is None: + return + self.process_pipeline_impl(input_segment) + self.debug_log("finished processing_pipeline_once") + + def get_output_segment(self): + if self.output_queue.empty(): + return None + + output_chunk = self.output_queue.get_nowait() + self.output_queue.task_done() + return output_chunk + + def start(self): + self.debug_log("starting transcoder in a thread") + threading.Thread(target=self.process_pipeline_loop).start() + + def first_translation_time(self): + return round((self.first_output_ts - self.first_input_ts) / 1000, 2) + + def get_buffered_output(self) -> SpeechAndTextOutput: + now = time.time() * 1000 + self.debug_log(f"get_buffered_output queue size: {self.output_queue.qsize()}") + while not self.output_queue.empty(): + tmp_out = self.get_output_segment() + if tmp_out and tmp_out.compute_length(self.g2p) > 0: + if len(self.output_buffer) == 0: + self.last_output_ts = now + self._populate_output_buffer(tmp_out) + self._increment_output_buffer_size(tmp_out) + + if tmp_out.finished: + self.debug_log("tmp_out.finished") + res = self._gather_output_buffer_data(final=True) + self.debug_log(f"gathered output data: {res}") + self.output_buffer = [] + self.increment_output_buffer_size = 0 + self.last_output_ts = now + self.first_output_ts = now + return res + else: + self.debug_log("tmp_out.compute_length is not > 0") + + if len(self.output_buffer) > 0 and ( + now - self.last_output_ts >= self.output_buffer_idle_ms + or self.output_buffer_cur_size >= self.output_buffer_size_limit + ): + self.debug_log( + "[get_buffered_output] output_buffer is not empty. getting res to return." + ) + self.last_output_ts = now + res = self._gather_output_buffer_data(final=False) + self.debug_log(f"gathered output data: {res}") + self.output_buffer = [] + self.output_buffer_phoneme_count = 0 + self.first_output_ts = now + return res + else: + self.debug_log("[get_buffered_output] output_buffer is empty...") + return None + + def _gather_output_buffer_data(self, final): + output = SpeechAndTextOutput() + output.final = final + output = OutputSegments.join_output_buffer(self.output_buffer, output) + return output + + def _increment_output_buffer_size(self, segment: OutputSegments): + self.output_buffer_cur_size += segment.compute_length(self.g2p) + + def _populate_output_buffer(self, segment: OutputSegments): + self.output_buffer.append(segment.segments) + + def _compute_phoneme_count(self, string: str) -> int: + return len([x for x in self.g2p(string) if x != " "]) diff --git a/seamless_server/src/speech_and_text_output.py b/seamless_server/src/speech_and_text_output.py new file mode 100644 index 0000000000000000000000000000000000000000..1a4e5c7884f8256df01b9edca6d5b1759d5ab5ba --- /dev/null +++ b/seamless_server/src/speech_and_text_output.py @@ -0,0 +1,15 @@ +# Provides a container to return both speech and text output from our model at the same time + + +class SpeechAndTextOutput: + def __init__( + self, + text: str = None, + speech_samples: list = None, + speech_sample_rate: float = None, + final: bool = False, + ): + self.text = text + self.speech_samples = speech_samples + self.speech_sample_rate = speech_sample_rate + self.final = final diff --git a/seamless_server/src/transcoder_helpers.py b/seamless_server/src/transcoder_helpers.py new file mode 100644 index 0000000000000000000000000000000000000000..f7bc39133538b71705be825f2a32ea48152bd3f2 --- /dev/null +++ b/seamless_server/src/transcoder_helpers.py @@ -0,0 +1,43 @@ +import logging + +logger = logging.getLogger("socketio_server_pubsub") + + +def get_transcoder_output_events(transcoder) -> list: + speech_and_text_output = transcoder.get_buffered_output() + if speech_and_text_output is None: + logger.debug("No output from transcoder.get_buffered_output()") + return [] + + logger.debug(f"We DID get output from the transcoder! {speech_and_text_output}") + + lat = None + + events = [] + + if speech_and_text_output.speech_samples: + events.append( + { + "event": "translation_speech", + "payload": speech_and_text_output.speech_samples, + "sample_rate": speech_and_text_output.speech_sample_rate, + } + ) + + if speech_and_text_output.text: + events.append( + { + "event": "translation_text", + "payload": speech_and_text_output.text, + } + ) + + for e in events: + e["eos"] = speech_and_text_output.final + + # if not latency_sent: + # lat = transcoder.first_translation_time() + # latency_sent = True + # to_send["latency"] = lat + + return events diff --git a/streaming-react-app/.eslintrc.cjs b/streaming-react-app/.eslintrc.cjs new file mode 100644 index 0000000000000000000000000000000000000000..b2106c966499a1f9306b8e0247ac9aba219f4628 --- /dev/null +++ b/streaming-react-app/.eslintrc.cjs @@ -0,0 +1,18 @@ +module.exports = { + root: true, + env: {browser: true, es2020: true}, + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:react-hooks/recommended', + ], + ignorePatterns: ['dist', '.eslintrc.cjs'], + parser: '@typescript-eslint/parser', + plugins: ['react-refresh'], + rules: { + 'react-refresh/only-export-components': [ + 'warn', + {allowConstantExport: true}, + ], + }, +}; diff --git a/streaming-react-app/.gitignore b/streaming-react-app/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..a547bf36d8d11a4f89c59c144f24795749086dd1 --- /dev/null +++ b/streaming-react-app/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/streaming-react-app/README.md b/streaming-react-app/README.md new file mode 100644 index 0000000000000000000000000000000000000000..94e03bb2a9869371663b4723ab5814f563283664 --- /dev/null +++ b/streaming-react-app/README.md @@ -0,0 +1,14 @@ +# 🚀 Streaming React App + +## Getting Started + +This project uses the [Yarn Package Manager](https://yarnpkg.com/). + +1. `yarn` - Install project dependencies +2. `yarn run dev` - Run the app with a development server that supports hot module reloading + +NOTE: You will either need to provide the server URL via environment variable (you can use the `.env` file for this) or via a url param when you load the react app (example: `http://localhost:5173/?serverURL=localhost:8000`) + +## URL Parameters + +You can provide URL parameters in order to change the behavior of the app. Those are documented in [URLParams.ts](src/URLParams.ts). diff --git a/streaming-react-app/index.html b/streaming-react-app/index.html new file mode 100644 index 0000000000000000000000000000000000000000..72538e8fc1bbaeefacd969c9655300850e148473 --- /dev/null +++ b/streaming-react-app/index.html @@ -0,0 +1,13 @@ + + + + + + + Illy's translator + + +
+ + + diff --git a/streaming-react-app/package-lock.json b/streaming-react-app/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..71fc6b51041b7fed2e75dccb54cc41ce92c279d0 --- /dev/null +++ b/streaming-react-app/package-lock.json @@ -0,0 +1,3491 @@ +{ + "name": "streaming-react-app", + "version": "0.0.13", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true + }, + "@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@aws-crypto/sha256-js": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-1.2.2.tgz", + "integrity": "sha512-Nr1QJIbW/afYYGzYvrF70LtaHrIRtd4TNAglX8BvlfxJLZ45SAmueIKYl5tWoNBPzp65ymXGFK0Bb1vZUpuc9g==", + "requires": { + "@aws-crypto/util": "^1.2.2", + "@aws-sdk/types": "^3.1.0", + "tslib": "^1.11.1" + } + }, + "@aws-crypto/util": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-1.2.2.tgz", + "integrity": "sha512-H8PjG5WJ4wz0UXAFXeJjWCW1vkvIJ3qUUD+rGRwJ2/hj+xT58Qle2MTql/2MGzkU+1JLAFuR6aJpLAjHwhmwwg==", + "requires": { + "@aws-sdk/types": "^3.1.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "@aws-sdk/types": { + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.460.0.tgz", + "integrity": "sha512-MyZSWS/FV8Bnux5eD9en7KLgVxevlVrGNEP3X2D7fpnUlLhl0a7k8+OpSI2ozEQB8hIU2DLc/XXTKRerHSefxQ==", + "requires": { + "@smithy/types": "^2.5.0", + "tslib": "^2.5.0" + }, + "dependencies": { + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + } + } + }, + "@aws-sdk/util-utf8-browser": { + "version": "3.259.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", + "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", + "requires": { + "tslib": "^2.3.1" + }, + "dependencies": { + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + } + } + }, + "@babel/code-frame": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", + "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", + "requires": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + } + }, + "@babel/compat-data": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz", + "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==", + "dev": true + }, + "@babel/core": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", + "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.3", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.2", + "@babel/parser": "^7.23.3", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.3", + "@babel/types": "^7.23.3", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "dependencies": { + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.4.tgz", + "integrity": "sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ==", + "dev": true, + "requires": { + "@babel/types": "^7.23.4", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.15", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "dependencies": { + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } + }, + "@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true + }, + "@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "requires": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "requires": { + "@babel/types": "^7.22.15" + } + }, + "@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true + }, + "@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==" + }, + "@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==" + }, + "@babel/helper-validator-option": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", + "dev": true + }, + "@babel/helpers": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.4.tgz", + "integrity": "sha512-HfcMizYz10cr3h29VqyfGL6ZWIjTwWfvYBMsBVGwpcbhNGe3wQ1ZXZRPzZoAHhd9OqHadHqjQ89iVKINXnbzuw==", + "dev": true, + "requires": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.4", + "@babel/types": "^7.23.4" + } + }, + "@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "requires": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.4.tgz", + "integrity": "sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==", + "dev": true + }, + "@babel/plugin-transform-react-jsx-self": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz", + "integrity": "sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-react-jsx-source": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.23.3.tgz", + "integrity": "sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/runtime": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.4.tgz", + "integrity": "sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg==", + "requires": { + "regenerator-runtime": "^0.14.0" + } + }, + "@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + } + }, + "@babel/traverse": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.4.tgz", + "integrity": "sha512-IYM8wSUwunWTB6tFC2dkKZhxbIjHoWemdK+3f8/wq8aKhbUscxD5MX72ubd90fxvFknaLPeGw5ycU84V1obHJg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.23.4", + "@babel/generator": "^7.23.4", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.4", + "@babel/types": "^7.23.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.4.tgz", + "integrity": "sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==", + "requires": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + } + }, + "@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "requires": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "requires": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, + "@emotion/is-prop-valid": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", + "requires": { + "@emotion/memoize": "^0.8.1" + } + }, + "@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "@emotion/react": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", + "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + } + }, + "@emotion/serialize": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz", + "integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==", + "requires": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "@emotion/styled": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + } + }, + "@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, + "@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==" + }, + "@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + }, + "@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + }, + "@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "dev": true, + "optional": true + }, + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true + }, + "@eslint/eslintrc": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz", + "integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + } + } + }, + "@eslint/js": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.54.0.tgz", + "integrity": "sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==", + "dev": true + }, + "@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "dev": true + }, + "@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "@mediapipe/tasks-vision": { + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/@mediapipe/tasks-vision/-/tasks-vision-0.10.8.tgz", + "integrity": "sha512-Rp7ll8BHrKB3wXaRFKhrltwZl1CiXGdibPxuWXvqGnKTnv8fqa/nvftYNuSbf+pbJWKYCXdBtYTITdAUTGGh0Q==" + }, + "@mui/base": { + "version": "5.0.0-beta.11", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.11.tgz", + "integrity": "sha512-FdKZGPd8qmC3ZNke7CNhzcEgToc02M6WYZc9hcBsNQ17bgAd3s9F//1bDDYgMVBYxDM71V0sv/hBHlOY4I1ZVA==", + "requires": { + "@babel/runtime": "^7.22.6", + "@emotion/is-prop-valid": "^1.2.1", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.5", + "@popperjs/core": "^2.11.8", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, + "@mui/core-downloads-tracker": { + "version": "5.14.18", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.18.tgz", + "integrity": "sha512-yFpF35fEVDV81nVktu0BE9qn2dD/chs7PsQhlyaV3EnTeZi9RZBuvoEfRym1/jmhJ2tcfeWXiRuHG942mQXJJQ==" + }, + "@mui/icons-material": { + "version": "5.14.3", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.14.3.tgz", + "integrity": "sha512-XkxWPhageu1OPUm2LWjo5XqeQ0t2xfGe8EiLkRW9oz2LHMMZmijvCxulhgquUVTF1DnoSh+3KoDLSsoAFtVNVw==", + "requires": { + "@babel/runtime": "^7.22.6" + } + }, + "@mui/material": { + "version": "5.14.5", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.5.tgz", + "integrity": "sha512-4qa4GMfuZH0Ai3mttk5ccXP8a3sf7aPlAJwyMrUSz6h9hPri6BPou94zeu3rENhhmKLby9S/W1y+pmficy8JKA==", + "requires": { + "@babel/runtime": "^7.22.6", + "@mui/base": "5.0.0-beta.11", + "@mui/core-downloads-tracker": "^5.14.5", + "@mui/system": "^5.14.5", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.5", + "@types/react-transition-group": "^4.4.6", + "clsx": "^2.0.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, + "@mui/private-theming": { + "version": "5.14.18", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.14.18.tgz", + "integrity": "sha512-WSgjqRlzfHU+2Rou3HlR2Gqfr4rZRsvFgataYO3qQ0/m6gShJN+lhVEvwEiJ9QYyVzMDvNpXZAcqp8Y2Vl+PAw==", + "requires": { + "@babel/runtime": "^7.23.2", + "@mui/utils": "^5.14.18", + "prop-types": "^15.8.1" + } + }, + "@mui/styled-engine": { + "version": "5.14.18", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.14.18.tgz", + "integrity": "sha512-pW8bpmF9uCB5FV2IPk6mfbQCjPI5vGI09NOLhtGXPeph/4xIfC3JdIX0TILU0WcTs3aFQqo6s2+1SFgIB9rCXA==", + "requires": { + "@babel/runtime": "^7.23.2", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + } + }, + "@mui/system": { + "version": "5.14.18", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.18.tgz", + "integrity": "sha512-hSQQdb3KF72X4EN2hMEiv8EYJZSflfdd1TRaGPoR7CIAG347OxCslpBUwWngYobaxgKvq6xTrlIl+diaactVww==", + "requires": { + "@babel/runtime": "^7.23.2", + "@mui/private-theming": "^5.14.18", + "@mui/styled-engine": "^5.14.18", + "@mui/types": "^7.2.9", + "@mui/utils": "^5.14.18", + "clsx": "^2.0.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + } + }, + "@mui/types": { + "version": "7.2.9", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.9.tgz", + "integrity": "sha512-k1lN/PolaRZfNsRdAqXtcR71sTnv3z/VCCGPxU8HfdftDkzi335MdJ6scZxvofMAd/K/9EbzCZTFBmlNpQVdCg==" + }, + "@mui/utils": { + "version": "5.14.18", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.18.tgz", + "integrity": "sha512-HZDRsJtEZ7WMSnrHV9uwScGze4wM/Y+u6pDVo+grUjt5yXzn+wI8QX/JwTHh9YSw/WpnUL80mJJjgCnWj2VrzQ==", + "requires": { + "@babel/runtime": "^7.23.2", + "@types/prop-types": "^15.7.10", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==" + }, + "@react-spring/animated": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.6.1.tgz", + "integrity": "sha512-ls/rJBrAqiAYozjLo5EPPLLOb1LM0lNVQcXODTC1SMtS6DbuBCPaKco5svFUQFMP2dso3O+qcC4k9FsKc0KxMQ==", + "requires": { + "@react-spring/shared": "~9.6.1", + "@react-spring/types": "~9.6.1" + } + }, + "@react-spring/core": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.6.1.tgz", + "integrity": "sha512-3HAAinAyCPessyQNNXe5W0OHzRfa8Yo5P748paPcmMowZ/4sMfaZ2ZB6e5x5khQI8NusOHj8nquoutd6FRY5WQ==", + "requires": { + "@react-spring/animated": "~9.6.1", + "@react-spring/rafz": "~9.6.1", + "@react-spring/shared": "~9.6.1", + "@react-spring/types": "~9.6.1" + } + }, + "@react-spring/rafz": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.6.1.tgz", + "integrity": "sha512-v6qbgNRpztJFFfSE3e2W1Uz+g8KnIBs6SmzCzcVVF61GdGfGOuBrbjIcp+nUz301awVmREKi4eMQb2Ab2gGgyQ==" + }, + "@react-spring/shared": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.6.1.tgz", + "integrity": "sha512-PBFBXabxFEuF8enNLkVqMC9h5uLRBo6GQhRMQT/nRTnemVENimgRd+0ZT4yFnAQ0AxWNiJfX3qux+bW2LbG6Bw==", + "requires": { + "@react-spring/rafz": "~9.6.1", + "@react-spring/types": "~9.6.1" + } + }, + "@react-spring/three": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@react-spring/three/-/three-9.6.1.tgz", + "integrity": "sha512-Tyw2YhZPKJAX3t2FcqvpLRb71CyTe1GvT3V+i+xJzfALgpk10uPGdGaQQ5Xrzmok1340DAeg2pR/MCfaW7b8AA==", + "requires": { + "@react-spring/animated": "~9.6.1", + "@react-spring/core": "~9.6.1", + "@react-spring/shared": "~9.6.1", + "@react-spring/types": "~9.6.1" + } + }, + "@react-spring/types": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.6.1.tgz", + "integrity": "sha512-POu8Mk0hIU3lRXB3bGIGe4VHIwwDsQyoD1F394OK7STTiX9w4dG3cTLljjYswkQN+hDSHRrj4O36kuVa7KPU8Q==" + }, + "@react-three/drei": { + "version": "9.89.0", + "resolved": "https://registry.npmjs.org/@react-three/drei/-/drei-9.89.0.tgz", + "integrity": "sha512-iddG7OAfng3a99nAO7erzb1wlwaY1Zlaz9EVfnW9ZiLm4rM322vXHnLX1zhrH5/AeRB/1t4bEu8uAHvXX3XwWA==", + "requires": { + "@babel/runtime": "^7.11.2", + "@mediapipe/tasks-vision": "0.10.8", + "@react-spring/three": "~9.6.1", + "@use-gesture/react": "^10.2.24", + "camera-controls": "^2.4.2", + "cross-env": "^7.0.3", + "detect-gpu": "^5.0.28", + "glsl-noise": "^0.0.0", + "lodash.clamp": "^4.0.3", + "lodash.omit": "^4.5.0", + "lodash.pick": "^4.4.0", + "maath": "^0.9.0", + "meshline": "^3.1.6", + "react-composer": "^5.0.3", + "react-merge-refs": "^1.1.0", + "stats-gl": "^1.0.4", + "stats.js": "^0.17.0", + "suspend-react": "^0.1.3", + "three-mesh-bvh": "^0.6.7", + "three-stdlib": "^2.28.0", + "troika-three-text": "^0.47.2", + "utility-types": "^3.10.0", + "uuid": "^9.0.1", + "zustand": "^3.5.13" + }, + "dependencies": { + "zustand": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", + "integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==" + } + } + }, + "@react-three/fiber": { + "version": "8.15.11", + "resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-8.15.11.tgz", + "integrity": "sha512-jOJjrjVMBJQwIK6Uirc3bErUCTiclbS2alJG1eU8pV1jIwDZwPwcfHzSi2TautxoA4ddMt5DmlpatK4rIqM4jA==", + "requires": { + "@babel/runtime": "^7.17.8", + "@types/react-reconciler": "^0.26.7", + "@types/webxr": "*", + "base64-js": "^1.5.1", + "buffer": "^6.0.3", + "its-fine": "^1.0.6", + "react-reconciler": "^0.27.0", + "react-use-measure": "^2.1.1", + "scheduler": "^0.21.0", + "suspend-react": "^0.1.3", + "zustand": "^3.7.1" + }, + "dependencies": { + "zustand": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", + "integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==" + } + } + }, + "@react-three/xr": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@react-three/xr/-/xr-5.7.1.tgz", + "integrity": "sha512-GaRUSA+lE8VJF/NrXq7QQByZ4UGHbQQ4rs3QCphZs9fVidK86hGrMOQ0kL79gZc5pa3V5uFGlOhNcUdsTYE3Bg==", + "requires": { + "@types/webxr": "*", + "three-stdlib": "^2.21.1", + "zustand": "^3.7.1" + }, + "dependencies": { + "zustand": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", + "integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==" + } + } + }, + "@smithy/types": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.6.0.tgz", + "integrity": "sha512-PgqxJq2IcdMF9iAasxcqZqqoOXBHufEfmbEUdN1pmJrJltT42b0Sc8UiYSWWzKkciIp9/mZDpzYi4qYG1qqg6g==", + "requires": { + "tslib": "^2.5.0" + }, + "dependencies": { + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + } + } + }, + "@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" + }, + "@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "requires": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.7", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.7.tgz", + "integrity": "sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.20.4", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz", + "integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==", + "dev": true, + "requires": { + "@babel/types": "^7.20.7" + } + }, + "@types/draco3d": { + "version": "1.4.9", + "resolved": "https://registry.npmjs.org/@types/draco3d/-/draco3d-1.4.9.tgz", + "integrity": "sha512-4MMUjMQb4yA5fJ4osXx+QxGHt0/ZSy4spT6jL1HM7Tn8OJEC35siqdnpOo+HxPhYjqEFumKfGVF9hJfdyKBIBA==" + }, + "@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "@types/node": { + "version": "20.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.0.tgz", + "integrity": "sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ==", + "dev": true, + "requires": { + "undici-types": "~5.26.4" + } + }, + "@types/offscreencanvas": { + "version": "2019.7.3", + "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz", + "integrity": "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==" + }, + "@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, + "@types/prop-types": { + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" + }, + "@types/react": { + "version": "18.2.39", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.39.tgz", + "integrity": "sha512-Oiw+ppED6IremMInLV4HXGbfbG6GyziY3kqAwJYOR0PNbkYDmLWQA3a95EhdSmamsvbkJN96ZNN+YD+fGjzSBA==", + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-dom": { + "version": "18.2.17", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.17.tgz", + "integrity": "sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, + "@types/react-reconciler": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.26.7.tgz", + "integrity": "sha512-mBDYl8x+oyPX/VBb3E638N0B7xG+SPk/EAMcVPeexqus/5aTpTphQi0curhhshOqRrc9t6OPoJfEUkbymse/lQ==", + "requires": { + "@types/react": "*" + } + }, + "@types/react-transition-group": { + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.9.tgz", + "integrity": "sha512-ZVNmWumUIh5NhH8aMD9CR2hdW0fNuYInlocZHaZ+dgk/1K49j1w/HoAuK1ki+pgscQrOFRTlXeoURtuzEkV3dg==", + "requires": { + "@types/react": "*" + } + }, + "@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" + }, + "@types/semver": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "dev": true + }, + "@types/uuid": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz", + "integrity": "sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==", + "dev": true + }, + "@types/webxr": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.10.tgz", + "integrity": "sha512-n3u5sqXQJhf1CS68mw3Wf16FQ4cRPNBBwdYLFzq3UddiADOim1Pn3Y6PBdDilz1vOJF3ybLxJ8ZEDlLIzrOQZg==" + }, + "@typescript-eslint/eslint-plugin": { + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.13.1.tgz", + "integrity": "sha512-5bQDGkXaxD46bPvQt08BUz9YSaO4S0fB1LB5JHQuXTfkGPI3+UUeS387C/e9jRie5GqT8u5kFTrMvAjtX4O5kA==", + "dev": true, + "requires": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.13.1", + "@typescript-eslint/type-utils": "6.13.1", + "@typescript-eslint/utils": "6.13.1", + "@typescript-eslint/visitor-keys": "6.13.1", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/parser": { + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.13.1.tgz", + "integrity": "sha512-fs2XOhWCzRhqMmQf0eicLa/CWSaYss2feXsy7xBD/pLyWke/jCIVc2s1ikEAtSW7ina1HNhv7kONoEfVNEcdDQ==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "6.13.1", + "@typescript-eslint/types": "6.13.1", + "@typescript-eslint/typescript-estree": "6.13.1", + "@typescript-eslint/visitor-keys": "6.13.1", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.1.tgz", + "integrity": "sha512-BW0kJ7ceiKi56GbT2KKzZzN+nDxzQK2DS6x0PiSMPjciPgd/JRQGMibyaN2cPt2cAvuoH0oNvn2fwonHI+4QUQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.13.1", + "@typescript-eslint/visitor-keys": "6.13.1" + } + }, + "@typescript-eslint/type-utils": { + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.13.1.tgz", + "integrity": "sha512-A2qPlgpxx2v//3meMqQyB1qqTg1h1dJvzca7TugM3Yc2USDY+fsRBiojAEo92HO7f5hW5mjAUF6qobOPzlBCBQ==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "6.13.1", + "@typescript-eslint/utils": "6.13.1", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/types": { + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.1.tgz", + "integrity": "sha512-gjeEskSmiEKKFIbnhDXUyiqVma1gRCQNbVZ1C8q7Zjcxh3WZMbzWVfGE9rHfWd1msQtPS0BVD9Jz9jded44eKg==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.1.tgz", + "integrity": "sha512-sBLQsvOC0Q7LGcUHO5qpG1HxRgePbT6wwqOiGLpR8uOJvPJbfs0mW3jPA3ujsDvfiVwVlWUDESNXv44KtINkUQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.13.1", + "@typescript-eslint/visitor-keys": "6.13.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/utils": { + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.1.tgz", + "integrity": "sha512-ouPn/zVoan92JgAegesTXDB/oUp6BP1v8WpfYcqh649ejNc9Qv+B4FF2Ff626kO1xg0wWwwG48lAJ4JuesgdOw==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.13.1", + "@typescript-eslint/types": "6.13.1", + "@typescript-eslint/typescript-estree": "6.13.1", + "semver": "^7.5.4" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.1.tgz", + "integrity": "sha512-NDhQUy2tg6XGNBGDRm1XybOHSia8mcXmlbKWoQP+nm1BIIMxa55shyJfZkHpEBN62KNPLrocSM2PdPcaLgDKMQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.13.1", + "eslint-visitor-keys": "^3.4.1" + } + }, + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "@use-gesture/core": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@use-gesture/core/-/core-10.3.0.tgz", + "integrity": "sha512-rh+6MND31zfHcy9VU3dOZCqGY511lvGcfyJenN4cWZe0u1BH6brBpBddLVXhF2r4BMqWbvxfsbL7D287thJU2A==" + }, + "@use-gesture/react": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@use-gesture/react/-/react-10.3.0.tgz", + "integrity": "sha512-3zc+Ve99z4usVP6l9knYVbVnZgfqhKah7sIG+PS2w+vpig2v2OLct05vs+ZXMzwxdNCMka8B+8WlOo0z6Pn6DA==", + "requires": { + "@use-gesture/core": "10.3.0" + } + }, + "@vitejs/plugin-react": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.2.0.tgz", + "integrity": "sha512-+MHTH/e6H12kRp5HUkzOGqPMksezRMmW+TNzlh/QXfI8rRf6l2Z2yH/v12no1UvTwhZgEDMuQ7g7rrfMseU6FQ==", + "dev": true, + "requires": { + "@babel/core": "^7.23.3", + "@babel/plugin-transform-react-jsx-self": "^7.23.3", + "@babel/plugin-transform-react-jsx-source": "^7.23.3", + "@types/babel__core": "^7.20.4", + "react-refresh": "^0.14.0" + } + }, + "acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "amazon-cognito-identity-js": { + "version": "6.3.7", + "resolved": "https://registry.npmjs.org/amazon-cognito-identity-js/-/amazon-cognito-identity-js-6.3.7.tgz", + "integrity": "sha512-tSjnM7KyAeOZ7UMah+oOZ6cW4Gf64FFcc7BE2l7MTcp7ekAPrXaCbpcW2xEpH1EiDS4cPcAouHzmCuc2tr72vQ==", + "requires": { + "@aws-crypto/sha256-js": "1.2.2", + "buffer": "4.9.2", + "fast-base64-decode": "^1.0.0", + "isomorphic-unfetch": "^3.0.0", + "js-cookie": "^2.2.1" + }, + "dependencies": { + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "js-cookie": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", + "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==" + } + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "audiobuffer-to-wav": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/audiobuffer-to-wav/-/audiobuffer-to-wav-1.0.0.tgz", + "integrity": "sha512-CAoir4NRrAzAgYo20tEMiKZR84coE8bq/L+H2kwAaULVY4+0xySsEVtNT5raqpzmH6y0pqzY6EmoViLd9W8F/w==" + }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" + }, + "aws-sdk": { + "version": "2.1506.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1506.0.tgz", + "integrity": "sha512-jSBbofvPa7HJykyM7Xph9psMcWPl6UgdiKjG2E7fHJb6psW+BZN9ZvSGOBvRIlT8Y6+JGzI0qkouS1OLK9slhg==", + "requires": { + "buffer": "4.9.2", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.16.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "util": "^0.12.4", + "uuid": "8.0.0", + "xml2js": "0.5.0" + }, + "dependencies": { + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + }, + "uuid": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", + "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==" + } + } + }, + "babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "requires": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "requires": { + "require-from-string": "^2.0.2" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browserslist": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", + "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.13" + } + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "requires": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "camera-controls": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/camera-controls/-/camera-controls-2.7.3.tgz", + "integrity": "sha512-L4mxjBd3u8qiOLozdWrH2P8ZybSsDXBF7iyNyqNEFJhPUkovmuARWR8JTc1B/qlclOIg6FvZZA/0uAZMMim0mw==" + }, + "caniuse-lite": { + "version": "1.0.30001565", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz", + "integrity": "sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + } + } + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==" + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "concurrently": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.1.tgz", + "integrity": "sha512-nVraf3aXOpIcNud5pB9M82p1tynmZkrSGQ1p6X/VY8cJ+2LMVqAgXsJxYYefACSHbTYlm92O1xuhdGTjwoEvbQ==", + "dev": true, + "requires": { + "chalk": "^4.1.2", + "date-fns": "^2.30.0", + "lodash": "^4.17.21", + "rxjs": "^7.8.1", + "shell-quote": "^1.8.1", + "spawn-command": "0.0.2", + "supports-color": "^8.1.1", + "tree-kill": "^1.2.2", + "yargs": "^17.7.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, + "cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "requires": { + "cross-spawn": "^7.0.1" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + }, + "date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.21.0" + } + }, + "debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "requires": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, + "detect-gpu": { + "version": "5.0.37", + "resolved": "https://registry.npmjs.org/detect-gpu/-/detect-gpu-5.0.37.tgz", + "integrity": "sha512-EraWs84faI4iskB4qvE39bevMIazEvd1RpoyGLOBesRLbiz6eMeJqqRPHjEFClfRByYZzi9IzU35rBXIO76oDw==", + "requires": { + "webgl-constants": "^1.1.1" + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "requires": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "draco3d": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.6.tgz", + "integrity": "sha512-+3NaRjWktb5r61ZFoDejlykPEFKT5N/LkbXsaddlw6xNSXBanUYpFc2AXXpbJDilPHazcSreU/DpQIaxfX0NfQ==" + }, + "electron-to-chromium": { + "version": "1.4.596", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.596.tgz", + "integrity": "sha512-zW3zbZ40Icb2BCWjm47nxwcFGYlIgdXkAx85XDO7cyky9J4QQfq8t0W19/TLZqq3JPQXtlv8BPIGmfa9Jb4scg==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "engine.io-client": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz", + "integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "engine.io-parser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz", + "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + }, + "eslint": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.54.0.tgz", + "integrity": "sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.3", + "@eslint/js": "8.54.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "dev": true + }, + "eslint-plugin-react-refresh": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.4.tgz", + "integrity": "sha512-eD83+65e8YPVg6603Om2iCIwcQJf/y7++MWm4tACtEswFLYMwxwVWAfwN+e19f5Ad/FOyyNg9Dfi5lXhH3Y3rA==", + "dev": true + }, + "eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true + }, + "espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "requires": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + } + }, + "esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==" + }, + "fast-base64-decode": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz", + "integrity": "sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "fflate": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz", + "integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==" + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "requires": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "requires": { + "is-callable": "^1.1.3" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "requires": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "glsl-noise": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/glsl-noise/-/glsl-noise-0.0.0.tgz", + "integrity": "sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w==" + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "requires": { + "get-intrinsic": "^1.2.2" + } + }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "requires": { + "has-symbols": "^1.0.2" + } + }, + "hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "requires": { + "function-bind": "^1.1.2" + } + }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" + }, + "is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "requires": { + "hasown": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "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", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "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, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "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 + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "requires": { + "which-typed-array": "^1.1.11" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "iso-639-1": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/iso-639-1/-/iso-639-1-3.1.0.tgz", + "integrity": "sha512-rWcHp9dcNbxa5C8jA/cxFlWNFNwy5Vup0KcFvgA8sPQs9ZeJHj/Eq0Y8Yz2eL8XlWYpxw4iwh9FfTeVxyqdRMw==" + }, + "isomorphic-unfetch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz", + "integrity": "sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==", + "requires": { + "node-fetch": "^2.6.1", + "unfetch": "^4.2.0" + } + }, + "its-fine": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/its-fine/-/its-fine-1.1.1.tgz", + "integrity": "sha512-v1Ia1xl20KbuSGlwoaGsW0oxsw8Be+TrXweidxD9oT/1lAh6O3K3/GIM95Tt6WCiv6W+h2M7RB1TwdoAjQyyKw==", + "requires": { + "@types/react-reconciler": "^0.28.0" + }, + "dependencies": { + "@types/react-reconciler": { + "version": "0.28.8", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.8.tgz", + "integrity": "sha512-SN9c4kxXZonFhbX4hJrZy37yw9e7EIxcpHCxQv5JUS18wDE5ovkQKlqQEkufdJCCMfuI9BnjUJvhYeJ9x5Ra7g==", + "requires": { + "@types/react": "*" + } + } + } + }, + "jmespath": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", + "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==" + }, + "js-cookie": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", + "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true + }, + "keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.clamp": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/lodash.clamp/-/lodash.clamp-4.0.3.tgz", + "integrity": "sha512-HvzRFWjtcguTW7yd8NJBshuNaCa8aqNFtnswdT7f/cMd/1YKy5Zzoq4W/Oxvnx9l7aeY258uSdDfM793+eLsVg==" + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.omit": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", + "integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==" + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "maath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/maath/-/maath-0.9.0.tgz", + "integrity": "sha512-aAR8hoUqPxlsU8VOxkS9y37jhUzdUxM017NpCuxFU1Gk+nMaZASZxymZrV8LRSHzRk/watlbfyNKu6XPUhCFrQ==" + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "meshline": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/meshline/-/meshline-3.1.7.tgz", + "integrity": "sha512-uf9fPI9wy0Ie0kZjvKuIkf2n7gi3ih0wdTeb/kmSvmzpPyEL5d9lFohg9+JV9VC4sQUBOZDgxu6fnjn57goSHg==" + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "dev": true, + "requires": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "potpack": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz", + "integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==" + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==" + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "requires": { + "loose-envify": "^1.1.0" + } + }, + "react-composer": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/react-composer/-/react-composer-5.0.3.tgz", + "integrity": "sha512-1uWd07EME6XZvMfapwZmc7NgCZqDemcvicRi3wMJzXsQLvZ3L7fTHVyPy1bZdnWXM4iPjYuNE+uJ41MLKeTtnA==", + "requires": { + "prop-types": "^15.6.0" + } + }, + "react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "requires": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "dependencies": { + "scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "requires": { + "loose-envify": "^1.1.0" + } + } + } + }, + "react-google-charts": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/react-google-charts/-/react-google-charts-4.0.1.tgz", + "integrity": "sha512-V/hcMcNuBgD5w49BYTUDye+bUKaPmsU5vy/9W/Nj2xEeGn+6/AuH9IvBkbDcNBsY00cV9OeexdmgfI5RFHgsXQ==" + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "react-merge-refs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/react-merge-refs/-/react-merge-refs-1.1.0.tgz", + "integrity": "sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ==" + }, + "react-reconciler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.27.0.tgz", + "integrity": "sha512-HmMDKciQjYmBRGuuhIaKA1ba/7a+UsM5FzOZsMO2JYHt9Jh8reCb7j1eDC95NOyUlKM9KRyvdx0flBuDvYSBoA==", + "requires": { + "loose-envify": "^1.1.0", + "scheduler": "^0.21.0" + } + }, + "react-refresh": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", + "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", + "dev": true + }, + "react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + }, + "react-use-measure": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.1.tgz", + "integrity": "sha512-nocZhN26cproIiIduswYpV5y5lQpSQS1y/4KuvUCjSKmw7ZWIS/+g3aFnX3WdBkyuGUtTLif3UTqnLLhbDoQig==", + "requires": { + "debounce": "^1.2.1" + } + }, + "regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + }, + "resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "requires": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "rollup": { + "version": "3.29.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", + "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + } + } + }, + "sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" + }, + "scheduler": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", + "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "requires": { + "loose-envify": "^1.1.0" + } + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "requires": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "socket.io-client": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.2.tgz", + "integrity": "sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.5.2", + "socket.io-parser": "~4.2.4" + } + }, + "socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true + }, + "spawn-command": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", + "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", + "dev": true + }, + "stats-gl": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/stats-gl/-/stats-gl-1.0.7.tgz", + "integrity": "sha512-vZI82CjefSxLC1bjw36z28v0+QE9rJKymGlXtfWu+ipW70ZEAwa4EbO4LxluAfLfpqiaAS04NzpYBRLDeAwYWQ==" + }, + "stats.js": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/stats.js/-/stats.js-0.17.0.tgz", + "integrity": "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "suspend-react": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/suspend-react/-/suspend-react-0.1.3.tgz", + "integrity": "sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==" + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "three": { + "version": "0.156.1", + "resolved": "https://registry.npmjs.org/three/-/three-0.156.1.tgz", + "integrity": "sha512-kP7H0FK9d/k6t/XvQ9FO6i+QrePoDcNhwl0I02+wmUJRNSLCUIDMcfObnzQvxb37/0Uc9TDT0T1HgsRRrO6SYQ==" + }, + "three-mesh-bvh": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/three-mesh-bvh/-/three-mesh-bvh-0.6.8.tgz", + "integrity": "sha512-EGebF9DZx1S8+7OZYNNTT80GXJZVf+UYXD/HyTg/e2kR/ApofIFfUS4ZzIHNnUVIadpnLSzM4n96wX+l7GMbnQ==" + }, + "three-mesh-ui": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/three-mesh-ui/-/three-mesh-ui-6.5.4.tgz", + "integrity": "sha512-QA2KlHrbj7zGjKqpNXcwvini8g5gOXb44ExdupVpxCqmHln/sWNGOmN0yIa/HjnMGYJWP4M+NchTHvwUp+MWIw==" + }, + "three-stdlib": { + "version": "2.28.7", + "resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.28.7.tgz", + "integrity": "sha512-E7NuztilCswBKnEoyqydvA7N4dy0cf/gLA0bKrrg6+Q6j4WtusGa/+t9oK2HVq47S1AHRH2CvFHpdIGNjPKo/A==", + "requires": { + "@types/draco3d": "^1.4.0", + "@types/offscreencanvas": "^2019.6.4", + "@types/webxr": "^0.5.2", + "draco3d": "^1.4.1", + "fflate": "^0.6.9", + "potpack": "^1.0.1" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" + }, + "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, + "requires": { + "is-number": "^7.0.0" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true + }, + "troika-three-text": { + "version": "0.47.2", + "resolved": "https://registry.npmjs.org/troika-three-text/-/troika-three-text-0.47.2.tgz", + "integrity": "sha512-qylT0F+U7xGs+/PEf3ujBdJMYWbn0Qci0kLqI5BJG2kW1wdg4T1XSxneypnF05DxFqJhEzuaOR9S2SjiyknMng==", + "requires": { + "bidi-js": "^1.0.2", + "troika-three-utils": "^0.47.2", + "troika-worker-utils": "^0.47.2", + "webgl-sdf-generator": "1.1.1" + } + }, + "troika-three-utils": { + "version": "0.47.2", + "resolved": "https://registry.npmjs.org/troika-three-utils/-/troika-three-utils-0.47.2.tgz", + "integrity": "sha512-/28plhCxfKtH7MSxEGx8e3b/OXU5A0xlwl+Sbdp0H8FXUHKZDoksduEKmjQayXYtxAyuUiCRunYIv/8Vi7aiyg==" + }, + "troika-worker-utils": { + "version": "0.47.2", + "resolved": "https://registry.npmjs.org/troika-worker-utils/-/troika-worker-utils-0.47.2.tgz", + "integrity": "sha512-mzss4MeyzUkYBppn4x5cdAqrhBHFEuVmMMgLMTyFV23x6GvQMyo+/R5E5Lsbrt7WSt5RfvewjcwD1DChRTA9lA==" + }, + "ts-api-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "dev": true + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "typescript": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", + "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "dev": true + }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "unfetch": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", + "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==" + }, + "update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true + } + } + }, + "url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==" + }, + "util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "utility-types": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", + "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==" + }, + "uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" + }, + "vite": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz", + "integrity": "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==", + "dev": true, + "requires": { + "esbuild": "^0.18.10", + "fsevents": "~2.3.2", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + } + }, + "webgl-constants": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/webgl-constants/-/webgl-constants-1.1.1.tgz", + "integrity": "sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg==" + }, + "webgl-sdf-generator": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/webgl-sdf-generator/-/webgl-sdf-generator-1.1.1.tgz", + "integrity": "sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA==" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", + "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.4", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==" + }, + "xml2js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + } + }, + "xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" + }, + "xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + }, + "zustand": { + "version": "4.4.7", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.4.7.tgz", + "integrity": "sha512-QFJWJMdlETcI69paJwhSMJz7PPWjVP8Sjhclxmxmxv/RYI7ZOvR5BHX+ktH0we9gTWQMxcne8q1OY8xxz604gw==", + "requires": { + "use-sync-external-store": "1.2.0" + } + } + } +} diff --git a/streaming-react-app/package.json b/streaming-react-app/package.json new file mode 100644 index 0000000000000000000000000000000000000000..c6a7b0318f78dfc3376e85f75ec21197494d8aeb --- /dev/null +++ b/streaming-react-app/package.json @@ -0,0 +1,53 @@ +{ + "name": "streaming-react-app", + "private": true, + "version": "0.0.14", + "type": "module", + "scripts": { + "dev": "vite --host --strictPort", + "build": "vite build", + "preview": "vite preview", + "clean:node-modules": "rm -rf node_modules/", + "ts-check": "tsc --noEmit", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "prettier-check": "cd ../ && yarn run prettier-base --check streaming-react-app", + "signal": "concurrently --names \"TS,LINT,PRETTIER\" -c \"bgBlack.bold,bgRed.bold,bgCyan.bold\" \"yarn run ts-check\" \"yarn run lint\" \"yarn run prettier-check\"" + }, + "dependencies": { + "@emotion/react": "11.11.1", + "@emotion/styled": "11.11.0", + "@mui/icons-material": "5.14.3", + "@mui/material": "5.14.5", + "@react-three/drei": "^9.83.9", + "@react-three/fiber": "^8.14.1", + "@react-three/xr": "^5.7.1", + "amazon-cognito-identity-js": "^6.3.6", + "audiobuffer-to-wav": "^1.0.0", + "aws-sdk": "^2.1472.0", + "js-cookie": "^3.0.5", + "lodash": "4.17.21", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-google-charts": "^4.0.1", + "socket.io-client": "^4.7.2", + "three": "^0.156.1", + "three-mesh-ui": "^6.5.4", + "uuid": "^9.0.0", + "zustand": "^4.4.3" + }, + "devDependencies": { + "@types/node": "^20.5.3", + "@types/react": "^18.2.15", + "@types/react-dom": "^18.2.7", + "@types/uuid": "^9.0.2", + "@typescript-eslint/eslint-plugin": "^6.0.0", + "@typescript-eslint/parser": "^6.0.0", + "@vitejs/plugin-react": "^4.0.3", + "concurrently": "8.2.1", + "eslint": "^8.45.0", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.3", + "typescript": "5.1.6", + "vite": "^4.4.5" + } +} diff --git a/streaming-react-app/src/App.tsx b/streaming-react-app/src/App.tsx new file mode 100644 index 0000000000000000000000000000000000000000..ed124a1b3cea3098e0a059f5ac0cf8e00c6bd88c --- /dev/null +++ b/streaming-react-app/src/App.tsx @@ -0,0 +1,57 @@ +import SocketWrapper from './SocketWrapper'; +import {ThemeProvider} from '@mui/material/styles'; +import theme from './theme'; +import StreamingInterface from './StreamingInterface'; +import CssBaseline from '@mui/material/CssBaseline'; +import {createContext, useCallback, useState} from 'react'; +import packageJson from '../package.json'; + +console.log(`Streaming React App version: ${packageJson?.version}`); + +// Roboto font for mui ui library +// import '@fontsource/roboto/300.css'; +// import '@fontsource/roboto/400.css'; +// import '@fontsource/roboto/500.css'; +// import '@fontsource/roboto/700.css'; + +export const AppResetKeyContext = createContext<(newKey: string) => void>( + () => { + throw new Error('AppResetKeyContext not initialized'); + }, +); + +function App() { + return ( + + + + + + + ); +} + +function AppWrapper() { + const [appResetKey, setAppResetKey] = useState('[initial value]'); + const setAppResetKeyHandler = useCallback((newKey: string) => { + setAppResetKey((prev) => { + console.warn( + `Resetting the app with appResetKey: ${newKey}; prevKey: ${prev}`, + ); + if (prev === newKey) { + console.error( + `The appResetKey was the same as the previous key, so the app will not reset.`, + ); + } + return newKey; + }); + }, []); + + return ( + + + + ); +} + +export default AppWrapper; diff --git a/streaming-react-app/src/Blink.tsx b/streaming-react-app/src/Blink.tsx new file mode 100644 index 0000000000000000000000000000000000000000..e569212f6edfa474406cb097109ea94f744448c8 --- /dev/null +++ b/streaming-react-app/src/Blink.tsx @@ -0,0 +1,41 @@ +import Box from '@mui/material/Box'; +import {useEffect, useState} from 'react'; + +type Props = { + intervalMs: number; + children: React.ReactNode; + shouldBlink: boolean; + // display?: 'block' | 'inline' | 'inline-block'; +}; + +export default function Blink({ + // display = 'inline-block', + shouldBlink, + intervalMs, + children, +}: Props): React.ReactElement { + const [cursorBlinkOn, setCursorBlinkOn] = useState(false); + + useEffect(() => { + if (shouldBlink) { + const interval = setInterval(() => { + setCursorBlinkOn((prev) => !prev); + }, intervalMs); + + return () => clearInterval(interval); + } else { + setCursorBlinkOn(false); + } + }, [intervalMs, shouldBlink]); + + return ( + + {children} + + ); +} diff --git a/streaming-react-app/src/DebugSection.tsx b/streaming-react-app/src/DebugSection.tsx new file mode 100644 index 0000000000000000000000000000000000000000..6bee96e157e84cbc04ec4f1a63968cf8e1838d62 --- /dev/null +++ b/streaming-react-app/src/DebugSection.tsx @@ -0,0 +1,62 @@ +import {Chart} from 'react-google-charts'; +import debug from './debug'; +import { + Accordion, + AccordionDetails, + AccordionSummary, + Button, + Typography, +} from '@mui/material'; +import {useState} from 'react'; +import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'; + +export default function DebugChart() { + const [showDebugTimings, setShowDebugTimings] = useState(false); + + const data = debug()?.getChartData(); + const options = { + timeline: { + groupByRowLabel: true, + }, + }; + + return ( +
+ setShowDebugTimings(!showDebugTimings)} + elevation={0} + sx={{border: 1, borderColor: 'rgba(0, 0, 0, 0.3)'}}> + } + className="debug-section"> + Debug Info + + + {data && data.length > 1 ? ( + <> + + + + ) : ( + No input / output detected + )} + + +
+ ); +} diff --git a/streaming-react-app/src/RoomConfig.tsx b/streaming-react-app/src/RoomConfig.tsx new file mode 100644 index 0000000000000000000000000000000000000000..e454ef92667247b149bd5c226a5f27092b12e44c --- /dev/null +++ b/streaming-react-app/src/RoomConfig.tsx @@ -0,0 +1,263 @@ +import Stack from '@mui/material/Stack'; +import TextField from '@mui/material/TextField'; +import {isValidRoomID, isValidPartialRoomID} from './generateNewRoomID'; +import {useCallback, useEffect, useState} from 'react'; +import Button from '@mui/material/Button'; +import {useSocket} from './useSocket'; +import FormGroup from '@mui/material/FormGroup'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import Checkbox from '@mui/material/Checkbox'; +import {RoomState} from './types/RoomState'; +import setURLParam from './setURLParam'; +import {getURLParams} from './URLParams'; +import { + JoinRoomConfig, + Roles, + ServerState, + StreamingStatus, +} from './types/StreamingTypes'; +import Alert from '@mui/material/Alert'; + +function capitalize(str: string): string { + return str.charAt(0).toUpperCase() + str.slice(1); +} + +type Props = { + roomState: RoomState | null; + serverState: ServerState | null; + onJoinRoomOrUpdateRoles?: () => void; + streamingStatus: StreamingStatus; +}; + +export default function RoomConfig({ + roomState, + serverState, + onJoinRoomOrUpdateRoles, + streamingStatus, +}: Props) { + const {socket, clientID} = useSocket(); + + const urlParams = getURLParams(); + const roomIDParam = urlParams.roomID; + const autoJoinRoom = urlParams.autoJoin; + + const [roomID, setRoomID] = useState( + (roomIDParam ?? '').toUpperCase(), + ); + const [roomIDError, setRoomIDError] = useState(false); + const [roles, setRoles] = useState<{speaker: boolean; listener: boolean}>({ + speaker: true, + listener: true, + }); + const [lockServer, setLockServer] = useState(false); + const [lockServerName, setLockServerName] = useState(''); + + const [joinInProgress, setJoinInProgress] = useState(false); + const [didAttemptAutoJoin, setDidAttemptAutoJoin] = useState(false); + + const isValidServerLock = + lockServer === false || + (lockServerName != null && lockServerName.length > 0); + const isValidRoles = Object.values(roles).filter(Boolean).length > 0; + const isValidAllInputs = + isValidRoomID(roomID) && isValidRoles && isValidServerLock; + const roomIDFromServer = roomState?.room_id ?? null; + + const onJoinRoom = useCallback( + (createNewRoom: boolean) => { + if (socket == null) { + console.error('Socket is null, cannot join room'); + return; + } + console.debug(`Attempting to join roomID ${roomID}...`); + + const lockServerValidated: string | null = + lockServer && roles['speaker'] ? lockServerName : null; + + setJoinInProgress(true); + + const configObject: JoinRoomConfig = { + roles: (Object.keys(roles) as Array).filter( + (role) => roles[role] === true, + ), + lockServerName: lockServerValidated, + }; + + socket.emit( + 'join_room', + clientID, + //createNewRoom ? null : roomID, + true, + configObject, + (result) => { + console.log('join_room result:', result); + if (createNewRoom) { + setRoomID(result.roomID); + } + if (onJoinRoomOrUpdateRoles != null) { + onJoinRoomOrUpdateRoles(); + } + setURLParam('roomID', result.roomID); + setJoinInProgress(false); + }, + ); + }, + [ + clientID, + lockServer, + lockServerName, + onJoinRoomOrUpdateRoles, + roles, + roomID, + socket, + ], + ); + + useEffect(() => { + if ( + autoJoinRoom === true && + didAttemptAutoJoin === false && + socket != null + ) { + // We want to consider this an attempt whether or not we actually try to join, because + // we only want auto-join to happen on initial load + setDidAttemptAutoJoin(true); + if ( + isValidAllInputs && + joinInProgress === false && + roomIDFromServer == null + ) { + console.debug('Attempting to auto-join room...'); + + onJoinRoom(false); + } else { + console.debug('Unable to auto-join room', { + isValidAllInputs, + joinInProgress, + roomIDFromServer, + }); + } + } + }, [ + autoJoinRoom, + didAttemptAutoJoin, + isValidAllInputs, + joinInProgress, + onJoinRoom, + roomIDFromServer, + socket, + ]); + + return ( + + + {/* { + const id = e.target.value.toUpperCase(); + if (isValidPartialRoomID(id)) { + setRoomIDError(false); + setRoomID(id); + } else { + setRoomIDError(true); + } + }} + sx={{width: '8em'}} + /> */} + + {/*
+ +
*/} + + {roomState?.room_id == null && ( +
+ +
+ )} +
+ + + {Object.keys(roles).map((role) => { + return ( + ) => { + setRoles((prevRoles) => ({ + ...prevRoles, + [role]: event.target.checked, + })); + }} + /> + } + label={capitalize(role)} + /> + ); + })} + + {urlParams.enableServerLock && roles['speaker'] === true && ( + <> + ) => { + setLockServer(event.target.checked); + }} + /> + } + label="Lock Server (prevent other users from streaming)" + /> + + )} + + + {urlParams.enableServerLock && + roles['speaker'] === true && + lockServer && ( + ) => { + setLockServerName(event.target.value); + }} + helperText="Locking the server will prevent anyone else from using it until you close the page, in order to maximize server performance. Please only use this for live demos." + /> + )} + + {serverState?.serverLock != null && + serverState.serverLock.clientID === clientID && ( + {`The server is now locked for your use (${serverState?.serverLock?.name}). Close this window to release the lock so that others may use the server.`} + )} +
+ ); +} diff --git a/streaming-react-app/src/SocketWrapper.tsx b/streaming-react-app/src/SocketWrapper.tsx new file mode 100644 index 0000000000000000000000000000000000000000..cc182434cf20c6269a424dbafc0613fd53771c4f --- /dev/null +++ b/streaming-react-app/src/SocketWrapper.tsx @@ -0,0 +1,218 @@ +import {useContext, useEffect, useMemo, useRef, useState} from 'react'; +import socketIOClient, {Socket} from 'socket.io-client'; +import useStable from './useStable'; +import {v4 as uuidv4} from 'uuid'; +import {SocketContext} from './useSocket'; +import {AppResetKeyContext} from './App'; +import Backdrop from '@mui/material/Backdrop'; +import CircularProgress from '@mui/material/CircularProgress'; +import Typography from '@mui/material/Typography'; +import {getURLParams} from './URLParams'; + +// The time to wait before showing a "disconnected" screen upon initial app load +const INITIAL_DISCONNECT_SCREEN_DELAY = 2000; +const SERVER_URL_DEFAULT = `${window.location.protocol === "https:" ? "wss" : "ws" + }://${window.location.host}`; + +export default function SocketWrapper({children}) { + const [socket, setSocket] = useState(null); + const [connected, setConnected] = useState(null); + // Default to true: + const [willAttemptReconnect] = useState(true); + const serverIDRef = useRef(null); + + const setAppResetKey = useContext(AppResetKeyContext); + + /** + * Previously we had stored the clientID in local storage, but in that case + * if a user refreshes their page they'll still have the same clientID, and + * will be put back into the same room, which may be confusing if they're trying + * to join a new room or reset the app interface. So now clientIDs persist only as + * long as the react app full lifecycle + */ + const clientID = useStable(() => { + const newID = uuidv4(); + // Set the clientID in session storage so if the page reloads the person + // still retains their member/room config + return newID; + }); + + const socketObject = useMemo( + () => ({socket, clientID, connected: connected ?? false}), + [socket, clientID, connected], + ); + + useEffect(() => { + const queryParams = { + clientID: clientID, + }; + + const serverURLFromParams = getURLParams().serverURL; + const serverURL = serverURLFromParams ?? SERVER_URL_DEFAULT; + + console.log( + `Opening socket connection to ${ + serverURL?.length === 0 ? 'window.location.host' : serverURL + } with query params:`, + queryParams, + ); + + const newSocket: Socket = socketIOClient(serverURL, { + query: queryParams, + // Normally socket.io will fallback to http polling, but we basically never + // want that because that'd mean awful performance. It'd be better for the app + // to simply break in that case and not connect. + transports: ['websocket'], + path: '/ws/socket.io' + }); + + const onServerID = (serverID: string) => { + console.debug('Received server ID:', serverID); + if (serverIDRef.current != null) { + if (serverIDRef.current !== serverID) { + console.error( + 'Server ID changed. Resetting the app using the app key', + ); + setAppResetKey(serverID); + } + } + serverIDRef.current = serverID; + }; + + newSocket.on('server_id', onServerID); + + setSocket(newSocket); + + return () => { + newSocket.off('server_id', onServerID); + console.log( + 'Closing socket connection in the useEffect cleanup function...', + ); + newSocket.disconnect(); + setSocket(null); + }; + }, [clientID, setAppResetKey]); + + useEffect(() => { + if (socket != null) { + const onAny = (eventName: string, ...args) => { + console.debug(`[event: ${eventName}] args:`, ...args); + }; + + socket.onAny(onAny); + + return () => { + socket.offAny(onAny); + }; + } + return () => {}; + }, [socket]); + + useEffect(() => { + if (socket != null) { + const onConnect = (...args) => { + console.debug('Connected to server with args:', ...args); + setConnected(true); + }; + + const onConnectError = (err) => { + console.error(`Connection error due to ${err.message}`); + }; + + const onDisconnect = (reason) => { + setConnected(false); + console.log(`Disconnected due to ${reason}`); + }; + + socket.on('connect', onConnect); + socket.on('connect_error', onConnectError); + socket.on('disconnect', onDisconnect); + + return () => { + socket.off('connect', onConnect); + socket.off('connect_error', onConnectError); + socket.off('disconnect', onDisconnect); + }; + } + }, [socket]); + + useEffect(() => { + if (socket != null) { + const onReconnectError = (err) => { + console.log(`Reconnect error due to ${err.message}`); + }; + + socket.io.on('reconnect_error', onReconnectError); + + const onError = (err) => { + console.log(`General socket error with message ${err.message}`); + }; + socket.io.on('error', onError); + + const onReconnect = (attempt) => { + console.log(`Reconnected after ${attempt} attempt(s)`); + }; + socket.io.on('reconnect', onReconnect); + + const disconnectOnBeforeUnload = () => { + console.log('Disconnecting due to beforeunload event...'); + socket.disconnect(); + setSocket(null); + }; + window.addEventListener('beforeunload', disconnectOnBeforeUnload); + + return () => { + socket.io.off('reconnect_error', onReconnectError); + socket.io.off('error', onError); + socket.io.off('reconnect', onReconnect); + window.removeEventListener('beforeunload', disconnectOnBeforeUnload); + }; + } + }, [clientID, setAppResetKey, socket]); + + /** + * Wait to show the disconnected screen on initial app load + */ + useEffect(() => { + window.setTimeout(() => { + setConnected((prev) => { + if (prev === null) { + return false; + } + return prev; + }); + }, INITIAL_DISCONNECT_SCREEN_DELAY); + }, []); + + return ( + + {children} + + theme.zIndex.drawer + 1, + }}> +
+ + + {'Disconnected. Attempting to reconnect...'} + +
+
+
+ ); +} diff --git a/streaming-react-app/src/StreamingInterface.css b/streaming-react-app/src/StreamingInterface.css new file mode 100644 index 0000000000000000000000000000000000000000..3ef953f83853d9cadfd700ad55b85b3bcd3b5403 --- /dev/null +++ b/streaming-react-app/src/StreamingInterface.css @@ -0,0 +1,56 @@ +.app-wrapper-sra { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.main-container-sra { + background-color: white; + display: flex; + flex-direction: column; + justify-content: flex-start; + text-align: left; + margin: 16px; + margin-bottom: 36px; + border-radius: 8px; + box-shadow: 0px 24px 30px rgba(0, 0, 0, 0.3); + border: 1px solid rgba(0, 0, 0, 0.05); + overflow: hidden; +} + +.top-section-sra { + padding-top: 24px; + margin-bottom: 24px; + display: flex; + flex-direction: column; + justify-content: flex-start; +} + +.horizontal-padding-sra { + padding-left: 20px; + padding-right: 20px; +} + +.header-container-sra { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + margin-bottom: 24px; +} + +.header-icon-sra { + display: block; + margin-right: 12px; +} + +.translation-text-container-sra { + background-color: #f8f8f8; + padding-top: 12px; + padding-bottom: 4px; +} + +.text-chunk-sra { + margin-bottom: 12px; +} diff --git a/streaming-react-app/src/StreamingInterface.tsx b/streaming-react-app/src/StreamingInterface.tsx new file mode 100644 index 0000000000000000000000000000000000000000..7e26cc9a136d58302109b16d4222e680a0bef9b6 --- /dev/null +++ b/streaming-react-app/src/StreamingInterface.tsx @@ -0,0 +1,1221 @@ +import {useCallback, useEffect, useLayoutEffect, useRef, useState} from 'react'; +import Button from '@mui/material/Button'; +import Typography from '@mui/material/Typography'; +import InputLabel from '@mui/material/InputLabel'; +import FormControl from '@mui/material/FormControl'; +import Select, {SelectChangeEvent} from '@mui/material/Select'; +import MenuItem from '@mui/material/MenuItem'; +import Stack from '@mui/material/Stack'; +import seamlessLogoUrl from './assets/illy.svg'; +import { + AgentCapabilities, + BaseResponse, + BrowserAudioStreamConfig, + DynamicConfig, + PartialDynamicConfig, + SUPPORTED_INPUT_SOURCES, + SUPPORTED_OUTPUT_MODES, + ServerExceptionData, + ServerSpeechData, + ServerState, + ServerTextData, + StartStreamEventConfig, + StreamingStatus, + SupportedInputSource, + SupportedOutputMode, + TranslationSentences, +} from './types/StreamingTypes'; +import FormLabel from '@mui/material/FormLabel'; +import RadioGroup from '@mui/material/RadioGroup'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import Radio from '@mui/material/Radio'; +import './StreamingInterface.css'; +import RoomConfig from './RoomConfig'; +import Divider from '@mui/material/Divider'; +import {useSocket} from './useSocket'; +import {RoomState} from './types/RoomState'; +import useStable from './useStable'; +import float32To16BitPCM from './float32To16BitPCM'; +import createBufferedSpeechPlayer from './createBufferedSpeechPlayer'; +import Checkbox from '@mui/material/Checkbox'; +import Alert from '@mui/material/Alert'; +import isScrolledToDocumentBottom from './isScrolledToDocumentBottom'; +import Box from '@mui/material/Box'; +import Slider from '@mui/material/Slider'; +import VolumeDown from '@mui/icons-material/VolumeDown'; +import VolumeUp from '@mui/icons-material/VolumeUp'; +import Mic from '@mui/icons-material/Mic'; +import MicOff from '@mui/icons-material/MicOff'; +import XRDialog from './react-xr/XRDialog'; +import getTranslationSentencesFromReceivedData from './getTranslationSentencesFromReceivedData'; +import { + sliceTranslationSentencesUpToIndex, + getTotalSentencesLength, +} from './sliceTranslationSentencesUtils'; +import Blink from './Blink'; +import {CURSOR_BLINK_INTERVAL_MS} from './cursorBlinkInterval'; +import {getURLParams} from './URLParams'; +import debug from './debug'; +import DebugSection from './DebugSection'; +import Switch from '@mui/material/Switch'; +import Grid from '@mui/material/Grid'; +import {getLanguageFromThreeLetterCode} from './languageLookup'; +import HeadphonesIcon from '@mui/icons-material/Headphones'; + +const AUDIO_STREAM_DEFAULTS = { + userMedia: { + echoCancellation: false, + noiseSuppression: true, + }, + displayMedia: { + echoCancellation: false, + noiseSuppression: false, + }, +} as const; + +async function requestUserMediaAudioStream( + config: BrowserAudioStreamConfig = AUDIO_STREAM_DEFAULTS['userMedia'], +) { + const stream = await navigator.mediaDevices.getUserMedia({ + audio: {...config, channelCount: 1}, + }); + console.debug( + '[requestUserMediaAudioStream] stream created with settings:', + stream.getAudioTracks()?.[0]?.getSettings(), + ); + return stream; +} + +async function requestDisplayMediaAudioStream( + config: BrowserAudioStreamConfig = AUDIO_STREAM_DEFAULTS['displayMedia'], +) { + const stream = await navigator.mediaDevices.getDisplayMedia({ + audio: {...config, channelCount: 1}, + }); + console.debug( + '[requestDisplayMediaAudioStream] stream created with settings:', + stream.getAudioTracks()?.[0]?.getSettings(), + ); + return stream; +} + +const buttonLabelMap: {[key in StreamingStatus]: string} = { + stopped: 'Start Streaming', + running: 'Stop Streaming', + starting: 'Starting...', +}; + +const BUFFER_LIMIT = 1; + +const SCROLLED_TO_BOTTOM_THRESHOLD_PX = 36; + +const GAIN_MULTIPLIER_OVER_1 = 3; + +const getGainScaledValue = (value) => + value > 1 ? (value - 1) * GAIN_MULTIPLIER_OVER_1 + 1 : value; + +const TOTAL_ACTIVE_TRANSCODER_WARNING_THRESHOLD = 2; + +const MAX_SERVER_EXCEPTIONS_TRACKED = 500; + +export const TYPING_ANIMATION_DELAY_MS = 6; + +export default function StreamingInterface() { + const urlParams = getURLParams(); + const debugParam = urlParams.debug; + const [animateTextDisplay, setAnimateTextDisplay] = useState( + urlParams.animateTextDisplay, + ); + + const socketObject = useSocket(); + const {socket, clientID} = socketObject; + + const [serverState, setServerState] = useState(null); + const [agent, setAgent] = useState(null); + const model = agent?.name ?? null; + const agentsCapabilities: Array = + serverState?.agentsCapabilities ?? []; + const currentAgent: AgentCapabilities | null = + agentsCapabilities.find((agent) => agent.name === model) ?? null; + + const [serverExceptions, setServerExceptions] = useState< + Array + >([]); + const [roomState, setRoomState] = useState(null); + const roomID = roomState?.room_id ?? null; + const isSpeaker = + (clientID != null && roomState?.speakers.includes(clientID)) ?? false; + const isListener = + (clientID != null && roomState?.listeners.includes(clientID)) ?? false; + + const [streamingStatus, setStreamingStatus] = + useState('stopped'); + + const isStreamConfiguredRef = useRef(false); + const [hasMaxSpeakers, setHasMaxSpeakers] = useState(false); + + const [outputMode, setOutputMode] = useState('s2s&t'); + const [inputSource, setInputSource] = + useState('userMedia'); + const [enableNoiseSuppression, setEnableNoiseSuppression] = useState< + boolean | null + >(null); + const [enableEchoCancellation, setEnableEchoCancellation] = useState< + boolean | null + >(null); + + // Dynamic Params: + const [targetLang, setTargetLang] = useState(null); + const [enableExpressive, setEnableExpressive] = useState( + null, + ); + + const [serverDebugFlag, setServerDebugFlag] = useState( + debugParam ?? false, + ); + + const [receivedData, setReceivedData] = useState>([]); + const [ + translationSentencesAnimatedIndex, + setTranslationSentencesAnimatedIndex, + ] = useState(0); + + const lastTranslationResultRef = useRef(null); + + const [inputStream, setInputStream] = useState(null); + const [inputStreamSource, setInputStreamSource] = + useState(null); + const audioContext = useStable(() => new AudioContext()); + const [scriptNodeProcessor, setScriptNodeProcessor] = + useState(null); + + const [muted, setMuted] = useState(false); + // The onaudioprocess script needs an up-to-date reference to the muted state, so + // we use a ref here and keep it in sync via useEffect + const mutedRef = useRef(muted); + useEffect(() => { + mutedRef.current = muted; + }, [muted]); + + const [gain, setGain] = useState(1); + + const isScrolledToBottomRef = useRef(isScrolledToDocumentBottom()); + + // Some config options must be set when starting streaming and cannot be chaned dynamically. + // This controls whether they are disabled or not + const streamFixedConfigOptionsDisabled = + streamingStatus !== 'stopped' || roomID == null; + + const bufferedSpeechPlayer = useStable(() => { + const player = createBufferedSpeechPlayer({ + onStarted: () => { + console.debug('📢 PLAYBACK STARTED 📢'); + }, + onEnded: () => { + console.debug('🛑 PLAYBACK ENDED 🛑'); + }, + }); + + // Start the player now so it eagerly plays audio when it arrives + player.start(); + return player; + }); + + const translationSentencesBase: TranslationSentences = + getTranslationSentencesFromReceivedData(receivedData); + + const translationSentencesBaseTotalLength = getTotalSentencesLength( + translationSentencesBase, + ); + + const translationSentences: TranslationSentences = animateTextDisplay + ? sliceTranslationSentencesUpToIndex( + translationSentencesBase, + translationSentencesAnimatedIndex, + ) + : translationSentencesBase; + + // We want the blinking cursor to show before any text has arrived, so let's add an empty string so that the cursor shows up + const translationSentencesWithEmptyStartingString = + streamingStatus === 'running' && translationSentences.length === 0 + ? [''] + : translationSentences; + + /****************************************** + * Event Handlers + ******************************************/ + + const setAgentAndUpdateParams = useCallback( + (newAgent: AgentCapabilities | null) => { + setAgent((prevAgent) => { + if (prevAgent?.name !== newAgent?.name) { + setTargetLang(newAgent?.targetLangs[0] ?? null); + setEnableExpressive(null); + } + return newAgent; + }); + }, + [], + ); + + const onSetDynamicConfig = useCallback( + async (partialConfig: PartialDynamicConfig) => { + return new Promise((resolve, reject) => { + if (socket == null) { + reject(new Error('[onSetDynamicConfig] socket is null ')); + return; + } + + socket.emit( + 'set_dynamic_config', + partialConfig, + (result: BaseResponse) => { + console.log('[emit result: set_dynamic_config]', result); + if (result.status === 'ok') { + resolve(); + } else { + reject(); + } + }, + ); + }); + }, + [socket], + ); + + const configureStreamAsync = ({sampleRate}: {sampleRate: number}) => { + return new Promise((resolve, reject) => { + if (socket == null) { + reject(new Error('[configureStreamAsync] socket is null ')); + return; + } + const modelName = agent?.name ?? null; + if (modelName == null) { + reject(new Error('[configureStreamAsync] modelName is null ')); + return; + } + + const config: StartStreamEventConfig = { + event: 'config', + rate: sampleRate, + model_name: modelName, + debug: serverDebugFlag, + // synchronous processing isn't implemented on the v2 pubsub server, so hardcode this to true + async_processing: true, + buffer_limit: BUFFER_LIMIT, + model_type: outputMode, + }; + + console.log('[configureStreamAsync] sending config', config); + + socket.emit('configure_stream', config, (statusObject) => { + setHasMaxSpeakers(statusObject.message === 'max_speakers') + if (statusObject.status === 'ok') { + isStreamConfiguredRef.current = true; + console.debug( + '[configureStreamAsync] stream configured!', + statusObject, + ); + resolve(); + } else { + isStreamConfiguredRef.current = false; + reject( + new Error( + `[configureStreamAsync] configure_stream returned status: ${statusObject.status}`, + ), + ); + return; + } + }); + }); + }; + + const startStreaming = async () => { + if (streamingStatus !== 'stopped') { + console.warn( + `Attempting to start stream when status is ${streamingStatus}`, + ); + return; + } + + setStreamingStatus('starting'); + + if (audioContext.state === 'suspended') { + console.warn('audioContext was suspended! resuming...'); + await audioContext.resume(); + } + + let stream: MediaStream | null = null; + + try { + if (inputSource === 'userMedia') { + stream = await requestUserMediaAudioStream({ + noiseSuppression: + enableNoiseSuppression ?? + AUDIO_STREAM_DEFAULTS['userMedia'].noiseSuppression, + echoCancellation: + enableEchoCancellation ?? + AUDIO_STREAM_DEFAULTS['userMedia'].echoCancellation, + }); + } else if (inputSource === 'displayMedia') { + stream = await requestDisplayMediaAudioStream({ + noiseSuppression: + enableNoiseSuppression ?? + AUDIO_STREAM_DEFAULTS['displayMedia'].noiseSuppression, + echoCancellation: + enableEchoCancellation ?? + AUDIO_STREAM_DEFAULTS['displayMedia'].echoCancellation, + }); + } else { + throw new Error(`Unsupported input source requested: ${inputSource}`); + } + setInputStream(stream); + } catch (e) { + console.error('[startStreaming] media stream request failed:', e); + setStreamingStatus('stopped'); + return; + } + + const mediaStreamSource = audioContext.createMediaStreamSource(stream); + setInputStreamSource(mediaStreamSource); + /** + * NOTE: This currently uses a deprecated way of processing the audio (createScriptProcessor), but + * which is easy and convenient for our purposes. + * + * Documentation for the deprecated way of doing it is here: https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/createScriptProcessor + * + * In an ideal world this would be migrated to something like this SO answer: https://stackoverflow.com/a/65448287 + */ + const scriptProcessor = audioContext.createScriptProcessor(16384, 1, 1); + setScriptNodeProcessor(scriptProcessor); + + scriptProcessor.onaudioprocess = (event) => { + if (isStreamConfiguredRef.current === false) { + console.debug('[onaudioprocess] stream is not configured yet!'); + return; + } + if (socket == null) { + console.warn('[onaudioprocess] socket is null in onaudioprocess'); + return; + } + + if (mutedRef.current) { + // We still want to send audio to the server when we're muted to ensure we + // get any remaining audio back from the server, so let's pass an array length 1 with a value of 0 + const mostlyEmptyInt16Array = new Int16Array(1); + socket.emit('incoming_audio', mostlyEmptyInt16Array); + } else { + const float32Audio = event.inputBuffer.getChannelData(0); + const pcm16Audio = float32To16BitPCM(float32Audio); + socket.emit('incoming_audio', pcm16Audio); + } + + debug()?.sentAudio(event); + }; + + mediaStreamSource.connect(scriptProcessor); + scriptProcessor.connect(audioContext.destination); + + bufferedSpeechPlayer.start(); + + try { + if (targetLang == null) { + throw new Error('[startStreaming] targetLang cannot be nullish'); + } + + // When we are starting the stream we want to pass all the dynamic config values + // available before actually configuring and starting the stream + const fullDynamicConfig: DynamicConfig = { + targetLanguage: targetLang, + expressive: enableExpressive, + }; + + await onSetDynamicConfig(fullDynamicConfig); + + // NOTE: this needs to be the *audioContext* sample rate, not the sample rate of the input stream. Not entirely sure why. + await configureStreamAsync({ + sampleRate: audioContext.sampleRate, + }); + } catch (e) { + console.error('configureStreamAsync failed', e); + setStreamingStatus('stopped'); + return; + } + + setStreamingStatus('running'); + }; + + const stopStreaming = useCallback(async () => { + if (streamingStatus === 'stopped') { + console.warn( + `Attempting to stop stream when status is ${streamingStatus}`, + ); + return; + } + + // Stop the speech playback right away + bufferedSpeechPlayer.stop(); + + if (inputStreamSource == null || scriptNodeProcessor == null) { + console.error( + 'inputStreamSource || scriptNodeProcessor is null in stopStreaming', + ); + } else { + inputStreamSource.disconnect(scriptNodeProcessor); + scriptNodeProcessor.disconnect(audioContext.destination); + + // Release the mic input so we stop showing the red recording icon in the browser + inputStream?.getTracks().forEach((track) => track.stop()); + } + + if (socket == null) { + console.warn('Unable to emit stop_stream because socket is null'); + } else { + socket.emit('stop_stream', (result) => { + console.debug('[emit result: stop_stream]', result); + }); + } + + setStreamingStatus('stopped'); + }, [ + audioContext.destination, + bufferedSpeechPlayer, + inputStream, + inputStreamSource, + scriptNodeProcessor, + socket, + streamingStatus, + ]); + + const onClearTranscriptForAll = useCallback(() => { + if (socket != null) { + socket.emit('clear_transcript_for_all'); + } + }, [socket]); + + /****************************************** + * Effects + ******************************************/ + + useEffect(() => { + if (socket == null) { + return; + } + + const onRoomStateUpdate = (roomState: RoomState) => { + setRoomState(roomState); + }; + + socket.on('room_state_update', onRoomStateUpdate); + + return () => { + socket.off('room_state_update', onRoomStateUpdate); + }; + }, [socket]); + + useEffect(() => { + if (socket != null) { + const onTranslationText = (data: ServerTextData) => { + setReceivedData((prev) => [...prev, data]); + debug()?.receivedText(data.payload); + }; + + const onTranslationSpeech = (data: ServerSpeechData) => { + bufferedSpeechPlayer.addAudioToBuffer(data.payload, data.sample_rate); + }; + + socket.on('translation_text', onTranslationText); + socket.on('translation_speech', onTranslationSpeech); + + return () => { + socket.off('translation_text', onTranslationText); + socket.off('translation_speech', onTranslationSpeech); + }; + } + }, [bufferedSpeechPlayer, socket]); + + useEffect(() => { + if (socket != null) { + const onServerStateUpdate = (newServerState: ServerState) => { + setServerState(newServerState); + + // If a client creates a server lock, we want to stop streaming if we're not them + if ( + newServerState.serverLock?.isActive === true && + newServerState.serverLock?.clientID !== clientID && + streamingStatus === 'running' + ) { + stopStreaming(); + } + + const firstAgentNullable = newServerState.agentsCapabilities[0]; + if (agent == null && firstAgentNullable != null) { + setAgentAndUpdateParams(firstAgentNullable); + } + }; + + socket.on('server_state_update', onServerStateUpdate); + + return () => { + socket.off('server_state_update', onServerStateUpdate); + }; + } + }, [ + agent, + clientID, + setAgentAndUpdateParams, + socket, + stopStreaming, + streamingStatus, + ]); + + useEffect(() => { + if (socket != null) { + const onServerException = ( + exceptionDataWithoutClientTime: ServerExceptionData, + ) => { + const exceptionData = { + ...exceptionDataWithoutClientTime, + timeStringClient: new Date( + exceptionDataWithoutClientTime['timeEpochMs'], + ).toLocaleString(), + }; + + setServerExceptions((prev) => + [exceptionData, ...prev].slice(0, MAX_SERVER_EXCEPTIONS_TRACKED), + ); + console.error( + `[server_exception] The server encountered an exception: ${exceptionData['message']}`, + exceptionData, + ); + }; + + socket.on('server_exception', onServerException); + + return () => { + socket.off('server_exception', onServerException); + }; + } + }, [socket]); + + useEffect(() => { + if (socket != null) { + const onClearTranscript = () => { + setReceivedData([]); + setTranslationSentencesAnimatedIndex(0); + }; + + socket.on('clear_transcript', onClearTranscript); + + return () => { + socket.off('clear_transcript', onClearTranscript); + }; + } + }, [socket]); + + useEffect(() => { + const onScroll = () => { + if (isScrolledToDocumentBottom(SCROLLED_TO_BOTTOM_THRESHOLD_PX)) { + isScrolledToBottomRef.current = true; + return; + } + isScrolledToBottomRef.current = false; + return; + }; + + document.addEventListener('scroll', onScroll); + + return () => { + document.removeEventListener('scroll', onScroll); + }; + }, []); + + useLayoutEffect(() => { + if ( + lastTranslationResultRef.current != null && + isScrolledToBottomRef.current + ) { + // Scroll the div to the most recent entry + lastTranslationResultRef.current.scrollIntoView(); + } + // Run the effect every time data is received, so that + // we scroll to the bottom even if we're just adding text to + // a pre-existing chunk + }, [receivedData]); + + useEffect(() => { + if (!animateTextDisplay) { + return; + } + + if ( + translationSentencesAnimatedIndex < translationSentencesBaseTotalLength + ) { + const timeout = setTimeout(() => { + setTranslationSentencesAnimatedIndex((prev) => prev + 1); + debug()?.startRenderText(); + }, TYPING_ANIMATION_DELAY_MS); + + return () => clearTimeout(timeout); + } else { + debug()?.endRenderText(); + } + }, [ + animateTextDisplay, + translationSentencesAnimatedIndex, + translationSentencesBaseTotalLength, + ]); + + /****************************************** + * Sub-components + ******************************************/ + + const volumeSliderNode = ( + + + `${(value * 100).toFixed(0)}%`} + valueLabelDisplay="auto" + value={gain} + onChange={(_event: Event, newValue: number | number[]) => { + if (typeof newValue === 'number') { + const scaledGain = getGainScaledValue(newValue); + // We want the actual gain node to use the scaled value + bufferedSpeechPlayer.setGain(scaledGain); + // But we want react state to keep track of the non-scaled value + setGain(newValue); + } else { + console.error( + `[volume slider] Unexpected non-number value: ${newValue}`, + ); + } + }} + /> + + + ); + + const xrDialogComponent = ( + { + setAnimateTextDisplay(urlParams.animateTextDisplay); + }} + onARVisible={() => setAnimateTextDisplay(false)} + /> + ); + + return ( +
+ +
+
+
+ Seamless Translation Logo + +
+ + Illy's translator + + + + Natale 2023 + + +
+
+
+
+ + Hey Illy, it's lovely to see you! +
+ You can use this platform to translate from/to Italian and many some other languages. +
+ Use headphones if you are both speaker and listener to prevent feedback. +
+
+ SeamlessStreaming is + a research model and streaming quality works best if you pause + every couple of sentences. The real-time performance will degrade + if you try streaming multiple speakers at the same time. +
+
+ Let's try! +
+
+
+ + + { { + // If the user has switched from speaker to listener we need to tell the + // player to play eagerly, since currently the listener doesn't have any stop/start controls + bufferedSpeechPlayer.start(); + }} + /> } + + {isListener && !isSpeaker && ( + + {volumeSliderNode} + + )} + + + {isSpeaker && ( + <> + + + + {/* + Model + */} + + {/* + Model + */} + {/* */} + + + + + + + Illy, can you please select the target language? + + + + + + Target Language + + + + + + + + + + setOutputMode( + e.target.value as SupportedOutputMode, + ) + } + name="output-modes-radio-buttons-group"> + { + // TODO: Use supported modalities from agentCapabilities + SUPPORTED_OUTPUT_MODES.map(({value, label}) => ( + } + label={label} + /> + )) + } + + + + + + + {/* {currentAgent?.dynamicParams?.includes( + 'expressive', + ) && ( + , + ) => { + const newValue = event.target.checked; + setEnableExpressive(newValue); + onSetDynamicConfig({ + expressive: newValue, + }); + }} + /> + } + label="Expressive" + /> + )} */} + + {isListener && ( + + {volumeSliderNode} + + )} + + + + + + + + + {/* + Input Source + */} + {/* ) => + setInputSource( + e.target.value as SupportedInputSource, + ) + } + name="input-source-radio-buttons-group"> + {SUPPORTED_INPUT_SOURCES.map(({label, value}) => ( + } + label={label} + /> + ))} */} + {/* */} + + + + + + Options + , + ) => + setEnableNoiseSuppression(event.target.checked) + } + /> + } + label="Noise Suppression" + /> + , + ) => + setEnableEchoCancellation(event.target.checked) + } + /> + } + label="Echo Cancellation (not recommended)" + /> + , + ) => setServerDebugFlag(event.target.checked)} + /> + } + label="Enable Server Debugging" + /> + + + + + {isSpeaker && + isListener && + inputSource === 'userMedia' && + !enableEchoCancellation && + gain !== 0 && ( +
+ }> + Headphones required to prevent feedback. + +
+ )} + + {isSpeaker && enableEchoCancellation && ( +
+ + We don't recommend using echo cancellation as it may + distort the input audio. If possible, use headphones and + disable echo cancellation instead. + +
+ )} + + + {streamingStatus === 'stopped' ? ( + + ) : ( + + )} + + + + + + {roomID == null ? null : ( + + {xrDialogComponent} + + )} + + + {serverExceptions.length > 0 && ( +
+ + {`The server encountered an exception. See the browser console for details. You may need to refresh the page to continue using the app.`} + +
+ )} + {serverState != null && hasMaxSpeakers && ( +
+ + {`Maximum number of speakers reached. Please try again at a later time.`} + +
+ )} + {serverState != null && + serverState.totalActiveTranscoders >= + TOTAL_ACTIVE_TRANSCODER_WARNING_THRESHOLD && ( +
+ + {`The server currently has ${serverState?.totalActiveTranscoders} active streaming sessions. Performance may be degraded.`} + +
+ )} + + {serverState?.serverLock != null && + serverState.serverLock.clientID !== clientID && ( +
+ + {`The server is currently locked. Priority will be given to that client when they are streaming, and your streaming session may be halted abruptly.`} + +
+ )} + + )} +
+ + {isListener && !isSpeaker && ( + + {xrDialogComponent} + + )} +
+ + {debugParam && roomID != null && } + +
+ + + Transcript + + {isSpeaker && ( + + )} + + +
+ {translationSentencesWithEmptyStartingString.map( + (sentence, index, arr) => { + const isLast = index === arr.length - 1; + const maybeRef = isLast + ? {ref: lastTranslationResultRef} + : {}; + return ( +
+ + {sentence} + {animateTextDisplay && isLast && ( + 0 + }> + + {'|'} + + + )} + +
+ ); + }, + )} +
+
+
+
+
+
+ ); +} diff --git a/streaming-react-app/src/URLParams.ts b/streaming-react-app/src/URLParams.ts new file mode 100644 index 0000000000000000000000000000000000000000..8c66072d365209a4c1dc06479335fab0e8a6e964 --- /dev/null +++ b/streaming-react-app/src/URLParams.ts @@ -0,0 +1,50 @@ +import { getBooleanParamFlag, getStringParamFlag } from './getParamFlag'; +import { URLParamsObject } from './types/URLParamsTypes'; + +/** + * These are the URL parameters you can provide to the app to change its behavior. + * + * Boolean flags can be set by just providing the flag name (`?autoJoin`), or by + * explicitly setting it to 1 (true) or 0 (false): `?autoJoin=1` or `?autoJoin=0` + * + * String flags require an explicit value: `?roomID=ABCD` + * + * Examples: + * + * - `http://localhost:5173/?roomID=BBCD&autoJoin&debug` + * - `http://localhost:5173/?serverURL=localhost:8000` + + * @returns + */ + +export function getURLParams(): URLParamsObject { + return { + // animate the translation text when it arrives, typing it out one letter at a time + animateTextDisplay: getBooleanParamFlag('animateTextDisplay', true), // default to true; + + // automatically join the room when the app loads. requires roomID to be set via url param as well + autoJoin: getBooleanParamFlag('autoJoin', false), + + // automatically check the server debug flag as true + debug: getBooleanParamFlag('debug', false), + + // Enable UI on the client that allows locking out other users of the server when it's being used for high profile demos + // NOTE: There is an escape hatch for disabling a server lock by setting the name field to remove_server_lock + enableServerLock: getBooleanParamFlag('enableServerLock', false), + + // Pre-populate the Room Code field with the provided roomID. Can be used in conjunction with autoJoin to jump straight into the room + roomID: getStringParamFlag('roomID'), + + // Use an alternate server URL as the streaming server (useful for pointing to dev servers: http://localhost:5173/?serverURL=localhost:8000) + serverURL: getStringParamFlag('serverURL'), + + // Skip the popup dialog that displays within VR, which is mostly redundant with the web based dialog + skipARIntro: getBooleanParamFlag('skipARIntro', true), // default to true + + // Shows the translation text in AR in front of an opaque panel covering all the text area + // single_block = original single text block with background + // lines = each line is a separate block and animates + // lines_with_background = adds a panel behind lines + ARTranscriptionType: getStringParamFlag('ARTranscriptionType') || 'lines', + }; +} diff --git a/streaming-react-app/src/assets/Roboto-msdf.json b/streaming-react-app/src/assets/Roboto-msdf.json new file mode 100644 index 0000000000000000000000000000000000000000..61119f1e046f8a1daa43deaa6c676a25757c0f58 --- /dev/null +++ b/streaming-react-app/src/assets/Roboto-msdf.json @@ -0,0 +1,7160 @@ +{ + "pages": ["Roboto-Regular.png"], + "chars": [ + { + "id": 40, + "index": 12, + "char": "(", + "width": 15, + "height": 47, + "xoffset": 1, + "yoffset": 0, + "xadvance": 14, + "chnl": 15, + "x": 0, + "y": 0, + "page": 0 + }, + { + "id": 41, + "index": 13, + "char": ")", + "width": 15, + "height": 47, + "xoffset": -1, + "yoffset": 0, + "xadvance": 15, + "chnl": 15, + "x": 0, + "y": 48, + "page": 0 + }, + { + "id": 91, + "index": 63, + "char": "[", + "width": 12, + "height": 45, + "xoffset": 1, + "yoffset": 0, + "xadvance": 11, + "chnl": 15, + "x": 0, + "y": 96, + "page": 0 + }, + { + "id": 93, + "index": 65, + "char": "]", + "width": 12, + "height": 45, + "xoffset": -2, + "yoffset": 0, + "xadvance": 11, + "chnl": 15, + "x": 0, + "y": 142, + "page": 0 + }, + { + "id": 123, + "index": 95, + "char": "{", + "width": 16, + "height": 44, + "xoffset": -1, + "yoffset": 1, + "xadvance": 14, + "chnl": 15, + "x": 0, + "y": 188, + "page": 0 + }, + { + "id": 125, + "index": 97, + "char": "}", + "width": 16, + "height": 44, + "xoffset": -2, + "yoffset": 1, + "xadvance": 14, + "chnl": 15, + "x": 13, + "y": 96, + "page": 0 + }, + { + "id": 1092, + "index": 247, + "char": "ф", + "width": 30, + "height": 44, + "xoffset": 0, + "yoffset": 3, + "xadvance": 30, + "chnl": 15, + "x": 13, + "y": 141, + "page": 0 + }, + { + "id": 197, + "index": 644, + "char": "Å", + "width": 30, + "height": 44, + "xoffset": -1, + "yoffset": -6, + "xadvance": 27, + "chnl": 15, + "x": 16, + "y": 0, + "page": 0 + }, + { + "id": 106, + "index": 78, + "char": "j", + "width": 12, + "height": 43, + "xoffset": -3, + "yoffset": 4, + "xadvance": 10, + "chnl": 15, + "x": 16, + "y": 45, + "page": 0 + }, + { + "id": 36, + "index": 8, + "char": "$", + "width": 23, + "height": 43, + "xoffset": 0, + "yoffset": -1, + "xadvance": 24, + "chnl": 15, + "x": 29, + "y": 45, + "page": 0 + }, + { + "id": 64, + "index": 36, + "char": "@", + "width": 37, + "height": 43, + "xoffset": 0, + "yoffset": 5, + "xadvance": 38, + "chnl": 15, + "x": 47, + "y": 0, + "page": 0 + }, + { + "id": 198, + "index": 129, + "char": "Æ", + "width": 43, + "height": 34, + "xoffset": -2, + "yoffset": 4, + "xadvance": 39, + "chnl": 15, + "x": 30, + "y": 89, + "page": 0 + }, + { + "id": 958, + "index": 197, + "char": "ξ", + "width": 21, + "height": 42, + "xoffset": 0, + "yoffset": 4, + "xadvance": 21, + "chnl": 15, + "x": 53, + "y": 44, + "page": 0 + }, + { + "id": 950, + "index": 192, + "char": "ζ", + "width": 22, + "height": 42, + "xoffset": 0, + "yoffset": 4, + "xadvance": 22, + "chnl": 15, + "x": 0, + "y": 233, + "page": 0 + }, + { + "id": 946, + "index": 188, + "char": "β", + "width": 23, + "height": 42, + "xoffset": 1, + "yoffset": 4, + "xadvance": 25, + "chnl": 15, + "x": 17, + "y": 186, + "page": 0 + }, + { + "id": 1044, + "index": 217, + "char": "Д", + "width": 33, + "height": 41, + "xoffset": -1, + "yoffset": 4, + "xadvance": 32, + "chnl": 15, + "x": 0, + "y": 276, + "page": 0 + }, + { + "id": 1025, + "index": 941, + "char": "Ё", + "width": 23, + "height": 41, + "xoffset": 1, + "yoffset": -3, + "xadvance": 24, + "chnl": 15, + "x": 23, + "y": 229, + "page": 0 + }, + { + "id": 1046, + "index": 218, + "char": "Ж", + "width": 41, + "height": 34, + "xoffset": -1, + "yoffset": 4, + "xadvance": 38, + "chnl": 15, + "x": 41, + "y": 186, + "page": 0 + }, + { + "id": 1049, + "index": 954, + "char": "Й", + "width": 27, + "height": 41, + "xoffset": 2, + "yoffset": -3, + "xadvance": 30, + "chnl": 15, + "x": 44, + "y": 124, + "page": 0 + }, + { + "id": 1062, + "index": 224, + "char": "Ц", + "width": 30, + "height": 41, + "xoffset": 2, + "yoffset": 4, + "xadvance": 31, + "chnl": 15, + "x": 72, + "y": 124, + "page": 0 + }, + { + "id": 1065, + "index": 227, + "char": "Щ", + "width": 39, + "height": 41, + "xoffset": 2, + "yoffset": 4, + "xadvance": 41, + "chnl": 15, + "x": 75, + "y": 44, + "page": 0 + }, + { + "id": 220, + "index": 664, + "char": "Ü", + "width": 26, + "height": 41, + "xoffset": 1, + "yoffset": -3, + "xadvance": 27, + "chnl": 15, + "x": 85, + "y": 0, + "page": 0 + }, + { + "id": 214, + "index": 660, + "char": "Ö", + "width": 28, + "height": 41, + "xoffset": 0, + "yoffset": -3, + "xadvance": 29, + "chnl": 15, + "x": 112, + "y": 0, + "page": 0 + }, + { + "id": 196, + "index": 643, + "char": "Ä", + "width": 30, + "height": 41, + "xoffset": -1, + "yoffset": -3, + "xadvance": 27, + "chnl": 15, + "x": 0, + "y": 318, + "page": 0 + }, + { + "id": 209, + "index": 655, + "char": "Ñ", + "width": 27, + "height": 41, + "xoffset": 1, + "yoffset": -3, + "xadvance": 30, + "chnl": 15, + "x": 0, + "y": 360, + "page": 0 + }, + { + "id": 81, + "index": 53, + "char": "Q", + "width": 28, + "height": 39, + "xoffset": 0, + "yoffset": 4, + "xadvance": 29, + "chnl": 15, + "x": 0, + "y": 402, + "page": 0 + }, + { + "id": 87, + "index": 59, + "char": "W", + "width": 39, + "height": 34, + "xoffset": -1, + "yoffset": 4, + "xadvance": 37, + "chnl": 15, + "x": 74, + "y": 87, + "page": 0 + }, + { + "id": 124, + "index": 96, + "char": "|", + "width": 7, + "height": 39, + "xoffset": 2, + "yoffset": 4, + "xadvance": 10, + "chnl": 15, + "x": 28, + "y": 360, + "page": 0 + }, + { + "id": 229, + "index": 671, + "char": "å", + "width": 22, + "height": 38, + "xoffset": 0, + "yoffset": 1, + "xadvance": 23, + "chnl": 15, + "x": 31, + "y": 318, + "page": 0 + }, + { + "id": 216, + "index": 131, + "char": "Ø", + "width": 28, + "height": 37, + "xoffset": 0, + "yoffset": 3, + "xadvance": 29, + "chnl": 15, + "x": 34, + "y": 271, + "page": 0 + }, + { + "id": 100, + "index": 72, + "char": "d", + "width": 23, + "height": 36, + "xoffset": 0, + "yoffset": 3, + "xadvance": 24, + "chnl": 15, + "x": 47, + "y": 221, + "page": 0 + }, + { + "id": 102, + "index": 74, + "char": "f", + "width": 17, + "height": 36, + "xoffset": -1, + "yoffset": 2, + "xadvance": 15, + "chnl": 15, + "x": 0, + "y": 442, + "page": 0 + }, + { + "id": 104, + "index": 76, + "char": "h", + "width": 21, + "height": 36, + "xoffset": 1, + "yoffset": 3, + "xadvance": 23, + "chnl": 15, + "x": 18, + "y": 442, + "page": 0 + }, + { + "id": 107, + "index": 79, + "char": "k", + "width": 22, + "height": 36, + "xoffset": 1, + "yoffset": 3, + "xadvance": 21, + "chnl": 15, + "x": 29, + "y": 400, + "page": 0 + }, + { + "id": 108, + "index": 80, + "char": "l", + "width": 8, + "height": 36, + "xoffset": 1, + "yoffset": 3, + "xadvance": 10, + "chnl": 15, + "x": 36, + "y": 357, + "page": 0 + }, + { + "id": 98, + "index": 70, + "char": "b", + "width": 23, + "height": 36, + "xoffset": 1, + "yoffset": 3, + "xadvance": 24, + "chnl": 15, + "x": 45, + "y": 357, + "page": 0 + }, + { + "id": 47, + "index": 19, + "char": "/", + "width": 20, + "height": 36, + "xoffset": -2, + "yoffset": 4, + "xadvance": 17, + "chnl": 15, + "x": 54, + "y": 309, + "page": 0 + }, + { + "id": 92, + "index": 64, + "char": "\\", + "width": 20, + "height": 36, + "xoffset": -1, + "yoffset": 4, + "xadvance": 17, + "chnl": 15, + "x": 63, + "y": 258, + "page": 0 + }, + { + "id": 1073, + "index": 234, + "char": "б", + "width": 24, + "height": 36, + "xoffset": 0, + "yoffset": 2, + "xadvance": 23, + "chnl": 15, + "x": 71, + "y": 221, + "page": 0 + }, + { + "id": 1060, + "index": 223, + "char": "Ф", + "width": 33, + "height": 36, + "xoffset": 0, + "yoffset": 3, + "xadvance": 32, + "chnl": 15, + "x": 83, + "y": 166, + "page": 0 + }, + { + "id": 1064, + "index": 226, + "char": "Ш", + "width": 36, + "height": 34, + "xoffset": 2, + "yoffset": 4, + "xadvance": 40, + "chnl": 15, + "x": 103, + "y": 122, + "page": 0 + }, + { + "id": 1070, + "index": 232, + "char": "Ю", + "width": 36, + "height": 35, + "xoffset": 2, + "yoffset": 4, + "xadvance": 38, + "chnl": 15, + "x": 114, + "y": 86, + "page": 0 + }, + { + "id": 948, + "index": 190, + "char": "δ", + "width": 24, + "height": 36, + "xoffset": 0, + "yoffset": 2, + "xadvance": 24, + "chnl": 15, + "x": 115, + "y": 42, + "page": 0 + }, + { + "id": 966, + "index": 204, + "char": "φ", + "width": 30, + "height": 36, + "xoffset": 0, + "yoffset": 12, + "xadvance": 30, + "chnl": 15, + "x": 140, + "y": 42, + "page": 0 + }, + { + "id": 968, + "index": 205, + "char": "ψ", + "width": 30, + "height": 36, + "xoffset": 0, + "yoffset": 12, + "xadvance": 29, + "chnl": 15, + "x": 141, + "y": 0, + "page": 0 + }, + { + "id": 230, + "index": 134, + "char": "æ", + "width": 36, + "height": 27, + "xoffset": 0, + "yoffset": 11, + "xadvance": 35, + "chnl": 15, + "x": 0, + "y": 479, + "page": 0 + }, + { + "id": 121, + "index": 93, + "char": "y", + "width": 23, + "height": 35, + "xoffset": -2, + "yoffset": 12, + "xadvance": 20, + "chnl": 15, + "x": 40, + "y": 437, + "page": 0 + }, + { + "id": 112, + "index": 84, + "char": "p", + "width": 23, + "height": 35, + "xoffset": 1, + "yoffset": 11, + "xadvance": 24, + "chnl": 15, + "x": 40, + "y": 473, + "page": 0 + }, + { + "id": 113, + "index": 85, + "char": "q", + "width": 23, + "height": 35, + "xoffset": 0, + "yoffset": 11, + "xadvance": 24, + "chnl": 15, + "x": 52, + "y": 394, + "page": 0 + }, + { + "id": 103, + "index": 75, + "char": "g", + "width": 23, + "height": 35, + "xoffset": 0, + "yoffset": 11, + "xadvance": 24, + "chnl": 15, + "x": 69, + "y": 346, + "page": 0 + }, + { + "id": 109, + "index": 81, + "char": "m", + "width": 35, + "height": 27, + "xoffset": 1, + "yoffset": 11, + "xadvance": 37, + "chnl": 15, + "x": 75, + "y": 295, + "page": 0 + }, + { + "id": 79, + "index": 51, + "char": "O", + "width": 28, + "height": 35, + "xoffset": 0, + "yoffset": 4, + "xadvance": 29, + "chnl": 15, + "x": 84, + "y": 258, + "page": 0 + }, + { + "id": 83, + "index": 55, + "char": "S", + "width": 26, + "height": 35, + "xoffset": 0, + "yoffset": 4, + "xadvance": 25, + "chnl": 15, + "x": 96, + "y": 203, + "page": 0 + }, + { + "id": 71, + "index": 43, + "char": "G", + "width": 27, + "height": 35, + "xoffset": 1, + "yoffset": 4, + "xadvance": 29, + "chnl": 15, + "x": 117, + "y": 157, + "page": 0 + }, + { + "id": 67, + "index": 39, + "char": "C", + "width": 27, + "height": 35, + "xoffset": 0, + "yoffset": 4, + "xadvance": 27, + "chnl": 15, + "x": 64, + "y": 430, + "page": 0 + }, + { + "id": 56, + "index": 28, + "char": "8", + "width": 23, + "height": 35, + "xoffset": 0, + "yoffset": 4, + "xadvance": 24, + "chnl": 15, + "x": 64, + "y": 466, + "page": 0 + }, + { + "id": 51, + "index": 23, + "char": "3", + "width": 23, + "height": 35, + "xoffset": 0, + "yoffset": 4, + "xadvance": 24, + "chnl": 15, + "x": 88, + "y": 466, + "page": 0 + }, + { + "id": 48, + "index": 20, + "char": "0", + "width": 23, + "height": 35, + "xoffset": 0, + "yoffset": 4, + "xadvance": 24, + "chnl": 15, + "x": 76, + "y": 382, + "page": 0 + }, + { + "id": 37, + "index": 9, + "char": "%", + "width": 31, + "height": 35, + "xoffset": 0, + "yoffset": 4, + "xadvance": 31, + "chnl": 15, + "x": 92, + "y": 418, + "page": 0 + }, + { + "id": 8364, + "index": 413, + "char": "€", + "width": 24, + "height": 35, + "xoffset": 0, + "yoffset": 4, + "xadvance": 24, + "chnl": 15, + "x": 93, + "y": 323, + "page": 0 + }, + { + "id": 38, + "index": 10, + "char": "&", + "width": 28, + "height": 35, + "xoffset": 0, + "yoffset": 4, + "xadvance": 26, + "chnl": 15, + "x": 112, + "y": 454, + "page": 0 + }, + { + "id": 1105, + "index": 971, + "char": "ё", + "width": 23, + "height": 35, + "xoffset": 0, + "yoffset": 4, + "xadvance": 22, + "chnl": 15, + "x": 100, + "y": 359, + "page": 0 + }, + { + "id": 1078, + "index": 238, + "char": "ж", + "width": 35, + "height": 26, + "xoffset": -2, + "yoffset": 12, + "xadvance": 32, + "chnl": 15, + "x": 111, + "y": 294, + "page": 0 + }, + { + "id": 1047, + "index": 219, + "char": "З", + "width": 26, + "height": 35, + "xoffset": 0, + "yoffset": 4, + "xadvance": 25, + "chnl": 15, + "x": 118, + "y": 321, + "page": 0 + }, + { + "id": 1054, + "index": 957, + "char": "О", + "width": 28, + "height": 35, + "xoffset": 0, + "yoffset": 4, + "xadvance": 29, + "chnl": 15, + "x": 113, + "y": 239, + "page": 0 + }, + { + "id": 1088, + "index": 967, + "char": "р", + "width": 23, + "height": 35, + "xoffset": 1, + "yoffset": 11, + "xadvance": 24, + "chnl": 15, + "x": 123, + "y": 193, + "page": 0 + }, + { + "id": 1057, + "index": 960, + "char": "С", + "width": 27, + "height": 35, + "xoffset": 0, + "yoffset": 4, + "xadvance": 27, + "chnl": 15, + "x": 142, + "y": 229, + "page": 0 + }, + { + "id": 1091, + "index": 969, + "char": "у", + "width": 23, + "height": 35, + "xoffset": -2, + "yoffset": 12, + "xadvance": 20, + "chnl": 15, + "x": 145, + "y": 122, + "page": 0 + }, + { + "id": 1097, + "index": 251, + "char": "щ", + "width": 35, + "height": 33, + "xoffset": 1, + "yoffset": 12, + "xadvance": 35, + "chnl": 15, + "x": 145, + "y": 158, + "page": 0 + }, + { + "id": 1069, + "index": 231, + "char": "Э", + "width": 27, + "height": 35, + "xoffset": 1, + "yoffset": 4, + "xadvance": 28, + "chnl": 15, + "x": 147, + "y": 192, + "page": 0 + }, + { + "id": 252, + "index": 691, + "char": "ü", + "width": 21, + "height": 35, + "xoffset": 1, + "yoffset": 4, + "xadvance": 23, + "chnl": 15, + "x": 151, + "y": 79, + "page": 0 + }, + { + "id": 246, + "index": 687, + "char": "ö", + "width": 24, + "height": 35, + "xoffset": 0, + "yoffset": 4, + "xadvance": 24, + "chnl": 15, + "x": 171, + "y": 37, + "page": 0 + }, + { + "id": 228, + "index": 670, + "char": "ä", + "width": 22, + "height": 35, + "xoffset": 0, + "yoffset": 4, + "xadvance": 23, + "chnl": 15, + "x": 172, + "y": 0, + "page": 0 + }, + { + "id": 241, + "index": 682, + "char": "ñ", + "width": 21, + "height": 35, + "xoffset": 1, + "yoffset": 3, + "xadvance": 23, + "chnl": 15, + "x": 195, + "y": 0, + "page": 0 + }, + { + "id": 961, + "index": 199, + "char": "ρ", + "width": 23, + "height": 35, + "xoffset": 1, + "yoffset": 11, + "xadvance": 24, + "chnl": 15, + "x": 169, + "y": 115, + "page": 0 + }, + { + "id": 952, + "index": 194, + "char": "θ", + "width": 23, + "height": 35, + "xoffset": 1, + "yoffset": 4, + "xadvance": 24, + "chnl": 15, + "x": 173, + "y": 73, + "page": 0 + }, + { + "id": 947, + "index": 189, + "char": "γ", + "width": 23, + "height": 35, + "xoffset": -1, + "yoffset": 12, + "xadvance": 21, + "chnl": 15, + "x": 196, + "y": 36, + "page": 0 + }, + { + "id": 951, + "index": 193, + "char": "η", + "width": 22, + "height": 35, + "xoffset": 1, + "yoffset": 11, + "xadvance": 24, + "chnl": 15, + "x": 217, + "y": 0, + "page": 0 + }, + { + "id": 955, + "index": 196, + "char": "λ", + "width": 25, + "height": 35, + "xoffset": -1, + "yoffset": 3, + "xadvance": 23, + "chnl": 15, + "x": 124, + "y": 357, + "page": 0 + }, + { + "id": 967, + "index": 935, + "char": "χ", + "width": 26, + "height": 35, + "xoffset": 0, + "yoffset": 12, + "xadvance": 21, + "chnl": 15, + "x": 145, + "y": 321, + "page": 0 + }, + { + "id": 956, + "index": 933, + "char": "μ", + "width": 21, + "height": 35, + "xoffset": 1, + "yoffset": 12, + "xadvance": 24, + "chnl": 15, + "x": 147, + "y": 265, + "page": 0 + }, + { + "id": 920, + "index": 179, + "char": "Θ", + "width": 28, + "height": 35, + "xoffset": 0, + "yoffset": 4, + "xadvance": 29, + "chnl": 15, + "x": 169, + "y": 265, + "page": 0 + }, + { + "id": 927, + "index": 919, + "char": "Ο", + "width": 28, + "height": 35, + "xoffset": 0, + "yoffset": 4, + "xadvance": 29, + "chnl": 15, + "x": 170, + "y": 228, + "page": 0 + }, + { + "id": 105, + "index": 77, + "char": "i", + "width": 8, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 10, + "chnl": 15, + "x": 175, + "y": 192, + "page": 0 + }, + { + "id": 119, + "index": 91, + "char": "w", + "width": 34, + "height": 26, + "xoffset": -1, + "yoffset": 12, + "xadvance": 32, + "chnl": 15, + "x": 181, + "y": 151, + "page": 0 + }, + { + "id": 65, + "index": 37, + "char": "A", + "width": 30, + "height": 34, + "xoffset": -1, + "yoffset": 4, + "xadvance": 27, + "chnl": 15, + "x": 193, + "y": 109, + "page": 0 + }, + { + "id": 90, + "index": 62, + "char": "Z", + "width": 26, + "height": 34, + "xoffset": 0, + "yoffset": 4, + "xadvance": 25, + "chnl": 15, + "x": 197, + "y": 72, + "page": 0 + }, + { + "id": 69, + "index": 41, + "char": "E", + "width": 23, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 24, + "chnl": 15, + "x": 220, + "y": 36, + "page": 0 + }, + { + "id": 82, + "index": 54, + "char": "R", + "width": 26, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 26, + "chnl": 15, + "x": 240, + "y": 0, + "page": 0 + }, + { + "id": 84, + "index": 56, + "char": "T", + "width": 27, + "height": 34, + "xoffset": -1, + "yoffset": 4, + "xadvance": 25, + "chnl": 15, + "x": 184, + "y": 178, + "page": 0 + }, + { + "id": 89, + "index": 61, + "char": "Y", + "width": 29, + "height": 34, + "xoffset": -2, + "yoffset": 4, + "xadvance": 25, + "chnl": 15, + "x": 124, + "y": 393, + "page": 0 + }, + { + "id": 85, + "index": 57, + "char": "U", + "width": 26, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 27, + "chnl": 15, + "x": 150, + "y": 357, + "page": 0 + }, + { + "id": 73, + "index": 45, + "char": "I", + "width": 8, + "height": 34, + "xoffset": 2, + "yoffset": 4, + "xadvance": 11, + "chnl": 15, + "x": 172, + "y": 301, + "page": 0 + }, + { + "id": 80, + "index": 52, + "char": "P", + "width": 25, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 26, + "chnl": 15, + "x": 141, + "y": 428, + "page": 0 + }, + { + "id": 68, + "index": 40, + "char": "D", + "width": 26, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 28, + "chnl": 15, + "x": 154, + "y": 392, + "page": 0 + }, + { + "id": 70, + "index": 42, + "char": "F", + "width": 22, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 23, + "chnl": 15, + "x": 141, + "y": 463, + "page": 0 + }, + { + "id": 72, + "index": 44, + "char": "H", + "width": 27, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 30, + "chnl": 15, + "x": 164, + "y": 463, + "page": 0 + }, + { + "id": 74, + "index": 46, + "char": "J", + "width": 23, + "height": 34, + "xoffset": -1, + "yoffset": 4, + "xadvance": 23, + "chnl": 15, + "x": 167, + "y": 427, + "page": 0 + }, + { + "id": 75, + "index": 47, + "char": "K", + "width": 27, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 26, + "chnl": 15, + "x": 177, + "y": 336, + "page": 0 + }, + { + "id": 76, + "index": 48, + "char": "L", + "width": 22, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 23, + "chnl": 15, + "x": 181, + "y": 301, + "page": 0 + }, + { + "id": 77, + "index": 49, + "char": "M", + "width": 34, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 37, + "chnl": 15, + "x": 198, + "y": 264, + "page": 0 + }, + { + "id": 88, + "index": 60, + "char": "X", + "width": 28, + "height": 34, + "xoffset": -1, + "yoffset": 4, + "xadvance": 26, + "chnl": 15, + "x": 204, + "y": 299, + "page": 0 + }, + { + "id": 86, + "index": 58, + "char": "V", + "width": 30, + "height": 34, + "xoffset": -1, + "yoffset": 4, + "xadvance": 27, + "chnl": 15, + "x": 199, + "y": 213, + "page": 0 + }, + { + "id": 66, + "index": 38, + "char": "B", + "width": 24, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 26, + "chnl": 15, + "x": 212, + "y": 178, + "page": 0 + }, + { + "id": 78, + "index": 50, + "char": "N", + "width": 27, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 30, + "chnl": 15, + "x": 230, + "y": 213, + "page": 0 + }, + { + "id": 55, + "index": 27, + "char": "7", + "width": 24, + "height": 34, + "xoffset": 0, + "yoffset": 4, + "xadvance": 24, + "chnl": 15, + "x": 181, + "y": 371, + "page": 0 + }, + { + "id": 57, + "index": 29, + "char": "9", + "width": 23, + "height": 34, + "xoffset": 0, + "yoffset": 4, + "xadvance": 24, + "chnl": 15, + "x": 205, + "y": 334, + "page": 0 + }, + { + "id": 52, + "index": 24, + "char": "4", + "width": 26, + "height": 34, + "xoffset": -1, + "yoffset": 4, + "xadvance": 24, + "chnl": 15, + "x": 191, + "y": 406, + "page": 0 + }, + { + "id": 53, + "index": 25, + "char": "5", + "width": 23, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 24, + "chnl": 15, + "x": 206, + "y": 369, + "page": 0 + }, + { + "id": 54, + "index": 26, + "char": "6", + "width": 23, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 24, + "chnl": 15, + "x": 229, + "y": 334, + "page": 0 + }, + { + "id": 49, + "index": 21, + "char": "1", + "width": 15, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 24, + "chnl": 15, + "x": 192, + "y": 441, + "page": 0 + }, + { + "id": 50, + "index": 22, + "char": "2", + "width": 24, + "height": 34, + "xoffset": 0, + "yoffset": 4, + "xadvance": 24, + "chnl": 15, + "x": 192, + "y": 476, + "page": 0 + }, + { + "id": 33, + "index": 5, + "char": "!", + "width": 8, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 11, + "chnl": 15, + "x": 208, + "y": 441, + "page": 0 + }, + { + "id": 63, + "index": 35, + "char": "?", + "width": 21, + "height": 34, + "xoffset": 0, + "yoffset": 4, + "xadvance": 20, + "chnl": 15, + "x": 217, + "y": 441, + "page": 0 + }, + { + "id": 163, + "index": 101, + "char": "£", + "width": 25, + "height": 34, + "xoffset": 0, + "yoffset": 4, + "xadvance": 24, + "chnl": 15, + "x": 218, + "y": 404, + "page": 0 + }, + { + "id": 35, + "index": 7, + "char": "#", + "width": 27, + "height": 34, + "xoffset": 0, + "yoffset": 4, + "xadvance": 26, + "chnl": 15, + "x": 230, + "y": 369, + "page": 0 + }, + { + "id": 1040, + "index": 950, + "char": "А", + "width": 30, + "height": 34, + "xoffset": -1, + "yoffset": 4, + "xadvance": 27, + "chnl": 15, + "x": 217, + "y": 476, + "page": 0 + }, + { + "id": 1041, + "index": 216, + "char": "Б", + "width": 25, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 26, + "chnl": 15, + "x": 239, + "y": 439, + "page": 0 + }, + { + "id": 1042, + "index": 951, + "char": "В", + "width": 24, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 26, + "chnl": 15, + "x": 244, + "y": 404, + "page": 0 + }, + { + "id": 1043, + "index": 952, + "char": "Г", + "width": 22, + "height": 34, + "xoffset": 2, + "yoffset": 4, + "xadvance": 23, + "chnl": 15, + "x": 248, + "y": 474, + "page": 0 + }, + { + "id": 1045, + "index": 953, + "char": "Е", + "width": 23, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 24, + "chnl": 15, + "x": 265, + "y": 439, + "page": 0 + }, + { + "id": 1048, + "index": 220, + "char": "И", + "width": 27, + "height": 34, + "xoffset": 2, + "yoffset": 4, + "xadvance": 30, + "chnl": 15, + "x": 271, + "y": 474, + "page": 0 + }, + { + "id": 1081, + "index": 965, + "char": "й", + "width": 22, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 24, + "chnl": 15, + "x": 233, + "y": 248, + "page": 0 + }, + { + "id": 1050, + "index": 947, + "char": "К", + "width": 27, + "height": 34, + "xoffset": 2, + "yoffset": 4, + "xadvance": 27, + "chnl": 15, + "x": 233, + "y": 283, + "page": 0 + }, + { + "id": 1051, + "index": 221, + "char": "Л", + "width": 29, + "height": 34, + "xoffset": -1, + "yoffset": 4, + "xadvance": 30, + "chnl": 15, + "x": 256, + "y": 248, + "page": 0 + }, + { + "id": 1052, + "index": 955, + "char": "М", + "width": 34, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 37, + "chnl": 15, + "x": 253, + "y": 318, + "page": 0 + }, + { + "id": 1053, + "index": 956, + "char": "Н", + "width": 27, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 30, + "chnl": 15, + "x": 261, + "y": 283, + "page": 0 + }, + { + "id": 1055, + "index": 958, + "char": "П", + "width": 27, + "height": 34, + "xoffset": 2, + "yoffset": 4, + "xadvance": 30, + "chnl": 15, + "x": 258, + "y": 353, + "page": 0 + }, + { + "id": 1056, + "index": 959, + "char": "Р", + "width": 25, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 26, + "chnl": 15, + "x": 269, + "y": 388, + "page": 0 + }, + { + "id": 1058, + "index": 961, + "char": "Т", + "width": 27, + "height": 34, + "xoffset": -1, + "yoffset": 4, + "xadvance": 25, + "chnl": 15, + "x": 286, + "y": 353, + "page": 0 + }, + { + "id": 1059, + "index": 222, + "char": "У", + "width": 28, + "height": 34, + "xoffset": 0, + "yoffset": 4, + "xadvance": 26, + "chnl": 15, + "x": 288, + "y": 318, + "page": 0 + }, + { + "id": 1061, + "index": 962, + "char": "Х", + "width": 28, + "height": 34, + "xoffset": -1, + "yoffset": 4, + "xadvance": 26, + "chnl": 15, + "x": 289, + "y": 423, + "page": 0 + }, + { + "id": 1063, + "index": 225, + "char": "Ч", + "width": 26, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 29, + "chnl": 15, + "x": 295, + "y": 388, + "page": 0 + }, + { + "id": 1066, + "index": 228, + "char": "Ъ", + "width": 34, + "height": 34, + "xoffset": -2, + "yoffset": 4, + "xadvance": 32, + "chnl": 15, + "x": 314, + "y": 353, + "page": 0 + }, + { + "id": 1067, + "index": 229, + "char": "Ы", + "width": 33, + "height": 34, + "xoffset": 2, + "yoffset": 4, + "xadvance": 36, + "chnl": 15, + "x": 299, + "y": 458, + "page": 0 + }, + { + "id": 1068, + "index": 230, + "char": "Ь", + "width": 25, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 26, + "chnl": 15, + "x": 318, + "y": 423, + "page": 0 + }, + { + "id": 1071, + "index": 233, + "char": "Я", + "width": 25, + "height": 34, + "xoffset": 0, + "yoffset": 4, + "xadvance": 27, + "chnl": 15, + "x": 322, + "y": 388, + "page": 0 + }, + { + "id": 962, + "index": 200, + "char": "ς", + "width": 22, + "height": 34, + "xoffset": 0, + "yoffset": 11, + "xadvance": 23, + "chnl": 15, + "x": 333, + "y": 458, + "page": 0 + }, + { + "id": 969, + "index": 206, + "char": "ω", + "width": 34, + "height": 27, + "xoffset": 1, + "yoffset": 12, + "xadvance": 35, + "chnl": 15, + "x": 216, + "y": 144, + "page": 0 + }, + { + "id": 917, + "index": 912, + "char": "Ε", + "width": 23, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 24, + "chnl": 15, + "x": 344, + "y": 423, + "page": 0 + }, + { + "id": 929, + "index": 920, + "char": "Ρ", + "width": 25, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 26, + "chnl": 15, + "x": 348, + "y": 388, + "page": 0 + }, + { + "id": 932, + "index": 921, + "char": "Τ", + "width": 27, + "height": 34, + "xoffset": -1, + "yoffset": 4, + "xadvance": 25, + "chnl": 15, + "x": 237, + "y": 172, + "page": 0 + }, + { + "id": 933, + "index": 922, + "char": "Υ", + "width": 29, + "height": 34, + "xoffset": -2, + "yoffset": 4, + "xadvance": 25, + "chnl": 15, + "x": 258, + "y": 207, + "page": 0 + }, + { + "id": 921, + "index": 915, + "char": "Ι", + "width": 8, + "height": 34, + "xoffset": 2, + "yoffset": 4, + "xadvance": 11, + "chnl": 15, + "x": 286, + "y": 242, + "page": 0 + }, + { + "id": 928, + "index": 182, + "char": "Π", + "width": 27, + "height": 34, + "xoffset": 2, + "yoffset": 4, + "xadvance": 30, + "chnl": 15, + "x": 289, + "y": 277, + "page": 0 + }, + { + "id": 913, + "index": 910, + "char": "Α", + "width": 30, + "height": 34, + "xoffset": -1, + "yoffset": 4, + "xadvance": 27, + "chnl": 15, + "x": 356, + "y": 458, + "page": 0 + }, + { + "id": 931, + "index": 183, + "char": "Σ", + "width": 25, + "height": 34, + "xoffset": -1, + "yoffset": 4, + "xadvance": 24, + "chnl": 15, + "x": 368, + "y": 423, + "page": 0 + }, + { + "id": 916, + "index": 178, + "char": "Δ", + "width": 32, + "height": 34, + "xoffset": -1, + "yoffset": 4, + "xadvance": 30, + "chnl": 15, + "x": 387, + "y": 458, + "page": 0 + }, + { + "id": 934, + "index": 184, + "char": "Φ", + "width": 31, + "height": 34, + "xoffset": 0, + "yoffset": 4, + "xadvance": 30, + "chnl": 15, + "x": 224, + "y": 71, + "page": 0 + }, + { + "id": 915, + "index": 177, + "char": "Γ", + "width": 22, + "height": 34, + "xoffset": 2, + "yoffset": 4, + "xadvance": 23, + "chnl": 15, + "x": 244, + "y": 35, + "page": 0 + }, + { + "id": 919, + "index": 914, + "char": "Η", + "width": 27, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 30, + "chnl": 15, + "x": 224, + "y": 106, + "page": 0 + }, + { + "id": 926, + "index": 181, + "char": "Ξ", + "width": 23, + "height": 34, + "xoffset": 0, + "yoffset": 4, + "xadvance": 24, + "chnl": 15, + "x": 252, + "y": 106, + "page": 0 + }, + { + "id": 922, + "index": 916, + "char": "Κ", + "width": 27, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 26, + "chnl": 15, + "x": 256, + "y": 70, + "page": 0 + }, + { + "id": 923, + "index": 180, + "char": "Λ", + "width": 29, + "height": 34, + "xoffset": -1, + "yoffset": 4, + "xadvance": 28, + "chnl": 15, + "x": 265, + "y": 141, + "page": 0 + }, + { + "id": 918, + "index": 913, + "char": "Ζ", + "width": 26, + "height": 34, + "xoffset": 0, + "yoffset": 4, + "xadvance": 25, + "chnl": 15, + "x": 276, + "y": 105, + "page": 0 + }, + { + "id": 935, + "index": 923, + "char": "Χ", + "width": 28, + "height": 34, + "xoffset": -1, + "yoffset": 4, + "xadvance": 26, + "chnl": 15, + "x": 288, + "y": 176, + "page": 0 + }, + { + "id": 936, + "index": 185, + "char": "Ψ", + "width": 29, + "height": 34, + "xoffset": 0, + "yoffset": 4, + "xadvance": 29, + "chnl": 15, + "x": 295, + "y": 140, + "page": 0 + }, + { + "id": 937, + "index": 186, + "char": "Ω", + "width": 27, + "height": 34, + "xoffset": 0, + "yoffset": 4, + "xadvance": 28, + "chnl": 15, + "x": 295, + "y": 211, + "page": 0 + }, + { + "id": 914, + "index": 911, + "char": "Β", + "width": 24, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 26, + "chnl": 15, + "x": 317, + "y": 175, + "page": 0 + }, + { + "id": 925, + "index": 918, + "char": "Ν", + "width": 27, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 30, + "chnl": 15, + "x": 267, + "y": 0, + "page": 0 + }, + { + "id": 924, + "index": 917, + "char": "Μ", + "width": 34, + "height": 34, + "xoffset": 1, + "yoffset": 4, + "xadvance": 37, + "chnl": 15, + "x": 267, + "y": 35, + "page": 0 + }, + { + "id": 1076, + "index": 237, + "char": "д", + "width": 27, + "height": 33, + "xoffset": -1, + "yoffset": 12, + "xadvance": 25, + "chnl": 15, + "x": 284, + "y": 70, + "page": 0 + }, + { + "id": 1094, + "index": 248, + "char": "ц", + "width": 24, + "height": 33, + "xoffset": 1, + "yoffset": 12, + "xadvance": 25, + "chnl": 15, + "x": 295, + "y": 0, + "page": 0 + }, + { + "id": 1102, + "index": 256, + "char": "ю", + "width": 33, + "height": 27, + "xoffset": 1, + "yoffset": 11, + "xadvance": 34, + "chnl": 15, + "x": 295, + "y": 246, + "page": 0 + }, + { + "id": 116, + "index": 88, + "char": "t", + "width": 16, + "height": 32, + "xoffset": -2, + "yoffset": 6, + "xadvance": 14, + "chnl": 15, + "x": 303, + "y": 104, + "page": 0 + }, + { + "id": 59, + "index": 31, + "char": ";", + "width": 10, + "height": 32, + "xoffset": -1, + "yoffset": 12, + "xadvance": 9, + "chnl": 15, + "x": 302, + "y": 34, + "page": 0 + }, + { + "id": 1096, + "index": 250, + "char": "ш", + "width": 32, + "height": 26, + "xoffset": 1, + "yoffset": 12, + "xadvance": 34, + "chnl": 15, + "x": 323, + "y": 210, + "page": 0 + }, + { + "id": 248, + "index": 137, + "char": "ø", + "width": 24, + "height": 32, + "xoffset": 0, + "yoffset": 9, + "xadvance": 24, + "chnl": 15, + "x": 312, + "y": 67, + "page": 0 + }, + { + "id": 1099, + "index": 253, + "char": "ы", + "width": 30, + "height": 26, + "xoffset": 1, + "yoffset": 12, + "xadvance": 33, + "chnl": 15, + "x": 313, + "y": 34, + "page": 0 + }, + { + "id": 1084, + "index": 243, + "char": "м", + "width": 29, + "height": 26, + "xoffset": 1, + "yoffset": 12, + "xadvance": 31, + "chnl": 15, + "x": 320, + "y": 0, + "page": 0 + }, + { + "id": 1098, + "index": 252, + "char": "ъ", + "width": 28, + "height": 26, + "xoffset": -1, + "yoffset": 12, + "xadvance": 26, + "chnl": 15, + "x": 320, + "y": 100, + "page": 0 + }, + { + "id": 960, + "index": 198, + "char": "π", + "width": 28, + "height": 26, + "xoffset": -1, + "yoffset": 12, + "xadvance": 25, + "chnl": 15, + "x": 337, + "y": 61, + "page": 0 + }, + { + "id": 97, + "index": 69, + "char": "a", + "width": 22, + "height": 27, + "xoffset": 0, + "yoffset": 11, + "xadvance": 23, + "chnl": 15, + "x": 265, + "y": 176, + "page": 0 + }, + { + "id": 101, + "index": 73, + "char": "e", + "width": 23, + "height": 27, + "xoffset": 0, + "yoffset": 11, + "xadvance": 22, + "chnl": 15, + "x": 344, + "y": 27, + "page": 0 + }, + { + "id": 114, + "index": 86, + "char": "r", + "width": 15, + "height": 27, + "xoffset": 1, + "yoffset": 11, + "xadvance": 14, + "chnl": 15, + "x": 325, + "y": 127, + "page": 0 + }, + { + "id": 117, + "index": 89, + "char": "u", + "width": 21, + "height": 27, + "xoffset": 1, + "yoffset": 12, + "xadvance": 23, + "chnl": 15, + "x": 341, + "y": 127, + "page": 0 + }, + { + "id": 111, + "index": 83, + "char": "o", + "width": 24, + "height": 27, + "xoffset": 0, + "yoffset": 11, + "xadvance": 24, + "chnl": 15, + "x": 349, + "y": 88, + "page": 0 + }, + { + "id": 115, + "index": 87, + "char": "s", + "width": 22, + "height": 27, + "xoffset": 0, + "yoffset": 11, + "xadvance": 22, + "chnl": 15, + "x": 366, + "y": 55, + "page": 0 + }, + { + "id": 99, + "index": 71, + "char": "c", + "width": 23, + "height": 27, + "xoffset": 0, + "yoffset": 11, + "xadvance": 22, + "chnl": 15, + "x": 342, + "y": 155, + "page": 0 + }, + { + "id": 110, + "index": 82, + "char": "n", + "width": 21, + "height": 27, + "xoffset": 1, + "yoffset": 11, + "xadvance": 23, + "chnl": 15, + "x": 363, + "y": 116, + "page": 0 + }, + { + "id": 58, + "index": 30, + "char": ":", + "width": 9, + "height": 27, + "xoffset": 1, + "yoffset": 12, + "xadvance": 10, + "chnl": 15, + "x": 251, + "y": 141, + "page": 0 + }, + { + "id": 126, + "index": 98, + "char": "~", + "width": 27, + "height": 12, + "xoffset": 1, + "yoffset": 18, + "xadvance": 29, + "chnl": 15, + "x": 112, + "y": 490, + "page": 0 + }, + { + "id": 1072, + "index": 963, + "char": "а", + "width": 22, + "height": 27, + "xoffset": 0, + "yoffset": 11, + "xadvance": 23, + "chnl": 15, + "x": 374, + "y": 83, + "page": 0 + }, + { + "id": 1077, + "index": 964, + "char": "е", + "width": 23, + "height": 27, + "xoffset": 0, + "yoffset": 11, + "xadvance": 22, + "chnl": 15, + "x": 368, + "y": 0, + "page": 0 + }, + { + "id": 1079, + "index": 239, + "char": "з", + "width": 21, + "height": 27, + "xoffset": 0, + "yoffset": 11, + "xadvance": 21, + "chnl": 15, + "x": 389, + "y": 28, + "page": 0 + }, + { + "id": 1086, + "index": 966, + "char": "о", + "width": 24, + "height": 27, + "xoffset": 0, + "yoffset": 11, + "xadvance": 24, + "chnl": 15, + "x": 392, + "y": 0, + "page": 0 + }, + { + "id": 1089, + "index": 968, + "char": "с", + "width": 23, + "height": 27, + "xoffset": 0, + "yoffset": 11, + "xadvance": 22, + "chnl": 15, + "x": 317, + "y": 274, + "page": 0 + }, + { + "id": 1101, + "index": 255, + "char": "э", + "width": 22, + "height": 27, + "xoffset": 0, + "yoffset": 11, + "xadvance": 23, + "chnl": 15, + "x": 329, + "y": 237, + "page": 0 + }, + { + "id": 949, + "index": 191, + "char": "ε", + "width": 23, + "height": 27, + "xoffset": 0, + "yoffset": 11, + "xadvance": 23, + "chnl": 15, + "x": 317, + "y": 302, + "page": 0 + }, + { + "id": 964, + "index": 202, + "char": "τ", + "width": 23, + "height": 27, + "xoffset": 0, + "yoffset": 12, + "xadvance": 22, + "chnl": 15, + "x": 341, + "y": 265, + "page": 0 + }, + { + "id": 965, + "index": 203, + "char": "υ", + "width": 22, + "height": 27, + "xoffset": 1, + "yoffset": 12, + "xadvance": 23, + "chnl": 15, + "x": 352, + "y": 237, + "page": 0 + }, + { + "id": 959, + "index": 932, + "char": "ο", + "width": 24, + "height": 27, + "xoffset": 0, + "yoffset": 11, + "xadvance": 24, + "chnl": 15, + "x": 356, + "y": 183, + "page": 0 + }, + { + "id": 945, + "index": 187, + "char": "α", + "width": 25, + "height": 27, + "xoffset": 0, + "yoffset": 11, + "xadvance": 24, + "chnl": 15, + "x": 366, + "y": 144, + "page": 0 + }, + { + "id": 963, + "index": 201, + "char": "σ", + "width": 26, + "height": 27, + "xoffset": 0, + "yoffset": 12, + "xadvance": 24, + "chnl": 15, + "x": 385, + "y": 111, + "page": 0 + }, + { + "id": 122, + "index": 94, + "char": "z", + "width": 22, + "height": 26, + "xoffset": 0, + "yoffset": 12, + "xadvance": 21, + "chnl": 15, + "x": 389, + "y": 56, + "page": 0 + }, + { + "id": 120, + "index": 92, + "char": "x", + "width": 23, + "height": 26, + "xoffset": -1, + "yoffset": 12, + "xadvance": 21, + "chnl": 15, + "x": 397, + "y": 83, + "page": 0 + }, + { + "id": 118, + "index": 90, + "char": "v", + "width": 23, + "height": 26, + "xoffset": -1, + "yoffset": 12, + "xadvance": 20, + "chnl": 15, + "x": 411, + "y": 28, + "page": 0 + }, + { + "id": 43, + "index": 15, + "char": "+", + "width": 24, + "height": 26, + "xoffset": 0, + "yoffset": 9, + "xadvance": 24, + "chnl": 15, + "x": 417, + "y": 0, + "page": 0 + }, + { + "id": 1074, + "index": 235, + "char": "в", + "width": 23, + "height": 26, + "xoffset": 1, + "yoffset": 12, + "xadvance": 24, + "chnl": 15, + "x": 412, + "y": 55, + "page": 0 + }, + { + "id": 1075, + "index": 236, + "char": "г", + "width": 18, + "height": 26, + "xoffset": 1, + "yoffset": 12, + "xadvance": 18, + "chnl": 15, + "x": 368, + "y": 28, + "page": 0 + }, + { + "id": 1080, + "index": 240, + "char": "и", + "width": 22, + "height": 26, + "xoffset": 1, + "yoffset": 12, + "xadvance": 24, + "chnl": 15, + "x": 435, + "y": 27, + "page": 0 + }, + { + "id": 1082, + "index": 241, + "char": "к", + "width": 23, + "height": 26, + "xoffset": 1, + "yoffset": 12, + "xadvance": 23, + "chnl": 15, + "x": 442, + "y": 0, + "page": 0 + }, + { + "id": 1083, + "index": 242, + "char": "л", + "width": 24, + "height": 26, + "xoffset": -1, + "yoffset": 12, + "xadvance": 24, + "chnl": 15, + "x": 466, + "y": 0, + "page": 0 + }, + { + "id": 1085, + "index": 244, + "char": "н", + "width": 22, + "height": 26, + "xoffset": 1, + "yoffset": 12, + "xadvance": 24, + "chnl": 15, + "x": 458, + "y": 27, + "page": 0 + }, + { + "id": 1087, + "index": 245, + "char": "п", + "width": 22, + "height": 26, + "xoffset": 1, + "yoffset": 12, + "xadvance": 24, + "chnl": 15, + "x": 481, + "y": 27, + "page": 0 + }, + { + "id": 1090, + "index": 246, + "char": "т", + "width": 23, + "height": 26, + "xoffset": -1, + "yoffset": 12, + "xadvance": 20, + "chnl": 15, + "x": 341, + "y": 293, + "page": 0 + }, + { + "id": 1093, + "index": 970, + "char": "х", + "width": 23, + "height": 26, + "xoffset": -1, + "yoffset": 12, + "xadvance": 21, + "chnl": 15, + "x": 341, + "y": 320, + "page": 0 + }, + { + "id": 1095, + "index": 249, + "char": "ч", + "width": 22, + "height": 26, + "xoffset": 0, + "yoffset": 12, + "xadvance": 23, + "chnl": 15, + "x": 349, + "y": 347, + "page": 0 + }, + { + "id": 1100, + "index": 254, + "char": "ь", + "width": 22, + "height": 26, + "xoffset": 1, + "yoffset": 12, + "xadvance": 23, + "chnl": 15, + "x": 436, + "y": 54, + "page": 0 + }, + { + "id": 1103, + "index": 257, + "char": "я", + "width": 23, + "height": 26, + "xoffset": -1, + "yoffset": 12, + "xadvance": 23, + "chnl": 15, + "x": 459, + "y": 54, + "page": 0 + }, + { + "id": 953, + "index": 195, + "char": "ι", + "width": 12, + "height": 26, + "xoffset": 2, + "yoffset": 12, + "xadvance": 14, + "chnl": 15, + "x": 350, + "y": 0, + "page": 0 + }, + { + "id": 954, + "index": 931, + "char": "κ", + "width": 23, + "height": 26, + "xoffset": 1, + "yoffset": 12, + "xadvance": 23, + "chnl": 15, + "x": 483, + "y": 54, + "page": 0 + }, + { + "id": 957, + "index": 934, + "char": "ν", + "width": 23, + "height": 26, + "xoffset": -1, + "yoffset": 12, + "xadvance": 20, + "chnl": 15, + "x": 436, + "y": 81, + "page": 0 + }, + { + "id": 8211, + "index": 385, + "char": "–", + "width": 25, + "height": 7, + "xoffset": 1, + "yoffset": 18, + "xadvance": 28, + "chnl": 15, + "x": 64, + "y": 503, + "page": 0 + }, + { + "id": 95, + "index": 67, + "char": "_", + "width": 23, + "height": 7, + "xoffset": -2, + "yoffset": 34, + "xadvance": 19, + "chnl": 15, + "x": 100, + "y": 395, + "page": 0 + }, + { + "id": 42, + "index": 14, + "char": "*", + "width": 21, + "height": 21, + "xoffset": -1, + "yoffset": 4, + "xadvance": 18, + "chnl": 15, + "x": 491, + "y": 0, + "page": 0 + }, + { + "id": 61, + "index": 33, + "char": "=", + "width": 21, + "height": 16, + "xoffset": 1, + "yoffset": 14, + "xadvance": 23, + "chnl": 15, + "x": 113, + "y": 275, + "page": 0 + }, + { + "id": 176, + "index": 113, + "char": "°", + "width": 14, + "height": 15, + "xoffset": 1, + "yoffset": 4, + "xadvance": 16, + "chnl": 15, + "x": 199, + "y": 248, + "page": 0 + }, + { + "id": 45, + "index": 17, + "char": "-", + "width": 14, + "height": 7, + "xoffset": -1, + "yoffset": 20, + "xadvance": 12, + "chnl": 15, + "x": 54, + "y": 346, + "page": 0 + }, + { + "id": 44, + "index": 16, + "char": ",", + "width": 10, + "height": 14, + "xoffset": -1, + "yoffset": 30, + "xadvance": 8, + "chnl": 15, + "x": 184, + "y": 213, + "page": 0 + }, + { + "id": 34, + "index": 6, + "char": "\"", + "width": 12, + "height": 14, + "xoffset": 1, + "yoffset": 3, + "xadvance": 13, + "chnl": 15, + "x": 83, + "y": 203, + "page": 0 + }, + { + "id": 39, + "index": 11, + "char": "'", + "width": 7, + "height": 14, + "xoffset": 0, + "yoffset": 3, + "xadvance": 7, + "chnl": 15, + "x": 140, + "y": 498, + "page": 0 + }, + { + "id": 46, + "index": 18, + "char": ".", + "width": 9, + "height": 9, + "xoffset": 1, + "yoffset": 30, + "xadvance": 11, + "chnl": 15, + "x": 123, + "y": 229, + "page": 0 + } + ], + "info": { + "face": "Roboto-Regular", + "size": 42, + "bold": 0, + "italic": 0, + "charset": [ + "a", + "z", + "e", + "r", + "t", + "y", + "u", + "i", + "o", + "p", + "q", + "s", + "d", + "f", + "g", + "h", + "j", + "k", + "l", + "m", + "w", + "x", + "c", + "v", + "b", + "n", + "A", + "Z", + "E", + "R", + "T", + "Y", + "U", + "I", + "O", + "P", + "Q", + "S", + "D", + "F", + "G", + "H", + "J", + "K", + "L", + "M", + "W", + "X", + "C", + "V", + "B", + "N", + "/", + "\\", + "*", + "-", + "–", + "+", + "7", + "8", + "9", + "4", + "5", + "6", + "1", + "2", + "3", + "0", + ",", + ";", + ":", + "!", + "?", + ".", + "%", + "$", + "£", + "€", + "=", + "{", + "}", + "(", + ")", + "[", + "]", + "&", + "~", + "\"", + "'", + "#", + "_", + "|", + "°", + "@", + "А", + "а", + "Б", + "б", + "В", + "в", + "Г", + "г", + "Д", + "д", + "Е", + "е", + "Ё", + "ё", + "Ж", + "ж", + "З", + "з", + "И", + "и", + "Й", + "й", + "К", + "к", + "Л", + "л", + "М", + "м", + "Н", + "н", + "О", + "о", + "П", + "п", + "Р", + "р", + "С", + "с", + "Т", + "т", + "У", + "у", + "Ф", + "ф", + "Х", + "х", + "Ц", + "ц", + "Ч", + "ч", + "Ш", + "ш", + "Щ", + "щ", + "Ъ", + "ъ", + "Ы", + "ы", + "Ь", + "ь", + "Э", + "э", + "Ю", + "ю", + "Я", + "я", + "ü", + "Ü", + "ö", + "Ö", + "ä", + "Ä", + "ñ", + "Ñ", + "ς", + "ε", + "ρ", + "τ", + "υ", + "θ", + "ι", + "ο", + "π", + "α", + "σ", + "δ", + "φ", + "γ", + "η", + "ξ", + "κ", + "λ", + "ζ", + "χ", + "ψ", + "ω", + "β", + "ν", + "μ", + "Ε", + "Ρ", + "Τ", + "Υ", + "Θ", + "Ι", + "Ο", + "Π", + "Α", + "Σ", + "Δ", + "Φ", + "Γ", + "Η", + "Ξ", + "Κ", + "Λ", + "Ζ", + "Χ", + "Ψ", + "Ω", + "Β", + "Ν", + "Μ", + "å", + "Å", + "æ", + "Æ", + "ø", + "Ø" + ], + "unicode": 1, + "stretchH": 100, + "smooth": 1, + "aa": 1, + "padding": [2, 2, 2, 2], + "spacing": [0, 0] + }, + "common": { + "lineHeight": 44, + "base": 34, + "scaleW": 512, + "scaleH": 512, + "pages": 1, + "packed": 0, + "alphaChnl": 0, + "redChnl": 0, + "greenChnl": 0, + "blueChnl": 0 + }, + "distanceField": {"fieldType": "msdf", "distanceRange": 4}, + "kernings": [ + {"first": 97, "second": 121, "amount": 0}, + {"first": 97, "second": 118, "amount": 0}, + {"first": 97, "second": 34, "amount": -1}, + {"first": 97, "second": 39, "amount": -1}, + {"first": 97, "second": 1090, "amount": 0}, + {"first": 97, "second": 1091, "amount": 0}, + {"first": 97, "second": 947, "amount": 0}, + {"first": 97, "second": 957, "amount": 0}, + {"first": 122, "second": 101, "amount": 0}, + {"first": 122, "second": 111, "amount": 0}, + {"first": 122, "second": 113, "amount": 0}, + {"first": 122, "second": 100, "amount": 0}, + {"first": 122, "second": 103, "amount": 0}, + {"first": 122, "second": 99, "amount": 0}, + {"first": 122, "second": 1077, "amount": 0}, + {"first": 122, "second": 1105, "amount": 0}, + {"first": 122, "second": 1086, "amount": 0}, + {"first": 122, "second": 1089, "amount": 0}, + {"first": 122, "second": 1092, "amount": 0}, + {"first": 122, "second": 246, "amount": 0}, + {"first": 122, "second": 962, "amount": 0}, + {"first": 122, "second": 959, "amount": 0}, + {"first": 122, "second": 945, "amount": 0}, + {"first": 122, "second": 963, "amount": 0}, + {"first": 101, "second": 121, "amount": 0}, + {"first": 101, "second": 118, "amount": 0}, + {"first": 101, "second": 34, "amount": 0}, + {"first": 101, "second": 39, "amount": 0}, + {"first": 101, "second": 1090, "amount": 0}, + {"first": 101, "second": 1091, "amount": 0}, + {"first": 101, "second": 947, "amount": 0}, + {"first": 101, "second": 957, "amount": 0}, + {"first": 114, "second": 97, "amount": -1}, + {"first": 114, "second": 101, "amount": 0}, + {"first": 114, "second": 116, "amount": 1}, + {"first": 114, "second": 121, "amount": 0}, + {"first": 114, "second": 111, "amount": 0}, + {"first": 114, "second": 113, "amount": 0}, + {"first": 114, "second": 100, "amount": 0}, + {"first": 114, "second": 102, "amount": 0}, + {"first": 114, "second": 103, "amount": 0}, + {"first": 114, "second": 119, "amount": 0}, + {"first": 114, "second": 99, "amount": 0}, + {"first": 114, "second": 118, "amount": 0}, + {"first": 114, "second": 44, "amount": -3}, + {"first": 114, "second": 46, "amount": -3}, + {"first": 114, "second": 34, "amount": 0}, + {"first": 114, "second": 39, "amount": 0}, + {"first": 114, "second": 1072, "amount": -1}, + {"first": 114, "second": 1077, "amount": 0}, + {"first": 114, "second": 1105, "amount": 0}, + {"first": 114, "second": 1086, "amount": 0}, + {"first": 114, "second": 1089, "amount": 0}, + {"first": 114, "second": 1091, "amount": 0}, + {"first": 114, "second": 1092, "amount": 0}, + {"first": 114, "second": 246, "amount": 0}, + {"first": 114, "second": 228, "amount": -1}, + {"first": 114, "second": 962, "amount": 0}, + {"first": 114, "second": 959, "amount": 0}, + {"first": 114, "second": 945, "amount": 0}, + {"first": 114, "second": 963, "amount": 0}, + {"first": 114, "second": 947, "amount": 0}, + {"first": 114, "second": 957, "amount": 0}, + {"first": 114, "second": 229, "amount": -1}, + {"first": 116, "second": 111, "amount": 0}, + {"first": 116, "second": 1086, "amount": 0}, + {"first": 116, "second": 246, "amount": 0}, + {"first": 116, "second": 959, "amount": 0}, + {"first": 121, "second": 97, "amount": 0}, + {"first": 121, "second": 101, "amount": 0}, + {"first": 121, "second": 111, "amount": 0}, + {"first": 121, "second": 113, "amount": 0}, + {"first": 121, "second": 100, "amount": 0}, + {"first": 121, "second": 102, "amount": 0}, + {"first": 121, "second": 103, "amount": 0}, + {"first": 121, "second": 99, "amount": 0}, + {"first": 121, "second": 44, "amount": -2}, + {"first": 121, "second": 46, "amount": -2}, + {"first": 121, "second": 34, "amount": 0}, + {"first": 121, "second": 39, "amount": 0}, + {"first": 121, "second": 1072, "amount": 0}, + {"first": 121, "second": 1076, "amount": -1}, + {"first": 121, "second": 1077, "amount": 0}, + {"first": 121, "second": 1105, "amount": 0}, + {"first": 121, "second": 1083, "amount": -1}, + {"first": 121, "second": 1086, "amount": 0}, + {"first": 121, "second": 1089, "amount": 0}, + {"first": 121, "second": 1092, "amount": 0}, + {"first": 121, "second": 246, "amount": 0}, + {"first": 121, "second": 228, "amount": 0}, + {"first": 121, "second": 962, "amount": 0}, + {"first": 121, "second": 961, "amount": 0}, + {"first": 121, "second": 964, "amount": 0}, + {"first": 121, "second": 959, "amount": 0}, + {"first": 121, "second": 960, "amount": 0}, + {"first": 121, "second": 945, "amount": 0}, + {"first": 121, "second": 963, "amount": 0}, + {"first": 121, "second": 948, "amount": 0}, + {"first": 121, "second": 229, "amount": 0}, + {"first": 111, "second": 122, "amount": 0}, + {"first": 111, "second": 121, "amount": 0}, + {"first": 111, "second": 120, "amount": 0}, + {"first": 111, "second": 118, "amount": 0}, + {"first": 111, "second": 34, "amount": -3}, + {"first": 111, "second": 39, "amount": -3}, + {"first": 111, "second": 1076, "amount": -1}, + {"first": 111, "second": 1078, "amount": 0}, + {"first": 111, "second": 1083, "amount": 0}, + {"first": 111, "second": 1090, "amount": 0}, + {"first": 111, "second": 1091, "amount": 0}, + {"first": 111, "second": 1093, "amount": 0}, + {"first": 111, "second": 964, "amount": 0}, + {"first": 111, "second": 947, "amount": 0}, + {"first": 111, "second": 957, "amount": 0}, + {"first": 112, "second": 122, "amount": 0}, + {"first": 112, "second": 121, "amount": 0}, + {"first": 112, "second": 120, "amount": 0}, + {"first": 112, "second": 118, "amount": 0}, + {"first": 112, "second": 34, "amount": -1}, + {"first": 112, "second": 39, "amount": -1}, + {"first": 112, "second": 1076, "amount": 0}, + {"first": 112, "second": 1078, "amount": 0}, + {"first": 112, "second": 1083, "amount": 0}, + {"first": 112, "second": 1090, "amount": -2}, + {"first": 112, "second": 1091, "amount": 0}, + {"first": 112, "second": 1093, "amount": 0}, + {"first": 112, "second": 964, "amount": 0}, + {"first": 112, "second": 947, "amount": 0}, + {"first": 112, "second": 957, "amount": 0}, + {"first": 102, "second": 101, "amount": 0}, + {"first": 102, "second": 113, "amount": 0}, + {"first": 102, "second": 100, "amount": 0}, + {"first": 102, "second": 103, "amount": 0}, + {"first": 102, "second": 99, "amount": 0}, + {"first": 102, "second": 125, "amount": 0}, + {"first": 102, "second": 41, "amount": 0}, + {"first": 102, "second": 93, "amount": 0}, + {"first": 102, "second": 34, "amount": 0}, + {"first": 102, "second": 39, "amount": 0}, + {"first": 102, "second": 1077, "amount": 0}, + {"first": 102, "second": 1105, "amount": 0}, + {"first": 102, "second": 1089, "amount": 0}, + {"first": 102, "second": 1092, "amount": 0}, + {"first": 102, "second": 962, "amount": 0}, + {"first": 102, "second": 945, "amount": 0}, + {"first": 102, "second": 963, "amount": 0}, + {"first": 104, "second": 34, "amount": -2}, + {"first": 104, "second": 39, "amount": -2}, + {"first": 104, "second": 1090, "amount": -1}, + {"first": 107, "second": 101, "amount": 0}, + {"first": 107, "second": 113, "amount": 0}, + {"first": 107, "second": 100, "amount": 0}, + {"first": 107, "second": 103, "amount": 0}, + {"first": 107, "second": 99, "amount": 0}, + {"first": 107, "second": 1077, "amount": 0}, + {"first": 107, "second": 1105, "amount": 0}, + {"first": 107, "second": 1089, "amount": 0}, + {"first": 107, "second": 1092, "amount": 0}, + {"first": 107, "second": 962, "amount": 0}, + {"first": 107, "second": 945, "amount": 0}, + {"first": 107, "second": 963, "amount": 0}, + {"first": 109, "second": 34, "amount": -2}, + {"first": 109, "second": 39, "amount": -2}, + {"first": 109, "second": 1090, "amount": -1}, + {"first": 119, "second": 44, "amount": -3}, + {"first": 119, "second": 46, "amount": -3}, + {"first": 120, "second": 101, "amount": 0}, + {"first": 120, "second": 111, "amount": 0}, + {"first": 120, "second": 113, "amount": 0}, + {"first": 120, "second": 100, "amount": 0}, + {"first": 120, "second": 103, "amount": 0}, + {"first": 120, "second": 99, "amount": 0}, + {"first": 120, "second": 1077, "amount": 0}, + {"first": 120, "second": 1105, "amount": 0}, + {"first": 120, "second": 1086, "amount": 0}, + {"first": 120, "second": 1089, "amount": 0}, + {"first": 120, "second": 1092, "amount": 0}, + {"first": 120, "second": 246, "amount": 0}, + {"first": 120, "second": 962, "amount": 0}, + {"first": 120, "second": 959, "amount": 0}, + {"first": 120, "second": 945, "amount": 0}, + {"first": 120, "second": 963, "amount": 0}, + {"first": 99, "second": 34, "amount": 0}, + {"first": 99, "second": 39, "amount": 0}, + {"first": 118, "second": 97, "amount": 0}, + {"first": 118, "second": 101, "amount": 0}, + {"first": 118, "second": 111, "amount": 0}, + {"first": 118, "second": 113, "amount": 0}, + {"first": 118, "second": 100, "amount": 0}, + {"first": 118, "second": 102, "amount": 0}, + {"first": 118, "second": 103, "amount": 0}, + {"first": 118, "second": 99, "amount": 0}, + {"first": 118, "second": 44, "amount": -2}, + {"first": 118, "second": 46, "amount": -2}, + {"first": 118, "second": 34, "amount": 0}, + {"first": 118, "second": 39, "amount": 0}, + {"first": 118, "second": 1072, "amount": 0}, + {"first": 118, "second": 1076, "amount": -1}, + {"first": 118, "second": 1077, "amount": 0}, + {"first": 118, "second": 1105, "amount": 0}, + {"first": 118, "second": 1083, "amount": -1}, + {"first": 118, "second": 1086, "amount": 0}, + {"first": 118, "second": 1089, "amount": 0}, + {"first": 118, "second": 1092, "amount": 0}, + {"first": 118, "second": 246, "amount": 0}, + {"first": 118, "second": 228, "amount": 0}, + {"first": 118, "second": 962, "amount": 0}, + {"first": 118, "second": 961, "amount": 0}, + {"first": 118, "second": 964, "amount": 0}, + {"first": 118, "second": 959, "amount": 0}, + {"first": 118, "second": 960, "amount": 0}, + {"first": 118, "second": 945, "amount": 0}, + {"first": 118, "second": 963, "amount": 0}, + {"first": 118, "second": 948, "amount": 0}, + {"first": 118, "second": 229, "amount": 0}, + {"first": 98, "second": 122, "amount": 0}, + {"first": 98, "second": 121, "amount": 0}, + {"first": 98, "second": 120, "amount": 0}, + {"first": 98, "second": 118, "amount": 0}, + {"first": 98, "second": 34, "amount": -1}, + {"first": 98, "second": 39, "amount": -1}, + {"first": 98, "second": 1076, "amount": 0}, + {"first": 98, "second": 1078, "amount": 0}, + {"first": 98, "second": 1083, "amount": 0}, + {"first": 98, "second": 1090, "amount": -2}, + {"first": 98, "second": 1091, "amount": 0}, + {"first": 98, "second": 1093, "amount": 0}, + {"first": 98, "second": 964, "amount": 0}, + {"first": 98, "second": 947, "amount": 0}, + {"first": 98, "second": 957, "amount": 0}, + {"first": 110, "second": 34, "amount": -2}, + {"first": 110, "second": 39, "amount": -2}, + {"first": 110, "second": 1090, "amount": -1}, + {"first": 65, "second": 122, "amount": 0}, + {"first": 65, "second": 116, "amount": 0}, + {"first": 65, "second": 121, "amount": -1}, + {"first": 65, "second": 117, "amount": 0}, + {"first": 65, "second": 111, "amount": 0}, + {"first": 65, "second": 119, "amount": -1}, + {"first": 65, "second": 118, "amount": -1}, + {"first": 65, "second": 84, "amount": -3}, + {"first": 65, "second": 89, "amount": -2}, + {"first": 65, "second": 85, "amount": 0}, + {"first": 65, "second": 79, "amount": 0}, + {"first": 65, "second": 81, "amount": 0}, + {"first": 65, "second": 71, "amount": 0}, + {"first": 65, "second": 87, "amount": -1}, + {"first": 65, "second": 67, "amount": 0}, + {"first": 65, "second": 86, "amount": -2}, + {"first": 65, "second": 63, "amount": -1}, + {"first": 65, "second": 34, "amount": -2}, + {"first": 65, "second": 39, "amount": -2}, + {"first": 65, "second": 1044, "amount": 0}, + {"first": 65, "second": 1051, "amount": 0}, + {"first": 65, "second": 1083, "amount": 0}, + {"first": 65, "second": 1054, "amount": 0}, + {"first": 65, "second": 1086, "amount": 0}, + {"first": 65, "second": 1057, "amount": 0}, + {"first": 65, "second": 1058, "amount": -3}, + {"first": 65, "second": 1090, "amount": -1}, + {"first": 65, "second": 1091, "amount": -1}, + {"first": 65, "second": 1063, "amount": -1}, + {"first": 65, "second": 1095, "amount": -2}, + {"first": 65, "second": 1068, "amount": -1}, + {"first": 65, "second": 252, "amount": 0}, + {"first": 65, "second": 220, "amount": 0}, + {"first": 65, "second": 246, "amount": 0}, + {"first": 65, "second": 214, "amount": 0}, + {"first": 65, "second": 964, "amount": -1}, + {"first": 65, "second": 965, "amount": 0}, + {"first": 65, "second": 959, "amount": 0}, + {"first": 65, "second": 947, "amount": -1}, + {"first": 65, "second": 955, "amount": 0}, + {"first": 65, "second": 957, "amount": -1}, + {"first": 65, "second": 933, "amount": -2}, + {"first": 65, "second": 920, "amount": 0}, + {"first": 65, "second": 927, "amount": 0}, + {"first": 65, "second": 934, "amount": -1}, + {"first": 65, "second": 936, "amount": -1}, + {"first": 65, "second": 216, "amount": 0}, + {"first": 90, "second": 101, "amount": 0}, + {"first": 90, "second": 121, "amount": -1}, + {"first": 90, "second": 117, "amount": 0}, + {"first": 90, "second": 111, "amount": 0}, + {"first": 90, "second": 113, "amount": 0}, + {"first": 90, "second": 100, "amount": 0}, + {"first": 90, "second": 103, "amount": 0}, + {"first": 90, "second": 119, "amount": -1}, + {"first": 90, "second": 99, "amount": 0}, + {"first": 90, "second": 118, "amount": -1}, + {"first": 90, "second": 65, "amount": 0}, + {"first": 90, "second": 79, "amount": -1}, + {"first": 90, "second": 81, "amount": -1}, + {"first": 90, "second": 71, "amount": -1}, + {"first": 90, "second": 67, "amount": -1}, + {"first": 90, "second": 1040, "amount": 0}, + {"first": 90, "second": 1077, "amount": 0}, + {"first": 90, "second": 1105, "amount": 0}, + {"first": 90, "second": 1054, "amount": -1}, + {"first": 90, "second": 1086, "amount": 0}, + {"first": 90, "second": 1057, "amount": -1}, + {"first": 90, "second": 1089, "amount": 0}, + {"first": 90, "second": 1091, "amount": -1}, + {"first": 90, "second": 1092, "amount": 0}, + {"first": 90, "second": 252, "amount": 0}, + {"first": 90, "second": 246, "amount": 0}, + {"first": 90, "second": 214, "amount": -1}, + {"first": 90, "second": 196, "amount": 0}, + {"first": 90, "second": 962, "amount": 0}, + {"first": 90, "second": 965, "amount": 0}, + {"first": 90, "second": 959, "amount": 0}, + {"first": 90, "second": 945, "amount": 0}, + {"first": 90, "second": 963, "amount": 0}, + {"first": 90, "second": 947, "amount": -1}, + {"first": 90, "second": 968, "amount": -1}, + {"first": 90, "second": 957, "amount": -1}, + {"first": 90, "second": 920, "amount": -1}, + {"first": 90, "second": 927, "amount": -1}, + {"first": 90, "second": 913, "amount": 0}, + {"first": 90, "second": 916, "amount": 0}, + {"first": 90, "second": 934, "amount": -1}, + {"first": 90, "second": 923, "amount": 0}, + {"first": 90, "second": 197, "amount": 0}, + {"first": 90, "second": 216, "amount": -1}, + {"first": 69, "second": 101, "amount": 0}, + {"first": 69, "second": 121, "amount": -1}, + {"first": 69, "second": 117, "amount": 0}, + {"first": 69, "second": 111, "amount": 0}, + {"first": 69, "second": 113, "amount": 0}, + {"first": 69, "second": 100, "amount": 0}, + {"first": 69, "second": 102, "amount": 0}, + {"first": 69, "second": 103, "amount": 0}, + {"first": 69, "second": 119, "amount": 0}, + {"first": 69, "second": 99, "amount": 0}, + {"first": 69, "second": 118, "amount": -1}, + {"first": 69, "second": 84, "amount": 0}, + {"first": 69, "second": 1077, "amount": 0}, + {"first": 69, "second": 1105, "amount": 0}, + {"first": 69, "second": 1086, "amount": 0}, + {"first": 69, "second": 1089, "amount": 0}, + {"first": 69, "second": 1058, "amount": 0}, + {"first": 69, "second": 1091, "amount": -1}, + {"first": 69, "second": 1092, "amount": 0}, + {"first": 69, "second": 252, "amount": 0}, + {"first": 69, "second": 246, "amount": 0}, + {"first": 69, "second": 962, "amount": 0}, + {"first": 69, "second": 965, "amount": 0}, + {"first": 69, "second": 959, "amount": 0}, + {"first": 69, "second": 945, "amount": 0}, + {"first": 69, "second": 963, "amount": 0}, + {"first": 69, "second": 947, "amount": -1}, + {"first": 69, "second": 957, "amount": -1}, + {"first": 82, "second": 84, "amount": -2}, + {"first": 82, "second": 89, "amount": -1}, + {"first": 82, "second": 86, "amount": 0}, + {"first": 82, "second": 1058, "amount": -2}, + {"first": 82, "second": 933, "amount": -1}, + {"first": 84, "second": 97, "amount": -2}, + {"first": 84, "second": 122, "amount": -1}, + {"first": 84, "second": 101, "amount": -2}, + {"first": 84, "second": 114, "amount": -2}, + {"first": 84, "second": 121, "amount": -1}, + {"first": 84, "second": 117, "amount": -2}, + {"first": 84, "second": 111, "amount": -2}, + {"first": 84, "second": 112, "amount": -2}, + {"first": 84, "second": 113, "amount": -2}, + {"first": 84, "second": 115, "amount": -2}, + {"first": 84, "second": 100, "amount": -2}, + {"first": 84, "second": 103, "amount": -2}, + {"first": 84, "second": 109, "amount": -2}, + {"first": 84, "second": 119, "amount": -1}, + {"first": 84, "second": 120, "amount": -2}, + {"first": 84, "second": 99, "amount": -2}, + {"first": 84, "second": 118, "amount": -1}, + {"first": 84, "second": 110, "amount": -2}, + {"first": 84, "second": 65, "amount": -2}, + {"first": 84, "second": 84, "amount": 0}, + {"first": 84, "second": 89, "amount": 0}, + {"first": 84, "second": 79, "amount": -1}, + {"first": 84, "second": 81, "amount": -1}, + {"first": 84, "second": 83, "amount": 0}, + {"first": 84, "second": 71, "amount": -1}, + {"first": 84, "second": 74, "amount": -5}, + {"first": 84, "second": 87, "amount": 0}, + {"first": 84, "second": 67, "amount": -1}, + {"first": 84, "second": 86, "amount": 0}, + {"first": 84, "second": 45, "amount": -5}, + {"first": 84, "second": 8211, "amount": -5}, + {"first": 84, "second": 44, "amount": -4}, + {"first": 84, "second": 46, "amount": -4}, + {"first": 84, "second": 1040, "amount": -2}, + {"first": 84, "second": 1072, "amount": -2}, + {"first": 84, "second": 1073, "amount": -1}, + {"first": 84, "second": 1074, "amount": -2}, + {"first": 84, "second": 1075, "amount": -2}, + {"first": 84, "second": 1044, "amount": -2}, + {"first": 84, "second": 1076, "amount": -3}, + {"first": 84, "second": 1077, "amount": -2}, + {"first": 84, "second": 1105, "amount": -2}, + {"first": 84, "second": 1078, "amount": -2}, + {"first": 84, "second": 1079, "amount": -3}, + {"first": 84, "second": 1080, "amount": -2}, + {"first": 84, "second": 1081, "amount": -2}, + {"first": 84, "second": 1082, "amount": -2}, + {"first": 84, "second": 1051, "amount": -1}, + {"first": 84, "second": 1083, "amount": -3}, + {"first": 84, "second": 1084, "amount": -2}, + {"first": 84, "second": 1085, "amount": -2}, + {"first": 84, "second": 1054, "amount": -1}, + {"first": 84, "second": 1086, "amount": -2}, + {"first": 84, "second": 1087, "amount": -2}, + {"first": 84, "second": 1088, "amount": -2}, + {"first": 84, "second": 1057, "amount": -1}, + {"first": 84, "second": 1089, "amount": -2}, + {"first": 84, "second": 1058, "amount": 0}, + {"first": 84, "second": 1090, "amount": -2}, + {"first": 84, "second": 1091, "amount": -1}, + {"first": 84, "second": 1092, "amount": -2}, + {"first": 84, "second": 1093, "amount": -2}, + {"first": 84, "second": 1094, "amount": -2}, + {"first": 84, "second": 1095, "amount": -3}, + {"first": 84, "second": 1096, "amount": -2}, + {"first": 84, "second": 1097, "amount": -2}, + {"first": 84, "second": 1099, "amount": -3}, + {"first": 84, "second": 1068, "amount": 0}, + {"first": 84, "second": 1100, "amount": -2}, + {"first": 84, "second": 1101, "amount": -3}, + {"first": 84, "second": 1102, "amount": -2}, + {"first": 84, "second": 1103, "amount": -3}, + {"first": 84, "second": 252, "amount": -2}, + {"first": 84, "second": 246, "amount": -2}, + {"first": 84, "second": 214, "amount": -1}, + {"first": 84, "second": 228, "amount": -2}, + {"first": 84, "second": 196, "amount": -2}, + {"first": 84, "second": 241, "amount": -2}, + {"first": 84, "second": 962, "amount": -2}, + {"first": 84, "second": 949, "amount": -3}, + {"first": 84, "second": 961, "amount": -3}, + {"first": 84, "second": 964, "amount": -2}, + {"first": 84, "second": 965, "amount": -2}, + {"first": 84, "second": 953, "amount": -3}, + {"first": 84, "second": 959, "amount": -2}, + {"first": 84, "second": 960, "amount": -2}, + {"first": 84, "second": 945, "amount": -2}, + {"first": 84, "second": 963, "amount": -2}, + {"first": 84, "second": 948, "amount": -1}, + {"first": 84, "second": 966, "amount": -3}, + {"first": 84, "second": 947, "amount": -1}, + {"first": 84, "second": 951, "amount": -2}, + {"first": 84, "second": 968, "amount": -3}, + {"first": 84, "second": 969, "amount": -3}, + {"first": 84, "second": 957, "amount": -1}, + {"first": 84, "second": 933, "amount": 0}, + {"first": 84, "second": 920, "amount": -1}, + {"first": 84, "second": 927, "amount": -1}, + {"first": 84, "second": 913, "amount": -2}, + {"first": 84, "second": 916, "amount": -2}, + {"first": 84, "second": 934, "amount": -2}, + {"first": 84, "second": 923, "amount": -2}, + {"first": 84, "second": 229, "amount": -2}, + {"first": 84, "second": 197, "amount": -2}, + {"first": 84, "second": 230, "amount": -2}, + {"first": 84, "second": 198, "amount": -4}, + {"first": 84, "second": 248, "amount": -2}, + {"first": 84, "second": 216, "amount": -1}, + {"first": 89, "second": 97, "amount": -1}, + {"first": 89, "second": 122, "amount": -1}, + {"first": 89, "second": 101, "amount": -1}, + {"first": 89, "second": 114, "amount": -1}, + {"first": 89, "second": 116, "amount": 0}, + {"first": 89, "second": 121, "amount": 0}, + {"first": 89, "second": 117, "amount": -1}, + {"first": 89, "second": 111, "amount": -1}, + {"first": 89, "second": 112, "amount": -1}, + {"first": 89, "second": 113, "amount": -1}, + {"first": 89, "second": 115, "amount": -1}, + {"first": 89, "second": 100, "amount": -1}, + {"first": 89, "second": 102, "amount": 0}, + {"first": 89, "second": 103, "amount": -1}, + {"first": 89, "second": 109, "amount": -1}, + {"first": 89, "second": 120, "amount": 0}, + {"first": 89, "second": 99, "amount": -1}, + {"first": 89, "second": 118, "amount": 0}, + {"first": 89, "second": 110, "amount": -1}, + {"first": 89, "second": 65, "amount": -2}, + {"first": 89, "second": 84, "amount": 0}, + {"first": 89, "second": 89, "amount": 0}, + {"first": 89, "second": 85, "amount": -2}, + {"first": 89, "second": 79, "amount": -1}, + {"first": 89, "second": 81, "amount": -1}, + {"first": 89, "second": 83, "amount": 0}, + {"first": 89, "second": 71, "amount": -1}, + {"first": 89, "second": 74, "amount": -2}, + {"first": 89, "second": 87, "amount": 0}, + {"first": 89, "second": 88, "amount": 0}, + {"first": 89, "second": 67, "amount": -1}, + {"first": 89, "second": 86, "amount": 0}, + {"first": 89, "second": 42, "amount": -1}, + {"first": 89, "second": 45, "amount": -1}, + {"first": 89, "second": 8211, "amount": -1}, + {"first": 89, "second": 44, "amount": -4}, + {"first": 89, "second": 46, "amount": -4}, + {"first": 89, "second": 125, "amount": 0}, + {"first": 89, "second": 41, "amount": 0}, + {"first": 89, "second": 93, "amount": 0}, + {"first": 89, "second": 38, "amount": -1}, + {"first": 89, "second": 1040, "amount": -2}, + {"first": 89, "second": 1072, "amount": -1}, + {"first": 89, "second": 1075, "amount": -1}, + {"first": 89, "second": 1077, "amount": -1}, + {"first": 89, "second": 1105, "amount": -1}, + {"first": 89, "second": 1046, "amount": 0}, + {"first": 89, "second": 1078, "amount": 0}, + {"first": 89, "second": 1080, "amount": -1}, + {"first": 89, "second": 1081, "amount": -1}, + {"first": 89, "second": 1082, "amount": -1}, + {"first": 89, "second": 1084, "amount": -1}, + {"first": 89, "second": 1085, "amount": -1}, + {"first": 89, "second": 1054, "amount": -1}, + {"first": 89, "second": 1086, "amount": -1}, + {"first": 89, "second": 1087, "amount": -1}, + {"first": 89, "second": 1088, "amount": -1}, + {"first": 89, "second": 1057, "amount": -1}, + {"first": 89, "second": 1089, "amount": -1}, + {"first": 89, "second": 1058, "amount": 0}, + {"first": 89, "second": 1091, "amount": 0}, + {"first": 89, "second": 1092, "amount": -1}, + {"first": 89, "second": 1061, "amount": 0}, + {"first": 89, "second": 1093, "amount": 0}, + {"first": 89, "second": 1094, "amount": -1}, + {"first": 89, "second": 1096, "amount": -1}, + {"first": 89, "second": 1097, "amount": -1}, + {"first": 89, "second": 1100, "amount": -1}, + {"first": 89, "second": 1102, "amount": -1}, + {"first": 89, "second": 252, "amount": -1}, + {"first": 89, "second": 220, "amount": -2}, + {"first": 89, "second": 246, "amount": -1}, + {"first": 89, "second": 214, "amount": -1}, + {"first": 89, "second": 228, "amount": -1}, + {"first": 89, "second": 196, "amount": -2}, + {"first": 89, "second": 241, "amount": -1}, + {"first": 89, "second": 962, "amount": -1}, + {"first": 89, "second": 949, "amount": -1}, + {"first": 89, "second": 961, "amount": -1}, + {"first": 89, "second": 964, "amount": 0}, + {"first": 89, "second": 965, "amount": -1}, + {"first": 89, "second": 952, "amount": 0}, + {"first": 89, "second": 953, "amount": -1}, + {"first": 89, "second": 959, "amount": -1}, + {"first": 89, "second": 960, "amount": 0}, + {"first": 89, "second": 945, "amount": -1}, + {"first": 89, "second": 963, "amount": -1}, + {"first": 89, "second": 948, "amount": 0}, + {"first": 89, "second": 966, "amount": -1}, + {"first": 89, "second": 947, "amount": 0}, + {"first": 89, "second": 951, "amount": -1}, + {"first": 89, "second": 950, "amount": 0}, + {"first": 89, "second": 968, "amount": -1}, + {"first": 89, "second": 969, "amount": -1}, + {"first": 89, "second": 946, "amount": 0}, + {"first": 89, "second": 957, "amount": 0}, + {"first": 89, "second": 933, "amount": 0}, + {"first": 89, "second": 920, "amount": -1}, + {"first": 89, "second": 927, "amount": -1}, + {"first": 89, "second": 913, "amount": -2}, + {"first": 89, "second": 916, "amount": -2}, + {"first": 89, "second": 934, "amount": -1}, + {"first": 89, "second": 923, "amount": -2}, + {"first": 89, "second": 935, "amount": 0}, + {"first": 89, "second": 229, "amount": -1}, + {"first": 89, "second": 197, "amount": -2}, + {"first": 89, "second": 230, "amount": -1}, + {"first": 89, "second": 198, "amount": -2}, + {"first": 89, "second": 248, "amount": -1}, + {"first": 89, "second": 216, "amount": -1}, + {"first": 85, "second": 65, "amount": 0}, + {"first": 85, "second": 1040, "amount": 0}, + {"first": 85, "second": 196, "amount": 0}, + {"first": 85, "second": 913, "amount": 0}, + {"first": 85, "second": 916, "amount": 0}, + {"first": 85, "second": 923, "amount": 0}, + {"first": 85, "second": 197, "amount": 0}, + {"first": 73, "second": 65, "amount": 0}, + {"first": 73, "second": 84, "amount": -1}, + {"first": 73, "second": 89, "amount": -1}, + {"first": 73, "second": 88, "amount": 0}, + {"first": 73, "second": 1040, "amount": 0}, + {"first": 73, "second": 1044, "amount": 0}, + {"first": 73, "second": 1076, "amount": 0}, + {"first": 73, "second": 1046, "amount": 0}, + {"first": 73, "second": 1051, "amount": 0}, + {"first": 73, "second": 1083, "amount": 0}, + {"first": 73, "second": 1058, "amount": -1}, + {"first": 73, "second": 1061, "amount": 0}, + {"first": 73, "second": 1063, "amount": -1}, + {"first": 73, "second": 1095, "amount": -1}, + {"first": 73, "second": 196, "amount": 0}, + {"first": 73, "second": 933, "amount": -1}, + {"first": 73, "second": 913, "amount": 0}, + {"first": 73, "second": 916, "amount": 0}, + {"first": 73, "second": 923, "amount": 0}, + {"first": 73, "second": 935, "amount": 0}, + {"first": 73, "second": 197, "amount": 0}, + {"first": 79, "second": 65, "amount": 0}, + {"first": 79, "second": 90, "amount": 0}, + {"first": 79, "second": 84, "amount": -1}, + {"first": 79, "second": 89, "amount": -1}, + {"first": 79, "second": 88, "amount": 0}, + {"first": 79, "second": 86, "amount": 0}, + {"first": 79, "second": 44, "amount": -2}, + {"first": 79, "second": 46, "amount": -2}, + {"first": 79, "second": 1040, "amount": 0}, + {"first": 79, "second": 1044, "amount": -1}, + {"first": 79, "second": 1046, "amount": 0}, + {"first": 79, "second": 1051, "amount": -1}, + {"first": 79, "second": 1058, "amount": -1}, + {"first": 79, "second": 1061, "amount": 0}, + {"first": 79, "second": 1068, "amount": -1}, + {"first": 79, "second": 196, "amount": 0}, + {"first": 79, "second": 955, "amount": 0}, + {"first": 79, "second": 933, "amount": -1}, + {"first": 79, "second": 913, "amount": 0}, + {"first": 79, "second": 931, "amount": 0}, + {"first": 79, "second": 916, "amount": 0}, + {"first": 79, "second": 926, "amount": 0}, + {"first": 79, "second": 923, "amount": 0}, + {"first": 79, "second": 918, "amount": 0}, + {"first": 79, "second": 935, "amount": 0}, + {"first": 79, "second": 197, "amount": 0}, + {"first": 79, "second": 198, "amount": -1}, + {"first": 80, "second": 97, "amount": 0}, + {"first": 80, "second": 101, "amount": 0}, + {"first": 80, "second": 116, "amount": 0}, + {"first": 80, "second": 121, "amount": 0}, + {"first": 80, "second": 111, "amount": 0}, + {"first": 80, "second": 113, "amount": 0}, + {"first": 80, "second": 100, "amount": 0}, + {"first": 80, "second": 103, "amount": 0}, + {"first": 80, "second": 99, "amount": 0}, + {"first": 80, "second": 118, "amount": 0}, + {"first": 80, "second": 65, "amount": -3}, + {"first": 80, "second": 90, "amount": -1}, + {"first": 80, "second": 74, "amount": -4}, + {"first": 80, "second": 88, "amount": -1}, + {"first": 80, "second": 44, "amount": -7}, + {"first": 80, "second": 46, "amount": -7}, + {"first": 80, "second": 1040, "amount": -3}, + {"first": 80, "second": 1072, "amount": 0}, + {"first": 80, "second": 1044, "amount": -2}, + {"first": 80, "second": 1076, "amount": -1}, + {"first": 80, "second": 1077, "amount": 0}, + {"first": 80, "second": 1105, "amount": 0}, + {"first": 80, "second": 1046, "amount": -1}, + {"first": 80, "second": 1051, "amount": -1}, + {"first": 80, "second": 1083, "amount": -1}, + {"first": 80, "second": 1086, "amount": 0}, + {"first": 80, "second": 1089, "amount": 0}, + {"first": 80, "second": 1091, "amount": 0}, + {"first": 80, "second": 1092, "amount": 0}, + {"first": 80, "second": 1061, "amount": -1}, + {"first": 80, "second": 246, "amount": 0}, + {"first": 80, "second": 228, "amount": 0}, + {"first": 80, "second": 196, "amount": -3}, + {"first": 80, "second": 962, "amount": 0}, + {"first": 80, "second": 961, "amount": -1}, + {"first": 80, "second": 959, "amount": 0}, + {"first": 80, "second": 945, "amount": 0}, + {"first": 80, "second": 963, "amount": 0}, + {"first": 80, "second": 948, "amount": 0}, + {"first": 80, "second": 947, "amount": 0}, + {"first": 80, "second": 955, "amount": -1}, + {"first": 80, "second": 957, "amount": 0}, + {"first": 80, "second": 913, "amount": -3}, + {"first": 80, "second": 916, "amount": -3}, + {"first": 80, "second": 923, "amount": -3}, + {"first": 80, "second": 918, "amount": -1}, + {"first": 80, "second": 935, "amount": -1}, + {"first": 80, "second": 229, "amount": 0}, + {"first": 80, "second": 197, "amount": -3}, + {"first": 80, "second": 198, "amount": -2}, + {"first": 81, "second": 84, "amount": -1}, + {"first": 81, "second": 89, "amount": -1}, + {"first": 81, "second": 87, "amount": 0}, + {"first": 81, "second": 86, "amount": -1}, + {"first": 81, "second": 1058, "amount": -1}, + {"first": 81, "second": 933, "amount": -1}, + {"first": 68, "second": 65, "amount": 0}, + {"first": 68, "second": 90, "amount": 0}, + {"first": 68, "second": 84, "amount": -1}, + {"first": 68, "second": 89, "amount": -1}, + {"first": 68, "second": 88, "amount": 0}, + {"first": 68, "second": 86, "amount": 0}, + {"first": 68, "second": 44, "amount": -2}, + {"first": 68, "second": 46, "amount": -2}, + {"first": 68, "second": 1040, "amount": 0}, + {"first": 68, "second": 1044, "amount": -1}, + {"first": 68, "second": 1046, "amount": 0}, + {"first": 68, "second": 1051, "amount": -1}, + {"first": 68, "second": 1058, "amount": -1}, + {"first": 68, "second": 1061, "amount": 0}, + {"first": 68, "second": 1068, "amount": -1}, + {"first": 68, "second": 196, "amount": 0}, + {"first": 68, "second": 955, "amount": 0}, + {"first": 68, "second": 933, "amount": -1}, + {"first": 68, "second": 913, "amount": 0}, + {"first": 68, "second": 931, "amount": 0}, + {"first": 68, "second": 916, "amount": 0}, + {"first": 68, "second": 926, "amount": 0}, + {"first": 68, "second": 923, "amount": 0}, + {"first": 68, "second": 918, "amount": 0}, + {"first": 68, "second": 935, "amount": 0}, + {"first": 68, "second": 197, "amount": 0}, + {"first": 68, "second": 198, "amount": -1}, + {"first": 70, "second": 97, "amount": -1}, + {"first": 70, "second": 101, "amount": 0}, + {"first": 70, "second": 114, "amount": -1}, + {"first": 70, "second": 121, "amount": 0}, + {"first": 70, "second": 117, "amount": 0}, + {"first": 70, "second": 111, "amount": 0}, + {"first": 70, "second": 113, "amount": 0}, + {"first": 70, "second": 100, "amount": 0}, + {"first": 70, "second": 103, "amount": 0}, + {"first": 70, "second": 99, "amount": 0}, + {"first": 70, "second": 118, "amount": 0}, + {"first": 70, "second": 65, "amount": -3}, + {"first": 70, "second": 84, "amount": 0}, + {"first": 70, "second": 74, "amount": -5}, + {"first": 70, "second": 44, "amount": -5}, + {"first": 70, "second": 46, "amount": -5}, + {"first": 70, "second": 1040, "amount": -3}, + {"first": 70, "second": 1072, "amount": -1}, + {"first": 70, "second": 1077, "amount": 0}, + {"first": 70, "second": 1105, "amount": 0}, + {"first": 70, "second": 1086, "amount": 0}, + {"first": 70, "second": 1089, "amount": 0}, + {"first": 70, "second": 1058, "amount": 0}, + {"first": 70, "second": 1091, "amount": 0}, + {"first": 70, "second": 1092, "amount": 0}, + {"first": 70, "second": 252, "amount": 0}, + {"first": 70, "second": 246, "amount": 0}, + {"first": 70, "second": 228, "amount": -1}, + {"first": 70, "second": 196, "amount": -3}, + {"first": 70, "second": 962, "amount": 0}, + {"first": 70, "second": 965, "amount": 0}, + {"first": 70, "second": 959, "amount": 0}, + {"first": 70, "second": 945, "amount": 0}, + {"first": 70, "second": 963, "amount": 0}, + {"first": 70, "second": 947, "amount": 0}, + {"first": 70, "second": 957, "amount": 0}, + {"first": 70, "second": 913, "amount": -3}, + {"first": 70, "second": 916, "amount": -3}, + {"first": 70, "second": 923, "amount": -3}, + {"first": 70, "second": 229, "amount": -1}, + {"first": 70, "second": 197, "amount": -3}, + {"first": 72, "second": 65, "amount": 0}, + {"first": 72, "second": 84, "amount": -1}, + {"first": 72, "second": 89, "amount": -1}, + {"first": 72, "second": 88, "amount": 0}, + {"first": 72, "second": 1040, "amount": 0}, + {"first": 72, "second": 1044, "amount": 0}, + {"first": 72, "second": 1076, "amount": 0}, + {"first": 72, "second": 1046, "amount": 0}, + {"first": 72, "second": 1051, "amount": 0}, + {"first": 72, "second": 1083, "amount": 0}, + {"first": 72, "second": 1058, "amount": -1}, + {"first": 72, "second": 1061, "amount": 0}, + {"first": 72, "second": 1063, "amount": -1}, + {"first": 72, "second": 1095, "amount": -1}, + {"first": 72, "second": 196, "amount": 0}, + {"first": 72, "second": 933, "amount": -1}, + {"first": 72, "second": 913, "amount": 0}, + {"first": 72, "second": 916, "amount": 0}, + {"first": 72, "second": 923, "amount": 0}, + {"first": 72, "second": 935, "amount": 0}, + {"first": 72, "second": 197, "amount": 0}, + {"first": 74, "second": 65, "amount": 0}, + {"first": 74, "second": 1040, "amount": 0}, + {"first": 74, "second": 196, "amount": 0}, + {"first": 74, "second": 913, "amount": 0}, + {"first": 74, "second": 916, "amount": 0}, + {"first": 74, "second": 923, "amount": 0}, + {"first": 74, "second": 197, "amount": 0}, + {"first": 75, "second": 101, "amount": -1}, + {"first": 75, "second": 121, "amount": -1}, + {"first": 75, "second": 117, "amount": 0}, + {"first": 75, "second": 111, "amount": -1}, + {"first": 75, "second": 112, "amount": 0}, + {"first": 75, "second": 113, "amount": -1}, + {"first": 75, "second": 100, "amount": -1}, + {"first": 75, "second": 103, "amount": -1}, + {"first": 75, "second": 109, "amount": 0}, + {"first": 75, "second": 119, "amount": -1}, + {"first": 75, "second": 99, "amount": -1}, + {"first": 75, "second": 118, "amount": -1}, + {"first": 75, "second": 110, "amount": 0}, + {"first": 75, "second": 79, "amount": -1}, + {"first": 75, "second": 81, "amount": -1}, + {"first": 75, "second": 71, "amount": -1}, + {"first": 75, "second": 67, "amount": -1}, + {"first": 75, "second": 45, "amount": -1}, + {"first": 75, "second": 8211, "amount": -1}, + {"first": 75, "second": 1073, "amount": -1}, + {"first": 75, "second": 1075, "amount": 0}, + {"first": 75, "second": 1077, "amount": -1}, + {"first": 75, "second": 1105, "amount": -1}, + {"first": 75, "second": 1080, "amount": 0}, + {"first": 75, "second": 1081, "amount": 0}, + {"first": 75, "second": 1082, "amount": 0}, + {"first": 75, "second": 1084, "amount": 0}, + {"first": 75, "second": 1085, "amount": 0}, + {"first": 75, "second": 1054, "amount": -1}, + {"first": 75, "second": 1086, "amount": -1}, + {"first": 75, "second": 1087, "amount": 0}, + {"first": 75, "second": 1088, "amount": 0}, + {"first": 75, "second": 1057, "amount": -1}, + {"first": 75, "second": 1089, "amount": -1}, + {"first": 75, "second": 1090, "amount": -1}, + {"first": 75, "second": 1091, "amount": -1}, + {"first": 75, "second": 1092, "amount": -1}, + {"first": 75, "second": 1094, "amount": 0}, + {"first": 75, "second": 1095, "amount": -2}, + {"first": 75, "second": 1096, "amount": 0}, + {"first": 75, "second": 1097, "amount": 0}, + {"first": 75, "second": 1100, "amount": 0}, + {"first": 75, "second": 1102, "amount": 0}, + {"first": 75, "second": 252, "amount": 0}, + {"first": 75, "second": 246, "amount": -1}, + {"first": 75, "second": 214, "amount": -1}, + {"first": 75, "second": 241, "amount": 0}, + {"first": 75, "second": 962, "amount": -1}, + {"first": 75, "second": 964, "amount": -2}, + {"first": 75, "second": 965, "amount": 0}, + {"first": 75, "second": 959, "amount": -1}, + {"first": 75, "second": 945, "amount": -1}, + {"first": 75, "second": 963, "amount": -1}, + {"first": 75, "second": 947, "amount": -1}, + {"first": 75, "second": 951, "amount": 0}, + {"first": 75, "second": 957, "amount": -1}, + {"first": 75, "second": 920, "amount": -1}, + {"first": 75, "second": 927, "amount": -1}, + {"first": 75, "second": 934, "amount": -1}, + {"first": 75, "second": 216, "amount": -1}, + {"first": 76, "second": 121, "amount": -3}, + {"first": 76, "second": 117, "amount": -1}, + {"first": 76, "second": 119, "amount": -2}, + {"first": 76, "second": 118, "amount": -3}, + {"first": 76, "second": 65, "amount": 0}, + {"first": 76, "second": 84, "amount": -6}, + {"first": 76, "second": 89, "amount": -5}, + {"first": 76, "second": 85, "amount": -1}, + {"first": 76, "second": 79, "amount": -1}, + {"first": 76, "second": 81, "amount": -1}, + {"first": 76, "second": 71, "amount": -1}, + {"first": 76, "second": 87, "amount": -3}, + {"first": 76, "second": 67, "amount": -1}, + {"first": 76, "second": 86, "amount": -4}, + {"first": 76, "second": 34, "amount": -7}, + {"first": 76, "second": 39, "amount": -7}, + {"first": 76, "second": 1040, "amount": 0}, + {"first": 76, "second": 1054, "amount": -1}, + {"first": 76, "second": 1057, "amount": -1}, + {"first": 76, "second": 1058, "amount": -6}, + {"first": 76, "second": 1091, "amount": -3}, + {"first": 76, "second": 252, "amount": -1}, + {"first": 76, "second": 220, "amount": -1}, + {"first": 76, "second": 214, "amount": -1}, + {"first": 76, "second": 196, "amount": 0}, + {"first": 76, "second": 965, "amount": -1}, + {"first": 76, "second": 947, "amount": -3}, + {"first": 76, "second": 957, "amount": -3}, + {"first": 76, "second": 933, "amount": -5}, + {"first": 76, "second": 920, "amount": -1}, + {"first": 76, "second": 927, "amount": -1}, + {"first": 76, "second": 913, "amount": 0}, + {"first": 76, "second": 916, "amount": 0}, + {"first": 76, "second": 923, "amount": 0}, + {"first": 76, "second": 197, "amount": 0}, + {"first": 76, "second": 216, "amount": -1}, + {"first": 77, "second": 65, "amount": 0}, + {"first": 77, "second": 84, "amount": -1}, + {"first": 77, "second": 89, "amount": -1}, + {"first": 77, "second": 88, "amount": 0}, + {"first": 77, "second": 1040, "amount": 0}, + {"first": 77, "second": 1044, "amount": 0}, + {"first": 77, "second": 1076, "amount": 0}, + {"first": 77, "second": 1046, "amount": 0}, + {"first": 77, "second": 1051, "amount": 0}, + {"first": 77, "second": 1083, "amount": 0}, + {"first": 77, "second": 1058, "amount": -1}, + {"first": 77, "second": 1061, "amount": 0}, + {"first": 77, "second": 1063, "amount": -1}, + {"first": 77, "second": 1095, "amount": -1}, + {"first": 77, "second": 196, "amount": 0}, + {"first": 77, "second": 933, "amount": -1}, + {"first": 77, "second": 913, "amount": 0}, + {"first": 77, "second": 916, "amount": 0}, + {"first": 77, "second": 923, "amount": 0}, + {"first": 77, "second": 935, "amount": 0}, + {"first": 77, "second": 197, "amount": 0}, + {"first": 87, "second": 97, "amount": -1}, + {"first": 87, "second": 101, "amount": -1}, + {"first": 87, "second": 114, "amount": 0}, + {"first": 87, "second": 117, "amount": 0}, + {"first": 87, "second": 111, "amount": -1}, + {"first": 87, "second": 113, "amount": -1}, + {"first": 87, "second": 100, "amount": -1}, + {"first": 87, "second": 103, "amount": -1}, + {"first": 87, "second": 99, "amount": -1}, + {"first": 87, "second": 65, "amount": -1}, + {"first": 87, "second": 84, "amount": 0}, + {"first": 87, "second": 45, "amount": -1}, + {"first": 87, "second": 8211, "amount": -1}, + {"first": 87, "second": 44, "amount": -3}, + {"first": 87, "second": 46, "amount": -3}, + {"first": 87, "second": 125, "amount": 0}, + {"first": 87, "second": 41, "amount": 0}, + {"first": 87, "second": 93, "amount": 0}, + {"first": 87, "second": 1040, "amount": -1}, + {"first": 87, "second": 1072, "amount": -1}, + {"first": 87, "second": 1077, "amount": -1}, + {"first": 87, "second": 1105, "amount": -1}, + {"first": 87, "second": 1086, "amount": -1}, + {"first": 87, "second": 1089, "amount": -1}, + {"first": 87, "second": 1058, "amount": 0}, + {"first": 87, "second": 1092, "amount": -1}, + {"first": 87, "second": 252, "amount": 0}, + {"first": 87, "second": 246, "amount": -1}, + {"first": 87, "second": 228, "amount": -1}, + {"first": 87, "second": 196, "amount": -1}, + {"first": 87, "second": 962, "amount": -1}, + {"first": 87, "second": 965, "amount": 0}, + {"first": 87, "second": 959, "amount": -1}, + {"first": 87, "second": 945, "amount": -1}, + {"first": 87, "second": 963, "amount": -1}, + {"first": 87, "second": 913, "amount": -1}, + {"first": 87, "second": 916, "amount": -1}, + {"first": 87, "second": 923, "amount": -1}, + {"first": 87, "second": 229, "amount": -1}, + {"first": 87, "second": 197, "amount": -1}, + {"first": 88, "second": 101, "amount": -1}, + {"first": 88, "second": 121, "amount": -1}, + {"first": 88, "second": 117, "amount": 0}, + {"first": 88, "second": 111, "amount": 0}, + {"first": 88, "second": 113, "amount": -1}, + {"first": 88, "second": 100, "amount": -1}, + {"first": 88, "second": 103, "amount": -1}, + {"first": 88, "second": 99, "amount": -1}, + {"first": 88, "second": 118, "amount": -1}, + {"first": 88, "second": 79, "amount": -1}, + {"first": 88, "second": 81, "amount": -1}, + {"first": 88, "second": 71, "amount": -1}, + {"first": 88, "second": 67, "amount": -1}, + {"first": 88, "second": 86, "amount": 0}, + {"first": 88, "second": 45, "amount": -1}, + {"first": 88, "second": 8211, "amount": -1}, + {"first": 88, "second": 1073, "amount": 0}, + {"first": 88, "second": 1044, "amount": 0}, + {"first": 88, "second": 1077, "amount": -1}, + {"first": 88, "second": 1105, "amount": -1}, + {"first": 88, "second": 1051, "amount": 0}, + {"first": 88, "second": 1083, "amount": 0}, + {"first": 88, "second": 1054, "amount": -1}, + {"first": 88, "second": 1086, "amount": 0}, + {"first": 88, "second": 1057, "amount": -1}, + {"first": 88, "second": 1089, "amount": -1}, + {"first": 88, "second": 1090, "amount": -1}, + {"first": 88, "second": 1091, "amount": -1}, + {"first": 88, "second": 1092, "amount": -1}, + {"first": 88, "second": 1095, "amount": -1}, + {"first": 88, "second": 252, "amount": 0}, + {"first": 88, "second": 246, "amount": 0}, + {"first": 88, "second": 214, "amount": -1}, + {"first": 88, "second": 962, "amount": -1}, + {"first": 88, "second": 964, "amount": -1}, + {"first": 88, "second": 965, "amount": 0}, + {"first": 88, "second": 952, "amount": 0}, + {"first": 88, "second": 959, "amount": 0}, + {"first": 88, "second": 945, "amount": -1}, + {"first": 88, "second": 963, "amount": -1}, + {"first": 88, "second": 948, "amount": 0}, + {"first": 88, "second": 966, "amount": -1}, + {"first": 88, "second": 947, "amount": -1}, + {"first": 88, "second": 955, "amount": 0}, + {"first": 88, "second": 968, "amount": -1}, + {"first": 88, "second": 969, "amount": 0}, + {"first": 88, "second": 957, "amount": -1}, + {"first": 88, "second": 920, "amount": -1}, + {"first": 88, "second": 927, "amount": -1}, + {"first": 88, "second": 934, "amount": -1}, + {"first": 88, "second": 216, "amount": -1}, + {"first": 67, "second": 84, "amount": -1}, + {"first": 67, "second": 125, "amount": 0}, + {"first": 67, "second": 41, "amount": -1}, + {"first": 67, "second": 93, "amount": 0}, + {"first": 67, "second": 1058, "amount": -1}, + {"first": 86, "second": 97, "amount": -1}, + {"first": 86, "second": 101, "amount": -1}, + {"first": 86, "second": 114, "amount": -1}, + {"first": 86, "second": 121, "amount": 0}, + {"first": 86, "second": 117, "amount": -1}, + {"first": 86, "second": 111, "amount": -1}, + {"first": 86, "second": 113, "amount": -1}, + {"first": 86, "second": 100, "amount": -1}, + {"first": 86, "second": 103, "amount": -1}, + {"first": 86, "second": 99, "amount": -1}, + {"first": 86, "second": 118, "amount": 0}, + {"first": 86, "second": 65, "amount": -2}, + {"first": 86, "second": 79, "amount": 0}, + {"first": 86, "second": 81, "amount": 0}, + {"first": 86, "second": 71, "amount": 0}, + {"first": 86, "second": 67, "amount": 0}, + {"first": 86, "second": 45, "amount": -1}, + {"first": 86, "second": 8211, "amount": -1}, + {"first": 86, "second": 44, "amount": -5}, + {"first": 86, "second": 46, "amount": -5}, + {"first": 86, "second": 125, "amount": 0}, + {"first": 86, "second": 41, "amount": 0}, + {"first": 86, "second": 93, "amount": 0}, + {"first": 86, "second": 1040, "amount": -2}, + {"first": 86, "second": 1072, "amount": -1}, + {"first": 86, "second": 1077, "amount": -1}, + {"first": 86, "second": 1105, "amount": -1}, + {"first": 86, "second": 1054, "amount": 0}, + {"first": 86, "second": 1086, "amount": -1}, + {"first": 86, "second": 1057, "amount": 0}, + {"first": 86, "second": 1089, "amount": -1}, + {"first": 86, "second": 1091, "amount": 0}, + {"first": 86, "second": 1092, "amount": -1}, + {"first": 86, "second": 252, "amount": -1}, + {"first": 86, "second": 246, "amount": -1}, + {"first": 86, "second": 214, "amount": 0}, + {"first": 86, "second": 228, "amount": -1}, + {"first": 86, "second": 196, "amount": -2}, + {"first": 86, "second": 962, "amount": -1}, + {"first": 86, "second": 965, "amount": -1}, + {"first": 86, "second": 959, "amount": -1}, + {"first": 86, "second": 945, "amount": -1}, + {"first": 86, "second": 963, "amount": -1}, + {"first": 86, "second": 947, "amount": 0}, + {"first": 86, "second": 957, "amount": 0}, + {"first": 86, "second": 920, "amount": 0}, + {"first": 86, "second": 927, "amount": 0}, + {"first": 86, "second": 913, "amount": -2}, + {"first": 86, "second": 916, "amount": -2}, + {"first": 86, "second": 923, "amount": -2}, + {"first": 86, "second": 229, "amount": -1}, + {"first": 86, "second": 197, "amount": -2}, + {"first": 86, "second": 216, "amount": 0}, + {"first": 66, "second": 84, "amount": -1}, + {"first": 66, "second": 89, "amount": -1}, + {"first": 66, "second": 86, "amount": 0}, + {"first": 66, "second": 1058, "amount": -1}, + {"first": 66, "second": 1059, "amount": 0}, + {"first": 66, "second": 933, "amount": -1}, + {"first": 78, "second": 65, "amount": 0}, + {"first": 78, "second": 84, "amount": -1}, + {"first": 78, "second": 89, "amount": -1}, + {"first": 78, "second": 88, "amount": 0}, + {"first": 78, "second": 1040, "amount": 0}, + {"first": 78, "second": 1044, "amount": 0}, + {"first": 78, "second": 1076, "amount": 0}, + {"first": 78, "second": 1046, "amount": 0}, + {"first": 78, "second": 1051, "amount": 0}, + {"first": 78, "second": 1083, "amount": 0}, + {"first": 78, "second": 1058, "amount": -1}, + {"first": 78, "second": 1061, "amount": 0}, + {"first": 78, "second": 1063, "amount": -1}, + {"first": 78, "second": 1095, "amount": -1}, + {"first": 78, "second": 196, "amount": 0}, + {"first": 78, "second": 933, "amount": -1}, + {"first": 78, "second": 913, "amount": 0}, + {"first": 78, "second": 916, "amount": 0}, + {"first": 78, "second": 923, "amount": 0}, + {"first": 78, "second": 935, "amount": 0}, + {"first": 78, "second": 197, "amount": 0}, + {"first": 47, "second": 47, "amount": -5}, + {"first": 44, "second": 34, "amount": -3}, + {"first": 44, "second": 39, "amount": -3}, + {"first": 46, "second": 34, "amount": -3}, + {"first": 46, "second": 39, "amount": -3}, + {"first": 123, "second": 85, "amount": 0}, + {"first": 123, "second": 74, "amount": 0}, + {"first": 123, "second": 220, "amount": 0}, + {"first": 40, "second": 89, "amount": 0}, + {"first": 40, "second": 87, "amount": 0}, + {"first": 40, "second": 86, "amount": 0}, + {"first": 40, "second": 933, "amount": 0}, + {"first": 91, "second": 85, "amount": 0}, + {"first": 91, "second": 74, "amount": 0}, + {"first": 91, "second": 220, "amount": 0}, + {"first": 34, "second": 97, "amount": -1}, + {"first": 34, "second": 101, "amount": -1}, + {"first": 34, "second": 111, "amount": -1}, + {"first": 34, "second": 112, "amount": 0}, + {"first": 34, "second": 113, "amount": -1}, + {"first": 34, "second": 115, "amount": -2}, + {"first": 34, "second": 100, "amount": -1}, + {"first": 34, "second": 103, "amount": -1}, + {"first": 34, "second": 109, "amount": 0}, + {"first": 34, "second": 119, "amount": 0}, + {"first": 34, "second": 99, "amount": -1}, + {"first": 34, "second": 110, "amount": 0}, + {"first": 34, "second": 65, "amount": -2}, + {"first": 34, "second": 34, "amount": -2}, + {"first": 34, "second": 39, "amount": -2}, + {"first": 34, "second": 1040, "amount": -2}, + {"first": 34, "second": 1072, "amount": -1}, + {"first": 34, "second": 1075, "amount": 0}, + {"first": 34, "second": 1077, "amount": -1}, + {"first": 34, "second": 1105, "amount": -1}, + {"first": 34, "second": 1080, "amount": 0}, + {"first": 34, "second": 1081, "amount": 0}, + {"first": 34, "second": 1082, "amount": 0}, + {"first": 34, "second": 1084, "amount": 0}, + {"first": 34, "second": 1085, "amount": 0}, + {"first": 34, "second": 1086, "amount": -1}, + {"first": 34, "second": 1087, "amount": 0}, + {"first": 34, "second": 1088, "amount": 0}, + {"first": 34, "second": 1089, "amount": -1}, + {"first": 34, "second": 1092, "amount": -1}, + {"first": 34, "second": 1094, "amount": 0}, + {"first": 34, "second": 1096, "amount": 0}, + {"first": 34, "second": 1097, "amount": 0}, + {"first": 34, "second": 1100, "amount": 0}, + {"first": 34, "second": 1102, "amount": 0}, + {"first": 34, "second": 246, "amount": -1}, + {"first": 34, "second": 228, "amount": -1}, + {"first": 34, "second": 196, "amount": -2}, + {"first": 34, "second": 241, "amount": 0}, + {"first": 34, "second": 962, "amount": -1}, + {"first": 34, "second": 959, "amount": -1}, + {"first": 34, "second": 945, "amount": -1}, + {"first": 34, "second": 963, "amount": -1}, + {"first": 34, "second": 951, "amount": 0}, + {"first": 34, "second": 913, "amount": -2}, + {"first": 34, "second": 916, "amount": -2}, + {"first": 34, "second": 923, "amount": -2}, + {"first": 34, "second": 229, "amount": -1}, + {"first": 34, "second": 197, "amount": -2}, + {"first": 39, "second": 97, "amount": -1}, + {"first": 39, "second": 101, "amount": -1}, + {"first": 39, "second": 111, "amount": -1}, + {"first": 39, "second": 112, "amount": 0}, + {"first": 39, "second": 113, "amount": -1}, + {"first": 39, "second": 115, "amount": -2}, + {"first": 39, "second": 100, "amount": -1}, + {"first": 39, "second": 103, "amount": -1}, + {"first": 39, "second": 109, "amount": 0}, + {"first": 39, "second": 119, "amount": 0}, + {"first": 39, "second": 99, "amount": -1}, + {"first": 39, "second": 110, "amount": 0}, + {"first": 39, "second": 65, "amount": -2}, + {"first": 39, "second": 34, "amount": -2}, + {"first": 39, "second": 39, "amount": -2}, + {"first": 39, "second": 1040, "amount": -2}, + {"first": 39, "second": 1072, "amount": -1}, + {"first": 39, "second": 1075, "amount": 0}, + {"first": 39, "second": 1077, "amount": -1}, + {"first": 39, "second": 1105, "amount": -1}, + {"first": 39, "second": 1080, "amount": 0}, + {"first": 39, "second": 1081, "amount": 0}, + {"first": 39, "second": 1082, "amount": 0}, + {"first": 39, "second": 1084, "amount": 0}, + {"first": 39, "second": 1085, "amount": 0}, + {"first": 39, "second": 1086, "amount": -1}, + {"first": 39, "second": 1087, "amount": 0}, + {"first": 39, "second": 1088, "amount": 0}, + {"first": 39, "second": 1089, "amount": -1}, + {"first": 39, "second": 1092, "amount": -1}, + {"first": 39, "second": 1094, "amount": 0}, + {"first": 39, "second": 1096, "amount": 0}, + {"first": 39, "second": 1097, "amount": 0}, + {"first": 39, "second": 1100, "amount": 0}, + {"first": 39, "second": 1102, "amount": 0}, + {"first": 39, "second": 246, "amount": -1}, + {"first": 39, "second": 228, "amount": -1}, + {"first": 39, "second": 196, "amount": -2}, + {"first": 39, "second": 241, "amount": 0}, + {"first": 39, "second": 962, "amount": -1}, + {"first": 39, "second": 959, "amount": -1}, + {"first": 39, "second": 945, "amount": -1}, + {"first": 39, "second": 963, "amount": -1}, + {"first": 39, "second": 951, "amount": 0}, + {"first": 39, "second": 913, "amount": -2}, + {"first": 39, "second": 916, "amount": -2}, + {"first": 39, "second": 923, "amount": -2}, + {"first": 39, "second": 229, "amount": -1}, + {"first": 39, "second": 197, "amount": -2}, + {"first": 1040, "second": 122, "amount": 0}, + {"first": 1040, "second": 116, "amount": 0}, + {"first": 1040, "second": 121, "amount": -1}, + {"first": 1040, "second": 117, "amount": 0}, + {"first": 1040, "second": 111, "amount": 0}, + {"first": 1040, "second": 119, "amount": -1}, + {"first": 1040, "second": 118, "amount": -1}, + {"first": 1040, "second": 84, "amount": -3}, + {"first": 1040, "second": 89, "amount": -2}, + {"first": 1040, "second": 85, "amount": 0}, + {"first": 1040, "second": 79, "amount": 0}, + {"first": 1040, "second": 81, "amount": 0}, + {"first": 1040, "second": 71, "amount": 0}, + {"first": 1040, "second": 87, "amount": -1}, + {"first": 1040, "second": 67, "amount": 0}, + {"first": 1040, "second": 86, "amount": -2}, + {"first": 1040, "second": 63, "amount": -1}, + {"first": 1040, "second": 34, "amount": -2}, + {"first": 1040, "second": 39, "amount": -2}, + {"first": 1040, "second": 1044, "amount": 0}, + {"first": 1040, "second": 1051, "amount": 0}, + {"first": 1040, "second": 1083, "amount": 0}, + {"first": 1040, "second": 1054, "amount": 0}, + {"first": 1040, "second": 1086, "amount": 0}, + {"first": 1040, "second": 1057, "amount": 0}, + {"first": 1040, "second": 1058, "amount": -3}, + {"first": 1040, "second": 1090, "amount": -1}, + {"first": 1040, "second": 1091, "amount": -1}, + {"first": 1040, "second": 1063, "amount": -1}, + {"first": 1040, "second": 1095, "amount": -2}, + {"first": 1040, "second": 1068, "amount": -1}, + {"first": 1040, "second": 252, "amount": 0}, + {"first": 1040, "second": 220, "amount": 0}, + {"first": 1040, "second": 246, "amount": 0}, + {"first": 1040, "second": 214, "amount": 0}, + {"first": 1040, "second": 964, "amount": -1}, + {"first": 1040, "second": 965, "amount": 0}, + {"first": 1040, "second": 959, "amount": 0}, + {"first": 1040, "second": 947, "amount": -1}, + {"first": 1040, "second": 955, "amount": 0}, + {"first": 1040, "second": 957, "amount": -1}, + {"first": 1040, "second": 933, "amount": -2}, + {"first": 1040, "second": 920, "amount": 0}, + {"first": 1040, "second": 927, "amount": 0}, + {"first": 1040, "second": 934, "amount": -1}, + {"first": 1040, "second": 936, "amount": -1}, + {"first": 1040, "second": 216, "amount": 0}, + {"first": 1072, "second": 121, "amount": 0}, + {"first": 1072, "second": 118, "amount": 0}, + {"first": 1072, "second": 34, "amount": -1}, + {"first": 1072, "second": 39, "amount": -1}, + {"first": 1072, "second": 1090, "amount": 0}, + {"first": 1072, "second": 1091, "amount": 0}, + {"first": 1072, "second": 947, "amount": 0}, + {"first": 1072, "second": 957, "amount": 0}, + {"first": 1041, "second": 120, "amount": 0}, + {"first": 1041, "second": 84, "amount": -1}, + {"first": 1041, "second": 89, "amount": -1}, + {"first": 1041, "second": 88, "amount": 0}, + {"first": 1041, "second": 86, "amount": -1}, + {"first": 1041, "second": 1046, "amount": 0}, + {"first": 1041, "second": 1078, "amount": 0}, + {"first": 1041, "second": 1058, "amount": -1}, + {"first": 1041, "second": 1090, "amount": -1}, + {"first": 1041, "second": 1059, "amount": 0}, + {"first": 1041, "second": 1061, "amount": 0}, + {"first": 1041, "second": 1093, "amount": 0}, + {"first": 1041, "second": 1063, "amount": 0}, + {"first": 1041, "second": 1068, "amount": -1}, + {"first": 1041, "second": 933, "amount": -1}, + {"first": 1041, "second": 935, "amount": 0}, + {"first": 1073, "second": 112, "amount": 0}, + {"first": 1073, "second": 109, "amount": 0}, + {"first": 1073, "second": 120, "amount": 0}, + {"first": 1073, "second": 110, "amount": 0}, + {"first": 1073, "second": 1075, "amount": 0}, + {"first": 1073, "second": 1076, "amount": 0}, + {"first": 1073, "second": 1078, "amount": 0}, + {"first": 1073, "second": 1080, "amount": 0}, + {"first": 1073, "second": 1081, "amount": 0}, + {"first": 1073, "second": 1082, "amount": 0}, + {"first": 1073, "second": 1084, "amount": 0}, + {"first": 1073, "second": 1085, "amount": 0}, + {"first": 1073, "second": 1087, "amount": 0}, + {"first": 1073, "second": 1088, "amount": 0}, + {"first": 1073, "second": 1090, "amount": 0}, + {"first": 1073, "second": 1093, "amount": 0}, + {"first": 1073, "second": 1094, "amount": 0}, + {"first": 1073, "second": 1096, "amount": 0}, + {"first": 1073, "second": 1097, "amount": 0}, + {"first": 1073, "second": 1100, "amount": 0}, + {"first": 1073, "second": 1102, "amount": 0}, + {"first": 1073, "second": 241, "amount": 0}, + {"first": 1073, "second": 951, "amount": 0}, + {"first": 1042, "second": 84, "amount": -1}, + {"first": 1042, "second": 89, "amount": -1}, + {"first": 1042, "second": 86, "amount": 0}, + {"first": 1042, "second": 1058, "amount": -1}, + {"first": 1042, "second": 1059, "amount": 0}, + {"first": 1042, "second": 933, "amount": -1}, + {"first": 1074, "second": 121, "amount": 0}, + {"first": 1074, "second": 118, "amount": 0}, + {"first": 1074, "second": 34, "amount": 0}, + {"first": 1074, "second": 39, "amount": 0}, + {"first": 1074, "second": 1090, "amount": 0}, + {"first": 1074, "second": 1091, "amount": 0}, + {"first": 1074, "second": 947, "amount": 0}, + {"first": 1074, "second": 957, "amount": 0}, + {"first": 1043, "second": 97, "amount": -4}, + {"first": 1043, "second": 122, "amount": -3}, + {"first": 1043, "second": 101, "amount": -4}, + {"first": 1043, "second": 114, "amount": -3}, + {"first": 1043, "second": 121, "amount": -3}, + {"first": 1043, "second": 117, "amount": -4}, + {"first": 1043, "second": 111, "amount": -4}, + {"first": 1043, "second": 112, "amount": -4}, + {"first": 1043, "second": 113, "amount": -4}, + {"first": 1043, "second": 115, "amount": -4}, + {"first": 1043, "second": 100, "amount": -4}, + {"first": 1043, "second": 103, "amount": -4}, + {"first": 1043, "second": 109, "amount": -4}, + {"first": 1043, "second": 119, "amount": -2}, + {"first": 1043, "second": 120, "amount": -3}, + {"first": 1043, "second": 99, "amount": -4}, + {"first": 1043, "second": 118, "amount": -3}, + {"first": 1043, "second": 110, "amount": -4}, + {"first": 1043, "second": 65, "amount": -4}, + {"first": 1043, "second": 84, "amount": 0}, + {"first": 1043, "second": 89, "amount": 0}, + {"first": 1043, "second": 79, "amount": -1}, + {"first": 1043, "second": 81, "amount": -1}, + {"first": 1043, "second": 83, "amount": -1}, + {"first": 1043, "second": 71, "amount": -1}, + {"first": 1043, "second": 87, "amount": 0}, + {"first": 1043, "second": 67, "amount": -1}, + {"first": 1043, "second": 86, "amount": 0}, + {"first": 1043, "second": 45, "amount": -8}, + {"first": 1043, "second": 8211, "amount": -8}, + {"first": 1043, "second": 44, "amount": -8}, + {"first": 1043, "second": 46, "amount": -8}, + {"first": 1043, "second": 1040, "amount": -4}, + {"first": 1043, "second": 1072, "amount": -4}, + {"first": 1043, "second": 1073, "amount": -1}, + {"first": 1043, "second": 1074, "amount": -4}, + {"first": 1043, "second": 1075, "amount": -4}, + {"first": 1043, "second": 1044, "amount": -4}, + {"first": 1043, "second": 1076, "amount": -5}, + {"first": 1043, "second": 1077, "amount": -4}, + {"first": 1043, "second": 1105, "amount": -4}, + {"first": 1043, "second": 1078, "amount": -3}, + {"first": 1043, "second": 1079, "amount": -5}, + {"first": 1043, "second": 1080, "amount": -4}, + {"first": 1043, "second": 1081, "amount": -4}, + {"first": 1043, "second": 1082, "amount": -4}, + {"first": 1043, "second": 1051, "amount": -2}, + {"first": 1043, "second": 1083, "amount": -5}, + {"first": 1043, "second": 1084, "amount": -4}, + {"first": 1043, "second": 1085, "amount": -4}, + {"first": 1043, "second": 1054, "amount": -1}, + {"first": 1043, "second": 1086, "amount": -4}, + {"first": 1043, "second": 1087, "amount": -4}, + {"first": 1043, "second": 1088, "amount": -4}, + {"first": 1043, "second": 1057, "amount": -1}, + {"first": 1043, "second": 1089, "amount": -4}, + {"first": 1043, "second": 1058, "amount": 0}, + {"first": 1043, "second": 1090, "amount": -3}, + {"first": 1043, "second": 1091, "amount": -3}, + {"first": 1043, "second": 1092, "amount": -4}, + {"first": 1043, "second": 1093, "amount": -3}, + {"first": 1043, "second": 1094, "amount": -4}, + {"first": 1043, "second": 1095, "amount": -5}, + {"first": 1043, "second": 1096, "amount": -4}, + {"first": 1043, "second": 1097, "amount": -4}, + {"first": 1043, "second": 1099, "amount": -5}, + {"first": 1043, "second": 1068, "amount": 0}, + {"first": 1043, "second": 1100, "amount": -4}, + {"first": 1043, "second": 1101, "amount": -5}, + {"first": 1043, "second": 1102, "amount": -4}, + {"first": 1043, "second": 1103, "amount": -5}, + {"first": 1043, "second": 252, "amount": -4}, + {"first": 1043, "second": 246, "amount": -4}, + {"first": 1043, "second": 214, "amount": -1}, + {"first": 1043, "second": 228, "amount": -4}, + {"first": 1043, "second": 196, "amount": -4}, + {"first": 1043, "second": 241, "amount": -4}, + {"first": 1043, "second": 962, "amount": -4}, + {"first": 1043, "second": 949, "amount": -5}, + {"first": 1043, "second": 961, "amount": -6}, + {"first": 1043, "second": 964, "amount": -4}, + {"first": 1043, "second": 965, "amount": -4}, + {"first": 1043, "second": 953, "amount": -6}, + {"first": 1043, "second": 959, "amount": -4}, + {"first": 1043, "second": 960, "amount": -5}, + {"first": 1043, "second": 945, "amount": -4}, + {"first": 1043, "second": 963, "amount": -4}, + {"first": 1043, "second": 948, "amount": -2}, + {"first": 1043, "second": 966, "amount": -6}, + {"first": 1043, "second": 947, "amount": -3}, + {"first": 1043, "second": 951, "amount": -4}, + {"first": 1043, "second": 968, "amount": -5}, + {"first": 1043, "second": 969, "amount": -6}, + {"first": 1043, "second": 957, "amount": -3}, + {"first": 1043, "second": 933, "amount": 0}, + {"first": 1043, "second": 920, "amount": -1}, + {"first": 1043, "second": 927, "amount": -1}, + {"first": 1043, "second": 913, "amount": -4}, + {"first": 1043, "second": 916, "amount": -4}, + {"first": 1043, "second": 934, "amount": -3}, + {"first": 1043, "second": 923, "amount": -4}, + {"first": 1043, "second": 229, "amount": -4}, + {"first": 1043, "second": 197, "amount": -4}, + {"first": 1043, "second": 230, "amount": -4}, + {"first": 1043, "second": 198, "amount": -7}, + {"first": 1043, "second": 248, "amount": -4}, + {"first": 1043, "second": 216, "amount": -1}, + {"first": 1075, "second": 101, "amount": 0}, + {"first": 1075, "second": 111, "amount": 0}, + {"first": 1075, "second": 113, "amount": 0}, + {"first": 1075, "second": 100, "amount": 0}, + {"first": 1075, "second": 103, "amount": 0}, + {"first": 1075, "second": 99, "amount": 0}, + {"first": 1075, "second": 1076, "amount": -1}, + {"first": 1075, "second": 1077, "amount": 0}, + {"first": 1075, "second": 1105, "amount": 0}, + {"first": 1075, "second": 1083, "amount": -1}, + {"first": 1075, "second": 1086, "amount": 0}, + {"first": 1075, "second": 1089, "amount": 0}, + {"first": 1075, "second": 1092, "amount": 0}, + {"first": 1075, "second": 246, "amount": 0}, + {"first": 1075, "second": 962, "amount": 0}, + {"first": 1075, "second": 959, "amount": 0}, + {"first": 1075, "second": 945, "amount": 0}, + {"first": 1075, "second": 963, "amount": 0}, + {"first": 1044, "second": 65, "amount": 0}, + {"first": 1044, "second": 84, "amount": -1}, + {"first": 1044, "second": 89, "amount": -1}, + {"first": 1044, "second": 79, "amount": 0}, + {"first": 1044, "second": 81, "amount": 0}, + {"first": 1044, "second": 71, "amount": 0}, + {"first": 1044, "second": 67, "amount": 0}, + {"first": 1044, "second": 86, "amount": -1}, + {"first": 1044, "second": 1040, "amount": 0}, + {"first": 1044, "second": 1044, "amount": 0}, + {"first": 1044, "second": 1076, "amount": 0}, + {"first": 1044, "second": 1051, "amount": 0}, + {"first": 1044, "second": 1083, "amount": 0}, + {"first": 1044, "second": 1054, "amount": 0}, + {"first": 1044, "second": 1057, "amount": 0}, + {"first": 1044, "second": 1058, "amount": -1}, + {"first": 1044, "second": 1063, "amount": -1}, + {"first": 1044, "second": 1095, "amount": -1}, + {"first": 1044, "second": 1068, "amount": -1}, + {"first": 1044, "second": 214, "amount": 0}, + {"first": 1044, "second": 196, "amount": 0}, + {"first": 1044, "second": 933, "amount": -1}, + {"first": 1044, "second": 920, "amount": 0}, + {"first": 1044, "second": 927, "amount": 0}, + {"first": 1044, "second": 913, "amount": 0}, + {"first": 1044, "second": 916, "amount": 0}, + {"first": 1044, "second": 923, "amount": 0}, + {"first": 1044, "second": 197, "amount": 0}, + {"first": 1044, "second": 216, "amount": 0}, + {"first": 1076, "second": 1076, "amount": 0}, + {"first": 1076, "second": 1090, "amount": 0}, + {"first": 1076, "second": 1095, "amount": 0}, + {"first": 1076, "second": 1098, "amount": -1}, + {"first": 1045, "second": 101, "amount": 0}, + {"first": 1045, "second": 121, "amount": -1}, + {"first": 1045, "second": 117, "amount": 0}, + {"first": 1045, "second": 111, "amount": 0}, + {"first": 1045, "second": 113, "amount": 0}, + {"first": 1045, "second": 100, "amount": 0}, + {"first": 1045, "second": 102, "amount": 0}, + {"first": 1045, "second": 103, "amount": 0}, + {"first": 1045, "second": 119, "amount": 0}, + {"first": 1045, "second": 99, "amount": 0}, + {"first": 1045, "second": 118, "amount": -1}, + {"first": 1045, "second": 84, "amount": 0}, + {"first": 1045, "second": 1077, "amount": 0}, + {"first": 1045, "second": 1105, "amount": 0}, + {"first": 1045, "second": 1086, "amount": 0}, + {"first": 1045, "second": 1089, "amount": 0}, + {"first": 1045, "second": 1058, "amount": 0}, + {"first": 1045, "second": 1091, "amount": -1}, + {"first": 1045, "second": 1092, "amount": 0}, + {"first": 1045, "second": 252, "amount": 0}, + {"first": 1045, "second": 246, "amount": 0}, + {"first": 1045, "second": 962, "amount": 0}, + {"first": 1045, "second": 965, "amount": 0}, + {"first": 1045, "second": 959, "amount": 0}, + {"first": 1045, "second": 945, "amount": 0}, + {"first": 1045, "second": 963, "amount": 0}, + {"first": 1045, "second": 947, "amount": -1}, + {"first": 1045, "second": 957, "amount": -1}, + {"first": 1077, "second": 121, "amount": 0}, + {"first": 1077, "second": 118, "amount": 0}, + {"first": 1077, "second": 34, "amount": 0}, + {"first": 1077, "second": 39, "amount": 0}, + {"first": 1077, "second": 1090, "amount": 0}, + {"first": 1077, "second": 1091, "amount": 0}, + {"first": 1077, "second": 947, "amount": 0}, + {"first": 1077, "second": 957, "amount": 0}, + {"first": 1025, "second": 101, "amount": 0}, + {"first": 1025, "second": 121, "amount": -1}, + {"first": 1025, "second": 117, "amount": 0}, + {"first": 1025, "second": 111, "amount": 0}, + {"first": 1025, "second": 113, "amount": 0}, + {"first": 1025, "second": 100, "amount": 0}, + {"first": 1025, "second": 102, "amount": 0}, + {"first": 1025, "second": 103, "amount": 0}, + {"first": 1025, "second": 119, "amount": 0}, + {"first": 1025, "second": 99, "amount": 0}, + {"first": 1025, "second": 118, "amount": -1}, + {"first": 1025, "second": 84, "amount": 0}, + {"first": 1025, "second": 1077, "amount": 0}, + {"first": 1025, "second": 1105, "amount": 0}, + {"first": 1025, "second": 1086, "amount": 0}, + {"first": 1025, "second": 1089, "amount": 0}, + {"first": 1025, "second": 1058, "amount": 0}, + {"first": 1025, "second": 1091, "amount": -1}, + {"first": 1025, "second": 1092, "amount": 0}, + {"first": 1025, "second": 252, "amount": 0}, + {"first": 1025, "second": 246, "amount": 0}, + {"first": 1025, "second": 962, "amount": 0}, + {"first": 1025, "second": 965, "amount": 0}, + {"first": 1025, "second": 959, "amount": 0}, + {"first": 1025, "second": 945, "amount": 0}, + {"first": 1025, "second": 963, "amount": 0}, + {"first": 1025, "second": 947, "amount": -1}, + {"first": 1025, "second": 957, "amount": -1}, + {"first": 1105, "second": 121, "amount": 0}, + {"first": 1105, "second": 118, "amount": 0}, + {"first": 1105, "second": 34, "amount": 0}, + {"first": 1105, "second": 39, "amount": 0}, + {"first": 1105, "second": 1090, "amount": 0}, + {"first": 1105, "second": 1091, "amount": 0}, + {"first": 1105, "second": 947, "amount": 0}, + {"first": 1105, "second": 957, "amount": 0}, + {"first": 1046, "second": 101, "amount": -1}, + {"first": 1046, "second": 121, "amount": -1}, + {"first": 1046, "second": 117, "amount": 0}, + {"first": 1046, "second": 111, "amount": 0}, + {"first": 1046, "second": 113, "amount": -1}, + {"first": 1046, "second": 100, "amount": -1}, + {"first": 1046, "second": 103, "amount": -1}, + {"first": 1046, "second": 99, "amount": -1}, + {"first": 1046, "second": 118, "amount": -1}, + {"first": 1046, "second": 79, "amount": -1}, + {"first": 1046, "second": 81, "amount": -1}, + {"first": 1046, "second": 71, "amount": -1}, + {"first": 1046, "second": 67, "amount": -1}, + {"first": 1046, "second": 86, "amount": 0}, + {"first": 1046, "second": 45, "amount": -1}, + {"first": 1046, "second": 8211, "amount": -1}, + {"first": 1046, "second": 1073, "amount": 0}, + {"first": 1046, "second": 1044, "amount": 0}, + {"first": 1046, "second": 1077, "amount": -1}, + {"first": 1046, "second": 1105, "amount": -1}, + {"first": 1046, "second": 1051, "amount": 0}, + {"first": 1046, "second": 1083, "amount": 0}, + {"first": 1046, "second": 1054, "amount": -1}, + {"first": 1046, "second": 1086, "amount": 0}, + {"first": 1046, "second": 1057, "amount": -1}, + {"first": 1046, "second": 1089, "amount": -1}, + {"first": 1046, "second": 1090, "amount": -1}, + {"first": 1046, "second": 1091, "amount": -1}, + {"first": 1046, "second": 1092, "amount": -1}, + {"first": 1046, "second": 1095, "amount": -1}, + {"first": 1046, "second": 252, "amount": 0}, + {"first": 1046, "second": 246, "amount": 0}, + {"first": 1046, "second": 214, "amount": -1}, + {"first": 1046, "second": 962, "amount": -1}, + {"first": 1046, "second": 964, "amount": -1}, + {"first": 1046, "second": 965, "amount": 0}, + {"first": 1046, "second": 952, "amount": 0}, + {"first": 1046, "second": 959, "amount": 0}, + {"first": 1046, "second": 945, "amount": -1}, + {"first": 1046, "second": 963, "amount": -1}, + {"first": 1046, "second": 948, "amount": 0}, + {"first": 1046, "second": 966, "amount": -1}, + {"first": 1046, "second": 947, "amount": -1}, + {"first": 1046, "second": 955, "amount": 0}, + {"first": 1046, "second": 968, "amount": -1}, + {"first": 1046, "second": 969, "amount": 0}, + {"first": 1046, "second": 957, "amount": -1}, + {"first": 1046, "second": 920, "amount": -1}, + {"first": 1046, "second": 927, "amount": -1}, + {"first": 1046, "second": 934, "amount": -1}, + {"first": 1046, "second": 216, "amount": -1}, + {"first": 1078, "second": 101, "amount": 0}, + {"first": 1078, "second": 111, "amount": 0}, + {"first": 1078, "second": 113, "amount": 0}, + {"first": 1078, "second": 100, "amount": 0}, + {"first": 1078, "second": 103, "amount": 0}, + {"first": 1078, "second": 99, "amount": 0}, + {"first": 1078, "second": 1077, "amount": 0}, + {"first": 1078, "second": 1105, "amount": 0}, + {"first": 1078, "second": 1086, "amount": 0}, + {"first": 1078, "second": 1089, "amount": 0}, + {"first": 1078, "second": 1092, "amount": 0}, + {"first": 1078, "second": 246, "amount": 0}, + {"first": 1078, "second": 962, "amount": 0}, + {"first": 1078, "second": 959, "amount": 0}, + {"first": 1078, "second": 945, "amount": 0}, + {"first": 1078, "second": 963, "amount": 0}, + {"first": 1047, "second": 84, "amount": 0}, + {"first": 1047, "second": 89, "amount": 0}, + {"first": 1047, "second": 88, "amount": 0}, + {"first": 1047, "second": 86, "amount": 0}, + {"first": 1047, "second": 55, "amount": 0}, + {"first": 1047, "second": 1046, "amount": 0}, + {"first": 1047, "second": 1051, "amount": 0}, + {"first": 1047, "second": 1058, "amount": 0}, + {"first": 1047, "second": 1059, "amount": 0}, + {"first": 1047, "second": 1061, "amount": 0}, + {"first": 1047, "second": 1068, "amount": 0}, + {"first": 1047, "second": 933, "amount": 0}, + {"first": 1047, "second": 935, "amount": 0}, + {"first": 1079, "second": 34, "amount": 0}, + {"first": 1079, "second": 39, "amount": 0}, + {"first": 1048, "second": 65, "amount": 0}, + {"first": 1048, "second": 84, "amount": -1}, + {"first": 1048, "second": 89, "amount": -1}, + {"first": 1048, "second": 88, "amount": 0}, + {"first": 1048, "second": 1040, "amount": 0}, + {"first": 1048, "second": 1044, "amount": 0}, + {"first": 1048, "second": 1076, "amount": 0}, + {"first": 1048, "second": 1046, "amount": 0}, + {"first": 1048, "second": 1051, "amount": 0}, + {"first": 1048, "second": 1083, "amount": 0}, + {"first": 1048, "second": 1058, "amount": -1}, + {"first": 1048, "second": 1061, "amount": 0}, + {"first": 1048, "second": 1063, "amount": -1}, + {"first": 1048, "second": 1095, "amount": -1}, + {"first": 1048, "second": 196, "amount": 0}, + {"first": 1048, "second": 933, "amount": -1}, + {"first": 1048, "second": 913, "amount": 0}, + {"first": 1048, "second": 916, "amount": 0}, + {"first": 1048, "second": 923, "amount": 0}, + {"first": 1048, "second": 935, "amount": 0}, + {"first": 1048, "second": 197, "amount": 0}, + {"first": 1050, "second": 101, "amount": -1}, + {"first": 1050, "second": 121, "amount": -1}, + {"first": 1050, "second": 117, "amount": 0}, + {"first": 1050, "second": 111, "amount": -1}, + {"first": 1050, "second": 112, "amount": 0}, + {"first": 1050, "second": 113, "amount": -1}, + {"first": 1050, "second": 100, "amount": -1}, + {"first": 1050, "second": 103, "amount": -1}, + {"first": 1050, "second": 109, "amount": 0}, + {"first": 1050, "second": 119, "amount": -1}, + {"first": 1050, "second": 99, "amount": -1}, + {"first": 1050, "second": 118, "amount": -1}, + {"first": 1050, "second": 110, "amount": 0}, + {"first": 1050, "second": 79, "amount": -1}, + {"first": 1050, "second": 81, "amount": -1}, + {"first": 1050, "second": 71, "amount": -1}, + {"first": 1050, "second": 67, "amount": -1}, + {"first": 1050, "second": 45, "amount": -1}, + {"first": 1050, "second": 8211, "amount": -1}, + {"first": 1050, "second": 1073, "amount": -1}, + {"first": 1050, "second": 1075, "amount": 0}, + {"first": 1050, "second": 1077, "amount": -1}, + {"first": 1050, "second": 1105, "amount": -1}, + {"first": 1050, "second": 1080, "amount": 0}, + {"first": 1050, "second": 1081, "amount": 0}, + {"first": 1050, "second": 1082, "amount": 0}, + {"first": 1050, "second": 1084, "amount": 0}, + {"first": 1050, "second": 1085, "amount": 0}, + {"first": 1050, "second": 1054, "amount": -1}, + {"first": 1050, "second": 1086, "amount": -1}, + {"first": 1050, "second": 1087, "amount": 0}, + {"first": 1050, "second": 1088, "amount": 0}, + {"first": 1050, "second": 1057, "amount": -1}, + {"first": 1050, "second": 1089, "amount": -1}, + {"first": 1050, "second": 1090, "amount": -1}, + {"first": 1050, "second": 1091, "amount": -1}, + {"first": 1050, "second": 1092, "amount": -1}, + {"first": 1050, "second": 1094, "amount": 0}, + {"first": 1050, "second": 1095, "amount": -2}, + {"first": 1050, "second": 1096, "amount": 0}, + {"first": 1050, "second": 1097, "amount": 0}, + {"first": 1050, "second": 1100, "amount": 0}, + {"first": 1050, "second": 1102, "amount": 0}, + {"first": 1050, "second": 252, "amount": 0}, + {"first": 1050, "second": 246, "amount": -1}, + {"first": 1050, "second": 214, "amount": -1}, + {"first": 1050, "second": 241, "amount": 0}, + {"first": 1050, "second": 962, "amount": -1}, + {"first": 1050, "second": 964, "amount": -2}, + {"first": 1050, "second": 965, "amount": 0}, + {"first": 1050, "second": 959, "amount": -1}, + {"first": 1050, "second": 945, "amount": -1}, + {"first": 1050, "second": 963, "amount": -1}, + {"first": 1050, "second": 947, "amount": -1}, + {"first": 1050, "second": 951, "amount": 0}, + {"first": 1050, "second": 957, "amount": -1}, + {"first": 1050, "second": 920, "amount": -1}, + {"first": 1050, "second": 927, "amount": -1}, + {"first": 1050, "second": 934, "amount": -1}, + {"first": 1050, "second": 216, "amount": -1}, + {"first": 1082, "second": 101, "amount": 0}, + {"first": 1082, "second": 111, "amount": 0}, + {"first": 1082, "second": 113, "amount": 0}, + {"first": 1082, "second": 100, "amount": 0}, + {"first": 1082, "second": 103, "amount": 0}, + {"first": 1082, "second": 99, "amount": 0}, + {"first": 1082, "second": 1077, "amount": 0}, + {"first": 1082, "second": 1105, "amount": 0}, + {"first": 1082, "second": 1086, "amount": 0}, + {"first": 1082, "second": 1089, "amount": 0}, + {"first": 1082, "second": 1092, "amount": 0}, + {"first": 1082, "second": 246, "amount": 0}, + {"first": 1082, "second": 962, "amount": 0}, + {"first": 1082, "second": 959, "amount": 0}, + {"first": 1082, "second": 945, "amount": 0}, + {"first": 1082, "second": 963, "amount": 0}, + {"first": 1051, "second": 65, "amount": 0}, + {"first": 1051, "second": 84, "amount": -1}, + {"first": 1051, "second": 89, "amount": -1}, + {"first": 1051, "second": 88, "amount": 0}, + {"first": 1051, "second": 1040, "amount": 0}, + {"first": 1051, "second": 1044, "amount": 0}, + {"first": 1051, "second": 1076, "amount": 0}, + {"first": 1051, "second": 1046, "amount": 0}, + {"first": 1051, "second": 1051, "amount": 0}, + {"first": 1051, "second": 1083, "amount": 0}, + {"first": 1051, "second": 1058, "amount": -1}, + {"first": 1051, "second": 1061, "amount": 0}, + {"first": 1051, "second": 1063, "amount": -1}, + {"first": 1051, "second": 1095, "amount": -1}, + {"first": 1051, "second": 196, "amount": 0}, + {"first": 1051, "second": 933, "amount": -1}, + {"first": 1051, "second": 913, "amount": 0}, + {"first": 1051, "second": 916, "amount": 0}, + {"first": 1051, "second": 923, "amount": 0}, + {"first": 1051, "second": 935, "amount": 0}, + {"first": 1051, "second": 197, "amount": 0}, + {"first": 1052, "second": 65, "amount": 0}, + {"first": 1052, "second": 84, "amount": -1}, + {"first": 1052, "second": 89, "amount": -1}, + {"first": 1052, "second": 88, "amount": 0}, + {"first": 1052, "second": 1040, "amount": 0}, + {"first": 1052, "second": 1044, "amount": 0}, + {"first": 1052, "second": 1076, "amount": 0}, + {"first": 1052, "second": 1046, "amount": 0}, + {"first": 1052, "second": 1051, "amount": 0}, + {"first": 1052, "second": 1083, "amount": 0}, + {"first": 1052, "second": 1058, "amount": -1}, + {"first": 1052, "second": 1061, "amount": 0}, + {"first": 1052, "second": 1063, "amount": -1}, + {"first": 1052, "second": 1095, "amount": -1}, + {"first": 1052, "second": 196, "amount": 0}, + {"first": 1052, "second": 933, "amount": -1}, + {"first": 1052, "second": 913, "amount": 0}, + {"first": 1052, "second": 916, "amount": 0}, + {"first": 1052, "second": 923, "amount": 0}, + {"first": 1052, "second": 935, "amount": 0}, + {"first": 1052, "second": 197, "amount": 0}, + {"first": 1053, "second": 65, "amount": 0}, + {"first": 1053, "second": 84, "amount": -1}, + {"first": 1053, "second": 89, "amount": -1}, + {"first": 1053, "second": 88, "amount": 0}, + {"first": 1053, "second": 1040, "amount": 0}, + {"first": 1053, "second": 1044, "amount": 0}, + {"first": 1053, "second": 1076, "amount": 0}, + {"first": 1053, "second": 1046, "amount": 0}, + {"first": 1053, "second": 1051, "amount": 0}, + {"first": 1053, "second": 1083, "amount": 0}, + {"first": 1053, "second": 1058, "amount": -1}, + {"first": 1053, "second": 1061, "amount": 0}, + {"first": 1053, "second": 1063, "amount": -1}, + {"first": 1053, "second": 1095, "amount": -1}, + {"first": 1053, "second": 196, "amount": 0}, + {"first": 1053, "second": 933, "amount": -1}, + {"first": 1053, "second": 913, "amount": 0}, + {"first": 1053, "second": 916, "amount": 0}, + {"first": 1053, "second": 923, "amount": 0}, + {"first": 1053, "second": 935, "amount": 0}, + {"first": 1053, "second": 197, "amount": 0}, + {"first": 1054, "second": 65, "amount": 0}, + {"first": 1054, "second": 90, "amount": 0}, + {"first": 1054, "second": 84, "amount": -1}, + {"first": 1054, "second": 89, "amount": -1}, + {"first": 1054, "second": 88, "amount": 0}, + {"first": 1054, "second": 86, "amount": 0}, + {"first": 1054, "second": 44, "amount": -2}, + {"first": 1054, "second": 46, "amount": -2}, + {"first": 1054, "second": 1040, "amount": 0}, + {"first": 1054, "second": 1044, "amount": -1}, + {"first": 1054, "second": 1046, "amount": 0}, + {"first": 1054, "second": 1051, "amount": -1}, + {"first": 1054, "second": 1058, "amount": -1}, + {"first": 1054, "second": 1061, "amount": 0}, + {"first": 1054, "second": 1068, "amount": -1}, + {"first": 1054, "second": 196, "amount": 0}, + {"first": 1054, "second": 955, "amount": 0}, + {"first": 1054, "second": 933, "amount": -1}, + {"first": 1054, "second": 913, "amount": 0}, + {"first": 1054, "second": 931, "amount": 0}, + {"first": 1054, "second": 916, "amount": 0}, + {"first": 1054, "second": 926, "amount": 0}, + {"first": 1054, "second": 923, "amount": 0}, + {"first": 1054, "second": 918, "amount": 0}, + {"first": 1054, "second": 935, "amount": 0}, + {"first": 1054, "second": 197, "amount": 0}, + {"first": 1054, "second": 198, "amount": -1}, + {"first": 1086, "second": 122, "amount": 0}, + {"first": 1086, "second": 121, "amount": 0}, + {"first": 1086, "second": 120, "amount": 0}, + {"first": 1086, "second": 118, "amount": 0}, + {"first": 1086, "second": 34, "amount": -3}, + {"first": 1086, "second": 39, "amount": -3}, + {"first": 1086, "second": 1076, "amount": -1}, + {"first": 1086, "second": 1078, "amount": 0}, + {"first": 1086, "second": 1083, "amount": 0}, + {"first": 1086, "second": 1090, "amount": 0}, + {"first": 1086, "second": 1091, "amount": 0}, + {"first": 1086, "second": 1093, "amount": 0}, + {"first": 1086, "second": 964, "amount": 0}, + {"first": 1086, "second": 947, "amount": 0}, + {"first": 1086, "second": 957, "amount": 0}, + {"first": 1056, "second": 97, "amount": 0}, + {"first": 1056, "second": 101, "amount": 0}, + {"first": 1056, "second": 116, "amount": 0}, + {"first": 1056, "second": 121, "amount": 0}, + {"first": 1056, "second": 111, "amount": 0}, + {"first": 1056, "second": 113, "amount": 0}, + {"first": 1056, "second": 100, "amount": 0}, + {"first": 1056, "second": 103, "amount": 0}, + {"first": 1056, "second": 99, "amount": 0}, + {"first": 1056, "second": 118, "amount": 0}, + {"first": 1056, "second": 65, "amount": -3}, + {"first": 1056, "second": 90, "amount": -1}, + {"first": 1056, "second": 74, "amount": -4}, + {"first": 1056, "second": 88, "amount": -1}, + {"first": 1056, "second": 44, "amount": -7}, + {"first": 1056, "second": 46, "amount": -7}, + {"first": 1056, "second": 1040, "amount": -3}, + {"first": 1056, "second": 1072, "amount": 0}, + {"first": 1056, "second": 1044, "amount": -2}, + {"first": 1056, "second": 1076, "amount": -1}, + {"first": 1056, "second": 1077, "amount": 0}, + {"first": 1056, "second": 1105, "amount": 0}, + {"first": 1056, "second": 1046, "amount": -1}, + {"first": 1056, "second": 1051, "amount": -1}, + {"first": 1056, "second": 1083, "amount": -1}, + {"first": 1056, "second": 1086, "amount": 0}, + {"first": 1056, "second": 1089, "amount": 0}, + {"first": 1056, "second": 1091, "amount": 0}, + {"first": 1056, "second": 1092, "amount": 0}, + {"first": 1056, "second": 1061, "amount": -1}, + {"first": 1056, "second": 246, "amount": 0}, + {"first": 1056, "second": 228, "amount": 0}, + {"first": 1056, "second": 196, "amount": -3}, + {"first": 1056, "second": 962, "amount": 0}, + {"first": 1056, "second": 961, "amount": -1}, + {"first": 1056, "second": 959, "amount": 0}, + {"first": 1056, "second": 945, "amount": 0}, + {"first": 1056, "second": 963, "amount": 0}, + {"first": 1056, "second": 948, "amount": 0}, + {"first": 1056, "second": 947, "amount": 0}, + {"first": 1056, "second": 955, "amount": -1}, + {"first": 1056, "second": 957, "amount": 0}, + {"first": 1056, "second": 913, "amount": -3}, + {"first": 1056, "second": 916, "amount": -3}, + {"first": 1056, "second": 923, "amount": -3}, + {"first": 1056, "second": 918, "amount": -1}, + {"first": 1056, "second": 935, "amount": -1}, + {"first": 1056, "second": 229, "amount": 0}, + {"first": 1056, "second": 197, "amount": -3}, + {"first": 1056, "second": 198, "amount": -2}, + {"first": 1088, "second": 122, "amount": 0}, + {"first": 1088, "second": 121, "amount": 0}, + {"first": 1088, "second": 120, "amount": 0}, + {"first": 1088, "second": 118, "amount": 0}, + {"first": 1088, "second": 34, "amount": -1}, + {"first": 1088, "second": 39, "amount": -1}, + {"first": 1088, "second": 1076, "amount": 0}, + {"first": 1088, "second": 1078, "amount": 0}, + {"first": 1088, "second": 1083, "amount": 0}, + {"first": 1088, "second": 1090, "amount": -2}, + {"first": 1088, "second": 1091, "amount": 0}, + {"first": 1088, "second": 1093, "amount": 0}, + {"first": 1088, "second": 964, "amount": 0}, + {"first": 1088, "second": 947, "amount": 0}, + {"first": 1088, "second": 957, "amount": 0}, + {"first": 1057, "second": 84, "amount": -1}, + {"first": 1057, "second": 125, "amount": 0}, + {"first": 1057, "second": 41, "amount": -1}, + {"first": 1057, "second": 93, "amount": 0}, + {"first": 1057, "second": 1058, "amount": -1}, + {"first": 1089, "second": 34, "amount": 0}, + {"first": 1089, "second": 39, "amount": 0}, + {"first": 1058, "second": 97, "amount": -2}, + {"first": 1058, "second": 122, "amount": -1}, + {"first": 1058, "second": 101, "amount": -2}, + {"first": 1058, "second": 114, "amount": -2}, + {"first": 1058, "second": 121, "amount": -1}, + {"first": 1058, "second": 117, "amount": -2}, + {"first": 1058, "second": 111, "amount": -2}, + {"first": 1058, "second": 112, "amount": -2}, + {"first": 1058, "second": 113, "amount": -2}, + {"first": 1058, "second": 115, "amount": -2}, + {"first": 1058, "second": 100, "amount": -2}, + {"first": 1058, "second": 103, "amount": -2}, + {"first": 1058, "second": 109, "amount": -2}, + {"first": 1058, "second": 119, "amount": -1}, + {"first": 1058, "second": 120, "amount": -2}, + {"first": 1058, "second": 99, "amount": -2}, + {"first": 1058, "second": 118, "amount": -1}, + {"first": 1058, "second": 110, "amount": -2}, + {"first": 1058, "second": 65, "amount": -2}, + {"first": 1058, "second": 84, "amount": 0}, + {"first": 1058, "second": 89, "amount": 0}, + {"first": 1058, "second": 79, "amount": -1}, + {"first": 1058, "second": 81, "amount": -1}, + {"first": 1058, "second": 83, "amount": 0}, + {"first": 1058, "second": 71, "amount": -1}, + {"first": 1058, "second": 74, "amount": -5}, + {"first": 1058, "second": 87, "amount": 0}, + {"first": 1058, "second": 67, "amount": -1}, + {"first": 1058, "second": 86, "amount": 0}, + {"first": 1058, "second": 45, "amount": -5}, + {"first": 1058, "second": 8211, "amount": -5}, + {"first": 1058, "second": 44, "amount": -4}, + {"first": 1058, "second": 46, "amount": -4}, + {"first": 1058, "second": 1040, "amount": -2}, + {"first": 1058, "second": 1072, "amount": -2}, + {"first": 1058, "second": 1073, "amount": -1}, + {"first": 1058, "second": 1074, "amount": -2}, + {"first": 1058, "second": 1075, "amount": -2}, + {"first": 1058, "second": 1044, "amount": -2}, + {"first": 1058, "second": 1076, "amount": -3}, + {"first": 1058, "second": 1077, "amount": -2}, + {"first": 1058, "second": 1105, "amount": -2}, + {"first": 1058, "second": 1078, "amount": -2}, + {"first": 1058, "second": 1079, "amount": -3}, + {"first": 1058, "second": 1080, "amount": -2}, + {"first": 1058, "second": 1081, "amount": -2}, + {"first": 1058, "second": 1082, "amount": -2}, + {"first": 1058, "second": 1051, "amount": -1}, + {"first": 1058, "second": 1083, "amount": -3}, + {"first": 1058, "second": 1084, "amount": -2}, + {"first": 1058, "second": 1085, "amount": -2}, + {"first": 1058, "second": 1054, "amount": -1}, + {"first": 1058, "second": 1086, "amount": -2}, + {"first": 1058, "second": 1087, "amount": -2}, + {"first": 1058, "second": 1088, "amount": -2}, + {"first": 1058, "second": 1057, "amount": -1}, + {"first": 1058, "second": 1089, "amount": -2}, + {"first": 1058, "second": 1058, "amount": 0}, + {"first": 1058, "second": 1090, "amount": -2}, + {"first": 1058, "second": 1091, "amount": -1}, + {"first": 1058, "second": 1092, "amount": -2}, + {"first": 1058, "second": 1093, "amount": -2}, + {"first": 1058, "second": 1094, "amount": -2}, + {"first": 1058, "second": 1095, "amount": -3}, + {"first": 1058, "second": 1096, "amount": -2}, + {"first": 1058, "second": 1097, "amount": -2}, + {"first": 1058, "second": 1099, "amount": -3}, + {"first": 1058, "second": 1068, "amount": 0}, + {"first": 1058, "second": 1100, "amount": -2}, + {"first": 1058, "second": 1101, "amount": -3}, + {"first": 1058, "second": 1102, "amount": -2}, + {"first": 1058, "second": 1103, "amount": -3}, + {"first": 1058, "second": 252, "amount": -2}, + {"first": 1058, "second": 246, "amount": -2}, + {"first": 1058, "second": 214, "amount": -1}, + {"first": 1058, "second": 228, "amount": -2}, + {"first": 1058, "second": 196, "amount": -2}, + {"first": 1058, "second": 241, "amount": -2}, + {"first": 1058, "second": 962, "amount": -2}, + {"first": 1058, "second": 949, "amount": -3}, + {"first": 1058, "second": 961, "amount": -3}, + {"first": 1058, "second": 964, "amount": -2}, + {"first": 1058, "second": 965, "amount": -2}, + {"first": 1058, "second": 953, "amount": -3}, + {"first": 1058, "second": 959, "amount": -2}, + {"first": 1058, "second": 960, "amount": -2}, + {"first": 1058, "second": 945, "amount": -2}, + {"first": 1058, "second": 963, "amount": -2}, + {"first": 1058, "second": 948, "amount": -1}, + {"first": 1058, "second": 966, "amount": -3}, + {"first": 1058, "second": 947, "amount": -1}, + {"first": 1058, "second": 951, "amount": -2}, + {"first": 1058, "second": 968, "amount": -3}, + {"first": 1058, "second": 969, "amount": -3}, + {"first": 1058, "second": 957, "amount": -1}, + {"first": 1058, "second": 933, "amount": 0}, + {"first": 1058, "second": 920, "amount": -1}, + {"first": 1058, "second": 927, "amount": -1}, + {"first": 1058, "second": 913, "amount": -2}, + {"first": 1058, "second": 916, "amount": -2}, + {"first": 1058, "second": 934, "amount": -2}, + {"first": 1058, "second": 923, "amount": -2}, + {"first": 1058, "second": 229, "amount": -2}, + {"first": 1058, "second": 197, "amount": -2}, + {"first": 1058, "second": 230, "amount": -2}, + {"first": 1058, "second": 198, "amount": -4}, + {"first": 1058, "second": 248, "amount": -2}, + {"first": 1058, "second": 216, "amount": -1}, + {"first": 1090, "second": 97, "amount": 0}, + {"first": 1090, "second": 101, "amount": -2}, + {"first": 1090, "second": 121, "amount": 0}, + {"first": 1090, "second": 111, "amount": -1}, + {"first": 1090, "second": 113, "amount": -2}, + {"first": 1090, "second": 100, "amount": -2}, + {"first": 1090, "second": 102, "amount": 0}, + {"first": 1090, "second": 103, "amount": -2}, + {"first": 1090, "second": 99, "amount": -2}, + {"first": 1090, "second": 118, "amount": 0}, + {"first": 1090, "second": 34, "amount": 0}, + {"first": 1090, "second": 39, "amount": 0}, + {"first": 1090, "second": 1072, "amount": 0}, + {"first": 1090, "second": 1076, "amount": -2}, + {"first": 1090, "second": 1077, "amount": -2}, + {"first": 1090, "second": 1105, "amount": -2}, + {"first": 1090, "second": 1083, "amount": -2}, + {"first": 1090, "second": 1086, "amount": -1}, + {"first": 1090, "second": 1089, "amount": -2}, + {"first": 1090, "second": 1091, "amount": 0}, + {"first": 1090, "second": 1092, "amount": -2}, + {"first": 1090, "second": 246, "amount": -1}, + {"first": 1090, "second": 228, "amount": 0}, + {"first": 1090, "second": 962, "amount": -1}, + {"first": 1090, "second": 961, "amount": -2}, + {"first": 1090, "second": 959, "amount": -1}, + {"first": 1090, "second": 945, "amount": -2}, + {"first": 1090, "second": 963, "amount": -2}, + {"first": 1090, "second": 948, "amount": -2}, + {"first": 1090, "second": 966, "amount": -1}, + {"first": 1090, "second": 947, "amount": 0}, + {"first": 1090, "second": 957, "amount": 0}, + {"first": 1090, "second": 229, "amount": 0}, + {"first": 1059, "second": 97, "amount": -2}, + {"first": 1059, "second": 101, "amount": -1}, + {"first": 1059, "second": 111, "amount": -1}, + {"first": 1059, "second": 112, "amount": -2}, + {"first": 1059, "second": 113, "amount": -1}, + {"first": 1059, "second": 115, "amount": -1}, + {"first": 1059, "second": 100, "amount": -1}, + {"first": 1059, "second": 103, "amount": -1}, + {"first": 1059, "second": 109, "amount": -2}, + {"first": 1059, "second": 99, "amount": -1}, + {"first": 1059, "second": 110, "amount": -2}, + {"first": 1059, "second": 65, "amount": -2}, + {"first": 1059, "second": 84, "amount": 0}, + {"first": 1059, "second": 89, "amount": 0}, + {"first": 1059, "second": 79, "amount": 0}, + {"first": 1059, "second": 81, "amount": 0}, + {"first": 1059, "second": 71, "amount": 0}, + {"first": 1059, "second": 67, "amount": 0}, + {"first": 1059, "second": 45, "amount": -2}, + {"first": 1059, "second": 8211, "amount": -2}, + {"first": 1059, "second": 44, "amount": -8}, + {"first": 1059, "second": 46, "amount": -8}, + {"first": 1059, "second": 1040, "amount": -2}, + {"first": 1059, "second": 1072, "amount": -2}, + {"first": 1059, "second": 1074, "amount": -1}, + {"first": 1059, "second": 1075, "amount": -2}, + {"first": 1059, "second": 1044, "amount": -2}, + {"first": 1059, "second": 1076, "amount": -2}, + {"first": 1059, "second": 1077, "amount": -1}, + {"first": 1059, "second": 1105, "amount": -1}, + {"first": 1059, "second": 1079, "amount": -1}, + {"first": 1059, "second": 1080, "amount": -2}, + {"first": 1059, "second": 1081, "amount": -2}, + {"first": 1059, "second": 1082, "amount": -2}, + {"first": 1059, "second": 1051, "amount": -1}, + {"first": 1059, "second": 1083, "amount": -1}, + {"first": 1059, "second": 1084, "amount": -2}, + {"first": 1059, "second": 1085, "amount": -2}, + {"first": 1059, "second": 1054, "amount": 0}, + {"first": 1059, "second": 1086, "amount": -1}, + {"first": 1059, "second": 1087, "amount": -2}, + {"first": 1059, "second": 1088, "amount": -2}, + {"first": 1059, "second": 1057, "amount": 0}, + {"first": 1059, "second": 1089, "amount": -1}, + {"first": 1059, "second": 1058, "amount": 0}, + {"first": 1059, "second": 1092, "amount": -1}, + {"first": 1059, "second": 1094, "amount": -2}, + {"first": 1059, "second": 1095, "amount": 0}, + {"first": 1059, "second": 1096, "amount": -2}, + {"first": 1059, "second": 1097, "amount": -2}, + {"first": 1059, "second": 1099, "amount": -1}, + {"first": 1059, "second": 1068, "amount": 0}, + {"first": 1059, "second": 1100, "amount": -2}, + {"first": 1059, "second": 1102, "amount": -2}, + {"first": 1059, "second": 1103, "amount": -1}, + {"first": 1059, "second": 246, "amount": -1}, + {"first": 1059, "second": 214, "amount": 0}, + {"first": 1059, "second": 228, "amount": -2}, + {"first": 1059, "second": 196, "amount": -2}, + {"first": 1059, "second": 241, "amount": -2}, + {"first": 1059, "second": 962, "amount": -1}, + {"first": 1059, "second": 959, "amount": -1}, + {"first": 1059, "second": 945, "amount": -1}, + {"first": 1059, "second": 963, "amount": -1}, + {"first": 1059, "second": 951, "amount": -2}, + {"first": 1059, "second": 933, "amount": 0}, + {"first": 1059, "second": 920, "amount": 0}, + {"first": 1059, "second": 927, "amount": 0}, + {"first": 1059, "second": 913, "amount": -2}, + {"first": 1059, "second": 916, "amount": -2}, + {"first": 1059, "second": 923, "amount": -2}, + {"first": 1059, "second": 229, "amount": -2}, + {"first": 1059, "second": 197, "amount": -2}, + {"first": 1059, "second": 216, "amount": 0}, + {"first": 1091, "second": 97, "amount": 0}, + {"first": 1091, "second": 101, "amount": 0}, + {"first": 1091, "second": 111, "amount": 0}, + {"first": 1091, "second": 113, "amount": 0}, + {"first": 1091, "second": 100, "amount": 0}, + {"first": 1091, "second": 102, "amount": 0}, + {"first": 1091, "second": 103, "amount": 0}, + {"first": 1091, "second": 99, "amount": 0}, + {"first": 1091, "second": 44, "amount": -2}, + {"first": 1091, "second": 46, "amount": -2}, + {"first": 1091, "second": 34, "amount": 0}, + {"first": 1091, "second": 39, "amount": 0}, + {"first": 1091, "second": 1072, "amount": 0}, + {"first": 1091, "second": 1076, "amount": -1}, + {"first": 1091, "second": 1077, "amount": 0}, + {"first": 1091, "second": 1105, "amount": 0}, + {"first": 1091, "second": 1083, "amount": -1}, + {"first": 1091, "second": 1086, "amount": 0}, + {"first": 1091, "second": 1089, "amount": 0}, + {"first": 1091, "second": 1092, "amount": 0}, + {"first": 1091, "second": 246, "amount": 0}, + {"first": 1091, "second": 228, "amount": 0}, + {"first": 1091, "second": 962, "amount": 0}, + {"first": 1091, "second": 961, "amount": 0}, + {"first": 1091, "second": 964, "amount": 0}, + {"first": 1091, "second": 959, "amount": 0}, + {"first": 1091, "second": 960, "amount": 0}, + {"first": 1091, "second": 945, "amount": 0}, + {"first": 1091, "second": 963, "amount": 0}, + {"first": 1091, "second": 948, "amount": 0}, + {"first": 1091, "second": 229, "amount": 0}, + {"first": 1092, "second": 122, "amount": 0}, + {"first": 1092, "second": 121, "amount": 0}, + {"first": 1092, "second": 120, "amount": 0}, + {"first": 1092, "second": 118, "amount": 0}, + {"first": 1092, "second": 34, "amount": -1}, + {"first": 1092, "second": 39, "amount": -1}, + {"first": 1092, "second": 1076, "amount": 0}, + {"first": 1092, "second": 1078, "amount": 0}, + {"first": 1092, "second": 1083, "amount": 0}, + {"first": 1092, "second": 1090, "amount": -2}, + {"first": 1092, "second": 1091, "amount": 0}, + {"first": 1092, "second": 1093, "amount": 0}, + {"first": 1092, "second": 964, "amount": 0}, + {"first": 1092, "second": 947, "amount": 0}, + {"first": 1092, "second": 957, "amount": 0}, + {"first": 1061, "second": 101, "amount": -1}, + {"first": 1061, "second": 121, "amount": -1}, + {"first": 1061, "second": 117, "amount": 0}, + {"first": 1061, "second": 111, "amount": 0}, + {"first": 1061, "second": 113, "amount": -1}, + {"first": 1061, "second": 100, "amount": -1}, + {"first": 1061, "second": 103, "amount": -1}, + {"first": 1061, "second": 99, "amount": -1}, + {"first": 1061, "second": 118, "amount": -1}, + {"first": 1061, "second": 79, "amount": -1}, + {"first": 1061, "second": 81, "amount": -1}, + {"first": 1061, "second": 71, "amount": -1}, + {"first": 1061, "second": 67, "amount": -1}, + {"first": 1061, "second": 86, "amount": 0}, + {"first": 1061, "second": 45, "amount": -1}, + {"first": 1061, "second": 8211, "amount": -1}, + {"first": 1061, "second": 1073, "amount": 0}, + {"first": 1061, "second": 1044, "amount": 0}, + {"first": 1061, "second": 1077, "amount": -1}, + {"first": 1061, "second": 1105, "amount": -1}, + {"first": 1061, "second": 1051, "amount": 0}, + {"first": 1061, "second": 1083, "amount": 0}, + {"first": 1061, "second": 1054, "amount": -1}, + {"first": 1061, "second": 1086, "amount": 0}, + {"first": 1061, "second": 1057, "amount": -1}, + {"first": 1061, "second": 1089, "amount": -1}, + {"first": 1061, "second": 1090, "amount": -1}, + {"first": 1061, "second": 1091, "amount": -1}, + {"first": 1061, "second": 1092, "amount": -1}, + {"first": 1061, "second": 1095, "amount": -1}, + {"first": 1061, "second": 252, "amount": 0}, + {"first": 1061, "second": 246, "amount": 0}, + {"first": 1061, "second": 214, "amount": -1}, + {"first": 1061, "second": 962, "amount": -1}, + {"first": 1061, "second": 964, "amount": -1}, + {"first": 1061, "second": 965, "amount": 0}, + {"first": 1061, "second": 952, "amount": 0}, + {"first": 1061, "second": 959, "amount": 0}, + {"first": 1061, "second": 945, "amount": -1}, + {"first": 1061, "second": 963, "amount": -1}, + {"first": 1061, "second": 948, "amount": 0}, + {"first": 1061, "second": 966, "amount": -1}, + {"first": 1061, "second": 947, "amount": -1}, + {"first": 1061, "second": 955, "amount": 0}, + {"first": 1061, "second": 968, "amount": -1}, + {"first": 1061, "second": 969, "amount": 0}, + {"first": 1061, "second": 957, "amount": -1}, + {"first": 1061, "second": 920, "amount": -1}, + {"first": 1061, "second": 927, "amount": -1}, + {"first": 1061, "second": 934, "amount": -1}, + {"first": 1061, "second": 216, "amount": -1}, + {"first": 1093, "second": 101, "amount": 0}, + {"first": 1093, "second": 111, "amount": 0}, + {"first": 1093, "second": 113, "amount": 0}, + {"first": 1093, "second": 100, "amount": 0}, + {"first": 1093, "second": 103, "amount": 0}, + {"first": 1093, "second": 99, "amount": 0}, + {"first": 1093, "second": 1077, "amount": 0}, + {"first": 1093, "second": 1105, "amount": 0}, + {"first": 1093, "second": 1086, "amount": 0}, + {"first": 1093, "second": 1089, "amount": 0}, + {"first": 1093, "second": 1092, "amount": 0}, + {"first": 1093, "second": 246, "amount": 0}, + {"first": 1093, "second": 962, "amount": 0}, + {"first": 1093, "second": 959, "amount": 0}, + {"first": 1093, "second": 945, "amount": 0}, + {"first": 1093, "second": 963, "amount": 0}, + {"first": 1062, "second": 65, "amount": 0}, + {"first": 1062, "second": 84, "amount": -1}, + {"first": 1062, "second": 89, "amount": -1}, + {"first": 1062, "second": 88, "amount": 0}, + {"first": 1062, "second": 1040, "amount": 0}, + {"first": 1062, "second": 1044, "amount": 0}, + {"first": 1062, "second": 1076, "amount": 0}, + {"first": 1062, "second": 1046, "amount": 0}, + {"first": 1062, "second": 1051, "amount": 0}, + {"first": 1062, "second": 1083, "amount": 0}, + {"first": 1062, "second": 1058, "amount": -1}, + {"first": 1062, "second": 1061, "amount": 0}, + {"first": 1062, "second": 1063, "amount": -1}, + {"first": 1062, "second": 1095, "amount": -1}, + {"first": 1062, "second": 196, "amount": 0}, + {"first": 1062, "second": 933, "amount": -1}, + {"first": 1062, "second": 913, "amount": 0}, + {"first": 1062, "second": 916, "amount": 0}, + {"first": 1062, "second": 923, "amount": 0}, + {"first": 1062, "second": 935, "amount": 0}, + {"first": 1062, "second": 197, "amount": 0}, + {"first": 1094, "second": 1076, "amount": 0}, + {"first": 1094, "second": 1083, "amount": 0}, + {"first": 1094, "second": 1090, "amount": 0}, + {"first": 1094, "second": 1095, "amount": 0}, + {"first": 1094, "second": 1103, "amount": 0}, + {"first": 1063, "second": 65, "amount": 0}, + {"first": 1063, "second": 84, "amount": -1}, + {"first": 1063, "second": 89, "amount": -1}, + {"first": 1063, "second": 88, "amount": 0}, + {"first": 1063, "second": 1040, "amount": 0}, + {"first": 1063, "second": 1044, "amount": 0}, + {"first": 1063, "second": 1076, "amount": 0}, + {"first": 1063, "second": 1046, "amount": 0}, + {"first": 1063, "second": 1051, "amount": 0}, + {"first": 1063, "second": 1083, "amount": 0}, + {"first": 1063, "second": 1058, "amount": -1}, + {"first": 1063, "second": 1061, "amount": 0}, + {"first": 1063, "second": 1063, "amount": -1}, + {"first": 1063, "second": 1095, "amount": -1}, + {"first": 1063, "second": 196, "amount": 0}, + {"first": 1063, "second": 933, "amount": -1}, + {"first": 1063, "second": 913, "amount": 0}, + {"first": 1063, "second": 916, "amount": 0}, + {"first": 1063, "second": 923, "amount": 0}, + {"first": 1063, "second": 935, "amount": 0}, + {"first": 1063, "second": 197, "amount": 0}, + {"first": 1064, "second": 65, "amount": 0}, + {"first": 1064, "second": 84, "amount": -1}, + {"first": 1064, "second": 89, "amount": -1}, + {"first": 1064, "second": 88, "amount": 0}, + {"first": 1064, "second": 1040, "amount": 0}, + {"first": 1064, "second": 1044, "amount": 0}, + {"first": 1064, "second": 1076, "amount": 0}, + {"first": 1064, "second": 1046, "amount": 0}, + {"first": 1064, "second": 1051, "amount": 0}, + {"first": 1064, "second": 1083, "amount": 0}, + {"first": 1064, "second": 1058, "amount": -1}, + {"first": 1064, "second": 1061, "amount": 0}, + {"first": 1064, "second": 1063, "amount": -1}, + {"first": 1064, "second": 1095, "amount": -1}, + {"first": 1064, "second": 196, "amount": 0}, + {"first": 1064, "second": 933, "amount": -1}, + {"first": 1064, "second": 913, "amount": 0}, + {"first": 1064, "second": 916, "amount": 0}, + {"first": 1064, "second": 923, "amount": 0}, + {"first": 1064, "second": 935, "amount": 0}, + {"first": 1064, "second": 197, "amount": 0}, + {"first": 1065, "second": 65, "amount": 0}, + {"first": 1065, "second": 84, "amount": -1}, + {"first": 1065, "second": 89, "amount": -1}, + {"first": 1065, "second": 88, "amount": 0}, + {"first": 1065, "second": 86, "amount": -1}, + {"first": 1065, "second": 1040, "amount": 0}, + {"first": 1065, "second": 1044, "amount": 0}, + {"first": 1065, "second": 1076, "amount": 0}, + {"first": 1065, "second": 1046, "amount": 0}, + {"first": 1065, "second": 1051, "amount": 0}, + {"first": 1065, "second": 1083, "amount": 0}, + {"first": 1065, "second": 1058, "amount": -1}, + {"first": 1065, "second": 1090, "amount": -1}, + {"first": 1065, "second": 1059, "amount": 0}, + {"first": 1065, "second": 1061, "amount": 0}, + {"first": 1065, "second": 1063, "amount": -1}, + {"first": 1065, "second": 1095, "amount": 0}, + {"first": 1065, "second": 1068, "amount": -1}, + {"first": 1065, "second": 1069, "amount": 0}, + {"first": 1065, "second": 196, "amount": 0}, + {"first": 1065, "second": 933, "amount": -1}, + {"first": 1065, "second": 913, "amount": 0}, + {"first": 1065, "second": 916, "amount": 0}, + {"first": 1065, "second": 923, "amount": 0}, + {"first": 1065, "second": 935, "amount": 0}, + {"first": 1065, "second": 197, "amount": 0}, + {"first": 1097, "second": 101, "amount": 0}, + {"first": 1097, "second": 113, "amount": 0}, + {"first": 1097, "second": 100, "amount": 0}, + {"first": 1097, "second": 103, "amount": 0}, + {"first": 1097, "second": 99, "amount": 0}, + {"first": 1097, "second": 1076, "amount": 1}, + {"first": 1097, "second": 1077, "amount": 0}, + {"first": 1097, "second": 1105, "amount": 0}, + {"first": 1097, "second": 1083, "amount": 0}, + {"first": 1097, "second": 1089, "amount": 0}, + {"first": 1097, "second": 1090, "amount": -1}, + {"first": 1097, "second": 1092, "amount": 0}, + {"first": 1097, "second": 1095, "amount": 0}, + {"first": 1097, "second": 962, "amount": 0}, + {"first": 1097, "second": 945, "amount": 0}, + {"first": 1097, "second": 963, "amount": 0}, + {"first": 1066, "second": 120, "amount": -1}, + {"first": 1066, "second": 84, "amount": -5}, + {"first": 1066, "second": 89, "amount": -2}, + {"first": 1066, "second": 88, "amount": 0}, + {"first": 1066, "second": 86, "amount": -1}, + {"first": 1066, "second": 34, "amount": -1}, + {"first": 1066, "second": 39, "amount": -1}, + {"first": 1066, "second": 1046, "amount": 0}, + {"first": 1066, "second": 1078, "amount": -1}, + {"first": 1066, "second": 1051, "amount": 0}, + {"first": 1066, "second": 1058, "amount": -5}, + {"first": 1066, "second": 1090, "amount": -1}, + {"first": 1066, "second": 1059, "amount": 0}, + {"first": 1066, "second": 1061, "amount": 0}, + {"first": 1066, "second": 1093, "amount": -1}, + {"first": 1066, "second": 1063, "amount": -1}, + {"first": 1066, "second": 1068, "amount": -1}, + {"first": 1066, "second": 933, "amount": -2}, + {"first": 1066, "second": 935, "amount": 0}, + {"first": 1098, "second": 121, "amount": -1}, + {"first": 1098, "second": 120, "amount": 0}, + {"first": 1098, "second": 118, "amount": -1}, + {"first": 1098, "second": 34, "amount": -3}, + {"first": 1098, "second": 39, "amount": -3}, + {"first": 1098, "second": 1078, "amount": 0}, + {"first": 1098, "second": 1090, "amount": -1}, + {"first": 1098, "second": 1091, "amount": -1}, + {"first": 1098, "second": 1093, "amount": 0}, + {"first": 1098, "second": 1095, "amount": -1}, + {"first": 1098, "second": 947, "amount": -1}, + {"first": 1098, "second": 957, "amount": -1}, + {"first": 1067, "second": 65, "amount": 0}, + {"first": 1067, "second": 84, "amount": -1}, + {"first": 1067, "second": 89, "amount": -1}, + {"first": 1067, "second": 88, "amount": 0}, + {"first": 1067, "second": 1040, "amount": 0}, + {"first": 1067, "second": 1044, "amount": 0}, + {"first": 1067, "second": 1076, "amount": 0}, + {"first": 1067, "second": 1046, "amount": 0}, + {"first": 1067, "second": 1051, "amount": 0}, + {"first": 1067, "second": 1083, "amount": 0}, + {"first": 1067, "second": 1058, "amount": -1}, + {"first": 1067, "second": 1061, "amount": 0}, + {"first": 1067, "second": 1063, "amount": -1}, + {"first": 1067, "second": 1095, "amount": -1}, + {"first": 1067, "second": 196, "amount": 0}, + {"first": 1067, "second": 933, "amount": -1}, + {"first": 1067, "second": 913, "amount": 0}, + {"first": 1067, "second": 916, "amount": 0}, + {"first": 1067, "second": 923, "amount": 0}, + {"first": 1067, "second": 935, "amount": 0}, + {"first": 1067, "second": 197, "amount": 0}, + {"first": 1068, "second": 120, "amount": -1}, + {"first": 1068, "second": 84, "amount": -5}, + {"first": 1068, "second": 89, "amount": -2}, + {"first": 1068, "second": 88, "amount": 0}, + {"first": 1068, "second": 86, "amount": -1}, + {"first": 1068, "second": 34, "amount": -1}, + {"first": 1068, "second": 39, "amount": -1}, + {"first": 1068, "second": 1046, "amount": 0}, + {"first": 1068, "second": 1078, "amount": -1}, + {"first": 1068, "second": 1051, "amount": 0}, + {"first": 1068, "second": 1058, "amount": -5}, + {"first": 1068, "second": 1090, "amount": -1}, + {"first": 1068, "second": 1059, "amount": 0}, + {"first": 1068, "second": 1061, "amount": 0}, + {"first": 1068, "second": 1093, "amount": -1}, + {"first": 1068, "second": 1063, "amount": -1}, + {"first": 1068, "second": 1068, "amount": -1}, + {"first": 1068, "second": 933, "amount": -2}, + {"first": 1068, "second": 935, "amount": 0}, + {"first": 1100, "second": 121, "amount": -1}, + {"first": 1100, "second": 120, "amount": 0}, + {"first": 1100, "second": 118, "amount": -1}, + {"first": 1100, "second": 34, "amount": -3}, + {"first": 1100, "second": 39, "amount": -3}, + {"first": 1100, "second": 1078, "amount": 0}, + {"first": 1100, "second": 1090, "amount": -1}, + {"first": 1100, "second": 1091, "amount": -1}, + {"first": 1100, "second": 1093, "amount": 0}, + {"first": 1100, "second": 1095, "amount": -1}, + {"first": 1100, "second": 947, "amount": -1}, + {"first": 1100, "second": 957, "amount": -1}, + {"first": 1069, "second": 84, "amount": -1}, + {"first": 1069, "second": 89, "amount": -1}, + {"first": 1069, "second": 88, "amount": -1}, + {"first": 1069, "second": 1044, "amount": -1}, + {"first": 1069, "second": 1046, "amount": -1}, + {"first": 1069, "second": 1051, "amount": -1}, + {"first": 1069, "second": 1083, "amount": 0}, + {"first": 1069, "second": 1058, "amount": -1}, + {"first": 1069, "second": 1059, "amount": 0}, + {"first": 1069, "second": 1061, "amount": -1}, + {"first": 1069, "second": 933, "amount": -1}, + {"first": 1069, "second": 935, "amount": -1}, + {"first": 1101, "second": 122, "amount": 0}, + {"first": 1101, "second": 121, "amount": 0}, + {"first": 1101, "second": 120, "amount": 0}, + {"first": 1101, "second": 118, "amount": 0}, + {"first": 1101, "second": 34, "amount": -1}, + {"first": 1101, "second": 39, "amount": -1}, + {"first": 1101, "second": 1076, "amount": 0}, + {"first": 1101, "second": 1078, "amount": 0}, + {"first": 1101, "second": 1083, "amount": 0}, + {"first": 1101, "second": 1090, "amount": -2}, + {"first": 1101, "second": 1091, "amount": 0}, + {"first": 1101, "second": 1093, "amount": 0}, + {"first": 1101, "second": 964, "amount": 0}, + {"first": 1101, "second": 947, "amount": 0}, + {"first": 1101, "second": 957, "amount": 0}, + {"first": 1070, "second": 84, "amount": -1}, + {"first": 1070, "second": 88, "amount": -1}, + {"first": 1070, "second": 1044, "amount": -1}, + {"first": 1070, "second": 1076, "amount": -1}, + {"first": 1070, "second": 1046, "amount": -1}, + {"first": 1070, "second": 1051, "amount": -1}, + {"first": 1070, "second": 1083, "amount": 0}, + {"first": 1070, "second": 1058, "amount": -1}, + {"first": 1070, "second": 1059, "amount": 0}, + {"first": 1070, "second": 1061, "amount": -1}, + {"first": 1070, "second": 935, "amount": -1}, + {"first": 1102, "second": 121, "amount": 0}, + {"first": 1102, "second": 120, "amount": 0}, + {"first": 1102, "second": 118, "amount": 0}, + {"first": 1102, "second": 1076, "amount": 0}, + {"first": 1102, "second": 1078, "amount": 0}, + {"first": 1102, "second": 1083, "amount": 0}, + {"first": 1102, "second": 1091, "amount": 0}, + {"first": 1102, "second": 1093, "amount": 0}, + {"first": 1102, "second": 947, "amount": 0}, + {"first": 1102, "second": 957, "amount": 0}, + {"first": 1071, "second": 84, "amount": 0}, + {"first": 1071, "second": 89, "amount": 0}, + {"first": 1071, "second": 1058, "amount": 0}, + {"first": 1071, "second": 933, "amount": 0}, + {"first": 220, "second": 65, "amount": 0}, + {"first": 220, "second": 1040, "amount": 0}, + {"first": 220, "second": 196, "amount": 0}, + {"first": 220, "second": 913, "amount": 0}, + {"first": 220, "second": 916, "amount": 0}, + {"first": 220, "second": 923, "amount": 0}, + {"first": 220, "second": 197, "amount": 0}, + {"first": 246, "second": 122, "amount": 0}, + {"first": 246, "second": 121, "amount": 0}, + {"first": 246, "second": 120, "amount": 0}, + {"first": 246, "second": 118, "amount": 0}, + {"first": 246, "second": 34, "amount": -3}, + {"first": 246, "second": 39, "amount": -3}, + {"first": 246, "second": 1076, "amount": -1}, + {"first": 246, "second": 1078, "amount": 0}, + {"first": 246, "second": 1083, "amount": 0}, + {"first": 246, "second": 1090, "amount": 0}, + {"first": 246, "second": 1091, "amount": 0}, + {"first": 246, "second": 1093, "amount": 0}, + {"first": 246, "second": 964, "amount": 0}, + {"first": 246, "second": 947, "amount": 0}, + {"first": 246, "second": 957, "amount": 0}, + {"first": 214, "second": 65, "amount": 0}, + {"first": 214, "second": 90, "amount": 0}, + {"first": 214, "second": 84, "amount": -1}, + {"first": 214, "second": 89, "amount": -1}, + {"first": 214, "second": 88, "amount": 0}, + {"first": 214, "second": 86, "amount": 0}, + {"first": 214, "second": 44, "amount": -2}, + {"first": 214, "second": 46, "amount": -2}, + {"first": 214, "second": 1040, "amount": 0}, + {"first": 214, "second": 1044, "amount": -1}, + {"first": 214, "second": 1046, "amount": 0}, + {"first": 214, "second": 1051, "amount": -1}, + {"first": 214, "second": 1058, "amount": -1}, + {"first": 214, "second": 1061, "amount": 0}, + {"first": 214, "second": 1068, "amount": -1}, + {"first": 214, "second": 196, "amount": 0}, + {"first": 214, "second": 955, "amount": 0}, + {"first": 214, "second": 933, "amount": -1}, + {"first": 214, "second": 913, "amount": 0}, + {"first": 214, "second": 931, "amount": 0}, + {"first": 214, "second": 916, "amount": 0}, + {"first": 214, "second": 926, "amount": 0}, + {"first": 214, "second": 923, "amount": 0}, + {"first": 214, "second": 918, "amount": 0}, + {"first": 214, "second": 935, "amount": 0}, + {"first": 214, "second": 197, "amount": 0}, + {"first": 214, "second": 198, "amount": -1}, + {"first": 228, "second": 121, "amount": 0}, + {"first": 228, "second": 118, "amount": 0}, + {"first": 228, "second": 34, "amount": -1}, + {"first": 228, "second": 39, "amount": -1}, + {"first": 228, "second": 1090, "amount": 0}, + {"first": 228, "second": 1091, "amount": 0}, + {"first": 228, "second": 947, "amount": 0}, + {"first": 228, "second": 957, "amount": 0}, + {"first": 196, "second": 122, "amount": 0}, + {"first": 196, "second": 116, "amount": 0}, + {"first": 196, "second": 121, "amount": -1}, + {"first": 196, "second": 117, "amount": 0}, + {"first": 196, "second": 111, "amount": 0}, + {"first": 196, "second": 119, "amount": -1}, + {"first": 196, "second": 118, "amount": -1}, + {"first": 196, "second": 84, "amount": -3}, + {"first": 196, "second": 89, "amount": -2}, + {"first": 196, "second": 85, "amount": 0}, + {"first": 196, "second": 79, "amount": 0}, + {"first": 196, "second": 81, "amount": 0}, + {"first": 196, "second": 71, "amount": 0}, + {"first": 196, "second": 87, "amount": -1}, + {"first": 196, "second": 67, "amount": 0}, + {"first": 196, "second": 86, "amount": -2}, + {"first": 196, "second": 63, "amount": -1}, + {"first": 196, "second": 34, "amount": -2}, + {"first": 196, "second": 39, "amount": -2}, + {"first": 196, "second": 1044, "amount": 0}, + {"first": 196, "second": 1051, "amount": 0}, + {"first": 196, "second": 1083, "amount": 0}, + {"first": 196, "second": 1054, "amount": 0}, + {"first": 196, "second": 1086, "amount": 0}, + {"first": 196, "second": 1057, "amount": 0}, + {"first": 196, "second": 1058, "amount": -3}, + {"first": 196, "second": 1090, "amount": -1}, + {"first": 196, "second": 1091, "amount": -1}, + {"first": 196, "second": 1063, "amount": -1}, + {"first": 196, "second": 1095, "amount": -2}, + {"first": 196, "second": 1068, "amount": -1}, + {"first": 196, "second": 252, "amount": 0}, + {"first": 196, "second": 220, "amount": 0}, + {"first": 196, "second": 246, "amount": 0}, + {"first": 196, "second": 214, "amount": 0}, + {"first": 196, "second": 964, "amount": -1}, + {"first": 196, "second": 965, "amount": 0}, + {"first": 196, "second": 959, "amount": 0}, + {"first": 196, "second": 947, "amount": -1}, + {"first": 196, "second": 955, "amount": 0}, + {"first": 196, "second": 957, "amount": -1}, + {"first": 196, "second": 933, "amount": -2}, + {"first": 196, "second": 920, "amount": 0}, + {"first": 196, "second": 927, "amount": 0}, + {"first": 196, "second": 934, "amount": -1}, + {"first": 196, "second": 936, "amount": -1}, + {"first": 196, "second": 216, "amount": 0}, + {"first": 241, "second": 34, "amount": -2}, + {"first": 241, "second": 39, "amount": -2}, + {"first": 241, "second": 1090, "amount": -1}, + {"first": 209, "second": 65, "amount": 0}, + {"first": 209, "second": 84, "amount": -1}, + {"first": 209, "second": 89, "amount": -1}, + {"first": 209, "second": 88, "amount": 0}, + {"first": 209, "second": 1040, "amount": 0}, + {"first": 209, "second": 1044, "amount": 0}, + {"first": 209, "second": 1076, "amount": 0}, + {"first": 209, "second": 1046, "amount": 0}, + {"first": 209, "second": 1051, "amount": 0}, + {"first": 209, "second": 1083, "amount": 0}, + {"first": 209, "second": 1058, "amount": -1}, + {"first": 209, "second": 1061, "amount": 0}, + {"first": 209, "second": 1063, "amount": -1}, + {"first": 209, "second": 1095, "amount": -1}, + {"first": 209, "second": 196, "amount": 0}, + {"first": 209, "second": 933, "amount": -1}, + {"first": 209, "second": 913, "amount": 0}, + {"first": 209, "second": 916, "amount": 0}, + {"first": 209, "second": 923, "amount": 0}, + {"first": 209, "second": 935, "amount": 0}, + {"first": 209, "second": 197, "amount": 0}, + {"first": 962, "second": 1090, "amount": -1}, + {"first": 961, "second": 122, "amount": 0}, + {"first": 961, "second": 121, "amount": 0}, + {"first": 961, "second": 120, "amount": 0}, + {"first": 961, "second": 118, "amount": 0}, + {"first": 961, "second": 34, "amount": -1}, + {"first": 961, "second": 39, "amount": -1}, + {"first": 961, "second": 1076, "amount": 0}, + {"first": 961, "second": 1078, "amount": 0}, + {"first": 961, "second": 1083, "amount": 0}, + {"first": 961, "second": 1090, "amount": -2}, + {"first": 961, "second": 1091, "amount": 0}, + {"first": 961, "second": 1093, "amount": 0}, + {"first": 961, "second": 964, "amount": 0}, + {"first": 961, "second": 947, "amount": 0}, + {"first": 961, "second": 957, "amount": 0}, + {"first": 964, "second": 101, "amount": 0}, + {"first": 964, "second": 121, "amount": 0}, + {"first": 964, "second": 111, "amount": 0}, + {"first": 964, "second": 113, "amount": 0}, + {"first": 964, "second": 100, "amount": 0}, + {"first": 964, "second": 102, "amount": 0}, + {"first": 964, "second": 103, "amount": 0}, + {"first": 964, "second": 99, "amount": 0}, + {"first": 964, "second": 118, "amount": 0}, + {"first": 964, "second": 34, "amount": 0}, + {"first": 964, "second": 39, "amount": 0}, + {"first": 964, "second": 1077, "amount": 0}, + {"first": 964, "second": 1105, "amount": 0}, + {"first": 964, "second": 1086, "amount": 0}, + {"first": 964, "second": 1089, "amount": 0}, + {"first": 964, "second": 1091, "amount": 0}, + {"first": 964, "second": 1092, "amount": 0}, + {"first": 964, "second": 246, "amount": 0}, + {"first": 964, "second": 962, "amount": 0}, + {"first": 964, "second": 964, "amount": 0}, + {"first": 964, "second": 959, "amount": 0}, + {"first": 964, "second": 960, "amount": 0}, + {"first": 964, "second": 945, "amount": 0}, + {"first": 964, "second": 963, "amount": 0}, + {"first": 964, "second": 948, "amount": 0}, + {"first": 964, "second": 947, "amount": 0}, + {"first": 964, "second": 957, "amount": 0}, + {"first": 965, "second": 1090, "amount": -1}, + {"first": 953, "second": 101, "amount": 0}, + {"first": 953, "second": 121, "amount": -1}, + {"first": 953, "second": 117, "amount": 0}, + {"first": 953, "second": 113, "amount": 0}, + {"first": 953, "second": 100, "amount": 0}, + {"first": 953, "second": 103, "amount": 0}, + {"first": 953, "second": 99, "amount": 0}, + {"first": 953, "second": 118, "amount": -1}, + {"first": 953, "second": 34, "amount": -1}, + {"first": 953, "second": 39, "amount": -1}, + {"first": 953, "second": 1077, "amount": 0}, + {"first": 953, "second": 1105, "amount": 0}, + {"first": 953, "second": 1089, "amount": 0}, + {"first": 953, "second": 1091, "amount": -1}, + {"first": 953, "second": 1092, "amount": 0}, + {"first": 953, "second": 252, "amount": 0}, + {"first": 953, "second": 962, "amount": 0}, + {"first": 953, "second": 964, "amount": -1}, + {"first": 953, "second": 965, "amount": 0}, + {"first": 953, "second": 952, "amount": 0}, + {"first": 953, "second": 960, "amount": 0}, + {"first": 953, "second": 945, "amount": 0}, + {"first": 953, "second": 963, "amount": 0}, + {"first": 953, "second": 966, "amount": -1}, + {"first": 953, "second": 947, "amount": -1}, + {"first": 953, "second": 955, "amount": 0}, + {"first": 953, "second": 957, "amount": -1}, + {"first": 959, "second": 122, "amount": 0}, + {"first": 959, "second": 121, "amount": 0}, + {"first": 959, "second": 120, "amount": 0}, + {"first": 959, "second": 118, "amount": 0}, + {"first": 959, "second": 34, "amount": -3}, + {"first": 959, "second": 39, "amount": -3}, + {"first": 959, "second": 1076, "amount": -1}, + {"first": 959, "second": 1078, "amount": 0}, + {"first": 959, "second": 1083, "amount": 0}, + {"first": 959, "second": 1090, "amount": 0}, + {"first": 959, "second": 1091, "amount": 0}, + {"first": 959, "second": 1093, "amount": 0}, + {"first": 959, "second": 964, "amount": 0}, + {"first": 959, "second": 947, "amount": 0}, + {"first": 959, "second": 957, "amount": 0}, + {"first": 945, "second": 955, "amount": 0}, + {"first": 963, "second": 964, "amount": 0}, + {"first": 948, "second": 1090, "amount": -1}, + {"first": 948, "second": 964, "amount": 0}, + {"first": 966, "second": 122, "amount": 0}, + {"first": 966, "second": 120, "amount": 0}, + {"first": 966, "second": 1078, "amount": 0}, + {"first": 966, "second": 1090, "amount": -2}, + {"first": 966, "second": 1093, "amount": 0}, + {"first": 947, "second": 97, "amount": 0}, + {"first": 947, "second": 101, "amount": 0}, + {"first": 947, "second": 111, "amount": 0}, + {"first": 947, "second": 113, "amount": 0}, + {"first": 947, "second": 100, "amount": 0}, + {"first": 947, "second": 102, "amount": 0}, + {"first": 947, "second": 103, "amount": 0}, + {"first": 947, "second": 99, "amount": 0}, + {"first": 947, "second": 44, "amount": -2}, + {"first": 947, "second": 46, "amount": -2}, + {"first": 947, "second": 34, "amount": 0}, + {"first": 947, "second": 39, "amount": 0}, + {"first": 947, "second": 1072, "amount": 0}, + {"first": 947, "second": 1076, "amount": -1}, + {"first": 947, "second": 1077, "amount": 0}, + {"first": 947, "second": 1105, "amount": 0}, + {"first": 947, "second": 1083, "amount": -1}, + {"first": 947, "second": 1086, "amount": 0}, + {"first": 947, "second": 1089, "amount": 0}, + {"first": 947, "second": 1092, "amount": 0}, + {"first": 947, "second": 246, "amount": 0}, + {"first": 947, "second": 228, "amount": 0}, + {"first": 947, "second": 962, "amount": 0}, + {"first": 947, "second": 961, "amount": 0}, + {"first": 947, "second": 964, "amount": 0}, + {"first": 947, "second": 959, "amount": 0}, + {"first": 947, "second": 960, "amount": 0}, + {"first": 947, "second": 945, "amount": 0}, + {"first": 947, "second": 963, "amount": 0}, + {"first": 947, "second": 948, "amount": 0}, + {"first": 947, "second": 229, "amount": 0}, + {"first": 951, "second": 34, "amount": -2}, + {"first": 951, "second": 39, "amount": -2}, + {"first": 951, "second": 1090, "amount": -1}, + {"first": 958, "second": 101, "amount": -1}, + {"first": 958, "second": 113, "amount": -1}, + {"first": 958, "second": 100, "amount": -1}, + {"first": 958, "second": 103, "amount": -1}, + {"first": 958, "second": 99, "amount": -1}, + {"first": 958, "second": 1077, "amount": -1}, + {"first": 958, "second": 1105, "amount": -1}, + {"first": 958, "second": 1089, "amount": -1}, + {"first": 958, "second": 1092, "amount": -1}, + {"first": 958, "second": 962, "amount": -1}, + {"first": 958, "second": 945, "amount": -1}, + {"first": 958, "second": 963, "amount": -1}, + {"first": 958, "second": 955, "amount": 0}, + {"first": 955, "second": 121, "amount": -1}, + {"first": 955, "second": 117, "amount": 0}, + {"first": 955, "second": 102, "amount": 0}, + {"first": 955, "second": 118, "amount": -1}, + {"first": 955, "second": 34, "amount": -2}, + {"first": 955, "second": 39, "amount": -2}, + {"first": 955, "second": 1091, "amount": -1}, + {"first": 955, "second": 252, "amount": 0}, + {"first": 955, "second": 964, "amount": -5}, + {"first": 955, "second": 965, "amount": 0}, + {"first": 955, "second": 952, "amount": 0}, + {"first": 955, "second": 960, "amount": 0}, + {"first": 955, "second": 947, "amount": -1}, + {"first": 955, "second": 955, "amount": 0}, + {"first": 955, "second": 957, "amount": -1}, + {"first": 950, "second": 101, "amount": -1}, + {"first": 950, "second": 121, "amount": -1}, + {"first": 950, "second": 117, "amount": -1}, + {"first": 950, "second": 111, "amount": -1}, + {"first": 950, "second": 112, "amount": 0}, + {"first": 950, "second": 113, "amount": -1}, + {"first": 950, "second": 100, "amount": -1}, + {"first": 950, "second": 103, "amount": -1}, + {"first": 950, "second": 109, "amount": 0}, + {"first": 950, "second": 99, "amount": -1}, + {"first": 950, "second": 118, "amount": -1}, + {"first": 950, "second": 110, "amount": 0}, + {"first": 950, "second": 1075, "amount": 0}, + {"first": 950, "second": 1077, "amount": -1}, + {"first": 950, "second": 1105, "amount": -1}, + {"first": 950, "second": 1080, "amount": 0}, + {"first": 950, "second": 1081, "amount": 0}, + {"first": 950, "second": 1082, "amount": 0}, + {"first": 950, "second": 1084, "amount": 0}, + {"first": 950, "second": 1085, "amount": 0}, + {"first": 950, "second": 1086, "amount": -1}, + {"first": 950, "second": 1087, "amount": 0}, + {"first": 950, "second": 1088, "amount": 0}, + {"first": 950, "second": 1089, "amount": -1}, + {"first": 950, "second": 1091, "amount": -1}, + {"first": 950, "second": 1092, "amount": -1}, + {"first": 950, "second": 1094, "amount": 0}, + {"first": 950, "second": 1096, "amount": 0}, + {"first": 950, "second": 1097, "amount": 0}, + {"first": 950, "second": 1100, "amount": 0}, + {"first": 950, "second": 1102, "amount": 0}, + {"first": 950, "second": 252, "amount": -1}, + {"first": 950, "second": 246, "amount": -1}, + {"first": 950, "second": 241, "amount": 0}, + {"first": 950, "second": 962, "amount": -1}, + {"first": 950, "second": 949, "amount": -1}, + {"first": 950, "second": 964, "amount": -1}, + {"first": 950, "second": 965, "amount": -1}, + {"first": 950, "second": 952, "amount": 0}, + {"first": 950, "second": 953, "amount": 0}, + {"first": 950, "second": 959, "amount": -1}, + {"first": 950, "second": 960, "amount": -1}, + {"first": 950, "second": 945, "amount": -1}, + {"first": 950, "second": 963, "amount": -1}, + {"first": 950, "second": 948, "amount": 0}, + {"first": 950, "second": 966, "amount": -1}, + {"first": 950, "second": 947, "amount": -1}, + {"first": 950, "second": 951, "amount": 0}, + {"first": 950, "second": 958, "amount": 0}, + {"first": 950, "second": 968, "amount": -1}, + {"first": 950, "second": 969, "amount": -1}, + {"first": 950, "second": 957, "amount": -1}, + {"first": 968, "second": 122, "amount": 0}, + {"first": 968, "second": 120, "amount": 0}, + {"first": 968, "second": 1078, "amount": 0}, + {"first": 968, "second": 1093, "amount": 0}, + {"first": 969, "second": 122, "amount": 0}, + {"first": 969, "second": 121, "amount": 0}, + {"first": 969, "second": 120, "amount": 0}, + {"first": 969, "second": 118, "amount": 0}, + {"first": 969, "second": 1078, "amount": 0}, + {"first": 969, "second": 1091, "amount": 0}, + {"first": 969, "second": 1093, "amount": 0}, + {"first": 969, "second": 947, "amount": 0}, + {"first": 969, "second": 957, "amount": 0}, + {"first": 957, "second": 97, "amount": 0}, + {"first": 957, "second": 101, "amount": 0}, + {"first": 957, "second": 111, "amount": 0}, + {"first": 957, "second": 113, "amount": 0}, + {"first": 957, "second": 100, "amount": 0}, + {"first": 957, "second": 102, "amount": 0}, + {"first": 957, "second": 103, "amount": 0}, + {"first": 957, "second": 99, "amount": 0}, + {"first": 957, "second": 44, "amount": -2}, + {"first": 957, "second": 46, "amount": -2}, + {"first": 957, "second": 34, "amount": 0}, + {"first": 957, "second": 39, "amount": 0}, + {"first": 957, "second": 1072, "amount": 0}, + {"first": 957, "second": 1076, "amount": -1}, + {"first": 957, "second": 1077, "amount": 0}, + {"first": 957, "second": 1105, "amount": 0}, + {"first": 957, "second": 1083, "amount": -1}, + {"first": 957, "second": 1086, "amount": 0}, + {"first": 957, "second": 1089, "amount": 0}, + {"first": 957, "second": 1092, "amount": 0}, + {"first": 957, "second": 246, "amount": 0}, + {"first": 957, "second": 228, "amount": 0}, + {"first": 957, "second": 962, "amount": 0}, + {"first": 957, "second": 961, "amount": 0}, + {"first": 957, "second": 964, "amount": 0}, + {"first": 957, "second": 959, "amount": 0}, + {"first": 957, "second": 960, "amount": 0}, + {"first": 957, "second": 945, "amount": 0}, + {"first": 957, "second": 963, "amount": 0}, + {"first": 957, "second": 948, "amount": 0}, + {"first": 957, "second": 229, "amount": 0}, + {"first": 917, "second": 101, "amount": 0}, + {"first": 917, "second": 121, "amount": -1}, + {"first": 917, "second": 117, "amount": 0}, + {"first": 917, "second": 111, "amount": 0}, + {"first": 917, "second": 113, "amount": 0}, + {"first": 917, "second": 100, "amount": 0}, + {"first": 917, "second": 102, "amount": 0}, + {"first": 917, "second": 103, "amount": 0}, + {"first": 917, "second": 119, "amount": 0}, + {"first": 917, "second": 99, "amount": 0}, + {"first": 917, "second": 118, "amount": -1}, + {"first": 917, "second": 84, "amount": 0}, + {"first": 917, "second": 1077, "amount": 0}, + {"first": 917, "second": 1105, "amount": 0}, + {"first": 917, "second": 1086, "amount": 0}, + {"first": 917, "second": 1089, "amount": 0}, + {"first": 917, "second": 1058, "amount": 0}, + {"first": 917, "second": 1091, "amount": -1}, + {"first": 917, "second": 1092, "amount": 0}, + {"first": 917, "second": 252, "amount": 0}, + {"first": 917, "second": 246, "amount": 0}, + {"first": 917, "second": 962, "amount": 0}, + {"first": 917, "second": 965, "amount": 0}, + {"first": 917, "second": 959, "amount": 0}, + {"first": 917, "second": 945, "amount": 0}, + {"first": 917, "second": 963, "amount": 0}, + {"first": 917, "second": 947, "amount": -1}, + {"first": 917, "second": 957, "amount": -1}, + {"first": 929, "second": 97, "amount": 0}, + {"first": 929, "second": 101, "amount": 0}, + {"first": 929, "second": 116, "amount": 0}, + {"first": 929, "second": 121, "amount": 0}, + {"first": 929, "second": 111, "amount": 0}, + {"first": 929, "second": 113, "amount": 0}, + {"first": 929, "second": 100, "amount": 0}, + {"first": 929, "second": 103, "amount": 0}, + {"first": 929, "second": 99, "amount": 0}, + {"first": 929, "second": 118, "amount": 0}, + {"first": 929, "second": 65, "amount": -3}, + {"first": 929, "second": 90, "amount": -1}, + {"first": 929, "second": 74, "amount": -4}, + {"first": 929, "second": 88, "amount": -1}, + {"first": 929, "second": 44, "amount": -7}, + {"first": 929, "second": 46, "amount": -7}, + {"first": 929, "second": 1040, "amount": -3}, + {"first": 929, "second": 1072, "amount": 0}, + {"first": 929, "second": 1044, "amount": -2}, + {"first": 929, "second": 1076, "amount": -1}, + {"first": 929, "second": 1077, "amount": 0}, + {"first": 929, "second": 1105, "amount": 0}, + {"first": 929, "second": 1046, "amount": -1}, + {"first": 929, "second": 1051, "amount": -1}, + {"first": 929, "second": 1083, "amount": -1}, + {"first": 929, "second": 1086, "amount": 0}, + {"first": 929, "second": 1089, "amount": 0}, + {"first": 929, "second": 1091, "amount": 0}, + {"first": 929, "second": 1092, "amount": 0}, + {"first": 929, "second": 1061, "amount": -1}, + {"first": 929, "second": 246, "amount": 0}, + {"first": 929, "second": 228, "amount": 0}, + {"first": 929, "second": 196, "amount": -3}, + {"first": 929, "second": 962, "amount": 0}, + {"first": 929, "second": 961, "amount": -1}, + {"first": 929, "second": 959, "amount": 0}, + {"first": 929, "second": 945, "amount": 0}, + {"first": 929, "second": 963, "amount": 0}, + {"first": 929, "second": 948, "amount": 0}, + {"first": 929, "second": 947, "amount": 0}, + {"first": 929, "second": 955, "amount": -1}, + {"first": 929, "second": 957, "amount": 0}, + {"first": 929, "second": 913, "amount": -3}, + {"first": 929, "second": 916, "amount": -3}, + {"first": 929, "second": 923, "amount": -3}, + {"first": 929, "second": 918, "amount": -1}, + {"first": 929, "second": 935, "amount": -1}, + {"first": 929, "second": 229, "amount": 0}, + {"first": 929, "second": 197, "amount": -3}, + {"first": 929, "second": 198, "amount": -2}, + {"first": 932, "second": 97, "amount": -2}, + {"first": 932, "second": 122, "amount": -1}, + {"first": 932, "second": 101, "amount": -2}, + {"first": 932, "second": 114, "amount": -2}, + {"first": 932, "second": 121, "amount": -1}, + {"first": 932, "second": 117, "amount": -2}, + {"first": 932, "second": 111, "amount": -2}, + {"first": 932, "second": 112, "amount": -2}, + {"first": 932, "second": 113, "amount": -2}, + {"first": 932, "second": 115, "amount": -2}, + {"first": 932, "second": 100, "amount": -2}, + {"first": 932, "second": 103, "amount": -2}, + {"first": 932, "second": 109, "amount": -2}, + {"first": 932, "second": 119, "amount": -1}, + {"first": 932, "second": 120, "amount": -2}, + {"first": 932, "second": 99, "amount": -2}, + {"first": 932, "second": 118, "amount": -1}, + {"first": 932, "second": 110, "amount": -2}, + {"first": 932, "second": 65, "amount": -2}, + {"first": 932, "second": 84, "amount": 0}, + {"first": 932, "second": 89, "amount": 0}, + {"first": 932, "second": 79, "amount": -1}, + {"first": 932, "second": 81, "amount": -1}, + {"first": 932, "second": 83, "amount": 0}, + {"first": 932, "second": 71, "amount": -1}, + {"first": 932, "second": 74, "amount": -5}, + {"first": 932, "second": 87, "amount": 0}, + {"first": 932, "second": 67, "amount": -1}, + {"first": 932, "second": 86, "amount": 0}, + {"first": 932, "second": 45, "amount": -5}, + {"first": 932, "second": 8211, "amount": -5}, + {"first": 932, "second": 44, "amount": -4}, + {"first": 932, "second": 46, "amount": -4}, + {"first": 932, "second": 1040, "amount": -2}, + {"first": 932, "second": 1072, "amount": -2}, + {"first": 932, "second": 1073, "amount": -1}, + {"first": 932, "second": 1074, "amount": -2}, + {"first": 932, "second": 1075, "amount": -2}, + {"first": 932, "second": 1044, "amount": -2}, + {"first": 932, "second": 1076, "amount": -3}, + {"first": 932, "second": 1077, "amount": -2}, + {"first": 932, "second": 1105, "amount": -2}, + {"first": 932, "second": 1078, "amount": -2}, + {"first": 932, "second": 1079, "amount": -3}, + {"first": 932, "second": 1080, "amount": -2}, + {"first": 932, "second": 1081, "amount": -2}, + {"first": 932, "second": 1082, "amount": -2}, + {"first": 932, "second": 1051, "amount": -1}, + {"first": 932, "second": 1083, "amount": -3}, + {"first": 932, "second": 1084, "amount": -2}, + {"first": 932, "second": 1085, "amount": -2}, + {"first": 932, "second": 1054, "amount": -1}, + {"first": 932, "second": 1086, "amount": -2}, + {"first": 932, "second": 1087, "amount": -2}, + {"first": 932, "second": 1088, "amount": -2}, + {"first": 932, "second": 1057, "amount": -1}, + {"first": 932, "second": 1089, "amount": -2}, + {"first": 932, "second": 1058, "amount": 0}, + {"first": 932, "second": 1090, "amount": -2}, + {"first": 932, "second": 1091, "amount": -1}, + {"first": 932, "second": 1092, "amount": -2}, + {"first": 932, "second": 1093, "amount": -2}, + {"first": 932, "second": 1094, "amount": -2}, + {"first": 932, "second": 1095, "amount": -3}, + {"first": 932, "second": 1096, "amount": -2}, + {"first": 932, "second": 1097, "amount": -2}, + {"first": 932, "second": 1099, "amount": -3}, + {"first": 932, "second": 1068, "amount": 0}, + {"first": 932, "second": 1100, "amount": -2}, + {"first": 932, "second": 1101, "amount": -3}, + {"first": 932, "second": 1102, "amount": -2}, + {"first": 932, "second": 1103, "amount": -3}, + {"first": 932, "second": 252, "amount": -2}, + {"first": 932, "second": 246, "amount": -2}, + {"first": 932, "second": 214, "amount": -1}, + {"first": 932, "second": 228, "amount": -2}, + {"first": 932, "second": 196, "amount": -2}, + {"first": 932, "second": 241, "amount": -2}, + {"first": 932, "second": 962, "amount": -2}, + {"first": 932, "second": 949, "amount": -3}, + {"first": 932, "second": 961, "amount": -3}, + {"first": 932, "second": 964, "amount": -2}, + {"first": 932, "second": 965, "amount": -2}, + {"first": 932, "second": 953, "amount": -3}, + {"first": 932, "second": 959, "amount": -2}, + {"first": 932, "second": 960, "amount": -2}, + {"first": 932, "second": 945, "amount": -2}, + {"first": 932, "second": 963, "amount": -2}, + {"first": 932, "second": 948, "amount": -1}, + {"first": 932, "second": 966, "amount": -3}, + {"first": 932, "second": 947, "amount": -1}, + {"first": 932, "second": 951, "amount": -2}, + {"first": 932, "second": 968, "amount": -3}, + {"first": 932, "second": 969, "amount": -3}, + {"first": 932, "second": 957, "amount": -1}, + {"first": 932, "second": 933, "amount": 0}, + {"first": 932, "second": 920, "amount": -1}, + {"first": 932, "second": 927, "amount": -1}, + {"first": 932, "second": 913, "amount": -2}, + {"first": 932, "second": 916, "amount": -2}, + {"first": 932, "second": 934, "amount": -2}, + {"first": 932, "second": 923, "amount": -2}, + {"first": 932, "second": 229, "amount": -2}, + {"first": 932, "second": 197, "amount": -2}, + {"first": 932, "second": 230, "amount": -2}, + {"first": 932, "second": 198, "amount": -4}, + {"first": 932, "second": 248, "amount": -2}, + {"first": 932, "second": 216, "amount": -1}, + {"first": 933, "second": 97, "amount": -1}, + {"first": 933, "second": 122, "amount": -1}, + {"first": 933, "second": 101, "amount": -1}, + {"first": 933, "second": 114, "amount": -1}, + {"first": 933, "second": 116, "amount": 0}, + {"first": 933, "second": 121, "amount": 0}, + {"first": 933, "second": 117, "amount": -1}, + {"first": 933, "second": 111, "amount": -1}, + {"first": 933, "second": 112, "amount": -1}, + {"first": 933, "second": 113, "amount": -1}, + {"first": 933, "second": 115, "amount": -1}, + {"first": 933, "second": 100, "amount": -1}, + {"first": 933, "second": 102, "amount": 0}, + {"first": 933, "second": 103, "amount": -1}, + {"first": 933, "second": 109, "amount": -1}, + {"first": 933, "second": 120, "amount": 0}, + {"first": 933, "second": 99, "amount": -1}, + {"first": 933, "second": 118, "amount": 0}, + {"first": 933, "second": 110, "amount": -1}, + {"first": 933, "second": 65, "amount": -2}, + {"first": 933, "second": 84, "amount": 0}, + {"first": 933, "second": 89, "amount": 0}, + {"first": 933, "second": 85, "amount": -2}, + {"first": 933, "second": 79, "amount": -1}, + {"first": 933, "second": 81, "amount": -1}, + {"first": 933, "second": 83, "amount": 0}, + {"first": 933, "second": 71, "amount": -1}, + {"first": 933, "second": 74, "amount": -2}, + {"first": 933, "second": 87, "amount": 0}, + {"first": 933, "second": 88, "amount": 0}, + {"first": 933, "second": 67, "amount": -1}, + {"first": 933, "second": 86, "amount": 0}, + {"first": 933, "second": 42, "amount": -1}, + {"first": 933, "second": 45, "amount": -1}, + {"first": 933, "second": 8211, "amount": -1}, + {"first": 933, "second": 44, "amount": -4}, + {"first": 933, "second": 46, "amount": -4}, + {"first": 933, "second": 125, "amount": 0}, + {"first": 933, "second": 41, "amount": 0}, + {"first": 933, "second": 93, "amount": 0}, + {"first": 933, "second": 38, "amount": -1}, + {"first": 933, "second": 1040, "amount": -2}, + {"first": 933, "second": 1072, "amount": -1}, + {"first": 933, "second": 1075, "amount": -1}, + {"first": 933, "second": 1077, "amount": -1}, + {"first": 933, "second": 1105, "amount": -1}, + {"first": 933, "second": 1046, "amount": 0}, + {"first": 933, "second": 1078, "amount": 0}, + {"first": 933, "second": 1080, "amount": -1}, + {"first": 933, "second": 1081, "amount": -1}, + {"first": 933, "second": 1082, "amount": -1}, + {"first": 933, "second": 1084, "amount": -1}, + {"first": 933, "second": 1085, "amount": -1}, + {"first": 933, "second": 1054, "amount": -1}, + {"first": 933, "second": 1086, "amount": -1}, + {"first": 933, "second": 1087, "amount": -1}, + {"first": 933, "second": 1088, "amount": -1}, + {"first": 933, "second": 1057, "amount": -1}, + {"first": 933, "second": 1089, "amount": -1}, + {"first": 933, "second": 1058, "amount": 0}, + {"first": 933, "second": 1091, "amount": 0}, + {"first": 933, "second": 1092, "amount": -1}, + {"first": 933, "second": 1061, "amount": 0}, + {"first": 933, "second": 1093, "amount": 0}, + {"first": 933, "second": 1094, "amount": -1}, + {"first": 933, "second": 1096, "amount": -1}, + {"first": 933, "second": 1097, "amount": -1}, + {"first": 933, "second": 1100, "amount": -1}, + {"first": 933, "second": 1102, "amount": -1}, + {"first": 933, "second": 252, "amount": -1}, + {"first": 933, "second": 220, "amount": -2}, + {"first": 933, "second": 246, "amount": -1}, + {"first": 933, "second": 214, "amount": -1}, + {"first": 933, "second": 228, "amount": -1}, + {"first": 933, "second": 196, "amount": -2}, + {"first": 933, "second": 241, "amount": -1}, + {"first": 933, "second": 962, "amount": -1}, + {"first": 933, "second": 949, "amount": -1}, + {"first": 933, "second": 961, "amount": -1}, + {"first": 933, "second": 964, "amount": 0}, + {"first": 933, "second": 965, "amount": -1}, + {"first": 933, "second": 952, "amount": 0}, + {"first": 933, "second": 953, "amount": -1}, + {"first": 933, "second": 959, "amount": -1}, + {"first": 933, "second": 960, "amount": 0}, + {"first": 933, "second": 945, "amount": -1}, + {"first": 933, "second": 963, "amount": -1}, + {"first": 933, "second": 948, "amount": 0}, + {"first": 933, "second": 966, "amount": -1}, + {"first": 933, "second": 947, "amount": 0}, + {"first": 933, "second": 951, "amount": -1}, + {"first": 933, "second": 950, "amount": 0}, + {"first": 933, "second": 968, "amount": -1}, + {"first": 933, "second": 969, "amount": -1}, + {"first": 933, "second": 946, "amount": 0}, + {"first": 933, "second": 957, "amount": 0}, + {"first": 933, "second": 933, "amount": 0}, + {"first": 933, "second": 920, "amount": -1}, + {"first": 933, "second": 927, "amount": -1}, + {"first": 933, "second": 913, "amount": -2}, + {"first": 933, "second": 916, "amount": -2}, + {"first": 933, "second": 934, "amount": -1}, + {"first": 933, "second": 923, "amount": -2}, + {"first": 933, "second": 935, "amount": 0}, + {"first": 933, "second": 229, "amount": -1}, + {"first": 933, "second": 197, "amount": -2}, + {"first": 933, "second": 230, "amount": -1}, + {"first": 933, "second": 198, "amount": -2}, + {"first": 933, "second": 248, "amount": -1}, + {"first": 933, "second": 216, "amount": -1}, + {"first": 920, "second": 65, "amount": 0}, + {"first": 920, "second": 90, "amount": 0}, + {"first": 920, "second": 84, "amount": -1}, + {"first": 920, "second": 89, "amount": -1}, + {"first": 920, "second": 88, "amount": 0}, + {"first": 920, "second": 86, "amount": 0}, + {"first": 920, "second": 44, "amount": -2}, + {"first": 920, "second": 46, "amount": -2}, + {"first": 920, "second": 1040, "amount": 0}, + {"first": 920, "second": 1044, "amount": -1}, + {"first": 920, "second": 1046, "amount": 0}, + {"first": 920, "second": 1051, "amount": -1}, + {"first": 920, "second": 1058, "amount": -1}, + {"first": 920, "second": 1061, "amount": 0}, + {"first": 920, "second": 1068, "amount": -1}, + {"first": 920, "second": 196, "amount": 0}, + {"first": 920, "second": 955, "amount": 0}, + {"first": 920, "second": 933, "amount": -1}, + {"first": 920, "second": 913, "amount": 0}, + {"first": 920, "second": 931, "amount": 0}, + {"first": 920, "second": 916, "amount": 0}, + {"first": 920, "second": 926, "amount": 0}, + {"first": 920, "second": 923, "amount": 0}, + {"first": 920, "second": 918, "amount": 0}, + {"first": 920, "second": 935, "amount": 0}, + {"first": 920, "second": 197, "amount": 0}, + {"first": 920, "second": 198, "amount": -1}, + {"first": 921, "second": 65, "amount": 0}, + {"first": 921, "second": 84, "amount": -1}, + {"first": 921, "second": 89, "amount": -1}, + {"first": 921, "second": 88, "amount": 0}, + {"first": 921, "second": 1040, "amount": 0}, + {"first": 921, "second": 1044, "amount": 0}, + {"first": 921, "second": 1076, "amount": 0}, + {"first": 921, "second": 1046, "amount": 0}, + {"first": 921, "second": 1051, "amount": 0}, + {"first": 921, "second": 1083, "amount": 0}, + {"first": 921, "second": 1058, "amount": -1}, + {"first": 921, "second": 1061, "amount": 0}, + {"first": 921, "second": 1063, "amount": -1}, + {"first": 921, "second": 1095, "amount": -1}, + {"first": 921, "second": 196, "amount": 0}, + {"first": 921, "second": 933, "amount": -1}, + {"first": 921, "second": 913, "amount": 0}, + {"first": 921, "second": 916, "amount": 0}, + {"first": 921, "second": 923, "amount": 0}, + {"first": 921, "second": 935, "amount": 0}, + {"first": 921, "second": 197, "amount": 0}, + {"first": 927, "second": 65, "amount": 0}, + {"first": 927, "second": 90, "amount": 0}, + {"first": 927, "second": 84, "amount": -1}, + {"first": 927, "second": 89, "amount": -1}, + {"first": 927, "second": 88, "amount": 0}, + {"first": 927, "second": 86, "amount": 0}, + {"first": 927, "second": 44, "amount": -2}, + {"first": 927, "second": 46, "amount": -2}, + {"first": 927, "second": 1040, "amount": 0}, + {"first": 927, "second": 1044, "amount": -1}, + {"first": 927, "second": 1046, "amount": 0}, + {"first": 927, "second": 1051, "amount": -1}, + {"first": 927, "second": 1058, "amount": -1}, + {"first": 927, "second": 1061, "amount": 0}, + {"first": 927, "second": 1068, "amount": -1}, + {"first": 927, "second": 196, "amount": 0}, + {"first": 927, "second": 955, "amount": 0}, + {"first": 927, "second": 933, "amount": -1}, + {"first": 927, "second": 913, "amount": 0}, + {"first": 927, "second": 931, "amount": 0}, + {"first": 927, "second": 916, "amount": 0}, + {"first": 927, "second": 926, "amount": 0}, + {"first": 927, "second": 923, "amount": 0}, + {"first": 927, "second": 918, "amount": 0}, + {"first": 927, "second": 935, "amount": 0}, + {"first": 927, "second": 197, "amount": 0}, + {"first": 927, "second": 198, "amount": -1}, + {"first": 913, "second": 122, "amount": 0}, + {"first": 913, "second": 116, "amount": 0}, + {"first": 913, "second": 121, "amount": -1}, + {"first": 913, "second": 117, "amount": 0}, + {"first": 913, "second": 111, "amount": 0}, + {"first": 913, "second": 119, "amount": -1}, + {"first": 913, "second": 118, "amount": -1}, + {"first": 913, "second": 84, "amount": -3}, + {"first": 913, "second": 89, "amount": -2}, + {"first": 913, "second": 85, "amount": 0}, + {"first": 913, "second": 79, "amount": 0}, + {"first": 913, "second": 81, "amount": 0}, + {"first": 913, "second": 71, "amount": 0}, + {"first": 913, "second": 87, "amount": -1}, + {"first": 913, "second": 67, "amount": 0}, + {"first": 913, "second": 86, "amount": -2}, + {"first": 913, "second": 63, "amount": -1}, + {"first": 913, "second": 34, "amount": -2}, + {"first": 913, "second": 39, "amount": -2}, + {"first": 913, "second": 1044, "amount": 0}, + {"first": 913, "second": 1051, "amount": 0}, + {"first": 913, "second": 1083, "amount": 0}, + {"first": 913, "second": 1054, "amount": 0}, + {"first": 913, "second": 1086, "amount": 0}, + {"first": 913, "second": 1057, "amount": 0}, + {"first": 913, "second": 1058, "amount": -3}, + {"first": 913, "second": 1090, "amount": -1}, + {"first": 913, "second": 1091, "amount": -1}, + {"first": 913, "second": 1063, "amount": -1}, + {"first": 913, "second": 1095, "amount": -2}, + {"first": 913, "second": 1068, "amount": -1}, + {"first": 913, "second": 252, "amount": 0}, + {"first": 913, "second": 220, "amount": 0}, + {"first": 913, "second": 246, "amount": 0}, + {"first": 913, "second": 214, "amount": 0}, + {"first": 913, "second": 964, "amount": -1}, + {"first": 913, "second": 965, "amount": 0}, + {"first": 913, "second": 959, "amount": 0}, + {"first": 913, "second": 947, "amount": -1}, + {"first": 913, "second": 955, "amount": 0}, + {"first": 913, "second": 957, "amount": -1}, + {"first": 913, "second": 933, "amount": -2}, + {"first": 913, "second": 920, "amount": 0}, + {"first": 913, "second": 927, "amount": 0}, + {"first": 913, "second": 934, "amount": -1}, + {"first": 913, "second": 936, "amount": -1}, + {"first": 913, "second": 216, "amount": 0}, + {"first": 931, "second": 79, "amount": -1}, + {"first": 931, "second": 81, "amount": -1}, + {"first": 931, "second": 71, "amount": -1}, + {"first": 931, "second": 67, "amount": -1}, + {"first": 931, "second": 1054, "amount": -1}, + {"first": 931, "second": 1057, "amount": -1}, + {"first": 931, "second": 214, "amount": -1}, + {"first": 931, "second": 955, "amount": 0}, + {"first": 931, "second": 920, "amount": -1}, + {"first": 931, "second": 927, "amount": -1}, + {"first": 931, "second": 934, "amount": -1}, + {"first": 931, "second": 216, "amount": -1}, + {"first": 916, "second": 122, "amount": 0}, + {"first": 916, "second": 116, "amount": 0}, + {"first": 916, "second": 121, "amount": -1}, + {"first": 916, "second": 117, "amount": 0}, + {"first": 916, "second": 111, "amount": 0}, + {"first": 916, "second": 119, "amount": -1}, + {"first": 916, "second": 118, "amount": -1}, + {"first": 916, "second": 84, "amount": -3}, + {"first": 916, "second": 89, "amount": -2}, + {"first": 916, "second": 85, "amount": 0}, + {"first": 916, "second": 79, "amount": 0}, + {"first": 916, "second": 81, "amount": 0}, + {"first": 916, "second": 71, "amount": 0}, + {"first": 916, "second": 87, "amount": -1}, + {"first": 916, "second": 67, "amount": 0}, + {"first": 916, "second": 86, "amount": -2}, + {"first": 916, "second": 63, "amount": -1}, + {"first": 916, "second": 34, "amount": -2}, + {"first": 916, "second": 39, "amount": -2}, + {"first": 916, "second": 1044, "amount": 0}, + {"first": 916, "second": 1051, "amount": 0}, + {"first": 916, "second": 1083, "amount": 0}, + {"first": 916, "second": 1054, "amount": 0}, + {"first": 916, "second": 1086, "amount": 0}, + {"first": 916, "second": 1057, "amount": 0}, + {"first": 916, "second": 1058, "amount": -3}, + {"first": 916, "second": 1090, "amount": -1}, + {"first": 916, "second": 1091, "amount": -1}, + {"first": 916, "second": 1063, "amount": -1}, + {"first": 916, "second": 1095, "amount": -2}, + {"first": 916, "second": 1068, "amount": -1}, + {"first": 916, "second": 252, "amount": 0}, + {"first": 916, "second": 220, "amount": 0}, + {"first": 916, "second": 246, "amount": 0}, + {"first": 916, "second": 214, "amount": 0}, + {"first": 916, "second": 964, "amount": -1}, + {"first": 916, "second": 965, "amount": 0}, + {"first": 916, "second": 959, "amount": 0}, + {"first": 916, "second": 947, "amount": -1}, + {"first": 916, "second": 955, "amount": 0}, + {"first": 916, "second": 957, "amount": -1}, + {"first": 916, "second": 933, "amount": -2}, + {"first": 916, "second": 920, "amount": 0}, + {"first": 916, "second": 927, "amount": 0}, + {"first": 916, "second": 934, "amount": -1}, + {"first": 916, "second": 936, "amount": -1}, + {"first": 916, "second": 216, "amount": 0}, + {"first": 934, "second": 65, "amount": -1}, + {"first": 934, "second": 89, "amount": -1}, + {"first": 934, "second": 88, "amount": -1}, + {"first": 934, "second": 1040, "amount": -1}, + {"first": 934, "second": 1046, "amount": -1}, + {"first": 934, "second": 1061, "amount": -1}, + {"first": 934, "second": 196, "amount": -1}, + {"first": 934, "second": 955, "amount": -1}, + {"first": 934, "second": 933, "amount": -1}, + {"first": 934, "second": 913, "amount": -1}, + {"first": 934, "second": 916, "amount": -1}, + {"first": 934, "second": 923, "amount": -1}, + {"first": 934, "second": 935, "amount": -1}, + {"first": 934, "second": 197, "amount": -1}, + {"first": 915, "second": 97, "amount": -4}, + {"first": 915, "second": 122, "amount": -3}, + {"first": 915, "second": 101, "amount": -4}, + {"first": 915, "second": 114, "amount": -3}, + {"first": 915, "second": 121, "amount": -3}, + {"first": 915, "second": 117, "amount": -4}, + {"first": 915, "second": 111, "amount": -4}, + {"first": 915, "second": 112, "amount": -4}, + {"first": 915, "second": 113, "amount": -4}, + {"first": 915, "second": 115, "amount": -4}, + {"first": 915, "second": 100, "amount": -4}, + {"first": 915, "second": 103, "amount": -4}, + {"first": 915, "second": 109, "amount": -4}, + {"first": 915, "second": 119, "amount": -2}, + {"first": 915, "second": 120, "amount": -3}, + {"first": 915, "second": 99, "amount": -4}, + {"first": 915, "second": 118, "amount": -3}, + {"first": 915, "second": 110, "amount": -4}, + {"first": 915, "second": 65, "amount": -4}, + {"first": 915, "second": 84, "amount": 0}, + {"first": 915, "second": 89, "amount": 0}, + {"first": 915, "second": 79, "amount": -1}, + {"first": 915, "second": 81, "amount": -1}, + {"first": 915, "second": 83, "amount": -1}, + {"first": 915, "second": 71, "amount": -1}, + {"first": 915, "second": 87, "amount": 0}, + {"first": 915, "second": 67, "amount": -1}, + {"first": 915, "second": 86, "amount": 0}, + {"first": 915, "second": 45, "amount": -8}, + {"first": 915, "second": 8211, "amount": -8}, + {"first": 915, "second": 44, "amount": -8}, + {"first": 915, "second": 46, "amount": -8}, + {"first": 915, "second": 1040, "amount": -4}, + {"first": 915, "second": 1072, "amount": -4}, + {"first": 915, "second": 1073, "amount": -1}, + {"first": 915, "second": 1074, "amount": -4}, + {"first": 915, "second": 1075, "amount": -4}, + {"first": 915, "second": 1044, "amount": -4}, + {"first": 915, "second": 1076, "amount": -5}, + {"first": 915, "second": 1077, "amount": -4}, + {"first": 915, "second": 1105, "amount": -4}, + {"first": 915, "second": 1078, "amount": -3}, + {"first": 915, "second": 1079, "amount": -5}, + {"first": 915, "second": 1080, "amount": -4}, + {"first": 915, "second": 1081, "amount": -4}, + {"first": 915, "second": 1082, "amount": -4}, + {"first": 915, "second": 1051, "amount": -2}, + {"first": 915, "second": 1083, "amount": -5}, + {"first": 915, "second": 1084, "amount": -4}, + {"first": 915, "second": 1085, "amount": -4}, + {"first": 915, "second": 1054, "amount": -1}, + {"first": 915, "second": 1086, "amount": -4}, + {"first": 915, "second": 1087, "amount": -4}, + {"first": 915, "second": 1088, "amount": -4}, + {"first": 915, "second": 1057, "amount": -1}, + {"first": 915, "second": 1089, "amount": -4}, + {"first": 915, "second": 1058, "amount": 0}, + {"first": 915, "second": 1090, "amount": -3}, + {"first": 915, "second": 1091, "amount": -3}, + {"first": 915, "second": 1092, "amount": -4}, + {"first": 915, "second": 1093, "amount": -3}, + {"first": 915, "second": 1094, "amount": -4}, + {"first": 915, "second": 1095, "amount": -5}, + {"first": 915, "second": 1096, "amount": -4}, + {"first": 915, "second": 1097, "amount": -4}, + {"first": 915, "second": 1099, "amount": -5}, + {"first": 915, "second": 1068, "amount": 0}, + {"first": 915, "second": 1100, "amount": -4}, + {"first": 915, "second": 1101, "amount": -5}, + {"first": 915, "second": 1102, "amount": -4}, + {"first": 915, "second": 1103, "amount": -5}, + {"first": 915, "second": 252, "amount": -4}, + {"first": 915, "second": 246, "amount": -4}, + {"first": 915, "second": 214, "amount": -1}, + {"first": 915, "second": 228, "amount": -4}, + {"first": 915, "second": 196, "amount": -4}, + {"first": 915, "second": 241, "amount": -4}, + {"first": 915, "second": 962, "amount": -4}, + {"first": 915, "second": 949, "amount": -5}, + {"first": 915, "second": 961, "amount": -6}, + {"first": 915, "second": 964, "amount": -4}, + {"first": 915, "second": 965, "amount": -4}, + {"first": 915, "second": 953, "amount": -6}, + {"first": 915, "second": 959, "amount": -4}, + {"first": 915, "second": 960, "amount": -5}, + {"first": 915, "second": 945, "amount": -4}, + {"first": 915, "second": 963, "amount": -4}, + {"first": 915, "second": 948, "amount": -2}, + {"first": 915, "second": 966, "amount": -6}, + {"first": 915, "second": 947, "amount": -3}, + {"first": 915, "second": 951, "amount": -4}, + {"first": 915, "second": 968, "amount": -5}, + {"first": 915, "second": 969, "amount": -6}, + {"first": 915, "second": 957, "amount": -3}, + {"first": 915, "second": 933, "amount": 0}, + {"first": 915, "second": 920, "amount": -1}, + {"first": 915, "second": 927, "amount": -1}, + {"first": 915, "second": 913, "amount": -4}, + {"first": 915, "second": 916, "amount": -4}, + {"first": 915, "second": 934, "amount": -3}, + {"first": 915, "second": 923, "amount": -4}, + {"first": 915, "second": 229, "amount": -4}, + {"first": 915, "second": 197, "amount": -4}, + {"first": 915, "second": 230, "amount": -4}, + {"first": 915, "second": 198, "amount": -7}, + {"first": 915, "second": 248, "amount": -4}, + {"first": 915, "second": 216, "amount": -1}, + {"first": 919, "second": 65, "amount": 0}, + {"first": 919, "second": 84, "amount": -1}, + {"first": 919, "second": 89, "amount": -1}, + {"first": 919, "second": 88, "amount": 0}, + {"first": 919, "second": 1040, "amount": 0}, + {"first": 919, "second": 1044, "amount": 0}, + {"first": 919, "second": 1076, "amount": 0}, + {"first": 919, "second": 1046, "amount": 0}, + {"first": 919, "second": 1051, "amount": 0}, + {"first": 919, "second": 1083, "amount": 0}, + {"first": 919, "second": 1058, "amount": -1}, + {"first": 919, "second": 1061, "amount": 0}, + {"first": 919, "second": 1063, "amount": -1}, + {"first": 919, "second": 1095, "amount": -1}, + {"first": 919, "second": 196, "amount": 0}, + {"first": 919, "second": 933, "amount": -1}, + {"first": 919, "second": 913, "amount": 0}, + {"first": 919, "second": 916, "amount": 0}, + {"first": 919, "second": 923, "amount": 0}, + {"first": 919, "second": 935, "amount": 0}, + {"first": 919, "second": 197, "amount": 0}, + {"first": 926, "second": 79, "amount": 0}, + {"first": 926, "second": 81, "amount": 0}, + {"first": 926, "second": 71, "amount": 0}, + {"first": 926, "second": 67, "amount": 0}, + {"first": 926, "second": 1054, "amount": 0}, + {"first": 926, "second": 1057, "amount": 0}, + {"first": 926, "second": 214, "amount": 0}, + {"first": 926, "second": 955, "amount": 0}, + {"first": 926, "second": 920, "amount": 0}, + {"first": 926, "second": 927, "amount": 0}, + {"first": 926, "second": 216, "amount": 0}, + {"first": 922, "second": 101, "amount": -1}, + {"first": 922, "second": 121, "amount": -1}, + {"first": 922, "second": 117, "amount": 0}, + {"first": 922, "second": 111, "amount": -1}, + {"first": 922, "second": 112, "amount": 0}, + {"first": 922, "second": 113, "amount": -1}, + {"first": 922, "second": 100, "amount": -1}, + {"first": 922, "second": 103, "amount": -1}, + {"first": 922, "second": 109, "amount": 0}, + {"first": 922, "second": 119, "amount": -1}, + {"first": 922, "second": 99, "amount": -1}, + {"first": 922, "second": 118, "amount": -1}, + {"first": 922, "second": 110, "amount": 0}, + {"first": 922, "second": 79, "amount": -1}, + {"first": 922, "second": 81, "amount": -1}, + {"first": 922, "second": 71, "amount": -1}, + {"first": 922, "second": 67, "amount": -1}, + {"first": 922, "second": 45, "amount": -1}, + {"first": 922, "second": 8211, "amount": -1}, + {"first": 922, "second": 1073, "amount": -1}, + {"first": 922, "second": 1075, "amount": 0}, + {"first": 922, "second": 1077, "amount": -1}, + {"first": 922, "second": 1105, "amount": -1}, + {"first": 922, "second": 1080, "amount": 0}, + {"first": 922, "second": 1081, "amount": 0}, + {"first": 922, "second": 1082, "amount": 0}, + {"first": 922, "second": 1084, "amount": 0}, + {"first": 922, "second": 1085, "amount": 0}, + {"first": 922, "second": 1054, "amount": -1}, + {"first": 922, "second": 1086, "amount": -1}, + {"first": 922, "second": 1087, "amount": 0}, + {"first": 922, "second": 1088, "amount": 0}, + {"first": 922, "second": 1057, "amount": -1}, + {"first": 922, "second": 1089, "amount": -1}, + {"first": 922, "second": 1090, "amount": -1}, + {"first": 922, "second": 1091, "amount": -1}, + {"first": 922, "second": 1092, "amount": -1}, + {"first": 922, "second": 1094, "amount": 0}, + {"first": 922, "second": 1095, "amount": -2}, + {"first": 922, "second": 1096, "amount": 0}, + {"first": 922, "second": 1097, "amount": 0}, + {"first": 922, "second": 1100, "amount": 0}, + {"first": 922, "second": 1102, "amount": 0}, + {"first": 922, "second": 252, "amount": 0}, + {"first": 922, "second": 246, "amount": -1}, + {"first": 922, "second": 214, "amount": -1}, + {"first": 922, "second": 241, "amount": 0}, + {"first": 922, "second": 962, "amount": -1}, + {"first": 922, "second": 964, "amount": -2}, + {"first": 922, "second": 965, "amount": 0}, + {"first": 922, "second": 959, "amount": -1}, + {"first": 922, "second": 945, "amount": -1}, + {"first": 922, "second": 963, "amount": -1}, + {"first": 922, "second": 947, "amount": -1}, + {"first": 922, "second": 951, "amount": 0}, + {"first": 922, "second": 957, "amount": -1}, + {"first": 922, "second": 920, "amount": -1}, + {"first": 922, "second": 927, "amount": -1}, + {"first": 922, "second": 934, "amount": -1}, + {"first": 922, "second": 216, "amount": -1}, + {"first": 923, "second": 122, "amount": 0}, + {"first": 923, "second": 116, "amount": 0}, + {"first": 923, "second": 121, "amount": -1}, + {"first": 923, "second": 117, "amount": 0}, + {"first": 923, "second": 111, "amount": 0}, + {"first": 923, "second": 119, "amount": -1}, + {"first": 923, "second": 118, "amount": -1}, + {"first": 923, "second": 84, "amount": -3}, + {"first": 923, "second": 89, "amount": -2}, + {"first": 923, "second": 85, "amount": 0}, + {"first": 923, "second": 79, "amount": 0}, + {"first": 923, "second": 81, "amount": 0}, + {"first": 923, "second": 71, "amount": 0}, + {"first": 923, "second": 87, "amount": -1}, + {"first": 923, "second": 67, "amount": 0}, + {"first": 923, "second": 86, "amount": -2}, + {"first": 923, "second": 63, "amount": -1}, + {"first": 923, "second": 34, "amount": -2}, + {"first": 923, "second": 39, "amount": -2}, + {"first": 923, "second": 1044, "amount": 0}, + {"first": 923, "second": 1051, "amount": 0}, + {"first": 923, "second": 1083, "amount": 0}, + {"first": 923, "second": 1054, "amount": 0}, + {"first": 923, "second": 1086, "amount": 0}, + {"first": 923, "second": 1057, "amount": 0}, + {"first": 923, "second": 1058, "amount": -3}, + {"first": 923, "second": 1090, "amount": -1}, + {"first": 923, "second": 1091, "amount": -1}, + {"first": 923, "second": 1063, "amount": -1}, + {"first": 923, "second": 1095, "amount": -2}, + {"first": 923, "second": 1068, "amount": -1}, + {"first": 923, "second": 252, "amount": 0}, + {"first": 923, "second": 220, "amount": 0}, + {"first": 923, "second": 246, "amount": 0}, + {"first": 923, "second": 214, "amount": 0}, + {"first": 923, "second": 964, "amount": -1}, + {"first": 923, "second": 965, "amount": 0}, + {"first": 923, "second": 959, "amount": 0}, + {"first": 923, "second": 947, "amount": -1}, + {"first": 923, "second": 955, "amount": 0}, + {"first": 923, "second": 957, "amount": -1}, + {"first": 923, "second": 933, "amount": -2}, + {"first": 923, "second": 920, "amount": 0}, + {"first": 923, "second": 927, "amount": 0}, + {"first": 923, "second": 934, "amount": -1}, + {"first": 923, "second": 936, "amount": -1}, + {"first": 923, "second": 216, "amount": 0}, + {"first": 918, "second": 101, "amount": 0}, + {"first": 918, "second": 121, "amount": -1}, + {"first": 918, "second": 117, "amount": 0}, + {"first": 918, "second": 111, "amount": 0}, + {"first": 918, "second": 113, "amount": 0}, + {"first": 918, "second": 100, "amount": 0}, + {"first": 918, "second": 103, "amount": 0}, + {"first": 918, "second": 119, "amount": -1}, + {"first": 918, "second": 99, "amount": 0}, + {"first": 918, "second": 118, "amount": -1}, + {"first": 918, "second": 65, "amount": 0}, + {"first": 918, "second": 79, "amount": -1}, + {"first": 918, "second": 81, "amount": -1}, + {"first": 918, "second": 71, "amount": -1}, + {"first": 918, "second": 67, "amount": -1}, + {"first": 918, "second": 1040, "amount": 0}, + {"first": 918, "second": 1077, "amount": 0}, + {"first": 918, "second": 1105, "amount": 0}, + {"first": 918, "second": 1054, "amount": -1}, + {"first": 918, "second": 1086, "amount": 0}, + {"first": 918, "second": 1057, "amount": -1}, + {"first": 918, "second": 1089, "amount": 0}, + {"first": 918, "second": 1091, "amount": -1}, + {"first": 918, "second": 1092, "amount": 0}, + {"first": 918, "second": 252, "amount": 0}, + {"first": 918, "second": 246, "amount": 0}, + {"first": 918, "second": 214, "amount": -1}, + {"first": 918, "second": 196, "amount": 0}, + {"first": 918, "second": 962, "amount": 0}, + {"first": 918, "second": 965, "amount": 0}, + {"first": 918, "second": 959, "amount": 0}, + {"first": 918, "second": 945, "amount": 0}, + {"first": 918, "second": 963, "amount": 0}, + {"first": 918, "second": 947, "amount": -1}, + {"first": 918, "second": 968, "amount": -1}, + {"first": 918, "second": 957, "amount": -1}, + {"first": 918, "second": 920, "amount": -1}, + {"first": 918, "second": 927, "amount": -1}, + {"first": 918, "second": 913, "amount": 0}, + {"first": 918, "second": 916, "amount": 0}, + {"first": 918, "second": 934, "amount": -1}, + {"first": 918, "second": 923, "amount": 0}, + {"first": 918, "second": 197, "amount": 0}, + {"first": 918, "second": 216, "amount": -1}, + {"first": 935, "second": 101, "amount": -1}, + {"first": 935, "second": 121, "amount": -1}, + {"first": 935, "second": 117, "amount": 0}, + {"first": 935, "second": 111, "amount": 0}, + {"first": 935, "second": 113, "amount": -1}, + {"first": 935, "second": 100, "amount": -1}, + {"first": 935, "second": 103, "amount": -1}, + {"first": 935, "second": 99, "amount": -1}, + {"first": 935, "second": 118, "amount": -1}, + {"first": 935, "second": 79, "amount": -1}, + {"first": 935, "second": 81, "amount": -1}, + {"first": 935, "second": 71, "amount": -1}, + {"first": 935, "second": 67, "amount": -1}, + {"first": 935, "second": 86, "amount": 0}, + {"first": 935, "second": 45, "amount": -1}, + {"first": 935, "second": 8211, "amount": -1}, + {"first": 935, "second": 1073, "amount": 0}, + {"first": 935, "second": 1044, "amount": 0}, + {"first": 935, "second": 1077, "amount": -1}, + {"first": 935, "second": 1105, "amount": -1}, + {"first": 935, "second": 1051, "amount": 0}, + {"first": 935, "second": 1083, "amount": 0}, + {"first": 935, "second": 1054, "amount": -1}, + {"first": 935, "second": 1086, "amount": 0}, + {"first": 935, "second": 1057, "amount": -1}, + {"first": 935, "second": 1089, "amount": -1}, + {"first": 935, "second": 1090, "amount": -1}, + {"first": 935, "second": 1091, "amount": -1}, + {"first": 935, "second": 1092, "amount": -1}, + {"first": 935, "second": 1095, "amount": -1}, + {"first": 935, "second": 252, "amount": 0}, + {"first": 935, "second": 246, "amount": 0}, + {"first": 935, "second": 214, "amount": -1}, + {"first": 935, "second": 962, "amount": -1}, + {"first": 935, "second": 964, "amount": -1}, + {"first": 935, "second": 965, "amount": 0}, + {"first": 935, "second": 952, "amount": 0}, + {"first": 935, "second": 959, "amount": 0}, + {"first": 935, "second": 945, "amount": -1}, + {"first": 935, "second": 963, "amount": -1}, + {"first": 935, "second": 948, "amount": 0}, + {"first": 935, "second": 966, "amount": -1}, + {"first": 935, "second": 947, "amount": -1}, + {"first": 935, "second": 955, "amount": 0}, + {"first": 935, "second": 968, "amount": -1}, + {"first": 935, "second": 969, "amount": 0}, + {"first": 935, "second": 957, "amount": -1}, + {"first": 935, "second": 920, "amount": -1}, + {"first": 935, "second": 927, "amount": -1}, + {"first": 935, "second": 934, "amount": -1}, + {"first": 935, "second": 216, "amount": -1}, + {"first": 936, "second": 65, "amount": -1}, + {"first": 936, "second": 44, "amount": -5}, + {"first": 936, "second": 46, "amount": -5}, + {"first": 936, "second": 1040, "amount": -1}, + {"first": 936, "second": 196, "amount": -1}, + {"first": 936, "second": 961, "amount": 0}, + {"first": 936, "second": 913, "amount": -1}, + {"first": 936, "second": 916, "amount": -1}, + {"first": 936, "second": 923, "amount": -1}, + {"first": 936, "second": 197, "amount": -1}, + {"first": 914, "second": 84, "amount": -1}, + {"first": 914, "second": 89, "amount": -1}, + {"first": 914, "second": 86, "amount": 0}, + {"first": 914, "second": 1058, "amount": -1}, + {"first": 914, "second": 1059, "amount": 0}, + {"first": 914, "second": 933, "amount": -1}, + {"first": 925, "second": 65, "amount": 0}, + {"first": 925, "second": 84, "amount": -1}, + {"first": 925, "second": 89, "amount": -1}, + {"first": 925, "second": 88, "amount": 0}, + {"first": 925, "second": 1040, "amount": 0}, + {"first": 925, "second": 1044, "amount": 0}, + {"first": 925, "second": 1076, "amount": 0}, + {"first": 925, "second": 1046, "amount": 0}, + {"first": 925, "second": 1051, "amount": 0}, + {"first": 925, "second": 1083, "amount": 0}, + {"first": 925, "second": 1058, "amount": -1}, + {"first": 925, "second": 1061, "amount": 0}, + {"first": 925, "second": 1063, "amount": -1}, + {"first": 925, "second": 1095, "amount": -1}, + {"first": 925, "second": 196, "amount": 0}, + {"first": 925, "second": 933, "amount": -1}, + {"first": 925, "second": 913, "amount": 0}, + {"first": 925, "second": 916, "amount": 0}, + {"first": 925, "second": 923, "amount": 0}, + {"first": 925, "second": 935, "amount": 0}, + {"first": 925, "second": 197, "amount": 0}, + {"first": 924, "second": 65, "amount": 0}, + {"first": 924, "second": 84, "amount": -1}, + {"first": 924, "second": 89, "amount": -1}, + {"first": 924, "second": 88, "amount": 0}, + {"first": 924, "second": 1040, "amount": 0}, + {"first": 924, "second": 1044, "amount": 0}, + {"first": 924, "second": 1076, "amount": 0}, + {"first": 924, "second": 1046, "amount": 0}, + {"first": 924, "second": 1051, "amount": 0}, + {"first": 924, "second": 1083, "amount": 0}, + {"first": 924, "second": 1058, "amount": -1}, + {"first": 924, "second": 1061, "amount": 0}, + {"first": 924, "second": 1063, "amount": -1}, + {"first": 924, "second": 1095, "amount": -1}, + {"first": 924, "second": 196, "amount": 0}, + {"first": 924, "second": 933, "amount": -1}, + {"first": 924, "second": 913, "amount": 0}, + {"first": 924, "second": 916, "amount": 0}, + {"first": 924, "second": 923, "amount": 0}, + {"first": 924, "second": 935, "amount": 0}, + {"first": 924, "second": 197, "amount": 0}, + {"first": 229, "second": 121, "amount": 0}, + {"first": 229, "second": 118, "amount": 0}, + {"first": 229, "second": 34, "amount": -1}, + {"first": 229, "second": 39, "amount": -1}, + {"first": 229, "second": 1090, "amount": 0}, + {"first": 229, "second": 1091, "amount": 0}, + {"first": 229, "second": 947, "amount": 0}, + {"first": 229, "second": 957, "amount": 0}, + {"first": 197, "second": 122, "amount": 0}, + {"first": 197, "second": 116, "amount": 0}, + {"first": 197, "second": 121, "amount": -1}, + {"first": 197, "second": 117, "amount": 0}, + {"first": 197, "second": 111, "amount": 0}, + {"first": 197, "second": 119, "amount": -1}, + {"first": 197, "second": 118, "amount": -1}, + {"first": 197, "second": 84, "amount": -3}, + {"first": 197, "second": 89, "amount": -2}, + {"first": 197, "second": 85, "amount": 0}, + {"first": 197, "second": 79, "amount": 0}, + {"first": 197, "second": 81, "amount": 0}, + {"first": 197, "second": 71, "amount": 0}, + {"first": 197, "second": 87, "amount": -1}, + {"first": 197, "second": 67, "amount": 0}, + {"first": 197, "second": 86, "amount": -2}, + {"first": 197, "second": 63, "amount": -1}, + {"first": 197, "second": 34, "amount": -2}, + {"first": 197, "second": 39, "amount": -2}, + {"first": 197, "second": 1044, "amount": 0}, + {"first": 197, "second": 1051, "amount": 0}, + {"first": 197, "second": 1083, "amount": 0}, + {"first": 197, "second": 1054, "amount": 0}, + {"first": 197, "second": 1086, "amount": 0}, + {"first": 197, "second": 1057, "amount": 0}, + {"first": 197, "second": 1058, "amount": -3}, + {"first": 197, "second": 1090, "amount": -1}, + {"first": 197, "second": 1091, "amount": -1}, + {"first": 197, "second": 1063, "amount": -1}, + {"first": 197, "second": 1095, "amount": -2}, + {"first": 197, "second": 1068, "amount": -1}, + {"first": 197, "second": 252, "amount": 0}, + {"first": 197, "second": 220, "amount": 0}, + {"first": 197, "second": 246, "amount": 0}, + {"first": 197, "second": 214, "amount": 0}, + {"first": 197, "second": 964, "amount": -1}, + {"first": 197, "second": 965, "amount": 0}, + {"first": 197, "second": 959, "amount": 0}, + {"first": 197, "second": 947, "amount": -1}, + {"first": 197, "second": 955, "amount": 0}, + {"first": 197, "second": 957, "amount": -1}, + {"first": 197, "second": 933, "amount": -2}, + {"first": 197, "second": 920, "amount": 0}, + {"first": 197, "second": 927, "amount": 0}, + {"first": 197, "second": 934, "amount": -1}, + {"first": 197, "second": 936, "amount": -1}, + {"first": 197, "second": 216, "amount": 0} + ] +} diff --git a/streaming-react-app/src/assets/Roboto-msdf.png b/streaming-react-app/src/assets/Roboto-msdf.png new file mode 100644 index 0000000000000000000000000000000000000000..8754035dfe5d04ebac970df0dc935c7f1d4a0b43 Binary files /dev/null and b/streaming-react-app/src/assets/Roboto-msdf.png differ diff --git a/streaming-react-app/src/assets/RobotoMono-Regular-msdf.json b/streaming-react-app/src/assets/RobotoMono-Regular-msdf.json new file mode 100644 index 0000000000000000000000000000000000000000..013c7409ba377e3e795f45069627a1ece4d83745 --- /dev/null +++ b/streaming-react-app/src/assets/RobotoMono-Regular-msdf.json @@ -0,0 +1,6228 @@ +{ + "pages": ["RobotoMono-Regular.png"], + "chars": [ + { + "id": 40, + "index": 116, + "char": "(", + "width": 15, + "height": 47, + "xoffset": 5, + "yoffset": 12, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 0, + "page": 0 + }, + { + "id": 41, + "index": 117, + "char": ")", + "width": 15, + "height": 47, + "xoffset": 5, + "yoffset": 12, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 48, + "page": 0 + }, + { + "id": 91, + "index": 118, + "char": "[", + "width": 12, + "height": 45, + "xoffset": 7, + "yoffset": 12, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 96, + "page": 0 + }, + { + "id": 93, + "index": 119, + "char": "]", + "width": 12, + "height": 45, + "xoffset": 6, + "yoffset": 12, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 142, + "page": 0 + }, + { + "id": 402, + "index": 86, + "char": "ƒ", + "width": 23, + "height": 45, + "xoffset": 1, + "yoffset": 14, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 188, + "page": 0 + }, + { + "id": 8747, + "index": 580, + "char": "∫", + "width": 19, + "height": 45, + "xoffset": 3, + "yoffset": 14, + "xadvance": 25, + "chnl": 15, + "x": 13, + "y": 96, + "page": 0 + }, + { + "id": 123, + "index": 120, + "char": "{", + "width": 18, + "height": 44, + "xoffset": 5, + "yoffset": 13, + "xadvance": 25, + "chnl": 15, + "x": 13, + "y": 142, + "page": 0 + }, + { + "id": 125, + "index": 121, + "char": "}", + "width": 18, + "height": 44, + "xoffset": 5, + "yoffset": 13, + "xadvance": 25, + "chnl": 15, + "x": 16, + "y": 0, + "page": 0 + }, + { + "id": 1092, + "index": 448, + "char": "ф", + "width": 24, + "height": 44, + "xoffset": 1, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 16, + "y": 45, + "page": 0 + }, + { + "id": 197, + "index": 165, + "char": "Å", + "width": 26, + "height": 44, + "xoffset": 0, + "yoffset": 6, + "xadvance": 25, + "chnl": 15, + "x": 35, + "y": 0, + "page": 0 + }, + { + "id": 167, + "index": 154, + "char": "§", + "width": 26, + "height": 44, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 234, + "page": 0 + }, + { + "id": 254, + "index": 78, + "char": "þ", + "width": 23, + "height": 44, + "xoffset": 2, + "yoffset": 14, + "xadvance": 25, + "chnl": 15, + "x": 24, + "y": 187, + "page": 0 + }, + { + "id": 106, + "index": 37, + "char": "j", + "width": 17, + "height": 43, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 32, + "y": 142, + "page": 0 + }, + { + "id": 212, + "index": 213, + "char": "Ô", + "width": 25, + "height": 43, + "xoffset": 0, + "yoffset": 7, + "xadvance": 25, + "chnl": 15, + "x": 33, + "y": 90, + "page": 0 + }, + { + "id": 199, + "index": 171, + "char": "Ç", + "width": 25, + "height": 43, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 41, + "y": 45, + "page": 0 + }, + { + "id": 253, + "index": 339, + "char": "ý", + "width": 26, + "height": 43, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 62, + "y": 0, + "page": 0 + }, + { + "id": 268, + "index": 170, + "char": "Č", + "width": 25, + "height": 43, + "xoffset": 0, + "yoffset": 7, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 279, + "page": 0 + }, + { + "id": 352, + "index": 226, + "char": "Š", + "width": 25, + "height": 43, + "xoffset": 0, + "yoffset": 7, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 323, + "page": 0 + }, + { + "id": 36, + "index": 82, + "char": "$", + "width": 23, + "height": 43, + "xoffset": 1, + "yoffset": 11, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 367, + "page": 0 + }, + { + "id": 213, + "index": 221, + "char": "Õ", + "width": 25, + "height": 43, + "xoffset": 0, + "yoffset": 7, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 411, + "page": 0 + }, + { + "id": 255, + "index": 341, + "char": "ÿ", + "width": 26, + "height": 43, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 24, + "y": 367, + "page": 0 + }, + { + "id": 217, + "index": 235, + "char": "Ù", + "width": 24, + "height": 42, + "xoffset": 1, + "yoffset": 9, + "xadvance": 25, + "chnl": 15, + "x": 26, + "y": 279, + "page": 0 + }, + { + "id": 220, + "index": 234, + "char": "Ü", + "width": 24, + "height": 42, + "xoffset": 1, + "yoffset": 9, + "xadvance": 25, + "chnl": 15, + "x": 26, + "y": 322, + "page": 0 + }, + { + "id": 194, + "index": 160, + "char": "Â", + "width": 26, + "height": 42, + "xoffset": 0, + "yoffset": 8, + "xadvance": 25, + "chnl": 15, + "x": 27, + "y": 232, + "page": 0 + }, + { + "id": 202, + "index": 178, + "char": "Ê", + "width": 22, + "height": 42, + "xoffset": 2, + "yoffset": 8, + "xadvance": 25, + "chnl": 15, + "x": 48, + "y": 186, + "page": 0 + }, + { + "id": 206, + "index": 193, + "char": "Î", + "width": 22, + "height": 42, + "xoffset": 2, + "yoffset": 8, + "xadvance": 25, + "chnl": 15, + "x": 50, + "y": 134, + "page": 0 + }, + { + "id": 219, + "index": 233, + "char": "Û", + "width": 24, + "height": 42, + "xoffset": 1, + "yoffset": 8, + "xadvance": 25, + "chnl": 15, + "x": 59, + "y": 89, + "page": 0 + }, + { + "id": 211, + "index": 211, + "char": "Ó", + "width": 25, + "height": 42, + "xoffset": 0, + "yoffset": 8, + "xadvance": 25, + "chnl": 15, + "x": 67, + "y": 44, + "page": 0 + }, + { + "id": 218, + "index": 231, + "char": "Ú", + "width": 24, + "height": 42, + "xoffset": 1, + "yoffset": 9, + "xadvance": 25, + "chnl": 15, + "x": 89, + "y": 0, + "page": 0 + }, + { + "id": 209, + "index": 210, + "char": "Ñ", + "width": 23, + "height": 42, + "xoffset": 1, + "yoffset": 8, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 455, + "page": 0 + }, + { + "id": 1049, + "index": 776, + "char": "Й", + "width": 23, + "height": 42, + "xoffset": 1, + "yoffset": 8, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 498, + "page": 0 + }, + { + "id": 214, + "index": 214, + "char": "Ö", + "width": 25, + "height": 42, + "xoffset": 0, + "yoffset": 8, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 541, + "page": 0 + }, + { + "id": 958, + "index": 399, + "char": "ξ", + "width": 22, + "height": 42, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 24, + "y": 455, + "page": 0 + }, + { + "id": 950, + "index": 394, + "char": "ζ", + "width": 24, + "height": 42, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 24, + "y": 498, + "page": 0 + }, + { + "id": 946, + "index": 390, + "char": "β", + "width": 23, + "height": 42, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 26, + "y": 411, + "page": 0 + }, + { + "id": 124, + "index": 142, + "char": "|", + "width": 7, + "height": 42, + "xoffset": 9, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 47, + "y": 454, + "page": 0 + }, + { + "id": 195, + "index": 167, + "char": "Ã", + "width": 26, + "height": 42, + "xoffset": 0, + "yoffset": 8, + "xadvance": 25, + "chnl": 15, + "x": 50, + "y": 411, + "page": 0 + }, + { + "id": 210, + "index": 215, + "char": "Ò", + "width": 25, + "height": 42, + "xoffset": 0, + "yoffset": 8, + "xadvance": 25, + "chnl": 15, + "x": 51, + "y": 275, + "page": 0 + }, + { + "id": 381, + "index": 251, + "char": "Ž", + "width": 24, + "height": 42, + "xoffset": 0, + "yoffset": 8, + "xadvance": 25, + "chnl": 15, + "x": 54, + "y": 229, + "page": 0 + }, + { + "id": 8225, + "index": 145, + "char": "‡", + "width": 24, + "height": 42, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 71, + "y": 177, + "page": 0 + }, + { + "id": 201, + "index": 175, + "char": "É", + "width": 22, + "height": 41, + "xoffset": 2, + "yoffset": 9, + "xadvance": 25, + "chnl": 15, + "x": 73, + "y": 132, + "page": 0 + }, + { + "id": 192, + "index": 162, + "char": "À", + "width": 26, + "height": 41, + "xoffset": 0, + "yoffset": 9, + "xadvance": 25, + "chnl": 15, + "x": 84, + "y": 87, + "page": 0 + }, + { + "id": 200, + "index": 181, + "char": "È", + "width": 22, + "height": 41, + "xoffset": 2, + "yoffset": 9, + "xadvance": 25, + "chnl": 15, + "x": 93, + "y": 43, + "page": 0 + }, + { + "id": 203, + "index": 179, + "char": "Ë", + "width": 22, + "height": 41, + "xoffset": 2, + "yoffset": 9, + "xadvance": 25, + "chnl": 15, + "x": 114, + "y": 0, + "page": 0 + }, + { + "id": 207, + "index": 194, + "char": "Ï", + "width": 22, + "height": 41, + "xoffset": 2, + "yoffset": 9, + "xadvance": 25, + "chnl": 15, + "x": 51, + "y": 318, + "page": 0 + }, + { + "id": 205, + "index": 191, + "char": "Í", + "width": 22, + "height": 41, + "xoffset": 2, + "yoffset": 9, + "xadvance": 25, + "chnl": 15, + "x": 51, + "y": 360, + "page": 0 + }, + { + "id": 193, + "index": 158, + "char": "Á", + "width": 26, + "height": 41, + "xoffset": 0, + "yoffset": 9, + "xadvance": 25, + "chnl": 15, + "x": 74, + "y": 318, + "page": 0 + }, + { + "id": 221, + "index": 246, + "char": "Ý", + "width": 26, + "height": 41, + "xoffset": -1, + "yoffset": 9, + "xadvance": 25, + "chnl": 15, + "x": 77, + "y": 272, + "page": 0 + }, + { + "id": 1044, + "index": 419, + "char": "Д", + "width": 26, + "height": 41, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 74, + "y": 360, + "page": 0 + }, + { + "id": 1025, + "index": 763, + "char": "Ё", + "width": 22, + "height": 41, + "xoffset": 2, + "yoffset": 9, + "xadvance": 25, + "chnl": 15, + "x": 79, + "y": 220, + "page": 0 + }, + { + "id": 1062, + "index": 425, + "char": "Ц", + "width": 25, + "height": 41, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 96, + "y": 129, + "page": 0 + }, + { + "id": 1065, + "index": 428, + "char": "Щ", + "width": 26, + "height": 41, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 111, + "y": 85, + "page": 0 + }, + { + "id": 196, + "index": 161, + "char": "Ä", + "width": 26, + "height": 41, + "xoffset": 0, + "yoffset": 9, + "xadvance": 25, + "chnl": 15, + "x": 116, + "y": 42, + "page": 0 + }, + { + "id": 204, + "index": 196, + "char": "Ì", + "width": 22, + "height": 41, + "xoffset": 2, + "yoffset": 9, + "xadvance": 25, + "chnl": 15, + "x": 137, + "y": 0, + "page": 0 + }, + { + "id": 376, + "index": 248, + "char": "Ÿ", + "width": 26, + "height": 41, + "xoffset": -1, + "yoffset": 9, + "xadvance": 25, + "chnl": 15, + "x": 96, + "y": 171, + "page": 0 + }, + { + "id": 81, + "index": 18, + "char": "Q", + "width": 26, + "height": 39, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 122, + "y": 127, + "page": 0 + }, + { + "id": 166, + "index": 143, + "char": "¦", + "width": 8, + "height": 39, + "xoffset": 8, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 138, + "y": 84, + "page": 0 + }, + { + "id": 8721, + "index": 577, + "char": "∑", + "width": 27, + "height": 39, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 143, + "y": 42, + "page": 0 + }, + { + "id": 8719, + "index": 576, + "char": "∏", + "width": 22, + "height": 38, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 160, + "y": 0, + "page": 0 + }, + { + "id": 229, + "index": 260, + "char": "å", + "width": 23, + "height": 37, + "xoffset": 1, + "yoffset": 13, + "xadvance": 25, + "chnl": 15, + "x": 147, + "y": 82, + "page": 0 + }, + { + "id": 216, + "index": 219, + "char": "Ø", + "width": 26, + "height": 37, + "xoffset": -1, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 102, + "y": 213, + "page": 0 + }, + { + "id": 100, + "index": 31, + "char": "d", + "width": 23, + "height": 36, + "xoffset": 1, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 123, + "y": 167, + "page": 0 + }, + { + "id": 102, + "index": 33, + "char": "f", + "width": 24, + "height": 36, + "xoffset": 1, + "yoffset": 14, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 584, + "page": 0 + }, + { + "id": 104, + "index": 35, + "char": "h", + "width": 22, + "height": 36, + "xoffset": 2, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 621, + "page": 0 + }, + { + "id": 107, + "index": 38, + "char": "k", + "width": 24, + "height": 36, + "xoffset": 2, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 658, + "page": 0 + }, + { + "id": 108, + "index": 39, + "char": "l", + "width": 23, + "height": 36, + "xoffset": 2, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 23, + "y": 621, + "page": 0 + }, + { + "id": 98, + "index": 29, + "char": "b", + "width": 23, + "height": 36, + "xoffset": 2, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 25, + "y": 584, + "page": 0 + }, + { + "id": 226, + "index": 255, + "char": "â", + "width": 23, + "height": 36, + "xoffset": 1, + "yoffset": 14, + "xadvance": 25, + "chnl": 15, + "x": 26, + "y": 541, + "page": 0 + }, + { + "id": 234, + "index": 273, + "char": "ê", + "width": 24, + "height": 36, + "xoffset": 1, + "yoffset": 14, + "xadvance": 25, + "chnl": 15, + "x": 49, + "y": 497, + "page": 0 + }, + { + "id": 244, + "index": 306, + "char": "ô", + "width": 24, + "height": 36, + "xoffset": 1, + "yoffset": 14, + "xadvance": 25, + "chnl": 15, + "x": 55, + "y": 454, + "page": 0 + }, + { + "id": 251, + "index": 326, + "char": "û", + "width": 22, + "height": 36, + "xoffset": 2, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 77, + "y": 402, + "page": 0 + }, + { + "id": 241, + "index": 303, + "char": "ñ", + "width": 22, + "height": 36, + "xoffset": 2, + "yoffset": 14, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 695, + "page": 0 + }, + { + "id": 322, + "index": 299, + "char": "ł", + "width": 23, + "height": 36, + "xoffset": 2, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 732, + "page": 0 + }, + { + "id": 231, + "index": 266, + "char": "ç", + "width": 23, + "height": 36, + "xoffset": 1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 23, + "y": 695, + "page": 0 + }, + { + "id": 269, + "index": 265, + "char": "č", + "width": 23, + "height": 36, + "xoffset": 1, + "yoffset": 14, + "xadvance": 25, + "chnl": 15, + "x": 25, + "y": 658, + "page": 0 + }, + { + "id": 353, + "index": 319, + "char": "š", + "width": 23, + "height": 36, + "xoffset": 2, + "yoffset": 14, + "xadvance": 25, + "chnl": 15, + "x": 47, + "y": 621, + "page": 0 + }, + { + "id": 47, + "index": 137, + "char": "/", + "width": 20, + "height": 36, + "xoffset": 3, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 49, + "y": 578, + "page": 0 + }, + { + "id": 92, + "index": 138, + "char": "\\", + "width": 20, + "height": 36, + "xoffset": 3, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 50, + "y": 534, + "page": 0 + }, + { + "id": 1073, + "index": 435, + "char": "б", + "width": 24, + "height": 36, + "xoffset": 1, + "yoffset": 14, + "xadvance": 25, + "chnl": 15, + "x": 70, + "y": 571, + "page": 0 + }, + { + "id": 948, + "index": 392, + "char": "δ", + "width": 25, + "height": 36, + "xoffset": 0, + "yoffset": 14, + "xadvance": 25, + "chnl": 15, + "x": 71, + "y": 534, + "page": 0 + }, + { + "id": 966, + "index": 406, + "char": "φ", + "width": 25, + "height": 36, + "xoffset": 0, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 74, + "y": 491, + "page": 0 + }, + { + "id": 968, + "index": 407, + "char": "ψ", + "width": 26, + "height": 36, + "xoffset": 0, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 80, + "y": 439, + "page": 0 + }, + { + "id": 162, + "index": 83, + "char": "¢", + "width": 23, + "height": 36, + "xoffset": 1, + "yoffset": 19, + "xadvance": 25, + "chnl": 15, + "x": 100, + "y": 402, + "page": 0 + }, + { + "id": 223, + "index": 80, + "char": "ß", + "width": 23, + "height": 36, + "xoffset": 1, + "yoffset": 14, + "xadvance": 25, + "chnl": 15, + "x": 101, + "y": 314, + "page": 0 + }, + { + "id": 227, + "index": 262, + "char": "ã", + "width": 23, + "height": 36, + "xoffset": 1, + "yoffset": 14, + "xadvance": 25, + "chnl": 15, + "x": 101, + "y": 351, + "page": 0 + }, + { + "id": 240, + "index": 76, + "char": "ð", + "width": 24, + "height": 36, + "xoffset": -1, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 104, + "y": 251, + "page": 0 + }, + { + "id": 245, + "index": 314, + "char": "õ", + "width": 24, + "height": 36, + "xoffset": 1, + "yoffset": 14, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 769, + "page": 0 + }, + { + "id": 8706, + "index": 575, + "char": "∂", + "width": 24, + "height": 36, + "xoffset": 1, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 24, + "y": 732, + "page": 0 + }, + { + "id": 121, + "index": 52, + "char": "y", + "width": 26, + "height": 35, + "xoffset": -1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 47, + "y": 695, + "page": 0 + }, + { + "id": 112, + "index": 43, + "char": "p", + "width": 23, + "height": 35, + "xoffset": 2, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 49, + "y": 658, + "page": 0 + }, + { + "id": 113, + "index": 44, + "char": "q", + "width": 23, + "height": 35, + "xoffset": 1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 71, + "y": 608, + "page": 0 + }, + { + "id": 103, + "index": 34, + "char": "g", + "width": 23, + "height": 35, + "xoffset": 1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 73, + "y": 644, + "page": 0 + }, + { + "id": 79, + "index": 16, + "char": "O", + "width": 25, + "height": 35, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 95, + "y": 571, + "page": 0 + }, + { + "id": 83, + "index": 20, + "char": "S", + "width": 25, + "height": 35, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 95, + "y": 607, + "page": 0 + }, + { + "id": 71, + "index": 8, + "char": "G", + "width": 25, + "height": 35, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 97, + "y": 528, + "page": 0 + }, + { + "id": 67, + "index": 4, + "char": "C", + "width": 25, + "height": 35, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 100, + "y": 476, + "page": 0 + }, + { + "id": 233, + "index": 270, + "char": "é", + "width": 24, + "height": 35, + "xoffset": 1, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 107, + "y": 439, + "page": 0 + }, + { + "id": 224, + "index": 257, + "char": "à", + "width": 23, + "height": 35, + "xoffset": 1, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 124, + "y": 388, + "page": 0 + }, + { + "id": 232, + "index": 276, + "char": "è", + "width": 24, + "height": 35, + "xoffset": 1, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 125, + "y": 288, + "page": 0 + }, + { + "id": 249, + "index": 328, + "char": "ù", + "width": 22, + "height": 35, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 125, + "y": 324, + "page": 0 + }, + { + "id": 235, + "index": 274, + "char": "ë", + "width": 24, + "height": 35, + "xoffset": 1, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 129, + "y": 204, + "page": 0 + }, + { + "id": 252, + "index": 327, + "char": "ü", + "width": 22, + "height": 35, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 147, + "y": 167, + "page": 0 + }, + { + "id": 238, + "index": 287, + "char": "î", + "width": 23, + "height": 35, + "xoffset": 2, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 149, + "y": 120, + "page": 0 + }, + { + "id": 225, + "index": 253, + "char": "á", + "width": 23, + "height": 35, + "xoffset": 1, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 129, + "y": 240, + "page": 0 + }, + { + "id": 243, + "index": 304, + "char": "ó", + "width": 24, + "height": 35, + "xoffset": 1, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 171, + "y": 39, + "page": 0 + }, + { + "id": 250, + "index": 324, + "char": "ú", + "width": 22, + "height": 35, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 183, + "y": 0, + "page": 0 + }, + { + "id": 338, + "index": 74, + "char": "Œ", + "width": 27, + "height": 35, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 171, + "y": 75, + "page": 0 + }, + { + "id": 56, + "index": 62, + "char": "8", + "width": 23, + "height": 35, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 196, + "y": 36, + "page": 0 + }, + { + "id": 51, + "index": 57, + "char": "3", + "width": 23, + "height": 35, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 206, + "y": 0, + "page": 0 + }, + { + "id": 48, + "index": 54, + "char": "0", + "width": 23, + "height": 35, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 806, + "page": 0 + }, + { + "id": 191, + "index": 94, + "char": "¿", + "width": 21, + "height": 35, + "xoffset": 2, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 842, + "page": 0 + }, + { + "id": 37, + "index": 140, + "char": "%", + "width": 27, + "height": 35, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 878, + "page": 0 + }, + { + "id": 8364, + "index": 566, + "char": "€", + "width": 24, + "height": 35, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 22, + "y": 842, + "page": 0 + }, + { + "id": 38, + "index": 152, + "char": "&", + "width": 26, + "height": 35, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 24, + "y": 806, + "page": 0 + }, + { + "id": 1105, + "index": 794, + "char": "ё", + "width": 24, + "height": 35, + "xoffset": 1, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 25, + "y": 769, + "page": 0 + }, + { + "id": 1047, + "index": 421, + "char": "З", + "width": 25, + "height": 35, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 49, + "y": 731, + "page": 0 + }, + { + "id": 1081, + "index": 788, + "char": "й", + "width": 22, + "height": 35, + "xoffset": 1, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 50, + "y": 767, + "page": 0 + }, + { + "id": 1054, + "index": 779, + "char": "О", + "width": 25, + "height": 35, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 74, + "y": 680, + "page": 0 + }, + { + "id": 1088, + "index": 790, + "char": "р", + "width": 23, + "height": 35, + "xoffset": 2, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 97, + "y": 643, + "page": 0 + }, + { + "id": 1057, + "index": 782, + "char": "С", + "width": 25, + "height": 35, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 914, + "page": 0 + }, + { + "id": 1091, + "index": 792, + "char": "у", + "width": 26, + "height": 35, + "xoffset": -1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 950, + "page": 0 + }, + { + "id": 1069, + "index": 432, + "char": "Э", + "width": 24, + "height": 35, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 26, + "y": 914, + "page": 0 + }, + { + "id": 1070, + "index": 433, + "char": "Ю", + "width": 25, + "height": 35, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 28, + "y": 878, + "page": 0 + }, + { + "id": 246, + "index": 307, + "char": "ö", + "width": 24, + "height": 35, + "xoffset": 1, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 47, + "y": 842, + "page": 0 + }, + { + "id": 228, + "index": 256, + "char": "ä", + "width": 23, + "height": 35, + "xoffset": 1, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 0, + "y": 986, + "page": 0 + }, + { + "id": 962, + "index": 402, + "char": "ς", + "width": 24, + "height": 35, + "xoffset": 0, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 51, + "y": 803, + "page": 0 + }, + { + "id": 961, + "index": 401, + "char": "ρ", + "width": 23, + "height": 35, + "xoffset": 1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 73, + "y": 767, + "page": 0 + }, + { + "id": 952, + "index": 396, + "char": "θ", + "width": 22, + "height": 35, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 24, + "y": 986, + "page": 0 + }, + { + "id": 947, + "index": 391, + "char": "γ", + "width": 27, + "height": 35, + "xoffset": -1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 27, + "y": 950, + "page": 0 + }, + { + "id": 951, + "index": 395, + "char": "η", + "width": 23, + "height": 35, + "xoffset": 1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 51, + "y": 914, + "page": 0 + }, + { + "id": 955, + "index": 398, + "char": "λ", + "width": 26, + "height": 35, + "xoffset": -1, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 54, + "y": 878, + "page": 0 + }, + { + "id": 956, + "index": 755, + "char": "μ", + "width": 21, + "height": 35, + "xoffset": 2, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 47, + "y": 986, + "page": 0 + }, + { + "id": 920, + "index": 381, + "char": "Θ", + "width": 25, + "height": 35, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 55, + "y": 950, + "page": 0 + }, + { + "id": 927, + "index": 741, + "char": "Ο", + "width": 25, + "height": 35, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 75, + "y": 914, + "page": 0 + }, + { + "id": 181, + "index": 363, + "char": "µ", + "width": 21, + "height": 35, + "xoffset": 2, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 72, + "y": 839, + "page": 0 + }, + { + "id": 242, + "index": 308, + "char": "ò", + "width": 24, + "height": 35, + "xoffset": 1, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 76, + "y": 803, + "page": 0 + }, + { + "id": 382, + "index": 344, + "char": "ž", + "width": 23, + "height": 35, + "xoffset": 1, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 69, + "y": 986, + "page": 0 + }, + { + "id": 8240, + "index": 141, + "char": "‰", + "width": 27, + "height": 35, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 81, + "y": 950, + "page": 0 + }, + { + "id": 105, + "index": 36, + "char": "i", + "width": 23, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 81, + "y": 875, + "page": 0 + }, + { + "id": 65, + "index": 2, + "char": "A", + "width": 26, + "height": 34, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 94, + "y": 839, + "page": 0 + }, + { + "id": 90, + "index": 27, + "char": "Z", + "width": 24, + "height": 34, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 93, + "y": 986, + "page": 0 + }, + { + "id": 69, + "index": 6, + "char": "E", + "width": 22, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 101, + "y": 910, + "page": 0 + }, + { + "id": 82, + "index": 19, + "char": "R", + "width": 24, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 105, + "y": 874, + "page": 0 + }, + { + "id": 84, + "index": 21, + "char": "T", + "width": 26, + "height": 34, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 109, + "y": 945, + "page": 0 + }, + { + "id": 89, + "index": 26, + "char": "Y", + "width": 26, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 124, + "y": 909, + "page": 0 + }, + { + "id": 85, + "index": 22, + "char": "U", + "width": 24, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 118, + "y": 980, + "page": 0 + }, + { + "id": 73, + "index": 10, + "char": "I", + "width": 22, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 136, + "y": 944, + "page": 0 + }, + { + "id": 80, + "index": 17, + "char": "P", + "width": 24, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 143, + "y": 979, + "page": 0 + }, + { + "id": 68, + "index": 5, + "char": "D", + "width": 24, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 75, + "y": 716, + "page": 0 + }, + { + "id": 70, + "index": 7, + "char": "F", + "width": 22, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 97, + "y": 751, + "page": 0 + }, + { + "id": 72, + "index": 9, + "char": "H", + "width": 23, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 101, + "y": 786, + "page": 0 + }, + { + "id": 74, + "index": 11, + "char": "J", + "width": 23, + "height": 34, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 121, + "y": 821, + "page": 0 + }, + { + "id": 75, + "index": 12, + "char": "K", + "width": 25, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 130, + "y": 856, + "page": 0 + }, + { + "id": 76, + "index": 13, + "char": "L", + "width": 22, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 151, + "y": 891, + "page": 0 + }, + { + "id": 77, + "index": 14, + "char": "M", + "width": 24, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 159, + "y": 926, + "page": 0 + }, + { + "id": 87, + "index": 24, + "char": "W", + "width": 27, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 168, + "y": 961, + "page": 0 + }, + { + "id": 88, + "index": 25, + "char": "X", + "width": 26, + "height": 34, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 100, + "y": 679, + "page": 0 + }, + { + "id": 86, + "index": 23, + "char": "V", + "width": 26, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 100, + "y": 714, + "page": 0 + }, + { + "id": 66, + "index": 3, + "char": "B", + "width": 23, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 120, + "y": 749, + "page": 0 + }, + { + "id": 78, + "index": 15, + "char": "N", + "width": 23, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 125, + "y": 784, + "page": 0 + }, + { + "id": 239, + "index": 288, + "char": "ï", + "width": 23, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 145, + "y": 819, + "page": 0 + }, + { + "id": 237, + "index": 285, + "char": "í", + "width": 23, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 156, + "y": 854, + "page": 0 + }, + { + "id": 321, + "index": 206, + "char": "Ł", + "width": 25, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 174, + "y": 889, + "page": 0 + }, + { + "id": 198, + "index": 72, + "char": "Æ", + "width": 28, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 184, + "y": 924, + "page": 0 + }, + { + "id": 55, + "index": 61, + "char": "7", + "width": 24, + "height": 34, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 196, + "y": 959, + "page": 0 + }, + { + "id": 57, + "index": 63, + "char": "9", + "width": 23, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 121, + "y": 564, + "page": 0 + }, + { + "id": 52, + "index": 58, + "char": "4", + "width": 26, + "height": 34, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 123, + "y": 512, + "page": 0 + }, + { + "id": 53, + "index": 59, + "char": "5", + "width": 23, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 126, + "y": 475, + "page": 0 + }, + { + "id": 54, + "index": 60, + "char": "6", + "width": 23, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 132, + "y": 424, + "page": 0 + }, + { + "id": 49, + "index": 55, + "char": "1", + "width": 16, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 121, + "y": 599, + "page": 0 + }, + { + "id": 50, + "index": 56, + "char": "2", + "width": 24, + "height": 34, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 121, + "y": 634, + "page": 0 + }, + { + "id": 59, + "index": 98, + "char": ";", + "width": 11, + "height": 34, + "xoffset": 8, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 138, + "y": 599, + "page": 0 + }, + { + "id": 33, + "index": 91, + "char": "!", + "width": 9, + "height": 34, + "xoffset": 8, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 145, + "y": 547, + "page": 0 + }, + { + "id": 63, + "index": 93, + "char": "?", + "width": 22, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 127, + "y": 669, + "page": 0 + }, + { + "id": 161, + "index": 92, + "char": "¡", + "width": 9, + "height": 34, + "xoffset": 8, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 146, + "y": 634, + "page": 0 + }, + { + "id": 163, + "index": 84, + "char": "£", + "width": 25, + "height": 34, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 127, + "y": 704, + "page": 0 + }, + { + "id": 35, + "index": 151, + "char": "#", + "width": 27, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 150, + "y": 669, + "page": 0 + }, + { + "id": 64, + "index": 153, + "char": "@", + "width": 26, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 144, + "y": 739, + "page": 0 + }, + { + "id": 1040, + "index": 772, + "char": "А", + "width": 26, + "height": 34, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 153, + "y": 704, + "page": 0 + }, + { + "id": 1041, + "index": 418, + "char": "Б", + "width": 23, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 149, + "y": 774, + "page": 0 + }, + { + "id": 1042, + "index": 773, + "char": "В", + "width": 23, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 171, + "y": 739, + "page": 0 + }, + { + "id": 1043, + "index": 774, + "char": "Г", + "width": 22, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 169, + "y": 809, + "page": 0 + }, + { + "id": 1045, + "index": 775, + "char": "Е", + "width": 22, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 173, + "y": 774, + "page": 0 + }, + { + "id": 1046, + "index": 420, + "char": "Ж", + "width": 28, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 180, + "y": 844, + "page": 0 + }, + { + "id": 1048, + "index": 422, + "char": "И", + "width": 23, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 192, + "y": 809, + "page": 0 + }, + { + "id": 1050, + "index": 769, + "char": "К", + "width": 25, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 200, + "y": 879, + "page": 0 + }, + { + "id": 1051, + "index": 423, + "char": "Л", + "width": 25, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 209, + "y": 844, + "page": 0 + }, + { + "id": 1052, + "index": 777, + "char": "М", + "width": 24, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 213, + "y": 914, + "page": 0 + }, + { + "id": 1053, + "index": 778, + "char": "Н", + "width": 23, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 226, + "y": 879, + "page": 0 + }, + { + "id": 1055, + "index": 780, + "char": "П", + "width": 23, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 150, + "y": 582, + "page": 0 + }, + { + "id": 1056, + "index": 781, + "char": "Р", + "width": 24, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 156, + "y": 617, + "page": 0 + }, + { + "id": 1058, + "index": 783, + "char": "Т", + "width": 26, + "height": 34, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 178, + "y": 652, + "page": 0 + }, + { + "id": 1059, + "index": 424, + "char": "У", + "width": 28, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 180, + "y": 687, + "page": 0 + }, + { + "id": 1060, + "index": 784, + "char": "Ф", + "width": 26, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 195, + "y": 722, + "page": 0 + }, + { + "id": 1061, + "index": 785, + "char": "Х", + "width": 26, + "height": 34, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 196, + "y": 757, + "page": 0 + }, + { + "id": 1063, + "index": 426, + "char": "Ч", + "width": 22, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 216, + "y": 792, + "page": 0 + }, + { + "id": 1064, + "index": 427, + "char": "Ш", + "width": 24, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 235, + "y": 827, + "page": 0 + }, + { + "id": 1066, + "index": 429, + "char": "Ъ", + "width": 26, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 221, + "y": 949, + "page": 0 + }, + { + "id": 1067, + "index": 430, + "char": "Ы", + "width": 24, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 238, + "y": 914, + "page": 0 + }, + { + "id": 1068, + "index": 431, + "char": "Ь", + "width": 23, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 221, + "y": 984, + "page": 0 + }, + { + "id": 1071, + "index": 434, + "char": "Я", + "width": 24, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 245, + "y": 984, + "page": 0 + }, + { + "id": 917, + "index": 734, + "char": "Ε", + "width": 22, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 248, + "y": 949, + "page": 0 + }, + { + "id": 929, + "index": 742, + "char": "Ρ", + "width": 24, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 270, + "y": 984, + "page": 0 + }, + { + "id": 932, + "index": 743, + "char": "Τ", + "width": 26, + "height": 34, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 250, + "y": 862, + "page": 0 + }, + { + "id": 933, + "index": 744, + "char": "Υ", + "width": 26, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 263, + "y": 897, + "page": 0 + }, + { + "id": 921, + "index": 737, + "char": "Ι", + "width": 22, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 271, + "y": 932, + "page": 0 + }, + { + "id": 928, + "index": 384, + "char": "Π", + "width": 23, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 150, + "y": 459, + "page": 0 + }, + { + "id": 913, + "index": 732, + "char": "Α", + "width": 26, + "height": 34, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 150, + "y": 494, + "page": 0 + }, + { + "id": 931, + "index": 385, + "char": "Σ", + "width": 25, + "height": 34, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 155, + "y": 529, + "page": 0 + }, + { + "id": 916, + "index": 380, + "char": "Δ", + "width": 28, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 174, + "y": 564, + "page": 0 + }, + { + "id": 934, + "index": 386, + "char": "Φ", + "width": 26, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 181, + "y": 599, + "page": 0 + }, + { + "id": 915, + "index": 379, + "char": "Γ", + "width": 22, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 205, + "y": 634, + "page": 0 + }, + { + "id": 919, + "index": 736, + "char": "Η", + "width": 23, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 209, + "y": 669, + "page": 0 + }, + { + "id": 926, + "index": 383, + "char": "Ξ", + "width": 23, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 222, + "y": 704, + "page": 0 + }, + { + "id": 922, + "index": 738, + "char": "Κ", + "width": 25, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 223, + "y": 739, + "page": 0 + }, + { + "id": 923, + "index": 382, + "char": "Λ", + "width": 27, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 239, + "y": 774, + "page": 0 + }, + { + "id": 918, + "index": 735, + "char": "Ζ", + "width": 24, + "height": 34, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 260, + "y": 809, + "page": 0 + }, + { + "id": 935, + "index": 745, + "char": "Χ", + "width": 26, + "height": 34, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 277, + "y": 844, + "page": 0 + }, + { + "id": 936, + "index": 387, + "char": "Ψ", + "width": 25, + "height": 34, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 290, + "y": 879, + "page": 0 + }, + { + "id": 937, + "index": 388, + "char": "Ω", + "width": 25, + "height": 34, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 294, + "y": 914, + "page": 0 + }, + { + "id": 914, + "index": 733, + "char": "Β", + "width": 23, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 294, + "y": 949, + "page": 0 + }, + { + "id": 925, + "index": 740, + "char": "Ν", + "width": 23, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 295, + "y": 984, + "page": 0 + }, + { + "id": 924, + "index": 739, + "char": "Μ", + "width": 24, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 318, + "y": 949, + "page": 0 + }, + { + "id": 165, + "index": 85, + "char": "¥", + "width": 28, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 319, + "y": 984, + "page": 0 + }, + { + "id": 182, + "index": 155, + "char": "¶", + "width": 20, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 148, + "y": 324, + "page": 0 + }, + { + "id": 188, + "index": 70, + "char": "¼", + "width": 27, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 150, + "y": 276, + "page": 0 + }, + { + "id": 189, + "index": 69, + "char": "½", + "width": 27, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 153, + "y": 240, + "page": 0 + }, + { + "id": 190, + "index": 71, + "char": "¾", + "width": 28, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 154, + "y": 203, + "page": 0 + }, + { + "id": 208, + "index": 185, + "char": "Ð", + "width": 29, + "height": 34, + "xoffset": -3, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 170, + "y": 156, + "page": 0 + }, + { + "id": 222, + "index": 77, + "char": "Þ", + "width": 23, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 173, + "y": 111, + "page": 0 + }, + { + "id": 236, + "index": 289, + "char": "ì", + "width": 23, + "height": 34, + "xoffset": 2, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 197, + "y": 111, + "page": 0 + }, + { + "id": 8224, + "index": 144, + "char": "†", + "width": 24, + "height": 34, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 199, + "y": 72, + "page": 0 + }, + { + "id": 8359, + "index": 89, + "char": "₧", + "width": 26, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 220, + "y": 36, + "page": 0 + }, + { + "id": 8710, + "index": 380, + "char": "∆", + "width": 28, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 230, + "y": 0, + "page": 0 + }, + { + "id": 8730, + "index": 578, + "char": "√", + "width": 27, + "height": 34, + "xoffset": -1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 148, + "y": 359, + "page": 0 + }, + { + "id": 9674, + "index": 581, + "char": "◊", + "width": 23, + "height": 34, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 169, + "y": 311, + "page": 0 + }, + { + "id": 1076, + "index": 438, + "char": "д", + "width": 27, + "height": 33, + "xoffset": -1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 178, + "y": 275, + "page": 0 + }, + { + "id": 1094, + "index": 449, + "char": "ц", + "width": 24, + "height": 33, + "xoffset": 1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 181, + "y": 238, + "page": 0 + }, + { + "id": 1097, + "index": 452, + "char": "щ", + "width": 26, + "height": 33, + "xoffset": 0, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 183, + "y": 191, + "page": 0 + }, + { + "id": 116, + "index": 47, + "char": "t", + "width": 23, + "height": 32, + "xoffset": 1, + "yoffset": 18, + "xadvance": 25, + "chnl": 15, + "x": 200, + "y": 146, + "page": 0 + }, + { + "id": 248, + "index": 312, + "char": "ø", + "width": 24, + "height": 32, + "xoffset": 1, + "yoffset": 21, + "xadvance": 25, + "chnl": 15, + "x": 221, + "y": 107, + "page": 0 + }, + { + "id": 177, + "index": 126, + "char": "±", + "width": 23, + "height": 30, + "xoffset": 1, + "yoffset": 20, + "xadvance": 25, + "chnl": 15, + "x": 196, + "y": 994, + "page": 0 + }, + { + "id": 230, + "index": 73, + "char": "æ", + "width": 28, + "height": 27, + "xoffset": -1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 148, + "y": 394, + "page": 0 + }, + { + "id": 339, + "index": 75, + "char": "œ", + "width": 28, + "height": 27, + "xoffset": -1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 224, + "y": 71, + "page": 0 + }, + { + "id": 58, + "index": 97, + "char": ":", + "width": 10, + "height": 28, + "xoffset": 9, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 168, + "y": 996, + "page": 0 + }, + { + "id": 1078, + "index": 439, + "char": "ж", + "width": 28, + "height": 26, + "xoffset": -2, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 247, + "y": 35, + "page": 0 + }, + { + "id": 8804, + "index": 134, + "char": "≤", + "width": 21, + "height": 28, + "xoffset": 2, + "yoffset": 22, + "xadvance": 25, + "chnl": 15, + "x": 259, + "y": 0, + "page": 0 + }, + { + "id": 8805, + "index": 135, + "char": "≥", + "width": 22, + "height": 28, + "xoffset": 2, + "yoffset": 21, + "xadvance": 25, + "chnl": 15, + "x": 156, + "y": 422, + "page": 0 + }, + { + "id": 97, + "index": 28, + "char": "a", + "width": 23, + "height": 27, + "xoffset": 1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 174, + "y": 451, + "page": 0 + }, + { + "id": 101, + "index": 32, + "char": "e", + "width": 24, + "height": 27, + "xoffset": 1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 176, + "y": 346, + "page": 0 + }, + { + "id": 114, + "index": 45, + "char": "r", + "width": 19, + "height": 27, + "xoffset": 5, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 125, + "y": 360, + "page": 0 + }, + { + "id": 117, + "index": 48, + "char": "u", + "width": 22, + "height": 27, + "xoffset": 2, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 193, + "y": 309, + "page": 0 + }, + { + "id": 111, + "index": 42, + "char": "o", + "width": 24, + "height": 27, + "xoffset": 1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 177, + "y": 374, + "page": 0 + }, + { + "id": 115, + "index": 46, + "char": "s", + "width": 23, + "height": 27, + "xoffset": 2, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 201, + "y": 337, + "page": 0 + }, + { + "id": 109, + "index": 40, + "char": "m", + "width": 25, + "height": 27, + "xoffset": 0, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 179, + "y": 402, + "page": 0 + }, + { + "id": 119, + "index": 50, + "char": "w", + "width": 27, + "height": 26, + "xoffset": -1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 202, + "y": 365, + "page": 0 + }, + { + "id": 99, + "index": 30, + "char": "c", + "width": 23, + "height": 27, + "xoffset": 1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 177, + "y": 479, + "page": 0 + }, + { + "id": 110, + "index": 41, + "char": "n", + "width": 22, + "height": 27, + "xoffset": 2, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 198, + "y": 430, + "page": 0 + }, + { + "id": 126, + "index": 157, + "char": "~", + "width": 27, + "height": 12, + "xoffset": -1, + "yoffset": 30, + "xadvance": 25, + "chnl": 15, + "x": 183, + "y": 225, + "page": 0 + }, + { + "id": 1072, + "index": 786, + "char": "а", + "width": 23, + "height": 27, + "xoffset": 1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 205, + "y": 392, + "page": 0 + }, + { + "id": 1077, + "index": 787, + "char": "е", + "width": 24, + "height": 27, + "xoffset": 1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 210, + "y": 179, + "page": 0 + }, + { + "id": 1079, + "index": 440, + "char": "з", + "width": 24, + "height": 27, + "xoffset": 1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 224, + "y": 140, + "page": 0 + }, + { + "id": 1086, + "index": 789, + "char": "о", + "width": 24, + "height": 27, + "xoffset": 1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 246, + "y": 99, + "page": 0 + }, + { + "id": 1089, + "index": 791, + "char": "с", + "width": 23, + "height": 27, + "xoffset": 1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 253, + "y": 62, + "page": 0 + }, + { + "id": 1101, + "index": 456, + "char": "э", + "width": 24, + "height": 27, + "xoffset": 1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 276, + "y": 29, + "page": 0 + }, + { + "id": 1102, + "index": 457, + "char": "ю", + "width": 25, + "height": 27, + "xoffset": 0, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 281, + "y": 0, + "page": 0 + }, + { + "id": 949, + "index": 393, + "char": "ε", + "width": 24, + "height": 27, + "xoffset": 1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 181, + "y": 507, + "page": 0 + }, + { + "id": 964, + "index": 404, + "char": "τ", + "width": 22, + "height": 27, + "xoffset": 2, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 181, + "y": 535, + "page": 0 + }, + { + "id": 965, + "index": 405, + "char": "υ", + "width": 23, + "height": 27, + "xoffset": 1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 203, + "y": 563, + "page": 0 + }, + { + "id": 953, + "index": 397, + "char": "ι", + "width": 22, + "height": 27, + "xoffset": 2, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 204, + "y": 535, + "page": 0 + }, + { + "id": 959, + "index": 754, + "char": "ο", + "width": 24, + "height": 27, + "xoffset": 1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 208, + "y": 591, + "page": 0 + }, + { + "id": 960, + "index": 400, + "char": "π", + "width": 27, + "height": 27, + "xoffset": 0, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 201, + "y": 458, + "page": 0 + }, + { + "id": 945, + "index": 389, + "char": "α", + "width": 25, + "height": 27, + "xoffset": 1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 221, + "y": 420, + "page": 0 + }, + { + "id": 963, + "index": 403, + "char": "σ", + "width": 26, + "height": 27, + "xoffset": 0, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 229, + "y": 392, + "page": 0 + }, + { + "id": 969, + "index": 408, + "char": "ω", + "width": 26, + "height": 27, + "xoffset": 0, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 206, + "y": 486, + "page": 0 + }, + { + "id": 164, + "index": 90, + "char": "¤", + "width": 26, + "height": 27, + "xoffset": 0, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 229, + "y": 448, + "page": 0 + }, + { + "id": 169, + "index": 146, + "char": "©", + "width": 26, + "height": 27, + "xoffset": 0, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 247, + "y": 420, + "page": 0 + }, + { + "id": 174, + "index": 147, + "char": "®", + "width": 26, + "height": 27, + "xoffset": 0, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 228, + "y": 619, + "page": 0 + }, + { + "id": 8734, + "index": 579, + "char": "∞", + "width": 27, + "height": 20, + "xoffset": -1, + "yoffset": 26, + "xadvance": 25, + "chnl": 15, + "x": 206, + "y": 514, + "page": 0 + }, + { + "id": 122, + "index": 53, + "char": "z", + "width": 23, + "height": 26, + "xoffset": 1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 233, + "y": 476, + "page": 0 + }, + { + "id": 120, + "index": 51, + "char": "x", + "width": 25, + "height": 26, + "xoffset": 0, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 256, + "y": 448, + "page": 0 + }, + { + "id": 118, + "index": 49, + "char": "v", + "width": 25, + "height": 26, + "xoffset": 0, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 227, + "y": 535, + "page": 0 + }, + { + "id": 8211, + "index": 104, + "char": "–", + "width": 26, + "height": 7, + "xoffset": 0, + "yoffset": 30, + "xadvance": 25, + "chnl": 15, + "x": 173, + "y": 146, + "page": 0 + }, + { + "id": 43, + "index": 124, + "char": "+", + "width": 24, + "height": 26, + "xoffset": 0, + "yoffset": 21, + "xadvance": 25, + "chnl": 15, + "x": 227, + "y": 562, + "page": 0 + }, + { + "id": 1074, + "index": 436, + "char": "в", + "width": 23, + "height": 26, + "xoffset": 1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 233, + "y": 589, + "page": 0 + }, + { + "id": 1075, + "index": 437, + "char": "г", + "width": 22, + "height": 26, + "xoffset": 2, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 252, + "y": 562, + "page": 0 + }, + { + "id": 1080, + "index": 441, + "char": "и", + "width": 22, + "height": 26, + "xoffset": 1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 234, + "y": 503, + "page": 0 + }, + { + "id": 1082, + "index": 442, + "char": "к", + "width": 25, + "height": 26, + "xoffset": 1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 253, + "y": 530, + "page": 0 + }, + { + "id": 1083, + "index": 443, + "char": "л", + "width": 25, + "height": 26, + "xoffset": -1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 257, + "y": 475, + "page": 0 + }, + { + "id": 1084, + "index": 444, + "char": "м", + "width": 23, + "height": 26, + "xoffset": 1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 257, + "y": 502, + "page": 0 + }, + { + "id": 1085, + "index": 445, + "char": "н", + "width": 22, + "height": 26, + "xoffset": 1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 233, + "y": 647, + "page": 0 + }, + { + "id": 1087, + "index": 446, + "char": "п", + "width": 22, + "height": 26, + "xoffset": 1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 233, + "y": 674, + "page": 0 + }, + { + "id": 1090, + "index": 447, + "char": "т", + "width": 25, + "height": 26, + "xoffset": 0, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 255, + "y": 616, + "page": 0 + }, + { + "id": 1093, + "index": 793, + "char": "х", + "width": 25, + "height": 26, + "xoffset": 0, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 257, + "y": 589, + "page": 0 + }, + { + "id": 1095, + "index": 450, + "char": "ч", + "width": 23, + "height": 26, + "xoffset": 1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 275, + "y": 557, + "page": 0 + }, + { + "id": 1096, + "index": 451, + "char": "ш", + "width": 24, + "height": 26, + "xoffset": 1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 279, + "y": 529, + "page": 0 + }, + { + "id": 1098, + "index": 453, + "char": "ъ", + "width": 26, + "height": 26, + "xoffset": -1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 281, + "y": 502, + "page": 0 + }, + { + "id": 1099, + "index": 454, + "char": "ы", + "width": 23, + "height": 26, + "xoffset": 1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 246, + "y": 701, + "page": 0 + }, + { + "id": 1100, + "index": 455, + "char": "ь", + "width": 23, + "height": 26, + "xoffset": 1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 249, + "y": 728, + "page": 0 + }, + { + "id": 1103, + "index": 458, + "char": "я", + "width": 24, + "height": 26, + "xoffset": 0, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 267, + "y": 755, + "page": 0 + }, + { + "id": 954, + "index": 753, + "char": "κ", + "width": 24, + "height": 26, + "xoffset": 2, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 267, + "y": 782, + "page": 0 + }, + { + "id": 967, + "index": 757, + "char": "χ", + "width": 25, + "height": 26, + "xoffset": 0, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 285, + "y": 809, + "page": 0 + }, + { + "id": 957, + "index": 756, + "char": "ν", + "width": 25, + "height": 26, + "xoffset": 0, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 304, + "y": 836, + "page": 0 + }, + { + "id": 305, + "index": 365, + "char": "ı", + "width": 23, + "height": 26, + "xoffset": 2, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 316, + "y": 863, + "page": 0 + }, + { + "id": 8212, + "index": 105, + "char": "—", + "width": 26, + "height": 7, + "xoffset": 0, + "yoffset": 30, + "xadvance": 25, + "chnl": 15, + "x": 253, + "y": 90, + "page": 0 + }, + { + "id": 8230, + "index": 99, + "char": "…", + "width": 26, + "height": 10, + "xoffset": 3, + "yoffset": 41, + "xadvance": 25, + "chnl": 15, + "x": 224, + "y": 168, + "page": 0 + }, + { + "id": 247, + "index": 128, + "char": "÷", + "width": 24, + "height": 25, + "xoffset": 0, + "yoffset": 21, + "xadvance": 25, + "chnl": 15, + "x": 277, + "y": 57, + "page": 0 + }, + { + "id": 8260, + "index": 139, + "char": "⁄", + "width": 17, + "height": 25, + "xoffset": 4, + "yoffset": 21, + "xadvance": 25, + "chnl": 15, + "x": 104, + "y": 288, + "page": 0 + }, + { + "id": 42, + "index": 150, + "char": "*", + "width": 24, + "height": 24, + "xoffset": 1, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 301, + "y": 28, + "page": 0 + }, + { + "id": 8482, + "index": 148, + "char": "™", + "width": 24, + "height": 15, + "xoffset": 0, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 210, + "y": 207, + "page": 0 + }, + { + "id": 95, + "index": 102, + "char": "_", + "width": 23, + "height": 7, + "xoffset": 1, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 181, + "y": 634, + "page": 0 + }, + { + "id": 60, + "index": 132, + "char": "<", + "width": 21, + "height": 23, + "xoffset": 1, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 316, + "y": 890, + "page": 0 + }, + { + "id": 62, + "index": 133, + "char": ">", + "width": 22, + "height": 23, + "xoffset": 2, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 307, + "y": 0, + "page": 0 + }, + { + "id": 215, + "index": 127, + "char": "×", + "width": 22, + "height": 23, + "xoffset": 2, + "yoffset": 23, + "xadvance": 25, + "chnl": 15, + "x": 320, + "y": 914, + "page": 0 + }, + { + "id": 8215, + "index": 561, + "char": "‗", + "width": 23, + "height": 12, + "xoffset": 1, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 246, + "y": 127, + "page": 0 + }, + { + "id": 8776, + "index": 131, + "char": "≈", + "width": 23, + "height": 19, + "xoffset": 1, + "yoffset": 25, + "xadvance": 25, + "chnl": 15, + "x": 338, + "y": 890, + "page": 0 + }, + { + "id": 8800, + "index": 130, + "char": "≠", + "width": 22, + "height": 23, + "xoffset": 1, + "yoffset": 24, + "xadvance": 25, + "chnl": 15, + "x": 249, + "y": 140, + "page": 0 + }, + { + "id": 61, + "index": 129, + "char": "=", + "width": 22, + "height": 16, + "xoffset": 2, + "yoffset": 27, + "xadvance": 25, + "chnl": 15, + "x": 271, + "y": 967, + "page": 0 + }, + { + "id": 172, + "index": 136, + "char": "¬", + "width": 21, + "height": 13, + "xoffset": 2, + "yoffset": 30, + "xadvance": 25, + "chnl": 15, + "x": 101, + "y": 388, + "page": 0 + }, + { + "id": 179, + "index": 66, + "char": "³", + "width": 16, + "height": 21, + "xoffset": 5, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 179, + "y": 996, + "page": 0 + }, + { + "id": 8319, + "index": 565, + "char": "ⁿ", + "width": 17, + "height": 21, + "xoffset": 5, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 271, + "y": 98, + "page": 0 + }, + { + "id": 45, + "index": 103, + "char": "-", + "width": 20, + "height": 7, + "xoffset": 2, + "yoffset": 31, + "xadvance": 25, + "chnl": 15, + "x": 50, + "y": 177, + "page": 0 + }, + { + "id": 170, + "index": 67, + "char": "ª", + "width": 18, + "height": 20, + "xoffset": 4, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 179, + "y": 430, + "page": 0 + }, + { + "id": 171, + "index": 362, + "char": "«", + "width": 20, + "height": 20, + "xoffset": 2, + "yoffset": 27, + "xadvance": 25, + "chnl": 15, + "x": 256, + "y": 643, + "page": 0 + }, + { + "id": 178, + "index": 65, + "char": "²", + "width": 17, + "height": 20, + "xoffset": 4, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 256, + "y": 664, + "page": 0 + }, + { + "id": 185, + "index": 64, + "char": "¹", + "width": 12, + "height": 20, + "xoffset": 6, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 270, + "y": 685, + "page": 0 + }, + { + "id": 186, + "index": 68, + "char": "º", + "width": 18, + "height": 20, + "xoffset": 4, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 274, + "y": 664, + "page": 0 + }, + { + "id": 187, + "index": 364, + "char": "»", + "width": 20, + "height": 20, + "xoffset": 3, + "yoffset": 27, + "xadvance": 25, + "chnl": 15, + "x": 277, + "y": 643, + "page": 0 + }, + { + "id": 8249, + "index": 122, + "char": "‹", + "width": 13, + "height": 20, + "xoffset": 6, + "yoffset": 27, + "xadvance": 25, + "chnl": 15, + "x": 270, + "y": 706, + "page": 0 + }, + { + "id": 8250, + "index": 123, + "char": "›", + "width": 13, + "height": 20, + "xoffset": 6, + "yoffset": 27, + "xadvance": 25, + "chnl": 15, + "x": 283, + "y": 685, + "page": 0 + }, + { + "id": 175, + "index": 350, + "char": "¯", + "width": 19, + "height": 7, + "xoffset": 3, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 80, + "y": 476, + "page": 0 + }, + { + "id": 733, + "index": 355, + "char": "˝", + "width": 19, + "height": 10, + "xoffset": 3, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 101, + "y": 821, + "page": 0 + }, + { + "id": 732, + "index": 349, + "char": "˜", + "width": 18, + "height": 10, + "xoffset": 1, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 216, + "y": 827, + "page": 0 + }, + { + "id": 168, + "index": 353, + "char": "¨", + "width": 17, + "height": 8, + "xoffset": 4, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 51, + "y": 402, + "page": 0 + }, + { + "id": 711, + "index": 356, + "char": "ˇ", + "width": 17, + "height": 9, + "xoffset": 4, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 79, + "y": 262, + "page": 0 + }, + { + "id": 710, + "index": 348, + "char": "ˆ", + "width": 16, + "height": 9, + "xoffset": 2, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 127, + "y": 739, + "page": 0 + }, + { + "id": 728, + "index": 351, + "char": "˘", + "width": 16, + "height": 9, + "xoffset": 4, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 149, + "y": 809, + "page": 0 + }, + { + "id": 8220, + "index": 111, + "char": "“", + "width": 16, + "height": 15, + "xoffset": 5, + "yoffset": 14, + "xadvance": 25, + "chnl": 15, + "x": 75, + "y": 751, + "page": 0 + }, + { + "id": 8221, + "index": 112, + "char": "”", + "width": 16, + "height": 15, + "xoffset": 4, + "yoffset": 14, + "xadvance": 25, + "chnl": 15, + "x": 100, + "y": 512, + "page": 0 + }, + { + "id": 8222, + "index": 113, + "char": "„", + "width": 16, + "height": 15, + "xoffset": 4, + "yoffset": 41, + "xadvance": 25, + "chnl": 15, + "x": 132, + "y": 459, + "page": 0 + }, + { + "id": 44, + "index": 95, + "char": ",", + "width": 10, + "height": 15, + "xoffset": 5, + "yoffset": 42, + "xadvance": 25, + "chnl": 15, + "x": 304, + "y": 863, + "page": 0 + }, + { + "id": 8216, + "index": 108, + "char": "‘", + "width": 10, + "height": 15, + "xoffset": 8, + "yoffset": 14, + "xadvance": 25, + "chnl": 15, + "x": 256, + "y": 685, + "page": 0 + }, + { + "id": 8217, + "index": 109, + "char": "’", + "width": 10, + "height": 15, + "xoffset": 7, + "yoffset": 14, + "xadvance": 25, + "chnl": 15, + "x": 123, + "y": 547, + "page": 0 + }, + { + "id": 176, + "index": 149, + "char": "°", + "width": 14, + "height": 15, + "xoffset": 5, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 180, + "y": 722, + "page": 0 + }, + { + "id": 8218, + "index": 110, + "char": "‚", + "width": 10, + "height": 15, + "xoffset": 7, + "yoffset": 41, + "xadvance": 25, + "chnl": 15, + "x": 134, + "y": 547, + "page": 0 + }, + { + "id": 39, + "index": 106, + "char": "'", + "width": 7, + "height": 14, + "xoffset": 8, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 151, + "y": 926, + "page": 0 + }, + { + "id": 34, + "index": 107, + "char": "\"", + "width": 14, + "height": 14, + "xoffset": 5, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 235, + "y": 862, + "page": 0 + }, + { + "id": 731, + "index": 359, + "char": "˛", + "width": 12, + "height": 14, + "xoffset": 6, + "yoffset": 45, + "xadvance": 25, + "chnl": 15, + "x": 250, + "y": 897, + "page": 0 + }, + { + "id": 184, + "index": 358, + "char": "¸", + "width": 10, + "height": 13, + "xoffset": 7, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 208, + "y": 619, + "page": 0 + }, + { + "id": 8226, + "index": 101, + "char": "•", + "width": 12, + "height": 13, + "xoffset": 6, + "yoffset": 26, + "xadvance": 25, + "chnl": 15, + "x": 209, + "y": 704, + "page": 0 + }, + { + "id": 96, + "index": 346, + "char": "`", + "width": 12, + "height": 9, + "xoffset": 7, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 180, + "y": 879, + "page": 0 + }, + { + "id": 180, + "index": 347, + "char": "´", + "width": 12, + "height": 9, + "xoffset": 6, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 200, + "y": 914, + "page": 0 + }, + { + "id": 730, + "index": 354, + "char": "˚", + "width": 12, + "height": 12, + "xoffset": 6, + "yoffset": 15, + "xadvance": 25, + "chnl": 15, + "x": 277, + "y": 879, + "page": 0 + }, + { + "id": 46, + "index": 96, + "char": ".", + "width": 10, + "height": 10, + "xoffset": 8, + "yoffset": 41, + "xadvance": 25, + "chnl": 15, + "x": 149, + "y": 156, + "page": 0 + }, + { + "id": 183, + "index": 100, + "char": "·", + "width": 9, + "height": 9, + "xoffset": 8, + "yoffset": 29, + "xadvance": 25, + "chnl": 15, + "x": 169, + "y": 844, + "page": 0 + }, + { + "id": 729, + "index": 352, + "char": "˙", + "width": 9, + "height": 9, + "xoffset": 8, + "yoffset": 16, + "xadvance": 25, + "chnl": 15, + "x": 118, + "y": 1015, + "page": 0 + }, + { + "id": 8729, + "index": 0, + "char": "∙", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 13, + "y": 187, + "page": 0 + }, + { + "id": 8745, + "index": 0, + "char": "∩", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 32, + "y": 186, + "page": 0 + }, + { + "id": 8801, + "index": 0, + "char": "≡", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 41, + "y": 89, + "page": 0 + }, + { + "id": 8976, + "index": 0, + "char": "⌐", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 62, + "y": 44, + "page": 0 + }, + { + "id": 8992, + "index": 0, + "char": "⌠", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 26, + "y": 454, + "page": 0 + }, + { + "id": 8993, + "index": 0, + "char": "⌡", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 89, + "y": 43, + "page": 0 + }, + { + "id": 9472, + "index": 0, + "char": "─", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 114, + "y": 42, + "page": 0 + }, + { + "id": 9474, + "index": 0, + "char": "│", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 116, + "y": 84, + "page": 0 + }, + { + "id": 9484, + "index": 0, + "char": "┌", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 122, + "y": 167, + "page": 0 + }, + { + "id": 9488, + "index": 0, + "char": "┐", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 47, + "y": 497, + "page": 0 + }, + { + "id": 9492, + "index": 0, + "char": "└", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 49, + "y": 534, + "page": 0 + }, + { + "id": 9496, + "index": 0, + "char": "┘", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 70, + "y": 608, + "page": 0 + }, + { + "id": 9500, + "index": 0, + "char": "├", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 47, + "y": 731, + "page": 0 + }, + { + "id": 9508, + "index": 0, + "char": "┤", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 49, + "y": 767, + "page": 0 + }, + { + "id": 9516, + "index": 0, + "char": "┬", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 49, + "y": 694, + "page": 0 + }, + { + "id": 9524, + "index": 0, + "char": "┴", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 73, + "y": 680, + "page": 0 + }, + { + "id": 9532, + "index": 0, + "char": "┼", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 95, + "y": 643, + "page": 0 + }, + { + "id": 9552, + "index": 0, + "char": "═", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 25, + "y": 805, + "page": 0 + }, + { + "id": 9553, + "index": 0, + "char": "║", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 50, + "y": 803, + "page": 0 + }, + { + "id": 9554, + "index": 0, + "char": "╒", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 94, + "y": 874, + "page": 0 + }, + { + "id": 9555, + "index": 0, + "char": "╓", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 105, + "y": 909, + "page": 0 + }, + { + "id": 9556, + "index": 0, + "char": "╔", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 124, + "y": 944, + "page": 0 + }, + { + "id": 9557, + "index": 0, + "char": "╕", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 136, + "y": 979, + "page": 0 + }, + { + "id": 9558, + "index": 0, + "char": "╖", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 74, + "y": 716, + "page": 0 + }, + { + "id": 9559, + "index": 0, + "char": "╗", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 97, + "y": 679, + "page": 0 + }, + { + "id": 9560, + "index": 0, + "char": "╘", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 107, + "y": 475, + "page": 0 + }, + { + "id": 9561, + "index": 0, + "char": "╙", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 195, + "y": 757, + "page": 0 + }, + { + "id": 9562, + "index": 0, + "char": "╚", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 222, + "y": 739, + "page": 0 + }, + { + "id": 9563, + "index": 0, + "char": "╛", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 147, + "y": 203, + "page": 0 + }, + { + "id": 9564, + "index": 0, + "char": "╜", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 153, + "y": 275, + "page": 0 + }, + { + "id": 9565, + "index": 0, + "char": "╝", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 220, + "y": 994, + "page": 0 + }, + { + "id": 9566, + "index": 0, + "char": "╞", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 220, + "y": 71, + "page": 0 + }, + { + "id": 9567, + "index": 0, + "char": "╟", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 230, + "y": 35, + "page": 0 + }, + { + "id": 9568, + "index": 0, + "char": "╠", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 176, + "y": 374, + "page": 0 + }, + { + "id": 9569, + "index": 0, + "char": "╡", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 201, + "y": 365, + "page": 0 + }, + { + "id": 9570, + "index": 0, + "char": "╢", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 181, + "y": 563, + "page": 0 + }, + { + "id": 9571, + "index": 0, + "char": "╣", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 233, + "y": 503, + "page": 0 + }, + { + "id": 9572, + "index": 0, + "char": "╤", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 256, + "y": 475, + "page": 0 + }, + { + "id": 9573, + "index": 0, + "char": "╥", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 257, + "y": 529, + "page": 0 + }, + { + "id": 9574, + "index": 0, + "char": "╦", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 279, + "y": 556, + "page": 0 + }, + { + "id": 9575, + "index": 0, + "char": "╧", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 276, + "y": 57, + "page": 0 + }, + { + "id": 9576, + "index": 0, + "char": "╨", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 281, + "y": 28, + "page": 0 + }, + { + "id": 9577, + "index": 0, + "char": "╩", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 123, + "y": 388, + "page": 0 + }, + { + "id": 9578, + "index": 0, + "char": "╪", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 253, + "y": 98, + "page": 0 + }, + { + "id": 9579, + "index": 0, + "char": "╫", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 50, + "y": 185, + "page": 0 + }, + { + "id": 9580, + "index": 0, + "char": "╬", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 255, + "y": 643, + "page": 0 + }, + { + "id": 9600, + "index": 0, + "char": "▀", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 270, + "y": 727, + "page": 0 + }, + { + "id": 9604, + "index": 0, + "char": "▄", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 149, + "y": 459, + "page": 0 + }, + { + "id": 9608, + "index": 0, + "char": "█", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 315, + "y": 863, + "page": 0 + }, + { + "id": 9612, + "index": 0, + "char": "▌", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 123, + "y": 563, + "page": 0 + }, + { + "id": 9616, + "index": 0, + "char": "▐", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 180, + "y": 738, + "page": 0 + }, + { + "id": 9617, + "index": 0, + "char": "░", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 208, + "y": 633, + "page": 0 + }, + { + "id": 9618, + "index": 0, + "char": "▒", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 179, + "y": 844, + "page": 0 + }, + { + "id": 9619, + "index": 0, + "char": "▓", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 14, + "y": 187, + "page": 0 + }, + { + "id": 9632, + "index": 0, + "char": "■", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 33, + "y": 186, + "page": 0 + }, + { + "id": 64257, + "index": 0, + "char": "fi", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 42, + "y": 89, + "page": 0 + }, + { + "id": 64258, + "index": 0, + "char": "fl", + "width": 0, + "height": 0, + "xoffset": -2, + "yoffset": 46, + "xadvance": 25, + "chnl": 15, + "x": 63, + "y": 44, + "page": 0 + } + ], + "info": { + "face": "RobotoMono-Regular", + "size": 42, + "bold": 0, + "italic": 0, + "charset": [ + "'", + "a", + ",", + "z", + "e", + "r", + "t", + "y", + "u", + "i", + "o", + "p", + "q", + "s", + "d", + "f", + "g", + "h", + "j", + "k", + "l", + "m", + "w", + "x", + "c", + "v", + "b", + "n", + "A", + "Z", + "E", + "R", + "T", + "Y", + "U", + "I", + "O", + "P", + "Q", + "S", + "D", + "F", + "G", + "H", + "J", + "K", + "L", + "M", + "W", + "X", + "C", + "V", + "B", + "N", + "é", + "É", + "à", + "À", + "è", + "È", + "ù", + "Ù", + "ë", + "Ë", + "ü", + "Ü", + "ï", + "Ï", + "â", + "ê", + "î", + "ô", + "û", + "Â", + "Ê", + "Î", + "Ô", + "Û", + "í", + "Í", + "á", + "Á", + "ó", + "Ó", + "ú", + "Ú", + "ñ", + "Ñ", + "ł", + "Ł", + "ç", + "Ç", + "ý", + "Ý", + "č", + "Č", + "š", + "Š", + "æ", + "Æ", + "œ", + "Œ", + "/", + "\\", + "*", + "-", + "–", + "+", + "7", + "8", + "9", + "4", + "5", + "6", + "1", + "2", + "3", + "0", + ";", + ":", + "!", + "?", + "¡", + "¿", + ".", + "%", + "$", + "£", + "€", + "=", + "{", + "}", + "(", + ")", + "[", + "]", + "&", + "~", + "\"", + "‘", + "’", + "`", + "#", + "_", + "°", + "@", + "А", + "а", + "Б", + "б", + "В", + "в", + "Г", + "г", + "Д", + "д", + "Е", + "е", + "Ё", + "ё", + "Ж", + "ж", + "З", + "з", + "И", + "и", + "Й", + "й", + "К", + "к", + "Л", + "л", + "М", + "м", + "Н", + "н", + "О", + "о", + "П", + "п", + "Р", + "р", + "С", + "с", + "Т", + "т", + "У", + "у", + "Ф", + "ф", + "Х", + "х", + "Ц", + "ц", + "Ч", + "ч", + "Ш", + "ш", + "Щ", + "щ", + "Ъ", + "ъ", + "Ы", + "ы", + "Ь", + "ь", + "Э", + "э", + "Ю", + "ю", + "Я", + "я", + "ö", + "Ö", + "ä", + "Ä", + "ς", + "ε", + "ρ", + "τ", + "υ", + "θ", + "ι", + "ο", + "π", + "α", + "σ", + "δ", + "φ", + "γ", + "η", + "ξ", + "κ", + "λ", + "ζ", + "χ", + "ψ", + "ω", + "β", + "ν", + "μ", + "Ε", + "Ρ", + "Τ", + "Υ", + "Θ", + "Ι", + "Ο", + "Π", + "Α", + "Σ", + "Δ", + "Φ", + "Γ", + "Η", + "Ξ", + "Κ", + "Λ", + "Ζ", + "Χ", + "Ψ", + "Ω", + "Β", + "Ν", + "Μ", + "å", + "Å", + "ø", + "Ø", + "<", + ">", + "|", + "¢", + "¤", + "¥", + "¦", + "§", + "¨", + "©", + "ª", + "«", + "¬", + "®", + "¯", + "±", + "²", + "³", + "´", + "µ", + "¶", + "·", + "¸", + "¹", + "º", + "»", + "¼", + "½", + "¾", + "Ã", + "Ì", + "Ð", + "Ò", + "Õ", + "×", + "Þ", + "ß", + "ã", + "ì", + "ð", + "ò", + "õ", + "÷", + "þ", + "ÿ", + "ı", + "Ÿ", + "Ž", + "ž", + "ƒ", + "ˆ", + "ˇ", + "˘", + "˙", + "˚", + "˛", + "˜", + "˝", + "—", + "‗", + "‚", + "“", + "”", + "„", + "†", + "‡", + "•", + "…", + "‰", + "‹", + "›", + "⁄", + "ⁿ", + "₧", + "™", + "∂", + "∆", + "∏", + "∑", + "∙", + "√", + "∞", + "∩", + "∫", + "≈", + "≠", + "≡", + "≤", + "≥", + "⌐", + "⌠", + "⌡", + "─", + "│", + "┌", + "┐", + "└", + "┘", + "├", + "┤", + "┬", + "┴", + "┼", + "═", + "║", + "╒", + "╓", + "╔", + "╕", + "╖", + "╗", + "╘", + "╙", + "╚", + "╛", + "╜", + "╝", + "╞", + "╟", + "╠", + "╡", + "╢", + "╣", + "╤", + "╥", + "╦", + "╧", + "╨", + "╩", + "╪", + "╫", + "╬", + "▀", + "▄", + "█", + "▌", + "▐", + "░", + "▒", + "▓", + "■", + "◊", + "fi", + "fl" + ], + "unicode": 1, + "stretchH": 100, + "smooth": 1, + "aa": 1, + "padding": [2, 2, 2, 2], + "spacing": [0, 0] + }, + "common": { + "lineHeight": 55, + "base": 46, + "scaleW": 1024, + "scaleH": 1024, + "pages": 1, + "packed": 0, + "alphaChnl": 0, + "redChnl": 0, + "greenChnl": 0, + "blueChnl": 0 + }, + "distanceField": {"fieldType": "msdf", "distanceRange": 4}, + "kernings": [] +} diff --git a/streaming-react-app/src/assets/RobotoMono-Regular.png b/streaming-react-app/src/assets/RobotoMono-Regular.png new file mode 100644 index 0000000000000000000000000000000000000000..8a84d8bacacf43d7f8f8349abce99acf666b4f92 Binary files /dev/null and b/streaming-react-app/src/assets/RobotoMono-Regular.png differ diff --git a/streaming-react-app/src/assets/illy.svg b/streaming-react-app/src/assets/illy.svg new file mode 100644 index 0000000000000000000000000000000000000000..59c9a2a5d4138ded258fe0f27fecbcdc2074811d --- /dev/null +++ b/streaming-react-app/src/assets/illy.svg @@ -0,0 +1,990 @@ + + + + +Created by potrace 1.10, written by Peter Selinger 2001-2011 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/streaming-react-app/src/assets/illy2.svg b/streaming-react-app/src/assets/illy2.svg new file mode 100644 index 0000000000000000000000000000000000000000..ed0cb345b888925cca8ecbcbd64c15bb8eac075f --- /dev/null +++ b/streaming-react-app/src/assets/illy2.svg @@ -0,0 +1,990 @@ + + + + +Created by potrace 1.10, written by Peter Selinger 2001-2011 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/streaming-react-app/src/createBufferedSpeechPlayer.ts b/streaming-react-app/src/createBufferedSpeechPlayer.ts new file mode 100644 index 0000000000000000000000000000000000000000..5ef2c5bab95190d485c6ffb34506c7862014778d --- /dev/null +++ b/streaming-react-app/src/createBufferedSpeechPlayer.ts @@ -0,0 +1,173 @@ +import debug from './debug'; + +type AddAudioToBufferFunction = ( + samples: Array, + sampleRate: number, +) => void; + +export type BufferedSpeechPlayer = { + addAudioToBuffer: AddAudioToBufferFunction; + setGain: (gain: number) => void; + start: () => void; + stop: () => void; +}; + +type Options = { + onEnded?: () => void; + onStarted?: () => void; +}; + +export default function createBufferedSpeechPlayer({ + onStarted, + onEnded, +}: Options): BufferedSpeechPlayer { + const audioContext = new AudioContext(); + const gainNode = audioContext.createGain(); + gainNode.connect(audioContext.destination); + + let unplayedAudioBuffers: Array = []; + + let currentPlayingBufferSource: AudioBufferSourceNode | null = null; + + let isPlaying = false; + + // This means that the player starts in the 'stopped' state, and you need to call player.start() for it to start playing + let shouldPlayWhenAudioAvailable = false; + + const setGain = (gain: number) => { + gainNode.gain.setValueAtTime(gain, audioContext.currentTime); + }; + + const start = () => { + shouldPlayWhenAudioAvailable = true; + debug()?.start(); + playNextBufferIfNotAlreadyPlaying(); + }; + + // Stop will stop the audio and clear the buffers + const stop = () => { + shouldPlayWhenAudioAvailable = false; + + // Stop the current buffers + currentPlayingBufferSource?.stop(); + currentPlayingBufferSource = null; + + unplayedAudioBuffers = []; + + onEnded != null && onEnded(); + isPlaying = false; + return; + }; + + const playNextBufferIfNotAlreadyPlaying = () => { + if (!isPlaying) { + playNextBuffer(); + } + }; + + const playNextBuffer = () => { + if (shouldPlayWhenAudioAvailable === false) { + console.debug( + '[BufferedSpeechPlayer][playNextBuffer] Not playing any more audio because shouldPlayWhenAudioAvailable is false.', + ); + // NOTE: we do not need to set isPlaying = false or call onEnded because that will be handled in the stop() function + return; + } + if (unplayedAudioBuffers.length === 0) { + console.debug( + '[BufferedSpeechPlayer][playNextBuffer] No buffers to play.', + ); + if (isPlaying) { + isPlaying = false; + onEnded != null && onEnded(); + } + return; + } + + // If isPlaying is false, then we are starting playback fresh rather than continuing it, and should call onStarted + if (isPlaying === false) { + isPlaying = true; + onStarted != null && onStarted(); + } + + const source = audioContext.createBufferSource(); + + // Get the first unplayed buffer from the array, and remove it from the array + const buffer = unplayedAudioBuffers.shift() ?? null; + source.buffer = buffer; + console.debug( + `[BufferedSpeechPlayer] Playing buffer with ${source.buffer?.length} samples`, + ); + + source.connect(gainNode); + + const startTime = new Date().getTime(); + source.start(); + currentPlayingBufferSource = source; + // This is probably not necessary, but it doesn't hurt + isPlaying = true; + + // TODO: consider changing this to a while loop to avoid deep recursion + const onThisBufferPlaybackEnded = () => { + console.debug( + `[BufferedSpeechPlayer] Buffer with ${source.buffer?.length} samples ended.`, + ); + source.removeEventListener('ended', onThisBufferPlaybackEnded); + const endTime = new Date().getTime(); + debug()?.playedAudio(startTime, endTime, buffer); + currentPlayingBufferSource = null; + + // We don't set isPlaying = false here because we are attempting to continue playing. It will get set to false if there are no more buffers to play + playNextBuffer(); + }; + + source.addEventListener('ended', onThisBufferPlaybackEnded); + }; + + const addAudioToBuffer: AddAudioToBufferFunction = (samples, sampleRate) => { + const incomingArrayBufferChunk = audioContext.createBuffer( + // 1 channel + 1, + samples.length, + sampleRate, + ); + + incomingArrayBufferChunk.copyToChannel( + new Float32Array(samples), + // first channel + 0, + ); + + console.debug( + `[addAudioToBufferAndPlay] Adding buffer with ${incomingArrayBufferChunk.length} samples to queue.`, + ); + + unplayedAudioBuffers.push(incomingArrayBufferChunk); + debug()?.receivedAudio( + incomingArrayBufferChunk.length / incomingArrayBufferChunk.sampleRate, + ); + const audioBuffersTableInfo = unplayedAudioBuffers.map((buffer, i) => { + return { + index: i, + duration: buffer.length / buffer.sampleRate, + samples: buffer.length, + }; + }); + const totalUnplayedDuration = unplayedAudioBuffers.reduce((acc, buffer) => { + return acc + buffer.length / buffer.sampleRate; + }, 0); + + console.debug( + `[addAudioToBufferAndPlay] Current state of incoming audio buffers (${totalUnplayedDuration.toFixed( + 1, + )}s unplayed):`, + ); + console.table(audioBuffersTableInfo); + + if (shouldPlayWhenAudioAvailable) { + playNextBufferIfNotAlreadyPlaying(); + } + }; + + return {addAudioToBuffer, setGain, stop, start}; +} diff --git a/streaming-react-app/src/cursorBlinkInterval.ts b/streaming-react-app/src/cursorBlinkInterval.ts new file mode 100644 index 0000000000000000000000000000000000000000..0d438028585312ca3c106cd34a071416aa8b1f62 --- /dev/null +++ b/streaming-react-app/src/cursorBlinkInterval.ts @@ -0,0 +1 @@ +export const CURSOR_BLINK_INTERVAL_MS = 500; diff --git a/streaming-react-app/src/debug.ts b/streaming-react-app/src/debug.ts new file mode 100644 index 0000000000000000000000000000000000000000..820ce46485f996fc998605bcb53045103286837a --- /dev/null +++ b/streaming-react-app/src/debug.ts @@ -0,0 +1,257 @@ +import {TYPING_ANIMATION_DELAY_MS} from './StreamingInterface'; +import {getURLParams} from './URLParams'; +import audioBuffertoWav from 'audiobuffer-to-wav'; +import './StreamingInterface.css'; + +type StartEndTime = { + start: number; + end: number; +}; + +type StartEndTimeWithAudio = StartEndTime & { + float32Audio: Float32Array; +}; + +type Text = { + time: number; + chars: number; +}; + +type DebugTimings = { + receivedAudio: StartEndTime[]; + playedAudio: StartEndTimeWithAudio[]; + receivedText: Text[]; + renderedText: StartEndTime[]; + sentAudio: StartEndTimeWithAudio[]; + startRenderTextTime: number | null; + startRecordingTime: number | null; + receivedAudioSampleRate: number | null; +}; + +function getInitialTimings(): DebugTimings { + return { + receivedAudio: [], + playedAudio: [], + receivedText: [], + renderedText: [], + sentAudio: [], + startRenderTextTime: null, + startRecordingTime: null, + receivedAudioSampleRate: null, + }; +} + +function downloadAudioBuffer(audioBuffer: AudioBuffer, fileName: string): void { + const wav = audioBuffertoWav(audioBuffer); + const wavBlob = new Blob([new DataView(wav)], { + type: 'audio/wav', + }); + const url = URL.createObjectURL(wavBlob); + const anchor = document.createElement('a'); + anchor.href = url; + anchor.target = '_blank'; + anchor.download = fileName; + anchor.click(); +} + +// Uncomment for debugging without download +// function playAudioBuffer(audioBuffer: AudioBuffer): void { +// const audioContext = new AudioContext(); +// const source = audioContext.createBufferSource(); + +// source.buffer = audioBuffer; +// source.connect(audioContext.destination); +// source.start(); +// } + +// Accumulate timings and audio / text translation samples for debugging and exporting +class DebugTimingsManager { + timings: DebugTimings = getInitialTimings(); + + start(): void { + this.timings = getInitialTimings(); + this.timings.startRecordingTime = new Date().getTime(); + } + + sentAudio(event: AudioProcessingEvent): void { + const end = new Date().getTime(); + const start = end - event.inputBuffer.duration * 1000; + // Copy or else buffer seems to be re-used + const float32Audio = new Float32Array(event.inputBuffer.getChannelData(0)); + this.timings.sentAudio.push({ + start, + end, + float32Audio, + }); + } + + receivedText(text: string): void { + this.timings.receivedText.push({ + time: new Date().getTime(), + chars: text.length, + }); + } + + startRenderText(): void { + if (this.timings.startRenderTextTime == null) { + this.timings.startRenderTextTime = new Date().getTime(); + } + } + + endRenderText(): void { + if (this.timings.startRenderTextTime == null) { + console.warn( + 'Wrong timings of start / end rendering text. startRenderText is null', + ); + return; + } + + this.timings.renderedText.push({ + start: this.timings.startRenderTextTime as number, + end: new Date().getTime(), + }); + this.timings.startRenderTextTime = null; + } + + receivedAudio(duration: number): void { + const start = new Date().getTime(); + this.timings.receivedAudio.push({ + start, + end: start + duration * 1000, + }); + } + + playedAudio(start: number, end: number, buffer: AudioBuffer | null): void { + if (buffer != null) { + if (this.timings.receivedAudioSampleRate == null) { + this.timings.receivedAudioSampleRate = buffer.sampleRate; + } + if (this.timings.receivedAudioSampleRate != buffer.sampleRate) { + console.error( + 'Sample rates of received audio are unequal, will fail to reconstruct debug audio', + this.timings.receivedAudioSampleRate, + buffer.sampleRate, + ); + } + } + this.timings.playedAudio.push({ + start, + end, + float32Audio: + buffer == null + ? new Float32Array() + : new Float32Array(buffer.getChannelData(0)), + }); + } + + getChartData() { + const columns = [ + {type: 'string', id: 'Series'}, + {type: 'date', id: 'Start'}, + {type: 'date', id: 'End'}, + ]; + return [ + columns, + ...this.timings.sentAudio.map((sentAudio) => [ + 'Sent Audio', + new Date(sentAudio.start), + new Date(sentAudio.end), + ]), + ...this.timings.receivedAudio.map((receivedAudio) => [ + 'Received Audio', + new Date(receivedAudio.start), + new Date(receivedAudio.end), + ]), + ...this.timings.playedAudio.map((playedAudio) => [ + 'Played Audio', + new Date(playedAudio.start), + new Date(playedAudio.end), + ]), + // Best estimate duration by multiplying length with animation duration for each letter + ...this.timings.receivedText.map((receivedText) => [ + 'Received Text', + new Date(receivedText.time), + new Date( + receivedText.time + receivedText.chars * TYPING_ANIMATION_DELAY_MS, + ), + ]), + ...this.timings.renderedText.map((renderedText) => [ + 'Rendered Text', + new Date(renderedText.start), + new Date(renderedText.end), + ]), + ]; + } + + downloadInputAudio() { + const audioContext = new AudioContext(); + const totalLength = this.timings.sentAudio.reduce((acc, cur) => { + return acc + cur?.float32Audio?.length ?? 0; + }, 0); + if (totalLength === 0) { + return; + } + + const incomingArrayBuffer = audioContext.createBuffer( + 1, // 1 channel + totalLength, + audioContext.sampleRate, + ); + + const buffer = incomingArrayBuffer.getChannelData(0); + let i = 0; + this.timings.sentAudio.forEach((sentAudio) => { + sentAudio.float32Audio.forEach((bytes) => { + buffer[i++] = bytes; + }); + }); + + // Play for debugging + // playAudioBuffer(incomingArrayBuffer); + downloadAudioBuffer(incomingArrayBuffer, `input_audio.wav`); + } + + downloadOutputAudio() { + const playedAudio = this.timings.playedAudio; + const sampleRate = this.timings.receivedAudioSampleRate; + if ( + playedAudio.length === 0 || + this.timings.startRecordingTime == null || + sampleRate == null + ) { + return null; + } + + let previousEndTime = this.timings.startRecordingTime; + const audioArray: number[] = []; + playedAudio.forEach((audio) => { + const delta = (audio.start - previousEndTime) / 1000; + for (let i = 0; i < delta * sampleRate; i++) { + audioArray.push(0.0); + } + audio.float32Audio.forEach((bytes) => audioArray.push(bytes)); + previousEndTime = audio.end; + }); + const audioContext = new AudioContext(); + const incomingArrayBuffer = audioContext.createBuffer( + 1, // 1 channel + audioArray.length, + sampleRate, + ); + + incomingArrayBuffer.copyToChannel( + new Float32Array(audioArray), + 0, // first channel + ); + + // Play for debugging + // playAudioBuffer(incomingArrayBuffer); + downloadAudioBuffer(incomingArrayBuffer, 'output_audio.wav'); + } +} + +const debugSingleton = new DebugTimingsManager(); +export default function debug(): DebugTimingsManager | null { + const debugParam = getURLParams().debug; + return debugParam ? debugSingleton : null; +} diff --git a/streaming-react-app/src/float32To16BitPCM.ts b/streaming-react-app/src/float32To16BitPCM.ts new file mode 100644 index 0000000000000000000000000000000000000000..8205eefce0666d81abe5914d824da08b31b2314e --- /dev/null +++ b/streaming-react-app/src/float32To16BitPCM.ts @@ -0,0 +1,16 @@ +export default function float32To16BitPCM( + float32Arr: Float32Array, +): Int16Array { + const pcm16bit = new Int16Array(float32Arr.length); + for (let i = 0; i < float32Arr.length; ++i) { + // force number in [-1,1] + const s = Math.max(-1, Math.min(1, float32Arr[i])); + + /** + * convert 32 bit float to 16 bit int pcm audio + * 0x8000 = minimum int16 value, 0x7fff = maximum int16 value + */ + pcm16bit[i] = s < 0 ? s * 0x8000 : s * 0x7fff; + } + return pcm16bit; +} diff --git a/streaming-react-app/src/generateNewRoomID.ts b/streaming-react-app/src/generateNewRoomID.ts new file mode 100644 index 0000000000000000000000000000000000000000..49db3780c52261a5c990e82f73a696f24255a4ad --- /dev/null +++ b/streaming-react-app/src/generateNewRoomID.ts @@ -0,0 +1,56 @@ +import {random} from 'lodash'; + +// const USABLE_CHARACTERS = 'BCDFGHJKMPQRTVWXY2346789'; +const USABLE_CHARACTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; +const ID_LENGTH = 4; + +export function isValidRoomID(id: string | null | undefined): boolean { + if (id == null) { + return false; + } + if (id.length !== ID_LENGTH) { + return false; + } + return isValidPartialRoomID(id); +} + +export function isValidPartialRoomID(roomID: string): boolean { + return ( + roomID.length <= ID_LENGTH && + roomID.split('').every((char) => USABLE_CHARACTERS.includes(char)) + ); +} + +export default function generateNewRoomID(): string { + return Array.from( + {length: ID_LENGTH}, + () => USABLE_CHARACTERS[random(USABLE_CHARACTERS.length - 1)], + ).join(''); +} + +export function getSequentialRoomIDForTestingGenerator(): () => string { + let counter = 0; + + return function generateNextRoomID(): string { + const counterInBase: string = Number(counter) + .toString(USABLE_CHARACTERS.length) + .padStart(ID_LENGTH, '0'); + + if (counterInBase.length > ID_LENGTH) { + throw new Error( + 'Ran out of unique room IDs from the sequential generator', + ); + } + + const result = counterInBase + .split('') + .map( + (digit) => USABLE_CHARACTERS[parseInt(digit, USABLE_CHARACTERS.length)], + ) + .join(''); + + counter++; + + return result; + }; +} diff --git a/streaming-react-app/src/getParamFlag.ts b/streaming-react-app/src/getParamFlag.ts new file mode 100644 index 0000000000000000000000000000000000000000..c469cc38c75fa10686f094548289c5034ee413f6 --- /dev/null +++ b/streaming-react-app/src/getParamFlag.ts @@ -0,0 +1,39 @@ +import type {URLParamNames} from './types/URLParamsTypes'; + +export function getBooleanParamFlag( + flag: URLParamNames, + defaultValue?: boolean, +): boolean { + const paramFlagValue = getBooleanParamFlagWithoutDefault(flag); + + if (paramFlagValue == null) { + // The default value for paramFlags is false, unless they explicitly provide a + // defaultValue via the config + return defaultValue ?? false; + } + + return paramFlagValue; +} + +export function getBooleanParamFlagWithoutDefault( + flag: URLParamNames, +): boolean | null { + const urlParams = new URLSearchParams(window.location.search); + + if (urlParams.get(flag) == null) { + return null; + } + + return urlParams.get(flag) !== '0'; +} + +export function getStringParamFlag( + flag: URLParamNames, + defaultValue?: string, +): string | null { + const urlParams = new URLSearchParams(window.location.search); + + const param = urlParams.get(flag); + + return param ?? defaultValue ?? null; +} diff --git a/streaming-react-app/src/getTranslationSentencesFromReceivedData.ts b/streaming-react-app/src/getTranslationSentencesFromReceivedData.ts new file mode 100644 index 0000000000000000000000000000000000000000..d7a6851f21e5c69dc2fd6428d21e9e86a0109000 --- /dev/null +++ b/streaming-react-app/src/getTranslationSentencesFromReceivedData.ts @@ -0,0 +1,22 @@ +import {ServerTextData, TranslationSentences} from './types/StreamingTypes'; + +export default function getTranslationSentencesFromReceivedData( + receivedData: Array, +): TranslationSentences { + return receivedData + .reduce( + (acc, data) => { + const newAcc = [ + ...acc.slice(0, -1), + acc[acc.length - 1].trim() + ' ' + data.payload, + ]; + if (data.eos) { + newAcc.push(''); + } + + return newAcc; + }, + [''], + ) + .filter((s) => s.trim().length !== 0); +} diff --git a/streaming-react-app/src/isScrolledToDocumentBottom.ts b/streaming-react-app/src/isScrolledToDocumentBottom.ts new file mode 100644 index 0000000000000000000000000000000000000000..90e3f2ff5a56c736e361e77e839f2897accec6d6 --- /dev/null +++ b/streaming-react-app/src/isScrolledToDocumentBottom.ts @@ -0,0 +1,11 @@ +export default function isScrolledToDocumentBottom( + bufferPx: number = 0, +): boolean { + if ( + window.innerHeight + window.scrollY >= + document.body.offsetHeight - bufferPx + ) { + return true; + } + return false; +} diff --git a/streaming-react-app/src/languageLookup.ts b/streaming-react-app/src/languageLookup.ts new file mode 100644 index 0000000000000000000000000000000000000000..fe2abbc61cfad97e5a36896cad50446595d7e8a0 --- /dev/null +++ b/streaming-react-app/src/languageLookup.ts @@ -0,0 +1,119 @@ +const LANG3_TO_NAME = { + afr: 'afrikaans', + amh: 'amharic', + arb: 'arabic', + asm: 'assamese', + azj: 'azerbaijani', + bak: 'bashkir', + bel: 'belarusian', + ben: 'bengali', + bod: 'tibetan', + bos: 'bosnian', + bre: 'breton', + bul: 'bulgarian', + cat: 'catalan', + ces: 'czech', + cmn: 'chinese', + cym: 'welsh', + dan: 'danish', + deu: 'german', + ell: 'greek', + eng: 'english', + est: 'estonian', + eus: 'basque', + fao: 'faroese', + fin: 'finnish', + fra: 'french', + glg: 'galician', + guj: 'gujarati', + hat: 'haitian creole', + hau: 'hausa', + haw: 'hawaiian', + heb: 'hebrew', + hin: 'hindi', + hrv: 'croatian', + hun: 'hungarian', + hye: 'armenian', + ind: 'indonesian', + isl: 'icelandic', + ita: 'italian', + jav: 'javanese', + jpn: 'japanese', + kan: 'kannada', + kat: 'georgian', + kaz: 'kazakh', + khk: 'mongolian', + khm: 'khmer', + kor: 'korean', + lao: 'lao', + lat: 'latin', + lin: 'lingala', + lit: 'lithuanian', + ltz: 'luxembourgish', + lvs: 'latvian', + mal: 'malayalam', + mar: 'marathi', + mkd: 'macedonian', + mlg: 'malagasy', + mlt: 'maltese', + mri: 'maori', + mya: 'myanmar', + nld: 'dutch', + nno: 'nynorsk', + nob: 'norwegian', + npi: 'nepali', + oci: 'occitan', + pan: 'punjabi', + pbt: 'pashto', + pes: 'persian', + pol: 'polish', + por: 'portuguese', + ron: 'romanian', + rus: 'russian', + san: 'sanskrit', + sin: 'sinhala', + slk: 'slovak', + slv: 'slovenian', + sna: 'shona', + snd: 'sindhi', + som: 'somali', + spa: 'spanish', + sqi: 'albanian', + srp: 'serbian', + sun: 'sundanese', + swe: 'swedish', + swh: 'swahili', + tam: 'tamil', + tat: 'tatar', + tel: 'telugu', + tgk: 'tajik', + tgl: 'tagalog', + tha: 'thai', + tuk: 'turkmen', + tur: 'turkish', + ukr: 'ukrainian', + urd: 'urdu', + uzn: 'uzbek', + vie: 'vietnamese', + yid: 'yiddish', + yor: 'yoruba', + zlm: 'malay', +}; + +export function getLanguageFromThreeLetterCode( + lang3Code: string, +): string | null { + try { + const name = LANG3_TO_NAME[lang3Code] ?? null; + if (name == null) { + return null; + } + const capitalizedWords = name + .split(' ') + .map((word: string) => word[0].toUpperCase() + word.slice(1)); + return capitalizedWords.join(' '); + } catch (e) { + console.warn(`Unable to get language name for code ${lang3Code}: ${e}`); + } + return null; +} diff --git a/streaming-react-app/src/main.tsx b/streaming-react-app/src/main.tsx new file mode 100644 index 0000000000000000000000000000000000000000..e5775c051a6fd4ebad5f583ef8d1d6413a47aa46 --- /dev/null +++ b/streaming-react-app/src/main.tsx @@ -0,0 +1,9 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import App from './App.tsx'; + +ReactDOM.createRoot(document.getElementById('root')!).render( + + + , +); diff --git a/streaming-react-app/src/react-xr/ARButton.tsx b/streaming-react-app/src/react-xr/ARButton.tsx new file mode 100644 index 0000000000000000000000000000000000000000..9de536a3071aad466f2426f596012d32a35f2c8d --- /dev/null +++ b/streaming-react-app/src/react-xr/ARButton.tsx @@ -0,0 +1,89 @@ +import * as THREE from 'three'; +import {Button} from '@mui/material'; +import {useCallback, useEffect, useState} from 'react'; +import {BufferedSpeechPlayer} from '../createBufferedSpeechPlayer'; + +type Props = { + bufferedSpeechPlayer: BufferedSpeechPlayer; + renderer: THREE.WebGLRenderer | null; + onARVisible?: () => void; + onARHidden?: () => void; +}; + +export default function ARButton({ + bufferedSpeechPlayer, + renderer, + onARVisible, + onARHidden, +}: Props) { + const [session, setSession] = useState(null); + const [supported, setSupported] = useState(true); + + useEffect(() => { + if (!navigator.xr) { + setSupported(false); + return; + } + navigator.xr.isSessionSupported('immersive-ar').then((supported) => { + setSupported(supported); + }); + }, []); + + const resetBuffers = useCallback( + (event: XRSessionEvent) => { + const session = event.target; + if (!(session instanceof XRSession)) { + return; + } + switch (session.visibilityState) { + case 'visible': + console.log('Restarting speech player, device is visible'); + bufferedSpeechPlayer.stop(); + bufferedSpeechPlayer.start(); + onARVisible?.(); + break; + case 'hidden': + console.log('Stopping speech player, device is hidden'); + bufferedSpeechPlayer.stop(); + bufferedSpeechPlayer.start(); + onARHidden?.(); + break; + } + }, + [bufferedSpeechPlayer], + ); + + async function onSessionStarted(session: XRSession) { + setSession(session); + + session.onvisibilitychange = resetBuffers; + session.onend = onSessionEnded; + + await renderer.xr.setSession(session); + } + + function onSessionEnded() { + setSession(null); + } + + const onClick = () => { + if (session === null) { + navigator.xr!.requestSession('immersive-ar').then(onSessionStarted); + } else { + session.end(); + } + }; + return ( + + ); +} diff --git a/streaming-react-app/src/react-xr/Button.tsx b/streaming-react-app/src/react-xr/Button.tsx new file mode 100644 index 0000000000000000000000000000000000000000..98bc06f99d68470ea2d3de6df424fbb665b60755 --- /dev/null +++ b/streaming-react-app/src/react-xr/Button.tsx @@ -0,0 +1,117 @@ +import {useRef, useEffect} from 'react'; +import * as THREE from 'three'; +import {extend} from '@react-three/fiber'; +import ThreeMeshUI from 'three-mesh-ui'; +import ThreeMeshUIText, {ThreeMeshUITextType} from './ThreeMeshUIText'; +import {Interactive} from '@react-three/xr'; + +/** + * Using `?url` at the end of this import tells vite this is a static asset, and + * provides us a URL to the hashed version of the file when the project is built. + * See: https://vitejs.dev/guide/assets.html#explicit-url-imports + */ +import robotoFontFamilyJson from '../assets/RobotoMono-Regular-msdf.json?url'; +import robotoFontTexture from '../assets/RobotoMono-Regular.png'; + +extend(ThreeMeshUI); + +/** + * Button component that renders as a three-mesh-ui block + */ +export default function Button({ + onClick, + content, + width, + height, + fontSize, + borderRadius, + padding, +}) { + const button = useRef(); + const textRef = useRef(); + + useEffect(() => { + if (textRef.current != null) { + textRef.current.set({content}); + } + }, [textRef, content]); + + useEffect(() => { + if (!button.current) { + return; + } + button.current.setupState({ + state: 'hovered', + attributes: { + offset: 0.002, + backgroundColor: new THREE.Color(0x607b8f), + fontColor: new THREE.Color(0xffffff), + }, + }); + button.current.setupState({ + state: 'idle', + attributes: { + offset: 0.001, + backgroundColor: new THREE.Color(0x465a69), + fontColor: new THREE.Color(0xffffff), + }, + }); + button.current.setupState({ + state: 'selected', + attributes: { + offset: 0.005, + backgroundColor: new THREE.Color(0x000000), + fontColor: new THREE.Color(0xffffff), + }, + }); + button.current.setState('idle'); + }, []); + + const args = [ + { + width, + height, + fontSize, + padding, + justifyContent: 'end', + textAlign: 'center', + alignItems: 'center', + borderRadius, + fontFamily: robotoFontFamilyJson, + fontTexture: robotoFontTexture, + backgroundOpacity: 1, + backgroundColor: new THREE.Color(0x779092), + fontColor: new THREE.Color(0x000000), + }, + ]; + + return ( + { + onClick(); + }} + onHover={() => button.current.setState('hovered')} + onBlur={() => button.current.setState('idle')} + onSelectStart={() => button.current.setState('selected')} + onSelectEnd={() => button.current.setState('idle')}> + button.current.setState('hovered')} + onPointerLeave={() => button.current.setState('idle')} + onPointerDown={() => button.current.setState('selected')} + onPointerUp={() => { + button.current.setState('hovered'); + onClick(); + }}> + + + + + + ); +} diff --git a/streaming-react-app/src/react-xr/Colors.ts b/streaming-react-app/src/react-xr/Colors.ts new file mode 100644 index 0000000000000000000000000000000000000000..86cb3bbd427d4b9509463e0e1694d73b1295bf5d --- /dev/null +++ b/streaming-react-app/src/react-xr/Colors.ts @@ -0,0 +1,6 @@ +import * as THREE from 'three'; + +export const WHITE = new THREE.Color('#FFFFFF'); +export const BLACK = new THREE.Color('#000000'); +export const RED = new THREE.Color('red'); +export const BLUE = new THREE.Color('blue'); diff --git a/streaming-react-app/src/react-xr/MovementController.tsx b/streaming-react-app/src/react-xr/MovementController.tsx new file mode 100644 index 0000000000000000000000000000000000000000..6a197112410b679bf6ea455c15f6d03897257afd --- /dev/null +++ b/streaming-react-app/src/react-xr/MovementController.tsx @@ -0,0 +1,64 @@ +import {useRef} from 'react'; +import {useFrame} from '@react-three/fiber'; +import {useController, useXR} from '@react-three/xr'; +import * as THREE from 'three'; + +const USE_HORIZONTAL = true; +const USE_VERTICAL = true; +const USE_ROTATION = true; +const HORIZONTAL_AXIS = 2; +const VERTICAL_AXIS = 3; +const ROTATION_AXIS = 2; +const SENSITIVITY = 0.05; +const DEADZONE = 0.05; + +/** + * Component to add into the ThreeJS canvas that reads controller (Quest) inputs to change camera position + */ +export default function MovementController() { + const xr = useXR(); + const controller = useController('right'); + const forward = useRef(new THREE.Vector3()); + const horizontal = useRef(new THREE.Vector3()); + + useFrame(() => { + const player = xr.player; + const camera = xr.player.children[0]; + const cameraMatrix = camera.matrixWorld.elements; + forward.current + .set(-cameraMatrix[8], -cameraMatrix[9], -cameraMatrix[10]) + .normalize(); + + const axes = controller?.inputSource?.gamepad?.axes ?? [0, 0, 0, 0]; + + if (USE_HORIZONTAL) { + horizontal.current.copy(forward.current); + horizontal.current.cross(camera.up).normalize(); + + player.position.add( + horizontal.current.multiplyScalar( + (Math.abs(axes[HORIZONTAL_AXIS]) > DEADZONE + ? axes[HORIZONTAL_AXIS] + : 0) * SENSITIVITY, + ), + ); + } + + if (USE_VERTICAL) { + player.position.add( + forward.current.multiplyScalar( + (Math.abs(axes[VERTICAL_AXIS]) > DEADZONE ? axes[VERTICAL_AXIS] : 0) * + SENSITIVITY, + ), + ); + } + + if (USE_ROTATION) { + player.rotation.y -= + (Math.abs(axes[ROTATION_AXIS]) > DEADZONE ? axes[ROTATION_AXIS] : 0) * + SENSITIVITY; + } + }); + + return <>; +} diff --git a/streaming-react-app/src/react-xr/Playground.tsx b/streaming-react-app/src/react-xr/Playground.tsx new file mode 100644 index 0000000000000000000000000000000000000000..5f03e1faca51e3225876d0b1805ff42454cbdaa3 --- /dev/null +++ b/streaming-react-app/src/react-xr/Playground.tsx @@ -0,0 +1,133 @@ +/** + * EXPERIMENTAL components to play around with but not officially use in the demo while + * we develop. + */ +import {useEffect, useState} from 'react'; +import {Object3DNode, extend} from '@react-three/fiber'; +import ThreeMeshUI from 'three-mesh-ui'; + +import {} from '@react-three/xr'; +import {Sparkles, Shadow} from '@react-three/drei'; + +// import FontImage from './assets/Roboto-msdf.png'; +import {FontLoader} from 'three/examples/jsm/loaders/FontLoader.js'; +import {TextGeometry} from 'three/examples/jsm/geometries/TextGeometry.js'; +import ThreeMeshUIText from './ThreeMeshUIText'; +import {ContactShadows, BakeShadows} from '@react-three/drei'; + +extend({TextGeometry}); +extend(ThreeMeshUI); + +declare module '@react-three/fiber' { + interface ThreeElements { + textGeometry: Object3DNode; + } +} + +// This is for textGeometry.. not using three-mesh-ui to display text +export function TitleMesh() { + const font = new FontLoader().parse(); + console.log('font', font); + const [text, setText] = useState('Text'); + + useEffect(() => { + setTimeout(() => { + setText(text + ' more '); + console.log('adding more tex..', text); + }, 1000); + }, [text]); + + return ( + + + + + ); +} + +export function Sphere({ + size = 1, + amount = 50, + color = 'white', + emissive, + ...props +}) { + return ( + + + + + + + ); +} + +export function Title({accentColor}) { + return ( + + + + + ); +} + +export function RandomComponents() { + return ( + <> + + + + + + + + ); +} diff --git a/streaming-react-app/src/react-xr/TextBlocks.tsx b/streaming-react-app/src/react-xr/TextBlocks.tsx new file mode 100644 index 0000000000000000000000000000000000000000..cf9bba848c4008b5956b2f1fbe5253c853321ea8 --- /dev/null +++ b/streaming-react-app/src/react-xr/TextBlocks.tsx @@ -0,0 +1,307 @@ +import {useEffect, useRef, useState} from 'react'; +import robotoFontFamilyJson from '../assets/RobotoMono-Regular-msdf.json?url'; +import robotoFontTexture from '../assets/RobotoMono-Regular.png'; +import ThreeMeshUIText, {ThreeMeshUITextType} from './ThreeMeshUIText'; +import supportedCharSet from './supportedCharSet'; + +const NUM_LINES = 3; + +export const CHARS_PER_LINE = 37; +const MAX_WIDTH = 0.89; +const CHAR_WIDTH = 0.0235; +const Y_COORD_START = -0.38; +const Z_COORD = -1.3; +const LINE_HEIGHT = 0.062; +const BLOCK_SPACING = 0.02; +const FONT_SIZE = 0.038; + +const SCROLL_Y_DELTA = 0.001; + +// Overlay an extra block for padding due to inflexibilities of native padding +const OFFSET = 0.01; +const OFFSET_WIDTH = OFFSET * 3; + +const CHARS_PER_SECOND = 10; + +// The tick interval +const RENDER_INTERVAL = 300; + +const CURSOR_BLINK_INTERVAL_MS = 1000; + +type TextBlockProps = { + content: string; + // The actual position or end position when animating + y: number; + // The start position when animating + startY: number; + textOpacity: number; + backgroundOpacity: number; + index: number; + isBottomLine: boolean; + // key: number; +}; + +type TranscriptState = { + textBlocksProps: TextBlockProps[]; + lastTranslationStringIndex: number; + lastTranslationLineStartIndex: number; + transcriptLines: string[]; + lastRenderTime: number; +}; + +function TextBlock({ + content, + y, + startY, + textOpacity, + backgroundOpacity, + index, + isBottomLine, +}: TextBlockProps) { + const [scrollY, setScrollY] = useState(y); + // We are reusing text blocks so this keeps track of when we changed rows so we can restart animation + const lastIndex = useRef(index); + useEffect(() => { + if (index != lastIndex.current) { + lastIndex.current = index; + !isBottomLine && setScrollY(startY); + } else if (scrollY < y) { + setScrollY((prev) => prev + SCROLL_Y_DELTA); + } + }, [isBottomLine, index, scrollY, setScrollY, startY, y]); + + const [cursorBlinkOn, setCursorBlinkOn] = useState(false); + useEffect(() => { + if (isBottomLine) { + const interval = setInterval(() => { + setCursorBlinkOn((prev) => !prev); + }, CURSOR_BLINK_INTERVAL_MS); + + return () => clearInterval(interval); + } else { + setCursorBlinkOn(false); + } + }, [isBottomLine]); + + const numChars = content.length; + + if (cursorBlinkOn) { + content = content + '|'; + } + + // Accounting for potential cursor for block width (the +1) + const width = + (numChars + (isBottomLine ? 1.1 : 0) + (numChars < 10 ? 1 : 0)) * + CHAR_WIDTH; + + const height = LINE_HEIGHT; + + // This is needed to update text content (doesn't work if we just update the content prop) + const textRef = useRef(); + useEffect(() => { + if (textRef.current != null) { + textRef.current.set({content}); + } + }, [content, textRef, y, startY]); + + // Width starts from 0 and goes 1/2 in each direction + const xPosition = width / 2 - MAX_WIDTH / 2 + OFFSET_WIDTH; + return ( + <> + + + + + + + + ); +} + +function initialTextBlockProps(count: number): TextBlockProps[] { + return Array.from({length: count}).map(() => { + // Push in non display blocks because mesh UI crashes if elements are add / removed from screen. + return { + y: Y_COORD_START, + startY: 0, + index: 0, + textOpacity: 0, + backgroundOpacity: 0, + width: MAX_WIDTH, + height: LINE_HEIGHT, + content: '', + isBottomLine: true, + }; + }); +} + +export default function TextBlocks({ + translationText, +}: { + translationText: string; +}) { + const transcriptStateRef = useRef({ + textBlocksProps: initialTextBlockProps(NUM_LINES), + lastTranslationStringIndex: 0, + lastTranslationLineStartIndex: 0, + transcriptLines: [], + lastRenderTime: new Date().getTime(), + }); + + const transcriptState = transcriptStateRef.current; + const {textBlocksProps, lastTranslationStringIndex, lastRenderTime} = + transcriptState; + + const [charsToRender, setCharsToRender] = useState(0); + + useEffect(() => { + const interval = setInterval(() => { + const currentTime = new Date().getTime(); + const charsToRender = Math.round( + ((currentTime - lastRenderTime) * CHARS_PER_SECOND) / 1000, + ); + setCharsToRender(charsToRender); + }, RENDER_INTERVAL); + + return () => clearInterval(interval); + }, [lastRenderTime]); + + const currentTime = new Date().getTime(); + if (charsToRender < 1) { + return textBlocksProps.map((props, idx) => ( + + )); + } + + const nextTranslationStringIndex = Math.min( + lastTranslationStringIndex + charsToRender, + translationText.length, + ); + const newString = translationText.substring( + lastTranslationStringIndex, + nextTranslationStringIndex, + ); + if (nextTranslationStringIndex === lastTranslationStringIndex) { + transcriptState.lastRenderTime = currentTime; + return textBlocksProps.map((props, idx) => ( + + )); + } + + // Wait until more characters are accumulated if its just blankspace + if (/^\s*$/.test(newString)) { + transcriptState.lastRenderTime = currentTime; + return textBlocksProps.map((props, idx) => ( + + )); + } + + // Ideally we continue where we left off but this is complicated when we have mid-words. Recalculating for now + const runAll = true; + const newSentences = runAll + ? translationText.substring(0, nextTranslationStringIndex).split('\n') + : newString.split('\n'); + const transcriptLines = runAll ? [''] : transcriptState.transcriptLines; + newSentences.forEach((newSentence, sentenceIdx) => { + const words = newSentence.split(/\s+/); + words.forEach((word) => { + const filteredWord = [...word] + .filter((c) => { + if (supportedCharSet().has(c)) { + return true; + } + console.error( + `Unsupported char ${c} - make sure this is supported in the font family msdf file`, + ); + return false; + }) + .join(''); + + const lastLineSoFar = transcriptLines[0]; + const charCount = lastLineSoFar.length + filteredWord.length + 1; + + if (charCount <= CHARS_PER_LINE) { + transcriptLines[0] = lastLineSoFar + ' ' + filteredWord; + } else { + transcriptLines.unshift(filteredWord); + } + }); + + if (sentenceIdx < newSentences.length - 1) { + transcriptLines.unshift('\n'); + transcriptLines.unshift(''); + } + }); + + transcriptState.transcriptLines = transcriptLines; + transcriptState.lastTranslationStringIndex = nextTranslationStringIndex; + + const newTextBlocksProps: TextBlockProps[] = []; + let currentY = Y_COORD_START; + + transcriptLines.forEach((line, i) => { + if (newTextBlocksProps.length == NUM_LINES) { + return; + } + + // const line = transcriptLines[i]; + if (line === '\n') { + currentY += BLOCK_SPACING; + return; + } + const y = currentY + LINE_HEIGHT / 2; + const isBottomLine = newTextBlocksProps.length === 0; + + const textOpacity = 1 - 0.1 * newTextBlocksProps.length; + newTextBlocksProps.push({ + y, + startY: currentY, + index: i, + textOpacity, + backgroundOpacity: 0.98, + content: line, + isBottomLine, + }); + + currentY = y + LINE_HEIGHT / 2; + }); + + const numRemainingBlocks = NUM_LINES - newTextBlocksProps.length; + if (numRemainingBlocks > 0) { + newTextBlocksProps.push(...initialTextBlockProps(numRemainingBlocks)); + } + + transcriptState.textBlocksProps = newTextBlocksProps; + transcriptState.lastRenderTime = currentTime; + return newTextBlocksProps.map((props, idx) => ( + + )); +} diff --git a/streaming-react-app/src/react-xr/ThreeMeshUIText.tsx b/streaming-react-app/src/react-xr/ThreeMeshUIText.tsx new file mode 100644 index 0000000000000000000000000000000000000000..bcaeb27b99b40f201973ed214f16d6656c26f0ad --- /dev/null +++ b/streaming-react-app/src/react-xr/ThreeMeshUIText.tsx @@ -0,0 +1,22 @@ +import {extend} from '@react-three/fiber'; +import {forwardRef} from 'react'; +import ThreeMeshUI, {TextOptions} from 'three-mesh-ui'; + +extend(ThreeMeshUI); + +/** + * Hacky but component that wraps since this has typescript issues because it collides with + * the native SVG element. Simple enough so abstracting it away in this file + * so it could be used in other places with low risk. e.g: + * + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type ThreeMeshUITextType = any; + +const ThreeMeshUIText = forwardRef( + function ThreeMeshUIText(props, ref) { + return ; + }, +); + +export default ThreeMeshUIText; diff --git a/streaming-react-app/src/react-xr/XRConfig.tsx b/streaming-react-app/src/react-xr/XRConfig.tsx new file mode 100644 index 0000000000000000000000000000000000000000..63a4ebee42a9471b1683c0626c3357cff3f82307 --- /dev/null +++ b/streaming-react-app/src/react-xr/XRConfig.tsx @@ -0,0 +1,389 @@ +import {useCallback, useEffect, useRef, useState} from 'react'; +import { + Canvas, + createPortal, + extend, + useFrame, + useThree, +} from '@react-three/fiber'; +import ThreeMeshUI from 'three-mesh-ui'; + +import {ARButton, XR, Hands, XREvent} from '@react-three/xr'; + +import {TextGeometry} from 'three/examples/jsm/geometries/TextGeometry.js'; +import {TranslationSentences} from '../types/StreamingTypes'; +import Button from './Button'; +import {RoomState} from '../types/RoomState'; +import ThreeMeshUIText, {ThreeMeshUITextType} from './ThreeMeshUIText'; +import {BLACK, WHITE} from './Colors'; + +/** + * Using `?url` at the end of this import tells vite this is a static asset, and + * provides us a URL to the hashed version of the file when the project is built. + * See: https://vitejs.dev/guide/assets.html#explicit-url-imports + */ +import robotoFontFamilyJson from '../assets/RobotoMono-Regular-msdf.json?url'; +import robotoFontTexture from '../assets/RobotoMono-Regular.png'; +import {getURLParams} from '../URLParams'; +import TextBlocks from './TextBlocks'; +import {BufferedSpeechPlayer} from '../createBufferedSpeechPlayer'; +import {CURSOR_BLINK_INTERVAL_MS} from '../cursorBlinkInterval'; +import supportedCharSet from './supportedCharSet'; + +// Adds on react JSX for add-on libraries to react-three-fiber +extend(ThreeMeshUI); +extend({TextGeometry}); + +// This component wraps any children so it is positioned relative to the camera, rather than from the origin +function CameraLinkedObject({children}) { + const camera = useThree((state) => state.camera); + return createPortal(<>{children}, camera); +} + +function ThreeMeshUIComponents({ + translationSentences, + skipARIntro, + roomState, + animateTextDisplay, +}: XRConfigProps & {skipARIntro: boolean}) { + // The "loop" for re-rendering required for threemeshUI + useFrame(() => { + ThreeMeshUI.update(); + }); + const [started, setStarted] = useState(skipARIntro); + return ( + <> + + {getURLParams().ARTranscriptionType === 'single_block' ? ( + + ) : ( + + )} + {skipARIntro ? null : ( + + )} + + + ); +} + +// Original UI that just uses a single block to render 6 lines in a panel +function TranscriptPanelSingleBlock({ + animateTextDisplay, + started, + translationSentences, + roomState, +}: { + animateTextDisplay: boolean; + started: boolean; + translationSentences: TranslationSentences; + roomState: RoomState | null; +}) { + const textRef = useRef(); + const [didReceiveTranslationSentences, setDidReceiveTranslationSentences] = + useState(false); + + const hasActiveTranscoders = (roomState?.activeTranscoders ?? 0) > 0; + + const [cursorBlinkOn, setCursorBlinkOn] = useState(false); + + // Normally we don't setState in render, but here we need to for computed state, and this if statement assures it won't loop infinitely + if (!didReceiveTranslationSentences && translationSentences.length > 0) { + setDidReceiveTranslationSentences(true); + } + + const width = 1; + const height = 0.3; + const fontSize = 0.03; + + useEffect(() => { + if (animateTextDisplay && hasActiveTranscoders) { + const interval = setInterval(() => { + setCursorBlinkOn((prev) => !prev); + }, CURSOR_BLINK_INTERVAL_MS); + + return () => clearInterval(interval); + } else { + setCursorBlinkOn(false); + } + }, [animateTextDisplay, hasActiveTranscoders]); + + useEffect(() => { + if (textRef.current != null) { + const initialPrompt = + 'Welcome to the presentation. We are excited to share with you the work we have been doing... Our model can now translate languages in less than 2 second latency.'; + // These are rough ratios based on spot checking + const maxLines = 6; + const charsPerLine = 55; + + const transcriptSentences: string[] = didReceiveTranslationSentences + ? translationSentences + : [initialPrompt]; + + // The transcript is an array of sentences. For each sentence we break this down into an array of words per line. + // This is needed so we can "scroll" through without changing the order of words in the transcript + const linesToDisplay = transcriptSentences.flatMap((sentence, idx) => { + const blinkingCursor = + cursorBlinkOn && idx === transcriptSentences.length - 1 ? '|' : ' '; + const words = sentence.concat(blinkingCursor).split(/\s+/); + // Here we break each sentence up with newlines so all words per line fit within the panel + return words.reduce( + (wordChunks, currentWord) => { + const filteredWord = [...currentWord] + .filter((c) => { + if (supportedCharSet().has(c)) { + return true; + } + console.error( + `Unsupported char ${c} - make sure this is supported in the font family msdf file`, + ); + return false; + }) + .join(''); + const lastLineSoFar = wordChunks[wordChunks.length - 1]; + const charCount = lastLineSoFar.length + filteredWord.length + 1; + if (charCount <= charsPerLine) { + wordChunks[wordChunks.length - 1] = + lastLineSoFar + ' ' + filteredWord; + } else { + wordChunks.push(filteredWord); + } + return wordChunks; + }, + [''], + ); + }); + + // Only keep the last maxLines so new text keeps scrolling up from the bottom + linesToDisplay.splice(0, linesToDisplay.length - maxLines); + textRef.current.set({content: linesToDisplay.join('\n')}); + } + }, [ + translationSentences, + textRef, + didReceiveTranslationSentences, + cursorBlinkOn, + ]); + + const opacity = started ? 1 : 0; + return ( + + + + + + ); +} + +// Splits up the lines into separate blocks to treat each one separately. +// This allows changing of opacity, animating per line, changing height / width per line etc +function TranscriptPanelBlocks({ + translationSentences, +}: { + translationSentences: TranslationSentences; +}) { + return ( + + ); +} + +function IntroPanel({started, setStarted}) { + const width = 0.5; + const height = 0.4; + const padding = 0.03; + + // Kind of hacky but making the panel disappear by moving it completely off the camera view. + // If we try to remove elements we end up throwing and stopping the experience + // opacity=0 also runs into weird bugs where not everything is invisible + const xCoordinate = started ? 1000000 : 0; + + const commonArgs = { + backgroundColor: WHITE, + width, + height, + padding, + backgroundOpacity: 1, + textAlign: 'center', + fontFamily: robotoFontFamilyJson, + fontTexture: robotoFontTexture, + }; + return ( + <> + + + + + + + + + {isDialogOpen && ( + setIsDialogOpen(false)} open={true}> + + FAIR Seamless Streaming Demo + + setIsDialogOpen(false)} + sx={{ + position: 'absolute', + right: 8, + top: 8, + color: (theme) => theme.palette.grey[500], + }}> + + + + + )} */} + + ); +} diff --git a/streaming-react-app/src/react-xr/XRRendering.ts b/streaming-react-app/src/react-xr/XRRendering.ts new file mode 100644 index 0000000000000000000000000000000000000000..7af665a44cc97cd7dbd75cfc5a011565f1f4f251 --- /dev/null +++ b/streaming-react-app/src/react-xr/XRRendering.ts @@ -0,0 +1,402 @@ +import * as THREE from 'three'; +import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js'; + +import ThreeMeshUI, {Block, Text} from 'three-mesh-ui'; + +import FontJSON from '../assets/RobotoMono-Regular-msdf.json?url'; +import FontImage from '../assets/RobotoMono-Regular.png'; +import {TranslationSentences} from '../types/StreamingTypes'; +import supportedCharSet from './supportedCharSet'; + +// Augment three-mesh-ui types which aren't implemented +declare module 'three-mesh-ui' { + interface Block { + add(any: any); + set(props: BlockOptions); + position: { + x: number; + y: number; + z: number; + set: (x: number, y: number, z: number) => void; + }; + } + interface Text { + set(props: {content: string}); + } +} + +// Various configuration parameters +const INITIAL_PROMPT = 'Listening...\n'; +const NUM_LINES = 3; +const CHARS_PER_LINE = 37; +const CHARS_PER_SECOND = 15; + +const MAX_WIDTH = 0.89; +const CHAR_WIDTH = 0.0233; +const Y_COORD_START = -0.38; +const Z_COORD = -1.3; +const LINE_HEIGHT = 0.062; +const BLOCK_SPACING = 0.02; +const FONT_SIZE = 0.038; + +// Speed of scrolling of text lines +const SCROLL_Y_DELTA = 0.01; + +// Overlay an extra block for padding due to inflexibilities of native padding +const OFFSET = 0.01; +const OFFSET_WIDTH = OFFSET * 3; + +// The tick interval +const CURSOR_BLINK_INTERVAL_MS = 500; + +type TranscriptState = { + translationText: string; + textBlocksProps: TextBlockProps[]; + lastTranslationStringIndex: number; + lastTranslationLineStartIndex: number; + transcriptLines: string[]; + lastUpdateTime: number; +}; + +type TextBlockProps = { + content: string; + // The end position when animating + targetY: number; + // Current scroll position that caps at targetY + currentY: number; + textOpacity: number; + backgroundOpacity: number; + index: number; + isBottomLine: boolean; +}; + +function initialTextBlockProps(count: number): TextBlockProps[] { + return Array.from({length: count}).map(() => { + // Push in non display blocks because mesh UI crashes if elements are add / removed from screen. + + return { + // key: textBlocksProps.length, + targetY: Y_COORD_START, + currentY: Y_COORD_START, + index: 0, + textOpacity: 0, + backgroundOpacity: 0, + width: MAX_WIDTH, + height: LINE_HEIGHT, + content: '', + isBottomLine: true, + }; + }); +} + +function initialState(): TranscriptState { + return { + translationText: '', + textBlocksProps: initialTextBlockProps(NUM_LINES), + lastTranslationStringIndex: 0, + lastTranslationLineStartIndex: 0, + transcriptLines: [], + lastUpdateTime: new Date().getTime(), + }; +} + +let transcriptState: TranscriptState = initialState(); + +let scene: THREE.Scene | null; +let camera: THREE.PerspectiveCamera | null; +let renderer: THREE.WebGLRenderer | null; +let controls: THREE.OrbitControls | null; + +let cursorBlinkOn: boolean = false; + +setInterval(() => { + cursorBlinkOn = !cursorBlinkOn; +}, CURSOR_BLINK_INTERVAL_MS); + +type TextBlock = { + textBlockOuterContainer: Block; + textBlockInnerContainer: Block; + text: Text; +}; +const textBlocks: TextBlock[] = []; + +export function getRenderer(): THREE.WebGLRenderer | null { + return renderer; +} + +export function init( + width: number, + height: number, + parentElement: HTMLDivElement | null, +): THREE.WebGLRenderer { + scene = new THREE.Scene(); + scene.background = new THREE.Color(0x505050); + + camera = new THREE.PerspectiveCamera(60, width / height, 0.1, 1000); + camera.position.z = 1; + + renderer = new THREE.WebGLRenderer({ + antialias: true, + }); + renderer.setPixelRatio(window.devicePixelRatio); + renderer.setSize(width, height); + renderer.xr.enabled = true; + + renderer.xr.setReferenceSpaceType('local'); + + parentElement?.appendChild(renderer.domElement); + + controls = new OrbitControls(camera, renderer.domElement); + controls.update(); + + scene.add(camera); + + textBlocks.push( + ...initialTextBlockProps(NUM_LINES).map((props) => makeTextBlock(props)), + ); + + renderer.setAnimationLoop(loop); + return renderer; +} + +export function updatetranslationText( + translationSentences: TranslationSentences, +): void { + const newText = INITIAL_PROMPT + translationSentences.join('\n'); + if (transcriptState.translationText === newText) { + return; + } + transcriptState.translationText = newText; +} + +export function resetState(): void { + transcriptState = initialState(); +} + +function makeTextBlock({ + content, + backgroundOpacity, +}: TextBlockProps): TextBlock { + const width = MAX_WIDTH; + const height = LINE_HEIGHT; + + const fontProps = { + fontSize: FONT_SIZE, + textAlign: 'left', + // TODO: support more language charsets + // This renders using MSDF format supported in WebGL. Renderable characters are defined in the "charset" json + // Currently supports most default keyboard inputs but this would exclude many non latin charset based languages. + // You can use https://msdf-bmfont.donmccurdy.com/ for easily generating these files + fontFamily: FontJSON, + fontTexture: FontImage, + }; + + const textBlockOuterContainer = new Block({ + backgroundOpacity, + width: width + OFFSET_WIDTH, + height: height, + borderRadius: 0, + ...fontProps, + }); + + const text = new Text({content}); + const textBlockInnerContainer = new Block({ + padding: 0, + backgroundOpacity: 0, + width, + height, + }); + + // Adding it to the camera makes the UI follow it. + camera.add(textBlockOuterContainer); + textBlockOuterContainer.add(textBlockInnerContainer); + textBlockInnerContainer.add(text); + + return { + textBlockOuterContainer, + textBlockInnerContainer, + text, + }; +} + +// Updates the position and text of a text block from its props +function updateTextBlock( + id: number, + {content, targetY, currentY, backgroundOpacity, isBottomLine}: TextBlockProps, +): void { + const {textBlockOuterContainer, textBlockInnerContainer, text} = + textBlocks[id]; + + const {lastTranslationStringIndex, translationText} = transcriptState; + + // Add blinking cursor if we don't have any new input to render + const numChars = content.length; + + if ( + isBottomLine && + cursorBlinkOn && + lastTranslationStringIndex >= translationText.length + ) { + content = content + '|'; + } + + // Accounting for potential cursor for block width (the +1) + const width = + (numChars + (isBottomLine ? 1.1 : 0) + (numChars < 10 ? 1 : 0)) * + CHAR_WIDTH; + const height = LINE_HEIGHT; + + // Width starts from 0 and goes 1/2 in each direction so offset x + const xPosition = width / 2 - MAX_WIDTH / 2 + OFFSET_WIDTH; + textBlockOuterContainer?.set({ + backgroundOpacity, + width: width + 2 * OFFSET_WIDTH, + height: height + OFFSET / 3, + borderRadius: 0, + }); + + // Scroll up line toward target + const y = isBottomLine + ? targetY + : Math.min(currentY + SCROLL_Y_DELTA, targetY); + transcriptState.textBlocksProps[id].currentY = y; + + textBlockOuterContainer.position.set(-OFFSET_WIDTH + xPosition, y, Z_COORD); + textBlockInnerContainer.set({ + padding: 0, + backgroundOpacity: 0, + width, + height, + }); + text.set({content}); +} + +// We split the text so it fits line by line into the UI +function chunkTranslationTextIntoLines( + translationText: string, + nextTranslationStringIndex: number, +): string[] { + // Ideally we continue where we left off but this is complicated when we have mid-words. Recalculating for now + const newSentences = translationText + .substring(0, nextTranslationStringIndex) + .split('\n'); + const transcriptLines = ['']; + newSentences.forEach((newSentence, sentenceIdx) => { + const words = newSentence.split(/\s+/); + words.forEach((word) => { + const filteredWord = [...word] + .filter((c) => { + if (supportedCharSet().has(c)) { + return true; + } + console.error( + `Unsupported char ${c} - make sure this is supported in the font family msdf file`, + ); + return false; + }) + .join('') + // Filter out unknown symbol + .replace('', ''); + + const lastLineSoFar = transcriptLines[0]; + const charCount = lastLineSoFar.length + filteredWord.length + 1; + + if (charCount <= CHARS_PER_LINE) { + transcriptLines[0] = lastLineSoFar + ' ' + filteredWord; + } else { + transcriptLines.unshift(filteredWord); + } + }); + + if (sentenceIdx < newSentences.length - 1) { + transcriptLines.unshift('\n'); + transcriptLines.unshift(''); + } + }); + return transcriptLines; +} + +// The main loop, +function updateTextBlocksProps(): void { + const {translationText, lastTranslationStringIndex, lastUpdateTime} = + transcriptState; + + const currentTime = new Date().getTime(); + const charsToRender = Math.round( + ((currentTime - lastUpdateTime) * CHARS_PER_SECOND) / 1000, + ); + + if (charsToRender < 1) { + // Wait some more until we render more characters + return; + } + + const nextTranslationStringIndex = Math.min( + lastTranslationStringIndex + charsToRender, + translationText.length, + ); + if (nextTranslationStringIndex === lastTranslationStringIndex) { + // No new characters to render + transcriptState.lastUpdateTime = currentTime; + return; + } + + // Ideally we continue where we left off but this is complicated when we have mid-words. Recalculating for now + const transcriptLines = chunkTranslationTextIntoLines( + translationText, + nextTranslationStringIndex, + ); + transcriptState.transcriptLines = transcriptLines; + transcriptState.lastTranslationStringIndex = nextTranslationStringIndex; + + // Compute the new props for each text block + const newTextBlocksProps: TextBlockProps[] = []; + // We start with the most recent line and increment the y coordinate for older lines. + // If it is a new sentence we increment the y coordinate a little more to leave a visible space + let y = Y_COORD_START; + transcriptLines.forEach((line, i) => { + if (newTextBlocksProps.length == NUM_LINES) { + return; + } + + if (line === '\n') { + y += BLOCK_SPACING; + return; + } + + const isBottomLine = newTextBlocksProps.length === 0; + + const textOpacity = 1 - 0.1 * newTextBlocksProps.length; + + const previousProps = transcriptState.textBlocksProps.find( + (props) => props.index === i, + ); + const props = { + targetY: y + LINE_HEIGHT / 2, + currentY: isBottomLine ? y : previousProps?.currentY || y, + index: i, + textOpacity, + backgroundOpacity: 1, + content: line, + isBottomLine, + }; + newTextBlocksProps.push(props); + + y += LINE_HEIGHT; + }); + + transcriptState.textBlocksProps = newTextBlocksProps; + transcriptState.lastUpdateTime = currentTime; +} + +// The main render loop, everything gets rendered here. +function loop() { + updateTextBlocksProps(); + + transcriptState.textBlocksProps.map((props, i) => updateTextBlock(i, props)); + + ThreeMeshUI.update(); + + controls.update(); + renderer.render(scene, camera); +} diff --git a/streaming-react-app/src/react-xr/supportedCharSet.ts b/streaming-react-app/src/react-xr/supportedCharSet.ts new file mode 100644 index 0000000000000000000000000000000000000000..8131ac5c44a1cc44a7b42d439da307afe63cef5b --- /dev/null +++ b/streaming-react-app/src/react-xr/supportedCharSet.ts @@ -0,0 +1,20 @@ +import robotoFontFamilyJson from '../assets/RobotoMono-Regular-msdf.json?url'; + +async function fetchSupportedCharSet(): Promise> { + try { + const response = await fetch(robotoFontFamilyJson); + const fontFamily = await response.json(); + + return new Set(fontFamily.info.charset); + } catch (e) { + console.error('Failed to fetch supported XR charset', e); + return new Set(); + } +} + +let charSet = new Set(); +fetchSupportedCharSet().then((result) => (charSet = result)); + +export default function supportedCharSet(): Set { + return charSet; +} diff --git a/streaming-react-app/src/setURLParam.ts b/streaming-react-app/src/setURLParam.ts new file mode 100644 index 0000000000000000000000000000000000000000..e58c8af1e52e5d2a5d3e21948e5d294eaf4c27c5 --- /dev/null +++ b/streaming-react-app/src/setURLParam.ts @@ -0,0 +1,40 @@ +export default function setURLParam( + paramName: string, + value: T, + // If there's no defaultValue specified then we always set the URL param explicitly + defaultValue?: T, +): void { + const urlParams = new URLSearchParams(window.location.search); + if (defaultValue != null && value === defaultValue) { + urlParams.delete(paramName); + } else { + let stringValue: string; + + switch (typeof value) { + case 'string': + stringValue = value; + break; + case 'boolean': + stringValue = value ? '1' : '0'; + break; + default: + throw new Error(`Unsupported URL param type: ${typeof value}`); + } + + if (urlParams.has(paramName)) { + urlParams.set(paramName, stringValue); + } else { + urlParams.append(paramName, stringValue); + } + } + + const paramStringWithoutQuestionMark = urlParams.toString(); + + window.history.replaceState( + null, + '', + `${window.location.pathname}${ + paramStringWithoutQuestionMark.length > 0 ? '?' : '' + }${paramStringWithoutQuestionMark}`, + ); +} diff --git a/streaming-react-app/src/sliceTranslationSentencesUtils.ts b/streaming-react-app/src/sliceTranslationSentencesUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..daee955ce91d3ac73061b61364ab0abfbd6b2f79 --- /dev/null +++ b/streaming-react-app/src/sliceTranslationSentencesUtils.ts @@ -0,0 +1,30 @@ +import {TranslationSentences} from './types/StreamingTypes'; + +export function getTotalSentencesLength( + translatedSentences: TranslationSentences, +) { + return translatedSentences.reduce((acc, curr) => acc + curr.length, 0); +} + +/** + * @returns A new array of strings where the total length of the strings === targetIndex, + * aka it's as if we joined all the strings together, called joined.slice(0, targetIndex), and then + * split the string back into an array of strings. + */ +export function sliceTranslationSentencesUpToIndex( + translatedSentences: TranslationSentences, + targetIndex: number, +): TranslationSentences { + return translatedSentences.reduce((acc, sentence) => { + const accTotalLength = getTotalSentencesLength(acc); + if (accTotalLength === targetIndex) { + return acc; + } + // If adding the current sentence does not exceed the targetIndex, then add the whole sentence + if (accTotalLength + sentence.length <= targetIndex) { + return [...acc, sentence]; + } + // If adding the current sentence DOES exceed the targetIndex, then slice the sentence and add it + return [...acc, sentence.slice(0, targetIndex - accTotalLength)]; + }, []); +} diff --git a/streaming-react-app/src/theme.ts b/streaming-react-app/src/theme.ts new file mode 100644 index 0000000000000000000000000000000000000000..15874ccd69f4b539bac90d49b34b6162c4e6a923 --- /dev/null +++ b/streaming-react-app/src/theme.ts @@ -0,0 +1,40 @@ +import {createTheme} from '@mui/material/styles'; + +const themeObject = { + palette: { + background: {default: '#999999' },//'#383838'}, + primary: { + main: '#465A69', + }, + info: { + main: '#9f0000'// '#0064E0', + }, + text: {primary: '#1C2A33'}, + }, + typography: { + fontFamily: [ + 'Optimistic Text', + 'Roboto', + '"Helvetica Neue"', + 'Arial', + 'sans-serif', + ].join(','), + h1: {fontSize: '1rem', fontWeight: '500'}, + }, +}; + +const theme = createTheme(themeObject); + +/** + * Set up a responsive font size at the 600px breakpoint + */ +// default is 1rem (16px) +theme.typography.body1[theme.breakpoints.down('sm')] = {fontSize: '0.875rem'}; +// default is 1rem (16px) +theme.typography.h1[theme.breakpoints.down('sm')] = {fontSize: '0.875rem'}; +// default is 0.875rem (14px) +theme.typography.button[theme.breakpoints.down('sm')] = {fontSize: '0.75rem'}; +// default is 0.875rem (14px) +theme.typography.body2[theme.breakpoints.down('sm')] = {fontSize: '0.75rem'}; + +export default theme; diff --git a/streaming-react-app/src/types/RoomState.ts b/streaming-react-app/src/types/RoomState.ts new file mode 100644 index 0000000000000000000000000000000000000000..ae074547413481f58c5004108acd43c0b0c70d8d --- /dev/null +++ b/streaming-react-app/src/types/RoomState.ts @@ -0,0 +1,16 @@ +export type MemberID = string; + +export type Member = { + client_id: MemberID; + session_id: string; + name: string; + connection_status: 'connected' | 'disconnected'; +}; + +export type RoomState = { + activeTranscoders: number; + room_id: string; + members: Array; + listeners: Array; + speakers: Array; +}; diff --git a/streaming-react-app/src/types/StreamingTypes.ts b/streaming-react-app/src/types/StreamingTypes.ts new file mode 100644 index 0000000000000000000000000000000000000000..800af114d13e2ce1a861c71ebb05e78597921799 --- /dev/null +++ b/streaming-react-app/src/types/StreamingTypes.ts @@ -0,0 +1,131 @@ +interface ServerTranslationDataBase { + eos: boolean; + event: string; + latency?: number; +} + +export interface ServerTextData extends ServerTranslationDataBase { + event: 'translation_text'; + payload: string; +} + +export interface ServerSpeechData extends ServerTranslationDataBase { + event: 'translation_speech'; + payload: Array; + sample_rate: number; +} + +export const OUTPUT_MODALITIES_BASE_VALUES = ['s2t', 's2s'] as const; +export type OutputModalitiesBase = + (typeof OUTPUT_MODALITIES_BASE_VALUES)[number]; + +export const DYNAMIC_PARAMS_VALUES = ['expressive'] as const; +export type DynamicParams = (typeof DYNAMIC_PARAMS_VALUES)[number]; + +export type AgentCapabilities = { + name: string; + description: string; + modalities: Array; + targetLangs: Array; + dynamicParams: Array; +}; + +export const SUPPORTED_OUTPUT_MODE_VALUES = ['s2s&t', 's2t', 's2s'] as const; + +export type SupportedOutputMode = (typeof SUPPORTED_OUTPUT_MODE_VALUES)[number]; + +export const SUPPORTED_OUTPUT_MODES: Array<{ + value: (typeof SUPPORTED_OUTPUT_MODE_VALUES)[number]; + label: string; +}> = [ + { value: 's2s&t', label: 'Text & Speech' }, + { value: 's2t', label: 'Text' }, + { value: 's2s', label: 'Speech' }, + ]; + +export const SUPPORTED_INPUT_SOURCE_VALUES = [ + 'userMedia', + 'displayMedia', +] as const; + +export type SupportedInputSource = + (typeof SUPPORTED_INPUT_SOURCE_VALUES)[number]; + +export const SUPPORTED_INPUT_SOURCES: Array<{ + value: SupportedInputSource; + label: string; +}> = [ + {value: 'userMedia', label: 'Microphone'}, + {value: 'displayMedia', label: 'Browser Tab (Chrome only)'}, +]; + +export type StartStreamEventConfig = { + event: 'config'; + rate: number; + model_name: string; + debug: boolean; + async_processing: boolean; + model_type: SupportedOutputMode; + buffer_limit: number; +}; + +export interface BrowserAudioStreamConfig { + echoCancellation: boolean; + noiseSuppression: boolean; + echoCancellation: boolean; +} + +export interface ServerStateItem { + activeConnections: number; + activeTranscoders: number; +} + +export type ServerLockObject = { + name: string | null; + clientID: string | null; + isActive: boolean; +}; + +export type ServerState = ServerStateItem & { + agentsCapabilities: Array; + statusByRoom: { + [key: string]: { activeConnections: number; activeTranscoders: number }; + }; + totalActiveConnections: number; + totalActiveTranscoders: number; + serverLock: ServerLockObject | null; +}; + +export type ServerExceptionData = { + message: string; + timeEpochMs: number; + // NOTE: This is added on the client + timeStringClient?: string; + room?: string; + member?: string; + clientID?: string; +}; + +export type StreamingStatus = 'stopped' | 'running' | 'starting'; + +export type TranslationSentences = Array; + +export type DynamicConfig = { + // targetLanguage: a 3-letter string representing the desired output language. + targetLanguage: string; + expressive: boolean | null; +}; + +export type PartialDynamicConfig = Partial; + +export type BaseResponse = { + status: 'ok' | 'error'; + message: string; +}; + +export type Roles = 'speaker' | 'listener'; + +export type JoinRoomConfig = { + roles: Array; + lockServerName: string | null; +}; diff --git a/streaming-react-app/src/types/URLParamsTypes.ts b/streaming-react-app/src/types/URLParamsTypes.ts new file mode 100644 index 0000000000000000000000000000000000000000..da5d23f81166b2881bff81ef75e1fc2bb7d3eced --- /dev/null +++ b/streaming-react-app/src/types/URLParamsTypes.ts @@ -0,0 +1,16 @@ +export type URLParamsObject = { + animateTextDisplay: boolean; + autoJoin: boolean; + debug: boolean; + enableServerLock: boolean; + roomID: string | null; + serverURL: string | null; + skipARIntro: boolean; + ARTranscriptionType: + | 'single_block' + | 'lines' + | 'lines_with_background' + | string; +}; + +export type URLParamNames = keyof URLParamsObject; diff --git a/streaming-react-app/src/types/exhaustivenessCheck.ts b/streaming-react-app/src/types/exhaustivenessCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..a794e637329a1c5e44a3380abd157b84cfdfd9aa --- /dev/null +++ b/streaming-react-app/src/types/exhaustivenessCheck.ts @@ -0,0 +1,6 @@ +// Useful for ensuring switch statements are exhaustive +export default function exhaustivenessCheck(p: never): never { + throw new Error( + `This should never happen. Value received: ${JSON.stringify(p)}`, + ); +} diff --git a/streaming-react-app/src/useSocket.ts b/streaming-react-app/src/useSocket.ts new file mode 100644 index 0000000000000000000000000000000000000000..f8a9794047120c17f4bcc1e1962c51cc94512d5c --- /dev/null +++ b/streaming-react-app/src/useSocket.ts @@ -0,0 +1,18 @@ +import {createContext, useContext} from 'react'; +import {Socket} from 'socket.io-client'; + +type SocketObject = { + socket: Socket | null; + clientID: string | null; + connected: boolean; +}; + +export const SocketContext = createContext({ + socket: null, + clientID: null, + connected: false, +}); + +export function useSocket(): SocketObject { + return useContext(SocketContext); +} diff --git a/streaming-react-app/src/useStable.ts b/streaming-react-app/src/useStable.ts new file mode 100644 index 0000000000000000000000000000000000000000..789f9168bed2687f244f5dc3ea1ed3bce6517c3e --- /dev/null +++ b/streaming-react-app/src/useStable.ts @@ -0,0 +1,15 @@ +import {useRef} from 'react'; + +type UninitializedMarker = Readonly> | symbol; +const UNINITIALIZED: UninitializedMarker = + typeof Symbol === 'function' && typeof Symbol() === 'symbol' + ? Symbol() + : Object.freeze({}); + +export default function useStable(initialValueCallback: () => T): T { + const ref = useRef(UNINITIALIZED); + if (ref.current === UNINITIALIZED) { + ref.current = initialValueCallback(); + } + return ref.current as T; +} diff --git a/streaming-react-app/src/vite-env.d.ts b/streaming-react-app/src/vite-env.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..11f02fe2a0061d6e6e1f271b21da95423b448b32 --- /dev/null +++ b/streaming-react-app/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/streaming-react-app/tsconfig.json b/streaming-react-app/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..ec35baecbe10e6b5cbf66bd1f1695f30c9285fc1 --- /dev/null +++ b/streaming-react-app/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": false + }, + "include": ["src"], + "references": [{"path": "./tsconfig.node.json"}] +} diff --git a/streaming-react-app/tsconfig.node.json b/streaming-react-app/tsconfig.node.json new file mode 100644 index 0000000000000000000000000000000000000000..b940375d3edcb36f8bf5cd96de5286c457f7cd17 --- /dev/null +++ b/streaming-react-app/tsconfig.node.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "types": ["node"] + }, + "include": ["vite.config.ts"] +} diff --git a/streaming-react-app/vite.config.ts b/streaming-react-app/vite.config.ts new file mode 100644 index 0000000000000000000000000000000000000000..e4ac725b69e8dff6561f7daac82d0d0a4ecfe4df --- /dev/null +++ b/streaming-react-app/vite.config.ts @@ -0,0 +1,24 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +// https://vitejs.dev/config/ +export default defineConfig(({ command }) => { + let define = {}; + if (command === 'serve') { + define = { + global: {}, + }; + } + return { + plugins: [react()], + define: define, + server: { + proxy: { + '/ws': { + target: 'ws://localhost:7860', + ws: true + } + }, + }, + } +}); diff --git a/streaming-react-app/yarn.lock b/streaming-react-app/yarn.lock new file mode 100644 index 0000000000000000000000000000000000000000..25441fad0b3457ae4dd9d899e589f48584c510c7 --- /dev/null +++ b/streaming-react-app/yarn.lock @@ -0,0 +1,2815 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@aws-crypto/sha256-js@1.2.2": + version "1.2.2" + resolved "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-1.2.2.tgz" + integrity sha512-Nr1QJIbW/afYYGzYvrF70LtaHrIRtd4TNAglX8BvlfxJLZ45SAmueIKYl5tWoNBPzp65ymXGFK0Bb1vZUpuc9g== + dependencies: + "@aws-crypto/util" "^1.2.2" + "@aws-sdk/types" "^3.1.0" + tslib "^1.11.1" + +"@aws-crypto/util@^1.2.2": + version "1.2.2" + resolved "https://registry.npmjs.org/@aws-crypto/util/-/util-1.2.2.tgz" + integrity sha512-H8PjG5WJ4wz0UXAFXeJjWCW1vkvIJ3qUUD+rGRwJ2/hj+xT58Qle2MTql/2MGzkU+1JLAFuR6aJpLAjHwhmwwg== + dependencies: + "@aws-sdk/types" "^3.1.0" + "@aws-sdk/util-utf8-browser" "^3.0.0" + tslib "^1.11.1" + +"@aws-sdk/types@^3.1.0": + version "3.425.0" + resolved "https://registry.npmjs.org/@aws-sdk/types/-/types-3.425.0.tgz" + integrity sha512-6lqbmorwerN4v+J5dqbHPAsjynI0mkEF+blf+69QTaKKGaxBBVaXgqoqul9RXYcK5MMrrYRbQIMd0zYOoy90kA== + dependencies: + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@aws-sdk/util-utf8-browser@^3.0.0": + version "3.259.0" + resolved "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz" + integrity sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw== + dependencies: + tslib "^2.3.1" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.22.10", "@babel/code-frame@^7.22.5": + version "7.22.10" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz" + integrity sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA== + dependencies: + "@babel/highlight" "^7.22.10" + chalk "^2.4.2" + +"@babel/compat-data@^7.22.9": + version "7.22.9" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz" + integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== + +"@babel/core@^7.22.9": + version "7.22.10" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.22.10.tgz" + integrity sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.22.10" + "@babel/generator" "^7.22.10" + "@babel/helper-compilation-targets" "^7.22.10" + "@babel/helper-module-transforms" "^7.22.9" + "@babel/helpers" "^7.22.10" + "@babel/parser" "^7.22.10" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.10" + "@babel/types" "^7.22.10" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.2" + semver "^6.3.1" + +"@babel/generator@^7.22.10": + version "7.22.10" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz" + integrity sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A== + dependencies: + "@babel/types" "^7.22.10" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/helper-compilation-targets@^7.22.10": + version "7.22.10" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz" + integrity sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-validator-option" "^7.22.5" + browserslist "^4.21.9" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-environment-visitor@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz" + integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== + +"@babel/helper-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz" + integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ== + dependencies: + "@babel/template" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz" + integrity sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-transforms@^7.22.9": + version "7.22.9" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz" + integrity sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.5" + +"@babel/helper-plugin-utils@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + +"@babel/helper-validator-identifier@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz" + integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== + +"@babel/helper-validator-option@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz" + integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== + +"@babel/helpers@^7.22.10": + version "7.22.10" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.10.tgz" + integrity sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw== + dependencies: + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.10" + "@babel/types" "^7.22.10" + +"@babel/highlight@^7.22.10": + version "7.22.10" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz" + integrity sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ== + dependencies: + "@babel/helper-validator-identifier" "^7.22.5" + chalk "^2.4.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.22.10", "@babel/parser@^7.22.5": + version "7.22.10" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.22.10.tgz" + integrity sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ== + +"@babel/plugin-transform-react-jsx-self@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.22.5.tgz" + integrity sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-react-jsx-source@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.22.5.tgz" + integrity sha512-yIiRO6yobeEIaI0RTbIr8iAK9FcBHLtZq0S89ZPjDLQXBA4xvghaKqI0etp/tF3htTM0sazJKKLz9oEiGRtu7w== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.21.0", "@babel/runtime@^7.22.6", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": + version "7.22.10" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.10.tgz" + integrity sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/template@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz" + integrity sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/traverse@^7.22.10": + version "7.22.10" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.10.tgz" + integrity sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig== + dependencies: + "@babel/code-frame" "^7.22.10" + "@babel/generator" "^7.22.10" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.22.10" + "@babel/types" "^7.22.10" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.22.10", "@babel/types@^7.22.5": + version "7.22.10" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz" + integrity sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" + to-fast-properties "^2.0.0" + +"@emotion/babel-plugin@^11.11.0": + version "11.11.0" + resolved "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz" + integrity sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/runtime" "^7.18.3" + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/serialize" "^1.1.2" + babel-plugin-macros "^3.1.0" + convert-source-map "^1.5.0" + escape-string-regexp "^4.0.0" + find-root "^1.1.0" + source-map "^0.5.7" + stylis "4.2.0" + +"@emotion/cache@^11.11.0": + version "11.11.0" + resolved "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz" + integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ== + dependencies: + "@emotion/memoize" "^0.8.1" + "@emotion/sheet" "^1.2.2" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + stylis "4.2.0" + +"@emotion/hash@^0.9.1": + version "0.9.1" + resolved "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz" + integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ== + +"@emotion/is-prop-valid@^1.2.1": + version "1.2.1" + resolved "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz" + integrity sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw== + dependencies: + "@emotion/memoize" "^0.8.1" + +"@emotion/memoize@^0.8.1": + version "0.8.1" + resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz" + integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== + +"@emotion/react@11.11.1": + version "11.11.1" + resolved "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz" + integrity sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA== + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/cache" "^11.11.0" + "@emotion/serialize" "^1.1.2" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + hoist-non-react-statics "^3.3.1" + +"@emotion/serialize@^1.1.2": + version "1.1.2" + resolved "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz" + integrity sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA== + dependencies: + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/unitless" "^0.8.1" + "@emotion/utils" "^1.2.1" + csstype "^3.0.2" + +"@emotion/sheet@^1.2.2": + version "1.2.2" + resolved "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz" + integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== + +"@emotion/styled@11.11.0": + version "11.11.0" + resolved "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz" + integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng== + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/is-prop-valid" "^1.2.1" + "@emotion/serialize" "^1.1.2" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" + +"@emotion/unitless@^0.8.1": + version "0.8.1" + resolved "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz" + integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ== + +"@emotion/use-insertion-effect-with-fallbacks@^1.0.1": + version "1.0.1" + resolved "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz" + integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw== + +"@emotion/utils@^1.2.1": + version "1.2.1" + resolved "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz" + integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg== + +"@emotion/weak-memoize@^0.3.1": + version "0.3.1" + resolved "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz" + integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww== + +"@esbuild/android-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622" + integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ== + +"@esbuild/android-arm@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682" + integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw== + +"@esbuild/android-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2" + integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg== + +"@esbuild/darwin-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz#08172cbeccf95fbc383399a7f39cfbddaeb0d7c1" + integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA== + +"@esbuild/darwin-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d" + integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ== + +"@esbuild/freebsd-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54" + integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw== + +"@esbuild/freebsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e" + integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ== + +"@esbuild/linux-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0" + integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA== + +"@esbuild/linux-arm@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0" + integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg== + +"@esbuild/linux-ia32@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7" + integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA== + +"@esbuild/linux-loong64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d" + integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg== + +"@esbuild/linux-mips64el@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231" + integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ== + +"@esbuild/linux-ppc64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb" + integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA== + +"@esbuild/linux-riscv64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6" + integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A== + +"@esbuild/linux-s390x@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071" + integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ== + +"@esbuild/linux-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz" + integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w== + +"@esbuild/netbsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1" + integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A== + +"@esbuild/openbsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae" + integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg== + +"@esbuild/sunos-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d" + integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ== + +"@esbuild/win32-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9" + integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg== + +"@esbuild/win32-ia32@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102" + integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g== + +"@esbuild/win32-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d" + integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ== + +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": + version "4.4.0" + resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": + version "4.6.2" + resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz" + integrity sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw== + +"@eslint/eslintrc@^2.1.2": + version "2.1.2" + resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz" + integrity sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@^8.47.0": + version "8.47.0" + resolved "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz" + integrity sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og== + +"@humanwhocodes/config-array@^0.11.10": + version "0.11.10" + resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz" + integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.19" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz" + integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@mediapipe/tasks-vision@0.10.2": + version "0.10.2" + resolved "https://registry.npmjs.org/@mediapipe/tasks-vision/-/tasks-vision-0.10.2.tgz" + integrity sha512-d8Q9uRK89ZRWmED2JLI9/blpJcfdbh0iEUuMo8TgkMzNfQBY1/GC0FEJWrairTwHkxIf6Oud1vFBP+aHicWqJA== + +"@mui/base@5.0.0-beta.11": + version "5.0.0-beta.11" + resolved "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.11.tgz" + integrity sha512-FdKZGPd8qmC3ZNke7CNhzcEgToc02M6WYZc9hcBsNQ17bgAd3s9F//1bDDYgMVBYxDM71V0sv/hBHlOY4I1ZVA== + dependencies: + "@babel/runtime" "^7.22.6" + "@emotion/is-prop-valid" "^1.2.1" + "@mui/types" "^7.2.4" + "@mui/utils" "^5.14.5" + "@popperjs/core" "^2.11.8" + clsx "^2.0.0" + prop-types "^15.8.1" + react-is "^18.2.0" + +"@mui/core-downloads-tracker@^5.14.5": + version "5.14.5" + resolved "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.5.tgz" + integrity sha512-+wpGH1USwPcKMFPMvXqYPC6fEvhxM3FzxC8lyDiNK/imLyyJ6y2DPb1Oue7OGIKJWBmYBqrWWtfovrxd1aJHTA== + +"@mui/icons-material@5.14.3": + version "5.14.3" + resolved "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.14.3.tgz" + integrity sha512-XkxWPhageu1OPUm2LWjo5XqeQ0t2xfGe8EiLkRW9oz2LHMMZmijvCxulhgquUVTF1DnoSh+3KoDLSsoAFtVNVw== + dependencies: + "@babel/runtime" "^7.22.6" + +"@mui/material@5.14.5": + version "5.14.5" + resolved "https://registry.npmjs.org/@mui/material/-/material-5.14.5.tgz" + integrity sha512-4qa4GMfuZH0Ai3mttk5ccXP8a3sf7aPlAJwyMrUSz6h9hPri6BPou94zeu3rENhhmKLby9S/W1y+pmficy8JKA== + dependencies: + "@babel/runtime" "^7.22.6" + "@mui/base" "5.0.0-beta.11" + "@mui/core-downloads-tracker" "^5.14.5" + "@mui/system" "^5.14.5" + "@mui/types" "^7.2.4" + "@mui/utils" "^5.14.5" + "@types/react-transition-group" "^4.4.6" + clsx "^2.0.0" + csstype "^3.1.2" + prop-types "^15.8.1" + react-is "^18.2.0" + react-transition-group "^4.4.5" + +"@mui/private-theming@^5.14.5": + version "5.14.5" + resolved "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.14.5.tgz" + integrity sha512-cC4C5RrpXpDaaZyH9QwmPhRLgz+f2SYbOty3cPkk4qPSOSfif2ZEcDD9HTENKDDd9deB+xkPKzzZhi8cxIx8Ig== + dependencies: + "@babel/runtime" "^7.22.6" + "@mui/utils" "^5.14.5" + prop-types "^15.8.1" + +"@mui/styled-engine@^5.13.2": + version "5.13.2" + resolved "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.13.2.tgz" + integrity sha512-VCYCU6xVtXOrIN8lcbuPmoG+u7FYuOERG++fpY74hPpEWkyFQG97F+/XfTQVYzlR2m7nPjnwVUgATcTCMEaMvw== + dependencies: + "@babel/runtime" "^7.21.0" + "@emotion/cache" "^11.11.0" + csstype "^3.1.2" + prop-types "^15.8.1" + +"@mui/system@^5.14.5": + version "5.14.5" + resolved "https://registry.npmjs.org/@mui/system/-/system-5.14.5.tgz" + integrity sha512-mextXZHDeGcR7E1kx43TRARrVXy+gI4wzpUgNv7MqZs1dvTVXQGVeAT6ydj9d6FUqHBPMNLGV/21vJOrpqsL+w== + dependencies: + "@babel/runtime" "^7.22.6" + "@mui/private-theming" "^5.14.5" + "@mui/styled-engine" "^5.13.2" + "@mui/types" "^7.2.4" + "@mui/utils" "^5.14.5" + clsx "^2.0.0" + csstype "^3.1.2" + prop-types "^15.8.1" + +"@mui/types@^7.2.4": + version "7.2.4" + resolved "https://registry.npmjs.org/@mui/types/-/types-7.2.4.tgz" + integrity sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA== + +"@mui/utils@^5.14.5": + version "5.14.5" + resolved "https://registry.npmjs.org/@mui/utils/-/utils-5.14.5.tgz" + integrity sha512-6Hzw63VR9C5xYv+CbjndoRLU6Gntal8rJ5W+GUzkyHrGWIyYPWZPa6AevnyGioySNETATe1H9oXS8f/7qgIHJA== + dependencies: + "@babel/runtime" "^7.22.6" + "@types/prop-types" "^15.7.5" + "@types/react-is" "^18.2.1" + prop-types "^15.8.1" + react-is "^18.2.0" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@popperjs/core@^2.11.8": + version "2.11.8" + resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz" + integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== + +"@react-spring/animated@~9.6.1": + version "9.6.1" + resolved "https://registry.npmjs.org/@react-spring/animated/-/animated-9.6.1.tgz" + integrity sha512-ls/rJBrAqiAYozjLo5EPPLLOb1LM0lNVQcXODTC1SMtS6DbuBCPaKco5svFUQFMP2dso3O+qcC4k9FsKc0KxMQ== + dependencies: + "@react-spring/shared" "~9.6.1" + "@react-spring/types" "~9.6.1" + +"@react-spring/core@~9.6.1": + version "9.6.1" + resolved "https://registry.npmjs.org/@react-spring/core/-/core-9.6.1.tgz" + integrity sha512-3HAAinAyCPessyQNNXe5W0OHzRfa8Yo5P748paPcmMowZ/4sMfaZ2ZB6e5x5khQI8NusOHj8nquoutd6FRY5WQ== + dependencies: + "@react-spring/animated" "~9.6.1" + "@react-spring/rafz" "~9.6.1" + "@react-spring/shared" "~9.6.1" + "@react-spring/types" "~9.6.1" + +"@react-spring/rafz@~9.6.1": + version "9.6.1" + resolved "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.6.1.tgz" + integrity sha512-v6qbgNRpztJFFfSE3e2W1Uz+g8KnIBs6SmzCzcVVF61GdGfGOuBrbjIcp+nUz301awVmREKi4eMQb2Ab2gGgyQ== + +"@react-spring/shared@~9.6.1": + version "9.6.1" + resolved "https://registry.npmjs.org/@react-spring/shared/-/shared-9.6.1.tgz" + integrity sha512-PBFBXabxFEuF8enNLkVqMC9h5uLRBo6GQhRMQT/nRTnemVENimgRd+0ZT4yFnAQ0AxWNiJfX3qux+bW2LbG6Bw== + dependencies: + "@react-spring/rafz" "~9.6.1" + "@react-spring/types" "~9.6.1" + +"@react-spring/three@~9.6.1": + version "9.6.1" + resolved "https://registry.npmjs.org/@react-spring/three/-/three-9.6.1.tgz" + integrity sha512-Tyw2YhZPKJAX3t2FcqvpLRb71CyTe1GvT3V+i+xJzfALgpk10uPGdGaQQ5Xrzmok1340DAeg2pR/MCfaW7b8AA== + dependencies: + "@react-spring/animated" "~9.6.1" + "@react-spring/core" "~9.6.1" + "@react-spring/shared" "~9.6.1" + "@react-spring/types" "~9.6.1" + +"@react-spring/types@~9.6.1": + version "9.6.1" + resolved "https://registry.npmjs.org/@react-spring/types/-/types-9.6.1.tgz" + integrity sha512-POu8Mk0hIU3lRXB3bGIGe4VHIwwDsQyoD1F394OK7STTiX9w4dG3cTLljjYswkQN+hDSHRrj4O36kuVa7KPU8Q== + +"@react-three/drei@^9.83.9": + version "9.83.9" + resolved "https://registry.npmjs.org/@react-three/drei/-/drei-9.83.9.tgz" + integrity sha512-WFwySXDbockMpOWCsx12JXEvWZgakw3LOmdiXYpd9kb5fJ+fBgaK4bNLMbJymfadpVIXjVaovWMqzUI98W1pxw== + dependencies: + "@babel/runtime" "^7.11.2" + "@mediapipe/tasks-vision" "0.10.2" + "@react-spring/three" "~9.6.1" + "@use-gesture/react" "^10.2.24" + camera-controls "^2.4.2" + cross-env "^7.0.3" + detect-gpu "^5.0.28" + glsl-noise "^0.0.0" + lodash.clamp "^4.0.3" + lodash.omit "^4.5.0" + lodash.pick "^4.4.0" + maath "^0.6.0" + meshline "^3.1.6" + react-composer "^5.0.3" + react-merge-refs "^1.1.0" + stats-gl "^1.0.4" + stats.js "^0.17.0" + suspend-react "^0.1.3" + three-mesh-bvh "^0.6.0" + three-stdlib "^2.25.1" + troika-three-text "^0.47.2" + utility-types "^3.10.0" + zustand "^3.5.13" + +"@react-three/fiber@^8.14.1": + version "8.14.1" + resolved "https://registry.npmjs.org/@react-three/fiber/-/fiber-8.14.1.tgz" + integrity sha512-Ky/FiCyJiyaI8bd+vckzgkHgKDSQDOcSSUVFOHCuCO9XOLb7Ebs6lof2hPpFa1HkaeE5ZIbTWIprvN0QqdPF0w== + dependencies: + "@babel/runtime" "^7.17.8" + "@types/react-reconciler" "^0.26.7" + base64-js "^1.5.1" + its-fine "^1.0.6" + react-reconciler "^0.27.0" + react-use-measure "^2.1.1" + scheduler "^0.21.0" + suspend-react "^0.1.3" + zustand "^3.7.1" + +"@react-three/xr@^5.7.1": + version "5.7.1" + resolved "https://registry.npmjs.org/@react-three/xr/-/xr-5.7.1.tgz" + integrity sha512-GaRUSA+lE8VJF/NrXq7QQByZ4UGHbQQ4rs3QCphZs9fVidK86hGrMOQ0kL79gZc5pa3V5uFGlOhNcUdsTYE3Bg== + dependencies: + "@types/webxr" "*" + three-stdlib "^2.21.1" + zustand "^3.7.1" + +"@smithy/types@^2.3.4": + version "2.3.5" + resolved "https://registry.npmjs.org/@smithy/types/-/types-2.3.5.tgz" + integrity sha512-ehyDt8M9hehyxrLQGoA1BGPou8Js1Ocoh5M0ngDhJMqbFmNK5N6Xhr9/ZExWkyIW8XcGkiMPq3ZUEE0ScrhbuQ== + dependencies: + tslib "^2.5.0" + +"@socket.io/component-emitter@~3.1.0": + version "3.1.0" + resolved "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz" + integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg== + +"@types/draco3d@^1.4.0": + version "1.4.2" + resolved "https://registry.npmjs.org/@types/draco3d/-/draco3d-1.4.2.tgz" + integrity sha512-goh23EGr6CLV6aKPwN1p8kBD/7tT5V/bLpToSbarKrwVejqNrspVrv8DhliteYkkhZYrlq/fwKZRRUzH4XN88w== + +"@types/json-schema@^7.0.12": + version "7.0.12" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz" + integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== + +"@types/node@^20.5.3": + version "20.5.3" + resolved "https://registry.npmjs.org/@types/node/-/node-20.5.3.tgz" + integrity sha512-ITI7rbWczR8a/S6qjAW7DMqxqFMjjTo61qZVWJ1ubPvbIQsL5D/TvwjYEalM8Kthpe3hTzOGrF2TGbAu2uyqeA== + +"@types/offscreencanvas@^2019.6.4": + version "2019.7.1" + resolved "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.1.tgz" + integrity sha512-+HSrJgjBW77ALieQdMJvXhRZUIRN1597L+BKvsyeiIlHHERnqjcuOLyodK3auJ3Y3zRezNKtKAhuQWYJfEgFHQ== + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + +"@types/prop-types@*", "@types/prop-types@^15.7.5": + version "15.7.5" + resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz" + integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== + +"@types/react-dom@^18.2.7": + version "18.2.7" + resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz" + integrity sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA== + dependencies: + "@types/react" "*" + +"@types/react-is@^18.2.1": + version "18.2.1" + resolved "https://registry.npmjs.org/@types/react-is/-/react-is-18.2.1.tgz" + integrity sha512-wyUkmaaSZEzFZivD8F2ftSyAfk6L+DfFliVj/mYdOXbVjRcS87fQJLTnhk6dRZPuJjI+9g6RZJO4PNCngUrmyw== + dependencies: + "@types/react" "*" + +"@types/react-reconciler@^0.26.7": + version "0.26.7" + resolved "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.26.7.tgz" + integrity sha512-mBDYl8x+oyPX/VBb3E638N0B7xG+SPk/EAMcVPeexqus/5aTpTphQi0curhhshOqRrc9t6OPoJfEUkbymse/lQ== + dependencies: + "@types/react" "*" + +"@types/react-reconciler@^0.28.0": + version "0.28.4" + resolved "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.4.tgz" + integrity sha512-Xd55E2aLI9Q/ikDQEmfRzIwYJs4oO0h9ZHA3FZDakzt1WR6JMZcpqtCZlF97I72KVjoY4rHXU5TfvkRDOyr/rg== + dependencies: + "@types/react" "*" + +"@types/react-transition-group@^4.4.6": + version "4.4.6" + resolved "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz" + integrity sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew== + dependencies: + "@types/react" "*" + +"@types/react@*", "@types/react@^18.2.15": + version "18.2.20" + resolved "https://registry.npmjs.org/@types/react/-/react-18.2.20.tgz" + integrity sha512-WKNtmsLWJM/3D5mG4U84cysVY31ivmyw85dE84fOCk5Hx78wezB/XEjVPWl2JTZ5FkEeaTJf+VgUAUn3PE7Isw== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/scheduler@*": + version "0.16.3" + resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz" + integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== + +"@types/semver@^7.5.0": + version "7.5.0" + resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz" + integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== + +"@types/uuid@^9.0.2": + version "9.0.2" + resolved "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz" + integrity sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ== + +"@types/webxr@*", "@types/webxr@^0.5.2": + version "0.5.4" + resolved "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.4.tgz" + integrity sha512-41gfGLTtqXZhcmoDlLDHqMJDuwAMwhHwXf9Q2job3TUBsvkNfPNI/3IWVEtLH4tyY1ElWtfwIaoNeqeEX238/Q== + +"@typescript-eslint/eslint-plugin@^6.0.0": + version "6.4.0" + resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.4.0.tgz" + integrity sha512-62o2Hmc7Gs3p8SLfbXcipjWAa6qk2wZGChXG2JbBtYpwSRmti/9KHLqfbLs9uDigOexG+3PaQ9G2g3201FWLKg== + dependencies: + "@eslint-community/regexpp" "^4.5.1" + "@typescript-eslint/scope-manager" "6.4.0" + "@typescript-eslint/type-utils" "6.4.0" + "@typescript-eslint/utils" "6.4.0" + "@typescript-eslint/visitor-keys" "6.4.0" + debug "^4.3.4" + graphemer "^1.4.0" + ignore "^5.2.4" + natural-compare "^1.4.0" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/parser@^6.0.0": + version "6.4.0" + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.4.0.tgz" + integrity sha512-I1Ah1irl033uxjxO9Xql7+biL3YD7w9IU8zF+xlzD/YxY6a4b7DYA08PXUUCbm2sEljwJF6ERFy2kTGAGcNilg== + dependencies: + "@typescript-eslint/scope-manager" "6.4.0" + "@typescript-eslint/types" "6.4.0" + "@typescript-eslint/typescript-estree" "6.4.0" + "@typescript-eslint/visitor-keys" "6.4.0" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@6.4.0": + version "6.4.0" + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.0.tgz" + integrity sha512-TUS7vaKkPWDVvl7GDNHFQMsMruD+zhkd3SdVW0d7b+7Zo+bd/hXJQ8nsiUZMi1jloWo6c9qt3B7Sqo+flC1nig== + dependencies: + "@typescript-eslint/types" "6.4.0" + "@typescript-eslint/visitor-keys" "6.4.0" + +"@typescript-eslint/type-utils@6.4.0": + version "6.4.0" + resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.4.0.tgz" + integrity sha512-TvqrUFFyGY0cX3WgDHcdl2/mMCWCDv/0thTtx/ODMY1QhEiyFtv/OlLaNIiYLwRpAxAtOLOY9SUf1H3Q3dlwAg== + dependencies: + "@typescript-eslint/typescript-estree" "6.4.0" + "@typescript-eslint/utils" "6.4.0" + debug "^4.3.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/types@6.4.0": + version "6.4.0" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.0.tgz" + integrity sha512-+FV9kVFrS7w78YtzkIsNSoYsnOtrYVnKWSTVXoL1761CsCRv5wpDOINgsXpxD67YCLZtVQekDDyaxfjVWUJmmg== + +"@typescript-eslint/typescript-estree@6.4.0": + version "6.4.0" + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.0.tgz" + integrity sha512-iDPJArf/K2sxvjOR6skeUCNgHR/tCQXBsa+ee1/clRKr3olZjZ/dSkXPZjG6YkPtnW6p5D1egeEPMCW6Gn4yLA== + dependencies: + "@typescript-eslint/types" "6.4.0" + "@typescript-eslint/visitor-keys" "6.4.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/utils@6.4.0": + version "6.4.0" + resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.4.0.tgz" + integrity sha512-BvvwryBQpECPGo8PwF/y/q+yacg8Hn/2XS+DqL/oRsOPK+RPt29h5Ui5dqOKHDlbXrAeHUTnyG3wZA0KTDxRZw== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@types/json-schema" "^7.0.12" + "@types/semver" "^7.5.0" + "@typescript-eslint/scope-manager" "6.4.0" + "@typescript-eslint/types" "6.4.0" + "@typescript-eslint/typescript-estree" "6.4.0" + semver "^7.5.4" + +"@typescript-eslint/visitor-keys@6.4.0": + version "6.4.0" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.0.tgz" + integrity sha512-yJSfyT+uJm+JRDWYRYdCm2i+pmvXJSMtPR9Cq5/XQs4QIgNoLcoRtDdzsLbLsFM/c6um6ohQkg/MLxWvoIndJA== + dependencies: + "@typescript-eslint/types" "6.4.0" + eslint-visitor-keys "^3.4.1" + +"@use-gesture/core@10.2.27": + version "10.2.27" + resolved "https://registry.npmjs.org/@use-gesture/core/-/core-10.2.27.tgz" + integrity sha512-V4XV7hn9GAD2MYu8yBBVi5iuWBsAMfjPRMsEVzoTNGYH72tf0kFP+OKqGKc8YJFQIJx6yj+AOqxmEHOmx2/MEA== + +"@use-gesture/react@^10.2.24": + version "10.2.27" + resolved "https://registry.npmjs.org/@use-gesture/react/-/react-10.2.27.tgz" + integrity sha512-7E5vnWCxeslWlxwZ8uKIcnUZVMTRMZ8cvSnLLKF1NkyNb3PnNiAzoXM4G1vTKJKRhgOTeI6wK1YsEpwo9ABV5w== + dependencies: + "@use-gesture/core" "10.2.27" + +"@vitejs/plugin-react@^4.0.3": + version "4.0.4" + resolved "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.0.4.tgz" + integrity sha512-7wU921ABnNYkETiMaZy7XqpueMnpu5VxvVps13MjmCo+utBdD79sZzrApHawHtVX66cCJQQTXFcjH0y9dSUK8g== + dependencies: + "@babel/core" "^7.22.9" + "@babel/plugin-transform-react-jsx-self" "^7.22.5" + "@babel/plugin-transform-react-jsx-source" "^7.22.5" + react-refresh "^0.14.0" + +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn@^8.9.0: + version "8.10.0" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + +ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +amazon-cognito-identity-js@^6.3.6: + version "6.3.6" + resolved "https://registry.npmjs.org/amazon-cognito-identity-js/-/amazon-cognito-identity-js-6.3.6.tgz" + integrity sha512-kBq+GE6OkLrxtFj3ZduIOlKBFYeOqZK3EhxbDBkv476UTvy+uwfR0tlriTq2QzNdnvlQAjBIXnXuOM7DwR1UEQ== + dependencies: + "@aws-crypto/sha256-js" "1.2.2" + buffer "4.9.2" + fast-base64-decode "^1.0.0" + isomorphic-unfetch "^3.0.0" + js-cookie "^2.2.1" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +audiobuffer-to-wav@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/audiobuffer-to-wav/-/audiobuffer-to-wav-1.0.0.tgz" + integrity sha512-CAoir4NRrAzAgYo20tEMiKZR84coE8bq/L+H2kwAaULVY4+0xySsEVtNT5raqpzmH6y0pqzY6EmoViLd9W8F/w== + +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + +aws-sdk@^2.1472.0: + version "2.1472.0" + resolved "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1472.0.tgz" + integrity sha512-U7kAHRbvTy753IXKV8Oom/AqlqnsbXG+Kw5gRbKi6VcsZ3hR/EpNMzdRXTWO5U415bnLWGo8WAqIz67PIaaKsw== + dependencies: + buffer "4.9.2" + events "1.1.1" + ieee754 "1.1.13" + jmespath "0.16.0" + querystring "0.2.0" + sax "1.2.1" + url "0.10.3" + util "^0.12.4" + uuid "8.0.0" + xml2js "0.5.0" + +babel-plugin-macros@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz" + integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== + dependencies: + "@babel/runtime" "^7.12.5" + cosmiconfig "^7.0.0" + resolve "^1.19.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-js@^1.0.2, base64-js@^1.5.1: + version "1.5.1" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +bidi-js@^1.0.2: + version "1.0.3" + resolved "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz" + integrity sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw== + dependencies: + require-from-string "^2.0.2" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^4.21.9: + version "4.21.10" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz" + integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ== + dependencies: + caniuse-lite "^1.0.30001517" + electron-to-chromium "^1.4.477" + node-releases "^2.0.13" + update-browserslist-db "^1.0.11" + +buffer@4.9.2: + version "4.9.2" + resolved "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camera-controls@^2.4.2: + version "2.7.2" + resolved "https://registry.npmjs.org/camera-controls/-/camera-controls-2.7.2.tgz" + integrity sha512-6+gaZFK3LYbWaXC94EN0BYLlvpo9xfUqwp59vsU3nV7WXIU05q4wyP5TOgyG1tqTHReuBofb20vKfZNBNjMtzw== + +caniuse-lite@^1.0.30001517: + version "1.0.30001520" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001520.tgz" + integrity sha512-tahF5O9EiiTzwTUqAeFjIZbn4Dnqxzz7ktrgGlMYNLH43Ul26IgTMH/zvL3DG0lZxBYnlT04axvInszUsZULdA== + +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + +clsx@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz" + integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +concurrently@8.2.1: + version "8.2.1" + resolved "https://registry.npmjs.org/concurrently/-/concurrently-8.2.1.tgz" + integrity sha512-nVraf3aXOpIcNud5pB9M82p1tynmZkrSGQ1p6X/VY8cJ+2LMVqAgXsJxYYefACSHbTYlm92O1xuhdGTjwoEvbQ== + dependencies: + chalk "^4.1.2" + date-fns "^2.30.0" + lodash "^4.17.21" + rxjs "^7.8.1" + shell-quote "^1.8.1" + spawn-command "0.0.2" + supports-color "^8.1.1" + tree-kill "^1.2.2" + yargs "^17.7.2" + +convert-source-map@^1.5.0, convert-source-map@^1.7.0: + version "1.9.0" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + +cosmiconfig@^7.0.0: + version "7.1.0" + resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz" + integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + +cross-env@^7.0.3: + version "7.0.3" + resolved "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz" + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== + dependencies: + cross-spawn "^7.0.1" + +cross-spawn@^7.0.1, cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +csstype@^3.0.2, csstype@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz" + integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== + +date-fns@^2.30.0: + version "2.30.0" + resolved "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz" + integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== + dependencies: + "@babel/runtime" "^7.21.0" + +debounce@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz" + integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== + +debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: + version "4.3.4" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +detect-gpu@^5.0.28: + version "5.0.37" + resolved "https://registry.npmjs.org/detect-gpu/-/detect-gpu-5.0.37.tgz" + integrity sha512-EraWs84faI4iskB4qvE39bevMIazEvd1RpoyGLOBesRLbiz6eMeJqqRPHjEFClfRByYZzi9IzU35rBXIO76oDw== + dependencies: + webgl-constants "^1.1.1" + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-helpers@^5.0.1: + version "5.2.1" + resolved "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz" + integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== + dependencies: + "@babel/runtime" "^7.8.7" + csstype "^3.0.2" + +draco3d@^1.4.1: + version "1.5.6" + resolved "https://registry.npmjs.org/draco3d/-/draco3d-1.5.6.tgz" + integrity sha512-+3NaRjWktb5r61ZFoDejlykPEFKT5N/LkbXsaddlw6xNSXBanUYpFc2AXXpbJDilPHazcSreU/DpQIaxfX0NfQ== + +electron-to-chromium@^1.4.477: + version "1.4.490" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.490.tgz" + integrity sha512-6s7NVJz+sATdYnIwhdshx/N/9O6rvMxmhVoDSDFdj6iA45gHR8EQje70+RYsF4GeB+k0IeNSBnP7yG9ZXJFr7A== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +engine.io-client@~6.5.2: + version "6.5.2" + resolved "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.2.tgz" + integrity sha512-CQZqbrpEYnrpGqC07a9dJDz4gePZUgTPMU3NKJPSeQOyw27Tst4Pl3FemKoFGAlHzgZmKjoRmiJvbWfhCXUlIg== + dependencies: + "@socket.io/component-emitter" "~3.1.0" + debug "~4.3.1" + engine.io-parser "~5.2.1" + ws "~8.11.0" + xmlhttprequest-ssl "~2.0.0" + +engine.io-parser@~5.2.1: + version "5.2.1" + resolved "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz" + integrity sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +esbuild@^0.18.10: + version "0.18.20" + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz" + integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA== + optionalDependencies: + "@esbuild/android-arm" "0.18.20" + "@esbuild/android-arm64" "0.18.20" + "@esbuild/android-x64" "0.18.20" + "@esbuild/darwin-arm64" "0.18.20" + "@esbuild/darwin-x64" "0.18.20" + "@esbuild/freebsd-arm64" "0.18.20" + "@esbuild/freebsd-x64" "0.18.20" + "@esbuild/linux-arm" "0.18.20" + "@esbuild/linux-arm64" "0.18.20" + "@esbuild/linux-ia32" "0.18.20" + "@esbuild/linux-loong64" "0.18.20" + "@esbuild/linux-mips64el" "0.18.20" + "@esbuild/linux-ppc64" "0.18.20" + "@esbuild/linux-riscv64" "0.18.20" + "@esbuild/linux-s390x" "0.18.20" + "@esbuild/linux-x64" "0.18.20" + "@esbuild/netbsd-x64" "0.18.20" + "@esbuild/openbsd-x64" "0.18.20" + "@esbuild/sunos-x64" "0.18.20" + "@esbuild/win32-arm64" "0.18.20" + "@esbuild/win32-ia32" "0.18.20" + "@esbuild/win32-x64" "0.18.20" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-plugin-react-hooks@^4.6.0: + version "4.6.0" + resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz" + integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== + +eslint-plugin-react-refresh@^0.4.3: + version "0.4.3" + resolved "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.3.tgz" + integrity sha512-Hh0wv8bUNY877+sI0BlCUlsS0TYYQqvzEwJsJJPM2WF4RnTStSnSR3zdJYa2nPOJgg3UghXi54lVyMSmpCalzA== + +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + +eslint@^8.45.0: + version "8.47.0" + resolved "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz" + integrity sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.2" + "@eslint/js" "^8.47.0" + "@humanwhocodes/config-array" "^0.11.10" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== + dependencies: + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + +esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +events@1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/events/-/events-1.1.1.tgz" + integrity sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw== + +fast-base64-decode@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz" + integrity sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.2.9: + version "3.3.1" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + +fflate@^0.6.9: + version "0.6.10" + resolved "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz" + integrity sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg== + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-root@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz" + integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flatted@^3.1.0: + version "3.2.7" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" + integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== + +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.3: + version "1.2.1" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz" + integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-proto "^1.0.1" + has-symbols "^1.0.3" + +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^13.19.0: + version "13.21.0" + resolved "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz" + integrity sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg== + dependencies: + type-fest "^0.20.2" + +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +glsl-noise@^0.0.0: + version "0.0.0" + resolved "https://registry.npmjs.org/glsl-noise/-/glsl-noise-0.0.0.tgz" + integrity sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w== + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hoist-non-react-statics@^3.3.1: + version "3.3.2" + resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + +ieee754@1.1.13, ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +ignore@^5.2.0, ignore@^5.2.4: + version "5.2.4" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.3: + version "2.0.4" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-callable@^1.1.3: + version "1.2.7" + resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-typed-array@^1.1.3: + version "1.1.12" + resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz" + integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== + dependencies: + which-typed-array "^1.1.11" + +isarray@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isomorphic-unfetch@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz" + integrity sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q== + dependencies: + node-fetch "^2.6.1" + unfetch "^4.2.0" + +its-fine@^1.0.6: + version "1.1.1" + resolved "https://registry.npmjs.org/its-fine/-/its-fine-1.1.1.tgz" + integrity sha512-v1Ia1xl20KbuSGlwoaGsW0oxsw8Be+TrXweidxD9oT/1lAh6O3K3/GIM95Tt6WCiv6W+h2M7RB1TwdoAjQyyKw== + dependencies: + "@types/react-reconciler" "^0.28.0" + +jmespath@0.16.0: + version "0.16.0" + resolved "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz" + integrity sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw== + +js-cookie@^2.2.1: + version "2.2.1" + resolved "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz" + integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ== + +js-cookie@^3.0.5: + version "3.0.5" + resolved "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz" + integrity sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +json5@^2.2.2: + version "2.2.3" + resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +ktx-parse@^0.4.5: + version "0.4.5" + resolved "https://registry.npmjs.org/ktx-parse/-/ktx-parse-0.4.5.tgz" + integrity sha512-MK3FOody4TXbFf8Yqv7EBbySw7aPvEcPX++Ipt6Sox+/YMFvR5xaTyhfNSk1AEmMy+RYIw81ctN4IMxCB8OAlg== + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.clamp@^4.0.3: + version "4.0.3" + resolved "https://registry.npmjs.org/lodash.clamp/-/lodash.clamp-4.0.3.tgz" + integrity sha512-HvzRFWjtcguTW7yd8NJBshuNaCa8aqNFtnswdT7f/cMd/1YKy5Zzoq4W/Oxvnx9l7aeY258uSdDfM793+eLsVg== + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.omit@^4.5.0: + version "4.5.0" + resolved "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz" + integrity sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg== + +lodash.pick@^4.4.0: + version "4.4.0" + resolved "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz" + integrity sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q== + +lodash@4.17.21, lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +loose-envify@^1.1.0, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +maath@^0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/maath/-/maath-0.6.0.tgz" + integrity sha512-dSb2xQuP7vDnaYqfoKzlApeRcR2xtN8/f7WV/TMAkBC8552TwTLtOO0JTcSygkYMjNDPoo6V01jTw/aPi4JrMw== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +meshline@^3.1.6: + version "3.1.6" + resolved "https://registry.npmjs.org/meshline/-/meshline-3.1.6.tgz" + integrity sha512-8JZJOdaL5oz3PI/upG8JvP/5FfzYUOhrkJ8np/WKvXzl0/PZ2V9pqTvCIjSKv+w9ccg2xb+yyBhXAwt6ier3ug== + +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +mmd-parser@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/mmd-parser/-/mmd-parser-1.0.4.tgz" + integrity sha512-Qi0VCU46t2IwfGv5KF0+D/t9cizcDug7qnNoy9Ggk7aucp0tssV8IwTMkBlDbm+VqAf3cdQHTCARKSsuS2MYFg== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +nanoid@^3.3.6: + version "3.3.6" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz" + integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +node-fetch@^2.6.1: + version "2.7.0" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== + dependencies: + whatwg-url "^5.0.0" + +node-releases@^2.0.13: + version "2.0.13" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== + +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +opentype.js@^1.3.3: + version "1.3.4" + resolved "https://registry.npmjs.org/opentype.js/-/opentype.js-1.3.4.tgz" + integrity sha512-d2JE9RP/6uagpQAVtJoF0pJJA/fgai89Cc50Yp0EJHk+eLp6QQ7gBoblsnubRULNY132I0J1QKMJ+JTbMqz4sw== + dependencies: + string.prototype.codepointat "^0.2.1" + tiny-inflate "^1.0.3" + +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +postcss@^8.4.27: + version "8.4.27" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz" + integrity sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ== + dependencies: + nanoid "^3.3.6" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +potpack@^1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz" + integrity sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ== + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.8.1: + version "15.8.1" + resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz" + integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw== + +punycode@^2.1.0: + version "2.3.0" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz" + integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +react-composer@^5.0.3: + version "5.0.3" + resolved "https://registry.npmjs.org/react-composer/-/react-composer-5.0.3.tgz" + integrity sha512-1uWd07EME6XZvMfapwZmc7NgCZqDemcvicRi3wMJzXsQLvZ3L7fTHVyPy1bZdnWXM4iPjYuNE+uJ41MLKeTtnA== + dependencies: + prop-types "^15.6.0" + +react-dom@^18.2.0: + version "18.2.0" + resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz" + integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.0" + +react-google-charts@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/react-google-charts/-/react-google-charts-4.0.1.tgz" + integrity sha512-V/hcMcNuBgD5w49BYTUDye+bUKaPmsU5vy/9W/Nj2xEeGn+6/AuH9IvBkbDcNBsY00cV9OeexdmgfI5RFHgsXQ== + +react-is@^16.13.1, react-is@^16.7.0: + version "16.13.1" + resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-is@^18.2.0: + version "18.2.0" + resolved "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + +react-merge-refs@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/react-merge-refs/-/react-merge-refs-1.1.0.tgz" + integrity sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ== + +react-reconciler@^0.27.0: + version "0.27.0" + resolved "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.27.0.tgz" + integrity sha512-HmMDKciQjYmBRGuuhIaKA1ba/7a+UsM5FzOZsMO2JYHt9Jh8reCb7j1eDC95NOyUlKM9KRyvdx0flBuDvYSBoA== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.21.0" + +react-refresh@^0.14.0: + version "0.14.0" + resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz" + integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ== + +react-transition-group@^4.4.5: + version "4.4.5" + resolved "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz" + integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g== + dependencies: + "@babel/runtime" "^7.5.5" + dom-helpers "^5.0.1" + loose-envify "^1.4.0" + prop-types "^15.6.2" + +react-use-measure@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.1.tgz" + integrity sha512-nocZhN26cproIiIduswYpV5y5lQpSQS1y/4KuvUCjSKmw7ZWIS/+g3aFnX3WdBkyuGUtTLif3UTqnLLhbDoQig== + dependencies: + debounce "^1.2.1" + +react@^18.2.0: + version "18.2.0" + resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== + dependencies: + loose-envify "^1.1.0" + +regenerator-runtime@^0.14.0: + version "0.14.0" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz" + integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve@^1.19.0: + version "1.22.4" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rollup@^3.27.1: + version "3.28.0" + resolved "https://registry.npmjs.org/rollup/-/rollup-3.28.0.tgz" + integrity sha512-d7zhvo1OUY2SXSM6pfNjgD5+d0Nz87CUp4mt8l/GgVP3oBsPwzNvSzyu1me6BSG9JIgWNTVcafIXBIyM8yQ3yw== + optionalDependencies: + fsevents "~2.3.2" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +rxjs@^7.8.1: + version "7.8.1" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== + dependencies: + tslib "^2.1.0" + +sax@1.2.1, sax@>=0.6.0: + version "1.2.1" + resolved "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz" + integrity sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA== + +scheduler@^0.21.0: + version "0.21.0" + resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz" + integrity sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ== + dependencies: + loose-envify "^1.1.0" + +scheduler@^0.23.0: + version "0.23.0" + resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz" + integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== + dependencies: + loose-envify "^1.1.0" + +semver@^6.3.1: + version "6.3.1" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.5.4: + version "7.5.4" + resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shell-quote@^1.8.1: + version "1.8.1" + resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz" + integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +socket.io-client@^4.7.2: + version "4.7.2" + resolved "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.2.tgz" + integrity sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w== + dependencies: + "@socket.io/component-emitter" "~3.1.0" + debug "~4.3.2" + engine.io-client "~6.5.2" + socket.io-parser "~4.2.4" + +socket.io-parser@~4.2.4: + version "4.2.4" + resolved "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz" + integrity sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew== + dependencies: + "@socket.io/component-emitter" "~3.1.0" + debug "~4.3.1" + +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== + +spawn-command@0.0.2: + version "0.0.2" + resolved "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz" + integrity sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ== + +stats-gl@^1.0.4: + version "1.0.5" + resolved "https://registry.npmjs.org/stats-gl/-/stats-gl-1.0.5.tgz" + integrity sha512-XimMxvwnf1Qf5KwebhcoA34kcX+fWEkIl0QjNkCbu4IpoyDMMsOajExn7FIq5w569k45+LhmsuRlGSrsvmGdNw== + +stats.js@^0.17.0: + version "0.17.0" + resolved "https://registry.npmjs.org/stats.js/-/stats.js-0.17.0.tgz" + integrity sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw== + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string.prototype.codepointat@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz" + integrity sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg== + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +stylis@4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz" + integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.1.1: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +suspend-react@^0.1.3: + version "0.1.3" + resolved "https://registry.npmjs.org/suspend-react/-/suspend-react-0.1.3.tgz" + integrity sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ== + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +three-mesh-bvh@^0.6.0: + version "0.6.7" + resolved "https://registry.npmjs.org/three-mesh-bvh/-/three-mesh-bvh-0.6.7.tgz" + integrity sha512-RYdjMsH+vZvjLwA+ehI4+ZqTaTehAz4iho2yfL5PdGsIHyxpB78g0iy4Emj8079m/9KBX02TzddkvPSKSruQjg== + +three-mesh-ui@^6.5.4: + version "6.5.4" + resolved "https://registry.npmjs.org/three-mesh-ui/-/three-mesh-ui-6.5.4.tgz" + integrity sha512-QA2KlHrbj7zGjKqpNXcwvini8g5gOXb44ExdupVpxCqmHln/sWNGOmN0yIa/HjnMGYJWP4M+NchTHvwUp+MWIw== + +three-stdlib@^2.21.1, three-stdlib@^2.25.1: + version "2.25.1" + resolved "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.25.1.tgz" + integrity sha512-cFlxaTJjlSM10NGoUVEoQkMRpSOftuAh3OCpSKiLTsUfA7/HuhpoBJy3StiOor/LZm5M+onegqsbr5UBCCYYjQ== + dependencies: + "@types/draco3d" "^1.4.0" + "@types/offscreencanvas" "^2019.6.4" + "@types/webxr" "^0.5.2" + draco3d "^1.4.1" + fflate "^0.6.9" + ktx-parse "^0.4.5" + mmd-parser "^1.0.4" + opentype.js "^1.3.3" + potpack "^1.0.1" + zstddec "^0.0.2" + +three@^0.156.1: + version "0.156.1" + resolved "https://registry.npmjs.org/three/-/three-0.156.1.tgz" + integrity sha512-kP7H0FK9d/k6t/XvQ9FO6i+QrePoDcNhwl0I02+wmUJRNSLCUIDMcfObnzQvxb37/0Uc9TDT0T1HgsRRrO6SYQ== + +tiny-inflate@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz" + integrity sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + 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== + dependencies: + is-number "^7.0.0" + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +tree-kill@^1.2.2: + version "1.2.2" + resolved "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz" + integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== + +troika-three-text@^0.47.2: + version "0.47.2" + resolved "https://registry.npmjs.org/troika-three-text/-/troika-three-text-0.47.2.tgz" + integrity sha512-qylT0F+U7xGs+/PEf3ujBdJMYWbn0Qci0kLqI5BJG2kW1wdg4T1XSxneypnF05DxFqJhEzuaOR9S2SjiyknMng== + dependencies: + bidi-js "^1.0.2" + troika-three-utils "^0.47.2" + troika-worker-utils "^0.47.2" + webgl-sdf-generator "1.1.1" + +troika-three-utils@^0.47.2: + version "0.47.2" + resolved "https://registry.npmjs.org/troika-three-utils/-/troika-three-utils-0.47.2.tgz" + integrity sha512-/28plhCxfKtH7MSxEGx8e3b/OXU5A0xlwl+Sbdp0H8FXUHKZDoksduEKmjQayXYtxAyuUiCRunYIv/8Vi7aiyg== + +troika-worker-utils@^0.47.2: + version "0.47.2" + resolved "https://registry.npmjs.org/troika-worker-utils/-/troika-worker-utils-0.47.2.tgz" + integrity sha512-mzss4MeyzUkYBppn4x5cdAqrhBHFEuVmMMgLMTyFV23x6GvQMyo+/R5E5Lsbrt7WSt5RfvewjcwD1DChRTA9lA== + +ts-api-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz" + integrity sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A== + +tslib@^1.11.1: + version "1.14.1" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.1.0, tslib@^2.3.1, tslib@^2.5.0: + version "2.6.2" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +typescript@5.1.6: + version "5.1.6" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== + +unfetch@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz" + integrity sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA== + +update-browserslist-db@^1.0.11: + version "1.0.11" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +url@0.10.3: + version "0.10.3" + resolved "https://registry.npmjs.org/url/-/url-0.10.3.tgz" + integrity sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ== + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use-sync-external-store@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz" + integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== + +util@^0.12.4: + version "0.12.5" + resolved "https://registry.npmjs.org/util/-/util-0.12.5.tgz" + integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + which-typed-array "^1.1.2" + +utility-types@^3.10.0: + version "3.10.0" + resolved "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz" + integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg== + +uuid@8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz" + integrity sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw== + +uuid@^9.0.0: + version "9.0.0" + resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz" + integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== + +vite@^4.4.5: + version "4.4.9" + resolved "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz" + integrity sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA== + dependencies: + esbuild "^0.18.10" + postcss "^8.4.27" + rollup "^3.27.1" + optionalDependencies: + fsevents "~2.3.2" + +webgl-constants@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/webgl-constants/-/webgl-constants-1.1.1.tgz" + integrity sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg== + +webgl-sdf-generator@1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/webgl-sdf-generator/-/webgl-sdf-generator-1.1.1.tgz" + integrity sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA== + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +which-typed-array@^1.1.11, which-typed-array@^1.1.2: + version "1.1.11" + resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz" + integrity sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@~8.11.0: + version "8.11.0" + resolved "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz" + integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== + +xml2js@0.5.0: + version "0.5.0" + resolved "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz" + integrity sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + +xmlhttprequest-ssl@~2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz" + integrity sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.10.0: + version "1.10.2" + resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^17.7.2: + version "17.7.2" + resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +zstddec@^0.0.2: + version "0.0.2" + resolved "https://registry.npmjs.org/zstddec/-/zstddec-0.0.2.tgz" + integrity sha512-DCo0oxvcvOTGP/f5FA6tz2Z6wF+FIcEApSTu0zV5sQgn9hoT5lZ9YRAKUraxt9oP7l4e8TnNdi8IZTCX6WCkwA== + +zustand@^3.5.13, zustand@^3.7.1: + version "3.7.2" + resolved "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz" + integrity sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA== + +zustand@^4.4.3: + version "4.4.3" + resolved "https://registry.npmjs.org/zustand/-/zustand-4.4.3.tgz" + integrity sha512-oRy+X3ZazZvLfmv6viIaQmtLOMeij1noakIsK/Y47PWYhT8glfXzQ4j0YcP5i0P0qI1A4rIB//SGROGyZhx91A== + dependencies: + use-sync-external-store "1.2.0"