diff --git a/pom.xml b/pom.xml
index 39c743e..a3d308a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -47,6 +47,13 @@
${org.springframework.version}
+
+ org.springframework
+ spring-test
+ ${org.springframework.version}
+
+
+
org.slf4j
slf4j-api
@@ -73,15 +80,9 @@
- javax.validation
- validation-api
- 1.0.0.GA
-
-
-
- org.hibernate
- hibernate-validator
- 4.1.0.Final
+ org.springframework
+ spring-orm
+ ${org.springframework.version}
@@ -90,11 +91,23 @@
3.6.7.Final
-
-
-
-
-
+
+ org.hibernate
+ hibernate-commons-annotations
+ 3.2.0.Final
+
+
+
+ org.hibernate.javax.persistence
+ hibernate-jpa-2.0-api
+ 1.0.1.Final
+
+
+
+ org.hsqldb
+ hsqldb
+ 1.8.0.10
+
com.h2database
@@ -103,6 +116,8 @@
+
+
joda-time
joda-time
@@ -153,11 +168,7 @@
jetty-server
${jettyVersion}
-
- org.springframework
- spring-orm
- 3.0.6.RELEASE
-
+
diff --git a/src/main/java/de/ctdo/bunti/dao/BuntiDevicesDAOImpl.java b/src/main/java/de/ctdo/bunti/dao/BuntiDevicesDAOImpl.java
index e9c009b..dc25b01 100644
--- a/src/main/java/de/ctdo/bunti/dao/BuntiDevicesDAOImpl.java
+++ b/src/main/java/de/ctdo/bunti/dao/BuntiDevicesDAOImpl.java
@@ -17,21 +17,21 @@ public final class BuntiDevicesDAOImpl implements BuntiDevicesDAO {
private List devices = new ArrayList();
public BuntiDevicesDAOImpl() {
- addDummyDevices();
+// addDummyDevices();
}
- private void addDummyDevices() {
- int deviceID = 0;
-
- devices.add(new Par56Spot(deviceID++, 1, "Par56 Lampe 1"));
- devices.add(new Par56Spot(deviceID++, 6, "Par56 Lampe 2"));
- devices.add(new Par56Spot(deviceID++, 11, "Par56 Lampe 3"));
- devices.add(new Par56Spot(deviceID++, 16, "Par56 Lampe 4"));
- devices.add(new Strobe1500(deviceID++, 21, "Stroboskop 1"));
- devices.add(new Par56Spot(deviceID, 508, "Par56 Lampe 5"));
- LOGGER.debug("added dummy devices in DAO");
- }
+// private void addDummyDevices() {
+// int deviceID = 0;
+//
+// devices.add(new Par56Spot(deviceID++, 1, "Par56 Lampe 1"));
+// devices.add(new Par56Spot(deviceID++, 6, "Par56 Lampe 2"));
+// devices.add(new Par56Spot(deviceID++, 11, "Par56 Lampe 3"));
+// devices.add(new Par56Spot(deviceID++, 16, "Par56 Lampe 4"));
+// devices.add(new Strobe1500(deviceID++, 21, "Stroboskop 1"));
+// devices.add(new Par56Spot(deviceID, 508, "Par56 Lampe 5"));
+// LOGGER.debug("added dummy devices in DAO");
+// }
@Override
diff --git a/src/main/java/de/ctdo/bunti/dao/RoomsDAOImpl.java b/src/main/java/de/ctdo/bunti/dao/RoomsDAOImpl.java
index bf0921c..3127851 100644
--- a/src/main/java/de/ctdo/bunti/dao/RoomsDAOImpl.java
+++ b/src/main/java/de/ctdo/bunti/dao/RoomsDAOImpl.java
@@ -13,26 +13,8 @@ public final class RoomsDAOImpl extends HibernateDaoSupport implements RoomsDAO
}
-
@Override
public List getRooms() {
-
- //if(getHibernateTemplate().loadAll(Room.class).size() == 0) {
-
- Room r = new Room();
- r.setId(1);
- r.setFloor("Floor 1");
- r.setName("Kueche");
- Par56Spot spot = new Par56Spot();
- spot.setDeviceName("Spot 1");
- spot.setStartAddress(1);
-// r.addDevice(spot);
-
- getHibernateTemplate().save(spot);
- getHibernateTemplate().save(r);
-
- //}
-
return getHibernateTemplate().loadAll(Room.class);
}
diff --git a/src/main/java/de/ctdo/bunti/model/BuntiDMXDevice.java b/src/main/java/de/ctdo/bunti/model/BuntiDMXDevice.java
index 5c7d239..cf49d11 100644
--- a/src/main/java/de/ctdo/bunti/model/BuntiDMXDevice.java
+++ b/src/main/java/de/ctdo/bunti/model/BuntiDMXDevice.java
@@ -22,16 +22,11 @@ public abstract class BuntiDMXDevice extends BuntiDevice {
}
- public BuntiDMXDevice(int deviceId, int startAddress, String name) {
- super(deviceId, name);
- setStartAddress(startAddress);
- }
-
/**
* Gets the DMX start address for this device
* @return The address value from 1 to max 512
*/
- public final int getStartAddress() {
+ public int getStartAddress() {
return startAddress;
}
@@ -40,7 +35,7 @@ public abstract class BuntiDMXDevice extends BuntiDevice {
* @param startAddress The address value from 1 to max 512
* @return True on success, false if start address is wrong
*/
- public final boolean setStartAddress(int startAddress) {
+ public boolean setStartAddress(int startAddress) {
if(startAddress < DMX.DMX_CHANNEL_INDEX_MIN ||
startAddress - 1 + dmxChannels.getCount() > DMX.DMX_CHANNEL_INDEX_MAX) {
return false;
diff --git a/src/main/java/de/ctdo/bunti/model/BuntiDevice.java b/src/main/java/de/ctdo/bunti/model/BuntiDevice.java
index 003a492..f9f4504 100644
--- a/src/main/java/de/ctdo/bunti/model/BuntiDevice.java
+++ b/src/main/java/de/ctdo/bunti/model/BuntiDevice.java
@@ -1,7 +1,7 @@
package de.ctdo.bunti.model;
-import org.hibernate.annotations.GenericGenerator;
-
+import javax.persistence.*;
+import java.io.Serializable;
import javax.persistence.*;
import java.util.Map;
@@ -14,19 +14,14 @@ import java.util.Map;
@Table(name = "devices")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public abstract class BuntiDevice {
- private int deviceId;
+ private int id;
private String deviceName;
private String picture;
-// private Room room;
public BuntiDevice() {
}
- public BuntiDevice(int deviceId, String deviceName) {
- this.deviceId = deviceId;
- this.deviceName = deviceName;
- }
/**
* Get the type of this device
@@ -47,21 +42,21 @@ public abstract class BuntiDevice {
* @return the device Id
*/
@Id
- @GeneratedValue(generator="increment")
- @GenericGenerator(name="increment", strategy = "increment")
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "BUNTIDEVICE_ID", updatable=false, nullable=false)
public final int getId() {
- return deviceId;
+ return id;
}
public final void setId(int id) {
- this.deviceId = id;
+ this.id = id;
}
/**
* Gets the device name
* @return The name of the device
*/
- public final String getDeviceName() {
+ public String getDeviceName() {
return deviceName;
}
@@ -69,7 +64,7 @@ public abstract class BuntiDevice {
* Sets the device Name
* @param deviceName a String with the device name
*/
- public final void setDeviceName(String deviceName) {
+ public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
@@ -77,7 +72,7 @@ public abstract class BuntiDevice {
* Get the relative URL to the picture of this device
* @return the relative URL to the picture
*/
- public final String getPicture() {
+ public String getPicture() {
return picture;
}
@@ -85,7 +80,7 @@ public abstract class BuntiDevice {
* Get the relative URL to the picture of this device
* @param picture The relative URL to the picture
*/
- public final void setPicture(String picture) {
+ public void setPicture(String picture) {
this.picture = picture;
}
diff --git a/src/main/java/de/ctdo/bunti/model/BuntiSwitchingDevice.java b/src/main/java/de/ctdo/bunti/model/BuntiSwitchingDevice.java
index 3c86416..293269d 100644
--- a/src/main/java/de/ctdo/bunti/model/BuntiSwitchingDevice.java
+++ b/src/main/java/de/ctdo/bunti/model/BuntiSwitchingDevice.java
@@ -7,15 +7,12 @@ import java.util.Map;
@Entity
public abstract class BuntiSwitchingDevice extends BuntiDevice {
private static final String OPTION_STATE = "state";
-
private boolean state = false;
- public BuntiSwitchingDevice(int deviceId, String deviceName) {
- super(deviceId, deviceName);
+ public BuntiSwitchingDevice() {
+
}
-
-
@Override
public final boolean setValuesFromOptions(Map options) {
diff --git a/src/main/java/de/ctdo/bunti/model/Par56Spot.java b/src/main/java/de/ctdo/bunti/model/Par56Spot.java
index 69ac634..92c2d41 100644
--- a/src/main/java/de/ctdo/bunti/model/Par56Spot.java
+++ b/src/main/java/de/ctdo/bunti/model/Par56Spot.java
@@ -20,11 +20,6 @@ public class Par56Spot extends BuntiDMXDevice {
addChannels();
}
- public Par56Spot(int deviceId, int startAddress, String deviceName) {
- super(deviceId, startAddress, deviceName);
- addChannels();
- }
-
private void addChannels() {
int offset = 0;
addChannel(new DMXChannel(offset++, CHANNEL_MODE));
diff --git a/src/main/java/de/ctdo/bunti/model/Room.java b/src/main/java/de/ctdo/bunti/model/Room.java
index 34e5a55..7512111 100644
--- a/src/main/java/de/ctdo/bunti/model/Room.java
+++ b/src/main/java/de/ctdo/bunti/model/Room.java
@@ -1,12 +1,10 @@
package de.ctdo.bunti.model;
-
-import org.hibernate.annotations.GenericGenerator;
-
import javax.persistence.*;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
+
@Entity
@Table( name = "rooms" )
@@ -17,11 +15,11 @@ public final class Room {
private String floor;
private int xCord;
private int yCord;
-// private List devices = new ArrayList();
+ private Set devices = new HashSet();
@Id
- @GeneratedValue(generator="increment")
- @GenericGenerator(name="increment", strategy = "increment")
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "ROOM_ID", updatable=false, nullable=false)
public int getId() {
return id;
}
@@ -65,14 +63,17 @@ public final class Room {
}
-// @OneToMany(mappedBy="room")
-// public List getDevices() {
-// return devices;
-// }
-//
-// public void setDevices(List devices) {
-// this.devices = devices;
-// }
+ @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, targetEntity = BuntiDevice.class)
+ @JoinTable(name = "ROOM_BUNTIDEVICE",
+ joinColumns = { @JoinColumn(name = "ROOM_ID") },
+ inverseJoinColumns = { @JoinColumn(name = "BUNTIDEVICE_ID") })
+ public Set getDevices() {
+ return this.devices;
+ }
+
+ public void setDevices(Set devices) {
+ this.devices = devices;
+ }
// @Transient
diff --git a/src/main/java/de/ctdo/bunti/model/Strobe1500.java b/src/main/java/de/ctdo/bunti/model/Strobe1500.java
index 0db3fe6..cdd647f 100644
--- a/src/main/java/de/ctdo/bunti/model/Strobe1500.java
+++ b/src/main/java/de/ctdo/bunti/model/Strobe1500.java
@@ -18,11 +18,6 @@ public class Strobe1500 extends BuntiDMXDevice {
addChannels();
}
- public Strobe1500(int deviceId, int startAddress, String deviceName) {
- super(deviceId, startAddress, deviceName);
- addChannels();
- }
-
private void addChannels() {
addChannel(new DMXChannel(0, CHANNEL_SPEED));
addChannel(new DMXChannel(1, CHANNEL_INTENSITY));
diff --git a/src/main/resources/META-INF/spring/hibernate-beans.xml b/src/main/resources/META-INF/spring/hibernate-beans.xml
index ccb9eb1..dd19922 100755
--- a/src/main/resources/META-INF/spring/hibernate-beans.xml
+++ b/src/main/resources/META-INF/spring/hibernate-beans.xml
@@ -1,44 +1,45 @@
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"
+ xmlns:jdbc="http://www.springframework.org/schema/jdbc">
+
+
+
+
+
+
-
+
-
-
-
-
-
-
- org.hibernate.dialect.HSQLDialect
-
+ org.hibernate.dialect.HSQLDialect
true
-
+ create
-
+
-
-
-
+
+
+
+
+
-
+
+
diff --git a/src/main/resources/bunti.hbm.xml b/src/main/resources/bunti.hbm.xml
deleted file mode 100755
index 4f32d5e..0000000
--- a/src/main/resources/bunti.hbm.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/resources/db.properties b/src/main/resources/db.properties
index e52abc7..7a44d51 100755
--- a/src/main/resources/db.properties
+++ b/src/main/resources/db.properties
@@ -1,2 +1,2 @@
-db.driverClassName=org.hsqldb.jdbcDriver
-db.url=jdbc:hsqldb:mem:buntiserver
+#db.driverClassName=org.hsqldb.jdbcDriver
+#db.url=jdbc:hsqldb:mem:buntiserver
diff --git a/src/main/resources/init.sql b/src/main/resources/init.sql
deleted file mode 100755
index 067434b..0000000
--- a/src/main/resources/init.sql
+++ /dev/null
@@ -1,24 +0,0 @@
-
-drop table rooms if exists;
-
-create table rooms (id integer identity primary key,
- roomName varchar (255) not null,
- floor varchar (255),
- yCord integer,
- xCord integer
-
-
-
- );
-
-create table devices (id integer primary key,
- ROOM_ID integer,
- deviceName varchar (255) not null,
- picture varchar (255),
- startAddress integer,
- DTYPE varchar (255)
-
- );
-
-
-
diff --git a/src/main/resources/init_data.sql b/src/main/resources/init_data.sql
new file mode 100755
index 0000000..3e189f7
--- /dev/null
+++ b/src/main/resources/init_data.sql
@@ -0,0 +1,11 @@
+
+
+insert into rooms (ROOM_ID, floor, roomName, xCord, yCord) values (null, '2. Etage', 'Kueche', '0', '0');
+insert into rooms (ROOM_ID, floor, roomName, xCord, yCord) values (null, '2. Etage', 'Wohnzimmer', '0', '1');
+insert into rooms (ROOM_ID, floor, roomName, xCord, yCord) values (null, '2. Etage', 'Werkstatt', '1', '0');
+insert into rooms (ROOM_ID, floor, roomName, xCord, yCord) values (null, '2. Etage', 'Flur', '1', '1');
+
+
+
+
+
diff --git a/src/main/resources/init_schema.sql b/src/main/resources/init_schema.sql
new file mode 100755
index 0000000..72ae1bc
--- /dev/null
+++ b/src/main/resources/init_schema.sql
@@ -0,0 +1,29 @@
+drop table ROOM_BUNTIDEVICE if exists;
+drop table devices if exists;
+drop table rooms if exists;
+
+create table ROOM_BUNTIDEVICE (ROOM_ID integer not null, BUNTIDEVICE_ID int not null,
+ primary key (ROOM_ID, BUNTIDEVICE_ID), unique (BUNTIDEVICE_ID));
+
+create table devices (DTYPE varchar(31) not null,
+ BUNTIDEVICE_ID integer generated by default as identity (start with 1),
+ deviceName varchar(255),
+ picture varchar(255),
+ startAddress integer,
+ primary key (BUNTIDEVICE_ID));
+
+create table rooms (ROOM_ID integer generated by default as identity (start with 1),
+ floor varchar(255),
+ roomName varchar(255),
+ xCord integer not null,
+ yCord integer not null,
+ primary key (ROOM_ID));
+
+alter table ROOM_BUNTIDEVICE add constraint FK96EF8F028BB4B62 foreign key (ROOM_ID) references rooms;
+alter table ROOM_BUNTIDEVICE add constraint FK96EF8F021E9F392 foreign key (BUNTIDEVICE_ID) references devices;
+
+
+
+
+
+
diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties
deleted file mode 100644
index 256221f..0000000
--- a/src/main/resources/log4j.properties
+++ /dev/null
@@ -1,15 +0,0 @@
-#log4j.rootLogger=debug, stdout
-
-#log4j.appender.stdout=org.apache.log4j.ConsoleAppender
-#log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
-
-# Print the date in ISO 8601 format
-##log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
-#log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p %c: %m%n
-
-#log4j.appender.R=org.apache.log4j.RollingFileAppender
-#log4j.appender.R.File=application.log
-#log4j.appender.R.MaxFileSize=100KB
-#log4j.appender.R.MaxBackupIndex=1
-#log4j.appender.R.layout=org.apache.log4j.PatternLayout
-#log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
diff --git a/src/main/resources/log4j.xml b/src/main/resources/log4j.xml
index c241217..85d124a 100644
--- a/src/main/resources/log4j.xml
+++ b/src/main/resources/log4j.xml
@@ -15,15 +15,15 @@
-
-
-
-
+
+
+
+
diff --git a/src/test/java/de/ctdo/bunti/dao/RoomsDAOImplTest.java b/src/test/java/de/ctdo/bunti/dao/RoomsDAOImplTest.java
new file mode 100644
index 0000000..b12d053
--- /dev/null
+++ b/src/test/java/de/ctdo/bunti/dao/RoomsDAOImplTest.java
@@ -0,0 +1,35 @@
+package de.ctdo.bunti.dao;
+
+import de.ctdo.bunti.model.Room;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+
+@ContextConfiguration()
+@RunWith(SpringJUnit4ClassRunner.class)
+public class RoomsDAOImplTest {
+
+ @Autowired
+ RoomsDAO dut;
+
+ @Test
+// @Transactional
+ public void testGetRooms() throws Exception {
+ assertEquals(4, dut.getRooms().size());
+ }
+
+ @Test
+ public void testGetRoomKueche() throws Exception {
+ assertEquals("Kueche", dut.getRoom(1).getName());
+ }
+
+ @Test
+ public void testGetRoomKuecheError() throws Exception {
+ assertNull(dut.getRoom(23));
+ }
+}
diff --git a/src/test/java/de/ctdo/bunti/dmx/DMXMixerImplTest.java b/src/test/java/de/ctdo/bunti/dmx/DMXMixerImplTest.java
index 50bc1ef..6d9b321 100644
--- a/src/test/java/de/ctdo/bunti/dmx/DMXMixerImplTest.java
+++ b/src/test/java/de/ctdo/bunti/dmx/DMXMixerImplTest.java
@@ -36,7 +36,10 @@ public class DMXMixerImplTest {
@Test
public void testUpdateDevice() throws Exception {
- BuntiDevice device = new Par56Spot(23,42,"deviceName");
+ Par56Spot device = new Par56Spot();
+ device.setId(23);
+ device.setStartAddress(42);
+ device.setDeviceName("deviceName");
Map options = new HashMap();
options.put("red", 44);
assertTrue(dut.updateDevice(device, options));
@@ -44,7 +47,10 @@ public class DMXMixerImplTest {
@Test
public void testUpdateDeviceWrong1() throws Exception {
- BuntiDevice device = new Par56Spot(23,42,"deviceName");
+ Par56Spot device = new Par56Spot();
+ device.setId(23);
+ device.setStartAddress(42);
+ device.setDeviceName("deviceName");
assertFalse(dut.updateDevice(device, null));
}
@@ -57,14 +63,20 @@ public class DMXMixerImplTest {
@Test
public void testUpdateDeviceWrong3() throws Exception {
- BuntiDevice device = new Par56Spot(23,42,"deviceName");
+ Par56Spot device = new Par56Spot();
+ device.setId(23);
+ device.setStartAddress(42);
+ device.setDeviceName("deviceName");
Map options = new HashMap();
assertFalse(dut.updateDevice(device, options));
}
@Test
public void testUpdateDeviceWrong4() throws Exception {
- BuntiDevice device = new Par56Spot(23,42,"deviceName");
+ Par56Spot device = new Par56Spot();
+ device.setId(23);
+ device.setStartAddress(42);
+ device.setDeviceName("deviceName");
Map options = new HashMap();
options.put("rednonexistent", 44);
assertFalse(dut.updateDevice(device, options));
diff --git a/src/test/java/de/ctdo/bunti/model/BuntiDMXDeviceTest.java b/src/test/java/de/ctdo/bunti/model/BuntiDMXDeviceTest.java
index c1388e8..0589455 100644
--- a/src/test/java/de/ctdo/bunti/model/BuntiDMXDeviceTest.java
+++ b/src/test/java/de/ctdo/bunti/model/BuntiDMXDeviceTest.java
@@ -16,7 +16,10 @@ public class BuntiDMXDeviceTest {
@Before
public void setUp() throws Exception {
- dut = new Par56Spot(DEVICEID,STARTADDRESS,"device");
+ dut = new Par56Spot();
+ dut.setId(23);
+ dut.setStartAddress(42);
+ dut.setDeviceName("deviceName");
}
@Test
diff --git a/src/test/java/de/ctdo/bunti/model/Par56SpotTest.java b/src/test/java/de/ctdo/bunti/model/Par56SpotTest.java
index fb1b664..5c304c3 100644
--- a/src/test/java/de/ctdo/bunti/model/Par56SpotTest.java
+++ b/src/test/java/de/ctdo/bunti/model/Par56SpotTest.java
@@ -9,8 +9,10 @@ public class Par56SpotTest {
@Before
public void setUp() throws Exception {
- dut = new Par56Spot(23,42,"device");
-
+ dut = new Par56Spot();
+ dut.setId(23);
+ dut.setStartAddress(42);
+ dut.setDeviceName("device");
}
@Test
diff --git a/src/test/java/de/ctdo/bunti/model/Strobe1500Test.java b/src/test/java/de/ctdo/bunti/model/Strobe1500Test.java
index 91f2264..433556b 100644
--- a/src/test/java/de/ctdo/bunti/model/Strobe1500Test.java
+++ b/src/test/java/de/ctdo/bunti/model/Strobe1500Test.java
@@ -10,8 +10,10 @@ public class Strobe1500Test {
@Before
public void setUp() throws Exception {
- dut = new Strobe1500(23,42,"device");
-
+ dut = new Strobe1500();
+ dut.setId(23);
+ dut.setStartAddress(42);
+ dut.setDeviceName("device");
}
@Test
diff --git a/src/test/resources/de/ctdo/bunti/dao/RoomsDAOImplTest-context.xml b/src/test/resources/de/ctdo/bunti/dao/RoomsDAOImplTest-context.xml
new file mode 100644
index 0000000..5816a46
--- /dev/null
+++ b/src/test/resources/de/ctdo/bunti/dao/RoomsDAOImplTest-context.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ org.hibernate.dialect.HSQLDialect
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file