diff --git a/.gitignore b/.gitignore index 40b878d..53452a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ -node_modules/ \ No newline at end of file +node_modules/ +__pycache__/ +venv/ +.vscode/ diff --git a/.hintrc b/.hintrc new file mode 100644 index 0000000..ae62a1a --- /dev/null +++ b/.hintrc @@ -0,0 +1,13 @@ +{ + "extends": [ + "development" + ], + "hints": { + "axe/text-alternatives": [ + "default", + { + "image-alt": "off" + } + ] + } +} \ No newline at end of file diff --git a/ReadMe.md b/ReadMe.md index 6e182a4..71b8b79 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -1,24 +1,33 @@ # GoodGarden -Welkom bij ons project genaamd "GoodGarden". Wij hebben besloten om er een monolitische project van te maken. Alles is te vinden binnen deze repository. +Welkom bij ons project genaamd "GoodGarden". Wij hebben besloten om er een semi-monolithic project van te maken. Alles is te vinden binnen deze repository, inclusief de "mqtt" publisher. ### Vereisten * Python * Node.Js * XAMPP (of andere naar keuze) + * MQTT Geinstalleerd en toegevoegd aan je PATH variable ### Installeren -Zorg dat je in de hoofdmap "GoodGarden" zit. Kijk in je path: "/GoodGarden". Als je in de correcte map zit moet je de volgende items installeren: +Zorg dat je in de hoofdmap "GoodGarden" zit. Kijk in je path: "../GoodGarden". Als je in de correcte map zit moet je de volgende items installeren: - - npm install electron - - npm install express - - npm install body-parser - - npm install python-shell + npm install electron + npm install express + npm install body-parser + npm install python-shell + npm install --save-dev npm-run-all + npm install wait-on --save-dev + npm install concurrently --save-dev + + + + + pip install mysql-connector-python + pip install requests + pip install flask-cors - - pip install mysql-connector-python - - pip install requests ## Gebruik diff --git a/app.js b/app.js index ef0679d..b4d2392 100644 --- a/app.js +++ b/app.js @@ -1,68 +1,109 @@ -const { app, BrowserWindow, ipcMain } = require('electron'); -const express = require('express'); -const bodyParser = require('body-parser'); -const { PythonShell } = require('python-shell'); -const path = require('path'); +const { app, BrowserWindow, ipcMain } = require("electron"); +const express = require("express"); +const bodyParser = require("body-parser"); +const { PythonShell } = require("python-shell"); +const path = require("path"); + const urlElectron = path.join(__dirname, "src/index.html"); -// Maak een Express-app const server = express(); server.use(bodyParser.urlencoded({ extended: true })); -// Definieer een route voor form POST verzoeken -server.post('/submit-form', (req, res) => { - const { plant_naam, plantensoort } = req.body; // Verkrijg de plant_naam uit het formulier - const plant_geteelt = req.body.plant_geteelt == 'true' ? 'true' : 'false'; // Zorgt dat de string "true" herkent wordt +// Define a route for form POST requests +server.post("/submit-form", (req, res) => { + const { plant_naam, plantensoort } = req.body; + const plant_geteelt = req.body.plant_geteelt == "true" ? "true" : "false"; let options = { - mode: 'text', - args: [plant_naam, plantensoort, plant_geteelt] // Zet hier een variable bij om de data toe te voegen aan de database + mode: "text", + args: [plant_naam, plantensoort, plant_geteelt], }; - // Voer Python script uit met de plant_naam als argument - PythonShell.run('./script/db_connect_form.py', options, (err, results) => { - if (err) { - console.error(err); - res.send('Er is een fout opgetreden'); - } else { - console.log('Python script uitvoering resultaten:', results); - res.send('Formulier succesvol verwerkt'); + // Execute Python script with plant name as an argument + PythonShell.run( + "src/py/script/db_connect_form.py", + options, + (err, results) => { + if (err) { + console.error(err); + res.send("Er is een fout opgetreden"); + } else { + console.log("Python script uitvoering resultaten:", results); + res.send("Formulier succesvol verwerkt"); + } } - }); + ); }); -// Start de server voor verbinding met de database +// Start the server const PORT = 3000; server.listen(PORT, () => { - console.log(`Server luistert op port ${PORT}`); + console.log(`Server is listening on port ${PORT}`); }); -// Maak de Electron applicatie aan met bijbehorende waardes +let mainWindow; + +// Create the Electron application window function createWindow() { - const mainWindow = new BrowserWindow({ + mainWindow = new BrowserWindow({ width: 1280, height: 800, frame: false, + icon: path.join(__dirname, "src/py/static/images/logo.png"), webPreferences: { nodeIntegration: true, - contextIsolation: false - } + contextIsolation: false, + enableRemoteModule: true, + webSecurity: true, + }, }); - mainWindow.loadURL(urlElectron); + mainWindow.loadFile( + path.join(__dirname, "src", "py", "templates", "index.html") + ); + + // IPC event listeners for running Python scripts and updating HTML data + setupIpcMainListeners(); } +// Start the Electron app app.whenReady().then(createWindow); -// Functionaliteit voor het openen en sluiten van de app -app.on('window-all-closed', () => { - if (process.platform !== 'darwin') { +// Close the app when all windows are closed, except on macOS +app.on("window-all-closed", () => { + if (process.platform !== "darwin") { app.quit(); } }); -app.on('activate', () => { +// Re-create a window in the app when the dock icon is clicked and there are no other windows open. +app.on("activate", () => { if (BrowserWindow.getAllWindows().length === 0) { createWindow(); } -}); \ No newline at end of file +}); + +function setupIpcMainListeners() { + ipcMain.on("run-python-script", (event, args) => { + let options = { + mode: "text", + args: args, + }; + + // The actual script path and event replies should be tailored to your application's needs + }); + + ipcMain.on("request-update-data", (event, args) => { + const databaseData = { + timestamp: "2022-01-01", + gateway_receive_time: "2022-01-01", + device: "Device1", + value: 50, + }; + event.reply("update-data-result", { databaseData }); + }); + + ipcMain.on("update-html-data", (event, data) => { + mainWindow.webContents.send("update-html-data", data); + }); +} diff --git a/app.py b/app.py new file mode 100644 index 0000000..e91b0fc --- /dev/null +++ b/app.py @@ -0,0 +1,50 @@ +from flask import Flask, jsonify +import mysql.connector + +app = Flask(__name__) + +# Function to get data from the MySQL database +def get_database_data(): + try: + connection = mysql.connector.connect( + host='localhost', + user='root', + password='', + database='goodgarden' + ) + cursor = connection.cursor() + + # Query to retrieve the latest battery voltage data + query = "SELECT id, timestamp, gateway_receive_time, device, value FROM battery_voltage_events ORDER BY timestamp DESC LIMIT 1" + cursor.execute(query) + battery_data = cursor.fetchone() + + connection.close() + + return battery_data + except Exception as e: + print("Error fetching data from database:", e) + return None + +@app.route('/', methods=['GET']) +def get_data(): + # Get data from the database + battery_data = get_database_data() + + if battery_data is None: + return jsonify({"error": "Failed to fetch data from database"}) + + # Convert the fetched data into a dictionary + data_dict = { + "id": battery_data[0], + "timestamp": str(battery_data[1]), # Convert timestamp to string for JSON serialization + "gateway_receive_time": str(battery_data[2]), # Convert timestamp to string for JSON serialization + "device": battery_data[3], + "value": battery_data[4] + } + + # Return the data as JSON + return jsonify(data_dict) + +if __name__ == "__main__": + app.run(host='127.0.0.1', port=5000) diff --git a/script/battery_voltage_events.py b/battery_voltage_events.py similarity index 54% rename from script/battery_voltage_events.py rename to battery_voltage_events.py index 5c777fe..b0faac6 100644 --- a/script/battery_voltage_events.py +++ b/battery_voltage_events.py @@ -1,190 +1,8 @@ -# import requests #** TYPE IN TERMINAL: "pip install requests" -# import time -# import mysql.connector #** TYPE IN TERMINAL: "pip install mysql-connector-python" - -# # Import python db_connect.py script -# from db_connect import database_connect - -# # Functie voor het aanmaken van gegevens in de database -# def create_data(url, access_token, repeat_count=5): -# for _ in range(repeat_count): -# try: -# headers = { -# "Authorization": f"Token {access_token}" -# } -# response = requests.get(url, headers=headers) -# response.raise_for_status() - -# data = response.json() - -# # print(f"Data from {url}:") -# print(data) -# insert_data(data) - -# except requests.exceptions.RequestException as e: -# print(f"Error fetching data from {url}: {e}") - -# print("Waiting for the next create action...") -# time.sleep(10) -# # time.sleep(300) - -# # Functie voor het invoegen van gegevens in de database -# def insert_data(data): -# mydb = database_connect() -# if mydb.is_connected(): -# mycursor = mydb.cursor() - -# insert_query = """ -# INSERT INTO goodgarden.battery_voltage_events (timestamp, gateway_receive_time, device, value) -# VALUES (%s, %s, %s, %s) -# """ - -# for record in data['results']: # Pas dit aan op basis van de werkelijke structuur van de JSON - -# timestamp = record.get('timestamp', '') -# gateway_receive_time = record.get('gateway_receive_time', '') -# device = record.get('device', '') -# value = record.get('value', '') - -# print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}") - -# # Voer de query uit -# mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value)) - -# # Bevestig de wijzigingen -# mydb.commit() - -# # Sluit cursor en verbinding -# mycursor.close() -# mydb.close() - -# # Functie voor het lezen van gegevens uit de database -# def read_data(url, access_token, repeat_count=5): -# for _ in range(repeat_count): -# try: -# headers = { -# "Authorization": f"Token {access_token}" -# } -# response = requests.get(url, headers=headers) -# response.raise_for_status() - -# data = response.json() -# print(f"Data from {url}:") -# print(data) - -# except requests.exceptions.RequestException as e: -# print(f"Error fetching data from {url}: {e}") - -# # Wacht een bepaalde tijd in secondes -# print("Waiting for the next read action...") -# time.sleep(300) - -# # Functie voor het bijwerken van gegevens in de database -# def update_data(record_id, new_value): -# try: -# mydb = database_connect() - -# if mydb.is_connected(): -# mycursor = mydb.cursor() - -# # Controleer of het record bestaat voordat je het bijwerkt -# mycursor.execute("SELECT * FROM goodgarden.battery_voltage_events WHERE id = %s", (record_id,)) -# existing_record = mycursor.fetchone() - -# if not existing_record: -# print(f"Record with ID {record_id} not found. Update operation aborted.") -# return - -# # Hier moet je de juiste kolomnamen aanpassen op basis van de structuur van je database -# update_query = """ -# UPDATE goodgarden.battery_voltage_events -# SET value = %s -# WHERE id = %s -# """ - -# # Voer de query uit -# print(f"Executing update query: {update_query}") -# print(f"Updating record with ID {record_id} to new value: {new_value}") - -# mycursor.execute(update_query, (new_value, record_id)) # Provide the tuple with values here - -# # Bevestig de wijzigingen -# mydb.commit() - -# print(f"Update executed. Rowcount: {mycursor.rowcount}") - -# except mysql.connector.Error as update_err: -# print(f"Error updating data: {update_err}") -# finally: -# # Zorg ervoor dat je altijd de cursor en de databaseverbinding sluit -# if 'mycursor' in locals() and mycursor is not None: -# mycursor.close() -# if 'mydb' in locals() and mydb.is_connected(): -# mydb.close() - - -# # Functie voor het verwijderen van gegevens uit de database -# def delete_data(record_id): -# mydb = database_connect() -# if mydb.is_connected(): -# mycursor = mydb.cursor() - -# # Hier moet je de juiste kolomnamen aanpassen op basis van de structuur van je database -# delete_query = """ -# DELETE FROM goodgarden.battery_voltage_events -# WHERE id = %s -# """ - -# # Voer de query uit -# mycursor.execute(delete_query, (record_id,)) - -# # Bevestig de wijzigingen -# mydb.commit() - -# # Sluit cursor en verbinding -# mycursor.close() -# mydb.close() - -# print(f"Data with ID {record_id} deleted.") - -# if __name__ == "__main__": -# url = "https://garden.inajar.nl/api/battery_voltage_events/?format=json" -# access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c" - -# repeat_count = 10 - -# operation_choice = input("Choose operation (C for Create, R for Read, U for Update, D for Delete): ").upper() - -# # Maak gegevens aan -# if operation_choice == "C": -# create_data(url, access_token, repeat_count) - -# # Lees gegevens -# elif operation_choice == "R": -# read_data(url, access_token, repeat_count) - -# # Update gegevens -# elif operation_choice == "U": -# record_id = int(input("Enter record ID to update: ")) -# new_value = input("Enter new value: ") -# update_data(record_id, new_value) - -# # Verwijder gegevens -# elif operation_choice == "D": -# record_id = int(input("Enter record ID to delete: ")) -# delete_data(record_id) - -# else: -# print("Invalid operation choice. Please choose C, R, U, or D.") - import mysql.connector import requests from datetime import datetime, timezone, timedelta import time -import os -# import paho.mqtt.client as mqtt -# from dotenv import load_dotenv - + # Functie om verbinding te maken met de database def database_connect(): return mysql.connector.connect( @@ -193,18 +11,17 @@ def database_connect(): password="", database="goodgarden" ) - + def calculate_timestamp(gateway_receive_time): # Converteer de stringrepresentatie naar een datetime-object in UTC datetime_obj_utc = datetime.strptime(gateway_receive_time, "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=timezone.utc) - + # Voeg het tijdsverschil van 1 uur toe voor de Nederlandse tijdzone (UTC+1) - datetime_obj_nl = datetime_obj_utc + timedelta(hours=0) - + datetime_obj_nl = datetime_obj_utc + timedelta(hours=1) + # Formateer het datetime-object als een leesbare datumstring formatted_date = datetime_obj_nl.strftime("%Y-%m-%d %H:%M:%S") return formatted_date - # Functie voor het aanmaken van gegevens in de database def create_data(url, access_token, repeat_count=5): for _ in range(repeat_count): @@ -212,10 +29,10 @@ def create_data(url, access_token, repeat_count=5): headers = {"Authorization": f"Token {access_token}"} response = requests.get(url, headers=headers) response.raise_for_status() - + data = response.json() print(f"Data from {url}:\n") - + # Check if data is a list (records directly under the root) if isinstance(data, list): records = data @@ -224,17 +41,17 @@ def create_data(url, access_token, repeat_count=5): else: print(f"Unexpected data format received: {data}") continue - + for record in records: # Now, record is assumed to be a dictionary timestamp = record.get('timestamp', '') gateway_receive_time = record.get('gateway_receive_time', '') device = record.get('device', '') value = record.get('value', '') - + # Voeg de timestamp-berekening toe calculated_timestamp = calculate_timestamp(gateway_receive_time) - + print(f"\nInserted data: Timestamp: {calculated_timestamp}, Device: {device}, Battery Voltage: {value}V") if float(value) < 3.0: print("Waarschuwing: Batterijspanning is lager dan 3.0 volt. Opladen aanbevolen.\n") @@ -243,47 +60,51 @@ def create_data(url, access_token, repeat_count=5): print("Melding: Batterijspanning is hoger dan 4.2 volt. Batterij is vol.\n") else: print("Melding: Batterijspanning is binnen het gewenste bereik.\n\n") - + # Insert data into the database insert_data(record) - + except requests.exceptions.RequestException as e: print(f"Error fetching data from {url}: {e}") - + print("Waiting for the next create action...\n") time.sleep(2) - -# Functie voor het invoegen van gegevens in de database + def insert_data(record): mydb = database_connect() if mydb.is_connected(): mycursor = mydb.cursor() - + # Hier moet je de juiste kolomnamen en gegevensindeling aanpassen op basis van de API-respons insert_query = """ INSERT INTO goodgarden.battery_voltage_events (timestamp, gateway_receive_time, device, value) VALUES (%s, %s, %s, %s) """ - # Pas dit aan op basis van de werkelijke structuur van de JSON - timestamp = calculate_timestamp(record.get('gateway_receive_time', '')) - gateway_receive_time = record.get('gateway_receive_time', '') - device = record.get('device', '') - value = record.get('value', '') - - print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}\n\n") # Print de ingevoerde gegevens - - # Voer de query uit - mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value)) - - # Bevestig de wijzigingen - mydb.commit() - - # Sluit cursor en verbinding - mycursor.close() - mydb.close() - - print("Data inserted into the database.") - + + try: + # Voer de query uit zonder de timestamp te berekenen + timestamp = record.get('timestamp', '') + gateway_receive_time = record.get('gateway_receive_time', '') + device = record.get('device', '') + value = record.get('value', '') + + print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}\n") # Print de ingevoerde gegevens + + mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value)) + + # Bevestig de wijzigingen + mydb.commit() + + print("Data inserted into the database.") + + except mysql.connector.Error as err: + print(f"Error: {err}") + + finally: + # Sluit cursor en verbinding + mycursor.close() + mydb.close() + # Functie voor het lezen van gegevens uit de database def read_data(url, access_token, repeat_count=5): for _ in range(repeat_count): @@ -291,16 +112,16 @@ def read_data(url, access_token, repeat_count=5): headers = {"Authorization": f"Token {access_token}"} response = requests.get(url, headers=headers) response.raise_for_status() - + data = response.json() print(f"Data from {url}:\n") - + for record in data['results']: timestamp = record.get('timestamp', '') device = record.get('device', '') value = record.get('value', '') print(f"Timestamp: {timestamp}, Device: {device}, Battery Voltage: {value}V\n") - + if float(value) < 3.0: print("Waarschuwing: Batterijspanning is lager dan 3.0 volt. Opladen aanbevolen.\n") # Controleer of de batterijspanning hoger is dan 4.2 volt en geef een melding @@ -308,53 +129,53 @@ def read_data(url, access_token, repeat_count=5): print("Melding: Batterijspanning is hoger dan 4.2 volt. Batterij is vol.\n") else: print("Melding: Batterijspanning is binnen het gewenste bereik.\n\n") - + except requests.exceptions.RequestException as e: print(f"Error fetching data from {url}: {e}") - + print("Waiting for the next read action...\n") time.sleep(300) - + # Functie voor het bijwerken van gegevens in de database def update_data(record_id): try: mydb = database_connect() - + if mydb.is_connected(): mycursor = mydb.cursor() - + # Controleer of het record bestaat voordat je het bijwerkt mycursor.execute("SELECT * FROM goodgarden.battery_voltage_events WHERE id = %s", (record_id,)) existing_record = mycursor.fetchone() - + if not existing_record: print(f"Record with ID {record_id} not found. Update operation aborted.") return - + # Vraag de gebruiker om nieuwe waarden voor de andere velden new_timestamp = input("Enter new timestamp: ") new_gateway_receive_time = input("Enter new gateway_receive_time: ") new_device = input("Enter new device: ") new_value = input("Enter new value: ") - + # Hier moet je de juiste kolomnamen aanpassen op basis van de structuur van je database update_query = """ UPDATE goodgarden.battery_voltage_events SET timestamp = %s, gateway_receive_time = %s, device = %s, value = %s WHERE id = %s """ - + # Voer de query uit print(f"Executing update query: {update_query}") print(f"Updating record with ID {record_id} to new values - timestamp: {new_timestamp}, gateway_receive_time: {new_gateway_receive_time}, device: {new_device}, value: {new_value}") - + mycursor.execute(update_query, (new_timestamp, new_gateway_receive_time, new_device, new_value, record_id)) - + # Bevestig de wijzigingen mydb.commit() - + print(f"Update executed. Rowcount: {mycursor.rowcount}") - + except mysql.connector.Error as update_err: print(f"Error updating data: {update_err}") finally: @@ -363,42 +184,42 @@ def update_data(record_id): mycursor.close() if 'mydb' in locals() and mydb.is_connected(): mydb.close() - + # Functie voor het verwijderen van gegevens uit de database def delete_data(record_id): mydb = database_connect() if mydb.is_connected(): mycursor = mydb.cursor() - + # Hier moet je de juiste kolomnamen aanpassen op basis van de structuur van je database delete_query = """ DELETE FROM goodgarden.battery_voltage_events WHERE id = %s """ - + # Voer de query uit mycursor.execute(delete_query, (record_id,)) - + # Bevestig de wijzigingen mydb.commit() - + # Sluit cursor en verbinding mycursor.close() mydb.close() - + print(f"Data with ID {record_id} deleted.") - + # Functie voor het aanmaken van gegevens in de database op basis van batterijspanningsinformatie if __name__ == "__main__": url = "https://garden.inajar.nl/api/battery_voltage_events/?format=json" access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c" # Vervang dit door je werkelijke toegangstoken - + # Je kunt repeat_count wijzigen om te bepalen hoe vaak je de bewerking wilt herhalen repeat_count = 10 - + # Keuze voor de bewerking operation_choice = input("Choose operation (C for Create, R for Read, U for Update, D for Delete): ").upper() - + if operation_choice == "C": # Maak gegevens aan create_data(url, access_token, repeat_count) @@ -415,4 +236,4 @@ if __name__ == "__main__": record_id = int(input("Enter record ID to delete: ")) delete_data(record_id) else: - print("Invalid operation choice. Please choose C, R, U, or D.") \ No newline at end of file + print("Invalid operation choice. Please choose C, R, U, or D.") diff --git a/goodgarden.sql b/goodgarden.sql new file mode 100644 index 0000000..c0e33a4 --- /dev/null +++ b/goodgarden.sql @@ -0,0 +1,316 @@ +-- phpMyAdmin SQL Dump +-- version 5.2.1 +-- https://www.phpmyadmin.net/ +-- +-- Host: 127.0.0.1 +-- Gegenereerd op: 20 mrt 2024 om 10:19 +-- Serverversie: 10.4.32-MariaDB +-- PHP-versie: 8.2.12 + +DROP DATABASE IF EXISTS goodgarden; +CREATE DATABASE goodgarden; + +USE goodgarden; + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +START TRANSACTION; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; + +-- +-- Database: `goodgarden` +-- + +-- -------------------------------------------------------- + +-- +-- Tabelstructuur voor tabel `battery_voltage_events` +-- + +CREATE TABLE `battery_voltage_events` ( + `id` int(10) UNSIGNED NOT NULL, + `timestamp` int(11) DEFAULT NULL, + `gateway_receive_time` varchar(50) DEFAULT NULL, + `device` int(11) DEFAULT NULL, + `value` decimal(10,5) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Gegevens worden geëxporteerd voor tabel `battery_voltage_events` +-- + +INSERT INTO `battery_voltage_events` (`id`, `timestamp`, `gateway_receive_time`, `device`, `value`) VALUES +(2185, 1710839863, '2024-03-19T09:17:43Z', 256, 4.03663), +(2186, 1710842346, '2024-03-19T09:59:06Z', 322, 4.08547); + +-- -------------------------------------------------------- + +-- +-- Tabelstructuur voor tabel `devices` +-- + +CREATE TABLE `devices` ( + `id` int(10) UNSIGNED NOT NULL, + `serial_number` varchar(255) DEFAULT NULL, + `name` varchar(255) DEFAULT NULL, + `label` varchar(255) DEFAULT NULL, + `last_seen` int(11) DEFAULT NULL, + `last_battery_voltage` float DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- -------------------------------------------------------- + +-- +-- Tabelstructuur voor tabel `fetch` +-- + +CREATE TABLE `fetch` ( + `id` int(10) UNSIGNED NOT NULL, + `timestamp` int(11) DEFAULT NULL, + `gateway_receive_time` varchar(50) DEFAULT NULL, + `device` int(11) DEFAULT NULL, + `value` decimal(10,5) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- -------------------------------------------------------- + +-- +-- Tabelstructuur voor tabel `par_events` +-- + +CREATE TABLE `par_events` ( + `id` int(10) UNSIGNED NOT NULL, + `timestamp` int(11) DEFAULT NULL, + `gateway_receive_time` varchar(50) DEFAULT NULL, + `device` int(11) DEFAULT NULL, + `value` decimal(10,5) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- -------------------------------------------------------- + +-- +-- Tabelstructuur voor tabel `planten` +-- + +CREATE TABLE `planten` ( + `id` int(20) UNSIGNED NOT NULL, + `plant_naam` varchar(255) DEFAULT NULL, + `plantensoort` varchar(255) DEFAULT NULL, + `plant_geteelt` tinyint(1) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Gegevens worden geëxporteerd voor tabel `planten` +-- + +INSERT INTO `planten` (`id`, `plant_naam`, `plantensoort`, `plant_geteelt`) VALUES +(47, 'Tomaten', 'Groente', 1), +(49, 'Komkommer', 'Groente', 1), +(50, 'Appel', 'Fruit', 1), +(51, 'Sla', 'Groente', 1), +(52, 'Wietplant', 'Onkruid', 0); + +-- -------------------------------------------------------- + +-- +-- Tabelstructuur voor tabel `relative_humidity_events` +-- + +CREATE TABLE `relative_humidity_events` ( + `id` int(10) UNSIGNED NOT NULL, + `timestamp` int(11) DEFAULT NULL, + `gateway_receive_time` varchar(50) DEFAULT NULL, + `device` int(11) DEFAULT NULL, + `value` decimal(10,5) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- -------------------------------------------------------- + +-- +-- Tabelstructuur voor tabel `soil_electric_conductivity_events` +-- + +CREATE TABLE `soil_electric_conductivity_events` ( + `id` int(10) UNSIGNED NOT NULL, + `timestamp` int(11) DEFAULT NULL, + `gateway_receive_time` varchar(50) DEFAULT NULL, + `device` int(11) DEFAULT NULL, + `value` decimal(10,5) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- -------------------------------------------------------- + +-- +-- Tabelstructuur voor tabel `soil_relative_permittivity_events` +-- + +CREATE TABLE `soil_relative_permittivity_events` ( + `id` int(10) UNSIGNED NOT NULL, + `timestamp` int(11) DEFAULT NULL, + `gateway_receive_time` varchar(50) DEFAULT NULL, + `device` int(11) DEFAULT NULL, + `value` decimal(10,5) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- -------------------------------------------------------- + +-- +-- Tabelstructuur voor tabel `soil_temperature_events` +-- + +CREATE TABLE `soil_temperature_events` ( + `id` int(10) NOT NULL, + `timestamp` int(11) DEFAULT NULL, + `gateway_receive_time` varchar(50) DEFAULT NULL, + `device` int(11) DEFAULT NULL, + `value` decimal(10,5) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Indexen voor geëxporteerde tabellen +-- + +-- +-- Indexen voor tabel `battery_voltage_events` +-- +ALTER TABLE `battery_voltage_events` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `timestamp` (`timestamp`), + ADD UNIQUE KEY `gateway_receive_time` (`gateway_receive_time`); + +-- +-- Indexen voor tabel `devices` +-- +ALTER TABLE `devices` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `last_seen` (`last_seen`), + ADD UNIQUE KEY `last_battery_voltage` (`last_battery_voltage`); + +-- +-- Indexen voor tabel `fetch` +-- +ALTER TABLE `fetch` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `timestamp` (`timestamp`), + ADD UNIQUE KEY `gateway_receive_time` (`gateway_receive_time`), + ADD UNIQUE KEY `value` (`value`); + +-- +-- Indexen voor tabel `par_events` +-- +ALTER TABLE `par_events` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `timestamp` (`timestamp`), + ADD UNIQUE KEY `gateway_receive_time` (`gateway_receive_time`), + ADD UNIQUE KEY `value` (`value`); + +-- +-- Indexen voor tabel `planten` +-- +ALTER TABLE `planten` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `plant_naam` (`plant_naam`); + +-- +-- Indexen voor tabel `relative_humidity_events` +-- +ALTER TABLE `relative_humidity_events` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `timestamp` (`timestamp`), + ADD UNIQUE KEY `gateway_receive_time` (`gateway_receive_time`), + ADD UNIQUE KEY `value` (`value`); + +-- +-- Indexen voor tabel `soil_electric_conductivity_events` +-- +ALTER TABLE `soil_electric_conductivity_events` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `timestamp` (`timestamp`), + ADD UNIQUE KEY `gateway_receive_time` (`gateway_receive_time`), + ADD UNIQUE KEY `value` (`value`); + +-- +-- Indexen voor tabel `soil_relative_permittivity_events` +-- +ALTER TABLE `soil_relative_permittivity_events` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `timestamp` (`timestamp`), + ADD UNIQUE KEY `gateway_receive_time` (`gateway_receive_time`), + ADD UNIQUE KEY `value` (`value`); + +-- +-- Indexen voor tabel `soil_temperature_events` +-- +ALTER TABLE `soil_temperature_events` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `timestamp` (`timestamp`), + ADD UNIQUE KEY `gateway_receive_time` (`gateway_receive_time`), + ADD UNIQUE KEY `value` (`value`); + +-- +-- AUTO_INCREMENT voor geëxporteerde tabellen +-- + +-- +-- AUTO_INCREMENT voor een tabel `battery_voltage_events` +-- +ALTER TABLE `battery_voltage_events` + MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2189; + +-- +-- AUTO_INCREMENT voor een tabel `devices` +-- +ALTER TABLE `devices` + MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=15; + +-- +-- AUTO_INCREMENT voor een tabel `fetch` +-- +ALTER TABLE `fetch` + MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=100; + +-- +-- AUTO_INCREMENT voor een tabel `par_events` +-- +ALTER TABLE `par_events` + MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=7; + +-- +-- AUTO_INCREMENT voor een tabel `planten` +-- +ALTER TABLE `planten` + MODIFY `id` int(20) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=53; + +-- +-- AUTO_INCREMENT voor een tabel `relative_humidity_events` +-- +ALTER TABLE `relative_humidity_events` + MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=9; + +-- +-- AUTO_INCREMENT voor een tabel `soil_electric_conductivity_events` +-- +ALTER TABLE `soil_electric_conductivity_events` + MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5; + +-- +-- AUTO_INCREMENT voor een tabel `soil_relative_permittivity_events` +-- +ALTER TABLE `soil_relative_permittivity_events` + MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4; + +-- +-- AUTO_INCREMENT voor een tabel `soil_temperature_events` +-- +ALTER TABLE `soil_temperature_events` + MODIFY `id` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=8; +COMMIT; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/mqtt/__pycache__/__init__.cpython-311.pyc b/mqtt/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..96c729c Binary files /dev/null and b/mqtt/__pycache__/__init__.cpython-311.pyc differ diff --git a/mqtt/__pycache__/db_connect.cpython-311.pyc b/mqtt/__pycache__/db_connect.cpython-311.pyc new file mode 100644 index 0000000..d6e3c70 Binary files /dev/null and b/mqtt/__pycache__/db_connect.cpython-311.pyc differ diff --git a/mqtt/__pycache__/mqtt_client.cpython-311.pyc b/mqtt/__pycache__/mqtt_client.cpython-311.pyc new file mode 100644 index 0000000..dae8fac Binary files /dev/null and b/mqtt/__pycache__/mqtt_client.cpython-311.pyc differ diff --git a/mqtt/db_connect.py b/mqtt/db_connect.py new file mode 100644 index 0000000..bc4922c --- /dev/null +++ b/mqtt/db_connect.py @@ -0,0 +1,16 @@ +import mysql.connector +from mysql.connector import Error + +def database_connect(): + try: + connection = mysql.connector.connect( + host="localhost", + user="root", + password="", + database="goodgarden" + ) + if connection.is_connected(): + return connection + except Error as e: + print(f"Connection NIET gelukt! ${e}") + return None \ No newline at end of file diff --git a/mqtt/mqtt_client.py b/mqtt/mqtt_client.py new file mode 100644 index 0000000..35f8402 --- /dev/null +++ b/mqtt/mqtt_client.py @@ -0,0 +1,15 @@ +import paho.mqtt.client as mqtt + +def create_client(client_id, on_connect, on_message, broker="localhost", port=1883): + client = mqtt.Client(client_id) + client.on_connect = on_connect + client.on_message = on_message + + client.connect(broker, port, 60) + return client + +def start_loop(client): + try: + client.loop_forever() + except KeyboardInterrupt: + print("Disconnecting from broker") diff --git a/mqtt/publisher.py b/mqtt/publisher.py new file mode 100644 index 0000000..b6ff42a --- /dev/null +++ b/mqtt/publisher.py @@ -0,0 +1,60 @@ +import requests +import time +import json + +from mqtt_client import create_client, start_loop + +publish_interval = 30 # Secondes om een aanvraag te doen - MOET ~300 ZIJN!!!!!!!!! + +api_endpoints = [ + {"url": "https://garden.inajar.nl/api/devices/", "topic": "goodgarden/devices"}, + {"url": "https://garden.inajar.nl/api/relative_humidity_events/", "topic": "goodgarden/relative_humidity"}, + {"url": "https://garden.inajar.nl/api/battery_voltage_events/", "topic": "goodgarden/battery_voltage"}, + {"url": "https://garden.inajar.nl/api/soil_electric_conductivity_events/", "topic": "goodgarden/soil_electric_conductivity"}, + {"url": "https://garden.inajar.nl/api/soil_relative_permittivity_events/", "topic": "goodgarden/soil_relative_permittivity"}, + {"url": "https://garden.inajar.nl/api/soil_temperature_events/", "topic": "goodgarden/soil_temperature"}, + {"url": "https://garden.inajar.nl/api/par_events/", "topic": "goodgarden/par_events"} +] + +def on_connect(client, userdata, flags, rc): + print("Connected with result code "+str(rc)) + +def on_message(client, userdata, msg): + print(f"Message: {msg.topic} {str(msg.payload)}") + +client = create_client("publisher1", on_connect, on_message) # Gebruik een unieke client ID + +def publish_to_mqtt(topic, data): + + json_data = json.dumps(data) # Serialiseer de data naar een JSON-string + client.publish(topic, json_data) + print(f"\033[92mData published to MQTT topic {topic}.\033[0m") + + +def fetch_and_publish_data(): + + for endpoint in api_endpoints: + url = endpoint["url"] + mqtt_topic = endpoint["topic"] + access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c" + + try: + headers = {"Authorization": f"Token {access_token}"} + response = requests.get(url, headers=headers) + response.raise_for_status() # Zorgt ervoor dat HTTPError wordt opgeworpen voor slechte responses + data = response.json() + print(f"Data from {url}: {data}") + publish_to_mqtt(mqtt_topic, data) + # load_data(data) # Zorg ervoor dat deze functie elders gedefinieerd is + except requests.exceptions.RequestException as e: + print(f"Error fetching data from {url}: {e}") + +if __name__ == "__main__": + client.loop_start() # Start de niet-blokkerende loop + while True: + fetch_and_publish_data() + print(f"\033[91mWachten, wachten en nog eens wachten... {publish_interval} secondes!\033[0m\n") + + + time.sleep(publish_interval) + client.loop_stop() diff --git a/package-lock.json b/package-lock.json index d36888a..e37043a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,13 @@ { "name": "goodgarden", - "version": "1.0.0", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "goodgarden", "license": "ISC", "dependencies": { + "axios": "^1.6.7", "body-parser": "^1.20.2", "elctron": "^0.0.1-security", "express": "^4.18.3", @@ -15,13 +15,64 @@ "python-shell": "^5.0.0" }, "devDependencies": { - "electron": "^23.3.13" + "concurrently": "^8.2.2", + "electron": "^23.3.13", + "npm-run-all": "^4.1.5", + "wait-on": "^7.2.0" + } + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "extraneous": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "extraneous": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "extraneous": true + }, + "express": { + "version": "4.18.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.3.tgz", + "integrity": "sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==", + "extraneous": true + }, + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "extraneous": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/@babel/runtime": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", + "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@electron/get": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.2.tgz", - "integrity": "sha512-eFZVFoRXb3GFGd7Ak7W4+6jBl9wBtiZ4AaYOse97ej6mKj5tkyO0dUnUChs1IhJZtx1BENo4/p4WUTXpi6vT+g==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", + "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", "dev": true, "dependencies": { "debug": "^4.1.1", @@ -39,106 +90,6 @@ "global-agent": "^3.0.0" } }, - "node_modules/@electron/get/node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@electron/get/node_modules/@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dev": true, - "dependencies": { - "defer-to-connect": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@electron/get/node_modules/@types/cacheable-request": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", - "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", - "dev": true, - "dependencies": { - "@types/http-cache-semantics": "*", - "@types/keyv": "^3.1.4", - "@types/node": "*", - "@types/responselike": "^1.0.0" - } - }, - "node_modules/@electron/get/node_modules/@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@electron/get/node_modules/@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@electron/get/node_modules/boolean": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", - "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", - "dev": true, - "optional": true - }, - "node_modules/@electron/get/node_modules/cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "dev": true, - "engines": { - "node": ">=10.6.0" - } - }, - "node_modules/@electron/get/node_modules/cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "dev": true, - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@electron/get/node_modules/clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@electron/get/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -156,506 +107,83 @@ } } }, - "node_modules/@electron/get/node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@electron/get/node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@electron/get/node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@electron/get/node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", - "dev": true, - "optional": true, - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/@electron/get/node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true, - "optional": true - }, - "node_modules/@electron/get/node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/@electron/get/node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@electron/get/node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true, - "optional": true - }, - "node_modules/@electron/get/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "optional": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@electron/get/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/@electron/get/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@electron/get/node_modules/global-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", - "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", - "dev": true, - "optional": true, - "dependencies": { - "boolean": "^3.0.1", - "es6-error": "^4.1.1", - "matcher": "^3.0.0", - "roarr": "^2.15.3", - "semver": "^7.3.2", - "serialize-error": "^7.0.1" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/@electron/get/node_modules/global-agent/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "optional": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@electron/get/node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "optional": true, - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/@electron/get/node_modules/got": { - "version": "11.8.6", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", - "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=10.19.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/@electron/get/node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "node_modules/@electron/get/node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "dev": true - }, - "node_modules/@electron/get/node_modules/http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", - "dev": true, - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/@electron/get/node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/@electron/get/node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "optional": true - }, - "node_modules/@electron/get/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@electron/get/node_modules/keyv": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", - "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/@electron/get/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@electron/get/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@electron/get/node_modules/matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "dev": true, - "optional": true, - "dependencies": { - "escape-string-regexp": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@electron/get/node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/@electron/get/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/@electron/get/node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@electron/get/node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "optional": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/@electron/get/node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/@electron/get/node_modules/p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@electron/get/node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/@electron/get/node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/@electron/get/node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@electron/get/node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", "dev": true }, - "node_modules/@electron/get/node_modules/responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", "dev": true, "dependencies": { - "lowercase-keys": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "@hapi/hoek": "^9.0.0" } }, - "node_modules/@electron/get/node_modules/roarr": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "node_modules/@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", "dev": true, - "optional": true, "dependencies": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" - }, - "engines": { - "node": ">=8.0" + "@hapi/hoek": "^9.0.0" } }, - "node_modules/@electron/get/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@electron/get/node_modules/semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "dev": true, - "optional": true - }, - "node_modules/@electron/get/node_modules/serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "dev": true, - "optional": true, - "dependencies": { - "type-fest": "^0.13.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@electron/get/node_modules/sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true, - "optional": true - }, - "node_modules/@electron/get/node_modules/sumchecker": { + "node_modules/@sideway/formula": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", - "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", - "dev": true, - "dependencies": { - "debug": "^4.1.0" - }, - "engines": { - "node": ">= 8.0" - } + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", + "dev": true }, - "node_modules/@electron/get/node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "dev": true + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "dev": true, - "optional": true, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sindresorhus/is?sponsor=1" } }, - "node_modules/@electron/get/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "dev": true, + "dependencies": { + "defer-to-connect": "^2.0.0" + }, "engines": { - "node": ">= 4.0.0" + "node": ">=10" } }, - "node_modules/@electron/get/node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/@electron/get/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", "dev": true, - "optional": true + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } }, "node_modules/@types/http-cache-semantics": { "version": "4.0.4", @@ -663,11 +191,42 @@ "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", "dev": true }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/node": { - "version": "16.18.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.13.tgz", - "integrity": "sha512-l0/3XZ153UTlNOnZK8xSNoJlQda9/WnYgiTdcKKPJSZjdjI9MU+A9oMXOesAWLSnqAaaJhj3qfQsU07Dr8OUwg==", - "dev": true + "version": "20.11.26", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.26.tgz", + "integrity": "sha512-YwOMmyhNnAWijOBQweOJnQPl068Oqd4K3OFbTc6AHJwzweUwwWG3GIFY74OKks2PJUDkQPeddOQES9mLn1CTEQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } }, "node_modules/accepts": { "version": "1.3.8", @@ -681,11 +240,106 @@ "node": ">= 0.6" } }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "dependencies": { + "follow-redirects": "^1.15.4", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, "node_modules/body-parser": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", @@ -720,6 +374,32 @@ "node": ">=0.10.0" } }, + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "dev": true, + "optional": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -728,6 +408,33 @@ "node": ">= 0.8" } }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -746,6 +453,199 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/concurrently": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz", + "integrity": "sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "date-fns": "^2.30.0", + "lodash": "^4.17.21", + "rxjs": "^7.8.1", + "shell-quote": "^1.8.1", + "spawn-command": "0.0.2", + "supports-color": "^8.1.1", + "tree-kill": "^1.2.2", + "yargs": "^17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": "^14.13.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/concurrently/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/concurrently/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concurrently/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/concurrently/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -778,6 +678,47 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -786,6 +727,42 @@ "ms": "2.0.0" } }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -802,6 +779,31 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/denque": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", @@ -827,6 +829,13 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true, + "optional": true + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -855,6 +864,18 @@ "node": ">= 12.20.55" } }, + "node_modules/electron/node_modules/@types/node": { + "version": "16.18.88", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.88.tgz", + "integrity": "sha512-Za3eRO5y0UWShynpsbNq/Dtqjc+g3GM9/PnrebiWiU4pYa5dOQbpCGuZ7ICqbiZ0JvLaZZ4eq7t5cSts2IEgkg==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -863,6 +884,88 @@ "node": ">= 0.8" } }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.22.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.5.tgz", + "integrity": "sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.1", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.0", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.5", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/es-define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", @@ -882,11 +985,71 @@ "node": ">= 0.4" } }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true, + "optional": true + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -956,25 +1119,6 @@ "@types/yauzl": "^2.9.1" } }, - "node_modules/extract-zip/node_modules/@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", - "dev": true, - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/extract-zip/node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/extract-zip/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -992,84 +1136,19 @@ } } }, - "node_modules/extract-zip/node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/extract-zip/node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/extract-zip/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/extract-zip/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/extract-zip/node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, "dependencies": { - "wrappy": "1" - } - }, - "node_modules/extract-zip/node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true - }, - "node_modules/extract-zip/node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/extract-zip/node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/extract-zip/node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" + "pend": "~1.2.0" } }, "node_modules/finalhandler": { @@ -1089,6 +1168,47 @@ "node": ">= 0.8" } }, + "node_modules/follow-redirects": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -1105,6 +1225,20 @@ "node": ">= 0.6" } }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -1113,6 +1247,33 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/generate-function": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", @@ -1121,6 +1282,15 @@ "is-property": "^1.0.2" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -1139,6 +1309,100 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "dev": true, + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/global-agent/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/global-agent/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "optional": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -1150,6 +1414,55 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/has-property-descriptors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", @@ -1162,9 +1475,9 @@ } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "engines": { "node": ">= 0.4" }, @@ -1183,6 +1496,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hasown": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", @@ -1194,6 +1522,18 @@ "node": ">= 0.4" } }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -1209,6 +1549,19 @@ "node": ">= 0.8" } }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -1225,6 +1578,20 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -1233,16 +1600,321 @@ "node": ">= 0.10" } }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-property": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/joi": { + "version": "17.12.2", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.2.tgz", + "integrity": "sha512-RonXAIzCiHLc8ss3Ibuz45u28GOsWE1UpfDXLbN/9NKbL4tCJf8TWYVKsoYuuh+sAUt7fsSNpA+r2+TBA6Wjmw==", + "dev": true, + "dependencies": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "optional": true + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, "node_modules/long": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/lru-cache": { "version": "8.0.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", @@ -1251,6 +1923,19 @@ "node": ">=16.14" } }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "optional": true, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -1259,6 +1944,15 @@ "node": ">= 0.6" } }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -1302,6 +1996,36 @@ "node": ">= 0.6" } }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -1352,6 +2076,70 @@ "node": ">= 0.6" } }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" + }, + "engines": { + "node": ">= 4" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -1360,6 +2148,33 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -1371,6 +2186,37 @@ "node": ">= 0.8" } }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -1379,11 +2225,83 @@ "node": ">= 0.8" } }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, + "node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "node_modules/pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -1396,6 +2314,21 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/python-shell": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/python-shell/-/python-shell-5.0.0.tgz", @@ -1418,6 +2351,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -1451,6 +2396,133 @@ "node": ">=0.10.0" } }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true + }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "dev": true, + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -1470,11 +2542,44 @@ } ] }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true, + "optional": true + }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -1508,6 +2613,22 @@ "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dev": true, + "optional": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", @@ -1538,11 +2659,56 @@ "node": ">= 0.4" } }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/side-channel": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", @@ -1560,6 +2726,51 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/spawn-command": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", + "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", + "dev": true + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", + "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true, + "optional": true + }, "node_modules/sqlstring": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", @@ -1576,6 +2787,162 @@ "node": ">= 0.8" } }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.padend": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.5.tgz", + "integrity": "sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/sumchecker": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", + "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", + "dev": true, + "dependencies": { + "debug": "^4.1.0" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/sumchecker/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/sumchecker/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -1584,6 +2951,34 @@ "node": ">=0.6" } }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -1596,6 +2991,109 @@ "node": ">= 0.6" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", + "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -1612,6 +3110,16 @@ "node": ">= 0.4.0" } }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -1619,1220 +3127,181 @@ "engines": { "node": ">= 0.8" } - } - }, - "dependencies": { - "@electron/get": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.2.tgz", - "integrity": "sha512-eFZVFoRXb3GFGd7Ak7W4+6jBl9wBtiZ4AaYOse97ej6mKj5tkyO0dUnUChs1IhJZtx1BENo4/p4WUTXpi6vT+g==", + }, + "node_modules/wait-on": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-7.2.0.tgz", + "integrity": "sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==", "dev": true, - "requires": { - "debug": "^4.1.1", - "env-paths": "^2.2.0", - "fs-extra": "^8.1.0", - "global-agent": "^3.0.0", - "got": "^11.8.5", - "progress": "^2.0.3", - "semver": "^6.2.0", - "sumchecker": "^3.0.1" - }, "dependencies": { - "@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "dev": true - }, - "@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dev": true, - "requires": { - "defer-to-connect": "^2.0.0" - } - }, - "@types/cacheable-request": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", - "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", - "dev": true, - "requires": { - "@types/http-cache-semantics": "*", - "@types/keyv": "^3.1.4", - "@types/node": "*", - "@types/responselike": "^1.0.0" - } - }, - "@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "boolean": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", - "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", - "dev": true, - "optional": true - }, - "cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "dev": true - }, - "cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - } - }, - "clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "requires": { - "mimic-response": "^3.1.0" - }, - "dependencies": { - "mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true - } - } - }, - "defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true - }, - "define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", - "dev": true, - "optional": true, - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true, - "optional": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true - }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true, - "optional": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "optional": true - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "global-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", - "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", - "dev": true, - "optional": true, - "requires": { - "boolean": "^3.0.1", - "es6-error": "^4.1.1", - "matcher": "^3.0.0", - "roarr": "^2.15.3", - "semver": "^7.3.2", - "serialize-error": "^7.0.1" - }, - "dependencies": { - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "optional": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "optional": true, - "requires": { - "define-properties": "^1.1.3" - } - }, - "got": { - "version": "11.8.6", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", - "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", - "dev": true, - "requires": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - } - }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "dev": true - }, - "http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", - "dev": true, - "requires": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - } - }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "optional": true - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "keyv": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", - "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", - "dev": true, - "requires": { - "json-buffer": "3.0.1" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "optional": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "dev": true, - "optional": true, - "requires": { - "escape-string-regexp": "^4.0.0" - } - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "dev": true - }, - "resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "dev": true - }, - "responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "dev": true, - "requires": { - "lowercase-keys": "^2.0.0" - } - }, - "roarr": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", - "dev": true, - "optional": true, - "requires": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "dev": true, - "optional": true - }, - "serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "dev": true, - "optional": true, - "requires": { - "type-fest": "^0.13.1" - } - }, - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true, - "optional": true - }, - "sumchecker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", - "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", - "dev": true, - "requires": { - "debug": "^4.1.0" - } - }, - "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true, - "optional": true - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "optional": true - } - } - }, - "@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", - "dev": true - }, - "@types/node": { - "version": "16.18.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.13.tgz", - "integrity": "sha512-l0/3XZ153UTlNOnZK8xSNoJlQda9/WnYgiTdcKKPJSZjdjI9MU+A9oMXOesAWLSnqAaaJhj3qfQsU07Dr8OUwg==", - "dev": true - }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" + "axios": "^1.6.1", + "joi": "^17.11.0", + "lodash": "^4.17.21", + "minimist": "^1.2.8", + "rxjs": "^7.8.1" }, - "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } + "bin": { + "wait-on": "bin/wait-on" + }, + "engines": { + "node": ">=12.0.0" } }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "requires": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - } - }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "requires": { - "safe-buffer": "5.2.1" - } - }, - "content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" - }, - "cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "requires": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - } - }, - "denque": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", - "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==" - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "elctron": { - "version": "0.0.1-security", - "resolved": "https://registry.npmjs.org/elctron/-/elctron-0.0.1-security.tgz", - "integrity": "sha512-7Wuk6B1NYD7yhzVsPAnXtVdw3LpZFiAteoVsNthzu8cfht+tts6aM3IenqpAbEIomABBFNDkUfCaZYR9z4PyEg==" - }, - "electron": { - "version": "23.3.13", - "resolved": "https://registry.npmjs.org/electron/-/electron-23.3.13.tgz", - "integrity": "sha512-BaXtHEb+KYKLouUXlUVDa/lj9pj4F5kiE0kwFdJV84Y2EU7euIDgPthfKtchhr5MVHmjtavRMIV/zAwEiSQ9rQ==", + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, - "requires": { - "@electron/get": "^2.0.0", - "@types/node": "^16.11.26", - "extract-zip": "^2.0.1" + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" } }, - "encodeurl": { + "node_modules/which-boxed-primitive": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" - }, - "es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "requires": { - "get-intrinsic": "^1.2.4" - } - }, - "es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" - }, - "express": { - "version": "4.18.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.3.tgz", - "integrity": "sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==", - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - } - }, - "extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, - "requires": { - "@types/yauzl": "^2.9.1", - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, "dependencies": { - "@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", - "dev": true, - "optional": true, - "requires": { - "@types/node": "*" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - } - } - }, - "finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - } - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" - }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" - }, - "generate-function": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", - "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", - "requires": { - "is-property": "^1.0.2" - } - }, - "get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "requires": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - } - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "requires": { - "es-define-property": "^1.0.0" - } - }, - "has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "hasown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", - "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", - "requires": { - "function-bind": "^1.1.2" - } - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" - }, - "long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" - }, - "lru-cache": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", - "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==" - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "mysql2": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.1.tgz", - "integrity": "sha512-3njoWAAhGBYy0tWBabqUQcLtczZUxrmmtc2vszQUekg3kTJyZ5/IeLC3Fo04u6y6Iy5Sba7pIIa2P/gs8D3ZeQ==", - "requires": { - "denque": "^2.1.0", - "generate-function": "^2.3.1", - "iconv-lite": "^0.6.3", - "long": "^5.2.1", - "lru-cache": "^8.0.0", - "named-placeholders": "^1.1.3", - "seq-queue": "^0.0.5", - "sqlstring": "^2.3.2" - } - }, - "named-placeholders": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz", - "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==", - "requires": { - "lru-cache": "^7.14.1" + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, "dependencies": { - "lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" - } - } - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" - }, - "object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==" - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - } - }, - "python-shell": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/python-shell/-/python-shell-5.0.0.tgz", - "integrity": "sha512-RUOOOjHLhgR1MIQrCtnEqz/HJ1RMZBIN+REnpSUrfft2bXqXy69fwJASVziWExfFXsR1bCY0TznnHooNsCo0/w==" - }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "requires": { - "side-channel": "^1.0.4" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "dependencies": { - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "seq-queue": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", - "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" - }, - "serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - } - }, - "set-function-length": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", - "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", - "requires": { - "define-data-property": "^1.1.2", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "side-channel": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", - "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", - "requires": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "sqlstring": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", - "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==" + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "statuses": { + "node_modules/wrap-ansi/node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "optional": true + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } } } } diff --git a/package.json b/package.json index 900b13d..78a1d37 100644 --- a/package.json +++ b/package.json @@ -3,15 +3,20 @@ "description": "", "main": "app.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "start": "electron app.js" + "start": "npm-run-all --parallel start-flask start-electron", + "start-electron": "wait-on http://localhost:5000 && electron app.js", + "start-flask": "python app.py" }, "author": "", "license": "ISC", "devDependencies": { - "electron": "^23.3.13" + "concurrently": "^8.2.2", + "electron": "^23.3.13", + "npm-run-all": "^4.1.5", + "wait-on": "^7.2.0" }, "dependencies": { + "axios": "^1.6.7", "body-parser": "^1.20.2", "elctron": "^0.0.1-security", "express": "^4.18.3", diff --git a/plants.json b/plants.json new file mode 100644 index 0000000..d5d1df0 --- /dev/null +++ b/plants.json @@ -0,0 +1,32 @@ +[ + { + "id": 47, + "plant_naam": "Tomaten", + "plantensoort": "Groente", + "plant_geteelt": 1 + }, + { + "id": 49, + "plant_naam": "Komkommer", + "plantensoort": "Groente", + "plant_geteelt": 1 + }, + { + "id": 50, + "plant_naam": "Appel", + "plantensoort": "Fruit", + "plant_geteelt": 1 + }, + { + "id": 51, + "plant_naam": "Sla", + "plantensoort": "Groente", + "plant_geteelt": 1 + }, + { + "id": 52, + "plant_naam": "Wietplant", + "plantensoort": "Onkruid", + "plant_geteelt": 0 + } +] \ No newline at end of file diff --git a/script/devices.py b/script/devices.py deleted file mode 100644 index 3825589..0000000 --- a/script/devices.py +++ /dev/null @@ -1,71 +0,0 @@ -import requests -import time - -from db_connect import database_connect - -def fetch_and_display_all(url, access_token, repeat_count=5): - for _ in range(repeat_count): - try: - headers = { - "Authorization": f"Token {access_token}" - } - response = requests.get(url, headers=headers) - response.raise_for_status() - - data = response.json() - print(f"Data from {url}:") - print(data) - load_data(data) - - except requests.exceptions.RequestException as e: - print(f"Error fetching data from {url}: {e}") - - print("Waiting for the next retrieval action...") - - # time.sleep(300) # Time here is in seconds. - - time.sleep(1) # Time here is in seconds. - -def load_data(data): - mydb = database_connect() - if mydb.is_connected(): - mycursor = mydb.cursor() - - # Here you need to adjust the correct column names and data formats based on the API response - insert_query = """ - INSERT INTO goodgarden.devices (serial_number, name, label, last_seen, last_battery_voltage) - VALUES (%s, %s, %s, %s, %s ) - """ - for record in data['results']: - serial_number = record.get('serial_number', '') - name = record.get('name', '') - label = record.get('label', '') - last_seen = record.get('last_seen', '') - last_battery_voltage = record.get('last_battery_voltage', '') - - print(f"Inserting data: serial_number={serial_number}, name={name}, label={label}, last_seen={last_seen}, last_battery_voltage={last_battery_voltage}") - - # Execute the query - mycursor.execute(insert_query, (serial_number, name, label, last_seen, last_battery_voltage)) - - # Commit the changes - mydb.commit() - - # Close cursor and connection - mycursor.close() - mydb.close() - - print("Data inserted into the database.") - -if __name__ == "__main__": - url = "https://garden.inajar.nl/api/devices/?format=json" - access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c" # Replace this with your actual access token - - - # access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c" - - # You can change the repeat_count to control how many times you want to repeat the process - repeat_count = 10 - - - fetch_and_display_all(url, access_token, repeat_count) diff --git a/script/fetch.py b/script/fetch.py deleted file mode 100644 index f7f707f..0000000 --- a/script/fetch.py +++ /dev/null @@ -1,73 +0,0 @@ -import requests -import time - -from db_connect import database_connect - -# Establish a database connection -connection = database_connect() - -def fetch_and_display_all(urls, access_token): - for url in urls: - try: - headers = { - "Authorization": f"Token {access_token}" - } - response = requests.get(url, headers=headers) - response.raise_for_status() - - data = response.json() - print(f"Data from {url}:") - print(data) - load_data(data) - - except requests.exceptions.RequestException as e: - print(f"Error fetching data from {url}: {e}") - - # Wait for a certain time (e.g., 60 seconds) before making the next call - print("Waiting for the next retrieval action...") - time.sleep(10) # Time here is in seconds. - -def load_data(data): - mydb = database_connect() - if mydb.is_connected(): - mycursor = mydb.cursor() - - # Here you need to adjust the correct column names and data formats based on the API response - insert_query = """ - INSERT INTO goodgarden.fetch (timestamp, gateway_receive_time, device, value) - VALUES (%s, %s, %s, %s) - """ - for record in data['results']: # Adjust this based on the actual structure of the JSON - timestamp = record.get('timestamp', '') - gateway_receive_time = record.get('gateway_receive_time', '') - device = record.get('device', '') - value = record.get('value', '') - - print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}") # Print the data being inserted - - # Execute the query - mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value)) - - # Commit the changes - mydb.commit() - - # Close cursor and connection - mycursor.close() - mydb.close() - - print("Data inserted into the database.") - -if __name__ == "__main__": - urls = [ - "https://garden.inajar.nl/api/battery_voltage_events/?format=json", - "https://garden.inajar.nl/api/devices/?format=json", - "https://garden.inajar.nl/api/par_events/?format=json", - "https://garden.inajar.nl/api/relative_humidity_events/?format=json", - "https://garden.inajar.nl/api/soil_electric_conductivity_events/?format=json", - "https://garden.inajar.nl/api/soil_relative_permittivity_events/?format=json", - "https://garden.inajar.nl/api/soil_temperature_events/?format=json" - ] - - access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c" # Vervang dit met jouw echte toegangstoken - - fetch_and_display_all(urls, access_token) diff --git a/script/fetch_data.py b/script/fetch_data.py deleted file mode 100644 index 72964ce..0000000 --- a/script/fetch_data.py +++ /dev/null @@ -1,57 +0,0 @@ -import requests -import time - -from db_connect import database_connect - -def fetch_battery_voltage_events(): - url = "https://garden.inajar.nl/api/battery_voltage_events/?format=json" - headers = { - "Authorization": "Token 33bb3b42452306c58ecedc3c86cfae28ba22329c" - } - - while True: - try: - response = requests.get(url, headers=headers) - response.raise_for_status() - - data = response.json() - load_data(data) - - print("Wachten voor de volgende ophaalactie...") - time.sleep(300) # De tijd hier is in seconden. - - except requests.exceptions.RequestException as e: - print(f"Error fetching data: {e}") - # Wacht ook hier bij een fout, om niet in een snelle foutloop te komen - time.sleep(300) - -def load_data(data): - mydb = database_connect() - if mydb.is_connected(): - mycursor = mydb.cursor() - - # Hier moet je de juiste kolomnamen en dataformaten aanpassen op basis van de API-respons - insert_query = """ - INSERT INTO goodgarden.battery_voltage_events (timestamp, gateway_receive_time, device, value) - VALUES (%s, %s, %s, %s) - """ - for record in data['results']: - timestamp = record['timestamp'] - gateway_receive_time = record['gateway_receive_time'] - device = record['device'] - value = record['value'] - - # print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}") - mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value)) - - # Commit de wijzigingen - mydb.commit() - - # Sluit cursor en verbinding - mycursor.close() - mydb.close() - - print("Data ingevoegd in de database.") - -if __name__ == "__main__": - fetch_battery_voltage_events() \ No newline at end of file diff --git a/script/par_events.py b/script/par_events.py deleted file mode 100644 index 8246737..0000000 --- a/script/par_events.py +++ /dev/null @@ -1,64 +0,0 @@ -import requests -import time - -from db_connect import database_connect - -def fetch_and_display_all(url, access_token, repeat_count=5): - for _ in range(repeat_count): - try: - headers = { - "Authorization": f"Token {access_token}" - } - response = requests.get(url, headers=headers) - response.raise_for_status() - - data = response.json() - print(f"Data from {url}:") - print(data) - load_data(data) - - except requests.exceptions.RequestException as e: - print(f"Error fetching data from {url}: {e}") - - print("Waiting for the next retrieval action...") - - time.sleep(1) # Time here is in seconds. - - -def load_data(data): - mydb = database_connect() - if mydb.is_connected(): - mycursor = mydb.cursor() - - # Here you need to adjust the correct column names and data formats based on the API response - insert_query = """ - INSERT INTO goodgarden.par_events (timestamp, gateway_receive_time, device, value) - VALUES (%s, %s, %s, %s) - """ - for record in data['results']: - timestamp = record.get('timestamp', '') - gateway_receive_time = record.get('gateway_receive_time', '') - device = record.get('device', '') - value = record.get('value', '') - - print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}") - - # Execute the query - mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value)) - - # Commit the changes - mydb.commit() - - # Close cursor and connection - mycursor.close() - mydb.close() - - print("Data inserted into the database.") - -if __name__ == "__main__": - url = "https://garden.inajar.nl/api/par_events/?format=json" - access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c" - # You can change the repeat_count to control how many times you want to repeat the process - repeat_count = 10 - - fetch_and_display_all(url, access_token, repeat_count) \ No newline at end of file diff --git a/script/relative_humidity_events.py b/script/relative_humidity_events.py deleted file mode 100644 index 6961094..0000000 --- a/script/relative_humidity_events.py +++ /dev/null @@ -1,64 +0,0 @@ -import requests -import time - -from db_connect import database_connect - -def fetch_and_display_all(url, access_token, repeat_count=5): - for _ in range(repeat_count): - try: - headers = { - "Authorization": f"Token {access_token}" - } - response = requests.get(url, headers=headers) - response.raise_for_status() - - data = response.json() - print(f"Data from {url}:") - print(data) - load_data(data) - - except requests.exceptions.RequestException as e: - print(f"Error fetching data from {url}: {e}") - - print("Waiting for the next retrieval action...") - - time.sleep(1) # Time here is in seconds. - -def load_data(data): - mydb = database_connect() - if mydb.is_connected(): - mycursor = mydb.cursor() - - # Here you need to adjust the correct column names and data formats based on the API response - insert_query = """ - INSERT INTO goodgarden.relative_humidity_events (timestamp, gateway_receive_time, device, value) - VALUES (%s, %s, %s, %s) - """ - for record in data['results']: - timestamp = record.get('timestamp', '') - gateway_receive_time = record.get('gateway_receive_time', '') - device = record.get('device', '') - value = record.get('value', '') - - print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}") - - # Execute the query - mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value)) - - # Commit the changes - mydb.commit() - - # Close cursor and connection - mycursor.close() - mydb.close() - - print("Data inserted into the database.") - -if __name__ == "__main__": - url = "https://garden.inajar.nl/api/relative_humidity_events/?format=json" - access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c" - - # You can change the repeat_count to control how many times you want to repeat the process - repeat_count = 10 - - fetch_and_display_all(url, access_token, repeat_count) \ No newline at end of file diff --git a/script/soil_electric_conductivity_events.py b/script/soil_electric_conductivity_events.py deleted file mode 100644 index d9a598a..0000000 --- a/script/soil_electric_conductivity_events.py +++ /dev/null @@ -1,63 +0,0 @@ -import requests -import time - -from db_connect import database_connect - -def fetch_and_display_all(url, access_token, repeat_count=5): - for _ in range(repeat_count): - try: - headers = { - "Authorization": f"Token {access_token}" - } - response = requests.get(url, headers=headers) - response.raise_for_status() - - data = response.json() - print(f"Data from {url}:") - print(data) - load_data(data) - - except requests.exceptions.RequestException as e: - print(f"Error fetching data from {url}: {e}") - - print("Waiting for the next retrieval action...") - - time.sleep(1) # Time here is in seconds. - -def load_data(data): - mydb = database_connect() - if mydb.is_connected(): - mycursor = mydb.cursor() - - # Here you need to adjust the correct column names and data formats based on the API response - insert_query = """ - INSERT INTO goodgarden.soil_electric_conductivity_events (timestamp, gateway_receive_time, device, value) - VALUES (%s, %s, %s, %s) - """ - for record in data['results']: - timestamp = record.get('timestamp', '') - gateway_receive_time = record.get('gateway_receive_time', '') - device = record.get('device', '') - value = record.get('value', '') - - print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}") - - # Execute the query - mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value)) - - # Commit the changes - mydb.commit() - - # Close cursor and connection - mycursor.close() - mydb.close() - - print("Data inserted into the database.") -if __name__ == "__main__": - url = "https://garden.inajar.nl/api/soil_electric_conductivity_events/?format=json" - access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c" # Replace this with your actual access token - - # You can change the repeat_count to control how many times you want to repeat the process - repeat_count = 10 - - fetch_and_display_all(url, access_token, repeat_count) \ No newline at end of file diff --git a/script/soil_relative_permittivity_events.py b/script/soil_relative_permittivity_events.py deleted file mode 100644 index 62b3483..0000000 --- a/script/soil_relative_permittivity_events.py +++ /dev/null @@ -1,66 +0,0 @@ -import requests -import time - -from db_connect import database_connect - -def fetch_and_display_all(url, access_token, repeat_count=5): - for _ in range(repeat_count): - try: - headers = { - "Authorization": f"Token {access_token}" - } - response = requests.get(url, headers=headers) - response.raise_for_status() - - data = response.json() - print(f"Data from {url}:") - print(data) - load_data(data) - - except requests.exceptions.RequestException as e: - print(f"Error fetching data from {url}: {e}") - - print("Waiting for the next retrieval action...") - - time.sleep(1) # Time here is in seconds. - - -def load_data(data): - mydb = database_connect() - if mydb.is_connected(): - mycursor = mydb.cursor() - - # Here you need to adjust the correct column names and data formats based on the API response - insert_query = """ - INSERT INTO goodgarden.soil_temperature_events (timestamp, gateway_receive_time, device, value) - VALUES (%s, %s, %s, %s) - """ - for record in data['results']: - timestamp = record.get('timestamp', '') - gateway_receive_time = record.get('gateway_receive_time', '') - device = record.get('device', '') - value = record.get('value', '') - - print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}") - - # Execute the query - mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value)) - - # Commit the changes - mydb.commit() - - # Close cursor and connection - mycursor.close() - mydb.close() - - print("Data inserted into the database.") - -if __name__ == "__main__": - url = "https://garden.inajar.nl/api/soil_relative_permittivity_events/?format=json" - access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c" - # You can change the repeat_count to control how many times you want to repeat the process - repeat_count = 10 - - # fetch_and_display_all(urls, access_token) - - fetch_and_display_all(url, access_token, repeat_count) \ No newline at end of file diff --git a/script/soil_temperature_events.py b/script/soil_temperature_events.py deleted file mode 100644 index 2cd9750..0000000 --- a/script/soil_temperature_events.py +++ /dev/null @@ -1,65 +0,0 @@ -import requests -import time - - -from db_connect import database_connect - -def fetch_and_display_all(url, access_token, repeat_count=5): - for _ in range(repeat_count): - - try: - headers = { - "Authorization": f"Token {access_token}" - } - response = requests.get(url, headers=headers) - response.raise_for_status() - - data = response.json() - print(f"Data from {url}:") - print(data) - load_data(data) - - except requests.exceptions.RequestException as e: - print(f"Error fetching data from {url}: {e}") - - print("Waiting for the next retrieval action...") - - time.sleep(1) # Time here is in seconds. - -def load_data(data): - mydb = database_connect() - if mydb.is_connected(): - mycursor = mydb.cursor() - - # Here you need to adjust the correct column names and data formats based on the API response - insert_query = """ - INSERT INTO goodgarden.soil_temperature_events (timestamp, gateway_receive_time, device, value) - VALUES (%s, %s, %s, %s) - """ - for record in data['results']: - timestamp = record.get('timestamp', '') - gateway_receive_time = record.get('gateway_receive_time', '') - device = record.get('device', '') - value = record.get('value', '') - - print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}") - - # Execute the query - mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value)) - - # Commit the changes - mydb.commit() - - # Close cursor and connection - mycursor.close() - mydb.close() - - print("Data inserted into the database.") -if __name__ == "__main__": - url = "https://garden.inajar.nl/api/soil_temperature_events/?format=json" - access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c" # Replace this with your actual access token - - # You can change the repeat_count to control how many times you want to repeat the process - repeat_count = 10 - - fetch_and_display_all(url, access_token, repeat_count) \ No newline at end of file diff --git a/src/css/style.css b/src/css/style.css index 158a644..0668a0e 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -1,32 +1,26 @@ @import url("https://fonts.googleapis.com/css2?family=Akaya+Kanadaka&display=swap"); @import url("https://fonts.googleapis.com/css2?family=Afacad:ital,wght@0,400..700;1,400..700&display=swap"); -h1, h2, h3, h4, h5 { +h1, +h2, +h3, +h4, +h5 { font-family: "Akaya Kanadaka", system-ui; margin: 0; } -p, td { +p, +td { font-family: "Afacad", sans-serif; + color: black; } -.containers-articles, body .mainContainer .mainBorder .content .kant-rechts #sensor-2, body .mainContainer .mainBorder .content .kant-links #sensor-1, body .mainContainer .mainBorder .content .kant-links #planten td article { - height: 7rem; - width: 10rem; - padding: 0.6rem; - margin: 0.1rem; - margin-left: 2rem; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - border: solid 3px rgb(171, 211, 174); - border-radius: 40px; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); - background-color: white; +a { + text-decoration: none; } body { - background-image: url("../images/achtergrond.png"); + background: linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5)), url("../images/achtergrond.png"); background-repeat: no-repeat; background-size: cover; background-position: center; @@ -40,7 +34,7 @@ body { body .mainContainer { width: 85vw; height: 38rem; - background-color: rgba(255, 255, 255, 0.95); + background-color: rgba(255, 255, 255, 0.85); border-radius: 40px; padding: 2rem; } @@ -81,6 +75,7 @@ body .mainContainer .mainBorder #sectie-1 .parent-algemeen-overzicht { border-radius: 40px; padding: 1rem; margin-top: 1rem; + background-color: white; } body .mainContainer .mainBorder #sectie-1 .parent-algemeen-overzicht .algemeen-overzicht { border: solid 2px rgb(171, 211, 174); @@ -101,6 +96,7 @@ body .mainContainer .mainBorder #sectie-1 .grafiek { border-radius: 40px; padding: 1rem; position: relative; + background-color: white; } body .mainContainer .mainBorder #sectie-1 .grafiek .grafiek-innerbox { border: solid 2px rgb(171, 211, 174); @@ -133,6 +129,20 @@ body .mainContainer .mainBorder .content .kant-links #planten { width: 100%; border-collapse: collapse; } +body .mainContainer .mainBorder .content .kant-links #planten td article { + height: 7rem; + width: 10rem; + padding: 0.6rem; + margin: 0.1rem; + margin-left: 2rem; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + border: solid 3px rgb(171, 211, 174); + border-radius: 40px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); +} body .mainContainer .mainBorder .content .kant-links #planten td article #toevoegen { height: 5rem; width: 5rem; @@ -143,15 +153,8 @@ body .mainContainer .mainBorder .content .kant-links #planten td article h2 { body .mainContainer .mainBorder .content .kant-links #planten td article:hover { background-color: lightgray; } -body .mainContainer .mainBorder .content .kant-links #sensor-1 { - border: none; - border-radius: 40px 0px 0px 40px; - width: 30vw; - margin-top: 10vh; -} body .mainContainer .mainBorder .content .kant-rechts { grid-column: 3; - margin-right: 2rem; } body .mainContainer .mainBorder .content .kant-rechts #metingen { border: solid 3px rgb(171, 211, 174); @@ -169,16 +172,12 @@ body .mainContainer .mainBorder .content .kant-rechts #metingen #main-waardes ta justify-content: space-between; width: 100%; } -body .mainContainer .mainBorder .content .kant-rechts #sensor-2 { - border-radius: 0px 40px 40px 0px; - width: 30vw; - margin-top: 10vh; -} body .mainContainer .mainBorder .grid-column-2 { box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5); border-radius: 40px; padding: 1rem; margin: 3.25rem 1rem 1.25rem 1rem; + background-color: white; } body .mainContainer .mainBorder .grid-column-2 .grid-2-child { border: solid 2px rgb(171, 211, 174); @@ -189,9 +188,17 @@ body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table { padding: 1.5rem 2rem; display: flex; flex-direction: column; + align-items: stretch; + gap: 2.5rem; justify-content: space-around; height: 90%; } +body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table table tr td { + font-size: 1.05rem; +} +body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas-table-1 tr td { + font-size: 1.25rem; +} body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas-table-2 { position: relative; } @@ -211,7 +218,6 @@ body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas- top: -20px; } -/* Divider */ .divider { display: flex; justify-content: center; @@ -221,7 +227,6 @@ body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas- margin: 0 auto; } -/* The Modal (background) */ .modal { display: none; position: fixed; @@ -234,17 +239,168 @@ body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); width: 30vw; height: auto; - border: solid 2px black; + border: solid 2px #abd3ae; border-radius: 10px; } + .modal .close { color: #aaa; float: right; font-size: 1.75rem; font-weight: bold; } -.modal .close:hover, .modal .close:active { + +.modal .close:hover, +.modal .close:active { color: black; text-decoration: none; cursor: pointer; +} + +#myModal select, +#myModal input { + width: calc(100% - 20px); + padding: 10px; + margin-bottom: 15px; + border: 2px solid #abd3ae; + border-radius: 5px; + box-sizing: border-box; +} + +#myModal .knop { + display: flex; + justify-content: space-between; +} + +#myModal button { + width: 48%; + padding: 10px; + box-sizing: border-box; + height: 40px; +} + +#myModal .knop-container { + display: flex; + justify-content: space-between; + margin-top: 20px; +} + +#myModal .knop-container input, +#myModal .knop-container button { + flex: 1; + margin: 0 5px; + padding: 10px; + box-sizing: border-box; +} + +#myModal input[type=text], +#myModal select { + border: 2px solid #abd3ae; + padding: 10px; + border-radius: 17px; + box-sizing: border-box; +} + +#myModal input[type=submit], +#myModal button { + color: #fff; + border: none; + border-radius: 15px; + cursor: pointer; +} + +#myModal input[type=submit] { + background-color: white; +} + +#myModal button { + background-color: white; + color: black; +} + +.toevoeging { + background: linear-gradient(45deg, #abd3ae, #2ecc71); +} + +.annulatie-knop { + background: linear-gradient(45deg, #ffcc00, #ff6600); +} + +#myModal button:hover { + background: linear-gradient(45deg, #abd3ae, #fff); + color: #000; +} + +.modal .close { + color: #aaa; + float: right; + font-size: 1.75rem; + font-weight: bold; +} + +.modal .close:hover, +.modal .close:active { + color: black; + text-decoration: none; + cursor: pointer; +} + +.switch-container { + display: flex; + align-items: end; +} + +.switch { + position: relative; + display: inline-block; + width: 60px; + height: 30px; +} + +.switch input { + opacity: 0; + width: 0; + height: 0; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + border-radius: 34px; + transition: 0.4s; +} + +.slider:before { + position: absolute; + content: ""; + height: 26px; + width: 26px; + left: 4px; + bottom: 4px; + background-color: white; + border-radius: 50%; + transition: 0.4s; +} + +input:checked + .slider { + background-color: #2ecc71; +} + +input:checked + .slider:before { + transform: translateX(26px); +} + +.rechterkant { + display: flex; + justify-content: end; +} + +.plant-container, +#modalButton { + background-color: white; }/*# sourceMappingURL=style.css.map */ \ No newline at end of file diff --git a/src/css/style.css.map b/src/css/style.css.map index 17d7627..90630c9 100644 --- a/src/css/style.css.map +++ b/src/css/style.css.map @@ -1 +1 @@ -{"version":3,"sources":["style.scss","style.css"],"names":[],"mappings":"AAGQ,mFAAA;AACA,2GAAA;AAgCR;EAEI,wCAhCU;EAiCV,SAAA;AClCJ;;ADqCA;EAEI,iCApCQ;ACCZ;;ADsCA;EAEI,YAAA;EACA,YAAA;EACA,eAAA;EACA,cAAA;EACA,iBAAA;EACA,aAAA;EACA,sBAAA;EACA,uBAAA;EACA,mBAAA;EACA,oCAAA;EACA,mBAAA;EACA,wCAAA;EACA,uBAAA;ACpCJ;;ADuCA;EAEI,kDAAA;EACA,4BAAA;EACA,sBAAA;EACA,2BAAA;EACA,iCA9DQ;EA+DR,aAAA;EACA,uBAAA;EACA,mBAAA;EACA,aAAA;EACA,SAAA;ACrCJ;ADuCI;EAEI,WAAA;EACA,aAAA;EACA,2CAAA;EACA,mBAAA;EACA,aAAA;ACtCR;ADwCQ;EAEI,kBAAA;EACA,WAAA;EACA,SAAA;EACA,WAAA;EACA,2BAAA;ACvCZ;AD0CQ;EAEI,aAAA;EACA,8BAAA;ACzCZ;AD4CQ;EAEI,uBAAA;EACA,eAAA;EACA,aAAA;EACA,oCAAA;EACA,mBAAA;AC3CZ;AD6CY;EAEI,eAAA;EACA,mBAAA;AC5ChB;AD+CY;EAEI,aAAA;EACA,sBAAA;EACA,SAAA;EACA,wBAAA;EACA,kBAAA;AC9ChB;ADgDgB;EAEI,uBAAA;AC/CpB;ADkDgB;EAxGZ,2CAAA;EAKA,mBAAA;EAuGgB,aAAA;EACA,gBAAA;ACjDpB;ADoDoB;EArHhB,oCAAA;EAeA,mBAAA;EA0GoB,kBAAA;EACA,oBAAA;ACnDxB;ADqDwB;EAEI,WAAA;ACpD5B;ADsD4B;EAEI,aAAA;EACA,8BAAA;EACA,gBAAA;ACrDhC;AD2DgB;EArIZ,2CAAA;EAKA,mBAAA;EAoIgB,aAAA;EACA,kBAAA;AC1DpB;AD4DoB;EAjJhB,oCAAA;EAeA,mBAAA;EAsIoB,kBAAA;EACA,sBAAA;EACA,aAAA;EACA,kBAAA;AC3DxB;AD6DwB;EAEI,kBAAA;EACA,SAAA;EACA,2BAAA;AC5D5B;AD+DwB;EAGI,kBAAA;EACA,QAAA;EACA,SAAA;EACA,gCAAA;AC/D5B;ADqEY;EAEI,aAAA;EACA,kCAAA;EACA,YAAA;ACpEhB;ADwEoB;EAEI,cAAA;ACvExB;ADyEwB;EAEI,WAAA;EACA,yBAAA;ACxE5B;ADgFoC;EAEI,YAAA;EACA,WAAA;AC/ExC;ADkFoC;EAEI,WAAA;ACjFxC;ADoFoC;EAEI,2BAAA;ACnFxC;AD6F4B;EAGA,YAAA;EACA,gCAAA;EACA,WAAA;EACA,gBAAA;AC7F5B;ADkGoB;EAEI,cAAA;EACA,kBAAA;ACjGxB;ADmGwB;EAGI,oCAAA;EACA,mBAAA;ACnG5B;ADqG4B;EAEA,aAAA;EACA,8BAAA;EACA,eAAA;EACA,iBAAA;EACA,WAAA;ACpG5B;ADsGgC;EAEI,aAAA;EACA,8BAAA;EACA,WAAA;ACrGpC;AD4G4B;EAGA,gCAAA;EACA,WAAA;EACA,gBAAA;AC5G5B;ADmHY;EA3QR,2CAAA;EAKA,mBAAA;EA0QY,aAAA;EACA,iCAAA;AClHhB;ADoHgB;EAvRZ,oCAAA;EAeA,mBAAA;EA4QgB,YAAA;ACnHpB;ADsHoB;EAEI,oBAAA;EACA,aAAA;EACA,sBAAA;EAGA,6BAAA;EACA,WAAA;ACvHxB;AD+IwB;EAEI,kBAAA;AC9I5B;ADgJ4B;EAGI,WAAA;EACA,kBAAA;EACA,OAAA;EACA,QAAA;EACA,WAAA;EACA,UAAA;EACA,iBAAA;AChJhC;ADmJ4B;EAEI,aAAA;AClJhC;ADqJ4B;EAEI,UAAA;ACpJhC;;ADgKI,YAAA;AACJ;EACI,aAAA;EACA,uBAAA;EACA,oCAAA;EACA,kBAAA;EACA,UAAA;EACA,cAAA;AC7JJ;;ADgKA,2BAAA;AAEA;EAEI,aAAA;EACA,eAAA;EACA,YAAA;EACA,SAAA;EACA,QAAA;EACA,gCAAA;EACA,iBAAA;EACA,gBAAA;EACA,wCAAA;EACA,WAAA;EACA,YAAA;EACA,uBAAA;EACA,mBAAA;AC/JJ;ADiKI;EAEI,WAAA;EACA,YAAA;EACA,kBAAA;EACA,iBAAA;AChKR;ADkKQ;EAGI,YAAA;EACA,qBAAA;EACA,eAAA;AClKZ","file":"style.css"} \ No newline at end of file +{"version":3,"sources":["style.scss","style.css"],"names":[],"mappings":"AAGQ,mFAAA;AACA,2GAAA;AAgCR;;;;;EAME,wCApCY;EAqCZ,SAAA;AClCF;;ADqCA;;EAGE,iCAzCU;EA0CV,YAAA;ACnCF;;ADsCA;EAEE,qBAAA;ACpCF;;ADuCA;EAEE,iHAAA;EACA,4BAAA;EACA,sBAAA;EACA,2BAAA;EACA,iCAxDU;EAyDV,aAAA;EACA,uBAAA;EACA,mBAAA;EACA,aAAA;EACA,SAAA;ACrCF;ADuCE;EAEE,WAAA;EACA,aAAA;EACA,2CAAA;EACA,mBAAA;EACA,aAAA;ACtCJ;ADwCI;EAEE,kBAAA;EACA,WAAA;EACA,SAAA;EACA,WAAA;EACA,2BAAA;ACvCN;AD0CI;EAEE,aAAA;EACA,8BAAA;ACzCN;AD4CI;EAEE,uBAAA;EACA,eAAA;EACA,aAAA;EACA,oCAAA;EACA,mBAAA;AC3CN;AD6CM;EAEE,eAAA;EACA,mBAAA;AC5CR;AD+CM;EAEE,aAAA;EACA,sBAAA;EACA,SAAA;EACA,wBAAA;EACA,kBAAA;AC9CR;ADgDQ;EAEE,uBAAA;AC/CV;ADkDQ;EAlGN,2CAAA;EAKA,mBAAA;EAiGQ,aAAA;EACA,gBAAA;EACA,uBAAA;ACjDV;ADmDU;EA/GR,oCAAA;EAeA,mBAAA;EAoGU,kBAAA;EACA,oBAAA;AClDZ;ADoDY;EAEE,WAAA;ACnDd;ADqDc;EAEE,aAAA;EACA,8BAAA;EACA,gBAAA;ACpDhB;AD0DQ;EA/HN,2CAAA;EAKA,mBAAA;EA8HQ,aAAA;EACA,kBAAA;EACA,uBAAA;ACzDV;AD2DU;EA5IR,oCAAA;EAeA,mBAAA;EAiIU,kBAAA;EACA,sBAAA;EACA,aAAA;EACA,kBAAA;AC1DZ;AD4DY;EAEE,kBAAA;EACA,SAAA;EACA,2BAAA;AC3Dd;AD8DY;EAGE,kBAAA;EACA,QAAA;EACA,SAAA;EACA,gCAAA;AC9Dd;ADoEM;EAEE,aAAA;EACA,kCAAA;EACA,YAAA;ACnER;ADuEU;EAEE,cAAA;ACtEZ;ADwEY;EAEE,WAAA;EACA,yBAAA;ACvEd;AD2EgB;EAEE,YAAA;EACA,YAAA;EACA,eAAA;EACA,cAAA;EACA,iBAAA;EACA,aAAA;EACA,sBAAA;EACA,uBAAA;EACA,mBAAA;EACA,oCAAA;EACA,mBAAA;EACA,wCAAA;AC1ElB;AD4EkB;EAEE,YAAA;EACA,WAAA;AC3EpB;AD8EkB;EAEE,WAAA;AC7EpB;ADgFkB;EAEE,2BAAA;AC/EpB;ADsFU;EAEE,cAAA;ACrFZ;ADwFY;EAEE,oCAAA;EACA,mBAAA;ACvFd;ADyFc;EAEE,aAAA;EACA,8BAAA;EACA,eAAA;EACA,iBAAA;EACA,WAAA;ACxFhB;AD0FgB;EAEE,aAAA;EACA,8BAAA;EACA,WAAA;ACzFlB;ADiGM;EAvPJ,2CAAA;EAKA,mBAAA;EAsPM,aAAA;EACA,iCAAA;EACA,uBAAA;AChGR;ADkGQ;EApQN,oCAAA;EAeA,mBAAA;EAyPQ,YAAA;ACjGV;ADmGU;EAEE,oBAAA;EACA,aAAA;EACA,sBAAA;EACA,oBAAA;EACA,WAAA;EACA,6BAAA;EACA,WAAA;AClGZ;ADwGgB;EAEE,kBAAA;ACvGlB;ADgHgB;EAEE,kBAAA;AC/GlB;ADoHY;EAEE,kBAAA;ACnHd;ADqHc;EAGE,WAAA;EACA,kBAAA;EACA,OAAA;EACA,QAAA;EACA,WAAA;EACA,UAAA;EACA,iBAAA;ACrHhB;ADwHc;EAEE,aAAA;ACvHhB;AD0Hc;EAEE,UAAA;ACzHhB;;ADmIA;EACE,aAAA;EACA,uBAAA;EACA,oCAAA;EACA,kBAAA;EACA,UAAA;EACA,cAAA;AChIF;;ADmIA;EACE,aAAA;EACA,eAAA;EACA,YAAA;EACA,SAAA;EACA,QAAA;EACA,gCAAA;EACA,iBAAA;EACA,gBAAA;EACA,wCAAA;EACA,WAAA;EACA,YAAA;EACA,yBAAA;EACA,mBAAA;AChIF;;ADkIA;EACE,WAAA;EACA,YAAA;EACA,kBAAA;EACA,iBAAA;AC/HF;;ADiIA;;EAEE,YAAA;EACA,qBAAA;EACA,eAAA;AC9HF;;ADiIA;;EAEE,wBAAA;EACA,aAAA;EACA,mBAAA;EACA,yBAAA;EACA,kBAAA;EACA,sBAAA;AC9HF;;ADiIA;EACE,aAAA;EACA,8BAAA;AC9HF;;ADiIA;EACE,UAAA;EACA,aAAA;EACA,sBAAA;EACA,YAAA;AC9HF;;ADiIA;EACE,aAAA;EACA,8BAAA;EACA,gBAAA;AC9HF;;ADiIA;;EAEE,OAAA;EACA,aAAA;EACA,aAAA;EACA,sBAAA;AC9HF;;ADiIA;;EAEE,yBAAA;EACA,aAAA;EACA,mBAAA;EACA,sBAAA;AC9HF;;ADiIA;;EAEE,WAAA;EACA,YAAA;EACA,mBAAA;EACA,eAAA;AC9HF;;ADiIA;EACE,uBAAA;AC9HF;;ADiIA;EACE,uBAAA;EACA,YAAA;AC9HF;;ADiIA;EACE,oDAAA;AC9HF;;ADiIA;EACE,oDAAA;AC9HF;;ADiIA;EACE,iDAAA;EACA,WAAA;AC9HF;;ADiIA;EACE,WAAA;EACA,YAAA;EACA,kBAAA;EACA,iBAAA;AC9HF;;ADiIA;;EAEE,YAAA;EACA,qBAAA;EACA,eAAA;AC9HF;;ADiIA;EACE,aAAA;EACA,gBAAA;AC9HF;;ADiIA;EACE,kBAAA;EACA,qBAAA;EACA,WAAA;EACA,YAAA;AC9HF;;ADiIA;EACE,UAAA;EACA,QAAA;EACA,SAAA;AC9HF;;ADiIA;EACE,kBAAA;EACA,eAAA;EACA,MAAA;EACA,OAAA;EACA,QAAA;EACA,SAAA;EACA,sBAAA;EACA,mBAAA;EACA,gBAAA;AC9HF;;ADiIA;EACE,kBAAA;EACA,WAAA;EACA,YAAA;EACA,WAAA;EACA,SAAA;EACA,WAAA;EACA,uBAAA;EACA,kBAAA;EACA,gBAAA;AC9HF;;ADiIA;EACE,yBAAA;AC9HF;;ADiIA;EACE,2BAAA;AC9HF;;ADiIA;EACE,aAAA;EACA,oBAAA;AC9HF;;ADiIE;;EAGE,uBAAA;AC/HJ","file":"style.css"} \ No newline at end of file diff --git a/src/css/style.scss b/src/css/style.scss index c5f1d70..87d6564 100644 --- a/src/css/style.scss +++ b/src/css/style.scss @@ -1,415 +1,535 @@ -$primary-color: rgb(171, 211, 174); +$primary-color: rgb(171, 211, 174); $secondary-color: rgb(143, 188, 143); - -@import url('https://fonts.googleapis.com/css2?family=Akaya+Kanadaka&display=swap'); -@import url('https://fonts.googleapis.com/css2?family=Afacad:ital,wght@0,400..700;1,400..700&display=swap'); - + +@import url("https://fonts.googleapis.com/css2?family=Akaya+Kanadaka&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Afacad:ital,wght@0,400..700;1,400..700&display=swap"); + $font-titels: "Akaya Kanadaka", system-ui; - + $font-text: "Afacad", sans-serif; - -@mixin flexbox + +@mixin flexbox-center { - display: flex; - justify-content: space-around; + display: flex; + justify-content: center; } - + @mixin groene-border { - border: solid 2px $primary-color; + border: solid 2px $primary-color; } - + @mixin box-shadow { - box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5); + box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5); } - + @mixin border-radius { - border-radius: 40px; + border-radius: 40px; } - + @mixin inner-border-radius { - border-radius: 35px; + border-radius: 35px; } - -h1, h2, h3, h4, h5 + +h1, +h2, +h3, +h4, +h5 { - font-family: $font-titels; - margin: 0; + font-family: $font-titels; + margin: 0; } - -p, td + +p, +td { - font-family: $font-text; + font-family: $font-text; + color: black; } - -.containers-articles + +a { - height: 7rem; - width: 10rem; - padding: .6rem; - margin: 0.1rem; - margin-left: 2rem; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - border: solid 3px $primary-color; - border-radius: 40px; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); - background-color: white; + text-decoration: none; } - + body { - background-image: url("../images/achtergrond.png"); - background-repeat: no-repeat; - background-size: cover; - background-position: center; - font-family: $font-text; - display: flex; - justify-content: center; - align-items: center; - height: 100vh; - margin: 0; - - .mainContainer + background: linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5)), url("../images/achtergrond.png"); + background-repeat: no-repeat; + background-size: cover; + background-position: center; + font-family: $font-text; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + margin: 0; + + .mainContainer + { + width: 85vw; + height: 38rem; + background-color: rgb(255, 255, 255, 85%); + border-radius: 40px; + padding: 2rem; + + .goodgarden-logo { - width: 85vw; - height: 38rem; - background-color: rgb(255, 255, 255, 95%); - border-radius: 40px; - padding: 2rem; - - .goodgarden-logo - { - position: absolute; - width: 10vw; - left: 50%; - top: 4.1rem; - transform: translateX(-50%); - } - - .informatie-kas-main-container - { - display: grid; - grid-template-columns: 5fr 7fr; - } - - .mainBorder - { - padding: 1.25rem 1.5rem; - padding: 1rem 0; - height: 35rem; - border: solid 5px $primary-color; - border-radius: 40px; - - .pagina-titel - { - font-size: 2rem; - margin-left: 1.5rem; - } - - #sectie-1 - { - display: flex; - flex-direction: column; - gap: 1rem; - padding: 0 2.5rem 0 1rem; - position: relative; - - h1 - { - background-color: green; - } - - .parent-algemeen-overzicht - { - @include box-shadow; - @include border-radius; - padding: 1rem; - margin-top: 1rem; - - - .algemeen-overzicht - { - @include groene-border; - @include inner-border-radius; - font-size: 1.25rem; - padding: .5rem 1rem; - - .table-informatie-kas - { - width: 100%; - - .tr-informatie-kas - { - display: flex; - justify-content: space-between; - text-align: left; - } - } - } - } - - .grafiek - { - @include box-shadow; - @include border-radius; - padding: 1rem; - position: relative; - - .grafiek-innerbox - { - @include groene-border; - @include inner-border-radius; - font-size: 1.25rem; - padding: 0 1rem 2.5rem; - height: 225px; - position: relative; - - h2 - { - position: absolute; - left: 50%; - transform: translateX(-50%); - } - - canvas - { - // Zorgt ervoor dat de grafiek precies in het midden komt - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - } - } - } - - } - .content - { - display: grid; - grid-template-columns: 3fr 1fr 3fr; - height: 100%; - - .kant - { - &-links - { - grid-column: 1; - - #planten - { - width: 100%; - border-collapse: collapse; - - td - { - article - { - @extend .containers-articles; - - #toevoegen - { - height: 5rem; - width: 5rem; - } - - h2 - { - color: gray; - } - - &:hover - { - background-color: lightgray; - } - - - } - } - } - - #sensor - { - &-1 - { - @extend .containers-articles; - border: none; - border-radius: 40px 0px 0px 40px; - width: 30vw; - margin-top: 10vh; - } - } - } - - &-rechts - { - grid-column: 3; - margin-right: 2rem; - - #metingen - { - - border: solid 3px $primary-color; - border-radius: 40px; - - #main-waardes - { - display: flex; - justify-content: space-between; - padding: .5rem; - padding-bottom: 0; - width: 100%; - - table - { - display: flex; - justify-content: space-between; - width: 100%; - } - } - } - - #sensor - { - &-2 - { - @extend .containers-articles; - border-radius: 0px 40px 40px 0px; - width: 30vw; - margin-top: 10vh; - } - } - } - } - } - - .grid-column-2 - { - @include box-shadow; - @include border-radius; - padding: 1rem; - margin: 3.25rem 1rem 1.25rem 1rem; - - .grid-2-child - { - @include groene-border; - @include inner-border-radius; - height: 100%; - - - .parent-table - { - padding: 1.5rem 2rem; - display: flex; - flex-direction: column; - // align-items: stretch; - // gap: 2.5rem; - justify-content: space-around; - height: 90%; - - table - { - tr - { - td - { - // font-size: 1.05rem; - } - } - } - - .kas-table-1 - { - tr - { - td - { - // font-size: 1.25rem; - } - } - } - - .kas-table-2 - { - position: relative; - - &::after, - &::before - { - content: ""; - position: absolute; - left: 0; - right: 0; - height: 1px; - width: 90%; - background: black; - } - - &::after - { - bottom: -20px; - } - - &::before - { - top: -20px; - } - } - - } - } - } - - } - } -} - - /* Divider */ -.divider { - display: flex; - justify-content: center; - border: solid 1px $primary-color; - border-radius: 5px; - width: 80%; - margin: 0 auto; -} - -/* The Modal (background) */ - -.modal -{ - display: none; - position: fixed; - z-index: 999; - left: 50%; - top: 50%; - transform: translate(-50%, -50%); - background: white; - padding: 1.25rem; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); - width: 30vw; - height: auto; - border: solid 2px black; - border-radius: 10px; - - .close - { - color: #aaa; - float: right; - font-size: 1.75rem; - font-weight: bold; - - &:hover, - &:active - { - color: black; - text-decoration: none; - cursor: pointer; - } + position: absolute; + width: 10vw; + left: 50%; + top: 4.1rem; + transform: translateX(-50%); } -} \ No newline at end of file + + .informatie-kas-main-container + { + display: grid; + grid-template-columns: 5fr 7fr; + } + + .mainBorder + { + padding: 1.25rem 1.5rem; + padding: 1rem 0; + height: 35rem; + border: solid 5px $primary-color; + border-radius: 40px; + + .pagina-titel + { + font-size: 2rem; + margin-left: 1.5rem; + } + + #sectie-1 + { + display: flex; + flex-direction: column; + gap: 1rem; + padding: 0 2.5rem 0 1rem; + position: relative; + + h1 + { + background-color: green; + } + + .parent-algemeen-overzicht + { + @include box-shadow; + @include border-radius; + padding: 1rem; + margin-top: 1rem; + background-color: white; + + .algemeen-overzicht + { + @include groene-border; + @include inner-border-radius; + font-size: 1.25rem; + padding: 0.5rem 1rem; + + .table-informatie-kas + { + width: 100%; + + .tr-informatie-kas + { + display: flex; + justify-content: space-between; + text-align: left; + } + } + } + } + + .grafiek + { + @include box-shadow; + @include border-radius; + padding: 1rem; + position: relative; + background-color: white; + + .grafiek-innerbox + { + @include groene-border; + @include inner-border-radius; + font-size: 1.25rem; + padding: 0 1rem 2.5rem; + height: 225px; + position: relative; + + h2 + { + position: absolute; + left: 50%; + transform: translateX(-50%); + } + + canvas + { + // Zorgt ervoor dat de grafiek precies in eht midden komt + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + } + } + } + } + + .content + { + display: grid; + grid-template-columns: 3fr 1fr 3fr; + height: 100%; + + .kant + { + &-links + { + grid-column: 1; + + #planten + { + width: 100%; + border-collapse: collapse; + + td + { + article + { + height: 7rem; + width: 10rem; + padding: 0.6rem; + margin: 0.1rem; + margin-left: 2rem; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + border: solid 3px $primary-color; + border-radius: 40px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + + #toevoegen + { + height: 5rem; + width: 5rem; + } + + h2 + { + color: gray; + } + + &:hover + { + background-color: lightgray; + } + } + } + } + } + + &-rechts + { + grid-column: 3; + // margin-right: 2rem; + + #metingen + { + border: solid 3px $primary-color; + border-radius: 40px; + + #main-waardes + { + display: flex; + justify-content: space-between; + padding: 0.5rem; + padding-bottom: 0; + width: 100%; + + table + { + display: flex; + justify-content: space-between; + width: 100%; + } + } + } + } + } + } + + .grid-column-2 + { + @include box-shadow; + @include border-radius; + padding: 1rem; + margin: 3.25rem 1rem 1.25rem 1rem; + background-color: white; + + .grid-2-child + { + @include groene-border; + @include inner-border-radius; + height: 100%; + + .parent-table + { + padding: 1.5rem 2rem; + display: flex; + flex-direction: column; + align-items: stretch; + gap: 2.5rem; + justify-content: space-around; + height: 90%; + + table + { + tr + { + td + { + font-size: 1.05rem; + } + } + } + + .kas-table-1 + { + tr + { + td + { + font-size: 1.25rem; + } + } + } + + .kas-table-2 + { + position: relative; + + &::after, + &::before + { + content: ""; + position: absolute; + left: 0; + right: 0; + height: 1px; + width: 90%; + background: black; + } + + &::after + { + bottom: -20px; + } + + &::before + { + top: -20px; + } + } + } + } + } + } + } +} + +.divider { + display: flex; + justify-content: center; + border: solid 1px $primary-color; + border-radius: 5px; + width: 80%; + margin: 0 auto; +} + +.modal { + display: none; + position: fixed; + z-index: 999; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + background: white; + padding: 1.25rem; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + width: 30vw; + height: auto; + border: solid 2px #abd3ae; + border-radius: 10px; +} +.modal .close { + color: #aaa; + float: right; + font-size: 1.75rem; + font-weight: bold; +} +.modal .close:hover, +.modal .close:active { + color: black; + text-decoration: none; + cursor: pointer; +} + +#myModal select, +#myModal input { + width: calc(100% - 20px); + padding: 10px; + margin-bottom: 15px; + border: 2px solid #abd3ae; + border-radius: 5px; + box-sizing: border-box; +} + +#myModal .knop { + display: flex; + justify-content: space-between; +} + +#myModal button { + width: 48%; + padding: 10px; + box-sizing: border-box; + height: 40px; +} + +#myModal .knop-container { + display: flex; + justify-content: space-between; + margin-top: 20px; +} + +#myModal .knop-container input, +#myModal .knop-container button { + flex: 1; + margin: 0 5px; + padding: 10px; + box-sizing: border-box; +} + +#myModal input[type="text"], +#myModal select { + border: 2px solid #abd3ae; + padding: 10px; + border-radius: 17px; + box-sizing: border-box; +} + +#myModal input[type="submit"], +#myModal button { + color: #fff; + border: none; + border-radius: 15px; + cursor: pointer; +} + +#myModal input[type="submit"] { + background-color: white; +} + +#myModal button { + background-color: white; + color: black; +} + +.toevoeging { + background: linear-gradient(45deg, #abd3ae, #2ecc71); +} + +.annulatie-knop { + background: linear-gradient(45deg, #ffcc00, #ff6600); +} + +#myModal button:hover { + background: linear-gradient(45deg, #abd3ae, #fff); + color: #000; +} + +.modal .close { + color: #aaa; + float: right; + font-size: 1.75rem; + font-weight: bold; +} + +.modal .close:hover, +.modal .close:active { + color: black; + text-decoration: none; + cursor: pointer; +} + +.switch-container { + display: flex; + align-items: end; +} + +.switch { + position: relative; + display: inline-block; + width: 60px; + height: 30px; +} + +.switch input { + opacity: 0; + width: 0; + height: 0; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + border-radius: 34px; + transition: 0.4s; +} + +.slider:before { + position: absolute; + content: ""; + height: 26px; + width: 26px; + left: 4px; + bottom: 4px; + background-color: white; + border-radius: 50%; + transition: 0.4s; +} + +input:checked + .slider { + background-color: #2ecc71; +} + +input:checked + .slider:before { + transform: translateX(26px); +} + +.rechterkant { + display: flex; + justify-content: end; +} + + .plant-container, + #modalButton + { + background-color: white; + } + \ No newline at end of file diff --git a/src/index.html b/src/index.html index e9a5d20..59dd1b6 100644 --- a/src/index.html +++ b/src/index.html @@ -95,4 +95,4 @@ - \ No newline at end of file + diff --git a/src/js/main.js b/src/js/main.js deleted file mode 100644 index a3e1eb4..0000000 --- a/src/js/main.js +++ /dev/null @@ -1,115 +0,0 @@ -const { ipcRenderer } = require("electron"); - -document.addEventListener('DOMContentLoaded', () => -{ - ipcRenderer.send('request-update-temp', ['some', 'arguments']); - - ipcRenderer.on('update-temp-result', (event, newTemperature) => { - if (newTemperature === 'error') { - console.error('Er is een fout opgetreden bij het ophalen van de nieuwe temperatuur'); - } else { - document.getElementById('bodem-temperatuur').textContent = newTemperature; - } - }); - -}); - -function openModal() -{ - const modal = document.getElementById("myModal"); - const button = document.getElementById("modalButton"); - const close = document.getElementsByClassName("close")[0]; - - // Toon de modal wanneer op de knop wordt geklikt - button.onclick = function() - { - modal.style.display = "block"; - } - - // Sluit de modal wanneer op het 'sluiten' icoon wordt geklikt - close.onclick = function() - { - modal.style.display = "none"; - } - - // Sluit de modal wanneer buiten de modal wordt geklikt - window.onclick = function(event) - { - if (event.target == modal) - { - modal.style.display = "none"; - } - } -} - -/** - * --- Functie om de grafiek te tekenen. Enigste belangrijke is de eerste 2 "const" arrays "data" & "xLabels". - */ -function drawLineChart() -{ - /*Dit is de data die getoond wordt als "punt" op de grafiek. 20 = y20 / x20, 50 = y50 / x50 enzovoort... De array "data" & "xLabels" moeten beide evenveel array items hebben!!*/ - const data = [20, 50, 60, 45, 50, 100, 70, 60, 65, 0, 85, 0]; - const xLabels = ["", "", "", "", "", 6, "", "", "", "", "", 12]; - - const yLabels = ["", 20, "", 40, "", 60, "", 80, "", 100]; /*NIET VERANDEREN!!!*/ - - const canvas = document.getElementById("myCanvas"); - const ctx = canvas.getContext("2d"); - - ctx.clearRect(0, 0, canvas.width, canvas.height); - - const padding = 35; // Increased padding for Y labels - const graphWidth = canvas.width - padding * 2; - const graphHeight = canvas.height - padding * 2; - - ctx.beginPath(); - ctx.moveTo(padding, padding); - ctx.lineTo(padding, canvas.height - padding); - ctx.lineTo(canvas.width - padding, canvas.height - padding); - ctx.stroke(); - - // Set the color of the line - ctx.strokeStyle = "rgb(143, 188, 143)"; - - const xIncrement = graphWidth / (xLabels.length - 1); - const yIncrement = graphHeight / (yLabels.length - 1); - - // Plot the data - ctx.beginPath(); - ctx.moveTo(padding, canvas.height - padding - (data[0] / 100) * graphHeight); - - for (let i = 1; i < data.length; i++) - { - const xPos = padding + i * xIncrement; - const yPos = canvas.height - padding - (data[i] / 100) * graphHeight; - ctx.lineTo(xPos, yPos); - } - ctx.stroke(); - - // Draw Y labels - ctx.fillStyle = "black"; - ctx.textAlign = "right"; // Align text to the right - ctx.textBaseline = "middle"; // Center vertically - - for (let i = 0; i < yLabels.length; i++) - { - if (yLabels[i] !== "") - { - const yPos = canvas.height - padding - i * yIncrement; - ctx.fillText(yLabels[i], padding - 10, yPos); - } - } - - // Draw X labels - ctx.textAlign = "center"; // Center horizontally for X labels - for (let i = 0; i < xLabels.length; i++) - { - if (xLabels[i] !== "") - { - const xPos = padding + i * xIncrement; - ctx.fillText(xLabels[i], xPos, canvas.height - padding + 20); - } - } -} - -drawLineChart(); \ No newline at end of file diff --git a/src/js/planten.class.js b/src/js/planten.class.js deleted file mode 100644 index efe074c..0000000 --- a/src/js/planten.class.js +++ /dev/null @@ -1,143 +0,0 @@ -class Plant { - constructor(dataObject) { - this.id = dataObject.id; - this.plantNaam = dataObject.plantNaam; - this.plantensoort = dataObject.plantensoort; - this.plantGeteelt = dataObject.plantGeteelt; - } -} - -class PlantGrid { - constructor() { - this.grid = []; - this.cols = 2; // Number of columns - this.rows = 4; // Number of rows (including the row for the "Add" button) - - // Initialize the grid with null values - for (let i = 0; i < this.rows; i++) { - this.grid[i] = new Array(this.cols).fill(null); - } - - // Sample data - const dataHardObject = [ - { - "id": 1, - "plantNaam": "Tomt", - "plantensoort": "Groente", - "plantGeteelt": 1 - }, - { - "id": 2, - "plantNaam": "Komkommer", - "plantensoort": "Groente", - "plantGeteelt": 1 - }, - { - "id": 3, - "plantNaam": "Appel", - "plantensoort": "Groente", - "plantGeteelt": 0 - }, - { - "id": 4, - "plantNaam": "KwamKwammer", - "plantensoort": "Groente", - "plantGeteelt": 1 - }, - { - "id": 5, - "plantNaam": ":p", - "plantensoort": "Groente", - "plantGeteelt": 1 - }, - { - "id": 6, - "plantNaam": ":3", - "plantensoort": "Groente", - "plantGeteelt": 1 - }, - { - "id": 7, - "plantNaam": "Groene", - "plantensoort": "Groente", - "plantGeteelt": 1 - }, - { - "id": 8, - "plantNaam": "test", - "plantensoort": "Groente", - "plantGeteelt": 0 - }, - { - "id": 9, - "plantNaam": "yippie", - "plantensoort": "Groente", - "plantGeteelt": 1 - } - ]; - - // Only save objects that have plantGeteelt as 1 - const filteredData = dataHardObject.filter(plantObject => plantObject.plantGeteelt === 1); - - // Populate the grid with plant objects - filteredData.slice(0, 8).forEach((plantObject, index) => { - const plant = new Plant(plantObject); - const col = index % this.cols; - const row = Math.floor(index / this.cols); - this.grid[row][col] = plant; - }); - - - // Display the grid in the HTML table with id "planten" - this.displayGrid(); - } - - displayGrid() { - const plantenTable = document.getElementById("planten"); - - let itemCount = 0; // Counter for the number of items in the grid - - this.grid.forEach((row, rowIndex) => { - const tr = document.createElement("tr"); - - row.forEach((plant, colIndex) => { - const td = document.createElement("td"); - - if (itemCount < 8) { - if (plant) { - // Handle regular plant items - const article = document.createElement("article"); - const img = article.appendChild(document.createElement("img")); - img.src = "images/Icon awesome-apple-alt.png"; - const h2 = article.appendChild(document.createElement("h2")); - h2.classList.add("plant-naam"); - h2.textContent = plant.plantNaam; - - td.appendChild(article); - itemCount++; - } else if (rowIndex === this.rows -1 && colIndex === this.cols -1 && itemCount <= 7) { - // Handle the "Add" button - const article = document.createElement("article"); - const img = article.appendChild(document.createElement("img")); - img.src = "images/Toevoegen.png"; - img.id = "toevoegen"; - img.alt = "Add"; - article.id = "modalButton"; - article.onclick = openModal; - - td.appendChild(article); - itemCount++; - } - } - - tr.appendChild(td); - }); - - plantenTable.appendChild(tr); - }); - } -} - -document.addEventListener("DOMContentLoaded", () => { - const plantGrid = new PlantGrid(); -}); diff --git a/src/kas_informatie.html b/src/kas_informatie.html deleted file mode 100644 index 7809eec..0000000 --- a/src/kas_informatie.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - Informatie Kas - - -
-
- -
-
-
-

