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 ? (
+ <>
+
+ {
+ debug()?.downloadInputAudio();
+ debug()?.downloadOutputAudio();
+ }}>
+ Download Input / Ouput Audio
+
+ >
+ ) : (
+ 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'}}
+ /> */}
+
+ {/*
+ onJoinRoom(false)}>
+ {roomState?.room_id != null ? 'Update Roles' : 'Join Room'}
+
+
*/}
+
+ {roomState?.room_id == null && (
+
+ onJoinRoom(true)}>
+ {'Start translating'}
+
+
+ )}
+
+
+
+ {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 (
+
+
+
+
+
+
+
+
+
+ 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
+ */}
+ {/* {
+ const newAgent =
+ agentsCapabilities.find(
+ (agent) => e.target.value === agent.name,
+ ) ?? null;
+ if (newAgent == null) {
+ console.error(
+ 'Unable to find agent with name',
+ e.target.value,
+ );
+ }
+ setAgentAndUpdateParams(newAgent);
+ }}
+ value={model ?? ''}>
+ {agentsCapabilities.map((agent) => (
+
+ {agent.name}
+
+ ))}
+ */}
+
+
+
+
+
+
+ Illy, can you please select the target language?
+
+
+
+
+
+ Target Language
+
+ {
+ setTargetLang(e.target.value);
+ onSetDynamicConfig({
+ targetLanguage: e.target.value,
+ });
+ }}
+ value={targetLang ?? ''}>
+ {currentAgent?.targetLangs.map((langCode) => (
+
+ {getLanguageFromThreeLetterCode(langCode) != null
+ ? `${getLanguageFromThreeLetterCode(
+ langCode,
+ )} (${langCode})`
+ : langCode}
+
+ ))}
+
+
+
+
+
+
+
+
+ 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' ? (
+
+ {buttonLabelMap[streamingStatus]}
+
+ ) : (
+
+ {buttonLabelMap[streamingStatus]}
+
+ )}
+
+
+ setMuted((prev) => !prev)}
+ sx={{
+ borderRadius: 100,
+ paddingX: 0,
+ minWidth: '36px',
+ }}>
+ {muted ? : }
+
+
+
+ {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 && (
+
+ Clear Transcript for All
+
+ )}
+
+
+
+ {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 (
+
+ {supported
+ ? renderer != null
+ ? 'Enter AR'
+ : 'Initializing AR...'
+ : 'AR Not Supported'}
+
+ );
+}
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 (
+ <>
+
+
+
+
+
+
+
+ setStarted(true)}
+ content={'Start Experience'}
+ width={0.2}
+ height={0.035}
+ fontSize={0.015}
+ padding={0.01}
+ borderRadius={0.01}
+ />
+
+ >
+ );
+}
+
+export type XRConfigProps = {
+ animateTextDisplay: boolean;
+ bufferedSpeechPlayer: BufferedSpeechPlayer;
+ translationSentences: TranslationSentences;
+ roomState: RoomState | null;
+ roomID: string | null;
+ startStreaming: () => Promise;
+ stopStreaming: () => Promise;
+ debugParam: boolean | null;
+ onARVisible?: () => void;
+ onARHidden?: () => void;
+};
+
+export default function XRConfig(props: XRConfigProps) {
+ const {bufferedSpeechPlayer, debugParam} = props;
+ const skipARIntro = getURLParams().skipARIntro;
+ const defaultDimensions = {width: 500, height: 500};
+ const [dimensions, setDimensions] = useState(
+ debugParam ? defaultDimensions : {width: 0, height: 0},
+ );
+ const {width, height} = dimensions;
+
+ // Make sure to reset buffer when headset is taken off / on so we don't get an endless stream
+ // of audio. The oculus actually runs for some time after the headset is taken off.
+ const resetBuffers = useCallback(
+ (event: XREvent) => {
+ const session = event.target;
+ if (!(session instanceof XRSession)) {
+ return;
+ }
+ switch (session.visibilityState) {
+ case 'visible':
+ bufferedSpeechPlayer.start();
+ break;
+ case 'hidden':
+ bufferedSpeechPlayer.stop();
+ break;
+ }
+ },
+ [bufferedSpeechPlayer],
+ );
+
+ return (
+
+ {/* This is the button that triggers AR flow if available via a button */}
+
console.error(e)}
+ onClick={() => setDimensions(defaultDimensions)}
+ style={{
+ position: 'absolute',
+ bottom: '24px',
+ left: '50%',
+ transform: 'translateX(-50%)',
+ padding: '12px 24px',
+ border: '1px solid white',
+ borderRadius: '4px',
+ backgroundColor: '#465a69',
+ color: 'white',
+ font: 'normal 0.8125rem sans-serif',
+ outline: 'none',
+ zIndex: 99999,
+ cursor: 'pointer',
+ }}
+ />
+ {/* Canvas to draw if in browser but if in AR mode displays in pass through mode */}
+ {/* The camera here just works in 2D mode. In AR mode it starts at at origin */}
+ {/* */}
+
+
+
+ {/*
+ Uncomment this for controllers to show up
+
+ */}
+
+
+ {/*
+ Uncomment this for moving with controllers
+
+ */}
+ {/*
+ Uncomment this for turning the view in non-vr mode
+
+ */}
+
+ {/* Just for testing */}
+ {/* */}
+
+
+
+ );
+}
diff --git a/streaming-react-app/src/react-xr/XRDialog.css b/streaming-react-app/src/react-xr/XRDialog.css
new file mode 100644
index 0000000000000000000000000000000000000000..1a9097a6f6707f528b6f25bcaaefecd1abe2eadb
--- /dev/null
+++ b/streaming-react-app/src/react-xr/XRDialog.css
@@ -0,0 +1,19 @@
+.xr-dialog-button {
+ margin-bottom: 16px;
+ padding-left: 20px;
+ padding-right: 20px;
+}
+
+.xr-dialog-container {
+ min-height: 200px;
+}
+
+.xr-dialog-text-center {
+ text-align: center;
+}
+
+.xr-dialog-canvas-container {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
diff --git a/streaming-react-app/src/react-xr/XRDialog.tsx b/streaming-react-app/src/react-xr/XRDialog.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..d39959520d90e027b2d73b964b93a01112ed23c8
--- /dev/null
+++ b/streaming-react-app/src/react-xr/XRDialog.tsx
@@ -0,0 +1,91 @@
+import * as THREE from 'three';
+import {
+ Button,
+ Dialog,
+ DialogContent,
+ DialogTitle,
+ IconButton,
+ Typography,
+} from '@mui/material';
+import CloseIcon from '@mui/icons-material/Close';
+import {XRConfigProps} from './XRConfig';
+import {useEffect, useRef, useState} from 'react';
+import './XRDialog.css';
+import {getRenderer, init, updatetranslationText} from './XRRendering';
+import ARButton from './ARButton';
+import {getURLParams} from '../URLParams';
+
+function XRContent(props: XRConfigProps) {
+ const debugParam = getURLParams().debug;
+ const {translationSentences} = props;
+ useEffect(() => {
+ updatetranslationText(translationSentences);
+ }, [translationSentences]);
+
+ const [renderer, setRenderer] = useState(null);
+ const canvasRef = useRef(null);
+ useEffect(() => {
+ if (canvasRef.current != null || debugParam === false) {
+ const existingRenderer = getRenderer();
+ if (existingRenderer) {
+ setRenderer(existingRenderer);
+ } else {
+ const newRenderer = init(
+ 400,
+ 300,
+ debugParam ? canvasRef.current : null,
+ );
+ setRenderer(newRenderer);
+ }
+ }
+ }, [canvasRef.current]);
+
+ return (
+
+
+ Welcome to the Seamless team streaming demo experience! In this demo you
+ will experience AI powered text and audio translation in real time.
+
+
+
+
+ );
+}
+
+export default function XRDialog(props: XRConfigProps) {
+ const [isDialogOpen, setIsDialogOpen] = useState(false);
+
+ return (
+ <>
+ {/* setIsDialogOpen(true)}>
+ Enter AR Experience
+
+ {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"