Compare commits

...

24 Commits

Author SHA1 Message Date
Nicolas Mowen
c35c7da82a Don't fail if deepstack detector times out (#8979) 2023-12-15 23:25:21 +00:00
Nicolas Mowen
e390533760 Make recording docs more clear about 24/7 recording (#8931)
* Make recording docs more clear about 24/7 recording

* Add note about partial days

* remove `X`
2023-12-12 23:21:06 +00:00
FinnakaLite
64bee7a64f Included caution about Snapcraft docker issues. (#8925)
* Included caution about Snapcraft docker issues.

* Accepted format suggestion from NickM-27

Co-authored-by: Nicolas Mowen <nickmowen213@gmail.com>

---------

Co-authored-by: Nicolas Mowen <nickmowen213@gmail.com>
2023-12-12 10:48:42 +00:00
Nicolas Mowen
ca4e0dbc75 Fix ffmpeg input arg parsing (#8924) 2023-12-12 10:48:09 +00:00
Nicolas Mowen
ee7eaff965 Don't fail if NaN is returned for segment duration (#8923) 2023-12-12 10:47:40 +00:00
Matti Hiljanen
e512406764 Fix inertia calculation check (#8890) 2023-12-08 07:30:22 -06:00
Josh Hawkins
a4f5ad3a94 Proxy websockets in devcontainers (#8886)
* proxy websockets

* remove whitespace
2023-12-08 01:08:35 +00:00
Blake Blackshear
a47068922f Update deps (#8872)
* update web deps

* update docs deps

* update gh actions
2023-12-07 06:09:20 -06:00
Nicolas Mowen
f8153bdacc Add docs specifically for reolink doorbell (#8851)
* Add docs specifically for reolink doorbell

* Update docs/docs/configuration/camera_specific.md
2023-12-04 18:46:54 -06:00
Nicolas Mowen
0de800a8e5 don't fail on empty producers (#8854) 2023-12-04 18:46:26 -06:00
Nicolas Mowen
ebcf25741b Fix timeline overlay for in progress events (#8852) 2023-12-04 13:43:23 -07:00
Eric M
eed08f534f Update output.py with NTSC DVT, Amcrest DV1 aspect ratio 704x480 (#8835)
* Update output.py with NTSC DVT, Amcrest DV1 aspect ratio 704x480

* linter fix
2023-12-03 03:22:50 +00:00
Nicolas Mowen
da5cf1867b Clarify radeon env variable (#8809)
* Clarify radeon env variable

* Make note consistent for intel as well
2023-12-03 03:15:43 +00:00
Josh Hawkins
cc5297f180 handle onvif connection failure in autotrack init (#8838)
* handle onvif connection failure in autotrack init

* remove whitespace and add consistency

* error message consistency

* more consistency
2023-12-03 03:14:52 +00:00
Nicolas Mowen
f27025aef3 don't fail on go2rtc stream with no url (#8839) 2023-12-03 03:14:30 +00:00
Nicolas Mowen
595fa3d111 Re-add support for go2rtc webrtc api (#8828) 2023-12-01 06:47:09 -07:00
Nicolas Mowen
89051c1b90 Create Edgetpu troubleshooting docs (#8827)
* Link to edgetpu troublehsooting

* Add troubleshooting docs for edgetpu

* Add to sidebar

* Add section about dual edge tpu
2023-12-01 07:41:30 -06:00
Blake Blackshear
f00ced5a33 Show bbox on in_progress events (#8785)
* fix default value in docs

* use default snapshot config for in progress
2023-11-29 23:37:53 +00:00
Nicolas Mowen
9b003e175d Don't incorrectly overwrite score history (#8795) 2023-11-29 23:37:28 +00:00
Blake Blackshear
a490c375f4 Limit exposed go2rtc api to bare minimum (#8762)
* only permit GET requests to go2rtc

* bare minimum go2rtc passthrough

* support frigate card

* expose go2rtc streams data only
2023-11-27 18:25:47 -06:00
Nicolas Mowen
15644a2b0c Fix dark color scheme for exports (#8770) 2023-11-27 18:13:41 -06:00
Marc Altmann
27cf1cdf15 Fix path of device tree on HassOS add on (#8764)
* fix device tree path for HassOS

* fix symlink call

* fix formatting
2023-11-27 18:13:12 -06:00
Jennifer
fef6a7ca74 Update reverse_proxy.md (#8763)
Thhe
2023-11-27 18:12:57 -06:00
Blake Blackshear
5c4501efbc remove mqtt password from config api (#8757) 2023-11-26 15:45:16 -06:00
28 changed files with 838 additions and 833 deletions

View File

@@ -65,7 +65,7 @@ jobs:
- name: Check out the repository
uses: actions/checkout@v4
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v4.7.1
uses: actions/setup-python@v5.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Install requirements

View File

@@ -164,19 +164,47 @@ http {
include proxy.conf;
}
location /live/mse/ {
proxy_pass http://go2rtc/;
# frigate lovelace card uses this path
location /live/mse/api/ws {
limit_except GET {
deny all;
}
proxy_pass http://go2rtc/api/ws;
include proxy.conf;
}
location /live/webrtc/ {
proxy_pass http://go2rtc/;
location /live/webrtc/api/ws {
limit_except GET {
deny all;
}
proxy_pass http://go2rtc/api/ws;
include proxy.conf;
}
location ~* /api/go2rtc([/]?.*)$ {
proxy_pass http://go2rtc;
rewrite ^/api/go2rtc(.*)$ /api$1 break;
# pass through go2rtc player
location /live/webrtc/webrtc.html {
limit_except GET {
deny all;
}
proxy_pass http://go2rtc/webrtc.html;
include proxy.conf;
}
# frontend uses this to fetch the version
location /api/go2rtc/api {
limit_except GET {
deny all;
}
proxy_pass http://go2rtc/api;
include proxy.conf;
}
# integration uses this to add webrtc candidate
location /api/go2rtc/webrtc {
limit_except POST {
deny all;
}
proxy_pass http://go2rtc/api/webrtc;
include proxy.conf;
}

View File

@@ -127,6 +127,20 @@ cameras:
- detect
```
#### Reolink Doorbell
The reolink doorbell supports 2-way audio via go2rtc and other applications. It is important that the http-flv stream is still used for stability, a secondary rtsp stream can be added that will be using for the two way audio only.
```yaml
go2rtc:
streams:
your_reolink_doorbell:
- "ffmpeg:http://reolink_ip/flv?port=1935&app=bcs&stream=channel0_main.bcs&user=username&password=password#video=copy#audio=copy#audio=opus"
- rtsp://reolink_ip/Preview_01_sub
your_reolink_doorbell_sub:
- "ffmpeg:http://reolink_ip/flv?port=1935&app=bcs&stream=channel0_ext.bcs&user=username&password=password"
```
### Unifi Protect Cameras
Unifi protect cameras require the rtspx stream to be used with go2rtc.

View File

@@ -49,7 +49,11 @@ ffmpeg:
hwaccel_args: preset-vaapi
```
**NOTICE**: With some of the processors, like the J4125, the default driver `iHD` doesn't seem to work correctly for hardware acceleration. You may need to change the driver to `i965` by adding the following environment variable `LIBVA_DRIVER_NAME=i965` to your docker-compose file or [in the `frigate.yaml` for HA OS users](advanced.md#environment_vars).
:::note
With some of the processors, like the J4125, the default driver `iHD` doesn't seem to work correctly for hardware acceleration. You may need to change the driver to `i965` by adding the following environment variable `LIBVA_DRIVER_NAME=i965` to your docker-compose file or [in the `frigate.yaml` for HA OS users](advanced.md#environment_vars).
:::
### Via Quicksync (>=10th Generation only)
@@ -137,7 +141,11 @@ Depending on your OS and kernel configuration, you may need to change the `/proc
VAAPI supports automatic profile selection so it will work automatically with both H.264 and H.265 streams.
**Note:** You also need to set `LIBVA_DRIVER_NAME=radeonsi` as an environment variable on the container.
:::note
You need to change the driver to `radeonsi` by adding the following environment variable `LIBVA_DRIVER_NAME=radeonsi` to your docker-compose file or [in the `frigate.yaml` for HA OS users](advanced.md#environment_vars).
:::
```yaml
ffmpeg:

View File

@@ -408,7 +408,7 @@ snapshots:
# Optional: print a timestamp on the snapshots (default: shown below)
timestamp: False
# Optional: draw bounding box on the snapshots (default: shown below)
bounding_box: False
bounding_box: True
# Optional: crop the snapshot (default: shown below)
crop: False
# Optional: height to resize the snapshot to (default: original size)

View File

@@ -37,6 +37,12 @@ The EdgeTPU device can be specified using the `"device"` attribute according to
A TensorFlow Lite model is provided in the container at `/edgetpu_model.tflite` and is used by this detector type by default. To provide your own model, bind mount the file into the container and provide the path with `model.path`.
:::tip
See [common Edge-TPU troubleshooting steps](/troubleshooting/edgetpu) if the EdgeTPu is not detected.
:::
### Single USB Coral
```yaml

View File

@@ -13,7 +13,30 @@ H265 recordings can be viewed in Chrome 108+, Edge and Safari only. All other br
As of Frigate 0.12 if there is less than an hour left of storage, the oldest 2 hours of recordings will be deleted.
## What if I don't want 24/7 recordings?
## Configuring Recording Retention
Frigate supports both 24/7 and event based recordings with separate retention modes and retention periods.
:::tip
Retention configs support decimals meaning they can be configured to retain `0.5` days, for example.
:::
### 24/7 Recording
The number of days to retain 24/7 recordings can be set via the following config where X is a number, by default 24/7 recording is disabled.
```yaml
record:
enabled: True
retain:
days: 1 # <- number of days to keep 24/7 recordings
```
24/7 recording supports different retention modes [which are described below](#what-do-the-different-retain-modes-mean)
### Event Recording
If you only used clips in previous versions with recordings disabled, you can use the following config to get the same behavior. This is also the default behavior when recordings are enabled.
@@ -22,17 +45,11 @@ record:
enabled: True
events:
retain:
default: 10
default: 10 # <- number of days to keep event recordings
```
This configuration will retain recording segments that overlap with events and have active tracked objects for 10 days. Because multiple events can reference the same recording segments, this avoids storing duplicate footage for overlapping events and reduces overall storage needs.
When `retain -> days` is set to `0`, segments will be deleted from the cache if no events are in progress.
## Can I have "24/7" recordings, but only at certain times?
Using Frigate UI, HomeAssistant, or MQTT, cameras can be automated to only record in certain situations or at certain times.
**WARNING**: Recordings still must be enabled in the config. If a camera has recordings disabled in the config, enabling via the methods listed above will have no effect.
## What do the different retain modes mean?
@@ -81,9 +98,13 @@ record:
car: 7
```
## Can I have "24/7" recordings, but only at certain times?
Using Frigate UI, HomeAssistant, or MQTT, cameras can be automated to only record in certain situations or at certain times.
## 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.
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 time-lapse 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.
## Syncing Recordings With Disk

View File

@@ -47,6 +47,12 @@ services:
...
```
:::caution
Users of the Snapcraft build of Docker cannot use storage locations outside your $HOME folder.
:::
### Calculating required shm-size
Frigate utilizes shared memory to store frames during processing. The default `shm-size` provided by Docker is **64MB**.

View File

@@ -125,7 +125,7 @@ This section points to your SSL files, the example below shows locations to a de
### Setup reverse proxy settings
Thhe settings below enabled connection upgrade, sets up logging (optional) and proxies everything from the `/` context to the docker host and port specified earlier in the configuration
The settings below enabled connection upgrade, sets up logging (optional) and proxies everything from the `/` context to the docker host and port specified earlier in the configuration
```
proxy_set_header Upgrade $http_upgrade;

View File

@@ -0,0 +1,48 @@
---
id: edgetpu
title: Troubleshooting EdgeTPU
---
## USB Coral Not Detected
There are many possible causes for a USB coral not being detected and some are OS specific. It is important to understand how the USB coral works:
1. When the device is first plugged in and has not initialized it will appear as `1a6e:089a Global Unichip Corp.` when running `lsusb` or checking the hardware page in HA OS.
2. Once initialized, the device will appear as `18d1:9302 Google Inc.` when running `lsusb` or checking the hardware page in HA OS.
If the coral does not initialize then Frigate can not interface with it. Some common reasons for the USB based Coral not initializing are:
### Not Enough Power
The USB coral can draw up to 900mA and this can be too much for some on-device USB ports, especially for small board computers like the RPi. If the coral is not initializing then some recommended steps are:
1. Try a different port, some ports are capable of providing more power than others.
2. Make sure the port is USB3, this is important for power and to ensure the coral runs at max speed.
3. Try a different cable, some users have found the included cable to not work well.
4. Use an externally powered USB hub.
### Incorrect Device Access
The USB coral has different IDs when it is uninitialized and initialized.
- When running Frigate in a VM, Proxmox lxc, etc. you must ensure both device IDs are mapped.
- When running HA OS you may need to run the Full Access version of the Frigate addon with the `Protected Mode` switch disabled so that the coral can be accessed.
## USB Coral Detection Appears to be Stuck
The USB Coral can become stuck and need to be restarted, this can happen for a number of reasons depending on hardware and software setup. Some common reasons are:
1. Some users have found the cable included with the coral to cause this problem and that switching to a different cable fixed it entirely.
2. Running Frigate in a VM may cause communication with the device to be lost and need to be reset.
## PCIe Coral Not Detected
The most common reason for the PCIe coral not being detected is that the driver has not been installed. See [the coral docs(https://coral.ai/docs/m2/get-started/#2-install-the-pcie-driver-and-edge-tpu-runtime) for how to install the driver for the PCIe based coral.
## Only One PCIe Coral Is Detected With Coral Dual EdgeTPU
Coral Dual EdgeTPU is one card with two identical TPU cores. Each core has it's own PCIe interface and motherboard needs to have two PCIe busses on the m.2 slot to make them both work.
E-key slot implemented to full m.2 electomechanical specification has two PCIe busses. Most motherboard manufacturers implement only one PCIe bus in m.2 E-key connector (this is why only one TPU is working). Some SBCs can have only USB bus on m.2 connector, ie none of TPUs will work.
In this case it is recommended to use a Dual EdgeTPU Adapter [like the one from MagicBlueSmoke](https://github.com/magic-blue-smoke/Dual-Edge-TPU-Adapter)

919
docs/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -14,11 +14,11 @@
"write-heading-ids": "docusaurus write-heading-ids"
},
"dependencies": {
"@docusaurus/core": "3.0.0",
"@docusaurus/preset-classic": "3.0.0",
"@docusaurus/theme-mermaid": "3.0.0",
"@docusaurus/core": "^3.0.0",
"@docusaurus/preset-classic": "^3.0.0",
"@docusaurus/theme-mermaid": "^3.0.0",
"@mdx-js/react": "^3.0.0",
"clsx": "^1.2.1",
"clsx": "^2.0.0",
"prism-react-renderer": "^2.1.0",
"raw-loader": "^4.0.2",
"react": "^18.2.0",

View File

@@ -60,7 +60,11 @@ module.exports = {
"integrations/third_party_extensions",
],
"Frigate+": ["plus/index"],
Troubleshooting: ["troubleshooting/faqs", "troubleshooting/recordings"],
Troubleshooting: [
"troubleshooting/faqs",
"troubleshooting/recordings",
"troubleshooting/edgetpu",
],
Development: [
"development/contributing",
"development/contributing-boards",

View File

@@ -49,12 +49,18 @@ class DeepStack(DetectionApi):
image.save(output, format="JPEG")
image_bytes = output.getvalue()
data = {"api_key": self.api_key}
response = requests.post(
self.api_url,
data=data,
files={"image": image_bytes},
timeout=self.api_timeout,
)
try:
response = requests.post(
self.api_url,
data=data,
files={"image": image_bytes},
timeout=self.api_timeout,
)
except requests.exceptions.RequestException:
logger.error("Error calling deepstack API")
return np.zeros((20, 6), np.float32)
response_json = response.json()
detections = np.zeros((20, 6), np.float32)
if response_json.get("predictions") is None:

View File

@@ -42,6 +42,11 @@ class Rknn(DetectionApi):
type_key = DETECTOR_KEY
def __init__(self, config: RknnDetectorConfig):
# create symlink for Home Assistant add on
if not os.path.isfile("/proc/device-tree/compatible"):
if os.path.isfile("/device-tree/compatible"):
os.symlink("/device-tree/compatible", "/proc/device-tree/compatible")
# find out SoC
try:
with open("/proc/device-tree/compatible") as file:

View File

@@ -43,9 +43,9 @@ def get_ffmpeg_command(ffmpeg: FfmpegConfig) -> list[str]:
ffmpeg_input: CameraInput = [i for i in ffmpeg.inputs if "audio" in i.roles][0]
input_args = get_ffmpeg_arg_list(ffmpeg.global_args) + (
parse_preset_input(ffmpeg_input.input_args, 1)
or ffmpeg_input.input_args
or get_ffmpeg_arg_list(ffmpeg_input.input_args)
or parse_preset_input(ffmpeg.input_args, 1)
or ffmpeg.input_args
or get_ffmpeg_arg_list(ffmpeg.input_args)
)
return (
["ffmpeg", "-vn"]

View File

@@ -16,6 +16,7 @@ from urllib.parse import unquote
import cv2
import numpy as np
import pytz
import requests
from flask import (
Blueprint,
Flask,
@@ -1154,6 +1155,9 @@ def end_event(event_id):
def config():
config = current_app.frigate_config.dict()
# remove the mqtt password
config["mqtt"].pop("password", None)
for camera_name, camera in current_app.frigate_config.cameras.items():
camera_dict = config["cameras"][camera_name]
@@ -1342,6 +1346,22 @@ def config_schema():
)
@bp.route("/go2rtc/streams")
def go2rtc_streams():
r = requests.get("http://127.0.0.1:1984/api/streams")
if not r.ok:
logger.error("Failed to fetch streams from go2rtc")
return make_response(
jsonify({"success": False, "message": "Error fetching stream data"}),
500,
)
stream_data = r.json()
for data in stream_data.values():
for producer in data.get("producers", []):
producer["url"] = clean_camera_user_pass(producer.get("url", ""))
return jsonify(stream_data)
@bp.route("/version")
def version():
return VERSION

View File

@@ -128,9 +128,6 @@ class TrackedObject:
self.frame = None
self.previous = self.to_dict()
# start the score history
self.score_history = [self.obj_data["score"]]
def _is_false_positive(self):
# once a true positive, always a true positive
if not self.false_positive:
@@ -198,7 +195,7 @@ class TrackedObject:
self.zone_presence[name] = zone_score + 1
# an object is only considered present in a zone if it has a zone inertia of 3+
if zone_score >= zone.inertia:
if self.zone_presence[name] >= zone.inertia:
current_zones.append(name)
if name not in self.entered_zones:

View File

@@ -45,6 +45,7 @@ def get_standard_aspect_ratio(width: int, height: int) -> tuple[int, int]:
(32, 9), # panoramic cameras
(12, 9),
(9, 12),
(22, 15), # Amcrest, NTSC DVT
] # aspects are scaled to have common relative size
known_aspects_ratios = list(
map(lambda aspect: aspect[0] / aspect[1], known_aspects)

View File

@@ -238,32 +238,40 @@ class PtzAutoTracker:
self.move_queues[camera] = queue.Queue()
self.move_queue_locks[camera] = threading.Lock()
# handle onvif constructor failing due to no connection
if camera not in self.onvif.cams:
logger.warning(
f"Disabling autotracking for {camera}: onvif connection failed"
)
camera_config.onvif.autotracking.enabled = False
self.ptz_metrics[camera]["ptz_autotracker_enabled"].value = False
return
if not self.onvif.cams[camera]["init"]:
if not self.onvif._init_onvif(camera):
logger.warning(f"Unable to initialize onvif for {camera}")
logger.warning(
f"Disabling autotracking for {camera}: Unable to initialize onvif"
)
camera_config.onvif.autotracking.enabled = False
self.ptz_metrics[camera]["ptz_autotracker_enabled"].value = False
return
if "pt-r-fov" not in self.onvif.cams[camera]["features"]:
camera_config.onvif.autotracking.enabled = False
self.ptz_metrics[camera]["ptz_autotracker_enabled"].value = False
logger.warning(
f"Disabling autotracking for {camera}: FOV relative movement not supported"
)
camera_config.onvif.autotracking.enabled = False
self.ptz_metrics[camera]["ptz_autotracker_enabled"].value = False
return
movestatus_supported = self.onvif.get_service_capabilities(camera)
if movestatus_supported is None or movestatus_supported.lower() != "true":
camera_config.onvif.autotracking.enabled = False
self.ptz_metrics[camera]["ptz_autotracker_enabled"].value = False
logger.warning(
f"Disabling autotracking for {camera}: ONVIF MoveStatus not supported"
)
camera_config.onvif.autotracking.enabled = False
self.ptz_metrics[camera]["ptz_autotracker_enabled"].value = False
return
if self.onvif.cams[camera]["init"]:

View File

@@ -371,7 +371,7 @@ def vainfo_hwaccel(device_name: Optional[str] = None) -> sp.CompletedProcess:
return sp.run(ffprobe_cmd, capture_output=True)
async def get_video_properties(url, get_duration=False):
async def get_video_properties(url, get_duration=False) -> dict[str, any]:
async def calculate_duration(video: Optional[any]) -> float:
duration = None
@@ -405,7 +405,10 @@ async def get_video_properties(url, get_duration=False):
result = None
if result:
duration = float(result.strip())
try:
duration = float(result.strip())
except ValueError:
duration = -1
else:
duration = -1

388
web/package-lock.json generated
View File

@@ -51,7 +51,7 @@
"postcss": "^8.4.29",
"prettier": "^3.0.3",
"tailwindcss": "^3.3.2",
"typescript": "^5.0.4",
"typescript": "^5.2.2",
"vite": "^4.4.9",
"vitest": "^0.34.3"
}
@@ -928,9 +928,9 @@
}
},
"node_modules/@eslint/eslintrc": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz",
"integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==",
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
"integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
"dev": true,
"dependencies": {
"ajv": "^6.12.4",
@@ -978,9 +978,9 @@
}
},
"node_modules/@eslint/js": {
"version": "8.54.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.54.0.tgz",
"integrity": "sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==",
"version": "8.55.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz",
"integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -1403,9 +1403,9 @@
}
},
"node_modules/@testing-library/jest-dom": {
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.1.4.tgz",
"integrity": "sha512-wpoYrCYwSZ5/AxcrjLxJmCU6I5QAJXslEeSiMQqaWmP2Kzpd1LvF/qxmAIW2qposULGWq2gw30GgVNFLSc2Jnw==",
"version": "6.1.5",
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.1.5.tgz",
"integrity": "sha512-3y04JLW+EceVPy2Em3VwNr95dOKqA8DhR0RJHhHKDZNYXcVXnEK7WIrpj4eYU8SVt/qYZ2aRWt/WgQ+grNES8g==",
"dev": true,
"dependencies": {
"@adobe/css-tools": "^4.3.1",
@@ -1664,16 +1664,16 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.11.0.tgz",
"integrity": "sha512-uXnpZDc4VRjY4iuypDBKzW1rz9T5YBBK0snMn8MaTSNd2kMlj50LnLBABELjJiOL5YHk7ZD8hbSpI9ubzqYI0w==",
"version": "6.13.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.13.2.tgz",
"integrity": "sha512-3+9OGAWHhk4O1LlcwLBONbdXsAhLjyCFogJY/cWy2lxdVJ2JrcTF2pTGMaLl2AE7U1l31n8Py4a8bx5DLf/0dQ==",
"dev": true,
"dependencies": {
"@eslint-community/regexpp": "^4.5.1",
"@typescript-eslint/scope-manager": "6.11.0",
"@typescript-eslint/type-utils": "6.11.0",
"@typescript-eslint/utils": "6.11.0",
"@typescript-eslint/visitor-keys": "6.11.0",
"@typescript-eslint/scope-manager": "6.13.2",
"@typescript-eslint/type-utils": "6.13.2",
"@typescript-eslint/utils": "6.13.2",
"@typescript-eslint/visitor-keys": "6.13.2",
"debug": "^4.3.4",
"graphemer": "^1.4.0",
"ignore": "^5.2.4",
@@ -1870,15 +1870,15 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.11.0.tgz",
"integrity": "sha512-+whEdjk+d5do5nxfxx73oanLL9ghKO3EwM9kBCkUtWMRwWuPaFv9ScuqlYfQ6pAD6ZiJhky7TZ2ZYhrMsfMxVQ==",
"version": "6.13.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.13.2.tgz",
"integrity": "sha512-MUkcC+7Wt/QOGeVlM8aGGJZy1XV5YKjTpq9jK6r6/iLsGXhBVaGP5N0UYvFsu9BFlSpwY9kMretzdBH01rkRXg==",
"dev": true,
"dependencies": {
"@typescript-eslint/scope-manager": "6.11.0",
"@typescript-eslint/types": "6.11.0",
"@typescript-eslint/typescript-estree": "6.11.0",
"@typescript-eslint/visitor-keys": "6.11.0",
"@typescript-eslint/scope-manager": "6.13.2",
"@typescript-eslint/types": "6.13.2",
"@typescript-eslint/typescript-estree": "6.13.2",
"@typescript-eslint/visitor-keys": "6.13.2",
"debug": "^4.3.4"
},
"engines": {
@@ -1898,13 +1898,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.11.0.tgz",
"integrity": "sha512-0A8KoVvIURG4uhxAdjSaxy8RdRE//HztaZdG8KiHLP8WOXSk0vlF7Pvogv+vlJA5Rnjj/wDcFENvDaHb+gKd1A==",
"version": "6.13.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz",
"integrity": "sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "6.11.0",
"@typescript-eslint/visitor-keys": "6.11.0"
"@typescript-eslint/types": "6.13.2",
"@typescript-eslint/visitor-keys": "6.13.2"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
@@ -1915,13 +1915,13 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.11.0.tgz",
"integrity": "sha512-nA4IOXwZtqBjIoYrJcYxLRO+F9ri+leVGoJcMW1uqr4r1Hq7vW5cyWrA43lFbpRvQ9XgNrnfLpIkO3i1emDBIA==",
"version": "6.13.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.13.2.tgz",
"integrity": "sha512-Qr6ssS1GFongzH2qfnWKkAQmMUyZSyOr0W54nZNU1MDfo+U4Mv3XveeLZzadc/yq8iYhQZHYT+eoXJqnACM1tw==",
"dev": true,
"dependencies": {
"@typescript-eslint/typescript-estree": "6.11.0",
"@typescript-eslint/utils": "6.11.0",
"@typescript-eslint/typescript-estree": "6.13.2",
"@typescript-eslint/utils": "6.13.2",
"debug": "^4.3.4",
"ts-api-utils": "^1.0.1"
},
@@ -1942,9 +1942,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.11.0.tgz",
"integrity": "sha512-ZbEzuD4DwEJxwPqhv3QULlRj8KYTAnNsXxmfuUXFCxZmO6CF2gM/y+ugBSAQhrqaJL3M+oe4owdWunaHM6beqA==",
"version": "6.13.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.2.tgz",
"integrity": "sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==",
"dev": true,
"engines": {
"node": "^16.0.0 || >=18.0.0"
@@ -1955,13 +1955,13 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.11.0.tgz",
"integrity": "sha512-Aezzv1o2tWJwvZhedzvD5Yv7+Lpu1by/U1LZ5gLc4tCx8jUmuSCMioPFRjliN/6SJIvY6HpTtJIWubKuYYYesQ==",
"version": "6.13.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz",
"integrity": "sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "6.11.0",
"@typescript-eslint/visitor-keys": "6.11.0",
"@typescript-eslint/types": "6.13.2",
"@typescript-eslint/visitor-keys": "6.13.2",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -1997,17 +1997,17 @@
}
},
"node_modules/@typescript-eslint/utils": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.11.0.tgz",
"integrity": "sha512-p23ibf68fxoZy605dc0dQAEoUsoiNoP3MD9WQGiHLDuTSOuqoTsa4oAy+h3KDkTcxbbfOtUjb9h3Ta0gT4ug2g==",
"version": "6.13.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.2.tgz",
"integrity": "sha512-b9Ptq4eAZUym4idijCRzl61oPCwwREcfDI8xGk751Vhzig5fFZR9CyzDz4Sp/nxSLBYxUPyh4QdIDqWykFhNmQ==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"@types/json-schema": "^7.0.12",
"@types/semver": "^7.5.0",
"@typescript-eslint/scope-manager": "6.11.0",
"@typescript-eslint/types": "6.11.0",
"@typescript-eslint/typescript-estree": "6.11.0",
"@typescript-eslint/scope-manager": "6.13.2",
"@typescript-eslint/types": "6.13.2",
"@typescript-eslint/typescript-estree": "6.13.2",
"semver": "^7.5.4"
},
"engines": {
@@ -2037,12 +2037,12 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.11.0.tgz",
"integrity": "sha512-+SUN/W7WjBr05uRxPggJPSzyB8zUpaYo2hByKasWbqr3PM8AXfZt8UHdNpBS1v9SA62qnSSMF3380SwDqqprgQ==",
"version": "6.13.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz",
"integrity": "sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "6.11.0",
"@typescript-eslint/types": "6.13.2",
"eslint-visitor-keys": "^3.4.1"
},
"engines": {
@@ -2268,12 +2268,12 @@
}
},
"node_modules/@vitest/ui": {
"version": "0.34.6",
"resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-0.34.6.tgz",
"integrity": "sha512-/fxnCwGC0Txmr3tF3BwAbo3v6U2SkBTGR9UB8zo0Ztlx0BTOXHucE0gDHY7SjwEktCOHatiGmli9kZD6gYSoWQ==",
"version": "0.34.7",
"resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-0.34.7.tgz",
"integrity": "sha512-iizUu9R5Rsvsq8FtdJ0suMqEfIsIIzziqnasMHe4VH8vG+FnZSA3UAtCHx6rLeRupIFVAVg7bptMmuvMcsn8WQ==",
"dev": true,
"dependencies": {
"@vitest/utils": "0.34.6",
"@vitest/utils": "0.34.7",
"fast-glob": "^3.3.0",
"fflate": "^0.8.0",
"flatted": "^3.2.7",
@@ -2288,6 +2288,52 @@
"vitest": ">=0.30.1 <1"
}
},
"node_modules/@vitest/ui/node_modules/@vitest/utils": {
"version": "0.34.7",
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.7.tgz",
"integrity": "sha512-ziAavQLpCYS9sLOorGrFFKmy2gnfiNU0ZJ15TsMz/K92NAPS/rp9K4z6AJQQk5Y8adCy4Iwpxy7pQumQ/psnRg==",
"dev": true,
"dependencies": {
"diff-sequences": "^29.4.3",
"loupe": "^2.3.6",
"pretty-format": "^29.5.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
}
},
"node_modules/@vitest/ui/node_modules/ansi-styles": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
"dev": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/@vitest/ui/node_modules/pretty-format": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
"integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
"dev": true,
"dependencies": {
"@jest/schemas": "^29.6.3",
"ansi-styles": "^5.0.0",
"react-is": "^18.0.0"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@vitest/ui/node_modules/react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
"dev": true
},
"node_modules/@vitest/utils": {
"version": "0.34.6",
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.6.tgz",
@@ -3667,15 +3713,15 @@
}
},
"node_modules/eslint": {
"version": "8.54.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.54.0.tgz",
"integrity": "sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==",
"version": "8.55.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz",
"integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
"@eslint/eslintrc": "^2.1.3",
"@eslint/js": "8.54.0",
"@eslint/eslintrc": "^2.1.4",
"@eslint/js": "8.55.0",
"@humanwhocodes/config-array": "^0.11.13",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
@@ -4013,9 +4059,9 @@
}
},
"node_modules/eslint-config-prettier": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz",
"integrity": "sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==",
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
"integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
"dev": true,
"bin": {
"eslint-config-prettier": "bin/cli.js"
@@ -6940,9 +6986,9 @@
}
},
"node_modules/nanoid": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
"version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
"dev": true,
"funding": [
{
@@ -7535,9 +7581,9 @@
}
},
"node_modules/postcss": {
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
"integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
"version": "8.4.32",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz",
"integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==",
"dev": true,
"funding": [
{
@@ -7554,7 +7600,7 @@
}
],
"dependencies": {
"nanoid": "^3.3.6",
"nanoid": "^3.3.7",
"picocolors": "^1.0.0",
"source-map-js": "^1.0.2"
},
@@ -8650,9 +8696,9 @@
}
},
"node_modules/tailwindcss": {
"version": "3.3.5",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.5.tgz",
"integrity": "sha512-5SEZU4J7pxZgSkv7FP1zY8i2TIAOooNZ1e/OGtxIEv6GltpoiXUqWvLy89+a10qYTB1N5Ifkuw9lqQkN9sscvA==",
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.6.tgz",
"integrity": "sha512-AKjF7qbbLvLaPieoKeTjG1+FyNZT6KaJMJPFeQyLfIp7l82ggH1fbHJSsYIvnbTFQOlkh+gBYpyby5GT1LIdLw==",
"dev": true,
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
@@ -9214,9 +9260,9 @@
}
},
"node_modules/vite": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz",
"integrity": "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==",
"version": "4.5.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.1.tgz",
"integrity": "sha512-AXXFaAJ8yebyqzoNB9fu2pHoo/nWX+xZlaRwoeYUxEqBO+Zj4msE5G+BhGBll9lYEKv9Hfks52PAF2X7qDYXQA==",
"dev": true,
"dependencies": {
"esbuild": "^0.18.10",
@@ -10248,9 +10294,9 @@
"dev": true
},
"@eslint/eslintrc": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz",
"integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==",
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
"integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
"dev": true,
"requires": {
"ajv": "^6.12.4",
@@ -10282,9 +10328,9 @@
}
},
"@eslint/js": {
"version": "8.54.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.54.0.tgz",
"integrity": "sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==",
"version": "8.55.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz",
"integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==",
"dev": true
},
"@humanwhocodes/config-array": {
@@ -10616,9 +10662,9 @@
}
},
"@testing-library/jest-dom": {
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.1.4.tgz",
"integrity": "sha512-wpoYrCYwSZ5/AxcrjLxJmCU6I5QAJXslEeSiMQqaWmP2Kzpd1LvF/qxmAIW2qposULGWq2gw30GgVNFLSc2Jnw==",
"version": "6.1.5",
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.1.5.tgz",
"integrity": "sha512-3y04JLW+EceVPy2Em3VwNr95dOKqA8DhR0RJHhHKDZNYXcVXnEK7WIrpj4eYU8SVt/qYZ2aRWt/WgQ+grNES8g==",
"dev": true,
"requires": {
"@adobe/css-tools": "^4.3.1",
@@ -10821,16 +10867,16 @@
}
},
"@typescript-eslint/eslint-plugin": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.11.0.tgz",
"integrity": "sha512-uXnpZDc4VRjY4iuypDBKzW1rz9T5YBBK0snMn8MaTSNd2kMlj50LnLBABELjJiOL5YHk7ZD8hbSpI9ubzqYI0w==",
"version": "6.13.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.13.2.tgz",
"integrity": "sha512-3+9OGAWHhk4O1LlcwLBONbdXsAhLjyCFogJY/cWy2lxdVJ2JrcTF2pTGMaLl2AE7U1l31n8Py4a8bx5DLf/0dQ==",
"dev": true,
"requires": {
"@eslint-community/regexpp": "^4.5.1",
"@typescript-eslint/scope-manager": "6.11.0",
"@typescript-eslint/type-utils": "6.11.0",
"@typescript-eslint/utils": "6.11.0",
"@typescript-eslint/visitor-keys": "6.11.0",
"@typescript-eslint/scope-manager": "6.13.2",
"@typescript-eslint/type-utils": "6.13.2",
"@typescript-eslint/utils": "6.13.2",
"@typescript-eslint/visitor-keys": "6.13.2",
"debug": "^4.3.4",
"graphemer": "^1.4.0",
"ignore": "^5.2.4",
@@ -10944,54 +10990,54 @@
}
},
"@typescript-eslint/parser": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.11.0.tgz",
"integrity": "sha512-+whEdjk+d5do5nxfxx73oanLL9ghKO3EwM9kBCkUtWMRwWuPaFv9ScuqlYfQ6pAD6ZiJhky7TZ2ZYhrMsfMxVQ==",
"version": "6.13.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.13.2.tgz",
"integrity": "sha512-MUkcC+7Wt/QOGeVlM8aGGJZy1XV5YKjTpq9jK6r6/iLsGXhBVaGP5N0UYvFsu9BFlSpwY9kMretzdBH01rkRXg==",
"dev": true,
"requires": {
"@typescript-eslint/scope-manager": "6.11.0",
"@typescript-eslint/types": "6.11.0",
"@typescript-eslint/typescript-estree": "6.11.0",
"@typescript-eslint/visitor-keys": "6.11.0",
"@typescript-eslint/scope-manager": "6.13.2",
"@typescript-eslint/types": "6.13.2",
"@typescript-eslint/typescript-estree": "6.13.2",
"@typescript-eslint/visitor-keys": "6.13.2",
"debug": "^4.3.4"
}
},
"@typescript-eslint/scope-manager": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.11.0.tgz",
"integrity": "sha512-0A8KoVvIURG4uhxAdjSaxy8RdRE//HztaZdG8KiHLP8WOXSk0vlF7Pvogv+vlJA5Rnjj/wDcFENvDaHb+gKd1A==",
"version": "6.13.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz",
"integrity": "sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==",
"dev": true,
"requires": {
"@typescript-eslint/types": "6.11.0",
"@typescript-eslint/visitor-keys": "6.11.0"
"@typescript-eslint/types": "6.13.2",
"@typescript-eslint/visitor-keys": "6.13.2"
}
},
"@typescript-eslint/type-utils": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.11.0.tgz",
"integrity": "sha512-nA4IOXwZtqBjIoYrJcYxLRO+F9ri+leVGoJcMW1uqr4r1Hq7vW5cyWrA43lFbpRvQ9XgNrnfLpIkO3i1emDBIA==",
"version": "6.13.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.13.2.tgz",
"integrity": "sha512-Qr6ssS1GFongzH2qfnWKkAQmMUyZSyOr0W54nZNU1MDfo+U4Mv3XveeLZzadc/yq8iYhQZHYT+eoXJqnACM1tw==",
"dev": true,
"requires": {
"@typescript-eslint/typescript-estree": "6.11.0",
"@typescript-eslint/utils": "6.11.0",
"@typescript-eslint/typescript-estree": "6.13.2",
"@typescript-eslint/utils": "6.13.2",
"debug": "^4.3.4",
"ts-api-utils": "^1.0.1"
}
},
"@typescript-eslint/types": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.11.0.tgz",
"integrity": "sha512-ZbEzuD4DwEJxwPqhv3QULlRj8KYTAnNsXxmfuUXFCxZmO6CF2gM/y+ugBSAQhrqaJL3M+oe4owdWunaHM6beqA==",
"version": "6.13.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.2.tgz",
"integrity": "sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.11.0.tgz",
"integrity": "sha512-Aezzv1o2tWJwvZhedzvD5Yv7+Lpu1by/U1LZ5gLc4tCx8jUmuSCMioPFRjliN/6SJIvY6HpTtJIWubKuYYYesQ==",
"version": "6.13.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz",
"integrity": "sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==",
"dev": true,
"requires": {
"@typescript-eslint/types": "6.11.0",
"@typescript-eslint/visitor-keys": "6.11.0",
"@typescript-eslint/types": "6.13.2",
"@typescript-eslint/visitor-keys": "6.13.2",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -11011,17 +11057,17 @@
}
},
"@typescript-eslint/utils": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.11.0.tgz",
"integrity": "sha512-p23ibf68fxoZy605dc0dQAEoUsoiNoP3MD9WQGiHLDuTSOuqoTsa4oAy+h3KDkTcxbbfOtUjb9h3Ta0gT4ug2g==",
"version": "6.13.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.2.tgz",
"integrity": "sha512-b9Ptq4eAZUym4idijCRzl61oPCwwREcfDI8xGk751Vhzig5fFZR9CyzDz4Sp/nxSLBYxUPyh4QdIDqWykFhNmQ==",
"dev": true,
"requires": {
"@eslint-community/eslint-utils": "^4.4.0",
"@types/json-schema": "^7.0.12",
"@types/semver": "^7.5.0",
"@typescript-eslint/scope-manager": "6.11.0",
"@typescript-eslint/types": "6.11.0",
"@typescript-eslint/typescript-estree": "6.11.0",
"@typescript-eslint/scope-manager": "6.13.2",
"@typescript-eslint/types": "6.13.2",
"@typescript-eslint/typescript-estree": "6.13.2",
"semver": "^7.5.4"
},
"dependencies": {
@@ -11037,12 +11083,12 @@
}
},
"@typescript-eslint/visitor-keys": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.11.0.tgz",
"integrity": "sha512-+SUN/W7WjBr05uRxPggJPSzyB8zUpaYo2hByKasWbqr3PM8AXfZt8UHdNpBS1v9SA62qnSSMF3380SwDqqprgQ==",
"version": "6.13.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz",
"integrity": "sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==",
"dev": true,
"requires": {
"@typescript-eslint/types": "6.11.0",
"@typescript-eslint/types": "6.13.2",
"eslint-visitor-keys": "^3.4.1"
}
},
@@ -11215,18 +11261,54 @@
}
},
"@vitest/ui": {
"version": "0.34.6",
"resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-0.34.6.tgz",
"integrity": "sha512-/fxnCwGC0Txmr3tF3BwAbo3v6U2SkBTGR9UB8zo0Ztlx0BTOXHucE0gDHY7SjwEktCOHatiGmli9kZD6gYSoWQ==",
"version": "0.34.7",
"resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-0.34.7.tgz",
"integrity": "sha512-iizUu9R5Rsvsq8FtdJ0suMqEfIsIIzziqnasMHe4VH8vG+FnZSA3UAtCHx6rLeRupIFVAVg7bptMmuvMcsn8WQ==",
"dev": true,
"requires": {
"@vitest/utils": "0.34.6",
"@vitest/utils": "0.34.7",
"fast-glob": "^3.3.0",
"fflate": "^0.8.0",
"flatted": "^3.2.7",
"pathe": "^1.1.1",
"picocolors": "^1.0.0",
"sirv": "^2.0.3"
},
"dependencies": {
"@vitest/utils": {
"version": "0.34.7",
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.7.tgz",
"integrity": "sha512-ziAavQLpCYS9sLOorGrFFKmy2gnfiNU0ZJ15TsMz/K92NAPS/rp9K4z6AJQQk5Y8adCy4Iwpxy7pQumQ/psnRg==",
"dev": true,
"requires": {
"diff-sequences": "^29.4.3",
"loupe": "^2.3.6",
"pretty-format": "^29.5.0"
}
},
"ansi-styles": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
"dev": true
},
"pretty-format": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
"integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
"dev": true,
"requires": {
"@jest/schemas": "^29.6.3",
"ansi-styles": "^5.0.0",
"react-is": "^18.0.0"
}
},
"react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
"dev": true
}
}
},
"@vitest/utils": {
@@ -12247,15 +12329,15 @@
"dev": true
},
"eslint": {
"version": "8.54.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.54.0.tgz",
"integrity": "sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==",
"version": "8.55.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz",
"integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==",
"dev": true,
"requires": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
"@eslint/eslintrc": "^2.1.3",
"@eslint/js": "8.54.0",
"@eslint/eslintrc": "^2.1.4",
"@eslint/js": "8.55.0",
"@humanwhocodes/config-array": "^0.11.13",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
@@ -12539,9 +12621,9 @@
}
},
"eslint-config-prettier": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz",
"integrity": "sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==",
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
"integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
"dev": true,
"requires": {}
},
@@ -14560,9 +14642,9 @@
}
},
"nanoid": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
"version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
"dev": true
},
"natural-compare": {
@@ -14983,12 +15065,12 @@
}
},
"postcss": {
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
"integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
"version": "8.4.32",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz",
"integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==",
"dev": true,
"requires": {
"nanoid": "^3.3.6",
"nanoid": "^3.3.7",
"picocolors": "^1.0.0",
"source-map-js": "^1.0.2"
}
@@ -15789,9 +15871,9 @@
}
},
"tailwindcss": {
"version": "3.3.5",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.5.tgz",
"integrity": "sha512-5SEZU4J7pxZgSkv7FP1zY8i2TIAOooNZ1e/OGtxIEv6GltpoiXUqWvLy89+a10qYTB1N5Ifkuw9lqQkN9sscvA==",
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.6.tgz",
"integrity": "sha512-AKjF7qbbLvLaPieoKeTjG1+FyNZT6KaJMJPFeQyLfIp7l82ggH1fbHJSsYIvnbTFQOlkh+gBYpyby5GT1LIdLw==",
"dev": true,
"requires": {
"@alloc/quick-lru": "^5.2.0",
@@ -16229,9 +16311,9 @@
}
},
"vite": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz",
"integrity": "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==",
"version": "4.5.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.1.tgz",
"integrity": "sha512-AXXFaAJ8yebyqzoNB9fu2pHoo/nWX+xZlaRwoeYUxEqBO+Zj4msE5G+BhGBll9lYEKv9Hfks52PAF2X7qDYXQA==",
"dev": true,
"requires": {
"esbuild": "^0.18.10",

View File

@@ -55,7 +55,7 @@
"postcss": "^8.4.29",
"prettier": "^3.0.3",
"tailwindcss": "^3.3.2",
"typescript": "^5.0.4",
"typescript": "^5.2.2",
"vite": "^4.4.9",
"vitest": "^0.34.3"
}

View File

@@ -34,10 +34,18 @@ export default function TimelineSummary({ event, onFrameSelected }) {
const [timeIndex, setTimeIndex] = useState(-1);
const recordingParams = {
before: event.end_time || Date.now(),
after: event.start_time,
};
const recordingParams = useMemo(() => {
if (!event.end_time) {
return {
after: event.start_time,
};
}
return {
before: event.end_time,
after: event.start_time,
};
}, [event]);
const { data: recordings } = useSWR([`${event.camera}/recordings`, recordingParams], { revalidateOnFocus: false });
// calculates the seek seconds by adding up all the seconds in the segments prior to the playback time

View File

@@ -123,12 +123,21 @@ export default function Events({ path, ...props }) {
[searchParams]
);
const { data: ongoingEvents, mutate: refreshOngoingEvents } = useSWR(['events', { in_progress: 1, include_thumbnails: 0 }]);
const { data: eventPages, mutate: refreshEvents, size, setSize, isValidating } = useSWRInfinite(getKey, eventsFetcher);
const { data: ongoingEvents, mutate: refreshOngoingEvents } = useSWR([
'events',
{ in_progress: 1, include_thumbnails: 0 },
]);
const {
data: eventPages,
mutate: refreshEvents,
size,
setSize,
isValidating,
} = useSWRInfinite(getKey, eventsFetcher);
const mutate = () => {
refreshEvents();
refreshOngoingEvents();
}
};
const { data: allLabels } = useSWR(['labels']);
const { data: allSubLabels } = useSWR(['sub_labels', { split_joined: 1 }]);
@@ -283,15 +292,12 @@ export default function Events({ path, ...props }) {
[path, searchParams, setSearchParams]
);
const onClickFilterSubmitted = useCallback(
() => {
if( ++searchParams.is_submitted > 1 ) {
searchParams.is_submitted = -1;
}
onFilter('is_submitted', searchParams.is_submitted);
},
[searchParams, onFilter]
);
const onClickFilterSubmitted = useCallback(() => {
if (++searchParams.is_submitted > 1) {
searchParams.is_submitted = -1;
}
onFilter('is_submitted', searchParams.is_submitted);
}, [searchParams, onFilter]);
const isDone = (eventPages?.[eventPages.length - 1]?.length ?? 0) < API_LIMIT;
@@ -918,7 +924,7 @@ function Event({
className="flex-grow-0"
src={
event.has_snapshot
? `${apiHost}api/events/${event.id}/snapshot.jpg`
? `${apiHost}api/events/${event.id}/snapshot.jpg?bbox=1`
: `${apiHost}api/events/${event.id}/thumbnail.jpg`
}
alt={`${event.label} at ${((event?.data?.top_score || event.top_score) * 100).toFixed(

View File

@@ -213,7 +213,7 @@ export default function Export() {
</div>
{exports && (
<div className="p-4 bg-gray-800 xl:w-1/2">
<div className="p-4 bg-gray-200 dark:bg-gray-800 xl:w-1/2">
<Heading size="md">Exports</Heading>
<Exports
exports={exports}
@@ -231,7 +231,7 @@ function Exports({ exports, onSetClip, onDeleteClip }) {
return (
<Fragment>
{exports.map((item) => (
<div className="my-4 p-4 bg-gray-700" key={item.name}>
<div className="my-4 p-4 bg-gray-100 dark:bg-gray-700" key={item.name}>
{item.name.startsWith('in_progress') ? (
<div className="flex justify-start text-center items-center">
<div>

View File

@@ -41,7 +41,7 @@ export default function System() {
const cameraNames = Object.keys(cameras || emptyObject);
const processesNames = Object.keys(processes || emptyObject);
const { data: go2rtc } = useSWR('go2rtc');
const { data: go2rtc } = useSWR('go2rtc/api');
const onHandleFfprobe = async (camera, e) => {
if (e) {
@@ -103,9 +103,9 @@ export default function System() {
className="text-blue-500 hover:underline"
target="_blank"
rel="noopener noreferrer"
href="/live/webrtc/"
href="/api/go2rtc/streams"
>
dashboard
streams info
</Link>
</span>
)}
@@ -302,16 +302,16 @@ export default function System() {
<Tr>
<Th>GPU %</Th>
<Th>Memory %</Th>
{'dec' in gpu_usages[gpu] && (<Th>Decoder %</Th>)}
{'enc' in gpu_usages[gpu] && (<Th>Encoder %</Th>)}
{'dec' in gpu_usages[gpu] && <Th>Decoder %</Th>}
{'enc' in gpu_usages[gpu] && <Th>Encoder %</Th>}
</Tr>
</Thead>
<Tbody>
<Tr>
<Td>{gpu_usages[gpu]['gpu']}</Td>
<Td>{gpu_usages[gpu]['mem']}</Td>
{'dec' in gpu_usages[gpu] && (<Td>{gpu_usages[gpu]['dec']}</Td>)}
{'enc' in gpu_usages[gpu] && (<Td>{gpu_usages[gpu]['enc']}</Td>)}
{'dec' in gpu_usages[gpu] && <Td>{gpu_usages[gpu]['dec']}</Td>}
{'enc' in gpu_usages[gpu] && <Td>{gpu_usages[gpu]['enc']}</Td>}
</Tr>
</Tbody>
</Table>
@@ -350,14 +350,14 @@ export default function System() {
<Link href={`/cameras/${camera}`}>{camera.replaceAll('_', ' ')}</Link>
<div className="flex">
{config.cameras[camera]['webui_url'] && (
<Button
href={config.cameras[camera]['webui_url']}
target="_blank"
>
Web UI<WebUI className="ml-1 h-4 w-4" fill="white" stroke="white" />
<Button href={config.cameras[camera]['webui_url']} target="_blank">
Web UI
<WebUI className="ml-1 h-4 w-4" fill="white" stroke="white" />
</Button>
)}
<Button className="ml-2" onClick={(e) => onHandleFfprobe(camera, e)}>ffprobe</Button>
<Button className="ml-2" onClick={(e) => onHandleFfprobe(camera, e)}>
ffprobe
</Button>
</div>
</div>
<div className="p-2">

View File

@@ -19,7 +19,16 @@ export default defineConfig({
},
'/exports': {
target: 'http://localhost:5000'
}
},
'/ws': {
target: 'ws://localhost:5000',
ws: true,
},
'/live': {
target: 'ws://localhost:5000',
changeOrigin: true,
ws: true,
},
}
},
plugins: [
@@ -43,4 +52,4 @@ export default defineConfig({
restoreMocks: true,
globals: true,
},
});
});