diff --git a/LineDetection.html b/LineDetection.html
index 1610050d6..86cb702c3 100644
--- a/LineDetection.html
+++ b/LineDetection.html
@@ -25,37 +25,51 @@
this.canvas.height = height;
this.ctx = this.canvas.getContext('2d');
this.lastDetectedLine = [];
- this.frameCount = 0;
- this.allCoordinates = [];
+ this.isProcessing = false;
}
async detectLine() {
+ if (this.isProcessing) return this.canvas.toDataURL();
+ this.isProcessing = true;
+
try {
const image = await this.loadImage(`http://${this.raspberryPiIp}:${port.camera}/${endpoint.video}`);
this.ctx.drawImage(image, 0, 0, this.width, this.height);
const imageData = this.ctx.getImageData(0, 0, this.width, this.height);
- const preprocessedImageData = this.preprocessImage(imageData);
- const lineCoordinates = this.processImageData(preprocessedImageData);
- const filteredCoordinates = this.filterContinuousLine(lineCoordinates);
- console.log("coordinates");
- console.log(filteredCoordinates);
- if (filteredCoordinates.length > 0) {
- this.lastDetectedLine = filteredCoordinates;
+
+ // Convert to grayscale
+ const data = imageData.data;
+ for (let i = 0; i < data.length; i += 4) {
+ const gray = (data[i] + data[i + 1] + data[i + 2]) / 3;
+ data[i] = gray;
+ data[i + 1] = gray;
+ data[i + 2] = gray;
}
+ this.ctx.putImageData(imageData, 0, 0);
- if (this.frameCount < 7) {
- this.allCoordinates.push(filteredCoordinates);
- this.frameCount++;
- if (this.frameCount === 7) {
- this.writeCoordinatesToFile(this.allCoordinates);
- }
+ // Apply Gaussian blur
+ const blurredData = this.gaussianBlur(imageData);
+ this.ctx.putImageData(blurredData, 0, 0);
+
+ // Apply threshold
+ const thresholdedData = this.threshold(blurredData);
+ this.ctx.putImageData(thresholdedData, 0, 0);
+
+ // Find contours and get largest
+ const contours = this.findContours(thresholdedData);
+ const sortedContours = contours.sort((c1, c2) => c2.length - c1.length);
+
+ if (sortedContours.length > 0) {
+ this.lastDetectedLine = sortedContours[0];
+ this.drawLine(this.lastDetectedLine);
}
- this.drawLine(this.lastDetectedLine);
return this.canvas.toDataURL();
} catch (error) {
console.error('Error detecting line:', error);
return null;
+ } finally {
+ this.isProcessing = false;
}
}
@@ -69,75 +83,104 @@
});
}
- preprocessImage(imageData) {
+ gaussianBlur(imageData) {
const data = imageData.data;
- const threshold = this.calculateBlackThreshold(data);
-
- for (let i = 0; i < data.length; i += 4) {
- const r = data[i];
- const g = data[i + 1];
- const b = data[i + 2];
-
- const brightness = (r + g + b) / 3;
-
- if (brightness < threshold) {
- data[i] = 0; // Set red to min
- data[i + 1] = 0; // Set green to min
- data[i + 2] = 0; // Set blue to min
- } else {
- data[i] = 255; // Set red to max
- data[i + 1] = 255; // Set green to max
- data[i + 2] = 255; // Set blue to max
+ const result = new ImageData(new Uint8ClampedArray(data), this.width, this.height);
+ const kernel = [
+ [1, 4, 6, 4, 1],
+ [4, 16, 24, 16, 4],
+ [6, 24, 36, 24, 6],
+ [4, 16, 24, 16, 4],
+ [1, 4, 6, 4, 1]
+ ];
+ const kernelSize = 5;
+ const kernelSum = 256;
+
+ for (let y = 2; y < this.height - 2; y++) {
+ for (let x = 2; x < this.width - 2; x++) {
+ let sum = 0;
+ for (let ky = 0; ky < kernelSize; ky++) {
+ for (let kx = 0; kx < kernelSize; kx++) {
+ const px = x + kx - 2;
+ const py = y + ky - 2;
+ const i = (py * this.width + px) * 4;
+ sum += data[i] * kernel[ky][kx];
+ }
+ }
+ const i = (y * this.width + x) * 4;
+ const val = sum / kernelSum;
+ result.data[i] = val;
+ result.data[i + 1] = val;
+ result.data[i + 2] = val;
+ result.data[i + 3] = 255;
}
}
-
- return imageData;
+ return result;
}
- calculateBlackThreshold(data) {
- let brightnessValues = [];
+ threshold(imageData) {
+ const data = imageData.data;
+ const result = new ImageData(new Uint8ClampedArray(data), this.width, this.height);
+
for (let i = 0; i < data.length; i += 4) {
- const brightness = (data[i] + data[i + 1] + data[i + 2]) / 3;
- brightnessValues.push(brightness);
+ const val = data[i] < 128 ? 0 : 255;
+ result.data[i] = val;
+ result.data[i + 1] = val;
+ result.data[i + 2] = val;
+ result.data[i + 3] = 255;
}
- brightnessValues.sort((a, b) => a - b);
- return brightnessValues[Math.floor(brightnessValues.length * 0.3)]; // 30th percentile as threshold
+ return result;
}
- processImageData(imageData) {
- const lineCoordinates = [];
-
+ findContours(imageData) {
+ const contours = [];
+ const data = imageData.data;
+ const visited = new Set();
+
for (let y = 0; y < this.height; y++) {
for (let x = 0; x < this.width; x++) {
- const index = (y * this.width + x) * 4;
- const r = imageData.data[index];
+ const idx = (y * this.width + x) * 4;
+ const key = `${x},${y}`;
- if (r === 0) { // Check for black pixels (preprocessed black line)
- lineCoordinates.push([x, y]);
- }
+ if (data[idx] === 0 && !visited.has(key)) {
+ const contour = [];
+ this.traceContour(x, y, data, visited, contour);
+ if (contour.length > 0) {
+ contours.push(contour);
+ }
+ }
}
}
- return lineCoordinates.sort((a, b) => a[1] - b[1]);
+ return contours;
}
- filterContinuousLine(coordinates) {
- if (coordinates.length < 2) return coordinates;
-
- const filteredCoordinates = [coordinates[0]];
- const maxDistance = 20; // Maximum allowed distance between consecutive points
-
- for (let i = 1; i < coordinates.length; i++) {
- const [prevX, prevY] = filteredCoordinates[filteredCoordinates.length - 1];
- const [currentX, currentY] = coordinates[i];
+ traceContour(startX, startY, data, visited, contour) {
+ const stack = [[startX, startY]];
+
+ while (stack.length > 0) {
+ const [x, y] = stack.pop();
+ const key = `${x},${y}`;
+
+ if (visited.has(key)) continue;
- const distance = Math.sqrt(Math.pow(currentX - prevX, 2) + Math.pow(currentY - prevY, 2));
+ visited.add(key);
+ contour.push([x, y]);
- if (distance <= maxDistance) {
- filteredCoordinates.push(coordinates[i]);
+ // Check 8-connected neighbors
+ for (let dy = -1; dy <= 1; dy++) {
+ for (let dx = -1; dx <= 1; dx++) {
+ const nx = x + dx;
+ const ny = y + dy;
+
+ if (nx >= 0 && nx < this.width && ny >= 0 && ny < this.height) {
+ const idx = (ny * this.width + nx) * 4;
+ if (data[idx] === 0 && !visited.has(`${nx},${ny}`)) {
+ stack.push([nx, ny]);
+ }
+ }
+ }
}
}
-
- return filteredCoordinates;
}
drawLine(coordinates) {
@@ -153,18 +196,6 @@
});
this.ctx.stroke();
}
-
- writeCoordinatesToFile(allCoordinates) {
- const content = allCoordinates.map((frame, index) =>
- `Frame ${index + 1}:\n${frame.map(coord => coord.join(',')).join('\n')}\n`
- ).join('\n');
- const blob = new Blob([content], { type: 'text/plain' });
- const a = document.createElement('a');
- a.href = URL.createObjectURL(blob);
- a.download = 'coordinates.txt';
- a.click();
- URL.revokeObjectURL(a.href);
- }
}
let detector;
diff --git a/extensions/src/doodlebot/LineDetection.ts b/extensions/src/doodlebot/LineDetection.ts
index 8cbfb845f..7002b29c4 100644
--- a/extensions/src/doodlebot/LineDetection.ts
+++ b/extensions/src/doodlebot/LineDetection.ts
@@ -1,34 +1,48 @@
-import { createCanvas, loadImage } from 'canvas';
import { endpoint, port } from "./enums";
+import cv from '@u4/opencv4nodejs';
+import axios from 'axios';
export class LineDetector {
private lastDetectedLine: number[][] = [];
private isProcessing = false;
- private canvas: any;
- private ctx: any;
- constructor(private raspberryPiIp: string, private width = 640, private height = 480) {
- this.canvas = createCanvas(this.width, this.height);
- this.ctx = this.canvas.getContext('2d');
- }
+ constructor(private raspberryPiIp: string, private width = 640, private height = 480) {}
async detectLine(): Promise {
if (this.isProcessing) return this.lastDetectedLine;
this.isProcessing = true;
try {
- const image = await loadImage(`http://${this.raspberryPiIp}:${port.camera}/${endpoint.video}`);
- this.ctx.drawImage(image, 0, 0, this.width, this.height);
- const imageData = this.ctx.getImageData(0, 0, this.width, this.height);
- const preprocessedImageData = this.preprocessImage(imageData);
- const lineCoordinates = this.processImageData(preprocessedImageData);
- const filteredCoordinates = this.filterContinuousLine(lineCoordinates);
+ // Get image from endpoint
+ const response = await axios.get(
+ `http://${this.raspberryPiIp}:${port.camera}/${endpoint.video}`,
+ { responseType: 'arraybuffer' }
+ );
+
+ // Convert response to cv Mat
+ const buffer = Buffer.from(response.data);
+ let mat = cv.imdecode(buffer);
+
+ // Resize if needed
+ if (mat.cols !== this.width || mat.rows !== this.height) {
+ mat = mat.resize(this.height, this.width);
+ }
- console.log("coordinates");
- console.log(filteredCoordinates);
+ // Convert to grayscale and apply threshold
+ const gray = mat.cvtColor(cv.COLOR_BGR2GRAY);
+ const blurred = gray.gaussianBlur(new cv.Size(5, 5), 0);
+ const thresh = blurred.threshold(0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU);
- if (filteredCoordinates.length > 0) {
- this.lastDetectedLine = filteredCoordinates;
+ // Find contours
+ const contours = thresh.findContours(cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE);
+
+ // Get the largest contour (assuming it's the line)
+ const sortedContours = contours.sort((c1, c2) => c2.area - c1.area);
+
+ if (sortedContours.length > 0) {
+ // Convert contour points to coordinate array
+ const coordinates = sortedContours[0].getPoints().map(point => [point.x, point.y]);
+ this.lastDetectedLine = coordinates;
}
return this.lastDetectedLine;
@@ -39,77 +53,6 @@ export class LineDetector {
this.isProcessing = false;
}
}
-
- private preprocessImage(imageData: ImageData): ImageData {
- const data = imageData.data;
- const threshold = this.calculateBlackThreshold(data);
-
- for (let i = 0; i < data.length; i += 4) {
- const r = data[i];
- const g = data[i + 1];
- const b = data[i + 2];
-
- const brightness = (r + g + b) / 3;
-
- if (brightness < threshold) {
- data[i] = 0;
- data[i + 1] = 0;
- data[i + 2] = 0;
- } else {
- data[i] = 255;
- data[i + 1] = 255;
- data[i + 2] = 255;
- }
- }
-
- return imageData;
- }
-
- private calculateBlackThreshold(data: Uint8ClampedArray): number {
- let brightnessValues: number[] = [];
- for (let i = 0; i < data.length; i += 4) {
- const brightness = (data[i] + data[i + 1] + data[i + 2]) / 3;
- brightnessValues.push(brightness);
- }
- brightnessValues.sort((a, b) => a - b);
- return brightnessValues[Math.floor(brightnessValues.length * 0.3)];
- }
-
- private processImageData(imageData: ImageData): number[][] {
- const lineCoordinates: number[][] = [];
-
- for (let y = 0; y < this.height; y++) {
- for (let x = 0; x < this.width; x++) {
- const index = (y * this.width + x) * 4;
- const r = imageData.data[index];
-
- if (r === 0) {
- lineCoordinates.push([x, y]);
- }
- }
- }
- return lineCoordinates.sort((a, b) => a[1] - b[1]);
- }
-
- private filterContinuousLine(coordinates: number[][]): number[][] {
- if (coordinates.length < 2) return coordinates;
-
- const filteredCoordinates: number[][] = [coordinates[0]];
- const maxDistance = 20;
-
- for (let i = 1; i < coordinates.length; i++) {
- const [prevX, prevY] = filteredCoordinates[filteredCoordinates.length - 1];
- const [currentX, currentY] = coordinates[i];
-
- const distance = Math.sqrt(Math.pow(currentX - prevX, 2) + Math.pow(currentY - prevY, 2));
-
- if (distance <= maxDistance) {
- filteredCoordinates.push(coordinates[i]);
- }
- }
-
- return filteredCoordinates;
- }
}
export function createLineDetector(raspberryPiIp: string): () => Promise {
diff --git a/package.json b/package.json
index 44fd3ca97..bb0721130 100644
--- a/package.json
+++ b/package.json
@@ -33,5 +33,9 @@
"ts-node": {
"typescript": "$typescript"
}
+ },
+ "dependencies": {
+ "@u4/opencv4nodejs": "^7.1.2",
+ "axios": "^1.7.7"
}
}
\ No newline at end of file
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 40e737ba1..6a4988cbe 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -7,6 +7,13 @@ settings:
importers:
.:
+ dependencies:
+ '@u4/opencv4nodejs':
+ specifier: ^7.1.2
+ version: 7.1.2
+ axios:
+ specifier: ^1.7.7
+ version: 1.7.7
devDependencies:
'@types/node':
specifier: ^20.12.2
@@ -39,6 +46,19 @@ packages:
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
engines: {node: '>=12'}
+ '@deno/shim-deno-test@0.5.0':
+ resolution: {integrity: sha512-4nMhecpGlPi0cSzT67L+Tm+GOJqvuk8gqHBziqcUQOarnuIax1z96/gJHCSIz2Z0zhxE6Rzwb3IZXPtFh51j+w==}
+
+ '@deno/shim-deno@0.19.2':
+ resolution: {integrity: sha512-q3VTHl44ad8T2Tw2SpeAvghdGOjlnLPDNO2cpOxwMrBE/PVas6geWpbpIgrM+czOCH0yejp0yi8OaTuB+NU40Q==}
+
+ '@denodnt/logger@1.1.6':
+ resolution: {integrity: sha512-LOupHr6kTPti9Bp9OeUWCv/azv1jDQJ69z+gGGQL+Q+ZJrQXTotSsPRxlUjOMytGqS5FUXSJExg2gmF083nTMw==}
+
+ '@isaacs/cliui@8.0.2':
+ resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
+ engines: {node: '>=12'}
+
'@jridgewell/resolve-uri@3.1.2':
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
engines: {node: '>=6.0.0'}
@@ -49,6 +69,18 @@ packages:
'@jridgewell/trace-mapping@0.3.9':
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
+ '@npmcli/agent@2.2.2':
+ resolution: {integrity: sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==}
+ engines: {node: ^16.14.0 || >=18.0.0}
+
+ '@npmcli/fs@3.1.1':
+ resolution: {integrity: sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==}
+ engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+
+ '@pkgjs/parseargs@0.11.0':
+ resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
+ engines: {node: '>=14'}
+
'@tsconfig/node10@1.0.11':
resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==}
@@ -73,6 +105,18 @@ packages:
'@types/yargs@17.0.32':
resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==}
+ '@u4/opencv-build@1.1.1':
+ resolution: {integrity: sha512-SSLqm8MgmIo+IdpuQElICbuFjucVwO85mP2EeahTuMgQN03spt/mE8ecGoKszuvRQLk0pyJV/87XwRr/ZZAFJA==}
+ hasBin: true
+
+ '@u4/opencv4nodejs@7.1.2':
+ resolution: {integrity: sha512-dNQNZ6COm5PQ5kpUkUFXlEYSWAhWm8niGCkJY+Pu3A45UJN/A7YwVhYKJZd2/YyoADgHjn6FcUabFHKFfuLcmw==}
+ hasBin: true
+
+ abbrev@2.0.0:
+ resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==}
+ engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+
acorn-walk@8.3.2:
resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==}
engines: {node: '>=0.4.0'}
@@ -82,17 +126,57 @@ packages:
engines: {node: '>=0.4.0'}
hasBin: true
+ agent-base@7.1.1:
+ resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==}
+ engines: {node: '>= 14'}
+
+ aggregate-error@3.1.0:
+ resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
+ engines: {node: '>=8'}
+
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
+ ansi-regex@6.1.0:
+ resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==}
+ engines: {node: '>=12'}
+
ansi-styles@4.3.0:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
+ ansi-styles@6.2.1:
+ resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
+ engines: {node: '>=12'}
+
arg@4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
+ asynckit@0.4.0:
+ resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+
+ axios@1.7.7:
+ resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==}
+
+ balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
+ brace-expansion@2.0.1:
+ resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
+
+ cacache@18.0.4:
+ resolution: {integrity: sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==}
+ engines: {node: ^16.14.0 || >=18.0.0}
+
+ chownr@2.0.0:
+ resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
+ engines: {node: '>=10'}
+
+ clean-stack@2.2.0:
+ resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
+ engines: {node: '>=6'}
+
cliui@8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
@@ -104,55 +188,360 @@ packages:
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+ combined-stream@1.0.8:
+ resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
+ engines: {node: '>= 0.8'}
+
create-require@1.1.1:
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
+ cross-spawn@7.0.3:
+ resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
+ engines: {node: '>= 8'}
+
+ debug@4.3.7:
+ resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ delayed-stream@1.0.0:
+ resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
+ engines: {node: '>=0.4.0'}
+
diff@4.0.2:
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
engines: {node: '>=0.3.1'}
+ eastasianwidth@0.2.0:
+ resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+ emoji-regex@9.2.2:
+ resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+
+ encoding@0.1.13:
+ resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==}
+
+ env-paths@2.2.1:
+ resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
+ engines: {node: '>=6'}
+
+ err-code@2.0.3:
+ resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==}
+
escalade@3.1.2:
resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==}
engines: {node: '>=6'}
+ exponential-backoff@3.1.1:
+ resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==}
+
+ follow-redirects@1.15.9:
+ resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
+ engines: {node: '>=4.0'}
+ peerDependencies:
+ debug: '*'
+ peerDependenciesMeta:
+ debug:
+ optional: true
+
+ foreground-child@3.3.0:
+ resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
+ engines: {node: '>=14'}
+
+ form-data@4.0.1:
+ resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==}
+ engines: {node: '>= 6'}
+
+ fs-minipass@2.1.0:
+ resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==}
+ engines: {node: '>= 8'}
+
+ fs-minipass@3.0.3:
+ resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==}
+ engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+
get-caller-file@2.0.5:
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
engines: {node: 6.* || 8.* || >= 10.*}
+ glob@10.4.5:
+ resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
+ hasBin: true
+
+ glob@11.0.0:
+ resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
+ http-cache-semantics@4.1.1:
+ resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==}
+
+ http-proxy-agent@7.0.2:
+ resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==}
+ engines: {node: '>= 14'}
+
+ https-proxy-agent@7.0.5:
+ resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==}
+ engines: {node: '>= 14'}
+
+ iconv-lite@0.6.3:
+ resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
+ engines: {node: '>=0.10.0'}
+
+ imurmurhash@0.1.4:
+ resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
+ engines: {node: '>=0.8.19'}
+
+ indent-string@4.0.0:
+ resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
+ engines: {node: '>=8'}
+
+ ip-address@9.0.5:
+ resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==}
+ engines: {node: '>= 12'}
+
is-fullwidth-code-point@3.0.0:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
+ is-lambda@1.0.1:
+ resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==}
+
+ isexe@2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+
+ isexe@3.1.1:
+ resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==}
+ engines: {node: '>=16'}
+
+ jackspeak@3.4.3:
+ resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
+
+ jackspeak@4.0.2:
+ resolution: {integrity: sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==}
+ engines: {node: 20 || >=22}
+
+ jsbn@1.1.0:
+ resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==}
+
json5@2.2.3:
resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
engines: {node: '>=6'}
hasBin: true
+ lru-cache@10.4.3:
+ resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
+
+ lru-cache@11.0.1:
+ resolution: {integrity: sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==}
+ engines: {node: 20 || >=22}
+
make-error@1.3.6:
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
+ make-fetch-happen@13.0.1:
+ resolution: {integrity: sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==}
+ engines: {node: ^16.14.0 || >=18.0.0}
+
+ mime-db@1.52.0:
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@2.1.35:
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+ engines: {node: '>= 0.6'}
+
+ minimatch@10.0.1:
+ resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==}
+ engines: {node: 20 || >=22}
+
+ minimatch@9.0.5:
+ resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+ minipass-collect@2.0.1:
+ resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ minipass-fetch@3.0.5:
+ resolution: {integrity: sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==}
+ engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+
+ minipass-flush@1.0.5:
+ resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==}
+ engines: {node: '>= 8'}
+
+ minipass-pipeline@1.2.4:
+ resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==}
+ engines: {node: '>=8'}
+
+ minipass-sized@1.0.3:
+ resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==}
+ engines: {node: '>=8'}
+
+ minipass@3.3.6:
+ resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==}
+ engines: {node: '>=8'}
+
+ minipass@5.0.0:
+ resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==}
+ engines: {node: '>=8'}
+
+ minipass@7.1.2:
+ resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ minizlib@2.1.2:
+ resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
+ engines: {node: '>= 8'}
+
+ mkdirp@1.0.4:
+ resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ nan@2.22.0:
+ resolution: {integrity: sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==}
+
+ negotiator@0.6.4:
+ resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==}
+ engines: {node: '>= 0.6'}
+
+ node-gyp@10.2.0:
+ resolution: {integrity: sha512-sp3FonBAaFe4aYTcFdZUn2NYkbP7xroPGYvQmP4Nl5PxamznItBnNCgjrVTKrEfQynInMsJvZrdmqUnysCJ8rw==}
+ engines: {node: ^16.14.0 || >=18.0.0}
+ hasBin: true
+
+ nopt@7.2.1:
+ resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==}
+ engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+ hasBin: true
+
+ p-map@4.0.0:
+ resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==}
+ engines: {node: '>=10'}
+
+ package-json-from-dist@1.0.1:
+ resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
+
+ path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+
+ path-scurry@1.11.1:
+ resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
+ engines: {node: '>=16 || 14 >=14.18'}
+
+ path-scurry@2.0.0:
+ resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==}
+ engines: {node: 20 || >=22}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ proc-log@4.2.0:
+ resolution: {integrity: sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==}
+ engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+
+ promise-retry@2.0.1:
+ resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==}
+ engines: {node: '>=10'}
+
+ proxy-from-env@1.1.0:
+ resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
+
require-directory@2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
+ retry@0.12.0:
+ resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==}
+ engines: {node: '>= 4'}
+
+ rimraf@6.0.1:
+ resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
+ safer-buffer@2.1.2:
+ resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+
+ semver@7.6.3:
+ resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+
+ shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+
+ signal-exit@4.1.0:
+ resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
+ engines: {node: '>=14'}
+
+ smart-buffer@4.2.0:
+ resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
+ engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
+
+ socks-proxy-agent@8.0.4:
+ resolution: {integrity: sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==}
+ engines: {node: '>= 14'}
+
+ socks@2.8.3:
+ resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==}
+ engines: {node: '>= 10.0.0', npm: '>= 3.0.0'}
+
+ sprintf-js@1.1.3:
+ resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==}
+
+ ssri@10.0.6:
+ resolution: {integrity: sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==}
+ engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+
string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
+ string-width@5.1.2:
+ resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
+ engines: {node: '>=12'}
+
strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
+ strip-ansi@7.1.0:
+ resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
+ engines: {node: '>=12'}
+
strip-bom@3.0.0:
resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
engines: {node: '>=4'}
+ tar@6.2.1:
+ resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==}
+ engines: {node: '>=10'}
+
ts-node@10.9.2:
resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==}
hasBin: true
@@ -182,17 +571,42 @@ packages:
undici-types@5.26.5:
resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
+ unique-filename@3.0.0:
+ resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==}
+ engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+
+ unique-slug@4.0.0:
+ resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==}
+ engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+
v8-compile-cache-lib@3.0.1:
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
+ which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+
+ which@4.0.0:
+ resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==}
+ engines: {node: ^16.13.0 || >=18.0.0}
+ hasBin: true
+
wrap-ansi@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
+ wrap-ansi@8.1.0:
+ resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
+ engines: {node: '>=12'}
+
y18n@5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
+ yallist@4.0.0:
+ resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
+
yargs-parser@21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
engines: {node: '>=12'}
@@ -211,6 +625,26 @@ snapshots:
dependencies:
'@jridgewell/trace-mapping': 0.3.9
+ '@deno/shim-deno-test@0.5.0': {}
+
+ '@deno/shim-deno@0.19.2':
+ dependencies:
+ '@deno/shim-deno-test': 0.5.0
+ which: 4.0.0
+
+ '@denodnt/logger@1.1.6':
+ dependencies:
+ '@deno/shim-deno': 0.19.2
+
+ '@isaacs/cliui@8.0.2':
+ dependencies:
+ string-width: 5.1.2
+ string-width-cjs: string-width@4.2.3
+ strip-ansi: 7.1.0
+ strip-ansi-cjs: strip-ansi@6.0.1
+ wrap-ansi: 8.1.0
+ wrap-ansi-cjs: wrap-ansi@7.0.0
+
'@jridgewell/resolve-uri@3.1.2': {}
'@jridgewell/sourcemap-codec@1.4.15': {}
@@ -220,6 +654,23 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.4.15
+ '@npmcli/agent@2.2.2':
+ dependencies:
+ agent-base: 7.1.1
+ http-proxy-agent: 7.0.2
+ https-proxy-agent: 7.0.5
+ lru-cache: 10.4.3
+ socks-proxy-agent: 8.0.4
+ transitivePeerDependencies:
+ - supports-color
+
+ '@npmcli/fs@3.1.1':
+ dependencies:
+ semver: 7.6.3
+
+ '@pkgjs/parseargs@0.11.0':
+ optional: true
+
'@tsconfig/node10@1.0.11': {}
'@tsconfig/node12@1.0.11': {}
@@ -240,18 +691,87 @@ snapshots:
dependencies:
'@types/yargs-parser': 21.0.3
+ '@u4/opencv-build@1.1.1':
+ dependencies:
+ '@deno/shim-deno': 0.19.2
+ '@denodnt/logger': 1.1.6
+ glob: 11.0.0
+ rimraf: 6.0.1
+
+ '@u4/opencv4nodejs@7.1.2':
+ dependencies:
+ '@u4/opencv-build': 1.1.1
+ glob: 11.0.0
+ nan: 2.22.0
+ node-gyp: 10.2.0
+ picocolors: 1.1.1
+ transitivePeerDependencies:
+ - supports-color
+
+ abbrev@2.0.0: {}
+
acorn-walk@8.3.2: {}
acorn@8.11.3: {}
+ agent-base@7.1.1:
+ dependencies:
+ debug: 4.3.7
+ transitivePeerDependencies:
+ - supports-color
+
+ aggregate-error@3.1.0:
+ dependencies:
+ clean-stack: 2.2.0
+ indent-string: 4.0.0
+
ansi-regex@5.0.1: {}
+ ansi-regex@6.1.0: {}
+
ansi-styles@4.3.0:
dependencies:
color-convert: 2.0.1
+ ansi-styles@6.2.1: {}
+
arg@4.1.3: {}
+ asynckit@0.4.0: {}
+
+ axios@1.7.7:
+ dependencies:
+ follow-redirects: 1.15.9
+ form-data: 4.0.1
+ proxy-from-env: 1.1.0
+ transitivePeerDependencies:
+ - debug
+
+ balanced-match@1.0.2: {}
+
+ brace-expansion@2.0.1:
+ dependencies:
+ balanced-match: 1.0.2
+
+ cacache@18.0.4:
+ dependencies:
+ '@npmcli/fs': 3.1.1
+ fs-minipass: 3.0.3
+ glob: 10.4.5
+ lru-cache: 10.4.3
+ minipass: 7.1.2
+ minipass-collect: 2.0.1
+ minipass-flush: 1.0.5
+ minipass-pipeline: 1.2.4
+ p-map: 4.0.0
+ ssri: 10.0.6
+ tar: 6.2.1
+ unique-filename: 3.0.0
+
+ chownr@2.0.0: {}
+
+ clean-stack@2.2.0: {}
+
cliui@8.0.1:
dependencies:
string-width: 4.2.3
@@ -264,38 +784,346 @@ snapshots:
color-name@1.1.4: {}
+ combined-stream@1.0.8:
+ dependencies:
+ delayed-stream: 1.0.0
+
create-require@1.1.1: {}
+ cross-spawn@7.0.3:
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+
+ debug@4.3.7:
+ dependencies:
+ ms: 2.1.3
+
+ delayed-stream@1.0.0: {}
+
diff@4.0.2: {}
+ eastasianwidth@0.2.0: {}
+
emoji-regex@8.0.0: {}
+ emoji-regex@9.2.2: {}
+
+ encoding@0.1.13:
+ dependencies:
+ iconv-lite: 0.6.3
+ optional: true
+
+ env-paths@2.2.1: {}
+
+ err-code@2.0.3: {}
+
escalade@3.1.2: {}
+ exponential-backoff@3.1.1: {}
+
+ follow-redirects@1.15.9: {}
+
+ foreground-child@3.3.0:
+ dependencies:
+ cross-spawn: 7.0.3
+ signal-exit: 4.1.0
+
+ form-data@4.0.1:
+ dependencies:
+ asynckit: 0.4.0
+ combined-stream: 1.0.8
+ mime-types: 2.1.35
+
+ fs-minipass@2.1.0:
+ dependencies:
+ minipass: 3.3.6
+
+ fs-minipass@3.0.3:
+ dependencies:
+ minipass: 7.1.2
+
get-caller-file@2.0.5: {}
+ glob@10.4.5:
+ dependencies:
+ foreground-child: 3.3.0
+ jackspeak: 3.4.3
+ minimatch: 9.0.5
+ minipass: 7.1.2
+ package-json-from-dist: 1.0.1
+ path-scurry: 1.11.1
+
+ glob@11.0.0:
+ dependencies:
+ foreground-child: 3.3.0
+ jackspeak: 4.0.2
+ minimatch: 10.0.1
+ minipass: 7.1.2
+ package-json-from-dist: 1.0.1
+ path-scurry: 2.0.0
+
+ graceful-fs@4.2.11: {}
+
+ http-cache-semantics@4.1.1: {}
+
+ http-proxy-agent@7.0.2:
+ dependencies:
+ agent-base: 7.1.1
+ debug: 4.3.7
+ transitivePeerDependencies:
+ - supports-color
+
+ https-proxy-agent@7.0.5:
+ dependencies:
+ agent-base: 7.1.1
+ debug: 4.3.7
+ transitivePeerDependencies:
+ - supports-color
+
+ iconv-lite@0.6.3:
+ dependencies:
+ safer-buffer: 2.1.2
+ optional: true
+
+ imurmurhash@0.1.4: {}
+
+ indent-string@4.0.0: {}
+
+ ip-address@9.0.5:
+ dependencies:
+ jsbn: 1.1.0
+ sprintf-js: 1.1.3
+
is-fullwidth-code-point@3.0.0: {}
+ is-lambda@1.0.1: {}
+
+ isexe@2.0.0: {}
+
+ isexe@3.1.1: {}
+
+ jackspeak@3.4.3:
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+ optionalDependencies:
+ '@pkgjs/parseargs': 0.11.0
+
+ jackspeak@4.0.2:
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+
+ jsbn@1.1.0: {}
+
json5@2.2.3: {}
+ lru-cache@10.4.3: {}
+
+ lru-cache@11.0.1: {}
+
make-error@1.3.6: {}
+ make-fetch-happen@13.0.1:
+ dependencies:
+ '@npmcli/agent': 2.2.2
+ cacache: 18.0.4
+ http-cache-semantics: 4.1.1
+ is-lambda: 1.0.1
+ minipass: 7.1.2
+ minipass-fetch: 3.0.5
+ minipass-flush: 1.0.5
+ minipass-pipeline: 1.2.4
+ negotiator: 0.6.4
+ proc-log: 4.2.0
+ promise-retry: 2.0.1
+ ssri: 10.0.6
+ transitivePeerDependencies:
+ - supports-color
+
+ mime-db@1.52.0: {}
+
+ mime-types@2.1.35:
+ dependencies:
+ mime-db: 1.52.0
+
+ minimatch@10.0.1:
+ dependencies:
+ brace-expansion: 2.0.1
+
+ minimatch@9.0.5:
+ dependencies:
+ brace-expansion: 2.0.1
+
minimist@1.2.8: {}
+ minipass-collect@2.0.1:
+ dependencies:
+ minipass: 7.1.2
+
+ minipass-fetch@3.0.5:
+ dependencies:
+ minipass: 7.1.2
+ minipass-sized: 1.0.3
+ minizlib: 2.1.2
+ optionalDependencies:
+ encoding: 0.1.13
+
+ minipass-flush@1.0.5:
+ dependencies:
+ minipass: 3.3.6
+
+ minipass-pipeline@1.2.4:
+ dependencies:
+ minipass: 3.3.6
+
+ minipass-sized@1.0.3:
+ dependencies:
+ minipass: 3.3.6
+
+ minipass@3.3.6:
+ dependencies:
+ yallist: 4.0.0
+
+ minipass@5.0.0: {}
+
+ minipass@7.1.2: {}
+
+ minizlib@2.1.2:
+ dependencies:
+ minipass: 3.3.6
+ yallist: 4.0.0
+
+ mkdirp@1.0.4: {}
+
+ ms@2.1.3: {}
+
+ nan@2.22.0: {}
+
+ negotiator@0.6.4: {}
+
+ node-gyp@10.2.0:
+ dependencies:
+ env-paths: 2.2.1
+ exponential-backoff: 3.1.1
+ glob: 10.4.5
+ graceful-fs: 4.2.11
+ make-fetch-happen: 13.0.1
+ nopt: 7.2.1
+ proc-log: 4.2.0
+ semver: 7.6.3
+ tar: 6.2.1
+ which: 4.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ nopt@7.2.1:
+ dependencies:
+ abbrev: 2.0.0
+
+ p-map@4.0.0:
+ dependencies:
+ aggregate-error: 3.1.0
+
+ package-json-from-dist@1.0.1: {}
+
+ path-key@3.1.1: {}
+
+ path-scurry@1.11.1:
+ dependencies:
+ lru-cache: 10.4.3
+ minipass: 7.1.2
+
+ path-scurry@2.0.0:
+ dependencies:
+ lru-cache: 11.0.1
+ minipass: 7.1.2
+
+ picocolors@1.1.1: {}
+
+ proc-log@4.2.0: {}
+
+ promise-retry@2.0.1:
+ dependencies:
+ err-code: 2.0.3
+ retry: 0.12.0
+
+ proxy-from-env@1.1.0: {}
+
require-directory@2.1.1: {}
+ retry@0.12.0: {}
+
+ rimraf@6.0.1:
+ dependencies:
+ glob: 11.0.0
+ package-json-from-dist: 1.0.1
+
+ safer-buffer@2.1.2:
+ optional: true
+
+ semver@7.6.3: {}
+
+ shebang-command@2.0.0:
+ dependencies:
+ shebang-regex: 3.0.0
+
+ shebang-regex@3.0.0: {}
+
+ signal-exit@4.1.0: {}
+
+ smart-buffer@4.2.0: {}
+
+ socks-proxy-agent@8.0.4:
+ dependencies:
+ agent-base: 7.1.1
+ debug: 4.3.7
+ socks: 2.8.3
+ transitivePeerDependencies:
+ - supports-color
+
+ socks@2.8.3:
+ dependencies:
+ ip-address: 9.0.5
+ smart-buffer: 4.2.0
+
+ sprintf-js@1.1.3: {}
+
+ ssri@10.0.6:
+ dependencies:
+ minipass: 7.1.2
+
string-width@4.2.3:
dependencies:
emoji-regex: 8.0.0
is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1
+ string-width@5.1.2:
+ dependencies:
+ eastasianwidth: 0.2.0
+ emoji-regex: 9.2.2
+ strip-ansi: 7.1.0
+
strip-ansi@6.0.1:
dependencies:
ansi-regex: 5.0.1
+ strip-ansi@7.1.0:
+ dependencies:
+ ansi-regex: 6.1.0
+
strip-bom@3.0.0: {}
+ tar@6.2.1:
+ dependencies:
+ chownr: 2.0.0
+ fs-minipass: 2.1.0
+ minipass: 5.0.0
+ minizlib: 2.1.2
+ mkdirp: 1.0.4
+ yallist: 4.0.0
+
ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5):
dependencies:
'@cspotcode/source-map-support': 0.8.1
@@ -326,16 +1154,40 @@ snapshots:
undici-types@5.26.5: {}
+ unique-filename@3.0.0:
+ dependencies:
+ unique-slug: 4.0.0
+
+ unique-slug@4.0.0:
+ dependencies:
+ imurmurhash: 0.1.4
+
v8-compile-cache-lib@3.0.1: {}
+ which@2.0.2:
+ dependencies:
+ isexe: 2.0.0
+
+ which@4.0.0:
+ dependencies:
+ isexe: 3.1.1
+
wrap-ansi@7.0.0:
dependencies:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
+ wrap-ansi@8.1.0:
+ dependencies:
+ ansi-styles: 6.2.1
+ string-width: 5.1.2
+ strip-ansi: 7.1.0
+
y18n@5.0.8: {}
+ yallist@4.0.0: {}
+
yargs-parser@21.1.1: {}
yargs@17.7.2: