Index: lams_tool_larsrc/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -re4eb88025154e19407aa4f68bf880fd8b6b06711 -rba64868d96bcde6a6de9afca8b58a32bd25085ff --- lams_tool_larsrc/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision e4eb88025154e19407aa4f68bf880fd8b6b06711) +++ lams_tool_larsrc/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision ba64868d96bcde6a6de9afca8b58a32bd25085ff) @@ -111,7 +111,7 @@ define.later.message = Please wait for the instructor to complete the contents of this activity. message.monitoring.summary.no.resource.for.group = No resource available for this group. button.try.again = Try again -open.in.new.window = Open URL in pop-up +open.in.new.window = Open in new window label.up = Move Up label.down = Move down label.monitoring.heading.access = Learners list Index: lams_tool_larsrc/conf/language/lams/ApplicationResources_en_AU.properties =================================================================== diff -u -re4eb88025154e19407aa4f68bf880fd8b6b06711 -rba64868d96bcde6a6de9afca8b58a32bd25085ff --- lams_tool_larsrc/conf/language/lams/ApplicationResources_en_AU.properties (.../ApplicationResources_en_AU.properties) (revision e4eb88025154e19407aa4f68bf880fd8b6b06711) +++ lams_tool_larsrc/conf/language/lams/ApplicationResources_en_AU.properties (.../ApplicationResources_en_AU.properties) (revision ba64868d96bcde6a6de9afca8b58a32bd25085ff) @@ -111,7 +111,7 @@ define.later.message = Please wait for the instructor to complete the contents of this activity. message.monitoring.summary.no.resource.for.group = No resource available for this group. button.try.again = Try again -open.in.new.window = Open URL in pop-up +open.in.new.window = Open in new window label.up = Move Up label.down = Move down label.monitoring.heading.access = Learners list Index: lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/ResourceConstants.java =================================================================== diff -u -r8ce4c8dc7ae724fbaca90e665060f93d4d0552a7 -rba64868d96bcde6a6de9afca8b58a32bd25085ff --- lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/ResourceConstants.java (.../ResourceConstants.java) (revision 8ce4c8dc7ae724fbaca90e665060f93d4d0552a7) +++ lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/ResourceConstants.java (.../ResourceConstants.java) (revision ba64868d96bcde6a6de9afca8b58a32bd25085ff) @@ -86,6 +86,10 @@ public static final String ATTR_RESOURCE_REVIEW_URL = "resourceItemReviewUrl"; + public static final String ATTR_ENCODED_RESOURCE_REVIEW_URL = "encodedResourceItemReviewUrl"; + + public static final String ATTR_IS_DOWNLOAD = "isDownload"; + public static final String ATTR_RESOURCE = "resource"; public static final String ATTR_RUN_AUTO = "runAuto"; @@ -123,9 +127,9 @@ public static final String ATTR_IS_GROUPED_ACTIVITY = "isGroupedActivity"; public static final String ATTR_IS_URL_ITEM_TYPE = "isUrlItemType"; - + public static final String ATTR_ALLOW_COMMENTS = "allowComments"; - + public static final String ATTR_COMPLETED_SUFFICIENT_TO_FINISH = "hasCompletedMinNumber"; // error message keys Index: lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/dbupdates/patch20220211.sql =================================================================== diff -u --- lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/dbupdates/patch20220211.sql (revision 0) +++ lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/dbupdates/patch20220211.sql (revision ba64868d96bcde6a6de9afca8b58a32bd25085ff) @@ -0,0 +1,14 @@ +-- Turn off autocommit, so nothing is committed if there is an error +SET AUTOCOMMIT = 0; +SET FOREIGN_KEY_CHECKS=0; +-- Put all sql statements below here + +-- LDEV-5287 Remove open URL in new window option +ALTER TABLE tl_larsrc11_resource_item DROP COLUMN open_url_new_window; + +-- Put all sql statements above here + +-- If there were no errors, commit and restore autocommit to on +COMMIT; +SET AUTOCOMMIT = 1; +SET FOREIGN_KEY_CHECKS=1; Index: lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/model/ResourceItem.java =================================================================== diff -u -r1ee503e3d0e0228ea8a45025fddf15d9623c0377 -rba64868d96bcde6a6de9afca8b58a32bd25085ff --- lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/model/ResourceItem.java (.../ResourceItem.java) (revision 1ee503e3d0e0228ea8a45025fddf15d9623c0377) +++ lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/model/ResourceItem.java (.../ResourceItem.java) (revision ba64868d96bcde6a6de9afca8b58a32bd25085ff) @@ -60,7 +60,7 @@ @Column @GeneratedValue(strategy = GenerationType.IDENTITY) private Long uid; - + // Resource Type:1=URL,2=File,3=Website,4=Learning Object @Column(name = "item_type") private short type; @@ -74,9 +74,6 @@ @Column private String url; - @Column(name = "open_url_new_window") - private boolean openUrlNewWindow; - @Column(name = "ims_schema") private String imsSchema; @@ -108,20 +105,20 @@ @Column(name = "is_hide") private boolean isHide; - + @Column(name = "create_by_author") private boolean isCreateByAuthor; @Column(name = "create_date") private Date createDate; - + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "create_by") private ResourceUser createBy; - + @Column(name = "is_allow_rating") private boolean allowRating; - + @Column(name = "is_allow_comments") private boolean allowComments; @@ -300,14 +297,6 @@ this.fileName = name; } - public boolean isOpenUrlNewWindow() { - return openUrlNewWindow; - } - - public void setOpenUrlNewWindow(boolean openUrlNewWindow) { - this.openUrlNewWindow = openUrlNewWindow; - } - public Integer getOrderId() { return orderId; } @@ -341,11 +330,11 @@ } public boolean isAllowComments() { - return allowComments; + return allowComments; } public void setAllowComments(boolean allowComments) { - this.allowComments = allowComments; + this.allowComments = allowComments; } @Override Index: lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/service/ResourceServiceImpl.java =================================================================== diff -u -r8ce4c8dc7ae724fbaca90e665060f93d4d0552a7 -rba64868d96bcde6a6de9afca8b58a32bd25085ff --- lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/service/ResourceServiceImpl.java (.../ResourceServiceImpl.java) (revision 8ce4c8dc7ae724fbaca90e665060f93d4d0552a7) +++ lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/service/ResourceServiceImpl.java (.../ResourceServiceImpl.java) (revision ba64868d96bcde6a6de9afca8b58a32bd25085ff) @@ -1276,7 +1276,6 @@ item.setFileVersionId(JsonUtil.optLong(itemData, "crVersionId")); item.setImsSchema(JsonUtil.optString(itemData, "imsSchema")); item.setOrganizationXml(JsonUtil.optString(itemData, "organizationXml")); - item.setOpenUrlNewWindow(JsonUtil.optBoolean(itemData, "openUrlNewWindow", Boolean.FALSE)); item.setUrl(JsonUtil.optString(itemData, "url")); ArrayNode instructionStrings = JsonUtil.optArray(itemData, "instructions"); Index: lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/web/controller/AuthoringController.java =================================================================== diff -u -r92525f17be9db4e57a8551ff92d004f319fb4b73 -rba64868d96bcde6a6de9afca8b58a32bd25085ff --- lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/web/controller/AuthoringController.java (.../AuthoringController.java) (revision 92525f17be9db4e57a8551ff92d004f319fb4b73) +++ lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/web/controller/AuthoringController.java (.../AuthoringController.java) (revision ba64868d96bcde6a6de9afca8b58a32bd25085ff) @@ -695,7 +695,6 @@ form.setDescription(item.getDescription()); form.setTitle(item.getTitle()); form.setUrl(item.getUrl()); - form.setOpenUrlNewWindow(item.isOpenUrlNewWindow()); form.setAllowRating(item.isAllowRating()); form.setAllowComments(item.isAllowComments()); if (itemIdx >= 0) { @@ -822,9 +821,6 @@ if (type == ResourceConstants.RESOURCE_TYPE_URL) { item.setUrl(itemForm.getUrl()); } - if (type == ResourceConstants.RESOURCE_TYPE_URL || type == ResourceConstants.RESOURCE_TYPE_FILE) { - item.setOpenUrlNewWindow(itemForm.isOpenUrlNewWindow()); - } item.setDescription(itemForm.getDescription()); // if it's a new item, add it to resourceList Index: lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/web/controller/LearningController.java =================================================================== diff -u -r586c8780429a9489900952ef8ed3156ea0aac464 -rba64868d96bcde6a6de9afca8b58a32bd25085ff --- lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/web/controller/LearningController.java (.../LearningController.java) (revision 586c8780429a9489900952ef8ed3156ea0aac464) +++ lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/web/controller/LearningController.java (.../LearningController.java) (revision ba64868d96bcde6a6de9afca8b58a32bd25085ff) @@ -397,13 +397,11 @@ request.setAttribute("errorMap", errorMap); return "pages/learning/addurl"; } - item.setOpenUrlNewWindow(resourceItemForm.isOpenUrlNewWindow()); } else { throw new ServletException("No file uploaded"); } } else if (type == ResourceConstants.RESOURCE_TYPE_URL) { item.setUrl(resourceItemForm.getUrl()); - item.setOpenUrlNewWindow(resourceItemForm.isOpenUrlNewWindow()); } // save and update session ResourceSession resSession = resourceService.getResourceSessionBySessionId(sessionId); Index: lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/web/controller/ViewItemController.java =================================================================== diff -u -r8ce4c8dc7ae724fbaca90e665060f93d4d0552a7 -rba64868d96bcde6a6de9afca8b58a32bd25085ff --- lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/web/controller/ViewItemController.java (.../ViewItemController.java) (revision 8ce4c8dc7ae724fbaca90e665060f93d4d0552a7) +++ lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/web/controller/ViewItemController.java (.../ViewItemController.java) (revision ba64868d96bcde6a6de9afca8b58a32bd25085ff) @@ -23,19 +23,19 @@ package org.lamsfoundation.lams.tool.rsrc.web.controller; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; -import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.commons.lang.math.NumberUtils; -import org.apache.log4j.Logger; import org.lamsfoundation.lams.tool.ToolAccessMode; import org.lamsfoundation.lams.tool.rsrc.ResourceConstants; import org.lamsfoundation.lams.tool.rsrc.dto.InstructionNavDTO; @@ -44,6 +44,8 @@ import org.lamsfoundation.lams.tool.rsrc.service.IResourceService; import org.lamsfoundation.lams.tool.rsrc.util.ResourceItemComparator; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +import org.lamsfoundation.lams.util.Configuration; +import org.lamsfoundation.lams.util.ConfigurationKeys; import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.web.session.SessionManager; import org.lamsfoundation.lams.web.util.AttributeNames; @@ -54,17 +56,17 @@ @Controller public class ViewItemController { - private static final Logger log = Logger.getLogger(ViewItemController.class); - @Autowired private IResourceService resourceService; /** * Display main frame to display instrcution and item content. + * + * @throws UnsupportedEncodingException */ @SuppressWarnings("unchecked") @RequestMapping("/reviewItem") - private String reviewItem(HttpServletRequest request) { + private String reviewItem(HttpServletRequest request) throws UnsupportedEncodingException { SessionMap sessionMap = null; String sessionMapID = WebUtil.readStrParam(request, ResourceConstants.ATTR_SESSION_MAP_ID, true); @@ -75,7 +77,7 @@ } else { sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); } - + String mode = request.getParameter(AttributeNames.ATTR_MODE); ResourceItem item = getResourceItem(request, sessionMap, mode); @@ -95,11 +97,16 @@ if (item.getType() == ResourceConstants.RESOURCE_TYPE_LEARNING_OBJECT) { sessionMap.put(ResourceConstants.ATT_LEARNING_OBJECT, item); } - // set url to content frame - int itemIdx = NumberUtils.stringToInt(request.getParameter(ResourceConstants.PARAM_ITEM_INDEX)); - request.setAttribute(ResourceConstants.ATTR_RESOURCE_REVIEW_URL, - getReviewUrl(request, item, sessionMapID, mode, itemIdx)); + Integer itemIdx = WebUtil.readIntParam(request, ResourceConstants.PARAM_ITEM_INDEX, true); + String reviewUrl = getReviewUrl(item, sessionMapID); + request.setAttribute(ResourceConstants.ATTR_RESOURCE_REVIEW_URL, reviewUrl); + if (item.getType() == ResourceConstants.RESOURCE_TYPE_URL) { + request.setAttribute(ResourceConstants.ATTR_ENCODED_RESOURCE_REVIEW_URL, + URLEncoder.encode(reviewUrl, "UTF-8")); + } + request.setAttribute(ResourceConstants.ATTR_IS_DOWNLOAD, item.getType() == ResourceConstants.RESOURCE_TYPE_FILE + || item.getType() == ResourceConstants.RESOURCE_TYPE_WEBSITE); request.setAttribute(ResourceConstants.ATTR_ALLOW_COMMENTS, item.isAllowComments()); @@ -115,7 +122,7 @@ } /** - * Return next instrucion to page. It need four input parameters, mode, itemIndex or itemUid, and insIdx. + * Return next instruction to page. It need four input parameters, mode, itemIndex or itemUid, and insIdx. */ @RequestMapping("/nextInstruction") private String nextInstruction(HttpServletRequest request) { @@ -130,8 +137,10 @@ return "error"; } - int currIns = NumberUtils.stringToInt(request.getParameter(ResourceConstants.PARAM_CURRENT_INSTRUCTION_INDEX), - 0); + Integer currIns = WebUtil.readIntParam(request, ResourceConstants.PARAM_CURRENT_INSTRUCTION_INDEX, true); + if (currIns == null) { + currIns = 0; + } Set instructions = item.getItemInstructions(); InstructionNavDTO navDto = new InstructionNavDTO(); @@ -164,30 +173,6 @@ return "pages/itemreview/instructionsnav"; } - /** - * Open url or file in a popup window page. - */ - @RequestMapping("/openUrlPopup") - private String openUrlPopup(HttpServletRequest request) { - String mode = request.getParameter(AttributeNames.ATTR_MODE); - - String sessionMapID = WebUtil.readStrParam(request, ResourceConstants.ATTR_SESSION_MAP_ID); - SessionMap sessionMap = (SessionMap) request.getSession() - .getAttribute(sessionMapID); - - ResourceItem item = getResourceItem(request, sessionMap, mode); - - boolean isUrlItemType = item.getType() == ResourceConstants.RESOURCE_TYPE_URL; - request.setAttribute(ResourceConstants.ATTR_IS_URL_ITEM_TYPE, isUrlItemType); - - String popupUrl = (isUrlItemType) ? item.getUrl() - : "/download/?uuid=" + item.getFileUuid() + "&preferDownload=false"; - request.setAttribute(ResourceConstants.PARAM_OPEN_URL_POPUP, popupUrl); - - request.setAttribute(ResourceConstants.PARAM_TITLE, item.getTitle()); - return "pages/itemreview/openurl"; - } - // ************************************************************************************* // Private methods // ************************************************************************************* @@ -216,86 +201,35 @@ return item; } - private static Pattern usePopupButtonForURL = Pattern.compile("wikipedia|google", - Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE); private static Pattern protocolExists = Pattern.compile("http://|https://|ftp://|nntp://", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE); - private static Pattern httpPattern = Pattern.compile("http://", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE); public static final String DEFAULT_PROTOCOL = "http://"; public static final String HTTPS_SCHEME = "https"; - private Object getReviewUrl(HttpServletRequest request, ResourceItem item, String sessionMapID, String mode, - int itemIdx) { - short type = item.getType(); + private String getReviewUrl(ResourceItem item, String sessionMapID) { String url = null; - switch (type) { + switch (item.getType()) { case ResourceConstants.RESOURCE_TYPE_URL: // protocol missing? Assume http. Must do before the popup checks otherwise LDEV-4503 case may be missed. url = item.getUrl(); if (!protocolExists.matcher(url).find()) { url = DEFAULT_PROTOCOL + url; } - - // check all three cases that trigger popup - first is set in authoring - boolean usePopup = item.isOpenUrlNewWindow(); - // See LDEV-4503 regarding https/http issues - if (!usePopup) { - String serverScheme = request.getScheme(); - usePopup = HTTPS_SCHEME.equalsIgnoreCase(serverScheme) && httpPattern.matcher(url).find(); - } - // See LDEV-1736 regarding wikipedia regex - if (!usePopup) { - Matcher matcher = usePopupButtonForURL.matcher(url); - usePopup = matcher.find(); - } - - if (usePopup) { - url = constructUrlOpenInNewWindow(item, sessionMapID, mode, itemIdx); - } break; - case ResourceConstants.RESOURCE_TYPE_FILE: - if (item.isOpenUrlNewWindow()) { - url = constructUrlOpenInNewWindow(item, sessionMapID, mode, itemIdx); - } else { - url = "/download/?uuid=" + item.getFileUuid() + "&preferDownload=false"; - } - break; - case ResourceConstants.RESOURCE_TYPE_WEBSITE: - url = "/download/?uuid=" + item.getFileUuid() + "&preferDownload=false"; + url = "/download/?uuid=" + item.getFileUuid() + "&preferDownload=true"; break; case ResourceConstants.RESOURCE_TYPE_LEARNING_OBJECT: - url = "/pages/learningobj/mainframe.jsp?sessionMapID=" + sessionMapID; + url = Configuration.get(ConfigurationKeys.SERVER_URL) + "pages/learningobj/mainframe.jsp?sessionMapID=" + + sessionMapID; break; } return url; } /** - * Creates url for opening in a new window depending whether it's authoring environment or not. - * - * @param item - * @param sessionMapID - * @param mode - * @param itemIdx - * @return - */ - private String constructUrlOpenInNewWindow(ResourceItem item, String sessionMapID, String mode, int itemIdx) { - String url; - if (ResourceConstants.MODE_AUTHOR_SESSION.equals(mode)) { - url = "/openUrlPopup.do?" + AttributeNames.ATTR_MODE + "=" + mode + "&" + ResourceConstants.PARAM_ITEM_INDEX - + "=" + itemIdx + "&" + ResourceConstants.ATTR_SESSION_MAP_ID + "=" + sessionMapID; - } else { - url = "/openUrlPopup.do?" + ResourceConstants.PARAM_RESOURCE_ITEM_UID + "=" + item.getUid() + "&" - + ResourceConstants.ATTR_SESSION_MAP_ID + "=" + sessionMapID; - } - - return url; - } - - /** * List save current resource items. * * @param request Index: lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/web/form/ResourceItemForm.java =================================================================== diff -u -ra07430557603483e95a40ae22062e79b68a37778 -rba64868d96bcde6a6de9afca8b58a32bd25085ff --- lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/web/form/ResourceItemForm.java (.../ResourceItemForm.java) (revision a07430557603483e95a40ae22062e79b68a37778) +++ lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/web/form/ResourceItemForm.java (.../ResourceItemForm.java) (revision ba64868d96bcde6a6de9afca8b58a32bd25085ff) @@ -39,7 +39,6 @@ private short itemType; private String description; private String url; - private boolean openUrlNewWindow; //flag of this item has attachment or not private boolean hasFile; private Long fileUuid; @@ -129,14 +128,6 @@ this.hasFile = hasFile; } - public boolean isOpenUrlNewWindow() { - return openUrlNewWindow; - } - - public void setOpenUrlNewWindow(boolean openUrlNewWindow) { - this.openUrlNewWindow = openUrlNewWindow; - } - public String getSessionMapID() { return sessionMapID; } Index: lams_tool_larsrc/web/pages/authoring/parts/addurl.jsp =================================================================== diff -u -r9dcc3e2d26b504f92d919f53f0d45dd4093a82a2 -rba64868d96bcde6a6de9afca8b58a32bd25085ff --- lams_tool_larsrc/web/pages/authoring/parts/addurl.jsp (.../addurl.jsp) (revision 9dcc3e2d26b504f92d919f53f0d45dd4093a82a2) +++ lams_tool_larsrc/web/pages/authoring/parts/addurl.jsp (.../addurl.jsp) (revision ba64868d96bcde6a6de9afca8b58a32bd25085ff) @@ -61,10 +61,6 @@
- -   -
- <%@ include file="ratings.jsp"%> Index: lams_tool_larsrc/web/pages/itemreview/mainframe.jsp =================================================================== diff -u -r3f803a81d714ccf1b8488fe7f0488708e765d26c -rba64868d96bcde6a6de9afca8b58a32bd25085ff --- lams_tool_larsrc/web/pages/itemreview/mainframe.jsp (.../mainframe.jsp) (revision 3f803a81d714ccf1b8488fe7f0488708e765d26c) +++ lams_tool_larsrc/web/pages/itemreview/mainframe.jsp (.../mainframe.jsp) (revision ba64868d96bcde6a6de9afca8b58a32bd25085ff) @@ -22,65 +22,84 @@ <%@ include file="/common/taglibs.jsp" %> <%@ page import="org.lamsfoundation.lams.tool.rsrc.ResourceConstants"%> +?mode=${mode}&itemIndex=${itemIndex}&itemUid=${itemUid}&toolSessionID=${toolSessionID}&sessionMapID=${sessionMapID} + + <%@ include file="/common/header.jsp"%> - ?mode=${mode}&itemIndex=${itemIndex}&itemUid=${itemUid}&toolSessionID=${toolSessionID}&sessionMapID=${sessionMapID} - - - @@ -94,10 +113,23 @@ - + - Index: lams_tool_larsrc/web/pages/learning/addurl.jsp =================================================================== diff -u -raced7ba6c1e7c5a9a50d3f64d8cdd96dd7e76194 -rba64868d96bcde6a6de9afca8b58a32bd25085ff --- lams_tool_larsrc/web/pages/learning/addurl.jsp (.../addurl.jsp) (revision aced7ba6c1e7c5a9a50d3f64d8cdd96dd7e76194) +++ lams_tool_larsrc/web/pages/learning/addurl.jsp (.../addurl.jsp) (revision ba64868d96bcde6a6de9afca8b58a32bd25085ff) @@ -22,9 +22,7 @@
-
  - +