v0.6.0 released! Weblate integration is complete. New icons (created for
weblate integration) now replace to old ugly ones for the notification area.
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<jardesc>
|
<jardesc>
|
||||||
<jar path="ATContentStudio/ATCS_v0.5.4.jar"/>
|
<jar path="ATContentStudio/ATCS_v0.6.0.jar"/>
|
||||||
<options buildIfNeeded="true" compress="true" descriptionLocation="/ATContentStudio/ATCS_JAR.jardesc" exportErrors="true" exportWarnings="true" includeDirectoryEntries="false" overwrite="false" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
|
<options buildIfNeeded="true" compress="true" descriptionLocation="/ATContentStudio/ATCS_JAR.jardesc" exportErrors="true" exportWarnings="true" includeDirectoryEntries="false" overwrite="false" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
|
||||||
<storedRefactorings deprecationInfo="true" structuralOnly="false"/>
|
<storedRefactorings deprecationInfo="true" structuralOnly="false"/>
|
||||||
<selectedProjects/>
|
<selectedProjects/>
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
</sealing>
|
</sealing>
|
||||||
</manifest>
|
</manifest>
|
||||||
<selectedElements exportClassFiles="true" exportJavaFiles="true" exportOutputFolder="false">
|
<selectedElements exportClassFiles="true" exportJavaFiles="true" exportOutputFolder="false">
|
||||||
|
<javaElement handleIdentifier="=ATContentStudio/siphash-zackehh\/src\/main\/java"/>
|
||||||
<javaElement handleIdentifier="=ATContentStudio/res"/>
|
<javaElement handleIdentifier="=ATContentStudio/res"/>
|
||||||
<javaElement handleIdentifier="=ATContentStudio/src"/>
|
<javaElement handleIdentifier="=ATContentStudio/src"/>
|
||||||
<javaElement handleIdentifier="=ATContentStudio/hacked-libtiled"/>
|
<javaElement handleIdentifier="=ATContentStudio/hacked-libtiled"/>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
!include MUI2.nsh
|
!include MUI2.nsh
|
||||||
|
|
||||||
!define VERSION "0.5.4"
|
!define VERSION "0.6.0"
|
||||||
!define TRAINER_VERSION "0.1.3"
|
!define TRAINER_VERSION "0.1.3"
|
||||||
!define JAVA_BIN "javaw"
|
!define JAVA_BIN "javaw"
|
||||||
|
|
||||||
@@ -92,6 +92,7 @@ Section install
|
|||||||
file "rsyntaxtextarea.jar"
|
file "rsyntaxtextarea.jar"
|
||||||
file "prefuse.jar"
|
file "prefuse.jar"
|
||||||
file "bsh-2.0b4.jar"
|
file "bsh-2.0b4.jar"
|
||||||
|
file "jsoup-1.10.2.jar"
|
||||||
|
|
||||||
SetOutPath $INSTDIR
|
SetOutPath $INSTDIR
|
||||||
|
|
||||||
@@ -120,6 +121,7 @@ Section uninstall
|
|||||||
Delete "$INSTDIR\lib\rsyntaxtextarea.jar"
|
Delete "$INSTDIR\lib\rsyntaxtextarea.jar"
|
||||||
Delete "$INSTDIR\lib\prefuse.jar"
|
Delete "$INSTDIR\lib\prefuse.jar"
|
||||||
Delete "$INSTDIR\lib\bsh-2.0b4.jar"
|
Delete "$INSTDIR\lib\bsh-2.0b4.jar"
|
||||||
|
Delete "$INSTDIR\lib\jsoup-1.10.2.jar"
|
||||||
RMDir "$INSTDIR\lib\"
|
RMDir "$INSTDIR\lib\"
|
||||||
Delete "$INSTDIR\ATCS.ico"
|
Delete "$INSTDIR\ATCS.ico"
|
||||||
Delete "$INSTDIR\ATCS.cmd"
|
Delete "$INSTDIR\ATCS.cmd"
|
||||||
|
|||||||
21
res/LICENSE.jsoup.txt
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
The MIT License
|
||||||
|
|
||||||
|
© 2009-2017, Jonathan Hedley <jonathan@hedley.net>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
@@ -19,14 +19,12 @@ import com.gpl.rpg.atcontentstudio.model.Workspace;
|
|||||||
import com.gpl.rpg.atcontentstudio.ui.StudioFrame;
|
import com.gpl.rpg.atcontentstudio.ui.StudioFrame;
|
||||||
import com.gpl.rpg.atcontentstudio.ui.WorkerDialog;
|
import com.gpl.rpg.atcontentstudio.ui.WorkerDialog;
|
||||||
import com.gpl.rpg.atcontentstudio.ui.WorkspaceSelector;
|
import com.gpl.rpg.atcontentstudio.ui.WorkspaceSelector;
|
||||||
import com.gpl.rpg.atcontentstudio.utils.HashUtils;
|
|
||||||
import com.zackehh.siphash.SipHash;
|
|
||||||
|
|
||||||
|
|
||||||
public class ATContentStudio {
|
public class ATContentStudio {
|
||||||
|
|
||||||
public static final String APP_NAME = "Andor's Trail Content Studio";
|
public static final String APP_NAME = "Andor's Trail Content Studio";
|
||||||
public static final String APP_VERSION = "v0.5.4";
|
public static final String APP_VERSION = "v0.6.0";
|
||||||
|
|
||||||
public static boolean STARTED = false;
|
public static boolean STARTED = false;
|
||||||
public static StudioFrame frame = null;
|
public static StudioFrame frame = null;
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 566 B |
|
Before Width: | Height: | Size: 278 B |
BIN
src/com/gpl/rpg/atcontentstudio/img/status_blue.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
src/com/gpl/rpg/atcontentstudio/img/status_green.png
Normal file
|
After Width: | Height: | Size: 1013 B |
BIN
src/com/gpl/rpg/atcontentstudio/img/status_orange.png
Normal file
|
After Width: | Height: | Size: 1023 B |
BIN
src/com/gpl/rpg/atcontentstudio/img/status_red.png
Normal file
|
After Width: | Height: | Size: 880 B |
BIN
src/com/gpl/rpg/atcontentstudio/img/status_unknown.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 481 B |
@@ -1,7 +1,6 @@
|
|||||||
package com.gpl.rpg.atcontentstudio.model;
|
package com.gpl.rpg.atcontentstudio.model;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -11,13 +10,9 @@ import java.util.LinkedHashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.swing.ComboBoxModel;
|
|
||||||
|
|
||||||
import org.json.simple.JSONObject;
|
import org.json.simple.JSONObject;
|
||||||
import org.json.simple.parser.JSONParser;
|
import org.json.simple.parser.JSONParser;
|
||||||
import org.json.simple.parser.ParseException;
|
|
||||||
|
|
||||||
import com.gpl.rpg.atcontentstudio.ATContentStudio;
|
|
||||||
import com.gpl.rpg.atcontentstudio.Notification;
|
import com.gpl.rpg.atcontentstudio.Notification;
|
||||||
import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter;
|
import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter;
|
||||||
|
|
||||||
@@ -41,10 +36,13 @@ public class WorkspaceSettings {
|
|||||||
public static Boolean DEFAULT_USE_SYS_IMG_EDITOR = false;
|
public static Boolean DEFAULT_USE_SYS_IMG_EDITOR = false;
|
||||||
public Setting<Boolean> useSystemDefaultImageEditor = new PrimitiveSetting<Boolean>("useSystemDefaultImageEditor", DEFAULT_USE_SYS_IMG_EDITOR);
|
public Setting<Boolean> useSystemDefaultImageEditor = new PrimitiveSetting<Boolean>("useSystemDefaultImageEditor", DEFAULT_USE_SYS_IMG_EDITOR);
|
||||||
public static String DEFAULT_IMG_EDITOR_COMMAND = "gimp";
|
public static String DEFAULT_IMG_EDITOR_COMMAND = "gimp";
|
||||||
public static String[] LANGUAGE_LIST = new String[]{null, "de", "ru", "pl", "fr", "it", "es", "nl", "uk", "ca", "sv", "pt", "pt_BR", "zh_Hant", "zh_Hans", "ja", "cs", "tr", "ko", "hu", "sl", "bg", "id", "fi", "th", "gl", "ms" ,"pa", "az"};
|
|
||||||
public Setting<String> imageEditorCommand = new PrimitiveSetting<String>("imageEditorCommand", DEFAULT_IMG_EDITOR_COMMAND);
|
public Setting<String> imageEditorCommand = new PrimitiveSetting<String>("imageEditorCommand", DEFAULT_IMG_EDITOR_COMMAND);
|
||||||
|
|
||||||
|
public static String[] LANGUAGE_LIST = new String[]{null, "de", "ru", "pl", "fr", "it", "es", "nl", "uk", "ca", "sv", "pt", "pt_BR", "zh_Hant", "zh_Hans", "ja", "cs", "tr", "ko", "hu", "sl", "bg", "id", "fi", "th", "gl", "ms" ,"pa", "az"};
|
||||||
public Setting<String> translatorLanguage = new NullDefaultPrimitiveSetting<String>("translatorLanguage");
|
public Setting<String> translatorLanguage = new NullDefaultPrimitiveSetting<String>("translatorLanguage");
|
||||||
|
public static Boolean DEFAULT_ALLOW_INTERNET = true;
|
||||||
|
public Setting<Boolean> useInternet = new PrimitiveSetting<Boolean>("useInternet", DEFAULT_ALLOW_INTERNET);
|
||||||
|
|
||||||
|
|
||||||
public List<Setting<? extends Object>> settings = new ArrayList<Setting<? extends Object>>();
|
public List<Setting<? extends Object>> settings = new ArrayList<Setting<? extends Object>>();
|
||||||
|
|
||||||
@@ -56,6 +54,7 @@ public class WorkspaceSettings {
|
|||||||
settings.add(useSystemDefaultImageEditor);
|
settings.add(useSystemDefaultImageEditor);
|
||||||
settings.add(imageEditorCommand);
|
settings.add(imageEditorCommand);
|
||||||
settings.add(translatorLanguage);
|
settings.add(translatorLanguage);
|
||||||
|
settings.add(useInternet);
|
||||||
file = new File(parent.baseFolder, FILENAME);
|
file = new File(parent.baseFolder, FILENAME);
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
load(file);
|
load(file);
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import com.gpl.rpg.atcontentstudio.Notification;
|
|||||||
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
|
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
|
||||||
import com.gpl.rpg.atcontentstudio.model.GameSource;
|
import com.gpl.rpg.atcontentstudio.model.GameSource;
|
||||||
import com.gpl.rpg.atcontentstudio.model.Project;
|
import com.gpl.rpg.atcontentstudio.model.Project;
|
||||||
import com.gpl.rpg.atcontentstudio.model.GameDataElement.State;
|
|
||||||
import com.gpl.rpg.atcontentstudio.model.gamedata.Requirement.RequirementType;
|
import com.gpl.rpg.atcontentstudio.model.gamedata.Requirement.RequirementType;
|
||||||
import com.gpl.rpg.atcontentstudio.model.maps.TMXMap;
|
import com.gpl.rpg.atcontentstudio.model.maps.TMXMap;
|
||||||
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
|
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import com.gpl.rpg.atcontentstudio.Notification;
|
|||||||
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
|
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
|
||||||
import com.gpl.rpg.atcontentstudio.model.GameSource;
|
import com.gpl.rpg.atcontentstudio.model.GameSource;
|
||||||
import com.gpl.rpg.atcontentstudio.model.Project;
|
import com.gpl.rpg.atcontentstudio.model.Project;
|
||||||
import com.gpl.rpg.atcontentstudio.model.GameDataElement.State;
|
|
||||||
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
|
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import com.gpl.rpg.atcontentstudio.Notification;
|
|||||||
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
|
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
|
||||||
import com.gpl.rpg.atcontentstudio.model.GameSource;
|
import com.gpl.rpg.atcontentstudio.model.GameSource;
|
||||||
import com.gpl.rpg.atcontentstudio.model.Project;
|
import com.gpl.rpg.atcontentstudio.model.Project;
|
||||||
import com.gpl.rpg.atcontentstudio.model.GameDataElement.State;
|
|
||||||
|
|
||||||
public class Item extends JSONElement {
|
public class Item extends JSONElement {
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import org.json.simple.parser.ParseException;
|
|||||||
import com.gpl.rpg.atcontentstudio.Notification;
|
import com.gpl.rpg.atcontentstudio.Notification;
|
||||||
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
|
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
|
||||||
import com.gpl.rpg.atcontentstudio.model.GameSource;
|
import com.gpl.rpg.atcontentstudio.model.GameSource;
|
||||||
import com.gpl.rpg.atcontentstudio.model.GameDataElement.State;
|
|
||||||
|
|
||||||
public class ItemCategory extends JSONElement {
|
public class ItemCategory extends JSONElement {
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import com.gpl.rpg.atcontentstudio.Notification;
|
|||||||
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
|
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
|
||||||
import com.gpl.rpg.atcontentstudio.model.GameSource;
|
import com.gpl.rpg.atcontentstudio.model.GameSource;
|
||||||
import com.gpl.rpg.atcontentstudio.model.Project;
|
import com.gpl.rpg.atcontentstudio.model.Project;
|
||||||
import com.gpl.rpg.atcontentstudio.model.GameDataElement.State;
|
|
||||||
|
|
||||||
public class NPC extends JSONElement {
|
public class NPC extends JSONElement {
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import org.json.simple.parser.ParseException;
|
|||||||
import com.gpl.rpg.atcontentstudio.Notification;
|
import com.gpl.rpg.atcontentstudio.Notification;
|
||||||
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
|
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
|
||||||
import com.gpl.rpg.atcontentstudio.model.GameSource;
|
import com.gpl.rpg.atcontentstudio.model.GameSource;
|
||||||
import com.gpl.rpg.atcontentstudio.model.GameDataElement.State;
|
|
||||||
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
|
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
|
||||||
|
|
||||||
public class Quest extends JSONElement {
|
public class Quest extends JSONElement {
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import java.awt.Image;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.FileSystems;
|
import java.nio.file.FileSystems;
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.nio.file.StandardWatchEventKinds;
|
import java.nio.file.StandardWatchEventKinds;
|
||||||
@@ -26,7 +25,6 @@ import com.gpl.rpg.atcontentstudio.model.Project;
|
|||||||
import com.gpl.rpg.atcontentstudio.model.Project.ResourceSet;
|
import com.gpl.rpg.atcontentstudio.model.Project.ResourceSet;
|
||||||
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
|
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
|
||||||
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
|
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
|
||||||
import com.gpl.rpg.atcontentstudio.model.sprites.SpriteSheetSet;
|
|
||||||
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
|
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
|
||||||
import com.gpl.rpg.atcontentstudio.utils.FileUtils;
|
import com.gpl.rpg.atcontentstudio.utils.FileUtils;
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import org.json.simple.parser.ParseException;
|
|||||||
import com.gpl.rpg.atcontentstudio.Notification;
|
import com.gpl.rpg.atcontentstudio.Notification;
|
||||||
import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter;
|
import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter;
|
||||||
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
|
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
|
||||||
import com.gpl.rpg.atcontentstudio.model.GameDataElement.State;
|
|
||||||
import com.gpl.rpg.atcontentstudio.model.GameSource;
|
import com.gpl.rpg.atcontentstudio.model.GameSource;
|
||||||
import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
|
import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
|
||||||
import com.gpl.rpg.atcontentstudio.model.Project;
|
import com.gpl.rpg.atcontentstudio.model.Project;
|
||||||
|
|||||||
@@ -75,6 +75,9 @@ public class AboutEditor extends Editor {
|
|||||||
"A slightly modified version of <a href=\"https://github.com/zackehh/siphash-java\">SipHash for Java</a> by Isaac Whitfield.<br/>" +
|
"A slightly modified version of <a href=\"https://github.com/zackehh/siphash-java\">SipHash for Java</a> by Isaac Whitfield.<br/>" +
|
||||||
"License: <a href=\"https://github.com/zackehh/siphash-java/blob/master/LICENSE\">MIT License</a><br/>" +
|
"License: <a href=\"https://github.com/zackehh/siphash-java/blob/master/LICENSE\">MIT License</a><br/>" +
|
||||||
"<br/>" +
|
"<br/>" +
|
||||||
|
"<a href=\"https://jsoup.org/\">jsoup</a> by Jonathan Hedley<br/>" +
|
||||||
|
"License: <a href=\"https://jsoup.org/license\">MIT License</a><br/>" +
|
||||||
|
"<br/>" +
|
||||||
"See the tabs below to find the full license text for each of these.<br/>" +
|
"See the tabs below to find the full license text for each of these.<br/>" +
|
||||||
"<br/>" +
|
"<br/>" +
|
||||||
"The Windows installer was created with:<br/>" +
|
"The Windows installer was created with:<br/>" +
|
||||||
@@ -125,6 +128,7 @@ public class AboutEditor extends Editor {
|
|||||||
editorTabsHolder.add("prefuse License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/license-prefuse.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
|
editorTabsHolder.add("prefuse License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/license-prefuse.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
|
||||||
editorTabsHolder.add("BeanShell License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.LGPLv3.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
|
editorTabsHolder.add("BeanShell License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.LGPLv3.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
|
||||||
editorTabsHolder.add("SipHash for Java License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.siphash-zackehh.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
|
editorTabsHolder.add("SipHash for Java License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.siphash-zackehh.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
|
||||||
|
editorTabsHolder.add("jsoup License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.jsoup.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
|
||||||
editorTabsHolder.add("ATCS License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.GPLv3.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
|
editorTabsHolder.add("ATCS License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.GPLv3.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -231,6 +231,27 @@ public class DefaultIcons {
|
|||||||
public static Image getZoomImage() { return getImage(ZOOM_RES); }
|
public static Image getZoomImage() { return getImage(ZOOM_RES); }
|
||||||
public static Image getZoomIcon() { return getIcon(ZOOM_RES); }
|
public static Image getZoomIcon() { return getIcon(ZOOM_RES); }
|
||||||
|
|
||||||
|
private static String STATUS_RED_RES = "/com/gpl/rpg/atcontentstudio/img/status_red.png";
|
||||||
|
public static Image getStatusRedImage() { return getImage(STATUS_RED_RES); }
|
||||||
|
public static Image getStatusRedIcon() { return getIcon(STATUS_RED_RES); }
|
||||||
|
|
||||||
|
private static String STATUS_ORANGE_RES = "/com/gpl/rpg/atcontentstudio/img/status_orange.png";
|
||||||
|
public static Image getStatusOrangeImage() { return getImage(STATUS_ORANGE_RES); }
|
||||||
|
public static Image getStatusOrangeIcon() { return getIcon(STATUS_ORANGE_RES); }
|
||||||
|
|
||||||
|
private static String STATUS_GREEN_RES = "/com/gpl/rpg/atcontentstudio/img/status_green.png";
|
||||||
|
public static Image getStatusGreenImage() { return getImage(STATUS_GREEN_RES); }
|
||||||
|
public static Image getStatusGreenIcon() { return getIcon(STATUS_GREEN_RES); }
|
||||||
|
|
||||||
|
private static String STATUS_BLUE_RES = "/com/gpl/rpg/atcontentstudio/img/status_blue.png";
|
||||||
|
public static Image getStatusBlueImage() { return getImage(STATUS_BLUE_RES); }
|
||||||
|
public static Image getStatusBlueIcon() { return getIcon(STATUS_BLUE_RES); }
|
||||||
|
|
||||||
|
private static String STATUS_UNKNOWN_RES = "/com/gpl/rpg/atcontentstudio/img/status_unknown.png";
|
||||||
|
public static Image getStatusUnknownImage() { return getImage(STATUS_UNKNOWN_RES); }
|
||||||
|
public static Image getStatusUnknownIcon() { return getIcon(STATUS_UNKNOWN_RES); }
|
||||||
|
|
||||||
|
|
||||||
private static Image getImage(String res) {
|
private static Image getImage(String res) {
|
||||||
if (imageCache.get(res) == null) {
|
if (imageCache.get(res) == null) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -121,12 +121,45 @@ public abstract class Editor extends JPanel implements ProjectElementListener {
|
|||||||
labelPane.setLayout(new JideBoxLayout(labelPane, JideBoxLayout.LINE_AXIS));
|
labelPane.setLayout(new JideBoxLayout(labelPane, JideBoxLayout.LINE_AXIS));
|
||||||
final JLabel translateLinkLabel = new JLabel(getWeblateLabelLink(initialValue));
|
final JLabel translateLinkLabel = new JLabel(getWeblateLabelLink(initialValue));
|
||||||
labelPane.add(translateLinkLabel, JideBoxLayout.FIX);
|
labelPane.add(translateLinkLabel, JideBoxLayout.FIX);
|
||||||
final JLabel translationStatus = new JLabel(" - Status: unknown - Retrieving...");
|
labelPane.add(new JLabel(" "), JideBoxLayout.FIX);
|
||||||
|
final JLabel translationStatus = new JLabel("Retrieving...");
|
||||||
|
translationStatus.setIcon(new ImageIcon(DefaultIcons.getStatusUnknownIcon()));
|
||||||
|
translationStatus.setToolTipText("Connecting to weblate...");
|
||||||
labelPane.add(translationStatus, JideBoxLayout.VARY);
|
labelPane.add(translationStatus, JideBoxLayout.VARY);
|
||||||
new Thread() {
|
new Thread() {
|
||||||
public void run() {
|
public void run() {
|
||||||
WeblateIntegration.WeblateTranslationUnit unit = WeblateIntegration.getTranslationUnit(initialValue);
|
WeblateIntegration.WeblateTranslationUnit unit = WeblateIntegration.getTranslationUnit(initialValue);
|
||||||
translationStatus.setText(" - Status: "+unit.status.toString()+" - "+unit.translatedText);
|
switch (unit.status) {
|
||||||
|
case absent:
|
||||||
|
translationStatus.setIcon(new ImageIcon(DefaultIcons.getStatusRedIcon()));
|
||||||
|
translationStatus.setToolTipText("This string isn't managed by weblate (yet).");
|
||||||
|
break;
|
||||||
|
case done:
|
||||||
|
translationStatus.setIcon(new ImageIcon(DefaultIcons.getStatusGreenIcon()));
|
||||||
|
translationStatus.setToolTipText("This string is translated on weblate.");
|
||||||
|
break;
|
||||||
|
case fuzzy:
|
||||||
|
translationStatus.setIcon(new ImageIcon(DefaultIcons.getStatusOrangeIcon()));
|
||||||
|
translationStatus.setToolTipText("This string is translated on weblate, but needs a review.");
|
||||||
|
break;
|
||||||
|
case notTranslated:
|
||||||
|
translationStatus.setIcon(new ImageIcon(DefaultIcons.getStatusRedIcon()));
|
||||||
|
translationStatus.setToolTipText("This string isn't translated in your language on weblate yet.");
|
||||||
|
break;
|
||||||
|
case warning:
|
||||||
|
translationStatus.setIcon(new ImageIcon(DefaultIcons.getStatusOrangeIcon()));
|
||||||
|
translationStatus.setToolTipText("This string is translated on weblate, but triggered some weblate checks.");
|
||||||
|
break;
|
||||||
|
case error:
|
||||||
|
translationStatus.setIcon(new ImageIcon(DefaultIcons.getStatusRedIcon()));
|
||||||
|
translationStatus.setToolTipText("Cannot connect to weblate. Check internet connection and firewall settings.");
|
||||||
|
break;
|
||||||
|
case notAllowed:
|
||||||
|
translationStatus.setIcon(new ImageIcon(DefaultIcons.getStatusBlueIcon()));
|
||||||
|
translationStatus.setToolTipText("You have not allowed ATCS to access to internet. You can change this in the workspace settings.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
translationStatus.setText(unit.translatedText);
|
||||||
};
|
};
|
||||||
}.start();
|
}.start();
|
||||||
pane.add(labelPane, JideBoxLayout.FIX);
|
pane.add(labelPane, JideBoxLayout.FIX);
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import java.awt.event.ActionEvent;
|
|||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.ItemEvent;
|
import java.awt.event.ItemEvent;
|
||||||
import java.awt.event.ItemListener;
|
import java.awt.event.ItemListener;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,11 @@ package com.gpl.rpg.atcontentstudio.ui;
|
|||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
@@ -30,22 +27,13 @@ public class NotificationsPane extends JList {
|
|||||||
|
|
||||||
private static final long serialVersionUID = -1100364214372392608L;
|
private static final long serialVersionUID = -1100364214372392608L;
|
||||||
|
|
||||||
public static final String success_img_name = "/com/gpl/rpg/atcontentstudio/img/success.png";
|
|
||||||
public static final String info_img_name = "/com/gpl/rpg/atcontentstudio/img/info.png";
|
|
||||||
public static final String warn_img_name = "/com/gpl/rpg/atcontentstudio/img/warn.png";
|
|
||||||
public static final String error_img_name = "/com/gpl/rpg/atcontentstudio/img/error.png";
|
|
||||||
|
|
||||||
public static final Map<Notification.Type, Icon> icons = new LinkedHashMap<Notification.Type, Icon>(Notification.Type.values().length);
|
public static final Map<Notification.Type, Icon> icons = new LinkedHashMap<Notification.Type, Icon>(Notification.Type.values().length);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
icons.put(Notification.Type.SUCCESS, new ImageIcon(DefaultIcons.getStatusGreenIcon()));
|
||||||
icons.put(Notification.Type.SUCCESS, new ImageIcon(ImageIO.read(NotificationsPane.class.getResourceAsStream(success_img_name))));
|
icons.put(Notification.Type.INFO, new ImageIcon(DefaultIcons.getStatusBlueIcon()));
|
||||||
icons.put(Notification.Type.INFO, new ImageIcon(ImageIO.read(NotificationsPane.class.getResourceAsStream(info_img_name))));
|
icons.put(Notification.Type.WARN, new ImageIcon(DefaultIcons.getStatusOrangeIcon()));
|
||||||
icons.put(Notification.Type.WARN, new ImageIcon(ImageIO.read(NotificationsPane.class.getResourceAsStream(warn_img_name))));
|
icons.put(Notification.Type.ERROR, new ImageIcon(DefaultIcons.getStatusRedIcon()));
|
||||||
icons.put(Notification.Type.ERROR, new ImageIcon(ImageIO.read(NotificationsPane.class.getResourceAsStream(error_img_name))));
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import java.awt.event.ActionEvent;
|
|||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import java.awt.Toolkit;
|
|||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import java.util.LinkedHashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentSkipListSet;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ public class WorkspaceSettingsEditor extends JDialog {
|
|||||||
|
|
||||||
JCheckBox translatorModeBox;
|
JCheckBox translatorModeBox;
|
||||||
JComboBox<String> translatorLanguagesBox;
|
JComboBox<String> translatorLanguagesBox;
|
||||||
|
JCheckBox useInternetBox;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -167,15 +168,20 @@ public class WorkspaceSettingsEditor extends JDialog {
|
|||||||
translatorLanguagesBox = new JComboBox<String>(WorkspaceSettings.LANGUAGE_LIST);
|
translatorLanguagesBox = new JComboBox<String>(WorkspaceSettings.LANGUAGE_LIST);
|
||||||
langPane.add(translatorLanguagesBox);
|
langPane.add(translatorLanguagesBox);
|
||||||
pane.add(langPane, JideBoxLayout.FIX);
|
pane.add(langPane, JideBoxLayout.FIX);
|
||||||
|
|
||||||
|
pane.add(new JLabel("If your language isn't here, complain on the forums at https://andorstrail.com/"), JideBoxLayout.FIX);
|
||||||
|
|
||||||
|
useInternetBox = new JCheckBox("Allow connecting to internet to retrieve data from weblate.");
|
||||||
|
pane.add(useInternetBox, JideBoxLayout.FIX);
|
||||||
|
|
||||||
translatorModeBox.addActionListener(new ActionListener() {
|
translatorModeBox.addActionListener(new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
translatorLanguagesBox.setEnabled(translatorModeBox.isSelected());
|
translatorLanguagesBox.setEnabled(translatorModeBox.isSelected());
|
||||||
|
useInternetBox.setEnabled(translatorModeBox.isSelected());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
pane.add(new JLabel("If your language isn't here, complain on the forums at https://andorstrail.com/"), JideBoxLayout.FIX);
|
|
||||||
|
|
||||||
return pane;
|
return pane;
|
||||||
}
|
}
|
||||||
@@ -194,10 +200,15 @@ public class WorkspaceSettingsEditor extends JDialog {
|
|||||||
if (settings.translatorLanguage.getCurrentValue() != null) {
|
if (settings.translatorLanguage.getCurrentValue() != null) {
|
||||||
translatorModeBox.setSelected(true);
|
translatorModeBox.setSelected(true);
|
||||||
translatorLanguagesBox.setSelectedItem(settings.translatorLanguage.getCurrentValue());
|
translatorLanguagesBox.setSelectedItem(settings.translatorLanguage.getCurrentValue());
|
||||||
|
translatorLanguagesBox.setEnabled(true);
|
||||||
|
useInternetBox.setEnabled(true);
|
||||||
} else {
|
} else {
|
||||||
translatorModeBox.setSelected(false);
|
translatorModeBox.setSelected(false);
|
||||||
translatorLanguagesBox.setSelectedItem(null);
|
translatorLanguagesBox.setSelectedItem(null);
|
||||||
|
translatorLanguagesBox.setEnabled(false);
|
||||||
|
useInternetBox.setEnabled(false);
|
||||||
}
|
}
|
||||||
|
useInternetBox.setSelected(settings.useInternet.getCurrentValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pushToModel() {
|
public void pushToModel() {
|
||||||
@@ -214,6 +225,7 @@ public class WorkspaceSettingsEditor extends JDialog {
|
|||||||
} else {
|
} else {
|
||||||
settings.translatorLanguage.resetDefault();
|
settings.translatorLanguage.resetDefault();
|
||||||
}
|
}
|
||||||
|
settings.useInternet.setCurrentValue(useInternetBox.isSelected());
|
||||||
settings.save();
|
settings.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import java.awt.Dimension;
|
|||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import java.awt.Dimension;
|
|||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.gpl.rpg.atcontentstudio.ui.tools;
|
package com.gpl.rpg.atcontentstudio.ui.tools;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.gpl.rpg.atcontentstudio.ui.tools;
|
package com.gpl.rpg.atcontentstudio.ui.tools;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import java.io.FileWriter;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.file.CopyOption;
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
|||||||
@@ -45,51 +45,57 @@ public class WeblateIntegration {
|
|||||||
public static String getWeblateLabelURI(String text) {
|
public static String getWeblateLabelURI(String text) {
|
||||||
return "https://hosted.weblate.org/translate/andors-trail/game-content/"+Workspace.activeWorkspace.settings.translatorLanguage.getCurrentValue()+"/?checksum="+weblateHash(text, "");
|
return "https://hosted.weblate.org/translate/andors-trail/game-content/"+Workspace.activeWorkspace.settings.translatorLanguage.getCurrentValue()+"/?checksum="+weblateHash(text, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class WeblateTranslationUnit {
|
public static class WeblateTranslationUnit {
|
||||||
public enum Status {
|
public enum Status {
|
||||||
absent, notTranslated, warning, fuzzy, done
|
notAllowed, error, absent, notTranslated, warning, fuzzy, done
|
||||||
}
|
}
|
||||||
|
|
||||||
public Status status;
|
public Status status;
|
||||||
public String translatedText;
|
public String translatedText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WeblateTranslationUnit getTranslationUnit(String text) {
|
public static WeblateTranslationUnit getTranslationUnit(String text) {
|
||||||
WeblateTranslationUnit unit = new WeblateTranslationUnit();
|
WeblateTranslationUnit unit = new WeblateTranslationUnit();
|
||||||
unit.status = Status.absent;
|
if (!Workspace.activeWorkspace.settings.useInternet.getCurrentValue()) {
|
||||||
unit.translatedText = "Cannot find this translated on weblate";
|
unit.status = Status.notAllowed;
|
||||||
String hash = weblateHash(text, "");
|
unit.translatedText = "Allow internet connection in the workspace settings to get translation status";
|
||||||
try {
|
} else {
|
||||||
Document wlDoc = Jsoup.connect(getWeblateLabelURI(text)).get();
|
unit.status = Status.absent;
|
||||||
Element textArea = wlDoc.getElementById("id_"+hash+"_0");
|
unit.translatedText = "Cannot find this on weblate";
|
||||||
if (textArea != null) {
|
String hash = weblateHash(text, "");
|
||||||
String trans = textArea.text();
|
try {
|
||||||
if (trans != null) {
|
Document wlDoc = Jsoup.connect(getWeblateLabelURI(text)).get();
|
||||||
unit.translatedText = trans.trim();
|
Element textArea = wlDoc.getElementById("id_"+hash+"_0");
|
||||||
if (unit.translatedText.isEmpty()) {
|
if (textArea != null) {
|
||||||
unit.translatedText = "Not yet translated";
|
String trans = textArea.text();
|
||||||
unit.status = Status.notTranslated;
|
if (trans != null) {
|
||||||
|
unit.translatedText = trans.trim();
|
||||||
|
if (unit.translatedText.isEmpty()) {
|
||||||
|
unit.translatedText = "Not yet translated";
|
||||||
|
unit.status = Status.notTranslated;
|
||||||
|
} else {
|
||||||
|
unit.status = Status.done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Element fuzzyBox = wlDoc.getElementById("id_"+hash+"_fuzzy");
|
||||||
|
if (fuzzyBox != null && fuzzyBox.hasAttr("checked")) {
|
||||||
|
if ("checked".equals(fuzzyBox.attr("checked"))) {
|
||||||
|
unit.status = Status.fuzzy;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
unit.status = Status.done;
|
Elements dangerZone = wlDoc.getElementsByAttributeValue("class", "panel panel-danger");
|
||||||
}
|
if (dangerZone != null && !dangerZone.isEmpty()) {
|
||||||
}
|
unit.status = Status.warning;
|
||||||
Element fuzzyBox = wlDoc.getElementById("id_"+hash+"_fuzzy");
|
}
|
||||||
if (fuzzyBox != null && fuzzyBox.hasAttr("checked")) {
|
|
||||||
if ("checked".equals(fuzzyBox.attr("checked"))) {
|
|
||||||
unit.status = Status.fuzzy;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Elements dangerZone = wlDoc.getElementsByAttributeValue("class", "panel panel-danger");
|
|
||||||
if (dangerZone != null && !dangerZone.isEmpty()) {
|
|
||||||
unit.status = Status.warning;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
unit.status = Status.error;
|
||||||
|
unit.translatedText = "Cannot connect to weblate: "+e.getMessage();
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return unit;
|
return unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||