Notice to GitKraken users: A vulnerability has been found in the SSH key generation of GitKraken versions 7.6.0 to 8.0.0 (https://www.gitkraken.com/blog/weak-ssh-key-fix). If you use GitKraken and have generated a SSH key using one of these versions, please remove it both from your local workstation and from your LRZ GitLab profile.

21.10.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

Commit 1c5e5874 authored by Benedikt Zoennchen's avatar Benedikt Zoennchen
Browse files

construct a new module called geometry and extracting the classes from the utils module.

parent 35ebbaa9
package org.vadere.util.geometry.mesh.gen;
package org.vadere.geometry.mesh.gen;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.mesh.inter.IFace;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.geometry.mesh.inter.IFace;
import org.vadere.geometry.shapes.IPoint;
/**
* @author Benedikt Zoennchen
......
package org.vadere.util.geometry.mesh.gen;
package org.vadere.geometry.mesh.gen;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.mesh.inter.IHalfEdge;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.geometry.mesh.inter.IHalfEdge;
import org.vadere.geometry.shapes.IPoint;
/**
* @author Benedikt Zoennchen
......
package org.vadere.util.geometry.mesh.gen;
package org.vadere.geometry.mesh.gen;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.GeometryUtils;
import org.vadere.util.geometry.mesh.inter.IMesh;
import org.vadere.util.geometry.mesh.inter.IPointLocator;
import org.vadere.util.geometry.mesh.inter.ITriangulation;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.shapes.MPoint;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VRectangle;
import org.vadere.util.math.SpaceFillingCurve;
import org.vadere.util.geometry.mesh.inter.IPointConstructor;
import org.vadere.geometry.Utils;
import org.vadere.geometry.SpaceFillingCurve;
import org.vadere.geometry.mesh.inter.IMesh;
import org.vadere.geometry.mesh.inter.IPointLocator;
import org.vadere.geometry.mesh.inter.ITriangulation;
import org.vadere.geometry.shapes.IPoint;
import org.vadere.geometry.shapes.MPoint;
import org.vadere.geometry.shapes.VPoint;
import org.vadere.geometry.shapes.VRectangle;
import org.vadere.geometry.mesh.inter.IPointConstructor;
import java.util.*;
import java.util.function.Predicate;
......@@ -589,7 +589,7 @@ public class AMesh<P extends IPoint> implements IMesh<P, AVertex<P>, AHalfEdge<P
List<VPoint> centroids = new ArrayList<>(this.numberOfFaces);
for(int i = 0; i < this.faces.size(); i++) {
VPoint incenter = GeometryUtils.getCentroid(this.getVertices(faces.get(i)));
VPoint incenter = Utils.getCentroid(this.getVertices(faces.get(i)));
centroids.add(incenter);
maxX = Math.max(maxX, incenter.getX());
maxY = Math.max(maxY, incenter.getY());
......
package org.vadere.util.geometry.mesh.gen;
package org.vadere.geometry.mesh.gen;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.mesh.inter.IVertex;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.geometry.mesh.inter.IVertex;
import org.vadere.geometry.shapes.IPoint;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
......
package org.vadere.util.geometry.mesh.gen;
package org.vadere.geometry.mesh.gen;
import org.vadere.util.geometry.mesh.inter.IFace;
import org.vadere.util.geometry.mesh.inter.IHalfEdge;
import org.vadere.util.geometry.mesh.inter.IPointLocator;
import org.vadere.util.geometry.mesh.inter.ITriConnectivity;
import org.vadere.util.geometry.mesh.inter.IVertex;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.geometry.mesh.inter.IFace;
import org.vadere.geometry.mesh.inter.IHalfEdge;
import org.vadere.geometry.mesh.inter.IPointLocator;
import org.vadere.geometry.mesh.inter.ITriConnectivity;
import org.vadere.geometry.mesh.inter.IVertex;
import org.vadere.geometry.shapes.IPoint;
import java.util.Optional;
......
package org.vadere.util.geometry.mesh.gen;
package org.vadere.geometry.mesh.gen;
import org.jetbrains.annotations.NotNull;
import org.lwjgl.system.MemoryUtil;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.geometry.shapes.IPoint;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
......
package org.vadere.util.geometry.mesh.gen;
package org.vadere.geometry.mesh.gen;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.vadere.util.geometry.GeometryUtils;
import org.vadere.util.geometry.mesh.inter.*;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.shapes.VLine;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.geometry.Utils;
import org.vadere.geometry.mesh.inter.*;
import org.vadere.geometry.shapes.IPoint;
import org.vadere.geometry.shapes.VLine;
import org.vadere.geometry.shapes.VPoint;
import java.util.*;
......@@ -73,6 +73,6 @@ public class ConstrainedTriangulation<P extends IPoint, V extends IVertex<P>, E
* @return
*/
private boolean faceIntersectsLine(final F face, IPoint p1, IPoint p2) {
return getMesh().streamEdges(face).anyMatch(edge -> GeometryUtils.intersectLine(p1, p2, getMesh().getPoint(edge), getMesh().getPoint(getMesh().getPrev(edge))));
return getMesh().streamEdges(face).anyMatch(edge -> Utils.intersectLine(p1, p2, getMesh().getPoint(edge), getMesh().getPoint(getMesh().getPrev(edge))));
}
}
package org.vadere.util.geometry.mesh.gen;
package org.vadere.geometry.mesh.gen;
import org.jetbrains.annotations.NotNull;
......
package org.vadere.util.geometry.mesh.gen;
package org.vadere.geometry.mesh.gen;
import org.apache.commons.lang3.tuple.Triple;
import org.vadere.util.geometry.mesh.inter.IFace;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VTriangle;
import org.vadere.geometry.mesh.inter.IFace;
import org.vadere.geometry.shapes.IPoint;
import org.vadere.geometry.shapes.VPoint;
import org.vadere.geometry.shapes.VTriangle;
import java.util.List;
......
package org.vadere.util.geometry.mesh.gen;
package org.vadere.geometry.mesh.gen;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.GeometryUtils;
import org.vadere.util.geometry.mesh.inter.IFace;
import org.vadere.util.geometry.mesh.inter.IHalfEdge;
import org.vadere.util.geometry.mesh.inter.IMesh;
import org.vadere.util.geometry.mesh.inter.IPointLocator;
import org.vadere.util.geometry.mesh.inter.ITriangulation;
import org.vadere.util.geometry.mesh.inter.IVertex;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.geometry.Utils;
import org.vadere.geometry.mesh.inter.IFace;
import org.vadere.geometry.mesh.inter.IHalfEdge;
import org.vadere.geometry.mesh.inter.IMesh;
import org.vadere.geometry.mesh.inter.IPointLocator;
import org.vadere.geometry.mesh.inter.ITriangulation;
import org.vadere.geometry.mesh.inter.IVertex;
import org.vadere.geometry.shapes.IPoint;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.function.Supplier;
......@@ -39,7 +36,7 @@ import java.util.function.Supplier;
*
* For more informations see devillers-2002 (The Delaunay Hierarchy).
*
* The {@link DelaunayHierarchy} is also a {@link org.vadere.util.geometry.mesh.inter.ITriEventListener}. It listens to
* The {@link DelaunayHierarchy} is also a {@link org.vadere.geometry.mesh.inter.ITriEventListener}. It listens to
* vertex insert events to update itself.
*
* Note that any insertion / deletion of a point into / from the triangulation has to be propagated to its Delaunay-Hierarchy.
......@@ -381,7 +378,7 @@ public class DelaunayHierarchy<P extends IPoint, V extends IVertex<P>, E extends
E edge = tri.getMesh().closestEdge(face, point.getX(), point.getY());
P p1 = tri.getMesh().getPoint(tri.getMesh().getPrev(edge));
P p2 = tri.getMesh().getPoint(edge);
return GeometryUtils.isOnEdge(p1, p2, point, tolerance);
return Utils.isOnEdge(p1, p2, point, tolerance);
}
@Override
......
package org.vadere.util.geometry.mesh.gen;
package org.vadere.geometry.mesh.gen;
import org.apache.commons.lang3.tuple.Triple;
import org.vadere.util.geometry.mesh.inter.IFace;
import org.vadere.util.geometry.mesh.inter.IHalfEdge;
import org.vadere.util.geometry.mesh.inter.IMesh;
import org.vadere.util.geometry.mesh.inter.IPointLocator;
import org.vadere.util.geometry.mesh.inter.ITriangulation;
import org.vadere.util.geometry.mesh.inter.IVertex;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.geometry.mesh.inter.IFace;
import org.vadere.geometry.mesh.inter.IHalfEdge;
import org.vadere.geometry.mesh.inter.IMesh;
import org.vadere.geometry.mesh.inter.IPointLocator;
import org.vadere.geometry.mesh.inter.ITriangulation;
import org.vadere.geometry.mesh.inter.IVertex;
import org.vadere.geometry.shapes.IPoint;
import java.util.HashMap;
import java.util.HashSet;
......
package org.vadere.util.geometry.mesh.gen;
package org.vadere.geometry.mesh.gen;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.GeometryUtils;
import org.vadere.util.geometry.mesh.inter.ITriConnectivity;
import org.vadere.util.geometry.mesh.inter.IVertex;
import org.vadere.util.geometry.mesh.iterators.FaceIterator;
import org.vadere.util.geometry.mesh.inter.IFace;
import org.vadere.util.geometry.mesh.inter.IHalfEdge;
import org.vadere.util.geometry.mesh.inter.IMesh;
import org.vadere.util.geometry.mesh.triangulation.BowyerWatsonSlow;
import org.vadere.util.geometry.mesh.inter.IPointConstructor;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.shapes.VCircle;
import org.vadere.util.geometry.shapes.VLine;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VRectangle;
import org.vadere.util.geometry.shapes.VTriangle;
import org.vadere.util.geometry.mesh.inter.IPointLocator;
import org.vadere.util.geometry.mesh.inter.ITriangulation;
import org.vadere.geometry.Utils;
import org.vadere.geometry.mesh.inter.ITriConnectivity;
import org.vadere.geometry.mesh.inter.IVertex;
import org.vadere.geometry.mesh.iterators.FaceIterator;
import org.vadere.geometry.mesh.inter.IFace;
import org.vadere.geometry.mesh.inter.IHalfEdge;
import org.vadere.geometry.mesh.inter.IMesh;
import org.vadere.geometry.mesh.triangulation.BowyerWatsonSlow;
import org.vadere.geometry.mesh.inter.IPointConstructor;
import org.vadere.geometry.shapes.IPoint;
import org.vadere.geometry.shapes.VCircle;
import org.vadere.geometry.shapes.VLine;
import org.vadere.geometry.shapes.VPoint;
import org.vadere.geometry.shapes.VRectangle;
import org.vadere.geometry.shapes.VTriangle;
import org.vadere.geometry.mesh.inter.IPointLocator;
import org.vadere.geometry.mesh.inter.ITriangulation;
import java.awt.*;
import java.util.ArrayList;
......@@ -40,8 +40,8 @@ import java.util.stream.StreamSupport;
import javax.swing.*;
import static org.vadere.util.geometry.mesh.inter.IPointLocator.Type.BASE;
import static org.vadere.util.geometry.mesh.inter.IPointLocator.Type.DELAUNAY_TREE;
import static org.vadere.geometry.mesh.inter.IPointLocator.Type.BASE;
import static org.vadere.geometry.mesh.inter.IPointLocator.Type.DELAUNAY_TREE;
public class IncrementalTriangulation<P extends IPoint, V extends IVertex<P>, E extends IHalfEdge<P>, F extends IFace<P>> implements ITriangulation<P, V, E, F> {
......@@ -89,7 +89,7 @@ public class IncrementalTriangulation<P extends IPoint, V extends IVertex<P>, E
this.mesh = mesh;
this.points = points;
this.illegalPredicate = illegalPredicate;
this.bound = GeometryUtils.bound(points, epsilon);
this.bound = Utils.bound(points, epsilon);
this.finalized = false;
this.initialized = false;
this.mesh = mesh;
......@@ -157,7 +157,7 @@ public class IncrementalTriangulation<P extends IPoint, V extends IVertex<P>, E
this.mesh = mesh;
this.points = new HashSet<>();
this.illegalPredicate = illegalPredicate;
this.bound = GeometryUtils.bound(mesh.getPoints(mesh.getBorder()), epsilon);
this.bound = Utils.bound(mesh.getPoints(mesh.getBorder()), epsilon);
this.initialized = false;
this.finalized = false;
this.virtualVertices = new ArrayList<>();
......@@ -305,7 +305,7 @@ public class IncrementalTriangulation<P extends IPoint, V extends IVertex<P>, E
initialized = false;
finalized = false;
points = mesh.getPoints();
bound = GeometryUtils.bound(points, epsilon);
bound = Utils.bound(points, epsilon);
mesh.clear();
setPointLocator(type);
compute();
......@@ -331,7 +331,7 @@ public class IncrementalTriangulation<P extends IPoint, V extends IVertex<P>, E
log.info("ignore insertion point, since the point " + point + " already exists or it is too close to another point!");
return edge;
}
if(GeometryUtils.isOnEdge(p1, p2, point, edgeCoincidenceTolerance)) {
if(Utils.isOnEdge(p1, p2, point, edgeCoincidenceTolerance)) {
//log.info("splitEdge()");
E newEdge = getAnyEdge(splitEdge(point, edge, true));
insertEvent(newEdge);
......@@ -585,14 +585,14 @@ public class IncrementalTriangulation<P extends IPoint, V extends IVertex<P>, E
V y = mesh.getVertex(t1);
V z = mesh.getVertex(t2);
//return GeometryUtils.angle(x, y, z) + GeometryUtils.angle(x, p, z) > Math.PI;
//return Utils.angle(x, y, z) + Utils.angle(x, p, z) > Math.PI;
//return GeometryUtils.isInCircumscribedCycle(x, y, z, p);
//if(GeometryUtils.ccw(z,x,y) > 0) {
return GeometryUtils.isInsideCircle(z, x, y, p);
//return Utils.isInCircumscribedCycle(x, y, z, p);
//if(Utils.ccw(z,x,y) > 0) {
return Utils.isInsideCircle(z, x, y, p);
//}
//else {
// return GeometryUtils.isInsideCircle(x, z, y, p);
// return Utils.isInsideCircle(x, z, y, p);
//}
}
......@@ -611,13 +611,13 @@ public class IncrementalTriangulation<P extends IPoint, V extends IVertex<P>, E
V y = mesh.getVertex(t1);
V z = mesh.getVertex(t2);
//return GeometryUtils.angle(x, y, z) + GeometryUtils.angle(x, p, z) > Math.PI;
//return Utils.angle(x, y, z) + Utils.angle(x, p, z) > Math.PI;
//return GeometryUtils.isInCircumscribedCycle(x, y, z, p);
if (GeometryUtils.ccw(x,y,z) > 0
//return Utils.isInCircumscribedCycle(x, y, z, p);
if (Utils.ccw(x,y,z) > 0
t.dest().rightOf(e) && v.isInCircle(e.orig(), t.dest(), e.dest())) {
log.info(GeometryUtils.ccw(x,y,z) > 0);
return GeometryUtils.isInsideCircle(x, y, z, p);
log.info(Utils.ccw(x,y,z) > 0);
return Utils.isInsideCircle(x, y, z, p);
}
return false;
}*/
......@@ -634,14 +634,14 @@ public class IncrementalTriangulation<P extends IPoint, V extends IVertex<P>, E
V y = mesh.getVertex(t1);
V z = mesh.getVertex(t2);
//return GeometryUtils.angle(x, y, z) + GeometryUtils.angle(x, p, z) > Math.PI;
//return Utils.angle(x, y, z) + Utils.angle(x, p, z) > Math.PI;
//return GeometryUtils.isInCircumscribedCycle(x, y, z, p);
//if(GeometryUtils.ccw(z,x,y) > 0) {
return GeometryUtils.isInsideCircle(z, x, y, p);
//return Utils.isInCircumscribedCycle(x, y, z, p);
//if(Utils.ccw(z,x,y) > 0) {
return Utils.isInsideCircle(z, x, y, p);
//}
//else {
// return GeometryUtils.isInsideCircle(x, z, y, p);
// return Utils.isInsideCircle(x, z, y, p);
//}
}
return false;
......
package org.vadere.util.geometry.mesh.gen;
package org.vadere.geometry.mesh.gen;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.mesh.inter.IFace;
import org.vadere.util.geometry.mesh.inter.IHalfEdge;
import org.vadere.util.geometry.mesh.inter.IPointLocator;
import org.vadere.util.geometry.mesh.inter.ITriangulation;
import org.vadere.util.geometry.mesh.inter.IVertex;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.geometry.mesh.inter.IFace;
import org.vadere.geometry.mesh.inter.IHalfEdge;
import org.vadere.geometry.mesh.inter.IPointLocator;
import org.vadere.geometry.mesh.inter.ITriangulation;
import org.vadere.geometry.mesh.inter.IVertex;
import org.vadere.geometry.shapes.IPoint;
import org.vadere.geometry.shapes.VPoint;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import static org.vadere.util.geometry.mesh.inter.IPointLocator.Type.JUMP_AND_WALK;
import static org.vadere.geometry.mesh.inter.IPointLocator.Type.JUMP_AND_WALK;
/**
* @author Benedikt Zoennchen
......
package org.vadere.util.geometry.mesh.gen;
package org.vadere.geometry.mesh.gen;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.mesh.inter.IFace;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.geometry.mesh.inter.IFace;
import org.vadere.geometry.shapes.IPoint;
/**
* A Face is a region of a planar separation of the 2-D space, e.g. the region of a Polygon/Triangle and so on.
......
package org.vadere.util.geometry.mesh.gen;
package org.vadere.geometry.mesh.gen;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.mesh.inter.IHalfEdge;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.shapes.VLine;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.geometry.mesh.inter.IHalfEdge;
import org.vadere.geometry.shapes.IPoint;
import org.vadere.geometry.shapes.VLine;
import org.vadere.geometry.shapes.VPoint;
public class PHalfEdge<P extends IPoint> implements IHalfEdge<P>, Cloneable {
......
package org.vadere.util.geometry.mesh.gen;
package org.vadere.geometry.mesh.gen;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.mesh.inter.IMesh;
import org.vadere.util.geometry.mesh.inter.IPointLocator;
import org.vadere.util.geometry.mesh.inter.ITriangulation;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.mesh.inter.IPointConstructor;
import org.vadere.geometry.mesh.inter.IMesh;
import org.vadere.geometry.mesh.inter.IPointLocator;
import org.vadere.geometry.mesh.inter.ITriangulation;
import org.vadere.geometry.shapes.IPoint;
import org.vadere.geometry.mesh.inter.IPointConstructor;
import java.util.*;
import java.util.function.Predicate;
......
package org.vadere.util.geometry.mesh.gen;
package org.vadere.geometry.mesh.gen;
import org.vadere.util.geometry.mesh.inter.IVertex;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.geometry.mesh.inter.IVertex;
import org.vadere.geometry.shapes.IPoint;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
......
package org.vadere.util.geometry.mesh.gen;
import org.vadere.util.geometry.mesh.gen.PFace;
import org.vadere.util.geometry.mesh.gen.PHalfEdge;
import org.vadere.util.geometry.mesh.gen.PVertex;
import org.vadere.util.geometry.mesh.inter.IMesh;
import org.vadere.util.geometry.shapes.VLine;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VPolygon;
package org.vadere.geometry.mesh.gen;
import org.vadere.geometry.mesh.gen.PFace;
import org.vadere.geometry.mesh.gen.PHalfEdge;
import org.vadere.geometry.mesh.gen.PVertex;
import org.vadere.geometry.mesh.inter.IMesh;
import org.vadere.geometry.shapes.VLine;
import org.vadere.geometry.shapes.VPoint;
import org.vadere.geometry.shapes.VPolygon;
import java.awt.geom.Point2D;
import java.util.ArrayList;
......
package org.vadere.util.geometry.mesh.gen;
package org.vadere.geometry.mesh.gen;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.mesh.inter.IFace;
import org.vadere.util.geometry.mesh.inter.IHalfEdge;
import org.vadere.util.geometry.mesh.inter.IMesh;
import org.vadere.util.geometry.mesh.inter.IPolyConnectivity;
import org.vadere.util.geometry.mesh.inter.IVertex;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.geometry.mesh.inter.IFace;
import org.vadere.geometry.mesh.inter.IHalfEdge;
import org.vadere.geometry.mesh.inter.IMesh;
import org.vadere.geometry.mesh.inter.IPolyConnectivity;
import org.vadere.geometry.mesh.inter.IVertex;
import org.vadere.geometry.shapes.IPoint;
import java.util.Iterator;
......
package org.vadere.util.geometry.mesh.impl;
package org.vadere.geometry.mesh.impl;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.mesh.gen.PFace;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.geometry.mesh.gen.PFace;
import org.vadere.geometry.shapes.VPoint;
/**
* @author Benedikt Zoennchen
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment