1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-11-25 06:17:33 +00:00
This commit is contained in:
Arnaud Roques 2023-01-16 20:06:31 +01:00
parent 1fe09aea4f
commit db9080e28f
16 changed files with 176 additions and 75 deletions

View File

@ -154,6 +154,11 @@ public class EmbeddedDiagram extends AbstractTextBlock implements Line, Atom {
public XDimension2D calculateDimension(StringBounder stringBounder) {
try {
if (stringBounder.getNativeFormat() == FileFormat.SVG) {
final String imageSvg = getImageSvg();
final UImageSvg svg = new UImageSvg(imageSvg, 1);
return new XDimension2D(svg.getWidth(), svg.getHeight());
}
final BufferedImage im = getImage();
return new XDimension2D(im.getWidth(), im.getHeight());
} catch (IOException e) {

View File

@ -162,12 +162,15 @@ public enum FileFormat {
return getJavaDimension(font, text);
}
public FileFormat getNativeFormat() {
return FileFormat.this;
}
};
}
private StringBounder getNormalStringBounder() {
return new StringBounderRaw() {
@Override
public String toString() {
return "FileFormat::getNormalStringBounder";
}
@ -176,6 +179,10 @@ public enum FileFormat {
return getJavaDimension(font, text);
}
public FileFormat getNativeFormat() {
return FileFormat.this;
}
};
}
@ -188,7 +195,6 @@ public enum FileFormat {
private StringBounder getBrailleStringBounder() {
return new StringBounderRaw() {
@Override
public String toString() {
return "FileFormat::getBrailleStringBounder";
}
@ -205,12 +211,16 @@ public enum FileFormat {
public double getDescent(UFont font, String text) {
return UGraphicBraille.QUANTA;
}
public FileFormat getNativeFormat() {
return FileFormat.this;
}
};
}
private StringBounder getTikzStringBounder(final TikzFontDistortion tikzFontDistortion) {
return new StringBounderRaw() {
@Override
public String toString() {
return "FileFormat::getTikzStringBounder";
}
@ -226,6 +236,10 @@ public enum FileFormat {
final double delta = (w2.getWidth() - w1.getWidth()) * factor * distortion;
return w2.withWidth(Math.max(w1.getWidth(), magnify * w2.getWidth() - delta));
}
public FileFormat getNativeFormat() {
return FileFormat.this;
}
};
}

View File

@ -35,6 +35,7 @@
*/
package net.sourceforge.plantuml.asciiart;
import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.awt.geom.XDimension2D;
import net.sourceforge.plantuml.graphic.StringBounderRaw;
import net.sourceforge.plantuml.ugraphic.UFont;
@ -48,4 +49,9 @@ public class TextStringBounder extends StringBounderRaw {
return new XDimension2D(length2, 1);
}
@Override
public FileFormat getNativeFormat() {
return FileFormat.ATXT;
}
}

View File

@ -297,7 +297,7 @@ public class EpsGraphics {
} else if (type == USegmentType.SEG_CLOSE) {
// Nothing
} else if (type == USegmentType.SEG_ARCTO) {
// Nothing
linetoNoMacro(coord[5] + x, coord[6] + y);
} else {
Log.println("unknown1 " + seg);
}
@ -323,7 +323,7 @@ public class EpsGraphics {
} else if (type == USegmentType.SEG_CLOSE) {
// Nothing
} else if (type == USegmentType.SEG_ARCTO) {
// Nothing
linetoNoMacro(coord[5] + x, coord[6] + y);
} else {
Log.println("unknown2 " + seg);
}

View File

@ -35,6 +35,7 @@
*/
package net.sourceforge.plantuml.graphic;
import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.awt.geom.XDimension2D;
import net.sourceforge.plantuml.ugraphic.UFont;
@ -44,4 +45,6 @@ public interface StringBounder {
public double getDescent(UFont font, String text);
public FileFormat getNativeFormat();
}

View File

@ -67,9 +67,9 @@ import net.sourceforge.plantuml.nwdiag.core.NStackable;
import net.sourceforge.plantuml.nwdiag.core.Network;
import net.sourceforge.plantuml.nwdiag.core.NwGroup;
import net.sourceforge.plantuml.nwdiag.next.GridTextBlockDecorated;
import net.sourceforge.plantuml.nwdiag.next.LinkedElement;
import net.sourceforge.plantuml.nwdiag.next.NBar;
import net.sourceforge.plantuml.nwdiag.next.NPlayField;
import net.sourceforge.plantuml.nwdiag.next.NServerDraw;
import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
@ -160,21 +160,33 @@ public class NwDiagram extends UmlDiagram {
if (initDone == false)
return errorNoInit();
String existingAddress = "";
final NServer server2;
if (lastNetwork() == null) {
createNetwork(name1);
server2 = NServer.create(name2);
server2 = NServer.create(name2, getSkinParam());
} else {
final NServer server1 = servers.get(name1);
final NServer previous2 = servers.get(name2);
if (previous2 != null)
existingAddress = previous2.someAddress();
final Network network1 = createNetwork("");
network1.goInvisible();
if (server1 != null)
server1.connectTo(lastNetwork());
if (server1 != null) {
final Network someNetwork = server1.someNetwork();
if (someNetwork != null && someNetwork.isVisible() == false && someNetwork.getUp() == null) {
final String tmp = server1.someAddress();
server1.blankSomeAddress();
server1.connectTo(lastNetwork(), tmp);
} else {
server1.connectTo(lastNetwork(), "");
}
}
server2 = new NServer(name2, server1.getBar());
server2 = new NServer(name2, server1.getBar(), getSkinParam());
}
servers.put(name2, server2);
server2.connectTo(lastNetwork());
server2.connectTo(lastNetwork(), existingAddress);
playField.addInPlayfield(server2.getBar());
return CommandExecutionResult.ok();
}
@ -198,13 +210,13 @@ public class NwDiagram extends UmlDiagram {
assert currentGroup == null;
final Network network1 = createNetwork("");
network1.goInvisible();
server = NServer.create(name);
server = NServer.create(name, getSkinParam());
servers.put(name, server);
server.doNotPrintFirstLink();
} else {
server = servers.get(name);
if (server == null) {
server = NServer.create(name);
server = NServer.create(name, getSkinParam());
servers.put(name, server);
}
}
@ -216,7 +228,7 @@ public class NwDiagram extends UmlDiagram {
}
private boolean alreadyInSomeGroup(String name) {
for (NwGroup g : groups)
for (NwGroup g : groups)
if (g.names().contains(name))
return true;
@ -368,11 +380,11 @@ public class NwDiagram extends UmlDiagram {
final Integer col = layout.get(server.getBar());
if (col == null)
continue;
double topMargin = LinkedElement.MAGIC;
double topMargin = NServerDraw.MAGIC;
NwGroup group = getGroupOf(server);
if (group != null)
topMargin += group.getTopHeaderHeight(stringBounder, getSkinParam());
grid.add(i, col, server.getLinkedElement(topMargin, conns, networks, getSkinParam()));
grid.add(i, col, server.getDraw(topMargin, conns, networks, getSkinParam()));
}
}
}
@ -399,8 +411,7 @@ public class NwDiagram extends UmlDiagram {
lastNetwork().setFullWidth("full".equalsIgnoreCase(value));
if ("color".equalsIgnoreCase(property)) {
final HColor color = value == null ? null
: getSkinParam().getIHtmlColorSet().getColorOrWhite(value);
final HColor color = value == null ? null : getSkinParam().getIHtmlColorSet().getColorOrWhite(value);
if (currentGroup != null)
currentGroup.setColor(color);
else if (lastNetwork() != null)

View File

@ -37,7 +37,6 @@ package net.sourceforge.plantuml.nwdiag.core;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import net.sourceforge.plantuml.ComponentStyle;
import net.sourceforge.plantuml.ISkinParam;
@ -49,8 +48,8 @@ import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.graphic.USymbol;
import net.sourceforge.plantuml.graphic.USymbols;
import net.sourceforge.plantuml.nwdiag.next.LinkedElement;
import net.sourceforge.plantuml.nwdiag.next.NBar;
import net.sourceforge.plantuml.nwdiag.next.NServerDraw;
import net.sourceforge.plantuml.skin.ActorStyle;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
@ -69,6 +68,7 @@ public class NServer {
private String description;
private String backcolor;
private final NBar bar;
private final ISkinParam skinParam;
private boolean printFirstLink = true;
@ -76,6 +76,25 @@ public class NServer {
this.printFirstLink = false;
}
public String someAddress() {
if (connections.size() > 0)
return connections.values().iterator().next();
return "";
}
public Network someNetwork() {
if (connections.size() > 0)
return connections.keySet().iterator().next();
return null;
}
public void blankSomeAddress() {
if (connections.size() > 0) {
final Network it = connections.keySet().iterator().next();
connections.put(it, "");
}
}
public final boolean printFirstLink() {
return printFirstLink;
}
@ -88,7 +107,7 @@ public class NServer {
return connections.get(network);
}
private TextBlock toTextBlock(String s, ISkinParam skinParam, SName sname) {
public TextBlock toTextBlock(SName sname, String s) {
if (s == null)
return null;
@ -96,21 +115,20 @@ public class NServer {
return TextBlockUtils.empty(0, 0);
s = s.replace(", ", "\\n");
return Display.getWithNewlines(s).create(getFontConfiguration(skinParam, sname), HorizontalAlignment.LEFT,
skinParam);
return Display.getWithNewlines(s).create(getFontConfiguration(sname), HorizontalAlignment.LEFT, skinParam);
}
private StyleSignatureBasic getStyleDefinition(SName sname) {
return StyleSignatureBasic.of(SName.root, SName.element, SName.nwdiagDiagram, sname);
}
private FontConfiguration getFontConfiguration(ISkinParam skinParam, SName sname) {
private FontConfiguration getFontConfiguration(SName sname) {
final StyleBuilder styleBuilder = skinParam.getCurrentStyleBuilder();
final Style style = getStyleDefinition(sname).getMergedStyle(styleBuilder);
return style.getFontConfiguration(skinParam.getIHtmlColorSet());
}
public LinkedElement getLinkedElement(double topMargin, Map<Network, String> conns, List<Network> networks,
public NServerDraw getDraw(double topMargin, Map<Network, String> conns, List<Network> networks,
ISkinParam skinParam) {
final StyleBuilder styleBuilder = skinParam.getCurrentStyleBuilder();
SymbolContext symbolContext = getStyleDefinition(SName.server).getMergedStyle(styleBuilder)
@ -122,18 +140,10 @@ public class NServer {
} catch (NoSuchColorException e) {
}
final Map<Network, TextBlock> conns2 = new LinkedHashMap<Network, TextBlock>();
for (Entry<Network, String> ent : conns.entrySet())
conns2.put(ent.getKey(), toTextBlock(ent.getValue(), skinParam, SName.arrow));
final TextBlock desc = toTextBlock(getDescription(), skinParam, SName.server);
final TextBlock desc = toTextBlock(SName.server, getDescription());
final TextBlock box = getShape().asSmall(TextBlockUtils.empty(0, 0), desc, TextBlockUtils.empty(0, 0),
symbolContext, HorizontalAlignment.CENTER);
return new LinkedElement(topMargin, this, box, conns2, networks);
}
public void connectTo(Network network) {
connectTo(network, "");
return new NServerDraw(this, box, conns, networks, topMargin);
}
public void connectTo(Network network, String address) {
@ -169,14 +179,15 @@ public class NServer {
return name;
}
public static NServer create(String name) {
return new NServer(name, new NBar());
public static NServer create(String name, ISkinParam skinParam) {
return new NServer(name, new NBar(), skinParam);
}
public NServer(String name, NBar bar) {
public NServer(String name, NBar bar, ISkinParam skinParam) {
this.description = name;
this.name = name;
this.bar = bar;
this.skinParam = skinParam;
}
public final String getDescription() {
@ -195,4 +206,8 @@ public class NServer {
return bar;
}
public final ISkinParam getSkinParam() {
return skinParam;
}
}

View File

@ -52,7 +52,7 @@ public class Network implements NStackable {
@Override
public String toString() {
return name;
return name + " visible=" + visible;
}
private boolean isEven() {
@ -87,9 +87,9 @@ public class Network implements NStackable {
}
public final String getDisplayName() {
if (this.description == null)
if (this.description == null)
return name;
return this.description;
}

View File

@ -106,7 +106,7 @@ public class GridTextBlockDecorated extends GridTextBlockSimple {
double x = 0;
for (int j = 0; j < data.getNbCols(); j++) {
final double colWidth = colWidth(stringBounder, j);
final LinkedElement element = data.get(i, j);
final NServerDraw element = data.get(i, j);
if (element != null && group.contains(element.getServer())) {
final MinMax minMax = element.getMinMax(stringBounder, colWidth, lineHeight)
.translate(new UTranslate(x, y));
@ -116,15 +116,14 @@ public class GridTextBlockDecorated extends GridTextBlockSimple {
}
y += lineHeight;
}
if (size != null) {
if (size != null)
group.drawGroup(ug, size, skinParam);
}
}
private boolean isThereALink(int j, Network network) {
for (int i = 0; i < data.getNbLines(); i++) {
final LinkedElement element = data.get(i, j);
final NServerDraw element = data.get(i, j);
if (element != null && element.isLinkedTo(network))
return true;
@ -144,15 +143,15 @@ public class GridTextBlockDecorated extends GridTextBlockSimple {
final Network network = getNetwork(i);
computeMixMax(data.getLine(i), stringBounder, network);
final URectangle rect = new URectangle(network.getXmax() - network.getXmin(), NETWORK_THIN);
final double width = Math.max(GridTextBlockSimple.MINIMUM_WIDTH, network.getXmax() - network.getXmin());
final URectangle rect = new URectangle(width, NETWORK_THIN);
UGraphic ug2 = ug.apply(new UTranslate(network.getXmin(), y));
final StyleBuilder styleBuilder = getSkinParam().getCurrentStyleBuilder();
final Style style = getStyleDefinitionNetwork(SName.network).getMergedStyle(styleBuilder);
final double deltaShadow = style.value(PName.Shadowing).asDouble();
ug2 = ug2.apply(style.value(PName.LineColor).asColor(getSkinParam().getIHtmlColorSet()));
ug2 = ug2.apply(style.value(PName.BackGroundColor)
.asColor(getSkinParam().getIHtmlColorSet()).bg());
ug2 = ug2.apply(style.value(PName.BackGroundColor).asColor(getSkinParam().getIHtmlColorSet()).bg());
rect.setDeltaShadow(deltaShadow);
if (network != null && network.getColor() != null)
@ -168,7 +167,7 @@ public class GridTextBlockDecorated extends GridTextBlockSimple {
}
}
private void computeMixMax(LinkedElement line[], StringBounder stringBounder, Network network) {
private void computeMixMax(NServerDraw line[], StringBounder stringBounder, Network network) {
double x = 0;
double xmin = network.isFullWidth() ? 0 : -1;
double xmax = 0;

View File

@ -46,6 +46,8 @@ import net.sourceforge.plantuml.ugraphic.UTranslate;
public class GridTextBlockSimple implements TextBlock {
public static final double MINIMUM_WIDTH = 70;
protected final NwArray data;
private final ISkinParam skinParam;
@ -105,7 +107,7 @@ public class GridTextBlockSimple implements TextBlock {
for (int j = 0; j < data.getNbCols(); j++)
width += colWidth(stringBounder, j);
return new XDimension2D(width, height);
return new XDimension2D(Math.max(MINIMUM_WIDTH, width), height);
}
public XRectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) {
@ -116,7 +118,7 @@ public class GridTextBlockSimple implements TextBlock {
throw new UnsupportedOperationException(getClass().toString());
}
public void add(int i, int j, LinkedElement value) {
public void add(int i, int j, NServerDraw value) {
data.set(i, j, value);
}

View File

@ -46,24 +46,30 @@ import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.nwdiag.VerticalLine;
import net.sourceforge.plantuml.nwdiag.core.NServer;
import net.sourceforge.plantuml.nwdiag.core.Network;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.utils.MathUtils;
public class LinkedElement {
public class NServerDraw {
public static final int MAGIC = 15;
private final TextBlock box;
private final Network network;
private final NServer server;
private final Map<Network, TextBlock> conns;
private final Map<Network, String> conns;
private final List<Network> networks;
private final double topMargin;
public LinkedElement(double topMargin, NServer server, TextBlock box, Map<Network, TextBlock> conns,
List<Network> networks) {
@Override
public String toString() {
return server.toString() + " " + conns;
}
public NServerDraw(NServer server, TextBlock box, Map<Network, String> conns, List<Network> networks,
double topMargin) {
this.topMargin = topMargin;
this.networks = networks;
this.box = box;
@ -121,10 +127,9 @@ public class LinkedElement {
final TreeSet<Double> skip = new TreeSet<>();
for (Network n : networks) {
for (Network n : networks)
if (xstart + xMiddle > n.getXmin() && xstart + xMiddle < n.getXmax())
skip.add(n.getY());
}
if (server.printFirstLink())
if (network.isVisible())
@ -134,25 +139,29 @@ public class LinkedElement {
new VerticalLine(ynet1, ynet1 + alpha, Collections.<Double>emptySet())
.drawU(ug.apply(UTranslate.dx(xLinkPos + network.magicDelta())));
drawCenter(ug, getTextBlockLink1(), xMiddle + network.magicDelta(), ynet1 + posLink1);
final TextBlock link = getTextBlockLink1();
drawCenter(ug, link, xMiddle + network.magicDelta(), ynet1 + posLink1);
final double seven = 9.0;
double x = xLinkPos - (conns.size() - 2) * seven / 2;
boolean first = true;
for (Entry<Network, TextBlock> ent : conns.entrySet()) {
for (Entry<Network, String> ent : conns.entrySet()) {
if (ent.getKey() == network)
continue;
final double ynet2 = ent.getKey().getY();
new VerticalLine(ynet1 + yMiddle + dimBox.getHeight() / 2, ynet2, skip)
.drawU(ug.apply(UTranslate.dx(x - ent.getKey().magicDelta())));
final TextBlock block = server.toTextBlock(SName.arrow, ent.getValue());
final double xtext;
if (first && conns.size() > 2)
xtext = x - ent.getValue().calculateDimension(stringBounder).getWidth() / 2;
xtext = x - block.calculateDimension(stringBounder).getWidth() / 2;
else
xtext = x;
drawCenter(ug, ent.getValue(), xtext - ent.getKey().magicDelta(), ynet2 - alpha / 2);
drawCenter(ug, block, xtext - ent.getKey().magicDelta(), ynet2 - alpha / 2);
x += seven;
first = false;
@ -161,21 +170,21 @@ public class LinkedElement {
}
private TextBlock getTextBlockLink1() {
return conns.get(network);
return server.toTextBlock(SName.arrow, conns.get(network));
}
private TextBlock link2() {
final int i = networks.indexOf(network);
if (i == networks.size() - 1)
if (i == networks.size() - 1)
return null;
return conns.get(networks.get(i + 1));
return server.toTextBlock(SName.arrow, conns.get(networks.get(i + 1)));
}
private void drawCenter(UGraphic ug, TextBlock block, double x, double y) {
if (block == null)
if (block == null)
return;
final XDimension2D dim = block.calculateDimension(ug.getStringBounder());
block.drawU(ug.apply(new UTranslate(x - dim.getWidth() / 2, y - dim.getHeight() / 2)));

View File

@ -36,10 +36,15 @@ package net.sourceforge.plantuml.nwdiag.next;
public class NwArray {
private final LinkedElement data[][];
private final NServerDraw data[][];
public NwArray(int lines, int cols) {
this.data = new LinkedElement[lines][cols];
this.data = new NServerDraw[lines][cols];
}
@Override
public String toString() {
return "lines=" + getNbLines() + " cols=" + getNbCols();
}
public int getNbLines() {
@ -50,15 +55,15 @@ public class NwArray {
return data[0].length;
}
public LinkedElement get(int i, int j) {
public NServerDraw get(int i, int j) {
return data[i][j];
}
public LinkedElement[] getLine(int i) {
public NServerDraw[] getLine(int i) {
return data[i];
}
public void set(int i, int j, LinkedElement value) {
public void set(int i, int j, NServerDraw value) {
data[i][j] = value;
}

View File

@ -129,7 +129,7 @@ public class TikzGraphics {
if (fillcolor.toColor(mapper).getAlpha() == 0)
return false;
return true;
}
@ -513,14 +513,20 @@ public class TikzGraphics {
sb.append(",dash pattern=" + dash);
sb.append("] ");
double lastx = 0;
double lasty = 0;
for (USegment seg : path) {
final USegmentType type = seg.getSegmentType();
final double coord[] = seg.getCoord();
if (type == USegmentType.SEG_MOVETO) {
sb.append(couple(coord[0] + x, coord[1] + y));
lastx = coord[0] + x;
lasty = coord[1] + y;
} else if (type == USegmentType.SEG_LINETO) {
sb.append(" -- ");
sb.append(couple(coord[0] + x, coord[1] + y));
lastx = coord[0] + x;
lasty = coord[1] + y;
} else if (type == USegmentType.SEG_QUADTO) {
throw new UnsupportedOperationException();
} else if (type == USegmentType.SEG_CUBICTO) {
@ -532,10 +538,27 @@ public class TikzGraphics {
sb.append(couple(coord[2] + x, coord[3] + y));
sb.append(" .. ");
sb.append(couple(coord[4] + x, coord[5] + y));
lastx = coord[4] + x;
lasty = coord[5] + y;
} else if (type == USegmentType.SEG_CLOSE) {
// Nothing
} else if (type == USegmentType.SEG_ARCTO) {
// Nothing
final double newx = coord[5] + x;
final double newy = coord[6] + y;
// if (newx > lastx && newy < lasty) {
// final int start = 180;
// final int end = 270;
// final String radius = format(coord[0]);
// sb.append(" arc(" + start + ":" + end + ":" + radius + "pt) ");
// }
sb.append(" -- ");
sb.append(couple(coord[5] + x, coord[6] + y));
lastx = newx;
lasty = newy;
} else {
Log.println("unknown4 " + seg);
}

View File

@ -37,6 +37,7 @@ package net.sourceforge.plantuml.ugraphic;
import static net.sourceforge.plantuml.utils.ObjectUtils.instanceOfAny;
import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.activitydiagram3.ftile.CenteredText;
import net.sourceforge.plantuml.awt.geom.XDimension2D;
import net.sourceforge.plantuml.graphic.SpecialText;
@ -62,6 +63,7 @@ public class LimitFinder extends UGraphicNo {
private final MinMaxMutable minmax;
private UClip clip;
private final FileFormat format;
public static LimitFinder create(StringBounder stringBounder, boolean initToZero) {
final LimitFinder result = new LimitFinder(stringBounder, new UTranslate(), MinMaxMutable.getEmpty(initToZero));
@ -72,6 +74,7 @@ public class LimitFinder extends UGraphicNo {
private LimitFinder(StringBounder stringBounder, UTranslate translate, MinMaxMutable minmax) {
super(stringBounder, translate);
this.minmax = minmax;
this.format = stringBounder.getNativeFormat();
}
private void addPoint(double x, double y) {

View File

@ -36,6 +36,7 @@ package net.sourceforge.plantuml.ugraphic.debug;
import java.util.Random;
import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.awt.geom.XDimension2D;
import net.sourceforge.plantuml.graphic.StringBounderRaw;
@ -60,4 +61,9 @@ public class StringBounderDebug extends StringBounderRaw {
return descent;
}
@Override
public FileFormat getNativeFormat() {
return FileFormat.PNG;
}
}

View File

@ -81,7 +81,7 @@ public class Version {
}
public static int beta() {
final int beta = 3;
final int beta = 4;
return beta;
}