tons of changes i definitely did not forget to commit earlier

main
AAGaming 3 months ago
commit 9b9f849f0f
Signed by: aa
GPG Key ID: 00CFCD925A3E0C50

48
.gitignore vendored

@ -0,0 +1,48 @@
lib-cov
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz
*.swp
pids
logs
results
tmp
# Coverage reports
coverage
# API keys and secrets
.env
# Dependency directory
node_modules
bower_components
# Editors
.idea
*.iml
# OS metadata
.DS_Store
Thumbs.db
# Ignore built ts files
dist/
__pycache__/
/.yalc
yalc.lock
.vscode/settings.json
rsbin
out
libs
deps
vendor

3
.gitmodules vendored

@ -0,0 +1,3 @@
[submodule "ReplaySorcery"]
path = backend/src
url = https://github.com/AAGaming00/ReplaySorcery.git

@ -0,0 +1 @@
18

12
.vscode/config.sh vendored

@ -0,0 +1,12 @@
#!/usr/bin/env bash
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]:-$0}"; )" &> /dev/null && pwd 2> /dev/null; )";
# printf "${SCRIPT_DIR}\n"
# printf "$(dirname $0)\n"
if ! [[ -e "${SCRIPT_DIR}/settings.json" ]]; then
printf '.vscode/settings.json does not exist. Creating it with default settings. Exiting afterwards. Run your task again.\n\n'
cp "${SCRIPT_DIR}/defsettings.json" "${SCRIPT_DIR}/settings.json"
exit 1
else
printf '.vscode/settings.json does exist. Congrats.\n'
printf 'Make sure to change settings.json to match your deck.\n'
fi

@ -0,0 +1,7 @@
{
"deckip" : "0.0.0.0",
"deckport" : "22",
"deckpass" : "ssap",
"deckkey" : "-i ${env:HOME}/.ssh/id_rsa",
"deckdir" : "/home/deck"
}

113
.vscode/tasks.json vendored

@ -0,0 +1,113 @@
{
"version": "2.0.0",
"tasks": [
// OTHER
{
"label": "checkforsettings",
"type": "shell",
"group": "none",
"detail": "Check that settings.json has been created",
"command": "bash -c ${workspaceFolder}/.vscode/config.sh",
"problemMatcher": []
},
// BUILD
{
"label": "pnpmsetup",
"type": "shell",
"group": "build",
"detail": "Setup pnpm",
"command": "NODE_VERSION=default ~/.nvm/nvm-exec pnpm i || pnpm i",
"problemMatcher": []
},
{
"label": "updatefrontendlib",
"type": "shell",
"group": "build",
"detail": "Update deck-frontend-lib",
"command": "NODE_VERSION=default ~/.nvm/nvm-exec pnpm update decky-frontend-lib --latest || pnpm update decky-frontend-lib --latest",
"problemMatcher": []
},
{
"label": "build",
"type": "npm",
"group": "build",
"detail": "rollup -c",
"script": "build",
"path": "",
"problemMatcher": []
},
// {
// "label": "buildrs",
// "type": "shell",
// "group": "build",
// "command": "./build.sh",
// "problemMatcher": []
// },
{
"label": "buildall",
"group": "build",
"detail": "Build decky-plugin-template",
"dependsOrder": "sequence",
"dependsOn": [
"pnpmsetup",
"build"
// "buildrs"
],
"problemMatcher": []
},
// DEPLOY
{
"label": "createfolders",
"detail": "Create plugins folder in expected directory",
"type": "shell",
"group": "none",
"dependsOn": [
"checkforsettings"
],
"command": "ssh deck@${config:deckip} -p ${config:deckport} ${config:deckkey} 'mkdir -p ${config:deckdir}/homebrew/pluginloader && mkdir -p ${config:deckdir}/homebrew/plugins'",
"problemMatcher": []
},
{
"label": "deploy",
"detail": "Deploy dev plugin to deck",
"type": "shell",
"group": "none",
"dependsOn": [
"createfolders"
],
"command": "rsync -azp --delete --rsh='ssh -p ${config:deckport} ${config:deckkey}' --exclude='.git/' --exclude='.github/' --exclude='.vscode/' --exclude='node_modules/' --exclude='src/' --exclude='ReplaySorcery/' --exclude='gstreamer-src/' --exclude='pipewire-src/' --exclude='vendor/' --exclude='*.log' --exclude='.gitignore' . deck@${config:deckip}:${config:deckdir}/homebrew/plugins/${workspaceFolderBasename}",
"problemMatcher": []
},
{
"label": "chmodfolders",
"detail": "chmods folders to prevent perms issues",
"type": "shell",
"group": "none",
"command": "ssh deck@${config:deckip} -p ${config:deckport} ${config:deckkey} 'echo '${config:deckpass}' | sudo -S chmod -R ug+rw ${config:deckdir}/homebrew/'",
"problemMatcher": []
},
{
"label": "deployall",
"dependsOrder": "sequence",
"group": "none",
"dependsOn": [
"chmodfolders",
"deploy",
"chmodfolders"
],
"problemMatcher": []
},
// ALL-IN-ONE
{
"label": "allinone",
"detail": "Build and deploy",
"dependsOrder": "sequence",
"group": "test",
"dependsOn": [
"buildall",
"deployall"
],
"problemMatcher": []
}
]
}

@ -0,0 +1,3 @@
FROM ghcr.io/steamdeckhomebrew/holo-base
RUN pacman -S --noconfirm gstreamer gst-plugins-base gst-plugins-bad-libs gst-plugins-good gst-plugin-pipewire gstreamer-vaapi

@ -0,0 +1,37 @@
# React-Frontend Plugin Template
Reference example for using [decky-frontend-lib](https://github.com/SteamDeckHomebrew/decky-frontend-lib) in a [PluginLoader](https://github.com/SteamDeckHomebrew/PluginLoader) plugin.
## PluginLoader Discord [![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg)](https://discord.gg/ZU74G2NJzk)
## Developers
### Dependencies
This template relies on the user having `pnpm` installed on their system.
This can be downloaded from `npm` itself which is recommended.
#### Linux
```bash
sudo npm i -g pnpm
```
### Getting Started
1. Clone the repository to use as an example for making your plugin.
2. In your clone of the repository run these commands:
1. ``pnpm i``
2. ``pnpm run build``
3. You should do this every time you make changes to your plugin.
Note: If you are recieveing build errors due to an out of date library, you should run this command inside of your repository:
```bash
pnpm update decky-frontend-lib --latest
```
### Distribution
WIP. Check back in later.

@ -0,0 +1,3 @@
FROM ghcr.io/steamdeckhomebrew/holo-base
RUN pacman -S --noconfirm linux-neptune-headers cmake ffmpeg

@ -0,0 +1,8 @@
#!/bin/sh
cd /src
cmake -B bin -DCMAKE_BUILD_TYPE=Release
make -C bin -j$(nproc)
cp -r ./bin/* /out

@ -0,0 +1 @@
Subproject commit 3046285870593b78b96bb50e1f20e0f34a9e0e64

@ -0,0 +1,5 @@
#!/bin/sh
docker run -it --rm -v $PWD/libs:/out ghcr.io/aagaming00/holo-gstreamer sh -c "cp -r /usr/lib/gstreamer-1.0/libgstvaapi.so /usr/lib/gstreamer-1.0/libgstpipewire.so /usr/lib/libgstcodecparsers* /usr/lib/gstreamer-1.0/libgstvideoparsersbad.so /usr/lib/gstreamer-1.0/libgstisomp4.so /usr/lib/gstreamer-1.0/libgstpulseaudio.so /usr/lib/gstreamer-1.0/libgstlame.so /out"
sudo chown -R aa:aa ./libs

@ -0,0 +1,3 @@
#!/bin/sh
docker run -it --rm -v $PWD/out:/out -v $PWD/vendor/ReplaySorcery:/src -v $PWD/entrypoint.rs.sh:/entrypoint.sh ghcr.io/aagaming00/holo-ffmpeg sh -c "pacman -S --noconfirm git ffmpeg && chmod +x /entrypoint.sh && /entrypoint.sh"

@ -0,0 +1,2 @@
#!/bin/sh

@ -0,0 +1,311 @@
# WIP GStreamer Recorder
import asyncio
import os
import errno
import shutil
import signal
import subprocess
import socket
import logging
import gi
import time
# gi.require_version('Gtk', '3.0') # for ui
gi.require_version('GIRepository', '2.0')
from gi.repository import GIRepository
# GIRepository.Repository.prepend_library_path(os.path.join(os.path.dirname(__file__), "out"))
gi.require_version('Gst', '1.0')
gi.require_version('GstVideo', '1.0')
import asyncio, gbulb
gbulb.install(gtk=False) # turn off gtk to remove ui
from gi.repository import Gst, GstVideo, GLib, GObject
# os.environ['HOME'] = "/home/deck"
# os.environ['XDG_RUNTIME_DIR'] = "/run/user/1000"
dirpath = "/home/deck/Videos/ReplaySorcery"
logging.basicConfig(
#filename="/tmp/recorder.log",
format='%(asctime)s %(levelname)s %(message)s',
filemode='w',
force=True)
logger=logging.getLogger()
logger.setLevel(logging.DEBUG)
Gst.init("--verbose")
Gst.debug_set_active(True)
Gst.debug_set_default_threshold(4)
# if "replay-sorcery.conf" not in os.listdir("/home/deck/.config"):
class Plugin:
def __del__(self):
pass
def __init__(self):
self.loop = asyncio.get_event_loop()
async def _start_recorder(self):
pass
async def start_recorder(self):
if not self.recording:
self.recording = True
logger.info("Starting")
asyncio.ensure_future(self._start_recorder(self))
async def stop_recorder(self):
if self.recording:
self.recording = False
logger.info("Stopping")
os.kill(self.process.pid, signal.SIGINT)
async def toggle_recorder(self):
if self.recording:
return await self.stop_recorder(self)
else:
return await self.start_recorder(self)
async def save(self):
if self.recording and not self.paused:
self.saving = asyncio.get_event_loop().create_future()
logger.info("Saving")
with open('/tmp/recorder.log', "a") as out:
subprocess.Popen([os.path.dirname(__file__) + "/out/replay-sorcery", "save"], stdin=subprocess.PIPE, stdout=out, stderr=out)
logger.info("Done saving")
return await self.saving
return False
async def suspend_pause(self):
if self.recording:
logger.info("Suspending")
self.paused = True
os.kill(self.process.pid, signal.SIGINT)
async def suspend_resume(self):
if self.recording and self.paused:
logger.info("Resuming")
self.paused = False
asyncio.ensure_future(self._start_recorder(self))
# await self.start_recorder(self)
async def get_status(self):
return self.recording
# client = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
# client.connect("/tmp/replay-sorcery/control.sock")
# client.close()
async def get_videos_len(self):
return len(os.listdir("/home/deck/Videos/ReplaySorcery"))
async def get_videos(self):
arr = sorted(filter(lambda s: os.path.isfile(os.path.join(dirpath, s)), os.listdir(dirpath)), key=lambda s: os.path.getmtime(os.path.join(dirpath, s)))
arr.reverse()
return arr
def _standalone(self):
self.loop.create_task(self._main())
self.loop.create_task(self._rec())
self.loop.run_forever()
async def _rec(self):
await asyncio.sleep(12)
print("start")
self.start_muxing()
# self.file.set_state(Gst.State.NULL)
# self.file.set_state(Gst.State.PLAYING)
# self.in_valve.set_property("drop", 1)
# self.out_valve.set_property("drop", 0)
await asyncio.sleep(10)
print("stopping")
self.stop_muxing()
# self.out_valve.set_property("drop", 1)
# self.in_valve.set_property("drop", 0)
# await asyncio.sleep(2)
# self.mux.send_event(Gst.Event.new_eos())
# await asyncio.sleep(4)
# self.file.set_state(Gst.State.NULL)
# self.file.set_property("location", "/dev/null")
# self.file.set_state(Gst.State.PLAYING)
# self.file.set_state(Gst.State.NULL)
# self.file.set_property("location", "/dev/null")
# self.file.set_state(Gst.State.PLAYING)
# self.valve.set_property("drop", 0)
# self.loc = f"./clips/{time.strftime('%Y-%m-%d-%H-%M-%S')}.mp4"
# self.drop = False
# self.play = True
# # self.pipeline.bus.add_signal_watch()
# # self.src.emit("end-of-stream")
# # self.valve.emit("end-of-stream")
# # self.proc.emit("end-of-stream")
# # self.mux.emit("end-of-stream")
# # self.parse.emit("end-of-stream")
# self.mp4mux.emit("end-of-stream")
# # self.sink.emit("end-of-stream")
# self.sink.set_state(Gst.State.NULL)
# self.mux.set_state(Gst.State.NULL)
# self.parse.set_state(Gst.State.NULL)
# self.mp4mux.set_state(Gst.State.NULL)
# self.sink.set_property("location", self.loc)
# # self.proc.send_event(Gst.Event.new_eos())
# # self.mux.send_event(Gst.Event.new_eos())
# # self.parse.send_event(Gst.Event.new_eos())
# # self.mp4mux.send_event(Gst.Event.new_eos())
# self.valve.set_property("drop", self.drop)
# self.sink.set_state(Gst.State.PLAYING)
# self.mux.set_state(Gst.State.PLAYING)
# self.parse.set_state(Gst.State.PLAYING)
# self.mp4mux.set_state(Gst.State.PLAYING)
# # self.sink.send_event(Gst.Event.new_eos())
# await asyncio.sleep(0.25)
# print("play")
# await asyncio.sleep(10)
# print("sw")
# self.loc = "/dev/null"
# self.drop = True
# self.play = False
# self.sink.set_state(Gst.State.NULL)
# self.sink.set_property("location", self.loc)
# self.valve.set_property("drop", self.drop)
# self.sink.set_state(Gst.State.PLAYING)
# # self.valve.send_event(Gst.Event.new_eos())
# # self.mux.send_event(Gst.Event.new_eos())
# # self.parse.send_event(Gst.Event.new_eos())
# # self.mp4mux.send_event(Gst.Event.new_eos())
# # self.sink.send_event(Gst.Event.new_eos())
# await asyncio.sleep(4)
# self.pipeline.bus.timed_pop_filtered(Gst.CLOCK_TIME_NONE, Gst.MessageType.EOS)
# self.pipeline.bus.add_signal_watch()
# self.pipeline.send_event(Gst.Event.new_eos())
# def on_message(self, bus, message: Gst.Message):
# mtype = message.type
# # if mtype == Gst.MessageType.EOS:
# # print("End of stream")
# # loop.quit()
# if mtype == Gst.MessageType.ERROR:
# err, debug = message.parse_error()
# self.pipeline.send_event(Gst.Event.new_eos())
# bus.timed_pop_filtered(Gst.CLOCK_TIME_NONE, Gst.MessageType.EOS)
# loop.quit()
# elif mtype == Gst.MessageType.ANY:
# err, debug = message.parse_warning()
# print(err, debug)
# return True
def on_msg(self, bus, message):
print("evt", message, message.type)
if message.type == Gst.MessageType.EOS:
print("start eos")
# self.mux.set_state(Gst.State.PAUSED)
# self.parse.set_state(Gst.State.PAUSED)
# self.mp4mux.set_state(Gst.State.PAUSED)
# self.sink.set_state(Gst.State.NULL)
# self.sink.set_property("location", self.loc)
# self.valve.set_property("drop", self.drop)
# if self.play:
# # self.mux.set_state(Gst.State.PLAYING)
# # self.parse.set_state(Gst.State.PLAYING)
# # self.mp4mux.set_state(Gst.State.PLAYING)
# self.sink.set_state(Gst.State.PLAYING)
print("finish eos")
# self.pipeline.bus.remove_signal_watch()
# self.pipeline.bus.add_signal_watch()
# return
if message.type == Gst.MessageType.WARNING:
err, debug = message.parse_warning()
print(err, debug)
if message.type == Gst.MessageType.ERROR:
err, debug = message.parse_error()
print(err, debug)
return True
def start_muxing(self):
enc = Gst.ElementFactory.make("vaapih264enc", "enc")
parse = Gst.ElementFactory.make("h264parse", "parse")
mp4mux = Gst.ElementFactory.make("mp4mux", "sink")
file = Gst.ElementFactory.make("filesink", "file")
file.set_property("sync", False)
file.set_property("location", f"./clips/{time.strftime('%Y-%m-%d-%H-%M-%S')}.mp4")
self.pipeline.add(enc)
self.pipeline.add(parse)
self.pipeline.add(mp4mux)
self.pipeline.add(file)
self.tee.link(enc)
enc.link(parse)
parse.link(mp4mux)
mp4mux.link(file)
enc.set_state(Gst.State.PLAYING)
parse.set_state(Gst.State.PLAYING)
mp4mux.set_state(Gst.State.PLAYING)
file.set_state(Gst.State.PLAYING)
self.enc = enc
self.parse = parse
self.mp4mux = mp4mux
self.file = file
# self.in_valve.set_property("drop", 1)
print("started muxer")
def stop_muxing(self):
# self.out_valve.set_property("drop", 1)
self.tee.unlink(self.enc)
# self.enc.send_event(Gst.Event.new_eos())
# self.parse.send_event(Gst.Event.new_eos())
self.mp4mux.send_event(Gst.Event.new_eos())
# self.file.send_event(Gst.Event.new_eos())
# self.out_valve.send_event(Gst.Event.new_eos())
# self.proc.unlink(self.enc)
# self.enc.unlink(self.parse)
# self.parse.unlink(self.mp4mux)
# self.mp4mux.unlink(self.file)
# self.in_valve.set_property("drop", 0)
async def _main(self):
pipeline = Gst.parse_launch("""
videotestsrc do-timestamp=true
! valve drop=0 name=in-flow
! vaapipostproc name=proc
! queue name=buf max-size-buffers=0 max-size-bytes=0 max-size-time=7000000000 min-threshold-time=5000000000 leaky=2
! tee name=t
t. ! fakesink sync=false
""")
# max-size-buffers=0 max-size-bytes=0 max-size-time=7000000000 min-threshold-time=5000000000 leaky=2
# pulsesrc
# ! audioconvert
# ! lamemp3enc target=bitrate bitrate=128 cbr=true
# ! sink.audio_0
# max-size-buffers=0 max-size-bytes=0 max-size-time=12000000000 min-threshold-time=10000000000 leaky=2
#! vaapipostproc
# !
# ! h264parse
# ! mp4mux name=sink
# ! filesink location=./video.mp4
pipeline.bus.add_signal_watch()
# pipeline.bus.enable_sync_message_emission()
pipeline.bus.connect("message", self.on_msg)
self.in_valve = pipeline.get_by_name("in-flow")
self.queue = pipeline.get_by_name("buf")
self.tee = pipeline.get_by_name("t")
self.pipeline = pipeline
pipeline.set_state(Gst.State.PLAYING)
# Asyncio-compatible long-running code, executed in a task when the plugin is loaded
# async def _main(self):
# self.recording = True
# self.paused = True
# path = os.path.dirname(os.path.abspath(__file__))
# try:
# os.symlink("/home/deck/Videos/ReplaySorcery", path + "/dist/assets", target_is_directory=True)
# except OSError as e:
# if e.errno == errno.EEXIST:
# pass
# # await self.start_recorder(self)
# pass
if __name__ == "__main__":
Plugin()._standalone()

@ -0,0 +1,132 @@
import asyncio
import os
import errno
import shutil
import signal
import subprocess
import socket
import logging
shutil.copy(os.path.dirname(__file__) + "/replay-sorcery.conf", "/home/deck/.config/replay-sorcery.conf")
os.chown("/home/deck/.config/replay-sorcery.conf", 1000, 1000)
try:
os.remove("/tmp/replay-sorcery/device.sock")
except FileNotFoundError:
pass
try:
os.remove("/tmp/replay-sorcery/control.sock")
except FileNotFoundError:
pass
with open('/tmp/recorder-daemon.log', "w") as out:
kmsgrabber = subprocess.Popen([os.path.dirname(__file__) + "/out/replay-sorcery", "kms-service"], stdin=subprocess.PIPE, stdout=out, stderr=out)
os.setuid(1000)
os.environ['HOME'] = "/home/deck"
os.environ['XDG_RUNTIME_DIR'] = "/run/user/1000"
dirpath = "/home/deck/Videos/Replays"
logging.basicConfig(filename="/tmp/recorder.log",
format='[Recorder] %(asctime)s %(levelname)s %(message)s',
filemode='w',
force=True)
logger=logging.getLogger()
logger.setLevel(logging.DEBUG)
# if "replay-sorcery.conf" not in os.listdir("/home/deck/.config"):
class Plugin:
def __del__():
kmsgrabber.terminate()
kmsgrabber.join()
async def _start_recorder(self):
self.process = await asyncio.create_subprocess_exec(*[os.path.dirname(__file__) + "/out/replay-sorcery"], stdin=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT)
while True:
line = await self.process.stdout.readline()
if line:
logger.info("OUT: " + line.decode("UTF-8"))
#if line == b"KMS service failed to get frame: Input/output error\n":
# Deck has switched window.
# if line.endswith(b"Failed to send frame to filter graph: Invalid argument\n"):
# await self.suspend_pause(self)
# await asyncio.sleep(0.2)
# await self.suspend_resume(self)
# break
#logger.info("RS: " + str(line))
if line.startswith(b"Saving video to '"):
self.saving.set_result(line.replace(b"Saving video to '", b"").replace(b"'...", b"").decode("UTF-8"))
else:
if self.process.returncode != 0 and self.recording and not self.paused:
await asyncio.sleep(1)
self.process = await asyncio.create_subprocess_exec(*[os.path.dirname(__file__) + "/out/replay-sorcery"], stdin=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT)
continue
break
async def start_recorder(self):
if not self.recording:
self.recording = True
logger.info("Starting")
asyncio.ensure_future(self._start_recorder(self))
async def stop_recorder(self):
if self.recording:
self.recording = False
logger.info("Stopping")
os.kill(self.process.pid, signal.SIGINT)
async def toggle_recorder(self):
if self.recording:
return await self.stop_recorder(self)
else:
return await self.start_recorder(self)
async def save(self):
if self.recording and not self.paused:
self.saving = asyncio.get_event_loop().create_future()
logger.info("Saving")
with open('/tmp/recorder.log', "a") as out:
subprocess.Popen([os.path.dirname(__file__) + "/out/replay-sorcery", "save"], stdin=subprocess.PIPE, stdout=out, stderr=out)
logger.info("Done saving")
return await self.saving
return False
async def suspend_pause(self):
if self.recording:
logger.info("Suspending")
self.paused = True
os.kill(self.process.pid, signal.SIGINT)
async def suspend_resume(self):
if self.recording and self.paused:
logger.info("Resuming")
self.paused = False
asyncio.ensure_future(self._start_recorder(self))
# await self.start_recorder(self)
async def get_status(self):
return self.recording
# client = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
# client.connect("/tmp/replay-sorcery/control.sock")
# client.close()
async def get_videos_len(self):
return len(os.listdir(dirpath))
async def get_videos(self):
arr = sorted(filter(lambda s: os.path.isfile(os.path.join(dirpath, s)), os.listdir(dirpath)), key=lambda s: os.path.getmtime(os.path.join(dirpath, s)))
arr.reverse()
return arr
# Asyncio-compatible long-running code, executed in a task when the plugin is loaded
async def _main(self):
self.recording = True
self.paused = True
path = os.path.dirname(os.path.abspath(__file__))
try:
os.symlink(dirpath, path + "/dist/assets", target_is_directory=True)
except OSError as e:
if e.errno == errno.EEXIST:
pass
# await self.start_recorder(self)
pass

@ -0,0 +1,54 @@
{
"name": "deck-recorder",
"version": "0.0.1",
"description": "Steam deck clips recorder",
"scripts": {
"build": "shx rm -rf dist && rollup -c",
"watch": "rollup -c -w",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/SteamDeckHomebrew/decky-plugin-template.git"
},
"keywords": [
"decky",
"plugin",
"plugin-template",
"steam-deck",
"deck"
],
"author": "Jonas Dellinger <jonas@dellinger.dev>",
"license": "GPL-2.0-or-later",
"bugs": {
"url": "https://github.com/SteamDeckHomebrew/decky-plugin-template/issues"
},
"homepage": "https://github.com/SteamDeckHomebrew/decky-plugin-template#readme",
"devDependencies": {
"@rollup/plugin-commonjs": "^21.1.0",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^13.2.1",
"@rollup/plugin-replace": "^4.0.0",
"@rollup/plugin-typescript": "^8.3.2",
"@types/react": "16.14.0",
"@types/webpack": "^5.28.0",
"rollup": "^2.70.2",
"rollup-plugin-import-assets": "^1.1.1",
"shx": "^0.3.4",
"tslib": "^2.4.0",
"typescript": "^4.6.4"
},
"dependencies": {
"decky-frontend-lib": "^2.0.0",
"react-icons": "^4.3.1",
"rooks": "^6.4.3"
},
"pnpm": {
"peerDependencyRules": {
"ignoreMissing": [
"react",
"react-dom"
]
}
}
}

@ -0,0 +1,5 @@
{
"name": "Recorder",
"author": "AAGaming00",
"flags": ["debug", "root"]
}

@ -0,0 +1,944 @@
lockfileVersion: 5.4
specifiers:
'@rollup/plugin-commonjs': ^21.1.0
'@rollup/plugin-json': ^4.1.0
'@rollup/plugin-node-resolve': ^13.2.1
'@rollup/plugin-replace': ^4.0.0
'@rollup/plugin-typescript': ^8.3.2
'@types/react': 16.14.0
'@types/webpack': ^5.28.0
decky-frontend-lib: ^2.0.0
react-icons: ^4.3.1
rollup: ^2.70.2
rollup-plugin-import-assets: ^1.1.1
rooks: ^6.4.3
shx: ^0.3.4
tslib: ^2.4.0
typescript: ^4.6.4
dependencies:
decky-frontend-lib: 2.0.0
react-icons: 4.4.0
rooks: 6.4.3
devDependencies:
'@rollup/plugin-commonjs': 21.1.0_rollup@2.75.6
'@rollup/plugin-json': 4.1.0_rollup@2.75.6
'@rollup/plugin-node-resolve': 13.3.0_rollup@2.75.6
'@rollup/plugin-replace': 4.0.0_rollup@2.75.6
'@rollup/plugin-typescript': 8.3.3_a4s7325ov6m337p2dvgeh54tg4
'@types/react': 16.14.0
'@types/webpack': 5.28.0
rollup: 2.75.6
rollup-plugin-import-assets: 1.1.1_rollup@2.75.6
shx: 0.3.4
tslib: 2.4.0
typescript: 4.7.3
packages:
/@jridgewell/gen-mapping/0.3.1:
resolution: {integrity: sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==}
engines: {node: '>=6.0.0'}
dependencies:
'@jridgewell/set-array': 1.1.1
'@jridgewell/sourcemap-codec': 1.4.13
'@jridgewell/trace-mapping': 0.3.13
dev: true
/@jridgewell/resolve-uri/3.0.7:
resolution: {integrity: sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==}
engines: {node: '>=6.0.0'}
dev: true
/@jridgewell/set-array/1.1.1:
resolution: {integrity: sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==}
engines: {node: '>=6.0.0'}
dev: true
/@jridgewell/source-map/0.3.2:
resolution: {integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==}
dependencies:
'@jridgewell/gen-mapping': 0.3.1
'@jridgewell/trace-mapping': 0.3.13
dev: true
/@jridgewell/sourcemap-codec/1.4.13:
resolution: {integrity: sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==}
dev: true
/@jridgewell/trace-mapping/0.3.13:
resolution: {integrity: sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==}
dependencies:
'@jridgewell/resolve-uri': 3.0.7
'@jridgewell/sourcemap-codec': 1.4.13
dev: true
/@rollup/plugin-commonjs/21.1.0_rollup@2.75.6:
resolution: {integrity: sha512-6ZtHx3VHIp2ReNNDxHjuUml6ur+WcQ28N1yHgCQwsbNkQg2suhxGMDQGJOn/KuDxKtd1xuZP5xSTwBA4GQ8hbA==}
engines: {node: '>= 8.0.0'}
peerDependencies:
rollup: ^2.38.3
dependencies:
'@rollup/pluginutils': 3.1.0_rollup@2.75.6
commondir: 1.0.1
estree-walker: 2.0.2
glob: 7.2.3
is-reference: 1.2.1
magic-string: 0.25.9
resolve: 1.22.0
rollup: 2.75.6
dev: true
/@rollup/plugin-json/4.1.0_rollup@2.75.6:
resolution: {integrity: sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==}
peerDependencies:
rollup: ^1.20.0 || ^2.0.0
dependencies:
'@rollup/pluginutils': 3.1.0_rollup@2.75.6
rollup: 2.75.6
dev: true
/@rollup/plugin-node-resolve/13.3.0_rollup@2.75.6:
resolution: {integrity: sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==}
engines: {node: '>= 10.0.0'}
peerDependencies:
rollup: ^2.42.0
dependencies:
'@rollup/pluginutils': 3.1.0_rollup@2.75.6
'@types/resolve': 1.17.1
deepmerge: 4.2.2
is-builtin-module: 3.1.0
is-module: 1.0.0
resolve: 1.22.0
rollup: 2.75.6
dev: true
/@rollup/plugin-replace/4.0.0_rollup@2.75.6:
resolution: {integrity: sha512-+rumQFiaNac9y64OHtkHGmdjm7us9bo1PlbgQfdihQtuNxzjpaB064HbRnewUOggLQxVCCyINfStkgmBeQpv1g==}
peerDependencies:
rollup: ^1.20.0 || ^2.0.0
dependencies:
'@rollup/pluginutils': 3.1.0_rollup@2.75.6
magic-string: 0.25.9
rollup: 2.75.6
dev: true
/@rollup/plugin-typescript/8.3.3_a4s7325ov6m337p2dvgeh54tg4:
resolution: {integrity: sha512-55L9SyiYu3r/JtqdjhwcwaECXP7JeJ9h1Sg1VWRJKIutla2MdZQodTgcCNybXLMCnqpNLEhS2vGENww98L1npg==}
engines: {node: '>=8.0.0'}
peerDependencies:
rollup: ^2.14.0
tslib: '*'
typescript: '>=3.7.0'
peerDependenciesMeta:
tslib:
optional: true
dependencies:
'@rollup/pluginutils': 3.1.0_rollup@2.75.6
resolve: 1.22.0
rollup: 2.75.6
tslib: 2.4.0
typescript: 4.7.3
dev: true
/@rollup/pluginutils/3.1.0_rollup@2.75.6:
resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==}
engines: {node: '>= 8.0.0'}
peerDependencies:
rollup: ^1.20.0||^2.0.0
dependencies:
'@types/estree': 0.0.39
estree-walker: 1.0.1
picomatch: 2.3.1
rollup: 2.75.6
dev: true
/@types/eslint-scope/3.7.3:
resolution: {integrity: sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==}
dependencies:
'@types/eslint': 8.4.3
'@types/estree': 0.0.51
dev: true
/@types/eslint/8.4.3:
resolution: {integrity: sha512-YP1S7YJRMPs+7KZKDb9G63n8YejIwW9BALq7a5j2+H4yl6iOv9CB29edho+cuFRrvmJbbaH2yiVChKLJVysDGw==}
dependencies:
'@types/estree': 0.0.51
'@types/json-schema': 7.0.11
dev: true
/@types/estree/0.0.39:
resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==}
dev: true
/@types/estree/0.0.51:
resolution: {integrity: sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==}
dev: true
/@types/json-schema/7.0.11:
resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==}
dev: true
/@types/node/17.0.42:
resolution: {integrity: sha512-Q5BPGyGKcvQgAMbsr7qEGN/kIPN6zZecYYABeTDBizOsau+2NMdSVTar9UQw21A2+JyA2KRNDYaYrPB0Rpk2oQ==}
dev: true
/@types/prop-types/15.7.5:
resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
dev: true
/@types/react/16.14.0:
resolution: {integrity: sha512-jJjHo1uOe+NENRIBvF46tJimUvPnmbQ41Ax0pEm7pRvhPg+wuj8VMOHHiMvaGmZRzRrCtm7KnL5OOE/6kHPK8w==}
dependencies:
'@types/prop-types': 15.7.5
csstype: 3.1.0
dev: true
/@types/resolve/1.17.1:
resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==}
dependencies:
'@types/node': 17.0.42
dev: true
/@types/webpack/5.28.0:
resolution: {integrity: sha512-8cP0CzcxUiFuA9xGJkfeVpqmWTk9nx6CWwamRGCj95ph1SmlRRk9KlCZ6avhCbZd4L68LvYT6l1kpdEnQXrF8w==}
dependencies:
'@types/node': 17.0.42
tapable: 2.2.1
webpack: 5.73.0
transitivePeerDependencies:
- '@swc/core'
- esbuild
- uglify-js
- webpack-cli
dev: true
/@webassemblyjs/ast/1.11.1:
resolution: {integrity: sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==}
dependencies:
'@webassemblyjs/helper-numbers': 1.11.1
'@webassemblyjs/helper-wasm-bytecode': 1.11.1
dev: true
/@webassemblyjs/floating-point-hex-parser/1.11.1:
resolution: {integrity: sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==}
dev: true
/@webassemblyjs/helper-api-error/1.11.1:
resolution: {integrity: sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==}
dev: true
/@webassemblyjs/helper-buffer/1.11.1:
resolution: {integrity: sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==}
dev: true
/@webassemblyjs/helper-numbers/1.11.1:
resolution: {integrity: sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==}
dependencies:
'@webassemblyjs/floating-point-hex-parser': 1.11.1
'@webassemblyjs/helper-api-error': 1.11.1
'@xtuc/long': 4.2.2
dev: true
/@webassemblyjs/helper-wasm-bytecode/1.11.1:
resolution: {integrity: sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==}
dev: true
/@webassemblyjs/helper-wasm-section/1.11.1:
resolution: {integrity: sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==}
dependencies:
'@webassemblyjs/ast': 1.11.1
'@webassemblyjs/helper-buffer': 1.11.1
'@webassemblyjs/helper-wasm-bytecode': 1.11.1
'@webassemblyjs/wasm-gen': 1.11.1
dev: true
/@webassemblyjs/ieee754/1.11.1:
resolution: {integrity: sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==}
dependencies:
'@xtuc/ieee754': 1.2.0
dev: true
/@webassemblyjs/leb128/1.11.1:
resolution: {integrity: sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==}
dependencies:
'@xtuc/long': 4.2.2
dev: true
/@webassemblyjs/utf8/1.11.1:
resolution: {integrity: sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==}
dev: true
/@webassemblyjs/wasm-edit/1.11.1:
resolution: {integrity: sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==}
dependencies:
'@webassemblyjs/ast': 1.11.1
'@webassemblyjs/helper-buffer': 1.11.1
'@webassemblyjs/helper-wasm-bytecode': 1.11.1
'@webassemblyjs/helper-wasm-section': 1.11.1
'@webassemblyjs/wasm-gen': 1.11.1
'@webassemblyjs/wasm-opt': 1.11.1
'@webassemblyjs/wasm-parser': 1.11.1
'@webassemblyjs/wast-printer': 1.11.1
dev: true
/@webassemblyjs/wasm-gen/1.11.1:
resolution: {integrity: sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==}
dependencies:
'@webassemblyjs/ast': 1.11.1
'@webassemblyjs/helper-wasm-bytecode': 1.11.1
'@webassemblyjs/ieee754': 1.11.1
'@webassemblyjs/leb128': 1.11.1
'@webassemblyjs/utf8': 1.11.1
dev: true
/@webassemblyjs/wasm-opt/1.11.1:
resolution: {integrity: sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==}
dependencies:
'@webassemblyjs/ast': 1.11.1
'@webassemblyjs/helper-buffer': 1.11.1
'@webassemblyjs/wasm-gen': 1.11.1
'@webassemblyjs/wasm-parser': 1.11.1
dev: true
/@webassemblyjs/wasm-parser/1.11.1:
resolution: {integrity: sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==}
dependencies:
'@webassemblyjs/ast': 1.11.1
'@webassemblyjs/helper-api-error': 1.11.1
'@webassemblyjs/helper-wasm-bytecode': 1.11.1
'@webassemblyjs/ieee754': 1.11.1
'@webassemblyjs/leb128': 1.11.1
'@webassemblyjs/utf8': 1.11.1
dev: true
/@webassemblyjs/wast-printer/1.11.1:
resolution: {integrity: sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==}
dependencies:
'@webassemblyjs/ast': 1.11.1
'@xtuc/long': 4.2.2
dev: true
/@xtuc/ieee754/1.2.0:
resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==}
dev: true
/@xtuc/long/4.2.2:
resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
dev: true
/acorn-import-assertions/1.8.0_acorn@8.7.1:
resolution: {integrity: sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==}
peerDependencies:
acorn: ^8
dependencies:
acorn: 8.7.1
dev: true
/acorn/8.7.1:
resolution: {integrity: sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==}
engines: {node: '>=0.4.0'}
hasBin: true
dev: true
/ajv-keywords/3.5.2_ajv@6.12.6:
resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==}
peerDependencies:
ajv: ^6.9.1
dependencies:
ajv: 6.12.6
dev: true
/ajv/6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
dependencies:
fast-deep-equal: 3.1.3
fast-json-stable-stringify: 2.1.0
json-schema-traverse: 0.4.1
uri-js: 4.4.1
dev: true
/balanced-match/1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
dev: true
/brace-expansion/1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
dependencies:
balanced-match: 1.0.2
concat-map: 0.0.1
dev: true
/browserslist/4.20.4:
resolution: {integrity: sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
dependencies:
caniuse-lite: 1.0.30001352
electron-to-chromium: 1.4.154
escalade: 3.1.1
node-releases: 2.0.5
picocolors: 1.0.0
dev: true
/buffer-from/1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
dev: true
/builtin-modules/3.3.0:
resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==}
engines: {node: '>=6'}
dev: true
/caniuse-lite/1.0.30001352:
resolution: {integrity: sha512-GUgH8w6YergqPQDGWhJGt8GDRnY0L/iJVQcU3eJ46GYf52R8tk0Wxp0PymuFVZboJYXGiCqwozAYZNRjVj6IcA==}
dev: true
/chrome-trace-event/1.0.3:
resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==}
engines: {node: '>=6.0'}
dev: true
/commander/2.20.3:
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
dev: true
/commondir/1.0.1:
resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==}
dev: true
/concat-map/0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
dev: true
/csstype/3.1.0:
resolution: {integrity: sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==}
dev: true
/decky-frontend-lib/2.0.0:
resolution: {integrity: sha512-H7+JpKHlClECVpo+MCEwej7R9wDWk9M2uMSyTvuhTfLZe3RThsxWCiqY640Cjh/zIW2A7GyVRd4SjLtn6Isdeg==}
dependencies:
minimist: 1.2.6
dev: false
/deepmerge/4.2.2:
resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==}
engines: {node: '>=0.10.0'}
dev: true
/electron-to-chromium/1.4.154:
resolution: {integrity: sha512-GbV9djOkrnj6xmW+YYVVEI3VCQnJ0pnSTu7TW2JyjKd5cakoiSaG5R4RbEtfaD92GsY10DzbU3GYRe+IOA9kqA==}
dev: true
/enhanced-resolve/5.9.3:
resolution: {integrity: sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow==}
engines: {node: '>=10.13.0'}
dependencies:
graceful-fs: 4.2.10
tapable: 2.2.1
dev: true
/es-module-lexer/0.9.3:
resolution: {integrity: sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==}
dev: true
/escalade/3.1.1:
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
engines: {node: '>=6'}
dev: true
/eslint-scope/5.1.1:
resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
engines: {node: '>=8.0.0'}
dependencies:
esrecurse: 4.3.0
estraverse: 4.3.0
dev: true
/esrecurse/4.3.0:
resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
engines: {node: '>=4.0'}
dependencies:
estraverse: 5.3.0
dev: true
/estraverse/4.3.0:
resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==}
engines: {node: '>=4.0'}
dev: true
/estraverse/5.3.0:
resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
engines: {node: '>=4.0'}
dev: true
/estree-walker/0.6.1:
resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==}
dev: true
/estree-walker/1.0.1:
resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==}
dev: true
/estree-walker/2.0.2:
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
dev: true
/events/3.3.0:
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
engines: {node: '>=0.8.x'}
dev: true
/fast-deep-equal/3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
dev: true
/fast-json-stable-stringify/2.1.0:
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
dev: true
/fs.realpath/1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
dev: true
/fsevents/2.3.2:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
requiresBuild: true
dev: true
optional: true
/function-bind/1.1.1:
resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
dev: true
/glob-to-regexp/0.4.1:
resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
dev: true
/glob/7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
dependencies:
fs.realpath: 1.0.0
inflight: 1.0.6
inherits: 2.0.4
minimatch: 3.1.2
once: 1.4.0
path-is-absolute: 1.0.1
dev: true
/graceful-fs/4.2.10:
resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==}
dev: true
/has-flag/4.0.0:
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
engines: {node: '>=8'}
dev: true
/has/1.0.3:
resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
engines: {node: '>= 0.4.0'}
dependencies:
function-bind: 1.1.1
dev: true
/inflight/1.0.6:
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
dependencies:
once: 1.4.0
wrappy: 1.0.2
dev: true
/inherits/2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
dev: true
/interpret/1.4.0:
resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==}
engines: {node: '>= 0.10'}
dev: true
/is-builtin-module/3.1.0:
resolution: {integrity: sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==}
engines: {node: '>=6'}
dependencies:
builtin-modules: 3.3.0
dev: true
/is-core-module/2.9.0:
resolution: {integrity: sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==}
dependencies:
has: 1.0.3
dev: true
/is-module/1.0.0:
resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==}
dev: true
/is-reference/1.2.1:
resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==}
dependencies:
'@types/estree': 0.0.51
dev: true
/jest-worker/27.5.1:
resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==}
engines: {node: '>= 10.13.0'}
dependencies:
'@types/node': 17.0.42
merge-stream: 2.0.0
supports-color: 8.1.1
dev: true
/json-parse-even-better-errors/2.3.1:
resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
dev: true
/json-schema-traverse/0.4.1:
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
dev: true
/loader-runner/4.3.0:
resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==}
engines: {node: '>=6.11.5'}
dev: true
/lodash.debounce/4.0.8:
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
dev: false
/magic-string/0.25.9:
resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
dependencies:
sourcemap-codec: 1.4.8
dev: true
/merge-stream/2.0.0:
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
dev: true
/mime-db/1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'}
dev: true
/mime-types/2.1.35:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
dependencies:
mime-db: 1.52.0
dev: true
/minimatch/3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
dependencies:
brace-expansion: 1.1.11
dev: true
/minimist/1.2.6:
resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==}
/neo-async/2.6.2:
resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
dev: true
/node-releases/2.0.5:
resolution: {integrity: sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==}
dev: true
/once/1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
dependencies:
wrappy: 1.0.2
dev: true
/path-is-absolute/1.0.1:
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
engines: {node: '>=0.10.0'}
dev: true
/path-parse/1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
dev: true
/performance-now/2.1.0:
resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==}
dev: false
/picocolors/1.0.0:
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
dev: true
/picomatch/2.3.1:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
dev: true
/punycode/2.1.1:
resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==}
engines: {node: '>=6'}
dev: true
/raf/3.4.1:
resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==}
dependencies:
performance-now: 2.1.0
dev: false
/randombytes/2.1.0:
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
dependencies:
safe-buffer: 5.2.1
dev: true
/react-icons/4.4.0:
resolution: {integrity: sha512-fSbvHeVYo/B5/L4VhB7sBA1i2tS8MkT0Hb9t2H1AVPkwGfVHLJCqyr2Py9dKMxsyM63Eng1GkdZfbWj+Fmv8Rg==}
peerDependencies:
react: '*'
peerDependenciesMeta:
react:
optional: true
dev: false
/rechoir/0.6.2:
resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==}
engines: {node: '>= 0.10'}
dependencies:
resolve: 1.22.0
dev: true
/resolve/1.22.0:
resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==}
hasBin: true
dependencies:
is-core-module: 2.9.0
path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0
dev: true
/rollup-plugin-import-assets/1.1.1_rollup@2.75.6:
resolution: {integrity: sha512-u5zJwOjguTf2N+wETq2weNKGvNkuVc1UX/fPgg215p5xPvGOaI6/BTc024E9brvFjSQTfIYqgvwogQdipknu1g==}
peerDependencies:
rollup: '>=1.9.0'
dependencies:
rollup: 2.75.6
rollup-pluginutils: 2.8.2
url-join: 4.0.1
dev: true
/rollup-pluginutils/2.8.2:
resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==}
dependencies: