[vcs-log] keep arrows with edges, not with nodes

(cherry picked from commit aa04742d1126bdc8648508f860a96f1443c6660b)
This commit is contained in:
Julia Beliaeva
2015-08-27 17:54:15 +03:00
parent a01ec2cc4e
commit 5ca4e12431
12 changed files with 142 additions and 153 deletions
@@ -17,8 +17,6 @@ package com.intellij.vcs.log.graph;
import org.jetbrains.annotations.NotNull;
/**
*/
public interface EdgePrintElement extends PrintElement {
int getPositionInOtherRow();
@@ -29,6 +27,8 @@ public interface EdgePrintElement extends PrintElement {
@NotNull
LineStyle getLineStyle();
boolean hasArrow();
enum Type {
UP,
DOWN
@@ -15,19 +15,5 @@
*/
package com.intellij.vcs.log.graph;
import org.jetbrains.annotations.NotNull;
/**
*/
public interface SimplePrintElement extends PrintElement {
@NotNull
Type getType();
enum Type {
NODE,
UP_ARROW,
DOWN_ARROW
}
public interface NodePrintElement extends PrintElement {
}
@@ -35,8 +35,6 @@ import java.awt.*;
import java.util.Collection;
import java.util.Collections;
import static com.intellij.vcs.log.graph.SimplePrintElement.Type.DOWN_ARROW;
import static com.intellij.vcs.log.graph.SimplePrintElement.Type.UP_ARROW;
import static com.intellij.vcs.log.graph.utils.LinearGraphUtils.getCursor;
public class VisibleGraphImpl<CommitId> implements VisibleGraph<CommitId> {
@@ -128,9 +126,9 @@ public class VisibleGraphImpl<CommitId> implements VisibleGraph<CommitId> {
@Nullable
private GraphAnswer<CommitId> performArrowAction(@NotNull LinearGraphAction action) {
PrintElementWithGraphElement affectedElement = action.getAffectedElement();
if (!(affectedElement instanceof SimplePrintElement)) return null;
SimplePrintElement.Type printElementType = ((SimplePrintElement)affectedElement).getType();
if (printElementType != DOWN_ARROW && printElementType != UP_ARROW) return null;
if (!(affectedElement instanceof EdgePrintElement)) return null;
EdgePrintElement edgePrintElement = (EdgePrintElement)affectedElement;
if (!edgePrintElement.hasArrow()) return null;
GraphElement graphElement = affectedElement.getGraphElement();
if (!(graphElement instanceof GraphEdge)) return null;
@@ -138,11 +136,11 @@ public class VisibleGraphImpl<CommitId> implements VisibleGraph<CommitId> {
Integer targetId = null;
if (edge.getType() == GraphEdgeType.NOT_LOAD_COMMIT) {
assert printElementType == DOWN_ARROW;
assert edgePrintElement.getType().equals(EdgePrintElement.Type.DOWN);
targetId = edge.getTargetId();
}
if (edge.getType().isNormalEdge()) {
if (printElementType == DOWN_ARROW) {
if (edgePrintElement.getType().equals(EdgePrintElement.Type.DOWN)) {
targetId = convertToNodeId(edge.getDownNodeIndex());
}
else {
@@ -15,9 +15,9 @@
*/
package com.intellij.vcs.log.graph.impl.print;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcs.log.graph.EdgePrintElement;
import com.intellij.vcs.log.graph.PrintElement;
import com.intellij.vcs.log.graph.SimplePrintElement;
import com.intellij.vcs.log.graph.api.LinearGraph;
import com.intellij.vcs.log.graph.api.elements.GraphEdge;
import com.intellij.vcs.log.graph.api.elements.GraphElement;
@@ -30,6 +30,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
public abstract class AbstractPrintElementGenerator implements PrintElementGenerator {
@@ -45,30 +46,59 @@ public abstract class AbstractPrintElementGenerator implements PrintElementGener
public Collection<PrintElementWithGraphElement> getPrintElements(int rowIndex) {
Collection<PrintElementWithGraphElement> result = new ArrayList<PrintElementWithGraphElement>();
Map<GraphEdge, SimpleRowElement> arrows = ContainerUtil.newHashMap();
for (SimpleRowElement rowElement : getSimpleRowElements(rowIndex)) {
if (!rowElement.myType.equals(RowElementType.NODE)) {
arrows.put((GraphEdge)rowElement.myElement, rowElement);
}
}
if (rowIndex < myLinearGraph.nodesCount() - 1) {
for (ShortEdge shortEdge : getDownShortEdges(rowIndex)) {
result.add(createEdgePrintElement(rowIndex, shortEdge, EdgePrintElement.Type.DOWN));
RowElementType rowElementType = RowElementType.NODE;
if ((arrows.get(shortEdge.myEdge) != null) && RowElementType.DOWN_ARROW.equals(arrows.get(shortEdge.myEdge).myType)) {
rowElementType = RowElementType.DOWN_ARROW;
arrows.remove(shortEdge.myEdge);
}
result.add(createEdgePrintElement(rowIndex, shortEdge, EdgePrintElement.Type.DOWN, !rowElementType.equals(RowElementType.NODE)));
}
}
if (rowIndex > 0) {
for (ShortEdge shortEdge : getDownShortEdges(rowIndex - 1)) {
result.add(createEdgePrintElement(rowIndex, shortEdge, EdgePrintElement.Type.UP));
RowElementType rowElementType = RowElementType.NODE;
if ((arrows.get(shortEdge.myEdge) != null) && RowElementType.UP_ARROW.equals(arrows.get(shortEdge.myEdge).myType)) {
rowElementType = RowElementType.UP_ARROW;
arrows.remove(shortEdge.myEdge);
}
result.add(createEdgePrintElement(rowIndex, shortEdge, EdgePrintElement.Type.UP, !rowElementType.equals(RowElementType.NODE)));
}
}
for (SimpleRowElement arrow : arrows.values()) {
result.add(new EdgePrintElementImpl(rowIndex, arrow.myPosition, arrow.myPosition,
arrow.myType == RowElementType.UP_ARROW ? EdgePrintElement.Type.UP : EdgePrintElement.Type.DOWN,
(GraphEdge)arrow.myElement, true, myPrintElementManager));
}
for (SimpleRowElement rowElement : getSimpleRowElements(rowIndex)) {
result.add(createSimplePrintElement(rowIndex, rowElement));
if (rowElement.myType.equals(RowElementType.NODE)) {
result.add(createSimplePrintElement(rowIndex, rowElement));
}
}
return result;
}
private SimplePrintElementImpl createSimplePrintElement(int rowIndex, SimpleRowElement rowElement) {
return new SimplePrintElementImpl(rowIndex, rowElement.myPosition, rowElement.myType, rowElement.myElement, myPrintElementManager);
return new SimplePrintElementImpl(rowIndex, rowElement.myPosition, rowElement.myElement, myPrintElementManager);
}
private EdgePrintElementImpl createEdgePrintElement(int rowIndex, @NotNull ShortEdge shortEdge, @NotNull EdgePrintElement.Type type) {
private EdgePrintElementImpl createEdgePrintElement(int rowIndex,
@NotNull ShortEdge shortEdge,
@NotNull EdgePrintElement.Type type,
@NotNull boolean hasArrow) {
int positionInCurrentRow, positionInOtherRow;
if (type == EdgePrintElement.Type.DOWN) {
positionInCurrentRow = shortEdge.myUpPosition;
@@ -78,7 +108,8 @@ public abstract class AbstractPrintElementGenerator implements PrintElementGener
positionInCurrentRow = shortEdge.myDownPosition;
positionInOtherRow = shortEdge.myUpPosition;
}
return new EdgePrintElementImpl(rowIndex, positionInCurrentRow, positionInOtherRow, type, shortEdge.myEdge, myPrintElementManager);
return new EdgePrintElementImpl(rowIndex, positionInCurrentRow, positionInOtherRow, type, shortEdge.myEdge, hasArrow,
myPrintElementManager);
}
@NotNull
@@ -116,13 +147,19 @@ public abstract class AbstractPrintElementGenerator implements PrintElementGener
protected static class SimpleRowElement {
@NotNull public final GraphElement myElement;
@NotNull public final SimplePrintElement.Type myType;
@NotNull public final RowElementType myType;
public final int myPosition;
public SimpleRowElement(@NotNull GraphElement element, @NotNull SimplePrintElement.Type type, int position) {
public SimpleRowElement(@NotNull GraphElement element, @NotNull RowElementType type, int position) {
myElement = element;
myPosition = position;
myType = type;
}
}
enum RowElementType {
NODE,
UP_ARROW,
DOWN_ARROW
}
}
@@ -20,7 +20,6 @@ import com.intellij.openapi.util.Pair;
import com.intellij.util.NullableFunction;
import com.intellij.util.SmartList;
import com.intellij.util.containers.SLRUMap;
import com.intellij.vcs.log.graph.SimplePrintElement;
import com.intellij.vcs.log.graph.api.EdgeFilter;
import com.intellij.vcs.log.graph.api.LinearGraph;
import com.intellij.vcs.log.graph.api.elements.GraphEdge;
@@ -151,7 +150,7 @@ public class PrintElementGeneratorImpl extends AbstractPrintElementGenerator {
for (int position = 0; position < sortedVisibleElementsInRow.size(); position++) {
GraphElement element = sortedVisibleElementsInRow.get(position);
if (element instanceof GraphNode) {
result.add(new SimpleRowElement(element, SimplePrintElement.Type.NODE, position));
result.add(new SimpleRowElement(element, RowElementType.NODE, position));
}
if (element instanceof GraphEdge) {
@@ -172,13 +171,13 @@ public class PrintElementGeneratorImpl extends AbstractPrintElementGenerator {
case DOTTED_ARROW_DOWN:
case NOT_LOAD_COMMIT:
if (intEqual(edge.getUpNodeIndex(), visibleRowIndex - 1)) {
result.add(new SimpleRowElement(edge, SimplePrintElement.Type.DOWN_ARROW, position));
result.add(new SimpleRowElement(edge, RowElementType.DOWN_ARROW, position));
}
break;
case DOTTED_ARROW_UP:
if (intEqual(edge.getDownNodeIndex(), visibleRowIndex + 1)) // todo case 0-row arrow
{
result.add(new SimpleRowElement(edge, SimplePrintElement.Type.UP_ARROW, position));
result.add(new SimpleRowElement(edge, RowElementType.UP_ARROW, position));
}
break;
default:
@@ -196,9 +195,9 @@ public class PrintElementGeneratorImpl extends AbstractPrintElementGenerator {
int upOffset,
int downOffset,
int showingPartSize) {
if (upOffset == showingPartSize) result.add(new SimpleRowElement(edge, SimplePrintElement.Type.DOWN_ARROW, position));
if (upOffset == showingPartSize) result.add(new SimpleRowElement(edge, RowElementType.DOWN_ARROW, position));
if (downOffset == showingPartSize) result.add(new SimpleRowElement(edge, SimplePrintElement.Type.UP_ARROW, position));
if (downOffset == showingPartSize) result.add(new SimpleRowElement(edge, RowElementType.UP_ARROW, position));
}
private boolean edgeIsVisibleInRow(@NotNull GraphEdge edge, int visibleRowIndex) {
@@ -41,17 +41,20 @@ public class EdgePrintElementImpl extends PrintElementWithGraphElement implement
@NotNull private final Type myType;
@NotNull private final LineStyle myLineStyle;
private final int myPositionInOtherRow;
private final boolean myHasArrow;
public EdgePrintElementImpl(int rowIndex,
int positionInCurrentRow,
int positionInOtherRow,
@NotNull Type type,
@NotNull GraphEdge graphEdge,
@NotNull boolean hasArrow,
@NotNull PrintElementManager printElementManager) {
super(rowIndex, positionInCurrentRow, graphEdge, printElementManager);
myType = type;
myLineStyle = convertToLineStyle(graphEdge.getType());
myPositionInOtherRow = positionInOtherRow;
myHasArrow = hasArrow;
}
@Override
@@ -71,6 +74,11 @@ public class EdgePrintElementImpl extends PrintElementWithGraphElement implement
return myLineStyle;
}
@Override
public boolean hasArrow() {
return myHasArrow;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -82,6 +90,7 @@ public class EdgePrintElementImpl extends PrintElementWithGraphElement implement
if (myPositionInOtherRow != that.getPositionInOtherRow()) return false;
if (myRowIndex != that.getRowIndex()) return false;
if (myType != that.getType()) return false;
if (myHasArrow != that.hasArrow()) return false;
return true;
}
@@ -92,6 +101,7 @@ public class EdgePrintElementImpl extends PrintElementWithGraphElement implement
result = 31 * result + myPositionInCurrentRow;
result = 31 * result + myPositionInOtherRow;
result = 37 * result + myType.hashCode();
result = 31 * result + (myHasArrow ? 1 : 0);
return result;
}
@@ -16,40 +16,29 @@
package com.intellij.vcs.log.graph.impl.print.elements;
import com.intellij.vcs.log.graph.SimplePrintElement;
import com.intellij.vcs.log.graph.NodePrintElement;
import com.intellij.vcs.log.graph.api.elements.GraphElement;
import com.intellij.vcs.log.graph.api.printer.PrintElementManager;
import org.jetbrains.annotations.NotNull;
public class SimplePrintElementImpl extends PrintElementWithGraphElement implements SimplePrintElement {
@NotNull private final Type myType;
public class SimplePrintElementImpl extends PrintElementWithGraphElement implements NodePrintElement {
public SimplePrintElementImpl(int rowIndex,
int positionInCurrentRow,
@NotNull Type type,
@NotNull GraphElement graphElement,
@NotNull PrintElementManager printElementManager) {
super(rowIndex, positionInCurrentRow, graphElement, printElementManager);
myType = type;
}
@NotNull
@Override
public Type getType() {
return myType;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof SimplePrintElement)) return false;
if (!(o instanceof NodePrintElement)) return false;
SimplePrintElement that = (SimplePrintElement)o;
NodePrintElement that = (NodePrintElement)o;
if (myPositionInCurrentRow != that.getPositionInCurrentRow()) return false;
if (myRowIndex != that.getRowIndex()) return false;
if (myType != that.getType()) return false;
return true;
}
@@ -58,7 +47,6 @@ public class SimplePrintElementImpl extends PrintElementWithGraphElement impleme
public int hashCode() {
int result = myRowIndex;
result = 31 * result + myPositionInCurrentRow;
result = 37 * result + myType.hashCode();
return result;
}
@@ -15,7 +15,6 @@
*/
package com.intellij.vcs.log.printer.idea;
import com.intellij.vcs.log.graph.SimplePrintElement;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
@@ -46,12 +45,10 @@ public class PositionUtil {
return distance(x1, y1, x, y) + distance(x2, y2, x, y) < distance(x1, y1, x2, y2) + thick;
}
public static boolean overNode(int position, int x, int y, SimplePrintElement.Type type, int rowHeight) {
public static boolean overNode(int position, int x, int y, int rowHeight) {
int r = CIRCLE_RADIUS;
int x0 = WIDTH_NODE * position + WIDTH_NODE / 2;
int y0 = rowHeight / 2;
if (type == SimplePrintElement.Type.DOWN_ARROW) y0 = rowHeight - r;
if (type == SimplePrintElement.Type.UP_ARROW) y0 = r;
return distance(x0, y0, x, y) <= r;
}
@@ -17,8 +17,8 @@ package com.intellij.vcs.log.printer.idea;
import com.intellij.ui.JBColor;
import com.intellij.vcs.log.graph.EdgePrintElement;
import com.intellij.vcs.log.graph.NodePrintElement;
import com.intellij.vcs.log.graph.PrintElement;
import com.intellij.vcs.log.graph.SimplePrintElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -88,7 +88,6 @@ public class SimpleGraphCellPainter implements GraphCellPainter {
int r = PrintParameters.CIRCLE_RADIUS;
int y0 = getRowHeight() - r - 2;
g2.setColor(color);
g2.drawLine(x0, getRowHeight() / 2, x0, y0 + r);
g2.drawLine(x0, y0 + r, x0 + r, y0);
g2.drawLine(x0, y0 + r, x0 - r, y0);
}
@@ -98,7 +97,6 @@ public class SimpleGraphCellPainter implements GraphCellPainter {
int r = PrintParameters.CIRCLE_RADIUS;
int y0 = r + 2;
g2.setColor(color);
g2.drawLine(x0, getRowHeight() / 2, x0, y0 - r);
g2.drawLine(x0, y0 - r, x0 + r, y0);
g2.drawLine(x0, y0 - r, x0 - r, y0);
}
@@ -167,42 +165,28 @@ public class SimpleGraphCellPainter implements GraphCellPainter {
if (edgePrintElement.getType() == EdgePrintElement.Type.DOWN) {
paintDownLine(from, to, color);
if (edgePrintElement.hasArrow()) {
paintDownArrow(from, color);
}
}
else {
paintUpLine(from, to, color);
if (edgePrintElement.hasArrow()) {
paintUpArrow(from, color);
}
}
}
};
}
if (printElement instanceof SimplePrintElement) {
final int position = printElement.getPositionInCurrentRow();
switch (((SimplePrintElement)printElement).getType()) {
case NODE:
if (printElement.isSelected()) {
paintCircle(position, MARK_COLOR, true);
paintCircle(position, getColor(printElement), false);
}
else {
paintCircle(position, getColor(printElement), false);
}
break;
case UP_ARROW:
printer = new LitePrinter() {
@Override
public void print(Color color) {
paintUpArrow(position, color);
}
};
break;
case DOWN_ARROW:
printer = new LitePrinter() {
@Override
public void print(Color color) {
paintDownArrow(position, color);
}
};
break;
if (printElement instanceof NodePrintElement) {
int position = printElement.getPositionInCurrentRow();
if (printElement.isSelected()) {
paintCircle(position, MARK_COLOR, true);
paintCircle(position, getColor(printElement), false);
}
else {
paintCircle(position, getColor(printElement), false);
}
}
@@ -214,8 +198,8 @@ public class SimpleGraphCellPainter implements GraphCellPainter {
@Override
public PrintElement mouseOver(@NotNull Collection<? extends PrintElement> printElements, int x, int y) {
for (PrintElement printElement : printElements) {
if (printElement instanceof SimplePrintElement) {
if (PositionUtil.overNode(printElement.getPositionInCurrentRow(), x, y, ((SimplePrintElement)printElement).getType(), getRowHeight())) {
if (printElement instanceof NodePrintElement) {
if (PositionUtil.overNode(printElement.getPositionInCurrentRow(), x, y, getRowHeight())) {
return printElement;
}
}
@@ -61,15 +61,15 @@ fun PrintElementWithGraphElement.asString(): String {
val pos = getPositionInCurrentRow()
val sel = if (isSelected()) "Select" else "Unselect"
return when (this) {
is SimplePrintElement -> {
val t = getType()
"Simple:${t}|-$row:${pos}|-$color:${sel}($element)"
is NodePrintElement -> {
"Simple:NODE|-$row:${pos}|-$color:${sel}($element)"
}
is EdgePrintElement -> {
val t = getType()
val ls = getLineStyle()
val posO = getPositionInOtherRow()
"Edge:$t:${ls}|-$row:$pos:${posO}|-$color:$sel($element)"
val arrow = if (hasArrow()) "_ARROW" else ""
"Edge:$t${arrow}:${ls}|-$row:$pos:${posO}|-$color:$sel($element)"
}
else -> {
@@ -85,8 +85,8 @@ fun PrintElementGenerator.asString(size: Int): String {
if (row > 0) s.append("\n")
val elements = getPrintElements(row).sortBy {
val pos = it.getPositionInCurrentRow()
if (it is SimplePrintElement) {
1024 * pos + it.getType().ordinal()
if (it is NodePrintElement) {
1024 * pos
} else if (it is EdgePrintElement) {
1024 * pos + (it.getType().ordinal() + 1) * 64 + it.getPositionInOtherRow()
} else 0
@@ -11,9 +11,8 @@ Simple:NODE|-0:0|-0:Unselect(0_U)
Edge:DOWN:SOLID|-0:0:9|-9:Unselect(0:9:n_U)
Edge:DOWN:SOLID|-0:0:10|-10:Unselect(0:10:n_U)
Edge:DOWN:SOLID|-0:0:11|-11:Unselect(0:11:n_U)
Simple:DOWN_ARROW|-1:0|-12:Unselect(0:12:n_U)
Edge:UP:SOLID|-1:0:0|-12:Unselect(0:12:n_U)
Edge:DOWN:SOLID|-1:0:0|-12:Unselect(0:12:n_U)
Edge:UP:SOLID|-1:0:0|-12:Unselect(0:12:n_U)
Edge:DOWN_ARROW:SOLID|-1:0:0|-12:Unselect(0:12:n_U)
Simple:NODE|-1:1|-1:Unselect(1_U)
Edge:UP:SOLID|-1:1:0|-1:Unselect(0:1:n_U)
Edge:DOWN:SOLID|-1:1:1|-13:Unselect(1:12:n_U)
@@ -33,17 +32,14 @@ Simple:DOWN_ARROW|-1:0|-12:Unselect(0:12:n_U)
Edge:DOWN:SOLID|-1:8:8|-8:Unselect(0:8:n_U)
Edge:UP:SOLID|-1:9:0|-9:Unselect(0:9:n_U)
Edge:DOWN:SOLID|-1:9:9|-9:Unselect(0:9:n_U)
Simple:DOWN_ARROW|-1:10|-10:Unselect(0:10:n_U)
Edge:UP:SOLID|-1:10:0|-10:Unselect(0:10:n_U)
Edge:DOWN:SOLID|-1:10:10|-10:Unselect(0:10:n_U)
Simple:DOWN_ARROW|-1:11|-11:Unselect(0:11:n_U)
Edge:DOWN_ARROW:SOLID|-1:10:10|-10:Unselect(0:10:n_U)
Edge:UP:SOLID|-1:11:0|-11:Unselect(0:11:n_U)
Edge:DOWN:SOLID|-1:11:11|-11:Unselect(0:11:n_U)
Simple:DOWN_ARROW|-2:0|-12:Unselect(0:12:n_U)
Edge:UP:SOLID|-2:0:0|-12:Unselect(0:12:n_U)
Simple:DOWN_ARROW|-2:1|-13:Unselect(1:12:n_U)
Edge:DOWN_ARROW:SOLID|-1:11:11|-11:Unselect(0:11:n_U)
Edge:UP:SOLID|-2:0:0|-12:Unselect(0:12:n_U)
Edge:DOWN_ARROW:SOLID|-2:0:0|-12:Unselect(0:12:n_U)
Edge:UP:SOLID|-2:1:1|-13:Unselect(1:12:n_U)
Edge:DOWN:SOLID|-2:1:0|-13:Unselect(1:12:n_U)
Edge:DOWN_ARROW:SOLID|-2:1:0|-13:Unselect(1:12:n_U)
Simple:NODE|-2:2|-2:Unselect(2_U)
Edge:UP:SOLID|-2:2:2|-2:Unselect(0:2:n_U)
Edge:DOWN:SOLID|-2:2:1|-14:Unselect(2:12:n_U)
@@ -55,21 +51,20 @@ Simple:DOWN_ARROW|-2:0|-12:Unselect(0:12:n_U)
Edge:DOWN:SOLID|-2:5:4|-5:Unselect(0:5:n_U)
Edge:UP:SOLID|-2:6:6|-6:Unselect(0:6:n_U)
Edge:DOWN:SOLID|-2:6:5|-6:Unselect(0:6:n_U)
Simple:DOWN_ARROW|-2:7|-7:Unselect(0:7:n_U)
Edge:UP:SOLID|-2:7:7|-7:Unselect(0:7:n_U)
Simple:DOWN_ARROW|-2:8|-8:Unselect(0:8:n_U)
Edge:DOWN_ARROW:SOLID|-2:7:7|-7:Unselect(0:7:n_U)
Edge:UP:SOLID|-2:8:8|-8:Unselect(0:8:n_U)
Simple:DOWN_ARROW|-2:9|-9:Unselect(0:9:n_U)
Edge:DOWN_ARROW:SOLID|-2:8:8|-8:Unselect(0:8:n_U)
Edge:UP:SOLID|-2:9:9|-9:Unselect(0:9:n_U)
Simple:DOWN_ARROW|-2:10|-10:Unselect(0:10:n_U)
Edge:DOWN_ARROW:SOLID|-2:9:9|-9:Unselect(0:9:n_U)
Edge:UP:SOLID|-2:10:10|-10:Unselect(0:10:n_U)
Simple:DOWN_ARROW|-2:11|-11:Unselect(0:11:n_U)
Edge:DOWN_ARROW:SOLID|-2:10:10|-10:Unselect(0:10:n_U)
Edge:UP:SOLID|-2:11:11|-11:Unselect(0:11:n_U)
Simple:DOWN_ARROW|-3:0|-13:Unselect(1:12:n_U)
Edge:UP:SOLID|-3:0:1|-13:Unselect(1:12:n_U)
Simple:DOWN_ARROW|-3:1|-14:Unselect(2:12:n_U)
Edge:DOWN_ARROW:SOLID|-2:11:11|-11:Unselect(0:11:n_U)
Edge:UP:SOLID|-3:0:1|-13:Unselect(1:12:n_U)
Edge:DOWN_ARROW:SOLID|-3:0:0|-13:Unselect(1:12:n_U)
Edge:UP:SOLID|-3:1:2|-14:Unselect(2:12:n_U)
Edge:DOWN:SOLID|-3:1:0|-14:Unselect(2:12:n_U)
Edge:DOWN_ARROW:SOLID|-3:1:0|-14:Unselect(2:12:n_U)
Simple:NODE|-3:2|-3:Unselect(3_U)
Edge:UP:SOLID|-3:2:3|-3:Unselect(0:3:n_U)
Edge:DOWN:SOLID|-3:2:1|-15:Unselect(3:12:n_U)
@@ -79,8 +74,8 @@ Simple:DOWN_ARROW|-3:0|-13:Unselect(1:12:n_U)
Edge:DOWN:SOLID|-3:4:3|-5:Unselect(0:5:n_U)
Edge:UP:SOLID|-3:5:6|-6:Unselect(0:6:n_U)
Edge:DOWN:SOLID|-3:5:4|-6:Unselect(0:6:n_U)
Simple:DOWN_ARROW|-4:0|-14:Unselect(2:12:n_U)
Edge:UP:SOLID|-4:0:1|-14:Unselect(2:12:n_U)
Edge:UP:SOLID|-4:0:1|-14:Unselect(2:12:n_U)
Edge:DOWN_ARROW:SOLID|-4:0:0|-14:Unselect(2:12:n_U)
Edge:UP:SOLID|-4:1:2|-15:Unselect(3:12:n_U)
Edge:DOWN:SOLID|-4:1:0|-15:Unselect(3:12:n_U)
Simple:NODE|-4:2|-4:Unselect(4_U)
@@ -90,8 +85,8 @@ Simple:DOWN_ARROW|-4:0|-14:Unselect(2:12:n_U)
Edge:DOWN:SOLID|-4:3:2|-5:Unselect(0:5:n_U)
Edge:UP:SOLID|-4:4:5|-6:Unselect(0:6:n_U)
Edge:DOWN:SOLID|-4:4:3|-6:Unselect(0:6:n_U)
Simple:DOWN_ARROW|-5:0|-15:Unselect(3:12:n_U)
Edge:UP:SOLID|-5:0:1|-15:Unselect(3:12:n_U)
Edge:UP:SOLID|-5:0:1|-15:Unselect(3:12:n_U)
Edge:DOWN_ARROW:SOLID|-5:0:0|-15:Unselect(3:12:n_U)
Edge:UP:SOLID|-5:1:2|-16:Unselect(4:12:n_U)
Edge:DOWN:SOLID|-5:1:0|-16:Unselect(4:12:n_U)
Simple:NODE|-5:2|-5:Unselect(5_U)
@@ -99,10 +94,10 @@ Simple:DOWN_ARROW|-5:0|-15:Unselect(3:12:n_U)
Edge:DOWN:SOLID|-5:2:1|-17:Unselect(5:12:n_U)
Edge:UP:SOLID|-5:3:4|-6:Unselect(0:6:n_U)
Edge:DOWN:SOLID|-5:3:2|-6:Unselect(0:6:n_U)
Simple:UP_ARROW|-5:4|-7:Unselect(0:7:n_U)
Edge:UP_ARROW:SOLID|-5:4:4|-7:Unselect(0:7:n_U)
Edge:DOWN:SOLID|-5:4:3|-7:Unselect(0:7:n_U)
Simple:DOWN_ARROW|-6:0|-16:Unselect(4:12:n_U)
Edge:UP:SOLID|-6:0:1|-16:Unselect(4:12:n_U)
Edge:UP:SOLID|-6:0:1|-16:Unselect(4:12:n_U)
Edge:DOWN_ARROW:SOLID|-6:0:0|-16:Unselect(4:12:n_U)
Edge:UP:SOLID|-6:1:2|-17:Unselect(5:12:n_U)
Edge:DOWN:SOLID|-6:1:0|-17:Unselect(5:12:n_U)
Simple:NODE|-6:2|-6:Unselect(6_U)
@@ -110,10 +105,10 @@ Simple:DOWN_ARROW|-6:0|-16:Unselect(4:12:n_U)
Edge:DOWN:SOLID|-6:2:1|-18:Unselect(6:12:n_U)
Edge:UP:SOLID|-6:3:4|-7:Unselect(0:7:n_U)
Edge:DOWN:SOLID|-6:3:2|-7:Unselect(0:7:n_U)
Simple:UP_ARROW|-6:4|-8:Unselect(0:8:n_U)
Edge:UP_ARROW:SOLID|-6:4:4|-8:Unselect(0:8:n_U)
Edge:DOWN:SOLID|-6:4:3|-8:Unselect(0:8:n_U)
Simple:DOWN_ARROW|-7:0|-17:Unselect(5:12:n_U)
Edge:UP:SOLID|-7:0:1|-17:Unselect(5:12:n_U)
Edge:UP:SOLID|-7:0:1|-17:Unselect(5:12:n_U)
Edge:DOWN_ARROW:SOLID|-7:0:0|-17:Unselect(5:12:n_U)
Edge:UP:SOLID|-7:1:2|-18:Unselect(6:12:n_U)
Edge:DOWN:SOLID|-7:1:0|-18:Unselect(6:12:n_U)
Simple:NODE|-7:2|-7:Unselect(7_U)
@@ -121,7 +116,7 @@ Simple:DOWN_ARROW|-7:0|-17:Unselect(5:12:n_U)
Edge:DOWN:SOLID|-7:2:1|-19:Unselect(7:12:n_U)
Edge:UP:SOLID|-7:3:4|-8:Unselect(0:8:n_U)
Edge:DOWN:SOLID|-7:3:2|-8:Unselect(0:8:n_U)
Simple:UP_ARROW|-7:4|-9:Unselect(0:9:n_U)
Edge:UP_ARROW:SOLID|-7:4:4|-9:Unselect(0:9:n_U)
Edge:DOWN:SOLID|-7:4:3|-9:Unselect(0:9:n_U)
Edge:UP:SOLID|-8:0:1|-18:Unselect(6:12:n_U)
Edge:DOWN:SOLID|-8:0:0|-18:Unselect(6:12:n_U)
@@ -132,7 +127,7 @@ Edge:UP:SOLID|-8:0:1|-18:Unselect(6:12:n_U)
Edge:DOWN:SOLID|-8:2:2|-20:Unselect(8:12:n_U)
Edge:UP:SOLID|-8:3:4|-9:Unselect(0:9:n_U)
Edge:DOWN:SOLID|-8:3:3|-9:Unselect(0:9:n_U)
Simple:UP_ARROW|-8:4|-10:Unselect(0:10:n_U)
Edge:UP_ARROW:SOLID|-8:4:4|-10:Unselect(0:10:n_U)
Edge:DOWN:SOLID|-8:4:4|-10:Unselect(0:10:n_U)
Edge:UP:SOLID|-9:0:0|-18:Unselect(6:12:n_U)
Edge:DOWN:SOLID|-9:0:6|-18:Unselect(6:12:n_U)
@@ -143,22 +138,21 @@ Edge:UP:SOLID|-9:0:0|-18:Unselect(6:12:n_U)
Simple:NODE|-9:3|-9:Unselect(9_U)
Edge:UP:SOLID|-9:3:3|-9:Unselect(0:9:n_U)
Edge:DOWN:SOLID|-9:3:9|-21:Unselect(9:12:n_U)
Simple:UP_ARROW|-9:4|-10:Unselect(0:10:n_U)
Edge:UP:SOLID|-9:4:4|-10:Unselect(0:10:n_U)
Edge:UP_ARROW:SOLID|-9:4:4|-10:Unselect(0:10:n_U)
Edge:DOWN:SOLID|-9:4:10|-10:Unselect(0:10:n_U)
Simple:UP_ARROW|-9:5|-11:Unselect(0:11:n_U)
Edge:UP_ARROW:SOLID|-9:5:5|-11:Unselect(0:11:n_U)
Edge:DOWN:SOLID|-9:5:11|-11:Unselect(0:11:n_U)
Simple:UP_ARROW|-10:0|-12:Unselect(0:12:n_U)
Edge:UP_ARROW:SOLID|-10:0:0|-12:Unselect(0:12:n_U)
Edge:DOWN:SOLID|-10:0:0|-12:Unselect(0:12:n_U)
Simple:UP_ARROW|-10:1|-13:Unselect(1:12:n_U)
Edge:UP_ARROW:SOLID|-10:1:1|-13:Unselect(1:12:n_U)
Edge:DOWN:SOLID|-10:1:1|-13:Unselect(1:12:n_U)
Simple:UP_ARROW|-10:2|-14:Unselect(2:12:n_U)
Edge:UP_ARROW:SOLID|-10:2:2|-14:Unselect(2:12:n_U)
Edge:DOWN:SOLID|-10:2:2|-14:Unselect(2:12:n_U)
Simple:UP_ARROW|-10:3|-15:Unselect(3:12:n_U)
Edge:UP_ARROW:SOLID|-10:3:3|-15:Unselect(3:12:n_U)
Edge:DOWN:SOLID|-10:3:3|-15:Unselect(3:12:n_U)
Simple:UP_ARROW|-10:4|-16:Unselect(4:12:n_U)
Edge:UP_ARROW:SOLID|-10:4:4|-16:Unselect(4:12:n_U)
Edge:DOWN:SOLID|-10:4:4|-16:Unselect(4:12:n_U)
Simple:UP_ARROW|-10:5|-17:Unselect(5:12:n_U)
Edge:UP_ARROW:SOLID|-10:5:5|-17:Unselect(5:12:n_U)
Edge:DOWN:SOLID|-10:5:5|-17:Unselect(5:12:n_U)
Edge:UP:SOLID|-10:6:0|-18:Unselect(6:12:n_U)
Edge:DOWN:SOLID|-10:6:6|-18:Unselect(6:12:n_U)
@@ -171,17 +165,13 @@ Simple:UP_ARROW|-10:0|-12:Unselect(0:12:n_U)
Simple:NODE|-10:10|-10:Unselect(10_U)
Edge:UP:SOLID|-10:10:4|-10:Unselect(0:10:n_U)
Edge:DOWN:SOLID|-10:10:10|-22:Unselect(10:12:n_U)
Simple:UP_ARROW|-10:11|-11:Unselect(0:11:n_U)
Edge:UP:SOLID|-10:11:5|-11:Unselect(0:11:n_U)
Edge:UP_ARROW:SOLID|-10:11:5|-11:Unselect(0:11:n_U)
Edge:DOWN:SOLID|-10:11:11|-11:Unselect(0:11:n_U)
Simple:UP_ARROW|-11:0|-12:Unselect(0:12:n_U)
Edge:UP:SOLID|-11:0:0|-12:Unselect(0:12:n_U)
Edge:UP_ARROW:SOLID|-11:0:0|-12:Unselect(0:12:n_U)
Edge:DOWN:SOLID|-11:0:0|-12:Unselect(0:12:n_U)
Simple:UP_ARROW|-11:1|-13:Unselect(1:12:n_U)
Edge:UP:SOLID|-11:1:1|-13:Unselect(1:12:n_U)
Edge:UP_ARROW:SOLID|-11:1:1|-13:Unselect(1:12:n_U)
Edge:DOWN:SOLID|-11:1:0|-13:Unselect(1:12:n_U)
Simple:UP_ARROW|-11:2|-14:Unselect(2:12:n_U)
Edge:UP:SOLID|-11:2:2|-14:Unselect(2:12:n_U)
Edge:UP_ARROW:SOLID|-11:2:2|-14:Unselect(2:12:n_U)
Edge:DOWN:SOLID|-11:2:0|-14:Unselect(2:12:n_U)
Edge:UP:SOLID|-11:3:3|-15:Unselect(3:12:n_U)
Edge:DOWN:SOLID|-11:3:0|-15:Unselect(3:12:n_U)
@@ -2,17 +2,17 @@ Simple:NODE|-0:0|-0:Unselect(0_G)
Edge:DOWN:DASHED|-0:0:0|-4:Unselect(0:4:n_D)
Edge:DOWN:SOLID|-0:0:1|-0:Unselect(0:n:10_N)
Edge:DOWN:DASHED|-0:0:2|-0:Unselect(0:n:11_O)
Simple:UP_ARROW|-0:1|-1:Unselect(n:1:0_P)
Edge:UP_ARROW:DASHED|-0:1:1|-1:Unselect(n:1:0_P)
Edge:DOWN:DASHED|-0:1:3|-1:Unselect(n:1:0_P)
Edge:UP:DASHED|-1:0:0|-4:Unselect(0:4:n_D)
Edge:DOWN:DASHED|-1:0:0|-4:Unselect(0:4:n_D)
Simple:DOWN_ARROW|-1:1|-0:Unselect(0:n:10_N)
Edge:UP:SOLID|-1:1:0|-0:Unselect(0:n:10_N)
Simple:DOWN_ARROW|-1:2|-0:Unselect(0:n:11_O)
Edge:DOWN_ARROW:SOLID|-1:1:1|-0:Unselect(0:n:10_N)
Edge:UP:DASHED|-1:2:0|-0:Unselect(0:n:11_O)
Edge:DOWN_ARROW:DASHED|-1:2:2|-0:Unselect(0:n:11_O)
Simple:NODE|-1:3|-1:Unselect(1_U)
Edge:UP:DASHED|-1:3:1|-1:Unselect(n:1:0_P)
Simple:UP_ARROW|-1:4|-2:Unselect(n:2:0_P)
Edge:UP_ARROW:DASHED|-1:4:4|-2:Unselect(n:2:0_P)
Edge:DOWN:DASHED|-1:4:1|-2:Unselect(n:2:0_P)
Edge:UP:DASHED|-2:0:0|-4:Unselect(0:4:n_D)
Edge:DOWN:DASHED|-2:0:0|-4:Unselect(0:4:n_D)
@@ -22,10 +22,10 @@ Edge:UP:DASHED|-2:0:0|-4:Unselect(0:4:n_D)
Edge:DOWN:SOLID|-2:1:2|-2:Unselect(2:n:12_N)
Edge:UP:DASHED|-3:0:0|-4:Unselect(0:4:n_D)
Edge:DOWN:DASHED|-3:0:0|-4:Unselect(0:4:n_D)
Simple:DOWN_ARROW|-3:1|-2:Unselect(2:n:3_O)
Edge:UP:DASHED|-3:1:1|-2:Unselect(2:n:3_O)
Simple:DOWN_ARROW|-3:2|-2:Unselect(2:n:12_N)
Edge:DOWN_ARROW:DASHED|-3:1:1|-2:Unselect(2:n:3_O)
Edge:UP:SOLID|-3:2:1|-2:Unselect(2:n:12_N)
Edge:DOWN_ARROW:SOLID|-3:2:2|-2:Unselect(2:n:12_N)
Simple:NODE|-3:3|-3:Unselect(3_G)
Simple:NODE|-4:0|-4:Unselect(4_U)
Edge:UP:DASHED|-4:0:0|-4:Unselect(0:4:n_D)