From 2536283784ad573298ebfd82b08e31e6bf1f0857 Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Wed, 28 Jan 2015 16:47:10 +0100
Subject: [PATCH] OO-1405: implement configuration to allow users as
 partcipants to leave a course

---
 .../course/run/CourseRuntimeController.java   |  64 +++++++++-
 .../org/olat/group/BusinessGroupService.java  |  11 ++
 .../manager/BusinessGroupServiceImpl.java     |  18 +++
 .../org/olat/login/LoginAdminController.java  |  19 +++
 .../olat/repository/LeavingStatusList.java    |  58 +++++++++
 .../org/olat/repository/RepositoryEntry.java  |  31 +++++
 .../RepositoryEntryAllowToLeaveOptions.java   |  34 ++++++
 .../olat/repository/RepositoryManager.java    |  25 ++++
 .../olat/repository/RepositoryService.java    |   6 +
 .../_i18n/LocalStrings_de.properties          |  10 ++
 .../_i18n/LocalStrings_en.properties          |   7 ++
 .../manager/RepositoryServiceImpl.java        |  33 ++++++
 .../ui/RepositoryEntryRuntimeController.java  |   5 +
 .../author/AuthoringEditAccessController.java |  15 +++
 ...oringEditAllowToLeaveOptionController.java | 112 ++++++++++++++++++
 .../ui/author/_content/editproptabpub.html    |   4 +-
 .../olat/repository/ui/list/LeavingEvent.java |  38 ++++++
 .../RepositoryEntryDetailsController.java     |  56 ++++++++-
 .../list/RepositoryEntryListController.java   |   5 +
 .../repository/ui/list/_content/details.html  |   6 +
 .../repository/course/CoursesWebService.java  |   9 ++
 .../database/mysql/alter_10_1_0_to_10_2_0.sql |   3 +
 .../database/mysql/setupDatabase.sql          |   1 +
 .../oracle/alter_10_1_0_to_10_2_0.sql         |   2 +
 .../database/oracle/setupDatabase.sql         |   1 +
 .../postgresql/alter_10_1_0_to_10_2_0.sql     |   2 +
 .../database/postgresql/setupDatabase.sql     |   1 +
 .../static/themes/light/modules/_icons.scss   |   1 +
 src/main/webapp/static/themes/light/theme.css |   2 +-
 .../repository/RepositoryManagerTest.java     |  96 +++++++++++++++
 30 files changed, 666 insertions(+), 9 deletions(-)
 create mode 100644 src/main/java/org/olat/repository/LeavingStatusList.java
 create mode 100644 src/main/java/org/olat/repository/RepositoryEntryAllowToLeaveOptions.java
 create mode 100644 src/main/java/org/olat/repository/ui/author/AuthoringEditAllowToLeaveOptionController.java
 create mode 100644 src/main/java/org/olat/repository/ui/list/LeavingEvent.java

diff --git a/src/main/java/org/olat/course/run/CourseRuntimeController.java b/src/main/java/org/olat/course/run/CourseRuntimeController.java
index bd0113d1c0b..308e271ae2f 100644
--- a/src/main/java/org/olat/course/run/CourseRuntimeController.java
+++ b/src/main/java/org/olat/course/run/CourseRuntimeController.java
@@ -32,6 +32,7 @@ import org.olat.core.commons.fullWebApp.LayoutMain3ColsController;
 import org.olat.core.commons.fullWebApp.popup.BaseFullWebappPopupLayoutFactory;
 import org.olat.core.commons.modules.bc.FolderRunController;
 import org.olat.core.commons.modules.glossary.GlossaryMainController;
+import org.olat.core.commons.persistence.DBFactory;
 import org.olat.core.commons.persistence.PersistenceHelper;
 import org.olat.core.commons.services.mark.Mark;
 import org.olat.core.gui.UserRequest;
@@ -56,6 +57,8 @@ import org.olat.core.gui.control.generic.dtabs.Activateable2;
 import org.olat.core.gui.control.generic.dtabs.DTab;
 import org.olat.core.gui.control.generic.dtabs.DTabs;
 import org.olat.core.gui.control.generic.messages.MessageUIFactory;
+import org.olat.core.gui.control.generic.modal.DialogBoxController;
+import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory;
 import org.olat.core.gui.control.generic.popup.PopupBrowserWindow;
 import org.olat.core.id.Identity;
 import org.olat.core.id.OLATResourceable;
@@ -68,6 +71,8 @@ import org.olat.core.util.StringHelper;
 import org.olat.core.util.coordinate.CoordinatorManager;
 import org.olat.core.util.event.GenericEventListener;
 import org.olat.core.util.event.MultiUserEvent;
+import org.olat.core.util.mail.MailPackage;
+import org.olat.core.util.mail.MailerResult;
 import org.olat.core.util.nodes.INode;
 import org.olat.core.util.prefs.Preferences;
 import org.olat.core.util.resource.OresHelper;
@@ -116,6 +121,7 @@ import org.olat.instantMessaging.InstantMessagingModule;
 import org.olat.instantMessaging.InstantMessagingService;
 import org.olat.instantMessaging.OpenInstantMessageEvent;
 import org.olat.note.NoteController;
+import org.olat.repository.LeavingStatusList;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryManagedFlag;
 import org.olat.repository.RepositoryManager;
@@ -147,7 +153,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
 		//settings
 		layoutLink, optionsLink, certificatesOptionsLink,
 		//my course
-		efficiencyStatementsLink, calendarLink, noteLink, chatLink,
+		efficiencyStatementsLink, calendarLink, noteLink, chatLink, leaveLink,
 		//glossary
 		openGlossaryLink, enableGlossaryLink,
 		//assessment
@@ -156,6 +162,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
 	private Dropdown myCourse, glossary;
 	
 	private CourseAreasController areasCtrl;
+	private DialogBoxController leaveDialogBox;
 	private ArchiverMainController archiverCtrl;
 	private CustomDBMainController databasesCtrl;
 	private FolderRunController courseFolderCtrl;
@@ -555,6 +562,14 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
 					myCourse.addComponent(link);
 				}
 			}
+			
+			if(repositoryService.isParticipantAllowedToLeave(getRepositoryEntry())
+					&& (uce.isParticipant() || !uce.getParticipatingGroups().isEmpty())) {
+				leaveLink = LinkFactory.createToolLink("sign.out", "leave", translate("sign.out"), this);
+				leaveLink.setIconLeftCSS("o_icon o_icon-fw o_icon_sign_out");
+				myCourse.addComponent(new Spacer("leaving-space"));
+				myCourse.addComponent(leaveLink);
+			}
 		}
 		if(myCourse.size() > 0) {
 			toolbarPanel.addTool(myCourse, Align.right);
@@ -568,8 +583,11 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
 		if (!assessmentLock && showInfos) {
 			detailsLink = LinkFactory.createToolLink("courseconfig",translate("command.courseconfig"), this, "o_icon_details");
 			toolbarPanel.addTool(detailsLink);
-		}		
-		if (!assessmentLock && !isGuestOnly && calendarModule.isEnabled() && calendarModule.isEnableCourseToolCalendar()) {
+		}
+		
+		boolean calendarIsEnabled =  !assessmentLock && !isGuestOnly && calendarModule.isEnabled()
+				&& calendarModule.isEnableCourseToolCalendar() && reSecurity.canLaunch();
+		if (calendarIsEnabled) {
 			calendarLink = LinkFactory.createToolLink("calendar",translate("command.calendar"), this, "o_icon_calendar");
 			calendarLink.setPopup(new LinkPopupSettings(950, 750, "cal"));
 			calendarLink.setVisible(cc.isCalendarEnabled());
@@ -592,7 +610,8 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
 		
 		//add group chat to toolbox
 		InstantMessagingModule imModule = CoreSpringFactory.getImpl(InstantMessagingModule.class);
-		boolean chatIsEnabled = !assessmentLock && !isGuestOnly && imModule.isEnabled() && imModule.isCourseEnabled();
+		boolean chatIsEnabled = !assessmentLock && !isGuestOnly && imModule.isEnabled()
+				&& imModule.isCourseEnabled() && reSecurity.canLaunch();
 		if(chatIsEnabled) {
 			chatLink = LinkFactory.createToolLink("chat",translate("command.coursechat"), this, "o_icon_chat");
 			chatLink.setVisible(CourseModule.isCourseChatEnabled() && cc.isChatEnabled());
@@ -688,6 +707,8 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
 			launchPersonalNotes(ureq);
 		} else if(openGlossaryLink == source) {
 			launchGlossary(ureq);
+		} else if(leaveLink == source) {
+			doConfirmLeave(ureq);
 		} else if(source instanceof Link && "group".equals(((Link)source).getCommand())) {
 			BusinessGroupRef ref = (BusinessGroupRef)((Link)source).getUserObject();
 			launchGroup(ureq, ref.getKey());
@@ -727,7 +748,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
 				initToolbar();
 				toolControllerDone(ureq);
 			}
-		} if(source == editorCtrl && source instanceof VetoableCloseController) {
+		} else if(source == editorCtrl && source instanceof VetoableCloseController) {
 			if(event == Event.DONE_EVENT) {
 				if(delayedClose != null) {
 					switch(delayedClose) {
@@ -758,6 +779,10 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
 					fireEvent(ureq, Event.DONE_EVENT);
 				}
 			}
+		} else if(source == leaveDialogBox) {
+			if (DialogBoxUIFactory.isYesEvent(event) || DialogBoxUIFactory.isOkEvent(event)) {
+				doLeave(ureq);
+			}
 		}
 		
 		super.event(ureq, source, event);
@@ -949,7 +974,36 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
 			delayedClose = Delayed.catalog;
 		}
 	}
+	
+	private void doConfirmLeave(UserRequest ureq) {
+		String reName = StringHelper.escapeHtml(getRepositoryEntry().getDisplayname());
+		String title = translate("sign.out");
+		String text = translate("sign.out.dialog.text", reName);
+		leaveDialogBox = activateYesNoDialog(ureq, title, text, leaveDialogBox);
+	}
+	
+	private void doLeave(UserRequest ureq) {
+		MailerResult result = new MailerResult();
+		MailPackage reMailing = new MailPackage(result, getWindowControl().getBusinessControl().getAsString(), true);
+		//leave course
+		LeavingStatusList status = new LeavingStatusList();
+		repositoryManager.leave(getIdentity(), getRepositoryEntry(), status, reMailing);
+		//leave groups
+		businessGroupService.leave(getIdentity(), getRepositoryEntry(), status, reMailing);
+		//reload this but make sure all changes are committed before reload
+		DBFactory.getInstance().commit();
+		
+		if(status.isWarningManagedGroup() || status.isWarningManagedCourse()) {
+			showWarning("sign.out.warning.managed");
+		} else if(status.isWarningGroupWithMultipleResources()) {
+			showWarning("sign.out.warning.mutiple.resources");
+		} else {
+			showInfo("sign.out.success", new String[]{ getRepositoryEntry().getDisplayname() });
+		}
 
+		doClose(ureq);
+	}
+	
 	private void doLayout(UserRequest ureq) {
 		if(delayedClose == Delayed.layout || requestForClose(ureq)) {
 			if (reSecurity.isEntryAdmin() || hasCourseRight(CourseRights.RIGHT_COURSEEDITOR)) {
diff --git a/src/main/java/org/olat/group/BusinessGroupService.java b/src/main/java/org/olat/group/BusinessGroupService.java
index 2eb49b61e93..27eeee4fee7 100644
--- a/src/main/java/org/olat/group/BusinessGroupService.java
+++ b/src/main/java/org/olat/group/BusinessGroupService.java
@@ -39,6 +39,7 @@ import org.olat.group.model.EnrollState;
 import org.olat.group.model.LeaveOption;
 import org.olat.group.model.MembershipModification;
 import org.olat.group.model.SearchBusinessGroupParams;
+import org.olat.repository.LeavingStatusList;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryRef;
 import org.olat.repository.RepositoryEntryShort;
@@ -348,6 +349,16 @@ public interface BusinessGroupService {
 	public int getPositionInWaitingListFor(Identity identity, BusinessGroup businessGroup);
 	
 	//memberships
+	/**
+	 * The method follow the business groups of the specified entry
+	 * and remove the participant membership of the group where
+	 * the entry is the only resource.
+	 * 
+	 * @param identity
+	 * @param entry
+	 */
+	public void leave(Identity identity, RepositoryEntry entry, LeavingStatusList status, MailPackage mailing);
+	
 	/**
 	 * Adds a user to a group as owner and does all the magic that needs to be
 	 * done: - add to security group (optional) - add to jabber roster - fire multi user event
diff --git a/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java b/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java
index 9ded82e7b70..8164dc6b136 100644
--- a/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java
+++ b/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java
@@ -102,6 +102,7 @@ import org.olat.group.right.BGRightsRole;
 import org.olat.group.ui.BGMailHelper;
 import org.olat.group.ui.edit.BusinessGroupModifiedEvent;
 import org.olat.properties.PropertyManager;
+import org.olat.repository.LeavingStatusList;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryRef;
 import org.olat.repository.RepositoryEntryRelationType;
@@ -803,6 +804,23 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD
 		return businessGroupRelationDAO.getMembersOf(resource, owner, attendee);
 	}
 
+	@Override
+	public void leave(Identity identity, RepositoryEntry entry, LeavingStatusList status, MailPackage mailing) {
+		SearchBusinessGroupParams params = new SearchBusinessGroupParams();
+		params.setIdentity(identity);
+		params.setAttendee(true);
+		List<BusinessGroup> groups = businessGroupDAO.findBusinessGroups(params, entry, 0, -1);
+		for(BusinessGroup group:groups) {
+			if(BusinessGroupManagedFlag.isManaged(group, BusinessGroupManagedFlag.membersmanagement)) {
+				status.setWarningManagedGroup(true);
+			} else if(businessGroupRelationDAO.countResources(group) > 1) {
+				status.setWarningGroupWithMultipleResources(true);
+			} else {
+				removeParticipant(identity, identity, group, mailing, null);
+			}
+		}
+	}
+
 	@Override
 	public BusinessGroupAddResponse addOwners(Identity ureqIdentity, Roles ureqRoles, List<Identity> addIdentities,
 			BusinessGroup group, MailPackage mailing) {
diff --git a/src/main/java/org/olat/login/LoginAdminController.java b/src/main/java/org/olat/login/LoginAdminController.java
index 84fcaa83a50..2c4443927ba 100644
--- a/src/main/java/org/olat/login/LoginAdminController.java
+++ b/src/main/java/org/olat/login/LoginAdminController.java
@@ -1,3 +1,22 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
 package org.olat.login;
 
 import org.olat.core.gui.UserRequest;
diff --git a/src/main/java/org/olat/repository/LeavingStatusList.java b/src/main/java/org/olat/repository/LeavingStatusList.java
new file mode 100644
index 00000000000..d1fae3326f1
--- /dev/null
+++ b/src/main/java/org/olat/repository/LeavingStatusList.java
@@ -0,0 +1,58 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.repository;
+
+/**
+ * 
+ * Initial date: 28.01.2015<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class LeavingStatusList {
+	
+	private boolean warningManagedCourse;
+	private boolean warningManagedGroup;
+	private boolean warningGroupWithMultipleResources;
+	
+	public boolean isWarningManagedCourse() {
+		return warningManagedCourse;
+	}
+	
+	public void setWarningManagedCourse(boolean warningManagedCourse) {
+		this.warningManagedCourse = warningManagedCourse;
+	}
+	
+	public boolean isWarningManagedGroup() {
+		return warningManagedGroup;
+	}
+	
+	public void setWarningManagedGroup(boolean warningManagedGroup) {
+		this.warningManagedGroup = warningManagedGroup;
+	}
+	
+	public boolean isWarningGroupWithMultipleResources() {
+		return warningGroupWithMultipleResources;
+	}
+	
+	public void setWarningGroupWithMultipleResources(
+			boolean warningGroupWithMultipleResources) {
+		this.warningGroupWithMultipleResources = warningGroupWithMultipleResources;
+	}
+}
diff --git a/src/main/java/org/olat/repository/RepositoryEntry.java b/src/main/java/org/olat/repository/RepositoryEntry.java
index b4689ba12a7..26c6549909f 100644
--- a/src/main/java/org/olat/repository/RepositoryEntry.java
+++ b/src/main/java/org/olat/repository/RepositoryEntry.java
@@ -51,6 +51,7 @@ import org.olat.core.id.Persistable;
 import org.olat.core.logging.AssertException;
 import org.olat.core.util.CodeHelper;
 import org.olat.core.util.Formatter;
+import org.olat.core.util.StringHelper;
 import org.olat.core.util.resource.OresHelper;
 import org.olat.repository.model.RepositoryEntryLifecycle;
 import org.olat.repository.model.RepositoryEntryStatistics;
@@ -164,6 +165,8 @@ public class RepositoryEntry implements CreateInfo, Persistable , RepositoryEntr
 	private boolean membersOnly;
 	@Column(name="statuscode", nullable=false, insertable=true, updatable=true)
 	private int statusCode;
+	@Column(name="allowToLeave", nullable=true, insertable=true, updatable=true)
+	private String allowToLeave;
 
 	
 	/**
@@ -425,7 +428,35 @@ public class RepositoryEntry implements CreateInfo, Persistable , RepositoryEntr
 	public void setMembersOnly(boolean membersOnly) {
 		this.membersOnly = membersOnly;
 	}
+
+	public String getAllowToLeave() {
+		return allowToLeave;
+	}
+
+	public void setAllowToLeave(String allowToLeave) {
+		this.allowToLeave = allowToLeave;
+	}
 	
+	public RepositoryEntryAllowToLeaveOptions getAllowToLeaveOption() {
+		RepositoryEntryAllowToLeaveOptions setting;
+		if(StringHelper.containsNonWhitespace(allowToLeave)) {
+			setting = RepositoryEntryAllowToLeaveOptions.valueOf(allowToLeave);
+		} else if(RepositoryEntryManagedFlag.isManaged(this, RepositoryEntryManagedFlag.membersmanagement)) {
+			setting = RepositoryEntryAllowToLeaveOptions.never;
+		} else {
+			setting = RepositoryEntryAllowToLeaveOptions.atAnyTime;
+		}
+		return setting;
+	}
+
+	public void setAllowToLeaveOption(RepositoryEntryAllowToLeaveOptions setting) {
+		if(setting == null) {
+			allowToLeave = null;
+		} else {
+			allowToLeave = setting.name();
+		}
+	}
+
 	/**
 	 * @return Returns the displayname.
 	 */
diff --git a/src/main/java/org/olat/repository/RepositoryEntryAllowToLeaveOptions.java b/src/main/java/org/olat/repository/RepositoryEntryAllowToLeaveOptions.java
new file mode 100644
index 00000000000..c81df104726
--- /dev/null
+++ b/src/main/java/org/olat/repository/RepositoryEntryAllowToLeaveOptions.java
@@ -0,0 +1,34 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.repository;
+
+/**
+ * 
+ * Initial date: 28.01.2015<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public enum RepositoryEntryAllowToLeaveOptions {
+	
+	atAnyTime,
+	afterEndDate,
+	never
+
+}
diff --git a/src/main/java/org/olat/repository/RepositoryManager.java b/src/main/java/org/olat/repository/RepositoryManager.java
index ec33076b3d5..7e15e2e783c 100644
--- a/src/main/java/org/olat/repository/RepositoryManager.java
+++ b/src/main/java/org/olat/repository/RepositoryManager.java
@@ -666,6 +666,19 @@ public class RepositoryManager extends BasicManager {
 		return updatedRe;
 	}
 	
+	public RepositoryEntry setLeaveSetting(final RepositoryEntry re,
+			RepositoryEntryAllowToLeaveOptions setting) {
+		RepositoryEntry reloadedRe = loadForUpdate(re);
+		reloadedRe.setAllowToLeaveOption(setting);
+		RepositoryEntry updatedRe = dbInstance.getCurrentEntityManager().merge(reloadedRe);
+		updatedRe.getStatistics().getLaunchCounter();
+		if(updatedRe.getLifecycle() != null) {
+			updatedRe.getLifecycle().getKey();
+		}
+		dbInstance.commit();
+		return updatedRe;
+	} 
+	
 	/**
 	 * This method doesn't update empty and null values! ( Reserved to unit tests
 	 * and REST API)
@@ -698,6 +711,9 @@ public class RepositoryManager extends BasicManager {
 		}
 		if(StringHelper.containsNonWhitespace(managedFlags)) {
 			reloadedRe.setManagedFlagsString(managedFlags);
+			if(RepositoryEntryManagedFlag.isManaged(reloadedRe, RepositoryEntryManagedFlag.membersmanagement)) {
+				reloadedRe.setAllowToLeaveOption(RepositoryEntryAllowToLeaveOptions.never);
+			}
 		}
 		
 		RepositoryEntryLifecycle cycleToDelete = null;
@@ -1414,6 +1430,15 @@ public class RepositoryManager extends BasicManager {
 		return dbQuery;
 	}
 	
+	public void leave(Identity identity, RepositoryEntry re, LeavingStatusList status, MailPackage mailing) {
+		if(RepositoryEntryManagedFlag.isManaged(re, RepositoryEntryManagedFlag.membersmanagement)) {
+			status.setWarningManagedCourse(true);
+		} else {
+			List<Identity> removeIdentities = Collections.singletonList(identity);
+			removeParticipants(identity, removeIdentities, re, mailing, true);
+		}
+	}
+	
 	/**
 	 * add provided list of identities as owners to the repo entry. silently ignore
 	 * if some identities were already owners before.
diff --git a/src/main/java/org/olat/repository/RepositoryService.java b/src/main/java/org/olat/repository/RepositoryService.java
index 8c7aa273760..82501935080 100644
--- a/src/main/java/org/olat/repository/RepositoryService.java
+++ b/src/main/java/org/olat/repository/RepositoryService.java
@@ -100,6 +100,12 @@ public interface RepositoryService {
 	
 	public int countMembers(RepositoryEntryRef re, String... roles);
 	
+	/**
+	 * @param re The repository entry
+	 * @return True if the configuration allowed user to leave the entry right now
+	 */
+	public boolean isParticipantAllowedToLeave(RepositoryEntry re);
+	
 	/**
 	 * Return the primary keys of the authors
 	 */
diff --git a/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties
index ff12a475035..e0f43743fd6 100644
--- a/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties
@@ -463,6 +463,11 @@ rentry.publish.authors=f\u00FCr Autoren
 rentry.publish.course.desc=Definieren Sie in diesem Formular ob andere Autoren diesen Kurs als Vorlage verwenden oder exportieren d\u00FCrfen und ob der Kurs f\u00FCr die Endbenutzer freigegeben ist. Die Besitzer der Kurses haben jederzeit Zugang zu dem Kurs. 
 rentry.publish.other.desc=Hinweis\: Sie m\u00FCssen Ressourcen f\u00FCr Benutzer nicht freigeben um diese in einem Kurs verwenden zu k\u00F6nnen. Es wird empfohlen nur Kurse direkt als Lernressourcen freizugeben und andere Ressourcen stattdessen in Kurse einzubinden. Die Freigabe f\u00FCr Autoren erm\u00F6glicht es anderen Autoren Ressourcen von Ihnen zu verwenden ohne selbst Besitzer dieser Ressourcen zu sein.  
 rentry.publish.users=f\u00FCr Benutzer
+rentry.leaving.title=Mitglieder Konfiguration
+rentry.leave.option=Teilnehmer k\u00F6nnen Kurs austreten
+rentry.leave.atanytime=Jederzeit
+rentry.leave.afterenddate=Nach Enddatum
+rentry.leave.never=Nie
 repo.login=Login
 repository.admin.title=Repository Einstellungen
 repositoryentry.not.existing=Diese Ressource ist nicht mehr verf\u00FCgbar.
@@ -510,6 +515,11 @@ security.disabled.title=Lernressource nicht verf\u00FCgbar
 settings.editor=Beschreibung \u00E4ndern
 sf.notconfigured=Kein Ressourcenordner ausgew\u00E4hlt
 sf.resourcetitle=Gew\u00E4hlter Ressourcenordner
+sign.out=Kurs austreten
+sign.out.dialog.text=Wollen Sie von diesem Kurs "{0}" austreten?
+sign.out.success=Sie wurden erfolgreich von diesem Kurs "{0}" ausgetreten.
+sign.out.warning.managed=Sie k\u00F6nnten nicht von diesem Kurs komplett ausgetreten werden weil Sie von einer oder meheren Gruppen nicht austreten d\u00FCrfen. 
+sign.out.warning.mutiple.resources=Sie k\u00F6nnten nicht von diesem Kurs komplett ausgetreten werden weil Sie Mitglied von einer oder mehreren Gruppen sind, die mit anderen Kursen verlinkt sind.
 start=starten
 start.with.type={0} starten
 status.closed=Beendet (Geschlossen)
diff --git a/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties
index a72fcb8330d..a45b822369d 100644
--- a/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties
@@ -453,6 +453,11 @@ referencableSearch.title=Search for referenceable learning resources
 references=Referenced resources
 references.expl=import and link
 remove=Remove
+rentry.leaving.title=Membership configuration
+rentry.leave.option=Members allow to leave course
+rentry.leave.atanytime=At any time
+rentry.leave.afterenddate=After course end date
+rentry.leave.never=Never
 rentry.movie=Teaser movie (mp4)
 rentry.movie.example=Optimal aspect ratio\: {0}
 rentry.pic=Cover image (jpg, png, gif)
@@ -510,6 +515,8 @@ security.disabled.title=Learning resource disabled
 settings.editor=Change description
 sf.notconfigured=No resource folder selected
 sf.resourcetitle=Selected resource folder
+sign.out=Leave course
+sign.out.dialog.text=Do you want to leave this course "{0}"?
 start=start
 start.with.type=Start {0}
 status.closed=Finished (closed)
diff --git a/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java b/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java
index 79fd1cb0609..dc37965af18 100644
--- a/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java
+++ b/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java
@@ -20,6 +20,7 @@
 package org.olat.repository.manager;
 
 import java.io.File;
+import java.util.Calendar;
 import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
@@ -54,6 +55,7 @@ import org.olat.course.assessment.manager.UserCourseInformationsManager;
 import org.olat.repository.ErrorList;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryAuthorView;
+import org.olat.repository.RepositoryEntryAllowToLeaveOptions;
 import org.olat.repository.RepositoryEntryMyView;
 import org.olat.repository.RepositoryEntryRef;
 import org.olat.repository.RepositoryEntryRelationType;
@@ -61,6 +63,7 @@ import org.olat.repository.RepositoryManager;
 import org.olat.repository.RepositoryService;
 import org.olat.repository.handlers.RepositoryHandler;
 import org.olat.repository.handlers.RepositoryHandlerFactory;
+import org.olat.repository.model.RepositoryEntryLifecycle;
 import org.olat.repository.model.RepositoryEntryStatistics;
 import org.olat.repository.model.RepositoryEntryToGroupRelation;
 import org.olat.repository.model.SearchAuthorRepositoryEntryViewParams;
@@ -146,6 +149,7 @@ public class RepositoryServiceImpl implements RepositoryService {
 		re.setDisplayname(displayname);
 		re.setResourcename(StringHelper.containsNonWhitespace(resourceName) ? resourceName : "-");
 		re.setDescription(description == null ? "" : description);
+		re.setAllowToLeaveOption(RepositoryEntryAllowToLeaveOptions.atAnyTime);
 		if(resource == null) {
 			OLATResourceable ores = OresHelper.createOLATResourceableInstance("RepositoryEntry", CodeHelper.getForeverUniqueID());
 			resource = resourceManager.createAndPersistOLATResourceInstance(ores);
@@ -375,6 +379,35 @@ public class RepositoryServiceImpl implements RepositoryService {
 		return reToGroupDao.hasRole(identity, re, roles);
 	}
 
+	@Override
+	public boolean isParticipantAllowedToLeave(RepositoryEntry re) {
+		boolean allowed = false;
+		RepositoryEntryAllowToLeaveOptions setting = re.getAllowToLeaveOption();
+		if(setting == RepositoryEntryAllowToLeaveOptions.atAnyTime) {
+			allowed = true;
+		} else if(setting == RepositoryEntryAllowToLeaveOptions.afterEndDate) {
+			RepositoryEntryLifecycle lifecycle = re.getLifecycle();
+			if(lifecycle == null || lifecycle.getValidTo() == null) {
+				allowed = false;
+			} else {
+				Calendar cal = Calendar.getInstance();
+				cal.set(Calendar.HOUR, 0);
+				cal.set(Calendar.MINUTE, 0);
+				cal.set(Calendar.SECOND, 0);
+				cal.set(Calendar.MILLISECOND, 0);
+				Date now = cal.getTime();
+				if(now.compareTo(lifecycle.getValidTo()) >= 0) {
+					allowed = true;
+				} else {
+					allowed = false;
+				}
+			}
+		} else {
+			allowed = false;
+		}
+		return allowed;
+	}
+
 	@Override
 	public boolean isMember(IdentityRef identity, RepositoryEntryRef entry) {
 		return reToGroupDao.isMember(identity, entry);
diff --git a/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java b/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java
index 9885798b7d7..d0c77cb836d 100644
--- a/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java
+++ b/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java
@@ -90,6 +90,7 @@ import org.olat.repository.ui.author.RepositoryEditDescriptionController;
 import org.olat.repository.ui.author.RepositoryMembersController;
 import org.olat.repository.ui.author.wizard.CloseResourceCallback;
 import org.olat.repository.ui.author.wizard.Close_1_ExplanationStep;
+import org.olat.repository.ui.list.LeavingEvent;
 import org.olat.repository.ui.list.RepositoryEntryDetailsController;
 import org.olat.resource.OLATResource;
 import org.olat.resource.accesscontrol.ACService;
@@ -539,6 +540,10 @@ public class RepositoryEntryRuntimeController extends MainLayoutBasicController
 			if(event == Event.CHANGED_EVENT) {
 				re = descriptionCtrl.getEntry();
 			}
+		} else if(detailsCtrl == source) {
+			if(event instanceof LeavingEvent) {
+				doClose(ureq);
+			}
 		} else if(closeCtrl == source) {
 			if(event == Event.CANCELLED_EVENT || event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) {
 				getWindowControl().pop();
diff --git a/src/main/java/org/olat/repository/ui/author/AuthoringEditAccessController.java b/src/main/java/org/olat/repository/ui/author/AuthoringEditAccessController.java
index 03948121ca8..5f25c07f9ec 100644
--- a/src/main/java/org/olat/repository/ui/author/AuthoringEditAccessController.java
+++ b/src/main/java/org/olat/repository/ui/author/AuthoringEditAccessController.java
@@ -30,6 +30,7 @@ import org.olat.core.util.Util;
 import org.olat.core.util.coordinate.CoordinatorManager;
 import org.olat.core.util.event.MultiUserEvent;
 import org.olat.repository.RepositoryEntry;
+import org.olat.repository.RepositoryEntryAllowToLeaveOptions;
 import org.olat.repository.RepositoryEntryManagedFlag;
 import org.olat.repository.RepositoryManager;
 import org.olat.repository.RepositoryService;
@@ -51,6 +52,7 @@ public class AuthoringEditAccessController extends BasicController {
 	private VelocityContainer editproptabpubVC;
 	
 	private AuthoringEntryPublishController propPupForm;
+	private final AuthoringEditAllowToLeaveOptionController leaveForm;
 	private AccessConfigurationController acCtr;
 	
 	private RepositoryEntry entry;
@@ -67,6 +69,10 @@ public class AuthoringEditAccessController extends BasicController {
 		propPupForm = new AuthoringEntryPublishController(ureq, wControl, entry);
 		listenTo(propPupForm);
 		editproptabpubVC.put("proppupform", propPupForm.getInitialComponent());
+		
+		leaveForm = new AuthoringEditAllowToLeaveOptionController(ureq, wControl, entry);
+		listenTo(leaveForm);
+		editproptabpubVC.put("leaveform", leaveForm.getInitialComponent());
 
 		boolean managedBookings = RepositoryEntryManagedFlag.isManaged(entry, RepositoryEntryManagedFlag.bookings);
 		acCtr = new AccessConfigurationController(ureq, getWindowControl(), entry.getOlatResource(), entry.getDisplayname(), true, !managedBookings);
@@ -125,6 +131,15 @@ public class AuthoringEditAccessController extends BasicController {
 				CoordinatorManager.getInstance().getCoordinator().getEventBus().fireEventToListenersOf(modifiedEvent, entry);			
 				fireEvent(ureq, Event.CHANGED_EVENT);
 			}
+		} else if(source == leaveForm) {
+			if (event == Event.DONE_EVENT) {
+				RepositoryEntryAllowToLeaveOptions leaveSetting = leaveForm.getSelectedLeaveSetting();
+				entry = repositoryManager.setLeaveSetting(entry, leaveSetting);	
+
+				MultiUserEvent modifiedEvent = new EntryChangedEvent(entry, getIdentity(), Change.modifiedAccess);
+				CoordinatorManager.getInstance().getCoordinator().getEventBus().fireEventToListenersOf(modifiedEvent, entry);	
+				fireEvent(ureq, Event.CHANGED_EVENT);
+			}
 		}
 	}
 }
diff --git a/src/main/java/org/olat/repository/ui/author/AuthoringEditAllowToLeaveOptionController.java b/src/main/java/org/olat/repository/ui/author/AuthoringEditAllowToLeaveOptionController.java
new file mode 100644
index 00000000000..04998ff6a8c
--- /dev/null
+++ b/src/main/java/org/olat/repository/ui/author/AuthoringEditAllowToLeaveOptionController.java
@@ -0,0 +1,112 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.repository.ui.author;
+
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.form.flexible.FormItemContainer;
+import org.olat.core.gui.components.form.flexible.elements.SingleSelection;
+import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
+import org.olat.core.gui.control.Controller;
+import org.olat.core.gui.control.Event;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.core.util.Util;
+import org.olat.repository.RepositoryEntry;
+import org.olat.repository.RepositoryEntryAllowToLeaveOptions;
+import org.olat.repository.RepositoryEntryManagedFlag;
+import org.olat.repository.RepositoryService;
+
+/**
+ * 
+ * Initial date: 28.01.2015<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class AuthoringEditAllowToLeaveOptionController extends FormBasicController {
+	
+	private static final String[] leaveKeys = new String[]{
+		RepositoryEntryAllowToLeaveOptions.atAnyTime.name(),
+		RepositoryEntryAllowToLeaveOptions.afterEndDate.name(),
+		RepositoryEntryAllowToLeaveOptions.never.name()
+	};
+	
+	private SingleSelection leaveEl;
+	
+	private RepositoryEntry entry;
+	
+	public AuthoringEditAllowToLeaveOptionController(UserRequest ureq, WindowControl wControl, RepositoryEntry entry) {
+		super(ureq, wControl);
+		setTranslator(Util.createPackageTranslator(RepositoryService.class, getLocale(), getTranslator()));
+		this.entry = entry;
+		initForm(ureq);
+	}
+
+	@Override
+	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		setFormTitle("rentry.leaving.title");
+		
+		String[] leaveValues = new String[]{
+				translate("rentry.leave.atanytime"),
+				translate("rentry.leave.afterenddate"),
+				translate("rentry.leave.never")
+		};
+		
+		final boolean managedLeaving = RepositoryEntryManagedFlag.isManaged(entry, RepositoryEntryManagedFlag.membersmanagement);
+		leaveEl = uifactory.addDropdownSingleselect("entry.leave", "rentry.leave.option", formLayout, leaveKeys, leaveValues, null);
+		boolean found = false;
+		for(String leaveKey:leaveKeys) {
+			if(leaveKey.equals(entry.getAllowToLeaveOption().name())) {
+				leaveEl.select(leaveKey, true);
+				found = true;
+			}
+		}
+		if(!found) {
+			if(managedLeaving) {
+				leaveEl.select(RepositoryEntryAllowToLeaveOptions.never.name(), true);
+			} else {
+				leaveEl.select(RepositoryEntryAllowToLeaveOptions.atAnyTime.name(), true);
+			}
+		}
+		leaveEl.setEnabled(!managedLeaving);
+		
+		if(!managedLeaving) {
+			uifactory.addFormSubmitButton("submit", formLayout);
+		}
+	}
+	
+	public RepositoryEntryAllowToLeaveOptions getSelectedLeaveSetting() {
+		RepositoryEntryAllowToLeaveOptions setting;
+		if(leaveEl.isOneSelected()) {
+			setting = RepositoryEntryAllowToLeaveOptions.valueOf(leaveEl.getSelectedKey());
+		} else {
+			setting = RepositoryEntryAllowToLeaveOptions.atAnyTime;
+		}
+		return setting;
+	}
+	
+	@Override
+	protected void doDispose() {
+		//
+	}
+
+	@Override
+	protected void formOK(UserRequest ureq) {
+		fireEvent(ureq, Event.DONE_EVENT);
+	}
+}
diff --git a/src/main/java/org/olat/repository/ui/author/_content/editproptabpub.html b/src/main/java/org/olat/repository/ui/author/_content/editproptabpub.html
index c3351c8c19f..f0298d51389 100644
--- a/src/main/java/org/olat/repository/ui/author/_content/editproptabpub.html
+++ b/src/main/java/org/olat/repository/ui/author/_content/editproptabpub.html
@@ -6,7 +6,9 @@ $r.render("proppupform")
 	$r.translate("cif.access.users_guests.warning")
 </div>
 #end
-
+#if($r.available("leaveform"))
+	$r.render("leaveform")
+#end
 #if($r.available("accesscontrol"))
 	$r.render("accesscontrol")
 #end
diff --git a/src/main/java/org/olat/repository/ui/list/LeavingEvent.java b/src/main/java/org/olat/repository/ui/list/LeavingEvent.java
new file mode 100644
index 00000000000..1adb6b38c89
--- /dev/null
+++ b/src/main/java/org/olat/repository/ui/list/LeavingEvent.java
@@ -0,0 +1,38 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.repository.ui.list;
+
+import org.olat.core.gui.control.Event;
+
+/**
+ * 
+ * Initial date: 28.01.2015<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class LeavingEvent extends Event {
+
+	private static final long serialVersionUID = -12672894980545992L;
+
+	public LeavingEvent() {
+		super("leaving");
+	}
+
+}
diff --git a/src/main/java/org/olat/repository/ui/list/RepositoryEntryDetailsController.java b/src/main/java/org/olat/repository/ui/list/RepositoryEntryDetailsController.java
index 02efe9d0f1f..6c502293768 100644
--- a/src/main/java/org/olat/repository/ui/list/RepositoryEntryDetailsController.java
+++ b/src/main/java/org/olat/repository/ui/list/RepositoryEntryDetailsController.java
@@ -26,6 +26,8 @@ import java.util.Map;
 
 import org.olat.NewControllerFactory;
 import org.olat.admin.restapi.RestapiAdminController;
+import org.olat.basesecurity.GroupRoles;
+import org.olat.core.commons.persistence.DBFactory;
 import org.olat.core.commons.services.commentAndRating.CommentAndRatingDefaultSecurityCallback;
 import org.olat.core.commons.services.commentAndRating.CommentAndRatingSecurityCallback;
 import org.olat.core.commons.services.commentAndRating.manager.UserRatingsDAO;
@@ -47,6 +49,8 @@ import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController;
+import org.olat.core.gui.control.generic.modal.DialogBoxController;
+import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory;
 import org.olat.core.helpers.Settings;
 import org.olat.core.id.OLATResourceable;
 import org.olat.core.id.Roles;
@@ -56,6 +60,8 @@ import org.olat.core.util.StringHelper;
 import org.olat.core.util.Util;
 import org.olat.core.util.coordinate.CoordinatorManager;
 import org.olat.core.util.filter.FilterFactory;
+import org.olat.core.util.mail.MailPackage;
+import org.olat.core.util.mail.MailerResult;
 import org.olat.core.util.resource.OresHelper;
 import org.olat.core.util.vfs.VFSContainer;
 import org.olat.core.util.vfs.VFSContainerMapper;
@@ -71,8 +77,10 @@ import org.olat.group.BusinessGroupService;
 import org.olat.group.model.SearchBusinessGroupParams;
 import org.olat.login.LoginModule;
 import org.olat.repository.CatalogEntry;
+import org.olat.repository.LeavingStatusList;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryRef;
+import org.olat.repository.RepositoryManager;
 import org.olat.repository.RepositoryModule;
 import org.olat.repository.RepositoryService;
 import org.olat.repository.handlers.RepositoryHandler;
@@ -102,10 +110,11 @@ import org.springframework.beans.factory.annotation.Autowired;
  */
 public class RepositoryEntryDetailsController extends FormBasicController {
 	
-	protected FormLink markLink, commentsLink, startLink;
+	protected FormLink markLink, commentsLink, startLink, leaveLink;
 	private RatingWithAverageFormItem ratingEl;
 	
 	private CloseableModalController cmc;
+	private DialogBoxController leaveDialogBox;
 	private UserCommentsController commentsCtrl;
 	
 	protected RepositoryEntry entry;
@@ -129,6 +138,8 @@ public class RepositoryEntryDetailsController extends FormBasicController {
 	@Autowired
 	protected RepositoryModule repositoryModule;
 	@Autowired
+	protected RepositoryManager repositoryManager;
+	@Autowired
 	protected RepositoryService repositoryService;
 	@Autowired
 	protected BusinessGroupService businessGroupService;
@@ -286,9 +297,12 @@ public class RepositoryEntryDetailsController extends FormBasicController {
 			}
 			
 			//load memberships
-			boolean isMember = repositoryService.isMember(getIdentity(), entry);
+			List<String> memberRoles = repositoryService.getRoles(getIdentity(), entry);
             List<Long> authorKeys = repositoryService.getAuthors(entry);
             boolean isAuthor = false;
+            boolean isMember = memberRoles.contains(GroupRoles.owner.name())
+            		|| memberRoles.contains(GroupRoles.coach.name())
+            		|| memberRoles.contains(GroupRoles.participant.name());
 			if (isMember) {
 				isAuthor = authorKeys.contains(getIdentity().getKey());
 				layoutCont.contextPut("isEntryAuthor", new Boolean(isAuthor));
@@ -297,6 +311,11 @@ public class RepositoryEntryDetailsController extends FormBasicController {
             Roles roles = ureq.getUserSession().getRoles();
 			layoutCont.contextPut("roles", roles);
 
+			if(memberRoles.contains(GroupRoles.participant.name()) && repositoryService.isParticipantAllowedToLeave(entry)) {
+				leaveLink = uifactory.addFormLink("sign.out", "leave", "sign.out", null, formLayout, Link.LINK);
+				leaveLink.setIconLeftCSS("o_icon o_icon_sign_out");
+			}
+
 			//access control
 			String accessI18n = null;
 			List<PriceMethod> types = new ArrayList<PriceMethod>();
@@ -478,6 +497,11 @@ public class RepositoryEntryDetailsController extends FormBasicController {
 				updateComments(commentsCtrl.getNumOfComments());
 			}
 			cleanUp();
+		} else if(leaveDialogBox == source) {
+			if (DialogBoxUIFactory.isYesEvent(event) || DialogBoxUIFactory.isOkEvent(event)) {
+				doLeave();
+				fireEvent(ureq, new LeavingEvent());
+			}
 		}
 		super.event(ureq, source, event);
 	}
@@ -519,6 +543,8 @@ public class RepositoryEntryDetailsController extends FormBasicController {
 			} else if("owner".equals(cmd)) {
 				Long ownerKey = (Long)link.getUserObject();
 				doOpenVisitCard(ureq, ownerKey);
+			} else if("leave".equals(cmd)) {
+				doConfirmLeave(ureq);
 			}
 		} else if(ratingEl == source && event instanceof RatingFormEvent) {
 			RatingFormEvent ratingEvent = (RatingFormEvent)event;
@@ -527,6 +553,32 @@ public class RepositoryEntryDetailsController extends FormBasicController {
 		super.formInnerEvent(ureq, source, event);
 	}
 	
+	protected void doConfirmLeave(UserRequest ureq) {
+		String reName = StringHelper.escapeHtml(entry.getDisplayname());
+		String title = translate("sign.out");
+		String text = translate("sign.out.dialog.text", reName);
+		leaveDialogBox = activateYesNoDialog(ureq, title, text, leaveDialogBox);
+	}
+	
+	protected void doLeave() {
+		MailerResult result = new MailerResult();
+		MailPackage reMailing = new MailPackage(result, getWindowControl().getBusinessControl().getAsString(), true);
+		LeavingStatusList status = new LeavingStatusList();
+		//leave course
+		repositoryManager.leave(getIdentity(), entry, status, reMailing);
+		//leave groups
+		businessGroupService.leave(getIdentity(), entry, status, reMailing);
+		DBFactory.getInstance().commit();//make sur all changes are committed
+		
+		if(status.isWarningManagedGroup() || status.isWarningManagedCourse()) {
+			showWarning("sign.out.warning.managed");
+		} else if(status.isWarningGroupWithMultipleResources()) {
+			showWarning("sign.out.warning.mutiple.resources");
+		} else {
+			showInfo("sign.out.success", new String[]{ entry.getDisplayname() });
+		}
+	}
+	
 	protected void doStart(UserRequest ureq) {
 		try {
 			String businessPath = "[RepositoryEntry:" + entry.getKey() + "]";
diff --git a/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java b/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java
index 20db06f33df..8ffa3b7d23b 100644
--- a/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java
+++ b/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java
@@ -430,6 +430,11 @@ public class RepositoryEntryListController extends FormBasicController
 				searchParams.setAuthor(null);
 				searchParams.setText(null);
 			}
+		} else if(detailsCtrl == source) {
+			if(event instanceof LeavingEvent) {
+				stackPanel.popUpToController(this);
+				tableEl.reset();
+			}
 		}
 		super.event(ureq, source, event);
 	}
diff --git a/src/main/java/org/olat/repository/ui/list/_content/details.html b/src/main/java/org/olat/repository/ui/list/_content/details.html
index 4e007909b39..4eb2190e541 100644
--- a/src/main/java/org/olat/repository/ui/list/_content/details.html
+++ b/src/main/java/org/olat/repository/ui/list/_content/details.html
@@ -144,6 +144,12 @@
 							</td>
 						</tr>
 						#end
+						#if($r.available("sign.out"))
+						<tr class="o_signout">					
+							<th></th>
+							<td>$r.render("sign.out")</td>
+						</tr>
+						#end
 					</tbody>
 					</table>
 				</div>
diff --git a/src/main/java/org/olat/restapi/repository/course/CoursesWebService.java b/src/main/java/org/olat/restapi/repository/course/CoursesWebService.java
index eafc888f7f1..13654edc543 100644
--- a/src/main/java/org/olat/restapi/repository/course/CoursesWebService.java
+++ b/src/main/java/org/olat/restapi/repository/course/CoursesWebService.java
@@ -67,6 +67,8 @@ import org.olat.course.config.CourseConfig;
 import org.olat.course.nodes.CourseNode;
 import org.olat.course.tree.CourseEditorTreeNode;
 import org.olat.repository.RepositoryEntry;
+import org.olat.repository.RepositoryEntryAllowToLeaveOptions;
+import org.olat.repository.RepositoryEntryManagedFlag;
 import org.olat.repository.RepositoryManager;
 import org.olat.repository.RepositoryService;
 import org.olat.repository.handlers.RepositoryHandler;
@@ -444,6 +446,8 @@ public class CoursesWebService {
 			} else {
 				preparedEntry.setAccess(access);
 			}
+			preparedEntry.setAllowToLeaveOption(src.getAllowToLeaveOption());
+
 			repositoryService.update(preparedEntry);
 			
 			// copy image if available
@@ -520,6 +524,11 @@ public class CoursesWebService {
 		addedEntry.setExternalId(externalId);
 		addedEntry.setExternalRef(externalRef);
 		addedEntry.setManagedFlagsString(managedFlags);
+		if(RepositoryEntryManagedFlag.isManaged(addedEntry, RepositoryEntryManagedFlag.membersmanagement)) {
+			addedEntry.setAllowToLeaveOption(RepositoryEntryAllowToLeaveOptions.never);
+		} else {
+			addedEntry.setAllowToLeaveOption(RepositoryEntryAllowToLeaveOptions.atAnyTime);//default
+		}
 		return addedEntry;//!!!no update at this point
 	}
 	
diff --git a/src/main/resources/database/mysql/alter_10_1_0_to_10_2_0.sql b/src/main/resources/database/mysql/alter_10_1_0_to_10_2_0.sql
index f05ab0887e8..38d26bb720f 100644
--- a/src/main/resources/database/mysql/alter_10_1_0_to_10_2_0.sql
+++ b/src/main/resources/database/mysql/alter_10_1_0_to_10_2_0.sql
@@ -53,3 +53,6 @@ alter table o_as_mode_course_to_group add constraint as_modetogroup_mode_idx for
 
 alter table o_as_mode_course_to_area add constraint as_modetoarea_area_idx foreign key (fk_area_id) references o_gp_bgarea (area_id);
 alter table o_as_mode_course_to_area add constraint as_modetoarea_mode_idx foreign key (fk_assessment_mode_id) references o_as_mode_course (id);
+
+
+alter table o_repositoryentry add column allowtoleave varchar(16);
diff --git a/src/main/resources/database/mysql/setupDatabase.sql b/src/main/resources/database/mysql/setupDatabase.sql
index 9e51ec27b10..ac878825d8e 100644
--- a/src/main/resources/database/mysql/setupDatabase.sql
+++ b/src/main/resources/database/mysql/setupDatabase.sql
@@ -318,6 +318,7 @@ create table if not exists o_repositoryentry (
    accesscode integer not null default 0,
    membersonly bit default 0,
    statuscode integer,
+   allowtoleave varchar(16),
    canlaunch bit not null,
    candownload bit not null,
    cancopy bit not null,
diff --git a/src/main/resources/database/oracle/alter_10_1_0_to_10_2_0.sql b/src/main/resources/database/oracle/alter_10_1_0_to_10_2_0.sql
index 2ca62b1b02c..4ea7d27979d 100644
--- a/src/main/resources/database/oracle/alter_10_1_0_to_10_2_0.sql
+++ b/src/main/resources/database/oracle/alter_10_1_0_to_10_2_0.sql
@@ -53,3 +53,5 @@ alter table o_as_mode_course_to_area add constraint as_modetoarea_mode_idx forei
 create index idx_as_modetoarea_area_idx on o_as_mode_course_to_area (fk_area_id);
 create index idx_as_modetoarea_mode_idx on o_as_mode_course_to_area (fk_assessment_mode_id);
 
+
+alter table o_repositoryentry add allowtoleave varchar2(16 char);
\ No newline at end of file
diff --git a/src/main/resources/database/oracle/setupDatabase.sql b/src/main/resources/database/oracle/setupDatabase.sql
index 60e3fac26a4..a32cdb8d57d 100644
--- a/src/main/resources/database/oracle/setupDatabase.sql
+++ b/src/main/resources/database/oracle/setupDatabase.sql
@@ -371,6 +371,7 @@ CREATE TABLE o_repositoryentry (
   accesscode number(11) NOT NULL,
   membersonly number default 0,
   statuscode number(11),
+  allowtoleave varchar2(16 char),
   canlaunch number NOT NULL,
   candownload number NOT NULL,
   cancopy number NOT NULL,
diff --git a/src/main/resources/database/postgresql/alter_10_1_0_to_10_2_0.sql b/src/main/resources/database/postgresql/alter_10_1_0_to_10_2_0.sql
index 8d5c7b8a926..d241ba99af0 100644
--- a/src/main/resources/database/postgresql/alter_10_1_0_to_10_2_0.sql
+++ b/src/main/resources/database/postgresql/alter_10_1_0_to_10_2_0.sql
@@ -53,3 +53,5 @@ alter table o_as_mode_course_to_area add constraint as_modetoarea_mode_idx forei
 create index idx_as_modetoarea_area_idx on o_as_mode_course_to_area (fk_area_id);
 create index idx_as_modetoarea_mode_idx on o_as_mode_course_to_area (fk_assessment_mode_id);
 
+
+alter table o_repositoryentry add column allowtoleave varchar(16);
\ No newline at end of file
diff --git a/src/main/resources/database/postgresql/setupDatabase.sql b/src/main/resources/database/postgresql/setupDatabase.sql
index 6db989b954d..c49b999046a 100644
--- a/src/main/resources/database/postgresql/setupDatabase.sql
+++ b/src/main/resources/database/postgresql/setupDatabase.sql
@@ -316,6 +316,7 @@ create table o_repositoryentry (
    accesscode int4 not null,
    membersonly boolean default false,
    statuscode int4,
+   allowtoleave varchar(16),
    canlaunch bool not null,
    candownload bool not null,
    cancopy bool not null,
diff --git a/src/main/webapp/static/themes/light/modules/_icons.scss b/src/main/webapp/static/themes/light/modules/_icons.scss
index 6aebfda428c..71bf4b3ab14 100644
--- a/src/main/webapp/static/themes/light/modules/_icons.scss
+++ b/src/main/webapp/static/themes/light/modules/_icons.scss
@@ -195,6 +195,7 @@ $fa-css-prefix: "o_icon" !default;
 .o_icon_share:before { content: $fa-var-share;}
 .o_icon_show_more:before { content: $fa-var-toggle-down; }
 .o_icon_show_less:before { content: $fa-var-toggle-up; }
+.o_icon_sign_out:before { content: $fa-var-sign-out; }
 .o_icon_spacer:before { content: $fa-var-arrows-h; }
 .o_icon_split:before { content: $fa-var-unlink;}
 .o_icon_sort:before { content: $fa-var-sort;}
diff --git a/src/main/webapp/static/themes/light/theme.css b/src/main/webapp/static/themes/light/theme.css
index 5b82ca60c3e..009a1d366fb 100644
--- a/src/main/webapp/static/themes/light/theme.css
+++ b/src/main/webapp/static/themes/light/theme.css
@@ -58,7 +58,7 @@ fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%
 @media (max-width: 767px){.hidden-xs{display:none !important}}@media (min-width: 768px) and (max-width: 991px){.hidden-sm{display:none !important}}@media (min-width: 992px) and (max-width: 1199px){.hidden-md{display:none !important}}@media (min-width: 1200px){.hidden-lg{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}}.visible-print-block{display:none !important}@media print{.visible-print-block{display:block !important}}
 .visible-print-inline{display:none !important}@media print{.visible-print-inline{display:inline !important}}
 .visible-print-inline-block{display:none !important}@media print{.visible-print-inline-block{display:inline-block !important}}
-@media print{.hidden-print{display:none !important}}body .modal{position:absolute;overflow:visible}body div.tooltip-inner{max-width:400px}body div.popover{max-width:450px}body .modal-body.alert{border-radius:0}body .progress{margin-bottom:0}.panel-body:nth-child(n+2){border-top:1px solid #ddd}#o_ajax_busy_backdrop{bottom:0;z-index:1020}.form-control-feedback{top:10px}.form-horizontal .has-feedback .form-control-feedback{top:10px}.btn.btn-primary.o_disabled{color:#fff !important}body .progress-bar[aria-valuenow="1"],body .progress-bar[aria-valuenow="2"]{min-width:1px}@font-face{font-family:'openolat';src:url("../light/fonts/openolat/openolat.eot?4yacgg");src:url("../light/fonts/openolat/openolat.eot?#iefix4yacgg") format("embedded-opentype"),url("../light/fonts/openolat/openolat.woff?4yacgg") format("woff"),url("../light/fonts/openolat/openolat.ttf?4yacgg") format("truetype"),url("../light/fonts/openolat/openolat.svg?4yacgg#openolat") format("svg");font-weight:normal;font-style:normal}@font-face{font-family:'FontAwesome';src:url("../../font-awesome/fonts/fontawesome-webfont.eot?v=4.2.0");src:url("../../font-awesome/fonts/fontawesome-webfont.eot?#iefix&v=4.2.0") format("embedded-opentype"),url("../../font-awesome/fonts/fontawesome-webfont.woff?v=4.2.0") format("woff"),url("../../font-awesome/fonts/fontawesome-webfont.ttf?v=4.2.0") format("truetype"),url("../../font-awesome/fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.o_icon{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.o_icon-lg{font-size:1.33333em;line-height:0.75em;vertical-align:-15%}.o_icon-2x{font-size:2em}.o_icon-3x{font-size:3em}.o_icon-4x{font-size:4em}.o_icon-5x{font-size:5em}.o_icon-fw{width:1.28571em;text-align:center}.o_icon-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.o_icon-ul>li{position:relative}.o_icon-li{position:absolute;left:-2.14286em;width:2.14286em;top:0.14286em;text-align:center}.o_icon-li.o_icon-lg{left:-1.85714em}.o_icon-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.o_icon.pull-left{margin-right:.3em}.o_icon.pull-right{margin-left:.3em}.o_icon-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.o_icon-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.o_icon-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.o_icon-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.o_icon-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.o_icon-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .o_icon-rotate-90,:root .o_icon-rotate-180,:root .o_icon-rotate-270,:root .o_icon-flip-horizontal,:root .o_icon-flip-vertical{filter:none}.o_icon-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.o_icon-stack-1x,.o_icon-stack-2x{position:absolute;left:0;width:100%;text-align:center}.o_icon-stack-1x{line-height:inherit}.o_icon-stack-2x{font-size:2em}.o_icon-inverse{color:#fff}.o_icon_accessibility:before{content:"\f193"}.o_icon_actions:before{content:"\f085"}.o_icon_archive_tool:before{content:"\f019"}.o_icon_assessment_mode:before{content:"\f044"}.o_icon_assessment_tool:before{content:"\f091"}.o_icon_attempt_limit:before{content:"\f021"}.o_icon_accept:before{content:"\f00c";color:#5cb85c}.o_icon_add:before{content:"\f055"}.o_icon_add_search:before{content:"\f00e"}.o_icon_audio:before{content:"\f028"}.o_icon_back:before{content:"\f053"}.o_icon_back_history:before{content:"\f1da"}.o_icon_bold:before{content:"\f032"}.o_icon_booking:before{content:"\f07a"}.o_icon_bookmark:before{content:"\f02e";color:#bc2d0c}.o_icon_bookmark_add:before{content:"\f097"}.o_icon_bookmark_header:before{content:"\f02e"}.o_icon_browse:before{content:"\f00e"}.o_icon_browsercheck:before{content:"\f164"}.o_icon_busy:before{content:"\f110"}.o_icon_calendar:before{content:"\f073"}.o_icon_calendar_enabled:before{content:"\f05d"}.o_icon_calendar_disabled:before{content:"\f10c"}.o_icon_calendar:before{content:"\f073"}.o_icon_caret:before{content:"\f0d7"}.o_icon_caret_right:before{content:"\f0da"}.o_icon_catalog:before{content:"\f0e8"}.o_icon_catalog_sub:before{content:"\f07b"}.o_icon_certificate:before{content:"\f0a3"}.o_icon_chat:before{content:"\f0e5"}.o_icon_check:before{content:"\f00c"}.o_icon_check_off:before{content:"\f096"}.o_icon_check_on:before{content:"\f046"}.o_icon_checkbox:before{content:"\f096"}.o_icon_checkbox_checked:before{content:"\f14a"}.o_icon_cleanup:before{content:"\f0f9"}.o_icon_close:before{content:"\f00d"}.o_icon_close_resource:before{content:"\f011"}.o_icon_close_tab:before{content:"\f00d"}.o_icon_close_tool:before{content:"\f00d"}.o_icon_close_tree:before{content:"\f0d7"}.o_icon_close_togglebox:before,.o_togglebox_wrapper .o_opener.o_in i:before{content:"\f0d7"}.o_icon_code:before{content:"\f121"}.o_icon_color_picker:before{content:"\f043"}.o_icon_copy:before{content:"\f0c5"}.o_icon_courseareas:before{content:"\f1db"}.o_icon_coursedb:before{content:"\f1c0"}.o_icon_courseeditor:before{content:"\f044"}.o_icon_coursefolder:before{content:"\f114"}.o_icon_courserun:before{content:"\f1b2"}.o_icon_comments:before{content:"\f086"}.o_icon_comments_none:before{content:"\f0e5"}.o_icon_content_popup:before{content:"\f08e"}.o_icon_correct_answer:before{content:"\f00c";color:#5cb85c}.o_icon_customize:before{content:"\f013"}.o_icon_delete_item:before{content:"\f1f8"}.o_icon_delete:before{content:"\f056";color:#A87E7E}.o_icon_details:before{content:"\f0eb"}.o_icon_dev:before{content:"\f188"}.o_icon_disabled:before{content:"\f10c"}.o_icon_download:before{content:"\f019"}.o_icon_edit:before{content:"\f044"}.o_icon_edit_file:before{content:"\f044"}.o_icon_edit_metadata:before{content:"\f013"}.o_icon_enabled:before{content:"\f111"}.o_icon_enlarge:before{content:"\f00e"}.o_icon_eportfolio_add:before{content:"\f12e"}.o_icon_eportfolio_link:before{content:"\f12e"}.o_icon_error:before{content:"\f06a";color:#d9534f}.o_icon_expenditure:before{content:"\f017"}.o_icon_export:before{content:"\f045"}.o_icon_external_link:before{content:"\f08e"}.o_icon_failed:before{content:"\f057"}.o_icon_filter:before{content:"\f0b0"}.o_icon_group:before,.o_BusinessGroup_icon:before{content:"\f0c0"}.o_icon_header:before{content:"\f1dc"}.o_icon_help:before{content:"\f059";cursor:help}.o_icon_home:before{content:"\f015"}.o_icon_impress:before{content:"\f05a"}.o_icon_important:before{content:"\f071";color:#f0ad4e}.o_icon_import:before{content:"\f093"}.o_icon_info:before{content:"\f05a";color:#5bc0de}.o_icon_info_msg:before{content:"\f06a";color:#d9534f}.o_icon_inline_editable:before{content:"\f044"}.o_icon_institution:before{content:"\f19c"}.o_icon_italic:before{content:"\f033"}.o_icon_landingpage:before{content:"\f140"}.o_icon_language:before{content:"\f0ac"}.o_icon_layout:before{content:"\f1c5"}.o_icon_link:before{content:"\f0c1"}.o_icon_link_extern:before{content:"\f08e"}.o_icon_list:before{content:"\f03a"}.o_icon_list_num :before{content:"\f0cb"}.o_icon_lifecycle:before{content:"\f073"}.o_icon_locked:before{content:"\f023"}.o_icon_login:before{content:"\f090"}.o_icon_logout:before{content:"\f08b"}.o_icon_mandatory:before{content:"\f069";color:#f0ad4e}.o_icon_managed:before{content:"\f079";color:#777}.o_icon_manual:before{content:"\f02d";cursor:help}.o_icon_mail:before{content:"\f003"}.o_icon_math:before{content:"\f198"}.o_icon_membersmanagement:before{content:"\f0c0"}.o_icon_menuhandel:before{content:"\f0c9"}.o_icon_message:before{content:"\f0e0"}.o_icon_move:before{content:"\f047"}.o_icon_move_down:before{content:"\f103"}.o_icon_move_left:before{content:"\f100"}.o_icon_move_right:before{content:"\f101"}.o_icon_move_up:before{content:"\f102"}.o_icon_new:before{content:"\f069";color:#5cb85c}.o_icon_new_document:before{content:"\f15c"}.o_icon_new_folder:before{content:"\f07b"}.o_icon_news:before{content:"\f05a"}.o_icon_next:before{content:"\f138"}.o_icon_next_page:before{content:"\f101"}.o_icon_next_toolbar:before{content:"\f0da"}.o_icon_node_after:before{content:"\f175"}.o_icon_node_before:before{content:"\f176"}.o_icon_node_under:before{content:"\f112"}.o_icon_notes:before{content:"\f1e8"}.o_icon_notification:before{content:"\f09e"}.o_icon_open_tree:before{content:"\f0da"}.o_icon_open_togglebox:before,.o_togglebox_wrapper .o_opener i:before{content:"\f0da"}.o_icon_openolat:before,.o_icon_provider_olat:before{content:"\E600";font-family:openolat;font-size:10px}.o_icon_options:before{content:"\f205"}.o_icon_pageing:before{content:"\f141"}.o_icon_passed:before{content:"\f058"}.o_icon_password:before{content:"\f023"}.o_icon_pending:before{content:"\f110"}.o_icon_phone:before{content:"\f095"}.o_icon_post:before{content:"\f0e5"}.o_icon_preview:before{content:"\f06e"}.o_icon_previous:before{content:"\f137"}.o_icon_previous_page:before{content:"\f100"}.o_icon_previous_toolbar:before{content:"\f0d9"}.o_icon_print:before{content:"\f02f"}.o_icon_private:before{content:"\f02f"}.o_icon_provider_adfs:before{content:"\f17a"}.o_icon_provider_facebook:before{content:"\f09a"}.o_icon_provider_google:before{content:"\f0d5"}.o_icon_provider_guest:before{content:"\f1ae"}.o_icon_provider_ldap:before{content:"\f19c"}.o_icon_provider_linkedin:before{content:"\f0e1"}.o_icon_provider_oauth:before{content:"\f0c2"}.o_icon_provider_shibboleth:before{content:"\f19c"}.o_icon_provider_twitter:before{content:"\f099"}.o_icon_publish:before{content:"\f064"}.o_icon_qrcode:before{content:"\f029"}.o_icon_quickview:before{content:"\f06e"}.o_icon_radio_off:before{content:"\f10c"}.o_icon_radio_on:before{content:"\f05d"}.o_icon_rating_on:before,.o_rating .o_rating_items.o_enabled .o_icon:hover:before{content:"\f005"}.o_icon_rating_off:before{content:"\f006"}.o_icon_read:before{content:"\f10c"}.o_icon_readonly:before{content:"\f044";color:red}.o_icon_readwrite:before{content:"\f044"}.o_icon_recycle:before{content:"\f1b8"}.o_icon_refresh:before{content:"\f021"}.o_icon_reject:before{content:"\f00d";color:#d9534f}.o_icon_remove:before{content:"\f00d"}.o_icon_replace:before{content:"\f0c5"}.o_icon_reply:before{content:"\f112"}.o_icon_reply_with_quote:before{content:"\f122"}.o_icon_response_feedback:before{content:"\f021"}.o_icon_review:before{content:"\f06e"}.o_icon_rss:before{content:"\f09e"}.o_icon_rss_unsubscribe:before{content:"\f09e";color:#996633}.o_icon_search:before{content:"\f002"}.o_icon_settings:before{content:"\f085"}.o_icon_share:before{content:"\f064"}.o_icon_show_more:before{content:"\f150"}.o_icon_show_less:before{content:"\f151"}.o_icon_spacer:before{content:"\f07e"}.o_icon_split:before{content:"\f127"}.o_icon_sort:before{content:"\f0dc"}.o_icon_sort_asc:before{content:"\f0de"}.o_icon_sort_desc:before{content:"\f0dd"}.o_icon_sort_menu:before{content:"\f160"}.o_icon_start:before{content:"\f054"}.o_icon_status_available:before{content:"\f111";color:#063}.o_icon_status_chat:before{content:"\f075"}.o_icon_status_dnd:before{content:"\f192";color:#cc3}.o_icon_status_unavailable:before{content:"\f05c";color:#963}.o_icon_statistics_tool:before{content:"\f080"}.o_icon_table:before{content:"\f0ce"}.o_icon_table_large:before{content:"\f009"}.o_icon_tags:before{content:"\f02c"}.o_icon_timelimit:before{content:"\f1e2"}.o_icon_toggle:before{content:"\f111"}.o_icon_to_read:before{content:"\f111"}.o_icon_tool:before{content:"\f013"}.o_icon_tools:before{content:"\f0ad"}.o_icon_top:before{content:"\f077"}.o_icon_translation_item:before{content:"\f1c9"}.o_icon_translation_package:before{content:"\f115"}.o_icon_user:before{content:"\f007"}.o_icon_user_vip:before{content:"\f19d"}.o_icon_user_anonymous:before{content:"\f128"}.o_icon_upload:before{content:"\f093"}.o_icon_version:before{content:"\f1da"}.o_icon_video:before{content:"\f008"}.o_icon_warn:before{content:"\f071";color:#f0ad4e}.o_icon_wizard:before{content:"\f0d0"}.o_CourseModule_icon:before,.o_course_icon:before{content:"\f1b2"}.o_EPStructuredMapTemplate_icon:before{content:"\f12e"}.o_FileResource-BLOG_icon:before{content:"\f0a1"}.o_FileResource-IMSCP_icon:before{content:"\f187"}.o_FileResource-PODCAST_icon:before{content:"\f03d"}.o_FileResource-SHAREDFOLDER:before{content:"\f08e"}.o_FileResource-SCORMCP_icon:before{content:"\f187"}.o_FileResource-SURVEY_icon:before{content:"\f11a"}.o_FileResource-TEST_icon:before{content:"\f044"}.o_FileResource-WIKI_icon:before{content:"\f0ac"}.o_FileResource-SHAREDFOLDER_icon:before{content:"\f115"}.o_FileResource-GLOSSARY_icon:before{content:"\f19d"}.o_FileResource-PDF_icon:before{content:"\f1c1"}.o_FileResource-XLS_icon:before{content:"\f1c3"}.o_FileResource-PPT_icon:before{content:"\f1c4"}.o_FileResource-DOC_icon:before{content:"\f1c2"}.o_FileResource-ANIM_icon:before{content:"\f1c8"}.o_FileResource-IMAGE_icon:before{content:"\f1c5"}.o_FileResource-SOUND_icon:before{content:"\f1c7"}.o_FileResource-MOVIE_icon:before{content:"\f1c8"}.o_FileResource-FILE_icon:before{content:"\f016"}.o_CourseModule_icon_closed:before{content:"\f05e"}.o_sp_icon:before{content:"\f0f6"}.o_st_icon:before{content:"\f1b3"}.o_tu_icon:before{content:"\f08e"}.o_bc_icon:before{content:"\f115"}.o_lti_icon:before{content:"\f08e"}.o_cp_icon:before{content:"\f187"}.o_cp_item:before{content:"\f0f6"}.o_scorm_icon:before{content:"\f187"}.o_en_icon:before{content:"\f090"}.o_fo_icon:before{content:"\f0e6"}.o_co_icon:before{content:"\f003"}.o_infomsg_icon:before{content:"\f05a"}.o_cal_icon:before{content:"\f073"}.o_wiki_icon:before{content:"\f0ac"}.o_podcast_icon:before{content:"\f03d"}.o_blog_icon:before{content:"\f0a1"}.o_ep_icon:before{content:"\f12e"}.o_iqtest_icon:before{content:"\f044"}.o_iqself_icon:before{content:"\f044"}.o_iqsurv_icon:before{content:"\f11a"}.o_ta_icon:before{content:"\f0ae"}.o_ms_icon:before{content:"\f087"}.o_dialog_icon:before{content:"\f0c5"}.o_projectbroker_icon:before{content:"\f10c"}.o_ll_icon:before{content:"\f0c1"}.o_den_icon:before{content:"\f133"}.o_cmembers_icon:before{content:"\f0c0"}.o_cl_icon:before{content:"\f046"}.o_vc_icon:before{content:"\f108"}.o_vitero_icon:before{content:"\f108"}.o_openmeetings_icon:before{content:"\f108"}.o_portlet_infomsg_icon:before{content:"\f05a"}.o_portlet_quickstart_icon:before{content:"\f1d9"}.o_portlet_bookmark_icon:before{content:"\f02e"}.o_portlet_groups_icon:before{content:"\f0c0"}.o_portlet_notes_icon:before{content:"\f1e8"}.o_portlet_noti_icon:before{content:"\f09e"}.o_portlet_eff_icon:before{content:"\f0a3"}.o_portlet_repository_student_icon:before{content:"\f1b3"}.o_portlet_repository_teacher_icon:before{content:"\f19d"}.o_portlet_iframe_icon:before{content:"\f005"}.o_portlet_sysinfo_icon:before{content:"\f0e4"}.o_portlet_dyk_icon:before{content:"\f0eb"}.o_portlet_infomessages_icon:before{content:"\f0e5"}.o_portlet_cal_icon:before{content:"\f073"}.o_portlet_institutions_icon:before{content:"\f19c"}.o_portlet_links_icon:before{content:"\f0c1"}.o_portlet_shibboleth_icon:before{content:"\f090"}.o_icon_qpool:before{content:"\f19c"}.o_icon_pool_private:before{content:"\f096"}.o_icon_pool_public:before{content:"\f046"}.o_icon_pool_my_items:before{content:"\f007"}.o_icon_pool_favorits:before{content:"\f02e"}.o_icon_pool_collection:before{content:"\f03a"}.o_icon_pool_pool:before{content:"\f1e1"}.o_icon_pool_share:before{content:"\f0c0"}.o_forum_message_icon:before{content:"\f0e5"}.o_calendar_icon:before{content:"\f073"}.o_forum_status_thread_icon:before{content:"\f0e6"}.o_forum_status_sticky_closed_icon:before{content:"\f05e"}.o_forum_status_sticky_icon:before{content:"\f086"}.o_forum_status_closed_icon:before{content:"\f05e";color:#a94442}.o_forum_status_opened_icon:before{content:"\f05e";color:#3c763d}.o_forum_status_hidden_icon:before{content:"\f070";color:#a94442}.o_forum_status_visible_icon:before{content:"\f06e";color:#3c763d}.o_mi_qpool_import:before{content:"\f1c0"}.o_mi_qtisection:before{content:"\f1b3"}.o_mi_qtisc:before{content:"\f192"}.o_mi_qtimc:before{content:"\f046"}.o_mi_qtikprim:before{content:"\f14a"}.o_mi_qtifib:before{content:"\f141"}.o_mi_qtiessay:before{content:"\f036"}.o_as_mode_leadtime:before{content:"\f017"}.o_as_mode_assessment:before{content:"\f04b"}.o_as_mode_followup:before{content:"\f05e"}.o_as_mode_closed:before{content:'-'}.o_black_led:before{content:"\f111";color:#337ab7}.o_green_led:before{content:"\f111";color:#5cb85c}.o_yellow_led:before{content:"\f111";color:#f0ad4e}.o_red_led:before{content:"\f111";color:#d9534f}.o_ac_token_icon:before{content:"\f084"}.o_ac_free_icon:before{content:"\f06b"}.o_ac_group_icon:before{content:"\f0c0"}.o_ac_membersonly_icon:before{content:"\f023"}.o_ac_paypal_icon:before{content:"\f1f4"}.o_ac_status_canceled_icon:before{content:"\f068";color:#f0ad4e}.o_ac_status_error_icon:before{content:"\f00d";color:#d9534f}.o_ac_status_new_icon:before{content:"\f069";color:#337ab7}.o_ac_status_succes_icon:before{content:"\f00c";color:#5cb85c}.o_ac_status_waiting_icon:before{content:"\f017";color:#337ab7}.o_ac_order_status_new_icon:before{content:"\f069";color:#337ab7}.o_ac_order_status_prepayment_icon:before{content:"\f0d6";color:#5bc0de}.o_ac_order_status_payed_icon:before{content:"\f00c";color:#5cb85c}.o_ac_order_status_canceled_icon:before{content:"\f068";color:#f0ad4e}.o_ac_order_status_error_icon:before{content:"\f00d";color:#d9534f}.o_ac_order_status_warning_icon:before{content:"\f12a";color:#f0ad4e}.o_scorm_org:before{content:"\f187"}.o_scorm_item:before{content:"\f016"}.o_scorm_completed:before,.o_scorm_passed:before{content:"\f058"}.o_scorm_failed:before{content:"\f071"}.o_scorm_incomplete:before{content:"\f071"}.o_scorm_not_attempted:before{background:none}.o_midpub:before{content:"\f058"}.o_midwarn:before{content:"\f071"}.o_midlock:before{content:"\f023"}.o_miderr:before{content:"\f071"}.o_middel:before{content:"\f12d"}.o_filetype_file:before,.o_filetype_ico:before{content:"\f016"}.o_filetype_folder:before{content:"\f114"}.o_filetype_folder_open:before{content:"\f115"}.o_filetype_zip:before,.o_filetype_gz:before,.o_filetype_tar:before,.o_filetype_tgz:before{content:"\f1c6"}.o_filetype_css:before,.o_filetype_js:before,.o_filetype_java:before,.o_filetype_numbers:before,.o_filetype_ods:before,.o_filetype_xml:before,.o_filetype_xsl:before{content:"\f1c9"}.o_filetype_bat_icon:before,.o_filetype_bat:before,.o_filetype_exe:before,.o_filetype_app:before,.o_filetype_sh:before{content:"\f1c9"}.o_filetype_xls:before,.o_filetype_xlsx:before{content:"\f1c3"}.o_filetype_png:before,.o_filetype_tiff:before,.o_filetype_webp:before,.o_filetype_gif:before,.o_filetype_ico:before,.o_filetype_jpeg:before,.o_filetype_bmp:before,.o_filetype_odg:before,.o_filetype_eps:before,.o_filetype_jpg:before{content:"\f1c5"}.o_filetype_psd:before,.o_filetype_avi:before,.o_filetype_dvi:before,.o_filetype_mp4:before,.o_filetype_m4v:before,.o_filetype_webm:before,.o_filetype_ogg:before,.o_filetype_video:before,.o_filetype_mov:before,.o_filetype_mpeg:before,.o_filetype_mpg:before,.o_filetype_qt:before,.o_filetype_ra:before,.o_filetype_ram:before,.o_filetype_swf:before,.o_filetype_flv:before{content:"\f1c8"}.o_filetype_midi:before,.o_filetype_audio:before,.o_filetype_mp3:before,.o_filetype_m3u:before,.o_filetype_wav:before{content:"\f1c7"}.o_filetype_ps:before,.o_filetype_pdf:before{content:"\f1c1"}.o_filetype_key:before,.o_filetype_odp:before,.o_filetype_ppt:before,.o_filetype_pptx:before{content:"\f1c4"}.o_filetype_odf:before,.o_filetype_rtf:before,.o_filetype_readme:before,.o_filetype_README:before,.o_filetype_log:before,.o_filetype_txt:before,.o_filetype_htm:before,.o_filetype_html:before{content:"\f0f6"}.o_filetype_odt:before,.o_filetype_pages:before,.o_filetype_doc:before,.o_filetype_docx:before{content:"\f1c2"}.o_icon_share_social:before{content:"\f14d"}.o_icon_apple:before{content:"\f179"}.o_icon_facebook:before{content:"\f082"}.o_icon_twitter:before{content:"\f081"}.o_icon_google:before{content:"\f0d4"}.o_icon_delicious:before{content:"\f1a5"}.o_icon_digg:before{content:"\f1a6"}.o_icon_mailto:before{content:"\f199"}.o_icon_link:before{content:"\f0c1"}.o_icon_yahoo:before{content:"\f19e"}a.o_icon:hover,a.o_icon:focus{text-decoration:none}img.o_emoticons_angel{background:url(../light/images/emoticons/smiley-angel.png);width:16px;height:16px}img.o_emoticons_angry{background:url(../light/images/emoticons/smiley-mad.png);width:16px;height:16px}img.o_emoticons_blushing{background:url(../light/images/emoticons/smiley-red.png);width:16px;height:16px}img.o_emoticons_confused{background:url(../light/images/emoticons/smiley-confuse.png);width:16px;height:16px}img.o_emoticons_cool{background:url(../light/images/emoticons/smiley-cool.png);width:16px;height:16px}img.o_emoticons_cry{background:url(../light/images/emoticons/smiley-cry.png);width:16px;height:16px}img.o_emoticons_devil{background:url(../light/images/emoticons/smiley-evil.png);width:16px;height:16px}img.o_emoticons_grin{background:url(../light/images/emoticons/smiley-grin.png);width:16px;height:16px}img.o_emoticons_kiss{background:url(../light/images/emoticons/smiley-kiss.png);width:16px;height:16px}img.o_emoticons_ohoh{background:url(../light/images/emoticons/smiley-eek.png);width:16px;height:16px}img.o_emoticons_sad{background:url(../light/images/emoticons/smiley-sad.png);width:16px;height:16px}img.o_emoticons_sick{background:url(../light/images/emoticons/smiley-sad-blue.png);width:16px;height:16px}img.o_emoticons_smile{background:url(../light/images/emoticons/smiley.png);width:16px;height:16px}img.o_emoticons_tongue{background:url(../light/images/emoticons/smiley-razz.png);width:16px;height:16px}img.o_emoticons_ugly{background:url(../light/images/emoticons/smiley-money.png);width:16px;height:16px}img.o_emoticons_weird{background:url(../light/images/emoticons/smiley-nerd.png);width:16px;height:16px}img.o_emoticons_wink{background:url(../light/images/emoticons/smiley-wink.png);width:16px;height:16px}img.o_emoticons_worried{background:url(../light/images/emoticons/smiley-roll-blue.png);width:16px;height:16px}img.o_emoticons_up{background:url(../light/images/emoticons/thumb-up.png);width:16px;height:16px}img.o_emoticons_down{background:url(../light/images/emoticons/thumb.png);width:16px;height:16px}.o_block_bottom,.o_block,.o_button_group,.o_block_with_datecomp .o_content,.o_course_run .o_toc .o_entry,.o_header_with_buttons,.o_search_result{margin-bottom:1em}.o_block_top,.o_block,.o_button_group,.o_block_with_datecomp .o_content,.o_course_run .o_toc .o_entry{margin-top:1em}.o_block_large_bottom,.o_block_large,.o_block_with_datecomp,.o_login .o_login_footer_wrapper,.o_portlet{margin-bottom:2em}.o_block_large_top,.o_block_large,.o_block_with_datecomp,.o_login .o_login_footer_wrapper,.o_portlet{margin-top:2em}.o_scrollblock{overflow-x:auto;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;-webkit-overflow-scrolling:touch}.o_button_group{text-align:center}.o_button_group a,.o_button_group input,.o_button_group button,.o_button_group .btn-group{margin-right:5px;margin-bottom:0.5em}.o_button_group a:last-child,.o_button_group input:last-child,.o_button_group button:last-child,.o_button_group .btn-group:last-child{margin-right:0}.o_button_group .btn-group a,.o_button_group .btn-group input,.o_button_group .btn-group button{margin-right:0;margin-bottom:0}.o_button_group .dropdown-menu{text-align:left}.o_button_group_left{text-align:left}.o_button_group_right{text-align:right}.o_button_group_top{margin-top:0}.o_header_with_buttons:before,.o_header_with_buttons:after{content:" ";display:table}.o_header_with_buttons:after{clear:both}.o_header_with_buttons h1,.o_header_with_buttons h3,.o_header_with_buttons h4,.o_header_with_buttons .o_cal .fc-header-title h2,.o_cal .fc-header-title .o_header_with_buttons h2{display:inline-block}.o_header_with_buttons .o_button_group{margin-top:10px;margin-bottom:0;float:right}.panel-heading.o_header_with_buttons{margin-bottom:0}.o_xsmall{font-size:12px}.o_small,.o_comments .o_comment_wrapper h5,.o_comments .o_comment_wrapper .o_comment,.o_bc_meta,.tooltip,.o_htmleditor .o_metadata .o_lastmodified,.o_noti,.o_block_with_datecomp .o_meta,.o_togglebox_wrapper div.o_togglebox_content .o_hide,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_state,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_score,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_bookings .o_label,.o_course_run .o_toc .o_entry{font-size:12px}.o_large{font-size:18px}.o_xlarge{font-size:18px}.o_disabled{color:#777 !important;cursor:default}.o_disabled:hover{color:#777 !important}.o_dimmed{opacity:0.4;filter:alpha(opacity=40)}.o_selected{font-weight:bold}.o_deleted{text-decoration:line-through}.o_clickable{cursor:pointer}.o_ochre{color:#c8a959}.o_blue{color:#12223F}.o_undecorated:hover,.o_undecorated:focus,.o_disabled:hover,#o_main_wrapper #o_toplink:hover,#o_footer_powered a:hover,#o_share a:hover,#o_share_social_container a:hover,.o_toolbar .o_tools_container a:hover,.o_button_toggle:hover,.o_im_message_group .o_im_from:hover,.o_noti .o_label:hover,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_social .o_comments:hover,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_start:hover,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_book:hover,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_details:hover,.o_coursetable.o_rendertype_custom .o_table_row .o_meta .o_title a:hover,.o_catalog .o_level .o_meta .o_title a:hover,.o_catalog .o_sublevels .o_sublevel .o_meta .o_title a:hover,.o_repo_details .o_social .o_comments:hover,.o_login .o_login_register:hover,.o_disabled:focus,#o_main_wrapper #o_toplink:focus,#o_footer_powered a:focus,#o_share a:focus,#o_share_social_container a:focus,.o_toolbar .o_tools_container a:focus,.o_button_toggle:focus,.o_im_message_group .o_im_from:focus,.o_noti .o_label:focus,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_social .o_comments:focus,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_start:focus,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_book:focus,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_details:focus,.o_coursetable.o_rendertype_custom .o_table_row .o_meta .o_title a:focus,.o_catalog .o_level .o_meta .o_title a:focus,.o_catalog .o_sublevels .o_sublevel .o_meta .o_title a:focus,.o_repo_details .o_social .o_comments:focus,.o_login .o_login_register:focus{text-decoration:none}.o_copy_code{overflow-x:auto;overflow-y:auto;font-family:Menlo,Monaco,Consolas,"Courier New",monospace;padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;white-space:nowrap;border-radius:4px}.o_nowrap{white-space:nowrap}.o_titled_wrapper .o_content{margin-top:20px}.o_video{display:inline-block;max-width:100%;height:auto}.o_image{display:inline-block;max-width:100%;height:auto}.o_with_hyphens{-webkit-hyphens:auto;-moz-hyphens:auto;-ms-hyphens:auto;hyphens:auto}h1{color:#337ab7}h2{color:#337ab7}h3{color:#337ab7}h4,.o_cal .fc-header-title h2{color:#337ab7}h5{color:#337ab7}h5{color:#337ab7}fieldset legend{color:#333}html{position:relative;min-height:100%}body{min-height:100%;margin-bottom:80px}#o_main_wrapper{background:#fff;z-index:3}#o_main_wrapper #o_main_container{background:#fff}#o_main_wrapper #o_main_container #o_main_left{float:left;z-index:2;position:relative;background:#fff}#o_main_wrapper #o_main_container #o_main_left #o_main_left_content{padding:0 0 0 15px}#o_main_wrapper #o_main_container #o_main_left #o_main_left_toggle{position:absolute;display:none;right:0;top:70px;margin-right:-30px;font-size:25px;line-height:35px;text-align:center;width:30px;height:35px;z-index:3;border:1px solid #ddd;border-left:none;border-bottom-right-radius:4px;border-top-right-radius:4px;background-color:#fbfbfb;-webkit-box-shadow:2px 0px 4px 1px rgba(0,0,0,0.15);box-shadow:2px 0px 4px 1px rgba(0,0,0,0.15);color:#337ab7}#o_main_wrapper #o_main_container #o_main_left.o_offcanvas{background:#fbfbfb;-webkit-box-shadow:0px 0px 6px 1px rgba(0,0,0,0.2);box-shadow:0px 0px 6px 1px rgba(0,0,0,0.2);min-width:250px}#o_main_wrapper #o_main_container #o_main_left.o_offcanvas #o_main_left_content{padding:0 0 0 0}#o_main_wrapper #o_main_container #o_main_right{float:right;z-index:2;position:relative;background:inherit}#o_main_wrapper #o_main_container #o_main_right #o_main_right_content{padding:0 15px 0 0}#o_main_wrapper #o_main_container #o_main_center{position:relative;z-index:1;background:inherit}#o_main_wrapper #o_main_container #o_main_center h2:first-child{margin-top:0}@media screen and (max-width: 767px){#o_main_wrapper #o_main_container #o_main_center{margin-left:0 !important}}#o_main_wrapper #o_main_container #o_main_center #o_main_center_content{padding:0 15px}#o_main_wrapper #o_main_container #o_main_center #o_main_center_content #o_main_center_content_inner{padding-bottom:15px}#o_main_wrapper #o_toplink{position:absolute;bottom:0;right:15px;text-align:center;z-index:3}@media (max-width: 767px){#o_main_wrapper #o_main_container #o_main_center #o_main_center_content{padding:15px}}
+@media print{.hidden-print{display:none !important}}body .modal{position:absolute;overflow:visible}body div.tooltip-inner{max-width:400px}body div.popover{max-width:450px}body .modal-body.alert{border-radius:0}body .progress{margin-bottom:0}.panel-body:nth-child(n+2){border-top:1px solid #ddd}#o_ajax_busy_backdrop{bottom:0;z-index:1020}.form-control-feedback{top:10px}.form-horizontal .has-feedback .form-control-feedback{top:10px}.btn.btn-primary.o_disabled{color:#fff !important}body .progress-bar[aria-valuenow="1"],body .progress-bar[aria-valuenow="2"]{min-width:1px}@font-face{font-family:'openolat';src:url("../light/fonts/openolat/openolat.eot?4yacgg");src:url("../light/fonts/openolat/openolat.eot?#iefix4yacgg") format("embedded-opentype"),url("../light/fonts/openolat/openolat.woff?4yacgg") format("woff"),url("../light/fonts/openolat/openolat.ttf?4yacgg") format("truetype"),url("../light/fonts/openolat/openolat.svg?4yacgg#openolat") format("svg");font-weight:normal;font-style:normal}@font-face{font-family:'FontAwesome';src:url("../../font-awesome/fonts/fontawesome-webfont.eot?v=4.2.0");src:url("../../font-awesome/fonts/fontawesome-webfont.eot?#iefix&v=4.2.0") format("embedded-opentype"),url("../../font-awesome/fonts/fontawesome-webfont.woff?v=4.2.0") format("woff"),url("../../font-awesome/fonts/fontawesome-webfont.ttf?v=4.2.0") format("truetype"),url("../../font-awesome/fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.o_icon{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.o_icon-lg{font-size:1.33333em;line-height:0.75em;vertical-align:-15%}.o_icon-2x{font-size:2em}.o_icon-3x{font-size:3em}.o_icon-4x{font-size:4em}.o_icon-5x{font-size:5em}.o_icon-fw{width:1.28571em;text-align:center}.o_icon-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.o_icon-ul>li{position:relative}.o_icon-li{position:absolute;left:-2.14286em;width:2.14286em;top:0.14286em;text-align:center}.o_icon-li.o_icon-lg{left:-1.85714em}.o_icon-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.o_icon.pull-left{margin-right:.3em}.o_icon.pull-right{margin-left:.3em}.o_icon-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.o_icon-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.o_icon-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.o_icon-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.o_icon-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.o_icon-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .o_icon-rotate-90,:root .o_icon-rotate-180,:root .o_icon-rotate-270,:root .o_icon-flip-horizontal,:root .o_icon-flip-vertical{filter:none}.o_icon-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.o_icon-stack-1x,.o_icon-stack-2x{position:absolute;left:0;width:100%;text-align:center}.o_icon-stack-1x{line-height:inherit}.o_icon-stack-2x{font-size:2em}.o_icon-inverse{color:#fff}.o_icon_accessibility:before{content:"\f193"}.o_icon_actions:before{content:"\f085"}.o_icon_archive_tool:before{content:"\f019"}.o_icon_assessment_mode:before{content:"\f044"}.o_icon_assessment_tool:before{content:"\f091"}.o_icon_attempt_limit:before{content:"\f021"}.o_icon_accept:before{content:"\f00c";color:#5cb85c}.o_icon_add:before{content:"\f055"}.o_icon_add_search:before{content:"\f00e"}.o_icon_audio:before{content:"\f028"}.o_icon_back:before{content:"\f053"}.o_icon_back_history:before{content:"\f1da"}.o_icon_bold:before{content:"\f032"}.o_icon_booking:before{content:"\f07a"}.o_icon_bookmark:before{content:"\f02e";color:#bc2d0c}.o_icon_bookmark_add:before{content:"\f097"}.o_icon_bookmark_header:before{content:"\f02e"}.o_icon_browse:before{content:"\f00e"}.o_icon_browsercheck:before{content:"\f164"}.o_icon_busy:before{content:"\f110"}.o_icon_calendar:before{content:"\f073"}.o_icon_calendar_enabled:before{content:"\f05d"}.o_icon_calendar_disabled:before{content:"\f10c"}.o_icon_calendar:before{content:"\f073"}.o_icon_caret:before{content:"\f0d7"}.o_icon_caret_right:before{content:"\f0da"}.o_icon_catalog:before{content:"\f0e8"}.o_icon_catalog_sub:before{content:"\f07b"}.o_icon_certificate:before{content:"\f0a3"}.o_icon_chat:before{content:"\f0e5"}.o_icon_check:before{content:"\f00c"}.o_icon_check_off:before{content:"\f096"}.o_icon_check_on:before{content:"\f046"}.o_icon_checkbox:before{content:"\f096"}.o_icon_checkbox_checked:before{content:"\f14a"}.o_icon_cleanup:before{content:"\f0f9"}.o_icon_close:before{content:"\f00d"}.o_icon_close_resource:before{content:"\f011"}.o_icon_close_tab:before{content:"\f00d"}.o_icon_close_tool:before{content:"\f00d"}.o_icon_close_tree:before{content:"\f0d7"}.o_icon_close_togglebox:before,.o_togglebox_wrapper .o_opener.o_in i:before{content:"\f0d7"}.o_icon_code:before{content:"\f121"}.o_icon_color_picker:before{content:"\f043"}.o_icon_copy:before{content:"\f0c5"}.o_icon_courseareas:before{content:"\f1db"}.o_icon_coursedb:before{content:"\f1c0"}.o_icon_courseeditor:before{content:"\f044"}.o_icon_coursefolder:before{content:"\f114"}.o_icon_courserun:before{content:"\f1b2"}.o_icon_comments:before{content:"\f086"}.o_icon_comments_none:before{content:"\f0e5"}.o_icon_content_popup:before{content:"\f08e"}.o_icon_correct_answer:before{content:"\f00c";color:#5cb85c}.o_icon_customize:before{content:"\f013"}.o_icon_delete_item:before{content:"\f1f8"}.o_icon_delete:before{content:"\f056";color:#A87E7E}.o_icon_details:before{content:"\f0eb"}.o_icon_dev:before{content:"\f188"}.o_icon_disabled:before{content:"\f10c"}.o_icon_download:before{content:"\f019"}.o_icon_edit:before{content:"\f044"}.o_icon_edit_file:before{content:"\f044"}.o_icon_edit_metadata:before{content:"\f013"}.o_icon_enabled:before{content:"\f111"}.o_icon_enlarge:before{content:"\f00e"}.o_icon_eportfolio_add:before{content:"\f12e"}.o_icon_eportfolio_link:before{content:"\f12e"}.o_icon_error:before{content:"\f06a";color:#d9534f}.o_icon_expenditure:before{content:"\f017"}.o_icon_export:before{content:"\f045"}.o_icon_external_link:before{content:"\f08e"}.o_icon_failed:before{content:"\f057"}.o_icon_filter:before{content:"\f0b0"}.o_icon_group:before,.o_BusinessGroup_icon:before{content:"\f0c0"}.o_icon_header:before{content:"\f1dc"}.o_icon_help:before{content:"\f059";cursor:help}.o_icon_home:before{content:"\f015"}.o_icon_impress:before{content:"\f05a"}.o_icon_important:before{content:"\f071";color:#f0ad4e}.o_icon_import:before{content:"\f093"}.o_icon_info:before{content:"\f05a";color:#5bc0de}.o_icon_info_msg:before{content:"\f06a";color:#d9534f}.o_icon_inline_editable:before{content:"\f044"}.o_icon_institution:before{content:"\f19c"}.o_icon_italic:before{content:"\f033"}.o_icon_landingpage:before{content:"\f140"}.o_icon_language:before{content:"\f0ac"}.o_icon_layout:before{content:"\f1c5"}.o_icon_link:before{content:"\f0c1"}.o_icon_link_extern:before{content:"\f08e"}.o_icon_list:before{content:"\f03a"}.o_icon_list_num :before{content:"\f0cb"}.o_icon_lifecycle:before{content:"\f073"}.o_icon_locked:before{content:"\f023"}.o_icon_login:before{content:"\f090"}.o_icon_logout:before{content:"\f08b"}.o_icon_mandatory:before{content:"\f069";color:#f0ad4e}.o_icon_managed:before{content:"\f079";color:#777}.o_icon_manual:before{content:"\f02d";cursor:help}.o_icon_mail:before{content:"\f003"}.o_icon_math:before{content:"\f198"}.o_icon_membersmanagement:before{content:"\f0c0"}.o_icon_menuhandel:before{content:"\f0c9"}.o_icon_message:before{content:"\f0e0"}.o_icon_move:before{content:"\f047"}.o_icon_move_down:before{content:"\f103"}.o_icon_move_left:before{content:"\f100"}.o_icon_move_right:before{content:"\f101"}.o_icon_move_up:before{content:"\f102"}.o_icon_new:before{content:"\f069";color:#5cb85c}.o_icon_new_document:before{content:"\f15c"}.o_icon_new_folder:before{content:"\f07b"}.o_icon_news:before{content:"\f05a"}.o_icon_next:before{content:"\f138"}.o_icon_next_page:before{content:"\f101"}.o_icon_next_toolbar:before{content:"\f0da"}.o_icon_node_after:before{content:"\f175"}.o_icon_node_before:before{content:"\f176"}.o_icon_node_under:before{content:"\f112"}.o_icon_notes:before{content:"\f1e8"}.o_icon_notification:before{content:"\f09e"}.o_icon_open_tree:before{content:"\f0da"}.o_icon_open_togglebox:before,.o_togglebox_wrapper .o_opener i:before{content:"\f0da"}.o_icon_openolat:before,.o_icon_provider_olat:before{content:"\E600";font-family:openolat;font-size:10px}.o_icon_options:before{content:"\f205"}.o_icon_pageing:before{content:"\f141"}.o_icon_passed:before{content:"\f058"}.o_icon_password:before{content:"\f023"}.o_icon_pending:before{content:"\f110"}.o_icon_phone:before{content:"\f095"}.o_icon_post:before{content:"\f0e5"}.o_icon_preview:before{content:"\f06e"}.o_icon_previous:before{content:"\f137"}.o_icon_previous_page:before{content:"\f100"}.o_icon_previous_toolbar:before{content:"\f0d9"}.o_icon_print:before{content:"\f02f"}.o_icon_private:before{content:"\f02f"}.o_icon_provider_adfs:before{content:"\f17a"}.o_icon_provider_facebook:before{content:"\f09a"}.o_icon_provider_google:before{content:"\f0d5"}.o_icon_provider_guest:before{content:"\f1ae"}.o_icon_provider_ldap:before{content:"\f19c"}.o_icon_provider_linkedin:before{content:"\f0e1"}.o_icon_provider_oauth:before{content:"\f0c2"}.o_icon_provider_shibboleth:before{content:"\f19c"}.o_icon_provider_twitter:before{content:"\f099"}.o_icon_publish:before{content:"\f064"}.o_icon_qrcode:before{content:"\f029"}.o_icon_quickview:before{content:"\f06e"}.o_icon_radio_off:before{content:"\f10c"}.o_icon_radio_on:before{content:"\f05d"}.o_icon_rating_on:before,.o_rating .o_rating_items.o_enabled .o_icon:hover:before{content:"\f005"}.o_icon_rating_off:before{content:"\f006"}.o_icon_read:before{content:"\f10c"}.o_icon_readonly:before{content:"\f044";color:red}.o_icon_readwrite:before{content:"\f044"}.o_icon_recycle:before{content:"\f1b8"}.o_icon_refresh:before{content:"\f021"}.o_icon_reject:before{content:"\f00d";color:#d9534f}.o_icon_remove:before{content:"\f00d"}.o_icon_replace:before{content:"\f0c5"}.o_icon_reply:before{content:"\f112"}.o_icon_reply_with_quote:before{content:"\f122"}.o_icon_response_feedback:before{content:"\f021"}.o_icon_review:before{content:"\f06e"}.o_icon_rss:before{content:"\f09e"}.o_icon_rss_unsubscribe:before{content:"\f09e";color:#996633}.o_icon_search:before{content:"\f002"}.o_icon_settings:before{content:"\f085"}.o_icon_share:before{content:"\f064"}.o_icon_show_more:before{content:"\f150"}.o_icon_show_less:before{content:"\f151"}.o_icon_sign_out:before{content:"\f08b"}.o_icon_spacer:before{content:"\f07e"}.o_icon_split:before{content:"\f127"}.o_icon_sort:before{content:"\f0dc"}.o_icon_sort_asc:before{content:"\f0de"}.o_icon_sort_desc:before{content:"\f0dd"}.o_icon_sort_menu:before{content:"\f160"}.o_icon_start:before{content:"\f054"}.o_icon_status_available:before{content:"\f111";color:#063}.o_icon_status_chat:before{content:"\f075"}.o_icon_status_dnd:before{content:"\f192";color:#cc3}.o_icon_status_unavailable:before{content:"\f05c";color:#963}.o_icon_statistics_tool:before{content:"\f080"}.o_icon_table:before{content:"\f0ce"}.o_icon_table_large:before{content:"\f009"}.o_icon_tags:before{content:"\f02c"}.o_icon_timelimit:before{content:"\f1e2"}.o_icon_toggle:before{content:"\f111"}.o_icon_to_read:before{content:"\f111"}.o_icon_tool:before{content:"\f013"}.o_icon_tools:before{content:"\f0ad"}.o_icon_top:before{content:"\f077"}.o_icon_translation_item:before{content:"\f1c9"}.o_icon_translation_package:before{content:"\f115"}.o_icon_user:before{content:"\f007"}.o_icon_user_vip:before{content:"\f19d"}.o_icon_user_anonymous:before{content:"\f128"}.o_icon_upload:before{content:"\f093"}.o_icon_version:before{content:"\f1da"}.o_icon_video:before{content:"\f008"}.o_icon_warn:before{content:"\f071";color:#f0ad4e}.o_icon_wizard:before{content:"\f0d0"}.o_CourseModule_icon:before,.o_course_icon:before{content:"\f1b2"}.o_EPStructuredMapTemplate_icon:before{content:"\f12e"}.o_FileResource-BLOG_icon:before{content:"\f0a1"}.o_FileResource-IMSCP_icon:before{content:"\f187"}.o_FileResource-PODCAST_icon:before{content:"\f03d"}.o_FileResource-SHAREDFOLDER:before{content:"\f08e"}.o_FileResource-SCORMCP_icon:before{content:"\f187"}.o_FileResource-SURVEY_icon:before{content:"\f11a"}.o_FileResource-TEST_icon:before{content:"\f044"}.o_FileResource-WIKI_icon:before{content:"\f0ac"}.o_FileResource-SHAREDFOLDER_icon:before{content:"\f115"}.o_FileResource-GLOSSARY_icon:before{content:"\f19d"}.o_FileResource-PDF_icon:before{content:"\f1c1"}.o_FileResource-XLS_icon:before{content:"\f1c3"}.o_FileResource-PPT_icon:before{content:"\f1c4"}.o_FileResource-DOC_icon:before{content:"\f1c2"}.o_FileResource-ANIM_icon:before{content:"\f1c8"}.o_FileResource-IMAGE_icon:before{content:"\f1c5"}.o_FileResource-SOUND_icon:before{content:"\f1c7"}.o_FileResource-MOVIE_icon:before{content:"\f1c8"}.o_FileResource-FILE_icon:before{content:"\f016"}.o_CourseModule_icon_closed:before{content:"\f05e"}.o_sp_icon:before{content:"\f0f6"}.o_st_icon:before{content:"\f1b3"}.o_tu_icon:before{content:"\f08e"}.o_bc_icon:before{content:"\f115"}.o_lti_icon:before{content:"\f08e"}.o_cp_icon:before{content:"\f187"}.o_cp_item:before{content:"\f0f6"}.o_scorm_icon:before{content:"\f187"}.o_en_icon:before{content:"\f090"}.o_fo_icon:before{content:"\f0e6"}.o_co_icon:before{content:"\f003"}.o_infomsg_icon:before{content:"\f05a"}.o_cal_icon:before{content:"\f073"}.o_wiki_icon:before{content:"\f0ac"}.o_podcast_icon:before{content:"\f03d"}.o_blog_icon:before{content:"\f0a1"}.o_ep_icon:before{content:"\f12e"}.o_iqtest_icon:before{content:"\f044"}.o_iqself_icon:before{content:"\f044"}.o_iqsurv_icon:before{content:"\f11a"}.o_ta_icon:before{content:"\f0ae"}.o_ms_icon:before{content:"\f087"}.o_dialog_icon:before{content:"\f0c5"}.o_projectbroker_icon:before{content:"\f10c"}.o_ll_icon:before{content:"\f0c1"}.o_den_icon:before{content:"\f133"}.o_cmembers_icon:before{content:"\f0c0"}.o_cl_icon:before{content:"\f046"}.o_vc_icon:before{content:"\f108"}.o_vitero_icon:before{content:"\f108"}.o_openmeetings_icon:before{content:"\f108"}.o_portlet_infomsg_icon:before{content:"\f05a"}.o_portlet_quickstart_icon:before{content:"\f1d9"}.o_portlet_bookmark_icon:before{content:"\f02e"}.o_portlet_groups_icon:before{content:"\f0c0"}.o_portlet_notes_icon:before{content:"\f1e8"}.o_portlet_noti_icon:before{content:"\f09e"}.o_portlet_eff_icon:before{content:"\f0a3"}.o_portlet_repository_student_icon:before{content:"\f1b3"}.o_portlet_repository_teacher_icon:before{content:"\f19d"}.o_portlet_iframe_icon:before{content:"\f005"}.o_portlet_sysinfo_icon:before{content:"\f0e4"}.o_portlet_dyk_icon:before{content:"\f0eb"}.o_portlet_infomessages_icon:before{content:"\f0e5"}.o_portlet_cal_icon:before{content:"\f073"}.o_portlet_institutions_icon:before{content:"\f19c"}.o_portlet_links_icon:before{content:"\f0c1"}.o_portlet_shibboleth_icon:before{content:"\f090"}.o_icon_qpool:before{content:"\f19c"}.o_icon_pool_private:before{content:"\f096"}.o_icon_pool_public:before{content:"\f046"}.o_icon_pool_my_items:before{content:"\f007"}.o_icon_pool_favorits:before{content:"\f02e"}.o_icon_pool_collection:before{content:"\f03a"}.o_icon_pool_pool:before{content:"\f1e1"}.o_icon_pool_share:before{content:"\f0c0"}.o_forum_message_icon:before{content:"\f0e5"}.o_calendar_icon:before{content:"\f073"}.o_forum_status_thread_icon:before{content:"\f0e6"}.o_forum_status_sticky_closed_icon:before{content:"\f05e"}.o_forum_status_sticky_icon:before{content:"\f086"}.o_forum_status_closed_icon:before{content:"\f05e";color:#a94442}.o_forum_status_opened_icon:before{content:"\f05e";color:#3c763d}.o_forum_status_hidden_icon:before{content:"\f070";color:#a94442}.o_forum_status_visible_icon:before{content:"\f06e";color:#3c763d}.o_mi_qpool_import:before{content:"\f1c0"}.o_mi_qtisection:before{content:"\f1b3"}.o_mi_qtisc:before{content:"\f192"}.o_mi_qtimc:before{content:"\f046"}.o_mi_qtikprim:before{content:"\f14a"}.o_mi_qtifib:before{content:"\f141"}.o_mi_qtiessay:before{content:"\f036"}.o_as_mode_leadtime:before{content:"\f017"}.o_as_mode_assessment:before{content:"\f04b"}.o_as_mode_followup:before{content:"\f05e"}.o_as_mode_closed:before{content:'-'}.o_black_led:before{content:"\f111";color:#337ab7}.o_green_led:before{content:"\f111";color:#5cb85c}.o_yellow_led:before{content:"\f111";color:#f0ad4e}.o_red_led:before{content:"\f111";color:#d9534f}.o_ac_token_icon:before{content:"\f084"}.o_ac_free_icon:before{content:"\f06b"}.o_ac_group_icon:before{content:"\f0c0"}.o_ac_membersonly_icon:before{content:"\f023"}.o_ac_paypal_icon:before{content:"\f1f4"}.o_ac_status_canceled_icon:before{content:"\f068";color:#f0ad4e}.o_ac_status_error_icon:before{content:"\f00d";color:#d9534f}.o_ac_status_new_icon:before{content:"\f069";color:#337ab7}.o_ac_status_succes_icon:before{content:"\f00c";color:#5cb85c}.o_ac_status_waiting_icon:before{content:"\f017";color:#337ab7}.o_ac_order_status_new_icon:before{content:"\f069";color:#337ab7}.o_ac_order_status_prepayment_icon:before{content:"\f0d6";color:#5bc0de}.o_ac_order_status_payed_icon:before{content:"\f00c";color:#5cb85c}.o_ac_order_status_canceled_icon:before{content:"\f068";color:#f0ad4e}.o_ac_order_status_error_icon:before{content:"\f00d";color:#d9534f}.o_ac_order_status_warning_icon:before{content:"\f12a";color:#f0ad4e}.o_scorm_org:before{content:"\f187"}.o_scorm_item:before{content:"\f016"}.o_scorm_completed:before,.o_scorm_passed:before{content:"\f058"}.o_scorm_failed:before{content:"\f071"}.o_scorm_incomplete:before{content:"\f071"}.o_scorm_not_attempted:before{background:none}.o_midpub:before{content:"\f058"}.o_midwarn:before{content:"\f071"}.o_midlock:before{content:"\f023"}.o_miderr:before{content:"\f071"}.o_middel:before{content:"\f12d"}.o_filetype_file:before,.o_filetype_ico:before{content:"\f016"}.o_filetype_folder:before{content:"\f114"}.o_filetype_folder_open:before{content:"\f115"}.o_filetype_zip:before,.o_filetype_gz:before,.o_filetype_tar:before,.o_filetype_tgz:before{content:"\f1c6"}.o_filetype_css:before,.o_filetype_js:before,.o_filetype_java:before,.o_filetype_numbers:before,.o_filetype_ods:before,.o_filetype_xml:before,.o_filetype_xsl:before{content:"\f1c9"}.o_filetype_bat_icon:before,.o_filetype_bat:before,.o_filetype_exe:before,.o_filetype_app:before,.o_filetype_sh:before{content:"\f1c9"}.o_filetype_xls:before,.o_filetype_xlsx:before{content:"\f1c3"}.o_filetype_png:before,.o_filetype_tiff:before,.o_filetype_webp:before,.o_filetype_gif:before,.o_filetype_ico:before,.o_filetype_jpeg:before,.o_filetype_bmp:before,.o_filetype_odg:before,.o_filetype_eps:before,.o_filetype_jpg:before{content:"\f1c5"}.o_filetype_psd:before,.o_filetype_avi:before,.o_filetype_dvi:before,.o_filetype_mp4:before,.o_filetype_m4v:before,.o_filetype_webm:before,.o_filetype_ogg:before,.o_filetype_video:before,.o_filetype_mov:before,.o_filetype_mpeg:before,.o_filetype_mpg:before,.o_filetype_qt:before,.o_filetype_ra:before,.o_filetype_ram:before,.o_filetype_swf:before,.o_filetype_flv:before{content:"\f1c8"}.o_filetype_midi:before,.o_filetype_audio:before,.o_filetype_mp3:before,.o_filetype_m3u:before,.o_filetype_wav:before{content:"\f1c7"}.o_filetype_ps:before,.o_filetype_pdf:before{content:"\f1c1"}.o_filetype_key:before,.o_filetype_odp:before,.o_filetype_ppt:before,.o_filetype_pptx:before{content:"\f1c4"}.o_filetype_odf:before,.o_filetype_rtf:before,.o_filetype_readme:before,.o_filetype_README:before,.o_filetype_log:before,.o_filetype_txt:before,.o_filetype_htm:before,.o_filetype_html:before{content:"\f0f6"}.o_filetype_odt:before,.o_filetype_pages:before,.o_filetype_doc:before,.o_filetype_docx:before{content:"\f1c2"}.o_icon_share_social:before{content:"\f14d"}.o_icon_apple:before{content:"\f179"}.o_icon_facebook:before{content:"\f082"}.o_icon_twitter:before{content:"\f081"}.o_icon_google:before{content:"\f0d4"}.o_icon_delicious:before{content:"\f1a5"}.o_icon_digg:before{content:"\f1a6"}.o_icon_mailto:before{content:"\f199"}.o_icon_link:before{content:"\f0c1"}.o_icon_yahoo:before{content:"\f19e"}a.o_icon:hover,a.o_icon:focus{text-decoration:none}img.o_emoticons_angel{background:url(../light/images/emoticons/smiley-angel.png);width:16px;height:16px}img.o_emoticons_angry{background:url(../light/images/emoticons/smiley-mad.png);width:16px;height:16px}img.o_emoticons_blushing{background:url(../light/images/emoticons/smiley-red.png);width:16px;height:16px}img.o_emoticons_confused{background:url(../light/images/emoticons/smiley-confuse.png);width:16px;height:16px}img.o_emoticons_cool{background:url(../light/images/emoticons/smiley-cool.png);width:16px;height:16px}img.o_emoticons_cry{background:url(../light/images/emoticons/smiley-cry.png);width:16px;height:16px}img.o_emoticons_devil{background:url(../light/images/emoticons/smiley-evil.png);width:16px;height:16px}img.o_emoticons_grin{background:url(../light/images/emoticons/smiley-grin.png);width:16px;height:16px}img.o_emoticons_kiss{background:url(../light/images/emoticons/smiley-kiss.png);width:16px;height:16px}img.o_emoticons_ohoh{background:url(../light/images/emoticons/smiley-eek.png);width:16px;height:16px}img.o_emoticons_sad{background:url(../light/images/emoticons/smiley-sad.png);width:16px;height:16px}img.o_emoticons_sick{background:url(../light/images/emoticons/smiley-sad-blue.png);width:16px;height:16px}img.o_emoticons_smile{background:url(../light/images/emoticons/smiley.png);width:16px;height:16px}img.o_emoticons_tongue{background:url(../light/images/emoticons/smiley-razz.png);width:16px;height:16px}img.o_emoticons_ugly{background:url(../light/images/emoticons/smiley-money.png);width:16px;height:16px}img.o_emoticons_weird{background:url(../light/images/emoticons/smiley-nerd.png);width:16px;height:16px}img.o_emoticons_wink{background:url(../light/images/emoticons/smiley-wink.png);width:16px;height:16px}img.o_emoticons_worried{background:url(../light/images/emoticons/smiley-roll-blue.png);width:16px;height:16px}img.o_emoticons_up{background:url(../light/images/emoticons/thumb-up.png);width:16px;height:16px}img.o_emoticons_down{background:url(../light/images/emoticons/thumb.png);width:16px;height:16px}.o_block_bottom,.o_block,.o_button_group,.o_block_with_datecomp .o_content,.o_course_run .o_toc .o_entry,.o_header_with_buttons,.o_search_result{margin-bottom:1em}.o_block_top,.o_block,.o_button_group,.o_block_with_datecomp .o_content,.o_course_run .o_toc .o_entry{margin-top:1em}.o_block_large_bottom,.o_block_large,.o_block_with_datecomp,.o_login .o_login_footer_wrapper,.o_portlet{margin-bottom:2em}.o_block_large_top,.o_block_large,.o_block_with_datecomp,.o_login .o_login_footer_wrapper,.o_portlet{margin-top:2em}.o_scrollblock{overflow-x:auto;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;-webkit-overflow-scrolling:touch}.o_button_group{text-align:center}.o_button_group a,.o_button_group input,.o_button_group button,.o_button_group .btn-group{margin-right:5px;margin-bottom:0.5em}.o_button_group a:last-child,.o_button_group input:last-child,.o_button_group button:last-child,.o_button_group .btn-group:last-child{margin-right:0}.o_button_group .btn-group a,.o_button_group .btn-group input,.o_button_group .btn-group button{margin-right:0;margin-bottom:0}.o_button_group .dropdown-menu{text-align:left}.o_button_group_left{text-align:left}.o_button_group_right{text-align:right}.o_button_group_top{margin-top:0}.o_header_with_buttons:before,.o_header_with_buttons:after{content:" ";display:table}.o_header_with_buttons:after{clear:both}.o_header_with_buttons h1,.o_header_with_buttons h3,.o_header_with_buttons h4,.o_header_with_buttons .o_cal .fc-header-title h2,.o_cal .fc-header-title .o_header_with_buttons h2{display:inline-block}.o_header_with_buttons .o_button_group{margin-top:10px;margin-bottom:0;float:right}.panel-heading.o_header_with_buttons{margin-bottom:0}.o_xsmall{font-size:12px}.o_small,.o_comments .o_comment_wrapper h5,.o_comments .o_comment_wrapper .o_comment,.o_bc_meta,.tooltip,.o_htmleditor .o_metadata .o_lastmodified,.o_noti,.o_block_with_datecomp .o_meta,.o_togglebox_wrapper div.o_togglebox_content .o_hide,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_state,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_score,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_bookings .o_label,.o_course_run .o_toc .o_entry{font-size:12px}.o_large{font-size:18px}.o_xlarge{font-size:18px}.o_disabled{color:#777 !important;cursor:default}.o_disabled:hover{color:#777 !important}.o_dimmed{opacity:0.4;filter:alpha(opacity=40)}.o_selected{font-weight:bold}.o_deleted{text-decoration:line-through}.o_clickable{cursor:pointer}.o_ochre{color:#c8a959}.o_blue{color:#12223F}.o_undecorated:hover,.o_undecorated:focus,.o_disabled:hover,#o_main_wrapper #o_toplink:hover,#o_footer_powered a:hover,#o_share a:hover,#o_share_social_container a:hover,.o_toolbar .o_tools_container a:hover,.o_button_toggle:hover,.o_im_message_group .o_im_from:hover,.o_noti .o_label:hover,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_social .o_comments:hover,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_start:hover,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_book:hover,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_details:hover,.o_coursetable.o_rendertype_custom .o_table_row .o_meta .o_title a:hover,.o_catalog .o_level .o_meta .o_title a:hover,.o_catalog .o_sublevels .o_sublevel .o_meta .o_title a:hover,.o_repo_details .o_social .o_comments:hover,.o_login .o_login_register:hover,.o_disabled:focus,#o_main_wrapper #o_toplink:focus,#o_footer_powered a:focus,#o_share a:focus,#o_share_social_container a:focus,.o_toolbar .o_tools_container a:focus,.o_button_toggle:focus,.o_im_message_group .o_im_from:focus,.o_noti .o_label:focus,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_social .o_comments:focus,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_start:focus,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_book:focus,.o_coursetable.o_rendertype_custom .o_table_row .o_access .o_details:focus,.o_coursetable.o_rendertype_custom .o_table_row .o_meta .o_title a:focus,.o_catalog .o_level .o_meta .o_title a:focus,.o_catalog .o_sublevels .o_sublevel .o_meta .o_title a:focus,.o_repo_details .o_social .o_comments:focus,.o_login .o_login_register:focus{text-decoration:none}.o_copy_code{overflow-x:auto;overflow-y:auto;font-family:Menlo,Monaco,Consolas,"Courier New",monospace;padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;white-space:nowrap;border-radius:4px}.o_nowrap{white-space:nowrap}.o_titled_wrapper .o_content{margin-top:20px}.o_video{display:inline-block;max-width:100%;height:auto}.o_image{display:inline-block;max-width:100%;height:auto}.o_with_hyphens{-webkit-hyphens:auto;-moz-hyphens:auto;-ms-hyphens:auto;hyphens:auto}h1{color:#337ab7}h2{color:#337ab7}h3{color:#337ab7}h4,.o_cal .fc-header-title h2{color:#337ab7}h5{color:#337ab7}h5{color:#337ab7}fieldset legend{color:#333}html{position:relative;min-height:100%}body{min-height:100%;margin-bottom:80px}#o_main_wrapper{background:#fff;z-index:3}#o_main_wrapper #o_main_container{background:#fff}#o_main_wrapper #o_main_container #o_main_left{float:left;z-index:2;position:relative;background:#fff}#o_main_wrapper #o_main_container #o_main_left #o_main_left_content{padding:0 0 0 15px}#o_main_wrapper #o_main_container #o_main_left #o_main_left_toggle{position:absolute;display:none;right:0;top:70px;margin-right:-30px;font-size:25px;line-height:35px;text-align:center;width:30px;height:35px;z-index:3;border:1px solid #ddd;border-left:none;border-bottom-right-radius:4px;border-top-right-radius:4px;background-color:#fbfbfb;-webkit-box-shadow:2px 0px 4px 1px rgba(0,0,0,0.15);box-shadow:2px 0px 4px 1px rgba(0,0,0,0.15);color:#337ab7}#o_main_wrapper #o_main_container #o_main_left.o_offcanvas{background:#fbfbfb;-webkit-box-shadow:0px 0px 6px 1px rgba(0,0,0,0.2);box-shadow:0px 0px 6px 1px rgba(0,0,0,0.2);min-width:250px}#o_main_wrapper #o_main_container #o_main_left.o_offcanvas #o_main_left_content{padding:0 0 0 0}#o_main_wrapper #o_main_container #o_main_right{float:right;z-index:2;position:relative;background:inherit}#o_main_wrapper #o_main_container #o_main_right #o_main_right_content{padding:0 15px 0 0}#o_main_wrapper #o_main_container #o_main_center{position:relative;z-index:1;background:inherit}#o_main_wrapper #o_main_container #o_main_center h2:first-child{margin-top:0}@media screen and (max-width: 767px){#o_main_wrapper #o_main_container #o_main_center{margin-left:0 !important}}#o_main_wrapper #o_main_container #o_main_center #o_main_center_content{padding:0 15px}#o_main_wrapper #o_main_container #o_main_center #o_main_center_content #o_main_center_content_inner{padding-bottom:15px}#o_main_wrapper #o_toplink{position:absolute;bottom:0;right:15px;text-align:center;z-index:3}@media (max-width: 767px){#o_main_wrapper #o_main_container #o_main_center #o_main_center_content{padding:15px}}
 #o_back_wrapper,#o_preview_wrapper{margin-top:10px}#o_back_wrapper.o_toolbar .o_breadcrumb .breadcrumb,#o_preview_wrapper.o_toolbar .o_breadcrumb .breadcrumb{font-size:14px}#o_footer_wrapper{position:absolute;bottom:0;width:100%;height:70px;overflow:hidden;background-color:#f5f5f5;color:#999;line-height:16px;font-size:12px}#o_footer_wrapper a{color:#999}#o_footer_wrapper a:hover{color:#000}#o_footer_container{position:relative;padding-top:10px;min-height:70px;background:#f5f5f5;z-index:1}#o_footer_user{position:absolute;left:15px;top:10px;z-index:1}#o_footer_user #o_counter{white-space:nowrap}#o_footer_user #o_username{white-space:nowrap;margin-right:1em}#o_footer_version{position:absolute;right:15px;top:10px;text-align:right;z-index:1}@media (max-width: 767px){#o_footer_version{padding-top:10px;text-align:left}}
 #o_footer_powered{position:absolute;top:30px;right:15px;z-index:1}#o_footer_powered img{opacity:0.6;filter:alpha(opacity=60)}#o_footer_powered img:hover{opacity:1;filter:alpha(opacity=100)}#o_footer_impressum{position:absolute;top:10px;width:100%;text-align:center;z-index:-1}#o_footer_impressum i{display:none}#o_footer_textline{position:absolute;top:30px;width:100%;text-align:center;z-index:-1}#o_share{margin-top:10px}#o_share a{opacity:0.6;filter:alpha(opacity=60)}#o_share a:hover{opacity:1;filter:alpha(opacity=100)}#o_share a,#o_share_social_container a{color:#999;margin:0 0.25em 0 0}#o_share a:hover,#o_share_social_container a:hover{color:#000}@media (max-width: 767px){#o_counter,#o_footer_version,#o_share{display:none}#o_footer_impressum{top:30px;text-align:left}#o_footer_textline{top:50px;text-align:left}#o_footer_powered{top:10px}#o_footer_powered a:after{content:"\221E";font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:bold;font-size:14px}#o_footer_powered img{display:none}}#o_navbar_wrapper{z-index:4;border-top:1px solid #e7e7e7;box-shadow:inset 0 1px 0 rgba(255,255,255,0.1)}#o_navbar_wrapper #o_navbar_container{position:relative}a.o_disabled.navbar-text{margin:0}.o_navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid #e7e7e7;background-color:#f8f8f8}.o_navbar:before,.o_navbar:after{content:" ";display:table}.o_navbar:after{clear:both}.o_navbar .o_navbar_tabs li{max-width:150px}.o_navbar .o_navbar_tabs li a{padding-right:30px}.o_navbar .o_navbar_tabs li a:first-child span{display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.o_navbar .o_navbar_tabs .o_icon-fw{position:absolute;top:15px;left:0.5em;padding-top:3px;width:1em;height:1em;display:none}.o_navbar .o_navbar_tabs .o_navbar_tab_close{position:absolute;top:15px;right:0.5em;padding:0;width:1em;height:1em}.o_navbar .o_navbar_tabs .o_navbar_tab_close i:before{color:#d9534f}.o_navbar .o_navbar_tabs .o_navbar_tab_close:hover i:before{color:#c9302c}.o_navbar .o_custom_navbar-brand{background-position:5px 0;background-repeat:no-repeat;height:50px;width:120px}.o_navbar #o_navbar_langchooser{color:#777;padding:7px 15px}.o_navbar #o_navbar_langchooser form span+div{display:inline}.o_navbar #o_navbar_tools_permanent #o_navbar_print a,.o_navbar #o_navbar_tools_permanent #o_navbar_impress a,.o_navbar #o_navbar_tools_permanent #o_navbar_help a{color:#777;padding-right:0}.o_navbar #o_navbar_tools_permanent #o_navbar_login a{color:#f0ad4e}.o_navbar .o_navbar_tools>#o_navbar_tools_permanent>li>a>span{display:none}@media (min-width: 768px){.o_navbar .o_navbar_tools li.o_portrait>a>span{display:inline}}.o_navbar #o_navbar_tools_personal .o_navbar_tool a,.o_navbar #o_navbar_tools_permanent .o_navbar_tool a{padding-right:5px}.o_navbar #o_navbar_tools_personal #o_navbar_my_menu a,.o_navbar #o_navbar_tools_permanent #o_navbar_my_menu a{padding-left:45px}.o_navbar #o_navbar_tools_personal #o_navbar_my_menu .dropdown-menu a,.o_navbar #o_navbar_tools_permanent #o_navbar_my_menu .dropdown-menu a{padding-left:15px}.o_navbar #o_navbar_tools_personal #o_navbar_my_menu .o_portrait,.o_navbar #o_navbar_tools_permanent #o_navbar_my_menu .o_portrait{position:absolute;left:7px;top:10px}.o_navbar #o_navbar_tools_personal .o_logout,.o_navbar #o_navbar_tools_permanent .o_logout{color:#d9534f}.o_navbar.o_navbar-offcanvas .o_navbar_tab_close{top:10px;right:10px}.o_navbar.o_navbar-offcanvas .o_navbar-right a{padding:3px 20px;color:#9d9d9d}.o_navbar.o_navbar-offcanvas .o_navbar-right a:hover,.o_navbar.o_navbar-offcanvas .o_navbar-right a:focus{color:#fff;background-color:transparent}.o_navbar.o_navbar-offcanvas .o_navbar-right a.o_logout{color:#d9534f}.o_navbar.o_navbar-offcanvas .o_navbar-right a.o_logout:hover,.o_navbar.o_navbar-offcanvas .o_navbar-right a.o_logout:focus{color:#c9302c}.o_navbar.o_navbar-offcanvas .o_navbar-right a .o_icon-lg{font-size:1.0em;vertical-align:baseline}.o_navbar.o_navbar-offcanvas .o_navbar-right .divider{height:1px;margin:9px 0;overflow:hidden;background-color:none}.o_navbar.o_navbar-offcanvas .o_navbar-right .dropdown-header{padding-left:15px}.o_navbar.o_navbar-offcanvas .o_navbar-right .dropdown-toggle{display:none}.o_navbar.o_navbar-offcanvas .o_navbar-right .dropdown-menu{box-shadow:none;position:relative;top:0;left:0;display:block;float:none;background-color:#222;color:#9d9d9d;font-size:14px;border:none}.o_navbar.o_navbar-offcanvas .o_navbar-right .dropdown-menu .divider{background:none}.o_navbar.o_navbar-offcanvas .o_navbar-nav a{color:#9d9d9d;text-shadow:none}.o_navbar.o_navbar-offcanvas .o_navbar-nav a:hover,.o_navbar.o_navbar-offcanvas .o_navbar-nav a:focus{background-color:transparent;color:#fff}.o_navbar.o_navbar-offcanvas .o_navbar-nav .active a,.o_navbar.o_navbar-offcanvas .o_navbar-nav .active a:hover,.o_navbar.o_navbar-offcanvas .o_navbar-nav .active a:focus{background-color:#090909;color:#fff}.o_navbar.o_navbar-offcanvas .o_navbar-nav .o_navbar-link{color:#9d9d9d}.o_navbar.o_navbar-offcanvas .o_navbar-nav .o_navbar-link:hover{color:#fff}.o_navbar.o_navbar-offcanvas .o_navbar-nav .open .dropdown-menu>li>a{color:#777}.o_navbar.o_navbar-offcanvas .o_navbar-nav .open .dropdown-menu>li>a:hover,.o_navbar.o_navbar-offcanvas .o_navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.o_navbar.o_navbar-offcanvas .o_navbar-nav .open .dropdown-menu>.active>a,.o_navbar.o_navbar-offcanvas .o_navbar-nav .open .dropdown-menu>.active>a:hover,.o_navbar.o_navbar-offcanvas .o_navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.o_navbar.o_navbar-offcanvas .o_navbar-nav .open .dropdown-menu>.disabled>a,.o_navbar.o_navbar-offcanvas .o_navbar-nav .open .dropdown-menu>.disabled>a:hover,.o_navbar.o_navbar-offcanvas .o_navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}#o_navbar_impress a span,#o_navbar_search_opener a span{display:none}body.o_dmz #o_navbar_print a span,body.o_dmz #o_navbar_impress a span,body.o_dmz #o_navbar_help a span,body.o_dmz #o_navbar_search_opener a span{display:inline}.o_navbar-collapse{max-height:340px;overflow-x:visible;padding-right:15px;padding-left:15px;-webkit-overflow-scrolling:touch}.o_navbar-collapse:before,.o_navbar-collapse:after{content:" ";display:table}.o_navbar-collapse:after{clear:both}.o_navbar-collapse.o_collapse{display:block !important;height:auto !important;padding-bottom:0;overflow:visible !important}.o_navbar-offcanvas .o_navbar-collapse{width:auto;box-shadow:none;margin-top:10px;margin-right:-15px;margin-left:-15px}.o_navbar-brand{float:left;font-size:18px;line-height:20px;height:50px;color:#777}.o_navbar-brand:hover,.o_navbar-brand:focus{text-decoration:none;color:#5e5e5e;background-color:transparent}.o_navbar-toggle{position:relative;margin-right:15px;margin-left:15px;padding:9px 10px;margin-top:8px;margin-bottom:8px;border:1px solid #ddd;border-radius:4px;background-color:transparent;background-image:none}.o_navbar-toggle:hover,.o_navbar-toggle:focus{outline:none;background-color:#ddd}.o_navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px;background-color:#888}.o_navbar-toggle .icon-bar+.icon-bar{margin-top:4px}#o_navbar_left-toggle{float:left}#o_navbar_right-toggle{float:right}.o_navbar-link{color:#777}.o_navbar-link:hover{color:#333}.o_navbar-nav{margin:7.5px -15px}.o_navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px;color:#777}.o_navbar-nav>li>a:hover,.o_navbar-nav>li>a:focus{color:#333;background-color:transparent}.o_navbar-nav>.active>a,.o_navbar-nav>.active>a:hover,.o_navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.o_navbar-nav>.disabled>a,.o_navbar-nav>.disabled>a:hover,.o_navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.o_navbar-nav>.open>a,.o_navbar-nav>.open>a:hover,.o_navbar-nav>.open>a:focus{background-color:#e7e7e7;color:#555}.o_collapse .o_navbar-nav{float:left;margin:0}.o_collapse .o_navbar-nav>li{float:left}.o_collapse .o_navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.o_collapse .o_navbar-nav.o_navbar-right:last-child{margin-right:-15px}.o_collapse.o_navbar-collapse .o_navbar-left{float:left !important}.o_collapse.o_navbar-collapse .o_navbar-right{float:right !important}.o_navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid #e7e7e7;border-bottom:1px solid #e7e7e7;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);margin-top:8px;margin-bottom:8px}@media (max-width: 767px){.o_navbar-form .form-group{margin-bottom:5px}}
 .o_collapse .o_navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}.o_collapse .o_navbar-form.o_navbar-right:last-child{margin-right:-15px}.o_navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.o_navbar-fixed-bottom .o_navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.o_navbar-btn{margin-top:8px;margin-bottom:8px}.o_navbar-btn.btn-sm,.btn-group-sm>.o_navbar-btn.btn{margin-top:10px;margin-bottom:10px}.o_navbar-btn.btn-xs,.btn-group-xs>.o_navbar-btn.btn{margin-top:14px;margin-bottom:14px}.o_navbar-text{margin-top:15px;margin-bottom:15px;color:#777}.o_collapse .o_navbar-text{float:left;margin-left:15px;margin-right:15px}.o_collapse .o_navbar-text.o_navbar-right:last-child{margin-right:0}.o_dropdown_tab{position:relative}.o_dropdown_tab>a:first-child{padding-right:30px}.o_dropdown_tab>a:first-child .o_icon-fw{display:none;position:absolute;top:0;left:10px;padding-top:3px;line-height:20px}.o_dropdown_tab>a:first-child span{display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.o_dropdown_tab .o_navbar_tab_close{position:absolute;top:0px;right:10px;padding-left:0px;padding-right:0px;color:#d9534f;background-color:inherit}.o_dropdown_tab .o_navbar_tab_close:focus,.o_dropdown_tab .o_navbar_tab_close:hover{color:#c9302c;background-color:inherit}#o_navbar_more .dropdown-menu .divider:last-child{display:none}@media (min-width: 768px){#o_navbar_more .dropdown-menu{max-width:300px}}@media (max-width: 767px){#o_navbar_more>li{position:inherit}#o_navbar_more .dropdown-menu{left:0px;right:0px}#o_navbar_more .dropdown-menu a,#o_navbar_more .dropdown-menu i{line-height:30px}#o_navbar_more .dropdown-menu .o_navbar_tab_close{line-height:inherit}}.o_body_popup #o_topnav_printview{display:inline-block}.o_body_popup #o_topnav_close{float:right}.o_body_popup #o_topnav_close span{display:block}.o_body_popup #o_navbar_tools_permanent li>a{background-color:transparent}.o_toolbar{position:relative;margin-bottom:20px;margin-top:-10px;border:1px solid #e7e7e7}.o_toolbar:before,.o_toolbar:after{content:" ";display:table}.o_toolbar:after{clear:both}@media (min-width: 768px){.o_toolbar{border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:4px;border-bottom-left-radius:4px}}.o_toolbar .o_breadcrumb:before,.o_toolbar .o_breadcrumb:after{content:" ";display:table}.o_toolbar .o_breadcrumb:after{clear:both}.o_toolbar .o_breadcrumb .breadcrumb{margin-bottom:0;padding:5px 9px;font-size:11px;line-height:15px;border-radius:0;background:#f5f5f5;border-top-right-radius:4px;border-top-left-radius:4px}.o_toolbar .o_breadcrumb .breadcrumb .o_breadcrumb_close{float:right;position:relative;margin:0 0 0 15px;vertical-align:middle}.o_toolbar .o_breadcrumb .breadcrumb .o_breadcrumb_close a{line-height:15px;color:#d9534f}.o_toolbar .o_breadcrumb .breadcrumb .o_breadcrumb_close a:hover{color:#b52b27}.o_toolbar .o_breadcrumb .breadcrumb .o_breadcrumb_close a i{font-size:16px}.o_toolbar .o_breadcrumb .breadcrumb .o_breadcrumb_close a span{display:none}.o_toolbar .o_breadcrumb .breadcrumb .o_breadcrumb_close:before{content:none}.o_toolbar .o_tools_container{text-align:center;min-height:37px;position:realtive;background-color:#f8f8f8;border-bottom-right-radius:4px;border-bottom-left-radius:4px;border-top:1px solid #e7e7e7}.o_toolbar .o_tools_container:before,.o_toolbar .o_tools_container:after{content:" ";display:table}.o_toolbar .o_tools_container:after{clear:both}@media (max-width: 991px){.o_toolbar .o_tools_container{min-height:35px}}@media (max-width: 767px){.o_toolbar .o_tools_container{min-height:22px;text-align:left}}.o_toolbar .o_tools_container a{color:#777;display:inline-block}.o_toolbar .o_tools_container a:hover{color:#333}.o_toolbar .o_tools_container a.o_disabled{color:#aaa !important}.o_toolbar .o_tools_container a.o_disabled:hover{color:#aaa !important}.o_toolbar .o_tools_container a.active{color:#337ab7;background-color:transparent}.o_toolbar .o_tools_container .dropdown-menu a{display:block}.o_toolbar .o_tools_container .dropdown-menu a.active{color:#337ab7;background-color:transparent}.o_toolbar .o_tools{margin-top:8px;margin-bottom:5px}.o_toolbar .o_tool,.o_toolbar .o_text{position:relative;margin:0 10px}.o_toolbar .o_tool:first-child,.o_toolbar .o_text:first-child{margin-left:0}.o_toolbar .o_tool:last-child,.o_toolbar .o_text:last-child{margin-right:0}.o_toolbar .o_tool a i,.o_toolbar .o_tool .o_disabled i,.o_toolbar .o_text a i,.o_toolbar .o_text .o_disabled i{font-size:18px}.o_toolbar .o_tool a span,.o_toolbar .o_tool .o_disabled span,.o_toolbar .o_text a span,.o_toolbar .o_text .o_disabled span{display:block;font-size:12px}.o_toolbar .o_tool a span.badge,.o_toolbar .o_tool .o_disabled span.badge,.o_toolbar .o_text a span.badge,.o_toolbar .o_text .o_disabled span.badge{position:absolute;right:50%;top:-18px;margin-right:-12px;font-size:13px}@media (min-width: 767px) and (max-width: 991px){.o_toolbar .o_tool a i,.o_toolbar .o_tool .o_disabled i,.o_toolbar .o_text a i,.o_toolbar .o_text .o_disabled i{font-size:16px}.o_toolbar .o_tool a span,.o_toolbar .o_tool .o_disabled span,.o_toolbar .o_text a span,.o_toolbar .o_text .o_disabled span{font-size:11px}.o_toolbar .o_tool a span.badge,.o_toolbar .o_tool .o_disabled span.badge,.o_toolbar .o_text a span.badge,.o_toolbar .o_text .o_disabled span.badge{top:-16.5px;margin-right:-11px;font-size:12px}}@media (max-width: 767px){.o_toolbar .o_tool a i,.o_toolbar .o_tool .o_disabled i,.o_toolbar .o_text a i,.o_toolbar .o_text .o_disabled i{font-size:20px}.o_toolbar .o_tool a span,.o_toolbar .o_tool .o_disabled span,.o_toolbar .o_text a span,.o_toolbar .o_text .o_disabled span{display:none}.o_toolbar .o_tool a span.badge,.o_toolbar .o_tool .o_disabled span.badge,.o_toolbar .o_text a span.badge,.o_toolbar .o_text .o_disabled span.badge{display:block;position:relative;top:0;left:0;margin-right:0}}.o_toolbar .o_tool .o_chelp,.o_toolbar .o_text .o_chelp{position:relative;top:-1em;vertical-align:top}.o_toolbar .o_tool_next,.o_toolbar .o_tool_previous{padding:0;margin-top:5px;border:1px solid #ccc;background-color:#eee}.o_toolbar .o_tool_next a,.o_toolbar .o_tool_previous a{color:#777}.o_toolbar .o_tool_next a:hover,.o_toolbar .o_tool_previous a:hover{color:#333}.o_toolbar .o_tool_next a.o_disabled,.o_toolbar .o_tool_previous a.o_disabled{color:#aaa !important}.o_toolbar .o_tool_next a.o_disabled:hover,.o_toolbar .o_tool_previous a.o_disabled:hover{color:#aaa !important}.o_toolbar .o_tool_next i,.o_toolbar .o_tool_previous i{font-size:21px}@media (min-width: 767px) and (max-width: 991px){.o_toolbar .o_tool_next,.o_toolbar .o_tool_previous{margin-top:4px}.o_toolbar .o_tool_next i,.o_toolbar .o_tool_previous i{font-size:18px}}@media (max-width: 767px){.o_toolbar .o_tool_next,.o_toolbar .o_tool_previous{margin-top:0}.o_toolbar .o_tool_next i,.o_toolbar .o_tool_previous i{font-size:20px}}.o_toolbar .o_tool_previous{margin-left:10px;border-bottom-left-radius:4px;border-top-left-radius:4px;border-right:0}.o_toolbar .o_tool_next{border-bottom-right-radius:4px;border-top-right-radius:4px}.o_toolbar .o_tool_dropdown{margin:0 10px}.o_toolbar .o_tool_dropdown:first-child{margin-left:0}.o_toolbar .o_tool_dropdown:last-child{margin-right:0}.o_toolbar .o_tool_dropdown a.dropdown-toggle{position:relative}.o_toolbar .o_tool_dropdown a.dropdown-toggle i{font-size:18px}.o_toolbar .o_tool_dropdown a.dropdown-toggle span{display:block;font-size:12px}.o_toolbar .o_tool_dropdown a.dropdown-toggle .o_icon_caret{position:absolute;right:50%;top:4px;margin-right:-20px;font-size:14px}@media (min-width: 767px) and (max-width: 991px){.o_toolbar .o_tool_dropdown a.dropdown-toggle i{font-size:16px}.o_toolbar .o_tool_dropdown a.dropdown-toggle span,.o_toolbar .o_tool_dropdown a.dropdown-toggle .o_icon_caret{font-size:11px}.o_toolbar .o_tool_dropdown a.dropdown-toggle .o_icon_caret{top:4px;margin-right:-18px;font-size:12px}}@media (max-width: 767px){.o_toolbar .o_tool_dropdown a.dropdown-toggle{padding:0 10px 0 5px}.o_toolbar .o_tool_dropdown a.dropdown-toggle i{font-size:20px}.o_toolbar .o_tool_dropdown a.dropdown-toggle span{display:none}}.o_toolbar .o_tool_dropdown .dropdown-menu{text-align:left}.o_toolbar .o_tools_left{float:left}.o_toolbar .o_tools_right{float:right}.o_toolbar .o_tools_right_edge{float:right}@media (max-width: 991px){.o_toolbar .o_tools{margin-top:6px;margin-bottom:4px}.o_toolbar .o_tool span{max-width:10em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.o_toolbar .o_tool,.o_toolbar .o_text,.o_toolbar .o_tool_dropdown{margin:0 5px}}@media (max-width: 767px){.o_toolbar .o_tools{margin-top:6px;margin-bottom:4px}.o_toolbar .o_tools .o_chelp{top:0;vertical-align:top}.o_toolbar .o_tools_center{float:left}.o_toolbar .o_tool,.o_toolbar .o_text,.o_toolbar .o_tool_dropdown{margin:0 0;position:static}.o_toolbar .o_tool_dropdown .dropdown-menu{left:0px;right:0px}.o_toolbar .o_tool_dropdown .dropdown-menu a,.o_toolbar .o_tool_dropdown .dropdown-menu i{line-height:30px}.o_toolbar .o_tool_dropdown .dropdown-menu .o_navbar_tab_close{line-height:inherit}}
diff --git a/src/test/java/org/olat/repository/RepositoryManagerTest.java b/src/test/java/org/olat/repository/RepositoryManagerTest.java
index 01b95493a13..c9d4bae10f3 100644
--- a/src/test/java/org/olat/repository/RepositoryManagerTest.java
+++ b/src/test/java/org/olat/repository/RepositoryManagerTest.java
@@ -1153,7 +1153,103 @@ public class RepositoryManagerTest extends OlatTestCase {
 		Assert.assertEquals(publicCycle, reloaded.getLifecycle());
 	}
 
+	@Test
+	public void setAllowToLeaveOption() {
+		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry();
+		dbInstance.commitAndCloseSession();
+		Assert.assertNotNull(re);
+		
+		RepositoryEntry updatedRe = repositoryManager.setLeaveSetting(re, RepositoryEntryAllowToLeaveOptions.never);
+		dbInstance.commitAndCloseSession();
+		Assert.assertNotNull(updatedRe);
+		Assert.assertEquals(re, updatedRe);
+		Assert.assertEquals(RepositoryEntryAllowToLeaveOptions.never, updatedRe.getAllowToLeaveOption());
+	}
+	
+	@Test
+	public void isParticipantAllowedToLeave() {
+		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry();
+		dbInstance.commitAndCloseSession();
+		re = repositoryManager.setLeaveSetting(re, RepositoryEntryAllowToLeaveOptions.never);
+		dbInstance.commitAndCloseSession();
+		
+		Assert.assertFalse(repositoryService.isParticipantAllowedToLeave(re));
+	}
+	
+	@Test
+	public void leave_simpleRepositoryEnty() {
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("leave-re-1");
+		Identity coach = JunitTestHelper.createAndPersistIdentityAsRndUser("leave-re-2");
+		Identity owner = JunitTestHelper.createAndPersistIdentityAsRndUser("leave-re-3");
+		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry();
+		repositoryEntryRelationDao.addRole(participant, re, GroupRoles.participant.name());
+		repositoryEntryRelationDao.addRole(coach, re, GroupRoles.coach.name());
+		repositoryEntryRelationDao.addRole(owner, re, GroupRoles.owner.name());
+		dbInstance.commitAndCloseSession();
+		
+		//participant leave
+		LeavingStatusList status = new LeavingStatusList();
+		repositoryManager.leave(participant, re, status, null);
+		dbInstance.commit();
+		Assert.assertFalse(repositoryService.isMember(participant, re));
+		
+		//coach and owner can't leave
+		repositoryManager.leave(coach, re, status, null);
+		dbInstance.commit();
+		Assert.assertTrue(repositoryService.isMember(coach, re));
+		repositoryManager.leave(owner, re, status, null);
+		dbInstance.commit();
+		Assert.assertTrue(repositoryService.isMember(owner, re));
+	}
 	
+	@Test
+	public void leave_withGroups() {
+		//create 2 entries and 2 groups
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("leave-re-4");
+		Identity owner = JunitTestHelper.createAndPersistIdentityAsRndUser("leave-re-5");
+		
+		//entry 1 is linked to the 2 groups
+		RepositoryEntry re1 = JunitTestHelper.createAndPersistRepositoryEntry();
+		repositoryEntryRelationDao.addRole(participant, re1, GroupRoles.participant.name());
+		repositoryEntryRelationDao.addRole(owner, re1, GroupRoles.owner.name());
+		
+		//entry 2 is only linked to group 2
+		RepositoryEntry re2 = JunitTestHelper.createAndPersistRepositoryEntry();
+		
+		BusinessGroup group1 = businessGroupService.createBusinessGroup(owner, "leaving-group-1", "tg", null, null, false, false, re1);
+	    businessGroupRelationDao.addRole(participant, group1, GroupRoles.participant.name());
+		
+	    BusinessGroup group2 = businessGroupService.createBusinessGroup(owner, "leaving-group-2", "tg", null, null, false, false, re1);
+	    businessGroupRelationDao.addRole(participant, group2, GroupRoles.participant.name());
+	    businessGroupRelationDao.addRelationToResource(group2, re2);
+		dbInstance.commitAndCloseSession();
+		
+		//participant leave
+		LeavingStatusList status = new LeavingStatusList();
+		repositoryManager.leave(participant, re1, status, null);
+		businessGroupService.leave(participant, re1, status, null);
+		dbInstance.commit();
+		
+		//participant is removed from entry 1, group 1 but not group 2 because this group is linked to entry 2 too
+		Assert.assertTrue(repositoryService.isMember(participant, re1));
+		//but removed from re
+		boolean re1Role = repositoryEntryRelationDao.hasRole(participant, re1, GroupRoles.participant.name());
+		Assert.assertFalse(re1Role);
+		boolean group1Role = businessGroupRelationDao.hasRole(participant, group1, GroupRoles.participant.name());
+		Assert.assertFalse(group1Role);
+		boolean group2Role = businessGroupRelationDao.hasRole(participant, group2, GroupRoles.participant.name());
+		Assert.assertTrue(group2Role);
+		
+		//owner are never remove (double check)
+		Assert.assertTrue(repositoryService.isMember(owner, re1));
+		//but removed from re
+		boolean re1OwnerRole = repositoryEntryRelationDao.hasRole(owner, re1, GroupRoles.owner.name());
+		Assert.assertTrue(re1OwnerRole);
+		boolean group1CoachRole = businessGroupRelationDao.hasRole(owner, group1, GroupRoles.coach.name());
+		Assert.assertTrue(group1CoachRole);
+		boolean group2CoachRole = businessGroupRelationDao.hasRole(owner, group2, GroupRoles.coach.name());
+		Assert.assertTrue(group2CoachRole);
+	}
 
 	private RepositoryEntry createRepositoryEntry(final String type, Identity owner, long i) {
 		OLATResourceable resourceable = OresHelper.createOLATResourceableInstance(type, new Long(i));
-- 
GitLab