You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2017/11/24 16:35:26 UTC

[3/3] openmeetings git commit: [OPENMEETINGS-1771] minified files are removed from source tree

[OPENMEETINGS-1771] minified files are removed from source tree


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/ae1b51a9
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/ae1b51a9
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/ae1b51a9

Branch: refs/heads/4.0.x
Commit: ae1b51a99a52ed679e2862656e0054018d11545c
Parents: f25da38
Author: Maxim Solodovnik <so...@gmail.com>
Authored: Fri Nov 24 23:35:04 2017 +0700
Committer: Maxim Solodovnik <so...@gmail.com>
Committed: Fri Nov 24 23:35:04 2017 +0700

----------------------------------------------------------------------
 .../src/main/assembly/components/templates.xml  |   1 +
 openmeetings-web/pom.xml                        |  59 ++
 .../web/room/activities/activities.js           |  19 +
 .../web/room/jquery.dialogextend.min.js         |   3 -
 .../apache/openmeetings/web/room/room-base.js   | 818 +++++++++++++++++++
 .../org/apache/openmeetings/web/room/room.js    | 818 -------------------
 .../openmeetings/web/room/wb/WbPanel.java       |   9 -
 .../apache/openmeetings/web/room/wb/fabric.js   |  15 +-
 .../openmeetings/web/room/wb/fabric.min.js      |   2 -
 .../apache/openmeetings/web/user/chat/Chat.java |   7 -
 .../openmeetings/web/user/chat/chat-base.js     | 373 +++++++++
 .../apache/openmeetings/web/user/chat/chat.js   | 374 ---------
 .../openmeetings/web/user/chat/cssemoticons.css | 295 -------
 .../web/user/chat/cssemoticons.min.js           |   2 -
 .../web/util/upload/fileinput.min.css           |   7 -
 .../web/util/upload/fileinput.min.js            |   7 -
 .../src/main/webapp/css/cssemoticons.css        | 295 +++++++
 17 files changed, 1570 insertions(+), 1534 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ae1b51a9/openmeetings-server/src/main/assembly/components/templates.xml
----------------------------------------------------------------------
diff --git a/openmeetings-server/src/main/assembly/components/templates.xml b/openmeetings-server/src/main/assembly/components/templates.xml
index 25cadf2..681f76c 100644
--- a/openmeetings-server/src/main/assembly/components/templates.xml
+++ b/openmeetings-server/src/main/assembly/components/templates.xml
@@ -36,6 +36,7 @@
 			<outputDirectory>${om.webapp}/WEB-INF/classes</outputDirectory>
 			<includes>
 				<include>**/*.js</include>
+				<include>**/*.css</include>
 			</includes>
 		</fileSet>
 		<fileSet>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ae1b51a9/openmeetings-web/pom.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/pom.xml b/openmeetings-web/pom.xml
index 505bebd..fdfd2bd 100644
--- a/openmeetings-web/pom.xml
+++ b/openmeetings-web/pom.xml
@@ -102,6 +102,7 @@
 								<cssSourceFile>activities.css</cssSourceFile>
 								<cssSourceFile>admin.css</cssSourceFile>
 								<cssSourceFile>calendar.css</cssSourceFile>
+								<cssSourceFile>cssemoticons.css</cssSourceFile>
 								<cssSourceFile>chat.css</cssSourceFile>
 								<cssSourceFile>menu.css</cssSourceFile>
 								<cssSourceFile>room.css</cssSourceFile>
@@ -150,6 +151,7 @@
 							<charset>UTF-8</charset>
 							<jsSourceDir>../java/org/apache/openmeetings/web/room/wb</jsSourceDir>
 							<jsSourceFiles>
+								<jsSourceFile>fabric.js</jsSourceFile>
 								<jsSourceFile>wb-all.js</jsSourceFile>
 								<jsSourceFile>uuid.js</jsSourceFile>
 								<jsSourceFile>player.js</jsSourceFile>
@@ -175,6 +177,63 @@
 							<jsEngine>CLOSURE</jsEngine>
 						</configuration>
 					</execution>
+					<execution>
+						<id>fileinput-js</id>
+						<goals>
+							<goal>minify</goal>
+						</goals>
+						<configuration>
+							<charset>UTF-8</charset>
+							<jsSourceDir>../java/org/apache/openmeetings/web/util/upload</jsSourceDir>
+							<jsSourceFiles>
+								<jsSourceFile>fileinput.js</jsSourceFile>
+							</jsSourceFiles>
+							<jsFinalFile>fileinput.js</jsFinalFile>
+							<jsTargetDir>../generated-sources/main/java/org/apache/openmeetings/web/util/upload</jsTargetDir>
+							<jsEngine>CLOSURE</jsEngine>
+							<cssSourceDir>../java/org/apache/openmeetings/web/util/upload</cssSourceDir>
+							<cssSourceFiles>
+								<cssSourceFile>fileinput.css</cssSourceFile>
+							</cssSourceFiles>
+							<skipMerge>true</skipMerge>
+							<cssFinalFile>fileinput.css</cssFinalFile>
+							<cssTargetDir>../generated-sources/main/java/org/apache/openmeetings/web/util/upload</cssTargetDir>
+						</configuration>
+					</execution>
+					<execution>
+						<id>room-js</id>
+						<goals>
+							<goal>minify</goal>
+						</goals>
+						<configuration>
+							<charset>UTF-8</charset>
+							<jsSourceDir>../java/org/apache/openmeetings/web/room</jsSourceDir>
+							<jsSourceFiles>
+								<jsSourceFile>jquery.dialogextend.js</jsSourceFile>
+								<jsSourceFile>room-base.js</jsSourceFile>
+							</jsSourceFiles>
+							<jsFinalFile>room.js</jsFinalFile>
+							<jsEngine>CLOSURE</jsEngine>
+							<jsTargetDir>../generated-sources/main/java/org/apache/openmeetings/web/room</jsTargetDir>
+						</configuration>
+					</execution>
+					<execution>
+						<id>chat-js</id>
+						<goals>
+							<goal>minify</goal>
+						</goals>
+						<configuration>
+							<charset>UTF-8</charset>
+							<jsSourceDir>../java/org/apache/openmeetings/web/user/chat</jsSourceDir>
+							<jsSourceFiles>
+								<jsSourceFile>cssemoticons.js</jsSourceFile>
+								<jsSourceFile>chat-base.js</jsSourceFile>
+							</jsSourceFiles>
+							<jsFinalFile>chat.js</jsFinalFile>
+							<jsEngine>CLOSURE</jsEngine>
+							<jsTargetDir>../generated-sources/main/java/org/apache/openmeetings/web/user/chat</jsTargetDir>
+						</configuration>
+					</execution>
 				</executions>
 			</plugin>
 			<plugin>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ae1b51a9/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/activities.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/activities.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/activities.js
index 635f51f..ddd0450 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/activities.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/activities.js
@@ -87,3 +87,22 @@ var Activities = function() {
 		}
 	};
 }();
+$(function() {
+	Wicket.Event.subscribe("/websocket/message", function(jqEvent, msg) {
+		try {
+			if (msg instanceof Blob) {
+				return; //ping
+			}
+			const m = jQuery.parseJSON(msg);
+			if (m) {
+				switch(m.type) {
+					case "activity":
+						Activities.addMessage(m);
+						break;
+				}
+			}
+		} catch (err) {
+			//no-op
+		}
+	});
+});

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ae1b51a9/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.min.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.min.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.min.js
deleted file mode 100644
index 293458c..0000000
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.min.js
+++ /dev/null
@@ -1,3 +0,0 @@
-/* Licensed MIT */
-/*! jquery-dialogextend 2.0.4 2014-07-08 */
-(function(){var i;i=jQuery,i.widget("ui.dialogExtend",{version:"2.0.4",modes:{},options:{closable:!0,dblclick:!1,titlebar:!1,icons:{close:"ui-icon-closethick",restore:"ui-icon-newwin"},load:null,beforeRestore:null,restore:null},_create:function(){return this._state="normal",i(this.element[0]).data("ui-dialog")||i.error("jQuery.dialogExtend Error : Only jQuery UI Dialog element is accepted"),this._verifyOptions(),this._initStyles(),this._initButtons(),this._initTitleBar(),this._setState("normal"),this._on("load",function(i){return console.log("test",i)}),this._trigger("load")},_setState:function(t){return i(this.element[0]).removeClass("ui-dialog-"+this._state).addClass("ui-dialog-"+t),this._state=t},_verifyOptions:function(){var t,e,o;!this.options.dblclick||this.options.dblclick in this.modes||(i.error("jQuery.dialogExtend Error : Invalid <dblclick> value '"+this.options.dblclick+"'"),this.options.dblclick=!1),this.options.titlebar&&"none"!==(e=this.options.titlebar)&&"transparent"
 !==e&&(i.error("jQuery.dialogExtend Error : Invalid <titlebar> value '"+this.options.titlebar+"'"),this.options.titlebar=!1),o=[];for(t in this.modes)this["_verifyOptions_"+t]?o.push(this["_verifyOptions_"+t]()):o.push(void 0);return o},_initStyles:function(){var t,e,o;i(".dialog-extend-css").length||(e="",e+='<style class="dialog-extend-css" type="text/css">',e+=".ui-dialog .ui-dialog-titlebar-buttonpane>a { float: right; }",e+=".ui-dialog .ui-dialog-titlebar-restore { width: 19px; height: 18px; }",e+=".ui-dialog .ui-dialog-titlebar-restore span { display: block; margin: 1px; }",e+=".ui-dialog .ui-dialog-titlebar-restore:hover,",e+=".ui-dialog .ui-dialog-titlebar-restore:focus { padding: 0; }",e+=".ui-dialog .ui-dialog-titlebar ::selection { background-color: transparent; }",e+="</style>",i(e).appendTo("body")),o=[];for(t in this.modes)o.push(this["_initStyles_"+t]());return o},_initButtons:function(){var t,e,o,n,a,l=this;n=i(this.element[0]).dialog("widget").find(".ui-dialog-title
 bar"),t=i('<div class="ui-dialog-titlebar-buttonpane"></div>').appendTo(n),t.css({position:"absolute",top:"50%",right:"0.3em","margin-top":"-10px",height:"18px"}),n.find(".ui-dialog-titlebar-close").css({position:"relative","float":"right",top:"auto",right:"auto",margin:0}).find(".ui-icon").removeClass("ui-icon-closethick").addClass(this.options.icons.close).end().appendTo(t).end(),t.append('<a class="ui-dialog-titlebar-restore ui-corner-all ui-state-default" href="#"><span class="ui-icon '+this.options.icons.restore+'" title="restore">restore</span></a>').find(".ui-dialog-titlebar-restore").attr("role","button").mouseover(function(){return i(this).addClass("ui-state-hover")}).mouseout(function(){return i(this).removeClass("ui-state-hover")}).focus(function(){return i(this).addClass("ui-state-focus")}).blur(function(){return i(this).removeClass("ui-state-focus")}).end().find(".ui-dialog-titlebar-close").toggle(this.options.closable).end().find(".ui-dialog-titlebar-restore").hide().c
 lick(function(i){return i.preventDefault(),l.restore()}).end(),a=this.modes;for(o in a)e=a[o],this._initModuleButton(o,e);return n.dblclick(function(){return l.options.dblclick?"normal"!==l._state?l.restore():l[l.options.dblclick]():void 0}).select(function(){return!1})},_initModuleButton:function(t,e){var o,n=this;return o=i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-buttonpane"),o.append('<a class="ui-dialog-titlebar-'+t+' ui-corner-all ui-state-default" href="#" title="'+t+'"><span class="ui-icon '+this.options.icons[t]+'">'+t+"</span></a>").find(".ui-dialog-titlebar-"+t).attr("role","button").mouseover(function(){return i(this).addClass("ui-state-hover")}).mouseout(function(){return i(this).removeClass("ui-state-hover")}).focus(function(){return i(this).addClass("ui-state-focus")}).blur(function(){return i(this).removeClass("ui-state-focus")}).end().find(".ui-dialog-titlebar-"+t).toggle(this.options[e.option]).click(function(i){return i.preventDefault(),n[t]()})
 .end()},_initTitleBar:function(){var t;switch(this.options.titlebar){case!1:return 0;case"none":return i(this.element[0]).dialog("option","draggable")&&(t=i("<div />").addClass("ui-dialog-draggable-handle").css("cursor","move").height(5),i(this.element[0]).dialog("widget").prepend(t).draggable("option","handle",t)),i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").find(".ui-dialog-title").html("&nbsp;").end().css({"background-color":"transparent","background-image":"none",border:0,position:"absolute",right:0,top:0,"z-index":9999}).end();case"transparent":return i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").css({"background-color":"transparent","background-image":"none",border:0});default:return i.error("jQuery.dialogExtend Error : Invalid <titlebar> value '"+this.options.titlebar+"'")}},state:function(){return this._state},restore:function(){return this._trigger("beforeRestore"),this._restore(),this._toggleButtons(),this._trigger("restore")},_restore:
 function(){return"normal"!==this._state?(this["_restore_"+this._state](),this._setState("normal"),i(this.element[0]).dialog("widget").focus()):void 0},_saveSnapshot:function(){return"normal"===this._state?(this.original_config_resizable=i(this.element[0]).dialog("option","resizable"),this.original_config_draggable=i(this.element[0]).dialog("option","draggable"),this.original_size_height=i(this.element[0]).dialog("widget").outerHeight(),this.original_size_width=i(this.element[0]).dialog("option","width"),this.original_size_maxHeight=i(this.element[0]).dialog("option","maxHeight"),this.original_position_mode=i(this.element[0]).dialog("widget").css("position"),this.original_position_left=i(this.element[0]).dialog("widget").offset().left-i("body").scrollLeft(),this.original_position_top=i(this.element[0]).dialog("widget").offset().top-i("body").scrollTop(),this.original_titlebar_wrap=i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").css("white-space")):void 0},_loadSnapsho
 t:function(){return{config:{resizable:this.original_config_resizable,draggable:this.original_config_draggable},size:{height:this.original_size_height,width:this.original_size_width,maxHeight:this.original_size_maxHeight},position:{mode:this.original_position_mode,left:this.original_position_left,top:this.original_position_top},titlebar:{wrap:this.original_titlebar_wrap}}},_toggleButtons:function(t){var e,o,n,a,l,s;n=t||this._state,i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-restore").toggle("normal"!==n).css({right:"1.4em"}).end(),a=this.modes;for(o in a)e=a[o],i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-"+o).toggle(n!==e.state&&this.options[e.option]);l=this.modes,s=[];for(o in l)e=l[o],e.state===n?s.push(i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-restore").insertAfter(i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-"+o)).end()):s.push(void 0);return s}})}).call(this),function(){var i;i=jQuery,i.extend(!0,i.ui.dia
 logExtend.prototype,{modes:{collapse:{option:"collapsable",state:"collapsed"}},options:{collapsable:!1,icons:{collapse:"ui-icon-triangle-1-s"},beforeCollapse:null,collapse:null},collapse:function(){var t,e;return t=i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").height()+2,this._trigger("beforeCollapse"),"normal"!==this._state&&this._restore(),this._saveSnapshot(),e=i(this.element[0]).dialog("widget").position(),i(this.element[0]).dialog("option",{resizable:!1,height:t,maxHeight:t,position:[e.left-i(document).scrollLeft(),e.top-i(document).scrollTop()]}).on("dialogclose",this._collapse_restore).dialog("widget").find(".ui-dialog-buttonpane:visible").hide().end().find(".ui-dialog-titlebar").css("white-space","nowrap").end().find(".ui-dialog-content"),this._setState("collapsed"),this._toggleButtons(),this._trigger("collapse")},_restore_collapsed:function(){var t;return t=this._loadSnapshot(),i(this.element[0]).show().dialog("widget").find(".ui-dialog-buttonpane:hidden")
 .show().end().find(".ui-dialog-titlebar").css("white-space",t.titlebar.wrap).end().find(".ui-dialog-content").dialog("option",{resizable:t.config.resizable,height:t.size.height,maxHeight:t.size.maxHeight}).off("dialogclose",this._collapse_restore)},_initStyles_collapse:function(){var t;return i(".dialog-extend-collapse-css").length?void 0:(t="",t+='<style class="dialog-extend-collapse-css" type="text/css">',t+=".ui-dialog .ui-dialog-titlebar-collapse { width: 19px; height: 18px; }",t+=".ui-dialog .ui-dialog-titlebar-collapse span { display: block; margin: 1px; }",t+=".ui-dialog .ui-dialog-titlebar-collapse:hover,",t+=".ui-dialog .ui-dialog-titlebar-collapse:focus { padding: 0; }",t+="</style>",i(t).appendTo("body"))},_collapse_restore:function(){return i(this).dialogExtend("restore")}})}.call(this);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ae1b51a9/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room-base.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room-base.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room-base.js
new file mode 100644
index 0000000..edafe4c
--- /dev/null
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room-base.js
@@ -0,0 +1,818 @@
+/* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */
+const WB_AREA_SEL = '.room.wb.area';
+const WBA_WB_SEL = '.room.wb.area .ui-tabs-panel.ui-corner-bottom.ui-widget-content:visible';
+var WBA_SEL = WB_AREA_SEL;
+const VID_SEL = '.video.user-video';
+var RoomUtil = (function() {
+	const self = {};
+	function _confirmDlg(_id, okHandler) {
+		const confirm = $('#' + _id);
+		confirm.dialog({
+			modal: true
+			, buttons: [
+				{
+					text: confirm.data('btn-ok')
+					, click: function() {
+						okHandler();
+						$(this).dialog('close');
+					}
+				}
+				, {
+					text: confirm.data('btn-cancel')
+					, click: function() {
+						$(this).dialog('close');
+					}
+				}
+			]
+		});
+		return confirm;
+	}
+
+	self.confirmDlg = _confirmDlg;
+	return self;
+})();
+var VideoUtil = (function() {
+	const self = {};
+	function _getVid(uid) {
+		return "video" + uid;
+	}
+	function _isSharing(c) {
+		return 'sharing' === c.type && c.screenActivities.indexOf('sharing') > -1;
+	}
+	function _isRecording(c) {
+		return 'sharing' === c.type
+			&& c.screenActivities.indexOf('recording') > -1
+			&& c.screenActivities.indexOf('sharing') < 0;
+	}
+	function _hasAudio(c) {
+		return c.activities.indexOf('broadcastA') > -1;
+	}
+	function _hasVideo(c) {
+		return c.activities.indexOf('broadcastV') > -1;
+	}
+	function _getRects(sel, excl) {
+		const list = [], elems = $(sel);
+		for (let i = 0; i < elems.length; ++i) {
+			if (excl !== $(elems[i]).attr('aria-describedby')) {
+				list.push(_getRect(elems[i]));
+			}
+		}
+		return list;
+	}
+	function _getRect(e) {
+		const win = $(e), winoff = win.offset();
+		return {left: winoff.left
+			, top: winoff.top
+			, right: winoff.left + win.width()
+			, bottom: winoff.top + win.height()};
+	}
+	function _getPos(list, w, h) {
+		if (Room.getOptions().interview) {
+			return {left: 0, top: 0};
+		}
+		const wba = $(WBA_SEL), woffset = wba.offset()
+			, offsetX = 20, offsetY = 10
+			, area = {left: woffset.left, top: woffset.top, right: woffset.left + wba.width(), bottom: woffset.top + wba.height()};
+		const rectNew = {
+				_left: area.left
+				, _top: area.top
+				, right: area.left + w
+				, bottom: area.top + h
+				, get left() {
+					return this._left
+				}
+				, set left(l) {
+					this._left = l;
+					this.right = l + w;
+				}
+				, get top() {
+					return this._top
+				}
+				, set top(t) {
+					this._top = t;
+					this.bottom = t + h;
+				}
+			};
+		let minY = area.bottom, posFound;
+		do {
+			posFound = true
+			for (let i = 0; i < list.length; ++i) {
+				const rect = list[i];
+				minY = Math.min(minY, rect.bottom);
+
+				if (rectNew.left < rect.right && rectNew.right > rect.left && rectNew.top < rect.bottom && rectNew.bottom > rect.top) {
+					rectNew.left = rect.right + offsetX;
+					posFound = false;
+				}
+				if (rectNew.right >= area.right) {
+					rectNew.left = area.left;
+					rectNew.top = minY + offsetY;
+					posFound = false;
+				}
+				if (rectNew.bottom >= area.bottom) {
+					rectNew.top = area.top;
+					posFound = true;
+					break;
+				}
+			}
+		} while (!posFound);
+		return {left: rectNew.left, top: rectNew.top};
+	}
+	function _arrange() {
+		const list = [], elems = $(VID_SEL);
+		for (let i = 0; i < elems.length; ++i) {
+			const v = $(elems[i]);
+			v.css(_getPos(list, v.width(), v.height()));
+			list.push(_getRect(v));
+		}
+	}
+
+	self.getVid = _getVid;
+	self.isSharing = _isSharing;
+	self.isRecording = _isRecording;
+	self.hasAudio = _hasAudio;
+	self.hasVideo = _hasVideo;
+	self.getRects = _getRects;
+	self.getPos = _getPos;
+	self.arrange = _arrange;
+	return self;
+})();
+var Video = (function() {
+	const self = {};
+	let c, v, vc, t, f, swf, size, vol, slider, handle
+		, lastVolume = 50;
+
+	function _getName() {
+		return c.user.firstName + ' ' + c.user.lastName;
+	}
+	function _resizeDlg(_ww, _hh) {
+		const interview = Room.getOptions().interview;
+		const _w = interview ? 320 : _ww, _h = interview ? 260 : _hh;
+		const h = _h + t.height() + 2 + (f.is(":visible") ? f.height() : 0);
+		v.dialog("option", "width", _w).dialog("option", "height", h);
+		_resize(_w, _h);
+		return h;
+	}
+	function _securityMode(on) {
+		if (Room.getOptions().interview) {
+			return;
+		}
+		if (on) {
+			//TODO buttons
+			v.dialog("option", "position", {my: "center", at: "center", of: WBA_SEL});
+		} else {
+			const h = _resizeDlg(size.width, size.height);
+			v.dialog("widget").css(VideoUtil.getPos(VideoUtil.getRects(VID_SEL, VideoUtil.getVid(c.uid)), c.width, h));
+		}
+	}
+	function _resize(w, h) {
+		vc.width(w).height(h);
+		swf.attr('width', w).attr('height', h);
+	}
+	function _handleMicStatus(state) {
+		if (!f.is(":visible")) {
+			return;
+		}
+		if (state) {
+			f.find('.off').hide();
+			f.find('.on').show();
+			f.addClass('ui-state-highlight');
+			t.addClass('ui-state-highlight');
+		} else {
+			f.find('.off').show();
+			f.find('.on').hide();
+			f.removeClass('ui-state-highlight');
+			t.removeClass('ui-state-highlight');
+		}
+	}
+	function _handleVolume(val) {
+		handle.text(val);
+		const ico = vol.find('.ui-icon');
+		if (val > 0 && ico.hasClass('ui-icon-volume-off')) {
+			ico.toggleClass('ui-icon-volume-off ui-icon-volume-on');
+			vol.removeClass('ui-state-error');
+			_handleMicStatus(true);
+		} else if (val === 0 && ico.hasClass('ui-icon-volume-on')) {
+			ico.toggleClass('ui-icon-volume-on ui-icon-volume-off');
+			vol.addClass('ui-state-error');
+			_handleMicStatus(false);
+		}
+		if (swf[0].setVolume !== undefined) {
+			swf[0].setVolume(val);
+		}
+	}
+	function _mute(mute) {
+		if (!slider) {
+			return;
+		}
+		if (mute) {
+			const val = slider.slider("option", "value");
+			if (val > 0) {
+				lastVolume = val;
+			}
+			slider.slider("option", "value", 0);
+			_handleVolume(0);
+		} else {
+			slider.slider("option", "value", lastVolume);
+			_handleVolume(lastVolume);
+		}
+	}
+	function _init(_c, _pos) {
+		c = _c;
+		size = {width: c.width, height: c.height};
+		const _id = VideoUtil.getVid(c.uid)
+			, name = _getName()
+			, _w = c.self ? Math.max(300, c.width) : c.width
+			, _h = c.self ? Math.max(200, c.height) : c.height
+			, opts = Room.getOptions();
+		{ //scope
+			const cont = opts.interview ? $('.pod.pod-' + c.pod) : $('.room.box');
+			cont.append($('#user-video').clone().attr('id', _id).attr('title', name)
+					.attr('data-client-uid', c.type + c.cuid).data(self));
+		}
+		v = $('#' + _id);
+		v.dialog({
+			classes: {
+				'ui-dialog': 'ui-corner-all video user-video' + (opts.showMicStatus ? ' mic-status' : '')
+				, 'ui-dialog-titlebar': 'ui-corner-all' + (opts.showMicStatus ? ' ui-state-highlight' : '')
+			}
+			, width: _w
+			, minWidth: 40
+			, minHeight: 50
+			, autoOpen: true
+			, appendTo: opts.interview ? '.pod.pod-' + c.pod : '.room.box'
+			, draggable: !opts.interview
+			, resizable: !opts.interview
+			, modal: false
+			, resizeStop: function(event, ui) {
+				const w = ui.size.width - 2
+					, h = ui.size.height - t.height() - 4 - (f.is(":visible") ? f.height() : 0);
+				_resize(w, h);
+				swf[0].vidResize(w, h);
+			}
+			, close: function() {
+				VideoManager.close(c.uid, true);
+			}
+		}).dialogExtend({
+			icons: {
+				'collapse': 'ui-icon-minus'
+			}
+			, closable: VideoUtil.isSharing(c)
+			, collapsable: true
+			, dblclick: "collapse"
+		});
+		t = v.parent().find('.ui-dialog-titlebar').attr('title', name);
+		f = v.find('.footer');
+		if (!VideoUtil.isSharing(c)) {
+			v.parent().find('.ui-dialog-titlebar-buttonpane')
+				.append($('#video-volume-btn').children().clone())
+				.append($('#video-refresh-btn').children().clone());
+			const volume = v.parent().find('.dropdown-menu.video.volume');
+			slider = v.parent().find('.slider');
+			if (opts.interview) {
+				v.parent().find('.ui-dialog-titlebar-collapse').hide();
+			}
+			vol = v.parent().find('.ui-dialog-titlebar-volume')
+				.on('mouseenter', function(e) {
+					e.stopImmediatePropagation();
+					volume.toggle();
+				})
+				.click(function(e) {
+					e.stopImmediatePropagation();
+					const muted = $(this).find('.ui-icon').hasClass('ui-icon-volume-off');
+					roomAction('mute', JSON.stringify({uid: c.cuid, mute: !muted}));
+					_mute(!muted);
+					volume.hide();
+					return false;
+				}).dblclick(function(e) {
+					e.stopImmediatePropagation();
+					return false;
+				});
+			v.parent().find('.ui-dialog-titlebar-refresh')
+				.click(function(e) {
+					e.stopImmediatePropagation();
+					_refresh();
+					return false;
+				}).dblclick(function(e) {
+					e.stopImmediatePropagation();
+					return false;
+				});
+			volume.on('mouseleave', function() {
+				$(this).hide();
+			});
+			handle = v.parent().find('.slider .handle');
+			slider.slider({
+				orientation: 'vertical'
+				, range: 'min'
+				, min: 0
+				, max: 100
+				, value: lastVolume
+				, create: function() {
+					handle.text($(this).slider("value"));
+				}
+				, slide: function(event, ui) {
+					_handleVolume(ui.value);
+				}
+			});
+			const hasAudio = VideoUtil.hasAudio(c);
+			_handleMicStatus(hasAudio);
+			if (!hasAudio) {
+				vol.hide();
+			}
+		}
+		vc = v.find('.video');
+		vc.width(_w).height(_h);
+		//broadcast
+		const o = Room.getOptions();
+		if (c.self) {
+			o.cam = c.cam;
+			o.mic = c.mic;
+			o.mode = 'broadcast';
+		} else {
+			o.mode = 'play';
+		}
+		o.av = c.activities.join();
+		o.rights = o.rights.join();
+		o.width = c.width;
+		o.height = c.height;
+		o.sid = c.sid;
+		o.uid = c.uid;
+		o.cuid = c.cuid;
+		o.userId = c.user.id;
+		o.broadcastId = c.broadcastId;
+		o.type = c.type;
+		delete o.keycode;
+		swf = initSwf(vc, 'main.swf', _id + '-swf', o);
+		swf.attr('width', _w).attr('height', _h);
+		v.dialog("widget").css(_pos);
+	}
+	function _update(_c) {
+		const opts = Room.getOptions();
+		c.screenActivities = _c.screenActivities;
+		c.activities = _c.activities;
+		c.user.firstName = _c.user.firstName;
+		c.user.lastName = _c.user.lastName;
+		const hasAudio = VideoUtil.hasAudio(c);
+		_handleMicStatus(hasAudio);
+		if (hasAudio) {
+			vol.show();
+		} else {
+			vol.hide();
+			v.parent().find('.dropdown-menu.video.volume').hide();
+		}
+		if (opts.interview && c.pod !== _c.pod) {
+			c.pod = _c.pod;
+			v.dialog('option', 'appendTo', '.pod.pod-' + c.pod);
+		}
+		const name = _getName();
+		v.dialog('option', 'title', name).parent().find('.ui-dialog-titlebar').attr('title', name);
+		if (swf[0].update !== undefined) {
+			c.self ? swf[0].update() : swf[0].update(c);
+		}
+	}
+	function _refresh(_opts) {
+		if (swf[0].refresh !== undefined) {
+			const opts = _opts || {};
+			if (!Room.getOptions().interview && !isNaN(opts.width)) {
+				_resizeDlg(opts.width, opts.height);
+			}
+			swf[0].refresh(opts);
+		}
+	}
+	function _setRights(_r) {
+		if (swf[0].setRights !== undefined) {
+			swf[0].setRights(_r);
+		}
+	}
+
+	self.update = _update;
+	self.refresh = _refresh;
+	self.mute = _mute;
+	self.isMuted = function() { return 0 === slider.slider("option", "value"); };
+	self.init = _init;
+	self.securityMode = _securityMode;
+	self.client = function() { return c; };
+	self.setRights = _setRights;
+	return self;
+});
+var VideoManager = (function() {
+	const self = {};
+	let share, inited = false;
+
+	function _init() {
+		if ($(WB_AREA_SEL + ' .wb-area .tabs').length > 0) {
+			WBA_SEL = WBA_WB_SEL;
+		}
+		VideoSettings.init(Room.getOptions());
+		share = $('.room.box').find('.icon.shared.ui-button');
+		inited = true;
+	}
+	function _update(c) {
+		if (!inited) {
+			return;
+		}
+		for (let i = 0; i < c.streams.length; ++i) {
+			const cl = JSON.parse(JSON.stringify(c)), s = c.streams[i];
+			delete cl.streams;
+			$.extend(cl, s);
+			if (cl.self && VideoUtil.isSharing(cl) || VideoUtil.isRecording(cl)) {
+				continue;
+			}
+			const _id = VideoUtil.getVid(cl.uid)
+				, av = VideoUtil.hasAudio(cl) || VideoUtil.hasVideo(cl)
+				, v = $('#' + _id);
+			if (av && v.length !== 1 && !!cl.self) {
+				Video().init(cl, VideoUtil.getPos(VideoUtil.getRects(VID_SEL), cl.width, cl.height + 25));
+			} else if (av && v.length === 1) {
+				v.data().update(cl);
+			} else if (!av && v.length === 1) {
+				_closeV(v);
+			}
+		}
+		if (c.uid === Room.getOptions().uid) {
+			Room.setRights(c.rights);
+			const windows = $(VID_SEL + ' .ui-dialog-content');
+			for (let i = 0; i < windows.length; ++i) {
+				const w = $(windows[i]);
+				w.data().setRights(c.rights);
+			}
+
+		}
+		if (c.streams.length === 0) {
+			// check for non inited video window
+			const v = $('#' + VideoUtil.getVid(c.uid));
+			if (v.length === 1) {
+				_closeV(v);
+			}
+		}
+	}
+	function _closeV(v) {
+		if (v.dialog('instance') !== undefined) {
+			v.dialog('destroy');
+		}
+		v.remove();
+	}
+	function _play(c) {
+		if (!inited) {
+			return;
+		}
+		if (VideoUtil.isSharing(c)) {
+			_highlight(share
+					.attr('title', share.data('user') + ' ' + c.user.firstName + ' ' + c.user.lastName + ' ' + share.data('text'))
+					.data('uid', c.uid)
+					.show(), 10);
+			share.tooltip().off('click').click(function() {
+				const v = $('#' + VideoUtil.getVid(c.uid))
+				if (v.length !== 1) {
+					Video().init(c, $(WBA_SEL).offset());
+				} else {
+					v.dialog('open');
+				}
+			});
+		} else if ('sharing' !== c.type) {
+			Video().init(c, VideoUtil.getPos(VideoUtil.getRects(VID_SEL), c.width, c.height + 25));
+		}
+	}
+	function _close(uid, showShareBtn) {
+		const _id = VideoUtil.getVid(uid), v = $('#' + _id);
+		if (v.length === 1) {
+			_closeV(v);
+		}
+		if (!showShareBtn && uid === share.data('uid')) {
+			share.off('click').hide();
+		}
+	}
+	function _highlight(el, count) {
+		if (count < 0) {
+			return;
+		}
+		el.addClass('ui-state-highlight', 2000, function() {
+			el.removeClass('ui-state-highlight', 2000, function() {
+				_highlight(el, --count);
+			});
+		});
+	}
+	function _find(uid) {
+		return $(VID_SEL + ' div[data-client-uid="room' + uid + '"]');
+	}
+	function _micActivity(uid, active) {
+		const u = $('#user' + uid + ' .audio-activity.ui-icon')
+			, v = _find(uid).parent();
+		if (active) {
+			u.addClass("speaking");
+			v.addClass('user-speaks')
+		} else {
+			u.removeClass("speaking");
+			v.removeClass('user-speaks')
+		}
+	}
+	function _refresh(uid, opts) {
+		const v = _find(uid);
+		if (v.length > 0) {
+			v.data().refresh(opts);
+		}
+	}
+	function _mute(uid, mute) {
+		const v = _find(uid);
+		if (v.length > 0) {
+			v.data().mute(mute);
+		}
+	}
+	function _clickExclusive(uid) {
+		const s = VideoSettings.load();
+		if (false !== s.video.confirmExclusive) {
+			const dlg = $('#exclusive-confirm');
+			dlg.dialog({
+				buttons: [
+					{
+						text: dlg.data('btn-ok')
+						, click: function() {
+							s.video.confirmExclusive = !$('#exclusive-confirm-dont-show').prop('checked');
+							VideoSettings.save();
+							roomAction('exclusive', uid);
+							$(this).dialog('close');
+						}
+					}
+					, {
+						text: dlg.data('btn-cancel')
+						, click: function() {
+							$(this).dialog('close');
+						}
+					}
+				]
+			})
+		}
+	}
+	function _exclusive(uid) {
+		const windows = $(VID_SEL + ' .ui-dialog-content');
+		for (let i = 0; i < windows.length; ++i) {
+			const w = $(windows[i]);
+			w.data().mute('room' + uid !== w.data('client-uid'));
+		}
+	}
+
+	self.init = _init;
+	self.update = _update;
+	self.play = _play;
+	self.close = _close;
+	self.securityMode = function(uid, on) { $('#' + VideoUtil.getVid(uid)).data().securityMode(on); };
+	self.micActivity = _micActivity;
+	self.refresh = _refresh;
+	self.mute = _mute;
+	self.clickExclusive = _clickExclusive;
+	self.exclusive = _exclusive;
+	return self;
+})();
+var Room = (function() {
+	const self = {}, sbSide = Settings.isRtl ? 'right' : 'left';
+	let options, menuHeight, chat, sb, dock;
+
+	function _init(_options) {
+		options = _options;
+		window.WbArea = options.interview ? InterviewWbArea() : DrawWbArea();
+		const menu = $('.room.box .room.menu');
+		chat = $('#chatPanel');
+		sb = $('.room.sidebar').css(sbSide, '0px');
+		dock = sb.find('.btn-dock').button({
+			icon: "ui-icon icon-undock"
+			, showLabel: false
+		}).click(function() {
+			const offset = parseInt(sb.css(sbSide));
+			if (offset < 0) {
+				sb.removeClass('closed');
+			}
+			dock.button('option', 'disabled', true);
+			const props = {};
+			props[sbSide] = offset < 0 ? '0px' : (-sb.width() + 45) + 'px';
+			sb.animate(props, 1500
+				, function() {
+					dock.button('option', 'disabled', false)
+						.button('option', 'icon', 'ui-icon ' + (offset < 0 ? 'icon-undock' : 'icon-dock'));
+					if (offset < 0) {
+						dock.attr('title', dock.data('ttl-undock'));
+						_sbAddResizable();
+					} else {
+						dock.attr('title', dock.data('ttl-dock'));
+						sb.addClass('closed').resizable('destroy');
+					}
+					_setSize();
+				});
+		});
+		dock.addClass(Settings.isRtl ? 'align-left' : 'align-right').attr('title', dock.data('ttl-undock'))
+			.button('option', 'label', dock.data('ttl-undock'))
+			.button('refresh');
+		menuHeight = menu.length === 0 ? 0 : menu.height();
+		VideoManager.init();
+		Activities.init();
+	}
+	function _getSelfAudioClient() {
+		const vw = $('#video' + Room.getOptions().uid);
+		if (vw.length > 0) {
+			const v = vw.data();
+			if (VideoUtil.hasAudio(v.client())) {
+				return v;
+			}
+		}
+		return null;
+	}
+	function _keyHandler(e) {
+		if (e.shiftKey) {
+			switch (e.which) {
+				case options.keycode.arrange: // Shift+F8 by default
+					VideoUtil.arrange();
+					break;
+				case options.keycode.exclusive: // Shift+F12 by default
+				{
+					const v = _getSelfAudioClient();
+					if (v !== null) {
+						VideoManager.clickExclusive(Room.getOptions().uid);
+					}
+				}
+					break;
+				case options.keycode.mute: // Shift+F7 by default
+				{
+					const v = _getSelfAudioClient();
+					if (v !== null) {
+						v.mute(!v.isMuted());
+					}
+				}
+					break;
+			}
+		}
+		if (e.which === 27) {
+			$('#wb-rename-menu').hide();
+		}
+	}
+	function _mouseHandler(e) {
+		if (e.which === 1) {
+			$('#wb-rename-menu').hide();
+		}
+	}
+	function _sbWidth() {
+		if (sb === undefined) {
+			sb = $('.room.sidebar');
+		}
+		return sb === undefined ? 0 : sb.width() + parseInt(sb.css(sbSide));
+	}
+	function _setSize() {
+		const sbW = _sbWidth()
+			, w = $(window).width() - sbW - 8
+			, h = $(window).height() - menuHeight - 3
+			, p = sb.find('.tabs')
+			, holder = $('.room.holder');
+		sb.height(h);
+		const hh = h - 5;
+		p.height(hh);
+		$(".user.list", p).height(hh - $("ul", p).height() - $(".user.header", p).height() - 5);
+		if (sbW > 255) {
+			holder.addClass('big').removeClass('small');
+		} else {
+			holder.removeClass('big').addClass('small');
+		}
+		Chat.setHeight(h);
+		if (typeof(WbArea) !== 'undefined') {
+			const chW = chat.width();
+			WbArea.resize(sbW + 5, chW + 5, w - chW, h);
+		}
+	}
+	function _reload() {
+		if (!!options && !!options.reloadUrl) {
+			window.location.href = options.reloadUrl;
+		} else {
+			window.location.reload();
+		}
+	}
+	function _close() {
+		_unload();
+		$(".room.holder").remove();
+		$("#chatPanel").remove();
+		const dlg = $('#disconnected-dlg');
+		dlg.dialog({
+			modal: true
+			, close: _reload
+			, buttons: [
+				{
+					text: dlg.data('reload')
+					, icons: {primary: "ui-icon-refresh"}
+					, click: function() {
+						$(this).dialog("close");
+					}
+				}
+			]
+		});
+	}
+	function _sbAddResizable() {
+		sb.resizable({
+			handles: Settings.isRtl ? 'w' : 'e'
+			, stop: function() {
+				_setSize();
+			}
+		});
+	}
+	function _load() {
+		if (sb !== undefined) {
+			sb.ready(function() {
+				_setSize();
+			});
+			_sbAddResizable();
+		}
+		$(window).on('resize.openmeetings', function() {
+			_setSize();
+		});
+		Wicket.Event.subscribe("/websocket/closed", _close);
+		Wicket.Event.subscribe("/websocket/error", _close);
+		$(window).keyup(_keyHandler);
+		$(document).click(_mouseHandler);
+	}
+	function _unload() {
+		$(window).off('resize.openmeetings');
+		Wicket.Event.unsubscribe("/websocket/closed", _close);
+		Wicket.Event.unsubscribe("/websocket/error", _close);
+		if (typeof(WbArea) !== 'undefined') {
+			WbArea.destroy();
+			WbArea = undefined;
+		}
+		if (typeof(VideoSettings) !== 'undefined') {
+			VideoSettings.close();
+		}
+		$('.ui-dialog.user-video').remove();
+		$(window).off('keyup', _keyHandler);
+		$(document).off('click', _mouseHandler);
+	}
+	function _showClipboard(txt) {
+		const dlg = $('#clipboard-dialog');
+		dlg.find('p .text').text(txt);
+		dlg.dialog({
+			resizable: false
+			, height: "auto"
+			, width: 400
+			, modal: true
+			, buttons: [
+				{
+					text: dlg.data('btn-ok')
+					, click: function() {
+						$(this).dialog('close');
+					}
+				}
+			]
+		});
+	}
+
+	self.init = _init;
+	self.getMenuHeight = function() { return menuHeight; };
+	self.getOptions = function() { return typeof(options) === 'object' ? JSON.parse(JSON.stringify(options)) : {}; };
+	self.setRights = function(_r) { return options.rights = _r; };
+	self.setSize = _setSize;
+	self.load = _load;
+	self.unload = _unload;
+	self.showClipboard = _showClipboard;
+	return self;
+})();
+function startPrivateChat(el) {
+	Chat.addTab('chatTab-u' + el.parent().parent().data("userid"), el.parent().parent().find('.user.name').text());
+	Chat.open();
+	$('#chatMessage .wysiwyg-editor').click();
+}
+/***** functions required by SIP   ******/
+function sipBtnClick() {
+	const txt = $('.sip-number');
+	txt.val(txt.val() + $(this).data('value'));
+}
+function sipBtnEraseClick() {
+	const txt = $('.sip-number')
+		, t = txt.val();
+	if (!!t) {
+		txt.val(t.substring(0, t.length -1));
+	}
+}
+function sipGetKey(evt) {
+	let k = -1;
+	if (evt.keyCode > 47 && evt.keyCode < 58) {
+		k = evt.keyCode - 48;
+	}
+	if (evt.keyCode > 95 && evt.keyCode < 106) {
+		k = evt.keyCode - 96;
+	}
+	return k;
+}
+function sipKeyDown(evt) {
+	const k = sipGetKey(evt);
+	if (k > 0) {
+		$('#sip-dialer-btn-' + k).addClass('ui-state-active');
+	}
+}
+function sipKeyUp(evt) {
+	const k = sipGetKey(evt);
+	if (k > 0) {
+		$('#sip-dialer-btn-' + k).removeClass('ui-state-active');
+	}
+}
+/***** functions required by SWF   ******/
+function typingActivity(uid, active) {
+	const u = $('#user' + uid + ' .typing-activity.ui-icon');
+	if (active) {
+		u.addClass("typing");
+	} else {
+		u.removeClass("typing");
+	}
+}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ae1b51a9/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
deleted file mode 100644
index edafe4c..0000000
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
+++ /dev/null
@@ -1,818 +0,0 @@
-/* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */
-const WB_AREA_SEL = '.room.wb.area';
-const WBA_WB_SEL = '.room.wb.area .ui-tabs-panel.ui-corner-bottom.ui-widget-content:visible';
-var WBA_SEL = WB_AREA_SEL;
-const VID_SEL = '.video.user-video';
-var RoomUtil = (function() {
-	const self = {};
-	function _confirmDlg(_id, okHandler) {
-		const confirm = $('#' + _id);
-		confirm.dialog({
-			modal: true
-			, buttons: [
-				{
-					text: confirm.data('btn-ok')
-					, click: function() {
-						okHandler();
-						$(this).dialog('close');
-					}
-				}
-				, {
-					text: confirm.data('btn-cancel')
-					, click: function() {
-						$(this).dialog('close');
-					}
-				}
-			]
-		});
-		return confirm;
-	}
-
-	self.confirmDlg = _confirmDlg;
-	return self;
-})();
-var VideoUtil = (function() {
-	const self = {};
-	function _getVid(uid) {
-		return "video" + uid;
-	}
-	function _isSharing(c) {
-		return 'sharing' === c.type && c.screenActivities.indexOf('sharing') > -1;
-	}
-	function _isRecording(c) {
-		return 'sharing' === c.type
-			&& c.screenActivities.indexOf('recording') > -1
-			&& c.screenActivities.indexOf('sharing') < 0;
-	}
-	function _hasAudio(c) {
-		return c.activities.indexOf('broadcastA') > -1;
-	}
-	function _hasVideo(c) {
-		return c.activities.indexOf('broadcastV') > -1;
-	}
-	function _getRects(sel, excl) {
-		const list = [], elems = $(sel);
-		for (let i = 0; i < elems.length; ++i) {
-			if (excl !== $(elems[i]).attr('aria-describedby')) {
-				list.push(_getRect(elems[i]));
-			}
-		}
-		return list;
-	}
-	function _getRect(e) {
-		const win = $(e), winoff = win.offset();
-		return {left: winoff.left
-			, top: winoff.top
-			, right: winoff.left + win.width()
-			, bottom: winoff.top + win.height()};
-	}
-	function _getPos(list, w, h) {
-		if (Room.getOptions().interview) {
-			return {left: 0, top: 0};
-		}
-		const wba = $(WBA_SEL), woffset = wba.offset()
-			, offsetX = 20, offsetY = 10
-			, area = {left: woffset.left, top: woffset.top, right: woffset.left + wba.width(), bottom: woffset.top + wba.height()};
-		const rectNew = {
-				_left: area.left
-				, _top: area.top
-				, right: area.left + w
-				, bottom: area.top + h
-				, get left() {
-					return this._left
-				}
-				, set left(l) {
-					this._left = l;
-					this.right = l + w;
-				}
-				, get top() {
-					return this._top
-				}
-				, set top(t) {
-					this._top = t;
-					this.bottom = t + h;
-				}
-			};
-		let minY = area.bottom, posFound;
-		do {
-			posFound = true
-			for (let i = 0; i < list.length; ++i) {
-				const rect = list[i];
-				minY = Math.min(minY, rect.bottom);
-
-				if (rectNew.left < rect.right && rectNew.right > rect.left && rectNew.top < rect.bottom && rectNew.bottom > rect.top) {
-					rectNew.left = rect.right + offsetX;
-					posFound = false;
-				}
-				if (rectNew.right >= area.right) {
-					rectNew.left = area.left;
-					rectNew.top = minY + offsetY;
-					posFound = false;
-				}
-				if (rectNew.bottom >= area.bottom) {
-					rectNew.top = area.top;
-					posFound = true;
-					break;
-				}
-			}
-		} while (!posFound);
-		return {left: rectNew.left, top: rectNew.top};
-	}
-	function _arrange() {
-		const list = [], elems = $(VID_SEL);
-		for (let i = 0; i < elems.length; ++i) {
-			const v = $(elems[i]);
-			v.css(_getPos(list, v.width(), v.height()));
-			list.push(_getRect(v));
-		}
-	}
-
-	self.getVid = _getVid;
-	self.isSharing = _isSharing;
-	self.isRecording = _isRecording;
-	self.hasAudio = _hasAudio;
-	self.hasVideo = _hasVideo;
-	self.getRects = _getRects;
-	self.getPos = _getPos;
-	self.arrange = _arrange;
-	return self;
-})();
-var Video = (function() {
-	const self = {};
-	let c, v, vc, t, f, swf, size, vol, slider, handle
-		, lastVolume = 50;
-
-	function _getName() {
-		return c.user.firstName + ' ' + c.user.lastName;
-	}
-	function _resizeDlg(_ww, _hh) {
-		const interview = Room.getOptions().interview;
-		const _w = interview ? 320 : _ww, _h = interview ? 260 : _hh;
-		const h = _h + t.height() + 2 + (f.is(":visible") ? f.height() : 0);
-		v.dialog("option", "width", _w).dialog("option", "height", h);
-		_resize(_w, _h);
-		return h;
-	}
-	function _securityMode(on) {
-		if (Room.getOptions().interview) {
-			return;
-		}
-		if (on) {
-			//TODO buttons
-			v.dialog("option", "position", {my: "center", at: "center", of: WBA_SEL});
-		} else {
-			const h = _resizeDlg(size.width, size.height);
-			v.dialog("widget").css(VideoUtil.getPos(VideoUtil.getRects(VID_SEL, VideoUtil.getVid(c.uid)), c.width, h));
-		}
-	}
-	function _resize(w, h) {
-		vc.width(w).height(h);
-		swf.attr('width', w).attr('height', h);
-	}
-	function _handleMicStatus(state) {
-		if (!f.is(":visible")) {
-			return;
-		}
-		if (state) {
-			f.find('.off').hide();
-			f.find('.on').show();
-			f.addClass('ui-state-highlight');
-			t.addClass('ui-state-highlight');
-		} else {
-			f.find('.off').show();
-			f.find('.on').hide();
-			f.removeClass('ui-state-highlight');
-			t.removeClass('ui-state-highlight');
-		}
-	}
-	function _handleVolume(val) {
-		handle.text(val);
-		const ico = vol.find('.ui-icon');
-		if (val > 0 && ico.hasClass('ui-icon-volume-off')) {
-			ico.toggleClass('ui-icon-volume-off ui-icon-volume-on');
-			vol.removeClass('ui-state-error');
-			_handleMicStatus(true);
-		} else if (val === 0 && ico.hasClass('ui-icon-volume-on')) {
-			ico.toggleClass('ui-icon-volume-on ui-icon-volume-off');
-			vol.addClass('ui-state-error');
-			_handleMicStatus(false);
-		}
-		if (swf[0].setVolume !== undefined) {
-			swf[0].setVolume(val);
-		}
-	}
-	function _mute(mute) {
-		if (!slider) {
-			return;
-		}
-		if (mute) {
-			const val = slider.slider("option", "value");
-			if (val > 0) {
-				lastVolume = val;
-			}
-			slider.slider("option", "value", 0);
-			_handleVolume(0);
-		} else {
-			slider.slider("option", "value", lastVolume);
-			_handleVolume(lastVolume);
-		}
-	}
-	function _init(_c, _pos) {
-		c = _c;
-		size = {width: c.width, height: c.height};
-		const _id = VideoUtil.getVid(c.uid)
-			, name = _getName()
-			, _w = c.self ? Math.max(300, c.width) : c.width
-			, _h = c.self ? Math.max(200, c.height) : c.height
-			, opts = Room.getOptions();
-		{ //scope
-			const cont = opts.interview ? $('.pod.pod-' + c.pod) : $('.room.box');
-			cont.append($('#user-video').clone().attr('id', _id).attr('title', name)
-					.attr('data-client-uid', c.type + c.cuid).data(self));
-		}
-		v = $('#' + _id);
-		v.dialog({
-			classes: {
-				'ui-dialog': 'ui-corner-all video user-video' + (opts.showMicStatus ? ' mic-status' : '')
-				, 'ui-dialog-titlebar': 'ui-corner-all' + (opts.showMicStatus ? ' ui-state-highlight' : '')
-			}
-			, width: _w
-			, minWidth: 40
-			, minHeight: 50
-			, autoOpen: true
-			, appendTo: opts.interview ? '.pod.pod-' + c.pod : '.room.box'
-			, draggable: !opts.interview
-			, resizable: !opts.interview
-			, modal: false
-			, resizeStop: function(event, ui) {
-				const w = ui.size.width - 2
-					, h = ui.size.height - t.height() - 4 - (f.is(":visible") ? f.height() : 0);
-				_resize(w, h);
-				swf[0].vidResize(w, h);
-			}
-			, close: function() {
-				VideoManager.close(c.uid, true);
-			}
-		}).dialogExtend({
-			icons: {
-				'collapse': 'ui-icon-minus'
-			}
-			, closable: VideoUtil.isSharing(c)
-			, collapsable: true
-			, dblclick: "collapse"
-		});
-		t = v.parent().find('.ui-dialog-titlebar').attr('title', name);
-		f = v.find('.footer');
-		if (!VideoUtil.isSharing(c)) {
-			v.parent().find('.ui-dialog-titlebar-buttonpane')
-				.append($('#video-volume-btn').children().clone())
-				.append($('#video-refresh-btn').children().clone());
-			const volume = v.parent().find('.dropdown-menu.video.volume');
-			slider = v.parent().find('.slider');
-			if (opts.interview) {
-				v.parent().find('.ui-dialog-titlebar-collapse').hide();
-			}
-			vol = v.parent().find('.ui-dialog-titlebar-volume')
-				.on('mouseenter', function(e) {
-					e.stopImmediatePropagation();
-					volume.toggle();
-				})
-				.click(function(e) {
-					e.stopImmediatePropagation();
-					const muted = $(this).find('.ui-icon').hasClass('ui-icon-volume-off');
-					roomAction('mute', JSON.stringify({uid: c.cuid, mute: !muted}));
-					_mute(!muted);
-					volume.hide();
-					return false;
-				}).dblclick(function(e) {
-					e.stopImmediatePropagation();
-					return false;
-				});
-			v.parent().find('.ui-dialog-titlebar-refresh')
-				.click(function(e) {
-					e.stopImmediatePropagation();
-					_refresh();
-					return false;
-				}).dblclick(function(e) {
-					e.stopImmediatePropagation();
-					return false;
-				});
-			volume.on('mouseleave', function() {
-				$(this).hide();
-			});
-			handle = v.parent().find('.slider .handle');
-			slider.slider({
-				orientation: 'vertical'
-				, range: 'min'
-				, min: 0
-				, max: 100
-				, value: lastVolume
-				, create: function() {
-					handle.text($(this).slider("value"));
-				}
-				, slide: function(event, ui) {
-					_handleVolume(ui.value);
-				}
-			});
-			const hasAudio = VideoUtil.hasAudio(c);
-			_handleMicStatus(hasAudio);
-			if (!hasAudio) {
-				vol.hide();
-			}
-		}
-		vc = v.find('.video');
-		vc.width(_w).height(_h);
-		//broadcast
-		const o = Room.getOptions();
-		if (c.self) {
-			o.cam = c.cam;
-			o.mic = c.mic;
-			o.mode = 'broadcast';
-		} else {
-			o.mode = 'play';
-		}
-		o.av = c.activities.join();
-		o.rights = o.rights.join();
-		o.width = c.width;
-		o.height = c.height;
-		o.sid = c.sid;
-		o.uid = c.uid;
-		o.cuid = c.cuid;
-		o.userId = c.user.id;
-		o.broadcastId = c.broadcastId;
-		o.type = c.type;
-		delete o.keycode;
-		swf = initSwf(vc, 'main.swf', _id + '-swf', o);
-		swf.attr('width', _w).attr('height', _h);
-		v.dialog("widget").css(_pos);
-	}
-	function _update(_c) {
-		const opts = Room.getOptions();
-		c.screenActivities = _c.screenActivities;
-		c.activities = _c.activities;
-		c.user.firstName = _c.user.firstName;
-		c.user.lastName = _c.user.lastName;
-		const hasAudio = VideoUtil.hasAudio(c);
-		_handleMicStatus(hasAudio);
-		if (hasAudio) {
-			vol.show();
-		} else {
-			vol.hide();
-			v.parent().find('.dropdown-menu.video.volume').hide();
-		}
-		if (opts.interview && c.pod !== _c.pod) {
-			c.pod = _c.pod;
-			v.dialog('option', 'appendTo', '.pod.pod-' + c.pod);
-		}
-		const name = _getName();
-		v.dialog('option', 'title', name).parent().find('.ui-dialog-titlebar').attr('title', name);
-		if (swf[0].update !== undefined) {
-			c.self ? swf[0].update() : swf[0].update(c);
-		}
-	}
-	function _refresh(_opts) {
-		if (swf[0].refresh !== undefined) {
-			const opts = _opts || {};
-			if (!Room.getOptions().interview && !isNaN(opts.width)) {
-				_resizeDlg(opts.width, opts.height);
-			}
-			swf[0].refresh(opts);
-		}
-	}
-	function _setRights(_r) {
-		if (swf[0].setRights !== undefined) {
-			swf[0].setRights(_r);
-		}
-	}
-
-	self.update = _update;
-	self.refresh = _refresh;
-	self.mute = _mute;
-	self.isMuted = function() { return 0 === slider.slider("option", "value"); };
-	self.init = _init;
-	self.securityMode = _securityMode;
-	self.client = function() { return c; };
-	self.setRights = _setRights;
-	return self;
-});
-var VideoManager = (function() {
-	const self = {};
-	let share, inited = false;
-
-	function _init() {
-		if ($(WB_AREA_SEL + ' .wb-area .tabs').length > 0) {
-			WBA_SEL = WBA_WB_SEL;
-		}
-		VideoSettings.init(Room.getOptions());
-		share = $('.room.box').find('.icon.shared.ui-button');
-		inited = true;
-	}
-	function _update(c) {
-		if (!inited) {
-			return;
-		}
-		for (let i = 0; i < c.streams.length; ++i) {
-			const cl = JSON.parse(JSON.stringify(c)), s = c.streams[i];
-			delete cl.streams;
-			$.extend(cl, s);
-			if (cl.self && VideoUtil.isSharing(cl) || VideoUtil.isRecording(cl)) {
-				continue;
-			}
-			const _id = VideoUtil.getVid(cl.uid)
-				, av = VideoUtil.hasAudio(cl) || VideoUtil.hasVideo(cl)
-				, v = $('#' + _id);
-			if (av && v.length !== 1 && !!cl.self) {
-				Video().init(cl, VideoUtil.getPos(VideoUtil.getRects(VID_SEL), cl.width, cl.height + 25));
-			} else if (av && v.length === 1) {
-				v.data().update(cl);
-			} else if (!av && v.length === 1) {
-				_closeV(v);
-			}
-		}
-		if (c.uid === Room.getOptions().uid) {
-			Room.setRights(c.rights);
-			const windows = $(VID_SEL + ' .ui-dialog-content');
-			for (let i = 0; i < windows.length; ++i) {
-				const w = $(windows[i]);
-				w.data().setRights(c.rights);
-			}
-
-		}
-		if (c.streams.length === 0) {
-			// check for non inited video window
-			const v = $('#' + VideoUtil.getVid(c.uid));
-			if (v.length === 1) {
-				_closeV(v);
-			}
-		}
-	}
-	function _closeV(v) {
-		if (v.dialog('instance') !== undefined) {
-			v.dialog('destroy');
-		}
-		v.remove();
-	}
-	function _play(c) {
-		if (!inited) {
-			return;
-		}
-		if (VideoUtil.isSharing(c)) {
-			_highlight(share
-					.attr('title', share.data('user') + ' ' + c.user.firstName + ' ' + c.user.lastName + ' ' + share.data('text'))
-					.data('uid', c.uid)
-					.show(), 10);
-			share.tooltip().off('click').click(function() {
-				const v = $('#' + VideoUtil.getVid(c.uid))
-				if (v.length !== 1) {
-					Video().init(c, $(WBA_SEL).offset());
-				} else {
-					v.dialog('open');
-				}
-			});
-		} else if ('sharing' !== c.type) {
-			Video().init(c, VideoUtil.getPos(VideoUtil.getRects(VID_SEL), c.width, c.height + 25));
-		}
-	}
-	function _close(uid, showShareBtn) {
-		const _id = VideoUtil.getVid(uid), v = $('#' + _id);
-		if (v.length === 1) {
-			_closeV(v);
-		}
-		if (!showShareBtn && uid === share.data('uid')) {
-			share.off('click').hide();
-		}
-	}
-	function _highlight(el, count) {
-		if (count < 0) {
-			return;
-		}
-		el.addClass('ui-state-highlight', 2000, function() {
-			el.removeClass('ui-state-highlight', 2000, function() {
-				_highlight(el, --count);
-			});
-		});
-	}
-	function _find(uid) {
-		return $(VID_SEL + ' div[data-client-uid="room' + uid + '"]');
-	}
-	function _micActivity(uid, active) {
-		const u = $('#user' + uid + ' .audio-activity.ui-icon')
-			, v = _find(uid).parent();
-		if (active) {
-			u.addClass("speaking");
-			v.addClass('user-speaks')
-		} else {
-			u.removeClass("speaking");
-			v.removeClass('user-speaks')
-		}
-	}
-	function _refresh(uid, opts) {
-		const v = _find(uid);
-		if (v.length > 0) {
-			v.data().refresh(opts);
-		}
-	}
-	function _mute(uid, mute) {
-		const v = _find(uid);
-		if (v.length > 0) {
-			v.data().mute(mute);
-		}
-	}
-	function _clickExclusive(uid) {
-		const s = VideoSettings.load();
-		if (false !== s.video.confirmExclusive) {
-			const dlg = $('#exclusive-confirm');
-			dlg.dialog({
-				buttons: [
-					{
-						text: dlg.data('btn-ok')
-						, click: function() {
-							s.video.confirmExclusive = !$('#exclusive-confirm-dont-show').prop('checked');
-							VideoSettings.save();
-							roomAction('exclusive', uid);
-							$(this).dialog('close');
-						}
-					}
-					, {
-						text: dlg.data('btn-cancel')
-						, click: function() {
-							$(this).dialog('close');
-						}
-					}
-				]
-			})
-		}
-	}
-	function _exclusive(uid) {
-		const windows = $(VID_SEL + ' .ui-dialog-content');
-		for (let i = 0; i < windows.length; ++i) {
-			const w = $(windows[i]);
-			w.data().mute('room' + uid !== w.data('client-uid'));
-		}
-	}
-
-	self.init = _init;
-	self.update = _update;
-	self.play = _play;
-	self.close = _close;
-	self.securityMode = function(uid, on) { $('#' + VideoUtil.getVid(uid)).data().securityMode(on); };
-	self.micActivity = _micActivity;
-	self.refresh = _refresh;
-	self.mute = _mute;
-	self.clickExclusive = _clickExclusive;
-	self.exclusive = _exclusive;
-	return self;
-})();
-var Room = (function() {
-	const self = {}, sbSide = Settings.isRtl ? 'right' : 'left';
-	let options, menuHeight, chat, sb, dock;
-
-	function _init(_options) {
-		options = _options;
-		window.WbArea = options.interview ? InterviewWbArea() : DrawWbArea();
-		const menu = $('.room.box .room.menu');
-		chat = $('#chatPanel');
-		sb = $('.room.sidebar').css(sbSide, '0px');
-		dock = sb.find('.btn-dock').button({
-			icon: "ui-icon icon-undock"
-			, showLabel: false
-		}).click(function() {
-			const offset = parseInt(sb.css(sbSide));
-			if (offset < 0) {
-				sb.removeClass('closed');
-			}
-			dock.button('option', 'disabled', true);
-			const props = {};
-			props[sbSide] = offset < 0 ? '0px' : (-sb.width() + 45) + 'px';
-			sb.animate(props, 1500
-				, function() {
-					dock.button('option', 'disabled', false)
-						.button('option', 'icon', 'ui-icon ' + (offset < 0 ? 'icon-undock' : 'icon-dock'));
-					if (offset < 0) {
-						dock.attr('title', dock.data('ttl-undock'));
-						_sbAddResizable();
-					} else {
-						dock.attr('title', dock.data('ttl-dock'));
-						sb.addClass('closed').resizable('destroy');
-					}
-					_setSize();
-				});
-		});
-		dock.addClass(Settings.isRtl ? 'align-left' : 'align-right').attr('title', dock.data('ttl-undock'))
-			.button('option', 'label', dock.data('ttl-undock'))
-			.button('refresh');
-		menuHeight = menu.length === 0 ? 0 : menu.height();
-		VideoManager.init();
-		Activities.init();
-	}
-	function _getSelfAudioClient() {
-		const vw = $('#video' + Room.getOptions().uid);
-		if (vw.length > 0) {
-			const v = vw.data();
-			if (VideoUtil.hasAudio(v.client())) {
-				return v;
-			}
-		}
-		return null;
-	}
-	function _keyHandler(e) {
-		if (e.shiftKey) {
-			switch (e.which) {
-				case options.keycode.arrange: // Shift+F8 by default
-					VideoUtil.arrange();
-					break;
-				case options.keycode.exclusive: // Shift+F12 by default
-				{
-					const v = _getSelfAudioClient();
-					if (v !== null) {
-						VideoManager.clickExclusive(Room.getOptions().uid);
-					}
-				}
-					break;
-				case options.keycode.mute: // Shift+F7 by default
-				{
-					const v = _getSelfAudioClient();
-					if (v !== null) {
-						v.mute(!v.isMuted());
-					}
-				}
-					break;
-			}
-		}
-		if (e.which === 27) {
-			$('#wb-rename-menu').hide();
-		}
-	}
-	function _mouseHandler(e) {
-		if (e.which === 1) {
-			$('#wb-rename-menu').hide();
-		}
-	}
-	function _sbWidth() {
-		if (sb === undefined) {
-			sb = $('.room.sidebar');
-		}
-		return sb === undefined ? 0 : sb.width() + parseInt(sb.css(sbSide));
-	}
-	function _setSize() {
-		const sbW = _sbWidth()
-			, w = $(window).width() - sbW - 8
-			, h = $(window).height() - menuHeight - 3
-			, p = sb.find('.tabs')
-			, holder = $('.room.holder');
-		sb.height(h);
-		const hh = h - 5;
-		p.height(hh);
-		$(".user.list", p).height(hh - $("ul", p).height() - $(".user.header", p).height() - 5);
-		if (sbW > 255) {
-			holder.addClass('big').removeClass('small');
-		} else {
-			holder.removeClass('big').addClass('small');
-		}
-		Chat.setHeight(h);
-		if (typeof(WbArea) !== 'undefined') {
-			const chW = chat.width();
-			WbArea.resize(sbW + 5, chW + 5, w - chW, h);
-		}
-	}
-	function _reload() {
-		if (!!options && !!options.reloadUrl) {
-			window.location.href = options.reloadUrl;
-		} else {
-			window.location.reload();
-		}
-	}
-	function _close() {
-		_unload();
-		$(".room.holder").remove();
-		$("#chatPanel").remove();
-		const dlg = $('#disconnected-dlg');
-		dlg.dialog({
-			modal: true
-			, close: _reload
-			, buttons: [
-				{
-					text: dlg.data('reload')
-					, icons: {primary: "ui-icon-refresh"}
-					, click: function() {
-						$(this).dialog("close");
-					}
-				}
-			]
-		});
-	}
-	function _sbAddResizable() {
-		sb.resizable({
-			handles: Settings.isRtl ? 'w' : 'e'
-			, stop: function() {
-				_setSize();
-			}
-		});
-	}
-	function _load() {
-		if (sb !== undefined) {
-			sb.ready(function() {
-				_setSize();
-			});
-			_sbAddResizable();
-		}
-		$(window).on('resize.openmeetings', function() {
-			_setSize();
-		});
-		Wicket.Event.subscribe("/websocket/closed", _close);
-		Wicket.Event.subscribe("/websocket/error", _close);
-		$(window).keyup(_keyHandler);
-		$(document).click(_mouseHandler);
-	}
-	function _unload() {
-		$(window).off('resize.openmeetings');
-		Wicket.Event.unsubscribe("/websocket/closed", _close);
-		Wicket.Event.unsubscribe("/websocket/error", _close);
-		if (typeof(WbArea) !== 'undefined') {
-			WbArea.destroy();
-			WbArea = undefined;
-		}
-		if (typeof(VideoSettings) !== 'undefined') {
-			VideoSettings.close();
-		}
-		$('.ui-dialog.user-video').remove();
-		$(window).off('keyup', _keyHandler);
-		$(document).off('click', _mouseHandler);
-	}
-	function _showClipboard(txt) {
-		const dlg = $('#clipboard-dialog');
-		dlg.find('p .text').text(txt);
-		dlg.dialog({
-			resizable: false
-			, height: "auto"
-			, width: 400
-			, modal: true
-			, buttons: [
-				{
-					text: dlg.data('btn-ok')
-					, click: function() {
-						$(this).dialog('close');
-					}
-				}
-			]
-		});
-	}
-
-	self.init = _init;
-	self.getMenuHeight = function() { return menuHeight; };
-	self.getOptions = function() { return typeof(options) === 'object' ? JSON.parse(JSON.stringify(options)) : {}; };
-	self.setRights = function(_r) { return options.rights = _r; };
-	self.setSize = _setSize;
-	self.load = _load;
-	self.unload = _unload;
-	self.showClipboard = _showClipboard;
-	return self;
-})();
-function startPrivateChat(el) {
-	Chat.addTab('chatTab-u' + el.parent().parent().data("userid"), el.parent().parent().find('.user.name').text());
-	Chat.open();
-	$('#chatMessage .wysiwyg-editor').click();
-}
-/***** functions required by SIP   ******/
-function sipBtnClick() {
-	const txt = $('.sip-number');
-	txt.val(txt.val() + $(this).data('value'));
-}
-function sipBtnEraseClick() {
-	const txt = $('.sip-number')
-		, t = txt.val();
-	if (!!t) {
-		txt.val(t.substring(0, t.length -1));
-	}
-}
-function sipGetKey(evt) {
-	let k = -1;
-	if (evt.keyCode > 47 && evt.keyCode < 58) {
-		k = evt.keyCode - 48;
-	}
-	if (evt.keyCode > 95 && evt.keyCode < 106) {
-		k = evt.keyCode - 96;
-	}
-	return k;
-}
-function sipKeyDown(evt) {
-	const k = sipGetKey(evt);
-	if (k > 0) {
-		$('#sip-dialer-btn-' + k).addClass('ui-state-active');
-	}
-}
-function sipKeyUp(evt) {
-	const k = sipGetKey(evt);
-	if (k > 0) {
-		$('#sip-dialer-btn-' + k).removeClass('ui-state-active');
-	}
-}
-/***** functions required by SWF   ******/
-function typingActivity(uid, active) {
-	const u = $('#user' + uid + ' .typing-activity.ui-icon');
-	if (active) {
-		u.addClass("typing");
-	} else {
-		u.removeClass("typing");
-	}
-}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ae1b51a9/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
index 9a8ed19..c09a68b 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
@@ -82,8 +82,6 @@ import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
 import org.apache.wicket.ajax.attributes.AjaxRequestAttributes.Method;
-import org.apache.wicket.markup.head.IHeaderResponse;
-import org.apache.wicket.markup.head.JavaScriptHeaderItem;
 import org.apache.wicket.markup.html.list.ListItem;
 import org.apache.wicket.markup.html.list.ListView;
 import org.apache.wicket.request.resource.JavaScriptResourceReference;
@@ -104,7 +102,6 @@ public class WbPanel extends AbstractWbPanel {
 	private static final int DEFAULT_HEIGHT = 480;
 	private static final int UNDO_SIZE = 20;
 	public static final ResourceReference WB_JS_REFERENCE = new JavaScriptResourceReference(WbPanel.class, "wb.js");
-	private static final ResourceReference FABRIC_JS_REFERENCE = new JavaScriptResourceReference(WbPanel.class, "fabric.js");
 	private final Long roomId;
 	private long wb2save = -1;
 	private final Map<Long, Deque<UndoObject>> undoList = new HashMap<>();
@@ -156,12 +153,6 @@ public class WbPanel extends AbstractWbPanel {
 	}
 
 	@Override
-	public void renderHead(IHeaderResponse response) {
-		super.renderHead(response);
-		response.render(JavaScriptHeaderItem.forReference(FABRIC_JS_REFERENCE));
-	}
-
-	@Override
 	void internalWbLoad(StringBuilder sb) {
 		Long langId = rp.getClient().getUser().getLanguageId();
 		if (!WhiteboardCache.contains(roomId) && rp.getRoom().getFiles() != null && !rp.getRoom().getFiles().isEmpty()) {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ae1b51a9/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/fabric.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/fabric.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/fabric.js
index 236a9ce..af55bf1 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/fabric.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/fabric.js
@@ -8307,7 +8307,7 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype
       var path = [], i, width = this.width / 1000,
           p1 = new fabric.Point(points[0].x, points[0].y),
           p2 = new fabric.Point(points[1].x, points[1].y),
-          len = points.length, multSignX, multSignY, manyPoints = len > 2;
+          len = points.length, multSignX = 1, multSignY = 1, manyPoints = len > 2;
 
       if (manyPoints) {
         multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1;
@@ -14345,7 +14345,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
         prefix = this.group.transformMatrixKey(skipGroup) + sep;
       };
       return prefix + this.top + sep + this.left + sep + this.scaleX + sep + this.scaleY +
-        sep + this.skewX + sep + this.skewY + sep + this.angle + sep + this.flipX + sep + this.flipY;
+        sep + this.skewX + sep + this.skewY + sep + this.angle + sep + this.flipX + sep + this.flipY +
+        sep + this.width + sep + this.height;
     },
 
     /**
@@ -18660,12 +18661,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
     return;
   }
 
-  var stateProperties = fabric.Object.prototype.stateProperties.concat();
-  stateProperties.push(
-    'cropX',
-    'cropY'
-  );
-
   /**
    * Image class
    * @class fabric.Image
@@ -18742,7 +18737,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
      * as well as for history (undo/redo) purposes
      * @type Array
      */
-    stateProperties: stateProperties,
+    stateProperties: fabric.Object.prototype.stateProperties.concat('cropX', 'cropY'),
 
     /**
      * When `true`, object is cached on an additional canvas.
@@ -26189,7 +26184,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
         return;
       }
 
-      this.hoverCursor = this._savedProps.overCursor;
+      this.hoverCursor = this._savedProps.hoverCursor;
       this.hasControls = this._savedProps.hasControls;
       this.borderColor = this._savedProps.borderColor;
       this.lockMovementX = this._savedProps.lockMovementX;