22 Commits
Author SHA1 Message Date
leukipp ac62dc17ce build: update version 2025-09-19 22:07:45 +02:00
leukipp f2f80e7d52 fix: mqtt config removal #79 2025-09-19 22:07:14 +02:00
leukipp 10e7ff078a build: update version 2025-09-19 16:49:12 +02:00
leukipp e677fff160 docs: update readme 2025-09-19 16:36:57 +02:00
leukipp 63db26611e build: update dependencies 2025-09-19 15:57:13 +02:00
leukipp 5ec6577b5a fix: option to ignore certificate errors #76 2025-09-19 15:52:09 +02:00
leukipp 0359742e70 docs: update readme 2025-09-11 08:55:00 +02:00
leukipp b70f4074e5 docs: add hardware 2025-09-10 16:43:24 +02:00
leukipp a4c300407b ref: remove unsupported mqtt config 2025-09-10 16:00:26 +02:00
leukipp 758f64ced4 ref: add cpu thermal zone 2025-09-10 15:49:22 +02:00
leukipp 7ab803d4ca ref: app update summary 2025-09-09 20:50:56 +02:00
leukipp 092697850d build: compress zip 2025-09-09 19:59:30 +02:00
leukipp 422e92dd89 build: update version 2025-09-09 19:41:09 +02:00
leukipp a15c0fc91d docs: update readme 2025-09-09 19:33:33 +02:00
leukipp 358fa3ca9c ref: use display status callback 2025-09-09 17:25:56 +02:00
leukipp 10722fa217 build: update build.json 2025-09-08 21:31:01 +02:00
leukipp 7267fafb97 ref: add console logs 2025-09-08 20:03:23 +02:00
leukipp b5e95936dc ref: obfuscate logged password 2025-09-08 18:58:29 +02:00
leukipp 047b38a41b feat: extended logging #73 2025-09-08 17:31:42 +02:00
leukipp a93fbb2ad3 build: update dependencies 2025-09-08 17:18:16 +02:00
leukipp 0b927a3ef6 fix: touch event handling for inactive screens #61 2025-09-08 16:23:04 +02:00
leukipp d35cf27de9 fix: update last active only on touch #71 2025-09-08 09:56:27 +02:00
9 changed files with 692 additions and 346 deletions
+1
View File
@@ -41,6 +41,7 @@ If you are running Linux with a graphical user interface (Wayland or X11), you s
| Raspberry Pi 5 (arm64) | Raspberry Pi OS (64-bit), Wayland, X11 | [ELECROW Portable Monitor 10.1" (1280x800)](https://www.amazon.co.uk/dp/B0BHHQLKPY) | 🟨 |
| Raspberry Pi 5 (arm64) | Raspberry Pi OS (64-bit), Wayland, X11 | Generic Non-Touch | 🟨 |
| Generic PC (x64) | Debian KDE (64-bit), Wayland, X11 | Generic Non-Touch | 🟧 |
| Generic PC (x64) | Ubuntu XFCE (64-bit), X11 | Generic Non-Touch | 🟧 |
| Generic PC (x64) | Ubuntu GNOME (64-bit), X11 | Generic Non-Touch | 🟧 |
| Generic PC (x64) | Ubuntu GNOME (64-bit), Wayland | Generic Non-Touch | 🟥 |
+21 -11
View File
@@ -17,13 +17,14 @@ Moreover, the device running the **kiosk application** also offers several **Hom
- [x] Configurable browser zoom and theme support.
- [x] Extended touch screen wake-up functionality.
- [x] Remote controllable via MQTT.
- [x] Manage kiosk window status.
- [x] Toggle the on-screen keyboard.
- [x] Touch display power and brightness.
- [x] Manage kiosk window status and zoom.
- [x] Show network interfaces and addresses.
- [x] List all available system package upgrades.
- [x] Multi-webpage switching and url navigation.
- [x] Monitor temperature, processor and memory usage.
- [x] Execute system reboot and shutdown commands.
- [x] Show available system package upgrades.
The kiosk application can be executed with command line arguments to load a **Home Assistant dashboard in fullscreen** mode.
Additionally, a **MQTT endpoint** can be defined, allowing the application to provide controls and sensors for the Linux device and the connected Touch Display.
@@ -91,7 +92,8 @@ yarn build
#### Update
If you have already installed TouchKio and want to upgrade to the latest version, simply install the newer version over the existing one.
The [install.sh](https://github.com/leukipp/touchkio/blob/main/install.sh) script can also be run to update an existing installation to the **latest version**. The setup procedure can be skipped to use the existing default arguments from the configuration file:
The [install.sh](https://github.com/leukipp/touchkio/blob/main/install.sh) script can also be run to update an existing installation to the **latest version**.
The setup procedure can be skipped to use the existing default arguments from the configuration file:
```bash
bash <(wget -qO- https://raw.githubusercontent.com/leukipp/touchkio/main/install.sh) update
```
@@ -249,9 +251,10 @@ Implementing stronger **security measures** would complicate the setup process a
When using the kiosk application without initializing the default arguments, you will need to provide them with every command.
This means that the password may be stored as plain text in various files, such as `touchkio.service`, `~/.bash_history`, etc.
To resolve the issue where the first **touch** on a **turned-off screen** triggers a **click event** (which could inadvertently activate Home Assistant actions), a workaround needed to be implemented.
When the screen **turns off** the **focus** is removed from the kiosk window.
This way, the first click only turns the screen on and focuses the window, allowing subsequent clicks to work as expected.
To address the problem where the first **touch** on a **turned-off screen** may trigger a **click event** (which could inadvertently activate Home Assistant actions), a workaround needed to be implemented.
When the screen **turns on/off**, the timestamps of these events are recorded.
If a touch event is detected and the **timestamp** of the **last screen-off** is more recent than the **last screen-on** timestamp, the touch event is discarded and the screen is turned on instead.
From that point onward, subsequent touch interactions will function normally as expected.
Additionally, to address the problem that scrolling only works with the **web browser scrollbar** on the right, the application is configured to **simulate a touch device** using `Emulation.setEmitTouchEventsForMouse`.
This adjustment provides a user experience similar to that of a proper mobile device.
@@ -259,7 +262,7 @@ This adjustment provides a user experience similar to that of a proper mobile de
</div></details>
## Issues
Please have a look into the [hardware](https://github.com/leukipp/touchkio/blob/main/HARDWARE.md) documentation if you ran into any issues.
Please review the [hardware](https://github.com/leukipp/touchkio/blob/main/HARDWARE.md) documentation first if you encounter any problems.
**Minimal features** are designed to run on any system without issues:
- A webview kiosk window launched in fullscreen mode and loading the specified `--web-url` website should not cause any problems.
@@ -267,7 +270,7 @@ Please have a look into the [hardware](https://github.com/leukipp/touchkio/blob/
**Extended features** become available when the `--mqtt-*` arguments are provided and the hardware is supported:
- If your hardware is not fully compatible there should be no crashes, but you may miss some sensors.
- On some Debian based systems (e.g. Ubuntu GNOME), the display status control may only be available when using X11.
- The following commands are currently implemented to modify the display status.
- The following commands are currently implemented to modify the display status. Make sure that one of these works for your display when you run it directly on the terminal, otherwise the MQTT switch will not work either.
- `wlopm --[on]/[off] *` (Raspberry Pi OS, Wayland)
- `kscreen-doctor --dpms [on]/[off]` (Debian KDE, Wayland)
- `xset dpms force [on]/[off]` (Generic, X11)
@@ -282,13 +285,20 @@ Please have a look into the [hardware](https://github.com/leukipp/touchkio/blob/
- On the terminal you may see some *ERROR:gbm_wrapper.cc* messages.
- This appears to be a [known issue](https://github.com/electron/electron/issues/42322) that currently lacks a fix, but the webview still works.
For debugging, stop the service and run `touchkio` directly on the terminal to view the log outputs.
If you encounter any problems, please [create an issue](https://github.com/leukipp/touchkio/issues) and include the output of `touchkio --version` along with your system setup and any additional terminal logs.
For debugging, stop the service and launch `touchkio` directly on the terminal to monitor the log output in real-time.
This output is also written into `~/.config/touchkio/logs/main.log` for review.
If you encounter any problems, please [create an issue](https://github.com/leukipp/touchkio/issues) and include the output of `touchkio --version`, additional information's about your system (such as operating system, hardware specs, etc.) and any relevant log files.
## Credits
Thanks to Sebastian ([@pdsccode](https://github.com/pdsccode)) for his contributions on issues and [community](https://community.home-assistant.io/t/kiosk-mode-for-raspberry-pi-with-touch-display/821196) discussions.
[Inspired by](https://www.jeffgeerling.com/blog/2024/home-assistant-and-carplay-pi-touch-display-2) the one and only Raspberry Pi Master, Jeff Geerling ([@geerlingguy](https://github.com/geerlingguy)).
Thanks to Sebastian ([@pdsccode](https://github.com/pdsccode)) for his contributions on issues and [community](https://community.home-assistant.io/t/kiosk-mode-for-raspberry-pi-with-touch-display/821196) discussions.
If you are looking for hardware or a well-designed mounting solution for the Raspberry Pi Display, check out the [blog post](https://www.thestockpot.net/videos/home-assistant-wall-display) from Dillan Stock ([@TheStockPot-AU](https://www.youtube.com/channel/UCmlzNHg8QiWVutUyFOV2UdQ)).
[![What My Smart Home Was Missing](https://img.youtube.com/vi/uTxURzmrVtA/maxresdefault.jpg)](https://www.youtube.com/watch?v=uTxURzmrVtA)
## License
[MIT](https://github.com/leukipp/touchkio/blob/main/LICENSE)
+4 -4
View File
@@ -62,13 +62,13 @@ module.exports = {
for (const result of results) {
const artifacts = [];
for (const artifact of result.artifacts) {
// Currently disabled for zip files as it seems to corrupt them
if (artifact.includes(".zip") && false) {
if (artifact.includes(".zip")) {
const [name, platform, arch] = path.basename(artifact).split("-");
const buildFile = path.join(`${name}-${platform}-${arch}`, "resources", "app", "build.json");
const zip = await jszip.loadAsync(fs.readFileSync(artifact, "utf8"));
const options = { type: "nodebuffer", compression: "DEFLATE", compressionOptions: { level: 9 } };
const zip = await jszip.loadAsync(fs.readFileSync(artifact));
zip.file(buildFile, generateBuildFile(platform, arch, "zip"));
fs.writeFileSync(artifact, await zip.generateAsync({ type: "nodebuffer" }));
fs.writeFileSync(artifact, await zip.generateAsync(options));
}
if (artifact.includes("amd64")) {
const renamed = artifact.replace("amd64", "x64");
+33 -2
View File
@@ -5,10 +5,13 @@ const readline = require("readline/promises");
const integration = require("./js/integration");
const hardware = require("./js/hardware");
const webview = require("./js/webview");
const log = require("electron-log");
const { app } = require("electron");
const Events = require("events");
global.APP = global.APP || {};
global.ARGS = global.ARGS || {};
global.EVENTS = global.EVENTS || new Events();
if (!process.env.DISPLAY) {
console.error(`\n$DISPLAY variable not set to run the GUI application, are you connected via SSH?\n`);
@@ -24,12 +27,16 @@ if (!process.env.DISPLAY) {
* initialization tasks.
*/
app.whenReady().then(async () => {
if (!(await initApp()) || !(await initArgs())) {
if (!(await initApp()) || !(await initArgs()) || !(await initLog())) {
return;
}
// Show used arguments
console.log(`Arguments: ${JSON.stringify(ARGS, null, 2)}`);
const args = Object.assign({}, ARGS);
if ("mqtt_password" in args) {
args.mqtt_password = "*".repeat((args.mqtt_password || "").length);
}
console.log(`Arguments: ${JSON.stringify(args, null, 2)}`);
// Chained init functions
const chained = [webview.init, hardware.init, integration.init];
@@ -58,6 +65,7 @@ const initApp = async () => {
APP.version = app.getVersion();
APP.path = app.getAppPath();
APP.config = app.getPath("userData");
APP.log = path.join(app.getPath("logs"), "main.log");
// Set additional update infos
APP.homepage = `https://github.com/${packageJson.author}/${packageJson.name}`;
@@ -133,6 +141,29 @@ const initArgs = async () => {
return true;
};
/**
* Initializes the global log object.
*
* @returns {bool} Returns true if the initialization was successful.
*/
const initLog = async () => {
try {
if (fs.existsSync(APP.log)) {
fs.unlinkSync(APP.log);
}
} catch (error) {
console.error("Failed to delete log file:", error.message);
}
// Overwrite console log settings
log.transports.file.resolvePathFn = () => {
return APP.log;
};
Object.assign(console, log.functions);
return true;
};
/**
* Parses command-line arguments from the given process object.
*
+29 -26
View File
@@ -3,13 +3,11 @@ const fs = require("fs");
const path = require("path");
const fsp = require("fs/promises");
const cpr = require("child_process");
const Events = require("events");
global.HARDWARE = global.HARDWARE || {
initialized: false,
events: new Events(),
session: {},
support: {},
session: {},
battery: {
level: {
path: null,
@@ -39,7 +37,7 @@ global.HARDWARE = global.HARDWARE || {
*/
const init = async () => {
if (!compatibleSystem()) {
console.warn("Operating system is not supported\n");
console.error("Operating system is not supported");
return false;
}
@@ -56,33 +54,35 @@ const init = async () => {
HARDWARE.initialized = true;
// Show supported features
console.log(`\nSupported: ${JSON.stringify(HARDWARE.support, null, 2)}`);
process.stdout.write("\n");
console.log(`Supported: ${JSON.stringify(HARDWARE.support, null, 2)}`);
// Show session infos
console.log("\nUser:", HARDWARE.session.user);
process.stdout.write("\n");
console.log("User:", HARDWARE.session.user);
console.log("Session:", HARDWARE.session.type);
console.log("Desktop:", HARDWARE.session.desktop);
// Show device infos
console.log("\nModel:", getModel());
process.stdout.write("\n");
console.log("Model:", getModel());
console.log("Vendor:", getVendor());
console.log("Serial Number:", getSerialNumber());
console.log("Network Addresses:", getNetworkAddresses());
console.log("Host Name:", getHostName());
// Show system infos
console.log("\nUp Time:", getUpTime());
process.stdout.write("\n");
console.log("Up Time:", getUpTime());
console.log("Memory Size:", getMemorySize());
console.log("Memory Usage:", getMemoryUsage());
console.log("Processor Usage:", getProcessorUsage());
console.log("Processor Temperature:", getProcessorTemperature());
// Show hardware infos
process.stdout.write("\n");
const unsupported = "unsupported";
console.log(
`\nBattery Level [${HARDWARE.battery.level.path || unsupported}]:`,
`${getBatteryLevel() || unsupported}`,
);
console.log(`Battery Level [${HARDWARE.battery.level.path || unsupported}]:`, `${getBatteryLevel() || unsupported}`);
console.log(
`Display Status [${HARDWARE.display.status.path || unsupported}]:`,
`${getDisplayStatus() || unsupported} (${HARDWARE.display.status.command || unsupported})`,
@@ -93,10 +93,11 @@ const init = async () => {
);
console.log(
`Keyboard Visibility [${HARDWARE.support.keyboardVisibility ? "squeekboard" : unsupported}]:`,
`${getKeyboardVisibility() || unsupported}\n`,
`${getKeyboardVisibility() || unsupported}`,
);
// Check for keyboard visibility
process.stdout.write("\n");
setKeyboardVisibility("OFF", (reply, error) => {
if (!reply || error) {
return;
@@ -106,12 +107,14 @@ const init = async () => {
return;
}
HARDWARE.keyboard.visibility = property.Visible === "true";
HARDWARE.events.emit("updateKeyboard");
EVENTS.emit("updateKeyboard");
});
});
// Check for display changes
setDisplayStatus("ON", () => {
interval(update, 1000);
});
return true;
};
@@ -130,7 +133,7 @@ const update = async () => {
if (status !== HARDWARE.display.status.value) {
console.log("Update Display Status:", getDisplayStatus());
HARDWARE.display.status.value = status;
HARDWARE.events.emit("updateDisplay");
EVENTS.emit("updateDisplay");
}
}
@@ -140,7 +143,7 @@ const update = async () => {
if (brightness !== HARDWARE.display.brightness.value) {
console.log("Update Display Brightness:", getDisplayBrightness());
HARDWARE.display.brightness.value = brightness;
HARDWARE.events.emit("updateDisplay");
EVENTS.emit("updateDisplay");
}
}
};
@@ -369,7 +372,7 @@ const getProcessorTemperature = () => {
continue;
}
const type = fs.readFileSync(typeFile, "utf8").trim();
if (["cpu-thermal", "x86_pkg_temp", "k10temp", "acpitz"].includes(type)) {
if (["cpu-thermal", "x86_pkg_temp", "k10temp", "acpitz", "cpu"].includes(type)) {
return parseFloat(fs.readFileSync(tempFile, "utf8").trim()) / 1000;
}
}
@@ -796,24 +799,24 @@ const execAsyncCommand = (cmd, args = [], callback = null) => {
* @returns {Object} The spawned process object.
*/
const execScriptCommand = (cmd, args = [], callback = null) => {
let progress = 10;
let progress = 1;
let proc = cpr.spawn(cmd, args);
if (typeof callback === "function") callback(progress, null);
proc.stdout.on("data", (data) => {
if (data) {
const lines = data.toString().trim();
const output = lines.replace(/\n+/g, "\n").replace(/^\n+|\n+$|\0/g, "");
if (output) {
console.log(output);
const output = data.toString().trim();
const lines = output.replace(/\n+/g, "\n").replace(/^\n+|\n+$|\0/g, "");
for (const line of lines.split("\n").filter(Boolean)) {
console.log(line);
}
}
});
proc.stderr.on("data", (data) => {
if (data) {
const lines = data.toString().trim();
const output = lines.replace(/\n+/g, "\n").replace(/^\n+|\n+$|\0/g, "");
if (output) {
const matches = output.match(/(\d{1,3})%/g);
const output = data.toString().trim();
const lines = output.replace(/\n+/g, "\n").replace(/^\n+|\n+$|\0/g, "");
for (const line of lines.split("\n").filter(Boolean)) {
const matches = line.match(/(\d{1,3})%/g);
if (matches) {
const match = Math.max(...matches.map((p) => parseInt(p)));
const percent = Math.floor(match / 10) * 10;
+86 -52
View File
@@ -1,11 +1,9 @@
const mqtt = require("mqtt");
const hardware = require("./hardware");
const { app } = require("electron");
const Events = require("events");
global.INTEGRATION = global.INTEGRATION || {
initialized: false,
events: new Events(),
};
/**
@@ -51,15 +49,17 @@ const init = async () => {
};
// Connection settings
const options = user === null || password === null ? null : { username: user, password: password };
const masked = password === null ? "null" : "*".repeat(password.length);
const masked = password === null ? null : "*".repeat(password.length);
const options = user === null || password === null ? {} : { username: user, password: password };
options.rejectUnauthorized = !("ignore_certificate_errors" in ARGS);
console.log("MQTT Connecting:", `${user}:${masked}@${url.toString()}`);
INTEGRATION.client = mqtt.connect(url.toString(), options);
// Client connected
INTEGRATION.client
.once("connect", () => {
console.log(`MQTT Connected: ${url.toString()}\n`);
console.log(`MQTT Connected: ${url.toString()}`);
process.stdout.write("\n");
// Init client controls
initApp();
@@ -96,8 +96,8 @@ const init = async () => {
});
// Update sensor states from events
HARDWARE.events.on("updateDisplay", updateDisplay);
HARDWARE.events.on("updateKeyboard", updateKeyboard);
EVENTS.on("updateDisplay", updateDisplay);
EVENTS.on("updateKeyboard", updateKeyboard);
// Update time sensors periodically (30s)
setInterval(() => {
@@ -141,6 +141,22 @@ const update = async () => {
updateBatteryLevel();
};
/**
* Removes the auto-discovery config via the mqtt connection.
*
* @param {string} type - The entity type name.
* @param {Object} config - The configuration object.
* @returns {Object} Instance of the mqtt client.
*/
const removeConfig = (type, config) => {
if (type === null || config === null) {
return INTEGRATION.client;
}
const path = config.unique_id.replace(`${INTEGRATION.node}_`, "");
const root = `${INTEGRATION.discovery}/${type}/${INTEGRATION.node}/${path}/config`;
return INTEGRATION.client.publish(root, JSON.stringify({}), { qos: 1, retain: true });
};
/**
* Publishes the auto-discovery config via the mqtt connection.
*
@@ -191,9 +207,6 @@ const publishState = (path, state) => {
* Initializes the app update entity and handles the execute logic.
*/
const initApp = () => {
if (!HARDWARE.support.appUpdate) {
return;
}
const root = `${INTEGRATION.root}/app`;
const config = {
name: "App",
@@ -203,15 +216,23 @@ const initApp = () => {
payload_install: "update",
device: INTEGRATION.device,
};
if (!HARDWARE.support.appUpdate) {
removeConfig("update", config);
return;
}
publishConfig("update", config)
.on("message", (topic, message) => {
if (topic === config.command_topic) {
console.log("Update App...");
hardware.setDisplayStatus("ON");
hardware.setDisplayStatus("ON", () => {
const args = ["-c", `bash <(wget -qO- ${APP.scripts.install}) update`];
hardware.execScriptCommand("bash", args, (progress, error) => {
if (progress) {
console.log(`Progress: ${progress}%`);
}
updateApp(progress);
});
});
}
})
.subscribe(config.command_topic);
@@ -223,14 +244,15 @@ const initApp = () => {
*/
const updateApp = async (progress = 0) => {
const latest = APP.releases.latest;
if (!latest) {
if (!HARDWARE.support.appUpdate || !latest || !latest.summary) {
return;
}
const summary = latest.summary.length > 250 ? latest.summary.slice(0, 250) + "..." : latest.summary;
const version = {
title: latest.title,
latest_version: latest.version,
installed_version: APP.version,
release_summary: latest.summary.slice(0, 250) + "...",
release_summary: summary,
release_url: latest.url,
update_percentage: progress || null,
in_progress: progress && progress > 0 && progress < 100,
@@ -242,9 +264,6 @@ const updateApp = async (progress = 0) => {
* Initializes the shutdown button and handles the execute logic.
*/
const initShutdown = () => {
if (!HARDWARE.support.sudoRights) {
return;
}
const root = `${INTEGRATION.root}/shutdown`;
const config = {
name: "Shutdown",
@@ -253,12 +272,17 @@ const initShutdown = () => {
icon: "mdi:power",
device: INTEGRATION.device,
};
if (!HARDWARE.support.sudoRights) {
removeConfig("button", config);
return;
}
publishConfig("button", config)
.on("message", (topic, message) => {
if (topic === config.command_topic) {
console.log("Shutdown system...");
hardware.setDisplayStatus("ON");
hardware.setDisplayStatus("ON", () => {
hardware.shutdownSystem();
});
}
})
.subscribe(config.command_topic);
@@ -268,9 +292,6 @@ const initShutdown = () => {
* Initializes the reboot button and handles the execute logic.
*/
const initReboot = () => {
if (!HARDWARE.support.sudoRights) {
return;
}
const root = `${INTEGRATION.root}/reboot`;
const config = {
name: "Reboot",
@@ -279,12 +300,17 @@ const initReboot = () => {
icon: "mdi:restart",
device: INTEGRATION.device,
};
if (!HARDWARE.support.sudoRights) {
removeConfig("button", config);
return;
}
publishConfig("button", config)
.on("message", (topic, message) => {
if (topic === config.command_topic) {
console.log("Rebooting system...");
hardware.setDisplayStatus("ON");
hardware.setDisplayStatus("ON", () => {
hardware.rebootSystem();
});
}
})
.subscribe(config.command_topic);
@@ -306,8 +332,9 @@ const initRefresh = () => {
.on("message", (topic, message) => {
if (topic === config.command_topic) {
console.log("Refreshing webview...");
hardware.setDisplayStatus("ON");
WEBVIEW.events.emit("reloadView");
hardware.setDisplayStatus("ON", () => {
EVENTS.emit("reloadView");
});
}
})
.subscribe(config.command_topic);
@@ -333,7 +360,7 @@ const initKiosk = () => {
if (topic === config.command_topic) {
const status = message.toString();
console.log("Set Kiosk Status:", status);
hardware.setDisplayStatus("ON");
hardware.setDisplayStatus("ON", () => {
switch (status) {
case "Framed":
WEBVIEW.window.restore();
@@ -358,6 +385,7 @@ const initKiosk = () => {
case "Terminated":
app.quit();
}
});
}
})
.subscribe(config.command_topic);
@@ -368,7 +396,7 @@ const initKiosk = () => {
* Updates the kiosk status via the mqtt connection.
*/
const updateKiosk = async () => {
const kiosk = WEBVIEW.status;
const kiosk = WEBVIEW.tracker.status;
publishState("kiosk", kiosk);
};
@@ -376,9 +404,6 @@ const updateKiosk = async () => {
* Initializes the display status, brightness and handles the execute logic.
*/
const initDisplay = () => {
if (!HARDWARE.support.displayStatus) {
return;
}
const root = `${INTEGRATION.root}/display`;
const config = {
name: "Display",
@@ -394,26 +419,30 @@ const initDisplay = () => {
brightness_scale: 100,
}),
};
if (!HARDWARE.support.displayStatus) {
removeConfig("light", config);
return;
}
publishConfig("light", config)
.on("message", (topic, message) => {
if (topic === config.command_topic) {
const status = message.toString();
console.log("Set Display Status:", status);
hardware.setDisplayStatus(status, (reply, error) => {
if (error) {
console.warn("Failed:", error);
} else {
if (!error) {
hardware.update();
} else {
console.warn("Failed:", error);
}
});
} else if (topic === config.brightness_command_topic) {
const brightness = parseInt(message, 10);
console.log("Set Display Brightness:", brightness);
hardware.setDisplayBrightness(brightness, (reply, error) => {
if (error) {
console.warn("Failed:", error);
} else {
if (!error) {
hardware.update();
} else {
console.warn("Failed:", error);
}
});
}
@@ -437,9 +466,6 @@ const updateDisplay = async () => {
* Initializes the keyboard visibility and handles the execute logic.
*/
const initKeyboard = () => {
if (!HARDWARE.support.keyboardVisibility) {
return;
}
const root = `${INTEGRATION.root}/keyboard`;
const config = {
name: "Keyboard",
@@ -449,12 +475,16 @@ const initKeyboard = () => {
icon: "mdi:keyboard-close-outline",
device: INTEGRATION.device,
};
if (!HARDWARE.support.keyboardVisibility) {
removeConfig("switch", config);
return;
}
publishConfig("switch", config)
.on("message", (topic, message) => {
if (topic === config.command_topic) {
const status = message.toString();
console.log("Set Keyboard Visibility:", status);
hardware.setKeyboardVisibility(status);
hardware.setDisplayStatus("ON", () => {
switch (status) {
case "OFF":
WEBVIEW.window.restore();
@@ -467,6 +497,8 @@ const initKeyboard = () => {
WEBVIEW.window.maximize();
break;
}
hardware.setKeyboardVisibility(status);
});
}
})
.subscribe(config.command_topic);
@@ -485,9 +517,6 @@ const updateKeyboard = async () => {
* Initializes the page number and handles the execute logic.
*/
const initPageNumber = () => {
if (WEBVIEW.viewUrls.length <= 2) {
return;
}
const root = `${INTEGRATION.root}/page_number`;
const config = {
name: "Page Number",
@@ -502,13 +531,17 @@ const initPageNumber = () => {
icon: "mdi:page-next",
device: INTEGRATION.device,
};
if (WEBVIEW.viewUrls.length <= 2) {
removeConfig("number", config);
return;
}
publishConfig("number", config)
.on("message", (topic, message) => {
if (topic === config.command_topic) {
const number = parseInt(message, 10);
console.log("Set Page Number:", number);
WEBVIEW.viewActive = number || 1;
WEBVIEW.events.emit("updateView");
EVENTS.emit("updateView");
}
})
.subscribe(config.command_topic);
@@ -519,7 +552,7 @@ const initPageNumber = () => {
* Updates the page number via the mqtt connection.
*/
const updatePageNumber = async () => {
const pageNumber = WEBVIEW.viewActive || 1;
const pageNumber = WEBVIEW.viewUrls.length <= 2 ? null : WEBVIEW.viewActive || 1;
publishState("page_number", pageNumber);
};
@@ -547,7 +580,7 @@ const initPageZoom = () => {
const zoom = parseInt(message, 10);
console.log("Set Page Zoom:", zoom);
WEBVIEW.views[WEBVIEW.viewActive || 1].webContents.setZoomFactor(zoom / 100.0);
WEBVIEW.events.emit("updateView");
EVENTS.emit("updateView");
}
})
.subscribe(config.command_topic);
@@ -840,9 +873,6 @@ const updateProcessorTemperature = async () => {
* Initializes the battery level sensor.
*/
const initBatteryLevel = () => {
if (!HARDWARE.support.batteryLevel) {
return;
}
const root = `${INTEGRATION.root}/battery_level`;
const config = {
name: "Battery Level",
@@ -853,6 +883,10 @@ const initBatteryLevel = () => {
icon: "mdi:battery-medium",
device: INTEGRATION.device,
};
if (!HARDWARE.support.batteryLevel) {
removeConfig("sensor", config);
return;
}
publishConfig("sensor", config);
updateBatteryLevel();
};
@@ -888,12 +922,12 @@ const initPackageUpgrades = () => {
*/
const updatePackageUpgrades = async () => {
const packages = hardware.checkPackageUpgrades();
const attributes = {
const upgrades = {
total: packages.length,
packages: packages.map((pkg) => pkg.replace(/\s*\[.*?\]\s*/g, "").trim()),
};
publishState("package_upgrades", attributes.total);
publishAttributes("package_upgrades", attributes);
publishState("package_upgrades", upgrades.total);
publishAttributes("package_upgrades", upgrades);
};
/**
@@ -946,8 +980,8 @@ const initLastActive = () => {
*/
const updateLastActive = async () => {
const now = new Date();
const then = WEBVIEW.pointer.time;
const lastActive = Math.abs(now - then) / (1000 * 60);
const then = WEBVIEW.tracker.pointer.time;
const lastActive = (now - then) / (1000 * 60);
publishState("last_active", lastActive);
};
+65 -45
View File
@@ -1,18 +1,20 @@
const path = require("path");
const axios = require("axios");
const https = require("https");
const hardware = require("./hardware");
const integration = require("./integration");
const { app, nativeTheme, globalShortcut, ipcMain, session, BaseWindow, WebContentsView } = require("electron");
const Events = require("events");
global.WEBVIEW = global.WEBVIEW || {
initialized: false,
events: new Events(),
status: null,
locked: false,
tracker: {
pointer: {
position: {},
time: new Date(),
},
display: {},
status: null,
},
};
/**
@@ -49,8 +51,6 @@ const init = async () => {
WEBVIEW.navigationTheme = theme;
WEBVIEW.navigationEnabled = widget;
nativeTheme.themeSource = WEBVIEW.viewTheme;
WEBVIEW.events.on("reloadView", reloadView);
WEBVIEW.events.on("updateView", updateView);
// Init global root window
WEBVIEW.window = new BaseWindow({
@@ -117,7 +117,17 @@ const init = async () => {
WEBVIEW.window.contentView.addChildView(WEBVIEW.navigation);
WEBVIEW.navigation.webContents.loadFile(path.join(APP.path, "html", "navigation.html"));
// Register events
// Register global events
EVENTS.on("reloadView", reloadView);
EVENTS.on("updateView", updateView);
EVENTS.on("updateDisplay", () => {
const status = hardware.getDisplayStatus();
if (status) {
WEBVIEW.tracker.display[status.toLowerCase()] = new Date();
}
});
// Register local events
await windowEvents();
await widgetEvents();
await navigationEvents();
@@ -135,15 +145,15 @@ const update = async () => {
return;
}
// Update windows status
// Update window status
if (WEBVIEW.window.isFullScreen()) {
WEBVIEW.status = "Fullscreen";
WEBVIEW.tracker.status = "Fullscreen";
} else if (WEBVIEW.window.isMinimized()) {
WEBVIEW.status = "Minimized";
WEBVIEW.tracker.status = "Minimized";
} else if (WEBVIEW.window.isMaximized()) {
WEBVIEW.status = "Maximized";
WEBVIEW.tracker.status = "Maximized";
} else {
WEBVIEW.status = "Framed";
WEBVIEW.tracker.status = "Framed";
}
// Update widget status
@@ -153,7 +163,7 @@ const update = async () => {
updateNavigation();
// Update integration sensor
console.log("Update Kiosk Status:", WEBVIEW.status);
console.log("Update Kiosk Status:", WEBVIEW.tracker.status);
integration.update();
};
@@ -433,21 +443,6 @@ const windowEvents = async () => {
WEBVIEW.window.on("resize", resizeView);
resizeView();
// Handle window focus events
WEBVIEW.window.on("focus", () => {
if (WEBVIEW.locked) {
hardware.setDisplayStatus("ON");
WEBVIEW.window.blur();
}
WEBVIEW.locked = false;
});
HARDWARE.events.on("updateDisplay", () => {
WEBVIEW.locked = hardware.getDisplayStatus() === "OFF";
if (WEBVIEW.locked) {
WEBVIEW.window.blur();
}
});
// Handle window status updates
WEBVIEW.window.on("minimize", update);
WEBVIEW.window.on("restore", update);
@@ -479,8 +474,8 @@ const windowEvents = async () => {
// Check for window touch events (1s)
setInterval(() => {
const now = new Date();
const then = WEBVIEW.pointer.time;
const delta = Math.abs(now - then) / 1000;
const then = WEBVIEW.tracker.pointer.time;
const delta = (now - then) / 1000;
// Auto-hide navigation
if (delta > 60) {
@@ -740,18 +735,38 @@ const viewEvents = async () => {
// Handle webview mouse events
view.webContents.on("before-mouse-event", (e, mouse) => {
const now = new Date();
const then = WEBVIEW.pointer.time;
const delta = Math.abs(now - then) / 1000;
WEBVIEW.pointer.time = now;
const then = WEBVIEW.tracker.pointer.time;
const delta = (now - then) / 1000;
switch (mouse.type) {
case "mouseMove":
const posNew = { x: mouse.globalX, y: mouse.globalY };
if (posNew.x < 0 || posNew.y < 0) {
break;
}
// Update last active on pointer position change
const posOld = WEBVIEW.tracker.pointer.position;
if (posOld.x !== posNew.x || posOld.y !== posNew.y) {
WEBVIEW.tracker.pointer.time = now;
WEBVIEW.tracker.pointer.position = posNew;
if (delta > 30) {
console.log("Update Last Active");
integration.update();
}
}
break;
case "mouseDown":
switch (mouse.button) {
case "left":
// Ignore touch event if display was off
if (WEBVIEW.tracker.display.off > WEBVIEW.tracker.display.on) {
console.log("Display Touch Event: Ignored");
e.preventDefault();
}
// Turn display on if it was off
if (hardware.getDisplayStatus() === "OFF") {
hardware.setDisplayStatus("ON");
}
break;
case "back":
historyBackward();
break;
@@ -769,13 +784,6 @@ const viewEvents = async () => {
* Register app events and handler.
*/
const appEvents = async () => {
// Handle signal and exit events
process.on("SIGINT", app.quit);
app.on("before-quit", () => {
WEBVIEW.status = "Terminated";
integration.update();
});
// Handle multiple instances
app.on("second-instance", () => {
if (WEBVIEW.window.isMinimized()) {
@@ -784,14 +792,22 @@ const appEvents = async () => {
WEBVIEW.window.focus();
});
// Handle signal and exit events
app.on("before-quit", () => {
WEBVIEW.tracker.status = "Terminated";
console.warn(`${APP.title} Terminated`);
integration.update();
});
process.on("SIGINT", app.quit);
// Webview initialized
WEBVIEW.initialized = true;
// Check for latest release infos (2h)
setInterval(() => {
latestRelease();
}, 7200 * 1000);
await latestRelease();
// Webview initialized
WEBVIEW.initialized = true;
};
/**
@@ -799,7 +815,7 @@ const appEvents = async () => {
*/
const latestRelease = async () => {
try {
const response = await axios.get(`${APP.releases.url}/latest`);
const response = await axios.get(`${APP.releases.url}/latest`, { timeout: 10000 });
const data = response ? response.data : null;
if (!data || data.draft || data.prerelease) {
return;
@@ -830,7 +846,8 @@ const onlineStatus = (url, interval = 1000, timeout = 60000) => {
const elapsed = Date.now() - start;
try {
if (!url.startsWith("data:")) {
await axios.get(url, { timeout: 10000 });
const agent = new https.Agent({ rejectUnauthorized: !("ignore_certificate_errors" in ARGS) });
await axios.get(url, { httpsAgent: agent, timeout: 10000 });
}
resolve(true);
} catch (error) {
@@ -838,6 +855,9 @@ const onlineStatus = (url, interval = 1000, timeout = 60000) => {
console.warn(`Checking Connection: ${url}`, error.message);
}
if (elapsed >= timeout) {
if (error.message?.includes("certificate")) {
console.error("Certificate Error: See https://github.com/leukipp/touchkio/issues/76");
}
resolve(false);
} else {
setTimeout(check, interval);
+9 -8
View File
@@ -4,27 +4,28 @@
"description": "Home Assistant Touch Kiosk",
"homepage": "https://github.com/leukipp/touchkio",
"author": "leukipp",
"version": "1.3.0",
"version": "1.3.3",
"license": "MIT",
"main": "index.js",
"scripts": {
"start": "electron . --web-url=https://demo.home-assistant.io,https://demo.immichkiosk.app --app-debug=false --trace-warnings",
"start": "electron . --web-url=https://demo.home-assistant.io,https://demo.immichkiosk.app --app-debug=false --trace-warnings --ignore-certificate-errors",
"build": "electron-forge make"
},
"prettier": {
"printWidth": 120
},
"devDependencies": {
"@electron-forge/cli": "^7.8.3",
"@electron-forge/maker-deb": "^7.8.3",
"@electron-forge/maker-zip": "^7.8.3",
"@electron-forge/publisher-github": "^7.8.3",
"electron": "^38.0.0",
"@electron-forge/cli": "^7.9.0",
"@electron-forge/maker-deb": "^7.9.0",
"@electron-forge/maker-zip": "^7.9.0",
"@electron-forge/publisher-github": "^7.9.0",
"electron": "^38.1.2",
"jszip": "^3.10.1",
"prettier": "^3.6.2"
},
"dependencies": {
"axios": "^1.11.0",
"axios": "^1.12.2",
"electron-log": "^5.4.3",
"mqtt": "^5.14.1"
}
}
+394 -148
View File
@@ -7,15 +7,17 @@
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.4.tgz#a70226016fabe25c5783b2f22d3e1c9bc5ca3326"
integrity sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==
"@electron-forge/cli@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@electron-forge/cli/-/cli-7.8.3.tgz#22eb1409047f747a9f2a8b697c1e2c5f461d2d84"
integrity sha512-BSAjGGfVf0yp3NQhXYmyCw9T//YCQHuktMv4HXfDVfo7AoV6DA1oEhqldI4Q7aHKeRob5+yBkvRRYPiu5ayCPw==
"@electron-forge/cli@^7.9.0":
version "7.9.0"
resolved "https://registry.yarnpkg.com/@electron-forge/cli/-/cli-7.9.0.tgz#de79184bbcdceaa5a8beb35c27bf15f4ba022ab7"
integrity sha512-FIs9rV6gN1v8rY73j/dvhQWF8tht035bN2LatY/z99H2KpWr0lhD03MOkIM2lRgrPEqVTExA4JEl9ja9yXBD3Q==
dependencies:
"@electron-forge/core" "7.8.3"
"@electron-forge/core-utils" "7.8.3"
"@electron-forge/shared-types" "7.8.3"
"@electron-forge/core" "7.9.0"
"@electron-forge/core-utils" "7.9.0"
"@electron-forge/shared-types" "7.9.0"
"@electron/get" "^3.0.0"
"@inquirer/prompts" "^6.0.1"
"@listr2/prompt-adapter-inquirer" "^2.0.22"
chalk "^4.0.0"
commander "^11.1.0"
debug "^4.3.1"
@@ -24,12 +26,12 @@
log-symbols "^4.0.0"
semver "^7.2.1"
"@electron-forge/core-utils@7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@electron-forge/core-utils/-/core-utils-7.8.3.tgz#8aac92271fbf5de3e1f657179db5e027ea5dd48a"
integrity sha512-8jhK7AvUKEqDyTMMuRhvS1TkE73YEnHYAxVvkJq35e1KdCwGbGnSRhaEs7OOqRfkKxfepdJ7BMKFSoKFeP+z0Q==
"@electron-forge/core-utils@7.9.0":
version "7.9.0"
resolved "https://registry.yarnpkg.com/@electron-forge/core-utils/-/core-utils-7.9.0.tgz#0c9fa40460182ad03e6eb392d72e7a65f3c04471"
integrity sha512-votOf1+20cUJim0smYZW7OylXrl89JlpuFTgFpn5WFpDfAV6C0iH9202K1sa33v9OQ989JnpWDZtQNQzQHHNtg==
dependencies:
"@electron-forge/shared-types" "7.8.3"
"@electron-forge/shared-types" "7.9.0"
"@electron/rebuild" "^3.7.0"
"@malept/cross-spawn-promise" "^2.0.0"
chalk "^4.0.0"
@@ -39,26 +41,27 @@
log-symbols "^4.0.0"
semver "^7.2.1"
"@electron-forge/core@7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@electron-forge/core/-/core-7.8.3.tgz#d7a715e9cef80b083e898b4c6b941178276d4a36"
integrity sha512-qX2vi/LP3HcSqSfLfzMeH2ll8SFZQnOk8VN/b3bq6XrBCbrfrSsTYYWakN6mmfalLJcQRm4jCEc6gcyuGO4i6Q==
"@electron-forge/core@7.9.0":
version "7.9.0"
resolved "https://registry.yarnpkg.com/@electron-forge/core/-/core-7.9.0.tgz#96e7b0990cc661b2344648be8108c45a815a910c"
integrity sha512-S5uFv9sFAVYSO80/K4HZsJL9L2Bs51IxCqR0a2Lk4NdKr9Fpzp6txwuALSJzM1bIpohtqbjmgut49o95wg30ZA==
dependencies:
"@electron-forge/core-utils" "7.8.3"
"@electron-forge/maker-base" "7.8.3"
"@electron-forge/plugin-base" "7.8.3"
"@electron-forge/publisher-base" "7.8.3"
"@electron-forge/shared-types" "7.8.3"
"@electron-forge/template-base" "7.8.3"
"@electron-forge/template-vite" "7.8.3"
"@electron-forge/template-vite-typescript" "7.8.3"
"@electron-forge/template-webpack" "7.8.3"
"@electron-forge/template-webpack-typescript" "7.8.3"
"@electron-forge/tracer" "7.8.3"
"@electron-forge/core-utils" "7.9.0"
"@electron-forge/maker-base" "7.9.0"
"@electron-forge/plugin-base" "7.9.0"
"@electron-forge/publisher-base" "7.9.0"
"@electron-forge/shared-types" "7.9.0"
"@electron-forge/template-base" "7.9.0"
"@electron-forge/template-vite" "7.9.0"
"@electron-forge/template-vite-typescript" "7.9.0"
"@electron-forge/template-webpack" "7.9.0"
"@electron-forge/template-webpack-typescript" "7.9.0"
"@electron-forge/tracer" "7.9.0"
"@electron/get" "^3.0.0"
"@electron/packager" "^18.3.5"
"@electron/rebuild" "^3.7.0"
"@malept/cross-spawn-promise" "^2.0.0"
"@vscode/sudo-prompt" "^9.3.1"
chalk "^4.0.0"
debug "^4.3.1"
fast-glob "^3.2.7"
@@ -76,60 +79,59 @@
rechoir "^0.8.0"
semver "^7.2.1"
source-map-support "^0.5.13"
sudo-prompt "^9.1.1"
username "^5.1.0"
"@electron-forge/maker-base@7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@electron-forge/maker-base/-/maker-base-7.8.3.tgz#e500ebe3eacfa84d3f02faac2aa3b2773c27250a"
integrity sha512-WmF66cHdziaK8Asi7IRTLxZjCZ8IqXXHr6IPl4d5oatN6s5RG+HHzG1hiJ7LzlOEntqdSpE8Wh2nB2TmyR4huQ==
"@electron-forge/maker-base@7.9.0":
version "7.9.0"
resolved "https://registry.yarnpkg.com/@electron-forge/maker-base/-/maker-base-7.9.0.tgz#0bcdac4573f88ba493beb2c42b382fc6f010f095"
integrity sha512-u0jo2kaYRxh/Rai6DyFSGJcNLRVWxiKaGUjMhX1LrKolufUkCxxR4TEmv4Hvl03WTr9pQb06umlIrVMaNb+j9A==
dependencies:
"@electron-forge/shared-types" "7.8.3"
"@electron-forge/shared-types" "7.9.0"
fs-extra "^10.0.0"
which "^2.0.2"
"@electron-forge/maker-deb@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@electron-forge/maker-deb/-/maker-deb-7.8.3.tgz#940427f406a107eca6bc80029c62d259833f9b9b"
integrity sha512-GZHJU06LRFJkv1wMc3bjMVzedQhyxnyMZqgDJjE9TIlXXZkN2EqGmKLw/HxwNRA1R8yuQeA4Ih6/dEB4bZTevg==
"@electron-forge/maker-deb@^7.9.0":
version "7.9.0"
resolved "https://registry.yarnpkg.com/@electron-forge/maker-deb/-/maker-deb-7.9.0.tgz#6309d8e6b78010a32a55f2eb51a5e952f233b7e3"
integrity sha512-b1TRMKkeuZ2PTKVsTMWLY+82O6UQVPQ17x5hkWe0lyIxRyCfJr6hD+AqYbvEJ50ncDkvyCtENBT6GnhfbKOGxA==
dependencies:
"@electron-forge/maker-base" "7.8.3"
"@electron-forge/shared-types" "7.8.3"
"@electron-forge/maker-base" "7.9.0"
"@electron-forge/shared-types" "7.9.0"
optionalDependencies:
electron-installer-debian "^3.2.0"
"@electron-forge/maker-zip@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@electron-forge/maker-zip/-/maker-zip-7.8.3.tgz#450b17d6517633bbdeb82397600db61abd8461d6"
integrity sha512-ytao285wKAjKBO6eULzLeqUDP5Zh7beQlGyHjgOMknk7FI0sNy+zGdh3CrCGIhkXSHU/DpukPwRu2SiKvIaIGA==
"@electron-forge/maker-zip@^7.9.0":
version "7.9.0"
resolved "https://registry.yarnpkg.com/@electron-forge/maker-zip/-/maker-zip-7.9.0.tgz#bf198f8b6316649f33f83d77ae539c904136636f"
integrity sha512-UGeziReiz8yuDTjliOjvbdyulIHpKAWkDeW3kOcMTUmRcCgrCkBNr+Pp6ih8Q3aBhG+CCd4++oe2rDnnuVvxFw==
dependencies:
"@electron-forge/maker-base" "7.8.3"
"@electron-forge/shared-types" "7.8.3"
"@electron-forge/maker-base" "7.9.0"
"@electron-forge/shared-types" "7.9.0"
cross-zip "^4.0.0"
fs-extra "^10.0.0"
got "^11.8.5"
"@electron-forge/plugin-base@7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@electron-forge/plugin-base/-/plugin-base-7.8.3.tgz#2def4cf41aca2f63c3486e651487571efafc284b"
integrity sha512-0CzPQlO3BGu5bLCrx2Xqo6B1yoHhA9wG9boZE58ANr8Qma1NQfAWZU3LnMmF3EdWNTX76PxpZeeb3QbPNcxSuA==
"@electron-forge/plugin-base@7.9.0":
version "7.9.0"
resolved "https://registry.yarnpkg.com/@electron-forge/plugin-base/-/plugin-base-7.9.0.tgz#a39f0e0a9e406686f298e0595ee514091e6144f9"
integrity sha512-2cnShgfes0sqH7A3+54fWhfJEfU++1OC2HE50a4sWtWEDwyWLGbwW7tp9BgSXrvIexO2AGKHQ1pKIjpZYVC0fA==
dependencies:
"@electron-forge/shared-types" "7.8.3"
"@electron-forge/shared-types" "7.9.0"
"@electron-forge/publisher-base@7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@electron-forge/publisher-base/-/publisher-base-7.8.3.tgz#a90ef4532e2a319c2ee44de741dd1968b5b42735"
integrity sha512-kurRKVNyLsK2JgmVl88UHu0+qSH+PysMtk/xP0YX5sYNMVxRay8+S1T10tAh6Qom94KwpF3CLYtkebvxb/fq+A==
"@electron-forge/publisher-base@7.9.0":
version "7.9.0"
resolved "https://registry.yarnpkg.com/@electron-forge/publisher-base/-/publisher-base-7.9.0.tgz#f129cc24d916c27adbee35f5cdf868172b5cc263"
integrity sha512-z3eH4+C++LiDqlKmri04IbSNNWLRYLvc49uNiOgfvnejplLsos720TTbwgruyI3D2fbpmhrVmz9kp9H9YzXdVg==
dependencies:
"@electron-forge/shared-types" "7.8.3"
"@electron-forge/shared-types" "7.9.0"
"@electron-forge/publisher-github@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@electron-forge/publisher-github/-/publisher-github-7.8.3.tgz#45e51d7d91e63e8c7872217e3b5d16111fd8a3e7"
integrity sha512-hFZMDAWXkNrvJA/dA64m2+uLVz1cVyMbX94YXqu9zbW6sMWJzT96om1Gr+c1CnK+mmj5E/ZqVu0846Rq+rcfEQ==
"@electron-forge/publisher-github@^7.9.0":
version "7.9.0"
resolved "https://registry.yarnpkg.com/@electron-forge/publisher-github/-/publisher-github-7.9.0.tgz#759f44a7cbc8c7fcd524ccc5cc57a99f9ad3a4fc"
integrity sha512-kJzRLRaYmRa9D0e/PCnnhDChWhs3nipYgx3b4QFDVUFmbQ1ytBCmZnCO2vH0NXr7HZE3ozcAHm+Zw0TvEpXmeA==
dependencies:
"@electron-forge/publisher-base" "7.8.3"
"@electron-forge/shared-types" "7.8.3"
"@electron-forge/publisher-base" "7.9.0"
"@electron-forge/shared-types" "7.9.0"
"@octokit/core" "^5.2.1"
"@octokit/plugin-retry" "^6.1.0"
"@octokit/request-error" "^5.1.1"
@@ -141,68 +143,69 @@
log-symbols "^4.0.0"
mime-types "^2.1.25"
"@electron-forge/shared-types@7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@electron-forge/shared-types/-/shared-types-7.8.3.tgz#0b7c54b3fa09bfdc931e22d254b70f1685744fde"
integrity sha512-gkZtD7ALXHPDOthJo1rQYLDNfG09fdDRMWvjEgaXdF3Z69xXFfnOWPNuOkRUODNalMnuuGs6l7jDl+QFQgHlDg==
"@electron-forge/shared-types@7.9.0":
version "7.9.0"
resolved "https://registry.yarnpkg.com/@electron-forge/shared-types/-/shared-types-7.9.0.tgz#ac3dd22da586957fcd6fb1c035155bd65bf2ffd3"
integrity sha512-6jZF+zq3SYMnweQpgr5fwlSgOd2yOZ5qlfz/CgXyVljiv0e0UThzpOjfTLuwuVgZX7a60xV+h0mg1h82Glu3wQ==
dependencies:
"@electron-forge/tracer" "7.8.3"
"@electron-forge/tracer" "7.9.0"
"@electron/packager" "^18.3.5"
"@electron/rebuild" "^3.7.0"
listr2 "^7.0.2"
"@electron-forge/template-base@7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@electron-forge/template-base/-/template-base-7.8.3.tgz#009ba783b3e214fb8a0ed23386cc2ff7c514f796"
integrity sha512-C0tVODDNKoqhCf7T1HRONJs9DKAmjmk8Of0t8rVjT0ERDzMvLGlBByd785v5lFlKbGERyoaXsYltxPAu92G3aA==
"@electron-forge/template-base@7.9.0":
version "7.9.0"
resolved "https://registry.yarnpkg.com/@electron-forge/template-base/-/template-base-7.9.0.tgz#1716913b7485f61a8a1ec73132b9e91c7cfb1ea4"
integrity sha512-DvXdJHh4qP+LBX6xNBlO0nfljvJNTmiQNfLRfSouRdYCWbr5hC7wyWAX803HqwRsVLRZj2oiLYZjmyG3jESp8Q==
dependencies:
"@electron-forge/core-utils" "7.8.3"
"@electron-forge/shared-types" "7.8.3"
"@electron-forge/core-utils" "7.9.0"
"@electron-forge/shared-types" "7.9.0"
"@malept/cross-spawn-promise" "^2.0.0"
debug "^4.3.1"
fs-extra "^10.0.0"
semver "^7.2.1"
username "^5.1.0"
"@electron-forge/template-vite-typescript@7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@electron-forge/template-vite-typescript/-/template-vite-typescript-7.8.3.tgz#57194eb6faa4e154118b4ac49ae6091f784eb0d3"
integrity sha512-HJjjY9xmlpl0vx10mrXdWn2RYHExfazACxmDNNmGO1eq3eqrQk/3R+NDGyqMJ7ajBsRVbkQNt+wayH7HkRJUjA==
"@electron-forge/template-vite-typescript@7.9.0":
version "7.9.0"
resolved "https://registry.yarnpkg.com/@electron-forge/template-vite-typescript/-/template-vite-typescript-7.9.0.tgz#1c5cedc3392e1dc2fdec2eec4549b0dea06d1d27"
integrity sha512-qGK649YnC3iOVrj/hHUu/TXG7Nn/a7QykEOPrCrxROWL7mtw8CMUE+FOVETd+eew7/4ldUNzl+5b9ebP8jHOmg==
dependencies:
"@electron-forge/shared-types" "7.8.3"
"@electron-forge/template-base" "7.8.3"
"@electron-forge/shared-types" "7.9.0"
"@electron-forge/template-base" "7.9.0"
fs-extra "^10.0.0"
"@electron-forge/template-vite@7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@electron-forge/template-vite/-/template-vite-7.8.3.tgz#ecc651c9641747b71becc740522ef0cf15c28bf5"
integrity sha512-tDL5h+UO5iOzdEYNVsSu4zkUVN4RTxti5iXzcBquKd9Kgt/A/M7xHeuKj7g1Ds7Ul/n2XcFvcfgLcRmiXQeVDA==
"@electron-forge/template-vite@7.9.0":
version "7.9.0"
resolved "https://registry.yarnpkg.com/@electron-forge/template-vite/-/template-vite-7.9.0.tgz#0233840a305280efbecf8d8a4930a6f031594895"
integrity sha512-m8Fi40XaF7YDJo7YqmfJbkjRRsttN9EEHkmq+McLrDUbln15Ppm59RAwUhizDQzs4enmLcNQPaFllbAg/2t8vQ==
dependencies:
"@electron-forge/shared-types" "7.8.3"
"@electron-forge/template-base" "7.8.3"
"@electron-forge/shared-types" "7.9.0"
"@electron-forge/template-base" "7.9.0"
fs-extra "^10.0.0"
"@electron-forge/template-webpack-typescript@7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@electron-forge/template-webpack-typescript/-/template-webpack-typescript-7.8.3.tgz#f79276aa60463a8cc45c85e17bec9c42779ac12b"
integrity sha512-Xz3X7YJvot08Xm+0BLIS28GJH+0z9vEN9xYX76SOL4jqDcHH8lRFpNWcE2HsxxxRbCVH+s0etVmACZcWoujUrw==
"@electron-forge/template-webpack-typescript@7.9.0":
version "7.9.0"
resolved "https://registry.yarnpkg.com/@electron-forge/template-webpack-typescript/-/template-webpack-typescript-7.9.0.tgz#ea4d31626d7790960857d119a3f1687bcbb69ada"
integrity sha512-z7PB72sI11LBSPz9w9nwwk0le/lZ3VT8TrLc0NYh4F4LbZ19Z+lxcraaAdf21efvWzodhWx8khAyA8WvkNxVSw==
dependencies:
"@electron-forge/shared-types" "7.8.3"
"@electron-forge/template-base" "7.8.3"
"@electron-forge/shared-types" "7.9.0"
"@electron-forge/template-base" "7.9.0"
fs-extra "^10.0.0"
"@electron-forge/template-webpack@7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@electron-forge/template-webpack/-/template-webpack-7.8.3.tgz#b82b47e8b5e3b2716a0afe4fa1c263b46b4c5271"
integrity sha512-1zkji5px1kDXbigFN5959anCf3HAVBvam3bHh2VejnCScegLQP3JBjAn2Nw2ILWq6ej5JNuA/V99b1dr11hPOw==
"@electron-forge/template-webpack@7.9.0":
version "7.9.0"
resolved "https://registry.yarnpkg.com/@electron-forge/template-webpack/-/template-webpack-7.9.0.tgz#2e48610cf28508c13f5b7adb64e743590df267bc"
integrity sha512-ser22QczYGor7N6bnMUwexdWbLMNApr6zpBoT+Xfn6P4Ks67ttzcfkAges7GXHNjXwox4ePYZ3+D7cWQem5C4g==
dependencies:
"@electron-forge/shared-types" "7.8.3"
"@electron-forge/template-base" "7.8.3"
"@electron-forge/shared-types" "7.9.0"
"@electron-forge/template-base" "7.9.0"
fs-extra "^10.0.0"
"@electron-forge/tracer@7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@electron-forge/tracer/-/tracer-7.8.3.tgz#c2c27fb9b2bd770b39f02bc3ae6e254064421af6"
integrity sha512-YVVDaPEUOvR1z+DDdj8wR/vO9OSlC91wz4/2Iqe9rqQz8sztnnQBClMAZTqu9bkDTFyHrns8j8v7tPVuVS6ULQ==
"@electron-forge/tracer@7.9.0":
version "7.9.0"
resolved "https://registry.yarnpkg.com/@electron-forge/tracer/-/tracer-7.9.0.tgz#a512ea5e0c4564ace978546b50e8ec1aa150fa68"
integrity sha512-7itsjW1WJQADg7Ly61ggI5CCRt+QDVx3HOZC1w69jMUtnipKyPRCbvTBf1oplsNqbIzZxceXdfex6W53YNehvA==
dependencies:
chrome-trace-event "^1.0.3"
@@ -357,6 +360,158 @@
resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6"
integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==
"@inquirer/checkbox@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@inquirer/checkbox/-/checkbox-3.0.1.tgz#0a57f704265f78c36e17f07e421b98efb4b9867b"
integrity sha512-0hm2nrToWUdD6/UHnel/UKGdk1//ke5zGUpHIvk5ZWmaKezlGxZkOJXNSWsdxO/rEqTkbB3lNC2J6nBElV2aAQ==
dependencies:
"@inquirer/core" "^9.2.1"
"@inquirer/figures" "^1.0.6"
"@inquirer/type" "^2.0.0"
ansi-escapes "^4.3.2"
yoctocolors-cjs "^2.1.2"
"@inquirer/confirm@^4.0.1":
version "4.0.1"
resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-4.0.1.tgz#9106d6bffa0b2fdd0e4f60319b6f04f2e06e6e25"
integrity sha512-46yL28o2NJ9doViqOy0VDcoTzng7rAb6yPQKU7VDLqkmbCaH4JqK4yk4XqlzNWy9PVC5pG1ZUXPBQv+VqnYs2w==
dependencies:
"@inquirer/core" "^9.2.1"
"@inquirer/type" "^2.0.0"
"@inquirer/core@^9.2.1":
version "9.2.1"
resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-9.2.1.tgz#677c49dee399c9063f31e0c93f0f37bddc67add1"
integrity sha512-F2VBt7W/mwqEU4bL0RnHNZmC/OxzNx9cOYxHqnXX3MP6ruYvZUZAW9imgN9+h/uBT/oP8Gh888J2OZSbjSeWcg==
dependencies:
"@inquirer/figures" "^1.0.6"
"@inquirer/type" "^2.0.0"
"@types/mute-stream" "^0.0.4"
"@types/node" "^22.5.5"
"@types/wrap-ansi" "^3.0.0"
ansi-escapes "^4.3.2"
cli-width "^4.1.0"
mute-stream "^1.0.0"
signal-exit "^4.1.0"
strip-ansi "^6.0.1"
wrap-ansi "^6.2.0"
yoctocolors-cjs "^2.1.2"
"@inquirer/editor@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@inquirer/editor/-/editor-3.0.1.tgz#d109f21e050af6b960725388cb1c04214ed7c7bc"
integrity sha512-VA96GPFaSOVudjKFraokEEmUQg/Lub6OXvbIEZU1SDCmBzRkHGhxoFAVaF30nyiB4m5cEbDgiI2QRacXZ2hw9Q==
dependencies:
"@inquirer/core" "^9.2.1"
"@inquirer/type" "^2.0.0"
external-editor "^3.1.0"
"@inquirer/expand@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@inquirer/expand/-/expand-3.0.1.tgz#aed9183cac4d12811be47a4a895ea8e82a17e22c"
integrity sha512-ToG8d6RIbnVpbdPdiN7BCxZGiHOTomOX94C2FaT5KOHupV40tKEDozp12res6cMIfRKrXLJyexAZhWVHgbALSQ==
dependencies:
"@inquirer/core" "^9.2.1"
"@inquirer/type" "^2.0.0"
yoctocolors-cjs "^2.1.2"
"@inquirer/figures@^1.0.6":
version "1.0.13"
resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-1.0.13.tgz#ad0afd62baab1c23175115a9b62f511b6a751e45"
integrity sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==
"@inquirer/input@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@inquirer/input/-/input-3.0.1.tgz#de63d49e516487388508d42049deb70f2cb5f28e"
integrity sha512-BDuPBmpvi8eMCxqC5iacloWqv+5tQSJlUafYWUe31ow1BVXjW2a5qe3dh4X/Z25Wp22RwvcaLCc2siHobEOfzg==
dependencies:
"@inquirer/core" "^9.2.1"
"@inquirer/type" "^2.0.0"
"@inquirer/number@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@inquirer/number/-/number-2.0.1.tgz#b9863080d02ab7dc2e56e16433d83abea0f2a980"
integrity sha512-QpR8jPhRjSmlr/mD2cw3IR8HRO7lSVOnqUvQa8scv1Lsr3xoAMMworcYW3J13z3ppjBFBD2ef1Ci6AE5Qn8goQ==
dependencies:
"@inquirer/core" "^9.2.1"
"@inquirer/type" "^2.0.0"
"@inquirer/password@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@inquirer/password/-/password-3.0.1.tgz#2a9a9143591088336bbd573bcb05d5bf080dbf87"
integrity sha512-haoeEPUisD1NeE2IanLOiFr4wcTXGWrBOyAyPZi1FfLJuXOzNmxCJPgUrGYKVh+Y8hfGJenIfz5Wb/DkE9KkMQ==
dependencies:
"@inquirer/core" "^9.2.1"
"@inquirer/type" "^2.0.0"
ansi-escapes "^4.3.2"
"@inquirer/prompts@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/@inquirer/prompts/-/prompts-6.0.1.tgz#43f5c0ed35c5ebfe52f1d43d46da2d363d950071"
integrity sha512-yl43JD/86CIj3Mz5mvvLJqAOfIup7ncxfJ0Btnl0/v5TouVUyeEdcpknfgc+yMevS/48oH9WAkkw93m7otLb/A==
dependencies:
"@inquirer/checkbox" "^3.0.1"
"@inquirer/confirm" "^4.0.1"
"@inquirer/editor" "^3.0.1"
"@inquirer/expand" "^3.0.1"
"@inquirer/input" "^3.0.1"
"@inquirer/number" "^2.0.1"
"@inquirer/password" "^3.0.1"
"@inquirer/rawlist" "^3.0.1"
"@inquirer/search" "^2.0.1"
"@inquirer/select" "^3.0.1"
"@inquirer/rawlist@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@inquirer/rawlist/-/rawlist-3.0.1.tgz#729def358419cc929045f264131878ed379e0af3"
integrity sha512-VgRtFIwZInUzTiPLSfDXK5jLrnpkuSOh1ctfaoygKAdPqjcjKYmGh6sCY1pb0aGnCGsmhUxoqLDUAU0ud+lGXQ==
dependencies:
"@inquirer/core" "^9.2.1"
"@inquirer/type" "^2.0.0"
yoctocolors-cjs "^2.1.2"
"@inquirer/search@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@inquirer/search/-/search-2.0.1.tgz#69b774a0a826de2e27b48981d01bc5ad81e73721"
integrity sha512-r5hBKZk3g5MkIzLVoSgE4evypGqtOannnB3PKTG9NRZxyFRKcfzrdxXXPcoJQsxJPzvdSU2Rn7pB7lw0GCmGAg==
dependencies:
"@inquirer/core" "^9.2.1"
"@inquirer/figures" "^1.0.6"
"@inquirer/type" "^2.0.0"
yoctocolors-cjs "^2.1.2"
"@inquirer/select@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@inquirer/select/-/select-3.0.1.tgz#1df9ed27fb85a5f526d559ac5ce7cc4e9dc4e7ec"
integrity sha512-lUDGUxPhdWMkN/fHy1Lk7pF3nK1fh/gqeyWXmctefhxLYxlDsc7vsPBEpxrfVGDsVdyYJsiJoD4bJ1b623cV1Q==
dependencies:
"@inquirer/core" "^9.2.1"
"@inquirer/figures" "^1.0.6"
"@inquirer/type" "^2.0.0"
ansi-escapes "^4.3.2"
yoctocolors-cjs "^2.1.2"
"@inquirer/type@^1.5.5":
version "1.5.5"
resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-1.5.5.tgz#303ea04ce7ad2e585b921b662b3be36ef7b4f09b"
integrity sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==
dependencies:
mute-stream "^1.0.0"
"@inquirer/type@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-2.0.0.tgz#08fa513dca2cb6264fe1b0a2fabade051444e3f6"
integrity sha512-XvJRx+2KR3YXyYtPUUy+qd9i7p+GO9Ko6VIIpWlBrpWwXDv8WLFeHTxz35CfQFUiBMLXlGHhGzys7lqit9gWag==
dependencies:
mute-stream "^1.0.0"
"@listr2/prompt-adapter-inquirer@^2.0.22":
version "2.0.22"
resolved "https://registry.yarnpkg.com/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-2.0.22.tgz#95f7730de62089be79a87a80aa333f5f4644f3c5"
integrity sha512-hV36ZoY+xKL6pYOt1nPNnkciFkn89KZwqLhAFzJvYysAvL5uBQdiADZx/8bIDXIukzzwG0QlPYolgMzQUtKgpQ==
dependencies:
"@inquirer/type" "^1.5.5"
"@malept/cross-spawn-promise@^1.0.0":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz#504af200af6b98e198bce768bc1730c6936ae01d"
@@ -570,17 +725,24 @@
dependencies:
"@types/node" "*"
"@types/node@*":
version "24.3.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-24.3.1.tgz#b0a3fb2afed0ef98e8d7f06d46ef6349047709f3"
integrity sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g==
"@types/mute-stream@^0.0.4":
version "0.0.4"
resolved "https://registry.yarnpkg.com/@types/mute-stream/-/mute-stream-0.0.4.tgz#77208e56a08767af6c5e1237be8888e2f255c478"
integrity sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==
dependencies:
undici-types "~7.10.0"
"@types/node" "*"
"@types/node@^22.7.7":
version "22.18.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.18.1.tgz#cc85ee6999b2a2928739281d2f56ff410a140c52"
integrity sha512-rzSDyhn4cYznVG+PCzGe1lwuMYJrcBS1fc3JqSa2PvtABwWo+dZ1ij5OVok3tqfpEBCBoaR4d7upFJk73HRJDw==
"@types/node@*":
version "24.5.2"
resolved "https://registry.yarnpkg.com/@types/node/-/node-24.5.2.tgz#52ceb83f50fe0fcfdfbd2a9fab6db2e9e7ef6446"
integrity sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==
dependencies:
undici-types "~7.12.0"
"@types/node@^22.5.5", "@types/node@^22.7.7":
version "22.18.6"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.18.6.tgz#38172ef0b65e09d1a4fc715eb09a7d5decfdc748"
integrity sha512-r8uszLPpeIWbNKtvWRt/DbVi5zbqZyj1PTmhRMqBMvDnaz1QpmSKujUtJLrqGZeoM8v72MfYggDceY4K1itzWQ==
dependencies:
undici-types "~6.21.0"
@@ -598,6 +760,11 @@
dependencies:
"@types/node" "*"
"@types/wrap-ansi@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz#18b97a972f94f60a679fd5c796d96421b9abb9fd"
integrity sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==
"@types/ws@^8.18.1":
version "8.18.1"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.1.tgz#48464e4bf2ddfd17db13d845467f6070ffea4aa9"
@@ -612,6 +779,11 @@
dependencies:
"@types/node" "*"
"@vscode/sudo-prompt@^9.3.1":
version "9.3.1"
resolved "https://registry.yarnpkg.com/@vscode/sudo-prompt/-/sudo-prompt-9.3.1.tgz#c562334bc6647733649fd42afc96c0eea8de3b65"
integrity sha512-9ORTwwS74VaTn38tNbQhsA5U44zkJfcb0BdTSyyG6frP4e8KMtHuTXYmwefe5dpL8XB1aGSIVTaLjD3BbWb5iA==
"@xmldom/xmldom@^0.8.8":
version "0.8.11"
resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.11.tgz#b79de2d67389734c57c52595f7a7305e30c2d608"
@@ -651,6 +823,13 @@ aggregate-error@^3.0.0:
clean-stack "^2.0.0"
indent-string "^4.0.0"
ansi-escapes@^4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e"
integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==
dependencies:
type-fest "^0.21.3"
ansi-escapes@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-5.0.0.tgz#b6a0caf0eef0c41af190e9a749e0c00ec04bb2a6"
@@ -664,9 +843,9 @@ ansi-regex@^5.0.1:
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
ansi-regex@^6.0.1:
version "6.2.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.2.0.tgz#2f302e7550431b1b7762705fffb52cf1ffa20447"
integrity sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==
version "6.2.2"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.2.2.tgz#60216eea464d864597ce2832000738a0589650c1"
integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==
ansi-styles@^4.0.0, ansi-styles@^4.1.0:
version "4.3.0"
@@ -676,9 +855,9 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
color-convert "^2.0.1"
ansi-styles@^6.0.0, ansi-styles@^6.1.0:
version "6.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
version "6.2.3"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.3.tgz#c044d5dcc521a076413472597a1acb1f103c4041"
integrity sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==
asynckit@^0.4.0:
version "0.4.0"
@@ -695,10 +874,10 @@ author-regex@^1.0.0:
resolved "https://registry.yarnpkg.com/author-regex/-/author-regex-1.0.0.tgz#d08885be6b9bbf9439fe087c76287245f0a81450"
integrity sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g==
axios@^1.11.0:
version "1.11.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.11.0.tgz#c2ec219e35e414c025b2095e8b8280278478fdb6"
integrity sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==
axios@^1.12.2:
version "1.12.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.12.2.tgz#6c307390136cf7a2278d09cec63b136dfc6e6da7"
integrity sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==
dependencies:
follow-redirects "^1.15.6"
form-data "^4.0.4"
@@ -869,6 +1048,11 @@ chalk@^4.0.0, chalk@^4.1.0:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
chardet@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
chownr@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece"
@@ -911,6 +1095,11 @@ cli-truncate@^3.1.0:
slice-ansi "^5.0.0"
string-width "^5.0.0"
cli-width@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5"
integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==
cliui@^7.0.2:
version "7.0.4"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
@@ -1041,9 +1230,9 @@ cross-zip@^4.0.0:
integrity sha512-n63i0lZ0rvQ6FXiGQ+/JFCKAUyPFhLQYJIqKaa+tSJtfKeULF/IDNDAbdnSIxgS4NTuw2b0+lj8LzfITuq+ZxQ==
debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.3, debug@^4.3.4, debug@^4.4.1:
version "4.4.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b"
integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==
version "4.4.3"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a"
integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==
dependencies:
ms "^2.1.3"
@@ -1102,9 +1291,9 @@ deprecation@^2.0.0:
integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==
detect-libc@^2.0.1:
version "2.0.4"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.4.tgz#f04715b8ba815e53b4d8109655b6508a6865a7e8"
integrity sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==
version "2.1.0"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.1.0.tgz#3ca811f60a7b504b0480e5008adacc660b0b8c4f"
integrity sha512-vEtk+OcP7VBRtQZ1EJ3bdgzSfBjgnEalLTp5zjJrS+2Z1w2KZly4SBdac/WDU3hhsNAZ9E8SC96ME4Ey8MZ7cg==
detect-node@^2.0.4:
version "2.1.0"
@@ -1164,10 +1353,15 @@ electron-installer-debian@^3.2.0:
word-wrap "^1.2.3"
yargs "^16.0.2"
electron@^38.0.0:
version "38.0.0"
resolved "https://registry.yarnpkg.com/electron/-/electron-38.0.0.tgz#e51803f62c8d4c368f77642a1b1b05444c687fba"
integrity sha512-egljptiPJqbL/oamFCEY+g3RNeONWTVxZSGeyLqzK8xq106JhzuxnhJZ3sxt4DzJFaofbGyGJA37Oe9d+gVzYw==
electron-log@^5.4.3:
version "5.4.3"
resolved "https://registry.yarnpkg.com/electron-log/-/electron-log-5.4.3.tgz#02a90baf4256950ca416095db6e5745268584d20"
integrity sha512-sOUsM3LjZdugatazSQ/XTyNcw8dfvH1SYhXWiJyfYodAAKOZdHs0txPiLDXFzOZbhXgAgshQkshH2ccq0feyLQ==
electron@^38.1.2:
version "38.1.2"
resolved "https://registry.yarnpkg.com/electron/-/electron-38.1.2.tgz#3509999a1b635fb92e99a8e5eaf239110a9a7734"
integrity sha512-WXUcN3W8h8NTTZViA3KNX0rV2YBU0X0mEUM3ubupXTDY4QtIN7tmiqYVOKSKpR2LckTmBWGuEeY4D6xVoffwKQ==
dependencies:
"@electron/get" "^2.0.0"
"@types/node" "^22.7.7"
@@ -1208,9 +1402,9 @@ err-code@^2.0.2:
integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==
error-ex@^1.2.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
version "1.3.4"
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.4.tgz#b3a8d8bb6f92eecc1629e3e27d3c8607a8a32414"
integrity sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==
dependencies:
is-arrayish "^0.2.1"
@@ -1294,6 +1488,15 @@ exponential-backoff@^3.1.1:
resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.2.tgz#a8f26adb96bf78e8cd8ad1037928d5e5c0679d91"
integrity sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==
external-editor@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495"
integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==
dependencies:
chardet "^0.7.0"
iconv-lite "^0.4.24"
tmp "^0.0.33"
extract-zip@^2.0.0, extract-zip@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a"
@@ -1408,9 +1611,9 @@ fs-extra@^10.0.0, fs-extra@^10.1.0:
universalify "^2.0.0"
fs-extra@^11.1.0, fs-extra@^11.1.1:
version "11.3.1"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.1.tgz#ba7a1f97a85f94c6db2e52ff69570db3671d5a74"
integrity sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==
version "11.3.2"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.2.tgz#c838aeddc6f4a8c74dd15f85e11fe5511bfe02a4"
integrity sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==
dependencies:
graceful-fs "^4.2.0"
jsonfile "^6.0.1"
@@ -1689,6 +1892,13 @@ humanize-ms@^1.2.1:
dependencies:
ms "^2.0.0"
iconv-lite@^0.4.24:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
dependencies:
safer-buffer ">= 2.1.2 < 3"
iconv-lite@^0.6.2:
version "0.6.3"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
@@ -2190,6 +2400,11 @@ ms@^2.0.0, ms@^2.1.3:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
mute-stream@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e"
integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==
negotiator@^0.6.3:
version "0.6.4"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.4.tgz#777948e2452651c570b712dd01c23e262713fff7"
@@ -2292,6 +2507,11 @@ ora@^5.1.0:
strip-ansi "^6.0.0"
wcwidth "^1.0.1"
os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==
p-cancelable@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf"
@@ -2669,7 +2889,7 @@ safe-buffer@~5.2.0:
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
"safer-buffer@>= 2.1.2 < 3.0.0":
"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0":
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
@@ -2735,6 +2955,11 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
signal-exit@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04"
integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==
slice-ansi@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-5.0.0.tgz#b73063c57aa96f9cd881654b15294d95d285c42a"
@@ -2861,9 +3086,9 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1:
ansi-regex "^5.0.1"
strip-ansi@^7.0.1:
version "7.1.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==
version "7.1.2"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.2.tgz#132875abde678c7ea8d691533f2e7e22bb744dba"
integrity sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==
dependencies:
ansi-regex "^6.0.1"
@@ -2884,11 +3109,6 @@ strip-outer@^1.0.1:
dependencies:
escape-string-regexp "^1.0.2"
sudo-prompt@^9.1.1:
version "9.2.1"
resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.2.1.tgz#77efb84309c9ca489527a4e749f287e6bdd52afd"
integrity sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw==
sumchecker@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-3.0.1.tgz#6377e996795abb0b6d348e9b3e1dfb24345a8e42"
@@ -2932,6 +3152,13 @@ tmp-promise@^3.0.2:
dependencies:
tmp "^0.2.0"
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==
dependencies:
os-tmpdir "~1.0.2"
tmp@^0.2.0:
version "0.2.5"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.5.tgz#b06bcd23f0f3c8357b426891726d16015abfd8f8"
@@ -2966,6 +3193,11 @@ type-fest@^0.13.1:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934"
integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==
type-fest@^0.21.3:
version "0.21.3"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
type-fest@^1.0.2:
version "1.4.0"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1"
@@ -2981,10 +3213,10 @@ undici-types@~6.21.0:
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb"
integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==
undici-types@~7.10.0:
version "7.10.0"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.10.0.tgz#4ac2e058ce56b462b056e629cc6a02393d3ff350"
integrity sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==
undici-types@~7.12.0:
version "7.12.0"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.12.0.tgz#15c5c7475c2a3ba30659529f5cdb4674b622fafb"
integrity sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==
unique-filename@^2.0.0:
version "2.0.1"
@@ -3114,6 +3346,15 @@ worker-timers@^8.0.23:
worker-timers-broker "^8.0.10"
worker-timers-worker "^9.0.10"
wrap-ansi@^6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53"
integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
@@ -3205,3 +3446,8 @@ yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
yoctocolors-cjs@^2.1.2:
version "2.1.3"
resolved "https://registry.yarnpkg.com/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz#7e4964ea8ec422b7a40ac917d3a344cfd2304baa"
integrity sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==