mirror of
				https://github.com/9technologygroup/patchmon.net.git
				synced 2025-11-04 05:53:27 +00:00 
			
		
		
		
	Compare commits
	
		
			21 Commits
		
	
	
		
			renovate/v
			...
			renovate/m
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					9335f821f7 | ||
| 
						 | 
					8361caabe8 | ||
| 
						 | 
					f6d23e45b2 | ||
| 
						 | 
					aba0f5cb6b | ||
| 
						 | 
					2ec2b3992c | ||
| 
						 | 
					f85721b292 | ||
| 
						 | 
					1d2c003830 | ||
| 
						 | 
					2975da0f69 | ||
| 
						 | 
					93760d03e1 | ||
| 
						 | 
					43fb54a683 | ||
| 
						 | 
					e9368d1a95 | ||
| 
						 | 
					3ce8c02a31 | ||
| 
						 | 
					ac420901a6 | ||
| 
						 | 
					eb0218bdcb | ||
| 
						 | 
					1f6f58360f | ||
| 
						 | 
					746451c296 | ||
| 
						 | 
					285e4c59ee | ||
| 
						 | 
					9050595b7c | ||
| 
						 | 
					cc46940b0c | ||
| 
						 | 
					203a065479 | ||
| 
						 | 
					8864de6c15 | 
@@ -48,7 +48,7 @@ WORKDIR /app/backend
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
RUN npm cache clean --force &&\
 | 
					RUN npm cache clean --force &&\
 | 
				
			||||||
    rm -rf node_modules ~/.npm /root/.npm &&\
 | 
					    rm -rf node_modules ~/.npm /root/.npm &&\
 | 
				
			||||||
    npm ci --ignore-scripts --legacy-peer-deps --no-audit --prefer-online --fetch-retries=0 &&\
 | 
					    npm ci --ignore-scripts --legacy-peer-deps --no-audit --prefer-online --fetch-retries=3 --fetch-retry-mintimeout=20000 --fetch-retry-maxtimeout=120000 &&\
 | 
				
			||||||
    PRISMA_CLI_BINARY_TYPE=binary npm run db:generate &&\
 | 
					    PRISMA_CLI_BINARY_TYPE=binary npm run db:generate &&\
 | 
				
			||||||
    npm prune --omit=dev &&\
 | 
					    npm prune --omit=dev &&\
 | 
				
			||||||
    npm cache clean --force
 | 
					    npm cache clean --force
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,9 +21,13 @@ WORKDIR /app/frontend
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
COPY frontend/package*.json ./
 | 
					COPY frontend/package*.json ./
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN npm cache clean --force &&\
 | 
					RUN echo "=== Starting npm install ===" &&\
 | 
				
			||||||
 | 
					    npm cache clean --force &&\
 | 
				
			||||||
    rm -rf node_modules ~/.npm /root/.npm &&\
 | 
					    rm -rf node_modules ~/.npm /root/.npm &&\
 | 
				
			||||||
    npm install --ignore-scripts --legacy-peer-deps --no-audit --prefer-online --fetch-retries=0
 | 
					    echo "=== npm install ===" &&\
 | 
				
			||||||
 | 
					    npm install --ignore-scripts --legacy-peer-deps --no-audit --prefer-online --fetch-retries=3 --fetch-retry-mintimeout=20000 --fetch-retry-maxtimeout=120000 &&\
 | 
				
			||||||
 | 
					    echo "=== npm install completed ===" &&\
 | 
				
			||||||
 | 
					    npm cache clean --force
 | 
				
			||||||
 | 
					
 | 
				
			||||||