Informatie Kas

-
-
-
- - - - - - - - - - - - - - - - - -
Dagen tot Oogst12
Dagen in Kas2
Tevredenheid80%
Aandachtspunten1
-
-
-
-
-

Zonlicht

- -
-
-
-
-
-
-
- - - - - - - - - - - - - -
Aantal geplant:2
Succesvolle Oogst:2
Gefaalde Oogst:2
- - - - - - - - - - - - - - - - - -
Warmste Maand:n.v.t.
koudste Maand:December
Gemiddelde Bodemtemp.:2˚C
Gemiddelde Uren Zonlicht:2u
- - - - - - - - - - - - - - - - - -
Laatste Irrigatie:2u
Aankomende Irrigatie:2u
Laatste Bemesting2d
Aankomende Bemesting:2w
-
-
-
-
-
- - diff --git a/script/main.py b/src/py/__init__.py similarity index 100% rename from script/main.py rename to src/py/__init__.py diff --git a/script/DUMMY.json b/src/py/script/DUMMY.json similarity index 54% rename from script/DUMMY.json rename to src/py/script/DUMMY.json index 98acdaf..abc4c3d 100644 --- a/script/DUMMY.json +++ b/src/py/script/DUMMY.json @@ -1,14 +1,10 @@ - - // Deze spanningswaarden zijn relatief hoog, wat suggereert dat de batterijen van de sensoren goed opgeladen zijn. De meeste sensorapparaten gebruiken batterijen die een nominale spanning van ongeveer 3,7 volt hebben (typisch voor lithium-ion batterijen) en kunnen worden beschouwd als "volledig opgeladen" wanneer ze een spanning dicht bij of iets boven 4,1 volt bereiken - "battery_voltage_events": [ +{ "battery_voltage_events": [ { "timestamp": 1707825721, "gateway_receive_time": "2024-02-13T12:02:01Z", "device": 256, "value": 4.098901271820068 - // Volledig opgeladen: Rond 4.2 volt. - // Nominale spanning: Ongeveer 3.7 volt. - // Kritiek laag: Minder dan 3.0 volt. + }, { "timestamp": 1707837460, @@ -44,7 +40,6 @@ - // Fotosyntese??? (zonlicht) "par_events": [ { "timestamp": 1707844638, @@ -63,7 +58,6 @@ - // Luchtvochtigheid "relative_humidity_events": [ { "timestamp": 1707844638, @@ -83,7 +77,6 @@ - // De "soil_electric_conductivity_events" gegevens wijzen op metingen van de elektrische geleidbaarheid (EC) van de bodem, een indicator van de hoeveelheid oplosbare zouten of voedingsstoffen in de bodem. EC wordt gemeten in Siemens per meter (S/m) of, voor bodemmetingen, vaak in milliSiemens per centimeter (mS/cm). Een hogere EC-waarde duidt op een hogere concentratie van opgeloste zouten, wat belangrijk is voor het bepalen van de voedingsstatus van de bodem en het beheren van de bemesting voor optimale plantengroei. "soil_electric_conductivity_events": [ { "timestamp": 1707851215, @@ -97,20 +90,17 @@ - // In de context van bodemmetingen, geeft deze waarde inzicht in het vochtgehalte van de bodem, omdat water een relatief hoge diëlektrische constante heeft in vergelijking met droge bodem of lucht. "soil_relative_permittivity_events": [ { "timestamp": 1707851215, "gateway_receive_time": "2024-02-13T19:06:55Z", "device": 322, "value": 1.52 - // Een waarde van 1.52 is relatief laag en suggereert dat de bodem droog kan zijn op het moment van meting. Ter referentie, de diëlektrische constante van lucht is ongeveer 1, terwijl water een diëlektrische constante heeft van ongeveer 80 bij kamertemperatuur. } ], - //De "soil_temperature_events" gegevens bevatten informatie over de temperatuur van de bodem op een specifiek tijdstip. De waarde geeft de temperatuur van de bodem aan in graden Celsius (°C). "soil_temperature_events": [ { "timestamp": 1707851215, diff --git a/script/__pycache__/db_connect.cpython-311.pyc b/src/py/script/__pycache__/db_connect.cpython-311.pyc similarity index 93% rename from script/__pycache__/db_connect.cpython-311.pyc rename to src/py/script/__pycache__/db_connect.cpython-311.pyc index 89c2567..2a248d0 100644 Binary files a/script/__pycache__/db_connect.cpython-311.pyc and b/src/py/script/__pycache__/db_connect.cpython-311.pyc differ diff --git a/src/py/script/battery_voltage_events.py b/src/py/script/battery_voltage_events.py new file mode 100644 index 0000000..8f989dc --- /dev/null +++ b/src/py/script/battery_voltage_events.py @@ -0,0 +1,223 @@ +import mysql.connector +import requests +from datetime import datetime, timezone, timedelta +import time + +# Function to make a connection to the database +def database_connect(): + return mysql.connector.connect( + host="localhost", + user="root", + password="", + database="goodgarden" + ) + +# Functie voor het aanmaken van gegevens in de database +def create_data(url, access_token, repeat_count=5): + for _ in range(repeat_count): + try: + headers = {"Authorization": f"Token {access_token}"} + response = requests.get(url, headers=headers) + response.raise_for_status() + + data = response.json() + print(f"Data from {url}:\n") + + # Check if data is a list (records directly under the root) + if isinstance(data, list): + records = data + elif isinstance(data, dict) and 'results' in data: + records = data['results'] + else: + print(f"Unexpected data format received: {data}") + continue + + for record in records: + # Now, record is assumed to be a dictionary + timestamp = record.get('timestamp', '') + gateway_receive_time = record.get('gateway_receive_time', '') + device = record.get('device', '') + value = record.get('value', '') + + print(f"\nInserted data: Timestamp: {timestamp}, Device: {device}, Battery Voltage: {value}V\n") + if float(value) < 3.0: + print("Waarschuwing: Batterijspanning is lager dan 3.0 volt. Opladen aanbevolen.\n") + # Controleer of de batterijspanning hoger is dan 4.2 volt en geef een melding + elif float(value) > 4.2: + print("Melding: Batterijspanning is hoger dan 4.2 volt. Batterij is vol.\n") + else: + print("Melding: Batterijspanning is binnen het gewenste bereik.\n\n") + + # Insert data into the database + insert_data(record) + + except requests.exceptions.RequestException as e: + print(f"Error fetching data from {url}: {e}") + + print("Waiting for the next create action...\n") + time.sleep(1) + +# Functie voor het invoegen van gegevens in de database +def insert_data(record): + mydb = database_connect() + if mydb.is_connected(): + mycursor = mydb.cursor() + + # Hier moet je de juiste kolomnamen en gegevensindeling aanpassen op basis van de API-respons + insert_query = """ + INSERT INTO goodgarden.battery_voltage_events (timestamp, gateway_receive_time, device, value) + VALUES (%s, %s, %s, %s) + """ + # Pas dit aan op basis van de werkelijke structuur van de JSON + timestamp = record.get('timestamp', '') + gateway_receive_time = record.get('gateway_receive_time', '') + device = record.get('device', '') + value = record.get('value', '') + + print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}") # Print de ingevoerde gegevens + + # Voer de query uit + mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value)) + + # Bevestig de wijzigingen + mydb.commit() + + # Sluit cursor en verbinding + mycursor.close() + mydb.close() + + print("Data inserted into the database.") + +# Functie voor het lezen van gegevens uit de database +def read_data(url, access_token, repeat_count=5): + for _ in range(repeat_count): + try: + headers = {"Authorization": f"Token {access_token}"} + response = requests.get(url, headers=headers) + response.raise_for_status() + + data = response.json() + print(f"Data from {url}:\n") + + for record in data['results']: + timestamp = record.get('timestamp', '') + device = record.get('device', '') + value = record.get('value', '') + print(f"Timestamp: {timestamp}, Device: {device}, Battery Voltage: {value}V\n") + + if float(value) < 3.0: + print("Waarschuwing: Batterijspanning is lager dan 3.0 volt. Opladen aanbevolen.\n") + # Controleer of de batterijspanning hoger is dan 4.2 volt en geef een melding + elif float(value) > 4.2: + print("Melding: Batterijspanning is hoger dan 4.2 volt. Batterij is vol.\n") + else: + print("Melding: Batterijspanning is binnen het gewenste bereik.\n\n") + + except requests.exceptions.RequestException as e: + print(f"Error fetching data from {url}: {e}") + + print("Waiting for the next read action...\n") + time.sleep(300) + +# Functie voor het bijwerken van gegevens in de database +def update_data(record_id): + try: + mydb = database_connect() + + if mydb.is_connected(): + mycursor = mydb.cursor() + + # Controleer of het record bestaat voordat je het bijwerkt + mycursor.execute("SELECT * FROM goodgarden.battery_voltage_events WHERE id = %s", (record_id,)) + existing_record = mycursor.fetchone() + + if not existing_record: + print(f"Record with ID {record_id} not found. Update operation aborted.") + return + + # Vraag de gebruiker om nieuwe waarden voor de andere velden + new_timestamp = input("Enter new timestamp: ") + new_gateway_receive_time = input("Enter new gateway_receive_time: ") + new_device = input("Enter new device: ") + new_value = input("Enter new value: ") + + # Hier moet je de juiste kolomnamen aanpassen op basis van de structuur van je database + update_query = """ + UPDATE goodgarden.battery_voltage_events + SET timestamp = %s, gateway_receive_time = %s, device = %s, value = %s + WHERE id = %s + """ + + # Voer de query uit + print(f"Executing update query: {update_query}") + print(f"Updating record with ID {record_id} to new values - timestamp: {new_timestamp}, gateway_receive_time: {new_gateway_receive_time}, device: {new_device}, value: {new_value}") + + mycursor.execute(update_query, (new_timestamp, new_gateway_receive_time, new_device, new_value, record_id)) + + # Bevestig de wijzigingen + mydb.commit() + + print(f"Update executed. Rowcount: {mycursor.rowcount}") + + except mysql.connector.Error as update_err: + print(f"Error updating data: {update_err}") + finally: + # Zorg ervoor dat je altijd de cursor en de databaseverbinding sluit + if 'mycursor' in locals() and mycursor is not None: + mycursor.close() + if 'mydb' in locals() and mydb.is_connected(): + mydb.close() + +# Functie voor het verwijderen van gegevens uit de database +def delete_data(record_id): + mydb = database_connect() + if mydb.is_connected(): + mycursor = mydb.cursor() + + # Hier moet je de juiste kolomnamen aanpassen op basis van de structuur van je database + delete_query = """ + DELETE FROM goodgarden.battery_voltage_events + WHERE id = %s + """ + + # Voer de query uit + mycursor.execute(delete_query, (record_id,)) + + # Bevestig de wijzigingen + mydb.commit() + + # Sluit cursor en verbinding + mycursor.close() + mydb.close() + + print(f"Data with ID {record_id} deleted.") + +# Functie voor het aanmaken van gegevens in de database op basis van batterijspanningsinformatie + +if __name__ == "__main__": + url = "https://garden.inajar.nl/api/battery_voltage_events/?format=json" + access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c" # Vervang dit door je werkelijke toegangstoken + + # Je kunt repeat_count wijzigen om te bepalen hoe vaak je de bewerking wilt herhalen + repeat_count = 10 + + # Keuze voor de bewerking + operation_choice = input("Choose operation (C for Create, R for Read, U for Update, D for Delete): ").upper() + + if operation_choice == "C": + # Maak gegevens aan + create_data(url, access_token, repeat_count) + elif operation_choice == "R": + # Lees gegevens + read_data(url, access_token, repeat_count) + elif operation_choice == "U": + # Update gegevens + record_id = int(input("Enter record ID to update: ")) + # Call the update_data function without additional arguments + update_data(record_id) + elif operation_choice == "D": + # Verwijder gegevens + record_id = int(input("Enter record ID to delete: ")) + delete_data(record_id) + else: + print("Invalid operation choice. Please choose C, R, U, or D.") diff --git a/script/db_connect.py b/src/py/script/db_connect.py similarity index 84% rename from script/db_connect.py rename to src/py/script/db_connect.py index fbed212..8d61b95 100644 --- a/script/db_connect.py +++ b/src/py/script/db_connect.py @@ -1,4 +1,4 @@ -import mysql.connector #** TYPE IN TERMINAL: "pip install mysql-connector-python" +import mysql.connector from mysql.connector import Error def database_connect(): diff --git a/script/db_connect_form.py b/src/py/script/db_connect_form.py similarity index 100% rename from script/db_connect_form.py rename to src/py/script/db_connect_form.py diff --git a/src/py/script/devices.py b/src/py/script/devices.py new file mode 100644 index 0000000..eb63fca --- /dev/null +++ b/src/py/script/devices.py @@ -0,0 +1,36 @@ +import json + +from paho.mqtt import subscribe + +def on_message(client, userdata, message): + payload_str = message.payload.decode("utf-8") + data = json.loads(payload_str) + + device_256 = None + last_seen = None + last_battery_voltage = None + + device_322 = None + last_seen = None + last_battery_voltage = None + + for key in data["results"]: + if int(key["id"]) == 256: + device_256 = int(key["id"]) + last_seen = int(key["last_seen"]) + last_battery_voltage = float(key["last_battery_voltage"]) + # print(f"{device_256}") + print(f"Het device {device_256} is voor het laatst geien op: {last_seen} met de voltage als {last_battery_voltage}") + + elif int(key["id"]) == 322: + device_322 = int(key["id"]) + last_seen = int(key["last_seen"]) + last_battery_voltage = float(key["last_battery_voltage"]) + # print(f"{device_256}") + print(f"Het device {device_322} is voor het laatst gezien op: {last_seen} met de voltage als {last_battery_voltage}") + + print(f"\033[92mMessage received on topic\033[0m {message.topic}: {data}") + +if __name__ == "__main__": + topic = "goodgarden/devices" + subscribe.callback(on_message, topic) \ No newline at end of file diff --git a/src/py/script/goodgarden.sql b/src/py/script/goodgarden.sql new file mode 100644 index 0000000..93d8664 --- /dev/null +++ b/src/py/script/goodgarden.sql @@ -0,0 +1,346 @@ +-- phpMyAdmin SQL Dump +-- version 5.2.1 +-- https://www.phpmyadmin.net/ +-- +-- Host: 127.0.0.1 +-- Gegenereerd op: 14 feb 2024 om 14:36 +-- Serverversie: 10.4.28-MariaDB +-- PHP-versie: 8.2.4 + +DROP DATABASE IF EXISTS goodgarden; +CREATE DATABASE goodgarden; + +USE goodgarden; + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +START TRANSACTION; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; + +-- +-- Database: `goodgarden` +-- + +-- -------------------------------------------------------- + +-- +-- Tabelstructuur voor tabel `battery_voltage_events` +-- + +CREATE TABLE `battery_voltage_events` ( + `id` int(10) UNSIGNED NOT NULL, + `timestamp` int(11) DEFAULT NULL, + `gateway_receive_time` varchar(50) DEFAULT NULL, + `device` int(11) DEFAULT NULL, + `value` decimal(10,5) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Gegevens worden geëxporteerd voor tabel `battery_voltage_events` +-- + +INSERT INTO `battery_voltage_events` (`id`, `timestamp`, `gateway_receive_time`, `device`, `value`) VALUES +(1, 1707825721, '2024-02-13T12:02:01Z', 256, 4.09890), +(2, 1707837460, '2024-02-13T15:17:40Z', 322, 4.10501), +(3, 1707825721, '2024-02-13T12:02:01Z', 256, 4.09890), +(4, 1707837460, '2024-02-13T15:17:40Z', 322, 4.10501), +(5, 1707825721, '2024-02-13T12:02:01Z', 256, 4.09890), +(6, 1707837460, '2024-02-13T15:17:40Z', 322, 4.10501), +(7, 1707825721, '2024-02-13T12:02:01Z', 256, 4.09890), +(8, 1707837460, '2024-02-13T15:17:40Z', 322, 4.10501), +(9, 1707825721, '2024-02-13T12:02:01Z', 256, 4.09890), +(10, 1707837460, '2024-02-13T15:17:40Z', 322, 4.10501); + +-- -------------------------------------------------------- + +-- +-- Tabelstructuur voor tabel `devices` +-- + +CREATE TABLE `devices` ( + `id` int(10) UNSIGNED NOT NULL, + `serial_number` varchar(255) DEFAULT NULL, + `name` varchar(255) DEFAULT NULL, + `label` varchar(255) DEFAULT NULL, + `last_seen` int(11) DEFAULT NULL, + `last_battery_voltage` float DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Gegevens worden geëxporteerd voor tabel `devices` +-- + +INSERT INTO `devices` (`id`, `serial_number`, `name`, `label`, `last_seen`, `last_battery_voltage`) VALUES +(1, '0033889B1BAB1169', 'firefly2_0051', 'The Field', 1707765066, 4.09768), +(2, '006FE1FC316ED7D8', 'firefly2_0111', 'The Field', 1707764966, 4.10745); + +-- -------------------------------------------------------- + +-- +-- Tabelstructuur voor tabel `fetch` +-- + +CREATE TABLE `fetch` ( + `id` int(10) UNSIGNED NOT NULL, + `timestamp` int(11) DEFAULT NULL, + `gateway_receive_time` varchar(50) DEFAULT NULL, + `device` int(11) DEFAULT NULL, + `value` decimal(10,5) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Gegevens worden geëxporteerd voor tabel `fetch` +-- + +INSERT INTO `fetch` (`id`, `timestamp`, `gateway_receive_time`, `device`, `value`) VALUES +(70, 1707851215, '2024-02-13T19:06:55Z', 322, 0.00000), +(71, 1707851215, '2024-02-13T19:06:55Z', 322, 1.52000), +(72, 1707851215, '2024-02-13T19:06:55Z', 322, 12.06000), +(73, 1707825721, '2024-02-13T12:02:01Z', 256, 4.09890), +(74, 1707837460, '2024-02-13T15:17:40Z', 322, 4.10501), +(75, 0, '', 0, 0.00000), +(76, 0, '', 0, 0.00000), +(77, 1707844638, '2024-02-13T17:17:18Z', 322, 0.00000), +(78, 1707851099, '2024-02-13T19:04:59Z', 256, 0.00000), +(79, 1707844638, '2024-02-13T17:17:18Z', 322, 71.08984), +(80, 1707851099, '2024-02-13T19:04:59Z', 256, 66.72949), +(81, 1707851215, '2024-02-13T19:06:55Z', 322, 0.00000), +(82, 1707851215, '2024-02-13T19:06:55Z', 322, 1.52000), +(83, 1707851215, '2024-02-13T19:06:55Z', 322, 12.06000), +(84, 0, '', 0, 0.00000), +(85, 0, '', 0, 0.00000), +(86, 1707844638, '2024-02-13T17:17:18Z', 322, 0.00000), +(87, 1707851099, '2024-02-13T19:04:59Z', 256, 0.00000), +(88, 1707844638, '2024-02-13T17:17:18Z', 322, 71.08984), +(89, 1707851099, '2024-02-13T19:04:59Z', 256, 66.72949), +(90, 1707825721, '2024-02-13T12:02:01Z', 256, 4.09890), +(91, 1707837460, '2024-02-13T15:17:40Z', 322, 4.10501), +(92, 0, '', 0, 0.00000), +(93, 0, '', 0, 0.00000), +(94, 1707844638, '2024-02-13T17:17:18Z', 322, 0.00000), +(95, 1707851099, '2024-02-13T19:04:59Z', 256, 0.00000), +(96, 1707844638, '2024-02-13T17:17:18Z', 322, 71.08984), +(97, 1707851099, '2024-02-13T19:04:59Z', 256, 66.72949); + +-- -------------------------------------------------------- + +-- +-- Tabelstructuur voor tabel `par_events` +-- + +CREATE TABLE `par_events` ( + `id` int(10) UNSIGNED NOT NULL, + `timestamp` int(11) DEFAULT NULL, + `gateway_receive_time` varchar(50) DEFAULT NULL, + `device` int(11) DEFAULT NULL, + `value` decimal(10,5) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Gegevens worden geëxporteerd voor tabel `par_events` +-- + +INSERT INTO `par_events` (`id`, `timestamp`, `gateway_receive_time`, `device`, `value`) VALUES +(1, 1707844638, '2024-02-13T17:17:18Z', 322, 0.00000), +(2, 1707851099, '2024-02-13T19:04:59Z', 256, 0.00000); + +-- -------------------------------------------------------- + +-- +-- Tabelstructuur voor tabel `relative_humidity_events` +-- + +CREATE TABLE `relative_humidity_events` ( + `id` int(10) UNSIGNED NOT NULL, + `timestamp` int(11) DEFAULT NULL, + `gateway_receive_time` varchar(50) DEFAULT NULL, + `device` int(11) DEFAULT NULL, + `value` decimal(10,5) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Gegevens worden geëxporteerd voor tabel `relative_humidity_events` +-- + +INSERT INTO `relative_humidity_events` (`id`, `timestamp`, `gateway_receive_time`, `device`, `value`) VALUES +(3, 1707844638, '2024-02-13T17:17:18Z', 322, 71.08984), +(4, 1707851099, '2024-02-13T19:04:59Z', 256, 66.72949), +(5, 1707844638, '2024-02-13T17:17:18Z', 322, 71.08984), +(6, 1707851099, '2024-02-13T19:04:59Z', 256, 66.72949); + +-- -------------------------------------------------------- + +-- +-- Tabelstructuur voor tabel `soil_electric_conductivity_events` +-- + +CREATE TABLE `soil_electric_conductivity_events` ( + `id` int(10) UNSIGNED NOT NULL, + `timestamp` int(11) DEFAULT NULL, + `gateway_receive_time` varchar(50) DEFAULT NULL, + `device` int(11) DEFAULT NULL, + `value` decimal(10,5) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Gegevens worden geëxporteerd voor tabel `soil_electric_conductivity_events` +-- + +INSERT INTO `soil_electric_conductivity_events` (`id`, `timestamp`, `gateway_receive_time`, `device`, `value`) VALUES +(3, 1707851215, '2024-02-13T19:06:55Z', 322, 0.00000); + +-- -------------------------------------------------------- + +-- +-- Tabelstructuur voor tabel `soil_relative_permittivity_events` +-- + +CREATE TABLE `soil_relative_permittivity_events` ( + `id` int(10) UNSIGNED NOT NULL, + `timestamp` int(11) DEFAULT NULL, + `gateway_receive_time` varchar(50) DEFAULT NULL, + `device` int(11) DEFAULT NULL, + `value` decimal(10,5) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Gegevens worden geëxporteerd voor tabel `soil_relative_permittivity_events` +-- + +INSERT INTO `soil_relative_permittivity_events` (`id`, `timestamp`, `gateway_receive_time`, `device`, `value`) VALUES +(3, 1707851215, '2024-02-13T19:06:55Z', 322, 1.52000); + +-- -------------------------------------------------------- + +-- +-- Tabelstructuur voor tabel `soil_temperature_events` +-- + +CREATE TABLE `soil_temperature_events` ( + `id` int(10) NOT NULL, + `timestamp` int(11) DEFAULT NULL, + `gateway_receive_time` varchar(50) DEFAULT NULL, + `device` int(11) DEFAULT NULL, + `value` decimal(10,5) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Gegevens worden geëxporteerd voor tabel `soil_temperature_events` +-- + +INSERT INTO `soil_temperature_events` (`id`, `timestamp`, `gateway_receive_time`, `device`, `value`) VALUES +(3, 1707851215, '2024-02-13T19:06:55Z', 322, 12.06000); + +-- +-- Indexen voor geëxporteerde tabellen +-- + +-- +-- Indexen voor tabel `battery_voltage_events` +-- +ALTER TABLE `battery_voltage_events` + ADD PRIMARY KEY (`id`); + +-- +-- Indexen voor tabel `devices` +-- +ALTER TABLE `devices` + ADD PRIMARY KEY (`id`); + +-- +-- Indexen voor tabel `fetch` +-- +ALTER TABLE `fetch` + ADD PRIMARY KEY (`id`); + +-- +-- Indexen voor tabel `par_events` +-- +ALTER TABLE `par_events` + ADD PRIMARY KEY (`id`); + +-- +-- Indexen voor tabel `relative_humidity_events` +-- +ALTER TABLE `relative_humidity_events` + ADD PRIMARY KEY (`id`); + +-- +-- Indexen voor tabel `soil_electric_conductivity_events` +-- +ALTER TABLE `soil_electric_conductivity_events` + ADD PRIMARY KEY (`id`); + +-- +-- Indexen voor tabel `soil_relative_permittivity_events` +-- +ALTER TABLE `soil_relative_permittivity_events` + ADD PRIMARY KEY (`id`); + +-- +-- Indexen voor tabel `soil_temperature_events` +-- +ALTER TABLE `soil_temperature_events` + ADD PRIMARY KEY (`id`); + +-- +-- AUTO_INCREMENT voor geëxporteerde tabellen +-- + +-- +-- AUTO_INCREMENT voor een tabel `battery_voltage_events` +-- +ALTER TABLE `battery_voltage_events` + MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=11; + +-- +-- AUTO_INCREMENT voor een tabel `devices` +-- +ALTER TABLE `devices` + MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3; + +-- +-- AUTO_INCREMENT voor een tabel `fetch` +-- +ALTER TABLE `fetch` + MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=98; + +-- +-- AUTO_INCREMENT voor een tabel `par_events` +-- +ALTER TABLE `par_events` + MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3; + +-- +-- AUTO_INCREMENT voor een tabel `relative_humidity_events` +-- +ALTER TABLE `relative_humidity_events` + MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=7; + +-- +-- AUTO_INCREMENT voor een tabel `soil_electric_conductivity_events` +-- +ALTER TABLE `soil_electric_conductivity_events` + MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4; + +-- +-- AUTO_INCREMENT voor een tabel `soil_relative_permittivity_events` +-- +ALTER TABLE `soil_relative_permittivity_events` + MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4; + +-- +-- AUTO_INCREMENT voor een tabel `soil_temperature_events` +-- +ALTER TABLE `soil_temperature_events` + MODIFY `id` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4; +COMMIT; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/src/py/script/par_events.py b/src/py/script/par_events.py new file mode 100644 index 0000000..a5cda5e --- /dev/null +++ b/src/py/script/par_events.py @@ -0,0 +1,25 @@ +import json + +from paho.mqtt import subscribe + +def on_message(client, userdata, message): + payload_str = message.payload.decode("utf-8") + data = json.loads(payload_str) + + device_322_value = None + device_256_value = None + + for key in data["results"]: + if key["device"] == 322: + device_322_value = key["value"] + elif key["device"] == 256: + device_256_value = key["value"] + + print(f"Device 322 value: {device_322_value}") + print(f"Device 256 value: {device_256_value}") + + print(f"Message received on topic {message.topic}: {data}") + +if __name__ == "__main__": + topic = "goodgarden/par_events" + subscribe.callback(on_message, topic) \ No newline at end of file diff --git a/src/py/script/planten.py b/src/py/script/planten.py new file mode 100644 index 0000000..4da2975 --- /dev/null +++ b/src/py/script/planten.py @@ -0,0 +1,49 @@ +import json +import mysql.connector +import os + +# Function to make a connection to the database +def database_connect(): + return mysql.connector.connect( + host="localhost", + user="root", + password="", + database="goodgarden" + ) + +# Function to get the absolute path of the current directory +def get_current_directory(): + return os.path.dirname(os.path.abspath(__file__)) + +def fetch_plant_and_write_to_json(): + # Establish a database connection + connection = database_connect() + + try: + cursor = connection.cursor(dictionary=True) # To fetch rows as dictionaries + # Execute the query to fetch data + cursor.execute("SELECT id, plant_naam, plantensoort, plant_geteelt FROM planten") + # Fetch all rows + plants = cursor.fetchall() + + # Get the absolute path of the current directory + current_directory = get_current_directory() + # Construct the absolute path for the JSON file + json_file_path = os.path.join(current_directory, 'plants.json') + + # Write fetched data to JSON file + with open(json_file_path, 'w') as json_file: + json.dump(plants, json_file, indent=4) + + except mysql.connector.Error as error: + print("Error fetching data from MySQL table:", error) + + finally: + # Close cursor and connection + if 'cursor' in locals(): + cursor.close() + if connection.is_connected(): + connection.close() + +# Call the function to fetch data and write to JSON +fetch_plant_and_write_to_json() diff --git a/src/py/script/plants.json b/src/py/script/plants.json new file mode 100644 index 0000000..d5d1df0 --- /dev/null +++ b/src/py/script/plants.json @@ -0,0 +1,32 @@ +[ + { + "id": 47, + "plant_naam": "Tomaten", + "plantensoort": "Groente", + "plant_geteelt": 1 + }, + { + "id": 49, + "plant_naam": "Komkommer", + "plantensoort": "Groente", + "plant_geteelt": 1 + }, + { + "id": 50, + "plant_naam": "Appel", + "plantensoort": "Fruit", + "plant_geteelt": 1 + }, + { + "id": 51, + "plant_naam": "Sla", + "plantensoort": "Groente", + "plant_geteelt": 1 + }, + { + "id": 52, + "plant_naam": "Wietplant", + "plantensoort": "Onkruid", + "plant_geteelt": 0 + } +] \ No newline at end of file diff --git a/src/py/script/relative_humidity_events.py b/src/py/script/relative_humidity_events.py new file mode 100644 index 0000000..4b71813 --- /dev/null +++ b/src/py/script/relative_humidity_events.py @@ -0,0 +1,13 @@ +import json + +from paho.mqtt import subscribe + +def on_message(client, userdata, message): + payload_str = message.payload.decode("utf-8") + data = json.loads(payload_str) + + print(f"Message received on topic {message.topic}: {data}") + +if __name__ == "__main__": + topic = "goodgarden/relative_humidity" + subscribe.callback(on_message, topic) \ No newline at end of file diff --git a/src/py/script/samenvoegen_databases.py b/src/py/script/samenvoegen_databases.py new file mode 100644 index 0000000..b604664 --- /dev/null +++ b/src/py/script/samenvoegen_databases.py @@ -0,0 +1,218 @@ +import requests +import time + +from db_connect import database_connect + +##########################* DEVICES ####################### + +def load_data(data): + mydb = database_connect() + if mydb.is_connected(): + mycursor = mydb.cursor() + + insert_query = """ + INSERT INTO goodgarden.devices (serial_number, name, label, last_seen, last_battery_voltage) + VALUES (%s, %s, %s, %s, %s ) + """ + for record in data['results']: + serial_number = record.get('serial_number', '') + name = record.get('name', '') + label = record.get('label', '') + last_seen = record.get('last_seen', '') + last_battery_voltage = record.get('last_battery_voltage', '') + + print(f"Inserting data: serial_number={serial_number}, name={name}, label={label}, last_seen={last_seen}, last_battery_voltage={last_battery_voltage}") + + mycursor.execute(insert_query, (serial_number, name, label, last_seen, last_battery_voltage)) + + mydb.commit() + + mycursor.close() + mydb.close() + + print("Data inserted into the database.") + +############################### EINDE ######################## + # # + # # + # # + # # +##########################* PAR_EVENTS ####################### + +def load_data(data): + mydb = database_connect() + if mydb.is_connected(): + mycursor = mydb.cursor() + + # Here you need to adjust the correct column names and data formats based on the API response + insert_query = """ + INSERT INTO goodgarden.par_events (timestamp, gateway_receive_time, device, value) + VALUES (%s, %s, %s, %s) + """ + for record in data['results']: + timestamp = record.get('timestamp', '') + gateway_receive_time = record.get('gateway_receive_time', '') + device = record.get('device', '') + value = record.get('value', '') + + print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}") + + # Execute the query + mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value)) + + # Commit the changes + mydb.commit() + + # Close cursor and connection + mycursor.close() + mydb.close() + + print("Data inserted into the database.") + +############################### EINDE ######################## + # # + # # + # # + # # +##########################* RELATIVE_HUMIDITY_EVENTS ####################### + +def load_data(data): + mydb = database_connect() + if mydb.is_connected(): + mycursor = mydb.cursor() + + # Here you need to adjust the correct column names and data formats based on the API response + insert_query = """ + INSERT INTO goodgarden.relative_humidity_events (timestamp, gateway_receive_time, device, value) + VALUES (%s, %s, %s, %s) + """ + for record in data['results']: + timestamp = record.get('timestamp', '') + gateway_receive_time = record.get('gateway_receive_time', '') + device = record.get('device', '') + value = record.get('value', '') + + print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}") + + # Execute the query + mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value)) + + # Commit the changes + mydb.commit() + + # Close cursor and connection + mycursor.close() + mydb.close() + + print("Data inserted into the database.") + +############################### EINDE ######################## + # # + # # + # # + # # +##########################* SOIL_ELECTRIC_CONDUCTIVITY_EVENTS ####################### + +def load_data(data): + mydb = database_connect() + if mydb.is_connected(): + mycursor = mydb.cursor() + + # Here you need to adjust the correct column names and data formats based on the API response + insert_query = """ + INSERT INTO goodgarden.soil_electric_conductivity_events (timestamp, gateway_receive_time, device, value) + VALUES (%s, %s, %s, %s) + """ + for record in data['results']: + timestamp = record.get('timestamp', '') + gateway_receive_time = record.get('gateway_receive_time', '') + device = record.get('device', '') + value = record.get('value', '') + + print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}") + + # Execute the query + mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value)) + + # Commit the changes + mydb.commit() + + # Close cursor and connection + mycursor.close() + mydb.close() + + print("Data inserted into the database.") + +############################### EINDE ######################## + # # + # # + # # + # # +##########################* SOIL_TEMPERATURE_EVENTS ####################### + +def load_data(data): + mydb = database_connect() + if mydb.is_connected(): + mycursor = mydb.cursor() + + # Here you need to adjust the correct column names and data formats based on the API response + insert_query = """ + INSERT INTO goodgarden.soil_temperature_events (timestamp, gateway_receive_time, device, value) + VALUES (%s, %s, %s, %s) + """ + for record in data['results']: + timestamp = record.get('timestamp', '') + gateway_receive_time = record.get('gateway_receive_time', '') + device = record.get('device', '') + value = record.get('value', '') + + print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}") + + # Execute the query + mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value)) + + # Commit the changes + mydb.commit() + + # Close cursor and connection + mycursor.close() + mydb.close() + + print("Data inserted into the database.") + +############################### EINDE ######################## + # # + # # + # # + # # +##########################* SOIL_TEMPERATURE_EVENTS ####################### + +def load_data(data): + mydb = database_connect() + if mydb.is_connected(): + mycursor = mydb.cursor() + + # Here you need to adjust the correct column names and data formats based on the API response + insert_query = """ + INSERT INTO goodgarden.soil_temperature_events (timestamp, gateway_receive_time, device, value) + VALUES (%s, %s, %s, %s) + """ + for record in data['results']: + timestamp = record.get('timestamp', '') + gateway_receive_time = record.get('gateway_receive_time', '') + device = record.get('device', '') + value = record.get('value', '') + + print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}") + + # Execute the query + mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value)) + + # Commit the changes + mydb.commit() + + # Close cursor and connection + mycursor.close() + mydb.close() + + print("Data inserted into the database.") \ No newline at end of file diff --git a/src/py/script/servermqtt.py b/src/py/script/servermqtt.py new file mode 100644 index 0000000..096efb8 --- /dev/null +++ b/src/py/script/servermqtt.py @@ -0,0 +1,74 @@ +import os +import time +import requests +import paho.mqtt.client as mqtt +from dotenv import load_dotenv + +load_dotenv() + +API_URL = os.getenv("API_URL") +MQTT_HOST = os.getenv("MQTT_HOST") +MQTT_PORT = int(os.getenv("MQTT_PORT", 1883)) + +def get_data_from_api(request): + links = { + 'battery': '/battery_voltage_events/', + 'devices': '/devices/', + 'parEvents': '/par_events/', + 'humidity': '/relative_humidity_events/', + 'soilConductifity': '/soil_electric_conductivity_events/', + 'soilPermittivity' : '/soil_relative_permittivity_events/', + 'soilTemperature': '/soil_temperature_events/' + } + headers = { + 'accept': 'application/json', + 'Authorization': f'Token {os.getenv("API_TOKEN")}' + } + url = API_URL + links[request] + try: + response = requests.get(url, headers=headers) + response.raise_for_status() + except requests.exceptions.HTTPError as errh: + print ("HTTP Error:",errh) + return None + except requests.exceptions.ConnectionError as errc: + print ("Error Connecting:",errc) + return None + except requests.exceptions.Timeout as errt: + print ("Timeout Error:",errt) + return None + except requests.exceptions.RequestException as err: + print ("Something went wrong",err) + return None + + data = response.json() + return data['results'] + +def publish_to_mqtt(topic, message): + client = mqtt.Client() + client.connect(MQTT_HOST, MQTT_PORT, 60) + try: + client.publish(topic, message) + except mqtt.MQTTException as e: + print(f"Failed to publish message: {e}") + finally: + client.disconnect() + +def process_results(link, results): + for result in results: + if 'timestamp' in result and 'gateway_receive_time' in result and 'device' in result and 'value' in result: + message = f"Timestamp: {result['timestamp']}, Gateway Receive Time: {result['gateway_receive_time']}, Device: {result['device']}, Value: {result['value']}" + print(message) + publish_to_mqtt(link, message) + +def main(): + links = ['battery', 'devices', 'parEvents', 'humidity', 'soilConductifity', 'soilPermittivity', 'soilTemperature'] + while True: + for link in links: + results = get_data_from_api(link) + if results is not None: + process_results(link, results) + time.sleep(5) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/py/script/soil_electric_conductivity_events.py b/src/py/script/soil_electric_conductivity_events.py new file mode 100644 index 0000000..69f0960 --- /dev/null +++ b/src/py/script/soil_electric_conductivity_events.py @@ -0,0 +1,13 @@ +import json + +from paho.mqtt import subscribe + +def on_message(client, userdata, message): + payload_str = message.payload.decode("utf-8") + data = json.loads(payload_str) + + print(f"Message received on topic {message.topic}: {data}") + +if __name__ == "__main__": + topic = "goodgarden/soil_electric_conductivity" + subscribe.callback(on_message, topic) \ No newline at end of file diff --git a/src/py/script/soil_relative_permittivity_events.py b/src/py/script/soil_relative_permittivity_events.py new file mode 100644 index 0000000..ce0cb25 --- /dev/null +++ b/src/py/script/soil_relative_permittivity_events.py @@ -0,0 +1,13 @@ +import json + +from paho.mqtt import subscribe + +def on_message(client, userdata, message): + payload_str = message.payload.decode("utf-8") + data = json.loads(payload_str) + + print(f"Message received on topic {message.topic}: {data}") + +if __name__ == "__main__": + topic = "goodgarden/soil_relative_permittivity" + subscribe.callback(on_message, topic) \ No newline at end of file diff --git a/src/py/script/soil_temperature_events.py b/src/py/script/soil_temperature_events.py new file mode 100644 index 0000000..89b7116 --- /dev/null +++ b/src/py/script/soil_temperature_events.py @@ -0,0 +1,13 @@ +import json + +from paho.mqtt import subscribe + +def on_message(client, userdata, message): + payload_str = message.payload.decode("utf-8") + data = json.loads(payload_str) + + print(f"Message received on topic {message.topic}: {data}") + +if __name__ == "__main__": + topic = "goodgarden/soil_temperature" + subscribe.callback(on_message, topic) \ No newline at end of file diff --git a/src/py/static/css/style.css b/src/py/static/css/style.css new file mode 100644 index 0000000..0668a0e --- /dev/null +++ b/src/py/static/css/style.css @@ -0,0 +1,406 @@ +@import url("https://fonts.googleapis.com/css2?family=Akaya+Kanadaka&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Afacad:ital,wght@0,400..700;1,400..700&display=swap"); +h1, +h2, +h3, +h4, +h5 { + font-family: "Akaya Kanadaka", system-ui; + margin: 0; +} + +p, +td { + font-family: "Afacad", sans-serif; + color: black; +} + +a { + text-decoration: none; +} + +body { + background: linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5)), url("../images/achtergrond.png"); + background-repeat: no-repeat; + background-size: cover; + background-position: center; + font-family: "Afacad", sans-serif; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + margin: 0; +} +body .mainContainer { + width: 85vw; + height: 38rem; + background-color: rgba(255, 255, 255, 0.85); + border-radius: 40px; + padding: 2rem; +} +body .mainContainer .goodgarden-logo { + position: absolute; + width: 10vw; + left: 50%; + top: 4.1rem; + transform: translateX(-50%); +} +body .mainContainer .informatie-kas-main-container { + display: grid; + grid-template-columns: 5fr 7fr; +} +body .mainContainer .mainBorder { + padding: 1.25rem 1.5rem; + padding: 1rem 0; + height: 35rem; + border: solid 5px rgb(171, 211, 174); + border-radius: 40px; +} +body .mainContainer .mainBorder .pagina-titel { + font-size: 2rem; + margin-left: 1.5rem; +} +body .mainContainer .mainBorder #sectie-1 { + display: flex; + flex-direction: column; + gap: 1rem; + padding: 0 2.5rem 0 1rem; + position: relative; +} +body .mainContainer .mainBorder #sectie-1 h1 { + background-color: green; +} +body .mainContainer .mainBorder #sectie-1 .parent-algemeen-overzicht { + box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5); + border-radius: 40px; + padding: 1rem; + margin-top: 1rem; + background-color: white; +} +body .mainContainer .mainBorder #sectie-1 .parent-algemeen-overzicht .algemeen-overzicht { + border: solid 2px rgb(171, 211, 174); + border-radius: 35px; + font-size: 1.25rem; + padding: 0.5rem 1rem; +} +body .mainContainer .mainBorder #sectie-1 .parent-algemeen-overzicht .algemeen-overzicht .table-informatie-kas { + width: 100%; +} +body .mainContainer .mainBorder #sectie-1 .parent-algemeen-overzicht .algemeen-overzicht .table-informatie-kas .tr-informatie-kas { + display: flex; + justify-content: space-between; + text-align: left; +} +body .mainContainer .mainBorder #sectie-1 .grafiek { + box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5); + border-radius: 40px; + padding: 1rem; + position: relative; + background-color: white; +} +body .mainContainer .mainBorder #sectie-1 .grafiek .grafiek-innerbox { + border: solid 2px rgb(171, 211, 174); + border-radius: 35px; + font-size: 1.25rem; + padding: 0 1rem 2.5rem; + height: 225px; + position: relative; +} +body .mainContainer .mainBorder #sectie-1 .grafiek .grafiek-innerbox h2 { + position: absolute; + left: 50%; + transform: translateX(-50%); +} +body .mainContainer .mainBorder #sectie-1 .grafiek .grafiek-innerbox canvas { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} +body .mainContainer .mainBorder .content { + display: grid; + grid-template-columns: 3fr 1fr 3fr; + height: 100%; +} +body .mainContainer .mainBorder .content .kant-links { + grid-column: 1; +} +body .mainContainer .mainBorder .content .kant-links #planten { + width: 100%; + border-collapse: collapse; +} +body .mainContainer .mainBorder .content .kant-links #planten td article { + height: 7rem; + width: 10rem; + padding: 0.6rem; + margin: 0.1rem; + margin-left: 2rem; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + border: solid 3px rgb(171, 211, 174); + border-radius: 40px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); +} +body .mainContainer .mainBorder .content .kant-links #planten td article #toevoegen { + height: 5rem; + width: 5rem; +} +body .mainContainer .mainBorder .content .kant-links #planten td article h2 { + color: gray; +} +body .mainContainer .mainBorder .content .kant-links #planten td article:hover { + background-color: lightgray; +} +body .mainContainer .mainBorder .content .kant-rechts { + grid-column: 3; +} +body .mainContainer .mainBorder .content .kant-rechts #metingen { + border: solid 3px rgb(171, 211, 174); + border-radius: 40px; +} +body .mainContainer .mainBorder .content .kant-rechts #metingen #main-waardes { + display: flex; + justify-content: space-between; + padding: 0.5rem; + padding-bottom: 0; + width: 100%; +} +body .mainContainer .mainBorder .content .kant-rechts #metingen #main-waardes table { + display: flex; + justify-content: space-between; + width: 100%; +} +body .mainContainer .mainBorder .grid-column-2 { + box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5); + border-radius: 40px; + padding: 1rem; + margin: 3.25rem 1rem 1.25rem 1rem; + background-color: white; +} +body .mainContainer .mainBorder .grid-column-2 .grid-2-child { + border: solid 2px rgb(171, 211, 174); + border-radius: 35px; + height: 100%; +} +body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table { + padding: 1.5rem 2rem; + display: flex; + flex-direction: column; + align-items: stretch; + gap: 2.5rem; + justify-content: space-around; + height: 90%; +} +body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table table tr td { + font-size: 1.05rem; +} +body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas-table-1 tr td { + font-size: 1.25rem; +} +body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas-table-2 { + position: relative; +} +body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas-table-2::after, body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas-table-2::before { + content: ""; + position: absolute; + left: 0; + right: 0; + height: 1px; + width: 90%; + background: black; +} +body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas-table-2::after { + bottom: -20px; +} +body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas-table-2::before { + top: -20px; +} + +.divider { + display: flex; + justify-content: center; + border: solid 1px rgb(171, 211, 174); + border-radius: 5px; + width: 80%; + margin: 0 auto; +} + +.modal { + display: none; + position: fixed; + z-index: 999; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + background: white; + padding: 1.25rem; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + width: 30vw; + height: auto; + border: solid 2px #abd3ae; + border-radius: 10px; +} + +.modal .close { + color: #aaa; + float: right; + font-size: 1.75rem; + font-weight: bold; +} + +.modal .close:hover, +.modal .close:active { + color: black; + text-decoration: none; + cursor: pointer; +} + +#myModal select, +#myModal input { + width: calc(100% - 20px); + padding: 10px; + margin-bottom: 15px; + border: 2px solid #abd3ae; + border-radius: 5px; + box-sizing: border-box; +} + +#myModal .knop { + display: flex; + justify-content: space-between; +} + +#myModal button { + width: 48%; + padding: 10px; + box-sizing: border-box; + height: 40px; +} + +#myModal .knop-container { + display: flex; + justify-content: space-between; + margin-top: 20px; +} + +#myModal .knop-container input, +#myModal .knop-container button { + flex: 1; + margin: 0 5px; + padding: 10px; + box-sizing: border-box; +} + +#myModal input[type=text], +#myModal select { + border: 2px solid #abd3ae; + padding: 10px; + border-radius: 17px; + box-sizing: border-box; +} + +#myModal input[type=submit], +#myModal button { + color: #fff; + border: none; + border-radius: 15px; + cursor: pointer; +} + +#myModal input[type=submit] { + background-color: white; +} + +#myModal button { + background-color: white; + color: black; +} + +.toevoeging { + background: linear-gradient(45deg, #abd3ae, #2ecc71); +} + +.annulatie-knop { + background: linear-gradient(45deg, #ffcc00, #ff6600); +} + +#myModal button:hover { + background: linear-gradient(45deg, #abd3ae, #fff); + color: #000; +} + +.modal .close { + color: #aaa; + float: right; + font-size: 1.75rem; + font-weight: bold; +} + +.modal .close:hover, +.modal .close:active { + color: black; + text-decoration: none; + cursor: pointer; +} + +.switch-container { + display: flex; + align-items: end; +} + +.switch { + position: relative; + display: inline-block; + width: 60px; + height: 30px; +} + +.switch input { + opacity: 0; + width: 0; + height: 0; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + border-radius: 34px; + transition: 0.4s; +} + +.slider:before { + position: absolute; + content: ""; + height: 26px; + width: 26px; + left: 4px; + bottom: 4px; + background-color: white; + border-radius: 50%; + transition: 0.4s; +} + +input:checked + .slider { + background-color: #2ecc71; +} + +input:checked + .slider:before { + transform: translateX(26px); +} + +.rechterkant { + display: flex; + justify-content: end; +} + +.plant-container, +#modalButton { + background-color: white; +}/*# sourceMappingURL=style.css.map */ \ No newline at end of file diff --git a/src/py/static/css/style.css.map b/src/py/static/css/style.css.map new file mode 100644 index 0000000..90630c9 --- /dev/null +++ b/src/py/static/css/style.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["style.scss","style.css"],"names":[],"mappings":"AAGQ,mFAAA;AACA,2GAAA;AAgCR;;;;;EAME,wCApCY;EAqCZ,SAAA;AClCF;;ADqCA;;EAGE,iCAzCU;EA0CV,YAAA;ACnCF;;ADsCA;EAEE,qBAAA;ACpCF;;ADuCA;EAEE,iHAAA;EACA,4BAAA;EACA,sBAAA;EACA,2BAAA;EACA,iCAxDU;EAyDV,aAAA;EACA,uBAAA;EACA,mBAAA;EACA,aAAA;EACA,SAAA;ACrCF;ADuCE;EAEE,WAAA;EACA,aAAA;EACA,2CAAA;EACA,mBAAA;EACA,aAAA;ACtCJ;ADwCI;EAEE,kBAAA;EACA,WAAA;EACA,SAAA;EACA,WAAA;EACA,2BAAA;ACvCN;AD0CI;EAEE,aAAA;EACA,8BAAA;ACzCN;AD4CI;EAEE,uBAAA;EACA,eAAA;EACA,aAAA;EACA,oCAAA;EACA,mBAAA;AC3CN;AD6CM;EAEE,eAAA;EACA,mBAAA;AC5CR;AD+CM;EAEE,aAAA;EACA,sBAAA;EACA,SAAA;EACA,wBAAA;EACA,kBAAA;AC9CR;ADgDQ;EAEE,uBAAA;AC/CV;ADkDQ;EAlGN,2CAAA;EAKA,mBAAA;EAiGQ,aAAA;EACA,gBAAA;EACA,uBAAA;ACjDV;ADmDU;EA/GR,oCAAA;EAeA,mBAAA;EAoGU,kBAAA;EACA,oBAAA;AClDZ;ADoDY;EAEE,WAAA;ACnDd;ADqDc;EAEE,aAAA;EACA,8BAAA;EACA,gBAAA;ACpDhB;AD0DQ;EA/HN,2CAAA;EAKA,mBAAA;EA8HQ,aAAA;EACA,kBAAA;EACA,uBAAA;ACzDV;AD2DU;EA5IR,oCAAA;EAeA,mBAAA;EAiIU,kBAAA;EACA,sBAAA;EACA,aAAA;EACA,kBAAA;AC1DZ;AD4DY;EAEE,kBAAA;EACA,SAAA;EACA,2BAAA;AC3Dd;AD8DY;EAGE,kBAAA;EACA,QAAA;EACA,SAAA;EACA,gCAAA;AC9Dd;ADoEM;EAEE,aAAA;EACA,kCAAA;EACA,YAAA;ACnER;ADuEU;EAEE,cAAA;ACtEZ;ADwEY;EAEE,WAAA;EACA,yBAAA;ACvEd;AD2EgB;EAEE,YAAA;EACA,YAAA;EACA,eAAA;EACA,cAAA;EACA,iBAAA;EACA,aAAA;EACA,sBAAA;EACA,uBAAA;EACA,mBAAA;EACA,oCAAA;EACA,mBAAA;EACA,wCAAA;AC1ElB;AD4EkB;EAEE,YAAA;EACA,WAAA;AC3EpB;AD8EkB;EAEE,WAAA;AC7EpB;ADgFkB;EAEE,2BAAA;AC/EpB;ADsFU;EAEE,cAAA;ACrFZ;ADwFY;EAEE,oCAAA;EACA,mBAAA;ACvFd;ADyFc;EAEE,aAAA;EACA,8BAAA;EACA,eAAA;EACA,iBAAA;EACA,WAAA;ACxFhB;AD0FgB;EAEE,aAAA;EACA,8BAAA;EACA,WAAA;ACzFlB;ADiGM;EAvPJ,2CAAA;EAKA,mBAAA;EAsPM,aAAA;EACA,iCAAA;EACA,uBAAA;AChGR;ADkGQ;EApQN,oCAAA;EAeA,mBAAA;EAyPQ,YAAA;ACjGV;ADmGU;EAEE,oBAAA;EACA,aAAA;EACA,sBAAA;EACA,oBAAA;EACA,WAAA;EACA,6BAAA;EACA,WAAA;AClGZ;ADwGgB;EAEE,kBAAA;ACvGlB;ADgHgB;EAEE,kBAAA;AC/GlB;ADoHY;EAEE,kBAAA;ACnHd;ADqHc;EAGE,WAAA;EACA,kBAAA;EACA,OAAA;EACA,QAAA;EACA,WAAA;EACA,UAAA;EACA,iBAAA;ACrHhB;ADwHc;EAEE,aAAA;ACvHhB;AD0Hc;EAEE,UAAA;ACzHhB;;ADmIA;EACE,aAAA;EACA,uBAAA;EACA,oCAAA;EACA,kBAAA;EACA,UAAA;EACA,cAAA;AChIF;;ADmIA;EACE,aAAA;EACA,eAAA;EACA,YAAA;EACA,SAAA;EACA,QAAA;EACA,gCAAA;EACA,iBAAA;EACA,gBAAA;EACA,wCAAA;EACA,WAAA;EACA,YAAA;EACA,yBAAA;EACA,mBAAA;AChIF;;ADkIA;EACE,WAAA;EACA,YAAA;EACA,kBAAA;EACA,iBAAA;AC/HF;;ADiIA;;EAEE,YAAA;EACA,qBAAA;EACA,eAAA;AC9HF;;ADiIA;;EAEE,wBAAA;EACA,aAAA;EACA,mBAAA;EACA,yBAAA;EACA,kBAAA;EACA,sBAAA;AC9HF;;ADiIA;EACE,aAAA;EACA,8BAAA;AC9HF;;ADiIA;EACE,UAAA;EACA,aAAA;EACA,sBAAA;EACA,YAAA;AC9HF;;ADiIA;EACE,aAAA;EACA,8BAAA;EACA,gBAAA;AC9HF;;ADiIA;;EAEE,OAAA;EACA,aAAA;EACA,aAAA;EACA,sBAAA;AC9HF;;ADiIA;;EAEE,yBAAA;EACA,aAAA;EACA,mBAAA;EACA,sBAAA;AC9HF;;ADiIA;;EAEE,WAAA;EACA,YAAA;EACA,mBAAA;EACA,eAAA;AC9HF;;ADiIA;EACE,uBAAA;AC9HF;;ADiIA;EACE,uBAAA;EACA,YAAA;AC9HF;;ADiIA;EACE,oDAAA;AC9HF;;ADiIA;EACE,oDAAA;AC9HF;;ADiIA;EACE,iDAAA;EACA,WAAA;AC9HF;;ADiIA;EACE,WAAA;EACA,YAAA;EACA,kBAAA;EACA,iBAAA;AC9HF;;ADiIA;;EAEE,YAAA;EACA,qBAAA;EACA,eAAA;AC9HF;;ADiIA;EACE,aAAA;EACA,gBAAA;AC9HF;;ADiIA;EACE,kBAAA;EACA,qBAAA;EACA,WAAA;EACA,YAAA;AC9HF;;ADiIA;EACE,UAAA;EACA,QAAA;EACA,SAAA;AC9HF;;ADiIA;EACE,kBAAA;EACA,eAAA;EACA,MAAA;EACA,OAAA;EACA,QAAA;EACA,SAAA;EACA,sBAAA;EACA,mBAAA;EACA,gBAAA;AC9HF;;ADiIA;EACE,kBAAA;EACA,WAAA;EACA,YAAA;EACA,WAAA;EACA,SAAA;EACA,WAAA;EACA,uBAAA;EACA,kBAAA;EACA,gBAAA;AC9HF;;ADiIA;EACE,yBAAA;AC9HF;;ADiIA;EACE,2BAAA;AC9HF;;ADiIA;EACE,aAAA;EACA,oBAAA;AC9HF;;ADiIE;;EAGE,uBAAA;AC/HJ","file":"style.css"} \ No newline at end of file diff --git a/src/py/static/css/style.scss b/src/py/static/css/style.scss new file mode 100644 index 0000000..05fda39 --- /dev/null +++ b/src/py/static/css/style.scss @@ -0,0 +1,534 @@ +$primary-color: rgb(171, 211, 174); +$secondary-color: rgb(143, 188, 143); + +@import url("https://fonts.googleapis.com/css2?family=Akaya+Kanadaka&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Afacad:ital,wght@0,400..700;1,400..700&display=swap"); + +$font-titels: "Akaya Kanadaka", system-ui; + +$font-text: "Afacad", sans-serif; + +@mixin flexbox-center +{ + display: flex; + justify-content: center; +} + +@mixin groene-border +{ + border: solid 2px $primary-color; +} + +@mixin box-shadow +{ + box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5); +} + +@mixin border-radius +{ + border-radius: 40px; +} + +@mixin inner-border-radius +{ + border-radius: 35px; +} + +h1, +h2, +h3, +h4, +h5 +{ + font-family: $font-titels; + margin: 0; +} + +p, +td +{ + font-family: $font-text; + color: black; +} + +a +{ + text-decoration: none; +} + +body +{ + background: linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5)), url("../images/achtergrond.png"); + background-repeat: no-repeat; + background-size: cover; + background-position: center; + font-family: $font-text; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + margin: 0; + + .mainContainer + { + width: 85vw; + height: 38rem; + background-color: rgb(255, 255, 255, 85%); + border-radius: 40px; + padding: 2rem; + + .goodgarden-logo + { + position: absolute; + width: 10vw; + left: 50%; + top: 4.1rem; + transform: translateX(-50%); + } + + .informatie-kas-main-container + { + display: grid; + grid-template-columns: 5fr 7fr; + } + + .mainBorder + { + padding: 1.25rem 1.5rem; + padding: 1rem 0; + height: 35rem; + border: solid 5px $primary-color; + border-radius: 40px; + + .pagina-titel + { + font-size: 2rem; + margin-left: 1.5rem; + } + + #sectie-1 + { + display: flex; + flex-direction: column; + gap: 1rem; + padding: 0 2.5rem 0 1rem; + position: relative; + + h1 + { + background-color: green; + } + + .parent-algemeen-overzicht + { + @include box-shadow; + @include border-radius; + padding: 1rem; + margin-top: 1rem; + background-color: white; + + .algemeen-overzicht + { + @include groene-border; + @include inner-border-radius; + font-size: 1.25rem; + padding: 0.5rem 1rem; + + .table-informatie-kas + { + width: 100%; + + .tr-informatie-kas + { + display: flex; + justify-content: space-between; + text-align: left; + } + } + } + } + + .grafiek + { + @include box-shadow; + @include border-radius; + padding: 1rem; + position: relative; + background-color: white; + + .grafiek-innerbox + { + @include groene-border; + @include inner-border-radius; + font-size: 1.25rem; + padding: 0 1rem 2.5rem; + height: 225px; + position: relative; + + h2 + { + position: absolute; + left: 50%; + transform: translateX(-50%); + } + + canvas + { + // Zorgt ervoor dat de grafiek precies in eht midden komt + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + } + } + } + } + + .content + { + display: grid; + grid-template-columns: 3fr 1fr 3fr; + height: 100%; + + .kant + { + &-links + { + grid-column: 1; + + #planten + { + width: 100%; + border-collapse: collapse; + + td + { + article + { + height: 7rem; + width: 10rem; + padding: 0.6rem; + margin: 0.1rem; + margin-left: 2rem; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + border: solid 3px $primary-color; + border-radius: 40px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + + #toevoegen + { + height: 5rem; + width: 5rem; + } + + h2 + { + color: gray; + } + + &:hover + { + background-color: lightgray; + } + } + } + } + } + + &-rechts + { + grid-column: 3; + // margin-right: 2rem; + + #metingen + { + border: solid 3px $primary-color; + border-radius: 40px; + + #main-waardes + { + display: flex; + justify-content: space-between; + padding: 0.5rem; + padding-bottom: 0; + width: 100%; + + table + { + display: flex; + justify-content: space-between; + width: 100%; + } + } + } + } + } + } + + .grid-column-2 + { + @include box-shadow; + @include border-radius; + padding: 1rem; + margin: 3.25rem 1rem 1.25rem 1rem; + background-color: white; + + .grid-2-child + { + @include groene-border; + @include inner-border-radius; + height: 100%; + + .parent-table + { + padding: 1.5rem 2rem; + display: flex; + flex-direction: column; + align-items: stretch; + gap: 2.5rem; + justify-content: space-around; + height: 90%; + + table + { + tr + { + td + { + font-size: 1.05rem; + } + } + } + + .kas-table-1 + { + tr + { + td + { + font-size: 1.25rem; + } + } + } + + .kas-table-2 + { + position: relative; + + &::after, + &::before + { + content: ""; + position: absolute; + left: 0; + right: 0; + height: 1px; + width: 90%; + background: black; + } + + &::after + { + bottom: -20px; + } + + &::before + { + top: -20px; + } + } + } + } + } + } + } +} + +.divider { + display: flex; + justify-content: center; + border: solid 1px $primary-color; + border-radius: 5px; + width: 80%; + margin: 0 auto; +} + +.modal { + display: none; + position: fixed; + z-index: 999; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + background: white; + padding: 1.25rem; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + width: 30vw; + height: auto; + border: solid 2px #abd3ae; + border-radius: 10px; +} +.modal .close { + color: #aaa; + float: right; + font-size: 1.75rem; + font-weight: bold; +} +.modal .close:hover, +.modal .close:active { + color: black; + text-decoration: none; + cursor: pointer; +} + +#myModal select, +#myModal input { + width: calc(100% - 20px); + padding: 10px; + margin-bottom: 15px; + border: 2px solid #abd3ae; + border-radius: 5px; + box-sizing: border-box; +} + +#myModal .knop { + display: flex; + justify-content: space-between; +} + +#myModal button { + width: 48%; + padding: 10px; + box-sizing: border-box; + height: 40px; +} + +#myModal .knop-container { + display: flex; + justify-content: space-between; + margin-top: 20px; +} + +#myModal .knop-container input, +#myModal .knop-container button { + flex: 1; + margin: 0 5px; + padding: 10px; + box-sizing: border-box; +} + +#myModal input[type="text"], +#myModal select { + border: 2px solid #abd3ae; + padding: 10px; + border-radius: 17px; + box-sizing: border-box; +} + +#myModal input[type="submit"], +#myModal button { + color: #fff; + border: none; + border-radius: 15px; + cursor: pointer; +} + +#myModal input[type="submit"] { + background-color: white; +} + +#myModal button { + background-color: white; + color: black; +} + +.toevoeging { + background: linear-gradient(45deg, #abd3ae, #2ecc71); +} + +.annulatie-knop { + background: linear-gradient(45deg, #ffcc00, #ff6600); +} + +#myModal button:hover { + background: linear-gradient(45deg, #abd3ae, #fff); + color: #000; +} + +.modal .close { + color: #aaa; + float: right; + font-size: 1.75rem; + font-weight: bold; +} + +.modal .close:hover, +.modal .close:active { + color: black; + text-decoration: none; + cursor: pointer; +} + +.switch-container { + display: flex; + align-items: end; +} + +.switch { + position: relative; + display: inline-block; + width: 60px; + height: 30px; +} + +.switch input { + opacity: 0; + width: 0; + height: 0; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + border-radius: 34px; + transition: 0.4s; +} + +.slider:before { + position: absolute; + content: ""; + height: 26px; + width: 26px; + left: 4px; + bottom: 4px; + background-color: white; + border-radius: 50%; + transition: 0.4s; +} + +input:checked + .slider { + background-color: #2ecc71; +} + +input:checked + .slider:before { + transform: translateX(26px); +} + +.rechterkant { + display: flex; + justify-content: end; +} + + .plant-container, + #modalButton + { + background-color: white; + } diff --git a/src/images/Icon awesome-apple-alt.png b/src/py/static/images/Icon_awesome-apple-alt.png similarity index 100% rename from src/images/Icon awesome-apple-alt.png rename to src/py/static/images/Icon_awesome-apple-alt.png diff --git a/src/images/Toevoegen.png b/src/py/static/images/Toevoegen.png similarity index 100% rename from src/images/Toevoegen.png rename to src/py/static/images/Toevoegen.png diff --git a/src/images/achtergrond.png b/src/py/static/images/achtergrond.png similarity index 100% rename from src/images/achtergrond.png rename to src/py/static/images/achtergrond.png diff --git a/src/images/logo.png b/src/py/static/images/logo.png similarity index 100% rename from src/images/logo.png rename to src/py/static/images/logo.png diff --git a/src/py/static/js/main.js b/src/py/static/js/main.js new file mode 100644 index 0000000..ad6370a --- /dev/null +++ b/src/py/static/js/main.js @@ -0,0 +1,300 @@ +// const { ipcRenderer } = require("electron"); + +// document.addEventListener('DOMContentLoaded', () => +// { +// ipcRenderer.send('request-update-temp', ['some', 'arguments']); + +// ipcRenderer.on('update-temp-result', (event, newTemperature) => { +// if (newTemperature === 'error') { +// console.error('Er is een fout opgetreden bij het ophalen van de nieuwe temperatuur'); +// } else { +// document.getElementById('bodem-temperatuur').textContent = newTemperature; +// } +// }); + +// }); + +// function openModal() +// { +// const modal = document.getElementById("myModal"); +// const button = document.getElementById("modalButton"); +// const close = document.getElementsByClassName("close")[0]; + +// // Toon de modal wanneer op de knop wordt geklikt +// button.onclick = function() +// { +// modal.style.display = "block"; +// } + +// // Sluit de modal wanneer op het 'sluiten' icoon wordt geklikt +// close.onclick = function() +// { +// modal.style.display = "none"; +// } + +// // Sluit de modal wanneer buiten de modal wordt geklikt +// window.onclick = function(event) +// { +// if (event.target == modal) +// { +// modal.style.display = "none"; +// } +// } +// } + +// /** +// * --- Functie om de grafiek te tekenen. Enigste belangrijke is de eerste 2 "const" arrays "data" & "xLabels". +// */ +// function drawLineChart() +// { +// /*Dit is de data die getoond wordt als "punt" op de grafiek. 20 = y20 / x20, 50 = y50 / x50 enzovoort... De array "data" & "xLabels" moeten beide evenveel array items hebben!!*/ +// const data = [20, 50, 60, 45, 50, 100, 70, 60, 65, 0, 85, 0]; +// const xLabels = ["", "", "", "", "", 6, "", "", "", "", "", 12]; + +// const yLabels = ["", 20, "", 40, "", 60, "", 80, "", 100]; /*NIET VERANDEREN!!!*/ + +// const canvas = document.getElementById("myCanvas"); +// const ctx = canvas.getContext("2d"); + +// ctx.clearRect(0, 0, canvas.width, canvas.height); + +// const padding = 35; // Increased padding for Y labels +// const graphWidth = canvas.width - padding * 2; +// const graphHeight = canvas.height - padding * 2; + +// ctx.beginPath(); +// ctx.moveTo(padding, padding); +// ctx.lineTo(padding, canvas.height - padding); +// ctx.lineTo(canvas.width - padding, canvas.height - padding); +// ctx.stroke(); + +// // Set the color of the line +// ctx.strokeStyle = "rgb(143, 188, 143)"; + +// const xIncrement = graphWidth / (xLabels.length - 1); +// const yIncrement = graphHeight / (yLabels.length - 1); + +// // Plot the data +// ctx.beginPath(); +// ctx.moveTo(padding, canvas.height - padding - (data[0] / 100) * graphHeight); + +// for (let i = 1; i < data.length; i++) +// { +// const xPos = padding + i * xIncrement; +// const yPos = canvas.height - padding - (data[i] / 100) * graphHeight; +// ctx.lineTo(xPos, yPos); +// } +// ctx.stroke(); + +// // Draw Y labels +// ctx.fillStyle = "black"; +// ctx.textAlign = "right"; // Align text to the right +// ctx.textBaseline = "middle"; // Center vertically + +// for (let i = 0; i < yLabels.length; i++) +// { +// if (yLabels[i] !== "") +// { +// const yPos = canvas.height - padding - i * yIncrement; +// ctx.fillText(yLabels[i], padding - 10, yPos); +// } +// } + +// // Draw X labels +// ctx.textAlign = "center"; // Center horizontally for X labels +// for (let i = 0; i < xLabels.length; i++) +// { +// if (xLabels[i] !== "") +// { +// const xPos = padding + i * xIncrement; +// ctx.fillText(xLabels[i], xPos, canvas.height - padding + 20); +// } +// } +// } + +// drawLineChart(); + +// ///////////////////////////////// + +// // Function to fetch battery data from Flask API +// function fetchBatteryData() { +// axios.get('http://127.0.0.1:5000') +// .then(response => { +// const batteryData = response.data; +// updateBatteryData(batteryData); +// }) +// .catch(error => { +// console.error('Error fetching battery data:', error); +// }); +// } + +// // Function to update HTML content with battery data +// function updateBatteryData(batteryData) { +// document.getElementById('deviceNumber').innerText = batteryData.device; +// document.getElementById('voltage').innerText = batteryData.value; +// document.getElementById('time').innerText = batteryData.gateway_receive_time; +// document.getElementById('tevredenheid').innerText = batteryData.timestamp; + +// // Voeg andere eigenschappen toe zoals nodig +// } + +// // Fetch battery data when the page loads +// fetchBatteryData(); +///////////////////////////////// + +const { ipcRenderer } = require("electron"); +const axios = require('axios'); + +// document.addEventListener('DOMContentLoaded', () => { + ipcRenderer.send('request-update-temp', ['some', 'arguments']); + + ipcRenderer.on('update-temp-result', (event, newTemperature) => { + if (newTemperature === 'error') { + console.error('Er is een fout opgetreden bij het ophalen van de nieuwe temperatuur'); + } else { + document.getElementById('bodem-temperatuur').textContent = newTemperature; + } + }); + + // Send a message to the main process to execute the Python script + ipcRenderer.send('run-python-script', ['some', 'arguments']); + + ipcRenderer.on('python-script-response', (event, pythonData) => { + if (pythonData === 'error') { + console.error('An error occurred while retrieving data from Python'); + } else { + // Update HTML elements with data received from Python + document.getElementById('bodem-temperatuur').textContent = pythonData.bodemTemperatuur; // Adjust the property based on your actual Python response + } + }); + + // Listen for updates to HTML data from the main process + ipcRenderer.on('update-html-data', (event, data) => { + // Update the HTML with the received data + document.getElementById('batteryVoltage').innerText = data.batteryVoltage; + // Add similar lines for other data fields + }); + + // Trigger an event to request data update + ipcRenderer.send('request-update-data'); + + // Function to open the modal + function openModal() { + const modal = document.getElementById("myModal"); + const button = document.getElementById("modalButton"); + const close = document.getElementsByClassName("close")[0]; + + // Check if elements are found before attaching events + if (modal && button && close) { + // Show the modal when the button is clicked + button.onclick = function () { + modal.style.display = "block"; + } + + // Close the modal when the 'close' icon is clicked + close.onclick = function () { + modal.style.display = "none"; + } + + // Close the modal when clicked outside the modal + window.onclick = function (event) { + if (event.target == modal) { + modal.style.display = "none"; + } + } + } + } + + // Call the function to open the modal + openModal(); + + /** + * --- Function to draw the chart. The important arrays are "data" & "xLabels". + */ + function drawLineChart() { + const data = [20, 50, 60, 45, 50, 100, 70, 60, 65, 0, 85, 0]; + const xLabels = ["", "", "", "", "", 6, "", "", "", "", "", 12]; + const yLabels = ["", 20, "", 40, "", 60, "", 80, "", 100]; /*NIET VERANDEREN!!!*/ + + const canvas = document.getElementById("myCanvas"); + const ctx = canvas.getContext("2d"); + + ctx.clearRect(0, 0, canvas.width, canvas.height); + + const padding = 35; // Increased padding for Y labels + const graphWidth = canvas.width - padding * 2; + const graphHeight = canvas.height - padding * 2; + + ctx.beginPath(); + ctx.moveTo(padding, padding); + ctx.lineTo(padding, canvas.height - padding); + ctx.lineTo(canvas.width - padding, canvas.height - padding); + ctx.stroke(); + + // Set the color of the line + ctx.strokeStyle = "rgb(143, 188, 143)"; + + const xIncrement = graphWidth / (xLabels.length - 1); + const yIncrement = graphHeight / (yLabels.length - 1); + + // Plot the data + ctx.beginPath(); + ctx.moveTo(padding, canvas.height - padding - (data[0] / 100) * graphHeight); + + for (let i = 1; i < data.length; i++) { + const xPos = padding + i * xIncrement; + const yPos = canvas.height - padding - (data[i] / 100) * graphHeight; + ctx.lineTo(xPos, yPos); + } + ctx.stroke(); + + // Draw Y labels + ctx.fillStyle = "black"; + ctx.textAlign = "right"; // Align text to the right + ctx.textBaseline = "middle"; // Center vertically + + for (let i = 0; i < yLabels.length; i++) { + if (yLabels[i] !== "") { + const yPos = canvas.height - padding - i * yIncrement; + ctx.fillText(yLabels[i], padding - 10, yPos); + } + } + + // Draw X labels + ctx.textAlign = "center"; // Center horizontally for X labels + for (let i = 0; i < xLabels.length; i++) { + if (xLabels[i] !== "") { + const xPos = padding + i * xIncrement; + ctx.fillText(xLabels[i], xPos, canvas.height - padding + 20); + } + } + } + + // Call the function to draw the line chart + drawLineChart(); + + // Function to fetch battery data from Flask API + function fetchBatteryData() { + axios.get('http://127.0.0.1:5000') + .then(response => { + const batteryData = response.data; + updateBatteryData(batteryData); + }) + .catch(error => { + console.error('Error fetching battery data:', error); + }); + } + + // Function to update HTML content with battery data + function updateBatteryData(batteryData) { + document.getElementById('deviceNumber').innerText = batteryData.device; + document.getElementById('voltage').innerText = batteryData.value; + document.getElementById('time').innerText = batteryData.gateway_receive_time; + document.getElementById('zulu').innerText = batteryData.timestamp; + + // Voeg andere eigenschappen toe zoals nodig + } + + // Fetch battery data when the page loads + fetchBatteryData(); +// }); \ No newline at end of file diff --git a/src/py/static/js/planten.class.js b/src/py/static/js/planten.class.js new file mode 100644 index 0000000..7f3fe96 --- /dev/null +++ b/src/py/static/js/planten.class.js @@ -0,0 +1,104 @@ +class Plant { + constructor(dataObject) { + this.id = dataObject.id; + this.plantNaam = dataObject.plant_naam; // Note the property name change + this.plantensoort = dataObject.plantensoort; + this.plantGeteelt = dataObject.plant_geteelt; + } +} + +class PlantGrid { + constructor() { + this.grid = []; + this.cols = 2; // Number of columns + this.rows = 4; // Number of rows (including the row for the "Add" button) + + // Initialize the grid with null values + for (let i = 0; i < this.rows; i++) { + this.grid[i] = new Array(this.cols).fill(null); + } + + // Load JSON data from the server + this.loadData(); + } + + loadData() { + fetch('../script/plants.json') // Assuming your JSON data is stored in 'plants.json' + .then(response => { + if (!response.ok) { + throw new Error('Network response was not ok'); + } + return response.json(); + }) + .then(data => { + const filteredData = data.filter(plantObject => plantObject.plant_geteelt === 1); + + // Populate the grid with plant objects + filteredData.slice(0, 8).forEach((plantObject, index) => { + const plant = new Plant(plantObject); + const col = index % this.cols; + const row = Math.floor(index / this.cols); + this.grid[row][col] = plant; + }); + + // Display the grid in the HTML table with id "planten" + this.displayGrid(); + }) + .catch(error => console.error('Error loading data:', error)); + } + + displayGrid() { + const plantenTable = document.getElementById("planten"); + + let itemCount = 0; // Counter for the number of items in the grid + + this.grid.forEach((row, rowIndex) => { + const tr = document.createElement("tr"); + + row.forEach((plant, colIndex) => { + const td = document.createElement("td"); + + if (itemCount < 8) { + if (plant) { + // Handle regular plant items + const link = document.createElement("a"); + link.href = `planteninfo.html?id=${plant.id}`; // Link naar de planteninfo pagina met plant id als query parameter + + const article = document.createElement("article"); + article.classList.add("plant-container"); + link.appendChild(article); // Voeg het artikel toe aan de link + + const img = article.appendChild(document.createElement("img")); + img.src = "../static/images/icon_awesome-apple-alt.png"; + const h2 = article.appendChild(document.createElement("h2")); + h2.classList.add("plant-naam"); + h2.textContent = plant.plantNaam; + + td.appendChild(link); // Voeg de link toe aan de td + itemCount++; + } else if (rowIndex === this.rows - 1 && colIndex === this.cols - 1 && itemCount <= 7) { + // Handle the "Add" button + const article = document.createElement("article"); + const img = article.appendChild(document.createElement("img")); + img.src = "../static/images/Toevoegen.png"; + img.id = "toevoegen"; + img.alt = "Add"; + article.id = "modalButton"; + article.onclick = openModal; + + td.appendChild(article); + itemCount++; + } + } + + tr.appendChild(td); + }); + + plantenTable.appendChild(tr); + }); + } +} + +document.addEventListener("DOMContentLoaded", () => { + const plantGrid = new PlantGrid(); +}); diff --git a/src/py/templates/index.html b/src/py/templates/index.html new file mode 100644 index 0000000..e64b3b3 --- /dev/null +++ b/src/py/templates/index.html @@ -0,0 +1,108 @@ + + + + + + + + + Dashboard + + + + + +
+
+ + + +
+
+
+ + +
+
+
+
+ +
+
+

Zonlicht

+ +
+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/src/py/templates/kas_informatie.html b/src/py/templates/kas_informatie.html new file mode 100644 index 0000000..c41e3ba --- /dev/null +++ b/src/py/templates/kas_informatie.html @@ -0,0 +1,126 @@ + + + + + + + + + + + Informatie Kas + + +
+
+ + + +
+
+
+

Informatie Kas

+
+
+
+ + + + + + + + + + + + + + + + + +
Device
Batterij Voltage
Tijden
Zulu
+
+
+
+
+

Zonlicht

+ +
+
+
+
+
+
+
+ + + + + + + + + + + + + +
Aantal geplant:Loading...
Succesvolle Oogst:2
Gefaalde Oogst:2
+ + + + + + + + + + + + + + + + + +
Warmste Maand:n.v.t.
koudste Maand:December
Gemiddelde Bodemtemp.:2˚C
Gemiddelde Uren Zonlicht:2u
+ + + + + + + + + + + + + + + + + +
Laatste Irrigatie:2u
Aankomende Irrigatie:2u
Laatste Bemesting2d
Aankomende Bemesting:2w
+
+
+
+
+
+ + + diff --git a/src/py/templates/planteninfo.html b/src/py/templates/planteninfo.html new file mode 100644 index 0000000..5b6ab93 --- /dev/null +++ b/src/py/templates/planteninfo.html @@ -0,0 +1,118 @@ + + + + + + + + + + + Informatie Kas + + +
+
+ + + +
+
+
+

Informatie Kas

+
+
+
+ + + + + + + + + + + + + + + + + +
Dagen tot Oogst12
Dagen in Kas2
Tevredenheid80%
Aandachtspunten1
+
+
+
+
+

Zonlicht

+ +
+
+
+
+
+
+
+ + + + + + + + + + + + + +
Aantal geplant:2
Succesvolle Oogst:2
Gefaalde Oogst:2
+ + + + + + + + + + + + + + + + + +
Warmste Maand:n.v.t.
koudste Maand:December
Gemiddelde Bodemtemp.:2˚C
Gemiddelde Uren Zonlicht:2u
+ + + + + + + + + + + + + + + + + +
Laatste Irrigatie:2u
Aankomende Irrigatie:2u
Laatste Bemesting2d
Aankomende Bemesting:2w
+
+
+
+
+
+ +