mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-02 17:25:22 +03:00
Merge branch 'release-0.11.0' of https://github.com/blakeblackshear/frigate into reorder-hide-cameras
This commit is contained in:
commit
60fb80ff24
@ -12,7 +12,6 @@
|
||||
"esbenp.prettier-vscode",
|
||||
"ms-python.vscode-pylance",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
"mikestead.dotenv",
|
||||
"csstools.postcss",
|
||||
"blanu.vscode-styled-jsx",
|
||||
|
||||
@ -57,7 +57,8 @@ RUN pip3 wheel --wheel-dir=/wheels \
|
||||
peewee_migrate \
|
||||
pydantic \
|
||||
zeroconf \
|
||||
ws4py
|
||||
ws4py \
|
||||
requests
|
||||
|
||||
# Frigate Container
|
||||
FROM debian:11-slim
|
||||
|
||||
14
docs/docs/configuration/birdseye.md
Normal file
14
docs/docs/configuration/birdseye.md
Normal file
@ -0,0 +1,14 @@
|
||||
# Birdseye
|
||||
|
||||
Birdseye allows a heads-up view of your cameras to see what is going on around your property / space without having to watch all cameras that may have nothing happening. Birdseye allows specific modes that intelligently show and disappear based on what you care about.
|
||||
|
||||
### Birdseye Modes
|
||||
|
||||
Birdseye offers different modes to customize which cameras show under which circumstances.
|
||||
- **continuous:** All cameras are always included
|
||||
- **motion:** Cameras that have detected motion within the last 30 seconds are included
|
||||
- **objects:** Cameras that have tracked an active object within the last 30 seconds are included
|
||||
|
||||
### Custom Birdseye Icon
|
||||
|
||||
A custom icon can be added to the birdseye background by provided a file `custom.png` inside of the Frigate `media` folder. The file must be a png with the icon as transparent, any non-transparent pixels will be white when displayed in the birdseye view.
|
||||
@ -22,6 +22,7 @@ module.exports = {
|
||||
'configuration/objects',
|
||||
'configuration/rtmp',
|
||||
'configuration/zones',
|
||||
'configuration/birdseye',
|
||||
'configuration/advanced',
|
||||
'configuration/hardware_acceleration',
|
||||
'configuration/nvdec',
|
||||
|
||||
@ -16,7 +16,7 @@ from playhouse.sqliteq import SqliteQueueDatabase
|
||||
from pydantic import ValidationError
|
||||
|
||||
from frigate.config import DetectorTypeEnum, FrigateConfig
|
||||
from frigate.const import CACHE_DIR, CLIPS_DIR, RECORD_DIR
|
||||
from frigate.const import CACHE_DIR, CLIPS_DIR, RECORD_DIR, PLUS_ENV_VAR, PLUS_API_HOST
|
||||
from frigate.edgetpu import EdgeTPUProcess
|
||||
from frigate.events import EventCleanup, EventProcessor
|
||||
from frigate.http import create_app
|
||||
@ -25,6 +25,7 @@ from frigate.models import Event, Recordings
|
||||
from frigate.mqtt import MqttSocketRelay, create_mqtt_client
|
||||
from frigate.object_processing import TrackedObjectProcessor
|
||||
from frigate.output import output_frames
|
||||
from frigate.plus import PlusApi
|
||||
from frigate.record import RecordingCleanup, RecordingMaintainer
|
||||
from frigate.stats import StatsEmitter, stats_init
|
||||
from frigate.version import VERSION
|
||||
@ -44,6 +45,11 @@ class FrigateApp:
|
||||
self.detection_out_events: Dict[str, mp.Event] = {}
|
||||
self.detection_shms: List[mp.shared_memory.SharedMemory] = []
|
||||
self.log_queue = mp.Queue()
|
||||
self.plus_api = (
|
||||
PlusApi(PLUS_API_HOST, os.environ.get(PLUS_ENV_VAR))
|
||||
if PLUS_ENV_VAR in os.environ
|
||||
else None
|
||||
)
|
||||
self.camera_metrics = {}
|
||||
|
||||
def set_environment_vars(self):
|
||||
@ -146,6 +152,7 @@ class FrigateApp:
|
||||
self.db,
|
||||
self.stats_tracking,
|
||||
self.detected_frames_processor,
|
||||
self.plus_api,
|
||||
)
|
||||
|
||||
def init_mqtt(self):
|
||||
|
||||
@ -3,3 +3,5 @@ CLIPS_DIR = f"{BASE_DIR}/clips"
|
||||
RECORD_DIR = f"{BASE_DIR}/recordings"
|
||||
CACHE_DIR = "/tmp/cache"
|
||||
YAML_EXT = (".yaml", ".yml")
|
||||
PLUS_ENV_VAR = "PLUS_API_KEY"
|
||||
PLUS_API_HOST = "https://api.frigate.video"
|
||||
|
||||
@ -29,7 +29,7 @@ from flask import (
|
||||
from peewee import SqliteDatabase, operator, fn, DoesNotExist, Value
|
||||
from playhouse.shortcuts import model_to_dict
|
||||
|
||||
from frigate.const import CLIPS_DIR, RECORD_DIR
|
||||
from frigate.const import CLIPS_DIR, PLUS_ENV_VAR
|
||||
from frigate.models import Event, Recordings
|
||||
from frigate.stats import stats_snapshot
|
||||
from frigate.util import calculate_region
|
||||
@ -45,6 +45,7 @@ def create_app(
|
||||
database: SqliteDatabase,
|
||||
stats_tracking,
|
||||
detected_frames_processor,
|
||||
plus_api,
|
||||
):
|
||||
app = Flask(__name__)
|
||||
|
||||
@ -61,6 +62,7 @@ def create_app(
|
||||
app.frigate_config = frigate_config
|
||||
app.stats_tracking = stats_tracking
|
||||
app.detected_frames_processor = detected_frames_processor
|
||||
app.plus_api = plus_api
|
||||
|
||||
app.register_blueprint(bp)
|
||||
|
||||
@ -137,6 +139,58 @@ def set_retain(id):
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/events/<id>/plus", methods=("POST",))
|
||||
def send_to_plus(id):
|
||||
if current_app.plus_api is None:
|
||||
return make_response(
|
||||
jsonify(
|
||||
{
|
||||
"success": False,
|
||||
"message": "PLUS_API_KEY environment variable is not set",
|
||||
}
|
||||
),
|
||||
400,
|
||||
)
|
||||
|
||||
try:
|
||||
event = Event.get(Event.id == id)
|
||||
except DoesNotExist:
|
||||
return make_response(
|
||||
jsonify({"success": False, "message": "Event" + id + " not found"}), 404
|
||||
)
|
||||
|
||||
if event.plus_id:
|
||||
return make_response(
|
||||
jsonify({"success": False, "message": "Already submitted to plus"}), 400
|
||||
)
|
||||
|
||||
# load clean.png
|
||||
try:
|
||||
filename = f"{event.camera}-{event.id}-clean.png"
|
||||
image = cv2.imread(os.path.join(CLIPS_DIR, filename))
|
||||
except Exception:
|
||||
return make_response(
|
||||
jsonify(
|
||||
{"success": False, "message": "Unable to load clean png for event"}
|
||||
),
|
||||
400,
|
||||
)
|
||||
|
||||
try:
|
||||
plus_id = current_app.plus_api.upload_image(image, event.camera)
|
||||
except Exception as ex:
|
||||
return make_response(
|
||||
jsonify({"success": False, "message": str(ex)}),
|
||||
400,
|
||||
)
|
||||
|
||||
# store image id in the database
|
||||
event.plus_id = plus_id
|
||||
event.save()
|
||||
|
||||
return make_response(jsonify({"success": True, "plus_id": plus_id}), 200)
|
||||
|
||||
|
||||
@bp.route("/events/<id>/retain", methods=("DELETE",))
|
||||
def delete_retain(id):
|
||||
try:
|
||||
@ -153,6 +207,7 @@ def delete_retain(id):
|
||||
jsonify({"success": True, "message": "Event " + id + " un-retained"}), 200
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/events/<id>/sub_label", methods=("POST",))
|
||||
def set_sub_label(id):
|
||||
try:
|
||||
@ -167,19 +222,31 @@ def set_sub_label(id):
|
||||
else:
|
||||
new_sub_label = None
|
||||
|
||||
|
||||
if new_sub_label and len(new_sub_label) > 20:
|
||||
return make_response(
|
||||
jsonify({"success": False, "message": new_sub_label + " exceeds the 20 character limit for sub_label"}), 400
|
||||
jsonify(
|
||||
{
|
||||
"success": False,
|
||||
"message": new_sub_label
|
||||
+ " exceeds the 20 character limit for sub_label",
|
||||
}
|
||||
),
|
||||
400,
|
||||
)
|
||||
|
||||
|
||||
event.sub_label = new_sub_label
|
||||
event.save()
|
||||
return make_response(
|
||||
jsonify({"success": True, "message": "Event " + id + " sub label set to " + new_sub_label}), 200
|
||||
jsonify(
|
||||
{
|
||||
"success": True,
|
||||
"message": "Event " + id + " sub label set to " + new_sub_label,
|
||||
}
|
||||
),
|
||||
200,
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/events/<id>", methods=("DELETE",))
|
||||
def delete_event(id):
|
||||
try:
|
||||
@ -252,6 +319,7 @@ def event_thumbnail(id):
|
||||
response.headers["Cache-Control"] = "private, max-age=31536000"
|
||||
return response
|
||||
|
||||
|
||||
@bp.route("/<camera_name>/<label>/best.jpg")
|
||||
@bp.route("/<camera_name>/<label>/thumbnail.jpg")
|
||||
def label_thumbnail(camera_name, label):
|
||||
@ -277,9 +345,7 @@ def label_thumbnail(camera_name, label):
|
||||
return event_thumbnail(event.id)
|
||||
except DoesNotExist:
|
||||
frame = np.zeros((175, 175, 3), np.uint8)
|
||||
ret, jpg = cv2.imencode(
|
||||
".jpg", frame, [int(cv2.IMWRITE_JPEG_QUALITY), 70]
|
||||
)
|
||||
ret, jpg = cv2.imencode(".jpg", frame, [int(cv2.IMWRITE_JPEG_QUALITY), 70])
|
||||
|
||||
response = make_response(jpg.tobytes())
|
||||
response.headers["Content-Type"] = "image/jpeg"
|
||||
@ -330,6 +396,7 @@ def event_snapshot(id):
|
||||
] = f"attachment; filename=snapshot-{id}.jpg"
|
||||
return response
|
||||
|
||||
|
||||
@bp.route("/<camera_name>/<label>/snapshot.jpg")
|
||||
def label_snapshot(camera_name, label):
|
||||
if label == "any":
|
||||
@ -353,9 +420,7 @@ def label_snapshot(camera_name, label):
|
||||
return event_snapshot(event.id)
|
||||
except DoesNotExist:
|
||||
frame = np.zeros((720, 1280, 3), np.uint8)
|
||||
ret, jpg = cv2.imencode(
|
||||
".jpg", frame, [int(cv2.IMWRITE_JPEG_QUALITY), 70]
|
||||
)
|
||||
ret, jpg = cv2.imencode(".jpg", frame, [int(cv2.IMWRITE_JPEG_QUALITY), 70])
|
||||
|
||||
response = make_response(jpg.tobytes())
|
||||
response.headers["Content-Type"] = "image/jpeg"
|
||||
@ -460,6 +525,8 @@ def config():
|
||||
for cmd in camera_dict["ffmpeg_cmds"]:
|
||||
cmd["cmd"] = " ".join(cmd["cmd"])
|
||||
|
||||
config["plus"] = {"enabled": PLUS_ENV_VAR in os.environ}
|
||||
|
||||
return jsonify(config)
|
||||
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@ class Event(Model):
|
||||
area = IntegerField()
|
||||
retain_indefinitely = BooleanField(default=False)
|
||||
ratio = FloatField(default=1.0)
|
||||
plus_id = CharField(max_length=30)
|
||||
|
||||
|
||||
class Recordings(Model):
|
||||
|
||||
@ -22,6 +22,7 @@ from ws4py.server.wsgiutils import WebSocketWSGIApplication
|
||||
from ws4py.websocket import WebSocket
|
||||
|
||||
from frigate.config import BirdseyeModeEnum, FrigateConfig
|
||||
from frigate.const import BASE_DIR
|
||||
from frigate.util import SharedMemoryFrameManager, copy_yuv_to_position, get_yuv_crop
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -104,12 +105,21 @@ class BirdsEyeFrameManager:
|
||||
self.blank_frame[0 : self.frame_shape[0], 0 : self.frame_shape[1]] = 16
|
||||
|
||||
# find and copy the logo on the blank frame
|
||||
birdseye_logo = None
|
||||
|
||||
custom_logo_files = glob.glob(f"{BASE_DIR}/custom.png")
|
||||
|
||||
if len(custom_logo_files) > 0:
|
||||
birdseye_logo = cv2.imread(custom_logo_files[0], cv2.IMREAD_UNCHANGED)
|
||||
|
||||
if birdseye_logo is None:
|
||||
logo_files = glob.glob("/opt/frigate/frigate/birdseye.png")
|
||||
frigate_logo = None
|
||||
|
||||
if len(logo_files) > 0:
|
||||
frigate_logo = cv2.imread(logo_files[0], cv2.IMREAD_UNCHANGED)
|
||||
if not frigate_logo is None:
|
||||
transparent_layer = frigate_logo[:, :, 3]
|
||||
birdseye_logo = cv2.imread(logo_files[0], cv2.IMREAD_UNCHANGED)
|
||||
|
||||
if not birdseye_logo is None:
|
||||
transparent_layer = birdseye_logo[:, :, 3]
|
||||
y_offset = height // 2 - transparent_layer.shape[0] // 2
|
||||
x_offset = width // 2 - transparent_layer.shape[1] // 2
|
||||
self.blank_frame[
|
||||
|
||||
96
frigate/plus.py
Normal file
96
frigate/plus.py
Normal file
@ -0,0 +1,96 @@
|
||||
import datetime
|
||||
import logging
|
||||
import requests
|
||||
import cv2
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_jpg_bytes(image, max_dim, quality):
|
||||
if image.shape[1] >= image.shape[0]:
|
||||
width = min(max_dim, image.shape[1])
|
||||
height = int(width * image.shape[0] / image.shape[1])
|
||||
else:
|
||||
height = min(max_dim, image.shape[0])
|
||||
width = int(height * image.shape[1] / image.shape[0])
|
||||
|
||||
original = cv2.resize(image, dsize=(width, height), interpolation=cv2.INTER_AREA)
|
||||
|
||||
ret, jpg = cv2.imencode(".jpg", original, [int(cv2.IMWRITE_JPEG_QUALITY), quality])
|
||||
return jpg.tobytes()
|
||||
|
||||
|
||||
class PlusApi:
|
||||
def __init__(self, host, key: str):
|
||||
self.host = host
|
||||
self.key = key
|
||||
self._token_data = None
|
||||
|
||||
def _refresh_token_if_needed(self):
|
||||
if (
|
||||
self._token_data is None
|
||||
or self._token_data["expires"] - datetime.datetime.now().timestamp() < 60
|
||||
):
|
||||
parts = self.key.split(":")
|
||||
r = requests.get(f"{self.host}/v1/auth/token", auth=(parts[0], parts[1]))
|
||||
self._token_data = r.json()
|
||||
|
||||
def _get_authorization_header(self):
|
||||
self._refresh_token_if_needed()
|
||||
return {"authorization": f"Bearer {self._token_data['accessToken']}"}
|
||||
|
||||
def _get(self, path):
|
||||
return requests.get(
|
||||
f"{self.host}/v1/{path}", headers=self._get_authorization_header()
|
||||
)
|
||||
|
||||
def _post(self, path, data):
|
||||
return requests.post(
|
||||
f"{self.host}/v1/{path}",
|
||||
headers=self._get_authorization_header(),
|
||||
json=data,
|
||||
)
|
||||
|
||||
def upload_image(self, image, camera: str):
|
||||
r = self._get("image/signed_urls")
|
||||
presigned_urls = r.json()
|
||||
if not r.ok:
|
||||
logger.exception(ex)
|
||||
raise Exception("Unable to get signed urls")
|
||||
|
||||
# resize and submit original
|
||||
files = {"file": get_jpg_bytes(image, 1920, 85)}
|
||||
data = presigned_urls["original"]["fields"]
|
||||
data["content-type"] = "image/jpeg"
|
||||
r = requests.post(presigned_urls["original"]["url"], files=files, data=data)
|
||||
if not r.ok:
|
||||
logger.error(f"Failed to upload original: {r.status_code} {r.text}")
|
||||
raise Exception(r.text)
|
||||
|
||||
# resize and submit annotate
|
||||
files = {"file": get_jpg_bytes(image, 640, 70)}
|
||||
data = presigned_urls["annotate"]["fields"]
|
||||
data["content-type"] = "image/jpeg"
|
||||
r = requests.post(presigned_urls["annotate"]["url"], files=files, data=data)
|
||||
if not r.ok:
|
||||
logger.error(f"Failed to upload annotate: {r.status_code} {r.text}")
|
||||
raise Exception(r.text)
|
||||
|
||||
# resize and submit thumbnail
|
||||
files = {"file": get_jpg_bytes(image, 200, 70)}
|
||||
data = presigned_urls["thumbnail"]["fields"]
|
||||
data["content-type"] = "image/jpeg"
|
||||
r = requests.post(presigned_urls["thumbnail"]["url"], files=files, data=data)
|
||||
if not r.ok:
|
||||
logger.error(f"Failed to upload thumbnail: {r.status_code} {r.text}")
|
||||
raise Exception(r.text)
|
||||
|
||||
# create image
|
||||
r = self._post(
|
||||
"image/create", {"id": presigned_urls["imageId"], "camera": camera}
|
||||
)
|
||||
if not r.ok:
|
||||
raise Exception(r.text)
|
||||
|
||||
# return image id
|
||||
return presigned_urls["imageId"]
|
||||
46
migrations/010_add_plus_image_id.py
Normal file
46
migrations/010_add_plus_image_id.py
Normal file
@ -0,0 +1,46 @@
|
||||
"""Peewee migrations -- 010_add_plus_image_id.py.
|
||||
|
||||
Some examples (model - class or model name)::
|
||||
|
||||
> Model = migrator.orm['model_name'] # Return model in current state by name
|
||||
|
||||
> migrator.sql(sql) # Run custom SQL
|
||||
> migrator.python(func, *args, **kwargs) # Run python code
|
||||
> migrator.create_model(Model) # Create a model (could be used as decorator)
|
||||
> migrator.remove_model(model, cascade=True) # Remove a model
|
||||
> migrator.add_fields(model, **fields) # Add fields to a model
|
||||
> migrator.change_fields(model, **fields) # Change fields
|
||||
> migrator.remove_fields(model, *field_names, cascade=True)
|
||||
> migrator.rename_field(model, old_field_name, new_field_name)
|
||||
> migrator.rename_table(model, new_table_name)
|
||||
> migrator.add_index(model, *col_names, unique=False)
|
||||
> migrator.drop_index(model, *col_names)
|
||||
> migrator.add_not_null(model, *field_names)
|
||||
> migrator.drop_not_null(model, *field_names)
|
||||
> migrator.add_default(model, field_name, default)
|
||||
|
||||
"""
|
||||
|
||||
import datetime as dt
|
||||
import peewee as pw
|
||||
from playhouse.sqlite_ext import *
|
||||
from decimal import ROUND_HALF_EVEN
|
||||
from frigate.models import Event
|
||||
|
||||
try:
|
||||
import playhouse.postgres_ext as pw_pext
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
SQL = pw.SQL
|
||||
|
||||
|
||||
def migrate(migrator, database, fake=False, **kwargs):
|
||||
migrator.add_fields(
|
||||
Event,
|
||||
plus_id=pw.CharField(max_length=30, null=True),
|
||||
)
|
||||
|
||||
|
||||
def rollback(migrator, database, fake=False, **kwargs):
|
||||
migrator.remove_fields(Event, ["plus_id"])
|
||||
736
web/package-lock.json
generated
736
web/package-lock.json
generated
@ -30,13 +30,13 @@
|
||||
"@testing-library/preact": "^2.0.1",
|
||||
"@testing-library/preact-hooks": "^1.1.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.13.0",
|
||||
"@typescript-eslint/parser": "^5.13.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.18.0",
|
||||
"@typescript-eslint/parser": "^5.18.0",
|
||||
"autoprefixer": "^10.4.2",
|
||||
"eslint": "^8.10.0",
|
||||
"eslint": "^8.13.0",
|
||||
"eslint-config-preact": "^1.3.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-jest": "^26.1.1",
|
||||
"eslint-plugin-jest": "^26.1.4",
|
||||
"jest": "^27.5.1",
|
||||
"msw": "^0.38.2",
|
||||
"postcss": "^8.4.7",
|
||||
@ -1823,16 +1823,16 @@
|
||||
"integrity": "sha512-eMN9QMtiPfiDqdJvE8agBOR53lGJXkz2pOy8lhttsuOBzfmf3gs10Uf0ogX/rjt3U7//ZSqKckRT/br1S2uZ6A=="
|
||||
},
|
||||
"node_modules/@eslint/eslintrc": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz",
|
||||
"integrity": "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==",
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz",
|
||||
"integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ajv": "^6.12.4",
|
||||
"debug": "^4.3.2",
|
||||
"espree": "^9.3.1",
|
||||
"globals": "^13.9.0",
|
||||
"ignore": "^4.0.6",
|
||||
"ignore": "^5.2.0",
|
||||
"import-fresh": "^3.2.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"minimatch": "^3.0.4",
|
||||
@ -1843,9 +1843,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc/node_modules/globals": {
|
||||
"version": "13.12.1",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz",
|
||||
"integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==",
|
||||
"version": "13.13.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz",
|
||||
"integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"type-fest": "^0.20.2"
|
||||
@ -1857,15 +1857,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc/node_modules/ignore": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
|
||||
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
|
||||
@ -3259,14 +3250,14 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "5.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.13.0.tgz",
|
||||
"integrity": "sha512-vLktb2Uec81fxm/cfz2Hd6QaWOs8qdmVAZXLdOBX6JFJDhf6oDZpMzZ4/LZ6SFM/5DgDcxIMIvy3F+O9yZBuiQ==",
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.18.0.tgz",
|
||||
"integrity": "sha512-tzrmdGMJI/uii9/V6lurMo4/o+dMTKDH82LkNjhJ3adCW22YQydoRs5MwTiqxGF9CSYxPxQ7EYb4jLNlIs+E+A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "5.13.0",
|
||||
"@typescript-eslint/type-utils": "5.13.0",
|
||||
"@typescript-eslint/utils": "5.13.0",
|
||||
"@typescript-eslint/scope-manager": "5.18.0",
|
||||
"@typescript-eslint/type-utils": "5.18.0",
|
||||
"@typescript-eslint/utils": "5.18.0",
|
||||
"debug": "^4.3.2",
|
||||
"functional-red-black-tree": "^1.0.1",
|
||||
"ignore": "^5.1.8",
|
||||
@ -3291,6 +3282,126 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.18.0.tgz",
|
||||
"integrity": "sha512-C0CZML6NyRDj+ZbMqh9FnPscg2PrzSaVQg3IpTmpe0NURMVBXlghGZgMYqBw07YW73i0MCqSDqv2SbywnCS8jQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"@typescript-eslint/visitor-keys": "5.18.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.18.0.tgz",
|
||||
"integrity": "sha512-bhV1+XjM+9bHMTmXi46p1Led5NP6iqQcsOxgx7fvk6gGiV48c6IynY0apQb7693twJDsXiVzNXTflhplmaiJaw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.18.0.tgz",
|
||||
"integrity": "sha512-wa+2VAhOPpZs1bVij9e5gyVu60ReMi/KuOx4LKjGx2Y3XTNUDJgQ+5f77D49pHtqef/klglf+mibuHs9TrPxdQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"@typescript-eslint/visitor-keys": "5.18.0",
|
||||
"debug": "^4.3.2",
|
||||
"globby": "^11.0.4",
|
||||
"is-glob": "^4.0.3",
|
||||
"semver": "^7.3.5",
|
||||
"tsutils": "^3.21.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.18.0.tgz",
|
||||
"integrity": "sha512-+hFGWUMMri7OFY26TsOlGa+zgjEy1ssEipxpLjtl4wSll8zy85x0GrUSju/FHdKfVorZPYJLkF3I4XPtnCTewA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.9",
|
||||
"@typescript-eslint/scope-manager": "5.18.0",
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"@typescript-eslint/typescript-estree": "5.18.0",
|
||||
"eslint-scope": "^5.1.1",
|
||||
"eslint-utils": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.18.0.tgz",
|
||||
"integrity": "sha512-Hf+t+dJsjAKpKSkg3EHvbtEpFFb/1CiOHnvI8bjHgOD4/wAw3gKrA0i94LrbekypiZVanJu3McWJg7rWDMzRTg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"eslint-visitor-keys": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-scope": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
|
||||
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"esrecurse": "^4.3.0",
|
||||
"estraverse": "^4.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin/node_modules/estraverse": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
|
||||
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": {
|
||||
"version": "7.3.5",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
||||
@ -3326,14 +3437,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser": {
|
||||
"version": "5.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.13.0.tgz",
|
||||
"integrity": "sha512-GdrU4GvBE29tm2RqWOM0P5QfCtgCyN4hXICj/X9ibKED16136l9ZpoJvCL5pSKtmJzA+NRDzQ312wWMejCVVfg==",
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.18.0.tgz",
|
||||
"integrity": "sha512-+08nYfurBzSSPndngnHvFw/fniWYJ5ymOrn/63oMIbgomVQOvIDhBoJmYZ9lwQOCnQV9xHGvf88ze3jFGUYooQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "5.13.0",
|
||||
"@typescript-eslint/types": "5.13.0",
|
||||
"@typescript-eslint/typescript-estree": "5.13.0",
|
||||
"@typescript-eslint/scope-manager": "5.18.0",
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"@typescript-eslint/typescript-estree": "5.18.0",
|
||||
"debug": "^4.3.2"
|
||||
},
|
||||
"engines": {
|
||||
@ -3352,6 +3463,104 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.18.0.tgz",
|
||||
"integrity": "sha512-C0CZML6NyRDj+ZbMqh9FnPscg2PrzSaVQg3IpTmpe0NURMVBXlghGZgMYqBw07YW73i0MCqSDqv2SbywnCS8jQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"@typescript-eslint/visitor-keys": "5.18.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.18.0.tgz",
|
||||
"integrity": "sha512-bhV1+XjM+9bHMTmXi46p1Led5NP6iqQcsOxgx7fvk6gGiV48c6IynY0apQb7693twJDsXiVzNXTflhplmaiJaw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.18.0.tgz",
|
||||
"integrity": "sha512-wa+2VAhOPpZs1bVij9e5gyVu60ReMi/KuOx4LKjGx2Y3XTNUDJgQ+5f77D49pHtqef/klglf+mibuHs9TrPxdQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"@typescript-eslint/visitor-keys": "5.18.0",
|
||||
"debug": "^4.3.2",
|
||||
"globby": "^11.0.4",
|
||||
"is-glob": "^4.0.3",
|
||||
"semver": "^7.3.5",
|
||||
"tsutils": "^3.21.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.18.0.tgz",
|
||||
"integrity": "sha512-Hf+t+dJsjAKpKSkg3EHvbtEpFFb/1CiOHnvI8bjHgOD4/wAw3gKrA0i94LrbekypiZVanJu3McWJg7rWDMzRTg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"eslint-visitor-keys": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser/node_modules/lru-cache": {
|
||||
"version": "7.8.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.8.1.tgz",
|
||||
"integrity": "sha512-E1v547OCgJvbvevfjgK9sNKIVXO96NnsTsFPBlg4ZxjhsJSODoH9lk8Bm0OxvHNm6Vm5Yqkl/1fErDxhYL8Skg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser/node_modules/semver": {
|
||||
"version": "7.3.6",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.6.tgz",
|
||||
"integrity": "sha512-HZWqcgwLsjaX1HBD31msI/rXktuIhS+lWvdE4kN9z+8IVT4Itc7vqU2WvYsyD6/sjYCt4dEKH/m1M3dwI9CC5w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^7.4.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10.0.0 || ^12.0.0 || ^14.0.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "5.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.13.0.tgz",
|
||||
@ -3370,12 +3579,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils": {
|
||||
"version": "5.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.13.0.tgz",
|
||||
"integrity": "sha512-/nz7qFizaBM1SuqAKb7GLkcNn2buRdDgZraXlkhz+vUGiN1NZ9LzkA595tHHeduAiS2MsHqMNhE2zNzGdw43Yg==",
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.18.0.tgz",
|
||||
"integrity": "sha512-vcn9/6J5D6jtHxpEJrgK8FhaM8r6J1/ZiNu70ZUJN554Y3D9t3iovi6u7JF8l/e7FcBIxeuTEidZDR70UuCIfA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/utils": "5.13.0",
|
||||
"@typescript-eslint/utils": "5.18.0",
|
||||
"debug": "^4.3.2",
|
||||
"tsutils": "^3.21.0"
|
||||
},
|
||||
@ -3395,6 +3604,150 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.18.0.tgz",
|
||||
"integrity": "sha512-C0CZML6NyRDj+ZbMqh9FnPscg2PrzSaVQg3IpTmpe0NURMVBXlghGZgMYqBw07YW73i0MCqSDqv2SbywnCS8jQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"@typescript-eslint/visitor-keys": "5.18.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.18.0.tgz",
|
||||
"integrity": "sha512-bhV1+XjM+9bHMTmXi46p1Led5NP6iqQcsOxgx7fvk6gGiV48c6IynY0apQb7693twJDsXiVzNXTflhplmaiJaw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.18.0.tgz",
|
||||
"integrity": "sha512-wa+2VAhOPpZs1bVij9e5gyVu60ReMi/KuOx4LKjGx2Y3XTNUDJgQ+5f77D49pHtqef/klglf+mibuHs9TrPxdQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"@typescript-eslint/visitor-keys": "5.18.0",
|
||||
"debug": "^4.3.2",
|
||||
"globby": "^11.0.4",
|
||||
"is-glob": "^4.0.3",
|
||||
"semver": "^7.3.5",
|
||||
"tsutils": "^3.21.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.18.0.tgz",
|
||||
"integrity": "sha512-+hFGWUMMri7OFY26TsOlGa+zgjEy1ssEipxpLjtl4wSll8zy85x0GrUSju/FHdKfVorZPYJLkF3I4XPtnCTewA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.9",
|
||||
"@typescript-eslint/scope-manager": "5.18.0",
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"@typescript-eslint/typescript-estree": "5.18.0",
|
||||
"eslint-scope": "^5.1.1",
|
||||
"eslint-utils": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.18.0.tgz",
|
||||
"integrity": "sha512-Hf+t+dJsjAKpKSkg3EHvbtEpFFb/1CiOHnvI8bjHgOD4/wAw3gKrA0i94LrbekypiZVanJu3McWJg7rWDMzRTg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"eslint-visitor-keys": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils/node_modules/eslint-scope": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
|
||||
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"esrecurse": "^4.3.0",
|
||||
"estraverse": "^4.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils/node_modules/estraverse": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
|
||||
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils/node_modules/lru-cache": {
|
||||
"version": "7.8.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.8.1.tgz",
|
||||
"integrity": "sha512-E1v547OCgJvbvevfjgK9sNKIVXO96NnsTsFPBlg4ZxjhsJSODoH9lk8Bm0OxvHNm6Vm5Yqkl/1fErDxhYL8Skg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils/node_modules/semver": {
|
||||
"version": "7.3.6",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.6.tgz",
|
||||
"integrity": "sha512-HZWqcgwLsjaX1HBD31msI/rXktuIhS+lWvdE4kN9z+8IVT4Itc7vqU2WvYsyD6/sjYCt4dEKH/m1M3dwI9CC5w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^7.4.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10.0.0 || ^12.0.0 || ^14.0.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/types": {
|
||||
"version": "5.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.13.0.tgz",
|
||||
@ -5363,12 +5716,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint": {
|
||||
"version": "8.10.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz",
|
||||
"integrity": "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==",
|
||||
"version": "8.13.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.13.0.tgz",
|
||||
"integrity": "sha512-D+Xei61eInqauAyTJ6C0q6x9mx7kTUC1KZ0m0LSEexR0V+e94K12LmWX076ZIsldwfQ2RONdaJe0re0TRGQbRQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint/eslintrc": "^1.2.0",
|
||||
"@eslint/eslintrc": "^1.2.1",
|
||||
"@humanwhocodes/config-array": "^0.9.2",
|
||||
"ajv": "^6.10.0",
|
||||
"chalk": "^4.0.0",
|
||||
@ -5508,15 +5861,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-jest": {
|
||||
"version": "26.1.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.1.1.tgz",
|
||||
"integrity": "sha512-HRKOuPi5ADhza4ZBK5ufyNXy28bXXkib87w+pQqdvBhSTsamndh6sIAKPAUl8y0/n9jSWBdTPslrwtKWqkp8dA==",
|
||||
"version": "26.1.4",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.1.4.tgz",
|
||||
"integrity": "sha512-wgqxujmqc2qpvZqMFWCh6Cniqc8lWpapvXt9j/19DmBDqeDaYhJrSRezYR1SKyemvjx+9e9kny/dgRahraHImA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/utils": "^5.10.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
||||
@ -9186,9 +9539,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/minimist": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/mpd-parser": {
|
||||
@ -13028,16 +13381,16 @@
|
||||
"integrity": "sha512-eMN9QMtiPfiDqdJvE8agBOR53lGJXkz2pOy8lhttsuOBzfmf3gs10Uf0ogX/rjt3U7//ZSqKckRT/br1S2uZ6A=="
|
||||
},
|
||||
"@eslint/eslintrc": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz",
|
||||
"integrity": "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==",
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz",
|
||||
"integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.12.4",
|
||||
"debug": "^4.3.2",
|
||||
"espree": "^9.3.1",
|
||||
"globals": "^13.9.0",
|
||||
"ignore": "^4.0.6",
|
||||
"ignore": "^5.2.0",
|
||||
"import-fresh": "^3.2.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"minimatch": "^3.0.4",
|
||||
@ -13045,19 +13398,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"globals": {
|
||||
"version": "13.12.1",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz",
|
||||
"integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==",
|
||||
"version": "13.13.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz",
|
||||
"integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"type-fest": "^0.20.2"
|
||||
}
|
||||
},
|
||||
"ignore": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
|
||||
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -14173,14 +14520,14 @@
|
||||
"dev": true
|
||||
},
|
||||
"@typescript-eslint/eslint-plugin": {
|
||||
"version": "5.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.13.0.tgz",
|
||||
"integrity": "sha512-vLktb2Uec81fxm/cfz2Hd6QaWOs8qdmVAZXLdOBX6JFJDhf6oDZpMzZ4/LZ6SFM/5DgDcxIMIvy3F+O9yZBuiQ==",
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.18.0.tgz",
|
||||
"integrity": "sha512-tzrmdGMJI/uii9/V6lurMo4/o+dMTKDH82LkNjhJ3adCW22YQydoRs5MwTiqxGF9CSYxPxQ7EYb4jLNlIs+E+A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/scope-manager": "5.13.0",
|
||||
"@typescript-eslint/type-utils": "5.13.0",
|
||||
"@typescript-eslint/utils": "5.13.0",
|
||||
"@typescript-eslint/scope-manager": "5.18.0",
|
||||
"@typescript-eslint/type-utils": "5.18.0",
|
||||
"@typescript-eslint/utils": "5.18.0",
|
||||
"debug": "^4.3.2",
|
||||
"functional-red-black-tree": "^1.0.1",
|
||||
"ignore": "^5.1.8",
|
||||
@ -14189,6 +14536,77 @@
|
||||
"tsutils": "^3.21.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.18.0.tgz",
|
||||
"integrity": "sha512-C0CZML6NyRDj+ZbMqh9FnPscg2PrzSaVQg3IpTmpe0NURMVBXlghGZgMYqBw07YW73i0MCqSDqv2SbywnCS8jQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"@typescript-eslint/visitor-keys": "5.18.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/types": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.18.0.tgz",
|
||||
"integrity": "sha512-bhV1+XjM+9bHMTmXi46p1Led5NP6iqQcsOxgx7fvk6gGiV48c6IynY0apQb7693twJDsXiVzNXTflhplmaiJaw==",
|
||||
"dev": true
|
||||
},
|
||||
"@typescript-eslint/typescript-estree": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.18.0.tgz",
|
||||
"integrity": "sha512-wa+2VAhOPpZs1bVij9e5gyVu60ReMi/KuOx4LKjGx2Y3XTNUDJgQ+5f77D49pHtqef/klglf+mibuHs9TrPxdQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"@typescript-eslint/visitor-keys": "5.18.0",
|
||||
"debug": "^4.3.2",
|
||||
"globby": "^11.0.4",
|
||||
"is-glob": "^4.0.3",
|
||||
"semver": "^7.3.5",
|
||||
"tsutils": "^3.21.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/utils": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.18.0.tgz",
|
||||
"integrity": "sha512-+hFGWUMMri7OFY26TsOlGa+zgjEy1ssEipxpLjtl4wSll8zy85x0GrUSju/FHdKfVorZPYJLkF3I4XPtnCTewA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/json-schema": "^7.0.9",
|
||||
"@typescript-eslint/scope-manager": "5.18.0",
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"@typescript-eslint/typescript-estree": "5.18.0",
|
||||
"eslint-scope": "^5.1.1",
|
||||
"eslint-utils": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/visitor-keys": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.18.0.tgz",
|
||||
"integrity": "sha512-Hf+t+dJsjAKpKSkg3EHvbtEpFFb/1CiOHnvI8bjHgOD4/wAw3gKrA0i94LrbekypiZVanJu3McWJg7rWDMzRTg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"eslint-visitor-keys": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"eslint-scope": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
|
||||
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esrecurse": "^4.3.0",
|
||||
"estraverse": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"estraverse": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
|
||||
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
|
||||
"dev": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.3.5",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
||||
@ -14210,15 +14628,73 @@
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/parser": {
|
||||
"version": "5.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.13.0.tgz",
|
||||
"integrity": "sha512-GdrU4GvBE29tm2RqWOM0P5QfCtgCyN4hXICj/X9ibKED16136l9ZpoJvCL5pSKtmJzA+NRDzQ312wWMejCVVfg==",
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.18.0.tgz",
|
||||
"integrity": "sha512-+08nYfurBzSSPndngnHvFw/fniWYJ5ymOrn/63oMIbgomVQOvIDhBoJmYZ9lwQOCnQV9xHGvf88ze3jFGUYooQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/scope-manager": "5.13.0",
|
||||
"@typescript-eslint/types": "5.13.0",
|
||||
"@typescript-eslint/typescript-estree": "5.13.0",
|
||||
"@typescript-eslint/scope-manager": "5.18.0",
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"@typescript-eslint/typescript-estree": "5.18.0",
|
||||
"debug": "^4.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.18.0.tgz",
|
||||
"integrity": "sha512-C0CZML6NyRDj+ZbMqh9FnPscg2PrzSaVQg3IpTmpe0NURMVBXlghGZgMYqBw07YW73i0MCqSDqv2SbywnCS8jQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"@typescript-eslint/visitor-keys": "5.18.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/types": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.18.0.tgz",
|
||||
"integrity": "sha512-bhV1+XjM+9bHMTmXi46p1Led5NP6iqQcsOxgx7fvk6gGiV48c6IynY0apQb7693twJDsXiVzNXTflhplmaiJaw==",
|
||||
"dev": true
|
||||
},
|
||||
"@typescript-eslint/typescript-estree": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.18.0.tgz",
|
||||
"integrity": "sha512-wa+2VAhOPpZs1bVij9e5gyVu60ReMi/KuOx4LKjGx2Y3XTNUDJgQ+5f77D49pHtqef/klglf+mibuHs9TrPxdQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"@typescript-eslint/visitor-keys": "5.18.0",
|
||||
"debug": "^4.3.2",
|
||||
"globby": "^11.0.4",
|
||||
"is-glob": "^4.0.3",
|
||||
"semver": "^7.3.5",
|
||||
"tsutils": "^3.21.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/visitor-keys": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.18.0.tgz",
|
||||
"integrity": "sha512-Hf+t+dJsjAKpKSkg3EHvbtEpFFb/1CiOHnvI8bjHgOD4/wAw3gKrA0i94LrbekypiZVanJu3McWJg7rWDMzRTg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"eslint-visitor-keys": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "7.8.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.8.1.tgz",
|
||||
"integrity": "sha512-E1v547OCgJvbvevfjgK9sNKIVXO96NnsTsFPBlg4ZxjhsJSODoH9lk8Bm0OxvHNm6Vm5Yqkl/1fErDxhYL8Skg==",
|
||||
"dev": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.3.6",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.6.tgz",
|
||||
"integrity": "sha512-HZWqcgwLsjaX1HBD31msI/rXktuIhS+lWvdE4kN9z+8IVT4Itc7vqU2WvYsyD6/sjYCt4dEKH/m1M3dwI9CC5w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lru-cache": "^7.4.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/scope-manager": {
|
||||
@ -14232,14 +14708,102 @@
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/type-utils": {
|
||||
"version": "5.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.13.0.tgz",
|
||||
"integrity": "sha512-/nz7qFizaBM1SuqAKb7GLkcNn2buRdDgZraXlkhz+vUGiN1NZ9LzkA595tHHeduAiS2MsHqMNhE2zNzGdw43Yg==",
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.18.0.tgz",
|
||||
"integrity": "sha512-vcn9/6J5D6jtHxpEJrgK8FhaM8r6J1/ZiNu70ZUJN554Y3D9t3iovi6u7JF8l/e7FcBIxeuTEidZDR70UuCIfA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/utils": "5.13.0",
|
||||
"@typescript-eslint/utils": "5.18.0",
|
||||
"debug": "^4.3.2",
|
||||
"tsutils": "^3.21.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.18.0.tgz",
|
||||
"integrity": "sha512-C0CZML6NyRDj+ZbMqh9FnPscg2PrzSaVQg3IpTmpe0NURMVBXlghGZgMYqBw07YW73i0MCqSDqv2SbywnCS8jQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"@typescript-eslint/visitor-keys": "5.18.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/types": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.18.0.tgz",
|
||||
"integrity": "sha512-bhV1+XjM+9bHMTmXi46p1Led5NP6iqQcsOxgx7fvk6gGiV48c6IynY0apQb7693twJDsXiVzNXTflhplmaiJaw==",
|
||||
"dev": true
|
||||
},
|
||||
"@typescript-eslint/typescript-estree": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.18.0.tgz",
|
||||
"integrity": "sha512-wa+2VAhOPpZs1bVij9e5gyVu60ReMi/KuOx4LKjGx2Y3XTNUDJgQ+5f77D49pHtqef/klglf+mibuHs9TrPxdQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"@typescript-eslint/visitor-keys": "5.18.0",
|
||||
"debug": "^4.3.2",
|
||||
"globby": "^11.0.4",
|
||||
"is-glob": "^4.0.3",
|
||||
"semver": "^7.3.5",
|
||||
"tsutils": "^3.21.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/utils": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.18.0.tgz",
|
||||
"integrity": "sha512-+hFGWUMMri7OFY26TsOlGa+zgjEy1ssEipxpLjtl4wSll8zy85x0GrUSju/FHdKfVorZPYJLkF3I4XPtnCTewA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/json-schema": "^7.0.9",
|
||||
"@typescript-eslint/scope-manager": "5.18.0",
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"@typescript-eslint/typescript-estree": "5.18.0",
|
||||
"eslint-scope": "^5.1.1",
|
||||
"eslint-utils": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/visitor-keys": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.18.0.tgz",
|
||||
"integrity": "sha512-Hf+t+dJsjAKpKSkg3EHvbtEpFFb/1CiOHnvI8bjHgOD4/wAw3gKrA0i94LrbekypiZVanJu3McWJg7rWDMzRTg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "5.18.0",
|
||||
"eslint-visitor-keys": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"eslint-scope": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
|
||||
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esrecurse": "^4.3.0",
|
||||
"estraverse": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"estraverse": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
|
||||
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
|
||||
"dev": true
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "7.8.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.8.1.tgz",
|
||||
"integrity": "sha512-E1v547OCgJvbvevfjgK9sNKIVXO96NnsTsFPBlg4ZxjhsJSODoH9lk8Bm0OxvHNm6Vm5Yqkl/1fErDxhYL8Skg==",
|
||||
"dev": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.3.6",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.6.tgz",
|
||||
"integrity": "sha512-HZWqcgwLsjaX1HBD31msI/rXktuIhS+lWvdE4kN9z+8IVT4Itc7vqU2WvYsyD6/sjYCt4dEKH/m1M3dwI9CC5w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lru-cache": "^7.4.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/types": {
|
||||
@ -15612,12 +16176,12 @@
|
||||
}
|
||||
},
|
||||
"eslint": {
|
||||
"version": "8.10.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz",
|
||||
"integrity": "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==",
|
||||
"version": "8.13.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.13.0.tgz",
|
||||
"integrity": "sha512-D+Xei61eInqauAyTJ6C0q6x9mx7kTUC1KZ0m0LSEexR0V+e94K12LmWX076ZIsldwfQ2RONdaJe0re0TRGQbRQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@eslint/eslintrc": "^1.2.0",
|
||||
"@eslint/eslintrc": "^1.2.1",
|
||||
"@humanwhocodes/config-array": "^0.9.2",
|
||||
"ajv": "^6.10.0",
|
||||
"chalk": "^4.0.0",
|
||||
@ -15783,9 +16347,9 @@
|
||||
}
|
||||
},
|
||||
"eslint-plugin-jest": {
|
||||
"version": "26.1.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.1.1.tgz",
|
||||
"integrity": "sha512-HRKOuPi5ADhza4ZBK5ufyNXy28bXXkib87w+pQqdvBhSTsamndh6sIAKPAUl8y0/n9jSWBdTPslrwtKWqkp8dA==",
|
||||
"version": "26.1.4",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.1.4.tgz",
|
||||
"integrity": "sha512-wgqxujmqc2qpvZqMFWCh6Cniqc8lWpapvXt9j/19DmBDqeDaYhJrSRezYR1SKyemvjx+9e9kny/dgRahraHImA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/utils": "^5.10.0"
|
||||
@ -18409,9 +18973,9 @@
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"mpd-parser": {
|
||||
|
||||
@ -32,13 +32,13 @@
|
||||
"@testing-library/preact": "^2.0.1",
|
||||
"@testing-library/preact-hooks": "^1.1.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.13.0",
|
||||
"@typescript-eslint/parser": "^5.13.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.18.0",
|
||||
"@typescript-eslint/parser": "^5.18.0",
|
||||
"autoprefixer": "^10.4.2",
|
||||
"eslint": "^8.10.0",
|
||||
"eslint": "^8.13.0",
|
||||
"eslint-config-preact": "^1.3.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-jest": "^26.1.1",
|
||||
"eslint-plugin-jest": "^26.1.4",
|
||||
"jest": "^27.5.1",
|
||||
"msw": "^0.38.2",
|
||||
"postcss": "^8.4.7",
|
||||
|
||||
@ -6,7 +6,7 @@ import AutoAwesomeIcon from './icons/AutoAwesome';
|
||||
import LightModeIcon from './icons/LightMode';
|
||||
import DarkModeIcon from './icons/DarkMode';
|
||||
import FrigateRestartIcon from './icons/FrigateRestart';
|
||||
import Dialog from './components/Dialog';
|
||||
import Prompt from './components/Prompt';
|
||||
import { useDarkMode } from './context';
|
||||
import { useCallback, useRef, useState } from 'preact/hooks';
|
||||
import { useRestart } from './api/mqtt';
|
||||
@ -65,7 +65,7 @@ export default function AppBar() {
|
||||
</Menu>
|
||||
) : null}
|
||||
{showDialog ? (
|
||||
<Dialog
|
||||
<Prompt
|
||||
onDismiss={handleDismissRestartDialog}
|
||||
title="Restart Frigate"
|
||||
text="Are you sure?"
|
||||
@ -76,7 +76,7 @@ export default function AppBar() {
|
||||
/>
|
||||
) : null}
|
||||
{showDialogWait ? (
|
||||
<Dialog
|
||||
<Prompt
|
||||
title="Restart in progress"
|
||||
text="Please wait a few seconds for the restart to complete before reloading the page."
|
||||
/>
|
||||
|
||||
23
web/src/icons/UploadPlus.jsx
Normal file
23
web/src/icons/UploadPlus.jsx
Normal file
@ -0,0 +1,23 @@
|
||||
import { h } from 'preact';
|
||||
import { memo } from 'preact/compat';
|
||||
|
||||
export function UploadPlus({ className = 'h-6 w-6', stroke = 'currentColor', onClick = () => {} }) {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={className}
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke={stroke}
|
||||
onClick={onClick}
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(UploadPlus);
|
||||
@ -10,6 +10,7 @@ import { useState, useRef, useCallback, useMemo } from 'preact/hooks';
|
||||
import VideoPlayer from '../components/VideoPlayer';
|
||||
import { StarRecording } from '../icons/StarRecording';
|
||||
import { Snapshot } from '../icons/Snapshot';
|
||||
import { UploadPlus } from '../icons/UploadPlus';
|
||||
import { Clip } from '../icons/Clip';
|
||||
import { Zone } from '../icons/Zone';
|
||||
import { Camera } from '../icons/Camera';
|
||||
@ -18,6 +19,8 @@ import { Download } from '../icons/Download';
|
||||
import Menu, { MenuItem } from '../components/Menu';
|
||||
import CalendarIcon from '../icons/Calendar';
|
||||
import Calendar from '../components/Calendar';
|
||||
import Button from '../components/Button';
|
||||
import Dialog from '../components/Dialog';
|
||||
|
||||
const API_LIMIT = 25;
|
||||
|
||||
@ -43,10 +46,12 @@ export default function Events({ path, ...props }) {
|
||||
zone: props.zone ?? 'all',
|
||||
});
|
||||
const [state, setState] = useState({
|
||||
showDownloadMenu: null,
|
||||
showDatePicker: null,
|
||||
showCalendar: null,
|
||||
showDownloadMenu: false,
|
||||
showDatePicker: false,
|
||||
showCalendar: false,
|
||||
showPlusConfig: false,
|
||||
});
|
||||
const [uploading, setUploading] = useState([]);
|
||||
const [viewEvent, setViewEvent] = useState();
|
||||
const [downloadEvent, setDownloadEvent] = useState({ id: null, has_clip: false, has_snapshot: false });
|
||||
|
||||
@ -167,6 +172,38 @@ export default function Events({ path, ...props }) {
|
||||
[size, setSize, isValidating, isDone]
|
||||
);
|
||||
|
||||
const onSendToPlus = async (id, e) => {
|
||||
if (e) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
if (!config.plus.enabled) {
|
||||
setState({ ...state, showDownloadMenu: false, showPlusConfig: true });
|
||||
return;
|
||||
}
|
||||
|
||||
setUploading((prev) => [...prev, id]);
|
||||
|
||||
const response = await axios.post(`events/${id}/plus`);
|
||||
|
||||
if (response.status === 200) {
|
||||
mutate(
|
||||
(pages) =>
|
||||
pages.map((page) =>
|
||||
page.map((event) => {
|
||||
if (event.id === id) {
|
||||
return { ...event, plus_id: response.data.plus_id };
|
||||
}
|
||||
return event;
|
||||
})
|
||||
),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
setUploading((prev) => prev.filter((i) => i !== id));
|
||||
};
|
||||
|
||||
if (!config) {
|
||||
return <ActivityIndicator />;
|
||||
}
|
||||
@ -238,6 +275,14 @@ export default function Events({ path, ...props }) {
|
||||
download
|
||||
/>
|
||||
)}
|
||||
{downloadEvent.has_snapshot && !downloadEvent.plus_id && (
|
||||
<MenuItem
|
||||
icon={UploadPlus}
|
||||
label="Send to Frigate+"
|
||||
value="plus"
|
||||
onSelect={() => onSendToPlus(downloadEvent.id)}
|
||||
/>
|
||||
)}
|
||||
</Menu>
|
||||
)}
|
||||
{state.showDatePicker && (
|
||||
@ -282,6 +327,27 @@ export default function Events({ path, ...props }) {
|
||||
/>
|
||||
</Menu>
|
||||
)}
|
||||
{state.showPlusConfig && (
|
||||
<Dialog>
|
||||
<div className="p-4">
|
||||
<Heading size="lg">Setup a Frigate+ Account</Heading>
|
||||
<p className="mb-2">In order to submit images to Frigate+, you first need to setup an account.</p>
|
||||
<a
|
||||
className="text-blue-500 hover:underline"
|
||||
href="https://plus.frigate.video"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
https://plus.frigate.video
|
||||
</a>
|
||||
</div>
|
||||
<div className="p-2 flex justify-start flex-row-reverse space-x-2">
|
||||
<Button className="ml-2" onClick={() => setState({ ...state, showPlusConfig: false })} type="text">
|
||||
Close
|
||||
</Button>
|
||||
</div>
|
||||
</Dialog>
|
||||
)}
|
||||
<div className="space-y-2">
|
||||
{eventPages ? (
|
||||
eventPages.map((page, i) => {
|
||||
@ -315,7 +381,8 @@ export default function Events({ path, ...props }) {
|
||||
<div className="m-2 flex grow">
|
||||
<div className="flex flex-col grow">
|
||||
<div className="capitalize text-lg font-bold">
|
||||
{event.sub_label ? `${event.label}: ${event.sub_label}` : event.label} ({(event.top_score * 100).toFixed(0)}%)
|
||||
{event.sub_label ? `${event.label}: ${event.sub_label}` : event.label} (
|
||||
{(event.top_score * 100).toFixed(0)}%)
|
||||
</div>
|
||||
<div className="text-sm">
|
||||
{new Date(event.start_time * 1000).toLocaleDateString()}{' '}
|
||||
@ -330,6 +397,19 @@ export default function Events({ path, ...props }) {
|
||||
{event.zones.join(',')}
|
||||
</div>
|
||||
</div>
|
||||
<div class="hidden sm:flex flex-col justify-end mr-2">
|
||||
{event.plus_id ? (
|
||||
<div className="uppercase text-xs">Sent to Frigate+</div>
|
||||
) : (
|
||||
<Button
|
||||
color="gray"
|
||||
disabled={uploading.includes(event.id)}
|
||||
onClick={(e) => onSendToPlus(event.id, e)}
|
||||
>
|
||||
{uploading.includes(event.id) ? 'Uploading...' : 'Send to Frigate+'}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<Delete className="cursor-pointer" stroke="#f87171" onClick={(e) => onDelete(e, event.id)} />
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user