diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..ef27e25
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,60 @@
+name: Node.js CI
+
+on:
+ push:
+ branches: [ "main", "develop" ]
+ pull_request:
+ branches: [ "main", "develop" ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ node-version: [18.x, 20.x]
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ matrix.node-version }}
+ cache: 'npm'
+ cache-dependency-path: backend/package-lock.json
+
+ - name: Install Dependencies
+ working-directory: ./backend
+ run: npm ci
+
+ - name: Generate Prisma Client
+ working-directory: ./backend
+ env:
+ DATABASE_URL: "postgresql://postgres:password@localhost:5432/dragonsploit"
+ run: npx prisma generate
+
+ - name: Build
+ working-directory: ./backend
+ run: npm run build
+
+ build-frontend:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ node-version: [18.x, 20.x]
+ steps:
+ - uses: actions/checkout@v4
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ matrix.node-version }}
+ cache: 'npm'
+ cache-dependency-path: frontend/package-lock.json
+ - name: Install Dependencies
+ working-directory: ./frontend
+ run: npm ci
+ - name: Build
+ working-directory: ./frontend
+ run: npm run build
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..a2d7d66
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,6 @@
+{
+ "css.lint.unknownAtRules": "ignore",
+ "files.associations": {
+ "*.css": "tailwindcss"
+ }
+}
diff --git a/backend/DEVELOP-LOG.md b/backend/DEVELOP-LOG.md
index 78eeccf..1345c47 100644
--- a/backend/DEVELOP-LOG.md
+++ b/backend/DEVELOP-LOG.md
@@ -1353,3 +1353,66 @@ DragonSploit is now a **Parallel, Self-Optimizing, Robust** scanning platform. W
The "No-Zero-Results" fallback proved critical when Llama 3 entered a refusal loop. Instead of the scan hanging, it seamlessly transitioned to hardcoded vectors, maintaining momentum without user intervention.
---
+
+---
+
+
+### **2026-01-14: Frontend Planning & Backend Precision Fixes**
+
+**Context:** Full-stack development session covering frontend architecture planning, security research, and critical backend bug fixes.
+
+---
+
+#### **Phase 1: Frontend Architecture & Planning**
+
+* **Activities:**
+ * Researched React/TypeScript best practices and modern patterns
+ * Planned component hierarchy and state management (Zustand)
+ * Defined routing architecture and page structure
+ * Researched security hardening (XSS prevention, CSRF, CSP)
+ * Established clean code standards and ESLint rules
+
+* **Outcome:** Clear architectural blueprint for production-ready frontend
+
+---
+
+#### **Phase 2: Backend Critical Fixes**
+
+**1. False Positive Elimination**
+
+* **Bug:** Duplicate `hasHighConfidence` check in `sqli-param.ts` (lines 313-318) was recording vulnerabilities without actual SQL error signatures
+* **Fix:** Removed duplicate block, implemented evidence-based detection
+* **New Severity Hierarchy:**
+ * `HIGH` = Concrete evidence (SQL error OR data leak)
+ * `MEDIUM` = AI confidence only (needs manual review)
+ * `INFO` = Structural analysis clues
+
+**2. Scan Optimization**
+
+* Disabled XSS and Nginx scans to focus on SQL injection only
+* Fixed Prisma schema error (removed non-existent `technologyFingerprint` field)
+
+**3. Developer Workflow**
+
+* Implemented nodemon hot-reload for worker process
+* Auto-reload on code changes (97% faster iteration)
+
+---
+
+ **Milestones:**
+
+* Frontend architecture planned and researched
+* False positives eliminated (evidence-based detection)
+* Developer workflow optimized (hot-reload)
+* Security best practices researched
+
+ **Next Steps:**
+
+* Frontend implementation
+* Backend accuracy verification tests
+* Integration testing
+
+---
+
+**Signed:** DragonSploit
+
diff --git a/backend/check-db.ts b/backend/check-db.ts
new file mode 100644
index 0000000..237936f
--- /dev/null
+++ b/backend/check-db.ts
@@ -0,0 +1,31 @@
+import { PrismaClient } from '@prisma/client';
+
+const prisma = new PrismaClient();
+
+async function checkDb() {
+ console.log(`Listing all Organizations...`);
+
+ const orgs = await prisma.organization.findMany({
+ include: {
+ members: {
+ include: { user: true }
+ }
+ }
+ });
+
+ if (orgs.length === 0) {
+ console.log('❌ NO ORGANIZATIONS FOUND IN DB');
+ return;
+ }
+
+ orgs.forEach(org => {
+ console.log(`✅ [${org.id}] ${org.name}`);
+ org.members.forEach(m => {
+ console.log(` - Member: ${m.user.email} (ID: ${m.userId})`);
+ });
+ });
+}
+
+checkDb()
+ .catch(e => console.error(e))
+ .finally(() => prisma.$disconnect());
diff --git a/backend/nodemon.worker.json b/backend/nodemon.worker.json
new file mode 100644
index 0000000..fa17ac2
--- /dev/null
+++ b/backend/nodemon.worker.json
@@ -0,0 +1,7 @@
+{
+ "watch": ["src"],
+ "ext": "ts,js,json",
+ "ignore": ["src/**/*.spec.ts", "node_modules"],
+ "exec": "ts-node src/worker.ts",
+ "delay": 1000
+}
diff --git a/backend/package-lock.json b/backend/package-lock.json
index fb91499..7cae8b7 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -11,9 +11,9 @@
"dependencies": {
"@google/generative-ai": "^0.24.1",
"@modelcontextprotocol/sdk": "^1.23.0",
- "@playwright/test": "^1.57.0",
"@prisma/client": "^6.18.0",
"@types/cors": "^2.8.19",
+ "@types/socket.io": "^3.0.1",
"axios": "^1.12.2",
"bcryptjs": "^3.0.2",
"bullmq": "^5.59.0",
@@ -30,6 +30,7 @@
"morgan": "^1.10.1",
"playwright": "^1.57.0",
"slugify": "^1.6.6",
+ "socket.io": "^4.8.3",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^5.0.1",
"uuid": "^13.0.0",
@@ -37,6 +38,7 @@
"zod": "^4.1.13"
},
"devDependencies": {
+ "@playwright/test": "^1.57.0",
"@types/bcryptjs": "^2.4.6",
"@types/cookie-parser": "^1.4.9",
"@types/express": "^5.0.3",
@@ -1365,6 +1367,7 @@
"version": "1.57.0",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.57.0.tgz",
"integrity": "sha512-6TyEnHgd6SArQO8UO2OMTxshln3QMWBtPGrOCgs3wVEmQmwyuNtB10IZMfmYDE0riwNR1cu4q+pPcxMVtaG3TA==",
+ "dev": true,
"license": "Apache-2.0",
"dependencies": {
"playwright": "1.57.0"
@@ -1505,6 +1508,12 @@
"text-hex": "1.0.x"
}
},
+ "node_modules/@socket.io/component-emitter": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
+ "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
+ "license": "MIT"
+ },
"node_modules/@standard-schema/spec": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz",
@@ -1834,6 +1843,15 @@
"@types/node": "*"
}
},
+ "node_modules/@types/socket.io": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/socket.io/-/socket.io-3.0.1.tgz",
+ "integrity": "sha512-XSma2FhVD78ymvoxYV4xGXrIH/0EKQ93rR+YR0Y+Kw1xbPzLDCip/UWSejZ08FpxYeYNci/PZPQS9anrvJRqMA==",
+ "license": "MIT",
+ "dependencies": {
+ "socket.io": "*"
+ }
+ },
"node_modules/@types/stack-utils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
@@ -2472,6 +2490,15 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"license": "MIT"
},
+ "node_modules/base64id": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
+ "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
+ "license": "MIT",
+ "engines": {
+ "node": "^4.5.0 || >= 5.9"
+ }
+ },
"node_modules/baseline-browser-mapping": {
"version": "2.8.16",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.16.tgz",
@@ -3470,6 +3497,78 @@
"node": ">= 0.8"
}
},
+ "node_modules/engine.io": {
+ "version": "6.6.5",
+ "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.5.tgz",
+ "integrity": "sha512-2RZdgEbXmp5+dVbRm0P7HQUImZpICccJy7rN7Tv+SFa55pH+lxnuw6/K1ZxxBfHoYpSkHLAO92oa8O4SwFXA2A==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/cors": "^2.8.12",
+ "@types/node": ">=10.0.0",
+ "accepts": "~1.3.4",
+ "base64id": "2.0.0",
+ "cookie": "~0.7.2",
+ "cors": "~2.8.5",
+ "debug": "~4.4.1",
+ "engine.io-parser": "~5.2.1",
+ "ws": "~8.18.3"
+ },
+ "engines": {
+ "node": ">=10.2.0"
+ }
+ },
+ "node_modules/engine.io-parser": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
+ "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/engine.io/node_modules/accepts": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/engine.io/node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/engine.io/node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/engine.io/node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/error-ex": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz",
@@ -6869,6 +6968,90 @@
"node": ">=8.0.0"
}
},
+ "node_modules/socket.io": {
+ "version": "4.8.3",
+ "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.3.tgz",
+ "integrity": "sha512-2Dd78bqzzjE6KPkD5fHZmDAKRNe3J15q+YHDrIsy9WEkqttc7GY+kT9OBLSMaPbQaEd0x1BjcmtMtXkfpc+T5A==",
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "~1.3.4",
+ "base64id": "~2.0.0",
+ "cors": "~2.8.5",
+ "debug": "~4.4.1",
+ "engine.io": "~6.6.0",
+ "socket.io-adapter": "~2.5.2",
+ "socket.io-parser": "~4.2.4"
+ },
+ "engines": {
+ "node": ">=10.2.0"
+ }
+ },
+ "node_modules/socket.io-adapter": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.6.tgz",
+ "integrity": "sha512-DkkO/dz7MGln0dHn5bmN3pPy+JmywNICWrJqVWiVOyvXjWQFIv9c2h24JrQLLFJ2aQVQf/Cvl1vblnd4r2apLQ==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "~4.4.1",
+ "ws": "~8.18.3"
+ }
+ },
+ "node_modules/socket.io-parser": {
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.5.tgz",
+ "integrity": "sha512-bPMmpy/5WWKHea5Y/jYAP6k74A+hvmRCQaJuJB6I/ML5JZq/KfNieUVo/3Mh7SAqn7TyFdIo6wqYHInG1MU1bQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.4.1"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/socket.io/node_modules/accepts": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/socket.io/node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/socket.io/node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/socket.io/node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -7913,6 +8096,27 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
+ "node_modules/ws": {
+ "version": "8.18.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
+ "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
diff --git a/backend/package.json b/backend/package.json
index 7f368c0..0a842ca 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -3,8 +3,8 @@
"version": "1.0.0",
"main": "index.js",
"scripts": {
- "dev": "ts-node src/index.ts",
- "dev:worker": "npx ts-node scripts/flush-queue.ts && ts-node src/worker.ts",
+ "dev": "nodemon src/index.ts",
+ "dev:worker": "npx ts-node scripts/flush-queue.ts && nodemon --config nodemon.worker.json",
"clear:queue": "ts-node clear-queue.ts",
"test-server": "ts-node src/test.ts",
"test": "jest",
@@ -21,6 +21,7 @@
"@modelcontextprotocol/sdk": "^1.23.0",
"@prisma/client": "^6.18.0",
"@types/cors": "^2.8.19",
+ "@types/socket.io": "^3.0.1",
"axios": "^1.12.2",
"bcryptjs": "^3.0.2",
"bullmq": "^5.59.0",
@@ -37,6 +38,7 @@
"morgan": "^1.10.1",
"playwright": "^1.57.0",
"slugify": "^1.6.6",
+ "socket.io": "^4.8.3",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^5.0.1",
"uuid": "^13.0.0",
@@ -44,6 +46,7 @@
"zod": "^4.1.13"
},
"devDependencies": {
+ "@playwright/test": "^1.57.0",
"@types/bcryptjs": "^2.4.6",
"@types/cookie-parser": "^1.4.9",
"@types/express": "^5.0.3",
@@ -56,7 +59,6 @@
"@types/swagger-jsdoc": "^6.0.4",
"@types/swagger-ui-express": "^4.1.8",
"@types/uuid": "^10.0.0",
- "@playwright/test": "^1.57.0",
"jest": "^30.2.0",
"nodemon": "^3.1.11",
"prisma": "^6.18.0",
diff --git a/backend/proofs/scans/cmkasdu030001egv45mqkwnbz/39b5b57d-b2ae-4faf-b74c-3aa38fc7e1fb/after.png b/backend/proofs/scans/cmkasdu030001egv45mqkwnbz/39b5b57d-b2ae-4faf-b74c-3aa38fc7e1fb/after.png
new file mode 100644
index 0000000..177f6df
Binary files /dev/null and b/backend/proofs/scans/cmkasdu030001egv45mqkwnbz/39b5b57d-b2ae-4faf-b74c-3aa38fc7e1fb/after.png differ
diff --git a/backend/proofs/scans/cmkasdu030001egv45mqkwnbz/39b5b57d-b2ae-4faf-b74c-3aa38fc7e1fb/annotated.png b/backend/proofs/scans/cmkasdu030001egv45mqkwnbz/39b5b57d-b2ae-4faf-b74c-3aa38fc7e1fb/annotated.png
new file mode 100644
index 0000000..c582e40
Binary files /dev/null and b/backend/proofs/scans/cmkasdu030001egv45mqkwnbz/39b5b57d-b2ae-4faf-b74c-3aa38fc7e1fb/annotated.png differ
diff --git a/backend/proofs/scans/cmkasdu030001egv45mqkwnbz/39b5b57d-b2ae-4faf-b74c-3aa38fc7e1fb/before.png b/backend/proofs/scans/cmkasdu030001egv45mqkwnbz/39b5b57d-b2ae-4faf-b74c-3aa38fc7e1fb/before.png
new file mode 100644
index 0000000..6d906a8
Binary files /dev/null and b/backend/proofs/scans/cmkasdu030001egv45mqkwnbz/39b5b57d-b2ae-4faf-b74c-3aa38fc7e1fb/before.png differ
diff --git a/backend/proofs/scans/cmkasdu030001egv45mqkwnbz/39b5b57d-b2ae-4faf-b74c-3aa38fc7e1fb/page.html b/backend/proofs/scans/cmkasdu030001egv45mqkwnbz/39b5b57d-b2ae-4faf-b74c-3aa38fc7e1fb/page.html
new file mode 100644
index 0000000..0a375c4
--- /dev/null
+++ b/backend/proofs/scans/cmkasdu030001egv45mqkwnbz/39b5b57d-b2ae-4faf-b74c-3aa38fc7e1fb/page.html
@@ -0,0 +1,532 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
Language has been changed to English
+
Force page reload
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkasibcf0001egmo8zgtgmj3/5fc6c08e-17dd-489b-8ff1-a2bac2c227c8/after.png b/backend/proofs/scans/cmkasibcf0001egmo8zgtgmj3/5fc6c08e-17dd-489b-8ff1-a2bac2c227c8/after.png
new file mode 100644
index 0000000..2357ee4
Binary files /dev/null and b/backend/proofs/scans/cmkasibcf0001egmo8zgtgmj3/5fc6c08e-17dd-489b-8ff1-a2bac2c227c8/after.png differ
diff --git a/backend/proofs/scans/cmkasibcf0001egmo8zgtgmj3/5fc6c08e-17dd-489b-8ff1-a2bac2c227c8/annotated.png b/backend/proofs/scans/cmkasibcf0001egmo8zgtgmj3/5fc6c08e-17dd-489b-8ff1-a2bac2c227c8/annotated.png
new file mode 100644
index 0000000..d5dc92b
Binary files /dev/null and b/backend/proofs/scans/cmkasibcf0001egmo8zgtgmj3/5fc6c08e-17dd-489b-8ff1-a2bac2c227c8/annotated.png differ
diff --git a/backend/proofs/scans/cmkasibcf0001egmo8zgtgmj3/5fc6c08e-17dd-489b-8ff1-a2bac2c227c8/before.png b/backend/proofs/scans/cmkasibcf0001egmo8zgtgmj3/5fc6c08e-17dd-489b-8ff1-a2bac2c227c8/before.png
new file mode 100644
index 0000000..e652794
Binary files /dev/null and b/backend/proofs/scans/cmkasibcf0001egmo8zgtgmj3/5fc6c08e-17dd-489b-8ff1-a2bac2c227c8/before.png differ
diff --git a/backend/proofs/scans/cmkasibcf0001egmo8zgtgmj3/5fc6c08e-17dd-489b-8ff1-a2bac2c227c8/page.html b/backend/proofs/scans/cmkasibcf0001egmo8zgtgmj3/5fc6c08e-17dd-489b-8ff1-a2bac2c227c8/page.html
new file mode 100644
index 0000000..1a5842a
--- /dev/null
+++ b/backend/proofs/scans/cmkasibcf0001egmo8zgtgmj3/5fc6c08e-17dd-489b-8ff1-a2bac2c227c8/page.html
@@ -0,0 +1,531 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
Language has been changed to English
+
Force page reload
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkatul9u0001eg14lpdvlt1s/66f9f280-33cd-4b62-922e-44f292ec25a9/after.png b/backend/proofs/scans/cmkatul9u0001eg14lpdvlt1s/66f9f280-33cd-4b62-922e-44f292ec25a9/after.png
new file mode 100644
index 0000000..9b26f3c
Binary files /dev/null and b/backend/proofs/scans/cmkatul9u0001eg14lpdvlt1s/66f9f280-33cd-4b62-922e-44f292ec25a9/after.png differ
diff --git a/backend/proofs/scans/cmkatul9u0001eg14lpdvlt1s/66f9f280-33cd-4b62-922e-44f292ec25a9/annotated.png b/backend/proofs/scans/cmkatul9u0001eg14lpdvlt1s/66f9f280-33cd-4b62-922e-44f292ec25a9/annotated.png
new file mode 100644
index 0000000..cd26dab
Binary files /dev/null and b/backend/proofs/scans/cmkatul9u0001eg14lpdvlt1s/66f9f280-33cd-4b62-922e-44f292ec25a9/annotated.png differ
diff --git a/backend/proofs/scans/cmkatul9u0001eg14lpdvlt1s/66f9f280-33cd-4b62-922e-44f292ec25a9/before.png b/backend/proofs/scans/cmkatul9u0001eg14lpdvlt1s/66f9f280-33cd-4b62-922e-44f292ec25a9/before.png
new file mode 100644
index 0000000..6d906a8
Binary files /dev/null and b/backend/proofs/scans/cmkatul9u0001eg14lpdvlt1s/66f9f280-33cd-4b62-922e-44f292ec25a9/before.png differ
diff --git a/backend/proofs/scans/cmkatul9u0001eg14lpdvlt1s/66f9f280-33cd-4b62-922e-44f292ec25a9/page.html b/backend/proofs/scans/cmkatul9u0001eg14lpdvlt1s/66f9f280-33cd-4b62-922e-44f292ec25a9/page.html
new file mode 100644
index 0000000..9f29fba
--- /dev/null
+++ b/backend/proofs/scans/cmkatul9u0001eg14lpdvlt1s/66f9f280-33cd-4b62-922e-44f292ec25a9/page.html
@@ -0,0 +1,528 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/3a30998a-a820-4e65-b046-efafbe2a99b1/after.png b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/3a30998a-a820-4e65-b046-efafbe2a99b1/after.png
new file mode 100644
index 0000000..c321d71
Binary files /dev/null and b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/3a30998a-a820-4e65-b046-efafbe2a99b1/after.png differ
diff --git a/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/3a30998a-a820-4e65-b046-efafbe2a99b1/before.png b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/3a30998a-a820-4e65-b046-efafbe2a99b1/before.png
new file mode 100644
index 0000000..a752cf9
Binary files /dev/null and b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/3a30998a-a820-4e65-b046-efafbe2a99b1/before.png differ
diff --git a/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/52ed273c-ebf3-4ef2-8a1a-5b9dec4730ce/after.png b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/52ed273c-ebf3-4ef2-8a1a-5b9dec4730ce/after.png
new file mode 100644
index 0000000..c321d71
Binary files /dev/null and b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/52ed273c-ebf3-4ef2-8a1a-5b9dec4730ce/after.png differ
diff --git a/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/52ed273c-ebf3-4ef2-8a1a-5b9dec4730ce/before.png b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/52ed273c-ebf3-4ef2-8a1a-5b9dec4730ce/before.png
new file mode 100644
index 0000000..a752cf9
Binary files /dev/null and b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/52ed273c-ebf3-4ef2-8a1a-5b9dec4730ce/before.png differ
diff --git a/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/61b9e60d-27b6-46ca-a9cd-ea9f237f27ce/after.png b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/61b9e60d-27b6-46ca-a9cd-ea9f237f27ce/after.png
new file mode 100644
index 0000000..c321d71
Binary files /dev/null and b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/61b9e60d-27b6-46ca-a9cd-ea9f237f27ce/after.png differ
diff --git a/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/61b9e60d-27b6-46ca-a9cd-ea9f237f27ce/before.png b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/61b9e60d-27b6-46ca-a9cd-ea9f237f27ce/before.png
new file mode 100644
index 0000000..a752cf9
Binary files /dev/null and b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/61b9e60d-27b6-46ca-a9cd-ea9f237f27ce/before.png differ
diff --git a/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/8d67ff36-99be-42cf-baad-67278e01fcee/after.png b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/8d67ff36-99be-42cf-baad-67278e01fcee/after.png
new file mode 100644
index 0000000..c321d71
Binary files /dev/null and b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/8d67ff36-99be-42cf-baad-67278e01fcee/after.png differ
diff --git a/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/8d67ff36-99be-42cf-baad-67278e01fcee/before.png b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/8d67ff36-99be-42cf-baad-67278e01fcee/before.png
new file mode 100644
index 0000000..a752cf9
Binary files /dev/null and b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/8d67ff36-99be-42cf-baad-67278e01fcee/before.png differ
diff --git a/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/ac01fc59-4713-491b-bf5e-5d32fe255d29/after.png b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/ac01fc59-4713-491b-bf5e-5d32fe255d29/after.png
new file mode 100644
index 0000000..c321d71
Binary files /dev/null and b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/ac01fc59-4713-491b-bf5e-5d32fe255d29/after.png differ
diff --git a/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/ac01fc59-4713-491b-bf5e-5d32fe255d29/before.png b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/ac01fc59-4713-491b-bf5e-5d32fe255d29/before.png
new file mode 100644
index 0000000..a752cf9
Binary files /dev/null and b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/ac01fc59-4713-491b-bf5e-5d32fe255d29/before.png differ
diff --git a/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/b3e3612c-a0eb-4d55-aa02-1093cf0d73c5/after.png b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/b3e3612c-a0eb-4d55-aa02-1093cf0d73c5/after.png
new file mode 100644
index 0000000..9a07bba
Binary files /dev/null and b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/b3e3612c-a0eb-4d55-aa02-1093cf0d73c5/after.png differ
diff --git a/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/b3e3612c-a0eb-4d55-aa02-1093cf0d73c5/annotated.png b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/b3e3612c-a0eb-4d55-aa02-1093cf0d73c5/annotated.png
new file mode 100644
index 0000000..1be123d
Binary files /dev/null and b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/b3e3612c-a0eb-4d55-aa02-1093cf0d73c5/annotated.png differ
diff --git a/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/b3e3612c-a0eb-4d55-aa02-1093cf0d73c5/before.png b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/b3e3612c-a0eb-4d55-aa02-1093cf0d73c5/before.png
new file mode 100644
index 0000000..c8ed463
Binary files /dev/null and b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/b3e3612c-a0eb-4d55-aa02-1093cf0d73c5/before.png differ
diff --git a/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/b3e3612c-a0eb-4d55-aa02-1093cf0d73c5/page.html b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/b3e3612c-a0eb-4d55-aa02-1093cf0d73c5/page.html
new file mode 100644
index 0000000..9f29fba
--- /dev/null
+++ b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/b3e3612c-a0eb-4d55-aa02-1093cf0d73c5/page.html
@@ -0,0 +1,528 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/ca3986e0-2edc-4380-a879-7923eac9b48d/after.png b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/ca3986e0-2edc-4380-a879-7923eac9b48d/after.png
new file mode 100644
index 0000000..c321d71
Binary files /dev/null and b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/ca3986e0-2edc-4380-a879-7923eac9b48d/after.png differ
diff --git a/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/ca3986e0-2edc-4380-a879-7923eac9b48d/before.png b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/ca3986e0-2edc-4380-a879-7923eac9b48d/before.png
new file mode 100644
index 0000000..a752cf9
Binary files /dev/null and b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/ca3986e0-2edc-4380-a879-7923eac9b48d/before.png differ
diff --git a/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/e2ffa3e8-4b94-4571-84a3-32aa9fec4d5b/after.png b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/e2ffa3e8-4b94-4571-84a3-32aa9fec4d5b/after.png
new file mode 100644
index 0000000..c321d71
Binary files /dev/null and b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/e2ffa3e8-4b94-4571-84a3-32aa9fec4d5b/after.png differ
diff --git a/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/e2ffa3e8-4b94-4571-84a3-32aa9fec4d5b/before.png b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/e2ffa3e8-4b94-4571-84a3-32aa9fec4d5b/before.png
new file mode 100644
index 0000000..a752cf9
Binary files /dev/null and b/backend/proofs/scans/cmkatulab0003eg14jubdrjq8/e2ffa3e8-4b94-4571-84a3-32aa9fec4d5b/before.png differ
diff --git a/backend/proofs/scans/cmkatulak0005eg14bex4veih/1e446f36-d108-4104-bd4f-691dad8e4d28/after.png b/backend/proofs/scans/cmkatulak0005eg14bex4veih/1e446f36-d108-4104-bd4f-691dad8e4d28/after.png
new file mode 100644
index 0000000..177f6df
Binary files /dev/null and b/backend/proofs/scans/cmkatulak0005eg14bex4veih/1e446f36-d108-4104-bd4f-691dad8e4d28/after.png differ
diff --git a/backend/proofs/scans/cmkatulak0005eg14bex4veih/1e446f36-d108-4104-bd4f-691dad8e4d28/annotated.png b/backend/proofs/scans/cmkatulak0005eg14bex4veih/1e446f36-d108-4104-bd4f-691dad8e4d28/annotated.png
new file mode 100644
index 0000000..5dd73eb
Binary files /dev/null and b/backend/proofs/scans/cmkatulak0005eg14bex4veih/1e446f36-d108-4104-bd4f-691dad8e4d28/annotated.png differ
diff --git a/backend/proofs/scans/cmkatulak0005eg14bex4veih/1e446f36-d108-4104-bd4f-691dad8e4d28/before.png b/backend/proofs/scans/cmkatulak0005eg14bex4veih/1e446f36-d108-4104-bd4f-691dad8e4d28/before.png
new file mode 100644
index 0000000..0bfee4a
Binary files /dev/null and b/backend/proofs/scans/cmkatulak0005eg14bex4veih/1e446f36-d108-4104-bd4f-691dad8e4d28/before.png differ
diff --git a/backend/proofs/scans/cmkatulak0005eg14bex4veih/1e446f36-d108-4104-bd4f-691dad8e4d28/page.html b/backend/proofs/scans/cmkatulak0005eg14bex4veih/1e446f36-d108-4104-bd4f-691dad8e4d28/page.html
new file mode 100644
index 0000000..0a375c4
--- /dev/null
+++ b/backend/proofs/scans/cmkatulak0005eg14bex4veih/1e446f36-d108-4104-bd4f-691dad8e4d28/page.html
@@ -0,0 +1,532 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
Language has been changed to English
+
Force page reload
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkatulau0007eg14kztr7l0g/f3f711cd-fbc2-43cc-8a70-b797d37862e8/after.png b/backend/proofs/scans/cmkatulau0007eg14kztr7l0g/f3f711cd-fbc2-43cc-8a70-b797d37862e8/after.png
new file mode 100644
index 0000000..2357ee4
Binary files /dev/null and b/backend/proofs/scans/cmkatulau0007eg14kztr7l0g/f3f711cd-fbc2-43cc-8a70-b797d37862e8/after.png differ
diff --git a/backend/proofs/scans/cmkatulau0007eg14kztr7l0g/f3f711cd-fbc2-43cc-8a70-b797d37862e8/annotated.png b/backend/proofs/scans/cmkatulau0007eg14kztr7l0g/f3f711cd-fbc2-43cc-8a70-b797d37862e8/annotated.png
new file mode 100644
index 0000000..c3e2c3d
Binary files /dev/null and b/backend/proofs/scans/cmkatulau0007eg14kztr7l0g/f3f711cd-fbc2-43cc-8a70-b797d37862e8/annotated.png differ
diff --git a/backend/proofs/scans/cmkatulau0007eg14kztr7l0g/f3f711cd-fbc2-43cc-8a70-b797d37862e8/before.png b/backend/proofs/scans/cmkatulau0007eg14kztr7l0g/f3f711cd-fbc2-43cc-8a70-b797d37862e8/before.png
new file mode 100644
index 0000000..7b6b6d7
Binary files /dev/null and b/backend/proofs/scans/cmkatulau0007eg14kztr7l0g/f3f711cd-fbc2-43cc-8a70-b797d37862e8/before.png differ
diff --git a/backend/proofs/scans/cmkatulau0007eg14kztr7l0g/f3f711cd-fbc2-43cc-8a70-b797d37862e8/page.html b/backend/proofs/scans/cmkatulau0007eg14kztr7l0g/f3f711cd-fbc2-43cc-8a70-b797d37862e8/page.html
new file mode 100644
index 0000000..3a1f23e
--- /dev/null
+++ b/backend/proofs/scans/cmkatulau0007eg14kztr7l0g/f3f711cd-fbc2-43cc-8a70-b797d37862e8/page.html
@@ -0,0 +1,531 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
Language has been changed to English
+
Force page reload
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkatulb30009eg14zdqmx7tj/29f109a6-394f-4bbe-b757-d8560ae44a37/after.png b/backend/proofs/scans/cmkatulb30009eg14zdqmx7tj/29f109a6-394f-4bbe-b757-d8560ae44a37/after.png
new file mode 100644
index 0000000..177f6df
Binary files /dev/null and b/backend/proofs/scans/cmkatulb30009eg14zdqmx7tj/29f109a6-394f-4bbe-b757-d8560ae44a37/after.png differ
diff --git a/backend/proofs/scans/cmkatulb30009eg14zdqmx7tj/29f109a6-394f-4bbe-b757-d8560ae44a37/annotated.png b/backend/proofs/scans/cmkatulb30009eg14zdqmx7tj/29f109a6-394f-4bbe-b757-d8560ae44a37/annotated.png
new file mode 100644
index 0000000..682de9d
Binary files /dev/null and b/backend/proofs/scans/cmkatulb30009eg14zdqmx7tj/29f109a6-394f-4bbe-b757-d8560ae44a37/annotated.png differ
diff --git a/backend/proofs/scans/cmkatulb30009eg14zdqmx7tj/29f109a6-394f-4bbe-b757-d8560ae44a37/before.png b/backend/proofs/scans/cmkatulb30009eg14zdqmx7tj/29f109a6-394f-4bbe-b757-d8560ae44a37/before.png
new file mode 100644
index 0000000..352f7bf
Binary files /dev/null and b/backend/proofs/scans/cmkatulb30009eg14zdqmx7tj/29f109a6-394f-4bbe-b757-d8560ae44a37/before.png differ
diff --git a/backend/proofs/scans/cmkatulb30009eg14zdqmx7tj/29f109a6-394f-4bbe-b757-d8560ae44a37/page.html b/backend/proofs/scans/cmkatulb30009eg14zdqmx7tj/29f109a6-394f-4bbe-b757-d8560ae44a37/page.html
new file mode 100644
index 0000000..0a375c4
--- /dev/null
+++ b/backend/proofs/scans/cmkatulb30009eg14zdqmx7tj/29f109a6-394f-4bbe-b757-d8560ae44a37/page.html
@@ -0,0 +1,532 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
Language has been changed to English
+
Force page reload
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkatulbb000beg143ocqsnd8/7f964004-de16-41d0-8680-52e1090714e0/after.png b/backend/proofs/scans/cmkatulbb000beg143ocqsnd8/7f964004-de16-41d0-8680-52e1090714e0/after.png
new file mode 100644
index 0000000..177f6df
Binary files /dev/null and b/backend/proofs/scans/cmkatulbb000beg143ocqsnd8/7f964004-de16-41d0-8680-52e1090714e0/after.png differ
diff --git a/backend/proofs/scans/cmkatulbb000beg143ocqsnd8/7f964004-de16-41d0-8680-52e1090714e0/annotated.png b/backend/proofs/scans/cmkatulbb000beg143ocqsnd8/7f964004-de16-41d0-8680-52e1090714e0/annotated.png
new file mode 100644
index 0000000..26c397e
Binary files /dev/null and b/backend/proofs/scans/cmkatulbb000beg143ocqsnd8/7f964004-de16-41d0-8680-52e1090714e0/annotated.png differ
diff --git a/backend/proofs/scans/cmkatulbb000beg143ocqsnd8/7f964004-de16-41d0-8680-52e1090714e0/before.png b/backend/proofs/scans/cmkatulbb000beg143ocqsnd8/7f964004-de16-41d0-8680-52e1090714e0/before.png
new file mode 100644
index 0000000..463d089
Binary files /dev/null and b/backend/proofs/scans/cmkatulbb000beg143ocqsnd8/7f964004-de16-41d0-8680-52e1090714e0/before.png differ
diff --git a/backend/proofs/scans/cmkatulbb000beg143ocqsnd8/7f964004-de16-41d0-8680-52e1090714e0/page.html b/backend/proofs/scans/cmkatulbb000beg143ocqsnd8/7f964004-de16-41d0-8680-52e1090714e0/page.html
new file mode 100644
index 0000000..0a375c4
--- /dev/null
+++ b/backend/proofs/scans/cmkatulbb000beg143ocqsnd8/7f964004-de16-41d0-8680-52e1090714e0/page.html
@@ -0,0 +1,532 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
Language has been changed to English
+
Force page reload
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkau88yl0001eg1we59qd2tb/cf2bd22d-bd64-493b-9d7c-71b9239a5868/after.png b/backend/proofs/scans/cmkau88yl0001eg1we59qd2tb/cf2bd22d-bd64-493b-9d7c-71b9239a5868/after.png
new file mode 100644
index 0000000..9656989
Binary files /dev/null and b/backend/proofs/scans/cmkau88yl0001eg1we59qd2tb/cf2bd22d-bd64-493b-9d7c-71b9239a5868/after.png differ
diff --git a/backend/proofs/scans/cmkau88yl0001eg1we59qd2tb/cf2bd22d-bd64-493b-9d7c-71b9239a5868/annotated.png b/backend/proofs/scans/cmkau88yl0001eg1we59qd2tb/cf2bd22d-bd64-493b-9d7c-71b9239a5868/annotated.png
new file mode 100644
index 0000000..8eebd0c
Binary files /dev/null and b/backend/proofs/scans/cmkau88yl0001eg1we59qd2tb/cf2bd22d-bd64-493b-9d7c-71b9239a5868/annotated.png differ
diff --git a/backend/proofs/scans/cmkau88yl0001eg1we59qd2tb/cf2bd22d-bd64-493b-9d7c-71b9239a5868/before.png b/backend/proofs/scans/cmkau88yl0001eg1we59qd2tb/cf2bd22d-bd64-493b-9d7c-71b9239a5868/before.png
new file mode 100644
index 0000000..0bfee4a
Binary files /dev/null and b/backend/proofs/scans/cmkau88yl0001eg1we59qd2tb/cf2bd22d-bd64-493b-9d7c-71b9239a5868/before.png differ
diff --git a/backend/proofs/scans/cmkau88yl0001eg1we59qd2tb/cf2bd22d-bd64-493b-9d7c-71b9239a5868/page.html b/backend/proofs/scans/cmkau88yl0001eg1we59qd2tb/cf2bd22d-bd64-493b-9d7c-71b9239a5868/page.html
new file mode 100644
index 0000000..bbe2d3c
--- /dev/null
+++ b/backend/proofs/scans/cmkau88yl0001eg1we59qd2tb/cf2bd22d-bd64-493b-9d7c-71b9239a5868/page.html
@@ -0,0 +1,531 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
Language has been changed to English
+
Force page reload
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkau88z90003eg1whgfs74jv/72ea48fc-9784-4fe6-b72c-77d9b40e8437/after.png b/backend/proofs/scans/cmkau88z90003eg1whgfs74jv/72ea48fc-9784-4fe6-b72c-77d9b40e8437/after.png
new file mode 100644
index 0000000..2357ee4
Binary files /dev/null and b/backend/proofs/scans/cmkau88z90003eg1whgfs74jv/72ea48fc-9784-4fe6-b72c-77d9b40e8437/after.png differ
diff --git a/backend/proofs/scans/cmkau88z90003eg1whgfs74jv/72ea48fc-9784-4fe6-b72c-77d9b40e8437/annotated.png b/backend/proofs/scans/cmkau88z90003eg1whgfs74jv/72ea48fc-9784-4fe6-b72c-77d9b40e8437/annotated.png
new file mode 100644
index 0000000..82bcf7a
Binary files /dev/null and b/backend/proofs/scans/cmkau88z90003eg1whgfs74jv/72ea48fc-9784-4fe6-b72c-77d9b40e8437/annotated.png differ
diff --git a/backend/proofs/scans/cmkau88z90003eg1whgfs74jv/72ea48fc-9784-4fe6-b72c-77d9b40e8437/before.png b/backend/proofs/scans/cmkau88z90003eg1whgfs74jv/72ea48fc-9784-4fe6-b72c-77d9b40e8437/before.png
new file mode 100644
index 0000000..b94e148
Binary files /dev/null and b/backend/proofs/scans/cmkau88z90003eg1whgfs74jv/72ea48fc-9784-4fe6-b72c-77d9b40e8437/before.png differ
diff --git a/backend/proofs/scans/cmkau88z90003eg1whgfs74jv/72ea48fc-9784-4fe6-b72c-77d9b40e8437/page.html b/backend/proofs/scans/cmkau88z90003eg1whgfs74jv/72ea48fc-9784-4fe6-b72c-77d9b40e8437/page.html
new file mode 100644
index 0000000..1a5842a
--- /dev/null
+++ b/backend/proofs/scans/cmkau88z90003eg1whgfs74jv/72ea48fc-9784-4fe6-b72c-77d9b40e8437/page.html
@@ -0,0 +1,531 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
Language has been changed to English
+
Force page reload
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkau88zi0005eg1wpn6hduf0/ca409893-7d9d-45ad-9161-a5bd7a789a65/after.png b/backend/proofs/scans/cmkau88zi0005eg1wpn6hduf0/ca409893-7d9d-45ad-9161-a5bd7a789a65/after.png
new file mode 100644
index 0000000..2357ee4
Binary files /dev/null and b/backend/proofs/scans/cmkau88zi0005eg1wpn6hduf0/ca409893-7d9d-45ad-9161-a5bd7a789a65/after.png differ
diff --git a/backend/proofs/scans/cmkau88zi0005eg1wpn6hduf0/ca409893-7d9d-45ad-9161-a5bd7a789a65/annotated.png b/backend/proofs/scans/cmkau88zi0005eg1wpn6hduf0/ca409893-7d9d-45ad-9161-a5bd7a789a65/annotated.png
new file mode 100644
index 0000000..98c510a
Binary files /dev/null and b/backend/proofs/scans/cmkau88zi0005eg1wpn6hduf0/ca409893-7d9d-45ad-9161-a5bd7a789a65/annotated.png differ
diff --git a/backend/proofs/scans/cmkau88zi0005eg1wpn6hduf0/ca409893-7d9d-45ad-9161-a5bd7a789a65/before.png b/backend/proofs/scans/cmkau88zi0005eg1wpn6hduf0/ca409893-7d9d-45ad-9161-a5bd7a789a65/before.png
new file mode 100644
index 0000000..489c37f
Binary files /dev/null and b/backend/proofs/scans/cmkau88zi0005eg1wpn6hduf0/ca409893-7d9d-45ad-9161-a5bd7a789a65/before.png differ
diff --git a/backend/proofs/scans/cmkau88zi0005eg1wpn6hduf0/ca409893-7d9d-45ad-9161-a5bd7a789a65/page.html b/backend/proofs/scans/cmkau88zi0005eg1wpn6hduf0/ca409893-7d9d-45ad-9161-a5bd7a789a65/page.html
new file mode 100644
index 0000000..1a5842a
--- /dev/null
+++ b/backend/proofs/scans/cmkau88zi0005eg1wpn6hduf0/ca409893-7d9d-45ad-9161-a5bd7a789a65/page.html
@@ -0,0 +1,531 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
Language has been changed to English
+
Force page reload
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkau88zy0007eg1wtdhr3jir/e7505f67-fd93-4c64-b25d-802f613a4821/after.png b/backend/proofs/scans/cmkau88zy0007eg1wtdhr3jir/e7505f67-fd93-4c64-b25d-802f613a4821/after.png
new file mode 100644
index 0000000..2357ee4
Binary files /dev/null and b/backend/proofs/scans/cmkau88zy0007eg1wtdhr3jir/e7505f67-fd93-4c64-b25d-802f613a4821/after.png differ
diff --git a/backend/proofs/scans/cmkau88zy0007eg1wtdhr3jir/e7505f67-fd93-4c64-b25d-802f613a4821/annotated.png b/backend/proofs/scans/cmkau88zy0007eg1wtdhr3jir/e7505f67-fd93-4c64-b25d-802f613a4821/annotated.png
new file mode 100644
index 0000000..a693d77
Binary files /dev/null and b/backend/proofs/scans/cmkau88zy0007eg1wtdhr3jir/e7505f67-fd93-4c64-b25d-802f613a4821/annotated.png differ
diff --git a/backend/proofs/scans/cmkau88zy0007eg1wtdhr3jir/e7505f67-fd93-4c64-b25d-802f613a4821/before.png b/backend/proofs/scans/cmkau88zy0007eg1wtdhr3jir/e7505f67-fd93-4c64-b25d-802f613a4821/before.png
new file mode 100644
index 0000000..7fea966
Binary files /dev/null and b/backend/proofs/scans/cmkau88zy0007eg1wtdhr3jir/e7505f67-fd93-4c64-b25d-802f613a4821/before.png differ
diff --git a/backend/proofs/scans/cmkau88zy0007eg1wtdhr3jir/e7505f67-fd93-4c64-b25d-802f613a4821/page.html b/backend/proofs/scans/cmkau88zy0007eg1wtdhr3jir/e7505f67-fd93-4c64-b25d-802f613a4821/page.html
new file mode 100644
index 0000000..6c1f4d1
--- /dev/null
+++ b/backend/proofs/scans/cmkau88zy0007eg1wtdhr3jir/e7505f67-fd93-4c64-b25d-802f613a4821/page.html
@@ -0,0 +1,531 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
Language has been changed to English
+
Force page reload
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkau890d0009eg1w2xoafjf6/a7f81a46-590d-4c94-ab00-6ee68abba149/after.png b/backend/proofs/scans/cmkau890d0009eg1w2xoafjf6/a7f81a46-590d-4c94-ab00-6ee68abba149/after.png
new file mode 100644
index 0000000..e397c2f
Binary files /dev/null and b/backend/proofs/scans/cmkau890d0009eg1w2xoafjf6/a7f81a46-590d-4c94-ab00-6ee68abba149/after.png differ
diff --git a/backend/proofs/scans/cmkau890d0009eg1w2xoafjf6/a7f81a46-590d-4c94-ab00-6ee68abba149/annotated.png b/backend/proofs/scans/cmkau890d0009eg1w2xoafjf6/a7f81a46-590d-4c94-ab00-6ee68abba149/annotated.png
new file mode 100644
index 0000000..cfcd62a
Binary files /dev/null and b/backend/proofs/scans/cmkau890d0009eg1w2xoafjf6/a7f81a46-590d-4c94-ab00-6ee68abba149/annotated.png differ
diff --git a/backend/proofs/scans/cmkau890d0009eg1w2xoafjf6/a7f81a46-590d-4c94-ab00-6ee68abba149/before.png b/backend/proofs/scans/cmkau890d0009eg1w2xoafjf6/a7f81a46-590d-4c94-ab00-6ee68abba149/before.png
new file mode 100644
index 0000000..9f26f53
Binary files /dev/null and b/backend/proofs/scans/cmkau890d0009eg1w2xoafjf6/a7f81a46-590d-4c94-ab00-6ee68abba149/before.png differ
diff --git a/backend/proofs/scans/cmkau890d0009eg1w2xoafjf6/a7f81a46-590d-4c94-ab00-6ee68abba149/page.html b/backend/proofs/scans/cmkau890d0009eg1w2xoafjf6/a7f81a46-590d-4c94-ab00-6ee68abba149/page.html
new file mode 100644
index 0000000..f395545
--- /dev/null
+++ b/backend/proofs/scans/cmkau890d0009eg1w2xoafjf6/a7f81a46-590d-4c94-ab00-6ee68abba149/page.html
@@ -0,0 +1,531 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
Language has been changed to English
+
Force page reload
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/733bcc88-2b58-4ac5-a6db-a921f36a1e9f/after.png b/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/733bcc88-2b58-4ac5-a6db-a921f36a1e9f/after.png
new file mode 100644
index 0000000..e397c2f
Binary files /dev/null and b/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/733bcc88-2b58-4ac5-a6db-a921f36a1e9f/after.png differ
diff --git a/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/733bcc88-2b58-4ac5-a6db-a921f36a1e9f/annotated.png b/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/733bcc88-2b58-4ac5-a6db-a921f36a1e9f/annotated.png
new file mode 100644
index 0000000..47d4b68
Binary files /dev/null and b/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/733bcc88-2b58-4ac5-a6db-a921f36a1e9f/annotated.png differ
diff --git a/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/733bcc88-2b58-4ac5-a6db-a921f36a1e9f/before.png b/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/733bcc88-2b58-4ac5-a6db-a921f36a1e9f/before.png
new file mode 100644
index 0000000..5f0b44e
Binary files /dev/null and b/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/733bcc88-2b58-4ac5-a6db-a921f36a1e9f/before.png differ
diff --git a/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/733bcc88-2b58-4ac5-a6db-a921f36a1e9f/page.html b/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/733bcc88-2b58-4ac5-a6db-a921f36a1e9f/page.html
new file mode 100644
index 0000000..88b66e0
--- /dev/null
+++ b/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/733bcc88-2b58-4ac5-a6db-a921f36a1e9f/page.html
@@ -0,0 +1,531 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
Language has been changed to English
+
Force page reload
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/99cbd62d-d0c0-4357-a16a-8cabf8189e73/after.png b/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/99cbd62d-d0c0-4357-a16a-8cabf8189e73/after.png
new file mode 100644
index 0000000..02b4fe6
Binary files /dev/null and b/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/99cbd62d-d0c0-4357-a16a-8cabf8189e73/after.png differ
diff --git a/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/99cbd62d-d0c0-4357-a16a-8cabf8189e73/before.png b/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/99cbd62d-d0c0-4357-a16a-8cabf8189e73/before.png
new file mode 100644
index 0000000..02b4fe6
Binary files /dev/null and b/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/99cbd62d-d0c0-4357-a16a-8cabf8189e73/before.png differ
diff --git a/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/e888b1ec-4919-44f6-ac75-33d6d5a0535f/after.png b/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/e888b1ec-4919-44f6-ac75-33d6d5a0535f/after.png
new file mode 100644
index 0000000..02b4fe6
Binary files /dev/null and b/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/e888b1ec-4919-44f6-ac75-33d6d5a0535f/after.png differ
diff --git a/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/e888b1ec-4919-44f6-ac75-33d6d5a0535f/before.png b/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/e888b1ec-4919-44f6-ac75-33d6d5a0535f/before.png
new file mode 100644
index 0000000..02b4fe6
Binary files /dev/null and b/backend/proofs/scans/cmkau890x000beg1wrkxrrh4n/e888b1ec-4919-44f6-ac75-33d6d5a0535f/before.png differ
diff --git a/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/0a0c987f-4cd7-4a46-9431-64e978b0bf0f/after.png b/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/0a0c987f-4cd7-4a46-9431-64e978b0bf0f/after.png
new file mode 100644
index 0000000..ce502aa
Binary files /dev/null and b/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/0a0c987f-4cd7-4a46-9431-64e978b0bf0f/after.png differ
diff --git a/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/0a0c987f-4cd7-4a46-9431-64e978b0bf0f/annotated.png b/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/0a0c987f-4cd7-4a46-9431-64e978b0bf0f/annotated.png
new file mode 100644
index 0000000..9147c85
Binary files /dev/null and b/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/0a0c987f-4cd7-4a46-9431-64e978b0bf0f/annotated.png differ
diff --git a/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/0a0c987f-4cd7-4a46-9431-64e978b0bf0f/before.png b/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/0a0c987f-4cd7-4a46-9431-64e978b0bf0f/before.png
new file mode 100644
index 0000000..a5d1e0e
Binary files /dev/null and b/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/0a0c987f-4cd7-4a46-9431-64e978b0bf0f/before.png differ
diff --git a/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/0a0c987f-4cd7-4a46-9431-64e978b0bf0f/page.html b/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/0a0c987f-4cd7-4a46-9431-64e978b0bf0f/page.html
new file mode 100644
index 0000000..c810f03
--- /dev/null
+++ b/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/0a0c987f-4cd7-4a46-9431-64e978b0bf0f/page.html
@@ -0,0 +1,49 @@
+
+
+ Error: Unexpected path: /rest/user/login?q=%27%7C%7C%28SELECT+sqlite_version%28%29%29%7C%7C%27
+
+
+
+
+
OWASP Juice Shop (Express ^4.21.0)
+
500 Error: Unexpected path: /rest/user/login?q=%27%7C%7C%28SELECT+sqlite_version%28%29%29%7C%7C%27
+
at /juice-shop/build/routes/angular.js:42:18 at Layer.handle [as handle_request] (/juice-shop/node_modules/express/lib/router/layer.js:95:5) at trim_prefix (/juice-shop/node_modules/express/lib/router/index.js:328:13) at /juice-shop/node_modules/express/lib/router/index.js:286:9 at Function.process_params (/juice-shop/node_modules/express/lib/router/index.js:346:12) at next (/juice-shop/node_modules/express/lib/router/index.js:280:10) at /juice-shop/build/routes/verify.js:187:5 at Layer.handle [as handle_request] (/juice-shop/node_modules/express/lib/router/layer.js:95:5) at trim_prefix (/juice-shop/node_modules/express/lib/router/index.js:328:13) at /juice-shop/node_modules/express/lib/router/index.js:286:9 at Function.process_params (/juice-shop/node_modules/express/lib/router/index.js:346:12) at next (/juice-shop/node_modules/express/lib/router/index.js:280:10) at /juice-shop/build/routes/verify.js:111:5 at Layer.handle [as handle_request] (/juice-shop/node_modules/express/lib/router/layer.js:95:5) at trim_prefix (/juice-shop/node_modules/express/lib/router/index.js:328:13) at /juice-shop/node_modules/express/lib/router/index.js:286:9 at Function.process_params (/juice-shop/node_modules/express/lib/router/index.js:346:12) at next (/juice-shop/node_modules/express/lib/router/index.js:280:10) at logger (/juice-shop/node_modules/morgan/index.js:144:5) at Layer.handle [as handle_request] (/juice-shop/node_modules/express/lib/router/layer.js:95:5) at trim_prefix (/juice-shop/node_modules/express/lib/router/index.js:328:13) at /juice-shop/node_modules/express/lib/router/index.js:286:9
+
+
+
+
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/16fafab8-f886-457b-8b21-75fcf26a237c/after.png b/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/16fafab8-f886-457b-8b21-75fcf26a237c/after.png
new file mode 100644
index 0000000..6e14704
Binary files /dev/null and b/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/16fafab8-f886-457b-8b21-75fcf26a237c/after.png differ
diff --git a/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/16fafab8-f886-457b-8b21-75fcf26a237c/before.png b/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/16fafab8-f886-457b-8b21-75fcf26a237c/before.png
new file mode 100644
index 0000000..a5d1e0e
Binary files /dev/null and b/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/16fafab8-f886-457b-8b21-75fcf26a237c/before.png differ
diff --git a/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/1d5e56c3-d8f1-4680-9aec-d717fb7f4c31/after.png b/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/1d5e56c3-d8f1-4680-9aec-d717fb7f4c31/after.png
new file mode 100644
index 0000000..589e406
Binary files /dev/null and b/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/1d5e56c3-d8f1-4680-9aec-d717fb7f4c31/after.png differ
diff --git a/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/1d5e56c3-d8f1-4680-9aec-d717fb7f4c31/annotated.png b/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/1d5e56c3-d8f1-4680-9aec-d717fb7f4c31/annotated.png
new file mode 100644
index 0000000..8cd6ab5
Binary files /dev/null and b/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/1d5e56c3-d8f1-4680-9aec-d717fb7f4c31/annotated.png differ
diff --git a/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/1d5e56c3-d8f1-4680-9aec-d717fb7f4c31/before.png b/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/1d5e56c3-d8f1-4680-9aec-d717fb7f4c31/before.png
new file mode 100644
index 0000000..3e3d5d6
Binary files /dev/null and b/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/1d5e56c3-d8f1-4680-9aec-d717fb7f4c31/before.png differ
diff --git a/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/1d5e56c3-d8f1-4680-9aec-d717fb7f4c31/page.html b/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/1d5e56c3-d8f1-4680-9aec-d717fb7f4c31/page.html
new file mode 100644
index 0000000..1dca99a
--- /dev/null
+++ b/backend/proofs/scans/cmkawahuu0001egskei1r9d9g/1d5e56c3-d8f1-4680-9aec-d717fb7f4c31/page.html
@@ -0,0 +1,528 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/39ab9c05-85ed-4dc9-b7a5-2fd18bb2bf5d/after.png b/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/39ab9c05-85ed-4dc9-b7a5-2fd18bb2bf5d/after.png
new file mode 100644
index 0000000..217b3f3
Binary files /dev/null and b/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/39ab9c05-85ed-4dc9-b7a5-2fd18bb2bf5d/after.png differ
diff --git a/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/39ab9c05-85ed-4dc9-b7a5-2fd18bb2bf5d/annotated.png b/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/39ab9c05-85ed-4dc9-b7a5-2fd18bb2bf5d/annotated.png
new file mode 100644
index 0000000..cbce542
Binary files /dev/null and b/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/39ab9c05-85ed-4dc9-b7a5-2fd18bb2bf5d/annotated.png differ
diff --git a/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/39ab9c05-85ed-4dc9-b7a5-2fd18bb2bf5d/before.png b/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/39ab9c05-85ed-4dc9-b7a5-2fd18bb2bf5d/before.png
new file mode 100644
index 0000000..1014d57
Binary files /dev/null and b/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/39ab9c05-85ed-4dc9-b7a5-2fd18bb2bf5d/before.png differ
diff --git a/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/39ab9c05-85ed-4dc9-b7a5-2fd18bb2bf5d/page.html b/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/39ab9c05-85ed-4dc9-b7a5-2fd18bb2bf5d/page.html
new file mode 100644
index 0000000..6101d2f
--- /dev/null
+++ b/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/39ab9c05-85ed-4dc9-b7a5-2fd18bb2bf5d/page.html
@@ -0,0 +1,532 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
Language has been changed to English
+
Force page reload
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/a5070679-8bdd-474f-bfb6-15552773c0ec/after.png b/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/a5070679-8bdd-474f-bfb6-15552773c0ec/after.png
new file mode 100644
index 0000000..05c9053
Binary files /dev/null and b/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/a5070679-8bdd-474f-bfb6-15552773c0ec/after.png differ
diff --git a/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/a5070679-8bdd-474f-bfb6-15552773c0ec/before.png b/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/a5070679-8bdd-474f-bfb6-15552773c0ec/before.png
new file mode 100644
index 0000000..a752cf9
Binary files /dev/null and b/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/a5070679-8bdd-474f-bfb6-15552773c0ec/before.png differ
diff --git a/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/d016eccf-1c88-4e15-b450-827bbbaa0297/after.png b/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/d016eccf-1c88-4e15-b450-827bbbaa0297/after.png
new file mode 100644
index 0000000..05c9053
Binary files /dev/null and b/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/d016eccf-1c88-4e15-b450-827bbbaa0297/after.png differ
diff --git a/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/d016eccf-1c88-4e15-b450-827bbbaa0297/before.png b/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/d016eccf-1c88-4e15-b450-827bbbaa0297/before.png
new file mode 100644
index 0000000..a752cf9
Binary files /dev/null and b/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/d016eccf-1c88-4e15-b450-827bbbaa0297/before.png differ
diff --git a/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/videos/08d309d8aec15a68a73c2c0acdf3a90c.webm b/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/videos/08d309d8aec15a68a73c2c0acdf3a90c.webm
new file mode 100644
index 0000000..8a1ed14
Binary files /dev/null and b/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/videos/08d309d8aec15a68a73c2c0acdf3a90c.webm differ
diff --git a/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/videos/e985d6fd43a8511b35b08013c9a502fc.webm b/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/videos/e985d6fd43a8511b35b08013c9a502fc.webm
new file mode 100644
index 0000000..99294e8
Binary files /dev/null and b/backend/proofs/scans/cmkawahv80003egsk4l4jc0io/videos/e985d6fd43a8511b35b08013c9a502fc.webm differ
diff --git a/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/45a11f66-148a-47dd-b321-de87b1bf3076/after.png b/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/45a11f66-148a-47dd-b321-de87b1bf3076/after.png
new file mode 100644
index 0000000..02b4fe6
Binary files /dev/null and b/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/45a11f66-148a-47dd-b321-de87b1bf3076/after.png differ
diff --git a/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/45a11f66-148a-47dd-b321-de87b1bf3076/before.png b/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/45a11f66-148a-47dd-b321-de87b1bf3076/before.png
new file mode 100644
index 0000000..02b4fe6
Binary files /dev/null and b/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/45a11f66-148a-47dd-b321-de87b1bf3076/before.png differ
diff --git a/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/65fbc343-ffd5-4c85-938b-a650381d5be0/after.png b/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/65fbc343-ffd5-4c85-938b-a650381d5be0/after.png
new file mode 100644
index 0000000..3d27a0e
Binary files /dev/null and b/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/65fbc343-ffd5-4c85-938b-a650381d5be0/after.png differ
diff --git a/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/65fbc343-ffd5-4c85-938b-a650381d5be0/annotated.png b/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/65fbc343-ffd5-4c85-938b-a650381d5be0/annotated.png
new file mode 100644
index 0000000..bd12ff3
Binary files /dev/null and b/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/65fbc343-ffd5-4c85-938b-a650381d5be0/annotated.png differ
diff --git a/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/65fbc343-ffd5-4c85-938b-a650381d5be0/before.png b/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/65fbc343-ffd5-4c85-938b-a650381d5be0/before.png
new file mode 100644
index 0000000..6784f77
Binary files /dev/null and b/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/65fbc343-ffd5-4c85-938b-a650381d5be0/before.png differ
diff --git a/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/65fbc343-ffd5-4c85-938b-a650381d5be0/page.html b/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/65fbc343-ffd5-4c85-938b-a650381d5be0/page.html
new file mode 100644
index 0000000..00cfd33
--- /dev/null
+++ b/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/65fbc343-ffd5-4c85-938b-a650381d5be0/page.html
@@ -0,0 +1,531 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
Language has been changed to English
+
Force page reload
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/67b708d7-7326-4305-b95c-502b5586fa85/after.png b/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/67b708d7-7326-4305-b95c-502b5586fa85/after.png
new file mode 100644
index 0000000..02b4fe6
Binary files /dev/null and b/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/67b708d7-7326-4305-b95c-502b5586fa85/after.png differ
diff --git a/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/67b708d7-7326-4305-b95c-502b5586fa85/before.png b/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/67b708d7-7326-4305-b95c-502b5586fa85/before.png
new file mode 100644
index 0000000..02b4fe6
Binary files /dev/null and b/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/67b708d7-7326-4305-b95c-502b5586fa85/before.png differ
diff --git a/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/d2d1b2c9-9c0b-4dee-bec5-cff8651c5788/after.png b/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/d2d1b2c9-9c0b-4dee-bec5-cff8651c5788/after.png
new file mode 100644
index 0000000..02b4fe6
Binary files /dev/null and b/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/d2d1b2c9-9c0b-4dee-bec5-cff8651c5788/after.png differ
diff --git a/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/d2d1b2c9-9c0b-4dee-bec5-cff8651c5788/before.png b/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/d2d1b2c9-9c0b-4dee-bec5-cff8651c5788/before.png
new file mode 100644
index 0000000..02b4fe6
Binary files /dev/null and b/backend/proofs/scans/cmkawahvf0005egskg4n0fe23/d2d1b2c9-9c0b-4dee-bec5-cff8651c5788/before.png differ
diff --git a/backend/proofs/scans/cmkawahvn0007egskb7k661r9/3944c4b6-5806-4273-b1c2-80a446680ff3/after.png b/backend/proofs/scans/cmkawahvn0007egskb7k661r9/3944c4b6-5806-4273-b1c2-80a446680ff3/after.png
new file mode 100644
index 0000000..2357ee4
Binary files /dev/null and b/backend/proofs/scans/cmkawahvn0007egskb7k661r9/3944c4b6-5806-4273-b1c2-80a446680ff3/after.png differ
diff --git a/backend/proofs/scans/cmkawahvn0007egskb7k661r9/3944c4b6-5806-4273-b1c2-80a446680ff3/annotated.png b/backend/proofs/scans/cmkawahvn0007egskb7k661r9/3944c4b6-5806-4273-b1c2-80a446680ff3/annotated.png
new file mode 100644
index 0000000..8a88e20
Binary files /dev/null and b/backend/proofs/scans/cmkawahvn0007egskb7k661r9/3944c4b6-5806-4273-b1c2-80a446680ff3/annotated.png differ
diff --git a/backend/proofs/scans/cmkawahvn0007egskb7k661r9/3944c4b6-5806-4273-b1c2-80a446680ff3/before.png b/backend/proofs/scans/cmkawahvn0007egskb7k661r9/3944c4b6-5806-4273-b1c2-80a446680ff3/before.png
new file mode 100644
index 0000000..b1d382f
Binary files /dev/null and b/backend/proofs/scans/cmkawahvn0007egskb7k661r9/3944c4b6-5806-4273-b1c2-80a446680ff3/before.png differ
diff --git a/backend/proofs/scans/cmkawahvn0007egskb7k661r9/3944c4b6-5806-4273-b1c2-80a446680ff3/page.html b/backend/proofs/scans/cmkawahvn0007egskb7k661r9/3944c4b6-5806-4273-b1c2-80a446680ff3/page.html
new file mode 100644
index 0000000..1a5842a
--- /dev/null
+++ b/backend/proofs/scans/cmkawahvn0007egskb7k661r9/3944c4b6-5806-4273-b1c2-80a446680ff3/page.html
@@ -0,0 +1,531 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
Language has been changed to English
+
Force page reload
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkawahvn0007egskb7k661r9/6e6a02fe-b26f-4e8f-b79c-adbcbce33d39/after.png b/backend/proofs/scans/cmkawahvn0007egskb7k661r9/6e6a02fe-b26f-4e8f-b79c-adbcbce33d39/after.png
new file mode 100644
index 0000000..05c9053
Binary files /dev/null and b/backend/proofs/scans/cmkawahvn0007egskb7k661r9/6e6a02fe-b26f-4e8f-b79c-adbcbce33d39/after.png differ
diff --git a/backend/proofs/scans/cmkawahvn0007egskb7k661r9/6e6a02fe-b26f-4e8f-b79c-adbcbce33d39/before.png b/backend/proofs/scans/cmkawahvn0007egskb7k661r9/6e6a02fe-b26f-4e8f-b79c-adbcbce33d39/before.png
new file mode 100644
index 0000000..6475f22
Binary files /dev/null and b/backend/proofs/scans/cmkawahvn0007egskb7k661r9/6e6a02fe-b26f-4e8f-b79c-adbcbce33d39/before.png differ
diff --git a/backend/proofs/scans/cmkawahvn0007egskb7k661r9/e775a3d3-dfd6-47eb-9334-ab7b710ec7e6/after.png b/backend/proofs/scans/cmkawahvn0007egskb7k661r9/e775a3d3-dfd6-47eb-9334-ab7b710ec7e6/after.png
new file mode 100644
index 0000000..05c9053
Binary files /dev/null and b/backend/proofs/scans/cmkawahvn0007egskb7k661r9/e775a3d3-dfd6-47eb-9334-ab7b710ec7e6/after.png differ
diff --git a/backend/proofs/scans/cmkawahvn0007egskb7k661r9/e775a3d3-dfd6-47eb-9334-ab7b710ec7e6/before.png b/backend/proofs/scans/cmkawahvn0007egskb7k661r9/e775a3d3-dfd6-47eb-9334-ab7b710ec7e6/before.png
new file mode 100644
index 0000000..6475f22
Binary files /dev/null and b/backend/proofs/scans/cmkawahvn0007egskb7k661r9/e775a3d3-dfd6-47eb-9334-ab7b710ec7e6/before.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/12ca211d-c677-4548-b658-77fa33cd66aa/after.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/12ca211d-c677-4548-b658-77fa33cd66aa/after.png
new file mode 100644
index 0000000..c9fcbd7
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/12ca211d-c677-4548-b658-77fa33cd66aa/after.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/12ca211d-c677-4548-b658-77fa33cd66aa/annotated.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/12ca211d-c677-4548-b658-77fa33cd66aa/annotated.png
new file mode 100644
index 0000000..6084754
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/12ca211d-c677-4548-b658-77fa33cd66aa/annotated.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/12ca211d-c677-4548-b658-77fa33cd66aa/before.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/12ca211d-c677-4548-b658-77fa33cd66aa/before.png
new file mode 100644
index 0000000..c9fcbd7
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/12ca211d-c677-4548-b658-77fa33cd66aa/before.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/12ca211d-c677-4548-b658-77fa33cd66aa/page.html b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/12ca211d-c677-4548-b658-77fa33cd66aa/page.html
new file mode 100644
index 0000000..1b1e827
--- /dev/null
+++ b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/12ca211d-c677-4548-b658-77fa33cd66aa/page.html
@@ -0,0 +1 @@
+{"status":"success","data":{"id":1,"name":"Apple Juice (1000ml)","description":"The all-time classic.","price":1.99,"deluxePrice":0.99,"image":"apple_juice.jpg","createdAt":"2026-01-12T06:14:40.837Z","updatedAt":"2026-01-12T06:14:40.837Z","deletedAt":null}}
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/3b647cec-20fc-4089-b906-3ab73d918c6c/after.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/3b647cec-20fc-4089-b906-3ab73d918c6c/after.png
new file mode 100644
index 0000000..c9fcbd7
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/3b647cec-20fc-4089-b906-3ab73d918c6c/after.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/3b647cec-20fc-4089-b906-3ab73d918c6c/annotated.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/3b647cec-20fc-4089-b906-3ab73d918c6c/annotated.png
new file mode 100644
index 0000000..2f6ec16
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/3b647cec-20fc-4089-b906-3ab73d918c6c/annotated.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/3b647cec-20fc-4089-b906-3ab73d918c6c/before.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/3b647cec-20fc-4089-b906-3ab73d918c6c/before.png
new file mode 100644
index 0000000..c9fcbd7
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/3b647cec-20fc-4089-b906-3ab73d918c6c/before.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/3b647cec-20fc-4089-b906-3ab73d918c6c/page.html b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/3b647cec-20fc-4089-b906-3ab73d918c6c/page.html
new file mode 100644
index 0000000..1b1e827
--- /dev/null
+++ b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/3b647cec-20fc-4089-b906-3ab73d918c6c/page.html
@@ -0,0 +1 @@
+{"status":"success","data":{"id":1,"name":"Apple Juice (1000ml)","description":"The all-time classic.","price":1.99,"deluxePrice":0.99,"image":"apple_juice.jpg","createdAt":"2026-01-12T06:14:40.837Z","updatedAt":"2026-01-12T06:14:40.837Z","deletedAt":null}}
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/47bc24be-7556-4f87-aa07-7f8831a875be/after.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/47bc24be-7556-4f87-aa07-7f8831a875be/after.png
new file mode 100644
index 0000000..0074861
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/47bc24be-7556-4f87-aa07-7f8831a875be/after.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/47bc24be-7556-4f87-aa07-7f8831a875be/annotated.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/47bc24be-7556-4f87-aa07-7f8831a875be/annotated.png
new file mode 100644
index 0000000..8182eb8
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/47bc24be-7556-4f87-aa07-7f8831a875be/annotated.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/47bc24be-7556-4f87-aa07-7f8831a875be/before.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/47bc24be-7556-4f87-aa07-7f8831a875be/before.png
new file mode 100644
index 0000000..c9fcbd7
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/47bc24be-7556-4f87-aa07-7f8831a875be/before.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/47bc24be-7556-4f87-aa07-7f8831a875be/page.html b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/47bc24be-7556-4f87-aa07-7f8831a875be/page.html
new file mode 100644
index 0000000..1b1e827
--- /dev/null
+++ b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/47bc24be-7556-4f87-aa07-7f8831a875be/page.html
@@ -0,0 +1 @@
+{"status":"success","data":{"id":1,"name":"Apple Juice (1000ml)","description":"The all-time classic.","price":1.99,"deluxePrice":0.99,"image":"apple_juice.jpg","createdAt":"2026-01-12T06:14:40.837Z","updatedAt":"2026-01-12T06:14:40.837Z","deletedAt":null}}
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/4eb4e609-cebd-45c5-9bcf-67e07e6bb8f9/after.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/4eb4e609-cebd-45c5-9bcf-67e07e6bb8f9/after.png
new file mode 100644
index 0000000..c9fcbd7
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/4eb4e609-cebd-45c5-9bcf-67e07e6bb8f9/after.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/4eb4e609-cebd-45c5-9bcf-67e07e6bb8f9/annotated.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/4eb4e609-cebd-45c5-9bcf-67e07e6bb8f9/annotated.png
new file mode 100644
index 0000000..439bb1f
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/4eb4e609-cebd-45c5-9bcf-67e07e6bb8f9/annotated.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/4eb4e609-cebd-45c5-9bcf-67e07e6bb8f9/before.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/4eb4e609-cebd-45c5-9bcf-67e07e6bb8f9/before.png
new file mode 100644
index 0000000..c9fcbd7
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/4eb4e609-cebd-45c5-9bcf-67e07e6bb8f9/before.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/4eb4e609-cebd-45c5-9bcf-67e07e6bb8f9/page.html b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/4eb4e609-cebd-45c5-9bcf-67e07e6bb8f9/page.html
new file mode 100644
index 0000000..1b1e827
--- /dev/null
+++ b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/4eb4e609-cebd-45c5-9bcf-67e07e6bb8f9/page.html
@@ -0,0 +1 @@
+{"status":"success","data":{"id":1,"name":"Apple Juice (1000ml)","description":"The all-time classic.","price":1.99,"deluxePrice":0.99,"image":"apple_juice.jpg","createdAt":"2026-01-12T06:14:40.837Z","updatedAt":"2026-01-12T06:14:40.837Z","deletedAt":null}}
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/50999045-b732-48cd-948a-4de28a8f4fac/after.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/50999045-b732-48cd-948a-4de28a8f4fac/after.png
new file mode 100644
index 0000000..c9fcbd7
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/50999045-b732-48cd-948a-4de28a8f4fac/after.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/50999045-b732-48cd-948a-4de28a8f4fac/annotated.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/50999045-b732-48cd-948a-4de28a8f4fac/annotated.png
new file mode 100644
index 0000000..9a1ef7f
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/50999045-b732-48cd-948a-4de28a8f4fac/annotated.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/50999045-b732-48cd-948a-4de28a8f4fac/before.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/50999045-b732-48cd-948a-4de28a8f4fac/before.png
new file mode 100644
index 0000000..c9fcbd7
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/50999045-b732-48cd-948a-4de28a8f4fac/before.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/50999045-b732-48cd-948a-4de28a8f4fac/page.html b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/50999045-b732-48cd-948a-4de28a8f4fac/page.html
new file mode 100644
index 0000000..1b1e827
--- /dev/null
+++ b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/50999045-b732-48cd-948a-4de28a8f4fac/page.html
@@ -0,0 +1 @@
+{"status":"success","data":{"id":1,"name":"Apple Juice (1000ml)","description":"The all-time classic.","price":1.99,"deluxePrice":0.99,"image":"apple_juice.jpg","createdAt":"2026-01-12T06:14:40.837Z","updatedAt":"2026-01-12T06:14:40.837Z","deletedAt":null}}
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/77f7c558-cdc7-4600-93aa-863a027f527c/after.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/77f7c558-cdc7-4600-93aa-863a027f527c/after.png
new file mode 100644
index 0000000..c9fcbd7
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/77f7c558-cdc7-4600-93aa-863a027f527c/after.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/77f7c558-cdc7-4600-93aa-863a027f527c/annotated.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/77f7c558-cdc7-4600-93aa-863a027f527c/annotated.png
new file mode 100644
index 0000000..a2e2cdd
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/77f7c558-cdc7-4600-93aa-863a027f527c/annotated.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/77f7c558-cdc7-4600-93aa-863a027f527c/before.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/77f7c558-cdc7-4600-93aa-863a027f527c/before.png
new file mode 100644
index 0000000..c9fcbd7
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/77f7c558-cdc7-4600-93aa-863a027f527c/before.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/77f7c558-cdc7-4600-93aa-863a027f527c/page.html b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/77f7c558-cdc7-4600-93aa-863a027f527c/page.html
new file mode 100644
index 0000000..1b1e827
--- /dev/null
+++ b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/77f7c558-cdc7-4600-93aa-863a027f527c/page.html
@@ -0,0 +1 @@
+{"status":"success","data":{"id":1,"name":"Apple Juice (1000ml)","description":"The all-time classic.","price":1.99,"deluxePrice":0.99,"image":"apple_juice.jpg","createdAt":"2026-01-12T06:14:40.837Z","updatedAt":"2026-01-12T06:14:40.837Z","deletedAt":null}}
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/a14a1580-a5b3-4812-82da-d1cd7ae73769/after.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/a14a1580-a5b3-4812-82da-d1cd7ae73769/after.png
new file mode 100644
index 0000000..c9fcbd7
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/a14a1580-a5b3-4812-82da-d1cd7ae73769/after.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/a14a1580-a5b3-4812-82da-d1cd7ae73769/annotated.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/a14a1580-a5b3-4812-82da-d1cd7ae73769/annotated.png
new file mode 100644
index 0000000..da3cb6f
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/a14a1580-a5b3-4812-82da-d1cd7ae73769/annotated.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/a14a1580-a5b3-4812-82da-d1cd7ae73769/before.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/a14a1580-a5b3-4812-82da-d1cd7ae73769/before.png
new file mode 100644
index 0000000..c9fcbd7
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/a14a1580-a5b3-4812-82da-d1cd7ae73769/before.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/a14a1580-a5b3-4812-82da-d1cd7ae73769/page.html b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/a14a1580-a5b3-4812-82da-d1cd7ae73769/page.html
new file mode 100644
index 0000000..1b1e827
--- /dev/null
+++ b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/a14a1580-a5b3-4812-82da-d1cd7ae73769/page.html
@@ -0,0 +1 @@
+{"status":"success","data":{"id":1,"name":"Apple Juice (1000ml)","description":"The all-time classic.","price":1.99,"deluxePrice":0.99,"image":"apple_juice.jpg","createdAt":"2026-01-12T06:14:40.837Z","updatedAt":"2026-01-12T06:14:40.837Z","deletedAt":null}}
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/bebea4e1-e8eb-442e-b393-5ec1002748a0/after.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/bebea4e1-e8eb-442e-b393-5ec1002748a0/after.png
new file mode 100644
index 0000000..c9fcbd7
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/bebea4e1-e8eb-442e-b393-5ec1002748a0/after.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/bebea4e1-e8eb-442e-b393-5ec1002748a0/annotated.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/bebea4e1-e8eb-442e-b393-5ec1002748a0/annotated.png
new file mode 100644
index 0000000..2a01bf0
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/bebea4e1-e8eb-442e-b393-5ec1002748a0/annotated.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/bebea4e1-e8eb-442e-b393-5ec1002748a0/before.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/bebea4e1-e8eb-442e-b393-5ec1002748a0/before.png
new file mode 100644
index 0000000..c9fcbd7
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/bebea4e1-e8eb-442e-b393-5ec1002748a0/before.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/bebea4e1-e8eb-442e-b393-5ec1002748a0/page.html b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/bebea4e1-e8eb-442e-b393-5ec1002748a0/page.html
new file mode 100644
index 0000000..1b1e827
--- /dev/null
+++ b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/bebea4e1-e8eb-442e-b393-5ec1002748a0/page.html
@@ -0,0 +1 @@
+{"status":"success","data":{"id":1,"name":"Apple Juice (1000ml)","description":"The all-time classic.","price":1.99,"deluxePrice":0.99,"image":"apple_juice.jpg","createdAt":"2026-01-12T06:14:40.837Z","updatedAt":"2026-01-12T06:14:40.837Z","deletedAt":null}}
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/d7038d15-98a8-43da-9587-2386f777310d/after.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/d7038d15-98a8-43da-9587-2386f777310d/after.png
new file mode 100644
index 0000000..9b26f3c
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/d7038d15-98a8-43da-9587-2386f777310d/after.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/d7038d15-98a8-43da-9587-2386f777310d/annotated.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/d7038d15-98a8-43da-9587-2386f777310d/annotated.png
new file mode 100644
index 0000000..a32ef2b
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/d7038d15-98a8-43da-9587-2386f777310d/annotated.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/d7038d15-98a8-43da-9587-2386f777310d/before.png b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/d7038d15-98a8-43da-9587-2386f777310d/before.png
new file mode 100644
index 0000000..5d0ae42
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/d7038d15-98a8-43da-9587-2386f777310d/before.png differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/d7038d15-98a8-43da-9587-2386f777310d/page.html b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/d7038d15-98a8-43da-9587-2386f777310d/page.html
new file mode 100644
index 0000000..259decf
--- /dev/null
+++ b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/d7038d15-98a8-43da-9587-2386f777310d/page.html
@@ -0,0 +1,528 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/videos/2d19f579e29e7c386b435d24078e6533.webm b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/videos/2d19f579e29e7c386b435d24078e6533.webm
new file mode 100644
index 0000000..58a093f
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/videos/2d19f579e29e7c386b435d24078e6533.webm differ
diff --git a/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/videos/b905433d79b580fbb872359d44ea643d.webm b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/videos/b905433d79b580fbb872359d44ea643d.webm
new file mode 100644
index 0000000..8d10a25
Binary files /dev/null and b/backend/proofs/scans/cmkawahvv0009egsk76e0x8fc/videos/b905433d79b580fbb872359d44ea643d.webm differ
diff --git a/backend/proofs/scans/cmkawahw5000begsk40c8knqp/cdb4aced-366e-4a06-8bf5-65791f8c0bd1/after.png b/backend/proofs/scans/cmkawahw5000begsk40c8knqp/cdb4aced-366e-4a06-8bf5-65791f8c0bd1/after.png
new file mode 100644
index 0000000..d472926
Binary files /dev/null and b/backend/proofs/scans/cmkawahw5000begsk40c8knqp/cdb4aced-366e-4a06-8bf5-65791f8c0bd1/after.png differ
diff --git a/backend/proofs/scans/cmkawahw5000begsk40c8knqp/cdb4aced-366e-4a06-8bf5-65791f8c0bd1/annotated.png b/backend/proofs/scans/cmkawahw5000begsk40c8knqp/cdb4aced-366e-4a06-8bf5-65791f8c0bd1/annotated.png
new file mode 100644
index 0000000..8bb6cd0
Binary files /dev/null and b/backend/proofs/scans/cmkawahw5000begsk40c8knqp/cdb4aced-366e-4a06-8bf5-65791f8c0bd1/annotated.png differ
diff --git a/backend/proofs/scans/cmkawahw5000begsk40c8knqp/cdb4aced-366e-4a06-8bf5-65791f8c0bd1/before.png b/backend/proofs/scans/cmkawahw5000begsk40c8knqp/cdb4aced-366e-4a06-8bf5-65791f8c0bd1/before.png
new file mode 100644
index 0000000..48ab877
Binary files /dev/null and b/backend/proofs/scans/cmkawahw5000begsk40c8knqp/cdb4aced-366e-4a06-8bf5-65791f8c0bd1/before.png differ
diff --git a/backend/proofs/scans/cmkawahw5000begsk40c8knqp/cdb4aced-366e-4a06-8bf5-65791f8c0bd1/page.html b/backend/proofs/scans/cmkawahw5000begsk40c8knqp/cdb4aced-366e-4a06-8bf5-65791f8c0bd1/page.html
new file mode 100644
index 0000000..f395545
--- /dev/null
+++ b/backend/proofs/scans/cmkawahw5000begsk40c8knqp/cdb4aced-366e-4a06-8bf5-65791f8c0bd1/page.html
@@ -0,0 +1,531 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
Language has been changed to English
+
Force page reload
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkawhyot0001eg5ocb0nqwm6/3a7ebf03-fa65-43e4-a9a2-c59e47ca60e7/after.png b/backend/proofs/scans/cmkawhyot0001eg5ocb0nqwm6/3a7ebf03-fa65-43e4-a9a2-c59e47ca60e7/after.png
new file mode 100644
index 0000000..b5fc78a
Binary files /dev/null and b/backend/proofs/scans/cmkawhyot0001eg5ocb0nqwm6/3a7ebf03-fa65-43e4-a9a2-c59e47ca60e7/after.png differ
diff --git a/backend/proofs/scans/cmkawhyot0001eg5ocb0nqwm6/3a7ebf03-fa65-43e4-a9a2-c59e47ca60e7/annotated.png b/backend/proofs/scans/cmkawhyot0001eg5ocb0nqwm6/3a7ebf03-fa65-43e4-a9a2-c59e47ca60e7/annotated.png
new file mode 100644
index 0000000..aa48616
Binary files /dev/null and b/backend/proofs/scans/cmkawhyot0001eg5ocb0nqwm6/3a7ebf03-fa65-43e4-a9a2-c59e47ca60e7/annotated.png differ
diff --git a/backend/proofs/scans/cmkawhyot0001eg5ocb0nqwm6/3a7ebf03-fa65-43e4-a9a2-c59e47ca60e7/before.png b/backend/proofs/scans/cmkawhyot0001eg5ocb0nqwm6/3a7ebf03-fa65-43e4-a9a2-c59e47ca60e7/before.png
new file mode 100644
index 0000000..c809c5b
Binary files /dev/null and b/backend/proofs/scans/cmkawhyot0001eg5ocb0nqwm6/3a7ebf03-fa65-43e4-a9a2-c59e47ca60e7/before.png differ
diff --git a/backend/proofs/scans/cmkawhyot0001eg5ocb0nqwm6/3a7ebf03-fa65-43e4-a9a2-c59e47ca60e7/page.html b/backend/proofs/scans/cmkawhyot0001eg5ocb0nqwm6/3a7ebf03-fa65-43e4-a9a2-c59e47ca60e7/page.html
new file mode 100644
index 0000000..95bf451
--- /dev/null
+++ b/backend/proofs/scans/cmkawhyot0001eg5ocb0nqwm6/3a7ebf03-fa65-43e4-a9a2-c59e47ca60e7/page.html
@@ -0,0 +1,532 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
Language has been changed to English
+
Force page reload
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkawhypu0003eg5o95mruvie/1279aa49-b3d2-4284-9bc3-9813ffd7b5c3/before.png b/backend/proofs/scans/cmkawhypu0003eg5o95mruvie/1279aa49-b3d2-4284-9bc3-9813ffd7b5c3/before.png
new file mode 100644
index 0000000..1a9a9f3
Binary files /dev/null and b/backend/proofs/scans/cmkawhypu0003eg5o95mruvie/1279aa49-b3d2-4284-9bc3-9813ffd7b5c3/before.png differ
diff --git a/backend/proofs/scans/cmkawhyq60005eg5om5vd7b3l/af2cbef4-c97a-47d6-82f8-2a2838564b91/after.png b/backend/proofs/scans/cmkawhyq60005eg5om5vd7b3l/af2cbef4-c97a-47d6-82f8-2a2838564b91/after.png
new file mode 100644
index 0000000..678d7d1
Binary files /dev/null and b/backend/proofs/scans/cmkawhyq60005eg5om5vd7b3l/af2cbef4-c97a-47d6-82f8-2a2838564b91/after.png differ
diff --git a/backend/proofs/scans/cmkawhyq60005eg5om5vd7b3l/af2cbef4-c97a-47d6-82f8-2a2838564b91/annotated.png b/backend/proofs/scans/cmkawhyq60005eg5om5vd7b3l/af2cbef4-c97a-47d6-82f8-2a2838564b91/annotated.png
new file mode 100644
index 0000000..780a079
Binary files /dev/null and b/backend/proofs/scans/cmkawhyq60005eg5om5vd7b3l/af2cbef4-c97a-47d6-82f8-2a2838564b91/annotated.png differ
diff --git a/backend/proofs/scans/cmkawhyq60005eg5om5vd7b3l/af2cbef4-c97a-47d6-82f8-2a2838564b91/before.png b/backend/proofs/scans/cmkawhyq60005eg5om5vd7b3l/af2cbef4-c97a-47d6-82f8-2a2838564b91/before.png
new file mode 100644
index 0000000..660fc3c
Binary files /dev/null and b/backend/proofs/scans/cmkawhyq60005eg5om5vd7b3l/af2cbef4-c97a-47d6-82f8-2a2838564b91/before.png differ
diff --git a/backend/proofs/scans/cmkawhyq60005eg5om5vd7b3l/af2cbef4-c97a-47d6-82f8-2a2838564b91/page.html b/backend/proofs/scans/cmkawhyq60005eg5om5vd7b3l/af2cbef4-c97a-47d6-82f8-2a2838564b91/page.html
new file mode 100644
index 0000000..81f464f
--- /dev/null
+++ b/backend/proofs/scans/cmkawhyq60005eg5om5vd7b3l/af2cbef4-c97a-47d6-82f8-2a2838564b91/page.html
@@ -0,0 +1,531 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
Language has been changed to English
+
Force page reload
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkawhyqe0007eg5or3z9drxk/be4c046b-1d3c-49b8-90e4-bed8632b0bb3/after.png b/backend/proofs/scans/cmkawhyqe0007eg5or3z9drxk/be4c046b-1d3c-49b8-90e4-bed8632b0bb3/after.png
new file mode 100644
index 0000000..2357ee4
Binary files /dev/null and b/backend/proofs/scans/cmkawhyqe0007eg5or3z9drxk/be4c046b-1d3c-49b8-90e4-bed8632b0bb3/after.png differ
diff --git a/backend/proofs/scans/cmkawhyqe0007eg5or3z9drxk/be4c046b-1d3c-49b8-90e4-bed8632b0bb3/annotated.png b/backend/proofs/scans/cmkawhyqe0007eg5or3z9drxk/be4c046b-1d3c-49b8-90e4-bed8632b0bb3/annotated.png
new file mode 100644
index 0000000..57cbfaf
Binary files /dev/null and b/backend/proofs/scans/cmkawhyqe0007eg5or3z9drxk/be4c046b-1d3c-49b8-90e4-bed8632b0bb3/annotated.png differ
diff --git a/backend/proofs/scans/cmkawhyqe0007eg5or3z9drxk/be4c046b-1d3c-49b8-90e4-bed8632b0bb3/before.png b/backend/proofs/scans/cmkawhyqe0007eg5or3z9drxk/be4c046b-1d3c-49b8-90e4-bed8632b0bb3/before.png
new file mode 100644
index 0000000..4f084a4
Binary files /dev/null and b/backend/proofs/scans/cmkawhyqe0007eg5or3z9drxk/be4c046b-1d3c-49b8-90e4-bed8632b0bb3/before.png differ
diff --git a/backend/proofs/scans/cmkawhyqe0007eg5or3z9drxk/be4c046b-1d3c-49b8-90e4-bed8632b0bb3/page.html b/backend/proofs/scans/cmkawhyqe0007eg5or3z9drxk/be4c046b-1d3c-49b8-90e4-bed8632b0bb3/page.html
new file mode 100644
index 0000000..0acd308
--- /dev/null
+++ b/backend/proofs/scans/cmkawhyqe0007eg5or3z9drxk/be4c046b-1d3c-49b8-90e4-bed8632b0bb3/page.html
@@ -0,0 +1,531 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
Language has been changed to English
+
Force page reload
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkawhyqx0009eg5owa3jqzk5/6309495c-04ba-47c0-aca4-872411921b92/after.png b/backend/proofs/scans/cmkawhyqx0009eg5owa3jqzk5/6309495c-04ba-47c0-aca4-872411921b92/after.png
new file mode 100644
index 0000000..9b26f3c
Binary files /dev/null and b/backend/proofs/scans/cmkawhyqx0009eg5owa3jqzk5/6309495c-04ba-47c0-aca4-872411921b92/after.png differ
diff --git a/backend/proofs/scans/cmkawhyqx0009eg5owa3jqzk5/6309495c-04ba-47c0-aca4-872411921b92/annotated.png b/backend/proofs/scans/cmkawhyqx0009eg5owa3jqzk5/6309495c-04ba-47c0-aca4-872411921b92/annotated.png
new file mode 100644
index 0000000..1129aac
Binary files /dev/null and b/backend/proofs/scans/cmkawhyqx0009eg5owa3jqzk5/6309495c-04ba-47c0-aca4-872411921b92/annotated.png differ
diff --git a/backend/proofs/scans/cmkawhyqx0009eg5owa3jqzk5/6309495c-04ba-47c0-aca4-872411921b92/before.png b/backend/proofs/scans/cmkawhyqx0009eg5owa3jqzk5/6309495c-04ba-47c0-aca4-872411921b92/before.png
new file mode 100644
index 0000000..0bfee4a
Binary files /dev/null and b/backend/proofs/scans/cmkawhyqx0009eg5owa3jqzk5/6309495c-04ba-47c0-aca4-872411921b92/before.png differ
diff --git a/backend/proofs/scans/cmkawhyqx0009eg5owa3jqzk5/6309495c-04ba-47c0-aca4-872411921b92/page.html b/backend/proofs/scans/cmkawhyqx0009eg5owa3jqzk5/6309495c-04ba-47c0-aca4-872411921b92/page.html
new file mode 100644
index 0000000..31a699d
--- /dev/null
+++ b/backend/proofs/scans/cmkawhyqx0009eg5owa3jqzk5/6309495c-04ba-47c0-aca4-872411921b92/page.html
@@ -0,0 +1,528 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkawhyre000beg5otitweoiq/ae7ca2b1-51f2-40c2-984a-c61307d6ba85/after.png b/backend/proofs/scans/cmkawhyre000beg5otitweoiq/ae7ca2b1-51f2-40c2-984a-c61307d6ba85/after.png
new file mode 100644
index 0000000..4b792ec
Binary files /dev/null and b/backend/proofs/scans/cmkawhyre000beg5otitweoiq/ae7ca2b1-51f2-40c2-984a-c61307d6ba85/after.png differ
diff --git a/backend/proofs/scans/cmkawhyre000beg5otitweoiq/ae7ca2b1-51f2-40c2-984a-c61307d6ba85/annotated.png b/backend/proofs/scans/cmkawhyre000beg5otitweoiq/ae7ca2b1-51f2-40c2-984a-c61307d6ba85/annotated.png
new file mode 100644
index 0000000..9be70c7
Binary files /dev/null and b/backend/proofs/scans/cmkawhyre000beg5otitweoiq/ae7ca2b1-51f2-40c2-984a-c61307d6ba85/annotated.png differ
diff --git a/backend/proofs/scans/cmkawhyre000beg5otitweoiq/ae7ca2b1-51f2-40c2-984a-c61307d6ba85/before.png b/backend/proofs/scans/cmkawhyre000beg5otitweoiq/ae7ca2b1-51f2-40c2-984a-c61307d6ba85/before.png
new file mode 100644
index 0000000..a8cd99d
Binary files /dev/null and b/backend/proofs/scans/cmkawhyre000beg5otitweoiq/ae7ca2b1-51f2-40c2-984a-c61307d6ba85/before.png differ
diff --git a/backend/proofs/scans/cmkawhyre000beg5otitweoiq/ae7ca2b1-51f2-40c2-984a-c61307d6ba85/page.html b/backend/proofs/scans/cmkawhyre000beg5otitweoiq/ae7ca2b1-51f2-40c2-984a-c61307d6ba85/page.html
new file mode 100644
index 0000000..a730de6
--- /dev/null
+++ b/backend/proofs/scans/cmkawhyre000beg5otitweoiq/ae7ca2b1-51f2-40c2-984a-c61307d6ba85/page.html
@@ -0,0 +1,528 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkaxbsxl0001egg0ehuvik7d/f813924b-f760-401f-82d8-2e965b6b807d/after.png b/backend/proofs/scans/cmkaxbsxl0001egg0ehuvik7d/f813924b-f760-401f-82d8-2e965b6b807d/after.png
new file mode 100644
index 0000000..f8e0505
Binary files /dev/null and b/backend/proofs/scans/cmkaxbsxl0001egg0ehuvik7d/f813924b-f760-401f-82d8-2e965b6b807d/after.png differ
diff --git a/backend/proofs/scans/cmkaxbsxl0001egg0ehuvik7d/f813924b-f760-401f-82d8-2e965b6b807d/annotated.png b/backend/proofs/scans/cmkaxbsxl0001egg0ehuvik7d/f813924b-f760-401f-82d8-2e965b6b807d/annotated.png
new file mode 100644
index 0000000..e6cdab7
Binary files /dev/null and b/backend/proofs/scans/cmkaxbsxl0001egg0ehuvik7d/f813924b-f760-401f-82d8-2e965b6b807d/annotated.png differ
diff --git a/backend/proofs/scans/cmkaxbsxl0001egg0ehuvik7d/f813924b-f760-401f-82d8-2e965b6b807d/before.png b/backend/proofs/scans/cmkaxbsxl0001egg0ehuvik7d/f813924b-f760-401f-82d8-2e965b6b807d/before.png
new file mode 100644
index 0000000..acf9454
Binary files /dev/null and b/backend/proofs/scans/cmkaxbsxl0001egg0ehuvik7d/f813924b-f760-401f-82d8-2e965b6b807d/before.png differ
diff --git a/backend/proofs/scans/cmkaxbsxl0001egg0ehuvik7d/f813924b-f760-401f-82d8-2e965b6b807d/page.html b/backend/proofs/scans/cmkaxbsxl0001egg0ehuvik7d/f813924b-f760-401f-82d8-2e965b6b807d/page.html
new file mode 100644
index 0000000..ff36262
--- /dev/null
+++ b/backend/proofs/scans/cmkaxbsxl0001egg0ehuvik7d/f813924b-f760-401f-82d8-2e965b6b807d/page.html
@@ -0,0 +1,528 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 0
+
+
+
Open side menu
Choose language
Language has been changed to English
+
Force page reload
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkaxbsyc0003egg0zi9f50cv/9c4c0eb4-e4db-48be-b63d-95f0fca9f5c5/after.png b/backend/proofs/scans/cmkaxbsyc0003egg0zi9f50cv/9c4c0eb4-e4db-48be-b63d-95f0fca9f5c5/after.png
new file mode 100644
index 0000000..19ed8c6
Binary files /dev/null and b/backend/proofs/scans/cmkaxbsyc0003egg0zi9f50cv/9c4c0eb4-e4db-48be-b63d-95f0fca9f5c5/after.png differ
diff --git a/backend/proofs/scans/cmkaxbsyc0003egg0zi9f50cv/9c4c0eb4-e4db-48be-b63d-95f0fca9f5c5/annotated.png b/backend/proofs/scans/cmkaxbsyc0003egg0zi9f50cv/9c4c0eb4-e4db-48be-b63d-95f0fca9f5c5/annotated.png
new file mode 100644
index 0000000..cc7ad1d
Binary files /dev/null and b/backend/proofs/scans/cmkaxbsyc0003egg0zi9f50cv/9c4c0eb4-e4db-48be-b63d-95f0fca9f5c5/annotated.png differ
diff --git a/backend/proofs/scans/cmkaxbsyc0003egg0zi9f50cv/9c4c0eb4-e4db-48be-b63d-95f0fca9f5c5/before.png b/backend/proofs/scans/cmkaxbsyc0003egg0zi9f50cv/9c4c0eb4-e4db-48be-b63d-95f0fca9f5c5/before.png
new file mode 100644
index 0000000..020066c
Binary files /dev/null and b/backend/proofs/scans/cmkaxbsyc0003egg0zi9f50cv/9c4c0eb4-e4db-48be-b63d-95f0fca9f5c5/before.png differ
diff --git a/backend/proofs/scans/cmkaxbsyc0003egg0zi9f50cv/9c4c0eb4-e4db-48be-b63d-95f0fca9f5c5/page.html b/backend/proofs/scans/cmkaxbsyc0003egg0zi9f50cv/9c4c0eb4-e4db-48be-b63d-95f0fca9f5c5/page.html
new file mode 100644
index 0000000..1d779a7
--- /dev/null
+++ b/backend/proofs/scans/cmkaxbsyc0003egg0zi9f50cv/9c4c0eb4-e4db-48be-b63d-95f0fca9f5c5/page.html
@@ -0,0 +1,538 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
+
🐉 DragonSploit - Vulnerability Confirmed
+
Auth Bypass via SQL Injection
+
+Payload: ' OR 1=1 --
+
+Result: Logout button found - user is authenticated
+
+ 2026-01-12T09:00:42.405Z
+
+
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkaxbsyc0003egg0zi9f50cv/f5512c29-f5b7-450c-a2f2-e72b92d50fdf/before.png b/backend/proofs/scans/cmkaxbsyc0003egg0zi9f50cv/f5512c29-f5b7-450c-a2f2-e72b92d50fdf/before.png
new file mode 100644
index 0000000..8d0d90a
Binary files /dev/null and b/backend/proofs/scans/cmkaxbsyc0003egg0zi9f50cv/f5512c29-f5b7-450c-a2f2-e72b92d50fdf/before.png differ
diff --git a/backend/proofs/scans/cmkaxbsyx0005egg00222u564/34aea10c-9cb1-4252-bb5d-2ac54335a552/after.png b/backend/proofs/scans/cmkaxbsyx0005egg00222u564/34aea10c-9cb1-4252-bb5d-2ac54335a552/after.png
new file mode 100644
index 0000000..2357ee4
Binary files /dev/null and b/backend/proofs/scans/cmkaxbsyx0005egg00222u564/34aea10c-9cb1-4252-bb5d-2ac54335a552/after.png differ
diff --git a/backend/proofs/scans/cmkaxbsyx0005egg00222u564/34aea10c-9cb1-4252-bb5d-2ac54335a552/annotated.png b/backend/proofs/scans/cmkaxbsyx0005egg00222u564/34aea10c-9cb1-4252-bb5d-2ac54335a552/annotated.png
new file mode 100644
index 0000000..ece82c0
Binary files /dev/null and b/backend/proofs/scans/cmkaxbsyx0005egg00222u564/34aea10c-9cb1-4252-bb5d-2ac54335a552/annotated.png differ
diff --git a/backend/proofs/scans/cmkaxbsyx0005egg00222u564/34aea10c-9cb1-4252-bb5d-2ac54335a552/before.png b/backend/proofs/scans/cmkaxbsyx0005egg00222u564/34aea10c-9cb1-4252-bb5d-2ac54335a552/before.png
new file mode 100644
index 0000000..abb78d0
Binary files /dev/null and b/backend/proofs/scans/cmkaxbsyx0005egg00222u564/34aea10c-9cb1-4252-bb5d-2ac54335a552/before.png differ
diff --git a/backend/proofs/scans/cmkaxbsyx0005egg00222u564/34aea10c-9cb1-4252-bb5d-2ac54335a552/page.html b/backend/proofs/scans/cmkaxbsyx0005egg00222u564/34aea10c-9cb1-4252-bb5d-2ac54335a552/page.html
new file mode 100644
index 0000000..fc22121
--- /dev/null
+++ b/backend/proofs/scans/cmkaxbsyx0005egg00222u564/34aea10c-9cb1-4252-bb5d-2ac54335a552/page.html
@@ -0,0 +1,538 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
+
🐉 DragonSploit - Vulnerability Confirmed
+
Auth Bypass via SQL Injection
+
+Payload: ' OR 1=1 --
+
+Result: Logout button found - user is authenticated
+
+ 2026-01-12T09:00:29.118Z
+
+
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkaxbsyx0005egg00222u564/4a749b55-3cbf-413f-8e28-01d4aad5d6bb/before.png b/backend/proofs/scans/cmkaxbsyx0005egg00222u564/4a749b55-3cbf-413f-8e28-01d4aad5d6bb/before.png
new file mode 100644
index 0000000..4b44cb2
Binary files /dev/null and b/backend/proofs/scans/cmkaxbsyx0005egg00222u564/4a749b55-3cbf-413f-8e28-01d4aad5d6bb/before.png differ
diff --git a/backend/proofs/scans/cmkaxbt1h0007egg0q94sh98s/667b89a3-2813-418a-a6cb-c6659ee9438f/after.png b/backend/proofs/scans/cmkaxbt1h0007egg0q94sh98s/667b89a3-2813-418a-a6cb-c6659ee9438f/after.png
new file mode 100644
index 0000000..19ed8c6
Binary files /dev/null and b/backend/proofs/scans/cmkaxbt1h0007egg0q94sh98s/667b89a3-2813-418a-a6cb-c6659ee9438f/after.png differ
diff --git a/backend/proofs/scans/cmkaxbt1h0007egg0q94sh98s/667b89a3-2813-418a-a6cb-c6659ee9438f/annotated.png b/backend/proofs/scans/cmkaxbt1h0007egg0q94sh98s/667b89a3-2813-418a-a6cb-c6659ee9438f/annotated.png
new file mode 100644
index 0000000..0469238
Binary files /dev/null and b/backend/proofs/scans/cmkaxbt1h0007egg0q94sh98s/667b89a3-2813-418a-a6cb-c6659ee9438f/annotated.png differ
diff --git a/backend/proofs/scans/cmkaxbt1h0007egg0q94sh98s/667b89a3-2813-418a-a6cb-c6659ee9438f/before.png b/backend/proofs/scans/cmkaxbt1h0007egg0q94sh98s/667b89a3-2813-418a-a6cb-c6659ee9438f/before.png
new file mode 100644
index 0000000..e5c759e
Binary files /dev/null and b/backend/proofs/scans/cmkaxbt1h0007egg0q94sh98s/667b89a3-2813-418a-a6cb-c6659ee9438f/before.png differ
diff --git a/backend/proofs/scans/cmkaxbt1h0007egg0q94sh98s/667b89a3-2813-418a-a6cb-c6659ee9438f/page.html b/backend/proofs/scans/cmkaxbt1h0007egg0q94sh98s/667b89a3-2813-418a-a6cb-c6659ee9438f/page.html
new file mode 100644
index 0000000..868de90
--- /dev/null
+++ b/backend/proofs/scans/cmkaxbt1h0007egg0q94sh98s/667b89a3-2813-418a-a6cb-c6659ee9438f/page.html
@@ -0,0 +1,538 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
+
🐉 DragonSploit - Vulnerability Confirmed
+
Auth Bypass via SQL Injection
+
+Payload: ' OR 1=1 --
+
+Result: Logout button found - user is authenticated
+
+ 2026-01-12T09:00:56.279Z
+
+
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkaxbt300009egg0b8bx5omm/a5154383-bebb-485c-9e7b-d03f91beb579/after.png b/backend/proofs/scans/cmkaxbt300009egg0b8bx5omm/a5154383-bebb-485c-9e7b-d03f91beb579/after.png
new file mode 100644
index 0000000..3f4a3af
Binary files /dev/null and b/backend/proofs/scans/cmkaxbt300009egg0b8bx5omm/a5154383-bebb-485c-9e7b-d03f91beb579/after.png differ
diff --git a/backend/proofs/scans/cmkaxbt300009egg0b8bx5omm/a5154383-bebb-485c-9e7b-d03f91beb579/annotated.png b/backend/proofs/scans/cmkaxbt300009egg0b8bx5omm/a5154383-bebb-485c-9e7b-d03f91beb579/annotated.png
new file mode 100644
index 0000000..5120187
Binary files /dev/null and b/backend/proofs/scans/cmkaxbt300009egg0b8bx5omm/a5154383-bebb-485c-9e7b-d03f91beb579/annotated.png differ
diff --git a/backend/proofs/scans/cmkaxbt300009egg0b8bx5omm/a5154383-bebb-485c-9e7b-d03f91beb579/before.png b/backend/proofs/scans/cmkaxbt300009egg0b8bx5omm/a5154383-bebb-485c-9e7b-d03f91beb579/before.png
new file mode 100644
index 0000000..4c866bb
Binary files /dev/null and b/backend/proofs/scans/cmkaxbt300009egg0b8bx5omm/a5154383-bebb-485c-9e7b-d03f91beb579/before.png differ
diff --git a/backend/proofs/scans/cmkaxbt300009egg0b8bx5omm/a5154383-bebb-485c-9e7b-d03f91beb579/page.html b/backend/proofs/scans/cmkaxbt300009egg0b8bx5omm/a5154383-bebb-485c-9e7b-d03f91beb579/page.html
new file mode 100644
index 0000000..6138432
--- /dev/null
+++ b/backend/proofs/scans/cmkaxbt300009egg0b8bx5omm/a5154383-bebb-485c-9e7b-d03f91beb579/page.html
@@ -0,0 +1,538 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
+
🐉 DragonSploit - Vulnerability Confirmed
+
Auth Bypass via SQL Injection
+
+Payload: ' OR 1=1 --
+
+Result: Logout button found - user is authenticated
+
+ 2026-01-12T09:01:07.300Z
+
+
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkaxbt3w000begg0cmb9ez3o/90368926-806d-41eb-8c80-ee2f216a0f8f/after.png b/backend/proofs/scans/cmkaxbt3w000begg0cmb9ez3o/90368926-806d-41eb-8c80-ee2f216a0f8f/after.png
new file mode 100644
index 0000000..b9fe3e0
Binary files /dev/null and b/backend/proofs/scans/cmkaxbt3w000begg0cmb9ez3o/90368926-806d-41eb-8c80-ee2f216a0f8f/after.png differ
diff --git a/backend/proofs/scans/cmkaxbt3w000begg0cmb9ez3o/90368926-806d-41eb-8c80-ee2f216a0f8f/annotated.png b/backend/proofs/scans/cmkaxbt3w000begg0cmb9ez3o/90368926-806d-41eb-8c80-ee2f216a0f8f/annotated.png
new file mode 100644
index 0000000..3845751
Binary files /dev/null and b/backend/proofs/scans/cmkaxbt3w000begg0cmb9ez3o/90368926-806d-41eb-8c80-ee2f216a0f8f/annotated.png differ
diff --git a/backend/proofs/scans/cmkaxbt3w000begg0cmb9ez3o/90368926-806d-41eb-8c80-ee2f216a0f8f/before.png b/backend/proofs/scans/cmkaxbt3w000begg0cmb9ez3o/90368926-806d-41eb-8c80-ee2f216a0f8f/before.png
new file mode 100644
index 0000000..020066c
Binary files /dev/null and b/backend/proofs/scans/cmkaxbt3w000begg0cmb9ez3o/90368926-806d-41eb-8c80-ee2f216a0f8f/before.png differ
diff --git a/backend/proofs/scans/cmkaxbt3w000begg0cmb9ez3o/90368926-806d-41eb-8c80-ee2f216a0f8f/page.html b/backend/proofs/scans/cmkaxbt3w000begg0cmb9ez3o/90368926-806d-41eb-8c80-ee2f216a0f8f/page.html
new file mode 100644
index 0000000..7fe6781
--- /dev/null
+++ b/backend/proofs/scans/cmkaxbt3w000begg0cmb9ez3o/90368926-806d-41eb-8c80-ee2f216a0f8f/page.html
@@ -0,0 +1,539 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
+
🐉 DragonSploit - Vulnerability Confirmed
+
Auth Bypass via SQL Injection
+
+Payload: ' OR 1=1 --
+
+Result: Logout button found - user is authenticated
+
+ 2026-01-12T09:01:19.706Z
+
+
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkaxfm3w0001eg44pgot875v/6e48ca47-5097-4727-8e2a-a22168fb6b15/after.png b/backend/proofs/scans/cmkaxfm3w0001eg44pgot875v/6e48ca47-5097-4727-8e2a-a22168fb6b15/after.png
new file mode 100644
index 0000000..0a85767
Binary files /dev/null and b/backend/proofs/scans/cmkaxfm3w0001eg44pgot875v/6e48ca47-5097-4727-8e2a-a22168fb6b15/after.png differ
diff --git a/backend/proofs/scans/cmkaxfm3w0001eg44pgot875v/6e48ca47-5097-4727-8e2a-a22168fb6b15/annotated.png b/backend/proofs/scans/cmkaxfm3w0001eg44pgot875v/6e48ca47-5097-4727-8e2a-a22168fb6b15/annotated.png
new file mode 100644
index 0000000..5c6e1ac
Binary files /dev/null and b/backend/proofs/scans/cmkaxfm3w0001eg44pgot875v/6e48ca47-5097-4727-8e2a-a22168fb6b15/annotated.png differ
diff --git a/backend/proofs/scans/cmkaxfm3w0001eg44pgot875v/6e48ca47-5097-4727-8e2a-a22168fb6b15/before.png b/backend/proofs/scans/cmkaxfm3w0001eg44pgot875v/6e48ca47-5097-4727-8e2a-a22168fb6b15/before.png
new file mode 100644
index 0000000..ecc07c8
Binary files /dev/null and b/backend/proofs/scans/cmkaxfm3w0001eg44pgot875v/6e48ca47-5097-4727-8e2a-a22168fb6b15/before.png differ
diff --git a/backend/proofs/scans/cmkaxfm3w0001eg44pgot875v/6e48ca47-5097-4727-8e2a-a22168fb6b15/page.html b/backend/proofs/scans/cmkaxfm3w0001eg44pgot875v/6e48ca47-5097-4727-8e2a-a22168fb6b15/page.html
new file mode 100644
index 0000000..36e6ffe
--- /dev/null
+++ b/backend/proofs/scans/cmkaxfm3w0001eg44pgot875v/6e48ca47-5097-4727-8e2a-a22168fb6b15/page.html
@@ -0,0 +1,539 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
+
🐉 DragonSploit - Vulnerability Confirmed
+
Auth Bypass via SQL Injection
+
+Payload: ' OR 1=1 --
+
+Result: Logout button found - user is authenticated
+
+ 2026-01-12T09:01:31.847Z
+
+
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkaxfm4s0003eg446sfq0chd/abdcd429-0321-4b9a-9404-8c306b65eab1/after.png b/backend/proofs/scans/cmkaxfm4s0003eg446sfq0chd/abdcd429-0321-4b9a-9404-8c306b65eab1/after.png
new file mode 100644
index 0000000..19ed8c6
Binary files /dev/null and b/backend/proofs/scans/cmkaxfm4s0003eg446sfq0chd/abdcd429-0321-4b9a-9404-8c306b65eab1/after.png differ
diff --git a/backend/proofs/scans/cmkaxfm4s0003eg446sfq0chd/abdcd429-0321-4b9a-9404-8c306b65eab1/annotated.png b/backend/proofs/scans/cmkaxfm4s0003eg446sfq0chd/abdcd429-0321-4b9a-9404-8c306b65eab1/annotated.png
new file mode 100644
index 0000000..ab0539d
Binary files /dev/null and b/backend/proofs/scans/cmkaxfm4s0003eg446sfq0chd/abdcd429-0321-4b9a-9404-8c306b65eab1/annotated.png differ
diff --git a/backend/proofs/scans/cmkaxfm4s0003eg446sfq0chd/abdcd429-0321-4b9a-9404-8c306b65eab1/before.png b/backend/proofs/scans/cmkaxfm4s0003eg446sfq0chd/abdcd429-0321-4b9a-9404-8c306b65eab1/before.png
new file mode 100644
index 0000000..4b44cb2
Binary files /dev/null and b/backend/proofs/scans/cmkaxfm4s0003eg446sfq0chd/abdcd429-0321-4b9a-9404-8c306b65eab1/before.png differ
diff --git a/backend/proofs/scans/cmkaxfm4s0003eg446sfq0chd/abdcd429-0321-4b9a-9404-8c306b65eab1/page.html b/backend/proofs/scans/cmkaxfm4s0003eg446sfq0chd/abdcd429-0321-4b9a-9404-8c306b65eab1/page.html
new file mode 100644
index 0000000..63e0c46
--- /dev/null
+++ b/backend/proofs/scans/cmkaxfm4s0003eg446sfq0chd/abdcd429-0321-4b9a-9404-8c306b65eab1/page.html
@@ -0,0 +1,538 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
+
🐉 DragonSploit - Vulnerability Confirmed
+
Auth Bypass via SQL Injection
+
+Payload: ' OR 1=1 --
+
+Result: Logout button found - user is authenticated
+
+ 2026-01-12T09:01:49.215Z
+
+
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkaxfm5a0005eg449iu5x5y9/32cb33ad-4cdd-40cd-88ab-cd4583741346/after.png b/backend/proofs/scans/cmkaxfm5a0005eg449iu5x5y9/32cb33ad-4cdd-40cd-88ab-cd4583741346/after.png
new file mode 100644
index 0000000..7a05535
Binary files /dev/null and b/backend/proofs/scans/cmkaxfm5a0005eg449iu5x5y9/32cb33ad-4cdd-40cd-88ab-cd4583741346/after.png differ
diff --git a/backend/proofs/scans/cmkaxfm5a0005eg449iu5x5y9/32cb33ad-4cdd-40cd-88ab-cd4583741346/annotated.png b/backend/proofs/scans/cmkaxfm5a0005eg449iu5x5y9/32cb33ad-4cdd-40cd-88ab-cd4583741346/annotated.png
new file mode 100644
index 0000000..59c559c
Binary files /dev/null and b/backend/proofs/scans/cmkaxfm5a0005eg449iu5x5y9/32cb33ad-4cdd-40cd-88ab-cd4583741346/annotated.png differ
diff --git a/backend/proofs/scans/cmkaxfm5a0005eg449iu5x5y9/32cb33ad-4cdd-40cd-88ab-cd4583741346/before.png b/backend/proofs/scans/cmkaxfm5a0005eg449iu5x5y9/32cb33ad-4cdd-40cd-88ab-cd4583741346/before.png
new file mode 100644
index 0000000..4b44cb2
Binary files /dev/null and b/backend/proofs/scans/cmkaxfm5a0005eg449iu5x5y9/32cb33ad-4cdd-40cd-88ab-cd4583741346/before.png differ
diff --git a/backend/proofs/scans/cmkaxfm5a0005eg449iu5x5y9/32cb33ad-4cdd-40cd-88ab-cd4583741346/page.html b/backend/proofs/scans/cmkaxfm5a0005eg449iu5x5y9/32cb33ad-4cdd-40cd-88ab-cd4583741346/page.html
new file mode 100644
index 0000000..737bae8
--- /dev/null
+++ b/backend/proofs/scans/cmkaxfm5a0005eg449iu5x5y9/32cb33ad-4cdd-40cd-88ab-cd4583741346/page.html
@@ -0,0 +1,538 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
+
🐉 DragonSploit - Vulnerability Confirmed
+
Auth Bypass via SQL Injection
+
+Payload: ' OR 1=1 --
+
+Result: Logout button found - user is authenticated
+
+ 2026-01-12T09:02:07.981Z
+
+
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkaxfm5l0007eg44a3lweg4h/8f53d716-6708-4e75-8199-7f9ae364e816/after.png b/backend/proofs/scans/cmkaxfm5l0007eg44a3lweg4h/8f53d716-6708-4e75-8199-7f9ae364e816/after.png
new file mode 100644
index 0000000..3ccc8dd
Binary files /dev/null and b/backend/proofs/scans/cmkaxfm5l0007eg44a3lweg4h/8f53d716-6708-4e75-8199-7f9ae364e816/after.png differ
diff --git a/backend/proofs/scans/cmkaxfm5l0007eg44a3lweg4h/8f53d716-6708-4e75-8199-7f9ae364e816/annotated.png b/backend/proofs/scans/cmkaxfm5l0007eg44a3lweg4h/8f53d716-6708-4e75-8199-7f9ae364e816/annotated.png
new file mode 100644
index 0000000..286fadc
Binary files /dev/null and b/backend/proofs/scans/cmkaxfm5l0007eg44a3lweg4h/8f53d716-6708-4e75-8199-7f9ae364e816/annotated.png differ
diff --git a/backend/proofs/scans/cmkaxfm5l0007eg44a3lweg4h/8f53d716-6708-4e75-8199-7f9ae364e816/before.png b/backend/proofs/scans/cmkaxfm5l0007eg44a3lweg4h/8f53d716-6708-4e75-8199-7f9ae364e816/before.png
new file mode 100644
index 0000000..4a724c4
Binary files /dev/null and b/backend/proofs/scans/cmkaxfm5l0007eg44a3lweg4h/8f53d716-6708-4e75-8199-7f9ae364e816/before.png differ
diff --git a/backend/proofs/scans/cmkaxfm5l0007eg44a3lweg4h/8f53d716-6708-4e75-8199-7f9ae364e816/page.html b/backend/proofs/scans/cmkaxfm5l0007eg44a3lweg4h/8f53d716-6708-4e75-8199-7f9ae364e816/page.html
new file mode 100644
index 0000000..8610f8a
--- /dev/null
+++ b/backend/proofs/scans/cmkaxfm5l0007eg44a3lweg4h/8f53d716-6708-4e75-8199-7f9ae364e816/page.html
@@ -0,0 +1,538 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
+
🐉 DragonSploit - Vulnerability Confirmed
+
Auth Bypass via SQL Injection
+
+Payload: ' OR 1=1 --
+
+Result: Logout button found - user is authenticated
+
+ 2026-01-12T09:02:23.370Z
+
+
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkaxfm6g0009eg44uty22f6u/32ac3852-b1cb-47a9-a88f-133d03407508/after.png b/backend/proofs/scans/cmkaxfm6g0009eg44uty22f6u/32ac3852-b1cb-47a9-a88f-133d03407508/after.png
new file mode 100644
index 0000000..7c22acf
Binary files /dev/null and b/backend/proofs/scans/cmkaxfm6g0009eg44uty22f6u/32ac3852-b1cb-47a9-a88f-133d03407508/after.png differ
diff --git a/backend/proofs/scans/cmkaxfm6g0009eg44uty22f6u/32ac3852-b1cb-47a9-a88f-133d03407508/before.png b/backend/proofs/scans/cmkaxfm6g0009eg44uty22f6u/32ac3852-b1cb-47a9-a88f-133d03407508/before.png
new file mode 100644
index 0000000..31f1beb
Binary files /dev/null and b/backend/proofs/scans/cmkaxfm6g0009eg44uty22f6u/32ac3852-b1cb-47a9-a88f-133d03407508/before.png differ
diff --git a/backend/proofs/scans/cmkaxfm6g0009eg44uty22f6u/75c2f59e-31e4-4504-bb5a-fc8e5c52e458/before.png b/backend/proofs/scans/cmkaxfm6g0009eg44uty22f6u/75c2f59e-31e4-4504-bb5a-fc8e5c52e458/before.png
new file mode 100644
index 0000000..4b44cb2
Binary files /dev/null and b/backend/proofs/scans/cmkaxfm6g0009eg44uty22f6u/75c2f59e-31e4-4504-bb5a-fc8e5c52e458/before.png differ
diff --git a/backend/proofs/scans/cmkaxfm6s000beg444kgcr66l/93bc2346-9cd1-49ee-8703-c6f9f1bde5f6/after.png b/backend/proofs/scans/cmkaxfm6s000beg444kgcr66l/93bc2346-9cd1-49ee-8703-c6f9f1bde5f6/after.png
new file mode 100644
index 0000000..6f72ea8
Binary files /dev/null and b/backend/proofs/scans/cmkaxfm6s000beg444kgcr66l/93bc2346-9cd1-49ee-8703-c6f9f1bde5f6/after.png differ
diff --git a/backend/proofs/scans/cmkaxfm6s000beg444kgcr66l/93bc2346-9cd1-49ee-8703-c6f9f1bde5f6/before.png b/backend/proofs/scans/cmkaxfm6s000beg444kgcr66l/93bc2346-9cd1-49ee-8703-c6f9f1bde5f6/before.png
new file mode 100644
index 0000000..cc34c81
Binary files /dev/null and b/backend/proofs/scans/cmkaxfm6s000beg444kgcr66l/93bc2346-9cd1-49ee-8703-c6f9f1bde5f6/before.png differ
diff --git a/backend/proofs/scans/cmkaxfm6s000beg444kgcr66l/9868fffd-a872-455a-9394-69e39d5b2b57/after.png b/backend/proofs/scans/cmkaxfm6s000beg444kgcr66l/9868fffd-a872-455a-9394-69e39d5b2b57/after.png
new file mode 100644
index 0000000..32b6ed1
Binary files /dev/null and b/backend/proofs/scans/cmkaxfm6s000beg444kgcr66l/9868fffd-a872-455a-9394-69e39d5b2b57/after.png differ
diff --git a/backend/proofs/scans/cmkaxfm6s000beg444kgcr66l/9868fffd-a872-455a-9394-69e39d5b2b57/before.png b/backend/proofs/scans/cmkaxfm6s000beg444kgcr66l/9868fffd-a872-455a-9394-69e39d5b2b57/before.png
new file mode 100644
index 0000000..ce00149
Binary files /dev/null and b/backend/proofs/scans/cmkaxfm6s000beg444kgcr66l/9868fffd-a872-455a-9394-69e39d5b2b57/before.png differ
diff --git a/backend/proofs/scans/cmkayjq1i0001eg58e6qnpvgs/3f689b1e-4024-41b6-a2bb-9c54be280ffd/after.png b/backend/proofs/scans/cmkayjq1i0001eg58e6qnpvgs/3f689b1e-4024-41b6-a2bb-9c54be280ffd/after.png
new file mode 100644
index 0000000..9b26f3c
Binary files /dev/null and b/backend/proofs/scans/cmkayjq1i0001eg58e6qnpvgs/3f689b1e-4024-41b6-a2bb-9c54be280ffd/after.png differ
diff --git a/backend/proofs/scans/cmkayjq1i0001eg58e6qnpvgs/3f689b1e-4024-41b6-a2bb-9c54be280ffd/before.png b/backend/proofs/scans/cmkayjq1i0001eg58e6qnpvgs/3f689b1e-4024-41b6-a2bb-9c54be280ffd/before.png
new file mode 100644
index 0000000..b00bd54
Binary files /dev/null and b/backend/proofs/scans/cmkayjq1i0001eg58e6qnpvgs/3f689b1e-4024-41b6-a2bb-9c54be280ffd/before.png differ
diff --git a/backend/proofs/scans/cmkayjq4d0003eg58urq5fgp6/2c950e6b-c66a-4501-8a4e-bf99a3f8ad93/after.png b/backend/proofs/scans/cmkayjq4d0003eg58urq5fgp6/2c950e6b-c66a-4501-8a4e-bf99a3f8ad93/after.png
new file mode 100644
index 0000000..19ed8c6
Binary files /dev/null and b/backend/proofs/scans/cmkayjq4d0003eg58urq5fgp6/2c950e6b-c66a-4501-8a4e-bf99a3f8ad93/after.png differ
diff --git a/backend/proofs/scans/cmkayjq4d0003eg58urq5fgp6/2c950e6b-c66a-4501-8a4e-bf99a3f8ad93/before.png b/backend/proofs/scans/cmkayjq4d0003eg58urq5fgp6/2c950e6b-c66a-4501-8a4e-bf99a3f8ad93/before.png
new file mode 100644
index 0000000..020066c
Binary files /dev/null and b/backend/proofs/scans/cmkayjq4d0003eg58urq5fgp6/2c950e6b-c66a-4501-8a4e-bf99a3f8ad93/before.png differ
diff --git a/backend/proofs/scans/cmkayqewe0001egf0lz6mou0k/716be774-a348-4b14-9746-1fa110e6319c/after.png b/backend/proofs/scans/cmkayqewe0001egf0lz6mou0k/716be774-a348-4b14-9746-1fa110e6319c/after.png
new file mode 100644
index 0000000..ecb0e49
Binary files /dev/null and b/backend/proofs/scans/cmkayqewe0001egf0lz6mou0k/716be774-a348-4b14-9746-1fa110e6319c/after.png differ
diff --git a/backend/proofs/scans/cmkayqewe0001egf0lz6mou0k/716be774-a348-4b14-9746-1fa110e6319c/before.png b/backend/proofs/scans/cmkayqewe0001egf0lz6mou0k/716be774-a348-4b14-9746-1fa110e6319c/before.png
new file mode 100644
index 0000000..e5c759e
Binary files /dev/null and b/backend/proofs/scans/cmkayqewe0001egf0lz6mou0k/716be774-a348-4b14-9746-1fa110e6319c/before.png differ
diff --git a/backend/proofs/scans/cmkayy9ad0001egfomk5qm5b2/8913b63f-2b12-4616-a9f4-3c7750f78d71/after.png b/backend/proofs/scans/cmkayy9ad0001egfomk5qm5b2/8913b63f-2b12-4616-a9f4-3c7750f78d71/after.png
new file mode 100644
index 0000000..47e4413
Binary files /dev/null and b/backend/proofs/scans/cmkayy9ad0001egfomk5qm5b2/8913b63f-2b12-4616-a9f4-3c7750f78d71/after.png differ
diff --git a/backend/proofs/scans/cmkayy9ad0001egfomk5qm5b2/8913b63f-2b12-4616-a9f4-3c7750f78d71/annotated.png b/backend/proofs/scans/cmkayy9ad0001egfomk5qm5b2/8913b63f-2b12-4616-a9f4-3c7750f78d71/annotated.png
new file mode 100644
index 0000000..b230f2a
Binary files /dev/null and b/backend/proofs/scans/cmkayy9ad0001egfomk5qm5b2/8913b63f-2b12-4616-a9f4-3c7750f78d71/annotated.png differ
diff --git a/backend/proofs/scans/cmkayy9ad0001egfomk5qm5b2/8913b63f-2b12-4616-a9f4-3c7750f78d71/before.png b/backend/proofs/scans/cmkayy9ad0001egfomk5qm5b2/8913b63f-2b12-4616-a9f4-3c7750f78d71/before.png
new file mode 100644
index 0000000..4b44cb2
Binary files /dev/null and b/backend/proofs/scans/cmkayy9ad0001egfomk5qm5b2/8913b63f-2b12-4616-a9f4-3c7750f78d71/before.png differ
diff --git a/backend/proofs/scans/cmkayy9ad0001egfomk5qm5b2/8913b63f-2b12-4616-a9f4-3c7750f78d71/page.html b/backend/proofs/scans/cmkayy9ad0001egfomk5qm5b2/8913b63f-2b12-4616-a9f4-3c7750f78d71/page.html
new file mode 100644
index 0000000..1f57897
--- /dev/null
+++ b/backend/proofs/scans/cmkayy9ad0001egfomk5qm5b2/8913b63f-2b12-4616-a9f4-3c7750f78d71/page.html
@@ -0,0 +1,539 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
+
🐉 DragonSploit - Vulnerability Confirmed
+
Auth Bypass via SQL Injection
+
+Payload: ' OR 1=1 --
+
+Result: Judge 1.5 High Confidence: URL Changed (+30), Login Form Gone (+40), Cookies Found (+10)
+
+ 2026-01-12T09:37:15.243Z
+
+
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkayy9b10003egfo3hx3yzxv/fc076c39-dd2a-45f4-ab1e-0aa08c16e18f/after.png b/backend/proofs/scans/cmkayy9b10003egfo3hx3yzxv/fc076c39-dd2a-45f4-ab1e-0aa08c16e18f/after.png
new file mode 100644
index 0000000..19ed8c6
Binary files /dev/null and b/backend/proofs/scans/cmkayy9b10003egfo3hx3yzxv/fc076c39-dd2a-45f4-ab1e-0aa08c16e18f/after.png differ
diff --git a/backend/proofs/scans/cmkayy9b10003egfo3hx3yzxv/fc076c39-dd2a-45f4-ab1e-0aa08c16e18f/annotated.png b/backend/proofs/scans/cmkayy9b10003egfo3hx3yzxv/fc076c39-dd2a-45f4-ab1e-0aa08c16e18f/annotated.png
new file mode 100644
index 0000000..3ac369d
Binary files /dev/null and b/backend/proofs/scans/cmkayy9b10003egfo3hx3yzxv/fc076c39-dd2a-45f4-ab1e-0aa08c16e18f/annotated.png differ
diff --git a/backend/proofs/scans/cmkayy9b10003egfo3hx3yzxv/fc076c39-dd2a-45f4-ab1e-0aa08c16e18f/before.png b/backend/proofs/scans/cmkayy9b10003egfo3hx3yzxv/fc076c39-dd2a-45f4-ab1e-0aa08c16e18f/before.png
new file mode 100644
index 0000000..e5c759e
Binary files /dev/null and b/backend/proofs/scans/cmkayy9b10003egfo3hx3yzxv/fc076c39-dd2a-45f4-ab1e-0aa08c16e18f/before.png differ
diff --git a/backend/proofs/scans/cmkayy9b10003egfo3hx3yzxv/fc076c39-dd2a-45f4-ab1e-0aa08c16e18f/page.html b/backend/proofs/scans/cmkayy9b10003egfo3hx3yzxv/fc076c39-dd2a-45f4-ab1e-0aa08c16e18f/page.html
new file mode 100644
index 0000000..0a58a8f
--- /dev/null
+++ b/backend/proofs/scans/cmkayy9b10003egfo3hx3yzxv/fc076c39-dd2a-45f4-ab1e-0aa08c16e18f/page.html
@@ -0,0 +1,538 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
+
🐉 DragonSploit - Vulnerability Confirmed
+
Auth Bypass via SQL Injection
+
+Payload: ' OR 1=1 --
+
+Result: Judge 1.5 High Confidence: URL Changed (+30), Login Form Gone (+40), Cookies Found (+10)
+
+ 2026-01-12T09:37:29.159Z
+
+
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkayy9bi0005egfop7gl6xzv/e2ed6407-568f-4075-8c97-8c3ef4dc1985/after.png b/backend/proofs/scans/cmkayy9bi0005egfop7gl6xzv/e2ed6407-568f-4075-8c97-8c3ef4dc1985/after.png
new file mode 100644
index 0000000..19ed8c6
Binary files /dev/null and b/backend/proofs/scans/cmkayy9bi0005egfop7gl6xzv/e2ed6407-568f-4075-8c97-8c3ef4dc1985/after.png differ
diff --git a/backend/proofs/scans/cmkayy9bi0005egfop7gl6xzv/e2ed6407-568f-4075-8c97-8c3ef4dc1985/annotated.png b/backend/proofs/scans/cmkayy9bi0005egfop7gl6xzv/e2ed6407-568f-4075-8c97-8c3ef4dc1985/annotated.png
new file mode 100644
index 0000000..6c938df
Binary files /dev/null and b/backend/proofs/scans/cmkayy9bi0005egfop7gl6xzv/e2ed6407-568f-4075-8c97-8c3ef4dc1985/annotated.png differ
diff --git a/backend/proofs/scans/cmkayy9bi0005egfop7gl6xzv/e2ed6407-568f-4075-8c97-8c3ef4dc1985/before.png b/backend/proofs/scans/cmkayy9bi0005egfop7gl6xzv/e2ed6407-568f-4075-8c97-8c3ef4dc1985/before.png
new file mode 100644
index 0000000..13f1a74
Binary files /dev/null and b/backend/proofs/scans/cmkayy9bi0005egfop7gl6xzv/e2ed6407-568f-4075-8c97-8c3ef4dc1985/before.png differ
diff --git a/backend/proofs/scans/cmkayy9bi0005egfop7gl6xzv/e2ed6407-568f-4075-8c97-8c3ef4dc1985/page.html b/backend/proofs/scans/cmkayy9bi0005egfop7gl6xzv/e2ed6407-568f-4075-8c97-8c3ef4dc1985/page.html
new file mode 100644
index 0000000..ae00fae
--- /dev/null
+++ b/backend/proofs/scans/cmkayy9bi0005egfop7gl6xzv/e2ed6407-568f-4075-8c97-8c3ef4dc1985/page.html
@@ -0,0 +1,538 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
+
🐉 DragonSploit - Vulnerability Confirmed
+
Auth Bypass via SQL Injection
+
+Payload: ' OR 1=1 --
+
+Result: Judge 1.5 High Confidence: URL Changed (+30), Login Form Gone (+40), Cookies Found (+10)
+
+ 2026-01-12T09:37:46.335Z
+
+
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkayy9bu0007egfoteqwpcht/58c2a22e-a763-4a92-8ee7-54102106e20f/after.png b/backend/proofs/scans/cmkayy9bu0007egfoteqwpcht/58c2a22e-a763-4a92-8ee7-54102106e20f/after.png
new file mode 100644
index 0000000..19ed8c6
Binary files /dev/null and b/backend/proofs/scans/cmkayy9bu0007egfoteqwpcht/58c2a22e-a763-4a92-8ee7-54102106e20f/after.png differ
diff --git a/backend/proofs/scans/cmkayy9bu0007egfoteqwpcht/58c2a22e-a763-4a92-8ee7-54102106e20f/annotated.png b/backend/proofs/scans/cmkayy9bu0007egfoteqwpcht/58c2a22e-a763-4a92-8ee7-54102106e20f/annotated.png
new file mode 100644
index 0000000..b000780
Binary files /dev/null and b/backend/proofs/scans/cmkayy9bu0007egfoteqwpcht/58c2a22e-a763-4a92-8ee7-54102106e20f/annotated.png differ
diff --git a/backend/proofs/scans/cmkayy9bu0007egfoteqwpcht/58c2a22e-a763-4a92-8ee7-54102106e20f/before.png b/backend/proofs/scans/cmkayy9bu0007egfoteqwpcht/58c2a22e-a763-4a92-8ee7-54102106e20f/before.png
new file mode 100644
index 0000000..92667b1
Binary files /dev/null and b/backend/proofs/scans/cmkayy9bu0007egfoteqwpcht/58c2a22e-a763-4a92-8ee7-54102106e20f/before.png differ
diff --git a/backend/proofs/scans/cmkayy9bu0007egfoteqwpcht/58c2a22e-a763-4a92-8ee7-54102106e20f/page.html b/backend/proofs/scans/cmkayy9bu0007egfoteqwpcht/58c2a22e-a763-4a92-8ee7-54102106e20f/page.html
new file mode 100644
index 0000000..620ae1f
--- /dev/null
+++ b/backend/proofs/scans/cmkayy9bu0007egfoteqwpcht/58c2a22e-a763-4a92-8ee7-54102106e20f/page.html
@@ -0,0 +1,538 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
+
🐉 DragonSploit - Vulnerability Confirmed
+
Auth Bypass via SQL Injection
+
+Payload: ' OR 1=1 --
+
+Result: Judge 1.5 High Confidence: URL Changed (+30), Login Form Gone (+40), Cookies Found (+10)
+
+ 2026-01-12T09:38:03.068Z
+
+
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkayy9co0009egfokbekbdfx/2df4580d-5e38-4b91-b0c4-f12945371b4b/after.png b/backend/proofs/scans/cmkayy9co0009egfokbekbdfx/2df4580d-5e38-4b91-b0c4-f12945371b4b/after.png
new file mode 100644
index 0000000..6fc3199
Binary files /dev/null and b/backend/proofs/scans/cmkayy9co0009egfokbekbdfx/2df4580d-5e38-4b91-b0c4-f12945371b4b/after.png differ
diff --git a/backend/proofs/scans/cmkayy9co0009egfokbekbdfx/2df4580d-5e38-4b91-b0c4-f12945371b4b/annotated.png b/backend/proofs/scans/cmkayy9co0009egfokbekbdfx/2df4580d-5e38-4b91-b0c4-f12945371b4b/annotated.png
new file mode 100644
index 0000000..33c6587
Binary files /dev/null and b/backend/proofs/scans/cmkayy9co0009egfokbekbdfx/2df4580d-5e38-4b91-b0c4-f12945371b4b/annotated.png differ
diff --git a/backend/proofs/scans/cmkayy9co0009egfokbekbdfx/2df4580d-5e38-4b91-b0c4-f12945371b4b/before.png b/backend/proofs/scans/cmkayy9co0009egfokbekbdfx/2df4580d-5e38-4b91-b0c4-f12945371b4b/before.png
new file mode 100644
index 0000000..544a515
Binary files /dev/null and b/backend/proofs/scans/cmkayy9co0009egfokbekbdfx/2df4580d-5e38-4b91-b0c4-f12945371b4b/before.png differ
diff --git a/backend/proofs/scans/cmkayy9co0009egfokbekbdfx/2df4580d-5e38-4b91-b0c4-f12945371b4b/page.html b/backend/proofs/scans/cmkayy9co0009egfokbekbdfx/2df4580d-5e38-4b91-b0c4-f12945371b4b/page.html
new file mode 100644
index 0000000..83a5032
--- /dev/null
+++ b/backend/proofs/scans/cmkayy9co0009egfokbekbdfx/2df4580d-5e38-4b91-b0c4-f12945371b4b/page.html
@@ -0,0 +1,538 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
+
🐉 DragonSploit - Vulnerability Confirmed
+
Auth Bypass via SQL Injection
+
+Payload: ' OR 1=1 --
+
+Result: Judge 1.5 High Confidence: URL Changed (+30), Login Form Gone (+40), Cookies Found (+10)
+
+ 2026-01-12T09:38:17.044Z
+
+
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkazlu840001ega84l004xha/85d4bc48-5460-4947-a738-2d03bbd472d0/after.png b/backend/proofs/scans/cmkazlu840001ega84l004xha/85d4bc48-5460-4947-a738-2d03bbd472d0/after.png
new file mode 100644
index 0000000..01647b1
Binary files /dev/null and b/backend/proofs/scans/cmkazlu840001ega84l004xha/85d4bc48-5460-4947-a738-2d03bbd472d0/after.png differ
diff --git a/backend/proofs/scans/cmkazlu840001ega84l004xha/85d4bc48-5460-4947-a738-2d03bbd472d0/annotated.png b/backend/proofs/scans/cmkazlu840001ega84l004xha/85d4bc48-5460-4947-a738-2d03bbd472d0/annotated.png
new file mode 100644
index 0000000..68c4bad
Binary files /dev/null and b/backend/proofs/scans/cmkazlu840001ega84l004xha/85d4bc48-5460-4947-a738-2d03bbd472d0/annotated.png differ
diff --git a/backend/proofs/scans/cmkazlu840001ega84l004xha/85d4bc48-5460-4947-a738-2d03bbd472d0/before.png b/backend/proofs/scans/cmkazlu840001ega84l004xha/85d4bc48-5460-4947-a738-2d03bbd472d0/before.png
new file mode 100644
index 0000000..020066c
Binary files /dev/null and b/backend/proofs/scans/cmkazlu840001ega84l004xha/85d4bc48-5460-4947-a738-2d03bbd472d0/before.png differ
diff --git a/backend/proofs/scans/cmkazlu840001ega84l004xha/85d4bc48-5460-4947-a738-2d03bbd472d0/page.html b/backend/proofs/scans/cmkazlu840001ega84l004xha/85d4bc48-5460-4947-a738-2d03bbd472d0/page.html
new file mode 100644
index 0000000..01504d5
--- /dev/null
+++ b/backend/proofs/scans/cmkazlu840001ega84l004xha/85d4bc48-5460-4947-a738-2d03bbd472d0/page.html
@@ -0,0 +1,538 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 6
+
+
+
Open side menu
Choose language
Click for more information
+
🐉 DragonSploit - Vulnerability Confirmed
+
Auth Bypass via SQL Injection
+
+Payload: ' OR 1=1 --
+
+Result: Judge 1.5 High Confidence: URL Changed (+30), Login Form Gone (+40), Cookies Found (+10)
+
+ 2026-01-12T09:55:34.769Z
+
+
\ No newline at end of file
diff --git a/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/18e187da573df290c282017b38135eea.webm b/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/18e187da573df290c282017b38135eea.webm
new file mode 100644
index 0000000..3b1c79d
Binary files /dev/null and b/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/18e187da573df290c282017b38135eea.webm differ
diff --git a/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/2ef2a9c5a1cdfab349db9fd2447890e0.webm b/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/2ef2a9c5a1cdfab349db9fd2447890e0.webm
new file mode 100644
index 0000000..7044162
Binary files /dev/null and b/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/2ef2a9c5a1cdfab349db9fd2447890e0.webm differ
diff --git a/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/4cd371bc6bacf74afd0793cc858d87b5.webm b/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/4cd371bc6bacf74afd0793cc858d87b5.webm
new file mode 100644
index 0000000..b783b9c
Binary files /dev/null and b/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/4cd371bc6bacf74afd0793cc858d87b5.webm differ
diff --git a/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/5c4419aff82f7e85843852bb40943631.webm b/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/5c4419aff82f7e85843852bb40943631.webm
new file mode 100644
index 0000000..53eca76
Binary files /dev/null and b/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/5c4419aff82f7e85843852bb40943631.webm differ
diff --git a/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/857a51a182aab4143b9909c0ea40146c.webm b/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/857a51a182aab4143b9909c0ea40146c.webm
new file mode 100644
index 0000000..f3be696
Binary files /dev/null and b/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/857a51a182aab4143b9909c0ea40146c.webm differ
diff --git a/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/daf02dc9cc3c94d5761de301b7b99d42.webm b/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/daf02dc9cc3c94d5761de301b7b99d42.webm
new file mode 100644
index 0000000..4a3924a
Binary files /dev/null and b/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/daf02dc9cc3c94d5761de301b7b99d42.webm differ
diff --git a/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/f13df82d393412fa28e4596a72a94fbe.webm b/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/f13df82d393412fa28e4596a72a94fbe.webm
new file mode 100644
index 0000000..58bb9c6
Binary files /dev/null and b/backend/proofs/scans/cmkdvcq910003egaclvh6y5gp/videos/f13df82d393412fa28e4596a72a94fbe.webm differ
diff --git a/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/2d4ffa3655d457c8167906a2d726a6ab.webm b/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/2d4ffa3655d457c8167906a2d726a6ab.webm
new file mode 100644
index 0000000..69604b8
Binary files /dev/null and b/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/2d4ffa3655d457c8167906a2d726a6ab.webm differ
diff --git a/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/32bd29958f76a6b884f9b2daa148b220.webm b/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/32bd29958f76a6b884f9b2daa148b220.webm
new file mode 100644
index 0000000..83c5905
Binary files /dev/null and b/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/32bd29958f76a6b884f9b2daa148b220.webm differ
diff --git a/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/7bf1f2b4cf0d6246a3b1650dcd362f78.webm b/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/7bf1f2b4cf0d6246a3b1650dcd362f78.webm
new file mode 100644
index 0000000..a0bc7b1
Binary files /dev/null and b/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/7bf1f2b4cf0d6246a3b1650dcd362f78.webm differ
diff --git a/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/9317bb8f35eda5a4a1fc2ec5872801c0.webm b/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/9317bb8f35eda5a4a1fc2ec5872801c0.webm
new file mode 100644
index 0000000..4f5991f
Binary files /dev/null and b/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/9317bb8f35eda5a4a1fc2ec5872801c0.webm differ
diff --git a/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/93c9f349ce51ddad398281a2b7f46290.webm b/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/93c9f349ce51ddad398281a2b7f46290.webm
new file mode 100644
index 0000000..99fb83b
Binary files /dev/null and b/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/93c9f349ce51ddad398281a2b7f46290.webm differ
diff --git a/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/9c66bafc6e6c3d09f1f35fac7733cb1e.webm b/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/9c66bafc6e6c3d09f1f35fac7733cb1e.webm
new file mode 100644
index 0000000..43c2e8f
Binary files /dev/null and b/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/9c66bafc6e6c3d09f1f35fac7733cb1e.webm differ
diff --git a/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/a74ac24d72dff1088c1e5bc7fcd4d079.webm b/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/a74ac24d72dff1088c1e5bc7fcd4d079.webm
new file mode 100644
index 0000000..2a3a521
Binary files /dev/null and b/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/a74ac24d72dff1088c1e5bc7fcd4d079.webm differ
diff --git a/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/af8a7012474dde4d54eab52f6f005c1a.webm b/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/af8a7012474dde4d54eab52f6f005c1a.webm
new file mode 100644
index 0000000..735ae6c
Binary files /dev/null and b/backend/proofs/scans/cmkdvylcs0001eghonwokqxdx/videos/af8a7012474dde4d54eab52f6f005c1a.webm differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/0a959d42-9378-4fbc-9af1-ad8a77fd9743/after.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/0a959d42-9378-4fbc-9af1-ad8a77fd9743/after.png
new file mode 100644
index 0000000..cf3ad96
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/0a959d42-9378-4fbc-9af1-ad8a77fd9743/after.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/0a959d42-9378-4fbc-9af1-ad8a77fd9743/before.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/0a959d42-9378-4fbc-9af1-ad8a77fd9743/before.png
new file mode 100644
index 0000000..fd933c7
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/0a959d42-9378-4fbc-9af1-ad8a77fd9743/before.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/0de22682-93cd-4397-a3e7-aecda8e035b7/after.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/0de22682-93cd-4397-a3e7-aecda8e035b7/after.png
new file mode 100644
index 0000000..c30cd49
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/0de22682-93cd-4397-a3e7-aecda8e035b7/after.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/0de22682-93cd-4397-a3e7-aecda8e035b7/before.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/0de22682-93cd-4397-a3e7-aecda8e035b7/before.png
new file mode 100644
index 0000000..a9374a4
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/0de22682-93cd-4397-a3e7-aecda8e035b7/before.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/11e48107-cb0c-42ac-a71a-dd8ace0a1b7f/after.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/11e48107-cb0c-42ac-a71a-dd8ace0a1b7f/after.png
new file mode 100644
index 0000000..4b40b8a
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/11e48107-cb0c-42ac-a71a-dd8ace0a1b7f/after.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/11e48107-cb0c-42ac-a71a-dd8ace0a1b7f/before.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/11e48107-cb0c-42ac-a71a-dd8ace0a1b7f/before.png
new file mode 100644
index 0000000..1632685
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/11e48107-cb0c-42ac-a71a-dd8ace0a1b7f/before.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/3f7dc3b0-17ce-4d0f-bed6-b843ce6998a2/after.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/3f7dc3b0-17ce-4d0f-bed6-b843ce6998a2/after.png
new file mode 100644
index 0000000..89bbdad
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/3f7dc3b0-17ce-4d0f-bed6-b843ce6998a2/after.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/3f7dc3b0-17ce-4d0f-bed6-b843ce6998a2/before.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/3f7dc3b0-17ce-4d0f-bed6-b843ce6998a2/before.png
new file mode 100644
index 0000000..7dc4693
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/3f7dc3b0-17ce-4d0f-bed6-b843ce6998a2/before.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/47c18efc-adc0-45a4-ab55-d1ea39a76b91/after.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/47c18efc-adc0-45a4-ab55-d1ea39a76b91/after.png
new file mode 100644
index 0000000..5037302
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/47c18efc-adc0-45a4-ab55-d1ea39a76b91/after.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/47c18efc-adc0-45a4-ab55-d1ea39a76b91/before.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/47c18efc-adc0-45a4-ab55-d1ea39a76b91/before.png
new file mode 100644
index 0000000..7dc4693
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/47c18efc-adc0-45a4-ab55-d1ea39a76b91/before.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/5076efe3-d9f2-41a1-97a5-2dc405e2c1f6/after.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/5076efe3-d9f2-41a1-97a5-2dc405e2c1f6/after.png
new file mode 100644
index 0000000..233ba82
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/5076efe3-d9f2-41a1-97a5-2dc405e2c1f6/after.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/5076efe3-d9f2-41a1-97a5-2dc405e2c1f6/before.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/5076efe3-d9f2-41a1-97a5-2dc405e2c1f6/before.png
new file mode 100644
index 0000000..1632685
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/5076efe3-d9f2-41a1-97a5-2dc405e2c1f6/before.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/582cdd6a-253e-4542-8417-27b1f3c4d809/after.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/582cdd6a-253e-4542-8417-27b1f3c4d809/after.png
new file mode 100644
index 0000000..c8bf1d5
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/582cdd6a-253e-4542-8417-27b1f3c4d809/after.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/582cdd6a-253e-4542-8417-27b1f3c4d809/before.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/582cdd6a-253e-4542-8417-27b1f3c4d809/before.png
new file mode 100644
index 0000000..7dc4693
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/582cdd6a-253e-4542-8417-27b1f3c4d809/before.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/aff65c4f-50bc-4707-a8ab-16f4ee878401/after.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/aff65c4f-50bc-4707-a8ab-16f4ee878401/after.png
new file mode 100644
index 0000000..17fadf4
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/aff65c4f-50bc-4707-a8ab-16f4ee878401/after.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/aff65c4f-50bc-4707-a8ab-16f4ee878401/before.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/aff65c4f-50bc-4707-a8ab-16f4ee878401/before.png
new file mode 100644
index 0000000..fd933c7
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/aff65c4f-50bc-4707-a8ab-16f4ee878401/before.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/b2134c7d-adc3-4efd-9c61-f93bd3833b5a/after.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/b2134c7d-adc3-4efd-9c61-f93bd3833b5a/after.png
new file mode 100644
index 0000000..8f3e832
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/b2134c7d-adc3-4efd-9c61-f93bd3833b5a/after.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/b2134c7d-adc3-4efd-9c61-f93bd3833b5a/before.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/b2134c7d-adc3-4efd-9c61-f93bd3833b5a/before.png
new file mode 100644
index 0000000..8017916
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/b2134c7d-adc3-4efd-9c61-f93bd3833b5a/before.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/b605a935-21be-4d74-9a0b-47669f19497f/after.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/b605a935-21be-4d74-9a0b-47669f19497f/after.png
new file mode 100644
index 0000000..d888d86
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/b605a935-21be-4d74-9a0b-47669f19497f/after.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/b605a935-21be-4d74-9a0b-47669f19497f/before.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/b605a935-21be-4d74-9a0b-47669f19497f/before.png
new file mode 100644
index 0000000..fd933c7
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/b605a935-21be-4d74-9a0b-47669f19497f/before.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/b63b8347-1428-4ae1-a9dd-1f7dc93ad3fd/after.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/b63b8347-1428-4ae1-a9dd-1f7dc93ad3fd/after.png
new file mode 100644
index 0000000..4d373bf
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/b63b8347-1428-4ae1-a9dd-1f7dc93ad3fd/after.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/b63b8347-1428-4ae1-a9dd-1f7dc93ad3fd/before.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/b63b8347-1428-4ae1-a9dd-1f7dc93ad3fd/before.png
new file mode 100644
index 0000000..d1bcabd
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/b63b8347-1428-4ae1-a9dd-1f7dc93ad3fd/before.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/d486cadd-1941-43f8-ba6c-39b20b321ac9/after.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/d486cadd-1941-43f8-ba6c-39b20b321ac9/after.png
new file mode 100644
index 0000000..573113c
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/d486cadd-1941-43f8-ba6c-39b20b321ac9/after.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/d486cadd-1941-43f8-ba6c-39b20b321ac9/before.png b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/d486cadd-1941-43f8-ba6c-39b20b321ac9/before.png
new file mode 100644
index 0000000..fd933c7
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/d486cadd-1941-43f8-ba6c-39b20b321ac9/before.png differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/04ec8cafc0514c24ae4692330aa04000.webm b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/04ec8cafc0514c24ae4692330aa04000.webm
new file mode 100644
index 0000000..cda2019
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/04ec8cafc0514c24ae4692330aa04000.webm differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/13028c006ee0ac9cca2ca905f65fcefa.webm b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/13028c006ee0ac9cca2ca905f65fcefa.webm
new file mode 100644
index 0000000..7a07b98
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/13028c006ee0ac9cca2ca905f65fcefa.webm differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/1c621f8c43a1caf7b0ced89f0274b8ec.webm b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/1c621f8c43a1caf7b0ced89f0274b8ec.webm
new file mode 100644
index 0000000..01373b4
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/1c621f8c43a1caf7b0ced89f0274b8ec.webm differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/1cb9105b0a6111ceab39f32c24ddc97d.webm b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/1cb9105b0a6111ceab39f32c24ddc97d.webm
new file mode 100644
index 0000000..e267bc5
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/1cb9105b0a6111ceab39f32c24ddc97d.webm differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/3bfa8cde94b4c1b57f22412e0af86796.webm b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/3bfa8cde94b4c1b57f22412e0af86796.webm
new file mode 100644
index 0000000..25d6a4f
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/3bfa8cde94b4c1b57f22412e0af86796.webm differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/642abb9a9b9c08ba233e056ca45271fd.webm b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/642abb9a9b9c08ba233e056ca45271fd.webm
new file mode 100644
index 0000000..6a1e756
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/642abb9a9b9c08ba233e056ca45271fd.webm differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/6bb06d399b588b842ce8486ebf14d867.webm b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/6bb06d399b588b842ce8486ebf14d867.webm
new file mode 100644
index 0000000..381f1da
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/6bb06d399b588b842ce8486ebf14d867.webm differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/b20eb9927f9e25a2873144a96ad26b31.webm b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/b20eb9927f9e25a2873144a96ad26b31.webm
new file mode 100644
index 0000000..f697fc5
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/b20eb9927f9e25a2873144a96ad26b31.webm differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/cfdaf0732b7508a28ec6f9d5424a1ec2.webm b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/cfdaf0732b7508a28ec6f9d5424a1ec2.webm
new file mode 100644
index 0000000..f6bb50b
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/cfdaf0732b7508a28ec6f9d5424a1ec2.webm differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/d28548480d384d112df81d3b7d8a144c.webm b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/d28548480d384d112df81d3b7d8a144c.webm
new file mode 100644
index 0000000..af2b3a5
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/d28548480d384d112df81d3b7d8a144c.webm differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/dab4e3eed0f046b3eae57e9ed3056cf7.webm b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/dab4e3eed0f046b3eae57e9ed3056cf7.webm
new file mode 100644
index 0000000..f2773f1
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/dab4e3eed0f046b3eae57e9ed3056cf7.webm differ
diff --git a/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/f3fe4349d9a9b94e8da0a9de596d0397.webm b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/f3fe4349d9a9b94e8da0a9de596d0397.webm
new file mode 100644
index 0000000..d6fb591
Binary files /dev/null and b/backend/proofs/scans/cmkeawj7l0003egfgyvnx760x/videos/f3fe4349d9a9b94e8da0a9de596d0397.webm differ
diff --git a/backend/proofs/scans/test-scan-001/88fb0709-9d49-4c45-b589-6b99b3da8656/after.png b/backend/proofs/scans/test-scan-001/88fb0709-9d49-4c45-b589-6b99b3da8656/after.png
new file mode 100644
index 0000000..3f42688
Binary files /dev/null and b/backend/proofs/scans/test-scan-001/88fb0709-9d49-4c45-b589-6b99b3da8656/after.png differ
diff --git a/backend/proofs/scans/test-scan-001/88fb0709-9d49-4c45-b589-6b99b3da8656/annotated.png b/backend/proofs/scans/test-scan-001/88fb0709-9d49-4c45-b589-6b99b3da8656/annotated.png
new file mode 100644
index 0000000..5f61eae
Binary files /dev/null and b/backend/proofs/scans/test-scan-001/88fb0709-9d49-4c45-b589-6b99b3da8656/annotated.png differ
diff --git a/backend/proofs/scans/test-scan-001/88fb0709-9d49-4c45-b589-6b99b3da8656/before.png b/backend/proofs/scans/test-scan-001/88fb0709-9d49-4c45-b589-6b99b3da8656/before.png
new file mode 100644
index 0000000..02854a8
Binary files /dev/null and b/backend/proofs/scans/test-scan-001/88fb0709-9d49-4c45-b589-6b99b3da8656/before.png differ
diff --git a/backend/proofs/scans/test-scan-001/88fb0709-9d49-4c45-b589-6b99b3da8656/page.html b/backend/proofs/scans/test-scan-001/88fb0709-9d49-4c45-b589-6b99b3da8656/page.html
new file mode 100644
index 0000000..53fd97b
--- /dev/null
+++ b/backend/proofs/scans/test-scan-001/88fb0709-9d49-4c45-b589-6b99b3da8656/page.html
@@ -0,0 +1,525 @@
+
+
+ OWASP Juice Shop
+
+
+
+
+
+
+
+
+This website uses fruit cookies to ensure you get the juiciest tracking experience. But me wait!
+
menu close search shopping_cart Your Basket 0
+
+
+
Open side menu
Choose language
\ No newline at end of file
diff --git a/backend/proofs/scans/test-scan-002/aaa2e0cd-e325-4cd2-9d61-f64e9bfb3e95/after.png b/backend/proofs/scans/test-scan-002/aaa2e0cd-e325-4cd2-9d61-f64e9bfb3e95/after.png
new file mode 100644
index 0000000..c321d71
Binary files /dev/null and b/backend/proofs/scans/test-scan-002/aaa2e0cd-e325-4cd2-9d61-f64e9bfb3e95/after.png differ
diff --git a/backend/proofs/scans/test-scan-002/aaa2e0cd-e325-4cd2-9d61-f64e9bfb3e95/annotated.png b/backend/proofs/scans/test-scan-002/aaa2e0cd-e325-4cd2-9d61-f64e9bfb3e95/annotated.png
new file mode 100644
index 0000000..c948cb7
Binary files /dev/null and b/backend/proofs/scans/test-scan-002/aaa2e0cd-e325-4cd2-9d61-f64e9bfb3e95/annotated.png differ
diff --git a/backend/proofs/scans/test-scan-002/aaa2e0cd-e325-4cd2-9d61-f64e9bfb3e95/before.png b/backend/proofs/scans/test-scan-002/aaa2e0cd-e325-4cd2-9d61-f64e9bfb3e95/before.png
new file mode 100644
index 0000000..937606c
Binary files /dev/null and b/backend/proofs/scans/test-scan-002/aaa2e0cd-e325-4cd2-9d61-f64e9bfb3e95/before.png differ
diff --git a/backend/proofs/scans/test-scan-002/aaa2e0cd-e325-4cd2-9d61-f64e9bfb3e95/page.html b/backend/proofs/scans/test-scan-002/aaa2e0cd-e325-4cd2-9d61-f64e9bfb3e95/page.html
new file mode 100644
index 0000000..efa7db6
--- /dev/null
+++ b/backend/proofs/scans/test-scan-002/aaa2e0cd-e325-4cd2-9d61-f64e9bfb3e95/page.html
@@ -0,0 +1,49 @@
+
+
+ Error: SQLITE_ERROR: near "UNION": syntax error
+
+
+
+
+
OWASP Juice Shop (Express ^4.21.0)
+
500 Error: SQLITE_ERROR: near "UNION": syntax error
+
+
+
+
+
\ No newline at end of file
diff --git a/backend/proofs/scans/test-scan-003/2cd55166-1990-41e9-b9b9-1dbf1e9c751e/after.png b/backend/proofs/scans/test-scan-003/2cd55166-1990-41e9-b9b9-1dbf1e9c751e/after.png
new file mode 100644
index 0000000..fe0e2d3
Binary files /dev/null and b/backend/proofs/scans/test-scan-003/2cd55166-1990-41e9-b9b9-1dbf1e9c751e/after.png differ
diff --git a/backend/proofs/scans/test-scan-003/2cd55166-1990-41e9-b9b9-1dbf1e9c751e/annotated.png b/backend/proofs/scans/test-scan-003/2cd55166-1990-41e9-b9b9-1dbf1e9c751e/annotated.png
new file mode 100644
index 0000000..4cdec0c
Binary files /dev/null and b/backend/proofs/scans/test-scan-003/2cd55166-1990-41e9-b9b9-1dbf1e9c751e/annotated.png differ
diff --git a/backend/proofs/scans/test-scan-003/2cd55166-1990-41e9-b9b9-1dbf1e9c751e/before.png b/backend/proofs/scans/test-scan-003/2cd55166-1990-41e9-b9b9-1dbf1e9c751e/before.png
new file mode 100644
index 0000000..937606c
Binary files /dev/null and b/backend/proofs/scans/test-scan-003/2cd55166-1990-41e9-b9b9-1dbf1e9c751e/before.png differ
diff --git a/backend/proofs/scans/test-scan-003/2cd55166-1990-41e9-b9b9-1dbf1e9c751e/page.html b/backend/proofs/scans/test-scan-003/2cd55166-1990-41e9-b9b9-1dbf1e9c751e/page.html
new file mode 100644
index 0000000..d87a5a1
--- /dev/null
+++ b/backend/proofs/scans/test-scan-003/2cd55166-1990-41e9-b9b9-1dbf1e9c751e/page.html
@@ -0,0 +1 @@
+{"status":"success","data":[{"id":null,"name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":1,"name":"Apple Juice (1000ml)","description":"The all-time classic.","price":1.99,"deluxePrice":0.99,"image":"apple_juice.jpg","createdAt":"2026-01-12 06:14:40.837 +00:00","updatedAt":"2026-01-12 06:14:40.837 +00:00","deletedAt":null},{"id":2,"name":"Orange Juice (1000ml)","description":"Made from oranges hand-picked by Uncle Dittmeyer.","price":2.99,"deluxePrice":2.49,"image":"orange_juice.jpg","createdAt":"2026-01-12 06:14:40.837 +00:00","updatedAt":"2026-01-12 06:14:40.837 +00:00","deletedAt":null},{"id":3,"name":"Eggfruit Juice (500ml)","description":"Now with even more exotic flavour.","price":8.99,"deluxePrice":8.99,"image":"eggfruit_juice.jpg","createdAt":"2026-01-12 06:14:40.837 +00:00","updatedAt":"2026-01-12 06:14:40.837 +00:00","deletedAt":null},{"id":4,"name":"Raspberry Juice (1000ml)","description":"Made from blended Raspberry Pi, water and sugar.","price":4.99,"deluxePrice":4.99,"image":"raspberry_juice.jpg","createdAt":"2026-01-12 06:14:40.837 +00:00","updatedAt":"2026-01-12 06:14:40.837 +00:00","deletedAt":null},{"id":5,"name":"Lemon Juice (500ml)","description":"Sour but full of vitamins.","price":2.99,"deluxePrice":1.99,"image":"lemon_juice.jpg","createdAt":"2026-01-12 06:14:40.837 +00:00","updatedAt":"2026-01-12 06:14:40.837 +00:00","deletedAt":null},{"id":6,"name":"Banana Juice (1000ml)","description":"Monkeys love it the most.","price":1.99,"deluxePrice":1.99,"image":"banana_juice.jpg","createdAt":"2026-01-12 06:14:40.837 +00:00","updatedAt":"2026-01-12 06:14:40.837 +00:00","deletedAt":null},{"id":7,"name":"OWASP Juice Shop T-Shirt","description":"Real fans wear it 24/7!","price":22.49,"deluxePrice":22.49,"image":"fan_shirt.jpg","createdAt":"2026-01-12 06:14:40.837 +00:00","updatedAt":"2026-01-12 06:14:40.837 +00:00","deletedAt":null},{"id":8,"name":"OWASP Juice Shop CTF Girlie-Shirt","description":"For serious Capture-the-Flag heroines only!","price":22.49,"deluxePrice":22.49,"image":"fan_girlie.jpg","createdAt":"2026-01-12 06:14:40.837 +00:00","updatedAt":"2026-01-12 06:14:40.837 +00:00","deletedAt":null},{"id":9,"name":"OWASP SSL Advanced Forensic Tool (O-Saft)","description":"O-Saft is an easy to use tool to show information about SSL certificate and tests the SSL connection according given list of ciphers and various SSL configurations. <a href=\"https://www.owasp.org/index.php/O-Saft\" target=\"_blank\">More...</a>","price":0.01,"deluxePrice":0.01,"image":"orange_juice.jpg","createdAt":"2026-01-12 06:14:40.839 +00:00","updatedAt":"2026-01-12 06:14:40.839 +00:00","deletedAt":null},{"id":10,"name":"Christmas Super-Surprise-Box (2014 Edition)","description":"Contains a random selection of 10 bottles (each 500ml) of our tastiest juices and an extra fan shirt for an unbeatable price! (Seasonal special offer! Limited availability!)","price":29.99,"deluxePrice":29.99,"image":"undefined.jpg","createdAt":"2026-01-12 06:14:40.839 +00:00","updatedAt":"2026-01-12 06:14:40.839 +00:00","deletedAt":"2026-01-12 06:14:40.917 +00:00"},{"id":11,"name":"Rippertuer Special Juice","description":"Contains a magical collection of the rarest fruits gathered from all around the world, like Cherymoya Annona cherimola, Jabuticaba Myrciaria cauliflora, Bael Aegle marmelos... and others, at an unbelievable price! <br />This item has been made unavailable because of lack of safety standards. (This product is unsafe! We plan to remove it from the stock!)","price":16.99,"deluxePrice":16.99,"image":"undefined.jpg","createdAt":"2026-01-12 06:14:40.839 +00:00","updatedAt":"2026-01-12 06:14:40.839 +00:00","deletedAt":"2026-01-12 06:14:40.924 +00:00"},{"id":12,"name":"OWASP Juice Shop Sticker (2015/2016 design)","description":"Die-cut sticker with the official 2015/2016 logo. By now this is a rare collectors item. <em>Out of stock!</em>","price":999.99,"deluxePrice":999.99,"image":"sticker.png","createdAt":"2026-01-12 06:14:40.839 +00:00","updatedAt":"2026-01-12 06:14:40.839 +00:00","deletedAt":"2026-01-12 06:14:40.928 +00:00"},{"id":13,"name":"OWASP Juice Shop Iron-Ons (16pcs)","description":"Upgrade your clothes with washer safe <a href=\"https://www.stickeryou.com/products/owasp-juice-shop/794\" target=\"_blank\">iron-ons</a> of the OWASP Juice Shop or CTF Extension logo!","price":14.99,"deluxePrice":14.99,"image":"iron-on.jpg","createdAt":"2026-01-12 06:14:40.839 +00:00","updatedAt":"2026-01-12 06:14:40.839 +00:00","deletedAt":null},{"id":14,"name":"OWASP Juice Shop Magnets (16pcs)","description":"Your fridge will be even cooler with these OWASP Juice Shop or CTF Extension logo <a href=\"https://www.stickeryou.com/products/owasp-juice-shop/794\" target=\"_blank\">magnets</a>!","price":15.99,"deluxePrice":15.99,"image":"magnets.jpg","createdAt":"2026-01-12 06:14:40.839 +00:00","updatedAt":"2026-01-12 06:14:40.839 +00:00","deletedAt":null},{"id":15,"name":"OWASP Juice Shop Sticker Page","description":"Massive decoration opportunities with these OWASP Juice Shop or CTF Extension <a href=\"https://www.stickeryou.com/products/owasp-juice-shop/794\" target=\"_blank\">sticker pages</a>! Each page has 16 stickers on it.","price":9.99,"deluxePrice":9.99,"image":"sticker_page.jpg","createdAt":"2026-01-12 06:14:40.840 +00:00","updatedAt":"2026-01-12 06:14:40.840 +00:00","deletedAt":null},{"id":16,"name":"OWASP Juice Shop Sticker Single","description":"Super high-quality vinyl <a href=\"https://www.stickeryou.com/products/owasp-juice-shop/794\" target=\"_blank\">sticker single</a> with the OWASP Juice Shop or CTF Extension logo! The ultimate laptop decal!","price":4.99,"deluxePrice":4.99,"image":"sticker_single.jpg","createdAt":"2026-01-12 06:14:40.840 +00:00","updatedAt":"2026-01-12 06:14:40.840 +00:00","deletedAt":null},{"id":17,"name":"OWASP Juice Shop Temporary Tattoos (16pcs)","description":"Get one of these <a href=\"https://www.stickeryou.com/products/owasp-juice-shop/794\" target=\"_blank\">temporary tattoos</a> to proudly wear the OWASP Juice Shop or CTF Extension logo on your skin! If you tweet a photo of yourself with the tattoo, you get a couple of our stickers for free! Please mention <a href=\"https://twitter.com/owasp_juiceshop\" target=\"_blank\"><code>@owasp_juiceshop</code></a> in your tweet!","price":14.99,"deluxePrice":14.99,"image":"tattoo.jpg","createdAt":"2026-01-12 06:14:40.840 +00:00","updatedAt":"2026-01-12 06:14:40.840 +00:00","deletedAt":null},{"id":18,"name":"OWASP Juice Shop Mug","description":"Black mug with regular logo on one side and CTF logo on the other! Your colleagues will envy you!","price":21.99,"deluxePrice":21.99,"image":"fan_mug.jpg","createdAt":"2026-01-12 06:14:40.840 +00:00","updatedAt":"2026-01-12 06:14:40.840 +00:00","deletedAt":null},{"id":19,"name":"OWASP Juice Shop Hoodie","description":"Mr. Robot-style apparel. But in black. And with logo.","price":49.99,"deluxePrice":49.99,"image":"fan_hoodie.jpg","createdAt":"2026-01-12 06:14:40.840 +00:00","updatedAt":"2026-01-12 06:14:40.840 +00:00","deletedAt":null},{"id":20,"name":"OWASP Juice Shop-CTF Velcro Patch","description":"4x3.5\" embroidered patch with velcro backside. The ultimate decal for every tactical bag or backpack!","price":2.92,"deluxePrice":2.92,"image":"velcro-patch.jpg","createdAt":"2026-01-12 06:14:40.840 +00:00","updatedAt":"2026-01-12 06:14:40.840 +00:00","deletedAt":null},{"id":21,"name":"Woodruff Syrup \"Forest Master X-Treme\"","description":"Harvested and manufactured in the Black Forest, Germany. Can cause hyperactive behavior in children. Can cause permanent green tongue when consumed undiluted.","price":6.99,"deluxePrice":6.99,"image":"woodruff_syrup.jpg","createdAt":"2026-01-12 06:14:40.840 +00:00","updatedAt":"2026-01-12 06:14:40.840 +00:00","deletedAt":null},{"id":22,"name":"Green Smoothie","description":"Looks poisonous but is actually very good for your health! Made from green cabbage, spinach, kiwi and grass.","price":1.99,"deluxePrice":1.99,"image":"green_smoothie.jpg","createdAt":"2026-01-12 06:14:40.840 +00:00","updatedAt":"2026-01-12 06:14:40.840 +00:00","deletedAt":null},{"id":23,"name":"Quince Juice (1000ml)","description":"Juice of the <em>Cydonia oblonga</em> fruit. Not exactly sweet but rich in Vitamin C.","price":4.99,"deluxePrice":4.99,"image":"quince.jpg","createdAt":"2026-01-12 06:14:40.841 +00:00","updatedAt":"2026-01-12 06:14:40.841 +00:00","deletedAt":null},{"id":24,"name":"Apple Pomace","description":"Finest pressings of apples. Allergy disclaimer: Might contain traces of worms. Can be <a href=\"/#recycle\">sent back to us</a> for recycling.","price":0.89,"deluxePrice":0.89,"image":"apple_pressings.jpg","createdAt":"2026-01-12 06:14:40.841 +00:00","updatedAt":"2026-01-12 06:14:40.841 +00:00","deletedAt":null},{"id":25,"name":"Fruit Press","description":"Fruits go in. Juice comes out. Pomace you can send back to us for recycling purposes.","price":89.99,"deluxePrice":89.99,"image":"fruit_press.jpg","createdAt":"2026-01-12 06:14:40.841 +00:00","updatedAt":"2026-01-12 06:14:40.841 +00:00","deletedAt":null},{"id":26,"name":"OWASP Juice Shop Logo (3D-printed)","description":"This rare item was designed and handcrafted in Sweden. This is why it is so incredibly expensive despite its complete lack of purpose.","price":99.99,"deluxePrice":99.99,"image":"3d_keychain.jpg","createdAt":"2026-01-12 06:14:40.841 +00:00","updatedAt":"2026-01-12 06:14:40.841 +00:00","deletedAt":null},{"id":27,"name":"Juice Shop Artwork","description":"Unique masterpiece painted with different kinds of juice on 90g/m² lined paper.","price":278.74,"deluxePrice":278.74,"image":"artwork.jpg","createdAt":"2026-01-12 06:14:40.841 +00:00","updatedAt":"2026-01-12 06:14:40.841 +00:00","deletedAt":"2026-01-12 06:14:41.021 +00:00"},{"id":28,"name":"Global OWASP WASPY Award 2017 Nomination","description":"Your chance to nominate up to three quiet pillars of the OWASP community ends 2017-06-30! <a href=\"https://www.owasp.org/index.php/WASPY_Awards_2017\">Nominate now!</a>","price":0.03,"deluxePrice":0.03,"image":"waspy.png","createdAt":"2026-01-12 06:14:40.841 +00:00","updatedAt":"2026-01-12 06:14:40.841 +00:00","deletedAt":"2026-01-12 06:14:41.027 +00:00"},{"id":29,"name":"Strawberry Juice (500ml)","description":"Sweet & tasty!","price":3.99,"deluxePrice":3.99,"image":"strawberry_juice.jpeg","createdAt":"2026-01-12 06:14:40.841 +00:00","updatedAt":"2026-01-12 06:14:40.841 +00:00","deletedAt":null},{"id":30,"name":"Carrot Juice (1000ml)","description":"As the old German saying goes: \"Carrots are good for the eyes. Or has anyone ever seen a rabbit with glasses?\"","price":2.99,"deluxePrice":2.99,"image":"carrot_juice.jpeg","createdAt":"2026-01-12 06:14:40.841 +00:00","updatedAt":"2026-01-12 06:14:40.841 +00:00","deletedAt":null},{"id":31,"name":"OWASP Juice Shop Sweden Tour 2017 Sticker Sheet (Special Edition)","description":"10 sheets of Sweden-themed stickers with 15 stickers on each.","price":19.1,"deluxePrice":19.1,"image":"stickersheet_se.png","createdAt":"2026-01-12 06:14:40.841 +00:00","updatedAt":"2026-01-12 06:14:40.841 +00:00","deletedAt":"2026-01-12 06:14:41.045 +00:00"},{"id":32,"name":"Pwning OWASP Juice Shop","description":"<em>The official Companion Guide</em> by Björn Kimminich available <a href=\"https://leanpub.com/juice-shop\">for free on LeanPub</a> and also <a href=\"https://pwning.owasp-juice.shop\">readable online</a>!","price":5.99,"deluxePrice":5.99,"image":"cover_small.jpg","createdAt":"2026-01-12 06:14:40.841 +00:00","updatedAt":"2026-01-12 06:14:40.841 +00:00","deletedAt":null},{"id":33,"name":"Melon Bike (Comeback-Product 2018 Edition)","description":"The wheels of this bicycle are made from real water melons. You might not want to ride it up/down the curb too hard.","price":2999,"deluxePrice":2999,"image":"melon_bike.jpeg","createdAt":"2026-01-12 06:14:40.841 +00:00","updatedAt":"2026-01-12 06:14:40.841 +00:00","deletedAt":null},{"id":34,"name":"OWASP Juice Shop Coaster (10pcs)","description":"Our 95mm circle coasters are printed in full color and made from thick, premium coaster board.","price":19.99,"deluxePrice":19.99,"image":"coaster.jpg","createdAt":"2026-01-12 06:14:40.842 +00:00","updatedAt":"2026-01-12 06:14:40.842 +00:00","deletedAt":null},{"id":35,"name":"OWASP Snakes and Ladders - Web Applications","description":"This amazing web application security awareness board game is <a href=\"https://steamcommunity.com/sharedfiles/filedetails/?id=1969196030\">available for Tabletop Simulator on Steam Workshop</a> now!","price":0.01,"deluxePrice":0.01,"image":"snakes_ladders.jpg","createdAt":"2026-01-12 06:14:40.842 +00:00","updatedAt":"2026-01-12 06:14:40.842 +00:00","deletedAt":null},{"id":36,"name":"OWASP Snakes and Ladders - Mobile Apps","description":"This amazing mobile app security awareness board game is <a href=\"https://steamcommunity.com/sharedfiles/filedetails/?id=1970691216\">available for Tabletop Simulator on Steam Workshop</a> now!","price":0.01,"deluxePrice":0.01,"image":"snakes_ladders_m.jpg","createdAt":"2026-01-12 06:14:40.842 +00:00","updatedAt":"2026-01-12 06:14:40.842 +00:00","deletedAt":null},{"id":37,"name":"OWASP Juice Shop Holographic Sticker","description":"Die-cut holographic sticker. Stand out from those 08/15-sticker-covered laptops with this shiny beacon of 80's coolness!","price":2,"deluxePrice":2,"image":"holo_sticker.png","createdAt":"2026-01-12 06:14:40.842 +00:00","updatedAt":"2026-01-12 06:14:40.842 +00:00","deletedAt":null},{"id":38,"name":"OWASP Juice Shop \"King of the Hill\" Facemask","description":"Facemask with compartment for filter from 50% cotton and 50% polyester.","price":13.49,"deluxePrice":13.49,"image":"fan_facemask.jpg","createdAt":"2026-01-12 06:14:40.842 +00:00","updatedAt":"2026-01-12 06:14:40.842 +00:00","deletedAt":null},{"id":39,"name":"Juice Shop Adversary Trading Card (Common)","description":"Common rarity \"Juice Shop\" card for the <a href=\"https://docs.google.com/forms/d/e/1FAIpQLSecLEakawSQ56lBe2JOSbFwFYrKDCIN7Yd3iHFdQc5z8ApwdQ/viewform\">Adversary Trading Cards</a> CCG.","price":2.99,"deluxePrice":0.99,"image":"ccg_common.png","createdAt":"2026-01-12 06:14:40.842 +00:00","updatedAt":"2026-01-12 06:14:40.842 +00:00","deletedAt":"2026-01-12 06:14:41.108 +00:00"},{"id":40,"name":"Juice Shop Adversary Trading Card (Super Rare)","description":"Super rare \"Juice Shop\" card with holographic foil-coating for the <a href=\"https://docs.google.com/forms/d/e/1FAIpQLSecLEakawSQ56lBe2JOSbFwFYrKDCIN7Yd3iHFdQc5z8ApwdQ/viewform\">Adversary Trading Cards</a> CCG.","price":99.99,"deluxePrice":69.99,"image":"ccg_foil.png","createdAt":"2026-01-12 06:14:40.842 +00:00","updatedAt":"2026-01-12 06:14:40.842 +00:00","deletedAt":"2026-01-12 06:14:41.127 +00:00"},{"id":41,"name":"Juice Shop \"Permafrost\" 2020 Edition","description":"Exact version of <a href=\"https://github.com/juice-shop/juice-shop/releases/tag/v9.3.1-PERMAFROST\">OWASP Juice Shop that was archived on 02/02/2020</a> by the GitHub Archive Program and ultimately went into the <a href=\"https://github.blog/2020-07-16-github-archive-program-the-journey-of-the-worlds-open-source-code-to-the-arctic\">Arctic Code Vault</a> on July 8. 2020 where it will be safely stored for at least 1000 years.","price":9999.99,"deluxePrice":9999.99,"image":"permafrost.jpg","createdAt":"2026-01-12 06:14:40.842 +00:00","updatedAt":"2026-01-12 06:14:40.842 +00:00","deletedAt":null},{"id":42,"name":"Best Juice Shop Salesman Artwork","description":"Unique digital painting depicting Stan, our most qualified and almost profitable salesman. He made a succesful carreer in selling used ships, coffins, krypts, crosses, real estate, life insurance, restaurant supplies, voodoo enhanced asbestos and courtroom souvenirs before <em>finally</em> adding his expertise to the Juice Shop marketing team.","price":5000,"deluxePrice":5000,"image":"artwork2.jpg","createdAt":"2026-01-12 06:14:40.842 +00:00","updatedAt":"2026-01-12 06:14:40.842 +00:00","deletedAt":null},{"id":43,"name":"OWASP Juice Shop Card (non-foil)","description":"Mythic rare <em>(obviously...)</em> card \"OWASP Juice Shop\" with three distinctly useful abilities. Alpha printing, mint condition. A true collectors piece to own!","price":1000,"deluxePrice":1000,"image":"card_alpha.jpg","createdAt":"2026-01-12 06:14:40.842 +00:00","updatedAt":"2026-01-12 06:14:40.842 +00:00","deletedAt":null},{"id":44,"name":"20th Anniversary Celebration Ticket","description":"Get your <a href=\"https://20thanniversary.owasp.org/\" target=\"_blank\">free 🎫 for OWASP 20th Anniversary Celebration</a> online conference! Hear from world renowned keynotes and special speakers, network with your peers and interact with our event sponsors. With an anticipated 10k+ attendees from around the world, you will not want to miss this live on-line event!","price":1e-20,"deluxePrice":1e-20,"image":"20th.jpeg","createdAt":"2026-01-12 06:14:40.842 +00:00","updatedAt":"2026-01-12 06:14:40.842 +00:00","deletedAt":"2026-01-12 06:14:41.168 +00:00"},{"id":45,"name":"OWASP Juice Shop LEGO™ Tower","description":"Want to host a Juice Shop CTF in style? Build <a href=\"https://github.com/OWASP/owasp-swag/blob/master/projects/juice-shop/lego/OWASP%20JuiceShop%20Pi-server%201.2.pdf\" target=\"_blank\">your own LEGO™ tower</a> which holds four Raspberry Pi 4 models with PoE HAT modules <a href=\"https://github.com/juice-shop/multi-juicer/blob/main/guides/raspberry-pi/raspberry-pi.md\" target=\"_blank\">running a MultiJuicer Kubernetes cluster</a>! Wire to a switch and connect to your network to have an out-of-the-box ready CTF up in no time!","price":799,"deluxePrice":799,"image":"lego_case.jpg","createdAt":"2026-01-12 06:14:40.842 +00:00","updatedAt":"2026-01-12 06:14:40.842 +00:00","deletedAt":null},{"id":46,"name":"DSOMM & Juice Shop User Day Ticket","description":"You are going to the OWASP Global AppSec San Francisco 2024? <a href=\"https://www.eventbrite.com/e/owasp-global-appsec-san-francisco-2024-tickets-723699172707\" target=\"_blank\">Get a ticket*</a> for this amazing side event as well! Check the juice-packed agenda <a href=\"https://owasp.org/www-project-juice-shop/#div-userday2024\" target=\"_blank\">here</a> for all the details!<br /><br />*=scroll down to <strong>Elevate: DSOMM and Juice Shop User Day (Sept. 25)</strong> after clicking <em>Get Tickets</em> on Eventbrite. Ticket price set to only covers fees for room, AV, and catering throughout the day.","price":55.2,"deluxePrice":55.2,"image":"user_day_ticket.png","createdAt":"2026-01-12 06:14:40.843 +00:00","updatedAt":"2026-01-12 06:14:40.843 +00:00","deletedAt":"2026-01-12 06:14:41.189 +00:00"},{"id":"CREATE TABLE `Addresses` (`UserId` INTEGER REFERENCES `Users` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE, `id` INTEGER PRIMARY KEY AUTOINCREMENT, `fullName` VARCHAR(255), `mobileNum` INTEGER, `zipCode` VARCHAR(255), `streetAddress` VARCHAR(255), `city` VARCHAR(255), `state` VARCHAR(255), `country` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL)","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":"CREATE TABLE `BasketItems` (`ProductId` INTEGER REFERENCES `Products` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, `BasketId` INTEGER REFERENCES `Baskets` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, `id` INTEGER PRIMARY KEY AUTOINCREMENT, `quantity` INTEGER, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, UNIQUE (`ProductId`, `BasketId`))","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":"CREATE TABLE `Baskets` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `coupon` VARCHAR(255), `UserId` INTEGER REFERENCES `Users` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL)","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":"CREATE TABLE `Captchas` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `captchaId` INTEGER, `captcha` VARCHAR(255), `answer` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL)","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":"CREATE TABLE `Cards` (`UserId` INTEGER REFERENCES `Users` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE, `id` INTEGER PRIMARY KEY AUTOINCREMENT, `fullName` VARCHAR(255), `cardNum` INTEGER, `expMonth` INTEGER, `expYear` INTEGER, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL)","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":"CREATE TABLE `Challenges` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `key` TEXT, `name` VARCHAR(255), `category` VARCHAR(255), `tags` VARCHAR(255), `description` VARCHAR(255), `difficulty` INTEGER, `mitigationUrl` VARCHAR(255), `solved` TINYINT(1), `disabledEnv` VARCHAR(255), `tutorialOrder` NUMBER, `codingChallengeStatus` NUMBER, `hasCodingChallenge` TINYINT(1), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL)","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":"CREATE TABLE `Complaints` (`UserId` INTEGER REFERENCES `Users` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE, `id` INTEGER PRIMARY KEY AUTOINCREMENT, `message` VARCHAR(255), `file` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL)","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":"CREATE TABLE `Deliveries` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` VARCHAR(255), `price` FLOAT, `deluxePrice` FLOAT, `eta` FLOAT, `icon` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL)","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":"CREATE TABLE `Feedbacks` (`UserId` INTEGER REFERENCES `Users` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE, `id` INTEGER PRIMARY KEY AUTOINCREMENT, `comment` VARCHAR(255), `rating` INTEGER NOT NULL, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL)","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":"CREATE TABLE `Hints` (`ChallengeId` INTEGER, `id` INTEGER PRIMARY KEY AUTOINCREMENT, `text` VARCHAR(255), `order` INTEGER, `unlocked` TINYINT(1), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL)","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":"CREATE TABLE `ImageCaptchas` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `image` VARCHAR(255), `answer` VARCHAR(255), `UserId` INTEGER REFERENCES `Users` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE, `createdAt` DATETIME, `updatedAt` DATETIME NOT NULL)","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":"CREATE TABLE `Memories` (`UserId` INTEGER REFERENCES `Users` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE, `id` INTEGER PRIMARY KEY AUTOINCREMENT, `caption` VARCHAR(255), `imagePath` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL)","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":"CREATE TABLE `PrivacyRequests` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `UserId` INTEGER REFERENCES `Users` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE, `deletionRequested` TINYINT(1) DEFAULT 0, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL)","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":"CREATE TABLE `Products` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` VARCHAR(255), `description` VARCHAR(255), `price` DECIMAL, `deluxePrice` DECIMAL, `image` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, `deletedAt` DATETIME)","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":"CREATE TABLE `Quantities` (`ProductId` INTEGER REFERENCES `Products` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE, `id` INTEGER PRIMARY KEY AUTOINCREMENT, `quantity` INTEGER, `limitPerUser` INTEGER DEFAULT NULL, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL)","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":"CREATE TABLE `Recycles` (`UserId` INTEGER REFERENCES `Users` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE, `AddressId` INTEGER REFERENCES `Addresses` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE, `id` INTEGER PRIMARY KEY AUTOINCREMENT, `quantity` INTEGER, `isPickup` TINYINT(1) DEFAULT 0, `date` DATETIME, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL)","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":"CREATE TABLE `SecurityAnswers` (`UserId` INTEGER UNIQUE REFERENCES `Users` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE, `SecurityQuestionId` INTEGER REFERENCES `SecurityQuestions` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE, `id` INTEGER PRIMARY KEY AUTOINCREMENT, `answer` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL)","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":"CREATE TABLE `SecurityQuestions` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `question` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL)","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":"CREATE TABLE `Users` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `username` VARCHAR(255) DEFAULT '', `email` VARCHAR(255) UNIQUE, `password` VARCHAR(255), `role` VARCHAR(255) DEFAULT 'customer', `deluxeToken` VARCHAR(255) DEFAULT '', `lastLoginIp` VARCHAR(255) DEFAULT '0.0.0.0', `profileImage` VARCHAR(255) DEFAULT '/assets/public/images/uploads/default.svg', `totpSecret` VARCHAR(255) DEFAULT '', `isActive` TINYINT(1) DEFAULT 1, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, `deletedAt` DATETIME)","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":"CREATE TABLE `Wallets` (`UserId` INTEGER REFERENCES `Users` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE, `id` INTEGER PRIMARY KEY AUTOINCREMENT, `balance` INTEGER DEFAULT 0, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL)","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9},{"id":"CREATE TABLE sqlite_sequence(name,seq)","name":2,"description":3,"price":4,"deluxePrice":5,"image":6,"createdAt":7,"updatedAt":8,"deletedAt":9}]}
\ No newline at end of file
diff --git a/backend/src/controllers/kullanici.ts b/backend/src/controllers/kullanici.ts
index 967a88a..a8878b5 100644
--- a/backend/src/controllers/kullanici.ts
+++ b/backend/src/controllers/kullanici.ts
@@ -25,7 +25,7 @@ export const kullaniciKaydi = async (req: Request, res: Response, next: NextFunc
const password_hash = await bcrypt.hash(password, 10);
// **تصحيح 2:** استدعاء الدالة الجديدة التي تقوم بكل شيء
- const yeniKullanici = await registerUserAndCreateOrg({ email, name, password_hash });
+ const { user: yeniKullanici, organizationId } = await registerUserAndCreateOrg({ email, name, password_hash });
// توقيع التوكنات مباشرة بعد التسجيل (الدور الافتراضي هو ADMIN لمنظمته)
const { accessToken, refreshToken } = signTokens({ id: yeniKullanici.id, role: 'ADMIN' });
@@ -41,8 +41,17 @@ export const kullaniciKaydi = async (req: Request, res: Response, next: NextFunc
maxAge: 7 * 24 * 60 * 60 * 1000,
} );
- // إرسال الـ Access Token
- return res.status(201).json({ accessToken });
+ // إرسال الـ Access Token مع بيانات المستخدم
+ return res.status(201).json({
+ accessToken,
+ user: {
+ id: yeniKullanici.id,
+ email: yeniKullanici.email,
+ name: yeniKullanici.name,
+ role: 'ADMIN',
+ organizationId // إرسال معرف المنظمة للفرونت اند
+ }
+ });
} catch (hata) {
next(hata);
@@ -86,7 +95,16 @@ export const kullaniciGiris = async (req: Request, res: Response, next: NextFunc
maxAge: 7 * 24 * 60 * 60 * 1000,
} );
- return res.status(200).json({ accessToken });
+ return res.status(200).json({
+ accessToken,
+ user: {
+ id: kullanici.id,
+ email: kullanici.email,
+ name: kullanici.name,
+ role: userRole,
+ organizationId: firstMembership.organizationId
+ }
+ });
} catch (hata) {
next(hata);
diff --git a/backend/src/controllers/scans.ts b/backend/src/controllers/scans.ts
index 26d4670..c97de1f 100644
--- a/backend/src/controllers/scans.ts
+++ b/backend/src/controllers/scans.ts
@@ -1,5 +1,6 @@
import { Request, Response, NextFunction } from 'express';
import * as scanService from '../services/scans';
+import { logger } from '../utils/logger';
export const createScan = async (
req: Request,
@@ -8,11 +9,13 @@ export const createScan = async (
) => {
try {
const userId = req.kullanici!.id;
- const { targetId, configurationId } = req.body;
+ const { targetId, configurationId, profile } = req.body;
// هذه الدالة الآن تضيف المهمة إلى قائمة الانتظار بفضل التعديلات في ملف الخدمة
- const scan = await scanService.initiateScan(userId, targetId, configurationId);
+ const scan = await scanService.initiateScan(userId, targetId, profile, configurationId);
+ logger.log(`OPERATIONS :: Scan sequence initiated for asset ${targetId}`, 'info');
+
// --- بداية التعديل ---
// تم تغيير الرسالة لتكون أكثر دقة وتوضح أن الفحص تم وضعه في قائمة الانتظار
res.status(201).json({
diff --git a/backend/src/controllers/target.ts b/backend/src/controllers/target.ts
index 24f0428..2e23f52 100644
--- a/backend/src/controllers/target.ts
+++ b/backend/src/controllers/target.ts
@@ -9,6 +9,7 @@ import {
tekHedefiGetir,
hedefiSil
} from '../services/target';
+import { logger } from '../utils/logger';
// --- وحدة التحكم 1: إنشاء هدف ---
export const hedefOlustur = async (req: Request, res: Response) => {
@@ -20,6 +21,7 @@ export const hedefOlustur = async (req: Request, res: Response) => {
const { name, url, organizationId } = req.body;
try {
const yeniHedef = await organizasyonIcinHedefOlustur({ name, url, organizationId, olusturanId });
+ logger.log(`ASSET_DISCOVERY :: New target localized: ${name} (${url})`, 'success');
return res.status(201).json(yeniHedef);
} catch (hata) {
if (hata instanceof Error && hata.message.startsWith('YASAK')) {
@@ -87,6 +89,7 @@ export const deleteTarget = async (req: Request, res: Response) => {
try {
// الآن TypeScript متأكد 100% أن 'id' هو 'string'
await hedefiSil(id, userId);
+ logger.log(`ASSET_PURGE :: Target asset decoupled: ${id}`, 'warning');
return res.status(204).send();
} catch (hata) {
diff --git a/backend/src/controllers/vulnerability.ts b/backend/src/controllers/vulnerability.ts
new file mode 100644
index 0000000..14d7b86
--- /dev/null
+++ b/backend/src/controllers/vulnerability.ts
@@ -0,0 +1,23 @@
+import { Request, Response, NextFunction } from 'express';
+import * as vulnerabilityService from '../services/vulnerability';
+
+export const listVulnerabilities = async (
+ req: Request,
+ res: Response,
+ next: NextFunction
+) => {
+ try {
+ const userId = req.kullanici!.id;
+ const organizationIdParam = req.query.organizationId;
+ const organizationId = Array.isArray(organizationIdParam) ? organizationIdParam[0] as string : organizationIdParam as string;
+
+ if (!organizationId) {
+ return res.status(400).json({ message: 'organizationId query parameter is required' });
+ }
+
+ const vulnerabilities = await vulnerabilityService.listVulnerabilitiesForOrg(userId, organizationId);
+ res.status(200).json({ data: vulnerabilities });
+ } catch (error) {
+ next(error);
+ }
+};
diff --git a/backend/src/index.ts b/backend/src/index.ts
index 5c02456..631f5ad 100644
--- a/backend/src/index.ts
+++ b/backend/src/index.ts
@@ -7,18 +7,20 @@ dotenv.config();
// الآن نستورد باقي المكتبات والملفات
import express, { Express, Request, Response, NextFunction } from 'express';
import { PrismaClient } from '@prisma/client';
-import { Server } from 'http';
+import http from 'http';
import cors from 'cors';
import cookieParser from 'cookie-parser';
import { AppError } from './utils/errors';
import { setupSecurity } from './middleware/security';
+import { logger } from './utils/logger';
// --- Import Routers ---
import authRouter from './routes/auth';
import organizationRouter from './routes/kurum';
import targetRouter from './routes/target';
import scanRouter from './routes/scans';
+import vulnerabilityRouter from './routes/vulnerability';
// --- Import Swagger and Worker Loader ---
import { setupSwagger } from './swagger';
@@ -37,8 +39,24 @@ async function main() {
console.log('✅ Database connection successful!');
// --- Middlewares ---
+ app.use(cors({
+ origin: ['http://localhost:5173', 'http://localhost:4173'], // Restrict to frontend dev/preview ports
+ credentials: true,
+ methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
+ allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With', 'Accept'],
+ }));
+
setupSecurity(app); // 🛡️ Apply security middleware
- app.use(cors());
+
+ // Custom Request Logger
+ app.use((req, res, next) => {
+ console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
+ if (req.method === 'OPTIONS') {
+ return res.sendStatus(200);
+ }
+ next();
+ });
+
app.use(express.json());
app.use(cookieParser());
@@ -53,6 +71,7 @@ async function main() {
app.use('/api/organizations', organizationRouter);
app.use('/api/targets', targetRouter);
app.use('/api/scans', scanRouter);
+ app.use('/api/vulnerabilities', vulnerabilityRouter);
// --- Global Error Handler ---
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
@@ -73,13 +92,15 @@ async function main() {
// --- Start Server and Workers ---
const PORT = process.env.PORT || 3001;
- app.listen(PORT, () => {
- console.log(`🚀 API Server is running on http://localhost:${PORT}`);
+ const server = http.createServer(app);
+
+ // Initialize Socket.io via our logger service
+ logger.init(server);
- // --- بداية التعديل الرئيسي ---
- // بعد أن يعمل الخادم بنجاح، قم ببدء تشغيل العمال
- // startWorkers(); // ❌ Disabled to prevent conflict with 'npm run dev:worker'
- // --- نهاية التعديل الرئيسي ---
+ server.listen(PORT, () => {
+ console.log(`🚀 API Server is running on http://localhost:${PORT}`);
+ logger.log('DRAGONSPLOIT KERNEL v2.4 OPERATIONAL', 'success');
+ logger.log('WEBSOCKET HANDSHAKE CHANNEL OPENED', 'info');
});
// --- Graceful Shutdown Handler ---
diff --git a/backend/src/middleware/auth.ts b/backend/src/middleware/auth.ts
new file mode 100644
index 0000000..57be76c
--- /dev/null
+++ b/backend/src/middleware/auth.ts
@@ -0,0 +1,60 @@
+import { Request, Response, NextFunction } from 'express';
+import jwt from 'jsonwebtoken';
+
+// توسيع واجهة الطلب (Request) في Express لإضافة خاصية 'kullanici'
+// هذا يسمح لنا بتخزين بيانات المستخدم من التوكن في الطلب نفسه
+declare global {
+ namespace Express {
+ interface Request {
+ kullanici?: any; // يمكنك استخدام واجهة أكثر تحديدًا بدلاً من 'any'
+ }
+ }
+}
+
+/**
+ * Middleware للتحقق من صحة توكن JWT
+ * @param req - كائن الطلب
+ * @param res - كائن الاستجابة
+ * @param next - دالة للانتقال إلى الـ Middleware التالي أو وحدة التحكم
+ */
+export const kimlikDoğrula = (req: Request, res: Response, next: NextFunction) => {
+ // استخراج التوكن من الهيدر 'Authorization'
+ // الشكل المتوقع: "Bearer "
+ const authHeader = req.headers['authorization'];
+ const token = authHeader && authHeader.split(' ')[1];
+
+ // إذا لم يتم توفير التوكن
+ if (token == null) {
+ return res.status(401).json({ mesaj: 'Yetkisiz: Erişim tokeni gerekli.' }); // Unauthorized
+ }
+
+ // --- بداية التعديل الرئيسي ---
+
+ // 1. اقرأ المفتاح السري الصحيح من متغيرات البيئة
+ const secret = process.env.JWT_ACCESS_SECRET;
+
+ // 2. تحقق من أن المفتاح السري موجود بالفعل
+ if (!secret) {
+ // هذا خطأ فادح في إعدادات الخادم ويجب أن يوقف العملية
+ console.error("FATAL ERROR: JWT_ACCESS_SECRET is not defined in the .env file.");
+ return res.status(500).json({ mesaj: "خطأ في إعدادات الخادم: مفتاح المصادقة غير موجود." });
+ }
+
+ // 3. التحقق من صحة التوكن باستخدام المفتاح السري الصحيح
+ jwt.verify(token, secret, (err: any, kullanici: any) => {
+ // إذا كان التوكن غير صالح (منتهي الصلاحية، تالف، إلخ)
+ if (err) {
+ // يمكنك إبقاء هذا السطر مؤقتًا لتصحيح الأخطاء
+ // console.error('JWT Verify Error:', err.message);
+ return res.status(403).json({ mesaj: 'Yasak: Geçersiz veya süresi dolmuş token.' }); // Forbidden
+ }
+
+ // إذا كان التوكن صالحًا، قم بتخزين بيانات المستخدم في كائن الطلب
+ // تعيين 'sub' إلى 'id' لضمان التوافق مع وحدات التحكم التي تتوقع 'id'
+ req.kullanici = { ...kullanici, id: kullanici.sub || kullanici.id };
+
+ // اسمح للطلب بالمرور إلى وجهته التالية
+ next();
+ });
+ // --- نهاية التعديل الرئيسي ---
+};
diff --git a/backend/src/middleware/security.ts b/backend/src/middleware/security.ts
index cd49bf9..f932eef 100644
--- a/backend/src/middleware/security.ts
+++ b/backend/src/middleware/security.ts
@@ -13,10 +13,10 @@ export const setupSecurity = (app: Express) => {
// 2. Rate limiting
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
- max: 100, // Limit each IP to 100 requests per windowMs
+ max: process.env.NODE_ENV === 'production' ? 100 : 1000, // 100 for prod, 1000 for dev
message: 'Too many requests from this IP, please try again later.',
- standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers
- legacyHeaders: false, // Disable the `X-RateLimit-*` headers
+ standardHeaders: true,
+ legacyHeaders: false,
});
// Apply rate limiting to all requests
diff --git a/backend/src/routes/kurum.ts b/backend/src/routes/kurum.ts
index ff6dc8c..1206fab 100644
--- a/backend/src/routes/kurum.ts
+++ b/backend/src/routes/kurum.ts
@@ -1,7 +1,7 @@
import { Router } from 'express';
import { body } from 'express-validator';
import { kurumOlustur, kurumlariListele } from '../controllers/kurum';
-import { kimlikDoğrula } from '../middlewares/auth';
+import { kimlikDoğrula } from '../middleware/auth';
import { validate } from '../utils/validate';
const organizationRouter = Router();
diff --git a/backend/src/routes/scans.ts b/backend/src/routes/scans.ts
index d4c6961..0ddc1ff 100644
--- a/backend/src/routes/scans.ts
+++ b/backend/src/routes/scans.ts
@@ -1,7 +1,7 @@
import { Router } from 'express';
import { body, query, param } from 'express-validator';
import { validate } from '../utils/validate';
-import { kimlikDoğrula } from '../middlewares/auth';
+import { kimlikDoğrula } from '../middleware/auth';
import * as scanController from '../controllers/scans';
const router = Router();
diff --git a/backend/src/routes/target.ts b/backend/src/routes/target.ts
index fec37bb..5ca0166 100644
--- a/backend/src/routes/target.ts
+++ b/backend/src/routes/target.ts
@@ -1,6 +1,6 @@
import { Router } from 'express';
import { body, query, param } from 'express-validator'; // استيراد query و param
-import { kimlikDoğrula } from '../middlewares/auth';
+import { kimlikDoğrula } from '../middleware/auth';
import { validate } from '../utils/validate'; // إضافة validate
import {
hedefOlustur,
diff --git a/backend/src/routes/vulnerability.ts b/backend/src/routes/vulnerability.ts
new file mode 100644
index 0000000..dde58ed
--- /dev/null
+++ b/backend/src/routes/vulnerability.ts
@@ -0,0 +1,46 @@
+import { Router } from 'express';
+import { query } from 'express-validator';
+import { validate } from '../utils/validate';
+import { kimlikDoğrula } from '../middleware/auth';
+import * as vulnerabilityController from '../controllers/vulnerability';
+
+const router = Router();
+
+const listVulnValidation = [
+ query('organizationId')
+ .notEmpty().withMessage('Organization ID is required')
+ .isString().withMessage('Organization ID must be a string'),
+ validate,
+];
+
+/**
+ * @swagger
+ * /vulnerabilities:
+ * get:
+ * summary: Lists all vulnerabilities for an organization across all scans
+ * tags: [Vulnerabilities]
+ * security:
+ * - bearerAuth: []
+ * parameters:
+ * - in: query
+ * name: organizationId
+ * schema:
+ * type: string
+ * required: true
+ * description: The ID of the organization to list vulnerabilities for.
+ * responses:
+ * 200:
+ * description: A list of vulnerabilities was successfully retrieved.
+ * content:
+ * application/json:
+ * schema:
+ * type: object
+ * properties:
+ * data:
+ * type: array
+ * items:
+ * $ref: '#/components/schemas/Vulnerability'
+ */
+router.get('/', kimlikDoğrula, listVulnValidation, vulnerabilityController.listVulnerabilities);
+
+export default router;
diff --git a/backend/src/services/kullanici.ts b/backend/src/services/kullanici.ts
index 20d39a5..13106ba 100644
--- a/backend/src/services/kullanici.ts
+++ b/backend/src/services/kullanici.ts
@@ -24,7 +24,7 @@ interface KullaniciOlusturmaVerisi {
*/
export const registerUserAndCreateOrg = async (veri: KullaniciOlusturmaVerisi) => {
try {
- const newUser = await prisma.$transaction(async (tx) => {
+ const { user: newUserWithoutPassword, organizationId } = await prisma.$transaction(async (tx) => {
// 1. إنشاء المستخدم
const user = await tx.user.create({
data: {
@@ -51,12 +51,11 @@ export const registerUserAndCreateOrg = async (veri: KullaniciOlusturmaVerisi) =
},
});
- return user;
+ const { password, ...userWithoutPassword } = user;
+ return { user: userWithoutPassword, organizationId: organization.id };
});
- // إرجاع المستخدم بدون كلمة المرور
- const { password, ...userWithoutPassword } = newUser;
- return userWithoutPassword;
+ return { user: newUserWithoutPassword, organizationId };
} catch (hata) {
if (hata instanceof Prisma.PrismaClientKnownRequestError && hata.code === 'P2002') {
diff --git a/backend/src/services/scans.ts b/backend/src/services/scans.ts
index 8451ac5..840c72f 100644
--- a/backend/src/services/scans.ts
+++ b/backend/src/services/scans.ts
@@ -26,8 +26,15 @@ const getTechnologyFingerprint = async (targetUrl: string): Promise => {
export const initiateScan = async (
userId: string,
targetId: string,
+ profile: string = 'balanced',
configurationId?: string
) => {
+ // Validate profile
+ const validProfiles = ['lightning', 'balanced', 'deep'];
+ if (!validProfiles.includes(profile)) {
+ throw new Error(`Invalid scan profile: ${profile}. Must be one of: ${validProfiles.join(', ')}`);
+ }
+
// 1. ابحث عن الهدف أولاً.
const target = await prisma.target.findUnique({
where: { id: targetId },
@@ -81,11 +88,11 @@ export const initiateScan = async (
});
// 5. أضف مهمة جديدة إلى قائمة الانتظار.
- // 🛑 لاحظ: تم استخدام await قبل create لضمان أن scan.id موجود في DB قبل الإرسال للطابور.
await scanQueue.add('scan-job', {
scanId: scan.id,
- targetUrl: target.url, // 🆕 إرسال الـ URL مباشرةً لتجنب البحث في DB
- technologyFingerprint: techFingerprint, // 🆕 إرسال البصمة مباشرةً للعامل
+ targetUrl: target.url,
+ technologyFingerprint: techFingerprint,
+ profile: profile, // 🆕 Passing the tactical profile (lightning, balanced, deep)
});
console.log(`✅ Scan job added to queue for scanId: ${scan.id}`);
diff --git a/backend/src/services/vulnerability.ts b/backend/src/services/vulnerability.ts
new file mode 100644
index 0000000..20a55f6
--- /dev/null
+++ b/backend/src/services/vulnerability.ts
@@ -0,0 +1,46 @@
+import { prisma } from '../db';
+import { ForbiddenError } from '../utils/errors';
+
+/**
+ * Lists all vulnerabilities for a specific organization across all scans.
+ * @param userId - ID of the user requesting the list.
+ * @param organizationId - ID of the organization.
+ * @returns List of vulnerabilities with their associated scan and target info.
+ */
+export const listVulnerabilitiesForOrg = async (userId: string, organizationId: string) => {
+ // Check membership
+ const membership = await prisma.membership.findUnique({
+ where: {
+ userId_organizationId: {
+ userId: userId,
+ organizationId: organizationId,
+ },
+ },
+ });
+
+ if (!membership) {
+ throw new ForbiddenError('You are not a member of this organization');
+ }
+
+ const vulnerabilities = await prisma.vulnerability.findMany({
+ where: {
+ scan: {
+ organizationId: organizationId,
+ },
+ },
+ include: {
+ scan: {
+ include: {
+ target: {
+ select: { name: true, url: true },
+ },
+ },
+ },
+ },
+ orderBy: {
+ foundAt: 'desc',
+ },
+ });
+
+ return vulnerabilities;
+};
diff --git a/backend/src/utils/logger.ts b/backend/src/utils/logger.ts
new file mode 100644
index 0000000..9af6ae6
--- /dev/null
+++ b/backend/src/utils/logger.ts
@@ -0,0 +1,67 @@
+import { Server as SocketIOServer } from 'socket.io';
+import { Server as HTTPServer } from 'http';
+
+class LoggerService {
+ private io: SocketIOServer | null = null;
+
+ init(server: HTTPServer) {
+ this.io = new SocketIOServer(server, {
+ cors: {
+ origin: ['http://localhost:5173', 'http://127.0.0.1:5173'],
+ methods: ['GET', 'POST'],
+ credentials: true
+ }
+ });
+
+ this.io.on('connection', (socket) => {
+ console.log(`[WebSocket] Operator connected: ${socket.id}`);
+
+ socket.on('join_terminal', () => {
+ socket.join('terminal_logs');
+ console.log(`[WebSocket] Operator ${socket.id} joined terminal chamber.`);
+ this.log('OPERATOR_LINK_ESTABLISHED :: ENCRYPTED_TUNNEL_ACTIVE', 'success');
+ });
+
+ socket.on('execute_command', (data: { command: string }) => {
+ this.log(`COMMAND_INPUT :: ${data.command}`, 'command');
+ this.processRemoteCommand(data.command);
+ });
+
+ socket.on('disconnect', () => {
+ console.log(`[WebSocket] Operator disconnected: ${socket.id}`);
+ });
+ });
+ }
+
+ private processRemoteCommand(cmd: string) {
+ const command = cmd.toLowerCase().trim();
+
+ if (command === 'status') {
+ this.log('NODE_STATUS :: ALL_SYSTEMS_OPERATIONAL', 'success');
+ } else if (command === 'list agents') {
+ this.log('ACTIVE_AGENTS :: [AGENT_01, AGENT_02, EDGE_NODE_09]', 'info');
+ } else if (command === 'whoami') {
+ this.log('IDENTITY :: DRAGONSPLOIT_OPERATOR_LEVEL_1', 'info');
+ } else {
+ this.log(`REMOTE_EXEC_ERROR :: Unknown or unauthorized command: ${command}`, 'error');
+ }
+ }
+
+ /**
+ * Broadcasts a log message to all connected clients in the terminal room.
+ */
+ log(content: string, type: 'info' | 'success' | 'warning' | 'error' | 'command' = 'info') {
+ if (this.io) {
+ this.io.to('terminal_logs').emit('terminal_log', {
+ id: Math.random().toString(36).substring(7),
+ timestamp: new Date().toLocaleTimeString(),
+ type,
+ content
+ });
+ }
+ // Also log to console for backend visibility
+ console.log(`[TerminalLog] [${type.toUpperCase()}] ${content}`);
+ }
+}
+
+export const logger = new LoggerService();
diff --git a/backend/src/worker/jobs/scan.processor.ts b/backend/src/worker/jobs/scan.processor.ts
index d4c3e5e..cf9d4ec 100644
--- a/backend/src/worker/jobs/scan.processor.ts
+++ b/backend/src/worker/jobs/scan.processor.ts
@@ -5,6 +5,7 @@ import { ScanStatus } from '@prisma/client';
import axios, { AxiosResponse } from 'axios';
import { prisma } from '../../db';
import { SCOUT_PERSONA, WARRIOR_PERSONA, ELDER_PERSONA, AttackerPersona } from '../config/personas';
+import { logger } from '../../utils/logger';
// --- بداية الدمج ---
// استيراد جميع الطوابير المتخصصة التي أنشأناها
@@ -43,7 +44,7 @@ interface TechnologyFingerprint {
*/
export const processScanJob = async (job: Job): Promise => {
const { scanId, targetUrl, profile } = job.data;
- console.log(`[Orchestrator] Starting orchestration for scan ID: ${scanId} on URL: ${targetUrl}`);
+ logger.log(`[Orchestrator] Starting orchestration for scan ID: ${scanId} on URL: ${targetUrl}`, 'info');
// Determine Persona based on profile string
let selectedPersona: AttackerPersona = WARRIOR_PERSONA; // Default
@@ -66,10 +67,10 @@ export const processScanJob = async (job: Job): Promise => {
headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' },
});
const fingerprint = analyzeResponse(response);
- console.log(`[Orchestrator] Fingerprint for ${targetUrl}:`, fingerprint);
-
+ logger.log(`[Orchestrator] Technology fingerprint identified for ${targetUrl}`, 'success');
+
// --- بداية منطق التنسيق المحدث والكامل ---
- console.log(`[Orchestrator] Analyzing fingerprint and dispatching specialized jobs...`);
+ logger.log(`[Orchestrator] Dispatching specialized agents for analysis...`, 'info');
let dispatchedJobsCount = 0;
// Pass Persona to all sub-jobs
@@ -107,20 +108,19 @@ export const processScanJob = async (job: Job): Promise => {
// في المستقبل، يمكن أن تكون هذه أكثر ذكاءً وتعتمد على نقاط الإدخال المكتشفة
await sqliQueue.add('sqli-check-job', jobPayload);
dispatchedJobsCount++;
- await xssQueue.add('xss-check-job', jobPayload);
- dispatchedJobsCount++;
+ // await xssQueue.add('xss-check-job', jobPayload); // Disabled - Focus on SQLi only
+ // dispatchedJobsCount++;
console.log(`[Orchestrator] Dispatched a total of ${dispatchedJobsCount} specialized jobs.`);
// --- نهاية منطق التنسيق ---
- // تحديث الفحص الرئيسي وتخزين البصمة
+ // Update scan status only (remove technologyFingerprint - not in schema)
await prisma.scan.update({
where: { id: scanId },
data: {
status: 'COMPLETED',
completedAt: new Date(),
- technologyFingerprint: fingerprint as any,
},
});
diff --git a/backend/src/worker/jobs/sqli-param.ts b/backend/src/worker/jobs/sqli-param.ts
index a350774..0db26b3 100644
--- a/backend/src/worker/jobs/sqli-param.ts
+++ b/backend/src/worker/jobs/sqli-param.ts
@@ -35,7 +35,7 @@ async function detectFingerprint(targetUrl: string): Promise {
// We use a harmless HEAD request first
const response = await axios.head(targetUrl, {
validateStatus: () => true,
- timeout: 5000
+ timeout: 15000
});
const headers = response.headers;
@@ -45,7 +45,7 @@ async function detectFingerprint(targetUrl: string): Promise {
// Use the Engine for Passive Analysis
const passiveResult = FingerprintEngine.analyzePassive(headers, cookies);
- fingerprint = passiveResult;
+ fingerprint = { ...fingerprint, ...passiveResult };
if (fingerprint.confidence > 0) {
console.log(`[Fingerprint] 💡 Passive Match: ${JSON.stringify(fingerprint)}`);
@@ -59,7 +59,7 @@ async function detectFingerprint(targetUrl: string): Promise {
try {
const errResponse = await axios.get(errorUrl, {
validateStatus: () => true,
- timeout: 5000
+ timeout: 15000
});
const body = typeof errResponse.data === 'string' ? errResponse.data : JSON.stringify(errResponse.data);
@@ -81,7 +81,7 @@ async function detectFingerprint(targetUrl: string): Promise {
console.log(`[Fingerprint] ❌ Fingerprinting failed: ${error.message}`);
}
- console.log(`[Fingerprint] 📝 FINAL REPORT: [DB: ${fingerprint.db}] | [Server: ${fingerprint.server}] | [Lang: ${fingerprint.lang}]`);
+ console.log(`[Fingerprint] 📝 FINAL REPORT: [DB: ${fingerprint.db || 'Unknown'}] | [Server: ${fingerprint.server || 'Unknown'}] | [Lang: ${fingerprint.lang || 'Unknown'}]`);
return fingerprint;
}
@@ -310,15 +310,9 @@ export const processSqliParamJob = async (job: Job, prisma: PrismaClient): Promi
successfulFindings++;
state = 'CONFIRMED';
}
- else if (hasHighConfidence) {
- console.log(`[${persona.name}] 💥 Confirmed by SQL Error Signature: "${errorSignature}"`);
- await recordVulnerability(prisma, scanId, VulnerabilityType.SQL_INJECTION, Severity.HIGH, `SQL Injection (Error-Based) in '${param}'`, `Payload: ${aiResponse.payload}\nError: ${errorSignature}`, targetUrl, aiResponse.payload);
- successfulFindings++;
- state = 'CONFIRMED';
- }
else if (hasHighConfidence) {
console.log(`[${persona.name}] 💥 Confirmed by AI High Confidence (${aiResponse.confidence}%).`);
- await recordVulnerability(prisma, scanId, VulnerabilityType.SQL_INJECTION, Severity.HIGH, `SQL Injection (AI-Verified) in '${param}'`, `Payload: ${aiResponse.payload}\nReasoning: ${aiResponse.reasoning}`, targetUrl, aiResponse.payload);
+ await recordVulnerability(prisma, scanId, VulnerabilityType.SQL_INJECTION, Severity.MEDIUM, `SQL Injection (AI-Verified) in '${param}'`, `Payload: ${aiResponse.payload}\nReasoning: ${aiResponse.reasoning}`, targetUrl, aiResponse.payload);
successfulFindings++;
state = 'CONFIRMED';
}
diff --git a/frontend/.gitignore b/frontend/.gitignore
new file mode 100644
index 0000000..a547bf3
--- /dev/null
+++ b/frontend/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/frontend/README.md b/frontend/README.md
new file mode 100644
index 0000000..d2e7761
--- /dev/null
+++ b/frontend/README.md
@@ -0,0 +1,73 @@
+# React + TypeScript + Vite
+
+This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
+
+Currently, two official plugins are available:
+
+- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
+- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
+
+## React Compiler
+
+The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
+
+## Expanding the ESLint configuration
+
+If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
+
+```js
+export default defineConfig([
+ globalIgnores(['dist']),
+ {
+ files: ['**/*.{ts,tsx}'],
+ extends: [
+ // Other configs...
+
+ // Remove tseslint.configs.recommended and replace with this
+ tseslint.configs.recommendedTypeChecked,
+ // Alternatively, use this for stricter rules
+ tseslint.configs.strictTypeChecked,
+ // Optionally, add this for stylistic rules
+ tseslint.configs.stylisticTypeChecked,
+
+ // Other configs...
+ ],
+ languageOptions: {
+ parserOptions: {
+ project: ['./tsconfig.node.json', './tsconfig.app.json'],
+ tsconfigRootDir: import.meta.dirname,
+ },
+ // other options...
+ },
+ },
+])
+```
+
+You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
+
+```js
+// eslint.config.js
+import reactX from 'eslint-plugin-react-x'
+import reactDom from 'eslint-plugin-react-dom'
+
+export default defineConfig([
+ globalIgnores(['dist']),
+ {
+ files: ['**/*.{ts,tsx}'],
+ extends: [
+ // Other configs...
+ // Enable lint rules for React
+ reactX.configs['recommended-typescript'],
+ // Enable lint rules for React DOM
+ reactDom.configs.recommended,
+ ],
+ languageOptions: {
+ parserOptions: {
+ project: ['./tsconfig.node.json', './tsconfig.app.json'],
+ tsconfigRootDir: import.meta.dirname,
+ },
+ // other options...
+ },
+ },
+])
+```
diff --git a/frontend/eslint.config.js b/frontend/eslint.config.js
new file mode 100644
index 0000000..5e6b472
--- /dev/null
+++ b/frontend/eslint.config.js
@@ -0,0 +1,23 @@
+import js from '@eslint/js'
+import globals from 'globals'
+import reactHooks from 'eslint-plugin-react-hooks'
+import reactRefresh from 'eslint-plugin-react-refresh'
+import tseslint from 'typescript-eslint'
+import { defineConfig, globalIgnores } from 'eslint/config'
+
+export default defineConfig([
+ globalIgnores(['dist']),
+ {
+ files: ['**/*.{ts,tsx}'],
+ extends: [
+ js.configs.recommended,
+ tseslint.configs.recommended,
+ reactHooks.configs.flat.recommended,
+ reactRefresh.configs.vite,
+ ],
+ languageOptions: {
+ ecmaVersion: 2020,
+ globals: globals.browser,
+ },
+ },
+])
diff --git a/frontend/index.html b/frontend/index.html
new file mode 100644
index 0000000..a6ca7e7
--- /dev/null
+++ b/frontend/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ DragonSploit
+
+
+
+
+
+
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
new file mode 100644
index 0000000..fc5a059
--- /dev/null
+++ b/frontend/package-lock.json
@@ -0,0 +1,5312 @@
+{
+ "name": "frontend",
+ "version": "0.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "frontend",
+ "version": "0.0.0",
+ "dependencies": {
+ "@react-three/drei": "^10.7.7",
+ "@react-three/fiber": "^9.5.0",
+ "@tailwindcss/postcss": "^4.1.18",
+ "@tailwindcss/vite": "^4.1.18",
+ "@tanstack/react-query": "^5.90.17",
+ "@types/three": "^0.182.0",
+ "autoprefixer": "^10.4.23",
+ "axios": "^1.13.2",
+ "clsx": "^2.1.1",
+ "dompurify": "^3.3.1",
+ "framer-motion": "^12.26.2",
+ "i18next": "^25.7.4",
+ "i18next-browser-languagedetector": "^8.2.0",
+ "is-hotkey": "^0.2.0",
+ "jspdf": "^4.0.0",
+ "jspdf-autotable": "^5.0.7",
+ "lucide-react": "^0.562.0",
+ "postcss": "^8.5.6",
+ "react": "^19.2.0",
+ "react-dom": "^19.2.0",
+ "react-i18next": "^16.5.3",
+ "react-router-dom": "^7.12.0",
+ "socket.io-client": "^4.8.3",
+ "tailwind-merge": "^3.4.0",
+ "tailwindcss": "^4.1.18",
+ "three": "^0.182.0",
+ "zustand": "^5.0.10"
+ },
+ "devDependencies": {
+ "@eslint/js": "^9.39.1",
+ "@types/node": "^24.10.8",
+ "@types/react": "^19.2.5",
+ "@types/react-dom": "^19.2.3",
+ "@vitejs/plugin-react": "^5.1.1",
+ "eslint": "^9.39.1",
+ "eslint-plugin-react-hooks": "^7.0.1",
+ "eslint-plugin-react-refresh": "^0.4.24",
+ "globals": "^16.5.0",
+ "typescript": "~5.9.3",
+ "typescript-eslint": "^8.46.4",
+ "vite": "^7.2.4"
+ }
+ },
+ "node_modules/@alloc/quick-lru": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
+ "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz",
+ "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.28.5",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.6.tgz",
+ "integrity": "sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz",
+ "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.28.6",
+ "@babel/generator": "^7.28.6",
+ "@babel/helper-compilation-targets": "^7.28.6",
+ "@babel/helper-module-transforms": "^7.28.6",
+ "@babel/helpers": "^7.28.6",
+ "@babel/parser": "^7.28.6",
+ "@babel/template": "^7.28.6",
+ "@babel/traverse": "^7.28.6",
+ "@babel/types": "^7.28.6",
+ "@jridgewell/remapping": "^2.3.5",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.6.tgz",
+ "integrity": "sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.28.6",
+ "@babel/types": "^7.28.6",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz",
+ "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.28.6",
+ "@babel/helper-validator-option": "^7.27.1",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-globals": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
+ "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz",
+ "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.28.6",
+ "@babel/types": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz",
+ "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.28.6",
+ "@babel/helper-validator-identifier": "^7.28.5",
+ "@babel/traverse": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz",
+ "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
+ "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
+ "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz",
+ "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.28.6",
+ "@babel/types": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz",
+ "integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.28.6"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz",
+ "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-source": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz",
+ "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz",
+ "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
+ "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.28.6",
+ "@babel/parser": "^7.28.6",
+ "@babel/types": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.6.tgz",
+ "integrity": "sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.28.6",
+ "@babel/generator": "^7.28.6",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/parser": "^7.28.6",
+ "@babel/template": "^7.28.6",
+ "@babel/types": "^7.28.6",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz",
+ "integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@dimforge/rapier3d-compat": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz",
+ "integrity": "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz",
+ "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz",
+ "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz",
+ "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz",
+ "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz",
+ "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz",
+ "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz",
+ "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz",
+ "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz",
+ "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz",
+ "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz",
+ "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz",
+ "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz",
+ "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz",
+ "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz",
+ "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz",
+ "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz",
+ "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz",
+ "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz",
+ "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz",
+ "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz",
+ "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz",
+ "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz",
+ "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz",
+ "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz",
+ "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz",
+ "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
+ "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.2",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
+ "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.21.1",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz",
+ "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.7",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz",
+ "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.17.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/core": {
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
+ "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz",
+ "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.1",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "9.39.2",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz",
+ "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz",
+ "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz",
+ "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.17.0",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@humanfs/core": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
+ "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node": {
+ "version": "0.16.7",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz",
+ "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanfs/core": "^0.19.1",
+ "@humanwhocodes/retry": "^0.4.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
+ "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@mediapipe/tasks-vision": {
+ "version": "0.10.17",
+ "resolved": "https://registry.npmjs.org/@mediapipe/tasks-vision/-/tasks-vision-0.10.17.tgz",
+ "integrity": "sha512-CZWV/q6TTe8ta61cZXjfnnHsfWIdFhms03M9T7Cnd5y2mdpylJM0rF1qRq+wsQVRMLz1OYPVEBU9ph2Bx8cxrg==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@monogrid/gainmap-js": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/@monogrid/gainmap-js/-/gainmap-js-3.4.0.tgz",
+ "integrity": "sha512-2Z0FATFHaoYJ8b+Y4y4Hgfn3FRFwuU5zRrk+9dFWp4uGAdHGqVEdP7HP+gLA3X469KXHmfupJaUbKo1b/aDKIg==",
+ "license": "MIT",
+ "dependencies": {
+ "promise-worker-transferable": "^1.0.4"
+ },
+ "peerDependencies": {
+ "three": ">= 0.159.0"
+ }
+ },
+ "node_modules/@react-three/drei": {
+ "version": "10.7.7",
+ "resolved": "https://registry.npmjs.org/@react-three/drei/-/drei-10.7.7.tgz",
+ "integrity": "sha512-ff+J5iloR0k4tC++QtD/j9u3w5fzfgFAWDtAGQah9pF2B1YgOq/5JxqY0/aVoQG5r3xSZz0cv5tk2YuBob4xEQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.26.0",
+ "@mediapipe/tasks-vision": "0.10.17",
+ "@monogrid/gainmap-js": "^3.0.6",
+ "@use-gesture/react": "^10.3.1",
+ "camera-controls": "^3.1.0",
+ "cross-env": "^7.0.3",
+ "detect-gpu": "^5.0.56",
+ "glsl-noise": "^0.0.0",
+ "hls.js": "^1.5.17",
+ "maath": "^0.10.8",
+ "meshline": "^3.3.1",
+ "stats-gl": "^2.2.8",
+ "stats.js": "^0.17.0",
+ "suspend-react": "^0.1.3",
+ "three-mesh-bvh": "^0.8.3",
+ "three-stdlib": "^2.35.6",
+ "troika-three-text": "^0.52.4",
+ "tunnel-rat": "^0.1.2",
+ "use-sync-external-store": "^1.4.0",
+ "utility-types": "^3.11.0",
+ "zustand": "^5.0.1"
+ },
+ "peerDependencies": {
+ "@react-three/fiber": "^9.0.0",
+ "react": "^19",
+ "react-dom": "^19",
+ "three": ">=0.159"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@react-three/fiber": {
+ "version": "9.5.0",
+ "resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-9.5.0.tgz",
+ "integrity": "sha512-FiUzfYW4wB1+PpmsE47UM+mCads7j2+giRBltfwH7SNhah95rqJs3ltEs9V3pP8rYdS0QlNne+9Aj8dS/SiaIA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.17.8",
+ "@types/webxr": "*",
+ "base64-js": "^1.5.1",
+ "buffer": "^6.0.3",
+ "its-fine": "^2.0.0",
+ "react-use-measure": "^2.1.7",
+ "scheduler": "^0.27.0",
+ "suspend-react": "^0.1.3",
+ "use-sync-external-store": "^1.4.0",
+ "zustand": "^5.0.3"
+ },
+ "peerDependencies": {
+ "expo": ">=43.0",
+ "expo-asset": ">=8.4",
+ "expo-file-system": ">=11.0",
+ "expo-gl": ">=11.0",
+ "react": ">=19 <19.3",
+ "react-dom": ">=19 <19.3",
+ "react-native": ">=0.78",
+ "three": ">=0.156"
+ },
+ "peerDependenciesMeta": {
+ "expo": {
+ "optional": true
+ },
+ "expo-asset": {
+ "optional": true
+ },
+ "expo-file-system": {
+ "optional": true
+ },
+ "expo-gl": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rolldown/pluginutils": {
+ "version": "1.0.0-beta.53",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.53.tgz",
+ "integrity": "sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.55.1.tgz",
+ "integrity": "sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.55.1.tgz",
+ "integrity": "sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.55.1.tgz",
+ "integrity": "sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.55.1.tgz",
+ "integrity": "sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.55.1.tgz",
+ "integrity": "sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.55.1.tgz",
+ "integrity": "sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.55.1.tgz",
+ "integrity": "sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.55.1.tgz",
+ "integrity": "sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.55.1.tgz",
+ "integrity": "sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.55.1.tgz",
+ "integrity": "sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.55.1.tgz",
+ "integrity": "sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-musl": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.55.1.tgz",
+ "integrity": "sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.55.1.tgz",
+ "integrity": "sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-musl": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.55.1.tgz",
+ "integrity": "sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.55.1.tgz",
+ "integrity": "sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.55.1.tgz",
+ "integrity": "sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.55.1.tgz",
+ "integrity": "sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.55.1.tgz",
+ "integrity": "sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.55.1.tgz",
+ "integrity": "sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openbsd-x64": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.55.1.tgz",
+ "integrity": "sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.55.1.tgz",
+ "integrity": "sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.55.1.tgz",
+ "integrity": "sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.55.1.tgz",
+ "integrity": "sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.55.1.tgz",
+ "integrity": "sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.55.1.tgz",
+ "integrity": "sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@socket.io/component-emitter": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
+ "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
+ "license": "MIT"
+ },
+ "node_modules/@tailwindcss/node": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.18.tgz",
+ "integrity": "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/remapping": "^2.3.4",
+ "enhanced-resolve": "^5.18.3",
+ "jiti": "^2.6.1",
+ "lightningcss": "1.30.2",
+ "magic-string": "^0.30.21",
+ "source-map-js": "^1.2.1",
+ "tailwindcss": "4.1.18"
+ }
+ },
+ "node_modules/@tailwindcss/oxide": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.18.tgz",
+ "integrity": "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10"
+ },
+ "optionalDependencies": {
+ "@tailwindcss/oxide-android-arm64": "4.1.18",
+ "@tailwindcss/oxide-darwin-arm64": "4.1.18",
+ "@tailwindcss/oxide-darwin-x64": "4.1.18",
+ "@tailwindcss/oxide-freebsd-x64": "4.1.18",
+ "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18",
+ "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18",
+ "@tailwindcss/oxide-linux-arm64-musl": "4.1.18",
+ "@tailwindcss/oxide-linux-x64-gnu": "4.1.18",
+ "@tailwindcss/oxide-linux-x64-musl": "4.1.18",
+ "@tailwindcss/oxide-wasm32-wasi": "4.1.18",
+ "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18",
+ "@tailwindcss/oxide-win32-x64-msvc": "4.1.18"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-android-arm64": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.18.tgz",
+ "integrity": "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-darwin-arm64": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.18.tgz",
+ "integrity": "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-darwin-x64": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.18.tgz",
+ "integrity": "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-freebsd-x64": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.18.tgz",
+ "integrity": "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.18.tgz",
+ "integrity": "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.18.tgz",
+ "integrity": "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.18.tgz",
+ "integrity": "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.18.tgz",
+ "integrity": "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-x64-musl": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.18.tgz",
+ "integrity": "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-wasm32-wasi": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.18.tgz",
+ "integrity": "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==",
+ "bundleDependencies": [
+ "@napi-rs/wasm-runtime",
+ "@emnapi/core",
+ "@emnapi/runtime",
+ "@tybys/wasm-util",
+ "@emnapi/wasi-threads",
+ "tslib"
+ ],
+ "cpu": [
+ "wasm32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "^1.7.1",
+ "@emnapi/runtime": "^1.7.1",
+ "@emnapi/wasi-threads": "^1.1.0",
+ "@napi-rs/wasm-runtime": "^1.1.0",
+ "@tybys/wasm-util": "^0.10.1",
+ "tslib": "^2.4.0"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz",
+ "integrity": "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.18.tgz",
+ "integrity": "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/postcss": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.18.tgz",
+ "integrity": "sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g==",
+ "license": "MIT",
+ "dependencies": {
+ "@alloc/quick-lru": "^5.2.0",
+ "@tailwindcss/node": "4.1.18",
+ "@tailwindcss/oxide": "4.1.18",
+ "postcss": "^8.4.41",
+ "tailwindcss": "4.1.18"
+ }
+ },
+ "node_modules/@tailwindcss/vite": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.18.tgz",
+ "integrity": "sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA==",
+ "license": "MIT",
+ "dependencies": {
+ "@tailwindcss/node": "4.1.18",
+ "@tailwindcss/oxide": "4.1.18",
+ "tailwindcss": "4.1.18"
+ },
+ "peerDependencies": {
+ "vite": "^5.2.0 || ^6 || ^7"
+ }
+ },
+ "node_modules/@tanstack/query-core": {
+ "version": "5.90.17",
+ "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.17.tgz",
+ "integrity": "sha512-hDww+RyyYhjhUfoYQ4es6pbgxY7LNiPWxt4l1nJqhByjndxJ7HIjDxTBtfvMr5HwjYavMrd+ids5g4Rfev3lVQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ }
+ },
+ "node_modules/@tanstack/react-query": {
+ "version": "5.90.17",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.17.tgz",
+ "integrity": "sha512-PGc2u9KLwohDUSchjW9MZqeDQJfJDON7y4W7REdNBgiFKxQy+Pf7eGjiFWEj5xPqKzAeHYdAb62IWI1a9UJyGQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@tanstack/query-core": "5.90.17"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "react": "^18 || ^19"
+ }
+ },
+ "node_modules/@tweenjs/tween.js": {
+ "version": "23.1.3",
+ "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz",
+ "integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==",
+ "license": "MIT"
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
+ "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
+ "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.28.2"
+ }
+ },
+ "node_modules/@types/draco3d": {
+ "version": "1.4.10",
+ "resolved": "https://registry.npmjs.org/@types/draco3d/-/draco3d-1.4.10.tgz",
+ "integrity": "sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw==",
+ "license": "MIT"
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "license": "MIT"
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "24.10.8",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.8.tgz",
+ "integrity": "sha512-r0bBaXu5Swb05doFYO2kTWHMovJnNVbCsII0fhesM8bNRlLhXIuckley4a2DaD+vOdmm5G+zGkQZAPZsF80+YQ==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~7.16.0"
+ }
+ },
+ "node_modules/@types/offscreencanvas": {
+ "version": "2019.7.3",
+ "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz",
+ "integrity": "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==",
+ "license": "MIT"
+ },
+ "node_modules/@types/pako": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@types/pako/-/pako-2.0.4.tgz",
+ "integrity": "sha512-VWDCbrLeVXJM9fihYodcLiIv0ku+AlOa/TQ1SvYOaBuyrSKgEcro95LJyIsJ4vSo6BXIxOKxiJAat04CmST9Fw==",
+ "license": "MIT"
+ },
+ "node_modules/@types/raf": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.3.tgz",
+ "integrity": "sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/@types/react": {
+ "version": "19.2.8",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.8.tgz",
+ "integrity": "sha512-3MbSL37jEchWZz2p2mjntRZtPt837ij10ApxKfgmXCTuHWagYg7iA5bqPw6C8BMPfwidlvfPI/fxOc42HLhcyg==",
+ "license": "MIT",
+ "dependencies": {
+ "csstype": "^3.2.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "19.2.3",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
+ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "^19.2.0"
+ }
+ },
+ "node_modules/@types/react-reconciler": {
+ "version": "0.28.9",
+ "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.9.tgz",
+ "integrity": "sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*"
+ }
+ },
+ "node_modules/@types/stats.js": {
+ "version": "0.17.4",
+ "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.4.tgz",
+ "integrity": "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==",
+ "license": "MIT"
+ },
+ "node_modules/@types/three": {
+ "version": "0.182.0",
+ "resolved": "https://registry.npmjs.org/@types/three/-/three-0.182.0.tgz",
+ "integrity": "sha512-WByN9V3Sbwbe2OkWuSGyoqQO8Du6yhYaXtXLoA5FkKTUJorZ+yOHBZ35zUUPQXlAKABZmbYp5oAqpA4RBjtJ/Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@dimforge/rapier3d-compat": "~0.12.0",
+ "@tweenjs/tween.js": "~23.1.3",
+ "@types/stats.js": "*",
+ "@types/webxr": ">=0.5.17",
+ "@webgpu/types": "*",
+ "fflate": "~0.8.2",
+ "meshoptimizer": "~0.22.0"
+ }
+ },
+ "node_modules/@types/trusted-types": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/@types/webxr": {
+ "version": "0.5.24",
+ "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.24.tgz",
+ "integrity": "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==",
+ "license": "MIT"
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.53.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.53.0.tgz",
+ "integrity": "sha512-eEXsVvLPu8Z4PkFibtuFJLJOTAV/nPdgtSjkGoPpddpFk3/ym2oy97jynY6ic2m6+nc5M8SE1e9v/mHKsulcJg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.12.2",
+ "@typescript-eslint/scope-manager": "8.53.0",
+ "@typescript-eslint/type-utils": "8.53.0",
+ "@typescript-eslint/utils": "8.53.0",
+ "@typescript-eslint/visitor-keys": "8.53.0",
+ "ignore": "^7.0.5",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^2.4.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^8.53.0",
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+ "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.53.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.53.0.tgz",
+ "integrity": "sha512-npiaib8XzbjtzS2N4HlqPvlpxpmZ14FjSJrteZpPxGUaYPlvhzlzUZ4mZyABo0EFrOWnvyd0Xxroq//hKhtAWg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "8.53.0",
+ "@typescript-eslint/types": "8.53.0",
+ "@typescript-eslint/typescript-estree": "8.53.0",
+ "@typescript-eslint/visitor-keys": "8.53.0",
+ "debug": "^4.4.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/project-service": {
+ "version": "8.53.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.53.0.tgz",
+ "integrity": "sha512-Bl6Gdr7NqkqIP5yP9z1JU///Nmes4Eose6L1HwpuVHwScgDPPuEWbUVhvlZmb8hy0vX9syLk5EGNL700WcBlbg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/tsconfig-utils": "^8.53.0",
+ "@typescript-eslint/types": "^8.53.0",
+ "debug": "^4.4.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.53.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.53.0.tgz",
+ "integrity": "sha512-kWNj3l01eOGSdVBnfAF2K1BTh06WS0Yet6JUgb9Cmkqaz3Jlu0fdVUjj9UI8gPidBWSMqDIglmEXifSgDT/D0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.53.0",
+ "@typescript-eslint/visitor-keys": "8.53.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/tsconfig-utils": {
+ "version": "8.53.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.53.0.tgz",
+ "integrity": "sha512-K6Sc0R5GIG6dNoPdOooQ+KtvT5KCKAvTcY8h2rIuul19vxH5OTQk7ArKkd4yTzkw66WnNY0kPPzzcmWA+XRmiA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.53.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.53.0.tgz",
+ "integrity": "sha512-BBAUhlx7g4SmcLhn8cnbxoxtmS7hcq39xKCgiutL3oNx1TaIp+cny51s8ewnKMpVUKQUGb41RAUWZ9kxYdovuw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.53.0",
+ "@typescript-eslint/typescript-estree": "8.53.0",
+ "@typescript-eslint/utils": "8.53.0",
+ "debug": "^4.4.3",
+ "ts-api-utils": "^2.4.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.53.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.53.0.tgz",
+ "integrity": "sha512-Bmh9KX31Vlxa13+PqPvt4RzKRN1XORYSLlAE+sO1i28NkisGbTtSLFVB3l7PWdHtR3E0mVMuC7JilWJ99m2HxQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "8.53.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.53.0.tgz",
+ "integrity": "sha512-pw0c0Gdo7Z4xOG987u3nJ8akL9093yEEKv8QTJ+Bhkghj1xyj8cgPaavlr9rq8h7+s6plUJ4QJYw2gCZodqmGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/project-service": "8.53.0",
+ "@typescript-eslint/tsconfig-utils": "8.53.0",
+ "@typescript-eslint/types": "8.53.0",
+ "@typescript-eslint/visitor-keys": "8.53.0",
+ "debug": "^4.4.3",
+ "minimatch": "^9.0.5",
+ "semver": "^7.7.3",
+ "tinyglobby": "^0.2.15",
+ "ts-api-utils": "^2.4.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
+ "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.53.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.53.0.tgz",
+ "integrity": "sha512-XDY4mXTez3Z1iRDI5mbRhH4DFSt46oaIFsLg+Zn97+sYrXACziXSQcSelMybnVZ5pa1P6xYkPr5cMJyunM1ZDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.9.1",
+ "@typescript-eslint/scope-manager": "8.53.0",
+ "@typescript-eslint/types": "8.53.0",
+ "@typescript-eslint/typescript-estree": "8.53.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.53.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.53.0.tgz",
+ "integrity": "sha512-LZ2NqIHFhvFwxG0qZeLL9DvdNAHPGCY5dIRwBhyYeU+LfLhcStE1ImjsuTG/WaVh3XysGaeLW8Rqq7cGkPCFvw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.53.0",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@use-gesture/core": {
+ "version": "10.3.1",
+ "resolved": "https://registry.npmjs.org/@use-gesture/core/-/core-10.3.1.tgz",
+ "integrity": "sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw==",
+ "license": "MIT"
+ },
+ "node_modules/@use-gesture/react": {
+ "version": "10.3.1",
+ "resolved": "https://registry.npmjs.org/@use-gesture/react/-/react-10.3.1.tgz",
+ "integrity": "sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g==",
+ "license": "MIT",
+ "dependencies": {
+ "@use-gesture/core": "10.3.1"
+ },
+ "peerDependencies": {
+ "react": ">= 16.8.0"
+ }
+ },
+ "node_modules/@vitejs/plugin-react": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.2.tgz",
+ "integrity": "sha512-EcA07pHJouywpzsoTUqNh5NwGayl2PPVEJKUSinGGSxFGYn+shYbqMGBg6FXDqgXum9Ou/ecb+411ssw8HImJQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.28.5",
+ "@babel/plugin-transform-react-jsx-self": "^7.27.1",
+ "@babel/plugin-transform-react-jsx-source": "^7.27.1",
+ "@rolldown/pluginutils": "1.0.0-beta.53",
+ "@types/babel__core": "^7.20.5",
+ "react-refresh": "^0.18.0"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "peerDependencies": {
+ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
+ }
+ },
+ "node_modules/@webgpu/types": {
+ "version": "0.1.69",
+ "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.69.tgz",
+ "integrity": "sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "license": "MIT"
+ },
+ "node_modules/autoprefixer": {
+ "version": "10.4.23",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.23.tgz",
+ "integrity": "sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/autoprefixer"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.28.1",
+ "caniuse-lite": "^1.0.30001760",
+ "fraction.js": "^5.3.4",
+ "picocolors": "^1.1.1",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "bin": {
+ "autoprefixer": "bin/autoprefixer"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/axios": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz",
+ "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==",
+ "license": "MIT",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.4",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/base64-arraybuffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
+ "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.9.14",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.14.tgz",
+ "integrity": "sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==",
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.js"
+ }
+ },
+ "node_modules/bidi-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz",
+ "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==",
+ "license": "MIT",
+ "dependencies": {
+ "require-from-string": "^2.0.2"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
+ "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "baseline-browser-mapping": "^2.9.0",
+ "caniuse-lite": "^1.0.30001759",
+ "electron-to-chromium": "^1.5.263",
+ "node-releases": "^2.0.27",
+ "update-browserslist-db": "^1.2.0"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camera-controls": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/camera-controls/-/camera-controls-3.1.0.tgz",
+ "integrity": "sha512-w5oULNpijgTRH0ARFJJ0R5ct1nUM3R3WP7/b8A6j9uTGpRfnsypc/RBMPQV8JQDPayUe37p/TZZY1PcUr4czOQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.11.0",
+ "npm": ">=10.8.2"
+ },
+ "peerDependencies": {
+ "three": ">=0.126.1"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001764",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001764.tgz",
+ "integrity": "sha512-9JGuzl2M+vPL+pz70gtMF9sHdMFbY9FJaQBi186cHKH3pSzDvzoUJUPV6fqiKIMyXbud9ZLg4F3Yza1vJ1+93g==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/canvg": {
+ "version": "3.0.11",
+ "resolved": "https://registry.npmjs.org/canvg/-/canvg-3.0.11.tgz",
+ "integrity": "sha512-5ON+q7jCTgMp9cjpu4Jo6XbvfYwSB2Ow3kzHKfIyJfaCAOHLbdKPQqGKgfED/R5B+3TFFfe8pegYA+b423SRyA==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@babel/runtime": "^7.12.5",
+ "@types/raf": "^3.4.0",
+ "core-js": "^3.8.3",
+ "raf": "^3.4.1",
+ "regenerator-runtime": "^0.13.7",
+ "rgbcolor": "^1.0.1",
+ "stackblur-canvas": "^2.0.0",
+ "svg-pathdata": "^6.0.3"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/clsx": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cookie": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz",
+ "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/core-js": {
+ "version": "3.47.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.47.0.tgz",
+ "integrity": "sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
+ "node_modules/cross-env": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
+ "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^7.0.1"
+ },
+ "bin": {
+ "cross-env": "src/bin/cross-env.js",
+ "cross-env-shell": "src/bin/cross-env-shell.js"
+ },
+ "engines": {
+ "node": ">=10.14",
+ "npm": ">=6",
+ "yarn": ">=1"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/css-line-break": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
+ "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "utrie": "^1.0.2"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "license": "MIT"
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/detect-gpu": {
+ "version": "5.0.70",
+ "resolved": "https://registry.npmjs.org/detect-gpu/-/detect-gpu-5.0.70.tgz",
+ "integrity": "sha512-bqerEP1Ese6nt3rFkwPnGbsUF9a4q+gMmpTVVOEzoCyeCc+y7/RvJnQZJx1JwhgQI5Ntg0Kgat8Uu7XpBqnz1w==",
+ "license": "MIT",
+ "dependencies": {
+ "webgl-constants": "^1.1.1"
+ }
+ },
+ "node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dompurify": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.1.tgz",
+ "integrity": "sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==",
+ "license": "(MPL-2.0 OR Apache-2.0)",
+ "optionalDependencies": {
+ "@types/trusted-types": "^2.0.7"
+ }
+ },
+ "node_modules/draco3d": {
+ "version": "1.5.7",
+ "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.7.tgz",
+ "integrity": "sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.267",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz",
+ "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==",
+ "license": "ISC"
+ },
+ "node_modules/engine.io-client": {
+ "version": "6.6.4",
+ "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.4.tgz",
+ "integrity": "sha512-+kjUJnZGwzewFDw951CDWcwj35vMNf2fcj7xQWOctq1F2i1jkDdVvdFG9kM/BEChymCH36KgjnW0NsL58JYRxw==",
+ "license": "MIT",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.4.1",
+ "engine.io-parser": "~5.2.1",
+ "ws": "~8.18.3",
+ "xmlhttprequest-ssl": "~2.1.1"
+ }
+ },
+ "node_modules/engine.io-parser": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
+ "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.18.4",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz",
+ "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==",
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz",
+ "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.27.2",
+ "@esbuild/android-arm": "0.27.2",
+ "@esbuild/android-arm64": "0.27.2",
+ "@esbuild/android-x64": "0.27.2",
+ "@esbuild/darwin-arm64": "0.27.2",
+ "@esbuild/darwin-x64": "0.27.2",
+ "@esbuild/freebsd-arm64": "0.27.2",
+ "@esbuild/freebsd-x64": "0.27.2",
+ "@esbuild/linux-arm": "0.27.2",
+ "@esbuild/linux-arm64": "0.27.2",
+ "@esbuild/linux-ia32": "0.27.2",
+ "@esbuild/linux-loong64": "0.27.2",
+ "@esbuild/linux-mips64el": "0.27.2",
+ "@esbuild/linux-ppc64": "0.27.2",
+ "@esbuild/linux-riscv64": "0.27.2",
+ "@esbuild/linux-s390x": "0.27.2",
+ "@esbuild/linux-x64": "0.27.2",
+ "@esbuild/netbsd-arm64": "0.27.2",
+ "@esbuild/netbsd-x64": "0.27.2",
+ "@esbuild/openbsd-arm64": "0.27.2",
+ "@esbuild/openbsd-x64": "0.27.2",
+ "@esbuild/openharmony-arm64": "0.27.2",
+ "@esbuild/sunos-x64": "0.27.2",
+ "@esbuild/win32-arm64": "0.27.2",
+ "@esbuild/win32-ia32": "0.27.2",
+ "@esbuild/win32-x64": "0.27.2"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "9.39.2",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz",
+ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.8.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.21.1",
+ "@eslint/config-helpers": "^0.4.2",
+ "@eslint/core": "^0.17.0",
+ "@eslint/eslintrc": "^3.3.1",
+ "@eslint/js": "9.39.2",
+ "@eslint/plugin-kit": "^0.4.1",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.4.0",
+ "eslint-visitor-keys": "^4.2.1",
+ "espree": "^10.4.0",
+ "esquery": "^1.5.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-plugin-react-hooks": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.1.tgz",
+ "integrity": "sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.24.4",
+ "@babel/parser": "^7.24.4",
+ "hermes-parser": "^0.25.1",
+ "zod": "^3.25.0 || ^4.0.0",
+ "zod-validation-error": "^3.5.0 || ^4.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-react-refresh": {
+ "version": "0.4.26",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.26.tgz",
+ "integrity": "sha512-1RETEylht2O6FM/MvgnyvT+8K21wLqDNg4qD51Zj3guhjt433XbnnkVttHMyaVyAFD03QSV4LPS5iE3VQmO7XQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "eslint": ">=8.40"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
+ "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+ "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz",
+ "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-png": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/fast-png/-/fast-png-6.4.0.tgz",
+ "integrity": "sha512-kAqZq1TlgBjZcLr5mcN6NP5Rv4V2f22z00c3g8vRrwkcqjerx7BEhPbOnWCPqaHUl2XWQBJQvOT/FQhdMT7X/Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/pako": "^2.0.3",
+ "iobuffer": "^5.3.2",
+ "pako": "^2.1.0"
+ }
+ },
+ "node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/fflate": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
+ "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==",
+ "license": "MIT"
+ },
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
+ "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
+ "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fraction.js": {
+ "version": "5.3.4",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz",
+ "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==",
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/rawify"
+ }
+ },
+ "node_modules/framer-motion": {
+ "version": "12.26.2",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.26.2.tgz",
+ "integrity": "sha512-lflOQEdjquUi9sCg5Y1LrsZDlsjrHw7m0T9Yedvnk7Bnhqfkc89/Uha10J3CFhkL+TCZVCRw9eUGyM/lyYhXQA==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-dom": "^12.26.2",
+ "motion-utils": "^12.24.10",
+ "tslib": "^2.4.0"
+ },
+ "peerDependencies": {
+ "@emotion/is-prop-valid": "*",
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/is-prop-valid": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "16.5.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz",
+ "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/glsl-noise": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/glsl-noise/-/glsl-noise-0.0.0.tgz",
+ "integrity": "sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w==",
+ "license": "MIT"
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "license": "ISC"
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/hermes-estree": {
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz",
+ "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/hermes-parser": {
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz",
+ "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hermes-estree": "0.25.1"
+ }
+ },
+ "node_modules/hls.js": {
+ "version": "1.6.15",
+ "resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.6.15.tgz",
+ "integrity": "sha512-E3a5VwgXimGHwpRGV+WxRTKeSp2DW5DI5MWv34ulL3t5UNmyJWCQ1KmLEHbYzcfThfXG8amBL+fCYPneGHC4VA==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/html-parse-stringify": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
+ "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
+ "license": "MIT",
+ "dependencies": {
+ "void-elements": "3.1.0"
+ }
+ },
+ "node_modules/html2canvas": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
+ "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "css-line-break": "^2.1.0",
+ "text-segmentation": "^1.0.3"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/i18next": {
+ "version": "25.7.4",
+ "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.7.4.tgz",
+ "integrity": "sha512-hRkpEblXXcXSNbw8mBNq9042OEetgyB/ahc/X17uV/khPwzV+uB8RHceHh3qavyrkPJvmXFKXME2Sy1E0KjAfw==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://locize.com"
+ },
+ {
+ "type": "individual",
+ "url": "https://locize.com/i18next.html"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.28.4"
+ },
+ "peerDependencies": {
+ "typescript": "^5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/i18next-browser-languagedetector": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.2.0.tgz",
+ "integrity": "sha512-P+3zEKLnOF0qmiesW383vsLdtQVyKtCNA9cjSoKCppTKPQVfKd2W8hbVo5ZhNJKDqeM7BOcvNoKJOjpHh4Js9g==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.23.2"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/immediate": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+ "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
+ "license": "MIT"
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/iobuffer": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/iobuffer/-/iobuffer-5.4.0.tgz",
+ "integrity": "sha512-DRebOWuqDvxunfkNJAlc3IzWIPD5xVxwUNbHr7xKB8E6aLJxIPfNX3CoMJghcFjpv6RWQsrcJbghtEwSPoJqMA==",
+ "license": "MIT"
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-hotkey": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/is-hotkey/-/is-hotkey-0.2.0.tgz",
+ "integrity": "sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw==",
+ "license": "MIT"
+ },
+ "node_modules/is-promise": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
+ "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==",
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "license": "ISC"
+ },
+ "node_modules/its-fine": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/its-fine/-/its-fine-2.0.0.tgz",
+ "integrity": "sha512-KLViCmWx94zOvpLwSlsx6yOCeMhZYaxrJV87Po5k/FoZzcPSahvK5qJ7fYhS61sZi5ikmh2S3Hz55A2l3U69ng==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/react-reconciler": "^0.28.9"
+ },
+ "peerDependencies": {
+ "react": "^19.0.0"
+ }
+ },
+ "node_modules/jiti": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
+ "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
+ "license": "MIT",
+ "bin": {
+ "jiti": "lib/jiti-cli.mjs"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
+ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/jspdf": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jspdf/-/jspdf-4.0.0.tgz",
+ "integrity": "sha512-w12U97Z6edKd2tXDn3LzTLg7C7QLJlx0BPfM3ecjK2BckUl9/81vZ+r5gK4/3KQdhAcEZhENUxRhtgYBj75MqQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.28.4",
+ "fast-png": "^6.2.0",
+ "fflate": "^0.8.1"
+ },
+ "optionalDependencies": {
+ "canvg": "^3.0.11",
+ "core-js": "^3.6.0",
+ "dompurify": "^3.2.4",
+ "html2canvas": "^1.0.0-rc.5"
+ }
+ },
+ "node_modules/jspdf-autotable": {
+ "version": "5.0.7",
+ "resolved": "https://registry.npmjs.org/jspdf-autotable/-/jspdf-autotable-5.0.7.tgz",
+ "integrity": "sha512-2wr7H6liNDBYNwt25hMQwXkEWFOEopgKIvR1Eukuw6Zmprm/ZcnmLTQEjW7Xx3FCbD3v7pflLcnMAv/h1jFDQw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "jspdf": "^2 || ^3 || ^4"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lie": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
+ "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
+ "license": "MIT",
+ "dependencies": {
+ "immediate": "~3.0.5"
+ }
+ },
+ "node_modules/lightningcss": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz",
+ "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==",
+ "license": "MPL-2.0",
+ "dependencies": {
+ "detect-libc": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "lightningcss-android-arm64": "1.30.2",
+ "lightningcss-darwin-arm64": "1.30.2",
+ "lightningcss-darwin-x64": "1.30.2",
+ "lightningcss-freebsd-x64": "1.30.2",
+ "lightningcss-linux-arm-gnueabihf": "1.30.2",
+ "lightningcss-linux-arm64-gnu": "1.30.2",
+ "lightningcss-linux-arm64-musl": "1.30.2",
+ "lightningcss-linux-x64-gnu": "1.30.2",
+ "lightningcss-linux-x64-musl": "1.30.2",
+ "lightningcss-win32-arm64-msvc": "1.30.2",
+ "lightningcss-win32-x64-msvc": "1.30.2"
+ }
+ },
+ "node_modules/lightningcss-android-arm64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz",
+ "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-arm64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz",
+ "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-x64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz",
+ "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-freebsd-x64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz",
+ "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz",
+ "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz",
+ "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz",
+ "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-gnu": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz",
+ "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-musl": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz",
+ "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-arm64-msvc": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz",
+ "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-x64-msvc": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz",
+ "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/lucide-react": {
+ "version": "0.562.0",
+ "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.562.0.tgz",
+ "integrity": "sha512-82hOAu7y0dbVuFfmO4bYF1XEwYk/mEbM5E+b1jgci/udUBEE/R7LF5Ip0CCEmXe8AybRM8L+04eP+LGZeDvkiw==",
+ "license": "ISC",
+ "peerDependencies": {
+ "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/maath": {
+ "version": "0.10.8",
+ "resolved": "https://registry.npmjs.org/maath/-/maath-0.10.8.tgz",
+ "integrity": "sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/three": ">=0.134.0",
+ "three": ">=0.134.0"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/meshline": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/meshline/-/meshline-3.3.1.tgz",
+ "integrity": "sha512-/TQj+JdZkeSUOl5Mk2J7eLcYTLiQm2IDzmlSvYm7ov15anEcDJ92GHqqazxTSreeNgfnYu24kiEvvv0WlbCdFQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "three": ">=0.137"
+ }
+ },
+ "node_modules/meshoptimizer": {
+ "version": "0.22.0",
+ "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.22.0.tgz",
+ "integrity": "sha512-IebiK79sqIy+E4EgOr+CAw+Ke8hAspXKzBd0JdgEmPHiAwmvEj2S4h1rfvo+o/BnfEYd/jAOg5IeeIjzlzSnDg==",
+ "license": "MIT"
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/motion-dom": {
+ "version": "12.26.2",
+ "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.26.2.tgz",
+ "integrity": "sha512-KLMT1BroY8oKNeliA3JMNJ+nbCIsTKg6hJpDb4jtRAJ7nCKnnpg/LTq/NGqG90Limitz3kdAnAVXecdFVGlWTw==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-utils": "^12.24.10"
+ }
+ },
+ "node_modules/motion-utils": {
+ "version": "12.24.10",
+ "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.24.10.tgz",
+ "integrity": "sha512-x5TFgkCIP4pPsRLpKoI86jv/q8t8FQOiM/0E8QKBzfMozWHfkKap2gA1hOki+B5g3IsBNpxbUnfOum1+dgvYww==",
+ "license": "MIT"
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.27",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
+ "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
+ "license": "MIT"
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/pako": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
+ "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==",
+ "license": "(MIT AND Zlib)"
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.6",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "license": "MIT"
+ },
+ "node_modules/potpack": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz",
+ "integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==",
+ "license": "ISC"
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/promise-worker-transferable": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/promise-worker-transferable/-/promise-worker-transferable-1.0.4.tgz",
+ "integrity": "sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "is-promise": "^2.1.0",
+ "lie": "^3.0.2"
+ }
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "license": "MIT"
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/raf": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
+ "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "performance-now": "^2.1.0"
+ }
+ },
+ "node_modules/react": {
+ "version": "19.2.3",
+ "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz",
+ "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "19.2.3",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz",
+ "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==",
+ "license": "MIT",
+ "dependencies": {
+ "scheduler": "^0.27.0"
+ },
+ "peerDependencies": {
+ "react": "^19.2.3"
+ }
+ },
+ "node_modules/react-i18next": {
+ "version": "16.5.3",
+ "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-16.5.3.tgz",
+ "integrity": "sha512-fo+/NNch37zqxOzlBYrWMx0uy/yInPkRfjSuy4lqKdaecR17nvCHnEUt3QyzA8XjQ2B/0iW/5BhaHR3ZmukpGw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.28.4",
+ "html-parse-stringify": "^3.0.1",
+ "use-sync-external-store": "^1.6.0"
+ },
+ "peerDependencies": {
+ "i18next": ">= 25.6.2",
+ "react": ">= 16.8.0",
+ "typescript": "^5"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ },
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-refresh": {
+ "version": "0.18.0",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz",
+ "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-router": {
+ "version": "7.12.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.12.0.tgz",
+ "integrity": "sha512-kTPDYPFzDVGIIGNLS5VJykK0HfHLY5MF3b+xj0/tTyNYL1gF1qs7u67Z9jEhQk2sQ98SUaHxlG31g1JtF7IfVw==",
+ "license": "MIT",
+ "dependencies": {
+ "cookie": "^1.0.1",
+ "set-cookie-parser": "^2.6.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "7.12.0",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.12.0.tgz",
+ "integrity": "sha512-pfO9fiBcpEfX4Tx+iTYKDtPbrSLLCbwJ5EqP+SPYQu1VYCXdy79GSj0wttR0U4cikVdlImZuEZ/9ZNCgoaxwBA==",
+ "license": "MIT",
+ "dependencies": {
+ "react-router": "7.12.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ }
+ },
+ "node_modules/react-use-measure": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.7.tgz",
+ "integrity": "sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=16.13",
+ "react-dom": ">=16.13"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/regenerator-runtime": {
+ "version": "0.13.11",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
+ "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/rgbcolor": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz",
+ "integrity": "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==",
+ "license": "MIT OR SEE LICENSE IN FEEL-FREE.md",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.8.15"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.55.1",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.55.1.tgz",
+ "integrity": "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.8"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.55.1",
+ "@rollup/rollup-android-arm64": "4.55.1",
+ "@rollup/rollup-darwin-arm64": "4.55.1",
+ "@rollup/rollup-darwin-x64": "4.55.1",
+ "@rollup/rollup-freebsd-arm64": "4.55.1",
+ "@rollup/rollup-freebsd-x64": "4.55.1",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.55.1",
+ "@rollup/rollup-linux-arm-musleabihf": "4.55.1",
+ "@rollup/rollup-linux-arm64-gnu": "4.55.1",
+ "@rollup/rollup-linux-arm64-musl": "4.55.1",
+ "@rollup/rollup-linux-loong64-gnu": "4.55.1",
+ "@rollup/rollup-linux-loong64-musl": "4.55.1",
+ "@rollup/rollup-linux-ppc64-gnu": "4.55.1",
+ "@rollup/rollup-linux-ppc64-musl": "4.55.1",
+ "@rollup/rollup-linux-riscv64-gnu": "4.55.1",
+ "@rollup/rollup-linux-riscv64-musl": "4.55.1",
+ "@rollup/rollup-linux-s390x-gnu": "4.55.1",
+ "@rollup/rollup-linux-x64-gnu": "4.55.1",
+ "@rollup/rollup-linux-x64-musl": "4.55.1",
+ "@rollup/rollup-openbsd-x64": "4.55.1",
+ "@rollup/rollup-openharmony-arm64": "4.55.1",
+ "@rollup/rollup-win32-arm64-msvc": "4.55.1",
+ "@rollup/rollup-win32-ia32-msvc": "4.55.1",
+ "@rollup/rollup-win32-x64-gnu": "4.55.1",
+ "@rollup/rollup-win32-x64-msvc": "4.55.1",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/scheduler": {
+ "version": "0.27.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
+ "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/set-cookie-parser": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz",
+ "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
+ "license": "MIT"
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/socket.io-client": {
+ "version": "4.8.3",
+ "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.3.tgz",
+ "integrity": "sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g==",
+ "license": "MIT",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.4.1",
+ "engine.io-client": "~6.6.1",
+ "socket.io-parser": "~4.2.4"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/socket.io-parser": {
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.5.tgz",
+ "integrity": "sha512-bPMmpy/5WWKHea5Y/jYAP6k74A+hvmRCQaJuJB6I/ML5JZq/KfNieUVo/3Mh7SAqn7TyFdIo6wqYHInG1MU1bQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.4.1"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/stackblur-canvas": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.7.0.tgz",
+ "integrity": "sha512-yf7OENo23AGJhBriGx0QivY5JP6Y1HbrrDI6WLt6C5auYZXlQrheoY8hD4ibekFKz1HOfE48Ww8kMWMnJD/zcQ==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=0.1.14"
+ }
+ },
+ "node_modules/stats-gl": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/stats-gl/-/stats-gl-2.4.2.tgz",
+ "integrity": "sha512-g5O9B0hm9CvnM36+v7SFl39T7hmAlv541tU81ME8YeSb3i1CIP5/QdDeSB3A0la0bKNHpxpwxOVRo2wFTYEosQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/three": "*",
+ "three": "^0.170.0"
+ },
+ "peerDependencies": {
+ "@types/three": "*",
+ "three": "*"
+ }
+ },
+ "node_modules/stats-gl/node_modules/three": {
+ "version": "0.170.0",
+ "resolved": "https://registry.npmjs.org/three/-/three-0.170.0.tgz",
+ "integrity": "sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ==",
+ "license": "MIT"
+ },
+ "node_modules/stats.js": {
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/stats.js/-/stats.js-0.17.0.tgz",
+ "integrity": "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==",
+ "license": "MIT"
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/suspend-react": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/suspend-react/-/suspend-react-0.1.3.tgz",
+ "integrity": "sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=17.0"
+ }
+ },
+ "node_modules/svg-pathdata": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz",
+ "integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/tailwind-merge": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.4.0.tgz",
+ "integrity": "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/dcastil"
+ }
+ },
+ "node_modules/tailwindcss": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz",
+ "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==",
+ "license": "MIT"
+ },
+ "node_modules/tapable": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz",
+ "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/text-segmentation": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
+ "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "utrie": "^1.0.2"
+ }
+ },
+ "node_modules/three": {
+ "version": "0.182.0",
+ "resolved": "https://registry.npmjs.org/three/-/three-0.182.0.tgz",
+ "integrity": "sha512-GbHabT+Irv+ihI1/f5kIIsZ+Ef9Sl5A1Y7imvS5RQjWgtTPfPnZ43JmlYI7NtCRDK9zir20lQpfg8/9Yd02OvQ==",
+ "license": "MIT"
+ },
+ "node_modules/three-mesh-bvh": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/three-mesh-bvh/-/three-mesh-bvh-0.8.3.tgz",
+ "integrity": "sha512-4G5lBaF+g2auKX3P0yqx+MJC6oVt6sB5k+CchS6Ob0qvH0YIhuUk1eYr7ktsIpY+albCqE80/FVQGV190PmiAg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "three": ">= 0.159.0"
+ }
+ },
+ "node_modules/three-stdlib": {
+ "version": "2.36.1",
+ "resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.36.1.tgz",
+ "integrity": "sha512-XyGQrFmNQ5O/IoKm556ftwKsBg11TIb301MB5dWNicziQBEs2g3gtOYIf7pFiLa0zI2gUwhtCjv9fmjnxKZ1Cg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/draco3d": "^1.4.0",
+ "@types/offscreencanvas": "^2019.6.4",
+ "@types/webxr": "^0.5.2",
+ "draco3d": "^1.4.1",
+ "fflate": "^0.6.9",
+ "potpack": "^1.0.1"
+ },
+ "peerDependencies": {
+ "three": ">=0.128.0"
+ }
+ },
+ "node_modules/three-stdlib/node_modules/fflate": {
+ "version": "0.6.10",
+ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz",
+ "integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==",
+ "license": "MIT"
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.15",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/troika-three-text": {
+ "version": "0.52.4",
+ "resolved": "https://registry.npmjs.org/troika-three-text/-/troika-three-text-0.52.4.tgz",
+ "integrity": "sha512-V50EwcYGruV5rUZ9F4aNsrytGdKcXKALjEtQXIOBfhVoZU9VAqZNIoGQ3TMiooVqFAbR1w15T+f+8gkzoFzawg==",
+ "license": "MIT",
+ "dependencies": {
+ "bidi-js": "^1.0.2",
+ "troika-three-utils": "^0.52.4",
+ "troika-worker-utils": "^0.52.0",
+ "webgl-sdf-generator": "1.1.1"
+ },
+ "peerDependencies": {
+ "three": ">=0.125.0"
+ }
+ },
+ "node_modules/troika-three-utils": {
+ "version": "0.52.4",
+ "resolved": "https://registry.npmjs.org/troika-three-utils/-/troika-three-utils-0.52.4.tgz",
+ "integrity": "sha512-NORAStSVa/BDiG52Mfudk4j1FG4jC4ILutB3foPnfGbOeIs9+G5vZLa0pnmnaftZUGm4UwSoqEpWdqvC7zms3A==",
+ "license": "MIT",
+ "peerDependencies": {
+ "three": ">=0.125.0"
+ }
+ },
+ "node_modules/troika-worker-utils": {
+ "version": "0.52.0",
+ "resolved": "https://registry.npmjs.org/troika-worker-utils/-/troika-worker-utils-0.52.0.tgz",
+ "integrity": "sha512-W1CpvTHykaPH5brv5VHLfQo9D1OYuo0cSBEUQFFT/nBUzM8iD6Lq2/tgG/f1OelbAS1WtaTPQzE5uM49egnngw==",
+ "license": "MIT"
+ },
+ "node_modules/ts-api-utils": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
+ "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.12"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
+ },
+ "node_modules/tunnel-rat": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/tunnel-rat/-/tunnel-rat-0.1.2.tgz",
+ "integrity": "sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ==",
+ "license": "MIT",
+ "dependencies": {
+ "zustand": "^4.3.2"
+ }
+ },
+ "node_modules/tunnel-rat/node_modules/zustand": {
+ "version": "4.5.7",
+ "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz",
+ "integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==",
+ "license": "MIT",
+ "dependencies": {
+ "use-sync-external-store": "^1.2.2"
+ },
+ "engines": {
+ "node": ">=12.7.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8",
+ "immer": ">=9.0.6",
+ "react": ">=16.8"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "immer": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.9.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+ "devOptional": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/typescript-eslint": {
+ "version": "8.53.0",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.53.0.tgz",
+ "integrity": "sha512-xHURCQNxZ1dsWn0sdOaOfCSQG0HKeqSj9OexIxrz6ypU6wHYOdX2I3D2b8s8wFSsSOYJb+6q283cLiLlkEsBYw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/eslint-plugin": "8.53.0",
+ "@typescript-eslint/parser": "8.53.0",
+ "@typescript-eslint/typescript-estree": "8.53.0",
+ "@typescript-eslint/utils": "8.53.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "7.16.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
+ "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
+ "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/use-sync-external-store": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
+ "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/utility-types": {
+ "version": "3.11.0",
+ "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz",
+ "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/utrie": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
+ "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "base64-arraybuffer": "^1.0.2"
+ }
+ },
+ "node_modules/vite": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz",
+ "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.27.0",
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3",
+ "postcss": "^8.5.6",
+ "rollup": "^4.43.0",
+ "tinyglobby": "^0.2.15"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^20.19.0 || >=22.12.0",
+ "jiti": ">=1.21.0",
+ "less": "^4.0.0",
+ "lightningcss": "^1.21.0",
+ "sass": "^1.70.0",
+ "sass-embedded": "^1.70.0",
+ "stylus": ">=0.54.8",
+ "sugarss": "^5.0.0",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/void-elements": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
+ "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/webgl-constants": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/webgl-constants/-/webgl-constants-1.1.1.tgz",
+ "integrity": "sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg=="
+ },
+ "node_modules/webgl-sdf-generator": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/webgl-sdf-generator/-/webgl-sdf-generator-1.1.1.tgz",
+ "integrity": "sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA==",
+ "license": "MIT"
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ws": {
+ "version": "8.18.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
+ "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/xmlhttprequest-ssl": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz",
+ "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/zod": {
+ "version": "4.3.5",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.5.tgz",
+ "integrity": "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/zod-validation-error": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz",
+ "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "zod": "^3.25.0 || ^4.0.0"
+ }
+ },
+ "node_modules/zustand": {
+ "version": "5.0.10",
+ "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.10.tgz",
+ "integrity": "sha512-U1AiltS1O9hSy3rul+Ub82ut2fqIAefiSuwECWt6jlMVUGejvf+5omLcRBSzqbRagSM3hQZbtzdeRc6QVScXTg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.20.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=18.0.0",
+ "immer": ">=9.0.6",
+ "react": ">=18.0.0",
+ "use-sync-external-store": ">=1.2.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "immer": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "use-sync-external-store": {
+ "optional": true
+ }
+ }
+ }
+ }
+}
diff --git a/frontend/package.json b/frontend/package.json
new file mode 100644
index 0000000..c14e588
--- /dev/null
+++ b/frontend/package.json
@@ -0,0 +1,55 @@
+{
+ "name": "frontend",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc -b && vite build",
+ "lint": "eslint .",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@react-three/drei": "^10.7.7",
+ "@react-three/fiber": "^9.5.0",
+ "@tailwindcss/postcss": "^4.1.18",
+ "@tailwindcss/vite": "^4.1.18",
+ "@tanstack/react-query": "^5.90.17",
+ "@types/three": "^0.182.0",
+ "autoprefixer": "^10.4.23",
+ "axios": "^1.13.2",
+ "clsx": "^2.1.1",
+ "dompurify": "^3.3.1",
+ "framer-motion": "^12.26.2",
+ "i18next": "^25.7.4",
+ "i18next-browser-languagedetector": "^8.2.0",
+ "is-hotkey": "^0.2.0",
+ "jspdf": "^4.0.0",
+ "jspdf-autotable": "^5.0.7",
+ "lucide-react": "^0.562.0",
+ "postcss": "^8.5.6",
+ "react": "^19.2.0",
+ "react-dom": "^19.2.0",
+ "react-i18next": "^16.5.3",
+ "react-router-dom": "^7.12.0",
+ "socket.io-client": "^4.8.3",
+ "tailwind-merge": "^3.4.0",
+ "tailwindcss": "^4.1.18",
+ "three": "^0.182.0",
+ "zustand": "^5.0.10"
+ },
+ "devDependencies": {
+ "@eslint/js": "^9.39.1",
+ "@types/node": "^24.10.8",
+ "@types/react": "^19.2.5",
+ "@types/react-dom": "^19.2.3",
+ "@vitejs/plugin-react": "^5.1.1",
+ "eslint": "^9.39.1",
+ "eslint-plugin-react-hooks": "^7.0.1",
+ "eslint-plugin-react-refresh": "^0.4.24",
+ "globals": "^16.5.0",
+ "typescript": "~5.9.3",
+ "typescript-eslint": "^8.46.4",
+ "vite": "^7.2.4"
+ }
+}
diff --git a/frontend/public/logo.png b/frontend/public/logo.png
new file mode 100644
index 0000000..3c9d74c
Binary files /dev/null and b/frontend/public/logo.png differ
diff --git a/frontend/public/vite.svg b/frontend/public/vite.svg
new file mode 100644
index 0000000..e7b8dfb
--- /dev/null
+++ b/frontend/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
new file mode 100644
index 0000000..312b314
--- /dev/null
+++ b/frontend/src/App.tsx
@@ -0,0 +1,40 @@
+import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
+import LoginPage from '@/pages/login/ui/Page';
+import HomePage from '@/pages/home/ui/Page';
+import TargetsPage from '@/pages/targets/ui/Page';
+import ScansPage from '@/pages/scans/ui/Page';
+import VulnerabilitiesPage from '@/pages/vulnerabilities/ui/Page';
+import TerminalPage from '@/pages/terminal/ui/Page';
+import SettingsPage from '@/pages/settings/ui/Page';
+import DashboardLayout from '@/widgets/layout/DashboardLayout';
+import { ProtectedRoute } from '@/app/providers/ProtectedRoute';
+
+function App() {
+ return (
+
+
+ {/* Public Routes */}
+ } />
+
+ {/* Protected Dashboard Routes */}
+ }>
+ }>
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+ {/* Other routes will go here */}
+ } />
+
+
+
+ } />
+
+
+ );
+}
+
+export default App;
diff --git a/frontend/src/app/providers/ProtectedRoute.tsx b/frontend/src/app/providers/ProtectedRoute.tsx
new file mode 100644
index 0000000..c67f0a5
--- /dev/null
+++ b/frontend/src/app/providers/ProtectedRoute.tsx
@@ -0,0 +1,17 @@
+import { Navigate, Outlet } from 'react-router-dom';
+import { useAuthStore } from '@/features/auth/model/authStore';
+
+export const ProtectedRoute = () => {
+ const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
+ const _hasHydrated = useAuthStore((state) => state._hasHydrated);
+
+ if (!_hasHydrated) {
+ return Loading Security Context...
;
+ }
+
+ if (!isAuthenticated) {
+ return ;
+ }
+
+ return ;
+};
diff --git a/frontend/src/assets/react.svg b/frontend/src/assets/react.svg
new file mode 100644
index 0000000..6c87de9
--- /dev/null
+++ b/frontend/src/assets/react.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/src/entities/scan/api/scanApi.ts b/frontend/src/entities/scan/api/scanApi.ts
new file mode 100644
index 0000000..e4a41e3
--- /dev/null
+++ b/frontend/src/entities/scan/api/scanApi.ts
@@ -0,0 +1,21 @@
+import { apiClient } from '@/shared/api/client';
+import type { Scan, CreateScanDto } from '../model/types';
+
+export const scanApi = {
+ list: async (organizationId: string): Promise => {
+ const { data } = await apiClient.get<{ data: Scan[] }>(`/scans`, {
+ params: { organizationId }
+ });
+ return data.data;
+ },
+
+ create: async (payload: CreateScanDto): Promise => {
+ const { data } = await apiClient.post<{ data: Scan }>(`/scans`, payload);
+ return data.data;
+ },
+
+ getOne: async (id: string): Promise => {
+ const { data } = await apiClient.get<{ data: Scan }>(`/scans/${id}`);
+ return data.data;
+ }
+};
diff --git a/frontend/src/entities/scan/model/types.ts b/frontend/src/entities/scan/model/types.ts
new file mode 100644
index 0000000..b3aa92c
--- /dev/null
+++ b/frontend/src/entities/scan/model/types.ts
@@ -0,0 +1,21 @@
+export type ScanStatus = 'PENDING' | 'RUNNING' | 'COMPLETED' | 'FAILED' | 'STOPPED';
+
+export interface Scan {
+ id: string;
+ status: ScanStatus;
+ startedAt: string | null;
+ completedAt: string | null;
+ createdAt: string;
+ targetId: string;
+ organizationId: string;
+ target?: {
+ name: string;
+ url: string;
+ };
+}
+
+export interface CreateScanDto {
+ targetId: string;
+ profile?: 'lightning' | 'balanced' | 'deep';
+ configurationId?: string;
+}
diff --git a/frontend/src/entities/target/api/targetApi.ts b/frontend/src/entities/target/api/targetApi.ts
new file mode 100644
index 0000000..9dcccf9
--- /dev/null
+++ b/frontend/src/entities/target/api/targetApi.ts
@@ -0,0 +1,25 @@
+import { apiClient } from '@/shared/api/client';
+import type { Target, CreateTargetDto } from '../model/types';
+
+export const targetApi = {
+ list: async (organizationId: string): Promise => {
+ const { data } = await apiClient.get(`/targets`, {
+ params: { organizationId }
+ });
+ return data;
+ },
+
+ create: async (payload: CreateTargetDto): Promise => {
+ const { data } = await apiClient.post('/targets', payload);
+ return data;
+ },
+
+ getOne: async (id: string): Promise => {
+ const { data } = await apiClient.get(`/targets/${id}`);
+ return data;
+ },
+
+ delete: async (id: string): Promise => {
+ await apiClient.delete(`/targets/${id}`);
+ }
+};
diff --git a/frontend/src/entities/target/model/types.ts b/frontend/src/entities/target/model/types.ts
new file mode 100644
index 0000000..bfba6e8
--- /dev/null
+++ b/frontend/src/entities/target/model/types.ts
@@ -0,0 +1,14 @@
+export interface Target {
+ id: string;
+ url: string;
+ name: string;
+ createdAt: string;
+ updatedAt: string;
+ organizationId: string;
+}
+
+export interface CreateTargetDto {
+ name: string;
+ url: string;
+ organizationId: string;
+}
diff --git a/frontend/src/entities/user/model/types.ts b/frontend/src/entities/user/model/types.ts
new file mode 100644
index 0000000..aed0e3c
--- /dev/null
+++ b/frontend/src/entities/user/model/types.ts
@@ -0,0 +1,13 @@
+export interface User {
+ id: string;
+ email: string;
+ name: string;
+ role: 'ADMIN' | 'MEMBER' | 'BILLING_MANAGER';
+ organizationId: string;
+}
+
+export interface AuthState {
+ user: User | null;
+ token: string | null;
+ isAuthenticated: boolean;
+}
diff --git a/frontend/src/entities/vulnerability/api/vulnerabilityApi.ts b/frontend/src/entities/vulnerability/api/vulnerabilityApi.ts
new file mode 100644
index 0000000..83c9b70
--- /dev/null
+++ b/frontend/src/entities/vulnerability/api/vulnerabilityApi.ts
@@ -0,0 +1,16 @@
+import { apiClient } from '@/shared/api/client';
+import type { Vulnerability } from '../model/types';
+
+export const vulnerabilityApi = {
+ list: async (organizationId: string): Promise => {
+ const { data } = await apiClient.get<{ data: Vulnerability[] }>(`/vulnerabilities`, {
+ params: { organizationId }
+ });
+ return data.data;
+ },
+
+ resolve: async (id: string): Promise => {
+ const { data } = await apiClient.post<{ data: Vulnerability }>(`/vulnerabilities/${id}/resolve`);
+ return data.data;
+ }
+};
diff --git a/frontend/src/entities/vulnerability/model/types.ts b/frontend/src/entities/vulnerability/model/types.ts
new file mode 100644
index 0000000..1f70742
--- /dev/null
+++ b/frontend/src/entities/vulnerability/model/types.ts
@@ -0,0 +1,35 @@
+export type VulnerabilitySeverity = 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW' | 'INFO';
+
+export type VulnerabilityType =
+ | 'SQL_INJECTION'
+ | 'XSS'
+ | 'XXE'
+ | 'IDOR'
+ | 'BROKEN_AUTH'
+ | 'SECURITY_MISCONFIG'
+ | 'SENSITIVE_DATA_EXPOSURE'
+ | 'CMD_INJECTION'
+ | 'PATH_TRAVERSAL'
+ | 'CSRF'
+ | 'OTHER';
+
+export interface Vulnerability {
+ id: string;
+ type: VulnerabilityType;
+ severity: VulnerabilitySeverity;
+ description: string;
+ proof: string;
+ isResolved: boolean;
+ foundAt: string;
+ resolvedAt: string | null;
+ resolvedByUserId: string | null;
+ scanId: string;
+ scan?: {
+ id: string;
+ organizationId: string;
+ target?: {
+ name: string;
+ url: string;
+ }
+ };
+}
diff --git a/frontend/src/features/auth/model/authStore.ts b/frontend/src/features/auth/model/authStore.ts
new file mode 100644
index 0000000..64593ea
--- /dev/null
+++ b/frontend/src/features/auth/model/authStore.ts
@@ -0,0 +1,30 @@
+import { create } from 'zustand';
+import { persist } from 'zustand/middleware';
+import type { User, AuthState } from '@/entities/user/model/types';
+
+interface AuthActions {
+ setAuth: (user: User, token: string) => void;
+ logout: () => void;
+ _hasHydrated: boolean;
+ setHasHydrated: (state: boolean) => void;
+}
+
+export const useAuthStore = create()(
+ persist(
+ (set) => ({
+ user: null,
+ token: null,
+ isAuthenticated: false,
+ setAuth: (user, token) => set({ user, token, isAuthenticated: true }),
+ logout: () => set({ user: null, token: null, isAuthenticated: false }),
+ _hasHydrated: false,
+ setHasHydrated: (state) => set({ _hasHydrated: state }),
+ }),
+ {
+ name: 'dragonsploit-auth-storage',
+ onRehydrateStorage: () => (state) => {
+ state?.setHasHydrated(true);
+ },
+ }
+ )
+);
diff --git a/frontend/src/features/auth/ui/ForgotCredentialsForm.tsx b/frontend/src/features/auth/ui/ForgotCredentialsForm.tsx
new file mode 100644
index 0000000..3af6126
--- /dev/null
+++ b/frontend/src/features/auth/ui/ForgotCredentialsForm.tsx
@@ -0,0 +1,110 @@
+import React, { useState } from 'react';
+import { motion, AnimatePresence } from 'framer-motion';
+import { Mail, Loader2, ArrowLeft, ShieldCheck } from 'lucide-react';
+import { useTranslation } from 'react-i18next';
+// import { authApi } from '@/shared/api/auth';
+
+export const ForgotCredentialsForm = ({ onBack }: { onBack: () => void }) => {
+ const { t } = useTranslation();
+ const [email, setEmail] = useState('');
+ const [isSending, setIsSending] = useState(false);
+ const [isSent, setIsSent] = useState(false);
+ const [error, setError] = useState(null);
+
+ const handleSubmit = async (e: React.FormEvent) => {
+ e.preventDefault();
+ setIsSending(true);
+ setError(null);
+
+ try {
+ // Mocking for now as backend doesn't have this yet
+ // await authApi.forgotPassword(email);
+ await new Promise(resolve => setTimeout(resolve, 2000));
+ setIsSent(true);
+ } catch (err: any) {
+ setError(t('common.error') || 'System Error');
+ } finally {
+ setIsSending(false);
+ }
+ };
+
+ if (isSent) {
+ return (
+
+
+
+ Request Logged
+
+
+ If an operator profile exists for {email} ,
+ recovery instructions have been dispatched via secure channel.
+
+
+ {t('auth.back_to_login')}
+
+
+ );
+ }
+
+ return (
+
+
+ {t('auth.back_to_login')}
+
+
+
+
+ {t('auth.forgot_creds').split('?')[0]} RECOVERY
+
+
+ Initiating secure credential reset protocol
+
+
+
+
+
+ );
+};
diff --git a/frontend/src/features/auth/ui/LoginForm.tsx b/frontend/src/features/auth/ui/LoginForm.tsx
new file mode 100644
index 0000000..2a493b5
--- /dev/null
+++ b/frontend/src/features/auth/ui/LoginForm.tsx
@@ -0,0 +1,174 @@
+import React, { useState } from 'react';
+import { motion, AnimatePresence } from 'framer-motion';
+import { Terminal, Lock, Eye, EyeOff, Loader2 } from 'lucide-react';
+import { authApi } from '@/shared/api/auth';
+import { useAuthStore } from '@/features/auth/model/authStore';
+import { useNavigate } from 'react-router-dom';
+import { useTranslation } from 'react-i18next';
+
+export const LoginForm = ({
+ onSignUp,
+ onForgot
+}: {
+ onSignUp: () => void;
+ onForgot: () => void;
+}) => {
+ const navigate = useNavigate();
+ const { t } = useTranslation();
+ const [email, setEmail] = useState('');
+ const [password, setPassword] = useState('');
+ const [showPassword, setShowPassword] = useState(false);
+ const [isAccessing, setIsAccessing] = useState(false);
+ const [error, setError] = useState(null);
+
+ const setAuth = useAuthStore(state => state.setAuth);
+
+ const handleSubmit = async (e: React.FormEvent) => {
+ e.preventDefault();
+ setIsAccessing(true);
+ setError(null);
+
+ try {
+ const { data } = await authApi.login({ email, password });
+ setAuth(data.user, data.accessToken);
+ // localStorage backup for the interceptor
+ localStorage.setItem('dragonsploit-auth-token', data.accessToken);
+ // console.log('Login successful');
+ navigate('/');
+ } catch (err: any) {
+ setError(err.response?.data?.message || 'Access Denied: Invalid Credentials');
+ } finally {
+ setIsAccessing(false);
+ }
+ };
+
+ return (
+
+ {/* Decorative scanner line */}
+
+
+
+
+
+
+
+
+ {t('auth.gateway')}
+
+
+ {t('auth.auth_required')} // SYSTEM ID: DS-ORC-01
+
+
+
+
+
+
+
+ {t('auth.forgot_creds')}
+
+
+ {t('auth.new_operator')}
+
+
+
+ );
+};
diff --git a/frontend/src/features/auth/ui/RegisterForm.tsx b/frontend/src/features/auth/ui/RegisterForm.tsx
new file mode 100644
index 0000000..96030ae
--- /dev/null
+++ b/frontend/src/features/auth/ui/RegisterForm.tsx
@@ -0,0 +1,127 @@
+import React, { useState } from 'react';
+import { motion, AnimatePresence } from 'framer-motion';
+import { User, Mail, Lock, Loader2, ArrowLeft } from 'lucide-react';
+import { authApi } from '@/shared/api/auth';
+import { useAuthStore } from '@/features/auth/model/authStore';
+import { useNavigate } from 'react-router-dom';
+import { useTranslation } from 'react-i18next';
+
+export const RegisterForm = ({ onBack }: { onBack: () => void }) => {
+ const navigate = useNavigate();
+ const { t } = useTranslation();
+ const setAuth = useAuthStore(state => state.setAuth);
+
+ const [formData, setFormData] = useState({
+ name: '',
+ email: '',
+ password: '',
+ });
+ const [isRegistering, setIsRegistering] = useState(false);
+ const [error, setError] = useState(null);
+
+ const handleSubmit = async (e: React.FormEvent) => {
+ e.preventDefault();
+ setIsRegistering(true);
+ setError(null);
+
+ try {
+ const { data } = await authApi.register(formData);
+ setAuth(data.user, data.accessToken);
+ localStorage.setItem('dragonsploit-auth-token', data.accessToken);
+ navigate('/');
+ } catch (err: any) {
+ if (err.response) {
+ // Log removed for production
+ }
+ const backendMessage = err.response?.data?.message || err.response?.data?.mesaj;
+ setError(backendMessage || `Access Denied: ${err.message || 'Registration Failed'}`);
+ } finally {
+ setIsRegistering(false);
+ }
+ };
+
+ return (
+
+
+ {t('auth.back_to_login')}
+
+
+
+
+ {t('auth.new_operator').split('[')[0]} {t('common.register')}
+
+
+ CREATING SECURE PROFILE // SYS_ACC_LEVEL: 0
+
+
+
+
+
+ );
+};
diff --git a/frontend/src/features/language/ui/LanguageSwitcher.tsx b/frontend/src/features/language/ui/LanguageSwitcher.tsx
new file mode 100644
index 0000000..a80ece5
--- /dev/null
+++ b/frontend/src/features/language/ui/LanguageSwitcher.tsx
@@ -0,0 +1,37 @@
+import React from 'react';
+import { useTranslation } from 'react-i18next';
+import { Languages } from 'lucide-react';
+
+const LanguageSwitcher: React.FC = () => {
+ const { i18n } = useTranslation();
+
+ const languages = [
+ { code: 'en', label: 'EN', flag: '🇺🇸' },
+ { code: 'ar', label: 'AR', flag: '🇸🇦' },
+ { code: 'tr', label: 'TR', flag: '🇹🇷' },
+ ];
+
+ return (
+
+
+
+ {languages.map((lang) => (
+ i18n.changeLanguage(lang.code)}
+ className={`text-[10px] font-mono font-bold px-1 transition-all ${
+ i18n.language.startsWith(lang.code)
+ ? 'text-cyber-green border-b border-cyber-green'
+ : 'text-cyber-green/30 hover:text-cyber-green/80'
+ }`}
+ >
+ {lang.label}
+
+ ))}
+
+
+ );
+};
+
+export default LanguageSwitcher;
diff --git a/frontend/src/index.css b/frontend/src/index.css
new file mode 100644
index 0000000..d1d3a7a
--- /dev/null
+++ b/frontend/src/index.css
@@ -0,0 +1,34 @@
+@import "tailwindcss";
+
+@theme {
+ --color-cyber-black: #0a0a0a;
+ --color-cyber-green: #00ff41;
+ --color-cyber-red: #ff0000;
+ --color-cyber-blue: #008f11;
+
+ --font-mono: "JetBrains Mono", monospace;
+ --font-display: "Orbitron", sans-serif;
+}
+
+:root {
+ color-scheme: dark;
+}
+
+body {
+ background-color: var(--color-cyber-black);
+ color: var(--color-cyber-green);
+ font-family: var(--font-mono);
+ overflow: hidden;
+}
+
+/* Custom scrollbar */
+::-webkit-scrollbar {
+ width: 8px;
+}
+::-webkit-scrollbar-track {
+ background: var(--color-cyber-black);
+}
+::-webkit-scrollbar-thumb {
+ background: var(--color-cyber-blue);
+ border-radius: 2px;
+}
diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx
new file mode 100644
index 0000000..be22244
--- /dev/null
+++ b/frontend/src/main.tsx
@@ -0,0 +1,23 @@
+import React from 'react'
+import ReactDOM from 'react-dom/client'
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
+import App from './App.tsx'
+import './index.css'
+import '@/shared/lib/i18n/config'
+
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ retry: 1,
+ refetchOnWindowFocus: false,
+ },
+ },
+})
+
+ReactDOM.createRoot(document.getElementById('root')!).render(
+
+
+
+
+ ,
+)
diff --git a/frontend/src/pages/home/ui/Page.tsx b/frontend/src/pages/home/ui/Page.tsx
new file mode 100644
index 0000000..a8a8b0b
--- /dev/null
+++ b/frontend/src/pages/home/ui/Page.tsx
@@ -0,0 +1,298 @@
+import React, { useState, useEffect } from 'react';
+import { motion } from 'framer-motion';
+import {
+ Activity,
+ Terminal as TerminalIcon,
+ Clock,
+ Zap,
+ AlertTriangle,
+ Globe,
+ Cpu
+} from 'lucide-react';
+import { vulnerabilityApi } from '@/entities/vulnerability/api/vulnerabilityApi';
+import { scanApi } from '@/entities/scan/api/scanApi';
+import { targetApi } from '@/entities/target/api/targetApi';
+import { useAuthStore } from '@/features/auth/model/authStore';
+import { useQuery } from '@tanstack/react-query';
+import { useTranslation } from 'react-i18next';
+import { useNavigate } from 'react-router-dom';
+import { generateTacticalReport } from '@/shared/lib/pdf/report-generator';
+
+const DashboardPage: React.FC = () => {
+ const { user } = useAuthStore();
+ const { t } = useTranslation();
+ const navigate = useNavigate();
+
+ const [telemetry, setTelemetry] = useState({
+ cpu: 24.8,
+ ram: 19.4,
+ health: 99.9
+ });
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setTelemetry({
+ cpu: Number((20 + Math.random() * 10).toFixed(1)),
+ ram: Number((18 + Math.random() * 5).toFixed(1)),
+ health: Number((98 + Math.random() * 2).toFixed(1))
+ });
+ }, 4000);
+ return () => clearInterval(interval);
+ }, []);
+
+ // Queries for real stats
+ const { data: scans = [] } = useQuery({
+ queryKey: ['scans', user?.organizationId],
+ queryFn: () => scanApi.list(user!.organizationId),
+ enabled: !!user?.organizationId
+ });
+
+ const { data: targets = [] } = useQuery({
+ queryKey: ['targets', user?.organizationId],
+ queryFn: () => targetApi.list(user!.organizationId),
+ enabled: !!user?.organizationId
+ });
+
+ const { data: vulns = [] } = useQuery({
+ queryKey: ['vulnerabilities', user?.organizationId],
+ queryFn: () => vulnerabilityApi.list(user!.organizationId),
+ enabled: !!user?.organizationId
+ });
+
+ const activeScansCount = scans.filter(s => s.status === 'RUNNING').length;
+
+ const handleExport = () => {
+ console.log('PDF_ENGINE :: Initializing tactical report generation...');
+ console.log('EXPORT_DATA :: Context:', { operator: user?.name, org: user?.organizationId, scans: scans.length, vulns: vulns.length });
+
+ try {
+ generateTacticalReport({
+ operatorName: user?.name || 'Unknown Operator',
+ organizationId: user?.organizationId || 'DS-UNSET',
+ timestamp: new Date().toLocaleString(),
+ stats: {
+ totalScans: scans.length,
+ activeScans: activeScansCount,
+ vulnerabilities: vulns.length,
+ targets: targets.length
+ },
+ recentScans: scans.slice(0, 10),
+ vulnerabilities: vulns.slice(0, 10)
+ });
+ console.log('PDF_ENGINE :: Success. Report dispatched to browser.');
+ } catch (err) {
+ console.error('PDF_ENGINE_FAILURE :: Critical disruption during document assembly:', err);
+ alert('FAILED TO GENERATE REPORT: Check the operational log (console) for details.');
+ }
+ };
+
+ const stats = [
+ { label: t('dashboard.active_missions'), value: activeScansCount.toString().padStart(2, '0'), icon: Activity, color: 'text-cyber-green', trend: 'LIVE' },
+ { label: t('dashboard.strategic_assets'), value: targets.length.toString(), icon: Globe, color: 'text-blue-400', trend: 'Stable' },
+ { label: t('dashboard.system_health'), value: `${telemetry.health}%`, icon: Clock, color: 'text-purple-400', trend: 'Optimal' },
+ { label: t('dashboard.detected_flaws'), value: vulns.length.toString().padStart(2, '0'), icon: AlertTriangle, color: 'text-cyber-red', trend: vulns.length > 0 ? '+New' : 'Zero' },
+ ];
+
+ const derivedLogs = scans.slice(0, 5).map(scan => ({
+ id: scan.id,
+ time: new Date(scan.createdAt).toLocaleTimeString(),
+ msg: `MISSION_${scan.status} :: ${scan.target?.name || 'Unknown'}`,
+ type: scan.status === 'RUNNING' ? 'info' : scan.status === 'COMPLETED' ? 'success' : 'warning'
+ }));
+
+ return (
+
+ {/* Header Section */}
+
+
+
+ {t('dashboard.command_center').split(' ')[0]} {t('dashboard.command_center').split(' ')[1]}
+
+
+
+ {t('dashboard.strategic_overview')} // {t('dashboard.operational_status')}: {t('dashboard.status_nominal')}
+
+
+
+
+ Export Report
+
+ navigate('/targets')}
+ className="px-6 py-2 bg-cyber-green/10 border border-cyber-green text-cyber-green text-[10px] font-mono uppercase hover:bg-cyber-green hover:text-black transition-all font-bold"
+ >
+ New Scan +
+
+
+
+
+ {/* Stats Grid */}
+
+ {stats.map((stat, i) => (
+
+
+
+
+
+
+
+
+
+ {stat.trend}
+
+
+
+
{stat.label}
+
{stat.value}
+
+
+ ))}
+
+
+
+ {/* Threat Map Placeholder */}
+
+
+
+ Global Threat Topology
+
+
+
+ {/* Holographic Circles Effect */}
+
+
+
+ {/* Radar Line */}
+
+
+
+
+
+ {/* Signal Intercept Overlay */}
+
+
Satellite link active
+
Coord: 25.276987, 55.296249
+
+
+
+ {/* Real-time Logs / Mission Status */}
+
+
+
+ {t('dashboard.mission_logs')}
+
+ LIVE
+
+
+ {derivedLogs.map((log) => (
+
+ [{log.time}]
+
+ {log.msg}
+
+
+ ))}
+ {derivedLogs.length === 0 && (
+
No active or past mission records available.
+ )}
+
+
+ {t('dashboard.waiting_data')}
+
+
+
+
+
+ Enter Full Terminal
+
+
+
+
+
+ {/* System Resources Container */}
+
+
+
+
+
+
+
+ Node-Central Load
+ {telemetry.cpu}%
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Memory Allocation
+ {(telemetry.ram * 0.32).toFixed(1)} / 32 GB
+
+
+
+
+
+
+
+
+ );
+};
+
+const Loader2 = ({ size, className }: { size: number, className?: string }) => (
+
+
+
+);
+
+export default DashboardPage;
diff --git a/frontend/src/pages/login/ui/Page.tsx b/frontend/src/pages/login/ui/Page.tsx
new file mode 100644
index 0000000..c0a2da5
--- /dev/null
+++ b/frontend/src/pages/login/ui/Page.tsx
@@ -0,0 +1,116 @@
+import React, { useState } from 'react';
+import { motion, AnimatePresence } from 'framer-motion';
+import { LoginForm } from '@/features/auth/ui/LoginForm';
+import { RegisterForm } from '@/features/auth/ui/RegisterForm';
+import { ForgotCredentialsForm } from '@/features/auth/ui/ForgotCredentialsForm';
+import { useTranslation } from 'react-i18next';
+import LanguageSwitcher from '@/features/language/ui/LanguageSwitcher';
+
+const LoginPage: React.FC = () => {
+ const [view, setView] = useState<'login' | 'register' | 'forgot'>('login');
+ const { t } = useTranslation();
+ return (
+
+ {/* Background Matrix/Grid Effect */}
+
+
+ {/* Radial Depth Aura */}
+
+
+ {/* Floating 3D Elements Placeholder (Particles) */}
+
+ {[...Array(20)].map((_, i) => (
+
+ ))}
+
+
+ {/* Brand Watermark */}
+
+
+
+
+
+
+ DRAGONSPLOIT
+
+
v2.0 // {t('auth.auth_required')}
+
+
+
+
+ {/* Main Form Holder */}
+
+
+ {view === 'login' ? (
+
+ setView('register')}
+ onForgot={() => setView('forgot')}
+ />
+
+ ) : view === 'register' ? (
+
+ setView('login')} />
+
+ ) : (
+
+ setView('login')} />
+
+ )}
+
+
+
+ {/* Footer Info */}
+
+ {t('dashboard.operational_status')}: {t('dashboard.status_nominal')}
+ Secure Protocol: AES-256-GCM
+
+
+ );
+};
+
+export default LoginPage;
diff --git a/frontend/src/pages/scans/ui/Page.tsx b/frontend/src/pages/scans/ui/Page.tsx
new file mode 100644
index 0000000..08da0b3
--- /dev/null
+++ b/frontend/src/pages/scans/ui/Page.tsx
@@ -0,0 +1,194 @@
+import React from 'react';
+import { motion } from 'framer-motion';
+import {
+ Activity,
+ Clock,
+ CheckCircle2,
+ AlertCircle,
+ Play,
+ StopCircle,
+ Loader2,
+ RefreshCcw,
+ Target as TargetIcon,
+ ChevronRight
+} from 'lucide-react';
+import { scanApi } from '@/entities/scan/api/scanApi';
+import { useAuthStore } from '@/features/auth/model/authStore';
+import { useQuery } from '@tanstack/react-query';
+import { useTranslation } from 'react-i18next';
+import type { ScanStatus } from '@/entities/scan/model/types';
+
+const ScansPage: React.FC = () => {
+ const { user } = useAuthStore();
+ const { t } = useTranslation();
+
+ // Fetch Scans with polling
+ const { data: scans = [], isLoading, refetch, isRefetching } = useQuery({
+ queryKey: ['scans', user?.organizationId],
+ queryFn: () => scanApi.list(user!.organizationId),
+ enabled: !!user?.organizationId,
+ refetchInterval: 5000, // Sync every 5 seconds
+ });
+
+ const getStatusColor = (status: ScanStatus) => {
+ switch (status) {
+ case 'RUNNING': return 'text-cyber-green';
+ case 'PENDING': return 'text-blue-400';
+ case 'COMPLETED': return 'text-purple-400';
+ case 'FAILED': return 'text-cyber-red';
+ default: return 'text-white/40';
+ }
+ };
+
+ const getStatusIcon = (status: ScanStatus) => {
+ switch (status) {
+ case 'RUNNING': return ;
+ case 'PENDING': return ;
+ case 'COMPLETED': return ;
+ case 'FAILED': return ;
+ default: return ;
+ }
+ };
+
+ return (
+
+
+
+ {/* Scans Table/List */}
+
+
+
{t('scans.op_target')}
+
{t('scans.exec_status')}
+
{t('scans.depth')}
+
{t('scans.timestamp')}
+
{t('common.actions')}
+
+
+ {isLoading ? (
+
+
+ {t('common.loading')}
+
+ ) : scans.length === 0 ? (
+
+ NO ACTIVE MISSIONS LOGGED IN THIS QUADRANT.
+
+ ) : (
+
+ {scans.map((scan, i) => (
+
+
+
+
+
+
+
+ {scan.target?.name || 'Unknown Target'}
+
+
+ ID: {scan.id.substring(0, 12)}...
+
+
+
+
+
+
+ {getStatusIcon(scan.status)}
+
+
+ {scan.status}
+
+
+
+
+
+
+
+ {new Date(scan.createdAt).toLocaleDateString()}
+
+
+ {new Date(scan.createdAt).toLocaleTimeString()}
+
+
+
+
+ {scan.status === 'COMPLETED' ? (
+
+ Report
+
+ ) : scan.status === 'RUNNING' ? (
+
+
+
+ ) : (
+
+
+
+ )}
+
+
+ ))}
+
+ )}
+
+
+ {/* Analytics Preview Cards */}
+
+
+
Payload Success Rate
+
+
84.2%
+ ▲ 2.4%
+
+
+
+
Average Vulnerability Depth
+
+
4.2
+ ▼ High Risk
+
+
+
+
Data Processed (Current Session)
+
+
12.8 GB
+ Nominal
+
+
+
+
+ );
+};
+
+export default ScansPage;
diff --git a/frontend/src/pages/settings/ui/Page.tsx b/frontend/src/pages/settings/ui/Page.tsx
new file mode 100644
index 0000000..2e889ec
--- /dev/null
+++ b/frontend/src/pages/settings/ui/Page.tsx
@@ -0,0 +1,158 @@
+import React from 'react';
+import { motion } from 'framer-motion';
+import {
+ User,
+ Settings as SettingsIcon,
+ Shield,
+ Database,
+ Key,
+ Monitor,
+ ChevronRight
+} from 'lucide-react';
+import { useAuthStore } from '@/features/auth/model/authStore';
+import { useTranslation } from 'react-i18next';
+
+const SettingsPage: React.FC = () => {
+ const { user } = useAuthStore();
+ const { t, i18n } = useTranslation();
+
+ const currentLang = i18n.language;
+
+ const sections = [
+ {
+ id: 'profile',
+ title: t('settings.operator_profile'),
+ icon: User,
+ description: 'Personal identification and credentials',
+ fields: [
+ { label: 'Full Designation', value: user?.name || 'Unknown' },
+ { label: 'Comm Channel (Email)', value: user?.email || 'N/A' },
+ { label: 'Access Role', value: user?.role || 'OPERATOR' }
+ ]
+ },
+ {
+ id: 'system',
+ title: t('settings.interface_config'),
+ icon: Monitor,
+ description: 'Adjust the tactical displays and localization',
+ content: (
+
+
+
+
System Language
+
{currentLang.toUpperCase()}
+
+
+ {['en', 'ar', 'tr'].map(lang => (
+ i18n.changeLanguage(lang)}
+ className={`px-3 py-1 text-[10px] font-mono border transition-all ${
+ currentLang.startsWith(lang)
+ ? 'bg-cyber-green/20 border-cyber-green text-cyber-green'
+ : 'border-cyber-green/10 text-cyber-green/40 hover:border-cyber-green/40'
+ }`}
+ >
+ {lang.toUpperCase()}
+
+ ))}
+
+
+
+ )
+ },
+ {
+ id: 'org',
+ title: t('settings.org_data'),
+ icon: Database,
+ description: 'Central command and strategic node info',
+ fields: [
+ { label: 'Unit Identifier (OrgID)', value: user?.organizationId || 'unassigned' },
+ { label: 'Deployment Region', value: 'Middle-East ME-0' }
+ ]
+ }
+ ];
+
+ return (
+
+
+
+
+ {sections.map((section, idx) => (
+
+
+
+
+
+
+
{section.title}
+
{section.description}
+
+
+
+
+ {section.fields && section.fields.map(field => (
+
+
+ {field.label}
+
+
+ {field.value}
+
+
+
+ ))}
+ {section.content}
+
+
+ ))}
+
+
+
+
+
+
+
{t('settings.danger_zone')}
+
High-risk administrative operations. Proceed with extreme caution.
+
+
+
+ Reset Session
+
+
+ Terminate Account
+
+
+
+
+
+ {/* Retro decorative text at bottom */}
+
+
+ -- DRAGONSPLOIT CRYPTOGRAPHIC CORE SECURE --
+
+
+
+ );
+};
+
+export default SettingsPage;
diff --git a/frontend/src/pages/targets/ui/Page.tsx b/frontend/src/pages/targets/ui/Page.tsx
new file mode 100644
index 0000000..3c6c06c
--- /dev/null
+++ b/frontend/src/pages/targets/ui/Page.tsx
@@ -0,0 +1,338 @@
+import React, { useState } from 'react';
+import { motion, AnimatePresence } from 'framer-motion';
+import {
+ Plus,
+ Search,
+ Globe,
+ Trash2,
+ Play,
+ Loader2,
+ X,
+ Zap,
+ Activity,
+ Target
+} from 'lucide-react';
+import { targetApi } from '@/entities/target/api/targetApi';
+import { scanApi } from '@/entities/scan/api/scanApi'; // New Import
+import { useAuthStore } from '@/features/auth/model/authStore';
+import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
+import { useNavigate } from 'react-router-dom'; // New Import
+import { useTranslation } from 'react-i18next';
+
+const TargetsPage: React.FC = () => {
+ const queryClient = useQueryClient();
+ const navigate = useNavigate();
+ const { user } = useAuthStore();
+ const { t } = useTranslation();
+ const [search, setSearch] = useState('');
+ const [isModalOpen, setIsModalOpen] = useState(false);
+ const [isMissionModalOpen, setIsMissionModalOpen] = useState(false); // New State
+ const [selectedTargetId, setSelectedTargetId] = useState(null); // New State
+ const [newTarget, setNewTarget] = useState({ name: '', url: '' });
+
+ // Scan Logic
+ const scanMutation = useMutation({
+ mutationFn: (payload: { targetId: string, profile: 'lightning' | 'balanced' | 'deep' }) =>
+ scanApi.create(payload),
+ onSuccess: () => {
+ navigate('/scans');
+ },
+ });
+
+ // Fetch Targets
+ const { data: targets = [], isLoading } = useQuery({
+ queryKey: ['targets', user?.organizationId],
+ queryFn: () => targetApi.list(user!.organizationId),
+ enabled: !!user?.organizationId,
+ });
+
+ // Create Target Mutation
+ const createMutation = useMutation({
+ mutationFn: (payload: { name: string; url: string; organizationId: string }) =>
+ targetApi.create(payload),
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ['targets'] });
+ setIsModalOpen(false);
+ setNewTarget({ name: '', url: '' });
+ },
+ });
+
+ // Delete Target Mutation
+ const deleteMutation = useMutation({
+ mutationFn: (id: string) => targetApi.delete(id),
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ['targets'] });
+ },
+ });
+
+ const filteredTargets = targets.filter(t =>
+ t.name.toLowerCase().includes(search.toLowerCase()) ||
+ t.url.toLowerCase().includes(search.toLowerCase())
+ );
+
+ const handleAddTarget = (e: React.FormEvent) => {
+ e.preventDefault();
+ if (!user?.organizationId) return;
+ createMutation.mutate({ ...newTarget, organizationId: user.organizationId });
+ };
+
+ return (
+
+
+
+ {/* Control Bar */}
+
+
+
+ setSearch(e.target.value)}
+ />
+
+
+
+ {['ALL', 'CLEAN', 'ACTIVE', 'VULNERABLE'].map(filter => (
+
+ {filter}
+
+ ))}
+
+
+
+ {/* Targets Grid */}
+ {isLoading ? (
+
+
+ RECALLING ASSETS FROM ENCRYPTED STORAGE...
+
+ ) : (
+
+
+ {filteredTargets.map((target, i) => (
+
+ {/* Status Indicator */}
+
+
+
+
+
+
+
+
+ {target.name}
+
+
+ {target.url}
+
+
+
+
+
+
+
+
{
+ setSelectedTargetId(target.id);
+ setIsMissionModalOpen(true);
+ }}
+ className="flex-1 bg-cyber-green/10 border border-cyber-green/40 text-cyber-green py-2 text-[10px] font-mono font-bold uppercase transition-all hover:bg-cyber-green hover:text-black flex items-center justify-center gap-2 disabled:opacity-50"
+ >
+ {scanMutation.isPending ? : }
+ {t('targets.launch_mission')}
+
+
deleteMutation.mutate(target.id)}
+ className="p-2 border border-cyber-red/20 text-cyber-red/40 hover:bg-cyber-red/10 hover:text-cyber-red hover:border-cyber-red transition-all"
+ >
+
+
+
+
+ ))}
+
+
+ )}
+
+ {/* Add Target Modal */}
+
+ {isModalOpen && (
+
+
setIsModalOpen(false)}
+ className="absolute inset-0 bg-black/80 backdrop-blur-md"
+ />
+
+ setIsModalOpen(false)}
+ className="absolute top-4 right-4 text-cyber-green/40 hover:text-cyber-green transition-colors"
+ >
+
+
+
+
+
+ {t('targets.add_target').split(' ')[0]} {t('targets.add_target').split(' ').slice(1).join(' ')}
+
+
Adding strategic node to the network
+
+
+
+
+
+ )}
+
+
+ {/* Mission Selector Modal */}
+
+ {isMissionModalOpen && (
+
+
setIsMissionModalOpen(false)}
+ className="absolute inset-0 bg-black/80 backdrop-blur-md"
+ />
+
+
+
+ {t('missions.select_title').split(' ')[0]} {t('missions.select_title').split(' ').slice(1).join(' ')}
+
+
Define the tactical parameters for this operation
+
+
+
+ {[
+ { id: 'lightning', icon: Zap, color: 'text-yellow-400' },
+ { id: 'balanced', icon: Activity, color: 'text-cyber-green' },
+ { id: 'deep', icon: Target, color: 'text-cyber-red' }
+ ].map((profile) => (
+
{
+ if (selectedTargetId) {
+ scanMutation.mutate({ targetId: selectedTargetId, profile: profile.id as any });
+ setIsMissionModalOpen(false);
+ }
+ }}
+ className="group p-6 bg-black/40 border border-cyber-green/10 hover:border-cyber-green/60 transition-all text-left relative overflow-hidden"
+ >
+
+
+ {t(`missions.${profile.id}`)}
+
+
+ {t(`missions.${profile.id}_desc`)}
+
+
+
+ ))}
+
+
+
+ setIsMissionModalOpen(false)}
+ className="text-[10px] font-mono text-cyber-green/40 hover:text-cyber-red transition-colors uppercase"
+ >
+ Abort Operation
+
+
+
+
+ )}
+
+
+ );
+};
+
+export default TargetsPage;
diff --git a/frontend/src/pages/terminal/ui/Page.tsx b/frontend/src/pages/terminal/ui/Page.tsx
new file mode 100644
index 0000000..40ee058
--- /dev/null
+++ b/frontend/src/pages/terminal/ui/Page.tsx
@@ -0,0 +1,276 @@
+import React, { useState, useEffect, useRef } from 'react';
+import { motion, AnimatePresence } from 'framer-motion';
+import {
+ Terminal as TerminalIcon,
+ Cpu,
+ Zap,
+ Wifi,
+ Shield,
+ Activity,
+ ChevronRight,
+ Database,
+ Lock
+} from 'lucide-react';
+import { io } from 'socket.io-client';
+import { useTranslation } from 'react-i18next';
+
+interface LogLine {
+ id: string;
+ timestamp: string;
+ type: 'info' | 'success' | 'warning' | 'error' | 'command';
+ content: string;
+}
+
+const TerminalPage: React.FC = () => {
+ const { t } = useTranslation();
+ const [logs, setLogs] = useState([]);
+ const [input, setInput] = useState('');
+ const terminalRef = useRef(null);
+ const inputRef = useRef(null);
+
+ const [systemStats, setSystemStats] = useState({
+ cpu: 18,
+ ram: 22,
+ net: 1.2
+ });
+
+ // Real-time WebSocket logs
+ const socketRef = useRef(null);
+
+ useEffect(() => {
+ const socket = io(import.meta.env.VITE_WS_URL || 'http://localhost:3001', {
+ withCredentials: true
+ });
+ socketRef.current = socket;
+
+ socket.on('connect', () => {
+ console.log('Connected to Command Center');
+ socket.emit('join_terminal');
+ });
+
+ socket.on('terminal_log', (log: LogLine) => {
+ setLogs(prev => [...prev.slice(-99), log]); // Keep last 100 logs for real data
+ });
+
+ return () => {
+ socket.disconnect();
+ };
+ }, []);
+
+ // Update system stats simulation
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setSystemStats({
+ cpu: Math.floor(Math.random() * 15) + 10,
+ ram: Math.floor(Math.random() * 5) + 20,
+ net: Number((Math.random() * 5).toFixed(1))
+ });
+ }, 3000);
+ return () => clearInterval(interval);
+ }, []);
+
+ // Auto-scroll
+ useEffect(() => {
+ if (terminalRef.current) {
+ terminalRef.current.scrollTop = terminalRef.current.scrollHeight;
+ }
+ }, [logs]);
+
+ const handleCommand = (e: React.FormEvent) => {
+ e.preventDefault();
+ if (!input.trim()) return;
+
+ const cmd = input.toLowerCase().trim();
+
+ // Clear is a local frontend command
+ if (cmd === 'clear') {
+ setLogs([]);
+ setInput('');
+ return;
+ }
+
+ // Send all other commands to backend via WebSocket
+ if (socketRef.current) {
+ socketRef.current.emit('execute_command', { command: input });
+ }
+
+ setInput('');
+ };
+
+ return (
+
+ {/* Top Header Information */}
+
+
+
+
+
+
+
+
Kernel Security
+
DRAGON_K2
+
+
+
+
+
+
+
+
Storage Cluster
+
POSTGRES_MASTER
+
+
+
+
+
+
+
+
Remote Tunnel
+
STX-VPN-01
+
+
+
+
+
+ {/* Telemetry Widgets */}
+
+
Agent Telemetry
+
+ {[1,0,1,1,1,0,1,1].map((v, i) => (
+
+ ))}
+
+
+
+
+
+
+ {/* Main Terminal Shell */}
+
+ {/* Scan Line Effect */}
+
+
+
+
+
+ root@dragonsploit:~# /usr/bin/bash
+
+
+
+
+
+
+ {logs.map((log) => (
+
+ [{log.timestamp}]
+ {log.content}
+
+ ))}
+
+
+
+
+
+
+ {/* Sidebar Health & Resources */}
+
+ {/* Telemetry Card */}
+
+
+ {t('terminal.telemetry')}
+
+
+
+
+
+ CPU Load
+ {systemStats.cpu}%
+
+
+
+
+
+
+
+
+ RAM Usage
+ {systemStats.ram}%
+
+
+
+
+
+
+
+
+ Net Flow
+ {systemStats.net} MB/s
+
+
+
+
+
+
+
+
+ {/* Quick Access Tools */}
+
+
+ {t('terminal.tools')}
+
+
+ {['IP_LOOKUP', 'HASH_GEN', 'PORT_SCAN', 'AGENT_SH'].map(tool => (
+
+ {tool}
+
+ ))}
+
+
+
+
+
+
+
Intrusion Alert
+
Unauthorized probing detected on Edge-Agent-09
+
+
+
+
+
+ );
+};
+
+export default TerminalPage;
diff --git a/frontend/src/pages/vulnerabilities/ui/Page.tsx b/frontend/src/pages/vulnerabilities/ui/Page.tsx
new file mode 100644
index 0000000..12b614e
--- /dev/null
+++ b/frontend/src/pages/vulnerabilities/ui/Page.tsx
@@ -0,0 +1,233 @@
+import React, { useState } from 'react';
+import { motion, AnimatePresence } from 'framer-motion';
+import {
+ ShieldCheck,
+ AlertTriangle,
+ Bug,
+ Eye,
+ CheckCircle,
+ ExternalLink,
+ Search,
+ Loader2
+} from 'lucide-react';
+import { vulnerabilityApi } from '@/entities/vulnerability/api/vulnerabilityApi';
+import { useAuthStore } from '@/features/auth/model/authStore';
+import { useQuery } from '@tanstack/react-query';
+import { useTranslation } from 'react-i18next';
+import type { VulnerabilitySeverity, Vulnerability } from '@/entities/vulnerability/model/types';
+
+const VulnerabilitiesPage: React.FC = () => {
+ const { user } = useAuthStore();
+ const { t } = useTranslation();
+ const [search, setSearch] = useState('');
+ const [selectedSeverity, setSelectedSeverity] = useState('ALL');
+ const [selectedVuln, setSelectedVuln] = useState(null);
+
+ // Fetch Vulnerabilities
+ const { data: vulnerabilities = [], isLoading } = useQuery({
+ queryKey: ['vulnerabilities', user?.organizationId],
+ queryFn: () => vulnerabilityApi.list(user!.organizationId),
+ enabled: !!user?.organizationId,
+ refetchInterval: 10000, // Sync every 10 seconds
+ });
+
+ const getSeverityColor = (severity: VulnerabilitySeverity) => {
+ switch (severity) {
+ case 'CRITICAL': return 'text-red-600 border-red-600/20 bg-red-600/5';
+ case 'HIGH': return 'text-orange-500 border-orange-500/20 bg-orange-500/5';
+ case 'MEDIUM': return 'text-yellow-500 border-yellow-500/20 bg-yellow-500/5';
+ case 'LOW': return 'text-blue-400 border-blue-400/20 bg-blue-400/5';
+ default: return 'text-cyber-green border-cyber-green/20 bg-cyber-green/5';
+ }
+ };
+
+ const filteredVulns = vulnerabilities.filter(v => {
+ const matchesSearch = v.description.toLowerCase().includes(search.toLowerCase()) ||
+ v.type.toLowerCase().includes(search.toLowerCase());
+ const matchesSeverity = selectedSeverity === 'ALL' || v.severity === selectedSeverity;
+ return matchesSearch && matchesSeverity;
+ });
+
+ return (
+
+
+
+ {/* Control Bar */}
+
+
+
+ setSearch(e.target.value)}
+ />
+
+
+
+ {['ALL', 'CRITICAL', 'HIGH', 'MEDIUM', 'LOW'].map(sev => (
+ setSelectedSeverity(sev as any)}
+ className={`px-3 py-1 text-[10px] font-mono border transition-all uppercase ${
+ selectedSeverity === sev
+ ? 'bg-cyber-red/20 border-cyber-red text-cyber-red font-bold'
+ : 'text-cyber-red/40 border-cyber-red/10 hover:border-cyber-red/40 hover:text-cyber-red'
+ }`}
+ >
+ {sev}
+
+ ))}
+
+
+
+ {/* Vulnerabilities List */}
+ {isLoading ? (
+
+
+ DECRYPTING THREAT INTELLIGENCE...
+
+ ) : filteredVulns.length === 0 ? (
+
+
+ SYSTEM SECURE. NO VULNERABILITIES DETECTED IN MONITORING ZONE.
+
+ ) : (
+
+ {filteredVulns.map((vuln, i) => (
+
+
+
+ {vuln.severity === 'CRITICAL' ?
:
}
+
+
+
+
+
+ {vuln.type.replace(/_/g, ' ')}
+
+
+ {vuln.severity}
+
+
+
+ Detected on: {vuln.scan?.target?.name} ({vuln.scan?.target?.url})
+
+
+
+
+
Found at
+
{new Date(vuln.foundAt).toLocaleString()}
+
+
+
setSelectedVuln(vuln)}
+ className="p-2 ml-4 bg-white/5 border border-white/10 text-white/40 hover:text-white hover:bg-white/10 transition-all"
+ >
+
+
+
+
+ ))}
+
+ )}
+
+ {/* Vulnerability Detail Modal */}
+
+ {selectedVuln && (
+
+
setSelectedVuln(null)}
+ className="absolute inset-0 bg-black/90 backdrop-blur-sm"
+ />
+
+
+
+
+
+ {selectedVuln.severity}
+
+ ID: {selectedVuln.id}
+
+
+ {selectedVuln.type.replace(/_/g, ' ')}
+
+
+
setSelectedVuln(null)}
+ className="p-2 text-cyber-red/40 hover:text-cyber-red transition-colors"
+ >
+
+
+
+
+
+
+
Description
+
+ {selectedVuln.description}
+
+
+
+
+
+
Target Asset
+
{selectedVuln.scan?.target?.name}
+
+
+
Associated Mission
+
Scan #{selectedVuln.scanId.substring(0,8)}
+
+
+
+
+
Technical Proof (PoC)
+
+
+ {selectedVuln.proof}
+
+
+
+
+
+
+ Generate Exploit Payload
+
+
+ Mark as Fixed
+
+
+
+
+
+ )}
+
+
+ );
+};
+
+export default VulnerabilitiesPage;
diff --git a/frontend/src/shared/api/auth.ts b/frontend/src/shared/api/auth.ts
new file mode 100644
index 0000000..3044bb9
--- /dev/null
+++ b/frontend/src/shared/api/auth.ts
@@ -0,0 +1,21 @@
+import { apiClient } from '../api/client';
+import type { User } from '@/entities/user/model/types';
+
+export interface LoginResponse {
+ accessToken: string;
+ user: User;
+}
+
+export const authApi = {
+ login: (credentials: Record) =>
+ apiClient.post('/auth/login', credentials),
+
+ register: (userData: Record) =>
+ apiClient.post('/auth/register', userData),
+
+ logout: () =>
+ apiClient.post('/auth/logout'),
+
+ refresh: () =>
+ apiClient.post<{ accessToken: string }>('/auth/refresh'),
+};
diff --git a/frontend/src/shared/api/client.ts b/frontend/src/shared/api/client.ts
new file mode 100644
index 0000000..2631936
--- /dev/null
+++ b/frontend/src/shared/api/client.ts
@@ -0,0 +1,45 @@
+import axios from 'axios';
+
+export const apiClient = axios.create({
+ baseURL: import.meta.env.VITE_API_URL || 'http://localhost:3001/api',
+ withCredentials: true,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+});
+
+apiClient.interceptors.request.use((config) => {
+ const token = localStorage.getItem('dragonsploit-auth-token');
+ if (token && config.headers) {
+ config.headers.Authorization = `Bearer ${token}`;
+ }
+ return config;
+});
+
+apiClient.interceptors.response.use(
+ (response) => response,
+ async (error) => {
+ // Session Recovery: Clear corrupted auth data on persistent 403
+ if (error.response?.status === 403) {
+ const authStorage = localStorage.getItem('dragonsploit-auth-storage');
+ if (authStorage) {
+ try {
+ const parsed = JSON.parse(authStorage);
+ // If we have a user but getting 403, the organizationId might be stale
+ if (parsed.state?.user?.organizationId) {
+ console.warn('🔴 SECURITY :: Stale session detected. Clearing auth storage.');
+ localStorage.removeItem('dragonsploit-auth-storage');
+ localStorage.removeItem('dragonsploit-auth-token');
+ window.location.href = '/login';
+ }
+ } catch (e) {
+ // Corrupted storage, clear it
+ localStorage.removeItem('token');
+ localStorage.removeItem('user');
+ window.location.href = '/login';
+ }
+ }
+ }
+ return Promise.reject(error);
+ }
+);
diff --git a/frontend/src/shared/lib/i18n/config.ts b/frontend/src/shared/lib/i18n/config.ts
new file mode 100644
index 0000000..e93e9b8
--- /dev/null
+++ b/frontend/src/shared/lib/i18n/config.ts
@@ -0,0 +1,40 @@
+import i18n from 'i18next';
+import { initReactI18next } from 'react-i18next';
+import LanguageDetector from 'i18next-browser-languagedetector';
+
+import en from './locales/en.json';
+import ar from './locales/ar.json';
+import tr from './locales/tr.json';
+
+i18n
+ .use(LanguageDetector)
+ .use(initReactI18next)
+ .init({
+ resources: {
+ en: { translation: en },
+ ar: { translation: ar },
+ tr: { translation: tr },
+ },
+ fallbackLng: 'en',
+ interpolation: {
+ escapeValue: false,
+ },
+ detection: {
+ order: ['localStorage', 'navigator'],
+ caches: ['localStorage'],
+ },
+ });
+
+// Handle RTL update on language change
+i18n.on('languageChanged', (lng) => {
+ const dir = lng === 'ar' ? 'rtl' : 'ltr';
+ document.documentElement.dir = dir;
+ document.documentElement.lang = lng;
+});
+
+// Set initial direction
+const initialDir = i18n.language === 'ar' ? 'rtl' : 'ltr';
+document.documentElement.dir = initialDir;
+document.documentElement.lang = i18n.language;
+
+export default i18n;
diff --git a/frontend/src/shared/lib/i18n/locales/ar.json b/frontend/src/shared/lib/i18n/locales/ar.json
new file mode 100644
index 0000000..dbc42ea
--- /dev/null
+++ b/frontend/src/shared/lib/i18n/locales/ar.json
@@ -0,0 +1,95 @@
+{
+ "common": {
+ "login": "تسجيل الدخول",
+ "register": "إنشاء حساب",
+ "logout": "إنهاء الجلسة",
+ "dashboard": "لوحة التحكم",
+ "targets": "الأهداف",
+ "scans": "الفحوصات النشطة",
+ "vulnerabilities": "الثغرات",
+ "terminal": "التيرمينال",
+ "settings": "الإعدادات",
+ "search": "بحث...",
+ "loading": "جاري المزامنة...",
+ "error": "خطأ في النظام",
+ "actions": "الإجراءات",
+ "save": "حفظ",
+ "cancel": "إلغاء",
+ "delete": "حذف"
+ },
+ "auth": {
+ "gateway": "بوابة العبور",
+ "auth_required": "المصادقة مطلوبة",
+ "operator_id": "معرف المشغل / البريد",
+ "security_key": "مفتاح الأمان",
+ "initiate_login": "بدء تسجيل الدخول",
+ "validating": "جاري التحقق من الهوية...",
+ "new_operator": "مشغل جديد؟ [إنشاء حساب]",
+ "forgot_creds": "نسيت بيانات الاعتماد؟",
+ "back_to_login": "العودة للبوابة",
+ "create_account": "إنشاء ملف عمليات جديد",
+ "full_name": "الاسم العملياتي الكامل"
+ },
+ "dashboard": {
+ "command_center": "مركز القيادة",
+ "strategic_overview": "نظرة استراتيجية شاملة",
+ "operational_status": "الحالة التشغيلية",
+ "status_nominal": "مثالية",
+ "active_missions": "المهمات النشطة",
+ "strategic_assets": "الأصول الاستراتيجية",
+ "system_health": "حالة النظام",
+ "detected_flaws": "التهديدات المكتشفة",
+ "mission_logs": "سجلات المهمة",
+ "waiting_data": "في انتظار البيانات الواردة...",
+ "system_resources": "موارد النظام"
+ },
+ "targets": {
+ "inventory": "مخزن الأهداف",
+ "operational_intelligence": "الذكاء العملياتي",
+ "add_target": "إضافة أصل جديد",
+ "target_name": "اسم الهدف / التعيين",
+ "target_url": "رابط الهدف / النقطة النهائية",
+ "initialize": "تهيئة الأصل",
+ "launch_mission": "بدء المهمة"
+ },
+ "scans": {
+ "mission_control": "التحكم في المهمات",
+ "operational_intel": "الذكاء العملياتي",
+ "active_threads": "الخيوط النشطة",
+ "op_target": "هدف العملية",
+ "exec_status": "حالة التنفيذ",
+ "depth": "عمق التسلل",
+ "timestamp": "الطابع الزمني"
+ },
+ "missions": {
+ "select_title": "اختر نوع المهمة التكتيكية",
+ "lightning": "استطلاع خاطف",
+ "balanced": "هجوم متوازن",
+ "deep": "تسلل عميق",
+ "lightning_desc": "اكتشاف سطحي. سريع وخفي.",
+ "balanced_desc": "عمق تشغيلي قياسي. استخدام مثالي للموارد.",
+ "deep_desc": "تسلل استغلالي. أقصى قدر من جمع المعلومات (أبطأ)."
+ },
+ "vulnerabilities": {
+ "intel_feed": "موجز الاستخبارات",
+ "threat_landscape": "مشهد التهديدات",
+ "found_at": "وقت الاكتشاف",
+ "severity": "مستوى الخطورة",
+ "description": "الوصف",
+ "poc": "الإثبات التقني (PoC)",
+ "mark_fixed": "تعيين كمصلح"
+ },
+ "terminal": {
+ "shell_ready": "root@dragonsploit:~# /usr/bin/bash",
+ "telemetry": "قياس أداء النظام",
+ "tools": "الأدوات الأمنية"
+ },
+ "settings": {
+ "system_settings": "إعدادات النظام",
+ "global_tactical": "التكوين التكتيكي العالمي",
+ "operator_profile": "ملف المشغل",
+ "interface_config": "تكوين الواجهة",
+ "org_data": "بيانات المنظمة",
+ "danger_zone": "منطقة الخطر"
+ }
+}
diff --git a/frontend/src/shared/lib/i18n/locales/en.json b/frontend/src/shared/lib/i18n/locales/en.json
new file mode 100644
index 0000000..1bdcf11
--- /dev/null
+++ b/frontend/src/shared/lib/i18n/locales/en.json
@@ -0,0 +1,95 @@
+{
+ "common": {
+ "login": "Login",
+ "register": "Register",
+ "logout": "Logout Session",
+ "dashboard": "Dashboard",
+ "targets": "Targets",
+ "scans": "Active Scans",
+ "vulnerabilities": "Vulnerabilities",
+ "terminal": "Terminal",
+ "settings": "Settings",
+ "search": "Search...",
+ "loading": "Synchronizing...",
+ "error": "System Error",
+ "actions": "Actions",
+ "save": "Save",
+ "cancel": "Cancel",
+ "delete": "Delete"
+ },
+ "auth": {
+ "gateway": "Access Gateway",
+ "auth_required": "Authentication Required",
+ "operator_id": "Operator ID / Email",
+ "security_key": "Security Key",
+ "initiate_login": "Initiate Login",
+ "validating": "Validating credentials...",
+ "new_operator": "New Operator? [Sign Up]",
+ "forgot_creds": "Forgot Credentials?",
+ "back_to_login": "Return to Gateway",
+ "create_account": "Initialize New Profile",
+ "full_name": "Full Operational Name"
+ },
+ "dashboard": {
+ "command_center": "Command Center",
+ "strategic_overview": "Strategic Overview",
+ "operational_status": "Operational Status",
+ "status_nominal": "Nominal",
+ "active_missions": "Active Missions",
+ "strategic_assets": "Strategic Assets",
+ "system_health": "System Health",
+ "detected_flaws": "Detected Flaws",
+ "mission_logs": "Mission Logs",
+ "waiting_data": "Waiting for incoming data...",
+ "system_resources": "System Resources"
+ },
+ "targets": {
+ "inventory": "Target Inventory",
+ "operational_intelligence": "Operational Intelligence",
+ "add_target": "Add New Asset",
+ "target_name": "Target Name / Designation",
+ "target_url": "Target URL / Endpoint",
+ "initialize": "Initialize Asset",
+ "launch_mission": "Launch Mission"
+ },
+ "scans": {
+ "mission_control": "Mission Control",
+ "operational_intel": "Operational Intelligence",
+ "active_threads": "Active Threads",
+ "op_target": "Operation Target",
+ "exec_status": "Execution Status",
+ "depth": "Infiltration Depth",
+ "timestamp": "Timestamp"
+ },
+ "missions": {
+ "select_title": "Select Tactical Profile",
+ "lightning": "Lightning Recon",
+ "balanced": "Balanced Assault",
+ "deep": "Deep Infiltration",
+ "lightning_desc": "Surface-level discovery. Fast and stealthy.",
+ "balanced_desc": "Standard operational depth. Optimal resource usage.",
+ "deep_desc": "Exploitative depth. Maximum intelligence gathering (Slower)."
+ },
+ "vulnerabilities": {
+ "intel_feed": "Intelligence Feed",
+ "threat_landscape": "Threat Landscape",
+ "found_at": "Found At",
+ "severity": "Severity",
+ "description": "Description",
+ "poc": "Technical Proof (PoC)",
+ "mark_fixed": "Mark as Fixed"
+ },
+ "terminal": {
+ "shell_ready": "root@dragonsploit:~# /usr/bin/bash",
+ "telemetry": "System Telemetry",
+ "tools": "Security Tools"
+ },
+ "settings": {
+ "system_settings": "System Settings",
+ "global_tactical": "Global Tactical Configuration",
+ "operator_profile": "Operator Profile",
+ "interface_config": "Interface Configuration",
+ "org_data": "Organization Data",
+ "danger_zone": "Danger Zone"
+ }
+}
diff --git a/frontend/src/shared/lib/i18n/locales/tr.json b/frontend/src/shared/lib/i18n/locales/tr.json
new file mode 100644
index 0000000..0c3f07c
--- /dev/null
+++ b/frontend/src/shared/lib/i18n/locales/tr.json
@@ -0,0 +1,92 @@
+{
+ "common": {
+ "login": "Giriş Yap",
+ "register": "Kayıt Ol",
+ "logout": "Oturumu Kapat",
+ "dashboard": "Panel",
+ "targets": "Hedefler",
+ "scans": "Aktif Taramalar",
+ "vulnerabilities": "Zafiyetler",
+ "terminal": "Terminal",
+ "settings": "Ayarlar",
+ "search": "Ara...",
+ "loading": "Senkronize ediliyor...",
+ "error": "Sistem Hatası",
+ "actions": "İşlemler",
+ "save": "Kaydet",
+ "cancel": "İptal",
+ "delete": "Sil"
+ },
+ "auth": {
+ "gateway": "Erişim Geçidi",
+ "auth_required": "Kimlik Doğrulama Gerekli",
+ "operator_id": "Operatör Kimliği / E-posta",
+ "security_key": "Güvenlik Anahtarı",
+ "initiate_login": "Girişi Başlat",
+ "validating": "Kimlik doğrulanıyor...",
+ "new_operator": "Yeni Operatör mü? [Kayıt Ol]",
+ "forgot_creds": "Bilgilerimi Unuttum",
+ "back_to_login": "Geçide Dön",
+ "create_account": "Yeni Profil Oluştur",
+ "full_name": "Tam Operasyonel Ad"
+ },
+ "dashboard": {
+ "command_center": "Komuta Merkezi",
+ "strategic_overview": "Stratejik Genel Bakış",
+ "operational_status": "Operasyonel Durum",
+ "status_nominal": "Nominal",
+ "active_missions": "Aktif Görevler",
+ "strategic_assets": "Stratejik Varlıklar",
+ "system_health": "Sistem Sağlığı",
+ "detected_flaws": "Tespit Edilen Kusurlar",
+ "mission_logs": "Görev Kayıtları",
+ "waiting_data": "Gelen veriler bekleniyor...",
+ "system_resources": "Sistem Kaynakları"
+ },
+ "targets": {
+ "inventory": "Hedef Envanteri",
+ "operational_intelligence": "Operasyonel İstihbarat",
+ "add_target": "Yeni Varlık Ekle",
+ "target_name": "Hedef Adı / Tanımlama",
+ "target_url": "Hedef URL / Bitiş Noktası",
+ "initialize": "Varlığı Hazırla",
+ "launch_mission": "Görevi Başlat"
+ },
+ "scans": {
+ "mission_control": "Görev Kontrolü",
+ "operational_intel": "Operasyonel İstihbarat",
+ "active_threads": "Aktif İş parçacıkları",
+ "op_target": "Operasyon Hedefi",
+ "exec_status": "Yürütme Durumu",
+ "depth": "Sızma Derinliği",
+ "timestamp": "Zaman Damgası"
+ },
+ "missions": {
+ "select_title": "Taktiksel Profil Seçin",
+ "lightning": "Yıldırım Keşif",
+ "balanced": "Dengeli Taarruz",
+ "deep": "Derin Sızma",
+ "lightning_desc": "Yüzeyel keşif. Hızlı ve gizli.",
+ "balanced_desc": "Standart operasyonel derinlik. Optimal kaynak kullanımı.",
+ "deep_desc": "Sömürü odaklı derinlik. Maksimum istihbarat toplama (Daha yavaş)."
+ },
+ "vulnerabilities": {
+ "dashboard_title": "İstihbarat Akışı",
+ "threat_landscape": "Tehdit Haritası",
+ "detected_flaws": "Tespit Edilen Açıklar",
+ "export_btn": "İstihbaratı Dışa Aktar"
+ },
+ "terminal": {
+ "shell_ready": "root@dragonsploit:~# /usr/bin/bash",
+ "telemetry": "Sistem Telemetrisi",
+ "tools": "Güvenlik Araçları"
+ },
+ "settings": {
+ "system_settings": "Sistem Ayarları",
+ "global_tactical": "Küresel Taktik Yapılandırma",
+ "operator_profile": "Operatör Profili",
+ "interface_config": "Arayüz Yapılandırması",
+ "org_data": "Organizasyon Verileri",
+ "danger_zone": "Tehlikeli Bölge"
+ }
+}
diff --git a/frontend/src/shared/lib/pdf/report-generator.ts b/frontend/src/shared/lib/pdf/report-generator.ts
new file mode 100644
index 0000000..85f405e
--- /dev/null
+++ b/frontend/src/shared/lib/pdf/report-generator.ts
@@ -0,0 +1,153 @@
+import { jsPDF } from 'jspdf';
+import autoTable from 'jspdf-autotable';
+
+interface ReportData {
+ operatorName: string;
+ organizationId: string;
+ timestamp: string;
+ stats: {
+ totalScans: number;
+ activeScans: number;
+ vulnerabilities: number;
+ targets: number;
+ };
+ recentScans: any[];
+ vulnerabilities: any[];
+}
+
+export const generateTacticalReport = (data: ReportData) => {
+ const doc = new jsPDF();
+
+ // --- Page Setup & Background ---
+ doc.setFillColor(10, 10, 10);
+ doc.rect(0, 0, 210, 297, 'F');
+
+ // --- Header ---
+ doc.setDrawColor(0, 255, 65);
+ doc.setLineWidth(0.5);
+ doc.line(10, 10, 200, 10);
+ doc.line(10, 10, 10, 25);
+
+ doc.setTextColor(0, 255, 65);
+ doc.setFont('courier', 'bold');
+ doc.setFontSize(22);
+ doc.text('DRAGONSPLOIT', 15, 20);
+ doc.setTextColor(255, 255, 255);
+ doc.text('STRATEGIC REPORT', 85, 20);
+
+ doc.setFontSize(8);
+ doc.setTextColor(0, 255, 65);
+ doc.text(`MISSION_ID: ${Math.random().toString(36).substring(7).toUpperCase()}`, 160, 17);
+ doc.text(`TIMESTAMP: ${data.timestamp}`, 160, 22);
+
+ doc.line(10, 25, 200, 25);
+ doc.line(200, 10, 200, 25);
+
+ // --- Operational Context ---
+ doc.setFontSize(10);
+ doc.setTextColor(150, 150, 150);
+ doc.text('OPERATOR DESIGNATION:', 15, 40);
+ doc.setTextColor(255, 255, 255);
+ doc.text((data.operatorName || 'UNKNOWN').toUpperCase(), 65, 40);
+
+ doc.setTextColor(150, 150, 150);
+ doc.text('ORGANIZATION CODE:', 15, 46);
+ doc.setTextColor(255, 255, 255);
+ doc.text((data.organizationId || 'UNKNOWN').toUpperCase(), 65, 46);
+
+ // --- Summary Grid ---
+ doc.setDrawColor(50, 50, 50);
+ doc.setFillColor(20, 20, 20);
+
+ // Total Scans Box
+ doc.rect(15, 60, 42, 25, 'FD');
+ doc.setTextColor(0, 255, 65);
+ doc.setFontSize(14);
+ doc.text(data.stats.totalScans.toString(), 36, 75, { align: 'center' });
+ doc.setFontSize(7);
+ doc.text('TOTAL MISSIONS', 36, 82, { align: 'center' });
+
+ // Active Scans Box
+ doc.rect(62, 60, 42, 25, 'FD');
+ doc.setTextColor(0, 255, 65);
+ doc.setFontSize(14);
+ doc.text(data.stats.activeScans.toString(), 83, 75, { align: 'center' });
+ doc.setFontSize(7);
+ doc.text('LIVE THREADS', 83, 82, { align: 'center' });
+
+ // Vulns Box
+ doc.rect(109, 60, 42, 25, 'FD');
+ doc.setTextColor(255, 65, 65);
+ doc.setFontSize(14);
+ doc.text(data.stats.vulnerabilities.toString(), 130, 75, { align: 'center' });
+ doc.setFontSize(7);
+ doc.text('DETECTED FLAWS', 130, 82, { align: 'center' });
+
+ // Targets Box
+ doc.rect(156, 60, 39, 25, 'FD');
+ doc.setTextColor(100, 149, 237);
+ doc.setFontSize(14);
+ doc.text(data.stats.targets.toString(), 175, 75, { align: 'center' });
+ doc.setFontSize(7);
+ doc.text('MAPPED ASSETS', 175, 82, { align: 'center' });
+
+ // --- Intelligence Feed Table ---
+ doc.setTextColor(255, 255, 255);
+ doc.setFontSize(12);
+ doc.text('CRITICAL THREAT LANDSCAPE', 15, 100);
+
+ const vulnRows = data.vulnerabilities.map(v => [
+ (v.severity || 'UNKNOWN').toUpperCase(),
+ v.title || (v.description ? v.description.substring(0, 40) + '...' : 'NO_DESCRIPTION'),
+ v.target?.name || 'EXTERNAL_NODE',
+ v.createdAt ? new Date(v.createdAt).toLocaleDateString() : 'UNKNOWN_DATE'
+ ]);
+
+ autoTable(doc, {
+ startY: 105,
+ head: [['SEVERITY', 'VULNERABILITY DESCRIPTION', 'AFFECTED ASSET', 'DETECTION']],
+ body: vulnRows,
+ theme: 'grid',
+ headStyles: { fillColor: [0, 255, 65], textColor: [0, 0, 0], font: 'courier', fontStyle: 'bold' },
+ bodyStyles: { fillColor: [15, 15, 15], textColor: [200, 200, 200], font: 'courier' },
+ alternateRowStyles: { fillColor: [10, 10, 10] },
+ margin: { left: 15, right: 15 },
+ styles: { lineColor: [50, 50, 50], lineWidth: 0.1 }
+ });
+
+ // --- Recent Operations Table ---
+ const finalY = (doc as any).lastAutoTable?.finalY || 150;
+ doc.setTextColor(255, 255, 255);
+ doc.setFontSize(12);
+ doc.text('RECENT DEPLOYMENT LOGS', 15, finalY + 15);
+
+ const scanRows = data.recentScans.map(s => [
+ s.target?.name || 'UNKNOWN_TARGET',
+ (s.status || 'UNKNOWN').toUpperCase(),
+ s.profile || 'BALANCED',
+ s.createdAt ? new Date(s.createdAt).toLocaleString() : 'UNKNOWN_TIME'
+ ]);
+
+ autoTable(doc, {
+ startY: finalY + 20,
+ head: [['TARGET ASSET', 'STATUS', 'PROFILE', 'EXECUTION TIME']],
+ body: scanRows,
+ theme: 'grid',
+ headStyles: { fillColor: [50, 50, 50], textColor: [0, 255, 65], font: 'courier' },
+ bodyStyles: { fillColor: [15, 15, 15], textColor: [150, 150, 150], font: 'courier' },
+ margin: { left: 15, right: 15 },
+ styles: { lineColor: [30, 30, 30], lineWidth: 0.1 }
+ });
+
+ // --- Footer ---
+ const pageCount = doc.getNumberOfPages();
+ for (let i = 1; i <= pageCount; i++) {
+ doc.setPage(i);
+ doc.setFontSize(8);
+ doc.setTextColor(50, 50, 50);
+ doc.text(`DRAGONSPLOIT INTERNAL SECURITY DOCUMENT // CONFIDENTIAL // PAGE ${i} OF ${pageCount}`, 105, 290, { align: 'center' });
+ }
+
+ // Save the PDF
+ doc.save(`DragonSploit_Tactical_Report_${Date.now()}.pdf`);
+};
diff --git a/frontend/src/widgets/layout/DashboardLayout.tsx b/frontend/src/widgets/layout/DashboardLayout.tsx
new file mode 100644
index 0000000..6a4c7a9
--- /dev/null
+++ b/frontend/src/widgets/layout/DashboardLayout.tsx
@@ -0,0 +1,108 @@
+import React from 'react';
+import { Outlet, Link, useLocation } from 'react-router-dom';
+import {
+ LayoutDashboard,
+ Target,
+ ShieldAlert,
+ Settings,
+ LogOut,
+ Terminal as TerminalIcon,
+ Activity
+} from 'lucide-react';
+import { useAuthStore } from '@/features/auth/model/authStore';
+import { useTranslation } from 'react-i18next';
+import LanguageSwitcher from '@/features/language/ui/LanguageSwitcher';
+
+const DashboardLayout: React.FC = () => {
+ const { logout, user } = useAuthStore();
+ const { t } = useTranslation();
+ const location = useLocation();
+
+ const getInitials = (name: string) => {
+ return name.split(' ').map(n => n[0]).join('').toUpperCase().substring(0, 2);
+ };
+
+ const menuItems = [
+ { icon: LayoutDashboard, label: t('common.dashboard'), path: '/' },
+ { icon: Target, label: t('common.targets'), path: '/targets' },
+ { icon: Activity, label: t('common.scans'), path: '/scans' },
+ { icon: ShieldAlert, label: t('common.vulnerabilities'), path: '/vulnerabilities' },
+ { icon: TerminalIcon, label: t('common.terminal'), path: '/terminal' },
+ { icon: Settings, label: t('common.settings'), path: '/settings' },
+ ];
+
+ return (
+
+ {/* Sidebar */}
+
+
+ {/* Main Content Area */}
+
+ {/* Top Header */}
+
+
+ {/* Dynamic Content */}
+
+ {/* Subtle noise/grain overlay */}
+
+
+
+
+
+ );
+};
+
+export default DashboardLayout;
diff --git a/frontend/tsconfig.app.json b/frontend/tsconfig.app.json
new file mode 100644
index 0000000..a132313
--- /dev/null
+++ b/frontend/tsconfig.app.json
@@ -0,0 +1,32 @@
+{
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+ "target": "ES2022",
+ "useDefineForClassFields": true,
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "types": ["vite/client"],
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "verbatimModuleSyntax": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+ "jsx": "react-jsx",
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "erasableSyntaxOnly": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true,
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ },
+ "include": ["src"]
+}
diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json
new file mode 100644
index 0000000..1ffef60
--- /dev/null
+++ b/frontend/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "files": [],
+ "references": [
+ { "path": "./tsconfig.app.json" },
+ { "path": "./tsconfig.node.json" }
+ ]
+}
diff --git a/frontend/tsconfig.node.json b/frontend/tsconfig.node.json
new file mode 100644
index 0000000..8a67f62
--- /dev/null
+++ b/frontend/tsconfig.node.json
@@ -0,0 +1,26 @@
+{
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+ "target": "ES2023",
+ "lib": ["ES2023"],
+ "module": "ESNext",
+ "types": ["node"],
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "verbatimModuleSyntax": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "erasableSyntaxOnly": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts
new file mode 100644
index 0000000..3571c8c
--- /dev/null
+++ b/frontend/vite.config.ts
@@ -0,0 +1,17 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+import tailwindcss from '@tailwindcss/vite'
+import path from 'path'
+
+// https://vite.dev/config/
+export default defineConfig({
+ plugins: [
+ react(),
+ tailwindcss(),
+ ],
+ resolve: {
+ alias: {
+ '@': path.resolve(__dirname, './src'),
+ },
+ },
+})
diff --git a/implementation_plan.md b/implementation_plan.md
new file mode 100644
index 0000000..7f05eb6
--- /dev/null
+++ b/implementation_plan.md
@@ -0,0 +1,56 @@
+# خطة هندسة الواجهة الأمامية لـ DragonSploit (Enterprise-Grade Engineering Plan)
+
+تستهدف هذه الخطة بناء واجهة أمامية بمستوى عالمي، تعكس التعقيد الهندسي للـ Backend (الذي يستخدم Intent-Based Orchestration). سنبتعد عن الحلول السطحية ونركز على **Feature-Sliced Design (FSD)**، **الأمان الدفاعي (Security-by-Design)**، و **الأداء العالي (High-Performance Computing)** في المتصفح.
+
+## 1. الفلسفة المعمارية: العمق الهندسي قبل الجماليات
+* **Feature-Sliced Design (FSD)**: تقسيم المشروع إلى طبقات (`app`, `pages`, `widgets`, `features`, `entities`, `shared`) لضمان قابلية التوسع والصيانة. هذا النمط هو المقياس الذهبي للتطبيقات الكبيرة في 2025.
+* **Hexagonal Architecture (Port & Adapters)**: فصل منطق العمل (Business Logic) عن واجهة المستخدم (UI)، مما يسمح باختبار "نواة التطبيق" بشكل مستقل تمامًا عن React.
+* **Security-First**: تطبيق مبادئ OWASP Top 10 للواجهات الأمامية (CSP, XSS Protection, Secure State Management).
+
+## 2. الهيكل الهندسي للمشروع (Structure)
+سنعتمد هيكلية FSD الصارمة:
+
+```bash
+frontend/
+├── src/
+│ ├── app/ # تهيئة التطبيق (Providers, Global Styles, Router)
+│ ├── processes/ # العمليات المعقدة التي تمتد عبر صفحات متعددة (مثل مسار المصادقة الكامل)
+│ ├── pages/ # تجميع للـ Widgets لإنشاء صفحات كاملة
+│ ├── widgets/ # كتل UI مستقلة (مثل Navbar, ActiveScanTerminal)
+│ ├── features/ # وظائف المستخدم (مثل AuthByEmail, LaunchScan, ExportReport)
+│ ├── entities/ # وحدات نطاق العمل (User, Target, Scan, Vulnerability)
+│ ├── shared/ # كود قابل لإعادة الاستخدام (UI Kit, API Client, Utils)
+│ │ ├── api/ # طبقة اتصال API (Axios Interceptors, Type-Safe Requests)
+│ │ ├── ui/ # مكتبة المكونات التصميمية (Atomic Design System)
+│ │ └── lib/ # مكتبات مساعدة (Security, Validation)
+```
+
+## 3. الركائز التقنية (Tech Stack)
+* **Core**: React 19 (أحدث الميزات), TypeScript 5.5 (Strict Mode).
+* **State Management**: `Zustand` (للحالة العامة الخفيفة) + `TanStack Query` (لإدارة حالة الخادم والكاش الذكي).
+* **Performance**: الاستعانة بـ **Web Workers** لمعالجة سجلات التيرمينال الضخمة (Log Processing) بعيداً عن الخيط الرئيسي (Main Thread) لضمان واجهة سلسة "60 FPS" حتى تحت الضغط.
+* **Security Layer**:
+ * **DomPurify**: لتعقيم أي مخرجات HTML (خاصة في تقارير الثغرات).
+ * **HttpOnly Cookie Support**: لن نقوم بتخزين التوكنات في LocalStorage أبدًا.
+ * **Content Security Policy (CSP)**: تكوين صارم لمنع هجمات XSS.
+
+## 4. الجودة والاختبار (Quality Assurance)
+* **Unit Testing**: استخدام `Vitest` لاختبار منطق العمل (Entities & Features).
+* **E2E Testing**: استخدام `Playwright` لمحاكاة سيناريوهات هجوم كاملة من الواجهة.
+* **Clean Code Standards**: تكوين `ESLint` مع قواعد `Airbnb` + `SonarQube` للتحليل الساكن.
+
+## 5. التصميم "الاحترافي" (Professional Aesthetic)
+رغم التركيز الهندسي، ستكون الواجهة مذهلة، ولكن بأسلوب "وظيفي" (Functional Aesthetics) مثل أدوات الاستخبارات الحقيقية (Palantir, Maltego):
+* **Data Density**: تصميم يراعي عرض كميات ضخمة من البيانات بوضوح.
+* **Visual Feedback**: مؤشرات دقيقة لكل حالة (Loading, Processing, Success, Failure).
+* **Theming**: نظام تصميمي ذكي يدعم التباين العالي (High Contrast) لسهولة القراءة في البيئات المظلمة.
+
+> [!IMPORTANT]
+> **ملاحظة للمستخدم**: هذه الخطة تنقل المشروع من مجرد "شكل جميل" إلى "منصة هندسية متكاملة".
+
+## 6. خطوات التنفيذ التدريجي
+1. **Init**: تهيئة المشروع مع FSD Structure ووأدوات الـ Quality (Husky, Lint-staged).
+2. **Core**: بناء طبقة الـ API والـ Auth (Entities/User, Features/Auth).
+3. **Domain**: بناء وحدات العمل الأساسية (Target Management, Scan Logic).
+4. **Complex UI**: تطوير "Ternimal Widget" باستخدام Web Workers.
+5. **Integration**: ربط الواجهة مع الـ Backend Orchestrator عبر WebSockets أو Polling ذكي.