Изменить 'wbld/orbits.html'
This commit is contained in:
431
wbld/orbits.html
431
wbld/orbits.html
@@ -1,215 +1,286 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Senthara Orbit, Rotation & Day/Night Visualization</title>
|
||||
<script src="https://cdn.jsdelivr.net/npm/phaser@3.60.0/dist/phaser.js"></script>
|
||||
<style>
|
||||
body { margin: 0; overflow: hidden; }
|
||||
canvas { display: block; }
|
||||
</style>
|
||||
<meta charset="UTF-8">
|
||||
<title>Senthara Orbit, Rotation & Day/Night Visualization</title>
|
||||
<script src="https://cdn.jsdelivr.net/npm/phaser@3.60.0/dist/phaser.js"></script>
|
||||
<style>
|
||||
body { margin: 0; overflow: hidden; }
|
||||
canvas { display: block; }
|
||||
/* Style for the control panel */
|
||||
#controlPanel {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
font-family: Arial, sans-serif;
|
||||
color: white;
|
||||
}
|
||||
#controlPanel button, #controlPanel select {
|
||||
margin: 5px;
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #ccc;
|
||||
background-color: #eee;
|
||||
color: black;
|
||||
cursor: pointer;
|
||||
}
|
||||
#controlPanel button:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
#controlPanel select:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
// Function to calculate the current Senthara date from simulationTime (in days)
|
||||
// We add an offset so that simulationTime = 0 corresponds to "Autumn 36"
|
||||
// With a 396-day year divided evenly into 4 seasons, an offset of 134 ensures:
|
||||
// floor(134) mod 99 = 35 so that dayOfSeason becomes 35+1 = 36 and seasonIndex = 1 (Autumn).
|
||||
function getSentharaDate(simDays) {
|
||||
const offset = 134;
|
||||
const X = Math.floor(simDays + offset);
|
||||
const year = Math.floor(X / 396) + 1;
|
||||
const dayOfYear = (X % 396) + 1;
|
||||
const seasonIndex = Math.floor((dayOfYear - 1) / 99);
|
||||
const dayOfSeason = dayOfYear - seasonIndex * 99;
|
||||
const seasons = ["Summer", "Autumn", "Winter", "Spring"];
|
||||
return `Year ${year} - ${seasons[seasonIndex]} ${dayOfSeason}`;
|
||||
}
|
||||
<div id="controlPanel">
|
||||
<button id="playPauseButton">Play</button>
|
||||
<button id="rewindButton">Rewind</button>
|
||||
<select id="speedSelect">
|
||||
<option value="1">x1</option>
|
||||
<option value="2">x2</option>
|
||||
<option value="5" selected>x5</option>
|
||||
<option value="10">x10</option>
|
||||
<option value="100">x100</option>
|
||||
<option value="1000">x1000</option>
|
||||
<option value="10000">x10000</option>
|
||||
<option value="100000">x100000</option>
|
||||
<option value="1000000">x1000000</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
// Phaser configuration (responsive)
|
||||
const config = {
|
||||
type: Phaser.AUTO,
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
backgroundColor: "#000000",
|
||||
scene: {
|
||||
preload: preload,
|
||||
create: create,
|
||||
update: update
|
||||
},
|
||||
scale: {
|
||||
mode: Phaser.Scale.RESIZE
|
||||
}
|
||||
};
|
||||
<script>
|
||||
// Function to calculate the current Senthara date from simulationTime (in days)
|
||||
function getSentharaDate(simDays) {
|
||||
const offset = 134;
|
||||
const X = Math.floor(simDays + offset);
|
||||
const year = Math.floor(X / 396) + 1;
|
||||
const dayOfYear = (X % 396) + 1;
|
||||
const seasonIndex = Math.floor((dayOfYear - 1) / 99);
|
||||
const dayOfSeason = dayOfYear - seasonIndex * 99;
|
||||
const seasons = ["Summer", "Autumn", "Winter", "Spring"];
|
||||
return `Year ${year} - ${seasons[seasonIndex]} ${dayOfSeason}`;
|
||||
}
|
||||
|
||||
const game = new Phaser.Game(config);
|
||||
// Phaser configuration (responsive)
|
||||
const config = {
|
||||
type: Phaser.AUTO,
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
backgroundColor: "#000000",
|
||||
scene: {
|
||||
preload: preload,
|
||||
create: create,
|
||||
update: update
|
||||
},
|
||||
scale: {
|
||||
mode: Phaser.Scale.RESIZE
|
||||
}
|
||||
};
|
||||
|
||||
let globalGraphics;
|
||||
let dateText;
|
||||
let simulationTime = 0; // in days (simulation time)
|
||||
const simulationSpeed = 5; // speed multiplier
|
||||
const game = new Phaser.Game(config);
|
||||
|
||||
// Orbital periods (in days)
|
||||
const planetPeriod = 396; // Senthara's orbital year
|
||||
const planetRotationPeriod = 1; // Planet rotates fully in 1 day
|
||||
const kerielPeriod = 27;
|
||||
const arkaenPeriod = 82;
|
||||
const minianPeriod = 98;
|
||||
let globalGraphics;
|
||||
let dateText;
|
||||
let simulationTime = 0; // in days (simulation time)
|
||||
let simulationSpeed = 5; // speed multiplier
|
||||
let isPlaying = false; // Start paused
|
||||
let isRewinding = false; // Control forward/backward
|
||||
|
||||
// Orbital radii (computed relative to window size)
|
||||
let planetOrbitRadius, kerielOrbitRadius, arkaenOrbitRadius, minianOrbitRadius;
|
||||
|
||||
// Containers for the planet and the moons
|
||||
let planetContainer;
|
||||
let kerielContainer, arkaenContainer, minianContainer;
|
||||
// Orbital periods (in days)
|
||||
const planetPeriod = 396; // Senthara's orbital year
|
||||
const planetRotationPeriod = 1; // Planet rotates fully in 1 day
|
||||
const kerielPeriod = 27;
|
||||
const arkaenPeriod = 82;
|
||||
const minianPeriod = 98;
|
||||
|
||||
function preload() {
|
||||
// No external assets are needed.
|
||||
}
|
||||
// Orbital radii (computed relative to window size)
|
||||
let planetOrbitRadius, kerielOrbitRadius, arkaenOrbitRadius, minianOrbitRadius;
|
||||
|
||||
function create() {
|
||||
globalGraphics = this.add.graphics();
|
||||
// Containers for the planet and the moons
|
||||
let planetContainer;
|
||||
let kerielContainer, arkaenContainer, minianContainer;
|
||||
|
||||
dateText = this.add.text(10, game.scale.height - 30, "", {
|
||||
font: "20px Arial",
|
||||
fill: "#ffffff"
|
||||
});
|
||||
function preload() {
|
||||
// No external assets are needed.
|
||||
}
|
||||
|
||||
recalcOrbitRadii();
|
||||
function create() {
|
||||
globalGraphics = this.add.graphics();
|
||||
|
||||
// Create a container for Senthara (the planet)
|
||||
planetContainer = this.add.container(0, 0);
|
||||
|
||||
// Draw the planet body (green circle) with a marker for rotation.
|
||||
let planetBody = this.add.graphics();
|
||||
planetBody.fillStyle(0x00FF00, 1);
|
||||
planetBody.fillCircle(0, 0, 12);
|
||||
// Marker line (points to the right)
|
||||
planetBody.lineStyle(2, 0x000000, 1);
|
||||
planetBody.beginPath();
|
||||
planetBody.moveTo(0, 0);
|
||||
planetBody.lineTo(12, 0);
|
||||
planetBody.strokePath();
|
||||
planetContainer.add(planetBody);
|
||||
dateText = this.add.text(10, game.scale.height - 30, "", {
|
||||
font: "20px Arial",
|
||||
fill: "#ffffff"
|
||||
});
|
||||
|
||||
// Create a night overlay (semi-transparent dark half-circle)
|
||||
let nightOverlay = this.add.graphics();
|
||||
nightOverlay.fillStyle(0x000000, 0.5);
|
||||
// Draw a half-circle (180° arc) with radius 12
|
||||
nightOverlay.slice(0, 0, 12, 0, Math.PI, false);
|
||||
nightOverlay.fillPath();
|
||||
// Save as a property for updating its rotation later.
|
||||
planetContainer.nightOverlay = nightOverlay;
|
||||
planetContainer.add(nightOverlay);
|
||||
recalcOrbitRadii();
|
||||
|
||||
// Create containers for each moon.
|
||||
kerielContainer = createMoonContainer(this, 6, 0xFF0000); // Keriel: red
|
||||
arkaenContainer = createMoonContainer(this, 5, 0x0000FF); // Arkaen: blue
|
||||
minianContainer = createMoonContainer(this, 5, 0xFFFFFF); // Minian: white
|
||||
// Create a container for Senthara (the planet)
|
||||
planetContainer = this.add.container(0, 0);
|
||||
|
||||
// Listen for window resize events.
|
||||
this.scale.on('resize', (gameSize) => {
|
||||
recalcOrbitRadii();
|
||||
dateText.setPosition(10, gameSize.height - 30);
|
||||
});
|
||||
}
|
||||
// Draw the planet body (green circle) with a marker for rotation.
|
||||
let planetBody = this.add.graphics();
|
||||
planetBody.fillStyle(0x00FF00, 1);
|
||||
planetBody.fillCircle(0, 0, 12);
|
||||
// Marker line (points to the right)
|
||||
planetBody.lineStyle(2, 0x000000, 1);
|
||||
planetBody.beginPath();
|
||||
planetBody.moveTo(0, 0);
|
||||
planetBody.lineTo(12, 0);
|
||||
planetBody.strokePath();
|
||||
planetContainer.add(planetBody);
|
||||
|
||||
// Helper function to create a moon container with a circular body and a marker.
|
||||
function createMoonContainer(scene, radius, color) {
|
||||
let moonContainer = scene.add.container(0, 0);
|
||||
let moonBody = scene.add.graphics();
|
||||
moonBody.fillStyle(color, 1);
|
||||
moonBody.fillCircle(0, 0, radius);
|
||||
// Marker line indicating the "front" of the moon.
|
||||
moonBody.lineStyle(2, 0x000000, 1);
|
||||
moonBody.beginPath();
|
||||
moonBody.moveTo(0, 0);
|
||||
moonBody.lineTo(radius, 0);
|
||||
moonBody.strokePath();
|
||||
moonContainer.add(moonBody);
|
||||
return moonContainer;
|
||||
}
|
||||
// Create a night overlay (semi-transparent dark half-circle)
|
||||
let nightOverlay = this.add.graphics();
|
||||
nightOverlay.fillStyle(0x000000, 0.5);
|
||||
// Draw a half-circle (180° arc) with radius 12
|
||||
nightOverlay.slice(0, 0, 12, 0, Math.PI, false);
|
||||
nightOverlay.fillPath();
|
||||
// Save as a property for updating its rotation later.
|
||||
planetContainer.nightOverlay = nightOverlay;
|
||||
planetContainer.add(nightOverlay);
|
||||
|
||||
// Recalculate orbital radii based on the current window size.
|
||||
function recalcOrbitRadii() {
|
||||
const minDim = Math.min(window.innerWidth, window.innerHeight);
|
||||
planetOrbitRadius = minDim * 0.3; // 30% of the smaller dimension
|
||||
kerielOrbitRadius = planetOrbitRadius * 0.25;
|
||||
arkaenOrbitRadius = planetOrbitRadius * 0.35;
|
||||
minianOrbitRadius = planetOrbitRadius * 0.45;
|
||||
}
|
||||
// Create containers for each moon.
|
||||
kerielContainer = createMoonContainer(this, 6, 0xFF0000); // Keriel: red
|
||||
arkaenContainer = createMoonContainer(this, 5, 0x0000FF); // Arkaen: blue
|
||||
minianContainer = createMoonContainer(this, 5, 0xFFFFFF); // Minian: white
|
||||
|
||||
function update(time, delta) {
|
||||
// Advance simulation time.
|
||||
simulationTime += (delta * simulationSpeed) / 1000;
|
||||
// Listen for window resize events.
|
||||
this.scale.on('resize', (gameSize) => {
|
||||
recalcOrbitRadii();
|
||||
dateText.setPosition(10, gameSize.height - 30);
|
||||
});
|
||||
|
||||
// Get center of the screen (position of the star).
|
||||
const centerX = game.scale.width / 2;
|
||||
const centerY = game.scale.height / 2;
|
||||
|
||||
// Clear global graphics.
|
||||
globalGraphics.clear();
|
||||
// --- UI Control Event Handlers ---
|
||||
const playPauseButton = document.getElementById("playPauseButton");
|
||||
const rewindButton = document.getElementById("rewindButton");
|
||||
const speedSelect = document.getElementById("speedSelect");
|
||||
|
||||
// Draw the central star.
|
||||
globalGraphics.fillStyle(0xFFFF00, 1);
|
||||
globalGraphics.fillCircle(centerX, centerY, 20);
|
||||
playPauseButton.addEventListener("click", () => {
|
||||
isPlaying = !isPlaying;
|
||||
playPauseButton.textContent = isPlaying ? "Pause" : "Play";
|
||||
if (isPlaying) isRewinding = false; // Stop rewinding when playing
|
||||
});
|
||||
|
||||
// Draw Senthara's orbital path (around the star).
|
||||
globalGraphics.lineStyle(1, 0x555555, 1);
|
||||
globalGraphics.strokeCircle(centerX, centerY, planetOrbitRadius);
|
||||
|
||||
// Calculate Senthara's (the planet's) position along its orbit.
|
||||
const planetOrbitAngle = Phaser.Math.DegToRad((360 * (simulationTime % planetPeriod)) / planetPeriod - 90);
|
||||
const planetX = centerX + planetOrbitRadius * Math.cos(planetOrbitAngle);
|
||||
const planetY = centerY + planetOrbitRadius * Math.sin(planetOrbitAngle);
|
||||
rewindButton.addEventListener("click", () => {
|
||||
isRewinding = !isRewinding;
|
||||
rewindButton.textContent = isRewinding ? "Forward" : "Rewind";
|
||||
if(isRewinding) isPlaying = false; // Pause when rewinding
|
||||
playPauseButton.textContent = "Play"; // Reset play/pause button
|
||||
});
|
||||
|
||||
// Update the planet container's position.
|
||||
planetContainer.x = planetX;
|
||||
planetContainer.y = planetY;
|
||||
// Set the planet's self-rotation (day/night cycle) with a 1-day period.
|
||||
const planetRotationAngle = Phaser.Math.DegToRad((360 * (simulationTime % planetRotationPeriod)) / planetRotationPeriod);
|
||||
planetContainer.rotation = planetRotationAngle;
|
||||
speedSelect.addEventListener("change", () => {
|
||||
simulationSpeed = parseFloat(speedSelect.value);
|
||||
});
|
||||
}
|
||||
|
||||
// Update the night overlay so that the dark half covers the side away from the star.
|
||||
const subsolarAngle = Phaser.Math.Angle.Between(planetX, planetY, centerX, centerY);
|
||||
// The night overlay's rotation is adjusted relative to the planet's rotation.
|
||||
planetContainer.nightOverlay.rotation = subsolarAngle + Math.PI / 2 - planetContainer.rotation;
|
||||
// Helper function to create a moon container with a circular body and a marker.
|
||||
function createMoonContainer(scene, radius, color) {
|
||||
let moonContainer = scene.add.container(0, 0);
|
||||
let moonBody = scene.add.graphics();
|
||||
moonBody.fillStyle(color, 1);
|
||||
moonBody.fillCircle(0, 0, radius);
|
||||
// Marker line indicating the "front" of the moon.
|
||||
moonBody.lineStyle(2, 0x000000, 1);
|
||||
moonBody.beginPath();
|
||||
moonBody.moveTo(0, 0);
|
||||
moonBody.lineTo(radius, 0);
|
||||
moonBody.strokePath();
|
||||
moonContainer.add(moonBody);
|
||||
return moonContainer;
|
||||
}
|
||||
|
||||
// Calculate and update moon positions (relative to Senthara).
|
||||
// Keriel:
|
||||
const kerielOrbitAngle = Phaser.Math.DegToRad((360 * (simulationTime % kerielPeriod)) / kerielPeriod - 90);
|
||||
const kerielX = planetX + kerielOrbitRadius * Math.cos(kerielOrbitAngle);
|
||||
const kerielY = planetY + kerielOrbitRadius * Math.sin(kerielOrbitAngle);
|
||||
kerielContainer.x = kerielX;
|
||||
kerielContainer.y = kerielY;
|
||||
// Ensure tidal locking: set Keriel's rotation so its marker points toward Senthara.
|
||||
kerielContainer.rotation = Phaser.Math.Angle.Between(kerielX, kerielY, planetX, planetY);
|
||||
// Recalculate orbital radii based on the current window size.
|
||||
function recalcOrbitRadii() {
|
||||
const minDim = Math.min(window.innerWidth, window.innerHeight);
|
||||
planetOrbitRadius = minDim * 0.3; // 30% of the smaller dimension
|
||||
kerielOrbitRadius = planetOrbitRadius * 0.25;
|
||||
arkaenOrbitRadius = planetOrbitRadius * 0.35;
|
||||
minianOrbitRadius = planetOrbitRadius * 0.45;
|
||||
}
|
||||
|
||||
// Arkaen:
|
||||
const arkaenOrbitAngle = Phaser.Math.DegToRad((360 * (simulationTime % arkaenPeriod)) / arkaenPeriod - 90);
|
||||
const arkaenX = planetX + arkaenOrbitRadius * Math.cos(arkaenOrbitAngle);
|
||||
const arkaenY = planetY + arkaenOrbitRadius * Math.sin(arkaenOrbitAngle);
|
||||
arkaenContainer.x = arkaenX;
|
||||
arkaenContainer.y = arkaenY;
|
||||
arkaenContainer.rotation = Phaser.Math.Angle.Between(arkaenX, arkaenY, planetX, planetY);
|
||||
function update(time, delta) {
|
||||
// Advance or rewind simulation time based on state.
|
||||
if (isPlaying) {
|
||||
simulationTime += (delta * simulationSpeed) / 1000;
|
||||
} else if (isRewinding) {
|
||||
simulationTime -= (delta * simulationSpeed) / 1000;
|
||||
}
|
||||
|
||||
// Minian:
|
||||
const minianOrbitAngle = Phaser.Math.DegToRad((360 * (simulationTime % minianPeriod)) / minianPeriod - 90);
|
||||
const minianX = planetX + minianOrbitRadius * Math.cos(minianOrbitAngle);
|
||||
const minianY = planetY + minianOrbitRadius * Math.sin(minianOrbitAngle);
|
||||
minianContainer.x = minianX;
|
||||
minianContainer.y = minianY;
|
||||
minianContainer.rotation = Phaser.Math.Angle.Between(minianX, minianY, planetX, planetY);
|
||||
|
||||
// Optionally, redraw the moons' orbital paths (around Senthara).
|
||||
globalGraphics.lineStyle(1, 0x888888, 1);
|
||||
globalGraphics.strokeCircle(planetX, planetY, kerielOrbitRadius);
|
||||
globalGraphics.strokeCircle(planetX, planetY, arkaenOrbitRadius);
|
||||
globalGraphics.strokeCircle(planetX, planetY, minianOrbitRadius);
|
||||
// Get center of the screen (position of the star).
|
||||
const centerX = game.scale.width / 2;
|
||||
const centerY = game.scale.height / 2;
|
||||
|
||||
// Update the Senthara calendar date text.
|
||||
dateText.setText(getSentharaDate(simulationTime));
|
||||
}
|
||||
</script>
|
||||
// Clear global graphics.
|
||||
globalGraphics.clear();
|
||||
|
||||
// Draw the central star.
|
||||
globalGraphics.fillStyle(0xFFFF00, 1);
|
||||
globalGraphics.fillCircle(centerX, centerY, 20);
|
||||
|
||||
// Draw Senthara's orbital path (around the star).
|
||||
globalGraphics.lineStyle(1, 0x555555, 1);
|
||||
globalGraphics.strokeCircle(centerX, centerY, planetOrbitRadius);
|
||||
|
||||
// Calculate Senthara's (the planet's) position along its orbit.
|
||||
const planetOrbitAngle = Phaser.Math.DegToRad((360 * (simulationTime % planetPeriod)) / planetPeriod - 90);
|
||||
const planetX = centerX + planetOrbitRadius * Math.cos(planetOrbitAngle);
|
||||
const planetY = centerY + planetOrbitRadius * Math.sin(planetOrbitAngle);
|
||||
|
||||
// Update the planet container's position.
|
||||
planetContainer.x = planetX;
|
||||
planetContainer.y = planetY;
|
||||
// Set the planet's self-rotation (day/night cycle) with a 1-day period.
|
||||
const planetRotationAngle = Phaser.Math.DegToRad((360 * (simulationTime % planetRotationPeriod)) / planetRotationPeriod);
|
||||
planetContainer.rotation = planetRotationAngle;
|
||||
|
||||
// Update the night overlay so that the dark half covers the side away from the star.
|
||||
const subsolarAngle = Phaser.Math.Angle.Between(planetX, planetY, centerX, centerY);
|
||||
// The night overlay's rotation is adjusted relative to the planet's rotation.
|
||||
planetContainer.nightOverlay.rotation = subsolarAngle + Math.PI / 2 - planetContainer.rotation;
|
||||
|
||||
// Calculate and update moon positions (relative to Senthara).
|
||||
// Keriel:
|
||||
const kerielOrbitAngle = Phaser.Math.DegToRad((360 * (simulationTime % kerielPeriod)) / kerielPeriod - 90);
|
||||
const kerielX = planetX + kerielOrbitRadius * Math.cos(kerielOrbitAngle);
|
||||
const kerielY = planetY + kerielOrbitRadius * Math.sin(kerielOrbitAngle);
|
||||
kerielContainer.x = kerielX;
|
||||
kerielContainer.y = kerielY;
|
||||
// Ensure tidal locking: set Keriel's rotation so its marker points toward Senthara.
|
||||
kerielContainer.rotation = Phaser.Math.Angle.Between(kerielX, kerielY, planetX, planetY);
|
||||
|
||||
// Arkaen:
|
||||
const arkaenOrbitAngle = Phaser.Math.DegToRad((360 * (simulationTime % arkaenPeriod)) / arkaenPeriod - 90);
|
||||
const arkaenX = planetX + arkaenOrbitRadius * Math.cos(arkaenOrbitAngle);
|
||||
const arkaenY = planetY + arkaenOrbitRadius * Math.sin(arkaenOrbitAngle);
|
||||
arkaenContainer.x = arkaenX;
|
||||
arkaenContainer.y = arkaenY;
|
||||
arkaenContainer.rotation = Phaser.Math.Angle.Between(arkaenX, arkaenY, planetX, planetY);
|
||||
|
||||
// Minian:
|
||||
const minianOrbitAngle = Phaser.Math.DegToRad((360 * (simulationTime % minianPeriod)) / minianPeriod - 90);
|
||||
const minianX = planetX + minianOrbitRadius * Math.cos(minianOrbitAngle);
|
||||
const minianY = planetY + minianOrbitRadius * Math.sin(minianOrbitAngle);
|
||||
minianContainer.x = minianX;
|
||||
minianContainer.y = minianY;
|
||||
minianContainer.rotation = Phaser.Math.Angle.Between(minianX, minianY, planetX, planetY);
|
||||
|
||||
// Optionally, redraw the moons' orbital paths (around Senthara).
|
||||
globalGraphics.lineStyle(1, 0x888888, 1);
|
||||
globalGraphics.strokeCircle(planetX, planetY, kerielOrbitRadius);
|
||||
globalGraphics.strokeCircle(planetX, planetY, arkaenOrbitRadius);
|
||||
globalGraphics.strokeCircle(planetX, planetY, minianOrbitRadius);
|
||||
|
||||
// Update the Senthara calendar date text.
|
||||
dateText.setText(getSentharaDate(simulationTime));
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
Reference in New Issue
Block a user