Merge branch 'develop' into story61_player_perspective
# Conflicts: # src/main/java/seng302/fxObjects/BoatAnnotations.java # src/main/java/seng302/gameServer/GameState.java # src/main/java/seng302/gameServer/ServerToClientThread.java # src/main/java/seng302/model/Yacht.java # src/main/java/seng302/visualiser/controllers/LobbyController.java
@@ -103,10 +103,14 @@ public class GameState {
|
|||||||
return windDirection;
|
return windDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Double getWindSpeed() {
|
public static Double getWindSpeedMMS() {
|
||||||
return windSpeed;
|
return windSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Double getWindSpeedKnots() {
|
||||||
|
return windSpeed / 1000 * ClientPacketParser.MS_TO_KNOTS;
|
||||||
|
}
|
||||||
|
|
||||||
public static Map<Integer, Yacht> getYachts() {
|
public static Map<Integer, Yacht> getYachts() {
|
||||||
return yachts;
|
return yachts;
|
||||||
}
|
}
|
||||||
@@ -116,6 +120,7 @@ public class GameState {
|
|||||||
// System.out.println("-----------------------");
|
// System.out.println("-----------------------");
|
||||||
switch (actionType) {
|
switch (actionType) {
|
||||||
case VMG:
|
case VMG:
|
||||||
|
playerYacht.turnToVMG();
|
||||||
// System.out.println("Snapping to VMG");
|
// System.out.println("Snapping to VMG");
|
||||||
// TODO: 22/07/17 wmu16 - Add in the vmg calculation code here
|
// TODO: 22/07/17 wmu16 - Add in the vmg calculation code here
|
||||||
break;
|
break;
|
||||||
@@ -141,12 +146,13 @@ public class GameState {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// System.out.println("-----------------------");
|
System.out.println("-----------------------");
|
||||||
// System.out.println("Heading: " + playerYacht.getHeading());
|
System.out.println("Sails are in: " + playerYacht.getSailIn());
|
||||||
// System.out.println("Sails are in: " + playerYacht.getSailIn());
|
System.out.println("Heading: " + playerYacht.getHeading());
|
||||||
// System.out.println("Lat: " + playerYacht.getLocation().getLat());
|
System.out.println("Velocity: " + playerYacht.getVelocityMMS() / 1000);
|
||||||
// System.out.println("Lng: " + playerYacht.getLocation().getLng());
|
System.out.println("Lat: " + playerYacht.getLocation().getLat());
|
||||||
// System.out.println("-----------------------\n");
|
System.out.println("Lng: " + playerYacht.getLocation().getLng());
|
||||||
|
System.out.println("-----------------------\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void update() {
|
public static void update() {
|
||||||
|
|||||||
@@ -339,7 +339,7 @@ public class ServerToClientThread implements Runnable, Observer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sendMessage(new RaceStatusMessage(1, raceStatus, startTime, GameState.getWindDirection(),
|
sendMessage(new RaceStatusMessage(1, raceStatus, startTime, GameState.getWindDirection(),
|
||||||
GameState.getWindSpeed().longValue(), GameState.getPlayers().size(),
|
GameState.getWindSpeedMMS().longValue(), GameState.getPlayers().size(),
|
||||||
RaceType.MATCH_RACE, 1, boatSubMessages));
|
RaceType.MATCH_RACE, 1, boatSubMessages));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ import static seng302.utilities.GeoUtility.getGeoCoordinate;
|
|||||||
|
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import javafx.scene.paint.Color;
|
||||||
|
import seng302.client.ClientPacketParser;
|
||||||
|
import seng302.controllers.RaceViewController;
|
||||||
import seng302.gameServer.GameState;
|
import seng302.gameServer.GameState;
|
||||||
import seng302.utilities.GeoPoint;
|
import seng302.utilities.GeoPoint;
|
||||||
|
|
||||||
@@ -110,8 +115,8 @@ public class Yacht {
|
|||||||
this.position = "-";
|
this.position = "-";
|
||||||
this.sailIn = false;
|
this.sailIn = false;
|
||||||
this.location = new GeoPoint(57.670341, 11.826856);
|
this.location = new GeoPoint(57.670341, 11.826856);
|
||||||
this.heading = 120.0;
|
this.heading = 120.0; //In degrees
|
||||||
this.velocity = 50000.0;
|
this.velocity = 0d; //in mms-1
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -120,24 +125,28 @@ public class Yacht {
|
|||||||
public void update(Long timeInterval) {
|
public void update(Long timeInterval) {
|
||||||
if (sailIn) {
|
if (sailIn) {
|
||||||
Double secondsElapsed = timeInterval / 1000000.0;
|
Double secondsElapsed = timeInterval / 1000000.0;
|
||||||
Double thisHeading = ((double) Math.floorMod(heading.longValue(), 360L));
|
Double windSpeedKnots = GameState.getWindSpeedKnots();
|
||||||
Double windSpeedKnots = 0d;
|
Double trueWindAngle = Math.abs(GameState.getWindDirection() - heading);
|
||||||
Double boatSpeedInKnots = PolarTable.getBoatSpeed(windSpeedKnots, thisHeading);
|
Double boatSpeedInKnots = PolarTable.getBoatSpeed(windSpeedKnots, trueWindAngle);
|
||||||
velocity = boatSpeedInKnots / 1.94384449 * 3000; // TODO: 25/07/17 cir27 - remove magic numbers
|
velocity = boatSpeedInKnots / ClientPacketParser.MS_TO_KNOTS * 1000;
|
||||||
//System.out.println("velocity = " + velocity);
|
|
||||||
Double metersCovered = velocity * secondsElapsed;
|
Double metersCovered = velocity * secondsElapsed;
|
||||||
location = getGeoCoordinate(location, heading, metersCovered);
|
location = getGeoCoordinate(location, heading, metersCovered);
|
||||||
|
} else {
|
||||||
|
velocity = 0d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void adjustHeading(Double amount) {
|
public void adjustHeading(Double amount) {
|
||||||
|
Double newVal = heading + amount;
|
||||||
lastHeading = heading;
|
lastHeading = heading;
|
||||||
// TODO: 24/07/17 wmu16 - '%' in java does remainder, we need modulo. All this must be changed here, this is why we have neg values!
|
// TODO: 24/07/17 wmu16 - '%' in java does remainder, we need modulo. All this must be changed here, this is why we have neg values!
|
||||||
heading = (heading + amount) % 360.0;
|
heading = (double) Math.floorMod(newVal.longValue(), 360L);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void tackGybe(Double windDirection) {
|
public void tackGybe(Double windDirection) {
|
||||||
adjustHeading(-2 * ((heading - windDirection) % 360));
|
Double normalizedHeading = heading - GameState.windDirection;
|
||||||
|
normalizedHeading = (double) Math.floorMod(normalizedHeading.longValue(), 360);
|
||||||
|
adjustHeading(-2 * normalizedHeading);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void toggleSailIn() {
|
public void toggleSailIn() {
|
||||||
@@ -145,7 +154,8 @@ public class Yacht {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void turnUpwind() {
|
public void turnUpwind() {
|
||||||
Double normalizedHeading = (heading - GameState.windDirection) % 360;
|
Double normalizedHeading = heading - GameState.windDirection;
|
||||||
|
normalizedHeading = (double) Math.floorMod(normalizedHeading.longValue(), 360);
|
||||||
if (normalizedHeading == 0) {
|
if (normalizedHeading == 0) {
|
||||||
if (lastHeading < 180) {
|
if (lastHeading < 180) {
|
||||||
adjustHeading(-TURN_STEP);
|
adjustHeading(-TURN_STEP);
|
||||||
@@ -166,7 +176,8 @@ public class Yacht {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void turnDownwind() {
|
public void turnDownwind() {
|
||||||
Double normalizedHeading = (heading - GameState.windDirection) % 360;
|
Double normalizedHeading = heading - GameState.windDirection;
|
||||||
|
normalizedHeading = (double) Math.floorMod(normalizedHeading.longValue(), 360);
|
||||||
if (normalizedHeading == 0) {
|
if (normalizedHeading == 0) {
|
||||||
if (lastHeading < 180) {
|
if (lastHeading < 180) {
|
||||||
adjustHeading(TURN_STEP);
|
adjustHeading(TURN_STEP);
|
||||||
@@ -186,6 +197,9 @@ public class Yacht {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void turnToVMG() {
|
||||||
|
// TODO: 25/07/17 wmu16 - Fix this so it grabs the optimal value from the optimal Polar
|
||||||
|
}
|
||||||
|
|
||||||
public String getBoatType() {
|
public String getBoatType() {
|
||||||
return boatType;
|
return boatType;
|
||||||
@@ -267,8 +281,19 @@ public class Yacht {
|
|||||||
return velocityProperty.getReadOnlyProperty();
|
return velocityProperty.getReadOnlyProperty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double getVelocityMMS() {
|
||||||
|
return velocity;
|
||||||
|
}
|
||||||
|
|
||||||
public ReadOnlyLongProperty timeTillNextProperty() {
|
public ReadOnlyLongProperty timeTillNextProperty() {
|
||||||
return timeTillNextProperty.getReadOnlyProperty();
|
return timeTillNextProperty.getReadOnlyProperty();
|
||||||
|
|
||||||
|
public Double getVelocityKnots() {
|
||||||
|
return velocity / 1000 * ClientPacketParser.MS_TO_KNOTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getTimeTillNext() {
|
||||||
|
return timeTillNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getMarkRoundTime() {
|
public Long getMarkRoundTime() {
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ public class BoatLocationMessage extends Message {
|
|||||||
* @param boatSpeed The boats speed
|
* @param boatSpeed The boats speed
|
||||||
*/
|
*/
|
||||||
public BoatLocationMessage(int sourceId, int sequenceNum, double latitude, double longitude, double heading, long boatSpeed){
|
public BoatLocationMessage(int sourceId, int sequenceNum, double latitude, double longitude, double heading, long boatSpeed){
|
||||||
boatSpeed /= 10;
|
|
||||||
messageVersionNumber = 1;
|
messageVersionNumber = 1;
|
||||||
time = System.currentTimeMillis();
|
time = System.currentTimeMillis();
|
||||||
this.sourceId = sourceId;
|
this.sourceId = sourceId;
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ public class ClientToServerThread implements Runnable {
|
|||||||
try {
|
try {
|
||||||
socket.close();
|
socket.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
System.out.println("IO error in server thread upon trying to close socket");
|
clientLog("Failed to close the socket", 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ import javafx.scene.image.ImageView;
|
|||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
import javafx.scene.layout.GridPane;
|
import javafx.scene.layout.GridPane;
|
||||||
import javafx.scene.layout.Pane;
|
import javafx.scene.layout.Pane;
|
||||||
import javafx.scene.media.Media;
|
|
||||||
import javafx.scene.media.MediaPlayer;
|
|
||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
import seng302.gameServer.GameStages;
|
import seng302.gameServer.GameStages;
|
||||||
import seng302.gameServer.GameState;
|
import seng302.gameServer.GameState;
|
||||||
@@ -90,6 +88,11 @@ public class LobbyController implements Initializable {
|
|||||||
private static ObservableList<String> seventhCompetitor = FXCollections.observableArrayList();
|
private static ObservableList<String> seventhCompetitor = FXCollections.observableArrayList();
|
||||||
private static ObservableList<String> eighthCompetitor = FXCollections.observableArrayList();
|
private static ObservableList<String> eighthCompetitor = FXCollections.observableArrayList();
|
||||||
// private ClientStateQueryingRunnable clientStateQueryingRunnable;
|
// private ClientStateQueryingRunnable clientStateQueryingRunnable;
|
||||||
|
private ClientStateQueryingRunnable clientStateQueryingRunnable;
|
||||||
|
private static List<ImageView> imageViews;
|
||||||
|
private static List<ListView> listViews;
|
||||||
|
|
||||||
|
private int MAX_NUM_PLAYERS = 8;
|
||||||
|
|
||||||
private Boolean switchedPane = false;
|
private Boolean switchedPane = false;
|
||||||
|
|
||||||
@@ -123,6 +126,27 @@ public class LobbyController implements Initializable {
|
|||||||
// }
|
// }
|
||||||
// initialiseListView();
|
// initialiseListView();
|
||||||
// initialiseLobbyControllerThread();
|
// initialiseLobbyControllerThread();
|
||||||
|
// initialiseImageView(); // parrot gif init
|
||||||
|
// if (ClientState.isHost()) {
|
||||||
|
// lobbyIpText.setText("Lobby Host IP: " + ClientState.getHostIp());
|
||||||
|
// readyButton.setDisable(false);
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// lobbyIpText.setText("Connected to IP: ");
|
||||||
|
// readyButton.setDisable(true);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// imageViews = new ArrayList<>();
|
||||||
|
// Collections.addAll(imageViews, firstImageView, secondImageView, thirdImageView, fourthImageView,
|
||||||
|
// fifthImageView, sixthImageView, seventhImageView, eighthImageView);
|
||||||
|
// listViews = new ArrayList<>();
|
||||||
|
// Collections.addAll(listViews, firstListView, secondListView, thirdListView, fourthListView, fifthListView,
|
||||||
|
// sixthListView, seventhListView, eighthListView);
|
||||||
|
// competitors = new ArrayList<>();
|
||||||
|
// Collections.addAll(competitors, firstCompetitor, secondCompetitor, thirdCompetitor,
|
||||||
|
// fourthCompetitor, fifthCompetitor, sixthCompetitor, seventhCompetitor, eighthCompetitor);
|
||||||
|
//
|
||||||
|
// initialiseListView();
|
||||||
// initialiseImageView(); // parrot gif init
|
// initialiseImageView(); // parrot gif init
|
||||||
|
|
||||||
// set up client state query thread, so that when it receives the race-started packet
|
// set up client state query thread, so that when it receives the race-started packet
|
||||||
@@ -161,13 +185,16 @@ public class LobbyController implements Initializable {
|
|||||||
// seventhListView.getItems().clear();
|
// seventhListView.getItems().clear();
|
||||||
// eighthListView.getItems().clear();
|
// eighthListView.getItems().clear();
|
||||||
|
|
||||||
competitors = new ArrayList<>();
|
// listViews.forEach(listView -> listView.getItems().clear());
|
||||||
Collections.addAll(competitors, firstCompetitor, secondCompetitor, thirdCompetitor,
|
// imageViews.forEach(gif -> gif.setVisible(false));
|
||||||
fourthCompetitor, fifthCompetitor, sixthCompetitor, seventhCompetitor, eighthCompetitor);
|
// competitors.forEach(ol -> ol.removeAll());
|
||||||
|
//
|
||||||
for (ObservableList<String> ol : competitors) {
|
// List<Integer> ids = new ArrayList<>(ClientState.getBoats().keySet());
|
||||||
ol.removeAll();
|
// for (int i = 0; i < ids.size(); i++) {
|
||||||
}
|
// competitors.get(i).add(String.format("Player ID: %d", ids.get(i)));
|
||||||
|
// listViews.get(i).setItems(competitors.get(i));
|
||||||
|
// imageViews.get(i).setVisible(true);
|
||||||
|
// }
|
||||||
|
|
||||||
// firstCompetitor.add(ClientState.getClientSourceId());
|
// firstCompetitor.add(ClientState.getClientSourceId());
|
||||||
|
|
||||||
@@ -183,15 +210,15 @@ public class LobbyController implements Initializable {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
firstListView.setItems(firstCompetitor);
|
// firstListView.setItems(firstCompetitor);
|
||||||
secondListView.setItems(secondCompetitor);
|
// secondListView.setItems(secondCompetitor);
|
||||||
thirdListView.setItems(thirdCompetitor);
|
// thirdListView.setItems(thirdCompetitor);
|
||||||
fourthListView.setItems(fourthCompetitor);
|
// fourthListView.setItems(fourthCompetitor);
|
||||||
fifthListView.setItems(fifthCompetitor);
|
// fifthListView.setItems(fifthCompetitor);
|
||||||
sixthListView.setItems(sixthCompetitor);
|
// sixthListView.setItems(sixthCompetitor);
|
||||||
seventhListView.setItems(seventhCompetitor);
|
// seventhListView.setItems(seventhCompetitor);
|
||||||
eighthListView.setItems(eighthCompetitor);
|
// eighthListView.setItems(eighthCompetitor);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// private void initialiseLobbyControllerThread() {
|
// private void initialiseLobbyControllerThread() {
|
||||||
// Thread thread = new Thread(new Runnable() {
|
// Thread thread = new Thread(new Runnable() {
|
||||||
@@ -209,22 +236,25 @@ public class LobbyController implements Initializable {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
private void initialiseImageView() {
|
private void initialiseImageView() {
|
||||||
Image image1 = new Image(getClass().getResourceAsStream("/ParrotGif/alistair.gif"));
|
for (int i = 0; i < MAX_NUM_PLAYERS; i++) {
|
||||||
firstImageView.setImage(image1);
|
imageViews.get(i).setImage(new Image(getClass().getResourceAsStream("/pics/sail.png")));
|
||||||
Image image2 = new Image(getClass().getResourceAsStream("/ParrotGif/calum.gif"));
|
}
|
||||||
secondImageView.setImage(image2);
|
// Image image1 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||||
Image image3 = new Image(getClass().getResourceAsStream("/ParrotGif/haoming.gif"));
|
// firstImageView.setImage(image1);
|
||||||
thirdImageView.setImage(image3);
|
// Image image2 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||||
Image image4 = new Image(getClass().getResourceAsStream("/ParrotGif/kusal.gif"));
|
// secondImageView.setImage(image2);
|
||||||
fourthImageView.setImage(image4);
|
// Image image3 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||||
Image image5 = new Image(getClass().getResourceAsStream("/ParrotGif/michael.gif"));
|
// thirdImageView.setImage(image3);
|
||||||
fifthImageView.setImage(image5);
|
// Image image4 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||||
Image image6 = new Image(getClass().getResourceAsStream("/ParrotGif/peter.gif"));
|
// fourthImageView.setImage(image4);
|
||||||
sixthImageView.setImage(image6);
|
// Image image5 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||||
Image image7 = new Image(getClass().getResourceAsStream("/ParrotGif/ryan.gif"));
|
// fifthImageView.setImage(image5);
|
||||||
seventhImageView.setImage(image7);
|
// Image image6 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||||
Image image8 = new Image(getClass().getResourceAsStream("/ParrotGif/will.gif"));
|
// sixthImageView.setImage(image6);
|
||||||
eighthImageView.setImage(image8);
|
// Image image7 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||||
|
// seventhImageView.setImage(image7);
|
||||||
|
// Image image8 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||||
|
// eighthImageView.setImage(image8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@@ -239,30 +269,30 @@ public class LobbyController implements Initializable {
|
|||||||
@FXML
|
@FXML
|
||||||
public void readyButtonPressed() {
|
public void readyButtonPressed() {
|
||||||
// setContentPane("/views/RaceView.fxml");
|
// setContentPane("/views/RaceView.fxml");
|
||||||
playTheme();
|
// playTheme();
|
||||||
GameState.setCurrentStage(GameStages.RACING);
|
GameState.setCurrentStage(GameStages.RACING);
|
||||||
for (LobbyCloseListener readyListener : lobbyListeners)
|
for (LobbyCloseListener readyListener : lobbyListeners)
|
||||||
readyListener.notify(CloseStatus.READY);
|
readyListener.notify(CloseStatus.READY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static MediaPlayer mediaPlayer;
|
// private static MediaPlayer mediaPlayer;
|
||||||
|
//
|
||||||
private void playTheme() {
|
// private void playTheme() {
|
||||||
Random random = new Random(System.currentTimeMillis());
|
// Random random = new Random(System.currentTimeMillis());
|
||||||
Integer rand = random.nextInt();
|
// Integer rand = random.nextInt();
|
||||||
if(rand == 10) {
|
// if(rand == 10) {
|
||||||
URL file = getClass().getResource("/music/Disturbed - down with the sickness.mp3");
|
// URL file = getClass().getResource("/music/Disturbed - down with the sickness.mp3");
|
||||||
Media hit = new Media(file.toString());
|
// Media hit = new Media(file.toString());
|
||||||
mediaPlayer = new MediaPlayer(hit);
|
// mediaPlayer = new MediaPlayer(hit);
|
||||||
mediaPlayer.play();
|
// mediaPlayer.play();
|
||||||
} else if(rand == 9) {
|
// } else if(rand == 9) {
|
||||||
URL file = getClass().getResource("/music/Owl City - Fireflies.mp3");
|
// URL file = getClass().getResource("/music/Owl City - Fireflies.mp3");
|
||||||
Media hit = new Media(file.toString());
|
// Media hit = new Media(file.toString());
|
||||||
mediaPlayer = new MediaPlayer(hit);
|
// mediaPlayer = new MediaPlayer(hit);
|
||||||
mediaPlayer.play();
|
// mediaPlayer.play();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// private void switchToRaceView() {
|
// private void switchToRaceView() {
|
||||||
// if (!switchedPane) {
|
// if (!switchedPane) {
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |