From 8fd36ba1e2b56787877d485b755bd515d2108ca0 Mon Sep 17 00:00:00 2001 From: mohammedthaqi Date: Fri, 8 Dec 2023 15:28:43 +0530 Subject: [PATCH] added community hall & feedback Form for playStore --- .../metro/community/config/DBConnection.java | 36 + .../controller/CommunityController.java | 14 + .../controller/CommunityHallController.java | 160 ++++ .../metro/community/dto/HallRegistration.java | 90 ++ .../service/CommunityHallService.java | 169 ++++ .../metro/community/service/DataEntry.java | 99 +++ .../com/metro/community/service/HallDto.java | 59 ++ .../component/UserSessionInterceptor.java | 4 +- .../controller/FeedbackController.java | 13 + src/main/resources/application.properties | 4 +- .../templates/community/communityhall.html | 823 ++++++++++++++++++ .../templates/feedback/RequestForm.html | 726 +++++++++++++++ 12 files changed, 2193 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/metro/community/config/DBConnection.java create mode 100644 src/main/java/com/metro/community/controller/CommunityController.java create mode 100644 src/main/java/com/metro/community/controller/CommunityHallController.java create mode 100644 src/main/java/com/metro/community/dto/HallRegistration.java create mode 100644 src/main/java/com/metro/community/service/CommunityHallService.java create mode 100644 src/main/java/com/metro/community/service/DataEntry.java create mode 100644 src/main/java/com/metro/community/service/HallDto.java create mode 100644 src/main/java/com/metro/feedback/controller/FeedbackController.java create mode 100644 src/main/resources/templates/community/communityhall.html create mode 100644 src/main/resources/templates/feedback/RequestForm.html diff --git a/src/main/java/com/metro/community/config/DBConnection.java b/src/main/java/com/metro/community/config/DBConnection.java new file mode 100644 index 0000000..0502a11 --- /dev/null +++ b/src/main/java/com/metro/community/config/DBConnection.java @@ -0,0 +1,36 @@ +package com.metro.community.config; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +public class DBConnection { + private static Connection dbcon; + + static String l_sErpUrl = "jdbc:oracle:thin:@10.1.0.14:1521:chncorp"; + static String l_sErpdriver = "oracle.jdbc.driver.OracleDriver"; + + public static Connection getConnection() { + try { + if(dbcon==null) { + Class.forName(l_sErpdriver); + Connection erp_conn = DriverManager.getConnection(l_sErpUrl,"coc","coc"); + System.out.println("erp_conn Con :"+ erp_conn ); + System.out.println("erp_conn Con "); + dbcon=erp_conn; + return erp_conn; + } + else { + return dbcon; + } + + } catch (ClassNotFoundException e) { + e.printStackTrace(); + //throw new SqlExcaptionClass("Sql"); + } catch (SQLException e) { + e.printStackTrace(); + + } + return dbcon; + } +} diff --git a/src/main/java/com/metro/community/controller/CommunityController.java b/src/main/java/com/metro/community/controller/CommunityController.java new file mode 100644 index 0000000..5538d2b --- /dev/null +++ b/src/main/java/com/metro/community/controller/CommunityController.java @@ -0,0 +1,14 @@ +package com.metro.community.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +public class CommunityController { + @RequestMapping("/community") + public String getmypage(){ + return "community/communityhall"; + } + + +} diff --git a/src/main/java/com/metro/community/controller/CommunityHallController.java b/src/main/java/com/metro/community/controller/CommunityHallController.java new file mode 100644 index 0000000..57012b2 --- /dev/null +++ b/src/main/java/com/metro/community/controller/CommunityHallController.java @@ -0,0 +1,160 @@ +package com.metro.community.controller; + +import java.text.SimpleDateFormat; +import java.util.*; + +import com.metro.community.dto.HallRegistration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.metro.community.service.CommunityHallService; + + +@RestController +@RequestMapping("/community/api") +public class CommunityHallController { + + + @Autowired + private CommunityHallService communityHallService; + +// @RequestMapping(value = "/division", method = RequestMethod.GET) +// public List getDivision(@RequestParam String zone) { +// communityHallService.setZone(zone); +// return communityHallService.getList("zone"); +// } + + @RequestMapping(value = "/getHall", method = RequestMethod.GET) + public List getSelectCommunityHallByZone(@RequestParam String zone) { + communityHallService.setZone(zone); + return communityHallService.getList("communityHall"); + + } + + @RequestMapping(value = "/getHallById", method = RequestMethod.GET) + public List getSelectCommunityHall(@RequestParam String hallId) { + communityHallService.setHallId(hallId); + return communityHallService.getList("hallId"); + + } + + @RequestMapping(value = "/getHallByName", method = RequestMethod.GET) + public List getSelectCommunityHallName(@RequestParam String hallName) { + communityHallService.setHallName(hallName); + return communityHallService.getList("hallName"); + + } + + @RequestMapping(value = "/getHallByMonthAndYear", method = RequestMethod.GET) + public List getCommunityHallByMonthAndYear(@RequestParam String hallId, @RequestParam String fromDay, @RequestParam String toDay) { + communityHallService.setHallId(hallId); + communityHallService.setFromDay(fromDay); + communityHallService.setToDay(toDay); + System.out.println(fromDay+"..."+toDay); + List hall = communityHallService.getHallRegistration("MonthAndYear"); + if(hall==null||hall.isEmpty()) { + return null; + } + else{ + List output = processInputData(hall); + Collections.sort(output, Comparator.comparing(ResultEntry::getDate)); + return output; + } + + + + } + + @RequestMapping(value = "/getHallByBookingStatus", method = RequestMethod.GET) + public List getSelectCommunityHallIdBookingStatus(@RequestParam String hallId) { + communityHallService.setHallId(hallId); + return communityHallService.getList("BookingStatus"); + + } + + + private static List processInputData(List data) { + Map outputMap = new HashMap<>(); + + for (HallRegistration entry : data) { + String date1 = extractDate(entry.getDATE1()); + String date2 = extractDate(entry.getDATE2()); + String date3 = extractDate(entry.getDATE3()); + + // Add entries to the map, combining if the date already exists + addToOutputMap(outputMap, date1,Integer.parseInt(entry.getMORNINGHALF1()) , Integer.parseInt(entry.getEVENINGHALF1())); + addToOutputMap(outputMap, date2,Integer.parseInt(entry.getMORNINGHALF2()),Integer.parseInt(entry.getEVENINGHALF2())); + addToOutputMap(outputMap, date3, Integer.parseInt(entry.getMORNINGHALF3()), Integer.parseInt(entry.getEVENINGHALF3())); + } + + return new ArrayList<>(outputMap.values()); + } + + private static String extractDate (String dateString){ + if (dateString != null) { + try { + return new SimpleDateFormat("dd").format(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateString)); + } catch (Exception e) { + e.printStackTrace(); + } + } + return null; + } + + private static void addToOutputMap(Map outputMap, String date, int morningHalf, int eveningHalf) { + if (date != null) { + ResultEntry existingEntry = outputMap.get(date); + if (existingEntry != null) { + // Combine morningHalf and eveningHalf if the date already exists + existingEntry.setMorningHalf(existingEntry.getMorningHalf() + morningHalf); + existingEntry.setEveningHalf(existingEntry.getEveningHalf() + eveningHalf); + } else { + // Add a new entry to the map if the date does not exist + outputMap.put(date, new ResultEntry(date, morningHalf, eveningHalf)); + } + } + + + } +} + class ResultEntry { + private String date; + private int morningHalf; + private int eveningHalf; + + public ResultEntry(String date, int morningHalf, int eveningHalf) { + this.date = date; + this.morningHalf = morningHalf; + this.eveningHalf = eveningHalf; + } + + public String getDate() { + return date; + } + + public int getMorningHalf() { + return morningHalf; + } + + public int getEveningHalf() { + return eveningHalf; + } + + public void setMorningHalf(int morningHalf) { + this.morningHalf = morningHalf; + } + + public void setEveningHalf(int eveningHalf) { + this.eveningHalf = eveningHalf; + } + + @Override + public String toString() { + return "{" + date + ",{" + morningHalf + "," + eveningHalf + "}}"; + } + } + + diff --git a/src/main/java/com/metro/community/dto/HallRegistration.java b/src/main/java/com/metro/community/dto/HallRegistration.java new file mode 100644 index 0000000..e3c63cd --- /dev/null +++ b/src/main/java/com/metro/community/dto/HallRegistration.java @@ -0,0 +1,90 @@ +package com.metro.community.dto; + +import org.springframework.stereotype.Component; + +import java.util.Date; +@Component +public class HallRegistration { + private String MORNINGHALF1; + private String EVENINGHALF1; + private String MORNINGHALF2; + private String EVENINGHALF2; + private String MORNINGHALF3; + private String EVENINGHALF3; + + private String DATE3; + private String DATE2; + private String DATE1; + + public String getMORNINGHALF1() { + return MORNINGHALF1; + } + + public void setMORNINGHALF1(String MORNINGHALF1) { + this.MORNINGHALF1 = MORNINGHALF1; + } + + public String getEVENINGHALF1() { + return EVENINGHALF1; + } + + public void setEVENINGHALF1(String EVENINGHALF1) { + this.EVENINGHALF1 = EVENINGHALF1; + } + + public String getMORNINGHALF2() { + return MORNINGHALF2; + } + + public void setMORNINGHALF2(String MORNINGHALF2) { + this.MORNINGHALF2 = MORNINGHALF2; + } + + public String getEVENINGHALF2() { + return EVENINGHALF2; + } + + public void setEVENINGHALF2(String EVENINGHALF2) { + this.EVENINGHALF2 = EVENINGHALF2; + } + + public String getMORNINGHALF3() { + return MORNINGHALF3; + } + + public void setMORNINGHALF3(String MORNINGHALF3) { + this.MORNINGHALF3 = MORNINGHALF3; + } + + public String getEVENINGHALF3() { + return EVENINGHALF3; + } + + public void setEVENINGHALF3(String EVENINGHALF3) { + this.EVENINGHALF3 = EVENINGHALF3; + } + + public String getDATE3() { + return DATE3; + } + + public void setDATE3(String DATE3) { + this.DATE3 = DATE3; + } + + public String getDATE2() { + return DATE2; + } + + public void setDATE2(String DATE2) { + this.DATE2 = DATE2; + } + + public String getDATE1() { + return DATE1; + } + + public void setDATE1(String DATE1) { + this.DATE1 = DATE1; + } +} diff --git a/src/main/java/com/metro/community/service/CommunityHallService.java b/src/main/java/com/metro/community/service/CommunityHallService.java new file mode 100644 index 0000000..5fbbcba --- /dev/null +++ b/src/main/java/com/metro/community/service/CommunityHallService.java @@ -0,0 +1,169 @@ +package com.metro.community.service; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.Statement; +import java.util.*; + +import com.metro.community.config.DBConnection; +import com.metro.community.dto.HallRegistration; +import org.springframework.stereotype.Service; + + +@Service +public class CommunityHallService extends HallDto{ + + + + public String getDivi(String zone) { + return "select * from tbl_online_division where zone_id ="+zone+" order by divison_id "; + } + + public String getSelectCommunityHall(String zone) { + return "select * from tbl_communityhall Where COMMUNITYHALLZONEID ="+zone; + + } + + public String getSelectCommunityHallName(String hallName) { + return "select * from tbl_communityhall Where COMMUNITYHALLADDRESS LIKE '"+hallName+"%'"; + } + + public String getSelectCommunityHallRegistration(String hallId, String fromDay ,String toDay){ + return "SELECT COMMUNITYHALLID, DATE1, MORNINGHALF1, EVENINGHALF1, DATE2, MORNINGHALF2, EVENINGHALF2, DATE3, MORNINGHALF3, EVENINGHALF3" + + " FROM TBL_COMMUNITYHALLREGISTRATION WHERE COMMUNITYHALLID = "+hallId+" AND (DATE1 BETWEEN TO_DATE('"+fromDay+"','YYYY-MM-DD') AND TO_DATE('"+toDay+"','YYYY-MM-DD'))"; + } + + + public String getSelectCommunityHallId(String hallId) { + return "SELECT communityhallhalfdayrate, communityhallhalfsurcharge," + + " nvl(CLEAN_CHRG_HALF,0)+nvl(PA_SYS_HALF,0)+nvl(EB_HALF,0) pa_eb_half," + + " round((nvl(CLEAN_CHRG_HALF,0)+nvl(PA_SYS_HALF,0)+nvl(EB_HALF,0))*18/100,0) pa_eb_serv_half," + + " communityhalldeposit, communityhallcapacity, communityhalladvance,evemorn_twodaysamount," + + " communityhallfulldayrate," + + " nvl(CLEAN_CHRG_FULL,0) +nvl(PA_SYS_FULL,0)+nvl(EB_FULL,0) pa_eb_full ," + + " round((nvl(CLEAN_CHRG_FULL,0) +nvl(PA_SYS_FULL,0)+nvl(EB_FULL,0))*18/100,0) pa_eb_serv_full," + + " SOUND_SERVICE_AMT,VESSEL_AMT,OTHER_AMT FROM coc.tbl_communityhall where communityhallid=" + hallId; + + } + + public List> getList(String type){ + Connection con =DBConnection.getConnection(); + Statement stmt3; + try { + System.out.println(getQuery(type)); + stmt3 = con.createStatement(); + ResultSet rs3 = stmt3.executeQuery(getQuery(type)); + List> rows = new ArrayList<>(); + if ( rows.isEmpty() && rs3==null) { + return rows; + } + while (rs3.next()) { + Map row = new HashMap<>(); + + ResultSetMetaData metaData = rs3.getMetaData(); + int columnCount = metaData.getColumnCount(); + + for (int i = 1; i <= columnCount; i++) { + String columnName = metaData.getColumnName(i); + Object columnValue = rs3.getObject(i); + row.put(columnName, columnValue); + } + + // Add the row to the List + rows.add(row); + } + return rows; + } + catch (Exception e){ + e.printStackTrace(); + } + return null; + } + + public String getQuery(String type){ + if(type.equals("zone")){ + return getDivi(getZone()); + } + else if(type.equals("communityHall")){ + return getSelectCommunityHall(getZone()); + } + else if(type.equals("hallId")){ + return getSelectCommunityHallId(getHallId()); + } + else if(type.equals("hallName")){ + return getSelectCommunityHallName(getHallName()); + }else if(type.equals("BookingStatus")){ + return getSelectCommunityHallId(getHallId()); + }else if(type.equals("MonthAndYear")){ + return getSelectCommunityHallRegistration(getHallId(), getFromDay(),getToDay()); + } + return null; + } + + + + + public List getHallRegistration(String type){ + Connection con =DBConnection.getConnection(); + Statement stmt3; + try { + System.out.println(getQuery(type)); + stmt3 = con.createStatement(); + ResultSet rs3 = stmt3.executeQuery(getQuery(type)); + List rows = new ArrayList<>(); + if (rs3==null) { + return rows; + } + while (rs3.next()) { + HallRegistration row = new HallRegistration(); + + ResultSetMetaData metaData = rs3.getMetaData(); + int columnCount = metaData.getColumnCount(); + + for (int i = 1; i <= columnCount; i++) { + String columnName = metaData.getColumnName(i); + Object columnValue = rs3.getObject(i); + + switch (columnName) { + case "MORNINGHALF1": + row.setMORNINGHALF1(columnValue!=null?columnValue.toString():null); + break; + case "MORNINGHALF2": + row.setMORNINGHALF2(columnValue!=null?columnValue.toString():null); + break; + case "MORNINGHALF3": + row.setMORNINGHALF3(columnValue!=null?columnValue.toString():null); + break; + case "EVENINGHALF1": + row.setEVENINGHALF1(columnValue!=null?columnValue.toString():null); + break; + case "EVENINGHALF2": + row.setEVENINGHALF2(columnValue!=null?columnValue.toString():null); + break; + case "EVENINGHALF3": + row.setEVENINGHALF3(columnValue!=null?columnValue.toString():null); + break; + case "DATE1": + row.setDATE1(columnValue!=null?columnValue.toString():null); + break; + case "DATE2": + row.setDATE2(columnValue!=null?columnValue.toString():null); + break; + case "DATE3": + row.setDATE3(columnValue!=null?columnValue.toString():null); + break; + + } + + } + rows.add(row); + } + return rows; + } + catch (Exception e){ + e.printStackTrace(); + } + return null; + } +} diff --git a/src/main/java/com/metro/community/service/DataEntry.java b/src/main/java/com/metro/community/service/DataEntry.java new file mode 100644 index 0000000..5c3281d --- /dev/null +++ b/src/main/java/com/metro/community/service/DataEntry.java @@ -0,0 +1,99 @@ +package com.metro.community.service; + +public class DataEntry { + private String date1; + private int morningHalf1; + private int eveningHalf1; + private String date2; + private int morningHalf2; + private int eveningHalf2; + private String date3; + private int morningHalf3; + private int eveningHalf3; + + public DataEntry(String date1, int morningHalf1, int eveningHalf1, + String date2, int morningHalf2, int eveningHalf2, + String date3, int morningHalf3, int eveningHalf3) { + this.date1 = date1; + this.morningHalf1 = morningHalf1; + this.eveningHalf1 = eveningHalf1; + this.date2 = date2; + this.morningHalf2 = morningHalf2; + this.eveningHalf2 = eveningHalf2; + this.date3 = date3; + this.morningHalf3 = morningHalf3; + this.eveningHalf3 = eveningHalf3; + } + + public String getDate1() { + return date1; + } + + public void setDate1(String date1) { + this.date1 = date1; + } + + public int getMorningHalf1() { + return morningHalf1; + } + + public void setMorningHalf1(int morningHalf1) { + this.morningHalf1 = morningHalf1; + } + + public int getEveningHalf1() { + return eveningHalf1; + } + + public void setEveningHalf1(int eveningHalf1) { + this.eveningHalf1 = eveningHalf1; + } + + public String getDate2() { + return date2; + } + + public void setDate2(String date2) { + this.date2 = date2; + } + + public int getMorningHalf2() { + return morningHalf2; + } + + public void setMorningHalf2(int morningHalf2) { + this.morningHalf2 = morningHalf2; + } + + public int getEveningHalf2() { + return eveningHalf2; + } + + public void setEveningHalf2(int eveningHalf2) { + this.eveningHalf2 = eveningHalf2; + } + + public String getDate3() { + return date3; + } + + public void setDate3(String date3) { + this.date3 = date3; + } + + public int getMorningHalf3() { + return morningHalf3; + } + + public void setMorningHalf3(int morningHalf3) { + this.morningHalf3 = morningHalf3; + } + + public int getEveningHalf3() { + return eveningHalf3; + } + + public void setEveningHalf3(int eveningHalf3) { + this.eveningHalf3 = eveningHalf3; + } +} diff --git a/src/main/java/com/metro/community/service/HallDto.java b/src/main/java/com/metro/community/service/HallDto.java new file mode 100644 index 0000000..7082d56 --- /dev/null +++ b/src/main/java/com/metro/community/service/HallDto.java @@ -0,0 +1,59 @@ +package com.metro.community.service; + +public class HallDto { + private String zone; + private String division; + private String hallId; + private String toDay; + private String fromDay; + + private String hallName; + + public String getHallName() { + return hallName; + } + + public void setHallName(String hallName) { + this.hallName = hallName; + } + + public String getZone() { + return zone; + } + + public void setZone(String zone) { + this.zone = zone; + } + + public String getDivision() { + return division; + } + + public void setDivision(String division) { + this.division = division; + } + + public String getHallId() { + return hallId; + } + + public void setHallId(String hallId) { + this.hallId = hallId; + } + + public String getToDay() { + return toDay; + } + + public void setToDay(String toDay) { + this.toDay = toDay; + } + + public String getFromDay() { + return fromDay; + } + + public void setFromDay(String fromDay) { + this.fromDay = fromDay; + } +} diff --git a/src/main/java/com/metro/component/UserSessionInterceptor.java b/src/main/java/com/metro/component/UserSessionInterceptor.java index 74d30db..bd43c2d 100644 --- a/src/main/java/com/metro/component/UserSessionInterceptor.java +++ b/src/main/java/com/metro/component/UserSessionInterceptor.java @@ -16,14 +16,14 @@ public class UserSessionInterceptor implements HandlerInterceptor { @Autowired private UserSession userSession; - private static final List EXCLUDED_URLS = Arrays.asList("/login", "/", "/api"); + private static final List EXCLUDED_URLS = Arrays.asList("/login", "/", "/api","/community","/feedback"); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // Get the current request URL String requestUrl = request.getRequestURI(); // Exclude static resources from the check - if (requestUrl.startsWith("/assets/") || requestUrl.startsWith("/css/") || requestUrl.startsWith("/js/") || requestUrl.startsWith("/images/") || requestUrl.startsWith("/api/")) { + if (requestUrl.startsWith("/assets/") || requestUrl.startsWith("/css/") || requestUrl.startsWith("/js/") || requestUrl.startsWith("/images/") || requestUrl.startsWith("/api/") || requestUrl.startsWith("/community/") ||requestUrl.startsWith("/feedback/")) { return true; // Allow the request to proceed without checking the login status } diff --git a/src/main/java/com/metro/feedback/controller/FeedbackController.java b/src/main/java/com/metro/feedback/controller/FeedbackController.java new file mode 100644 index 0000000..5bc9ede --- /dev/null +++ b/src/main/java/com/metro/feedback/controller/FeedbackController.java @@ -0,0 +1,13 @@ +package com.metro.feedback.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +@RequestMapping("/feedback") +@Controller +public class FeedbackController { + @RequestMapping(value={"/",""}) + public String getmypage(){ + return "feedback/RequestForm"; + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 9cc7b9b..dcc14f2 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -3,8 +3,8 @@ server.port=8068 # Database connection properties spring.datasource.url=jdbc:mysql://localhost:3306/metro spring.datasource.username=root -spring.datasource.password=gccroot -#spring.datasource.password=root +#spring.datasource.password=gccroot +spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # Connection pool properties diff --git a/src/main/resources/templates/community/communityhall.html b/src/main/resources/templates/community/communityhall.html new file mode 100644 index 0000000..ce792b1 --- /dev/null +++ b/src/main/resources/templates/community/communityhall.html @@ -0,0 +1,823 @@ + + + + + + + + + + + + + Community Hall Availability + + + + + +
+
+
+
+

Select Your Community Hall:

+
+
+ + + +
+
+ + + +
+
+ +
+
+ + + +
+
+ + + + +
+
+ + +
+ + +
+
+
+ +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/templates/feedback/RequestForm.html b/src/main/resources/templates/feedback/RequestForm.html new file mode 100644 index 0000000..ade683b --- /dev/null +++ b/src/main/resources/templates/feedback/RequestForm.html @@ -0,0 +1,726 @@ + + + + + + + + + GCC Grabage Collection Request + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+
+
+
+

Government of Tamil Nadu

+

தமிழ்நாடு அரசு பெருநகர சென்னை மாநகராட்சி

+
+
+
+
+ + + + +
+ +
+ + +
+
+
+
+

New Request Form

+
+ +
+ +
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+ +
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ +
+
+
+ + +
+ +
+
+
+ +
+ + +
+
+
+ + + + + + + + + + + + + + + + + + + +