From ab50d0b00623297f6d2e32b9add16925b670d85e Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Mon, 29 May 2023 12:31:17 +0200 Subject: [PATCH 1/8] Add isort and ruff linter (#6575) * Add isort and ruff linter Both linters are pretty common among modern python code bases. The isort tool provides stable sorting and grouping, as well as pruning of unused imports. Ruff is a modern linter, that is very fast due to being written in rust. It can detect many common issues in a python codebase. Removes the pylint dev requirement, since ruff replaces it. * treewide: fix issues detected by ruff * treewide: fix bare except clauses * .devcontainer: Set up isort * treewide: optimize imports * treewide: apply black * treewide: make regex patterns raw strings This is necessary for escape sequences to be properly recognized. --- .devcontainer/devcontainer.json | 6 +- .github/workflows/pull_request.yml | 14 ++-- benchmark.py | 12 ++-- .../rootfs/usr/local/go2rtc/create_config.py | 7 +- frigate/__main__.py | 9 +-- frigate/app.py | 24 +++---- frigate/comms/dispatcher.py | 15 ++-- frigate/comms/mqtt.py | 12 ++-- frigate/comms/ws.py | 8 +-- frigate/config.py | 44 +++++------- frigate/const.py | 6 +- frigate/detectors/__init__.py | 10 +-- frigate/detectors/detection_api.py | 1 - frigate/detectors/detector_config.py | 12 ++-- frigate/detectors/detector_types.py | 8 +-- frigate/detectors/plugins/cpu_tfl.py | 5 +- frigate/detectors/plugins/deepstack.py | 14 ++-- frigate/detectors/plugins/edgetpu_tfl.py | 5 +- frigate/detectors/plugins/openvino.py | 8 +-- frigate/detectors/plugins/tensorrt.py | 11 +-- frigate/events/cleanup.py | 42 ++++++----- frigate/events/external.py | 6 +- frigate/events/maintainer.py | 16 ++--- frigate/ffmpeg_presets.py | 4 +- frigate/http.py | 70 +++++++++---------- frigate/log.py | 23 +++--- frigate/models.py | 7 +- frigate/motion.py | 1 + frigate/object_detection.py | 3 +- frigate/object_processing.py | 18 ++--- frigate/objects.py | 9 +-- frigate/output.py | 15 ++-- frigate/plus.py | 10 +-- frigate/ptz.py | 5 +- frigate/record/cleanup.py | 8 +-- frigate/record/maintainer.py | 14 ++-- frigate/record/record.py | 3 +- frigate/stats.py | 31 ++++---- frigate/storage.py | 6 +- frigate/test/test_config.py | 12 ++-- frigate/test/test_copy_yuv_to_position.py | 6 +- frigate/test/test_ffmpeg_presets.py | 1 + frigate/test/test_gpu_stats.py | 2 +- frigate/test/test_http.py | 15 ++-- frigate/test/test_object_detector.py | 4 +- frigate/test/test_reduce_boxes.py | 2 +- frigate/test/test_storage.py | 6 +- frigate/test/test_yuv_region_2_rgb.py | 6 +- frigate/timeline.py | 8 +-- frigate/types.py | 4 +- frigate/util.py | 30 ++++---- frigate/video.py | 20 +++--- frigate/watchdog.py | 6 +- migrations/001_create_events_table.py | 7 -- migrations/002_add_clip_snapshot.py | 8 +-- migrations/003_create_recordings_table.py | 2 - migrations/004_add_bbox_region_area.py | 10 +-- migrations/005_make_end_time_nullable.py | 9 +-- migrations/006_add_motion_active_objects.py | 9 +-- migrations/007_add_retain_indefinitely.py | 9 +-- migrations/008_add_sub_label.py | 9 +-- migrations/009_add_object_filter_ratio.py | 1 + migrations/010_add_plus_image_id.py | 9 +-- migrations/012_add_segment_size.py | 9 +-- migrations/013_create_timeline_table.py | 21 +++--- migrations/014_event_updates_for_fp.py | 9 +-- migrations/015_event_refactor.py | 10 +-- migrations/016_sublabel_increase.py | 3 +- process_clip.py | 28 ++++---- pyproject.toml | 5 ++ requirements-dev.txt | 3 +- 71 files changed, 346 insertions(+), 459 deletions(-) create mode 100644 pyproject.toml diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 3e654335f..60065a965 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -52,7 +52,8 @@ "mikestead.dotenv", "csstools.postcss", "blanu.vscode-styled-jsx", - "bradlc.vscode-tailwindcss" + "bradlc.vscode-tailwindcss", + "ms-python.isort" ], "settings": { "remote.autoForwardPorts": false, @@ -68,6 +69,9 @@ "python.testing.unittestArgs": ["-v", "-s", "./frigate/test"], "files.trimTrailingWhitespace": true, "eslint.workingDirectories": ["./web"], + "isort.args": [ + "--settings-path=./pyproject.toml" + ], "[python]": { "editor.defaultFormatter": "ms-python.black-formatter", "editor.formatOnSave": true diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 1c1d2cd76..7e38c3b99 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -70,11 +70,17 @@ jobs: python-version: ${{ env.DEFAULT_PYTHON }} - name: Install requirements run: | - pip install pip - pip install -r requirements-dev.txt - - name: Lint + python3 -m pip install -U pip + python3 -m pip install -r requirements-dev.txt + - name: Check black run: | - python3 -m black frigate --check + black --check --diff frigate migrations docker *.py + - name: Check isort + run: | + isort --check --diff frigate migrations docker *.py + - name: Check ruff + run: | + ruff check frigate migrations docker *.py python_tests: runs-on: ubuntu-latest diff --git a/benchmark.py b/benchmark.py index 3d0cacd87..8ba22d093 100755 --- a/benchmark.py +++ b/benchmark.py @@ -1,11 +1,11 @@ -import os -from statistics import mean -import multiprocessing as mp -import numpy as np import datetime +import multiprocessing as mp +from statistics import mean + +import numpy as np + from frigate.config import DetectorTypeEnum from frigate.object_detection import ( - LocalObjectDetector, ObjectDetectProcess, RemoteObjectDetector, load_labels, @@ -53,7 +53,7 @@ def start(id, num_detections, detection_queue, event): frame_times = [] for x in range(0, num_detections): start_frame = datetime.datetime.now().timestamp() - detections = object_detector.detect(my_frame) + object_detector.detect(my_frame) frame_times.append(datetime.datetime.now().timestamp() - start_frame) duration = datetime.datetime.now().timestamp() - start diff --git a/docker/rootfs/usr/local/go2rtc/create_config.py b/docker/rootfs/usr/local/go2rtc/create_config.py index d201eb381..1397adee8 100644 --- a/docker/rootfs/usr/local/go2rtc/create_config.py +++ b/docker/rootfs/usr/local/go2rtc/create_config.py @@ -3,11 +3,14 @@ import json import os import sys + import yaml sys.path.insert(0, "/opt/frigate") -from frigate.const import BIRDSEYE_PIPE, BTBN_PATH -from frigate.ffmpeg_presets import parse_preset_hardware_acceleration_encode +from frigate.const import BIRDSEYE_PIPE, BTBN_PATH # noqa: E402 +from frigate.ffmpeg_presets import ( # noqa: E402 + parse_preset_hardware_acceleration_encode, +) sys.path.remove("/opt/frigate") diff --git a/frigate/__main__.py b/frigate/__main__.py index b36881151..844206908 100644 --- a/frigate/__main__.py +++ b/frigate/__main__.py @@ -1,13 +1,14 @@ import faulthandler -from flask import cli - -faulthandler.enable() import threading -threading.current_thread().name = "frigate" +from flask import cli from frigate.app import FrigateApp +faulthandler.enable() + +threading.current_thread().name = "frigate" + cli.show_server_banner = lambda *x: None if __name__ == "__main__": diff --git a/frigate/app.py b/frigate/app.py index 5e934cc4b..bcbd3ed2d 100644 --- a/frigate/app.py +++ b/frigate/app.py @@ -1,16 +1,16 @@ import logging import multiprocessing as mp -from multiprocessing.queues import Queue -from multiprocessing.synchronize import Event as MpEvent import os import shutil import signal import sys -from typing import Optional -from types import FrameType -import psutil - import traceback +from multiprocessing.queues import Queue +from multiprocessing.synchronize import Event as MpEvent +from types import FrameType +from typing import Optional + +import psutil from peewee_migrate import Router from playhouse.sqlite_ext import SqliteExtDatabase from playhouse.sqliteq import SqliteQueueDatabase @@ -27,13 +27,13 @@ from frigate.const import ( MODEL_CACHE_DIR, RECORD_DIR, ) -from frigate.object_detection import ObjectDetectProcess from frigate.events.cleanup import EventCleanup from frigate.events.external import ExternalEventProcessor from frigate.events.maintainer import EventProcessor from frigate.http import create_app from frigate.log import log_process, root_configurer from frigate.models import Event, Recordings, Timeline +from frigate.object_detection import ObjectDetectProcess from frigate.object_processing import TrackedObjectProcessor from frigate.output import output_frames from frigate.plus import PlusApi @@ -42,10 +42,10 @@ from frigate.record.record import manage_recordings from frigate.stats import StatsEmitter, stats_init from frigate.storage import StorageMaintainer from frigate.timeline import TimelineProcessor +from frigate.types import CameraMetricsTypes, RecordMetricsTypes from frigate.version import VERSION from frigate.video import capture_camera, track_camera from frigate.watchdog import FrigateWatchdog -from frigate.types import CameraMetricsTypes, RecordMetricsTypes logger = logging.getLogger(__name__) @@ -133,10 +133,10 @@ class FrigateApp: for log, level in self.config.logger.logs.items(): logging.getLogger(log).setLevel(level.value.upper()) - if not "werkzeug" in self.config.logger.logs: + if "werkzeug" not in self.config.logger.logs: logging.getLogger("werkzeug").setLevel("ERROR") - if not "ws4py" in self.config.logger.logs: + if "ws4py" not in self.config.logger.logs: logging.getLogger("ws4py").setLevel("ERROR") def init_queues(self) -> None: @@ -294,7 +294,7 @@ class FrigateApp: def start_video_output_processor(self) -> None: output_processor = mp.Process( target=output_frames, - name=f"output_processor", + name="output_processor", args=( self.config, self.video_output_queue, @@ -467,7 +467,7 @@ class FrigateApp: self.stop() def stop(self) -> None: - logger.info(f"Stopping...") + logger.info("Stopping...") self.stop_event.set() for detector in self.detectors.values(): diff --git a/frigate/comms/dispatcher.py b/frigate/comms/dispatcher.py index d7fd2b4d4..b7e9e8858 100644 --- a/frigate/comms/dispatcher.py +++ b/frigate/comms/dispatcher.py @@ -1,17 +1,14 @@ """Handle communication between Frigate and other applications.""" import logging - +from abc import ABC, abstractmethod from typing import Any, Callable -from abc import ABC, abstractmethod - from frigate.config import FrigateConfig -from frigate.ptz import OnvifController, OnvifCommandEnum +from frigate.ptz import OnvifCommandEnum, OnvifController from frigate.types import CameraMetricsTypes, RecordMetricsTypes from frigate.util import restart_frigate - logger = logging.getLogger(__name__) @@ -72,7 +69,7 @@ class Dispatcher: camera_name = topic.split("/")[-3] command = topic.split("/")[-2] self._camera_settings_handlers[command](camera_name, payload) - except IndexError as e: + except IndexError: logger.error(f"Received invalid set command: {topic}") return elif topic.endswith("ptz"): @@ -80,7 +77,7 @@ class Dispatcher: # example /cam_name/ptz payload=MOVE_UP|MOVE_DOWN|STOP... camera_name = topic.split("/")[-2] self._on_ptz_command(camera_name, payload) - except IndexError as e: + except IndexError: logger.error(f"Received invalid ptz command: {topic}") return elif topic == "restart": @@ -128,7 +125,7 @@ class Dispatcher: elif payload == "OFF": if self.camera_metrics[camera_name]["detection_enabled"].value: logger.error( - f"Turning off motion is not allowed when detection is enabled." + "Turning off motion is not allowed when detection is enabled." ) return @@ -196,7 +193,7 @@ class Dispatcher: if payload == "ON": if not self.config.cameras[camera_name].record.enabled_in_config: logger.error( - f"Recordings must be enabled in the config to be turned on via MQTT." + "Recordings must be enabled in the config to be turned on via MQTT." ) return diff --git a/frigate/comms/mqtt.py b/frigate/comms/mqtt.py index 37fdd44ae..07799f9da 100644 --- a/frigate/comms/mqtt.py +++ b/frigate/comms/mqtt.py @@ -1,6 +1,5 @@ import logging import threading - from typing import Any, Callable import paho.mqtt.client as mqtt @@ -8,7 +7,6 @@ import paho.mqtt.client as mqtt from frigate.comms.dispatcher import Communicator from frigate.config import FrigateConfig - logger = logging.getLogger(__name__) @@ -177,10 +175,10 @@ class MqttClient(Communicator): # type: ignore[misc] f"{self.mqtt_config.topic_prefix}/restart", self.on_mqtt_command ) - if not self.mqtt_config.tls_ca_certs is None: + if self.mqtt_config.tls_ca_certs is not None: if ( - not self.mqtt_config.tls_client_cert is None - and not self.mqtt_config.tls_client_key is None + self.mqtt_config.tls_client_cert is not None + and self.mqtt_config.tls_client_key is not None ): self.client.tls_set( self.mqtt_config.tls_ca_certs, @@ -189,9 +187,9 @@ class MqttClient(Communicator): # type: ignore[misc] ) else: self.client.tls_set(self.mqtt_config.tls_ca_certs) - if not self.mqtt_config.tls_insecure is None: + if self.mqtt_config.tls_insecure is not None: self.client.tls_insecure_set(self.mqtt_config.tls_insecure) - if not self.mqtt_config.user is None: + if self.mqtt_config.user is not None: self.client.username_pw_set( self.mqtt_config.user, password=self.mqtt_config.password ) diff --git a/frigate/comms/ws.py b/frigate/comms/ws.py index c9cc3988a..3c1d2eb12 100644 --- a/frigate/comms/ws.py +++ b/frigate/comms/ws.py @@ -3,10 +3,9 @@ import json import logging import threading - from typing import Callable - from wsgiref.simple_server import make_server + from ws4py.server.wsgirefserver import ( WebSocketWSGIHandler, WebSocketWSGIRequestHandler, @@ -18,7 +17,6 @@ from ws4py.websocket import WebSocket from frigate.comms.dispatcher import Communicator from frigate.config import FrigateConfig - logger = logging.getLogger(__name__) @@ -45,7 +43,7 @@ class WebSocketClient(Communicator): # type: ignore[misc] "topic": json_message.get("topic"), "payload": json_message.get("payload"), } - except Exception as e: + except Exception: logger.warning( f"Unable to parse websocket message as valid json: {message.data.decode('utf-8')}" ) @@ -82,7 +80,7 @@ class WebSocketClient(Communicator): # type: ignore[misc] "payload": payload, } ) - except Exception as e: + except Exception: # if the payload can't be decoded don't relay to clients logger.debug(f"payload for {topic} wasn't text. Skipping...") return diff --git a/frigate/config.py b/frigate/config.py index 56e4dc496..5c2f27b5a 100644 --- a/frigate/config.py +++ b/frigate/config.py @@ -8,26 +8,14 @@ from typing import Dict, List, Optional, Tuple, Union import matplotlib.pyplot as plt import numpy as np -import yaml -from pydantic import BaseModel, Extra, Field, validator, parse_obj_as +from pydantic import BaseModel, Extra, Field, parse_obj_as, validator from pydantic.fields import PrivateAttr -from frigate.const import ( - CACHE_DIR, - DEFAULT_DB_PATH, - REGEX_CAMERA_NAME, - YAML_EXT, -) +from frigate.const import CACHE_DIR, DEFAULT_DB_PATH, REGEX_CAMERA_NAME, YAML_EXT +from frigate.detectors import DetectorConfig, ModelConfig +from frigate.detectors.detector_config import InputTensorEnum # noqa: F401 +from frigate.detectors.detector_config import PixelFormatEnum # noqa: F401 from frigate.detectors.detector_config import BaseDetectorConfig -from frigate.plus import PlusApi -from frigate.util import ( - create_mask, - deep_merge, - get_ffmpeg_arg_list, - escape_special_characters, - load_config_with_no_duplicates, - load_labels, -) from frigate.ffmpeg_presets import ( parse_preset_hardware_acceleration_decode, parse_preset_hardware_acceleration_scale, @@ -35,14 +23,14 @@ from frigate.ffmpeg_presets import ( parse_preset_output_record, parse_preset_output_rtmp, ) -from frigate.detectors import ( - PixelFormatEnum, - InputTensorEnum, - ModelConfig, - DetectorConfig, +from frigate.plus import PlusApi +from frigate.util import ( + create_mask, + deep_merge, + escape_special_characters, + get_ffmpeg_arg_list, + load_config_with_no_duplicates, ) -from frigate.version import VERSION - logger = logging.getLogger(__name__) @@ -487,7 +475,7 @@ class CameraFfmpegConfig(FfmpegConfig): if len(roles) > len(roles_set): raise ValueError("Each input role may only be used once.") - if not "detect" in roles: + if "detect" not in roles: raise ValueError("The detect role is required.") return v @@ -776,12 +764,12 @@ def verify_config_roles(camera_config: CameraConfig) -> None: set([r for i in camera_config.ffmpeg.inputs for r in i.roles]) ) - if camera_config.record.enabled and not "record" in assigned_roles: + if camera_config.record.enabled and "record" not in assigned_roles: raise ValueError( f"Camera {camera_config.name} has record enabled, but record is not assigned to an input." ) - if camera_config.rtmp.enabled and not "rtmp" in assigned_roles: + if camera_config.rtmp.enabled and "rtmp" not in assigned_roles: raise ValueError( f"Camera {camera_config.name} has rtmp enabled, but rtmp is not assigned to an input." ) @@ -1062,7 +1050,7 @@ class FrigateConfig(FrigateBaseModel): config.model.dict(exclude_unset=True), ) - if not "path" in merged_model: + if "path" not in merged_model: if detector_config.type == "cpu": merged_model["path"] = "/cpu_model.tflite" elif detector_config.type == "edgetpu": diff --git a/frigate/const.py b/frigate/const.py index cfcdc2a53..df5098853 100644 --- a/frigate/const.py +++ b/frigate/const.py @@ -13,9 +13,9 @@ BTBN_PATH = "/usr/lib/btbn-ffmpeg" # Regex Consts -REGEX_CAMERA_NAME = "^[a-zA-Z0-9_-]+$" -REGEX_RTSP_CAMERA_USER_PASS = ":\/\/[a-zA-Z0-9_-]+:[\S]+@" -REGEX_HTTP_CAMERA_USER_PASS = "user=[a-zA-Z0-9_-]+&password=[\S]+" +REGEX_CAMERA_NAME = r"^[a-zA-Z0-9_-]+$" +REGEX_RTSP_CAMERA_USER_PASS = r":\/\/[a-zA-Z0-9_-]+:[\S]+@" +REGEX_HTTP_CAMERA_USER_PASS = r"user=[a-zA-Z0-9_-]+&password=[\S]+" # Known Driver Names diff --git a/frigate/detectors/__init__.py b/frigate/detectors/__init__.py index 7cbd82f08..7465ed7c0 100644 --- a/frigate/detectors/__init__.py +++ b/frigate/detectors/__init__.py @@ -1,13 +1,7 @@ import logging -from .detection_api import DetectionApi -from .detector_config import ( - PixelFormatEnum, - InputTensorEnum, - ModelConfig, -) -from .detector_types import DetectorTypeEnum, api_types, DetectorConfig - +from .detector_config import InputTensorEnum, ModelConfig, PixelFormatEnum # noqa: F401 +from .detector_types import DetectorConfig, DetectorTypeEnum, api_types # noqa: F401 logger = logging.getLogger(__name__) diff --git a/frigate/detectors/detection_api.py b/frigate/detectors/detection_api.py index 60a90b1b5..f829da27a 100644 --- a/frigate/detectors/detection_api.py +++ b/frigate/detectors/detection_api.py @@ -1,7 +1,6 @@ import logging from abc import ABC, abstractmethod - logger = logging.getLogger(__name__) diff --git a/frigate/detectors/detector_config.py b/frigate/detectors/detector_config.py index e949065b4..f65826a57 100644 --- a/frigate/detectors/detector_config.py +++ b/frigate/detectors/detector_config.py @@ -1,20 +1,18 @@ import hashlib import json import logging -from enum import Enum import os -from typing import Dict, List, Optional, Tuple, Union, Literal +from enum import Enum +from typing import Dict, Optional, Tuple - -import requests import matplotlib.pyplot as plt -from pydantic import BaseModel, Extra, Field, validator +import requests +from pydantic import BaseModel, Extra, Field from pydantic.fields import PrivateAttr + from frigate.plus import PlusApi - from frigate.util import load_labels - logger = logging.getLogger(__name__) diff --git a/frigate/detectors/detector_types.py b/frigate/detectors/detector_types.py index 5c96b2e16..418fcd625 100644 --- a/frigate/detectors/detector_types.py +++ b/frigate/detectors/detector_types.py @@ -1,16 +1,16 @@ -import logging import importlib +import logging import pkgutil -from typing import Union -from typing_extensions import Annotated from enum import Enum +from typing import Union + from pydantic import Field +from typing_extensions import Annotated from . import plugins from .detection_api import DetectionApi from .detector_config import BaseDetectorConfig - logger = logging.getLogger(__name__) diff --git a/frigate/detectors/plugins/cpu_tfl.py b/frigate/detectors/plugins/cpu_tfl.py index a831a9190..8a54363e1 100644 --- a/frigate/detectors/plugins/cpu_tfl.py +++ b/frigate/detectors/plugins/cpu_tfl.py @@ -1,10 +1,11 @@ import logging + import numpy as np +from pydantic import Field +from typing_extensions import Literal from frigate.detectors.detection_api import DetectionApi from frigate.detectors.detector_config import BaseDetectorConfig -from typing_extensions import Literal -from pydantic import Extra, Field try: from tflite_runtime.interpreter import Interpreter diff --git a/frigate/detectors/plugins/deepstack.py b/frigate/detectors/plugins/deepstack.py index 639cd396c..fd79e27d0 100644 --- a/frigate/detectors/plugins/deepstack.py +++ b/frigate/detectors/plugins/deepstack.py @@ -1,14 +1,14 @@ +import io import logging + import numpy as np import requests -import io +from PIL import Image +from pydantic import Field +from typing_extensions import Literal from frigate.detectors.detection_api import DetectionApi from frigate.detectors.detector_config import BaseDetectorConfig -from typing_extensions import Literal -from pydantic import Extra, Field -from PIL import Image - logger = logging.getLogger(__name__) @@ -64,11 +64,11 @@ class DeepStack(DetectionApi): for i, detection in enumerate(response_json.get("predictions")): logger.debug(f"Response: {detection}") if detection["confidence"] < 0.4: - logger.debug(f"Break due to confidence < 0.4") + logger.debug("Break due to confidence < 0.4") break label = self.get_label_index(detection["label"]) if label < 0: - logger.debug(f"Break due to unknown label") + logger.debug("Break due to unknown label") break detections[i] = [ label, diff --git a/frigate/detectors/plugins/edgetpu_tfl.py b/frigate/detectors/plugins/edgetpu_tfl.py index d671dea4d..ca03d483b 100644 --- a/frigate/detectors/plugins/edgetpu_tfl.py +++ b/frigate/detectors/plugins/edgetpu_tfl.py @@ -1,10 +1,11 @@ import logging + import numpy as np +from pydantic import Field +from typing_extensions import Literal from frigate.detectors.detection_api import DetectionApi from frigate.detectors.detector_config import BaseDetectorConfig -from typing_extensions import Literal -from pydantic import Extra, Field try: from tflite_runtime.interpreter import Interpreter, load_delegate diff --git a/frigate/detectors/plugins/openvino.py b/frigate/detectors/plugins/openvino.py index fe87ac567..5cb1ea39c 100644 --- a/frigate/detectors/plugins/openvino.py +++ b/frigate/detectors/plugins/openvino.py @@ -1,12 +1,12 @@ import logging + import numpy as np import openvino.runtime as ov +from pydantic import Field +from typing_extensions import Literal from frigate.detectors.detection_api import DetectionApi from frigate.detectors.detector_config import BaseDetectorConfig, ModelTypeEnum -from typing_extensions import Literal -from pydantic import Extra, Field - logger = logging.getLogger(__name__) @@ -41,7 +41,7 @@ class OvDetector(DetectionApi): tensor_shape = self.interpreter.output(self.output_indexes).shape logger.info(f"Model Output-{self.output_indexes} Shape: {tensor_shape}") self.output_indexes += 1 - except: + except Exception: logger.info(f"Model has {self.output_indexes} Output Tensors") break if self.ov_model_type == ModelTypeEnum.yolox: diff --git a/frigate/detectors/plugins/tensorrt.py b/frigate/detectors/plugins/tensorrt.py index ac0c4befc..7251b8751 100644 --- a/frigate/detectors/plugins/tensorrt.py +++ b/frigate/detectors/plugins/tensorrt.py @@ -1,6 +1,6 @@ +import ctypes import logging -import ctypes import numpy as np try: @@ -8,13 +8,14 @@ try: from cuda import cuda TRT_SUPPORT = True -except ModuleNotFoundError as e: +except ModuleNotFoundError: TRT_SUPPORT = False +from pydantic import Field +from typing_extensions import Literal + from frigate.detectors.detection_api import DetectionApi from frigate.detectors.detector_config import BaseDetectorConfig -from typing_extensions import Literal -from pydantic import Field logger = logging.getLogger(__name__) @@ -172,7 +173,7 @@ class TensorRtDetector(DetectionApi): if not self.context.execute_async_v2( bindings=self.bindings, stream_handle=self.stream ): - logger.warn(f"Execute returned false") + logger.warn("Execute returned false") # Transfer predictions back from the GPU. [ diff --git a/frigate/events/cleanup.py b/frigate/events/cleanup.py index 09b1964fd..ada45e6fa 100644 --- a/frigate/events/cleanup.py +++ b/frigate/events/cleanup.py @@ -4,17 +4,13 @@ import datetime import logging import os import threading - +from multiprocessing.synchronize import Event as MpEvent from pathlib import Path -from peewee import fn - from frigate.config import FrigateConfig from frigate.const import CLIPS_DIR from frigate.models import Event -from multiprocessing.synchronize import Event as MpEvent - logger = logging.getLogger(__name__) @@ -45,9 +41,9 @@ class EventCleanup(threading.Thread): ) # loop over object types in db - for l in distinct_labels: + for event in distinct_labels: # get expiration time for this label - expire_days = retain_config.objects.get(l.label, retain_config.default) + expire_days = retain_config.objects.get(event.label, retain_config.default) expire_after = ( datetime.datetime.now() - datetime.timedelta(days=expire_days) ).timestamp() @@ -55,8 +51,8 @@ class EventCleanup(threading.Thread): expired_events = Event.select().where( Event.camera.not_in(self.camera_keys), Event.start_time < expire_after, - Event.label == l.label, - Event.retain_indefinitely == False, + Event.label == event.label, + Event.retain_indefinitely is False, ) # delete the media from disk for event in expired_events: @@ -75,8 +71,8 @@ class EventCleanup(threading.Thread): update_query = Event.update(update_params).where( Event.camera.not_in(self.camera_keys), Event.start_time < expire_after, - Event.label == l.label, - Event.retain_indefinitely == False, + Event.label == event.label, + Event.retain_indefinitely is False, ) update_query.execute() @@ -92,9 +88,11 @@ class EventCleanup(threading.Thread): ) # loop over object types in db - for l in distinct_labels: + for event in distinct_labels: # get expiration time for this label - expire_days = retain_config.objects.get(l.label, retain_config.default) + expire_days = retain_config.objects.get( + event.label, retain_config.default + ) expire_after = ( datetime.datetime.now() - datetime.timedelta(days=expire_days) ).timestamp() @@ -102,8 +100,8 @@ class EventCleanup(threading.Thread): expired_events = Event.select().where( Event.camera == name, Event.start_time < expire_after, - Event.label == l.label, - Event.retain_indefinitely == False, + Event.label == event.label, + Event.retain_indefinitely is False, ) # delete the grabbed clips from disk for event in expired_events: @@ -121,8 +119,8 @@ class EventCleanup(threading.Thread): update_query = Event.update(update_params).where( Event.camera == name, Event.start_time < expire_after, - Event.label == l.label, - Event.retain_indefinitely == False, + Event.label == event.label, + Event.retain_indefinitely is False, ) update_query.execute() @@ -131,9 +129,9 @@ class EventCleanup(threading.Thread): select id, label, camera, - has_snapshot, - has_clip, - row_number() over ( + has_snapshot, + has_clip, + row_number() over ( partition by label, camera, round(start_time/5,0)*5 order by end_time-start_time desc ) as copy_number @@ -169,8 +167,8 @@ class EventCleanup(threading.Thread): # drop events from db where has_clip and has_snapshot are false delete_query = Event.delete().where( - Event.has_clip == False, Event.has_snapshot == False + Event.has_clip is False, Event.has_snapshot is False ) delete_query.execute() - logger.info(f"Exiting event cleanup...") + logger.info("Exiting event cleanup...") diff --git a/frigate/events/external.py b/frigate/events/external.py index ee2906e02..5422de260 100644 --- a/frigate/events/external.py +++ b/frigate/events/external.py @@ -1,17 +1,15 @@ """Handle external events created by the user.""" import base64 -import cv2 import datetime -import glob import logging import os import random import string - +from multiprocessing.queues import Queue from typing import Optional -from multiprocessing.queues import Queue +import cv2 from frigate.config import CameraConfig, FrigateConfig from frigate.const import CLIPS_DIR diff --git a/frigate/events/maintainer.py b/frigate/events/maintainer.py index 898218ef0..5459fea6c 100644 --- a/frigate/events/maintainer.py +++ b/frigate/events/maintainer.py @@ -2,20 +2,16 @@ import datetime import logging import queue import threading - from enum import Enum - -from peewee import fn +from multiprocessing.queues import Queue +from multiprocessing.synchronize import Event as MpEvent +from typing import Dict from frigate.config import EventsConfig, FrigateConfig from frigate.models import Event from frigate.types import CameraMetricsTypes from frigate.util import to_relative_box -from multiprocessing.queues import Queue -from multiprocessing.synchronize import Event as MpEvent -from typing import Dict - logger = logging.getLogger(__name__) @@ -65,7 +61,7 @@ class EventProcessor(threading.Thread): def run(self) -> None: # set an end_time on events without an end_time on startup Event.update(end_time=Event.start_time + 30).where( - Event.end_time == None + Event.end_time is None ).execute() while not self.stop_event.is_set(): @@ -99,9 +95,9 @@ class EventProcessor(threading.Thread): # set an end_time on events without an end_time before exiting Event.update(end_time=datetime.datetime.now().timestamp()).where( - Event.end_time == None + Event.end_time is None ).execute() - logger.info(f"Exiting event processor...") + logger.info("Exiting event processor...") def handle_object_detection( self, diff --git a/frigate/ffmpeg_presets.py b/frigate/ffmpeg_presets.py index 353a8b922..d78cd72ef 100644 --- a/frigate/ffmpeg_presets.py +++ b/frigate/ffmpeg_presets.py @@ -2,13 +2,11 @@ import logging import os - from typing import Any -from frigate.version import VERSION from frigate.const import BTBN_PATH from frigate.util import vainfo_hwaccel - +from frigate.version import VERSION logger = logging.getLogger(__name__) diff --git a/frigate/http.py b/frigate/http.py index de9fd033c..9d7aa2c47 100644 --- a/frigate/http.py +++ b/frigate/http.py @@ -1,23 +1,20 @@ import base64 -from datetime import datetime, timedelta, timezone import copy -import logging import glob import json +import logging import os import subprocess as sp -import pytz import time import traceback - +from datetime import datetime, timedelta, timezone from functools import reduce from pathlib import Path -from tzlocal import get_localzone_name from urllib.parse import unquote import cv2 - import numpy as np +import pytz from flask import ( Blueprint, Flask, @@ -27,26 +24,26 @@ from flask import ( make_response, request, ) - -from peewee import SqliteDatabase, operator, fn, DoesNotExist +from peewee import DoesNotExist, SqliteDatabase, fn, operator from playhouse.shortcuts import model_to_dict +from tzlocal import get_localzone_name from frigate.config import FrigateConfig from frigate.const import CLIPS_DIR, MAX_SEGMENT_DURATION, RECORD_DIR -from frigate.models import Event, Recordings, Timeline from frigate.events.external import ExternalEventProcessor +from frigate.models import Event, Recordings, Timeline from frigate.object_processing import TrackedObject from frigate.plus import PlusApi from frigate.ptz import OnvifController from frigate.stats import stats_snapshot +from frigate.storage import StorageMaintainer from frigate.util import ( clean_camera_user_pass, ffprobe_stream, + get_tz_modifiers, restart_frigate, vainfo_hwaccel, - get_tz_modifiers, ) -from frigate.storage import StorageMaintainer from frigate.version import VERSION logger = logging.getLogger(__name__) @@ -105,10 +102,10 @@ def events_summary(): clauses = [] - if not has_clip is None: + if has_clip is not None: clauses.append((Event.has_clip == has_clip)) - if not has_snapshot is None: + if has_snapshot is not None: clauses.append((Event.has_snapshot == has_snapshot)) if len(clauses) == 0: @@ -253,7 +250,7 @@ def send_to_plus(id): event.plus_id = plus_id event.save() - if not include_annotation is None: + if include_annotation is not None: box = event.data["box"] try: @@ -296,12 +293,12 @@ def false_positive(id): # events from before the conversion to relative dimensions cant include annotations if event.data.get("box") is None: - message = f"Events prior to 0.13 cannot be submitted as false positives" + message = "Events prior to 0.13 cannot be submitted as false positives" logger.error(message) return make_response(jsonify({"success": False, "message": message}), 400) if event.false_positive: - message = f"False positive already submitted to Frigate+" + message = "False positive already submitted to Frigate+" logger.error(message) return make_response(jsonify({"success": False, "message": message}), 400) @@ -437,7 +434,7 @@ def get_sub_labels(): parts = label.split(",") for part in parts: - if not (part.strip()) in sub_labels: + if part.strip() not in sub_labels: sub_labels.append(part.strip()) sub_labels.sort() @@ -476,7 +473,7 @@ def event_thumbnail(id, max_cache_age=2592000): event_complete = False try: event = Event.get(Event.id == id) - if not event.end_time is None: + if event.end_time is not None: event_complete = True thumbnail_bytes = base64.b64decode(event.thumbnail) except DoesNotExist: @@ -486,9 +483,9 @@ def event_thumbnail(id, max_cache_age=2592000): for camera_state in camera_states: if id in camera_state.tracked_objects: tracked_obj = camera_state.tracked_objects.get(id) - if not tracked_obj is None: + if tracked_obj is not None: thumbnail_bytes = tracked_obj.get_thumbnail() - except: + except Exception: return "Event not found", 404 if thumbnail_bytes is None: @@ -593,7 +590,7 @@ def event_snapshot(id): event_complete = False jpg_bytes = None try: - event = Event.get(Event.id == id, Event.end_time != None) + event = Event.get(Event.id == id, Event.end_time is not None) event_complete = True if not event.has_snapshot: return "Snapshot not available", 404 @@ -609,7 +606,7 @@ def event_snapshot(id): for camera_state in camera_states: if id in camera_state.tracked_objects: tracked_obj = camera_state.tracked_objects.get(id) - if not tracked_obj is None: + if tracked_obj is not None: jpg_bytes = tracked_obj.get_jpg_bytes( timestamp=request.args.get("timestamp", type=int), bounding_box=request.args.get("bbox", type=int), @@ -617,9 +614,9 @@ def event_snapshot(id): height=request.args.get("h", type=int), quality=request.args.get("quality", default=70, type=int), ) - except: + except Exception: return "Event not found", 404 - except: + except Exception: return "Event not found", 404 if jpg_bytes is None: @@ -645,7 +642,7 @@ def label_snapshot(camera_name, label): event_query = ( Event.select() .where(Event.camera == camera_name) - .where(Event.has_snapshot == True) + .where(Event.has_snapshot is True) .order_by(Event.start_time.desc()) ) else: @@ -653,7 +650,7 @@ def label_snapshot(camera_name, label): Event.select() .where(Event.camera == camera_name) .where(Event.label == label) - .where(Event.has_snapshot == True) + .where(Event.has_snapshot is True) .order_by(Event.start_time.desc()) ) @@ -820,13 +817,13 @@ def events(): if before: clauses.append((Event.start_time < before)) - if not has_clip is None: + if has_clip is not None: clauses.append((Event.has_clip == has_clip)) - if not has_snapshot is None: + if has_snapshot is not None: clauses.append((Event.has_snapshot == has_snapshot)) - if not in_progress is None: + if in_progress is not None: clauses.append((Event.end_time.is_null(in_progress))) if not include_thumbnails: @@ -894,12 +891,12 @@ def create_event(camera_name, label): def end_event(event_id): try: current_app.external_processor.finish_manual_event(event_id) - except: + except Exception: return jsonify( {"success": False, "message": f"{event_id} must be set and valid."}, 404 ) - return jsonify({"success": True, "message": f"Event successfully ended."}, 200) + return jsonify({"success": True, "message": "Event successfully ended."}, 200) @bp.route("/config") @@ -959,9 +956,8 @@ def config_save(): # Validate the config schema try: - new_yaml = FrigateConfig.parse_raw(new_config) - check_runtime = new_yaml.runtime_config - except Exception as e: + FrigateConfig.parse_raw(new_config) + except Exception: return make_response( jsonify( { @@ -985,12 +981,12 @@ def config_save(): with open(config_file, "w") as f: f.write(new_config) f.close() - except Exception as e: + except Exception: return make_response( jsonify( { "success": False, - "message": f"Could not write config file, be sure that Frigate has write permission on the config file.", + "message": "Could not write config file, be sure that Frigate has write permission on the config file.", } ), 400, @@ -1531,7 +1527,7 @@ def ffprobe(): if not path_param: return jsonify( - {"success": False, "message": f"Path needs to be provided."}, "404" + {"success": False, "message": "Path needs to be provided."}, "404" ) if path_param.startswith("camera"): diff --git a/frigate/log.py b/frigate/log.py index 67866942c..4a44545ad 100644 --- a/frigate/log.py +++ b/frigate/log.py @@ -1,18 +1,17 @@ # adapted from https://medium.com/@jonathonbao/python3-logging-with-multiprocessing-f51f460b8778 import logging -import threading -import os -import signal -import queue import multiprocessing as mp -from multiprocessing.queues import Queue -from logging import handlers -from typing import Optional -from types import FrameType -from setproctitle import setproctitle -from typing import Deque, Optional -from types import FrameType +import os +import queue +import signal +import threading from collections import deque +from logging import handlers +from multiprocessing.queues import Queue +from types import FrameType +from typing import Deque, Optional + +from setproctitle import setproctitle from frigate.util import clean_camera_user_pass @@ -44,7 +43,7 @@ def root_configurer(queue: Queue) -> None: def log_process(log_queue: Queue) -> None: - threading.current_thread().name = f"logger" + threading.current_thread().name = "logger" setproctitle("frigate.logger") listener_configurer() diff --git a/frigate/models.py b/frigate/models.py index 0d5f1ab4a..5f6ac7339 100644 --- a/frigate/models.py +++ b/frigate/models.py @@ -1,12 +1,11 @@ -from numpy import unique from peewee import ( - Model, + BooleanField, CharField, DateTimeField, FloatField, - BooleanField, - TextField, IntegerField, + Model, + TextField, ) from playhouse.sqlite_ext import JSONField diff --git a/frigate/motion.py b/frigate/motion.py index 5580803a3..19d162956 100644 --- a/frigate/motion.py +++ b/frigate/motion.py @@ -1,6 +1,7 @@ import cv2 import imutils import numpy as np + from frigate.config import MotionConfig diff --git a/frigate/object_detection.py b/frigate/object_detection.py index 129fd6b26..9201dfcd1 100644 --- a/frigate/object_detection.py +++ b/frigate/object_detection.py @@ -12,7 +12,6 @@ from setproctitle import setproctitle from frigate.config import InputTensorEnum from frigate.detectors import create_detector - from frigate.util import EventsPerSecond, SharedMemoryFrameManager, listen, load_labels logger = logging.getLogger(__name__) @@ -161,7 +160,7 @@ class ObjectDetectProcess: def start_or_restart(self): self.detection_start.value = 0.0 - if (not self.detect_process is None) and self.detect_process.is_alive(): + if (self.detect_process is not None) and self.detect_process.is_alive(): self.stop() self.detect_process = mp.Process( target=run_detector, diff --git a/frigate/object_processing.py b/frigate/object_processing.py index 3088857fa..f9046d0ab 100644 --- a/frigate/object_processing.py +++ b/frigate/object_processing.py @@ -15,10 +15,10 @@ import numpy as np from frigate.comms.dispatcher import Dispatcher from frigate.config import ( CameraConfig, - MqttConfig, - SnapshotsConfig, - RecordConfig, FrigateConfig, + MqttConfig, + RecordConfig, + SnapshotsConfig, ) from frigate.const import CLIPS_DIR from frigate.events.maintainer import EventTypeEnum @@ -141,7 +141,7 @@ class TrackedObject: # check each zone for name, zone in self.camera_config.zones.items(): # if the zone is not for this object type, skip - if len(zone.objects) > 0 and not obj_data["label"] in zone.objects: + if len(zone.objects) > 0 and obj_data["label"] not in zone.objects: continue contour = zone.contour # check if the object is in the zone @@ -177,11 +177,7 @@ class TrackedObject: return (thumb_update, significant_change) def to_dict(self, include_thumbnail: bool = False): - snapshot_time = ( - self.thumbnail_data["frame_time"] - if not self.thumbnail_data is None - else 0.0 - ) + (self.thumbnail_data["frame_time"] if self.thumbnail_data is not None else 0.0) event = { "id": self.obj_data["id"], "camera": self.camera, @@ -526,7 +522,7 @@ class CameraState: for id in removed_ids: # publish events to mqtt removed_obj = tracked_objects[id] - if not "end_time" in removed_obj.obj_data: + if "end_time" not in removed_obj.obj_data: removed_obj.obj_data["end_time"] = frame_time for c in self.callbacks["end"]: c(self.name, removed_obj, frame_time) @@ -1028,4 +1024,4 @@ class TrackedObjectProcessor(threading.Thread): event_id, camera = self.event_processed_queue.get() self.camera_states[camera].finished(event_id) - logger.info(f"Exiting object processor...") + logger.info("Exiting object processor...") diff --git a/frigate/objects.py b/frigate/objects.py index ed04ae191..d11aff293 100644 --- a/frigate/objects.py +++ b/frigate/objects.py @@ -1,14 +1,7 @@ -import copy -import datetime -import itertools -import multiprocessing as mp import random import string -import threading -import time from collections import defaultdict -import cv2 import numpy as np from scipy.spatial import distance as dist @@ -160,7 +153,7 @@ class ObjectTracker: # update any tracked objects with labels that are not # seen in the current objects and deregister if needed for obj in list(self.tracked_objects.values()): - if not obj["label"] in new_object_groups: + if obj["label"] not in new_object_groups: if self.disappeared[obj["id"]] >= self.max_disappeared: self.deregister(obj["id"]) else: diff --git a/frigate/output.py b/frigate/output.py index 79a081837..1a394d79f 100644 --- a/frigate/output.py +++ b/frigate/output.py @@ -4,7 +4,6 @@ import logging import math import multiprocessing as mp import os -import operator import queue import signal import subprocess as sp @@ -149,7 +148,7 @@ class BroadcastThread(threading.Thread): ): try: ws.send(buf, binary=True) - except: + except ValueError: pass elif self.converter.process.poll() is not None: break @@ -185,7 +184,7 @@ class BirdsEyeFrameManager: if len(logo_files) > 0: birdseye_logo = cv2.imread(logo_files[0], cv2.IMREAD_UNCHANGED) - if not birdseye_logo is None: + if birdseye_logo is not None: transparent_layer = birdseye_logo[:, :, 3] y_offset = height // 2 - transparent_layer.shape[0] // 2 x_offset = width // 2 - transparent_layer.shape[1] // 2 @@ -229,7 +228,7 @@ class BirdsEyeFrameManager: self.last_output_time = 0.0 def clear_frame(self): - logger.debug(f"Clearing the birdseye frame") + logger.debug("Clearing the birdseye frame") self.frame[:] = self.blank_frame def copy_to_position(self, position, camera=None, frame_time=None): @@ -301,7 +300,7 @@ class BirdsEyeFrameManager: # reset the layout if it needs to be different if layout_dim != self.layout_dim or reset_layout: if reset_layout: - logger.debug(f"Added new cameras, resetting layout...") + logger.debug("Added new cameras, resetting layout...") logger.debug(f"Changing layout size from {self.layout_dim} to {layout_dim}") self.layout_dim = layout_dim @@ -385,7 +384,7 @@ class BirdsEyeFrameManager: ] # if not an empty spot and the camera has a newer frame, copy it elif ( - not camera is None + camera is not None and self.cameras[camera]["current_frame"] != self.cameras[camera]["layout_frame"] ): @@ -423,8 +422,8 @@ class BirdsEyeFrameManager: def output_frames(config: FrigateConfig, video_output_queue): - threading.current_thread().name = f"output" - setproctitle(f"frigate.output") + threading.current_thread().name = "output" + setproctitle("frigate.output") stop_event = mp.Event() diff --git a/frigate/plus.py b/frigate/plus.py index 7ba67a62d..b219e02a2 100644 --- a/frigate/plus.py +++ b/frigate/plus.py @@ -3,12 +3,14 @@ import json import logging import os import re -from typing import Any, Dict, List -import requests -from frigate.const import PLUS_ENV_VAR, PLUS_API_HOST -from requests.models import Response +from typing import Any, List + import cv2 +import requests from numpy import ndarray +from requests.models import Response + +from frigate.const import PLUS_API_HOST, PLUS_ENV_VAR logger = logging.getLogger(__name__) diff --git a/frigate/ptz.py b/frigate/ptz.py index a52006b5c..385a230bc 100644 --- a/frigate/ptz.py +++ b/frigate/ptz.py @@ -2,13 +2,12 @@ import logging import site - from enum import Enum + from onvif import ONVIFCamera, ONVIFError from frigate.config import FrigateConfig - logger = logging.getLogger(__name__) @@ -145,7 +144,7 @@ class OnvifController: onvif.get_service("ptz").ContinuousMove(move_request) def _move_to_preset(self, camera_name: str, preset: str) -> None: - if not preset in self.cams[camera_name]["presets"]: + if preset not in self.cams[camera_name]["presets"]: logger.error(f"{preset} is not a valid preset for {camera_name}") return diff --git a/frigate/record/cleanup.py b/frigate/record/cleanup.py index 605979ee4..bb54d8b86 100644 --- a/frigate/record/cleanup.py +++ b/frigate/record/cleanup.py @@ -5,12 +5,12 @@ import itertools import logging import os import threading +from multiprocessing.synchronize import Event as MpEvent from pathlib import Path from peewee import DoesNotExist -from multiprocessing.synchronize import Event as MpEvent -from frigate.config import RetainModeEnum, FrigateConfig +from frigate.config import FrigateConfig, RetainModeEnum from frigate.const import RECORD_DIR, SECONDS_IN_DAY from frigate.models import Event, Recordings, Timeline from frigate.record.util import remove_empty_directories @@ -225,7 +225,7 @@ class RecordingCleanup(threading.Thread): recordings_to_delete = [] for recording in recordings.objects().iterator(): - if not recording.path in files_on_disk: + if recording.path not in files_on_disk: recordings_to_delete.append(recording.id) logger.debug( @@ -247,7 +247,7 @@ class RecordingCleanup(threading.Thread): # Expire tmp clips every minute, recordings and clean directories every hour. for counter in itertools.cycle(range(self.config.record.expire_interval)): if self.stop_event.wait(60): - logger.info(f"Exiting recording cleanup...") + logger.info("Exiting recording cleanup...") break self.clean_tmp_clips() diff --git a/frigate/record/maintainer.py b/frigate/record/maintainer.py index 651bd1214..afcd6af28 100644 --- a/frigate/record/maintainer.py +++ b/frigate/record/maintainer.py @@ -9,14 +9,14 @@ import random import string import subprocess as sp import threading -import psutil - from collections import defaultdict from multiprocessing.synchronize import Event as MpEvent from pathlib import Path from typing import Any, Tuple -from frigate.config import RetainModeEnum, FrigateConfig +import psutil + +from frigate.config import FrigateConfig, RetainModeEnum from frigate.const import CACHE_DIR, MAX_SEGMENT_DURATION, RECORD_DIR from frigate.models import Event, Recordings from frigate.types import RecordMetricsTypes @@ -63,7 +63,7 @@ class RecordingMaintainer(threading.Thread): for nt in flist: if nt.path.startswith(CACHE_DIR): files_in_use.append(nt.path.split("/")[-1]) - except: + except psutil.Error: continue # group recordings by camera @@ -115,7 +115,7 @@ class RecordingMaintainer(threading.Thread): Event.select() .where( Event.camera == camera, - (Event.end_time == None) + (Event.end_time is None) | (Event.end_time >= recordings[0]["start_time"].timestamp()), Event.has_clip, ) @@ -127,7 +127,7 @@ class RecordingMaintainer(threading.Thread): # Just delete files if recordings are turned off if ( - not camera in self.config.cameras + camera not in self.config.cameras or not self.process_info[camera]["record_enabled"].value ): Path(cache_path).unlink(missing_ok=True) @@ -394,4 +394,4 @@ class RecordingMaintainer(threading.Thread): duration = datetime.datetime.now().timestamp() - run_start wait_time = max(0, 5 - duration) - logger.info(f"Exiting recording maintenance...") + logger.info("Exiting recording maintenance...") diff --git a/frigate/record/record.py b/frigate/record/record.py index 59fda095b..3aaf56476 100644 --- a/frigate/record/record.py +++ b/frigate/record/record.py @@ -4,12 +4,11 @@ import logging import multiprocessing as mp import signal import threading - -from setproctitle import setproctitle from types import FrameType from typing import Optional from playhouse.sqliteq import SqliteQueueDatabase +from setproctitle import setproctitle from frigate.config import FrigateConfig from frigate.models import Event, Recordings, Timeline diff --git a/frigate/stats.py b/frigate/stats.py index 55db809d3..3fd881029 100644 --- a/frigate/stats.py +++ b/frigate/stats.py @@ -1,23 +1,30 @@ import asyncio import json import logging +import os +import shutil import threading import time -import psutil -import shutil -import os -import requests -from typing import Optional, Any from multiprocessing.synchronize import Event as MpEvent +from typing import Any, Optional + +import psutil +import requests +from requests.exceptions import RequestException from frigate.comms.dispatcher import Dispatcher from frigate.config import FrigateConfig -from frigate.const import DRIVER_AMD, DRIVER_ENV_VAR, RECORD_DIR, CLIPS_DIR, CACHE_DIR -from frigate.types import StatsTrackingTypes, CameraMetricsTypes -from frigate.util import get_amd_gpu_stats, get_intel_gpu_stats, get_nvidia_gpu_stats -from frigate.version import VERSION -from frigate.util import get_cpu_stats, get_bandwidth_stats +from frigate.const import CACHE_DIR, CLIPS_DIR, DRIVER_AMD, DRIVER_ENV_VAR, RECORD_DIR from frigate.object_detection import ObjectDetectProcess +from frigate.types import CameraMetricsTypes, StatsTrackingTypes +from frigate.util import ( + get_amd_gpu_stats, + get_bandwidth_stats, + get_cpu_stats, + get_intel_gpu_stats, + get_nvidia_gpu_stats, +) +from frigate.version import VERSION logger = logging.getLogger(__name__) @@ -31,7 +38,7 @@ def get_latest_version(config: FrigateConfig) -> str: "https://api.github.com/repos/blakeblackshear/frigate/releases/latest", timeout=10, ) - except: + except RequestException: return "unknown" response = request.json() @@ -308,4 +315,4 @@ class StatsEmitter(threading.Thread): ) self.dispatcher.publish("stats", json.dumps(stats), retain=False) logger.debug("Finished stats collection") - logger.info(f"Exiting stats emitter...") + logger.info("Exiting stats emitter...") diff --git a/frigate/storage.py b/frigate/storage.py index 5b66abbdc..6cdd54bdc 100644 --- a/frigate/storage.py +++ b/frigate/storage.py @@ -1,9 +1,9 @@ """Handle storage retention and usage.""" import logging -from pathlib import Path import shutil import threading +from pathlib import Path from peewee import fn @@ -107,7 +107,7 @@ class StorageMaintainer(threading.Thread): retained_events: Event = ( Event.select() .where( - Event.retain_indefinitely == True, + Event.retain_indefinitely is True, Event.has_clip, ) .order_by(Event.start_time.asc()) @@ -188,4 +188,4 @@ class StorageMaintainer(threading.Thread): if self.check_storage_needs_cleanup(): self.reduce_storage_consumption() - logger.info(f"Exiting storage maintainer...") + logger.info("Exiting storage maintainer...") diff --git a/frigate/test/test_config.py b/frigate/test/test_config.py index 7cd5e2217..8c1b5b586 100644 --- a/frigate/test/test_config.py +++ b/frigate/test/test_config.py @@ -1,13 +1,11 @@ import json import os import unittest + import numpy as np from pydantic import ValidationError -from frigate.config import ( - BirdseyeModeEnum, - FrigateConfig, -) +from frigate.config import BirdseyeModeEnum, FrigateConfig from frigate.const import MODEL_CACHE_DIR from frigate.detectors import DetectorTypeEnum from frigate.plus import PlusApi @@ -675,7 +673,7 @@ class TestConfig(unittest.TestCase): runtime_config = frigate_config.runtime_config() ffmpeg_cmds = runtime_config.cameras["back"].ffmpeg_cmds assert len(ffmpeg_cmds) == 1 - assert not "clips" in ffmpeg_cmds[0]["roles"] + assert "clips" not in ffmpeg_cmds[0]["roles"] def test_max_disappeared_default(self): config = { @@ -986,7 +984,7 @@ class TestConfig(unittest.TestCase): } frigate_config = FrigateConfig(**config) - runtime_config = frigate_config.runtime_config() + frigate_config.runtime_config() def test_global_detect(self): config = { @@ -1145,7 +1143,7 @@ class TestConfig(unittest.TestCase): assert config == frigate_config.dict(exclude_unset=True) runtime_config = frigate_config.runtime_config() - assert runtime_config.cameras["back"].snapshots.bounding_box == False + assert runtime_config.cameras["back"].snapshots.bounding_box is False assert runtime_config.cameras["back"].snapshots.height == 150 assert runtime_config.cameras["back"].snapshots.enabled diff --git a/frigate/test/test_copy_yuv_to_position.py b/frigate/test/test_copy_yuv_to_position.py index 16c97b79d..33582e2d1 100644 --- a/frigate/test/test_copy_yuv_to_position.py +++ b/frigate/test/test_copy_yuv_to_position.py @@ -1,7 +1,9 @@ +from unittest import TestCase, main + import cv2 import numpy as np -from unittest import TestCase, main -from frigate.util import get_yuv_crop, copy_yuv_to_position + +from frigate.util import copy_yuv_to_position, get_yuv_crop class TestCopyYuvToPosition(TestCase): diff --git a/frigate/test/test_ffmpeg_presets.py b/frigate/test/test_ffmpeg_presets.py index 92e0fa3bd..0d3dab856 100644 --- a/frigate/test/test_ffmpeg_presets.py +++ b/frigate/test/test_ffmpeg_presets.py @@ -1,4 +1,5 @@ import unittest + from frigate.config import FFMPEG_INPUT_ARGS_DEFAULT, FrigateConfig from frigate.ffmpeg_presets import parse_preset_input diff --git a/frigate/test/test_gpu_stats.py b/frigate/test/test_gpu_stats.py index 5742a583d..2cf92def1 100644 --- a/frigate/test/test_gpu_stats.py +++ b/frigate/test/test_gpu_stats.py @@ -1,7 +1,7 @@ import unittest from unittest.mock import MagicMock, patch -from frigate.util import get_amd_gpu_stats, get_intel_gpu_stats, get_nvidia_gpu_stats +from frigate.util import get_amd_gpu_stats, get_intel_gpu_stats class TestGpuStats(unittest.TestCase): diff --git a/frigate/test/test_http.py b/frigate/test/test_http.py index ecb500383..3557eccd3 100644 --- a/frigate/test/test_http.py +++ b/frigate/test/test_http.py @@ -6,15 +6,14 @@ import unittest from unittest.mock import patch from peewee_migrate import Router +from playhouse.shortcuts import model_to_dict from playhouse.sqlite_ext import SqliteExtDatabase from playhouse.sqliteq import SqliteQueueDatabase -from playhouse.shortcuts import model_to_dict from frigate.config import FrigateConfig from frigate.http import create_app from frigate.models import Event, Recordings from frigate.plus import PlusApi - from frigate.test.const import TEST_DB, TEST_DB_CLEANUPS @@ -128,22 +127,22 @@ class TestHttp(unittest.TestCase): with app.test_client() as client: _insert_mock_event(id) - events = client.get(f"/events").json + events = client.get("/events").json assert events assert len(events) == 1 assert events[0]["id"] == id _insert_mock_event(id2) - events = client.get(f"/events").json + events = client.get("/events").json assert events assert len(events) == 2 events = client.get( - f"/events", + "/events", query_string={"limit": 1}, ).json assert events assert len(events) == 1 events = client.get( - f"/events", + "/events", query_string={"has_clip": 0}, ).json assert not events @@ -230,12 +229,12 @@ class TestHttp(unittest.TestCase): event = client.get(f"/events/{id}").json assert event assert event["id"] == id - assert event["retain_indefinitely"] == True + assert event["retain_indefinitely"] is True client.delete(f"/events/{id}/retain") event = client.get(f"/events/{id}").json assert event assert event["id"] == id - assert event["retain_indefinitely"] == False + assert event["retain_indefinitely"] is False def test_set_delete_sub_label(self): app = create_app( diff --git a/frigate/test/test_object_detector.py b/frigate/test/test_object_detector.py index 9cdeeb6c7..1e1efa957 100644 --- a/frigate/test/test_object_detector.py +++ b/frigate/test/test_object_detector.py @@ -4,10 +4,10 @@ from unittest.mock import Mock, patch import numpy as np from pydantic import parse_obj_as -from frigate.config import DetectorConfig, InputTensorEnum, ModelConfig -from frigate.detectors import DetectorTypeEnum import frigate.detectors as detectors import frigate.object_detection +from frigate.config import DetectorConfig, InputTensorEnum, ModelConfig +from frigate.detectors import DetectorTypeEnum class TestLocalObjectDetector(unittest.TestCase): diff --git a/frigate/test/test_reduce_boxes.py b/frigate/test/test_reduce_boxes.py index 69d6f7177..d26fcd40c 100644 --- a/frigate/test/test_reduce_boxes.py +++ b/frigate/test/test_reduce_boxes.py @@ -1,5 +1,5 @@ -import numpy as np from unittest import TestCase, main + from frigate.video import box_overlaps, reduce_boxes diff --git a/frigate/test/test_storage.py b/frigate/test/test_storage.py index 22ea6fc1e..468d31916 100644 --- a/frigate/test/test_storage.py +++ b/frigate/test/test_storage.py @@ -1,21 +1,17 @@ import datetime -import json import logging import os import unittest -from unittest.mock import MagicMock, patch +from unittest.mock import MagicMock from peewee import DoesNotExist from peewee_migrate import Router from playhouse.sqlite_ext import SqliteExtDatabase from playhouse.sqliteq import SqliteQueueDatabase -from playhouse.shortcuts import model_to_dict from frigate.config import FrigateConfig -from frigate.http import create_app from frigate.models import Event, Recordings from frigate.storage import StorageMaintainer - from frigate.test.const import TEST_DB, TEST_DB_CLEANUPS diff --git a/frigate/test/test_yuv_region_2_rgb.py b/frigate/test/test_yuv_region_2_rgb.py index 96f421565..a56a78b1c 100644 --- a/frigate/test/test_yuv_region_2_rgb.py +++ b/frigate/test/test_yuv_region_2_rgb.py @@ -1,6 +1,8 @@ +from unittest import TestCase, main + import cv2 import numpy as np -from unittest import TestCase, main + from frigate.util import yuv_region_2_rgb @@ -33,7 +35,7 @@ class TestYuvRegion2RGB(TestCase): # cv2.imwrite(f"bgr_frame.jpg", self.bgr_frame) yuv_frame = cv2.cvtColor(bgr_frame, cv2.COLOR_BGR2YUV_I420) - cropped = yuv_region_2_rgb(yuv_frame, (0, 852, 648, 1500)) + yuv_region_2_rgb(yuv_frame, (0, 852, 648, 1500)) # cv2.imwrite(f"cropped.jpg", cv2.cvtColor(cropped, cv2.COLOR_RGB2BGR)) diff --git a/frigate/timeline.py b/frigate/timeline.py index e40549d08..9ca617ba9 100644 --- a/frigate/timeline.py +++ b/frigate/timeline.py @@ -1,16 +1,14 @@ """Record events for object, audio, etc. detections.""" import logging -import threading import queue +import threading +from multiprocessing.queues import Queue +from multiprocessing.synchronize import Event as MpEvent from frigate.config import FrigateConfig from frigate.events.maintainer import EventTypeEnum from frigate.models import Timeline - -from multiprocessing.queues import Queue -from multiprocessing.synchronize import Event as MpEvent - from frigate.util import to_relative_box logger = logging.getLogger(__name__) diff --git a/frigate/types.py b/frigate/types.py index 3cc401ebb..8c3e54654 100644 --- a/frigate/types.py +++ b/frigate/types.py @@ -1,7 +1,7 @@ -from typing import Optional, TypedDict +from multiprocessing.context import Process from multiprocessing.queues import Queue from multiprocessing.sharedctypes import Synchronized -from multiprocessing.context import Process +from typing import Optional, TypedDict from frigate.object_detection import ObjectDetectProcess diff --git a/frigate/util.py b/frigate/util.py index 47b7b4323..e624e877a 100755 --- a/frigate/util.py +++ b/frigate/util.py @@ -1,28 +1,26 @@ import copy import datetime -import logging -import shlex -import subprocess as sp import json +import logging +import os import re +import shlex import signal +import subprocess as sp import traceback import urllib.parse -import yaml -import os - from abc import ABC, abstractmethod from collections import Counter from collections.abc import Mapping from multiprocessing import shared_memory from typing import Any, AnyStr, Optional, Tuple -import py3nvml.py3nvml as nvml import cv2 import numpy as np -import os import psutil +import py3nvml.py3nvml as nvml import pytz +import yaml from frigate.const import REGEX_HTTP_CAMERA_USER_PASS, REGEX_RTSP_CAMERA_USER_PASS @@ -457,7 +455,7 @@ def copy_yuv_to_position( # clear v2 destination_frame[v2[1] : v2[3], v2[0] : v2[2]] = 128 - if not source_frame is None: + if source_frame is not None: # calculate the resized frame, maintaining the aspect ratio source_aspect_ratio = source_frame.shape[1] / (source_frame.shape[0] // 3 * 2) dest_aspect_ratio = destination_shape[1] / destination_shape[0] @@ -840,7 +838,7 @@ def get_cpu_stats() -> dict[str, dict]: "mem": f"{mem_pct}", "cmdline": " ".join(cmdline), } - except: + except Exception: continue return usages @@ -865,13 +863,13 @@ def get_bandwidth_stats() -> dict[str, dict]: stats = list(filter(lambda a: a != "", line.strip().split("\t"))) try: if re.search( - "(^ffmpeg|\/go2rtc|frigate\.detector\.[a-z]+)/([0-9]+)/", stats[0] + r"(^ffmpeg|\/go2rtc|frigate\.detector\.[a-z]+)/([0-9]+)/", stats[0] ): process = stats[0].split("/") usages[process[len(process) - 2]] = { "bandwidth": round(float(stats[1]) + float(stats[2]), 1), } - except: + except (IndexError, ValueError): continue return usages @@ -932,7 +930,7 @@ def get_intel_gpu_stats() -> dict[str, str]: # render is used for qsv render = [] - for result in re.findall('"Render/3D/0":{[a-z":\d.,%]+}', reading): + for result in re.findall(r'"Render/3D/0":{[a-z":\d.,%]+}', reading): packet = json.loads(result[14:]) single = packet.get("busy", 0.0) render.append(float(single)) @@ -991,11 +989,11 @@ def get_nvidia_gpu_stats() -> dict[int, dict]: "gpu": gpu_util, "mem": gpu_mem_util, } - except: + except Exception: + pass + finally: return results - return results - def ffprobe_stream(path: str) -> sp.CompletedProcess: """Run ffprobe on stream.""" diff --git a/frigate/video.py b/frigate/video.py index a3356a586..f7ec08e99 100755 --- a/frigate/video.py +++ b/frigate/video.py @@ -10,15 +10,15 @@ import threading import time from collections import defaultdict -import numpy as np import cv2 +import numpy as np from setproctitle import setproctitle from frigate.config import CameraConfig, DetectConfig, PixelFormatEnum from frigate.const import CACHE_DIR -from frigate.object_detection import RemoteObjectDetector from frigate.log import LogPipe from frigate.motion import MotionDetector +from frigate.object_detection import RemoteObjectDetector from frigate.objects import ObjectTracker from frigate.util import ( EventsPerSecond, @@ -30,8 +30,8 @@ from frigate.util import ( intersection, intersection_over_union, listen, - yuv_region_2_rgb, yuv_region_2_bgr, + yuv_region_2_rgb, yuv_region_2_yuv, ) @@ -45,7 +45,7 @@ def filtered(obj, objects_to_track, object_filters): object_area = obj[3] object_ratio = obj[4] - if not object_name in objects_to_track: + if object_name not in objects_to_track: return True if object_name in object_filters: @@ -73,7 +73,7 @@ def filtered(obj, objects_to_track, object_filters): if obj_settings.max_ratio < object_ratio: return True - if not obj_settings.mask is None: + if obj_settings.mask is not None: # compute the coordinates of the object and make sure # the location isn't outside the bounds of the image (can happen from rounding) object_xmin = object_box[0] @@ -169,20 +169,20 @@ def capture_frames( skipped_eps.start() while True: fps.value = frame_rate.eps() - skipped_fps = skipped_eps.eps() + skipped_eps.eps() current_frame.value = datetime.datetime.now().timestamp() frame_name = f"{camera_name}{current_frame.value}" frame_buffer = frame_manager.create(frame_name, frame_size) try: frame_buffer[:] = ffmpeg_process.stdout.read(frame_size) - except Exception as e: + except Exception: # shutdown has been initiated if stop_event.is_set(): break logger.error(f"{camera_name}: Unable to read frames from ffmpeg process.") - if ffmpeg_process.poll() != None: + if ffmpeg_process.poll() is not None: logger.error( f"{camera_name}: ffmpeg process is not running. exiting capture thread..." ) @@ -604,7 +604,7 @@ def process_frames( while not stop_event.is_set(): if exit_on_empty and frame_queue.empty(): - logger.info(f"Exiting track_objects...") + logger.info("Exiting track_objects...") break try: @@ -655,7 +655,7 @@ def process_frames( tracked_object_boxes = [ obj["box"] for obj in object_tracker.tracked_objects.values() - if not obj["id"] in stationary_object_ids + if obj["id"] not in stationary_object_ids ] # combine motion boxes with known locations of existing objects diff --git a/frigate/watchdog.py b/frigate/watchdog.py index 5df826f0e..d1573f0b0 100644 --- a/frigate/watchdog.py +++ b/frigate/watchdog.py @@ -2,12 +2,10 @@ import datetime import logging import threading import time -import os -import signal +from multiprocessing.synchronize import Event as MpEvent from frigate.object_detection import ObjectDetectProcess from frigate.util import restart_frigate -from multiprocessing.synchronize import Event as MpEvent logger = logging.getLogger(__name__) @@ -39,4 +37,4 @@ class FrigateWatchdog(threading.Thread): logger.info("Detection appears to have stopped. Exiting Frigate...") restart_frigate() - logger.info(f"Exiting watchdog...") + logger.info("Exiting watchdog...") diff --git a/migrations/001_create_events_table.py b/migrations/001_create_events_table.py index d9b0f0853..9e8ad1b60 100644 --- a/migrations/001_create_events_table.py +++ b/migrations/001_create_events_table.py @@ -21,14 +21,7 @@ Some examples (model - class or model name):: """ -import datetime as dt import peewee as pw -from decimal import ROUND_HALF_EVEN - -try: - import playhouse.postgres_ext as pw_pext -except ImportError: - pass SQL = pw.SQL diff --git a/migrations/002_add_clip_snapshot.py b/migrations/002_add_clip_snapshot.py index aaa4a03c9..1431c9c85 100644 --- a/migrations/002_add_clip_snapshot.py +++ b/migrations/002_add_clip_snapshot.py @@ -21,15 +21,9 @@ Some examples (model - class or model name):: """ -import datetime as dt import peewee as pw -from decimal import ROUND_HALF_EVEN -from frigate.models import Event -try: - import playhouse.postgres_ext as pw_pext -except ImportError: - pass +from frigate.models import Event SQL = pw.SQL diff --git a/migrations/003_create_recordings_table.py b/migrations/003_create_recordings_table.py index e13ae657e..82b15eb9c 100644 --- a/migrations/003_create_recordings_table.py +++ b/migrations/003_create_recordings_table.py @@ -22,8 +22,6 @@ Some examples (model - class or model name):: """ import peewee as pw -from frigate.models import Recordings - SQL = pw.SQL diff --git a/migrations/004_add_bbox_region_area.py b/migrations/004_add_bbox_region_area.py index bcc362aac..da4ca7ac8 100644 --- a/migrations/004_add_bbox_region_area.py +++ b/migrations/004_add_bbox_region_area.py @@ -21,16 +21,10 @@ Some examples (model - class or model name):: """ -import datetime as dt import peewee as pw -from playhouse.sqlite_ext import * -from decimal import ROUND_HALF_EVEN -from frigate.models import Event +from playhouse.sqlite_ext import JSONField -try: - import playhouse.postgres_ext as pw_pext -except ImportError: - pass +from frigate.models import Event SQL = pw.SQL diff --git a/migrations/005_make_end_time_nullable.py b/migrations/005_make_end_time_nullable.py index 5c8cf6505..87d0e3fd4 100644 --- a/migrations/005_make_end_time_nullable.py +++ b/migrations/005_make_end_time_nullable.py @@ -21,16 +21,9 @@ Some examples (model - class or model name):: """ -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 +from frigate.models import Event SQL = pw.SQL diff --git a/migrations/006_add_motion_active_objects.py b/migrations/006_add_motion_active_objects.py index 6bd564b8c..2980b441d 100644 --- a/migrations/006_add_motion_active_objects.py +++ b/migrations/006_add_motion_active_objects.py @@ -21,16 +21,9 @@ Some examples (model - class or model name):: """ -import datetime as dt import peewee as pw -from playhouse.sqlite_ext import * -from decimal import ROUND_HALF_EVEN -from frigate.models import Recordings -try: - import playhouse.postgres_ext as pw_pext -except ImportError: - pass +from frigate.models import Recordings SQL = pw.SQL diff --git a/migrations/007_add_retain_indefinitely.py b/migrations/007_add_retain_indefinitely.py index a46b72e29..cb5f9da92 100644 --- a/migrations/007_add_retain_indefinitely.py +++ b/migrations/007_add_retain_indefinitely.py @@ -21,16 +21,9 @@ Some examples (model - class or model name):: """ -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 +from frigate.models import Event SQL = pw.SQL diff --git a/migrations/008_add_sub_label.py b/migrations/008_add_sub_label.py index 00603c63e..56c4bb75a 100644 --- a/migrations/008_add_sub_label.py +++ b/migrations/008_add_sub_label.py @@ -21,16 +21,9 @@ Some examples (model - class or model name):: """ -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 +from frigate.models import Event SQL = pw.SQL diff --git a/migrations/009_add_object_filter_ratio.py b/migrations/009_add_object_filter_ratio.py index cc23e1d86..e5a00683d 100644 --- a/migrations/009_add_object_filter_ratio.py +++ b/migrations/009_add_object_filter_ratio.py @@ -22,6 +22,7 @@ Some examples (model - class or model name):: """ import peewee as pw + from frigate.models import Event SQL = pw.SQL diff --git a/migrations/010_add_plus_image_id.py b/migrations/010_add_plus_image_id.py index 0e239e58b..6b8c7ccc6 100644 --- a/migrations/010_add_plus_image_id.py +++ b/migrations/010_add_plus_image_id.py @@ -21,16 +21,9 @@ Some examples (model - class or model name):: """ -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 +from frigate.models import Event SQL = pw.SQL diff --git a/migrations/012_add_segment_size.py b/migrations/012_add_segment_size.py index c5ac1ed93..7a1c79736 100644 --- a/migrations/012_add_segment_size.py +++ b/migrations/012_add_segment_size.py @@ -21,16 +21,9 @@ Some examples (model - class or model name):: """ -import datetime as dt import peewee as pw -from playhouse.sqlite_ext import * -from decimal import ROUND_HALF_EVEN -from frigate.models import Recordings -try: - import playhouse.postgres_ext as pw_pext -except ImportError: - pass +from frigate.models import Recordings SQL = pw.SQL diff --git a/migrations/013_create_timeline_table.py b/migrations/013_create_timeline_table.py index fea7867af..7a83d96c7 100644 --- a/migrations/013_create_timeline_table.py +++ b/migrations/013_create_timeline_table.py @@ -21,16 +21,7 @@ Some examples (model - class or model name):: """ -import datetime as dt import peewee as pw -from playhouse.sqlite_ext import * -from decimal import ROUND_HALF_EVEN -from frigate.models import Recordings - -try: - import playhouse.postgres_ext as pw_pext -except ImportError: - pass SQL = pw.SQL @@ -39,9 +30,15 @@ def migrate(migrator, database, fake=False, **kwargs): migrator.sql( 'CREATE TABLE IF NOT EXISTS "timeline" ("timestamp" DATETIME NOT NULL, "camera" VARCHAR(20) NOT NULL, "source" VARCHAR(20) NOT NULL, "source_id" VARCHAR(30), "class_type" VARCHAR(50) NOT NULL, "data" JSON)' ) - migrator.sql('CREATE INDEX IF NOT EXISTS "timeline_camera" ON "timeline" ("camera")') - migrator.sql('CREATE INDEX IF NOT EXISTS "timeline_source" ON "timeline" ("source")') - migrator.sql('CREATE INDEX IF NOT EXISTS "timeline_source_id" ON "timeline" ("source_id")') + migrator.sql( + 'CREATE INDEX IF NOT EXISTS "timeline_camera" ON "timeline" ("camera")' + ) + migrator.sql( + 'CREATE INDEX IF NOT EXISTS "timeline_source" ON "timeline" ("source")' + ) + migrator.sql( + 'CREATE INDEX IF NOT EXISTS "timeline_source_id" ON "timeline" ("source_id")' + ) def rollback(migrator, database, fake=False, **kwargs): diff --git a/migrations/014_event_updates_for_fp.py b/migrations/014_event_updates_for_fp.py index 5d075596b..caa609bfa 100644 --- a/migrations/014_event_updates_for_fp.py +++ b/migrations/014_event_updates_for_fp.py @@ -21,16 +21,9 @@ Some examples (model - class or model name):: """ -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 +from frigate.models import Event SQL = pw.SQL diff --git a/migrations/015_event_refactor.py b/migrations/015_event_refactor.py index d8a8a387c..1bcb9c510 100644 --- a/migrations/015_event_refactor.py +++ b/migrations/015_event_refactor.py @@ -21,16 +21,10 @@ Some examples (model - class or model name):: """ -import datetime as dt import peewee as pw -from playhouse.sqlite_ext import * -from decimal import ROUND_HALF_EVEN -from frigate.models import Event +from playhouse.sqlite_ext import JSONField -try: - import playhouse.postgres_ext as pw_pext -except ImportError: - pass +from frigate.models import Event SQL = pw.SQL diff --git a/migrations/016_sublabel_increase.py b/migrations/016_sublabel_increase.py index b46b9fc79..536ea0a61 100644 --- a/migrations/016_sublabel_increase.py +++ b/migrations/016_sublabel_increase.py @@ -1,6 +1,5 @@ import peewee as pw -from playhouse.migrate import * -from playhouse.sqlite_ext import * + from frigate.models import Event diff --git a/process_clip.py b/process_clip.py index d8dabbedd..9eb6f324b 100644 --- a/process_clip.py +++ b/process_clip.py @@ -1,8 +1,4 @@ -import sys -from typing_extensions import runtime - -sys.path.append("/lab/frigate") - +import csv import json import logging import multiprocessing as mp @@ -11,21 +7,26 @@ import subprocess as sp import sys import click -import csv import cv2 import numpy as np -from frigate.config import FrigateConfig -from frigate.object_detection import LocalObjectDetector -from frigate.motion import MotionDetector -from frigate.object_processing import CameraState -from frigate.objects import ObjectTracker -from frigate.util import ( +sys.path.append("/lab/frigate") + +from frigate.config import FrigateConfig # noqa: E402 +from frigate.motion import MotionDetector # noqa: E402 +from frigate.object_detection import LocalObjectDetector # noqa: E402 +from frigate.object_processing import CameraState # noqa: E402 +from frigate.objects import ObjectTracker # noqa: E402 +from frigate.util import ( # noqa: E402 EventsPerSecond, SharedMemoryFrameManager, draw_box_with_label, ) -from frigate.video import capture_frames, process_frames, start_or_restart_ffmpeg +from frigate.video import ( # noqa: E402 + capture_frames, + process_frames, + start_or_restart_ffmpeg, +) logging.basicConfig() logging.root.setLevel(logging.DEBUG) @@ -310,7 +311,6 @@ def process(path, label, output, debug_path): for result in results: if count == 0: - # Writing headers of CSV file header = ["file"] + list(result[1].keys()) csv_writer.writerow(header) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..e3ef3faf5 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,5 @@ +[tool.isort] +profile = "black" + +[tool.ruff] +ignore = ["E501"] \ No newline at end of file diff --git a/requirements-dev.txt b/requirements-dev.txt index 29f004455..0acd15ae4 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,2 +1,3 @@ -pylint == 2.17.* black == 23.3.* +isort +ruff From bd1d13d78c4ee7bcc5c45f431686a85548e47341 Mon Sep 17 00:00:00 2001 From: Paul Philippov Date: Wed, 31 May 2023 08:15:01 -0400 Subject: [PATCH 2/8] Update docs link (#6657) --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index eb435c5b6..bd4aded51 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,4 +2,4 @@ This website is built using [Docusaurus 2](https://v2.docusaurus.io/), a modern static website generator. -For installation and contributing instructions, please follow the [Contributing Docs](https://blakeblackshear.github.io/frigate/contributing). +For installation and contributing instructions, please follow the [Contributing Docs](https://docs.frigate.video/development/contributing). From ae0aba44dc4584d6f21fee25ca1d289ef3ba155a Mon Sep 17 00:00:00 2001 From: Blake Blackshear Date: Wed, 31 May 2023 10:12:43 -0400 Subject: [PATCH 3/8] Improve tracking (#6516) --- .devcontainer/devcontainer.json | 7 +- frigate/log.py | 2 + frigate/track/__init__.py | 13 + .../{objects.py => track/centroid_tracker.py} | 17 +- frigate/track/norfair_tracker.py | 285 ++++++++++++++++++ frigate/video.py | 16 +- process_clip.py | 10 +- requirements-wheels.txt | 1 + 8 files changed, 332 insertions(+), 19 deletions(-) create mode 100644 frigate/track/__init__.py rename frigate/{objects.py => track/centroid_tracker.py} (95%) create mode 100644 frigate/track/norfair_tracker.py diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 60065a965..a8264a227 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -53,7 +53,8 @@ "csstools.postcss", "blanu.vscode-styled-jsx", "bradlc.vscode-tailwindcss", - "ms-python.isort" + "ms-python.isort", + "charliermarsh.ruff" ], "settings": { "remote.autoForwardPorts": false, @@ -69,9 +70,7 @@ "python.testing.unittestArgs": ["-v", "-s", "./frigate/test"], "files.trimTrailingWhitespace": true, "eslint.workingDirectories": ["./web"], - "isort.args": [ - "--settings-path=./pyproject.toml" - ], + "isort.args": ["--settings-path=./pyproject.toml"], "[python]": { "editor.defaultFormatter": "ms-python.black-formatter", "editor.formatOnSave": true diff --git a/frigate/log.py b/frigate/log.py index 4a44545ad..5dbf4eed0 100644 --- a/frigate/log.py +++ b/frigate/log.py @@ -62,6 +62,8 @@ def log_process(log_queue: Queue) -> None: if stop_event.is_set(): break continue + if record.msg.startswith("You are using a scalar distance function"): + continue logger = logging.getLogger(record.name) logger.handle(record) diff --git a/frigate/track/__init__.py b/frigate/track/__init__.py new file mode 100644 index 000000000..421a968da --- /dev/null +++ b/frigate/track/__init__.py @@ -0,0 +1,13 @@ +from abc import ABC, abstractmethod + +from frigate.config import DetectConfig + + +class ObjectTracker(ABC): + @abstractmethod + def __init__(self, config: DetectConfig): + pass + + @abstractmethod + def match_and_update(self, detections): + pass diff --git a/frigate/objects.py b/frigate/track/centroid_tracker.py similarity index 95% rename from frigate/objects.py rename to frigate/track/centroid_tracker.py index d11aff293..fd4a293f9 100644 --- a/frigate/objects.py +++ b/frigate/track/centroid_tracker.py @@ -6,10 +6,11 @@ import numpy as np from scipy.spatial import distance as dist from frigate.config import DetectConfig +from frigate.track import ObjectTracker from frigate.util import intersection_over_union -class ObjectTracker: +class CentroidTracker(ObjectTracker): def __init__(self, config: DetectConfig): self.tracked_objects = {} self.disappeared = {} @@ -134,11 +135,11 @@ class ObjectTracker: if self.is_expired(id): self.deregister(id) - def match_and_update(self, frame_time, new_objects): + def match_and_update(self, frame_time, detections): # group by name - new_object_groups = defaultdict(lambda: []) - for obj in new_objects: - new_object_groups[obj[0]].append( + detection_groups = defaultdict(lambda: []) + for obj in detections: + detection_groups[obj[0]].append( { "label": obj[0], "score": obj[1], @@ -153,17 +154,17 @@ class ObjectTracker: # update any tracked objects with labels that are not # seen in the current objects and deregister if needed for obj in list(self.tracked_objects.values()): - if obj["label"] not in new_object_groups: + if obj["label"] not in detection_groups: if self.disappeared[obj["id"]] >= self.max_disappeared: self.deregister(obj["id"]) else: self.disappeared[obj["id"]] += 1 - if len(new_objects) == 0: + if len(detections) == 0: return # track objects for each label type - for label, group in new_object_groups.items(): + for label, group in detection_groups.items(): current_objects = [ o for o in self.tracked_objects.values() if o["label"] == label ] diff --git a/frigate/track/norfair_tracker.py b/frigate/track/norfair_tracker.py new file mode 100644 index 000000000..76f50fd73 --- /dev/null +++ b/frigate/track/norfair_tracker.py @@ -0,0 +1,285 @@ +import random +import string + +import numpy as np +from norfair import Detection, Drawable, Tracker, draw_boxes +from norfair.drawing.drawer import Drawer + +from frigate.config import DetectConfig +from frigate.track import ObjectTracker +from frigate.util import intersection_over_union + + +# Normalizes distance from estimate relative to object size +# Other ideas: +# - if estimates are inaccurate for first N detections, compare with last_detection (may be fine) +# - could be variable based on time since last_detection +# - include estimated velocity in the distance (car driving by of a parked car) +# - include some visual similarity factor in the distance for occlusions +def distance(detection: np.array, estimate: np.array) -> float: + # ultimately, this should try and estimate distance in 3-dimensional space + # consider change in location, width, and height + + estimate_dim = np.diff(estimate, axis=0).flatten() + detection_dim = np.diff(detection, axis=0).flatten() + + # get bottom center positions + detection_position = np.array( + [np.average(detection[:, 0]), np.max(detection[:, 1])] + ) + estimate_position = np.array([np.average(estimate[:, 0]), np.max(estimate[:, 1])]) + + distance = (detection_position - estimate_position).astype(float) + # change in x relative to w + distance[0] /= estimate_dim[0] + # change in y relative to h + distance[1] /= estimate_dim[1] + + # get ratio of widths and heights + # normalize to 1 + widths = np.sort([estimate_dim[0], detection_dim[0]]) + heights = np.sort([estimate_dim[1], detection_dim[1]]) + width_ratio = widths[1] / widths[0] - 1.0 + height_ratio = heights[1] / heights[0] - 1.0 + + # change vector is relative x,y change and w,h ratio + change = np.append(distance, np.array([width_ratio, height_ratio])) + + # calculate euclidean distance of the change vector + return np.linalg.norm(change) + + +def frigate_distance(detection: Detection, tracked_object) -> float: + return distance(detection.points, tracked_object.estimate) + + +class NorfairTracker(ObjectTracker): + def __init__(self, config: DetectConfig): + self.tracked_objects = {} + self.disappeared = {} + self.positions = {} + self.max_disappeared = config.max_disappeared + self.detect_config = config + self.track_id_map = {} + # TODO: could also initialize a tracker per object class if there + # was a good reason to have different distance calculations + self.tracker = Tracker( + distance_function=frigate_distance, + distance_threshold=2.5, + initialization_delay=0, + hit_counter_max=self.max_disappeared, + ) + + def register(self, track_id, obj): + rand_id = "".join(random.choices(string.ascii_lowercase + string.digits, k=6)) + id = f"{obj['frame_time']}-{rand_id}" + self.track_id_map[track_id] = id + obj["id"] = id + obj["start_time"] = obj["frame_time"] + obj["motionless_count"] = 0 + obj["position_changes"] = 0 + self.tracked_objects[id] = obj + self.disappeared[id] = 0 + self.positions[id] = { + "xmins": [], + "ymins": [], + "xmaxs": [], + "ymaxs": [], + "xmin": 0, + "ymin": 0, + "xmax": self.detect_config.width, + "ymax": self.detect_config.height, + } + + def deregister(self, id): + del self.tracked_objects[id] + del self.disappeared[id] + + # tracks the current position of the object based on the last N bounding boxes + # returns False if the object has moved outside its previous position + def update_position(self, id, box): + position = self.positions[id] + position_box = ( + position["xmin"], + position["ymin"], + position["xmax"], + position["ymax"], + ) + + xmin, ymin, xmax, ymax = box + + iou = intersection_over_union(position_box, box) + + # if the iou drops below the threshold + # assume the object has moved to a new position and reset the computed box + if iou < 0.6: + self.positions[id] = { + "xmins": [xmin], + "ymins": [ymin], + "xmaxs": [xmax], + "ymaxs": [ymax], + "xmin": xmin, + "ymin": ymin, + "xmax": xmax, + "ymax": ymax, + } + return False + + # if there are less than 10 entries for the position, add the bounding box + # and recompute the position box + if len(position["xmins"]) < 10: + position["xmins"].append(xmin) + position["ymins"].append(ymin) + position["xmaxs"].append(xmax) + position["ymaxs"].append(ymax) + # by using percentiles here, we hopefully remove outliers + position["xmin"] = np.percentile(position["xmins"], 15) + position["ymin"] = np.percentile(position["ymins"], 15) + position["xmax"] = np.percentile(position["xmaxs"], 85) + position["ymax"] = np.percentile(position["ymaxs"], 85) + + return True + + def is_expired(self, id): + obj = self.tracked_objects[id] + # get the max frames for this label type or the default + max_frames = self.detect_config.stationary.max_frames.objects.get( + obj["label"], self.detect_config.stationary.max_frames.default + ) + + # if there is no max_frames for this label type, continue + if max_frames is None: + return False + + # if the object has exceeded the max_frames setting, deregister + if ( + obj["motionless_count"] - self.detect_config.stationary.threshold + > max_frames + ): + return True + + return False + + def update(self, track_id, obj): + id = self.track_id_map[track_id] + self.disappeared[id] = 0 + # update the motionless count if the object has not moved to a new position + if self.update_position(id, obj["box"]): + self.tracked_objects[id]["motionless_count"] += 1 + if self.is_expired(id): + self.deregister(id) + return + else: + # register the first position change and then only increment if + # the object was previously stationary + if ( + self.tracked_objects[id]["position_changes"] == 0 + or self.tracked_objects[id]["motionless_count"] + >= self.detect_config.stationary.threshold + ): + self.tracked_objects[id]["position_changes"] += 1 + self.tracked_objects[id]["motionless_count"] = 0 + + self.tracked_objects[id].update(obj) + + def update_frame_times(self, frame_time): + # if the object was there in the last frame, assume it's still there + detections = [ + ( + obj["label"], + obj["score"], + obj["box"], + obj["area"], + obj["ratio"], + obj["region"], + ) + for id, obj in self.tracked_objects.items() + if self.disappeared[id] == 0 + ] + self.match_and_update(frame_time, detections=detections) + + def match_and_update(self, frame_time, detections): + norfair_detections = [] + + for obj in detections: + # centroid is used for other things downstream + centroid_x = int((obj[2][0] + obj[2][2]) / 2.0) + centroid_y = int((obj[2][1] + obj[2][3]) / 2.0) + + # track based on top,left and bottom,right corners instead of centroid + points = np.array([[obj[2][0], obj[2][1]], [obj[2][2], obj[2][3]]]) + + norfair_detections.append( + Detection( + points=points, + label=obj[0], + data={ + "label": obj[0], + "score": obj[1], + "box": obj[2], + "area": obj[3], + "ratio": obj[4], + "region": obj[5], + "frame_time": frame_time, + "centroid": (centroid_x, centroid_y), + }, + ) + ) + + tracked_objects = self.tracker.update(detections=norfair_detections) + + # update or create new tracks + active_ids = [] + for t in tracked_objects: + active_ids.append(t.global_id) + if t.global_id not in self.track_id_map: + self.register(t.global_id, t.last_detection.data) + # if there wasn't a detection in this frame, increment disappeared + elif t.last_detection.data["frame_time"] != frame_time: + id = self.track_id_map[t.global_id] + self.disappeared[id] += 1 + # else update it + else: + self.update(t.global_id, t.last_detection.data) + + # clear expired tracks + expired_ids = [k for k in self.track_id_map.keys() if k not in active_ids] + for e_id in expired_ids: + self.deregister(self.track_id_map[e_id]) + del self.track_id_map[e_id] + + def debug_draw(self, frame, frame_time): + active_detections = [ + Drawable(id=obj.id, points=obj.last_detection.points, label=obj.label) + for obj in self.tracker.tracked_objects + if obj.last_detection.data["frame_time"] == frame_time + ] + missing_detections = [ + Drawable(id=obj.id, points=obj.last_detection.points, label=obj.label) + for obj in self.tracker.tracked_objects + if obj.last_detection.data["frame_time"] != frame_time + ] + # draw the estimated bounding box + draw_boxes(frame, self.tracker.tracked_objects, color="green", draw_ids=True) + # draw the detections that were detected in the current frame + draw_boxes(frame, active_detections, color="blue", draw_ids=True) + # draw the detections that are missing in the current frame + draw_boxes(frame, missing_detections, color="red", draw_ids=True) + + # draw the distance calculation for the last detection + # estimate vs detection + for obj in self.tracker.tracked_objects: + ld = obj.last_detection + # bottom right + text_anchor = ( + ld.points[1, 0], + ld.points[1, 1], + ) + frame = Drawer.text( + frame, + f"{obj.id}: {str(obj.last_distance)}", + position=text_anchor, + size=None, + color=(255, 0, 0), + thickness=None, + ) diff --git a/frigate/video.py b/frigate/video.py index f7ec08e99..08808038e 100755 --- a/frigate/video.py +++ b/frigate/video.py @@ -19,7 +19,8 @@ from frigate.const import CACHE_DIR from frigate.log import LogPipe from frigate.motion import MotionDetector from frigate.object_detection import RemoteObjectDetector -from frigate.objects import ObjectTracker +from frigate.track import ObjectTracker +from frigate.track.norfair_tracker import NorfairTracker from frigate.util import ( EventsPerSecond, FrameManager, @@ -472,7 +473,7 @@ def track_camera( name, labelmap, detection_queue, result_connection, model_config, stop_event ) - object_tracker = ObjectTracker(config.detect) + object_tracker = NorfairTracker(config.detect) frame_manager = SharedMemoryFrameManager() @@ -847,6 +848,17 @@ def process_frames( else: object_tracker.update_frame_times(frame_time) + # debug tracking by writing frames + if False: + bgr_frame = cv2.cvtColor( + frame, + cv2.COLOR_YUV2BGR_I420, + ) + object_tracker.debug_draw(bgr_frame, frame_time) + cv2.imwrite( + f"debug/frames/track-{'{:.6f}'.format(frame_time)}.jpg", bgr_frame + ) + # add to the queue if not full if detected_objects_queue.full(): frame_manager.delete(f"{camera_name}{frame_time}") diff --git a/process_clip.py b/process_clip.py index 9eb6f324b..16bf7afa4 100644 --- a/process_clip.py +++ b/process_clip.py @@ -10,13 +10,13 @@ import click import cv2 import numpy as np -sys.path.append("/lab/frigate") +sys.path.append("/workspace/frigate") from frigate.config import FrigateConfig # noqa: E402 from frigate.motion import MotionDetector # noqa: E402 from frigate.object_detection import LocalObjectDetector # noqa: E402 from frigate.object_processing import CameraState # noqa: E402 -from frigate.objects import ObjectTracker # noqa: E402 +from frigate.track.centroid_tracker import CentroidTracker # noqa: E402 from frigate.util import ( # noqa: E402 EventsPerSecond, SharedMemoryFrameManager, @@ -108,7 +108,7 @@ class ProcessClip: motion_detector = MotionDetector(self.frame_shape, self.camera_config.motion) motion_detector.save_images = False - object_tracker = ObjectTracker(self.camera_config.detect) + object_tracker = CentroidTracker(self.camera_config.detect) process_info = { "process_fps": mp.Value("d", 0.0), "detection_fps": mp.Value("d", 0.0), @@ -248,7 +248,7 @@ def process(path, label, output, debug_path): clips.append(path) json_config = { - "mqtt": {"host": "mqtt"}, + "mqtt": {"enabled": False}, "detectors": {"coral": {"type": "edgetpu", "device": "usb"}}, "cameras": { "camera": { @@ -282,7 +282,7 @@ def process(path, label, output, debug_path): json_config["cameras"]["camera"]["ffmpeg"]["inputs"][0]["path"] = c frigate_config = FrigateConfig(**json_config) - runtime_config = frigate_config.runtime_config + runtime_config = frigate_config.runtime_config() runtime_config.cameras["camera"].create_ffmpeg_cmds() process_clip = ProcessClip(c, frame_shape, runtime_config) diff --git a/requirements-wheels.txt b/requirements-wheels.txt index d785df5d6..f1f228291 100644 --- a/requirements-wheels.txt +++ b/requirements-wheels.txt @@ -19,6 +19,7 @@ types-PyYAML == 6.0.* requests == 2.30.* types-requests == 2.28.* scipy == 1.10.* +norfair == 2.2.* setproctitle == 1.3.* ws4py == 0.5.* # Openvino Library - Custom built with MYRIAD support From 62f36b221e65a1eecf58174b82fd7bb095d07099 Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Thu, 1 Jun 2023 04:46:34 -0600 Subject: [PATCH 4/8] Remove ffmpeg banner (#6600) * Hide banner in maintainer * Hide banner in event download --- frigate/http.py | 1 + frigate/record/maintainer.py | 1 + 2 files changed, 2 insertions(+) diff --git a/frigate/http.py b/frigate/http.py index 9d7aa2c47..b94637976 100644 --- a/frigate/http.py +++ b/frigate/http.py @@ -1347,6 +1347,7 @@ def recording_clip(camera_name, start_ts, end_ts): if not os.path.exists(path): ffmpeg_cmd = [ "ffmpeg", + "-hide_banner", "-y", "-protocol_whitelist", "pipe,file", diff --git a/frigate/record/maintainer.py b/frigate/record/maintainer.py index afcd6af28..079c4ffa9 100644 --- a/frigate/record/maintainer.py +++ b/frigate/record/maintainer.py @@ -296,6 +296,7 @@ class RecordingMaintainer(threading.Thread): # add faststart to kept segments to improve metadata reading ffmpeg_cmd = [ "ffmpeg", + "-hide_banner", "-y", "-i", cache_path, From 699248d769ed5772ba8373d9c519c35c9e81132f Mon Sep 17 00:00:00 2001 From: Blake Blackshear Date: Thu, 1 Jun 2023 07:59:50 -0400 Subject: [PATCH 5/8] Update deps (#6669) * fix gh host key * python deps * update web deps * update docs deps --- .devcontainer/post_create.sh | 6 + docs/package-lock.json | 1111 +++++++++++++++++----------------- docs/package.json | 4 +- requirements-wheels.txt | 8 +- web/package-lock.json | 940 +++++++++++++--------------- 5 files changed, 1004 insertions(+), 1065 deletions(-) diff --git a/.devcontainer/post_create.sh b/.devcontainer/post_create.sh index 9dd1249c6..9c5dec5bb 100755 --- a/.devcontainer/post_create.sh +++ b/.devcontainer/post_create.sh @@ -2,6 +2,12 @@ set -euxo pipefail +# Cleanup the old github host key +sed -i -e '/AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31\/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi\/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==/d' ~/.ssh/known_hosts +# Add new github host key +curl -L https://api.github.com/meta | jq -r '.ssh_keys | .[]' | \ + sed -e 's/^/github.com /' >> ~/.ssh/known_hosts + # Frigate normal container runs as root, so it have permission to create # the folders. But the devcontainer runs as the host user, so we need to # create the folders and give the host user permission to write to them. diff --git a/docs/package-lock.json b/docs/package-lock.json index 7f946b030..2d808422b 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -8,8 +8,8 @@ "name": "docs", "version": "0.0.0", "dependencies": { - "@docusaurus/core": "^2.4.0", - "@docusaurus/preset-classic": "^2.4.0", + "@docusaurus/core": "^2.4.1", + "@docusaurus/preset-classic": "^2.4.1", "@mdx-js/react": "^1.6.22", "clsx": "^1.2.1", "prism-react-renderer": "^1.3.5", @@ -26,19 +26,19 @@ } }, "node_modules/@algolia/autocomplete-core": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.7.4.tgz", - "integrity": "sha512-daoLpQ3ps/VTMRZDEBfU8ixXd+amZcNJ4QSP3IERGyzqnL5Ch8uSRFt/4G8pUvW9c3o6GA4vtVv4I4lmnkdXyg==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.8.2.tgz", + "integrity": "sha512-mTeshsyFhAqw/ebqNsQpMtbnjr+qVOSKXArEj4K0d7sqc8It1XD0gkASwecm9mF/jlOQ4Z9RNg1HbdA8JPdRwQ==", "dependencies": { - "@algolia/autocomplete-shared": "1.7.4" + "@algolia/autocomplete-shared": "1.8.2" } }, "node_modules/@algolia/autocomplete-preset-algolia": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.7.4.tgz", - "integrity": "sha512-s37hrvLEIfcmKY8VU9LsAXgm2yfmkdHT3DnA3SgHaY93yjZ2qL57wzb5QweVkYuEBZkT2PIREvRoLXC2sxTbpQ==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.8.2.tgz", + "integrity": "sha512-J0oTx4me6ZM9kIKPuL3lyU3aB8DEvpVvR6xWmHVROx5rOYJGQcZsdG4ozxwcOyiiu3qxMkIbzntnV1S1VWD8yA==", "dependencies": { - "@algolia/autocomplete-shared": "1.7.4" + "@algolia/autocomplete-shared": "1.8.2" }, "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", @@ -46,79 +46,79 @@ } }, "node_modules/@algolia/autocomplete-shared": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.7.4.tgz", - "integrity": "sha512-2VGCk7I9tA9Ge73Km99+Qg87w0wzW4tgUruvWAn/gfey1ZXgmxZtyIRBebk35R1O8TbK77wujVtCnpsGpRy1kg==" + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.8.2.tgz", + "integrity": "sha512-b6Z/X4MczChMcfhk6kfRmBzPgjoPzuS9KGR4AFsiLulLNRAAqhP+xZTKtMnZGhLuc61I20d5WqlId02AZvcO6g==" }, "node_modules/@algolia/cache-browser-local-storage": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.17.0.tgz", - "integrity": "sha512-myRSRZDIMYB8uCkO+lb40YKiYHi0fjpWRtJpR/dgkaiBlSD0plRyB6lLOh1XIfmMcSeBOqDE7y9m8xZMrXYfyQ==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.17.1.tgz", + "integrity": "sha512-e91Jpu93X3t3mVdQwF3ZDjSFMFIfzSc+I76G4EX8nl9RYXgqcjframoL05VTjcD2YCsI18RIHAWVCBoCXVZnrw==", "dependencies": { - "@algolia/cache-common": "4.17.0" + "@algolia/cache-common": "4.17.1" } }, "node_modules/@algolia/cache-common": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.17.0.tgz", - "integrity": "sha512-g8mXzkrcUBIPZaulAuqE7xyHhLAYAcF2xSch7d9dABheybaU3U91LjBX6eJTEB7XVhEsgK4Smi27vWtAJRhIKQ==" + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.17.1.tgz", + "integrity": "sha512-fvi1WT8aSiGAKrcTw8Qg3RYgcwW8GZMHcqEm4AyDBEy72JZlFBSY80cTQ75MslINjCHXLDT+9EN8AGI9WVY7uA==" }, "node_modules/@algolia/cache-in-memory": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.17.0.tgz", - "integrity": "sha512-PT32ciC/xI8z919d0oknWVu3kMfTlhQn3MKxDln3pkn+yA7F7xrxSALysxquv+MhFfNAcrtQ/oVvQVBAQSHtdw==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.17.1.tgz", + "integrity": "sha512-NbBt6eBWlsXc5geSpfPRC5dkIB/0Ptthw8r0yM5Z7D3sPlYdnTZSO9y9XWXIptRMwmZe4cM8iBMN8y0tzbcBkA==", "dependencies": { - "@algolia/cache-common": "4.17.0" + "@algolia/cache-common": "4.17.1" } }, "node_modules/@algolia/client-account": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.17.0.tgz", - "integrity": "sha512-sSEHx9GA6m7wrlsSMNBGfyzlIfDT2fkz2u7jqfCCd6JEEwmxt8emGmxAU/0qBfbhRSuGvzojoLJlr83BSZAKjA==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.17.1.tgz", + "integrity": "sha512-3rL/6ofJvyL+q8TiWM3qoM9tig+SY4gB1Vbsj+UeJPnJm8Khm+7OS+r+mFraqR6pTehYqN8yGYoE7x4diEn4aA==", "dependencies": { - "@algolia/client-common": "4.17.0", - "@algolia/client-search": "4.17.0", - "@algolia/transporter": "4.17.0" + "@algolia/client-common": "4.17.1", + "@algolia/client-search": "4.17.1", + "@algolia/transporter": "4.17.1" } }, "node_modules/@algolia/client-analytics": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.17.0.tgz", - "integrity": "sha512-84ooP8QA3mQ958hQ9wozk7hFUbAO+81CX1CjAuerxBqjKIInh1fOhXKTaku05O/GHBvcfExpPLIQuSuLYziBXQ==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.17.1.tgz", + "integrity": "sha512-Bepr2w249vODqeBtM7i++tPmUsQ9B81aupUGbDWmjA/FX+jzQqOdhW8w1CFO5kWViNKTbz2WBIJ9U3x8hOa4bA==", "dependencies": { - "@algolia/client-common": "4.17.0", - "@algolia/client-search": "4.17.0", - "@algolia/requester-common": "4.17.0", - "@algolia/transporter": "4.17.0" + "@algolia/client-common": "4.17.1", + "@algolia/client-search": "4.17.1", + "@algolia/requester-common": "4.17.1", + "@algolia/transporter": "4.17.1" } }, "node_modules/@algolia/client-common": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.17.0.tgz", - "integrity": "sha512-jHMks0ZFicf8nRDn6ma8DNNsdwGgP/NKiAAL9z6rS7CymJ7L0+QqTJl3rYxRW7TmBhsUH40wqzmrG6aMIN/DrQ==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.17.1.tgz", + "integrity": "sha512-+r7kg4EgbFnGsDnoGSVNtXZO8xvZ0vzf1WAOV7sqV9PMf1bp6cpJP/3IuPrSk4t5w2KVl+pC8jfTM7HcFlfBEQ==", "dependencies": { - "@algolia/requester-common": "4.17.0", - "@algolia/transporter": "4.17.0" + "@algolia/requester-common": "4.17.1", + "@algolia/transporter": "4.17.1" } }, "node_modules/@algolia/client-personalization": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.17.0.tgz", - "integrity": "sha512-RMzN4dZLIta1YuwT7QC9o+OeGz2cU6eTOlGNE/6RcUBLOU3l9tkCOdln5dPE2jp8GZXPl2yk54b2nSs1+pAjqw==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.17.1.tgz", + "integrity": "sha512-gJku9DG/THJpfsSlG/az0a3QIn+VVff9kKh8PG8+7ZfxOHS+C+Y5YSeZVsC+c2cfoKLPo3CuHIiJ/p86erR3bA==", "dependencies": { - "@algolia/client-common": "4.17.0", - "@algolia/requester-common": "4.17.0", - "@algolia/transporter": "4.17.0" + "@algolia/client-common": "4.17.1", + "@algolia/requester-common": "4.17.1", + "@algolia/transporter": "4.17.1" } }, "node_modules/@algolia/client-search": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.17.0.tgz", - "integrity": "sha512-x4P2wKrrRIXszT8gb7eWsMHNNHAJs0wE7/uqbufm4tZenAp+hwU/hq5KVsY50v+PfwM0LcDwwn/1DroujsTFoA==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.17.1.tgz", + "integrity": "sha512-Q5YfT5gVkx60PZDQBqp/zH9aUbBdC7HVvxupiHUgnCKqRQsRZjOhLest7AI6FahepuZLBZS62COrO7v+JvKY7w==", "dependencies": { - "@algolia/client-common": "4.17.0", - "@algolia/requester-common": "4.17.0", - "@algolia/transporter": "4.17.0" + "@algolia/client-common": "4.17.1", + "@algolia/requester-common": "4.17.1", + "@algolia/transporter": "4.17.1" } }, "node_modules/@algolia/events": { @@ -127,47 +127,47 @@ "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==" }, "node_modules/@algolia/logger-common": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.17.0.tgz", - "integrity": "sha512-DGuoZqpTmIKJFDeyAJ7M8E/LOenIjWiOsg1XJ1OqAU/eofp49JfqXxbfgctlVZVmDABIyOz8LqEoJ6ZP4DTyvw==" + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.17.1.tgz", + "integrity": "sha512-Us28Ot+fLEmX9M96sa65VZ8EyEEzhYPxfhV9aQyKDjfXbUdJlJxKt6wZpoEg9RAPSdO8IjK9nmuW2P8au3rRsg==" }, "node_modules/@algolia/logger-console": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.17.0.tgz", - "integrity": "sha512-zMPvugQV/gbXUvWBCzihw6m7oxIKp48w37QBIUu/XqQQfxhjoOE9xyfJr1KldUt5FrYOKZJVsJaEjTsu+bIgQg==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.17.1.tgz", + "integrity": "sha512-iKGQTpOjHiE64W3JIOu6dmDvn+AfYIElI9jf/Nt6umRPmP/JI9rK+OHUoW4pKrBtdG0DPd62ppeNXzSnLxY6/g==", "dependencies": { - "@algolia/logger-common": "4.17.0" + "@algolia/logger-common": "4.17.1" } }, "node_modules/@algolia/requester-browser-xhr": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.17.0.tgz", - "integrity": "sha512-aSOX/smauyTkP21Pf52pJ1O2LmNFJ5iHRIzEeTh0mwBeADO4GdG94cAWDILFA9rNblq/nK3EDh3+UyHHjplZ1A==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.17.1.tgz", + "integrity": "sha512-W5mGfGDsyfVR+r4pUFrYLGBEM18gs38+GNt5PE5uPULy4uVTSnnVSkJkWeRkmLBk9zEZ/Nld8m4zavK6dtEuYg==", "dependencies": { - "@algolia/requester-common": "4.17.0" + "@algolia/requester-common": "4.17.1" } }, "node_modules/@algolia/requester-common": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.17.0.tgz", - "integrity": "sha512-XJjmWFEUlHu0ijvcHBoixuXfEoiRUdyzQM6YwTuB8usJNIgShua8ouFlRWF8iCeag0vZZiUm4S2WCVBPkdxFgg==" + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.17.1.tgz", + "integrity": "sha512-HggXdjvVFQR0I5l7hM5WdHgQ1tqcRWeyXZz8apQ7zPWZhirmY2E9D6LVhDh/UnWQNEm7nBtM+eMFONJ3bZccIQ==" }, "node_modules/@algolia/requester-node-http": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.17.0.tgz", - "integrity": "sha512-bpb/wDA1aC6WxxM8v7TsFspB7yBN3nqCGs2H1OADolQR/hiAIjAxusbuMxVbRFOdaUvAIqioIIkWvZdpYNIn8w==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.17.1.tgz", + "integrity": "sha512-NzFWecXT6d0PPsQY9L+/qoK2deF74OLcpvqCH+Vh3mh+QzPsFafcBExdguAjZsAWDn1R6JEeFW7/fo/p0SE57w==", "dependencies": { - "@algolia/requester-common": "4.17.0" + "@algolia/requester-common": "4.17.1" } }, "node_modules/@algolia/transporter": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.17.0.tgz", - "integrity": "sha512-6xL6H6fe+Fi0AEP3ziSgC+G04RK37iRb4uUUqVAH9WPYFI8g+LYFq6iv5HS8Cbuc5TTut+Bwj6G+dh/asdb9uA==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.17.1.tgz", + "integrity": "sha512-ZM+qhX47Vh46mWH8/U9ihvy98HdTYpYQDSlqBD7IbiUbbyoCMke+qmdSX2MGhR2FCcXBSxejsJKKVAfbpaLVgg==", "dependencies": { - "@algolia/cache-common": "4.17.0", - "@algolia/logger-common": "4.17.0", - "@algolia/requester-common": "4.17.0" + "@algolia/cache-common": "4.17.1", + "@algolia/logger-common": "4.17.1", + "@algolia/requester-common": "4.17.1" } }, "node_modules/@ampproject/remapping": { @@ -1938,18 +1938,18 @@ } }, "node_modules/@docsearch/css": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.3.3.tgz", - "integrity": "sha512-6SCwI7P8ao+se1TUsdZ7B4XzL+gqeQZnBc+2EONZlcVa0dVrk0NjETxozFKgMv0eEGH8QzP1fkN+A1rH61l4eg==" + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.4.0.tgz", + "integrity": "sha512-Hg8Xfma+rFwRi6Y/pfei4FJoQ1hdVURmmNs/XPoMTCPAImU+d5yxj+M+qdLtNjWRpfWziU4dQcqY94xgFBn2dg==" }, "node_modules/@docsearch/react": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.3.3.tgz", - "integrity": "sha512-pLa0cxnl+G0FuIDuYlW+EBK6Rw2jwLw9B1RHIeS4N4s2VhsfJ/wzeCi3CWcs5yVfxLd5ZK50t//TMA5e79YT7Q==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.4.0.tgz", + "integrity": "sha512-ufrp5879XYGojgS30ZAp8H4qIMbahRHB9M85VDBP36Xgz5QjYM54i1URKj5e219F7gqTtOivfztFTij6itc0MQ==", "dependencies": { - "@algolia/autocomplete-core": "1.7.4", - "@algolia/autocomplete-preset-algolia": "1.7.4", - "@docsearch/css": "3.3.3", + "@algolia/autocomplete-core": "1.8.2", + "@algolia/autocomplete-preset-algolia": "1.8.2", + "@docsearch/css": "3.4.0", "algoliasearch": "^4.0.0" }, "peerDependencies": { @@ -1970,9 +1970,9 @@ } }, "node_modules/@docusaurus/core": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-2.4.0.tgz", - "integrity": "sha512-J55/WEoIpRcLf3afO5POHPguVZosKmJEQWKBL+K7TAnfuE7i+Y0NPLlkKtnWCehagGsgTqClfQEexH/UT4kELA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-2.4.1.tgz", + "integrity": "sha512-SNsY7PshK3Ri7vtsLXVeAJGS50nJN3RgF836zkyUfAD01Fq+sAk5EwWgLw+nnm5KVNGDu7PRR2kRGDsWvqpo0g==", "dependencies": { "@babel/core": "^7.18.6", "@babel/generator": "^7.18.7", @@ -1984,13 +1984,13 @@ "@babel/runtime": "^7.18.6", "@babel/runtime-corejs3": "^7.18.6", "@babel/traverse": "^7.18.8", - "@docusaurus/cssnano-preset": "2.4.0", - "@docusaurus/logger": "2.4.0", - "@docusaurus/mdx-loader": "2.4.0", + "@docusaurus/cssnano-preset": "2.4.1", + "@docusaurus/logger": "2.4.1", + "@docusaurus/mdx-loader": "2.4.1", "@docusaurus/react-loadable": "5.5.2", - "@docusaurus/utils": "2.4.0", - "@docusaurus/utils-common": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/utils": "2.4.1", + "@docusaurus/utils-common": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "@slorber/static-site-generator-webpack-plugin": "^4.0.7", "@svgr/webpack": "^6.2.1", "autoprefixer": "^10.4.7", @@ -2058,9 +2058,9 @@ } }, "node_modules/@docusaurus/cssnano-preset": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-2.4.0.tgz", - "integrity": "sha512-RmdiA3IpsLgZGXRzqnmTbGv43W4OD44PCo+6Q/aYjEM2V57vKCVqNzuafE94jv0z/PjHoXUrjr69SaRymBKYYw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-2.4.1.tgz", + "integrity": "sha512-ka+vqXwtcW1NbXxWsh6yA1Ckii1klY9E53cJ4O9J09nkMBgrNX3iEFED1fWdv8wf4mJjvGi5RLZ2p9hJNjsLyQ==", "dependencies": { "cssnano-preset-advanced": "^5.3.8", "postcss": "^8.4.14", @@ -2072,9 +2072,9 @@ } }, "node_modules/@docusaurus/logger": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-2.4.0.tgz", - "integrity": "sha512-T8+qR4APN+MjcC9yL2Es+xPJ2923S9hpzDmMtdsOcUGLqpCGBbU1vp3AAqDwXtVgFkq+NsEk7sHdVsfLWR/AXw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-2.4.1.tgz", + "integrity": "sha512-5h5ysIIWYIDHyTVd8BjheZmQZmEgWDR54aQ1BX9pjFfpyzFo5puKXKYrYJXbjEHGyVhEzmB9UXwbxGfaZhOjcg==", "dependencies": { "chalk": "^4.1.2", "tslib": "^2.4.0" @@ -2084,14 +2084,14 @@ } }, "node_modules/@docusaurus/mdx-loader": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-2.4.0.tgz", - "integrity": "sha512-GWoH4izZKOmFoC+gbI2/y8deH/xKLvzz/T5BsEexBye8EHQlwsA7FMrVa48N063bJBH4FUOiRRXxk5rq9cC36g==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-2.4.1.tgz", + "integrity": "sha512-4KhUhEavteIAmbBj7LVFnrVYDiU51H5YWW1zY6SmBSte/YLhDutztLTBE0PQl1Grux1jzUJeaSvAzHpTn6JJDQ==", "dependencies": { "@babel/parser": "^7.18.8", "@babel/traverse": "^7.18.8", - "@docusaurus/logger": "2.4.0", - "@docusaurus/utils": "2.4.0", + "@docusaurus/logger": "2.4.1", + "@docusaurus/utils": "2.4.1", "@mdx-js/mdx": "^1.6.22", "escape-html": "^1.0.3", "file-loader": "^6.2.0", @@ -2115,12 +2115,12 @@ } }, "node_modules/@docusaurus/module-type-aliases": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-2.4.0.tgz", - "integrity": "sha512-YEQO2D3UXs72qCn8Cr+RlycSQXVGN9iEUyuHwTuK4/uL/HFomB2FHSU0vSDM23oLd+X/KibQ3Ez6nGjQLqXcHg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-2.4.1.tgz", + "integrity": "sha512-gLBuIFM8Dp2XOCWffUDSjtxY7jQgKvYujt7Mx5s4FCTfoL5dN1EVbnrn+O2Wvh8b0a77D57qoIDY7ghgmatR1A==", "dependencies": { "@docusaurus/react-loadable": "5.5.2", - "@docusaurus/types": "2.4.0", + "@docusaurus/types": "2.4.1", "@types/history": "^4.7.11", "@types/react": "*", "@types/react-router-config": "*", @@ -2134,17 +2134,17 @@ } }, "node_modules/@docusaurus/plugin-content-blog": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.4.0.tgz", - "integrity": "sha512-YwkAkVUxtxoBAIj/MCb4ohN0SCtHBs4AS75jMhPpf67qf3j+U/4n33cELq7567hwyZ6fMz2GPJcVmctzlGGThQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.4.1.tgz", + "integrity": "sha512-E2i7Knz5YIbE1XELI6RlTnZnGgS52cUO4BlCiCUCvQHbR+s1xeIWz4C6BtaVnlug0Ccz7nFSksfwDpVlkujg5Q==", "dependencies": { - "@docusaurus/core": "2.4.0", - "@docusaurus/logger": "2.4.0", - "@docusaurus/mdx-loader": "2.4.0", - "@docusaurus/types": "2.4.0", - "@docusaurus/utils": "2.4.0", - "@docusaurus/utils-common": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/logger": "2.4.1", + "@docusaurus/mdx-loader": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils": "2.4.1", + "@docusaurus/utils-common": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "cheerio": "^1.0.0-rc.12", "feed": "^4.2.2", "fs-extra": "^10.1.0", @@ -2164,17 +2164,17 @@ } }, "node_modules/@docusaurus/plugin-content-docs": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-2.4.0.tgz", - "integrity": "sha512-ic/Z/ZN5Rk/RQo+Io6rUGpToOtNbtPloMR2JcGwC1xT2riMu6zzfSwmBi9tHJgdXH6CB5jG+0dOZZO8QS5tmDg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-2.4.1.tgz", + "integrity": "sha512-Lo7lSIcpswa2Kv4HEeUcGYqaasMUQNpjTXpV0N8G6jXgZaQurqp7E8NGYeGbDXnb48czmHWbzDL4S3+BbK0VzA==", "dependencies": { - "@docusaurus/core": "2.4.0", - "@docusaurus/logger": "2.4.0", - "@docusaurus/mdx-loader": "2.4.0", - "@docusaurus/module-type-aliases": "2.4.0", - "@docusaurus/types": "2.4.0", - "@docusaurus/utils": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/logger": "2.4.1", + "@docusaurus/mdx-loader": "2.4.1", + "@docusaurus/module-type-aliases": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "@types/react-router-config": "^5.0.6", "combine-promises": "^1.1.0", "fs-extra": "^10.1.0", @@ -2194,15 +2194,15 @@ } }, "node_modules/@docusaurus/plugin-content-pages": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-2.4.0.tgz", - "integrity": "sha512-Pk2pOeOxk8MeU3mrTU0XLIgP9NZixbdcJmJ7RUFrZp1Aj42nd0RhIT14BGvXXyqb8yTQlk4DmYGAzqOfBsFyGw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-2.4.1.tgz", + "integrity": "sha512-/UjuH/76KLaUlL+o1OvyORynv6FURzjurSjvn2lbWTFc4tpYY2qLYTlKpTCBVPhlLUQsfyFnshEJDLmPneq2oA==", "dependencies": { - "@docusaurus/core": "2.4.0", - "@docusaurus/mdx-loader": "2.4.0", - "@docusaurus/types": "2.4.0", - "@docusaurus/utils": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/mdx-loader": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "fs-extra": "^10.1.0", "tslib": "^2.4.0", "webpack": "^5.73.0" @@ -2216,13 +2216,13 @@ } }, "node_modules/@docusaurus/plugin-debug": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-2.4.0.tgz", - "integrity": "sha512-KC56DdYjYT7Txyux71vXHXGYZuP6yYtqwClvYpjKreWIHWus5Zt6VNi23rMZv3/QKhOCrN64zplUbdfQMvddBQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-2.4.1.tgz", + "integrity": "sha512-7Yu9UPzRShlrH/G8btOpR0e6INFZr0EegWplMjOqelIwAcx3PKyR8mgPTxGTxcqiYj6hxSCRN0D8R7YrzImwNA==", "dependencies": { - "@docusaurus/core": "2.4.0", - "@docusaurus/types": "2.4.0", - "@docusaurus/utils": "2.4.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils": "2.4.1", "fs-extra": "^10.1.0", "react-json-view": "^1.21.3", "tslib": "^2.4.0" @@ -2236,13 +2236,13 @@ } }, "node_modules/@docusaurus/plugin-google-analytics": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-2.4.0.tgz", - "integrity": "sha512-uGUzX67DOAIglygdNrmMOvEp8qG03X20jMWadeqVQktS6nADvozpSLGx4J0xbkblhJkUzN21WiilsP9iVP+zkw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-2.4.1.tgz", + "integrity": "sha512-dyZJdJiCoL+rcfnm0RPkLt/o732HvLiEwmtoNzOoz9MSZz117UH2J6U2vUDtzUzwtFLIf32KkeyzisbwUCgcaQ==", "dependencies": { - "@docusaurus/core": "2.4.0", - "@docusaurus/types": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "tslib": "^2.4.0" }, "engines": { @@ -2254,13 +2254,13 @@ } }, "node_modules/@docusaurus/plugin-google-gtag": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-2.4.0.tgz", - "integrity": "sha512-adj/70DANaQs2+TF/nRdMezDXFAV/O/pjAbUgmKBlyOTq5qoMe0Tk4muvQIwWUmiUQxFJe+sKlZGM771ownyOg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-2.4.1.tgz", + "integrity": "sha512-mKIefK+2kGTQBYvloNEKtDmnRD7bxHLsBcxgnbt4oZwzi2nxCGjPX6+9SQO2KCN5HZbNrYmGo5GJfMgoRvy6uA==", "dependencies": { - "@docusaurus/core": "2.4.0", - "@docusaurus/types": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "tslib": "^2.4.0" }, "engines": { @@ -2272,13 +2272,13 @@ } }, "node_modules/@docusaurus/plugin-google-tag-manager": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-2.4.0.tgz", - "integrity": "sha512-E66uGcYs4l7yitmp/8kMEVQftFPwV9iC62ORh47Veqzs6ExwnhzBkJmwDnwIysHBF1vlxnzET0Fl2LfL5fRR3A==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-2.4.1.tgz", + "integrity": "sha512-Zg4Ii9CMOLfpeV2nG74lVTWNtisFaH9QNtEw48R5QE1KIwDBdTVaiSA18G1EujZjrzJJzXN79VhINSbOJO/r3g==", "dependencies": { - "@docusaurus/core": "2.4.0", - "@docusaurus/types": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "tslib": "^2.4.0" }, "engines": { @@ -2290,16 +2290,16 @@ } }, "node_modules/@docusaurus/plugin-sitemap": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-2.4.0.tgz", - "integrity": "sha512-pZxh+ygfnI657sN8a/FkYVIAmVv0CGk71QMKqJBOfMmDHNN1FeDeFkBjWP49ejBqpqAhjufkv5UWq3UOu2soCw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-2.4.1.tgz", + "integrity": "sha512-lZx+ijt/+atQ3FVE8FOHV/+X3kuok688OydDXrqKRJyXBJZKgGjA2Qa8RjQ4f27V2woaXhtnyrdPop/+OjVMRg==", "dependencies": { - "@docusaurus/core": "2.4.0", - "@docusaurus/logger": "2.4.0", - "@docusaurus/types": "2.4.0", - "@docusaurus/utils": "2.4.0", - "@docusaurus/utils-common": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/logger": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils": "2.4.1", + "@docusaurus/utils-common": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "fs-extra": "^10.1.0", "sitemap": "^7.1.1", "tslib": "^2.4.0" @@ -2313,23 +2313,23 @@ } }, "node_modules/@docusaurus/preset-classic": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-2.4.0.tgz", - "integrity": "sha512-/5z5o/9bc6+P5ool2y01PbJhoGddEGsC0ej1MF6mCoazk8A+kW4feoUd68l7Bnv01rCnG3xy7kHUQP97Y0grUA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-2.4.1.tgz", + "integrity": "sha512-P4//+I4zDqQJ+UDgoFrjIFaQ1MeS9UD1cvxVQaI6O7iBmiHQm0MGROP1TbE7HlxlDPXFJjZUK3x3cAoK63smGQ==", "dependencies": { - "@docusaurus/core": "2.4.0", - "@docusaurus/plugin-content-blog": "2.4.0", - "@docusaurus/plugin-content-docs": "2.4.0", - "@docusaurus/plugin-content-pages": "2.4.0", - "@docusaurus/plugin-debug": "2.4.0", - "@docusaurus/plugin-google-analytics": "2.4.0", - "@docusaurus/plugin-google-gtag": "2.4.0", - "@docusaurus/plugin-google-tag-manager": "2.4.0", - "@docusaurus/plugin-sitemap": "2.4.0", - "@docusaurus/theme-classic": "2.4.0", - "@docusaurus/theme-common": "2.4.0", - "@docusaurus/theme-search-algolia": "2.4.0", - "@docusaurus/types": "2.4.0" + "@docusaurus/core": "2.4.1", + "@docusaurus/plugin-content-blog": "2.4.1", + "@docusaurus/plugin-content-docs": "2.4.1", + "@docusaurus/plugin-content-pages": "2.4.1", + "@docusaurus/plugin-debug": "2.4.1", + "@docusaurus/plugin-google-analytics": "2.4.1", + "@docusaurus/plugin-google-gtag": "2.4.1", + "@docusaurus/plugin-google-tag-manager": "2.4.1", + "@docusaurus/plugin-sitemap": "2.4.1", + "@docusaurus/theme-classic": "2.4.1", + "@docusaurus/theme-common": "2.4.1", + "@docusaurus/theme-search-algolia": "2.4.1", + "@docusaurus/types": "2.4.1" }, "engines": { "node": ">=16.14" @@ -2352,22 +2352,22 @@ } }, "node_modules/@docusaurus/theme-classic": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-2.4.0.tgz", - "integrity": "sha512-GMDX5WU6Z0OC65eQFgl3iNNEbI9IMJz9f6KnOyuMxNUR6q0qVLsKCNopFUDfFNJ55UU50o7P7o21yVhkwpfJ9w==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-2.4.1.tgz", + "integrity": "sha512-Rz0wKUa+LTW1PLXmwnf8mn85EBzaGSt6qamqtmnh9Hflkc+EqiYMhtUJeLdV+wsgYq4aG0ANc+bpUDpsUhdnwg==", "dependencies": { - "@docusaurus/core": "2.4.0", - "@docusaurus/mdx-loader": "2.4.0", - "@docusaurus/module-type-aliases": "2.4.0", - "@docusaurus/plugin-content-blog": "2.4.0", - "@docusaurus/plugin-content-docs": "2.4.0", - "@docusaurus/plugin-content-pages": "2.4.0", - "@docusaurus/theme-common": "2.4.0", - "@docusaurus/theme-translations": "2.4.0", - "@docusaurus/types": "2.4.0", - "@docusaurus/utils": "2.4.0", - "@docusaurus/utils-common": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/mdx-loader": "2.4.1", + "@docusaurus/module-type-aliases": "2.4.1", + "@docusaurus/plugin-content-blog": "2.4.1", + "@docusaurus/plugin-content-docs": "2.4.1", + "@docusaurus/plugin-content-pages": "2.4.1", + "@docusaurus/theme-common": "2.4.1", + "@docusaurus/theme-translations": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils": "2.4.1", + "@docusaurus/utils-common": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "@mdx-js/react": "^1.6.22", "clsx": "^1.2.1", "copy-text-to-clipboard": "^3.0.1", @@ -2391,17 +2391,17 @@ } }, "node_modules/@docusaurus/theme-common": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-2.4.0.tgz", - "integrity": "sha512-IkG/l5f/FLY6cBIxtPmFnxpuPzc5TupuqlOx+XDN+035MdQcAh8wHXXZJAkTeYDeZ3anIUSUIvWa7/nRKoQEfg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-2.4.1.tgz", + "integrity": "sha512-G7Zau1W5rQTaFFB3x3soQoZpkgMbl/SYNG8PfMFIjKa3M3q8n0m/GRf5/H/e5BqOvt8c+ZWIXGCiz+kUCSHovA==", "dependencies": { - "@docusaurus/mdx-loader": "2.4.0", - "@docusaurus/module-type-aliases": "2.4.0", - "@docusaurus/plugin-content-blog": "2.4.0", - "@docusaurus/plugin-content-docs": "2.4.0", - "@docusaurus/plugin-content-pages": "2.4.0", - "@docusaurus/utils": "2.4.0", - "@docusaurus/utils-common": "2.4.0", + "@docusaurus/mdx-loader": "2.4.1", + "@docusaurus/module-type-aliases": "2.4.1", + "@docusaurus/plugin-content-blog": "2.4.1", + "@docusaurus/plugin-content-docs": "2.4.1", + "@docusaurus/plugin-content-pages": "2.4.1", + "@docusaurus/utils": "2.4.1", + "@docusaurus/utils-common": "2.4.1", "@types/history": "^4.7.11", "@types/react": "*", "@types/react-router-config": "*", @@ -2421,18 +2421,18 @@ } }, "node_modules/@docusaurus/theme-search-algolia": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-2.4.0.tgz", - "integrity": "sha512-pPCJSCL1Qt4pu/Z0uxBAuke0yEBbxh0s4fOvimna7TEcBLPq0x06/K78AaABXrTVQM6S0vdocFl9EoNgU17hqA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-2.4.1.tgz", + "integrity": "sha512-6BcqW2lnLhZCXuMAvPRezFs1DpmEKzXFKlYjruuas+Xy3AQeFzDJKTJFIm49N77WFCTyxff8d3E4Q9pi/+5McQ==", "dependencies": { "@docsearch/react": "^3.1.1", - "@docusaurus/core": "2.4.0", - "@docusaurus/logger": "2.4.0", - "@docusaurus/plugin-content-docs": "2.4.0", - "@docusaurus/theme-common": "2.4.0", - "@docusaurus/theme-translations": "2.4.0", - "@docusaurus/utils": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/logger": "2.4.1", + "@docusaurus/plugin-content-docs": "2.4.1", + "@docusaurus/theme-common": "2.4.1", + "@docusaurus/theme-translations": "2.4.1", + "@docusaurus/utils": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "algoliasearch": "^4.13.1", "algoliasearch-helper": "^3.10.0", "clsx": "^1.2.1", @@ -2451,9 +2451,9 @@ } }, "node_modules/@docusaurus/theme-translations": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-2.4.0.tgz", - "integrity": "sha512-kEoITnPXzDPUMBHk3+fzEzbopxLD3fR5sDoayNH0vXkpUukA88/aDL1bqkhxWZHA3LOfJ3f0vJbOwmnXW5v85Q==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-2.4.1.tgz", + "integrity": "sha512-T1RAGP+f86CA1kfE8ejZ3T3pUU3XcyvrGMfC/zxCtc2BsnoexuNI9Vk2CmuKCb+Tacvhxjv5unhxXce0+NKyvA==", "dependencies": { "fs-extra": "^10.1.0", "tslib": "^2.4.0" @@ -2463,9 +2463,9 @@ } }, "node_modules/@docusaurus/types": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-2.4.0.tgz", - "integrity": "sha512-xaBXr+KIPDkIaef06c+i2HeTqVNixB7yFut5fBXPGI2f1rrmEV2vLMznNGsFwvZ5XmA3Quuefd4OGRkdo97Dhw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-2.4.1.tgz", + "integrity": "sha512-0R+cbhpMkhbRXX138UOc/2XZFF8hiZa6ooZAEEJFp5scytzCw4tC1gChMFXrpa3d2tYE6AX8IrOEpSonLmfQuQ==", "dependencies": { "@types/history": "^4.7.11", "@types/react": "*", @@ -2482,11 +2482,11 @@ } }, "node_modules/@docusaurus/utils": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-2.4.0.tgz", - "integrity": "sha512-89hLYkvtRX92j+C+ERYTuSUK6nF9bGM32QThcHPg2EDDHVw6FzYQXmX6/p+pU5SDyyx5nBlE4qXR92RxCAOqfg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-2.4.1.tgz", + "integrity": "sha512-1lvEZdAQhKNht9aPXPoh69eeKnV0/62ROhQeFKKxmzd0zkcuE/Oc5Gpnt00y/f5bIsmOsYMY7Pqfm/5rteT5GA==", "dependencies": { - "@docusaurus/logger": "2.4.0", + "@docusaurus/logger": "2.4.1", "@svgr/webpack": "^6.2.1", "escape-string-regexp": "^4.0.0", "file-loader": "^6.2.0", @@ -2516,9 +2516,9 @@ } }, "node_modules/@docusaurus/utils-common": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-2.4.0.tgz", - "integrity": "sha512-zIMf10xuKxddYfLg5cS19x44zud/E9I7lj3+0bv8UIs0aahpErfNrGhijEfJpAfikhQ8tL3m35nH3hJ3sOG82A==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-2.4.1.tgz", + "integrity": "sha512-bCVGdZU+z/qVcIiEQdyx0K13OC5mYwxhSuDUR95oFbKVuXYRrTVrwZIqQljuo1fyJvFTKHiL9L9skQOPokuFNQ==", "dependencies": { "tslib": "^2.4.0" }, @@ -2535,12 +2535,12 @@ } }, "node_modules/@docusaurus/utils-validation": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-2.4.0.tgz", - "integrity": "sha512-IrBsBbbAp6y7mZdJx4S4pIA7dUyWSA0GNosPk6ZJ0fX3uYIEQgcQSGIgTeSC+8xPEx3c16o03en1jSDpgQgz/w==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-2.4.1.tgz", + "integrity": "sha512-unII3hlJlDwZ3w8U+pMO3Lx3RhI4YEbY3YNsQj4yzrkZzlpqZOLuAiZK2JyULnD+TKbceKU0WyWkQXtYbLNDFA==", "dependencies": { - "@docusaurus/logger": "2.4.0", - "@docusaurus/utils": "2.4.0", + "@docusaurus/logger": "2.4.1", + "@docusaurus/utils": "2.4.1", "joi": "^17.6.0", "js-yaml": "^4.1.0", "tslib": "^2.4.0" @@ -3257,9 +3257,9 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" }, "node_modules/@types/mdast": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", - "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==", + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.11.tgz", + "integrity": "sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw==", "dependencies": { "@types/unist": "*" } @@ -3667,30 +3667,30 @@ } }, "node_modules/algoliasearch": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.17.0.tgz", - "integrity": "sha512-JMRh2Mw6sEnVMiz6+APsi7lx9a2jiDFF+WUtANaUVCv6uSU9UOLdo5h9K3pdP6frRRybaM2fX8b1u0nqICS9aA==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.17.1.tgz", + "integrity": "sha512-4GDQ1RhP2qUR3x8PevFRbEdqZqIARNViZYjgTJmA1T7wRNtFA3W4Aqc/RsODqa1J8IO/QDla5x4tWuUS8NV8wA==", "dependencies": { - "@algolia/cache-browser-local-storage": "4.17.0", - "@algolia/cache-common": "4.17.0", - "@algolia/cache-in-memory": "4.17.0", - "@algolia/client-account": "4.17.0", - "@algolia/client-analytics": "4.17.0", - "@algolia/client-common": "4.17.0", - "@algolia/client-personalization": "4.17.0", - "@algolia/client-search": "4.17.0", - "@algolia/logger-common": "4.17.0", - "@algolia/logger-console": "4.17.0", - "@algolia/requester-browser-xhr": "4.17.0", - "@algolia/requester-common": "4.17.0", - "@algolia/requester-node-http": "4.17.0", - "@algolia/transporter": "4.17.0" + "@algolia/cache-browser-local-storage": "4.17.1", + "@algolia/cache-common": "4.17.1", + "@algolia/cache-in-memory": "4.17.1", + "@algolia/client-account": "4.17.1", + "@algolia/client-analytics": "4.17.1", + "@algolia/client-common": "4.17.1", + "@algolia/client-personalization": "4.17.1", + "@algolia/client-search": "4.17.1", + "@algolia/logger-common": "4.17.1", + "@algolia/logger-console": "4.17.1", + "@algolia/requester-browser-xhr": "4.17.1", + "@algolia/requester-common": "4.17.1", + "@algolia/requester-node-http": "4.17.1", + "@algolia/transporter": "4.17.1" } }, "node_modules/algoliasearch-helper": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.12.0.tgz", - "integrity": "sha512-/j1U3PEwdan0n6P/QqSnSpNSLC5+cEMvyljd5CnmNmUjDlGrys+vFEOwjVEnqELIiAGMHEA/Nl3CiKVFBUYqyQ==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.13.0.tgz", + "integrity": "sha512-kV3c1jMQCvkARtGsSDvAwuht4PAMSsQILqPiH4WFiARoa3jXJ/r1TQoBWAjWyWF48rsNYCv7kzxgB4LTxrvvuw==", "dependencies": { "@algolia/events": "^4.0.1" }, @@ -4881,11 +4881,11 @@ } }, "node_modules/cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.6.tgz", + "integrity": "sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==", "dependencies": { - "node-fetch": "2.6.7" + "node-fetch": "^2.6.11" } }, "node_modules/cross-spawn": { @@ -5447,13 +5447,13 @@ } }, "node_modules/domutils": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", - "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", - "domhandler": "^5.0.1" + "domhandler": "^5.0.3" }, "funding": { "url": "https://github.com/fb55/domutils?sponsor=1" @@ -7968,9 +7968,9 @@ } }, "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -8983,9 +8983,9 @@ } }, "node_modules/postcss-sort-media-queries": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-4.3.0.tgz", - "integrity": "sha512-jAl8gJM2DvuIJiI9sL1CuiHtKM4s5aEIomkU8G3LFvbP+p8i7Sz8VV63uieTgoewGqKbi+hxBTiOKJlB35upCg==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-4.4.1.tgz", + "integrity": "sha512-QDESFzDDGKgpiIh4GYXsSy6sek2yAwQx1JASl5AxBtU1Lq2JfKBljIPNdil989NcSKRQX1ToiaKphImtBuhXWw==", "dependencies": { "sort-css-media-queries": "2.1.0" }, @@ -11126,7 +11126,8 @@ "node_modules/trim": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==" + "integrity": "sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==", + "deprecated": "Use String.prototype.trim() instead" }, "node_modules/trim-trailing-lines": { "version": "1.1.4", @@ -12338,95 +12339,95 @@ }, "dependencies": { "@algolia/autocomplete-core": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.7.4.tgz", - "integrity": "sha512-daoLpQ3ps/VTMRZDEBfU8ixXd+amZcNJ4QSP3IERGyzqnL5Ch8uSRFt/4G8pUvW9c3o6GA4vtVv4I4lmnkdXyg==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.8.2.tgz", + "integrity": "sha512-mTeshsyFhAqw/ebqNsQpMtbnjr+qVOSKXArEj4K0d7sqc8It1XD0gkASwecm9mF/jlOQ4Z9RNg1HbdA8JPdRwQ==", "requires": { - "@algolia/autocomplete-shared": "1.7.4" + "@algolia/autocomplete-shared": "1.8.2" } }, "@algolia/autocomplete-preset-algolia": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.7.4.tgz", - "integrity": "sha512-s37hrvLEIfcmKY8VU9LsAXgm2yfmkdHT3DnA3SgHaY93yjZ2qL57wzb5QweVkYuEBZkT2PIREvRoLXC2sxTbpQ==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.8.2.tgz", + "integrity": "sha512-J0oTx4me6ZM9kIKPuL3lyU3aB8DEvpVvR6xWmHVROx5rOYJGQcZsdG4ozxwcOyiiu3qxMkIbzntnV1S1VWD8yA==", "requires": { - "@algolia/autocomplete-shared": "1.7.4" + "@algolia/autocomplete-shared": "1.8.2" } }, "@algolia/autocomplete-shared": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.7.4.tgz", - "integrity": "sha512-2VGCk7I9tA9Ge73Km99+Qg87w0wzW4tgUruvWAn/gfey1ZXgmxZtyIRBebk35R1O8TbK77wujVtCnpsGpRy1kg==" + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.8.2.tgz", + "integrity": "sha512-b6Z/X4MczChMcfhk6kfRmBzPgjoPzuS9KGR4AFsiLulLNRAAqhP+xZTKtMnZGhLuc61I20d5WqlId02AZvcO6g==" }, "@algolia/cache-browser-local-storage": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.17.0.tgz", - "integrity": "sha512-myRSRZDIMYB8uCkO+lb40YKiYHi0fjpWRtJpR/dgkaiBlSD0plRyB6lLOh1XIfmMcSeBOqDE7y9m8xZMrXYfyQ==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.17.1.tgz", + "integrity": "sha512-e91Jpu93X3t3mVdQwF3ZDjSFMFIfzSc+I76G4EX8nl9RYXgqcjframoL05VTjcD2YCsI18RIHAWVCBoCXVZnrw==", "requires": { - "@algolia/cache-common": "4.17.0" + "@algolia/cache-common": "4.17.1" } }, "@algolia/cache-common": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.17.0.tgz", - "integrity": "sha512-g8mXzkrcUBIPZaulAuqE7xyHhLAYAcF2xSch7d9dABheybaU3U91LjBX6eJTEB7XVhEsgK4Smi27vWtAJRhIKQ==" + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.17.1.tgz", + "integrity": "sha512-fvi1WT8aSiGAKrcTw8Qg3RYgcwW8GZMHcqEm4AyDBEy72JZlFBSY80cTQ75MslINjCHXLDT+9EN8AGI9WVY7uA==" }, "@algolia/cache-in-memory": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.17.0.tgz", - "integrity": "sha512-PT32ciC/xI8z919d0oknWVu3kMfTlhQn3MKxDln3pkn+yA7F7xrxSALysxquv+MhFfNAcrtQ/oVvQVBAQSHtdw==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.17.1.tgz", + "integrity": "sha512-NbBt6eBWlsXc5geSpfPRC5dkIB/0Ptthw8r0yM5Z7D3sPlYdnTZSO9y9XWXIptRMwmZe4cM8iBMN8y0tzbcBkA==", "requires": { - "@algolia/cache-common": "4.17.0" + "@algolia/cache-common": "4.17.1" } }, "@algolia/client-account": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.17.0.tgz", - "integrity": "sha512-sSEHx9GA6m7wrlsSMNBGfyzlIfDT2fkz2u7jqfCCd6JEEwmxt8emGmxAU/0qBfbhRSuGvzojoLJlr83BSZAKjA==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.17.1.tgz", + "integrity": "sha512-3rL/6ofJvyL+q8TiWM3qoM9tig+SY4gB1Vbsj+UeJPnJm8Khm+7OS+r+mFraqR6pTehYqN8yGYoE7x4diEn4aA==", "requires": { - "@algolia/client-common": "4.17.0", - "@algolia/client-search": "4.17.0", - "@algolia/transporter": "4.17.0" + "@algolia/client-common": "4.17.1", + "@algolia/client-search": "4.17.1", + "@algolia/transporter": "4.17.1" } }, "@algolia/client-analytics": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.17.0.tgz", - "integrity": "sha512-84ooP8QA3mQ958hQ9wozk7hFUbAO+81CX1CjAuerxBqjKIInh1fOhXKTaku05O/GHBvcfExpPLIQuSuLYziBXQ==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.17.1.tgz", + "integrity": "sha512-Bepr2w249vODqeBtM7i++tPmUsQ9B81aupUGbDWmjA/FX+jzQqOdhW8w1CFO5kWViNKTbz2WBIJ9U3x8hOa4bA==", "requires": { - "@algolia/client-common": "4.17.0", - "@algolia/client-search": "4.17.0", - "@algolia/requester-common": "4.17.0", - "@algolia/transporter": "4.17.0" + "@algolia/client-common": "4.17.1", + "@algolia/client-search": "4.17.1", + "@algolia/requester-common": "4.17.1", + "@algolia/transporter": "4.17.1" } }, "@algolia/client-common": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.17.0.tgz", - "integrity": "sha512-jHMks0ZFicf8nRDn6ma8DNNsdwGgP/NKiAAL9z6rS7CymJ7L0+QqTJl3rYxRW7TmBhsUH40wqzmrG6aMIN/DrQ==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.17.1.tgz", + "integrity": "sha512-+r7kg4EgbFnGsDnoGSVNtXZO8xvZ0vzf1WAOV7sqV9PMf1bp6cpJP/3IuPrSk4t5w2KVl+pC8jfTM7HcFlfBEQ==", "requires": { - "@algolia/requester-common": "4.17.0", - "@algolia/transporter": "4.17.0" + "@algolia/requester-common": "4.17.1", + "@algolia/transporter": "4.17.1" } }, "@algolia/client-personalization": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.17.0.tgz", - "integrity": "sha512-RMzN4dZLIta1YuwT7QC9o+OeGz2cU6eTOlGNE/6RcUBLOU3l9tkCOdln5dPE2jp8GZXPl2yk54b2nSs1+pAjqw==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.17.1.tgz", + "integrity": "sha512-gJku9DG/THJpfsSlG/az0a3QIn+VVff9kKh8PG8+7ZfxOHS+C+Y5YSeZVsC+c2cfoKLPo3CuHIiJ/p86erR3bA==", "requires": { - "@algolia/client-common": "4.17.0", - "@algolia/requester-common": "4.17.0", - "@algolia/transporter": "4.17.0" + "@algolia/client-common": "4.17.1", + "@algolia/requester-common": "4.17.1", + "@algolia/transporter": "4.17.1" } }, "@algolia/client-search": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.17.0.tgz", - "integrity": "sha512-x4P2wKrrRIXszT8gb7eWsMHNNHAJs0wE7/uqbufm4tZenAp+hwU/hq5KVsY50v+PfwM0LcDwwn/1DroujsTFoA==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.17.1.tgz", + "integrity": "sha512-Q5YfT5gVkx60PZDQBqp/zH9aUbBdC7HVvxupiHUgnCKqRQsRZjOhLest7AI6FahepuZLBZS62COrO7v+JvKY7w==", "requires": { - "@algolia/client-common": "4.17.0", - "@algolia/requester-common": "4.17.0", - "@algolia/transporter": "4.17.0" + "@algolia/client-common": "4.17.1", + "@algolia/requester-common": "4.17.1", + "@algolia/transporter": "4.17.1" } }, "@algolia/events": { @@ -12435,47 +12436,47 @@ "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==" }, "@algolia/logger-common": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.17.0.tgz", - "integrity": "sha512-DGuoZqpTmIKJFDeyAJ7M8E/LOenIjWiOsg1XJ1OqAU/eofp49JfqXxbfgctlVZVmDABIyOz8LqEoJ6ZP4DTyvw==" + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.17.1.tgz", + "integrity": "sha512-Us28Ot+fLEmX9M96sa65VZ8EyEEzhYPxfhV9aQyKDjfXbUdJlJxKt6wZpoEg9RAPSdO8IjK9nmuW2P8au3rRsg==" }, "@algolia/logger-console": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.17.0.tgz", - "integrity": "sha512-zMPvugQV/gbXUvWBCzihw6m7oxIKp48w37QBIUu/XqQQfxhjoOE9xyfJr1KldUt5FrYOKZJVsJaEjTsu+bIgQg==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.17.1.tgz", + "integrity": "sha512-iKGQTpOjHiE64W3JIOu6dmDvn+AfYIElI9jf/Nt6umRPmP/JI9rK+OHUoW4pKrBtdG0DPd62ppeNXzSnLxY6/g==", "requires": { - "@algolia/logger-common": "4.17.0" + "@algolia/logger-common": "4.17.1" } }, "@algolia/requester-browser-xhr": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.17.0.tgz", - "integrity": "sha512-aSOX/smauyTkP21Pf52pJ1O2LmNFJ5iHRIzEeTh0mwBeADO4GdG94cAWDILFA9rNblq/nK3EDh3+UyHHjplZ1A==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.17.1.tgz", + "integrity": "sha512-W5mGfGDsyfVR+r4pUFrYLGBEM18gs38+GNt5PE5uPULy4uVTSnnVSkJkWeRkmLBk9zEZ/Nld8m4zavK6dtEuYg==", "requires": { - "@algolia/requester-common": "4.17.0" + "@algolia/requester-common": "4.17.1" } }, "@algolia/requester-common": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.17.0.tgz", - "integrity": "sha512-XJjmWFEUlHu0ijvcHBoixuXfEoiRUdyzQM6YwTuB8usJNIgShua8ouFlRWF8iCeag0vZZiUm4S2WCVBPkdxFgg==" + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.17.1.tgz", + "integrity": "sha512-HggXdjvVFQR0I5l7hM5WdHgQ1tqcRWeyXZz8apQ7zPWZhirmY2E9D6LVhDh/UnWQNEm7nBtM+eMFONJ3bZccIQ==" }, "@algolia/requester-node-http": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.17.0.tgz", - "integrity": "sha512-bpb/wDA1aC6WxxM8v7TsFspB7yBN3nqCGs2H1OADolQR/hiAIjAxusbuMxVbRFOdaUvAIqioIIkWvZdpYNIn8w==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.17.1.tgz", + "integrity": "sha512-NzFWecXT6d0PPsQY9L+/qoK2deF74OLcpvqCH+Vh3mh+QzPsFafcBExdguAjZsAWDn1R6JEeFW7/fo/p0SE57w==", "requires": { - "@algolia/requester-common": "4.17.0" + "@algolia/requester-common": "4.17.1" } }, "@algolia/transporter": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.17.0.tgz", - "integrity": "sha512-6xL6H6fe+Fi0AEP3ziSgC+G04RK37iRb4uUUqVAH9WPYFI8g+LYFq6iv5HS8Cbuc5TTut+Bwj6G+dh/asdb9uA==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.17.1.tgz", + "integrity": "sha512-ZM+qhX47Vh46mWH8/U9ihvy98HdTYpYQDSlqBD7IbiUbbyoCMke+qmdSX2MGhR2FCcXBSxejsJKKVAfbpaLVgg==", "requires": { - "@algolia/cache-common": "4.17.0", - "@algolia/logger-common": "4.17.0", - "@algolia/requester-common": "4.17.0" + "@algolia/cache-common": "4.17.1", + "@algolia/logger-common": "4.17.1", + "@algolia/requester-common": "4.17.1" } }, "@ampproject/remapping": { @@ -13671,25 +13672,25 @@ "optional": true }, "@docsearch/css": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.3.3.tgz", - "integrity": "sha512-6SCwI7P8ao+se1TUsdZ7B4XzL+gqeQZnBc+2EONZlcVa0dVrk0NjETxozFKgMv0eEGH8QzP1fkN+A1rH61l4eg==" + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.4.0.tgz", + "integrity": "sha512-Hg8Xfma+rFwRi6Y/pfei4FJoQ1hdVURmmNs/XPoMTCPAImU+d5yxj+M+qdLtNjWRpfWziU4dQcqY94xgFBn2dg==" }, "@docsearch/react": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.3.3.tgz", - "integrity": "sha512-pLa0cxnl+G0FuIDuYlW+EBK6Rw2jwLw9B1RHIeS4N4s2VhsfJ/wzeCi3CWcs5yVfxLd5ZK50t//TMA5e79YT7Q==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.4.0.tgz", + "integrity": "sha512-ufrp5879XYGojgS30ZAp8H4qIMbahRHB9M85VDBP36Xgz5QjYM54i1URKj5e219F7gqTtOivfztFTij6itc0MQ==", "requires": { - "@algolia/autocomplete-core": "1.7.4", - "@algolia/autocomplete-preset-algolia": "1.7.4", - "@docsearch/css": "3.3.3", + "@algolia/autocomplete-core": "1.8.2", + "@algolia/autocomplete-preset-algolia": "1.8.2", + "@docsearch/css": "3.4.0", "algoliasearch": "^4.0.0" } }, "@docusaurus/core": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-2.4.0.tgz", - "integrity": "sha512-J55/WEoIpRcLf3afO5POHPguVZosKmJEQWKBL+K7TAnfuE7i+Y0NPLlkKtnWCehagGsgTqClfQEexH/UT4kELA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-2.4.1.tgz", + "integrity": "sha512-SNsY7PshK3Ri7vtsLXVeAJGS50nJN3RgF836zkyUfAD01Fq+sAk5EwWgLw+nnm5KVNGDu7PRR2kRGDsWvqpo0g==", "requires": { "@babel/core": "^7.18.6", "@babel/generator": "^7.18.7", @@ -13701,13 +13702,13 @@ "@babel/runtime": "^7.18.6", "@babel/runtime-corejs3": "^7.18.6", "@babel/traverse": "^7.18.8", - "@docusaurus/cssnano-preset": "2.4.0", - "@docusaurus/logger": "2.4.0", - "@docusaurus/mdx-loader": "2.4.0", + "@docusaurus/cssnano-preset": "2.4.1", + "@docusaurus/logger": "2.4.1", + "@docusaurus/mdx-loader": "2.4.1", "@docusaurus/react-loadable": "5.5.2", - "@docusaurus/utils": "2.4.0", - "@docusaurus/utils-common": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/utils": "2.4.1", + "@docusaurus/utils-common": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "@slorber/static-site-generator-webpack-plugin": "^4.0.7", "@svgr/webpack": "^6.2.1", "autoprefixer": "^10.4.7", @@ -13765,9 +13766,9 @@ } }, "@docusaurus/cssnano-preset": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-2.4.0.tgz", - "integrity": "sha512-RmdiA3IpsLgZGXRzqnmTbGv43W4OD44PCo+6Q/aYjEM2V57vKCVqNzuafE94jv0z/PjHoXUrjr69SaRymBKYYw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-2.4.1.tgz", + "integrity": "sha512-ka+vqXwtcW1NbXxWsh6yA1Ckii1klY9E53cJ4O9J09nkMBgrNX3iEFED1fWdv8wf4mJjvGi5RLZ2p9hJNjsLyQ==", "requires": { "cssnano-preset-advanced": "^5.3.8", "postcss": "^8.4.14", @@ -13776,23 +13777,23 @@ } }, "@docusaurus/logger": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-2.4.0.tgz", - "integrity": "sha512-T8+qR4APN+MjcC9yL2Es+xPJ2923S9hpzDmMtdsOcUGLqpCGBbU1vp3AAqDwXtVgFkq+NsEk7sHdVsfLWR/AXw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-2.4.1.tgz", + "integrity": "sha512-5h5ysIIWYIDHyTVd8BjheZmQZmEgWDR54aQ1BX9pjFfpyzFo5puKXKYrYJXbjEHGyVhEzmB9UXwbxGfaZhOjcg==", "requires": { "chalk": "^4.1.2", "tslib": "^2.4.0" } }, "@docusaurus/mdx-loader": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-2.4.0.tgz", - "integrity": "sha512-GWoH4izZKOmFoC+gbI2/y8deH/xKLvzz/T5BsEexBye8EHQlwsA7FMrVa48N063bJBH4FUOiRRXxk5rq9cC36g==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-2.4.1.tgz", + "integrity": "sha512-4KhUhEavteIAmbBj7LVFnrVYDiU51H5YWW1zY6SmBSte/YLhDutztLTBE0PQl1Grux1jzUJeaSvAzHpTn6JJDQ==", "requires": { "@babel/parser": "^7.18.8", "@babel/traverse": "^7.18.8", - "@docusaurus/logger": "2.4.0", - "@docusaurus/utils": "2.4.0", + "@docusaurus/logger": "2.4.1", + "@docusaurus/utils": "2.4.1", "@mdx-js/mdx": "^1.6.22", "escape-html": "^1.0.3", "file-loader": "^6.2.0", @@ -13809,12 +13810,12 @@ } }, "@docusaurus/module-type-aliases": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-2.4.0.tgz", - "integrity": "sha512-YEQO2D3UXs72qCn8Cr+RlycSQXVGN9iEUyuHwTuK4/uL/HFomB2FHSU0vSDM23oLd+X/KibQ3Ez6nGjQLqXcHg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-2.4.1.tgz", + "integrity": "sha512-gLBuIFM8Dp2XOCWffUDSjtxY7jQgKvYujt7Mx5s4FCTfoL5dN1EVbnrn+O2Wvh8b0a77D57qoIDY7ghgmatR1A==", "requires": { "@docusaurus/react-loadable": "5.5.2", - "@docusaurus/types": "2.4.0", + "@docusaurus/types": "2.4.1", "@types/history": "^4.7.11", "@types/react": "*", "@types/react-router-config": "*", @@ -13824,17 +13825,17 @@ } }, "@docusaurus/plugin-content-blog": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.4.0.tgz", - "integrity": "sha512-YwkAkVUxtxoBAIj/MCb4ohN0SCtHBs4AS75jMhPpf67qf3j+U/4n33cELq7567hwyZ6fMz2GPJcVmctzlGGThQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.4.1.tgz", + "integrity": "sha512-E2i7Knz5YIbE1XELI6RlTnZnGgS52cUO4BlCiCUCvQHbR+s1xeIWz4C6BtaVnlug0Ccz7nFSksfwDpVlkujg5Q==", "requires": { - "@docusaurus/core": "2.4.0", - "@docusaurus/logger": "2.4.0", - "@docusaurus/mdx-loader": "2.4.0", - "@docusaurus/types": "2.4.0", - "@docusaurus/utils": "2.4.0", - "@docusaurus/utils-common": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/logger": "2.4.1", + "@docusaurus/mdx-loader": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils": "2.4.1", + "@docusaurus/utils-common": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "cheerio": "^1.0.0-rc.12", "feed": "^4.2.2", "fs-extra": "^10.1.0", @@ -13847,17 +13848,17 @@ } }, "@docusaurus/plugin-content-docs": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-2.4.0.tgz", - "integrity": "sha512-ic/Z/ZN5Rk/RQo+Io6rUGpToOtNbtPloMR2JcGwC1xT2riMu6zzfSwmBi9tHJgdXH6CB5jG+0dOZZO8QS5tmDg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-2.4.1.tgz", + "integrity": "sha512-Lo7lSIcpswa2Kv4HEeUcGYqaasMUQNpjTXpV0N8G6jXgZaQurqp7E8NGYeGbDXnb48czmHWbzDL4S3+BbK0VzA==", "requires": { - "@docusaurus/core": "2.4.0", - "@docusaurus/logger": "2.4.0", - "@docusaurus/mdx-loader": "2.4.0", - "@docusaurus/module-type-aliases": "2.4.0", - "@docusaurus/types": "2.4.0", - "@docusaurus/utils": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/logger": "2.4.1", + "@docusaurus/mdx-loader": "2.4.1", + "@docusaurus/module-type-aliases": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "@types/react-router-config": "^5.0.6", "combine-promises": "^1.1.0", "fs-extra": "^10.1.0", @@ -13870,100 +13871,100 @@ } }, "@docusaurus/plugin-content-pages": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-2.4.0.tgz", - "integrity": "sha512-Pk2pOeOxk8MeU3mrTU0XLIgP9NZixbdcJmJ7RUFrZp1Aj42nd0RhIT14BGvXXyqb8yTQlk4DmYGAzqOfBsFyGw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-2.4.1.tgz", + "integrity": "sha512-/UjuH/76KLaUlL+o1OvyORynv6FURzjurSjvn2lbWTFc4tpYY2qLYTlKpTCBVPhlLUQsfyFnshEJDLmPneq2oA==", "requires": { - "@docusaurus/core": "2.4.0", - "@docusaurus/mdx-loader": "2.4.0", - "@docusaurus/types": "2.4.0", - "@docusaurus/utils": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/mdx-loader": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "fs-extra": "^10.1.0", "tslib": "^2.4.0", "webpack": "^5.73.0" } }, "@docusaurus/plugin-debug": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-2.4.0.tgz", - "integrity": "sha512-KC56DdYjYT7Txyux71vXHXGYZuP6yYtqwClvYpjKreWIHWus5Zt6VNi23rMZv3/QKhOCrN64zplUbdfQMvddBQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-2.4.1.tgz", + "integrity": "sha512-7Yu9UPzRShlrH/G8btOpR0e6INFZr0EegWplMjOqelIwAcx3PKyR8mgPTxGTxcqiYj6hxSCRN0D8R7YrzImwNA==", "requires": { - "@docusaurus/core": "2.4.0", - "@docusaurus/types": "2.4.0", - "@docusaurus/utils": "2.4.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils": "2.4.1", "fs-extra": "^10.1.0", "react-json-view": "^1.21.3", "tslib": "^2.4.0" } }, "@docusaurus/plugin-google-analytics": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-2.4.0.tgz", - "integrity": "sha512-uGUzX67DOAIglygdNrmMOvEp8qG03X20jMWadeqVQktS6nADvozpSLGx4J0xbkblhJkUzN21WiilsP9iVP+zkw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-2.4.1.tgz", + "integrity": "sha512-dyZJdJiCoL+rcfnm0RPkLt/o732HvLiEwmtoNzOoz9MSZz117UH2J6U2vUDtzUzwtFLIf32KkeyzisbwUCgcaQ==", "requires": { - "@docusaurus/core": "2.4.0", - "@docusaurus/types": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "tslib": "^2.4.0" } }, "@docusaurus/plugin-google-gtag": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-2.4.0.tgz", - "integrity": "sha512-adj/70DANaQs2+TF/nRdMezDXFAV/O/pjAbUgmKBlyOTq5qoMe0Tk4muvQIwWUmiUQxFJe+sKlZGM771ownyOg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-2.4.1.tgz", + "integrity": "sha512-mKIefK+2kGTQBYvloNEKtDmnRD7bxHLsBcxgnbt4oZwzi2nxCGjPX6+9SQO2KCN5HZbNrYmGo5GJfMgoRvy6uA==", "requires": { - "@docusaurus/core": "2.4.0", - "@docusaurus/types": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "tslib": "^2.4.0" } }, "@docusaurus/plugin-google-tag-manager": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-2.4.0.tgz", - "integrity": "sha512-E66uGcYs4l7yitmp/8kMEVQftFPwV9iC62ORh47Veqzs6ExwnhzBkJmwDnwIysHBF1vlxnzET0Fl2LfL5fRR3A==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-2.4.1.tgz", + "integrity": "sha512-Zg4Ii9CMOLfpeV2nG74lVTWNtisFaH9QNtEw48R5QE1KIwDBdTVaiSA18G1EujZjrzJJzXN79VhINSbOJO/r3g==", "requires": { - "@docusaurus/core": "2.4.0", - "@docusaurus/types": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "tslib": "^2.4.0" } }, "@docusaurus/plugin-sitemap": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-2.4.0.tgz", - "integrity": "sha512-pZxh+ygfnI657sN8a/FkYVIAmVv0CGk71QMKqJBOfMmDHNN1FeDeFkBjWP49ejBqpqAhjufkv5UWq3UOu2soCw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-2.4.1.tgz", + "integrity": "sha512-lZx+ijt/+atQ3FVE8FOHV/+X3kuok688OydDXrqKRJyXBJZKgGjA2Qa8RjQ4f27V2woaXhtnyrdPop/+OjVMRg==", "requires": { - "@docusaurus/core": "2.4.0", - "@docusaurus/logger": "2.4.0", - "@docusaurus/types": "2.4.0", - "@docusaurus/utils": "2.4.0", - "@docusaurus/utils-common": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/logger": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils": "2.4.1", + "@docusaurus/utils-common": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "fs-extra": "^10.1.0", "sitemap": "^7.1.1", "tslib": "^2.4.0" } }, "@docusaurus/preset-classic": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-2.4.0.tgz", - "integrity": "sha512-/5z5o/9bc6+P5ool2y01PbJhoGddEGsC0ej1MF6mCoazk8A+kW4feoUd68l7Bnv01rCnG3xy7kHUQP97Y0grUA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-2.4.1.tgz", + "integrity": "sha512-P4//+I4zDqQJ+UDgoFrjIFaQ1MeS9UD1cvxVQaI6O7iBmiHQm0MGROP1TbE7HlxlDPXFJjZUK3x3cAoK63smGQ==", "requires": { - "@docusaurus/core": "2.4.0", - "@docusaurus/plugin-content-blog": "2.4.0", - "@docusaurus/plugin-content-docs": "2.4.0", - "@docusaurus/plugin-content-pages": "2.4.0", - "@docusaurus/plugin-debug": "2.4.0", - "@docusaurus/plugin-google-analytics": "2.4.0", - "@docusaurus/plugin-google-gtag": "2.4.0", - "@docusaurus/plugin-google-tag-manager": "2.4.0", - "@docusaurus/plugin-sitemap": "2.4.0", - "@docusaurus/theme-classic": "2.4.0", - "@docusaurus/theme-common": "2.4.0", - "@docusaurus/theme-search-algolia": "2.4.0", - "@docusaurus/types": "2.4.0" + "@docusaurus/core": "2.4.1", + "@docusaurus/plugin-content-blog": "2.4.1", + "@docusaurus/plugin-content-docs": "2.4.1", + "@docusaurus/plugin-content-pages": "2.4.1", + "@docusaurus/plugin-debug": "2.4.1", + "@docusaurus/plugin-google-analytics": "2.4.1", + "@docusaurus/plugin-google-gtag": "2.4.1", + "@docusaurus/plugin-google-tag-manager": "2.4.1", + "@docusaurus/plugin-sitemap": "2.4.1", + "@docusaurus/theme-classic": "2.4.1", + "@docusaurus/theme-common": "2.4.1", + "@docusaurus/theme-search-algolia": "2.4.1", + "@docusaurus/types": "2.4.1" } }, "@docusaurus/react-loadable": { @@ -13976,22 +13977,22 @@ } }, "@docusaurus/theme-classic": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-2.4.0.tgz", - "integrity": "sha512-GMDX5WU6Z0OC65eQFgl3iNNEbI9IMJz9f6KnOyuMxNUR6q0qVLsKCNopFUDfFNJ55UU50o7P7o21yVhkwpfJ9w==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-2.4.1.tgz", + "integrity": "sha512-Rz0wKUa+LTW1PLXmwnf8mn85EBzaGSt6qamqtmnh9Hflkc+EqiYMhtUJeLdV+wsgYq4aG0ANc+bpUDpsUhdnwg==", "requires": { - "@docusaurus/core": "2.4.0", - "@docusaurus/mdx-loader": "2.4.0", - "@docusaurus/module-type-aliases": "2.4.0", - "@docusaurus/plugin-content-blog": "2.4.0", - "@docusaurus/plugin-content-docs": "2.4.0", - "@docusaurus/plugin-content-pages": "2.4.0", - "@docusaurus/theme-common": "2.4.0", - "@docusaurus/theme-translations": "2.4.0", - "@docusaurus/types": "2.4.0", - "@docusaurus/utils": "2.4.0", - "@docusaurus/utils-common": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/mdx-loader": "2.4.1", + "@docusaurus/module-type-aliases": "2.4.1", + "@docusaurus/plugin-content-blog": "2.4.1", + "@docusaurus/plugin-content-docs": "2.4.1", + "@docusaurus/plugin-content-pages": "2.4.1", + "@docusaurus/theme-common": "2.4.1", + "@docusaurus/theme-translations": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils": "2.4.1", + "@docusaurus/utils-common": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "@mdx-js/react": "^1.6.22", "clsx": "^1.2.1", "copy-text-to-clipboard": "^3.0.1", @@ -14008,17 +14009,17 @@ } }, "@docusaurus/theme-common": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-2.4.0.tgz", - "integrity": "sha512-IkG/l5f/FLY6cBIxtPmFnxpuPzc5TupuqlOx+XDN+035MdQcAh8wHXXZJAkTeYDeZ3anIUSUIvWa7/nRKoQEfg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-2.4.1.tgz", + "integrity": "sha512-G7Zau1W5rQTaFFB3x3soQoZpkgMbl/SYNG8PfMFIjKa3M3q8n0m/GRf5/H/e5BqOvt8c+ZWIXGCiz+kUCSHovA==", "requires": { - "@docusaurus/mdx-loader": "2.4.0", - "@docusaurus/module-type-aliases": "2.4.0", - "@docusaurus/plugin-content-blog": "2.4.0", - "@docusaurus/plugin-content-docs": "2.4.0", - "@docusaurus/plugin-content-pages": "2.4.0", - "@docusaurus/utils": "2.4.0", - "@docusaurus/utils-common": "2.4.0", + "@docusaurus/mdx-loader": "2.4.1", + "@docusaurus/module-type-aliases": "2.4.1", + "@docusaurus/plugin-content-blog": "2.4.1", + "@docusaurus/plugin-content-docs": "2.4.1", + "@docusaurus/plugin-content-pages": "2.4.1", + "@docusaurus/utils": "2.4.1", + "@docusaurus/utils-common": "2.4.1", "@types/history": "^4.7.11", "@types/react": "*", "@types/react-router-config": "*", @@ -14031,18 +14032,18 @@ } }, "@docusaurus/theme-search-algolia": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-2.4.0.tgz", - "integrity": "sha512-pPCJSCL1Qt4pu/Z0uxBAuke0yEBbxh0s4fOvimna7TEcBLPq0x06/K78AaABXrTVQM6S0vdocFl9EoNgU17hqA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-2.4.1.tgz", + "integrity": "sha512-6BcqW2lnLhZCXuMAvPRezFs1DpmEKzXFKlYjruuas+Xy3AQeFzDJKTJFIm49N77WFCTyxff8d3E4Q9pi/+5McQ==", "requires": { "@docsearch/react": "^3.1.1", - "@docusaurus/core": "2.4.0", - "@docusaurus/logger": "2.4.0", - "@docusaurus/plugin-content-docs": "2.4.0", - "@docusaurus/theme-common": "2.4.0", - "@docusaurus/theme-translations": "2.4.0", - "@docusaurus/utils": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/logger": "2.4.1", + "@docusaurus/plugin-content-docs": "2.4.1", + "@docusaurus/theme-common": "2.4.1", + "@docusaurus/theme-translations": "2.4.1", + "@docusaurus/utils": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "algoliasearch": "^4.13.1", "algoliasearch-helper": "^3.10.0", "clsx": "^1.2.1", @@ -14054,18 +14055,18 @@ } }, "@docusaurus/theme-translations": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-2.4.0.tgz", - "integrity": "sha512-kEoITnPXzDPUMBHk3+fzEzbopxLD3fR5sDoayNH0vXkpUukA88/aDL1bqkhxWZHA3LOfJ3f0vJbOwmnXW5v85Q==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-2.4.1.tgz", + "integrity": "sha512-T1RAGP+f86CA1kfE8ejZ3T3pUU3XcyvrGMfC/zxCtc2BsnoexuNI9Vk2CmuKCb+Tacvhxjv5unhxXce0+NKyvA==", "requires": { "fs-extra": "^10.1.0", "tslib": "^2.4.0" } }, "@docusaurus/types": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-2.4.0.tgz", - "integrity": "sha512-xaBXr+KIPDkIaef06c+i2HeTqVNixB7yFut5fBXPGI2f1rrmEV2vLMznNGsFwvZ5XmA3Quuefd4OGRkdo97Dhw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-2.4.1.tgz", + "integrity": "sha512-0R+cbhpMkhbRXX138UOc/2XZFF8hiZa6ooZAEEJFp5scytzCw4tC1gChMFXrpa3d2tYE6AX8IrOEpSonLmfQuQ==", "requires": { "@types/history": "^4.7.11", "@types/react": "*", @@ -14078,11 +14079,11 @@ } }, "@docusaurus/utils": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-2.4.0.tgz", - "integrity": "sha512-89hLYkvtRX92j+C+ERYTuSUK6nF9bGM32QThcHPg2EDDHVw6FzYQXmX6/p+pU5SDyyx5nBlE4qXR92RxCAOqfg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-2.4.1.tgz", + "integrity": "sha512-1lvEZdAQhKNht9aPXPoh69eeKnV0/62ROhQeFKKxmzd0zkcuE/Oc5Gpnt00y/f5bIsmOsYMY7Pqfm/5rteT5GA==", "requires": { - "@docusaurus/logger": "2.4.0", + "@docusaurus/logger": "2.4.1", "@svgr/webpack": "^6.2.1", "escape-string-regexp": "^4.0.0", "file-loader": "^6.2.0", @@ -14101,20 +14102,20 @@ } }, "@docusaurus/utils-common": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-2.4.0.tgz", - "integrity": "sha512-zIMf10xuKxddYfLg5cS19x44zud/E9I7lj3+0bv8UIs0aahpErfNrGhijEfJpAfikhQ8tL3m35nH3hJ3sOG82A==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-2.4.1.tgz", + "integrity": "sha512-bCVGdZU+z/qVcIiEQdyx0K13OC5mYwxhSuDUR95oFbKVuXYRrTVrwZIqQljuo1fyJvFTKHiL9L9skQOPokuFNQ==", "requires": { "tslib": "^2.4.0" } }, "@docusaurus/utils-validation": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-2.4.0.tgz", - "integrity": "sha512-IrBsBbbAp6y7mZdJx4S4pIA7dUyWSA0GNosPk6ZJ0fX3uYIEQgcQSGIgTeSC+8xPEx3c16o03en1jSDpgQgz/w==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-2.4.1.tgz", + "integrity": "sha512-unII3hlJlDwZ3w8U+pMO3Lx3RhI4YEbY3YNsQj4yzrkZzlpqZOLuAiZK2JyULnD+TKbceKU0WyWkQXtYbLNDFA==", "requires": { - "@docusaurus/logger": "2.4.0", - "@docusaurus/utils": "2.4.0", + "@docusaurus/logger": "2.4.1", + "@docusaurus/utils": "2.4.1", "joi": "^17.6.0", "js-yaml": "^4.1.0", "tslib": "^2.4.0" @@ -14636,9 +14637,9 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" }, "@types/mdast": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", - "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==", + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.11.tgz", + "integrity": "sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw==", "requires": { "@types/unist": "*" } @@ -15010,30 +15011,30 @@ "requires": {} }, "algoliasearch": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.17.0.tgz", - "integrity": "sha512-JMRh2Mw6sEnVMiz6+APsi7lx9a2jiDFF+WUtANaUVCv6uSU9UOLdo5h9K3pdP6frRRybaM2fX8b1u0nqICS9aA==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.17.1.tgz", + "integrity": "sha512-4GDQ1RhP2qUR3x8PevFRbEdqZqIARNViZYjgTJmA1T7wRNtFA3W4Aqc/RsODqa1J8IO/QDla5x4tWuUS8NV8wA==", "requires": { - "@algolia/cache-browser-local-storage": "4.17.0", - "@algolia/cache-common": "4.17.0", - "@algolia/cache-in-memory": "4.17.0", - "@algolia/client-account": "4.17.0", - "@algolia/client-analytics": "4.17.0", - "@algolia/client-common": "4.17.0", - "@algolia/client-personalization": "4.17.0", - "@algolia/client-search": "4.17.0", - "@algolia/logger-common": "4.17.0", - "@algolia/logger-console": "4.17.0", - "@algolia/requester-browser-xhr": "4.17.0", - "@algolia/requester-common": "4.17.0", - "@algolia/requester-node-http": "4.17.0", - "@algolia/transporter": "4.17.0" + "@algolia/cache-browser-local-storage": "4.17.1", + "@algolia/cache-common": "4.17.1", + "@algolia/cache-in-memory": "4.17.1", + "@algolia/client-account": "4.17.1", + "@algolia/client-analytics": "4.17.1", + "@algolia/client-common": "4.17.1", + "@algolia/client-personalization": "4.17.1", + "@algolia/client-search": "4.17.1", + "@algolia/logger-common": "4.17.1", + "@algolia/logger-console": "4.17.1", + "@algolia/requester-browser-xhr": "4.17.1", + "@algolia/requester-common": "4.17.1", + "@algolia/requester-node-http": "4.17.1", + "@algolia/transporter": "4.17.1" } }, "algoliasearch-helper": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.12.0.tgz", - "integrity": "sha512-/j1U3PEwdan0n6P/QqSnSpNSLC5+cEMvyljd5CnmNmUjDlGrys+vFEOwjVEnqELIiAGMHEA/Nl3CiKVFBUYqyQ==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.13.0.tgz", + "integrity": "sha512-kV3c1jMQCvkARtGsSDvAwuht4PAMSsQILqPiH4WFiARoa3jXJ/r1TQoBWAjWyWF48rsNYCv7kzxgB4LTxrvvuw==", "requires": { "@algolia/events": "^4.0.1" } @@ -15891,11 +15892,11 @@ } }, "cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.6.tgz", + "integrity": "sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==", "requires": { - "node-fetch": "2.6.7" + "node-fetch": "^2.6.11" } }, "cross-spawn": { @@ -16270,13 +16271,13 @@ } }, "domutils": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", - "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "requires": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", - "domhandler": "^5.0.1" + "domhandler": "^5.0.3" } }, "dot-case": { @@ -18100,9 +18101,9 @@ } }, "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", "requires": { "whatwg-url": "^5.0.0" } @@ -18753,9 +18754,9 @@ } }, "postcss-sort-media-queries": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-4.3.0.tgz", - "integrity": "sha512-jAl8gJM2DvuIJiI9sL1CuiHtKM4s5aEIomkU8G3LFvbP+p8i7Sz8VV63uieTgoewGqKbi+hxBTiOKJlB35upCg==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-4.4.1.tgz", + "integrity": "sha512-QDESFzDDGKgpiIh4GYXsSy6sek2yAwQx1JASl5AxBtU1Lq2JfKBljIPNdil989NcSKRQX1ToiaKphImtBuhXWw==", "requires": { "sort-css-media-queries": "2.1.0" } diff --git a/docs/package.json b/docs/package.json index 4ed541a73..d2d68ee83 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,8 +14,8 @@ "write-heading-ids": "docusaurus write-heading-ids" }, "dependencies": { - "@docusaurus/core": "^2.4.0", - "@docusaurus/preset-classic": "^2.4.0", + "@docusaurus/core": "^2.4.1", + "@docusaurus/preset-classic": "^2.4.1", "@mdx-js/react": "^1.6.22", "clsx": "^1.2.1", "prism-react-renderer": "^1.3.5", diff --git a/requirements-wheels.txt b/requirements-wheels.txt index f1f228291..f02317e41 100644 --- a/requirements-wheels.txt +++ b/requirements-wheels.txt @@ -8,16 +8,16 @@ onvif_zeep == 0.2.12 opencv-python-headless == 4.5.5.* paho-mqtt == 1.6.* peewee == 3.16.* -peewee_migrate == 1.7.* +peewee_migrate == 1.10.* psutil == 5.9.* pydantic == 1.10.* git+https://github.com/fbcotter/py3nvml#egg=py3nvml PyYAML == 6.0 pytz == 2023.3 -tzlocal == 4.3 +tzlocal == 5.0.* types-PyYAML == 6.0.* -requests == 2.30.* -types-requests == 2.28.* +requests == 2.31.* +types-requests == 2.31.* scipy == 1.10.* norfair == 2.2.* setproctitle == 1.3.* diff --git a/web/package-lock.json b/web/package-lock.json index 26720e3ea..d1076106f 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -71,12 +71,12 @@ } }, "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", "dev": true, "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { @@ -175,20 +175,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", @@ -908,14 +894,14 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz", - "integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", + "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.1", + "espree": "^9.5.2", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -958,9 +944,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz", - "integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz", + "integrity": "sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1120,13 +1106,14 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "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, "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { "node": ">=6.0.0" @@ -1593,9 +1580,9 @@ "dev": true }, "node_modules/@types/chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", + "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", "dev": true }, "node_modules/@types/chai-subset": { @@ -1787,15 +1774,15 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.2.tgz", - "integrity": "sha512-yVrXupeHjRxLDcPKL10sGQ/QlVrA8J5IYOEWVqk0lJaSZP7X5DfnP7Ns3cc74/blmbipQ1htFNVGsHX6wsYm0A==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.8.tgz", + "integrity": "sha512-JDMOmhXteJ4WVKOiHXGCoB96ADWg9q7efPWHRViT/f09bA8XOMLAVHHju3l0MkZnG1izaWXYmgvQcUjTRcpShQ==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.2", - "@typescript-eslint/type-utils": "5.59.2", - "@typescript-eslint/utils": "5.59.2", + "@typescript-eslint/scope-manager": "5.59.8", + "@typescript-eslint/type-utils": "5.59.8", + "@typescript-eslint/utils": "5.59.8", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -1821,13 +1808,13 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz", - "integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz", + "integrity": "sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/visitor-keys": "5.59.2" + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1838,9 +1825,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz", - "integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", + "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1851,13 +1838,13 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz", - "integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz", + "integrity": "sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/visitor-keys": "5.59.2", + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1878,17 +1865,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.2.tgz", - "integrity": "sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.8.tgz", + "integrity": "sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.2", - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/typescript-estree": "5.59.2", + "@typescript-eslint/scope-manager": "5.59.8", + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/typescript-estree": "5.59.8", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -1904,12 +1891,12 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz", - "integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", + "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/types": "5.59.8", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -1943,9 +1930,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -1977,14 +1964,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.2.tgz", - "integrity": "sha512-uq0sKyw6ao1iFOZZGk9F8Nro/8+gfB5ezl1cA06SrqbgJAt0SRoFhb9pXaHvkrxUpZaoLxt8KlovHNk8Gp6/HQ==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.8.tgz", + "integrity": "sha512-AnR19RjJcpjoeGojmwZtCwBX/RidqDZtzcbG3xHrmz0aHHoOcbWnpDllenRDmDvsV0RQ6+tbb09/kyc+UT9Orw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.59.2", - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/typescript-estree": "5.59.2", + "@typescript-eslint/scope-manager": "5.59.8", + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/typescript-estree": "5.59.8", "debug": "^4.3.4" }, "engines": { @@ -2004,13 +1991,13 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz", - "integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz", + "integrity": "sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/visitor-keys": "5.59.2" + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2021,9 +2008,9 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz", - "integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", + "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2034,13 +2021,13 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz", - "integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz", + "integrity": "sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/visitor-keys": "5.59.2", + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2061,12 +2048,12 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz", - "integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", + "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/types": "5.59.8", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -2078,9 +2065,9 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -2110,13 +2097,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.2.tgz", - "integrity": "sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.8.tgz", + "integrity": "sha512-+5M518uEIHFBy3FnyqZUF3BMP+AXnYn4oyH8RF012+e7/msMY98FhGL5SrN29NQ9xDgvqCgYnsOiKp1VjZ/fpA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.2", - "@typescript-eslint/utils": "5.59.2", + "@typescript-eslint/typescript-estree": "5.59.8", + "@typescript-eslint/utils": "5.59.8", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -2137,13 +2124,13 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz", - "integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz", + "integrity": "sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/visitor-keys": "5.59.2" + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2154,9 +2141,9 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz", - "integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", + "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2167,13 +2154,13 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz", - "integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz", + "integrity": "sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/visitor-keys": "5.59.2", + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2194,17 +2181,17 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.2.tgz", - "integrity": "sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.8.tgz", + "integrity": "sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.2", - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/typescript-estree": "5.59.2", + "@typescript-eslint/scope-manager": "5.59.8", + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/typescript-estree": "5.59.8", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -2220,12 +2207,12 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz", - "integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", + "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/types": "5.59.8", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -2259,9 +2246,9 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -2455,12 +2442,12 @@ } }, "node_modules/@vitest/coverage-c8": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@vitest/coverage-c8/-/coverage-c8-0.31.0.tgz", - "integrity": "sha512-h72qN1D962AO7UefQVulm9JFP5ACS7OfhCdBHioXU8f7ohH/+NTZCgAqmgcfRNHHO/8wLFxx+93YVxhodkEJVA==", + "version": "0.31.4", + "resolved": "https://registry.npmjs.org/@vitest/coverage-c8/-/coverage-c8-0.31.4.tgz", + "integrity": "sha512-VPx368m4DTcpA/P0v3YdVxl4QOSh1DbUcXURLRvDShrIB5KxOgfzw4Bn2R8AhAe/GyiWW/FIsJ/OJdYXCCiC1w==", "dev": true, "dependencies": { - "@ampproject/remapping": "^2.2.0", + "@ampproject/remapping": "^2.2.1", "c8": "^7.13.0", "magic-string": "^0.30.0", "picocolors": "^1.0.0", @@ -2474,13 +2461,13 @@ } }, "node_modules/@vitest/expect": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.31.0.tgz", - "integrity": "sha512-Jlm8ZTyp6vMY9iz9Ny9a0BHnCG4fqBa8neCF6Pk/c/6vkUk49Ls6UBlgGAU82QnzzoaUs9E/mUhq/eq9uMOv/g==", + "version": "0.31.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.31.4.tgz", + "integrity": "sha512-tibyx8o7GUyGHZGyPgzwiaPaLDQ9MMuCOrc03BYT0nryUuhLbL7NV2r/q98iv5STlwMgaKuFJkgBW/8iPKwlSg==", "dev": true, "dependencies": { - "@vitest/spy": "0.31.0", - "@vitest/utils": "0.31.0", + "@vitest/spy": "0.31.4", + "@vitest/utils": "0.31.4", "chai": "^4.3.7" }, "funding": { @@ -2488,12 +2475,12 @@ } }, "node_modules/@vitest/runner": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.31.0.tgz", - "integrity": "sha512-H1OE+Ly7JFeBwnpHTrKyCNm/oZgr+16N4qIlzzqSG/YRQDATBYmJb/KUn3GrZaiQQyL7GwpNHVZxSQd6juLCgw==", + "version": "0.31.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.31.4.tgz", + "integrity": "sha512-Wgm6UER+gwq6zkyrm5/wbpXGF+g+UBB78asJlFkIOwyse0pz8lZoiC6SW5i4gPnls/zUcPLWS7Zog0LVepXnpg==", "dev": true, "dependencies": { - "@vitest/utils": "0.31.0", + "@vitest/utils": "0.31.4", "concordance": "^5.0.4", "p-limit": "^4.0.0", "pathe": "^1.1.0" @@ -2530,9 +2517,9 @@ } }, "node_modules/@vitest/snapshot": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.31.0.tgz", - "integrity": "sha512-5dTXhbHnyUMTMOujZPB0wjFjQ6q5x9c8TvAsSPUNKjp1tVU7i9pbqcKPqntyu2oXtmVxKbuHCqrOd+Ft60r4tg==", + "version": "0.31.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.31.4.tgz", + "integrity": "sha512-LemvNumL3NdWSmfVAMpXILGyaXPkZbG5tyl6+RQSdcHnTj6hvA49UAI8jzez9oQyE/FWLKRSNqTGzsHuk89LRA==", "dev": true, "dependencies": { "magic-string": "^0.30.0", @@ -2544,9 +2531,9 @@ } }, "node_modules/@vitest/spy": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.31.0.tgz", - "integrity": "sha512-IzCEQ85RN26GqjQNkYahgVLLkULOxOm5H/t364LG0JYb3Apg0PsYCHLBYGA006+SVRMWhQvHlBBCyuByAMFmkg==", + "version": "0.31.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.31.4.tgz", + "integrity": "sha512-3ei5ZH1s3aqbEyftPAzSuunGICRuhE+IXOmpURFdkm5ybUADk+viyQfejNk6q8M5QGX8/EVKw+QWMEP3DTJDag==", "dev": true, "dependencies": { "tinyspy": "^2.1.0" @@ -2556,18 +2543,18 @@ } }, "node_modules/@vitest/ui": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-0.31.0.tgz", - "integrity": "sha512-Dy86l6r3/dbJposgm7w+oqb/15UWJ0lDBbEQaS1ived3+0CTaMbT8OMkUf9vNBkSL47kvBHEBnZLa5fw5i9gUQ==", + "version": "0.31.4", + "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-0.31.4.tgz", + "integrity": "sha512-sKM16ITX6HrNFF+lNZ2AQAen4/6Bx2i6KlBfIvkUjcTgc5YII/j2ltcX14oCUv4EA0OTWGQuGhO3zDoAsTENGA==", "dev": true, "dependencies": { - "@vitest/utils": "0.31.0", + "@vitest/utils": "0.31.4", "fast-glob": "^3.2.12", "fflate": "^0.7.4", "flatted": "^3.2.7", "pathe": "^1.1.0", "picocolors": "^1.0.0", - "sirv": "^2.0.2" + "sirv": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" @@ -2577,9 +2564,9 @@ } }, "node_modules/@vitest/utils": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.31.0.tgz", - "integrity": "sha512-kahaRyLX7GS1urekRXN2752X4gIgOGVX4Wo8eDUGUkTWlGpXzf5ZS6N9RUUS+Re3XEE8nVGqNyxkSxF5HXlGhQ==", + "version": "0.31.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.31.4.tgz", + "integrity": "sha512-DobZbHacWznoGUfYU8XDPY78UubJxXfMNY1+SUdOp1NsI34eopSA6aZMeaGu10waSOeYwE8lxrd/pLfT0RMxjQ==", "dev": true, "dependencies": { "concordance": "^5.0.4", @@ -3457,9 +3444,9 @@ } }, "node_modules/concordance/node_modules/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -3969,15 +3956,15 @@ } }, "node_modules/eslint": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz", - "integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz", + "integrity": "sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.2", - "@eslint/js": "8.39.0", + "@eslint/eslintrc": "^2.0.3", + "@eslint/js": "8.41.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -3988,8 +3975,8 @@ "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.0", - "espree": "^9.5.1", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -3997,13 +3984,12 @@ "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", @@ -4237,9 +4223,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4358,14 +4344,14 @@ } }, "node_modules/espree": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz", - "integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==", + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", + "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", "dev": true, "dependencies": { "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4489,9 +4475,9 @@ "dev": true }, "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "dev": true }, "node_modules/fast-glob": { @@ -4908,6 +4894,12 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, "node_modules/graphql": { "version": "16.6.0", "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.6.0.tgz", @@ -5114,12 +5106,9 @@ } }, "node_modules/idb-keyval": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.0.tgz", - "integrity": "sha512-uw+MIyQn2jl3+hroD7hF8J7PUviBU7BPKWw4f/ISf32D4LoGu98yHjrzWWJDASu9QNrX10tCJqk9YY0ClWm8Ng==", - "dependencies": { - "safari-14-idb-fix": "^3.0.0" - } + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.1.tgz", + "integrity": "sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==" }, "node_modules/ieee754": { "version": "1.2.1", @@ -5151,9 +5140,9 @@ } }, "node_modules/immer": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.1.tgz", - "integrity": "sha512-zg++jJLsKKTwXGeSYIw0HgChSYQGtu0UDTnbKx5aGLYgte4CwTmH9eJDYyQ6FheyUtBe+lQW9FrGxya1G+Dtmg==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.2.tgz", + "integrity": "sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==", "funding": { "type": "opencollective", "url": "https://opencollective.com/immer" @@ -6217,12 +6206,6 @@ "node": ">=0.10.0" } }, - "node_modules/js-sdsl": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", - "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", - "dev": true - }, "node_modules/js-string-escape": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", @@ -6251,9 +6234,9 @@ } }, "node_modules/jsdom": { - "version": "22.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.0.0.tgz", - "integrity": "sha512-p5ZTEb5h+O+iU02t0GfEjAnkdYPrQSkfuTSMkMYyIoMvUNEHsbG0bHHbfXIcfTqD2UfvjQX7mmgiFsyRwGscVw==", + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz", + "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==", "dev": true, "dependencies": { "abab": "^2.0.6", @@ -6749,15 +6732,15 @@ } }, "node_modules/mlly": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.2.0.tgz", - "integrity": "sha512-+c7A3CV0KGdKcylsI6khWyts/CYrGTrRVo4R/I7u/cUsy0Conxa6LUhiEzVKIw14lc2L5aiO4+SeVe4TeGRKww==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.3.0.tgz", + "integrity": "sha512-HT5mcgIQKkOrZecOjOX3DJorTikWXwsBfpcr/MGBkhfWcjiqvnaL/9ppxvIUXfjT6xt4DVIAsN9fMUz1ev4bIw==", "dev": true, "dependencies": { "acorn": "^8.8.2", "pathe": "^1.1.0", - "pkg-types": "^1.0.2", - "ufo": "^1.1.1" + "pkg-types": "^1.0.3", + "ufo": "^1.1.2" } }, "node_modules/monaco-editor": { @@ -7555,9 +7538,9 @@ } }, "node_modules/postcss": { - "version": "8.4.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", - "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==", + "version": "8.4.24", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", + "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", "dev": true, "funding": [ { @@ -7686,9 +7669,9 @@ "dev": true }, "node_modules/preact": { - "version": "10.13.2", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.13.2.tgz", - "integrity": "sha512-q44QFLhOhty2Bd0Y46fnYW0gD/cbVM9dUVtNTDKPcdXSMA7jfY+Jpd6rk3GB0lcQss0z5s/6CmVP0Z/hV+g6pw==", + "version": "10.15.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.15.1.tgz", + "integrity": "sha512-qs2ansoQEwzNiV5eAcRT1p1EC/dmEzaATVDJNiB3g2sRDWdA7b7MurXdJjB2+/WQktGWZwxvDrnuRFbWuIr64g==", "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" @@ -7700,9 +7683,9 @@ "integrity": "sha512-8bg1007akXs3YDmzYT4McaTe6ji2FIzcc0/NTlu+vjJaKPNQ8lNG/HQ6LP+FoIxQ4m/KH5vvJCHJN5ADp2iNGA==" }, "node_modules/preact-router": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/preact-router/-/preact-router-4.1.0.tgz", - "integrity": "sha512-y1w2YvVpKAju9FMV+fAVR1NpH4MW5q07BZrziMZeg6F/rGJ9KvLUZtjOqsy2I8fDYiX36AM1AQTXIIK3jigBhA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/preact-router/-/preact-router-4.1.1.tgz", + "integrity": "sha512-+LGrB3b2nR7+8vzyHw8i2/TjZazs3oMJovIEgBChPBXMDSISmwj2WDynZh8KDxZRK2GuXlqHPk15mMjaYWZH4g==", "peerDependencies": { "preact": ">=10" } @@ -8136,11 +8119,6 @@ "tslib": "^2.1.0" } }, - "node_modules/safari-14-idb-fix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/safari-14-idb-fix/-/safari-14-idb-fix-3.0.0.tgz", - "integrity": "sha512-eBNFLob4PMq8JA1dGyFn6G97q3/WzNtFK4RnzT1fnLq+9RyrGknzYiM/9B12MnKAxuj1IXr7UKYtTNtjyKMBog==" - }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -8250,9 +8228,9 @@ "dev": true }, "node_modules/sirv": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.2.tgz", - "integrity": "sha512-4Qog6aE29nIjAOKe/wowFTxOdmbEZKb+3tsLljaBRzJwtqto0BChD2zzH0LhgCSXiI+V7X+Y45v14wBZQ1TK3w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.3.tgz", + "integrity": "sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==", "dev": true, "dependencies": { "@polka/url": "^1.0.0-next.20", @@ -8315,9 +8293,9 @@ "dev": true }, "node_modules/strftime": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/strftime/-/strftime-0.10.1.tgz", - "integrity": "sha512-nVvH6JG8KlXFPC0f8lojLgEsPA18lRpLZ+RrJh/NkQV2tqOgZfbas8gcU8SFgnnqR3rWzZPYu6N2A3xzs/8rQg==", + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/strftime/-/strftime-0.10.2.tgz", + "integrity": "sha512-Y6IZaTVM80chcMe7j65Gl/0nmlNdtt+KWPle5YeCAjmsBfw+id2qdaJ5MDrxUq+OmHKab+jHe7mUjU/aNMSZZg==", "engines": { "node": ">=0.2.0" } @@ -8471,20 +8449,6 @@ "node": ">=8" } }, - "node_modules/sucrase/node_modules/@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, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/sucrase/node_modules/glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -8697,9 +8661,9 @@ } }, "node_modules/tinybench": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.4.0.tgz", - "integrity": "sha512-iyziEiyFxX4kyxSp+MtY1oCH/lvjH3PxFN8PGCDeqcZWAJ/i+9y+nL85w99PxVzrIvew/GSkSbDYtiGVa85Afg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.0.tgz", + "integrity": "sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==", "dev": true }, "node_modules/tinypool": { @@ -8712,9 +8676,9 @@ } }, "node_modules/tinyspy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.1.0.tgz", - "integrity": "sha512-7eORpyqImoOvkQJCSkL0d0mB4NHHIFAy4b1u8PHdDa7SjGS2njzl6/lyGoZLm+eyYEtlUmFGE0rFj66SWxZgQQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.1.1.tgz", + "integrity": "sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==", "dev": true, "engines": { "node": ">=14.0.0" @@ -8759,9 +8723,9 @@ "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" }, "node_modules/totalist": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.0.tgz", - "integrity": "sha512-eM+pCBxXO/njtF7vdFsHuqb+ElbxqtI4r5EAvk6grfAFyJ6IvWlSkfZ5T9ozC6xWw3Fj1fGoSmrl0gUs46JVIw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true, "engines": { "node": ">=6" @@ -9108,9 +9072,9 @@ } }, "node_modules/vite": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.5.tgz", - "integrity": "sha512-0gEnL9wiRFxgz40o/i/eTBwm+NEbpUeTWhzKrZDSdKm6nplj+z4lKz8ANDgildxHm47Vg8EUia0aicKbawUVVA==", + "version": "4.3.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz", + "integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==", "dev": true, "dependencies": { "esbuild": "^0.17.5", @@ -9156,9 +9120,9 @@ } }, "node_modules/vite-node": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.31.0.tgz", - "integrity": "sha512-8x1x1LNuPvE2vIvkSB7c1mApX5oqlgsxzHQesYF7l5n1gKrEmrClIiZuOFbFDQcjLsmcWSwwmrWrcGWm9Fxc/g==", + "version": "0.31.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.31.4.tgz", + "integrity": "sha512-uzL377GjJtTbuc5KQxVbDu2xfU/x0wVjUtXQR2ihS21q/NK6ROr4oG0rsSkBBddZUVCwzfx22in76/0ZZHXgkQ==", "dev": true, "dependencies": { "cac": "^6.7.14", @@ -9187,19 +9151,19 @@ } }, "node_modules/vitest": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.31.0.tgz", - "integrity": "sha512-JwWJS9p3GU9GxkG7eBSmr4Q4x4bvVBSswaCFf1PBNHiPx00obfhHRJfgHcnI0ffn+NMlIh9QGvG75FlaIBdKGA==", + "version": "0.31.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.31.4.tgz", + "integrity": "sha512-GoV0VQPmWrUFOZSg3RpQAPN+LPmHg2/gxlMNJlyxJihkz6qReHDV6b0pPDcqFLNEPya4tWJ1pgwUNP9MLmUfvQ==", "dev": true, "dependencies": { - "@types/chai": "^4.3.4", + "@types/chai": "^4.3.5", "@types/chai-subset": "^1.3.3", "@types/node": "*", - "@vitest/expect": "0.31.0", - "@vitest/runner": "0.31.0", - "@vitest/snapshot": "0.31.0", - "@vitest/spy": "0.31.0", - "@vitest/utils": "0.31.0", + "@vitest/expect": "0.31.4", + "@vitest/runner": "0.31.4", + "@vitest/snapshot": "0.31.4", + "@vitest/spy": "0.31.4", + "@vitest/utils": "0.31.4", "acorn": "^8.8.2", "acorn-walk": "^8.2.0", "cac": "^6.7.14", @@ -9212,10 +9176,10 @@ "picocolors": "^1.0.0", "std-env": "^3.3.2", "strip-literal": "^1.0.1", - "tinybench": "^2.4.0", + "tinybench": "^2.5.0", "tinypool": "^0.5.0", "vite": "^3.0.0 || ^4.0.0", - "vite-node": "0.31.0", + "vite-node": "0.31.4", "why-is-node-running": "^2.2.2" }, "bin": { @@ -9627,12 +9591,12 @@ "dev": true }, "@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "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.1.0", + "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" } }, @@ -9702,19 +9666,6 @@ "@babel/types": "^7.20.2", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - } } }, "@babel/helper-annotate-as-pure": { @@ -10136,14 +10087,14 @@ "dev": true }, "@eslint/eslintrc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz", - "integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", + "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.1", + "espree": "^9.5.2", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -10170,9 +10121,9 @@ } }, "@eslint/js": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz", - "integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz", + "integrity": "sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==", "dev": true }, "@humanwhocodes/config-array": { @@ -10288,13 +10239,14 @@ } }, "@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "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.0", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" } }, "@jridgewell/resolve-uri": { @@ -10659,9 +10611,9 @@ "dev": true }, "@types/chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", + "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", "dev": true }, "@types/chai-subset": { @@ -10846,15 +10798,15 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.2.tgz", - "integrity": "sha512-yVrXupeHjRxLDcPKL10sGQ/QlVrA8J5IYOEWVqk0lJaSZP7X5DfnP7Ns3cc74/blmbipQ1htFNVGsHX6wsYm0A==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.8.tgz", + "integrity": "sha512-JDMOmhXteJ4WVKOiHXGCoB96ADWg9q7efPWHRViT/f09bA8XOMLAVHHju3l0MkZnG1izaWXYmgvQcUjTRcpShQ==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.2", - "@typescript-eslint/type-utils": "5.59.2", - "@typescript-eslint/utils": "5.59.2", + "@typescript-eslint/scope-manager": "5.59.8", + "@typescript-eslint/type-utils": "5.59.8", + "@typescript-eslint/utils": "5.59.8", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -10864,29 +10816,29 @@ }, "dependencies": { "@typescript-eslint/scope-manager": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz", - "integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz", + "integrity": "sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/visitor-keys": "5.59.2" + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8" } }, "@typescript-eslint/types": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz", - "integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", + "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz", - "integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz", + "integrity": "sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/visitor-keys": "5.59.2", + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -10895,28 +10847,28 @@ } }, "@typescript-eslint/utils": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.2.tgz", - "integrity": "sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.8.tgz", + "integrity": "sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.2", - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/typescript-estree": "5.59.2", + "@typescript-eslint/scope-manager": "5.59.8", + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/typescript-estree": "5.59.8", "eslint-scope": "^5.1.1", "semver": "^7.3.7" } }, "@typescript-eslint/visitor-keys": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz", - "integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", + "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/types": "5.59.8", "eslint-visitor-keys": "^3.3.0" } }, @@ -10937,9 +10889,9 @@ "dev": true }, "semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -10957,41 +10909,41 @@ } }, "@typescript-eslint/parser": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.2.tgz", - "integrity": "sha512-uq0sKyw6ao1iFOZZGk9F8Nro/8+gfB5ezl1cA06SrqbgJAt0SRoFhb9pXaHvkrxUpZaoLxt8KlovHNk8Gp6/HQ==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.8.tgz", + "integrity": "sha512-AnR19RjJcpjoeGojmwZtCwBX/RidqDZtzcbG3xHrmz0aHHoOcbWnpDllenRDmDvsV0RQ6+tbb09/kyc+UT9Orw==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.59.2", - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/typescript-estree": "5.59.2", + "@typescript-eslint/scope-manager": "5.59.8", + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/typescript-estree": "5.59.8", "debug": "^4.3.4" }, "dependencies": { "@typescript-eslint/scope-manager": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz", - "integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz", + "integrity": "sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/visitor-keys": "5.59.2" + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8" } }, "@typescript-eslint/types": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz", - "integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", + "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz", - "integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz", + "integrity": "sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/visitor-keys": "5.59.2", + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -11000,19 +10952,19 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz", - "integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", + "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/types": "5.59.8", "eslint-visitor-keys": "^3.3.0" } }, "semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -11031,41 +10983,41 @@ } }, "@typescript-eslint/type-utils": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.2.tgz", - "integrity": "sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.8.tgz", + "integrity": "sha512-+5M518uEIHFBy3FnyqZUF3BMP+AXnYn4oyH8RF012+e7/msMY98FhGL5SrN29NQ9xDgvqCgYnsOiKp1VjZ/fpA==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.59.2", - "@typescript-eslint/utils": "5.59.2", + "@typescript-eslint/typescript-estree": "5.59.8", + "@typescript-eslint/utils": "5.59.8", "debug": "^4.3.4", "tsutils": "^3.21.0" }, "dependencies": { "@typescript-eslint/scope-manager": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz", - "integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz", + "integrity": "sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/visitor-keys": "5.59.2" + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8" } }, "@typescript-eslint/types": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz", - "integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", + "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz", - "integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz", + "integrity": "sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/visitor-keys": "5.59.2", + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -11074,28 +11026,28 @@ } }, "@typescript-eslint/utils": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.2.tgz", - "integrity": "sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.8.tgz", + "integrity": "sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.2", - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/typescript-estree": "5.59.2", + "@typescript-eslint/scope-manager": "5.59.8", + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/typescript-estree": "5.59.8", "eslint-scope": "^5.1.1", "semver": "^7.3.7" } }, "@typescript-eslint/visitor-keys": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz", - "integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", + "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/types": "5.59.8", "eslint-visitor-keys": "^3.3.0" } }, @@ -11116,9 +11068,9 @@ "dev": true }, "semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -11247,12 +11199,12 @@ } }, "@vitest/coverage-c8": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@vitest/coverage-c8/-/coverage-c8-0.31.0.tgz", - "integrity": "sha512-h72qN1D962AO7UefQVulm9JFP5ACS7OfhCdBHioXU8f7ohH/+NTZCgAqmgcfRNHHO/8wLFxx+93YVxhodkEJVA==", + "version": "0.31.4", + "resolved": "https://registry.npmjs.org/@vitest/coverage-c8/-/coverage-c8-0.31.4.tgz", + "integrity": "sha512-VPx368m4DTcpA/P0v3YdVxl4QOSh1DbUcXURLRvDShrIB5KxOgfzw4Bn2R8AhAe/GyiWW/FIsJ/OJdYXCCiC1w==", "dev": true, "requires": { - "@ampproject/remapping": "^2.2.0", + "@ampproject/remapping": "^2.2.1", "c8": "^7.13.0", "magic-string": "^0.30.0", "picocolors": "^1.0.0", @@ -11260,23 +11212,23 @@ } }, "@vitest/expect": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.31.0.tgz", - "integrity": "sha512-Jlm8ZTyp6vMY9iz9Ny9a0BHnCG4fqBa8neCF6Pk/c/6vkUk49Ls6UBlgGAU82QnzzoaUs9E/mUhq/eq9uMOv/g==", + "version": "0.31.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.31.4.tgz", + "integrity": "sha512-tibyx8o7GUyGHZGyPgzwiaPaLDQ9MMuCOrc03BYT0nryUuhLbL7NV2r/q98iv5STlwMgaKuFJkgBW/8iPKwlSg==", "dev": true, "requires": { - "@vitest/spy": "0.31.0", - "@vitest/utils": "0.31.0", + "@vitest/spy": "0.31.4", + "@vitest/utils": "0.31.4", "chai": "^4.3.7" } }, "@vitest/runner": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.31.0.tgz", - "integrity": "sha512-H1OE+Ly7JFeBwnpHTrKyCNm/oZgr+16N4qIlzzqSG/YRQDATBYmJb/KUn3GrZaiQQyL7GwpNHVZxSQd6juLCgw==", + "version": "0.31.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.31.4.tgz", + "integrity": "sha512-Wgm6UER+gwq6zkyrm5/wbpXGF+g+UBB78asJlFkIOwyse0pz8lZoiC6SW5i4gPnls/zUcPLWS7Zog0LVepXnpg==", "dev": true, "requires": { - "@vitest/utils": "0.31.0", + "@vitest/utils": "0.31.4", "concordance": "^5.0.4", "p-limit": "^4.0.0", "pathe": "^1.1.0" @@ -11300,9 +11252,9 @@ } }, "@vitest/snapshot": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.31.0.tgz", - "integrity": "sha512-5dTXhbHnyUMTMOujZPB0wjFjQ6q5x9c8TvAsSPUNKjp1tVU7i9pbqcKPqntyu2oXtmVxKbuHCqrOd+Ft60r4tg==", + "version": "0.31.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.31.4.tgz", + "integrity": "sha512-LemvNumL3NdWSmfVAMpXILGyaXPkZbG5tyl6+RQSdcHnTj6hvA49UAI8jzez9oQyE/FWLKRSNqTGzsHuk89LRA==", "dev": true, "requires": { "magic-string": "^0.30.0", @@ -11311,33 +11263,33 @@ } }, "@vitest/spy": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.31.0.tgz", - "integrity": "sha512-IzCEQ85RN26GqjQNkYahgVLLkULOxOm5H/t364LG0JYb3Apg0PsYCHLBYGA006+SVRMWhQvHlBBCyuByAMFmkg==", + "version": "0.31.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.31.4.tgz", + "integrity": "sha512-3ei5ZH1s3aqbEyftPAzSuunGICRuhE+IXOmpURFdkm5ybUADk+viyQfejNk6q8M5QGX8/EVKw+QWMEP3DTJDag==", "dev": true, "requires": { "tinyspy": "^2.1.0" } }, "@vitest/ui": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-0.31.0.tgz", - "integrity": "sha512-Dy86l6r3/dbJposgm7w+oqb/15UWJ0lDBbEQaS1ived3+0CTaMbT8OMkUf9vNBkSL47kvBHEBnZLa5fw5i9gUQ==", + "version": "0.31.4", + "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-0.31.4.tgz", + "integrity": "sha512-sKM16ITX6HrNFF+lNZ2AQAen4/6Bx2i6KlBfIvkUjcTgc5YII/j2ltcX14oCUv4EA0OTWGQuGhO3zDoAsTENGA==", "dev": true, "requires": { - "@vitest/utils": "0.31.0", + "@vitest/utils": "0.31.4", "fast-glob": "^3.2.12", "fflate": "^0.7.4", "flatted": "^3.2.7", "pathe": "^1.1.0", "picocolors": "^1.0.0", - "sirv": "^2.0.2" + "sirv": "^2.0.3" } }, "@vitest/utils": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.31.0.tgz", - "integrity": "sha512-kahaRyLX7GS1urekRXN2752X4gIgOGVX4Wo8eDUGUkTWlGpXzf5ZS6N9RUUS+Re3XEE8nVGqNyxkSxF5HXlGhQ==", + "version": "0.31.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.31.4.tgz", + "integrity": "sha512-DobZbHacWznoGUfYU8XDPY78UubJxXfMNY1+SUdOp1NsI34eopSA6aZMeaGu10waSOeYwE8lxrd/pLfT0RMxjQ==", "dev": true, "requires": { "concordance": "^5.0.4", @@ -11985,9 +11937,9 @@ }, "dependencies": { "semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -12388,15 +12340,15 @@ "dev": true }, "eslint": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz", - "integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz", + "integrity": "sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.2", - "@eslint/js": "8.39.0", + "@eslint/eslintrc": "^2.0.3", + "@eslint/js": "8.41.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -12407,8 +12359,8 @@ "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.0", - "espree": "^9.5.1", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -12416,13 +12368,12 @@ "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", @@ -12652,20 +12603,20 @@ } }, "eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", "dev": true }, "espree": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz", - "integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==", + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", + "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", "dev": true, "requires": { "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.0" + "eslint-visitor-keys": "^3.4.1" } }, "esquery": { @@ -12761,9 +12712,9 @@ "dev": true }, "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "dev": true }, "fast-glob": { @@ -13070,6 +13021,12 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, "graphql": { "version": "16.6.0", "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.6.0.tgz", @@ -13233,12 +13190,9 @@ } }, "idb-keyval": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.0.tgz", - "integrity": "sha512-uw+MIyQn2jl3+hroD7hF8J7PUviBU7BPKWw4f/ISf32D4LoGu98yHjrzWWJDASu9QNrX10tCJqk9YY0ClWm8Ng==", - "requires": { - "safari-14-idb-fix": "^3.0.0" - } + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.1.tgz", + "integrity": "sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==" }, "ieee754": { "version": "1.2.1", @@ -13253,9 +13207,9 @@ "dev": true }, "immer": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.1.tgz", - "integrity": "sha512-zg++jJLsKKTwXGeSYIw0HgChSYQGtu0UDTnbKx5aGLYgte4CwTmH9eJDYyQ6FheyUtBe+lQW9FrGxya1G+Dtmg==" + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.2.tgz", + "integrity": "sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==" }, "import-fresh": { "version": "3.3.0", @@ -14030,12 +13984,6 @@ "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", "dev": true }, - "js-sdsl": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", - "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", - "dev": true - }, "js-string-escape": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", @@ -14058,9 +14006,9 @@ } }, "jsdom": { - "version": "22.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.0.0.tgz", - "integrity": "sha512-p5ZTEb5h+O+iU02t0GfEjAnkdYPrQSkfuTSMkMYyIoMvUNEHsbG0bHHbfXIcfTqD2UfvjQX7mmgiFsyRwGscVw==", + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz", + "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==", "dev": true, "requires": { "abab": "^2.0.6", @@ -14433,15 +14381,15 @@ } }, "mlly": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.2.0.tgz", - "integrity": "sha512-+c7A3CV0KGdKcylsI6khWyts/CYrGTrRVo4R/I7u/cUsy0Conxa6LUhiEzVKIw14lc2L5aiO4+SeVe4TeGRKww==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.3.0.tgz", + "integrity": "sha512-HT5mcgIQKkOrZecOjOX3DJorTikWXwsBfpcr/MGBkhfWcjiqvnaL/9ppxvIUXfjT6xt4DVIAsN9fMUz1ev4bIw==", "dev": true, "requires": { "acorn": "^8.8.2", "pathe": "^1.1.0", - "pkg-types": "^1.0.2", - "ufo": "^1.1.1" + "pkg-types": "^1.0.3", + "ufo": "^1.1.2" } }, "monaco-editor": { @@ -15017,9 +14965,9 @@ } }, "postcss": { - "version": "8.4.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", - "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==", + "version": "8.4.24", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", + "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", "dev": true, "requires": { "nanoid": "^3.3.6", @@ -15083,9 +15031,9 @@ "dev": true }, "preact": { - "version": "10.13.2", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.13.2.tgz", - "integrity": "sha512-q44QFLhOhty2Bd0Y46fnYW0gD/cbVM9dUVtNTDKPcdXSMA7jfY+Jpd6rk3GB0lcQss0z5s/6CmVP0Z/hV+g6pw==" + "version": "10.15.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.15.1.tgz", + "integrity": "sha512-qs2ansoQEwzNiV5eAcRT1p1EC/dmEzaATVDJNiB3g2sRDWdA7b7MurXdJjB2+/WQktGWZwxvDrnuRFbWuIr64g==" }, "preact-async-route": { "version": "2.2.1", @@ -15093,9 +15041,9 @@ "integrity": "sha512-8bg1007akXs3YDmzYT4McaTe6ji2FIzcc0/NTlu+vjJaKPNQ8lNG/HQ6LP+FoIxQ4m/KH5vvJCHJN5ADp2iNGA==" }, "preact-router": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/preact-router/-/preact-router-4.1.0.tgz", - "integrity": "sha512-y1w2YvVpKAju9FMV+fAVR1NpH4MW5q07BZrziMZeg6F/rGJ9KvLUZtjOqsy2I8fDYiX36AM1AQTXIIK3jigBhA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/preact-router/-/preact-router-4.1.1.tgz", + "integrity": "sha512-+LGrB3b2nR7+8vzyHw8i2/TjZazs3oMJovIEgBChPBXMDSISmwj2WDynZh8KDxZRK2GuXlqHPk15mMjaYWZH4g==", "requires": {} }, "prelude-ls": { @@ -15417,11 +15365,6 @@ "tslib": "^2.1.0" } }, - "safari-14-idb-fix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/safari-14-idb-fix/-/safari-14-idb-fix-3.0.0.tgz", - "integrity": "sha512-eBNFLob4PMq8JA1dGyFn6G97q3/WzNtFK4RnzT1fnLq+9RyrGknzYiM/9B12MnKAxuj1IXr7UKYtTNtjyKMBog==" - }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -15513,9 +15456,9 @@ "dev": true }, "sirv": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.2.tgz", - "integrity": "sha512-4Qog6aE29nIjAOKe/wowFTxOdmbEZKb+3tsLljaBRzJwtqto0BChD2zzH0LhgCSXiI+V7X+Y45v14wBZQ1TK3w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.3.tgz", + "integrity": "sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==", "dev": true, "requires": { "@polka/url": "^1.0.0-next.20", @@ -15565,9 +15508,9 @@ "dev": true }, "strftime": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/strftime/-/strftime-0.10.1.tgz", - "integrity": "sha512-nVvH6JG8KlXFPC0f8lojLgEsPA18lRpLZ+RrJh/NkQV2tqOgZfbas8gcU8SFgnnqR3rWzZPYu6N2A3xzs/8rQg==" + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/strftime/-/strftime-0.10.2.tgz", + "integrity": "sha512-Y6IZaTVM80chcMe7j65Gl/0nmlNdtt+KWPle5YeCAjmsBfw+id2qdaJ5MDrxUq+OmHKab+jHe7mUjU/aNMSZZg==" }, "strict-event-emitter": { "version": "0.2.8", @@ -15684,17 +15627,6 @@ "ts-interface-checker": "^0.1.9" }, "dependencies": { - "@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" - } - }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -15872,9 +15804,9 @@ "dev": true }, "tinybench": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.4.0.tgz", - "integrity": "sha512-iyziEiyFxX4kyxSp+MtY1oCH/lvjH3PxFN8PGCDeqcZWAJ/i+9y+nL85w99PxVzrIvew/GSkSbDYtiGVa85Afg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.0.tgz", + "integrity": "sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==", "dev": true }, "tinypool": { @@ -15884,9 +15816,9 @@ "dev": true }, "tinyspy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.1.0.tgz", - "integrity": "sha512-7eORpyqImoOvkQJCSkL0d0mB4NHHIFAy4b1u8PHdDa7SjGS2njzl6/lyGoZLm+eyYEtlUmFGE0rFj66SWxZgQQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.1.1.tgz", + "integrity": "sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==", "dev": true }, "tmp": { @@ -15919,9 +15851,9 @@ "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" }, "totalist": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.0.tgz", - "integrity": "sha512-eM+pCBxXO/njtF7vdFsHuqb+ElbxqtI4r5EAvk6grfAFyJ6IvWlSkfZ5T9ozC6xWw3Fj1fGoSmrl0gUs46JVIw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true }, "tough-cookie": { @@ -16191,9 +16123,9 @@ } }, "vite": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.5.tgz", - "integrity": "sha512-0gEnL9wiRFxgz40o/i/eTBwm+NEbpUeTWhzKrZDSdKm6nplj+z4lKz8ANDgildxHm47Vg8EUia0aicKbawUVVA==", + "version": "4.3.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz", + "integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==", "dev": true, "requires": { "esbuild": "^0.17.5", @@ -16203,9 +16135,9 @@ } }, "vite-node": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.31.0.tgz", - "integrity": "sha512-8x1x1LNuPvE2vIvkSB7c1mApX5oqlgsxzHQesYF7l5n1gKrEmrClIiZuOFbFDQcjLsmcWSwwmrWrcGWm9Fxc/g==", + "version": "0.31.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.31.4.tgz", + "integrity": "sha512-uzL377GjJtTbuc5KQxVbDu2xfU/x0wVjUtXQR2ihS21q/NK6ROr4oG0rsSkBBddZUVCwzfx22in76/0ZZHXgkQ==", "dev": true, "requires": { "cac": "^6.7.14", @@ -16223,19 +16155,19 @@ "requires": {} }, "vitest": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.31.0.tgz", - "integrity": "sha512-JwWJS9p3GU9GxkG7eBSmr4Q4x4bvVBSswaCFf1PBNHiPx00obfhHRJfgHcnI0ffn+NMlIh9QGvG75FlaIBdKGA==", + "version": "0.31.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.31.4.tgz", + "integrity": "sha512-GoV0VQPmWrUFOZSg3RpQAPN+LPmHg2/gxlMNJlyxJihkz6qReHDV6b0pPDcqFLNEPya4tWJ1pgwUNP9MLmUfvQ==", "dev": true, "requires": { - "@types/chai": "^4.3.4", + "@types/chai": "^4.3.5", "@types/chai-subset": "^1.3.3", "@types/node": "*", - "@vitest/expect": "0.31.0", - "@vitest/runner": "0.31.0", - "@vitest/snapshot": "0.31.0", - "@vitest/spy": "0.31.0", - "@vitest/utils": "0.31.0", + "@vitest/expect": "0.31.4", + "@vitest/runner": "0.31.4", + "@vitest/snapshot": "0.31.4", + "@vitest/spy": "0.31.4", + "@vitest/utils": "0.31.4", "acorn": "^8.8.2", "acorn-walk": "^8.2.0", "cac": "^6.7.14", @@ -16248,10 +16180,10 @@ "picocolors": "^1.0.0", "std-env": "^3.3.2", "strip-literal": "^1.0.1", - "tinybench": "^2.4.0", + "tinybench": "^2.5.0", "tinypool": "^0.5.0", "vite": "^3.0.0 || ^4.0.0", - "vite-node": "0.31.0", + "vite-node": "0.31.4", "why-is-node-running": "^2.2.2" } }, From f0c1b66b0f1da88f16d84e02ebd24e46d874fe5c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Jun 2023 07:05:39 -0500 Subject: [PATCH 6/8] Bump actions/setup-python from 4.6.0 to 4.6.1 (#6609) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4.6.0 to 4.6.1. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v4.6.0...v4.6.1) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/pull_request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 7e38c3b99..7e97cfb6c 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -65,7 +65,7 @@ jobs: - name: Check out the repository uses: actions/checkout@v3 - name: Set up Python ${{ env.DEFAULT_PYTHON }} - uses: actions/setup-python@v4.6.0 + uses: actions/setup-python@v4.6.1 with: python-version: ${{ env.DEFAULT_PYTHON }} - name: Install requirements From d1701e127ec311e12c002839aabeab7c9ee06d76 Mon Sep 17 00:00:00 2001 From: Michael Wei Date: Mon, 5 Jun 2023 14:13:54 -0700 Subject: [PATCH 7/8] fix: don't assume build platform is amd64 (#6709) --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index bb010c780..0c244f901 100644 --- a/Dockerfile +++ b/Dockerfile @@ -227,8 +227,8 @@ CMD ["sleep", "infinity"] # Frigate web build -# force this to run on amd64 because QEMU is painfully slow -FROM --platform=linux/amd64 node:16 AS web-build +# This should be architecture agnostic, so speed up the build on multiarch by not using QEMU. +FROM --platform=$BUILDPLATFORM node:16 AS web-build WORKDIR /work COPY web/package.json web/package-lock.json ./ From d3949eebfa1d5adf38e22f1d719321969c51b787 Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Thu, 8 Jun 2023 05:32:35 -0600 Subject: [PATCH 8/8] Add API and WebUI to export recordings (#6550) * Add ability to export frigate clips * Add http endpoint * Add dir to nginx * Add webUI * Formatting * Cleanup unused * Optimize timelapse * Fix pts * Use JSON body for params * Use hwaccel to encode when available * Print ffmpeg command when fail * Print ffmpeg command when fail * Add separate ffmpeg preset for timelapse * Add docs outlining the export directory * Add export docs * Use '' * Fix playlist max time * Lower max playlist time * Add api docs for export * isort fixes --- docker/rootfs/usr/local/nginx/conf/nginx.conf | 21 ++++ docs/docs/configuration/record.md | 4 + docs/docs/frigate/installation.md | 3 +- docs/docs/integrations/api.md | 14 +++ frigate/app.py | 10 +- frigate/const.py | 2 + frigate/ffmpeg_presets.py | 36 +++++-- frigate/http.py | 17 +++ frigate/record/export.py | 101 ++++++++++++++++++ web/src/Sidebar.jsx | 1 + web/src/app.tsx | 1 + web/src/routes/Export.jsx | 83 ++++++++++++++ web/src/routes/index.js | 5 + 13 files changed, 290 insertions(+), 8 deletions(-) create mode 100644 frigate/record/export.py create mode 100644 web/src/routes/Export.jsx diff --git a/docker/rootfs/usr/local/nginx/conf/nginx.conf b/docker/rootfs/usr/local/nginx/conf/nginx.conf index a6b50e317..35703fb2c 100644 --- a/docker/rootfs/usr/local/nginx/conf/nginx.conf +++ b/docker/rootfs/usr/local/nginx/conf/nginx.conf @@ -172,6 +172,27 @@ http { root /media/frigate; } + location /exports/ { + add_header 'Access-Control-Allow-Origin' "$http_origin" always; + add_header 'Access-Control-Allow-Credentials' 'true'; + add_header 'Access-Control-Expose-Headers' 'Content-Length'; + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Allow-Origin' "$http_origin"; + add_header 'Access-Control-Max-Age' 1728000; + add_header 'Content-Type' 'text/plain charset=UTF-8'; + add_header 'Content-Length' 0; + return 204; + } + + types { + video/mp4 mp4; + } + + autoindex on; + autoindex_format json; + root /media/frigate; + } + location /ws { proxy_pass http://mqtt_ws/; proxy_http_version 1.1; diff --git a/docs/docs/configuration/record.md b/docs/docs/configuration/record.md index f22f37d02..29a2fb36b 100644 --- a/docs/docs/configuration/record.md +++ b/docs/docs/configuration/record.md @@ -80,3 +80,7 @@ record: dog: 2 car: 7 ``` + +## How do I export recordings? + +The export page in the Frigate WebUI allows for exporting real time clips with a designated start and stop time as well as exporting a timelapse for a designated start and stop time. These exports can take a while so it is important to leave the file until it is no longer in progress. diff --git a/docs/docs/frigate/installation.md b/docs/docs/frigate/installation.md index 115a85c17..1397f8741 100644 --- a/docs/docs/frigate/installation.md +++ b/docs/docs/frigate/installation.md @@ -24,6 +24,7 @@ Frigate uses the following locations for read/write operations in the container. - `/config`: Used to store the Frigate config file and sqlite database. You will also see a few files alongside the database file while Frigate is running. - `/media/frigate/clips`: Used for snapshot storage. In the future, it will likely be renamed from `clips` to `snapshots`. The file structure here cannot be modified and isn't intended to be browsed or managed manually. - `/media/frigate/recordings`: Internal system storage for recording segments. The file structure here cannot be modified and isn't intended to be browsed or managed manually. +- `/media/frigate/exports`: Storage for clips and timelapses that have been exported via the WebUI or API. - `/tmp/cache`: Cache location for recording segments. Initial recordings are written here before being checked and converted to mp4 and moved to the recordings folder. - `/dev/shm`: It is not recommended to modify this directory or map it with docker. This is the location for raw decoded frames in shared memory and it's size is impacted by the `shm-size` calculations below. @@ -221,7 +222,7 @@ These settings were tested on DSM 7.1.1-42962 Update 4 The `Execute container using high privilege` option needs to be enabled in order to give the frigate container the elevated privileges it may need. -The `Enable auto-restart` option can be enabled if you want the container to automatically restart whenever it improperly shuts down due to an error. +The `Enable auto-restart` option can be enabled if you want the container to automatically restart whenever it improperly shuts down due to an error. ![image](https://user-images.githubusercontent.com/4516296/232586790-0b659a82-561d-4bc5-899b-0f5b39c6b11d.png) diff --git a/docs/docs/integrations/api.md b/docs/docs/integrations/api.md index 3e5fdfe3e..f36f33770 100644 --- a/docs/docs/integrations/api.md +++ b/docs/docs/integrations/api.md @@ -271,6 +271,20 @@ HTTP Live Streaming Video on Demand URL for the specified event. Can be viewed i HTTP Live Streaming Video on Demand URL for the camera with the specified time range. Can be viewed in an application like VLC. +### `POST /api/export//start//end/` + +Export recordings from `start-timestamp` to `end-timestamp` for `camera` as a single mp4 file. These recordings will be exported to the `/media/frigate/exports` folder. + +It is also possible to export this recording as a timelapse. + +**Optional Body:** + +```json +{ + "playback": "realtime", // playback factor: realtime or timelapse_25x +} +``` + ### `GET /api//recordings/summary` Hourly summary of recordings data for a camera. diff --git a/frigate/app.py b/frigate/app.py index bcbd3ed2d..2db8728b2 100644 --- a/frigate/app.py +++ b/frigate/app.py @@ -24,6 +24,7 @@ from frigate.const import ( CLIPS_DIR, CONFIG_DIR, DEFAULT_DB_PATH, + EXPORT_DIR, MODEL_CACHE_DIR, RECORD_DIR, ) @@ -68,7 +69,14 @@ class FrigateApp: os.environ[key] = value def ensure_dirs(self) -> None: - for d in [CONFIG_DIR, RECORD_DIR, CLIPS_DIR, CACHE_DIR, MODEL_CACHE_DIR]: + for d in [ + CONFIG_DIR, + RECORD_DIR, + CLIPS_DIR, + CACHE_DIR, + MODEL_CACHE_DIR, + EXPORT_DIR, + ]: if not os.path.exists(d) and not os.path.islink(d): logger.info(f"Creating directory: {d}") os.makedirs(d) diff --git a/frigate/const.py b/frigate/const.py index df5098853..9b7e177f2 100644 --- a/frigate/const.py +++ b/frigate/const.py @@ -4,6 +4,7 @@ MODEL_CACHE_DIR = f"{CONFIG_DIR}/model_cache" BASE_DIR = "/media/frigate" CLIPS_DIR = f"{BASE_DIR}/clips" RECORD_DIR = f"{BASE_DIR}/recordings" +EXPORT_DIR = f"{BASE_DIR}/exports" BIRDSEYE_PIPE = "/tmp/cache/birdseye" CACHE_DIR = "/tmp/cache" YAML_EXT = (".yaml", ".yml") @@ -28,3 +29,4 @@ DRIVER_INTEL_iHD = "iHD" MAX_SEGMENT_DURATION = 600 SECONDS_IN_DAY = 60 * 60 * 24 +MAX_PLAYLIST_SECONDS = 7200 # support 2 hour segments for a single playlist to account for cameras with inconsistent segment times diff --git a/frigate/ffmpeg_presets.py b/frigate/ffmpeg_presets.py index d78cd72ef..dde158916 100644 --- a/frigate/ffmpeg_presets.py +++ b/frigate/ffmpeg_presets.py @@ -2,6 +2,7 @@ import logging import os +from enum import Enum from typing import Any from frigate.const import BTBN_PATH @@ -116,7 +117,7 @@ PRESETS_HW_ACCEL_SCALE = { "default": "-r {0} -s {1}x{2}", } -PRESETS_HW_ACCEL_ENCODE = { +PRESETS_HW_ACCEL_ENCODE_BIRDSEYE = { "preset-rpi-32-h264": "ffmpeg -hide_banner {0} -c:v h264_v4l2m2m {1}", "preset-rpi-64-h264": "ffmpeg -hide_banner {0} -c:v h264_v4l2m2m {1}", "preset-vaapi": "ffmpeg -hide_banner -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_device {2} {0} -c:v h264_vaapi -g 50 -bf 0 -profile:v high -level:v 4.1 -sei:v 0 -an -vf format=vaapi|nv12,hwupload {1}", @@ -127,6 +128,17 @@ PRESETS_HW_ACCEL_ENCODE = { "default": "ffmpeg -hide_banner {0} -c:v libx264 -g 50 -profile:v high -level:v 4.1 -preset:v superfast -tune:v zerolatency {1}", } +PRESETS_HW_ACCEL_ENCODE_TIMELAPSE = { + "preset-rpi-32-h264": "ffmpeg -hide_banner {0} -c:v h264_v4l2m2m {1}", + "preset-rpi-64-h264": "ffmpeg -hide_banner {0} -c:v h264_v4l2m2m {1}", + "preset-vaapi": "ffmpeg -hide_banner -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_device {2} {0} -c:v h264_vaapi {1}", + "preset-intel-qsv-h264": "ffmpeg -hide_banner {0} -c:v h264_qsv -g 50 -bf 0 -profile:v high -level:v 4.1 -async_depth:v 1 {1}", + "preset-intel-qsv-h265": "ffmpeg -hide_banner {0} -c:v hevc_qsv -g 50 -bf 0 -profile:v high -level:v 4.1 -async_depth:v 1 {1}", + "preset-nvidia-h264": "ffmpeg -hide_banner -hwaccel cuda -hwaccel_output_format cuda -extra_hw_frames 8 {0} -c:v h264_nvenc {1}", + "preset-nvidia-h265": "ffmpeg -hide_banner -hwaccel cuda -hwaccel_output_format cuda -extra_hw_frames 8 {0} -c:v hevc_nvenc {1}", + "default": "ffmpeg -hide_banner {0} -c:v libx264 -preset:v ultrafast -tune:v zerolatency {1}", +} + def parse_preset_hardware_acceleration_decode(arg: Any) -> list[str]: """Return the correct preset if in preset format otherwise return None.""" @@ -161,12 +173,24 @@ def parse_preset_hardware_acceleration_scale( return scale -def parse_preset_hardware_acceleration_encode(arg: Any, input: str, output: str) -> str: - """Return the correct scaling preset or default preset if none is set.""" - if not isinstance(arg, str): - return PRESETS_HW_ACCEL_ENCODE["default"].format(input, output) +class EncodeTypeEnum(str, Enum): + birdseye = "birdseye" + timelapse = "timelapse" - return PRESETS_HW_ACCEL_ENCODE.get(arg, PRESETS_HW_ACCEL_ENCODE["default"]).format( + +def parse_preset_hardware_acceleration_encode( + arg: Any, input: str, output: str, type: EncodeTypeEnum = EncodeTypeEnum.birdseye +) -> str: + """Return the correct scaling preset or default preset if none is set.""" + if type == EncodeTypeEnum.birdseye: + arg_map = PRESETS_HW_ACCEL_ENCODE_BIRDSEYE + elif type == EncodeTypeEnum.timelapse: + arg_map = PRESETS_HW_ACCEL_ENCODE_TIMELAPSE + + if not isinstance(arg, str): + return arg_map["default"].format(input, output) + + return arg_map.get(arg, arg_map["default"]).format( input, output, _gpu_selector.get_selected_gpu(), diff --git a/frigate/http.py b/frigate/http.py index b94637976..7ee4c7f43 100644 --- a/frigate/http.py +++ b/frigate/http.py @@ -35,6 +35,7 @@ from frigate.models import Event, Recordings, Timeline from frigate.object_processing import TrackedObject from frigate.plus import PlusApi from frigate.ptz import OnvifController +from frigate.record.export import PlaybackFactorEnum, RecordingExporter from frigate.stats import stats_snapshot from frigate.storage import StorageMaintainer from frigate.util import ( @@ -1504,6 +1505,22 @@ def vod_event(id): ) +@bp.route("/export//start//end/", methods=["POST"]) +def export_recording(camera_name: str, start_time: int, end_time: int): + playback_factor = request.get_json(silent=True).get("playback", "realtime") + exporter = RecordingExporter( + current_app.frigate_config, + camera_name, + int(start_time), + int(end_time), + PlaybackFactorEnum[playback_factor] + if playback_factor in PlaybackFactorEnum.__members__.values() + else PlaybackFactorEnum.realtime, + ) + exporter.start() + return "Starting export of recording", 200 + + def imagestream(detected_frames_processor, camera_name, fps, height, draw_options): while True: # max out at specified FPS diff --git a/frigate/record/export.py b/frigate/record/export.py new file mode 100644 index 000000000..077f24638 --- /dev/null +++ b/frigate/record/export.py @@ -0,0 +1,101 @@ +"""Export recordings to storage.""" + +import datetime +import logging +import os +import subprocess as sp +import threading +from enum import Enum + +from frigate.config import FrigateConfig +from frigate.const import EXPORT_DIR, MAX_PLAYLIST_SECONDS +from frigate.ffmpeg_presets import ( + EncodeTypeEnum, + parse_preset_hardware_acceleration_encode, +) + +logger = logging.getLogger(__name__) + + +class PlaybackFactorEnum(str, Enum): + realtime = "realtime" + timelapse_25x = "timelapse_25x" + + +class RecordingExporter(threading.Thread): + """Exports a specific set of recordings for a camera to storage as a single file.""" + + def __init__( + self, + config: FrigateConfig, + camera: str, + start_time: int, + end_time: int, + playback_factor: PlaybackFactorEnum, + ) -> None: + threading.Thread.__init__(self) + self.config = config + self.camera = camera + self.start_time = start_time + self.end_time = end_time + self.playback_factor = playback_factor + + def get_datetime_from_timestamp(self, timestamp: int) -> str: + """Convenience fun to get a simple date time from timestamp.""" + return datetime.datetime.fromtimestamp(timestamp).strftime("%Y_%m_%d_%I:%M") + + def run(self) -> None: + logger.debug( + f"Beginning export for {self.camera} from {self.start_time} to {self.end_time}" + ) + file_name = f"{EXPORT_DIR}/in_progress.{self.camera}@{self.get_datetime_from_timestamp(self.start_time)}__{self.get_datetime_from_timestamp(self.end_time)}.mp4" + final_file_name = f"{EXPORT_DIR}/{self.camera}_{self.get_datetime_from_timestamp(self.start_time)}__{self.get_datetime_from_timestamp(self.end_time)}.mp4" + + if (self.end_time - self.start_time) <= MAX_PLAYLIST_SECONDS: + playlist_lines = f"http://127.0.0.1:5000/vod/{self.camera}/start/{self.start_time}/end/{self.end_time}/index.m3u8" + ffmpeg_input = ( + f"-y -protocol_whitelist pipe,file,http,tcp -i {playlist_lines}" + ) + else: + playlist_lines = [] + playlist_start = self.start_time + + while playlist_start < self.end_time: + playlist_lines.append( + f"file 'http://127.0.0.1:5000/vod/{self.camera}/start/{playlist_start}/end/{min(playlist_start + MAX_PLAYLIST_SECONDS, self.end_time)}/index.m3u8'" + ) + playlist_start += MAX_PLAYLIST_SECONDS + + ffmpeg_input = "-y -protocol_whitelist pipe,file,http,tcp -f concat -safe 0 -i /dev/stdin" + + if self.playback_factor == PlaybackFactorEnum.realtime: + ffmpeg_cmd = ( + f"ffmpeg -hide_banner {ffmpeg_input} -c copy {file_name}" + ).split(" ") + elif self.playback_factor == PlaybackFactorEnum.timelapse_25x: + ffmpeg_cmd = ( + parse_preset_hardware_acceleration_encode( + self.config.ffmpeg.hwaccel_args, + ffmpeg_input, + f"-vf setpts=0.04*PTS -r 30 -an {file_name}", + EncodeTypeEnum.timelapse, + ) + ).split(" ") + + p = sp.run( + ffmpeg_cmd, + input="\n".join(playlist_lines), + encoding="ascii", + capture_output=True, + ) + + if p.returncode != 0: + logger.error( + f"Failed to export recording for command {' '.join(ffmpeg_cmd)}" + ) + logger.error(p.stderr) + return + + logger.debug(f"Updating finalized export {file_name}") + os.rename(file_name, final_file_name) + logger.debug(f"Finished exporting {file_name}") diff --git a/web/src/Sidebar.jsx b/web/src/Sidebar.jsx index a7d7639e8..4497dba15 100644 --- a/web/src/Sidebar.jsx +++ b/web/src/Sidebar.jsx @@ -44,6 +44,7 @@ export default function Sidebar() { {birdseye?.enabled ? : null} + diff --git a/web/src/app.tsx b/web/src/app.tsx index 124a0f3cb..4e5123563 100644 --- a/web/src/app.tsx +++ b/web/src/app.tsx @@ -31,6 +31,7 @@ export default function App() { + { + if (camera == 'select') { + setMessage({ text: 'A camera needs to be selected.', error: true }); + return; + } + + if (playback == 'select') { + setMessage({ text: 'A playback factor needs to be selected.', error: true }); + return; + } + + const start = new Date(document.getElementById('start').value).getTime() / 1000; + const end = new Date(document.getElementById('end').value).getTime() / 1000; + + if (!start || !end) { + setMessage({ text: 'A start and end time needs to be selected', error: true }); + return; + } + + setMessage({ text: 'Successfully started export. View the file in the /exports folder.', error: false }); + axios.post(`export/${camera}/start/${start}/end/${end}`, { playback }); + }; + + return ( +
+ Export + + {message.text && ( +
{message.text}
+ )} + +
+ + +
+ +
+ + From: + + + + To: + + +
+ +
+ ); +} diff --git a/web/src/routes/index.js b/web/src/routes/index.js index eeadbbb4f..322a2b69a 100644 --- a/web/src/routes/index.js +++ b/web/src/routes/index.js @@ -23,6 +23,11 @@ export async function getEvents(_url, _cb, _props) { return module.default; } +export async function getExports(_url, _cb, _props) { + const module = await import('./Export.jsx'); + return module.default; +} + export async function getRecording(_url, _cb, _props) { const module = await import('./Recording.jsx'); return module.default;