mirror of
https://github.com/mudabbir-ahmad/peworkshop.git
synced 2026-10-07 19:50:20 +00:00
SCANNER WORKS!!! JUST ADD THE MORE CLUE BUTTONS !!! AND NEXT CLUE ERROR CHECKING
This commit is contained in:
1 parent
07099ba6b4
commit
02a0088d28
11 files changed
+857
-213
No files matched your search
@@ -1,5 +1,5 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect, useRef } from "react";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { useSession } from "next-auth/react";
|
import { useSession } from "next-auth/react";
|
||||||
import {
|
import {
|
||||||
@@ -10,9 +10,8 @@ import {
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
import { use } from "react";
|
import { use } from "react";
|
||||||
import QRCodeHelper from "@/components/QRCodeHelper";
|
|
||||||
|
|
||||||
// Dynamically import the new QR scanner component with no SSR
|
// Dynamically import the QR scanner component with no SSR
|
||||||
const EnhancedQRScanner = dynamic(
|
const EnhancedQRScanner = dynamic(
|
||||||
() => import("@/components/EnhancedQRScanner"),
|
() => import("@/components/EnhancedQRScanner"),
|
||||||
{
|
{
|
||||||
@@ -35,10 +34,13 @@ export default function CluePage({ params }) {
|
|||||||
const [clueFound, setClueFound] = useState(false);
|
const [clueFound, setClueFound] = useState(false);
|
||||||
const [allClues, setAllClues] = useState([]);
|
const [allClues, setAllClues] = useState([]);
|
||||||
const [nextClueId, setNextClueId] = useState(null);
|
const [nextClueId, setNextClueId] = useState(null);
|
||||||
const [huntActive, setHuntActive] = useState(true); // Track hunt active status
|
const [huntActive, setHuntActive] = useState(true);
|
||||||
const [previousHuntState, setPreviousHuntState] = useState(true); // To detect changes
|
const [previousHuntState, setPreviousHuntState] = useState(true);
|
||||||
|
const [showSuccessNotification, setShowSuccessNotification] = useState(false);
|
||||||
|
const [teamData, setTeamData] = useState(null);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { data: session, status } = useSession();
|
const { data: session, status } = useSession();
|
||||||
|
const notificationTimeoutRef = useRef(null);
|
||||||
|
|
||||||
// Check if user is admin
|
// Check if user is admin
|
||||||
const isAdmin = session?.user?.role === "admin";
|
const isAdmin = session?.user?.role === "admin";
|
||||||
@@ -219,9 +221,41 @@ export default function CluePage({ params }) {
|
|||||||
};
|
};
|
||||||
}, [router]);
|
}, [router]);
|
||||||
|
|
||||||
|
// Fetch team data on component mount
|
||||||
|
useEffect(() => {
|
||||||
|
if (status === "authenticated") {
|
||||||
|
fetchTeamData();
|
||||||
|
}
|
||||||
|
}, [status]);
|
||||||
|
|
||||||
|
// Add function to fetch team data
|
||||||
|
const fetchTeamData = async () => {
|
||||||
|
if (!session) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch("/api/user/team", {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Cache-Control": "no-cache, no-store, must-revalidate",
|
||||||
|
},
|
||||||
|
credentials: "include",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const data = await response.json();
|
||||||
|
setTeamData(data);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Failed to fetch team data:", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Handle QR scan result
|
// Handle QR scan result
|
||||||
const handleScan = (data) => {
|
const handleScan = (data) => {
|
||||||
|
// Only update message if we have data
|
||||||
|
if (data) {
|
||||||
setScanMessage(`QR Code scanned: ${data}`);
|
setScanMessage(`QR Code scanned: ${data}`);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Handle multiple QR code formats: "QR123", "123", or even "Clue 123"
|
// Handle multiple QR code formats: "QR123", "123", or even "Clue 123"
|
||||||
@@ -284,6 +318,19 @@ export default function CluePage({ params }) {
|
|||||||
setScanMessage(
|
setScanMessage(
|
||||||
"✅ Clue verified! You can now proceed to the next clue."
|
"✅ Clue verified! You can now proceed to the next clue."
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Show success notification
|
||||||
|
setShowSuccessNotification(true);
|
||||||
|
|
||||||
|
// Clear previous timeout if it exists
|
||||||
|
if (notificationTimeoutRef.current) {
|
||||||
|
clearTimeout(notificationTimeoutRef.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-hide the notification after 5 seconds
|
||||||
|
notificationTimeoutRef.current = setTimeout(() => {
|
||||||
|
setShowSuccessNotification(false);
|
||||||
|
}, 5000);
|
||||||
} else {
|
} else {
|
||||||
setScanMessage("Error verifying clue. Please try again.");
|
setScanMessage("Error verifying clue. Please try again.");
|
||||||
}
|
}
|
||||||
@@ -293,6 +340,15 @@ export default function CluePage({ params }) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Clear notification timeout on component unmount
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
if (notificationTimeoutRef.current) {
|
||||||
|
clearTimeout(notificationTimeoutRef.current);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
// Navigate to the next clue
|
// Navigate to the next clue
|
||||||
const handleNextClue = () => {
|
const handleNextClue = () => {
|
||||||
if (nextClueId) {
|
if (nextClueId) {
|
||||||
@@ -381,7 +437,27 @@ export default function CluePage({ params }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="clue-container">
|
<div className="clue-container">
|
||||||
<div className="timer-display">{elapsedTime}</div>
|
{/* Map Banner with team info and timer */}
|
||||||
|
<div className="map-banner">
|
||||||
|
<div className="team-name">{teamData?.team?.name || "Loading..."}</div>
|
||||||
|
<div className="elapsed-time">
|
||||||
|
<span className="time-value">{elapsedTime}</span>
|
||||||
|
</div>
|
||||||
|
<div className="team-code">{teamData?.team?.code || ""}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{showSuccessNotification && (
|
||||||
|
<div className="success-notification">
|
||||||
|
<div className="success-notification-content">
|
||||||
|
<div className="success-icon">🎉</div>
|
||||||
|
<div className="success-text">
|
||||||
|
<h3>Clue Found!</h3>
|
||||||
|
<p>Great work! You've found this clue.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="clue-content-wrapper">
|
<div className="clue-content-wrapper">
|
||||||
{/* Admin tools section - only visible to admins */}
|
{/* Admin tools section - only visible to admins */}
|
||||||
{isAdmin && (
|
{isAdmin && (
|
||||||
@@ -396,7 +472,7 @@ export default function CluePage({ params }) {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* QR Scanner Section - Removed manual entry button */}
|
{/* QR Scanner Section */}
|
||||||
<div className="scanner-section">
|
<div className="scanner-section">
|
||||||
<h2>Scan QR Code</h2>
|
<h2>Scan QR Code</h2>
|
||||||
<EnhancedQRScanner onScan={handleScan} width={280} height={280} />
|
<EnhancedQRScanner onScan={handleScan} width={280} height={280} />
|
||||||
@@ -405,8 +481,7 @@ export default function CluePage({ params }) {
|
|||||||
{scanMessage}
|
{scanMessage}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{/* Add the QR Code helper component */}
|
{/* QR Code helper removed as requested */}
|
||||||
<QRCodeHelper clueId={clueId} />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Clue Information Section */}
|
{/* Clue Information Section */}
|
||||||
@@ -455,9 +530,9 @@ export default function CluePage({ params }) {
|
|||||||
<div className="nav-icon">👥</div>
|
<div className="nav-icon">👥</div>
|
||||||
<div className="nav-label">Team</div>
|
<div className="nav-label">Team</div>
|
||||||
</Link>
|
</Link>
|
||||||
<Link href="/" className="nav-item">
|
<Link href="/leaderboard" className="nav-item">
|
||||||
<div className="nav-icon">🏠</div>
|
<div className="nav-icon">🏆</div>
|
||||||
<div className="nav-label">Home</div>
|
<div className="nav-label">Leaderboard</div>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -467,11 +542,57 @@ export default function CluePage({ params }) {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background-color: #f4f1ea;
|
background-color: #f4f1ea;
|
||||||
padding: 20px;
|
|
||||||
padding-bottom: 70px; /* Space for bottom navbar */
|
padding-bottom: 70px; /* Space for bottom navbar */
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.success-notification {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: rgba(0, 0, 0, 0.7);
|
||||||
|
z-index: 1000;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
animation: slide-down 0.5s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-notification-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background-color: #4caf50;
|
||||||
|
color: white;
|
||||||
|
padding: 15px 25px;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
|
||||||
|
max-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-icon {
|
||||||
|
font-size: 2rem;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-text h3 {
|
||||||
|
margin: 0 0 5px 0;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-text p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slide-down {
|
||||||
|
0% {
|
||||||
|
transform: translateY(-100%);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.hunt-ended {
|
.hunt-ended {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 30px;
|
padding: 30px;
|
||||||
@@ -497,6 +618,7 @@ export default function CluePage({ params }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.clue-content-wrapper {
|
.clue-content-wrapper {
|
||||||
|
padding: 0 20px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -506,19 +628,6 @@ export default function CluePage({ params }) {
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timer-display {
|
|
||||||
position: absolute;
|
|
||||||
top: 15px;
|
|
||||||
right: 15px;
|
|
||||||
background-color: rgba(0, 0, 0, 0.1);
|
|
||||||
padding: 5px 10px;
|
|
||||||
border-radius: 5px;
|
|
||||||
font-family: monospace;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 1rem;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scanner-section {
|
.scanner-section {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -724,6 +833,61 @@ export default function CluePage({ params }) {
|
|||||||
.admin-refresh-button:hover {
|
.admin-refresh-button:hover {
|
||||||
background-color: #c9302c;
|
background-color: #c9302c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Map Banner Styles */
|
||||||
|
.map-banner {
|
||||||
|
background-color: #68543c;
|
||||||
|
color: white;
|
||||||
|
padding: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
border-bottom: 2px solid #4a3c2a;
|
||||||
|
z-index: 10;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.team-name {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
flex: 1;
|
||||||
|
text-align: left;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.elapsed-time {
|
||||||
|
text-align: center;
|
||||||
|
padding: 5px 10px;
|
||||||
|
background-color: rgba(0, 0, 0, 0.2);
|
||||||
|
border-radius: 8px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-value {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.team-code {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
flex: 1;
|
||||||
|
text-align: right;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove the standalone timer display as it's now in the banner */
|
||||||
|
.timer-display {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
`}</style>
|
`}</style>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -24,8 +24,9 @@ export async function GET(request, context) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the clueId directly from the params
|
// Get the clueId from params - properly awaited
|
||||||
const { clueId } = context.params;
|
const params = await context.params;
|
||||||
|
const { clueId } = params;
|
||||||
|
|
||||||
// Validate clueId is a number
|
// Validate clueId is a number
|
||||||
if (isNaN(parseInt(clueId))) {
|
if (isNaN(parseInt(clueId))) {
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
import { query } from "@/lib/db";
|
||||||
|
import { cookies } from "next/headers";
|
||||||
|
import { verifyToken } from "@/app/api/auth/[...nextauth]/route";
|
||||||
|
|
||||||
|
export async function GET(request, context) {
|
||||||
|
try {
|
||||||
|
const cookieStore = cookies();
|
||||||
|
const token = cookieStore.get("next-auth.session-token")?.value;
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
return Response.json({ error: "Unauthorized" }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const userData = verifyToken(token);
|
||||||
|
if (!userData) {
|
||||||
|
return Response.json({ error: "Invalid session" }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const { teamId } = context.params;
|
||||||
|
const requestedTeamId = parseInt(teamId, 10);
|
||||||
|
const userTeamId = parseInt(userData.teamId, 10);
|
||||||
|
|
||||||
|
console.log("Requested team:", requestedTeamId);
|
||||||
|
console.log("User team:", userTeamId);
|
||||||
|
console.log("User role:", userData.role);
|
||||||
|
|
||||||
|
// Ensure the user is requesting their own team or is an admin
|
||||||
|
if (userTeamId !== requestedTeamId && userData.role !== "admin") {
|
||||||
|
return Response.json(
|
||||||
|
{ error: "Not authorized to view this team" },
|
||||||
|
{ status: 403 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const teamMembers = await query("SELECT * FROM users WHERE team_id = ?", [
|
||||||
|
requestedTeamId,
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!teamMembers) {
|
||||||
|
return Response.json(
|
||||||
|
{ error: "Team members not found" },
|
||||||
|
{ status: 404 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response.json(teamMembers);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Team members fetch error:", error);
|
||||||
|
return Response.json(
|
||||||
|
{ error: "Failed to fetch team members" },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
+342
-69
@@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import { useState, useEffect, useRef } from "react";
|
import { useState, useEffect, useRef } from "react";
|
||||||
import { Scanner } from "@yudiel/react-qr-scanner";
|
import { useZxing } from "react-zxing";
|
||||||
|
import { ensureScannerCompatibility } from "./scanner-polyfill";
|
||||||
|
|
||||||
export default function EnhancedQRScanner({
|
export default function EnhancedQRScanner({
|
||||||
onScan,
|
onScan,
|
||||||
@@ -12,12 +13,38 @@ export default function EnhancedQRScanner({
|
|||||||
const [initialized, setInitialized] = useState(false);
|
const [initialized, setInitialized] = useState(false);
|
||||||
const [cameraActive, setCameraActive] = useState(false);
|
const [cameraActive, setCameraActive] = useState(false);
|
||||||
const [hasCameras, setHasCameras] = useState(true);
|
const [hasCameras, setHasCameras] = useState(true);
|
||||||
const [retryCount, setRetryCount] = useState(0);
|
const [scanSuccess, setScanSuccess] = useState(false);
|
||||||
const maxRetries = 3;
|
const [manualInputValue, setManualInputValue] = useState("");
|
||||||
const scannerRef = useRef(null);
|
const [torchEnabled, setTorchEnabled] = useState(false);
|
||||||
|
const inputRef = useRef(null);
|
||||||
|
const [cameraPermissionDenied, setCameraPermissionDenied] = useState(false);
|
||||||
|
|
||||||
// Check if we're in a secure context
|
// Define video constraints explicitly
|
||||||
|
const videoConstraints = {
|
||||||
|
facingMode: "environment",
|
||||||
|
width: { min: 640, ideal: 1280, max: 1920 },
|
||||||
|
height: { min: 480, ideal: 720, max: 1080 },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Setup the zxing scanner hook with explicit video constraints
|
||||||
|
const { ref, torch } = useZxing({
|
||||||
|
onDecodeResult(result) {
|
||||||
|
handleDecode(result.getText());
|
||||||
|
},
|
||||||
|
onError(error) {
|
||||||
|
handleError(error);
|
||||||
|
},
|
||||||
|
constraints: {
|
||||||
|
video: videoConstraints,
|
||||||
|
},
|
||||||
|
paused: !cameraActive,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check if we're in a secure context and if camera is accessible
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// Ensure scanner compatibility
|
||||||
|
ensureScannerCompatibility();
|
||||||
|
|
||||||
// Check if we're in a secure context (https or localhost)
|
// Check if we're in a secure context (https or localhost)
|
||||||
const secure = window.isSecureContext;
|
const secure = window.isSecureContext;
|
||||||
setIsSecureContext(secure);
|
setIsSecureContext(secure);
|
||||||
@@ -25,6 +52,23 @@ export default function EnhancedQRScanner({
|
|||||||
// Check if camera can be accessed
|
// Check if camera can be accessed
|
||||||
async function checkCameraAccess() {
|
async function checkCameraAccess() {
|
||||||
try {
|
try {
|
||||||
|
// First check if MediaDevices API is supported
|
||||||
|
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
|
||||||
|
throw new Error("MediaDevices API is not supported in this browser");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Explicitly request video permission - important to avoid the error
|
||||||
|
const stream = await navigator.mediaDevices.getUserMedia({
|
||||||
|
video: true,
|
||||||
|
audio: false
|
||||||
|
});
|
||||||
|
|
||||||
|
// If we got a stream, we have permission - release it immediately
|
||||||
|
if (stream) {
|
||||||
|
stream.getTracks().forEach(track => track.stop());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now enumerate devices to confirm we have video devices
|
||||||
const devices = await navigator.mediaDevices.enumerateDevices();
|
const devices = await navigator.mediaDevices.enumerateDevices();
|
||||||
const videoDevices = devices.filter(
|
const videoDevices = devices.filter(
|
||||||
(device) => device.kind === "videoinput"
|
(device) => device.kind === "videoinput"
|
||||||
@@ -37,38 +81,88 @@ export default function EnhancedQRScanner({
|
|||||||
setHasCameras(false);
|
setHasCameras(false);
|
||||||
} else {
|
} else {
|
||||||
setHasCameras(true);
|
setHasCameras(true);
|
||||||
|
setCameraActive(true); // Activate camera if we have permission
|
||||||
}
|
}
|
||||||
|
|
||||||
setInitialized(true);
|
setInitialized(true);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Error checking camera devices:", err);
|
console.error("Camera access error:", err);
|
||||||
setError(`Camera initialization error: ${err.message}`);
|
|
||||||
|
// Handle permission denied specifically
|
||||||
|
if (err.name === "NotAllowedError" || err.name === "PermissionDeniedError") {
|
||||||
|
setCameraPermissionDenied(true);
|
||||||
|
setError("Camera permission denied. Please allow camera access in your browser settings.");
|
||||||
|
} else {
|
||||||
|
setError(`Camera error: ${err.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
setInitialized(true);
|
setInitialized(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isSecureContext) {
|
||||||
checkCameraAccess();
|
checkCameraAccess();
|
||||||
|
} else {
|
||||||
|
setInitialized(true); // Still mark as initialized even if not secure
|
||||||
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Handle successful scan
|
// Toggle torch/flashlight
|
||||||
const handleDecode = (result) => {
|
const toggleTorch = () => {
|
||||||
if (onScan && result) {
|
if (torch) {
|
||||||
onScan(result);
|
setTorchEnabled(!torchEnabled);
|
||||||
|
torch.toggled = !torchEnabled;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Try to restart the camera
|
// Handle decode result
|
||||||
const retryCamera = () => {
|
const handleDecode = (text) => {
|
||||||
if (retryCount < maxRetries) {
|
console.log("QR scan result:", text);
|
||||||
|
|
||||||
|
if (!onScan || !text) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Show success visual
|
||||||
|
setScanSuccess(true);
|
||||||
|
setTimeout(() => setScanSuccess(false), 1500);
|
||||||
|
|
||||||
|
// Call the onScan callback with the decoded text
|
||||||
|
onScan(text);
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error processing QR scan result:", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Manually request camera access
|
||||||
|
const requestCameraAccess = async () => {
|
||||||
|
try {
|
||||||
setError(null);
|
setError(null);
|
||||||
setRetryCount((prev) => prev + 1);
|
|
||||||
// Force re-render of scanner component
|
// Explicitly request video permission
|
||||||
setCameraActive(false);
|
const stream = await navigator.mediaDevices.getUserMedia({
|
||||||
setTimeout(() => setCameraActive(true), 500);
|
video: true,
|
||||||
} else {
|
audio: false
|
||||||
setError(
|
});
|
||||||
"Could not access camera after multiple attempts. Please refresh the page or try another device."
|
|
||||||
);
|
// If we got a stream, we have permission
|
||||||
|
if (stream) {
|
||||||
|
// Release the stream since useZxing will request it again
|
||||||
|
stream.getTracks().forEach(track => track.stop());
|
||||||
|
setCameraActive(true);
|
||||||
|
setCameraPermissionDenied(false);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Failed to get camera permission:", err);
|
||||||
|
setError(`Camera error: ${err.message}`);
|
||||||
|
setCameraPermissionDenied(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle manual input submission
|
||||||
|
const handleManualSubmit = () => {
|
||||||
|
if (manualInputValue.trim()) {
|
||||||
|
onScan(manualInputValue.trim());
|
||||||
|
setManualInputValue("");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -89,6 +183,7 @@ export default function EnhancedQRScanner({
|
|||||||
) {
|
) {
|
||||||
errorMessage +=
|
errorMessage +=
|
||||||
"Camera permission denied. Please allow camera access in your browser settings.";
|
"Camera permission denied. Please allow camera access in your browser settings.";
|
||||||
|
setCameraPermissionDenied(true);
|
||||||
} else if (
|
} else if (
|
||||||
error.name === "NotFoundError" ||
|
error.name === "NotFoundError" ||
|
||||||
error.name === "DevicesNotFoundError"
|
error.name === "DevicesNotFoundError"
|
||||||
@@ -111,13 +206,6 @@ export default function EnhancedQRScanner({
|
|||||||
setError(errorMessage);
|
setError(errorMessage);
|
||||||
};
|
};
|
||||||
|
|
||||||
// When initialized, activate camera
|
|
||||||
useEffect(() => {
|
|
||||||
if (initialized && hasCameras && isSecureContext && !error) {
|
|
||||||
setCameraActive(true);
|
|
||||||
}
|
|
||||||
}, [initialized, hasCameras, isSecureContext, error]);
|
|
||||||
|
|
||||||
// Handle secure context warning
|
// Handle secure context warning
|
||||||
if (!isSecureContext) {
|
if (!isSecureContext) {
|
||||||
return (
|
return (
|
||||||
@@ -129,6 +217,7 @@ export default function EnhancedQRScanner({
|
|||||||
network IP.
|
network IP.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<ManualInput onScan={onScan} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -147,8 +236,29 @@ export default function EnhancedQRScanner({
|
|||||||
{error && (
|
{error && (
|
||||||
<div className="scanner-error">
|
<div className="scanner-error">
|
||||||
<p>{error}</p>
|
<p>{error}</p>
|
||||||
{retryCount < maxRetries && (
|
{cameraPermissionDenied ? (
|
||||||
<button className="retry-button" onClick={retryCamera}>
|
<div className="permission-help">
|
||||||
|
<p>To fix this issue:</p>
|
||||||
|
<ol>
|
||||||
|
<li>Click the camera icon in your browser's address bar</li>
|
||||||
|
<li>Select "Allow" for camera access</li>
|
||||||
|
<li>Refresh this page</li>
|
||||||
|
</ol>
|
||||||
|
<button
|
||||||
|
className="retry-button"
|
||||||
|
onClick={requestCameraAccess}
|
||||||
|
>
|
||||||
|
Request Camera Permission
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
className="retry-button"
|
||||||
|
onClick={() => {
|
||||||
|
setError(null);
|
||||||
|
requestCameraAccess();
|
||||||
|
}}
|
||||||
|
>
|
||||||
Retry Camera Access
|
Retry Camera Access
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
@@ -157,63 +267,54 @@ export default function EnhancedQRScanner({
|
|||||||
|
|
||||||
{cameraActive && !error && (
|
{cameraActive && !error && (
|
||||||
<div
|
<div
|
||||||
className="scanner-container"
|
className={`scanner-container ${scanSuccess ? "scan-success" : ""}`}
|
||||||
style={{ width, height }}
|
style={{ width, height }}
|
||||||
ref={scannerRef}
|
|
||||||
>
|
>
|
||||||
<Scanner
|
<video
|
||||||
onResult={handleDecode}
|
ref={ref}
|
||||||
onError={handleError}
|
className="scanner-video"
|
||||||
constraints={{
|
style={{
|
||||||
facingMode: "environment",
|
width: '100%',
|
||||||
width: { min: 640, ideal: 1280, max: 1920 },
|
height: '100%',
|
||||||
height: { min: 480, ideal: 720, max: 1080 },
|
objectFit: 'cover',
|
||||||
aspectRatio: { ideal: 1 },
|
|
||||||
}}
|
}}
|
||||||
containerStyle={{
|
|
||||||
width: "100%",
|
|
||||||
height: "100%",
|
|
||||||
borderRadius: "8px",
|
|
||||||
overflow: "hidden",
|
|
||||||
}}
|
|
||||||
videoStyle={{
|
|
||||||
objectFit: "cover",
|
|
||||||
width: "100%",
|
|
||||||
height: "100%",
|
|
||||||
}}
|
|
||||||
scanDelay={500}
|
|
||||||
/>
|
/>
|
||||||
|
{scanSuccess && <div className="scan-overlay">✓</div>}
|
||||||
|
|
||||||
|
{/* Scanning frame to help user focus */}
|
||||||
|
<div className="scanning-frame"></div>
|
||||||
|
|
||||||
|
{/* Add flashlight toggle button if available */}
|
||||||
|
{torch && (
|
||||||
|
<button
|
||||||
|
className={`torch-button ${torchEnabled ? 'active' : ''}`}
|
||||||
|
onClick={toggleTorch}
|
||||||
|
>
|
||||||
|
{torchEnabled ? '💡 Off' : '💡 On'}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Text input fallback when camera fails */}
|
{/* Text input fallback when camera fails */}
|
||||||
{(!cameraActive || error) && (
|
{(!cameraActive || error) && (
|
||||||
<div className="manual-input-container">
|
<div className="manual-input-container">
|
||||||
<p className="fallback-text">
|
<p className="fallback-text">Enter the QR code manually:</p>
|
||||||
Having trouble with the camera? Try entering a code manually:
|
|
||||||
</p>
|
|
||||||
<div className="input-container">
|
<div className="input-container">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Enter QR code (e.g. QR1)"
|
placeholder="Enter QR code (e.g. QR1)"
|
||||||
className="manual-input"
|
className="manual-input"
|
||||||
|
value={manualInputValue}
|
||||||
|
onChange={(e) => setManualInputValue(e.target.value)}
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (e.key === "Enter" && e.target.value) {
|
if (e.key === "Enter") {
|
||||||
onScan(e.target.value);
|
handleManualSubmit();
|
||||||
e.target.value = "";
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
ref={inputRef}
|
||||||
/>
|
/>
|
||||||
<button
|
<button className="submit-button" onClick={handleManualSubmit}>
|
||||||
className="submit-button"
|
|
||||||
onClick={(e) => {
|
|
||||||
const input = e.target.previousSibling;
|
|
||||||
if (input.value) {
|
|
||||||
onScan(input.value);
|
|
||||||
input.value = "";
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Submit
|
Submit
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -238,6 +339,29 @@ export default function EnhancedQRScanner({
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.permission-help {
|
||||||
|
margin-top: 12px;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 10px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.permission-help p {
|
||||||
|
margin: 0 0 8px 0;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.permission-help ol {
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.permission-help li {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.retry-button {
|
.retry-button {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
@@ -271,6 +395,76 @@ export default function EnhancedQRScanner({
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border: 2px solid #ddd;
|
border: 2px solid #ddd;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scanning-frame {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
width: 70%;
|
||||||
|
height: 70%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
border: 2px solid rgba(255, 255, 255, 0.8);
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.3);
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.torch-button {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 15px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
z-index: 3;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.torch-button.active {
|
||||||
|
background-color: rgba(255, 193, 7, 0.8);
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scan-success {
|
||||||
|
border-color: #4caf50;
|
||||||
|
box-shadow: 0 0 15px rgba(76, 175, 80, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.scan-overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background-color: rgba(76, 175, 80, 0.5);
|
||||||
|
color: white;
|
||||||
|
font-size: 80px;
|
||||||
|
animation: fade-in-out 1.5s forwards;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in-out {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
20% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
80% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.manual-input-container {
|
.manual-input-container {
|
||||||
@@ -315,3 +509,82 @@ export default function EnhancedQRScanner({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper component for manual input
|
||||||
|
function ManualInput({ onScan }) {
|
||||||
|
const [value, setValue] = useState("");
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
if (value.trim()) {
|
||||||
|
onScan(value.trim());
|
||||||
|
setValue("");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="manual-input-wrapper">
|
||||||
|
<h3>Manual Code Entry</h3>
|
||||||
|
<p>Enter the QR code value manually:</p>
|
||||||
|
<div className="input-row">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={value}
|
||||||
|
onChange={(e) => setValue(e.target.value)}
|
||||||
|
placeholder="Enter code (e.g. QR1)"
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
handleSubmit();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<button onClick={handleSubmit}>Submit</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style jsx>{`
|
||||||
|
.manual-input-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 300px;
|
||||||
|
margin: 20px 0;
|
||||||
|
padding: 15px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin-top: 0;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
color: #666;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-row {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
flex: 1;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px 0 0 4px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 10px 15px;
|
||||||
|
background-color: #68543c;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0 4px 4px 0;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
+34
-4
@@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { Scanner } from "@yudiel/react-qr-scanner";
|
import QrScanner from "@yudiel/react-qr-scanner"; // Correct import
|
||||||
|
|
||||||
export default function QRScanner({ onScan, width = 300, height = 300 }) {
|
export default function QRScanner({ onScan, width = 300, height = 300 }) {
|
||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
@@ -39,8 +39,37 @@ export default function QRScanner({ onScan, width = 300, height = 300 }) {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleDecode = (result) => {
|
const handleDecode = (result) => {
|
||||||
if (onScan && result) {
|
console.log("QR scan result:", result);
|
||||||
|
|
||||||
|
if (!onScan || !result) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Handle different result formats
|
||||||
|
if (result && typeof result === "object") {
|
||||||
|
if (result.text) {
|
||||||
|
onScan(result.text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (result.data) {
|
||||||
|
onScan(result.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (result.toString && typeof result.toString === "function") {
|
||||||
|
const stringValue = result.toString();
|
||||||
|
if (stringValue !== "[object Object]") {
|
||||||
|
onScan(stringValue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (typeof result === "string") {
|
||||||
onScan(result);
|
onScan(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last resort
|
||||||
|
onScan(String(result));
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error processing QR scan result:", err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -112,8 +141,8 @@ export default function QRScanner({ onScan, width = 300, height = 300 }) {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="scanner-container" style={{ width, height }}>
|
<div className="scanner-container" style={{ width, height }}>
|
||||||
<Scanner
|
<QrScanner
|
||||||
onResult={handleDecode}
|
onDecode={handleDecode} // Using onDecode instead of onResult
|
||||||
onError={handleError}
|
onError={handleError}
|
||||||
constraints={{
|
constraints={{
|
||||||
facingMode: "environment",
|
facingMode: "environment",
|
||||||
@@ -131,6 +160,7 @@ export default function QRScanner({ onScan, width = 300, height = 300 }) {
|
|||||||
width: "100%",
|
width: "100%",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
}}
|
}}
|
||||||
|
scanDelay={300} // Faster scanning
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
// This is a helper function to ensure QR scanner compatibility
|
||||||
|
export const ensureScannerCompatibility = () => {
|
||||||
|
// Add basic polyfills for methods that might be missing
|
||||||
|
if (typeof Function.prototype.bind !== "function") {
|
||||||
|
Function.prototype.bind = function (context) {
|
||||||
|
const fn = this;
|
||||||
|
return function () {
|
||||||
|
return fn.apply(context, arguments);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure MediaDevices API is available
|
||||||
|
if (typeof window !== "undefined") {
|
||||||
|
if (!navigator.mediaDevices) {
|
||||||
|
navigator.mediaDevices = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Polyfill for older browsers that don't implement getUserMedia
|
||||||
|
if (!navigator.mediaDevices.getUserMedia) {
|
||||||
|
navigator.mediaDevices.getUserMedia = function(constraints) {
|
||||||
|
const getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
|
||||||
|
|
||||||
|
// Return a rejected promise if getUserMedia is not implemented
|
||||||
|
if (!getUserMedia) {
|
||||||
|
return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, wrap the call to the old navigator.getUserMedia with a Promise
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
getUserMedia.call(navigator, constraints, resolve, reject);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure console methods exist for debugging
|
||||||
|
if (!window.console) window.console = {};
|
||||||
|
const methods = ["log", "error", "warn", "info"];
|
||||||
|
methods.forEach((method) => {
|
||||||
|
if (!window.console[method]) {
|
||||||
|
window.console[method] = function () {};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper function to check if camera is available and accessible
|
||||||
|
export const checkCameraAvailability = async () => {
|
||||||
|
try {
|
||||||
|
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
|
||||||
|
return { available: false, error: 'MediaDevices API not supported' };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to access the camera with explicit video request
|
||||||
|
const stream = await navigator.mediaDevices.getUserMedia({
|
||||||
|
video: true,
|
||||||
|
audio: false
|
||||||
|
});
|
||||||
|
|
||||||
|
// If we get here, camera is available - stop the stream
|
||||||
|
if (stream) {
|
||||||
|
stream.getTracks().forEach(track => track.stop());
|
||||||
|
}
|
||||||
|
|
||||||
|
return { available: true };
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
available: false,
|
||||||
|
error: error.message,
|
||||||
|
name: error.name,
|
||||||
|
permission: error.name === 'NotAllowedError' || error.name === 'PermissionDeniedError'
|
||||||
|
? 'denied'
|
||||||
|
: 'unknown'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import sqlite3 from "sqlite3";
|
import sqlite3 from "sqlite3";
|
||||||
|
|
||||||
|
// Create a singleton database connection
|
||||||
let db = null;
|
let db = null;
|
||||||
|
|
||||||
export function getDb() {
|
export function getDb() {
|
||||||
@@ -15,11 +16,12 @@ export function getDb() {
|
|||||||
return db;
|
return db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Execute a query that returns a single row
|
||||||
export function queryOne(sql, params = []) {
|
export function queryOne(sql, params = []) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const db = getDb();
|
const db = getDb();
|
||||||
if (!db) {
|
if (!db) {
|
||||||
reject(new Error("Database connection not available"));
|
reject(Error("Database connection not available"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,17 +33,17 @@ export function queryOne(sql, params = []) {
|
|||||||
reject(err);
|
reject(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve(row);
|
resolve(row);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Execute a query that returns multiple rows
|
||||||
export function query(sql, params = []) {
|
export function query(sql, params = []) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const db = getDb();
|
const db = getDb();
|
||||||
if (!db) {
|
if (!db) {
|
||||||
reject(new Error("Database connection not available"));
|
reject(Error("Database connection not available"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,23 +55,23 @@ export function query(sql, params = []) {
|
|||||||
reject(err);
|
reject(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve(rows || []);
|
resolve(rows || []);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Execute a query that doesn't return results (INSERT, UPDATE, DELETE)
|
||||||
export function run(sql, params = []) {
|
export function run(sql, params = []) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const db = getDb();
|
const db = getDb();
|
||||||
if (!db) {
|
if (!db) {
|
||||||
const error = new Error("Database connection not available");
|
const error = Error("Database connection not available");
|
||||||
console.error(error);
|
console.error(error);
|
||||||
reject(error);
|
reject(error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add better logging
|
// Log transaction operations for debugging
|
||||||
if (
|
if (
|
||||||
sql.toLowerCase().includes("begin") ||
|
sql.toLowerCase().includes("begin") ||
|
||||||
sql.toLowerCase().includes("commit") ||
|
sql.toLowerCase().includes("commit") ||
|
||||||
@@ -86,12 +88,28 @@ export function run(sql, params = []) {
|
|||||||
reject(err);
|
reject(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
resolve({ lastID: this.lastID, changes: this.changes });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
resolve({
|
// Close database connection - useful for tests and clean shutdown
|
||||||
lastID: this.lastID,
|
export function closeDb() {
|
||||||
changes: this.changes,
|
return new Promise((resolve, reject) => {
|
||||||
});
|
if (db) {
|
||||||
|
db.close((err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("Error closing database:", err.message);
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
console.log("Database connection closed");
|
||||||
|
db = null;
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Generated
+18
-1
@@ -21,6 +21,7 @@
|
|||||||
"qrcode.react": "^4.2.0",
|
"qrcode.react": "^4.2.0",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
|
"react-zxing": "^2.0.0",
|
||||||
"sqlite": "^5.1.1",
|
"sqlite": "^5.1.1",
|
||||||
"sqlite3": "^5.1.7"
|
"sqlite3": "^5.1.7"
|
||||||
},
|
},
|
||||||
@@ -1446,7 +1447,7 @@
|
|||||||
"react-dom": "^18.0.0"
|
"react-dom": "^18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@yudiel/react-qr-scanner/node_modules/@zxing/library": {
|
"node_modules/@zxing/library": {
|
||||||
"version": "0.20.0",
|
"version": "0.20.0",
|
||||||
"resolved": "https://registry.npmjs.org/@zxing/library/-/library-0.20.0.tgz",
|
"resolved": "https://registry.npmjs.org/@zxing/library/-/library-0.20.0.tgz",
|
||||||
"integrity": "sha512-6Ev6rcqVjMakZFIDvbUf0dtpPGeZMTfyxYg4HkVWioWeN7cRcnUWT3bU6sdohc82O1nPXcjq6WiGfXX2Pnit6A==",
|
"integrity": "sha512-6Ev6rcqVjMakZFIDvbUf0dtpPGeZMTfyxYg4HkVWioWeN7cRcnUWT3bU6sdohc82O1nPXcjq6WiGfXX2Pnit6A==",
|
||||||
@@ -5782,6 +5783,22 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/react-zxing": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-zxing/-/react-zxing-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-iFZ8KPfZl+biiT5/bluuMGaSLQAwnE0ialQHbJioHFuwqhCo1WmjQmAtI4WN8BmiKYFVkHGgwHSl+pgwpwtQEg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@zxing/library": "^0.20.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18 || ^20 || ^22",
|
||||||
|
"yarn": "^1.22"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/readable-stream": {
|
"node_modules/readable-stream": {
|
||||||
"version": "3.6.2",
|
"version": "3.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
"qrcode.react": "^4.2.0",
|
"qrcode.react": "^4.2.0",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
|
"react-zxing": "^2.0.0",
|
||||||
"sqlite": "^5.1.1",
|
"sqlite": "^5.1.1",
|
||||||
"sqlite3": "^5.1.7"
|
"sqlite3": "^5.1.7"
|
||||||
},
|
},
|
||||||
@@ -39,3 +40,4 @@
|
|||||||
"typescript": "^5"
|
"typescript": "^5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
"@emnapi/runtime@^1.2.0":
|
"@emnapi/runtime@^1.2.0":
|
||||||
version "1.3.1"
|
version "1.3.1"
|
||||||
resolved "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz"
|
resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.3.1.tgz#0fcaa575afc31f455fd33534c19381cfce6c6f60"
|
||||||
integrity sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==
|
integrity sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib "^2.4.0"
|
tslib "^2.4.0"
|
||||||
@@ -122,110 +122,110 @@
|
|||||||
|
|
||||||
"@img/sharp-darwin-arm64@0.33.5":
|
"@img/sharp-darwin-arm64@0.33.5":
|
||||||
version "0.33.5"
|
version "0.33.5"
|
||||||
resolved "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz"
|
resolved "https://registry.yarnpkg.com/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz#ef5b5a07862805f1e8145a377c8ba6e98813ca08"
|
||||||
integrity sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==
|
integrity sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
"@img/sharp-libvips-darwin-arm64" "1.0.4"
|
"@img/sharp-libvips-darwin-arm64" "1.0.4"
|
||||||
|
|
||||||
"@img/sharp-darwin-x64@0.33.5":
|
"@img/sharp-darwin-x64@0.33.5":
|
||||||
version "0.33.5"
|
version "0.33.5"
|
||||||
resolved "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz"
|
resolved "https://registry.yarnpkg.com/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz#e03d3451cd9e664faa72948cc70a403ea4063d61"
|
||||||
integrity sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==
|
integrity sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
"@img/sharp-libvips-darwin-x64" "1.0.4"
|
"@img/sharp-libvips-darwin-x64" "1.0.4"
|
||||||
|
|
||||||
"@img/sharp-libvips-darwin-arm64@1.0.4":
|
"@img/sharp-libvips-darwin-arm64@1.0.4":
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz"
|
resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz#447c5026700c01a993c7804eb8af5f6e9868c07f"
|
||||||
integrity sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==
|
integrity sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==
|
||||||
|
|
||||||
"@img/sharp-libvips-darwin-x64@1.0.4":
|
"@img/sharp-libvips-darwin-x64@1.0.4":
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz"
|
resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz#e0456f8f7c623f9dbfbdc77383caa72281d86062"
|
||||||
integrity sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==
|
integrity sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==
|
||||||
|
|
||||||
"@img/sharp-libvips-linux-arm@1.0.5":
|
|
||||||
version "1.0.5"
|
|
||||||
resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz"
|
|
||||||
integrity sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==
|
|
||||||
|
|
||||||
"@img/sharp-libvips-linux-arm64@1.0.4":
|
"@img/sharp-libvips-linux-arm64@1.0.4":
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz"
|
resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz#979b1c66c9a91f7ff2893556ef267f90ebe51704"
|
||||||
integrity sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==
|
integrity sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==
|
||||||
|
|
||||||
|
"@img/sharp-libvips-linux-arm@1.0.5":
|
||||||
|
version "1.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz#99f922d4e15216ec205dcb6891b721bfd2884197"
|
||||||
|
integrity sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==
|
||||||
|
|
||||||
"@img/sharp-libvips-linux-s390x@1.0.4":
|
"@img/sharp-libvips-linux-s390x@1.0.4":
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz"
|
resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz#f8a5eb1f374a082f72b3f45e2fb25b8118a8a5ce"
|
||||||
integrity sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==
|
integrity sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==
|
||||||
|
|
||||||
"@img/sharp-libvips-linux-x64@1.0.4":
|
"@img/sharp-libvips-linux-x64@1.0.4":
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz"
|
resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz#d4c4619cdd157774906e15770ee119931c7ef5e0"
|
||||||
integrity sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==
|
integrity sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==
|
||||||
|
|
||||||
"@img/sharp-libvips-linuxmusl-arm64@1.0.4":
|
"@img/sharp-libvips-linuxmusl-arm64@1.0.4":
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz"
|
resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz#166778da0f48dd2bded1fa3033cee6b588f0d5d5"
|
||||||
integrity sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==
|
integrity sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==
|
||||||
|
|
||||||
"@img/sharp-libvips-linuxmusl-x64@1.0.4":
|
"@img/sharp-libvips-linuxmusl-x64@1.0.4":
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz"
|
resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz#93794e4d7720b077fcad3e02982f2f1c246751ff"
|
||||||
integrity sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==
|
integrity sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==
|
||||||
|
|
||||||
"@img/sharp-linux-arm@0.33.5":
|
|
||||||
version "0.33.5"
|
|
||||||
resolved "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz"
|
|
||||||
integrity sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==
|
|
||||||
optionalDependencies:
|
|
||||||
"@img/sharp-libvips-linux-arm" "1.0.5"
|
|
||||||
|
|
||||||
"@img/sharp-linux-arm64@0.33.5":
|
"@img/sharp-linux-arm64@0.33.5":
|
||||||
version "0.33.5"
|
version "0.33.5"
|
||||||
resolved "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz"
|
resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz#edb0697e7a8279c9fc829a60fc35644c4839bb22"
|
||||||
integrity sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==
|
integrity sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
"@img/sharp-libvips-linux-arm64" "1.0.4"
|
"@img/sharp-libvips-linux-arm64" "1.0.4"
|
||||||
|
|
||||||
|
"@img/sharp-linux-arm@0.33.5":
|
||||||
|
version "0.33.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz#422c1a352e7b5832842577dc51602bcd5b6f5eff"
|
||||||
|
integrity sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==
|
||||||
|
optionalDependencies:
|
||||||
|
"@img/sharp-libvips-linux-arm" "1.0.5"
|
||||||
|
|
||||||
"@img/sharp-linux-s390x@0.33.5":
|
"@img/sharp-linux-s390x@0.33.5":
|
||||||
version "0.33.5"
|
version "0.33.5"
|
||||||
resolved "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz"
|
resolved "https://registry.yarnpkg.com/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz#f5c077926b48e97e4a04d004dfaf175972059667"
|
||||||
integrity sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==
|
integrity sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
"@img/sharp-libvips-linux-s390x" "1.0.4"
|
"@img/sharp-libvips-linux-s390x" "1.0.4"
|
||||||
|
|
||||||
"@img/sharp-linux-x64@0.33.5":
|
"@img/sharp-linux-x64@0.33.5":
|
||||||
version "0.33.5"
|
version "0.33.5"
|
||||||
resolved "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz"
|
resolved "https://registry.yarnpkg.com/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz#d806e0afd71ae6775cc87f0da8f2d03a7c2209cb"
|
||||||
integrity sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==
|
integrity sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
"@img/sharp-libvips-linux-x64" "1.0.4"
|
"@img/sharp-libvips-linux-x64" "1.0.4"
|
||||||
|
|
||||||
"@img/sharp-linuxmusl-arm64@0.33.5":
|
"@img/sharp-linuxmusl-arm64@0.33.5":
|
||||||
version "0.33.5"
|
version "0.33.5"
|
||||||
resolved "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz"
|
resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz#252975b915894fb315af5deea174651e208d3d6b"
|
||||||
integrity sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==
|
integrity sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
"@img/sharp-libvips-linuxmusl-arm64" "1.0.4"
|
"@img/sharp-libvips-linuxmusl-arm64" "1.0.4"
|
||||||
|
|
||||||
"@img/sharp-linuxmusl-x64@0.33.5":
|
"@img/sharp-linuxmusl-x64@0.33.5":
|
||||||
version "0.33.5"
|
version "0.33.5"
|
||||||
resolved "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz"
|
resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz#3f4609ac5d8ef8ec7dadee80b560961a60fd4f48"
|
||||||
integrity sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==
|
integrity sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
"@img/sharp-libvips-linuxmusl-x64" "1.0.4"
|
"@img/sharp-libvips-linuxmusl-x64" "1.0.4"
|
||||||
|
|
||||||
"@img/sharp-wasm32@0.33.5":
|
"@img/sharp-wasm32@0.33.5":
|
||||||
version "0.33.5"
|
version "0.33.5"
|
||||||
resolved "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz"
|
resolved "https://registry.yarnpkg.com/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz#6f44f3283069d935bb5ca5813153572f3e6f61a1"
|
||||||
integrity sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==
|
integrity sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@emnapi/runtime" "^1.2.0"
|
"@emnapi/runtime" "^1.2.0"
|
||||||
|
|
||||||
"@img/sharp-win32-ia32@0.33.5":
|
"@img/sharp-win32-ia32@0.33.5":
|
||||||
version "0.33.5"
|
version "0.33.5"
|
||||||
resolved "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz"
|
resolved "https://registry.yarnpkg.com/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz#1a0c839a40c5351e9885628c85f2e5dfd02b52a9"
|
||||||
integrity sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==
|
integrity sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==
|
||||||
|
|
||||||
"@img/sharp-win32-x64@0.33.5":
|
"@img/sharp-win32-x64@0.33.5":
|
||||||
@@ -247,37 +247,37 @@
|
|||||||
|
|
||||||
"@next/swc-darwin-arm64@15.2.2":
|
"@next/swc-darwin-arm64@15.2.2":
|
||||||
version "15.2.2"
|
version "15.2.2"
|
||||||
resolved "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.2.2.tgz"
|
resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.2.2.tgz#d3131279d4815ed7604eba7bf0063e0b8bfd2135"
|
||||||
integrity sha512-HNBRnz+bkZ+KfyOExpUxTMR0Ow8nkkcE6IlsdEa9W/rI7gefud19+Sn1xYKwB9pdCdxIP1lPru/ZfjfA+iT8pw==
|
integrity sha512-HNBRnz+bkZ+KfyOExpUxTMR0Ow8nkkcE6IlsdEa9W/rI7gefud19+Sn1xYKwB9pdCdxIP1lPru/ZfjfA+iT8pw==
|
||||||
|
|
||||||
"@next/swc-darwin-x64@15.2.2":
|
"@next/swc-darwin-x64@15.2.2":
|
||||||
version "15.2.2"
|
version "15.2.2"
|
||||||
resolved "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.2.2.tgz"
|
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-15.2.2.tgz#8562f6b51177aa30f3a6e95a8b3e0e176a6cb04f"
|
||||||
integrity sha512-mJOUwp7al63tDpLpEFpKwwg5jwvtL1lhRW2fI1Aog0nYCPAhxbJsaZKdoVyPZCy8MYf/iQVNDuk/+i29iLCzIA==
|
integrity sha512-mJOUwp7al63tDpLpEFpKwwg5jwvtL1lhRW2fI1Aog0nYCPAhxbJsaZKdoVyPZCy8MYf/iQVNDuk/+i29iLCzIA==
|
||||||
|
|
||||||
"@next/swc-linux-arm64-gnu@15.2.2":
|
"@next/swc-linux-arm64-gnu@15.2.2":
|
||||||
version "15.2.2"
|
version "15.2.2"
|
||||||
resolved "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.2.2.tgz"
|
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.2.2.tgz#c2466cffc541f39ae4d435087c81f5899d401903"
|
||||||
integrity sha512-5ZZ0Zwy3SgMr7MfWtRE7cQWVssfOvxYfD9O7XHM7KM4nrf5EOeqwq67ZXDgo86LVmffgsu5tPO57EeFKRnrfSQ==
|
integrity sha512-5ZZ0Zwy3SgMr7MfWtRE7cQWVssfOvxYfD9O7XHM7KM4nrf5EOeqwq67ZXDgo86LVmffgsu5tPO57EeFKRnrfSQ==
|
||||||
|
|
||||||
"@next/swc-linux-arm64-musl@15.2.2":
|
"@next/swc-linux-arm64-musl@15.2.2":
|
||||||
version "15.2.2"
|
version "15.2.2"
|
||||||
resolved "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.2.2.tgz"
|
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.2.2.tgz#24ed87fe47325597e986bd01c427efae53d6b677"
|
||||||
integrity sha512-cgKWBuFMLlJ4TWcFHl1KOaVVUAF8vy4qEvX5KsNd0Yj5mhu989QFCq1WjuaEbv/tO1ZpsQI6h/0YR8bLwEi+nA==
|
integrity sha512-cgKWBuFMLlJ4TWcFHl1KOaVVUAF8vy4qEvX5KsNd0Yj5mhu989QFCq1WjuaEbv/tO1ZpsQI6h/0YR8bLwEi+nA==
|
||||||
|
|
||||||
"@next/swc-linux-x64-gnu@15.2.2":
|
"@next/swc-linux-x64-gnu@15.2.2":
|
||||||
version "15.2.2"
|
version "15.2.2"
|
||||||
resolved "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.2.2.tgz"
|
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.2.2.tgz#0240f44530ca39c1fc899fabe8f33aa35d7e77da"
|
||||||
integrity sha512-c3kWSOSsVL8rcNBBfOq1+/j2PKs2nsMwJUV4icUxRgGBwUOfppeh7YhN5s79enBQFU+8xRgVatFkhHU1QW7yUA==
|
integrity sha512-c3kWSOSsVL8rcNBBfOq1+/j2PKs2nsMwJUV4icUxRgGBwUOfppeh7YhN5s79enBQFU+8xRgVatFkhHU1QW7yUA==
|
||||||
|
|
||||||
"@next/swc-linux-x64-musl@15.2.2":
|
"@next/swc-linux-x64-musl@15.2.2":
|
||||||
version "15.2.2"
|
version "15.2.2"
|
||||||
resolved "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.2.2.tgz"
|
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.2.2.tgz#cca6ce8e9ec89afaa618673f0f8658682c30ff56"
|
||||||
integrity sha512-PXTW9PLTxdNlVYgPJ0equojcq1kNu5NtwcNjRjHAB+/sdoKZ+X8FBu70fdJFadkxFIGekQTyRvPMFF+SOJaQjw==
|
integrity sha512-PXTW9PLTxdNlVYgPJ0equojcq1kNu5NtwcNjRjHAB+/sdoKZ+X8FBu70fdJFadkxFIGekQTyRvPMFF+SOJaQjw==
|
||||||
|
|
||||||
"@next/swc-win32-arm64-msvc@15.2.2":
|
"@next/swc-win32-arm64-msvc@15.2.2":
|
||||||
version "15.2.2"
|
version "15.2.2"
|
||||||
resolved "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.2.2.tgz"
|
resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.2.2.tgz#08f621602ed53fa21ddf6f656160b9186860be15"
|
||||||
integrity sha512-nG644Es5llSGEcTaXhnGWR/aThM/hIaz0jx4MDg4gWC8GfTCp8eDBWZ77CVuv2ha/uL9Ce+nPTfYkSLG67/sHg==
|
integrity sha512-nG644Es5llSGEcTaXhnGWR/aThM/hIaz0jx4MDg4gWC8GfTCp8eDBWZ77CVuv2ha/uL9Ce+nPTfYkSLG67/sHg==
|
||||||
|
|
||||||
"@next/swc-win32-x64-msvc@15.2.2":
|
"@next/swc-win32-x64-msvc@15.2.2":
|
||||||
@@ -293,7 +293,7 @@
|
|||||||
"@nodelib/fs.stat" "2.0.5"
|
"@nodelib/fs.stat" "2.0.5"
|
||||||
run-parallel "^1.1.9"
|
run-parallel "^1.1.9"
|
||||||
|
|
||||||
"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5":
|
"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
|
||||||
version "2.0.5"
|
version "2.0.5"
|
||||||
resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz"
|
resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz"
|
||||||
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
|
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
|
||||||
@@ -365,52 +365,52 @@
|
|||||||
|
|
||||||
"@tailwindcss/oxide-android-arm64@4.0.12":
|
"@tailwindcss/oxide-android-arm64@4.0.12":
|
||||||
version "4.0.12"
|
version "4.0.12"
|
||||||
resolved "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.0.12.tgz"
|
resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.0.12.tgz#f79cf637bc11b0ae71e75b66d7c5ba5159bd3df3"
|
||||||
integrity sha512-dAXCaemu3mHLXcA5GwGlQynX8n7tTdvn5i1zAxRvZ5iC9fWLl5bGnjZnzrQqT7ttxCvRwdVf3IHUnMVdDBO/kQ==
|
integrity sha512-dAXCaemu3mHLXcA5GwGlQynX8n7tTdvn5i1zAxRvZ5iC9fWLl5bGnjZnzrQqT7ttxCvRwdVf3IHUnMVdDBO/kQ==
|
||||||
|
|
||||||
"@tailwindcss/oxide-darwin-arm64@4.0.12":
|
"@tailwindcss/oxide-darwin-arm64@4.0.12":
|
||||||
version "4.0.12"
|
version "4.0.12"
|
||||||
resolved "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.0.12.tgz"
|
resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.0.12.tgz#6b730b5d19ff01748a27af5103966f534a899f07"
|
||||||
integrity sha512-vPNI+TpJQ7sizselDXIJdYkx9Cu6JBdtmRWujw9pVIxW8uz3O2PjgGGzL/7A0sXI8XDjSyRChrUnEW9rQygmJQ==
|
integrity sha512-vPNI+TpJQ7sizselDXIJdYkx9Cu6JBdtmRWujw9pVIxW8uz3O2PjgGGzL/7A0sXI8XDjSyRChrUnEW9rQygmJQ==
|
||||||
|
|
||||||
"@tailwindcss/oxide-darwin-x64@4.0.12":
|
"@tailwindcss/oxide-darwin-x64@4.0.12":
|
||||||
version "4.0.12"
|
version "4.0.12"
|
||||||
resolved "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.0.12.tgz"
|
resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.0.12.tgz#2eb33ba40cbb78922004be9d6b81542347043fe5"
|
||||||
integrity sha512-RL/9jM41Fdq4Efr35C5wgLx98BirnrfwuD+zgMFK6Ir68HeOSqBhW9jsEeC7Y/JcGyPd3MEoJVIU4fAb7YLg7A==
|
integrity sha512-RL/9jM41Fdq4Efr35C5wgLx98BirnrfwuD+zgMFK6Ir68HeOSqBhW9jsEeC7Y/JcGyPd3MEoJVIU4fAb7YLg7A==
|
||||||
|
|
||||||
"@tailwindcss/oxide-freebsd-x64@4.0.12":
|
"@tailwindcss/oxide-freebsd-x64@4.0.12":
|
||||||
version "4.0.12"
|
version "4.0.12"
|
||||||
resolved "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.0.12.tgz"
|
resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.0.12.tgz#317b980504b0bbcaee32c9e4e961f77cdadb02a6"
|
||||||
integrity sha512-7WzWiax+LguJcMEimY0Q4sBLlFXu1tYxVka3+G2M9KmU/3m84J3jAIV4KZWnockbHsbb2XgrEjtlJKVwHQCoRA==
|
integrity sha512-7WzWiax+LguJcMEimY0Q4sBLlFXu1tYxVka3+G2M9KmU/3m84J3jAIV4KZWnockbHsbb2XgrEjtlJKVwHQCoRA==
|
||||||
|
|
||||||
"@tailwindcss/oxide-linux-arm-gnueabihf@4.0.12":
|
"@tailwindcss/oxide-linux-arm-gnueabihf@4.0.12":
|
||||||
version "4.0.12"
|
version "4.0.12"
|
||||||
resolved "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.0.12.tgz"
|
resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.0.12.tgz#0f7153dec6e200327b76775ad2d1154706cef34d"
|
||||||
integrity sha512-X9LRC7jjE1QlfIaBbXjY0PGeQP87lz5mEfLSVs2J1yRc9PSg1tEPS9NBqY4BU9v5toZgJgzKeaNltORyTs22TQ==
|
integrity sha512-X9LRC7jjE1QlfIaBbXjY0PGeQP87lz5mEfLSVs2J1yRc9PSg1tEPS9NBqY4BU9v5toZgJgzKeaNltORyTs22TQ==
|
||||||
|
|
||||||
"@tailwindcss/oxide-linux-arm64-gnu@4.0.12":
|
"@tailwindcss/oxide-linux-arm64-gnu@4.0.12":
|
||||||
version "4.0.12"
|
version "4.0.12"
|
||||||
resolved "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.0.12.tgz"
|
resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.0.12.tgz#50a3ec46600cc998f45a265ebdd5de2d7bb27ee0"
|
||||||
integrity sha512-i24IFNq2402zfDdoWKypXz0ZNS2G4NKaA82tgBlE2OhHIE+4mg2JDb5wVfyP6R+MCm5grgXvurcIcKWvo44QiQ==
|
integrity sha512-i24IFNq2402zfDdoWKypXz0ZNS2G4NKaA82tgBlE2OhHIE+4mg2JDb5wVfyP6R+MCm5grgXvurcIcKWvo44QiQ==
|
||||||
|
|
||||||
"@tailwindcss/oxide-linux-arm64-musl@4.0.12":
|
"@tailwindcss/oxide-linux-arm64-musl@4.0.12":
|
||||||
version "4.0.12"
|
version "4.0.12"
|
||||||
resolved "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.0.12.tgz"
|
resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.0.12.tgz#2de10c5239766e2fb810045fe5b75db54d481fd4"
|
||||||
integrity sha512-LmOdshJBfAGIBG0DdBWhI0n5LTMurnGGJCHcsm9F//ISfsHtCnnYIKgYQui5oOz1SUCkqsMGfkAzWyNKZqbGNw==
|
integrity sha512-LmOdshJBfAGIBG0DdBWhI0n5LTMurnGGJCHcsm9F//ISfsHtCnnYIKgYQui5oOz1SUCkqsMGfkAzWyNKZqbGNw==
|
||||||
|
|
||||||
"@tailwindcss/oxide-linux-x64-gnu@4.0.12":
|
"@tailwindcss/oxide-linux-x64-gnu@4.0.12":
|
||||||
version "4.0.12"
|
version "4.0.12"
|
||||||
resolved "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.0.12.tgz"
|
resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.0.12.tgz#f89a24ffb0f14ea23d110efcbf58baa1db783582"
|
||||||
integrity sha512-OSK667qZRH30ep8RiHbZDQfqkXjnzKxdn0oRwWzgCO8CoTxV+MvIkd0BWdQbYtYuM1wrakARV/Hwp0eA/qzdbw==
|
integrity sha512-OSK667qZRH30ep8RiHbZDQfqkXjnzKxdn0oRwWzgCO8CoTxV+MvIkd0BWdQbYtYuM1wrakARV/Hwp0eA/qzdbw==
|
||||||
|
|
||||||
"@tailwindcss/oxide-linux-x64-musl@4.0.12":
|
"@tailwindcss/oxide-linux-x64-musl@4.0.12":
|
||||||
version "4.0.12"
|
version "4.0.12"
|
||||||
resolved "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.0.12.tgz"
|
resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.0.12.tgz#c53a5b494e241a744f067ba3a261adca80c20af4"
|
||||||
integrity sha512-uylhWq6OWQ8krV8Jk+v0H/3AZKJW6xYMgNMyNnUbbYXWi7hIVdxRKNUB5UvrlC3RxtgsK5EAV2i1CWTRsNcAnA==
|
integrity sha512-uylhWq6OWQ8krV8Jk+v0H/3AZKJW6xYMgNMyNnUbbYXWi7hIVdxRKNUB5UvrlC3RxtgsK5EAV2i1CWTRsNcAnA==
|
||||||
|
|
||||||
"@tailwindcss/oxide-win32-arm64-msvc@4.0.12":
|
"@tailwindcss/oxide-win32-arm64-msvc@4.0.12":
|
||||||
version "4.0.12"
|
version "4.0.12"
|
||||||
resolved "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.0.12.tgz"
|
resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.0.12.tgz#63c0befad43355fb5cea6c64efd946a718acb06b"
|
||||||
integrity sha512-XDLnhMoXZEEOir1LK43/gHHwK84V1GlV8+pAncUAIN2wloeD+nNciI9WRIY/BeFTqES22DhTIGoilSO39xDb2g==
|
integrity sha512-XDLnhMoXZEEOir1LK43/gHHwK84V1GlV8+pAncUAIN2wloeD+nNciI9WRIY/BeFTqES22DhTIGoilSO39xDb2g==
|
||||||
|
|
||||||
"@tailwindcss/oxide-win32-x64-msvc@4.0.12":
|
"@tailwindcss/oxide-win32-x64-msvc@4.0.12":
|
||||||
@@ -603,7 +603,7 @@ acorn@^8.14.0:
|
|||||||
resolved "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz"
|
resolved "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz"
|
||||||
integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==
|
integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==
|
||||||
|
|
||||||
agent-base@^6.0.2, agent-base@6:
|
agent-base@6, agent-base@^6.0.2:
|
||||||
version "6.0.2"
|
version "6.0.2"
|
||||||
resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz"
|
resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz"
|
||||||
integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==
|
integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==
|
||||||
@@ -954,15 +954,14 @@ client-only@0.0.1:
|
|||||||
resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz"
|
resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz"
|
||||||
integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==
|
integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==
|
||||||
|
|
||||||
"clue-hunt-app@file:":
|
"clue-hunt-app@file:.":
|
||||||
version "0.1.0"
|
version "0.1.0"
|
||||||
resolved "file:"
|
|
||||||
dependencies:
|
dependencies:
|
||||||
"@panva/hkdf" "^1.1.1"
|
"@panva/hkdf" "^1.1.1"
|
||||||
"@yudiel/react-qr-scanner" "^1.2.4"
|
"@yudiel/react-qr-scanner" "^1.2.4"
|
||||||
bcryptjs "^3.0.2"
|
bcryptjs "^3.0.2"
|
||||||
better-sqlite3 "^11.8.1"
|
better-sqlite3 "^11.8.1"
|
||||||
clue-hunt-app "file:"
|
clue-hunt-app "file:../../AppData/Local/Yarn/Cache/v6/npm-clue-hunt-app-0.1.0-dfb72df2-52f6-42b4-8429-9f5630443ed9-1742214702181/node_modules/clue-hunt-app"
|
||||||
html5-qrcode "^2.3.8"
|
html5-qrcode "^2.3.8"
|
||||||
jose "^4.14.4"
|
jose "^4.14.4"
|
||||||
jsonwebtoken "^9.0.2"
|
jsonwebtoken "^9.0.2"
|
||||||
@@ -971,6 +970,7 @@ client-only@0.0.1:
|
|||||||
qrcode.react "^4.2.0"
|
qrcode.react "^4.2.0"
|
||||||
react "^19.0.0"
|
react "^19.0.0"
|
||||||
react-dom "^19.0.0"
|
react-dom "^19.0.0"
|
||||||
|
react-zxing "^2.0.0"
|
||||||
sqlite "^5.1.1"
|
sqlite "^5.1.1"
|
||||||
sqlite3 "^5.1.7"
|
sqlite3 "^5.1.7"
|
||||||
|
|
||||||
@@ -1068,6 +1068,13 @@ data-view-byte-offset@^1.0.1:
|
|||||||
es-errors "^1.3.0"
|
es-errors "^1.3.0"
|
||||||
is-data-view "^1.0.1"
|
is-data-view "^1.0.1"
|
||||||
|
|
||||||
|
debug@4, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@^4.3.7:
|
||||||
|
version "4.4.0"
|
||||||
|
resolved "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz"
|
||||||
|
integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==
|
||||||
|
dependencies:
|
||||||
|
ms "^2.1.3"
|
||||||
|
|
||||||
debug@^3.2.7:
|
debug@^3.2.7:
|
||||||
version "3.2.7"
|
version "3.2.7"
|
||||||
resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz"
|
resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz"
|
||||||
@@ -1075,13 +1082,6 @@ debug@^3.2.7:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ms "^2.1.1"
|
ms "^2.1.1"
|
||||||
|
|
||||||
debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@^4.3.7, debug@4:
|
|
||||||
version "4.4.0"
|
|
||||||
resolved "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz"
|
|
||||||
integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==
|
|
||||||
dependencies:
|
|
||||||
ms "^2.1.3"
|
|
||||||
|
|
||||||
decompress-response@^6.0.0:
|
decompress-response@^6.0.0:
|
||||||
version "6.0.0"
|
version "6.0.0"
|
||||||
resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz"
|
resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz"
|
||||||
@@ -1541,17 +1541,6 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
|||||||
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
|
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
|
||||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||||
|
|
||||||
fast-glob@^3.3.2:
|
|
||||||
version "3.3.3"
|
|
||||||
resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz"
|
|
||||||
integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==
|
|
||||||
dependencies:
|
|
||||||
"@nodelib/fs.stat" "^2.0.2"
|
|
||||||
"@nodelib/fs.walk" "^1.2.3"
|
|
||||||
glob-parent "^5.1.2"
|
|
||||||
merge2 "^1.3.0"
|
|
||||||
micromatch "^4.0.8"
|
|
||||||
|
|
||||||
fast-glob@3.3.1:
|
fast-glob@3.3.1:
|
||||||
version "3.3.1"
|
version "3.3.1"
|
||||||
resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz"
|
resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz"
|
||||||
@@ -1563,6 +1552,17 @@ fast-glob@3.3.1:
|
|||||||
merge2 "^1.3.0"
|
merge2 "^1.3.0"
|
||||||
micromatch "^4.0.4"
|
micromatch "^4.0.4"
|
||||||
|
|
||||||
|
fast-glob@^3.3.2:
|
||||||
|
version "3.3.3"
|
||||||
|
resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz"
|
||||||
|
integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==
|
||||||
|
dependencies:
|
||||||
|
"@nodelib/fs.stat" "^2.0.2"
|
||||||
|
"@nodelib/fs.walk" "^1.2.3"
|
||||||
|
glob-parent "^5.1.2"
|
||||||
|
merge2 "^1.3.0"
|
||||||
|
micromatch "^4.0.8"
|
||||||
|
|
||||||
fast-json-stable-stringify@^2.0.0:
|
fast-json-stable-stringify@^2.0.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz"
|
resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz"
|
||||||
@@ -1914,7 +1914,7 @@ inflight@^1.0.4:
|
|||||||
once "^1.3.0"
|
once "^1.3.0"
|
||||||
wrappy "1"
|
wrappy "1"
|
||||||
|
|
||||||
inherits@^2.0.3, inherits@^2.0.4, inherits@2:
|
inherits@2, inherits@^2.0.3, inherits@^2.0.4:
|
||||||
version "2.0.4"
|
version "2.0.4"
|
||||||
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
|
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
|
||||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||||
@@ -2283,47 +2283,47 @@ levn@^0.4.1:
|
|||||||
|
|
||||||
lightningcss-darwin-arm64@1.29.2:
|
lightningcss-darwin-arm64@1.29.2:
|
||||||
version "1.29.2"
|
version "1.29.2"
|
||||||
resolved "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.2.tgz"
|
resolved "https://registry.yarnpkg.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.2.tgz#6ceff38b01134af48e859394e1ca21e5d49faae6"
|
||||||
integrity sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==
|
integrity sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==
|
||||||
|
|
||||||
lightningcss-darwin-x64@1.29.2:
|
lightningcss-darwin-x64@1.29.2:
|
||||||
version "1.29.2"
|
version "1.29.2"
|
||||||
resolved "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.2.tgz"
|
resolved "https://registry.yarnpkg.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.2.tgz#891b6f9e57682d794223c33463ca66d3af3fb038"
|
||||||
integrity sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==
|
integrity sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==
|
||||||
|
|
||||||
lightningcss-freebsd-x64@1.29.2:
|
lightningcss-freebsd-x64@1.29.2:
|
||||||
version "1.29.2"
|
version "1.29.2"
|
||||||
resolved "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.2.tgz"
|
resolved "https://registry.yarnpkg.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.2.tgz#8a95f9ab73b2b2b0beefe1599fafa8b058938495"
|
||||||
integrity sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==
|
integrity sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==
|
||||||
|
|
||||||
lightningcss-linux-arm-gnueabihf@1.29.2:
|
lightningcss-linux-arm-gnueabihf@1.29.2:
|
||||||
version "1.29.2"
|
version "1.29.2"
|
||||||
resolved "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.2.tgz"
|
resolved "https://registry.yarnpkg.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.2.tgz#5c60bbf92b39d7ed51e363f7b98a7111bf5914a1"
|
||||||
integrity sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==
|
integrity sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==
|
||||||
|
|
||||||
lightningcss-linux-arm64-gnu@1.29.2:
|
lightningcss-linux-arm64-gnu@1.29.2:
|
||||||
version "1.29.2"
|
version "1.29.2"
|
||||||
resolved "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.2.tgz"
|
resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.2.tgz#e73d7608c4cce034c3654e5e8b53be74846224de"
|
||||||
integrity sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==
|
integrity sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==
|
||||||
|
|
||||||
lightningcss-linux-arm64-musl@1.29.2:
|
lightningcss-linux-arm64-musl@1.29.2:
|
||||||
version "1.29.2"
|
version "1.29.2"
|
||||||
resolved "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.2.tgz"
|
resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.2.tgz#a95a18d5a909831c092e0a8d2de4b9ac1a8db151"
|
||||||
integrity sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==
|
integrity sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==
|
||||||
|
|
||||||
lightningcss-linux-x64-gnu@1.29.2:
|
lightningcss-linux-x64-gnu@1.29.2:
|
||||||
version "1.29.2"
|
version "1.29.2"
|
||||||
resolved "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.2.tgz"
|
resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.2.tgz#551ca07e565394928642edee92acc042e546cb78"
|
||||||
integrity sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==
|
integrity sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==
|
||||||
|
|
||||||
lightningcss-linux-x64-musl@1.29.2:
|
lightningcss-linux-x64-musl@1.29.2:
|
||||||
version "1.29.2"
|
version "1.29.2"
|
||||||
resolved "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.2.tgz"
|
resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.2.tgz#2fd164554340831bce50285b57101817850dd258"
|
||||||
integrity sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==
|
integrity sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==
|
||||||
|
|
||||||
lightningcss-win32-arm64-msvc@1.29.2:
|
lightningcss-win32-arm64-msvc@1.29.2:
|
||||||
version "1.29.2"
|
version "1.29.2"
|
||||||
resolved "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.2.tgz"
|
resolved "https://registry.yarnpkg.com/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.2.tgz#da43ea49fafc5d2de38e016f1a8539d5eed98318"
|
||||||
integrity sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==
|
integrity sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==
|
||||||
|
|
||||||
lightningcss-win32-x64-msvc@1.29.2:
|
lightningcss-win32-x64-msvc@1.29.2:
|
||||||
@@ -2837,15 +2837,6 @@ possible-typed-array-names@^1.0.0:
|
|||||||
resolved "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz"
|
resolved "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz"
|
||||||
integrity sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==
|
integrity sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==
|
||||||
|
|
||||||
postcss@^8.4.41:
|
|
||||||
version "8.5.3"
|
|
||||||
resolved "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz"
|
|
||||||
integrity sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==
|
|
||||||
dependencies:
|
|
||||||
nanoid "^3.3.8"
|
|
||||||
picocolors "^1.1.1"
|
|
||||||
source-map-js "^1.2.1"
|
|
||||||
|
|
||||||
postcss@8.4.31:
|
postcss@8.4.31:
|
||||||
version "8.4.31"
|
version "8.4.31"
|
||||||
resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz"
|
resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz"
|
||||||
@@ -2855,6 +2846,15 @@ postcss@8.4.31:
|
|||||||
picocolors "^1.0.0"
|
picocolors "^1.0.0"
|
||||||
source-map-js "^1.0.2"
|
source-map-js "^1.0.2"
|
||||||
|
|
||||||
|
postcss@^8.4.41:
|
||||||
|
version "8.5.3"
|
||||||
|
resolved "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz"
|
||||||
|
integrity sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==
|
||||||
|
dependencies:
|
||||||
|
nanoid "^3.3.8"
|
||||||
|
picocolors "^1.1.1"
|
||||||
|
source-map-js "^1.2.1"
|
||||||
|
|
||||||
preact-render-to-string@^5.1.19:
|
preact-render-to-string@^5.1.19:
|
||||||
version "5.2.6"
|
version "5.2.6"
|
||||||
resolved "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz"
|
resolved "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz"
|
||||||
@@ -2962,6 +2962,13 @@ react-is@^16.13.1:
|
|||||||
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
|
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
|
||||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||||
|
|
||||||
|
react-zxing@^2.0.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.npmjs.org/react-zxing/-/react-zxing-2.1.0.tgz"
|
||||||
|
integrity sha512-iFZ8KPfZl+biiT5/bluuMGaSLQAwnE0ialQHbJioHFuwqhCo1WmjQmAtI4WN8BmiKYFVkHGgwHSl+pgwpwtQEg==
|
||||||
|
dependencies:
|
||||||
|
"@zxing/library" "^0.20.0"
|
||||||
|
|
||||||
react@^19.0.0:
|
react@^19.0.0:
|
||||||
version "19.0.0"
|
version "19.0.0"
|
||||||
resolved "https://registry.npmjs.org/react/-/react-19.0.0.tgz"
|
resolved "https://registry.npmjs.org/react/-/react-19.0.0.tgz"
|
||||||
@@ -3287,11 +3294,6 @@ sprintf-js@^1.1.3:
|
|||||||
resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz"
|
resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz"
|
||||||
integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==
|
integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==
|
||||||
|
|
||||||
sqlite@^5.1.1:
|
|
||||||
version "5.1.1"
|
|
||||||
resolved "https://registry.npmjs.org/sqlite/-/sqlite-5.1.1.tgz"
|
|
||||||
integrity sha512-oBkezXa2hnkfuJwUo44Hl9hS3er+YFtueifoajrgidvqsJRQFpc5fKoAkAor1O5ZnLoa28GBScfHXs8j0K358Q==
|
|
||||||
|
|
||||||
sqlite3@^5.1.7:
|
sqlite3@^5.1.7:
|
||||||
version "5.1.7"
|
version "5.1.7"
|
||||||
resolved "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.7.tgz"
|
resolved "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.7.tgz"
|
||||||
@@ -3304,6 +3306,11 @@ sqlite3@^5.1.7:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
node-gyp "8.x"
|
node-gyp "8.x"
|
||||||
|
|
||||||
|
sqlite@^5.1.1:
|
||||||
|
version "5.1.1"
|
||||||
|
resolved "https://registry.npmjs.org/sqlite/-/sqlite-5.1.1.tgz"
|
||||||
|
integrity sha512-oBkezXa2hnkfuJwUo44Hl9hS3er+YFtueifoajrgidvqsJRQFpc5fKoAkAor1O5ZnLoa28GBScfHXs8j0K358Q==
|
||||||
|
|
||||||
ssri@^8.0.0, ssri@^8.0.1:
|
ssri@^8.0.0, ssri@^8.0.1:
|
||||||
version "8.0.1"
|
version "8.0.1"
|
||||||
resolved "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz"
|
resolved "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz"
|
||||||
@@ -3321,13 +3328,6 @@ streamsearch@^1.1.0:
|
|||||||
resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz"
|
resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz"
|
||||||
integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==
|
integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==
|
||||||
|
|
||||||
string_decoder@^1.1.1:
|
|
||||||
version "1.3.0"
|
|
||||||
resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz"
|
|
||||||
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
|
|
||||||
dependencies:
|
|
||||||
safe-buffer "~5.2.0"
|
|
||||||
|
|
||||||
"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.2.3:
|
"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.2.3:
|
||||||
version "4.2.3"
|
version "4.2.3"
|
||||||
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
|
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
|
||||||
@@ -3405,6 +3405,13 @@ string.prototype.trimstart@^1.0.8:
|
|||||||
define-properties "^1.2.1"
|
define-properties "^1.2.1"
|
||||||
es-object-atoms "^1.0.0"
|
es-object-atoms "^1.0.0"
|
||||||
|
|
||||||
|
string_decoder@^1.1.1:
|
||||||
|
version "1.3.0"
|
||||||
|
resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz"
|
||||||
|
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
|
||||||
|
dependencies:
|
||||||
|
safe-buffer "~5.2.0"
|
||||||
|
|
||||||
strip-ansi@^6.0.1:
|
strip-ansi@^6.0.1:
|
||||||
version "6.0.1"
|
version "6.0.1"
|
||||||
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
|
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
|
||||||
@@ -3446,7 +3453,7 @@ supports-preserve-symlinks-flag@^1.0.0:
|
|||||||
resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
|
resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
|
||||||
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
||||||
|
|
||||||
tailwindcss@^4, tailwindcss@4.0.12:
|
tailwindcss@4.0.12, tailwindcss@^4:
|
||||||
version "4.0.12"
|
version "4.0.12"
|
||||||
resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.0.12.tgz"
|
resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.0.12.tgz"
|
||||||
integrity sha512-bT0hJo91FtncsAMSsMzUkoo/iEU0Xs5xgFgVC9XmdM9bw5MhZuQFjPNl6wxAE0SiQF/YTZJa+PndGWYSDtuxAg==
|
integrity sha512-bT0hJo91FtncsAMSsMzUkoo/iEU0Xs5xgFgVC9XmdM9bw5MhZuQFjPNl6wxAE0SiQF/YTZJa+PndGWYSDtuxAg==
|
||||||
|
|||||||
Reference in new issue
Block a user