COPY frontend/ ./
 | 
					COPY frontend/ ./
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,8 +27,7 @@
 | 
				
			|||||||
		"react-chartjs-2": "^5.2.0",
 | 
							"react-chartjs-2": "^5.2.0",
 | 
				
			||||||
		"react-dom": "^18.3.1",
 | 
							"react-dom": "^18.3.1",
 | 
				
			||||||
		"react-icons": "^5.5.0",
 | 
							"react-icons": "^5.5.0",
 | 
				
			||||||
		"react-router-dom": "^6.30.1",
 | 
							"react-router-dom": "^6.30.1"
 | 
				
			||||||
		"trianglify": "^4.1.1"
 | 
					 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	"devDependencies": {
 | 
						"devDependencies": {
 | 
				
			||||||
		"@types/react": "^18.3.14",
 | 
							"@types/react": "^18.3.14",
 | 
				
			||||||
@@ -36,7 +35,7 @@
 | 
				
			|||||||
		"@vitejs/plugin-react": "^4.3.4",
 | 
							"@vitejs/plugin-react": "^4.3.4",
 | 
				
			||||||
		"autoprefixer": "^10.4.20",
 | 
							"autoprefixer": "^10.4.20",
 | 
				
			||||||
		"postcss": "^8.5.6",
 | 
							"postcss": "^8.5.6",
 | 
				
			||||||
		"tailwindcss": "^3.4.17",
 | 
							"tailwindcss": "^4.0.0",
 | 
				
			||||||
		"vite": "^7.1.5"
 | 
							"vite": "^7.1.5"
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	"overrides": {
 | 
						"overrides": {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,7 +28,6 @@ import {
 | 
				
			|||||||
import { useCallback, useEffect, useRef, useState } from "react";
 | 
					import { useCallback, useEffect, useRef, useState } from "react";
 | 
				
			||||||
import { FaReddit, FaYoutube } from "react-icons/fa";
 | 
					import { FaReddit, FaYoutube } from "react-icons/fa";
 | 
				
			||||||
import { Link, useLocation, useNavigate } from "react-router-dom";
 | 
					import { Link, useLocation, useNavigate } from "react-router-dom";
 | 
				
			||||||
import trianglify from "trianglify";
 | 
					 | 
				
			||||||
import { useAuth } from "../contexts/AuthContext";
 | 
					import { useAuth } from "../contexts/AuthContext";
 | 
				
			||||||
import { useColorTheme } from "../contexts/ColorThemeContext";
 | 
					import { useColorTheme } from "../contexts/ColorThemeContext";
 | 
				
			||||||
import { useUpdateNotification } from "../contexts/UpdateNotificationContext";
 | 
					import { useUpdateNotification } from "../contexts/UpdateNotificationContext";
 | 
				
			||||||
@@ -237,31 +236,93 @@ const Layout = ({ children }) => {
 | 
				
			|||||||
		navigate("/hosts?action=add");
 | 
							navigate("/hosts?action=add");
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Generate Trianglify background for dark mode
 | 
						// Generate clean radial gradient background with subtle triangular accents for dark mode
 | 
				
			||||||
	useEffect(() => {
 | 
						useEffect(() => {
 | 
				
			||||||
		const generateBackground = () => {
 | 
							const generateBackground = () => {
 | 
				
			||||||
			if (
 | 
								if (
 | 
				
			||||||
				bgCanvasRef.current &&
 | 
									!bgCanvasRef.current ||
 | 
				
			||||||
				themeConfig?.login &&
 | 
									!themeConfig?.login ||
 | 
				
			||||||
				document.documentElement.classList.contains("dark")
 | 
									!document.documentElement.classList.contains("dark")
 | 
				
			||||||
			) {
 | 
								) {
 | 
				
			||||||
				// Get current date as seed for daily variation
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								const canvas = bgCanvasRef.current;
 | 
				
			||||||
 | 
								canvas.width = window.innerWidth;
 | 
				
			||||||
 | 
								canvas.height = window.innerHeight;
 | 
				
			||||||
 | 
								const ctx = canvas.getContext("2d");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Get theme colors - pick first color from each palette
 | 
				
			||||||
 | 
								const xColors = themeConfig.login.xColors || [
 | 
				
			||||||
 | 
									"#667eea",
 | 
				
			||||||
 | 
									"#764ba2",
 | 
				
			||||||
 | 
									"#f093fb",
 | 
				
			||||||
 | 
									"#4facfe",
 | 
				
			||||||
 | 
								];
 | 
				
			||||||
 | 
								const yColors = themeConfig.login.yColors || [
 | 
				
			||||||
 | 
									"#667eea",
 | 
				
			||||||
 | 
									"#764ba2",
 | 
				
			||||||
 | 
									"#f093fb",
 | 
				
			||||||
 | 
									"#4facfe",
 | 
				
			||||||
 | 
								];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Use date for daily color rotation
 | 
				
			||||||
			const today = new Date();
 | 
								const today = new Date();
 | 
				
			||||||
				const dateSeed = `${today.getFullYear()}-${today.getMonth()}-${today.getDate()}`;
 | 
								const seed =
 | 
				
			||||||
 | 
									today.getFullYear() * 10000 + today.getMonth() * 100 + today.getDate();
 | 
				
			||||||
 | 
								const random = (s) => {
 | 
				
			||||||
 | 
									const x = Math.sin(s) * 10000;
 | 
				
			||||||
 | 
									return x - Math.floor(x);
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Generate pattern with selected theme configuration
 | 
								const color1 = xColors[Math.floor(random(seed) * xColors.length)];
 | 
				
			||||||
				const pattern = trianglify({
 | 
								const color2 = yColors[Math.floor(random(seed + 1000) * yColors.length)];
 | 
				
			||||||
					width: window.innerWidth,
 | 
					 | 
				
			||||||
					height: window.innerHeight,
 | 
					 | 
				
			||||||
					cellSize: themeConfig.login.cellSize,
 | 
					 | 
				
			||||||
					variance: themeConfig.login.variance,
 | 
					 | 
				
			||||||
					seed: dateSeed,
 | 
					 | 
				
			||||||
					xColors: themeConfig.login.xColors,
 | 
					 | 
				
			||||||
					yColors: themeConfig.login.yColors,
 | 
					 | 
				
			||||||
				});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Render to canvas
 | 
								// Create clean radial gradient from center to bottom-right corner
 | 
				
			||||||
				pattern.toCanvas(bgCanvasRef.current);
 | 
								const gradient = ctx.createRadialGradient(
 | 
				
			||||||
 | 
									canvas.width * 0.3, // Center slightly left
 | 
				
			||||||
 | 
									canvas.height * 0.3, // Center slightly up
 | 
				
			||||||
 | 
									0,
 | 
				
			||||||
 | 
									canvas.width * 0.5, // Expand to cover screen
 | 
				
			||||||
 | 
									canvas.height * 0.5,
 | 
				
			||||||
 | 
									Math.max(canvas.width, canvas.height) * 1.2,
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Subtle gradient with darker corners
 | 
				
			||||||
 | 
								gradient.addColorStop(0, color1);
 | 
				
			||||||
 | 
								gradient.addColorStop(0.6, color2);
 | 
				
			||||||
 | 
								gradient.addColorStop(1, "#0a0a0a"); // Very dark edges
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ctx.fillStyle = gradient;
 | 
				
			||||||
 | 
								ctx.fillRect(0, 0, canvas.width, canvas.height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Add subtle triangular shapes as accents across entire background
 | 
				
			||||||
 | 
								const cellSize = 180;
 | 
				
			||||||
 | 
								const cols = Math.ceil(canvas.width / cellSize) + 1;
 | 
				
			||||||
 | 
								const rows = Math.ceil(canvas.height / cellSize) + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								for (let y = 0; y < rows; y++) {
 | 
				
			||||||
 | 
									for (let x = 0; x < cols; x++) {
 | 
				
			||||||
 | 
										const idx = y * cols + x;
 | 
				
			||||||
 | 
										// Draw more triangles (less sparse)
 | 
				
			||||||
 | 
										if (random(seed + idx + 5000) > 0.4) {
 | 
				
			||||||
 | 
											const baseX =
 | 
				
			||||||
 | 
												x * cellSize + random(seed + idx * 3) * cellSize * 0.8;
 | 
				
			||||||
 | 
											const baseY =
 | 
				
			||||||
 | 
												y * cellSize + random(seed + idx * 3 + 100) * cellSize * 0.8;
 | 
				
			||||||
 | 
											const size = 50 + random(seed + idx * 4) * 100;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											ctx.beginPath();
 | 
				
			||||||
 | 
											ctx.moveTo(baseX, baseY);
 | 
				
			||||||
 | 
											ctx.lineTo(baseX + size, baseY);
 | 
				
			||||||
 | 
											ctx.lineTo(baseX + size / 2, baseY - size * 0.866);
 | 
				
			||||||
 | 
											ctx.closePath();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											// More visible white with slightly higher opacity
 | 
				
			||||||
 | 
											ctx.fillStyle = `rgba(255, 255, 255, ${0.05 + random(seed + idx * 5) * 0.08})`;
 | 
				
			||||||
 | 
											ctx.fill();
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,6 @@ import { useEffect, useId, useRef, useState } from "react";
 | 
				
			|||||||
import { FaReddit, FaYoutube } from "react-icons/fa";
 | 
					import { FaReddit, FaYoutube } from "react-icons/fa";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { useNavigate } from "react-router-dom";
 | 
					import { useNavigate } from "react-router-dom";
 | 
				
			||||||
import trianglify from "trianglify";
 | 
					 | 
				
			||||||
import DiscordIcon from "../components/DiscordIcon";
 | 
					import DiscordIcon from "../components/DiscordIcon";
 | 
				
			||||||
import { useAuth } from "../contexts/AuthContext";
 | 
					import { useAuth } from "../contexts/AuthContext";
 | 
				
			||||||
import { useColorTheme } from "../contexts/ColorThemeContext";
 | 
					import { useColorTheme } from "../contexts/ColorThemeContext";
 | 
				
			||||||
@@ -57,27 +56,87 @@ const Login = () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	const navigate = useNavigate();
 | 
						const navigate = useNavigate();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Generate Trianglify background based on selected theme
 | 
						// Generate clean radial gradient background with subtle triangular accents
 | 
				
			||||||
	useEffect(() => {
 | 
						useEffect(() => {
 | 
				
			||||||
		const generateBackground = () => {
 | 
							const generateBackground = () => {
 | 
				
			||||||
			if (canvasRef.current && themeConfig?.login) {
 | 
								if (!canvasRef.current || !themeConfig?.login) return;
 | 
				
			||||||
				// Get current date as seed for daily variation
 | 
					
 | 
				
			||||||
 | 
								const canvas = canvasRef.current;
 | 
				
			||||||
 | 
								canvas.width = canvas.offsetWidth;
 | 
				
			||||||
 | 
								canvas.height = canvas.offsetHeight;
 | 
				
			||||||
 | 
								const ctx = canvas.getContext("2d");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Get theme colors - pick first color from each palette
 | 
				
			||||||
 | 
								const xColors = themeConfig.login.xColors || [
 | 
				
			||||||
 | 
									"#667eea",
 | 
				
			||||||
 | 
									"#764ba2",
 | 
				
			||||||
 | 
									"#f093fb",
 | 
				
			||||||
 | 
									"#4facfe",
 | 
				
			||||||
 | 
								];
 | 
				
			||||||
 | 
								const yColors = themeConfig.login.yColors || [
 | 
				
			||||||
 | 
									"#667eea",
 | 
				
			||||||
 | 
									"#764ba2",
 | 
				
			||||||
 | 
									"#f093fb",
 | 
				
			||||||
 | 
									"#4facfe",
 | 
				
			||||||
 | 
								];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Use date for daily color rotation
 | 
				
			||||||
			const today = new Date();
 | 
								const today = new Date();
 | 
				
			||||||
				const dateSeed = `${today.getFullYear()}-${today.getMonth()}-${today.getDate()}`;
 | 
								const seed =
 | 
				
			||||||
 | 
									today.getFullYear() * 10000 + today.getMonth() * 100 + today.getDate();
 | 
				
			||||||
 | 
								const random = (s) => {
 | 
				
			||||||
 | 
									const x = Math.sin(s) * 10000;
 | 
				
			||||||
 | 
									return x - Math.floor(x);
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Generate pattern with selected theme configuration
 | 
								const color1 = xColors[Math.floor(random(seed) * xColors.length)];
 | 
				
			||||||
				const pattern = trianglify({
 | 
								const color2 = yColors[Math.floor(random(seed + 1000) * yColors.length)];
 | 
				
			||||||
					width: canvasRef.current.offsetWidth,
 | 
					 | 
				
			||||||
					height: canvasRef.current.offsetHeight,
 | 
					 | 
				
			||||||
					cellSize: themeConfig.login.cellSize,
 | 
					 | 
				
			||||||
					variance: themeConfig.login.variance,
 | 
					 | 
				
			||||||
					seed: dateSeed,
 | 
					 | 
				
			||||||
					xColors: themeConfig.login.xColors,
 | 
					 | 
				
			||||||
					yColors: themeConfig.login.yColors,
 | 
					 | 
				
			||||||
				});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Render to canvas
 | 
								// Create clean radial gradient from center to bottom-right corner
 | 
				
			||||||
				pattern.toCanvas(canvasRef.current);
 | 
								const gradient = ctx.createRadialGradient(
 | 
				
			||||||
 | 
									canvas.width * 0.3, // Center slightly left
 | 
				
			||||||
 | 
									canvas.height * 0.3, // Center slightly up
 | 
				
			||||||
 | 
									0,
 | 
				
			||||||
 | 
									canvas.width * 0.5, // Expand to cover screen
 | 
				
			||||||
 | 
									canvas.height * 0.5,
 | 
				
			||||||
 | 
									Math.max(canvas.width, canvas.height) * 1.2,
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Subtle gradient with darker corners
 | 
				
			||||||
 | 
								gradient.addColorStop(0, color1);
 | 
				
			||||||
 | 
								gradient.addColorStop(0.6, color2);
 | 
				
			||||||
 | 
								gradient.addColorStop(1, "#0a0a0a"); // Very dark edges
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ctx.fillStyle = gradient;
 | 
				
			||||||
 | 
								ctx.fillRect(0, 0, canvas.width, canvas.height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Add subtle triangular shapes as accents across entire background
 | 
				
			||||||
 | 
								const cellSize = 180;
 | 
				
			||||||
 | 
								const cols = Math.ceil(canvas.width / cellSize) + 1;
 | 
				
			||||||
 | 
								const rows = Math.ceil(canvas.height / cellSize) + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								for (let y = 0; y < rows; y++) {
 | 
				
			||||||
 | 
									for (let x = 0; x < cols; x++) {
 | 
				
			||||||
 | 
										const idx = y * cols + x;
 | 
				
			||||||
 | 
										// Draw more triangles (less sparse)
 | 
				
			||||||
 | 
										if (random(seed + idx + 5000) > 0.4) {
 | 
				
			||||||
 | 
											const baseX =
 | 
				
			||||||
 | 
												x * cellSize + random(seed + idx * 3) * cellSize * 0.8;
 | 
				
			||||||
 | 
											const baseY =
 | 
				
			||||||
 | 
												y * cellSize + random(seed + idx * 3 + 100) * cellSize * 0.8;
 | 
				
			||||||
 | 
											const size = 50 + random(seed + idx * 4) * 100;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											ctx.beginPath();
 | 
				
			||||||
 | 
											ctx.moveTo(baseX, baseY);
 | 
				
			||||||
 | 
											ctx.lineTo(baseX + size, baseY);
 | 
				
			||||||
 | 
											ctx.lineTo(baseX + size / 2, baseY - size * 0.866);
 | 
				
			||||||
 | 
											ctx.closePath();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											// More visible white with slightly higher opacity
 | 
				
			||||||
 | 
											ctx.fillStyle = `rgba(255, 255, 255, ${0.05 + random(seed + idx * 5) * 0.08})`;
 | 
				
			||||||
 | 
											ctx.fill();
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -90,7 +149,7 @@ const Login = () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		window.addEventListener("resize", handleResize);
 | 
							window.addEventListener("resize", handleResize);
 | 
				
			||||||
		return () => window.removeEventListener("resize", handleResize);
 | 
							return () => window.removeEventListener("resize", handleResize);
 | 
				
			||||||
	}, [themeConfig]); // Regenerate when theme changes
 | 
						}, [themeConfig]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Check if signup is enabled
 | 
						// Check if signup is enabled
 | 
				
			||||||
	useEffect(() => {
 | 
						useEffect(() => {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1498
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1498
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2
									
								
								setup.sh
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								setup.sh
									
									
									
									
									
								
							@@ -2931,6 +2931,8 @@ update_installation() {
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
    # Load existing .env to get database credentials
 | 
					    # Load existing .env to get database credentials
 | 
				
			||||||
    if [ -f "$instance_dir/backend/.env" ]; then
 | 
					    if [ -f "$instance_dir/backend/.env" ]; then
 | 
				
			||||||
 | 
					        # Unset color variables before sourcing to prevent ANSI escape sequences from leaking into .env
 | 
				
			||||||
 | 
					        unset RED GREEN YELLOW BLUE NC
 | 
				
			||||||
        source "$instance_dir/backend/.env"
 | 
					        source "$instance_dir/backend/.env"
 | 
				
			||||||
        print_status "Loaded existing configuration"
 | 
					        print_status "Loaded existing configuration"
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user