diff --git a/pandora_console/include/visual-console-client/vc.main.e5acbc3b.min.js b/pandora_console/include/visual-console-client/vc.main.938b11e8.min.js similarity index 63% rename from pandora_console/include/visual-console-client/vc.main.e5acbc3b.min.js rename to pandora_console/include/visual-console-client/vc.main.938b11e8.min.js index a4d787ec57..a28c80d611 100644 --- a/pandora_console/include/visual-console-client/vc.main.e5acbc3b.min.js +++ b/pandora_console/include/visual-console-client/vc.main.938b11e8.min.js @@ -1,2 +1,2 @@ -!function(t){var e={};function r(n){if(e[n])return e[n].exports;var i=e[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)r.d(n,i,function(e){return t[e]}.bind(null,i));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=9)}([function(t,e,r){"use strict";r.d(e,"h",function(){return i}),r.d(e,"g",function(){return o}),r.d(e,"l",function(){return s}),r.d(e,"d",function(){return a}),r.d(e,"f",function(){return l}),r.d(e,"e",function(){return c}),r.d(e,"i",function(){return u}),r.d(e,"k",function(){return p}),r.d(e,"c",function(){return h}),r.d(e,"b",function(){return f}),r.d(e,"j",function(){return d}),r.d(e,"a",function(){return _});var n=function(){return(n=Object.assign||function(t){for(var e,r=1,n=arguments.length;r0&&!isNaN(parseInt(t))?parseInt(t):e}function o(t,e){return"number"==typeof t?t:"string"==typeof t&&t.length>0&&!isNaN(parseFloat(t))?parseFloat(t):e}function s(t){return null==t||0===t.length}function a(t,e){return"string"==typeof t&&t.length>0?t:e}function l(t){return"boolean"==typeof t?t:"number"==typeof t?t>0:"string"==typeof t&&("1"===t||"true"===t)}function c(t,e,r){void 0===r&&(r=" "),"number"==typeof t&&(t=""+t),"number"==typeof r&&(r=""+r);var n=e-t.length;if(0===n)return t;if(n<0)return t.substr(Math.abs(n));if(n===r.length)return""+r+t;if(n0?r:null},function(t){var e=t.metaconsoleId,r=t.agentId,o=t.agentName,s={agentId:i(r,null),agentName:"string"==typeof o&&o.length>0?o:null};return null!=e?n({metaconsoleId:e},s):s}(t))}function f(t){var e=t.metaconsoleId,r=t.linkedLayoutId,o=t.linkedLayoutAgentId,s={linkedLayoutStatusType:"default"};switch(t.linkedLayoutStatusType){case"weight":var a=i(t.linkedLayoutStatusTypeWeight,null);if(null==a)throw new TypeError("invalid status calculation properties.");t.linkedLayoutStatusTypeWeight&&(s={linkedLayoutStatusType:"weight",linkedLayoutStatusTypeWeight:a});break;case"service":var l=i(t.linkedLayoutStatusTypeWarningThreshold,null),c=i(t.linkedLayoutStatusTypeCriticalThreshold,null);if(null==l||null==c)throw new TypeError("invalid status calculation properties.");s={linkedLayoutStatusType:"service",linkedLayoutStatusTypeWarningThreshold:l,linkedLayoutStatusTypeCriticalThreshold:c}}var u=n({linkedLayoutId:i(r,null),linkedLayoutAgentId:i(o,null)},s);return null!=e?n({metaconsoleId:e},u):u}function d(t,e){var r=t+": "+e+";";return["-webkit-"+r,"-moz-"+r,"-ms-"+r,"-o-"+r,""+r]}function _(t){return decodeURIComponent(escape(window.atob(t)))}},function(t,e,r){"use strict";r.d(e,"b",function(){return a});var n=r(0),i=r(2),o=function(){return(o=Object.assign||function(t){for(var e,r=1,n=arguments.length;r0?t+"px":null,this.childElementRef.style.height=e>0?e+"px":null},t.prototype.resize=function(t,e){this.resizeElement(t,e),this.itemProps=o({},this.props,{width:t,height:e})},t.prototype.onClick=function(t){var e=this.clickEventManager.on(t);return this.disposables.push(e),e},t.prototype.onRemove=function(t){var e=this.removeEventManager.on(t);return this.disposables.push(e),e},t}();e.a=l},function(t,e,r){"use strict";var n=function(){return function(){var t=this;this.listeners=[],this.listenersOncer=[],this.on=function(e){return t.listeners.push(e),{dispose:function(){return t.off(e)}}},this.once=function(e){t.listenersOncer.push(e)},this.off=function(e){var r=t.listeners.indexOf(e);r>-1&&t.listeners.splice(r,1)},this.emit=function(e){t.listeners.forEach(function(t){return t(e)}),t.listenersOncer.forEach(function(t){return t(e)}),t.listenersOncer=[]},this.pipe=function(e){return t.on(function(t){return e.emit(t)})}}}();e.a=n},function(module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.d(__webpack_exports__,"b",function(){return eventsHistoryPropsDecoder});var _lib__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(0),_Item__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(1),__extends=(extendStatics=function(t,e){return(extendStatics=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])})(t,e)},function(t,e){function r(){this.constructor=t}extendStatics(t,e),t.prototype=null===e?Object.create(e):(r.prototype=e.prototype,new r)}),extendStatics,__assign=function(){return(__assign=Object.assign||function(t){for(var e,r=1,n=arguments.length;r0){var m=document.createElementNS(t,"text");m.setAttribute("text-anchor","middle"),m.setAttribute("font-size","8"),m.setAttribute("transform","translate(30 50) rotate(90)"),m.setAttribute("fill",n),m.textContent=_,f.append(m)}var b=document.createElementNS(t,"g");b.setAttribute("class","marks");var y=document.createElementNS(t,"g");y.setAttribute("class","mark"),y.setAttribute("transform","translate(50 50)");var g=document.createElementNS(t,"line");g.setAttribute("x1","36"),g.setAttribute("y1","0"),g.setAttribute("x2","46"),g.setAttribute("y2","0"),g.setAttribute("stroke",n),g.setAttribute("stroke-width","5");var v=document.createElementNS(t,"line");v.setAttribute("x1","36"),v.setAttribute("y1","0"),v.setAttribute("x2","46"),v.setAttribute("y2","0"),v.setAttribute("stroke",e),v.setAttribute("stroke-width","1"),y.append(g,v),b.append(y);for(var E=1;E<60;E++){var O=document.createElementNS(t,"line");O.setAttribute("y1","0"),O.setAttribute("y2","0"),O.setAttribute("stroke",n),O.setAttribute("transform","translate(50 50) rotate("+6*E+")"),E%5==0?(O.setAttribute("x1","38"),O.setAttribute("x2","46"),O.setAttribute("stroke-width",E%15==0?"2":"1")):(O.setAttribute("x1","42"),O.setAttribute("x2","46"),O.setAttribute("stroke-width","0.5")),b.append(O)}var w=document.createElementNS(t,"g");w.setAttribute("class","hour-hand"),w.setAttribute("transform","translate(50 50)");var A=document.createElementNS(t,"line");A.setAttribute("class","hour-hand-a"),A.setAttribute("x1","0"),A.setAttribute("y1","0"),A.setAttribute("x2","30"),A.setAttribute("y2","0"),A.setAttribute("stroke",s),A.setAttribute("stroke-width","4"),A.setAttribute("stroke-linecap","round");var j=document.createElementNS(t,"line");j.setAttribute("class","hour-hand-b"),j.setAttribute("x1","0"),j.setAttribute("y1","0"),j.setAttribute("x2","29.9"),j.setAttribute("y2","0"),j.setAttribute("stroke",o),j.setAttribute("stroke-width","3.1"),j.setAttribute("stroke-linecap","round"),w.append(A,j);var T=document.createElementNS(t,"g");T.setAttribute("class","minute-hand"),T.setAttribute("transform","translate(50 50)");var P=document.createElementNS(t,"line");P.setAttribute("class","minute-hand-a"),P.setAttribute("x1","0"),P.setAttribute("y1","0"),P.setAttribute("x2","40"),P.setAttribute("y2","0"),P.setAttribute("stroke",s),P.setAttribute("stroke-width","2"),P.setAttribute("stroke-linecap","round");var x=document.createElementNS(t,"line");x.setAttribute("class","minute-hand-b"),x.setAttribute("x1","0"),x.setAttribute("y1","0"),x.setAttribute("x2","39.9"),x.setAttribute("y2","0"),x.setAttribute("stroke",o),x.setAttribute("stroke-width","1.5"),x.setAttribute("stroke-linecap","round");var k=document.createElementNS(t,"circle");k.setAttribute("r","3"),k.setAttribute("fill",o),T.append(P,x,k);var I=document.createElementNS(t,"g");I.setAttribute("class","second-hand"),I.setAttribute("transform","translate(50 50)");var M=document.createElementNS(t,"line");M.setAttribute("x1","0"),M.setAttribute("y1","0"),M.setAttribute("x2","46"),M.setAttribute("y2","0"),M.setAttribute("stroke",a),M.setAttribute("stroke-width","1"),M.setAttribute("stroke-linecap","round");var D=document.createElementNS(t,"circle");D.setAttribute("r","2"),D.setAttribute("fill",a),I.append(M,D);var L=document.createElementNS(t,"circle");L.setAttribute("cx","50"),L.setAttribute("cy","50"),L.setAttribute("r","0.3"),L.setAttribute("fill",o);var S=this.getDate(),R=S.getSeconds(),C=S.getMinutes(),N=6*R,B=6*C+R/60*6,W=30*S.getHours()+C/60*30;return w.setAttribute("transform","translate(50 50) rotate("+W+")"),T.setAttribute("transform","translate(50 50) rotate("+B+")"),I.setAttribute("transform","translate(50 50) rotate("+N+")"),h.append(f,b,w,T,I,L),h.setAttribute("transform","rotate(-90)"),p.innerHTML="\n \n ",p.append(h),p},e.prototype.createDigitalClock=function(){var t=document.createElement("div");t.className="digital-clock";var e=this.getElementSize().width,r=6/this.props.clockTimezone.length,n=20*e/100,i=10*e/100,o=Math.min(20*r*e/100,e/100*10);if("datetime"===this.props.clockFormat){var s=document.createElement("span");s.className="date",s.textContent=this.getDigitalDate(),s.style.fontSize=i+"px",this.props.color&&(s.style.color=this.props.color),t.append(s)}var a=document.createElement("span");a.className="time",a.textContent=this.getDigitalTime(),a.style.fontSize=n+"px",this.props.color&&(a.style.color=this.props.color),t.append(a);var l=this.getHumanTimezone();if(l.length>0){var c=document.createElement("span");c.className="timezone",c.textContent=l,c.style.fontSize=o+"px",this.props.color&&(c.style.color=this.props.color),t.append(c)}return t},e.prototype.getDate=function(){var t=new Date,e=60*this.props.clockTimezoneOffset*1e3,r=60*t.getTimezoneOffset()*1e3,n=t.getTime()+e+r;return console.log(e,r),new Date(n)},e.prototype.getDigitalDate=function(t){void 0===t&&(t=null);var e=t||this.getDate();return Object(i.e)(e.getDate(),2,0)+"/"+Object(i.e)(e.getMonth()+1,2,0)+"/"+Object(i.e)(e.getFullYear(),4,0)},e.prototype.getDigitalTime=function(t){void 0===t&&(t=null);var e=t||this.getDate();return Object(i.e)(e.getHours(),2,0)+":"+Object(i.e)(e.getMinutes(),2,0)+":"+Object(i.e)(e.getSeconds(),2,0)},e.prototype.getHumanTimezone=function(t){void 0===t&&(t=this.props.clockTimezone);var e=t.split("/")[1];return(void 0===e?"":e).replace("_"," ")},e.prototype.getElementSize=function(t,e){switch(void 0===t&&(t=this.props.width),void 0===e&&(e=this.props.height),this.props.clockType){case"analogic":var r=100;return t>0&&e>0?r=Math.min(t,e):t>0?r=t:e>0&&(r=e),{width:r,height:r};case"digital":return t>0&&e>0?e=t/20?e=t/2:e>0?t=2*e:(t=100,e=50),{width:t,height:e};default:throw new Error("invalid clock type.")}},e.TICK_INTERVAL=1e3,e}(o.a),I=function(){var t=function(e,r){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])})(e,r)};return function(e,r){function n(){this.constructor=e}t(e,r),e.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}(),M=function(){return(M=Object.assign||function(t){for(var e,r=1,n=arguments.length;r0){t.style.borderStyle="solid";var e=Math.min(this.props.width,this.props.height)/2,r=Math.min(this.props.borderWidth,e);t.style.borderWidth=r+"px",this.props.borderColor&&(t.style.borderColor=this.props.borderColor)}return t},e}(o.a),S=function(){var t=function(e,r){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])})(e,r)};return function(e,r){function n(){this.constructor=e}t(e,r),e.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}(),R=function(){return(R=Object.assign||function(t){for(var e,r=1,n=arguments.length;r0){var c=document.createElementNS(et,"tspan");c.setAttribute("x","0"),c.setAttribute("dy","1em"),c.textContent=""+this.props.value;var u=document.createElementNS(et,"tspan");u.setAttribute("x","0"),u.setAttribute("dy","1em"),u.textContent=""+this.props.unit,a.append(c,u),a.setAttribute("transform","translate(50 33)")}else a.textContent=""+this.props.value,a.setAttribute("transform","translate(50 50)");else a.textContent=e+"%",a.setAttribute("transform","translate(50 50)");n.setAttribute("viewBox","0 0 100 100"),n.append(s,l,a)}return r.append(n),r},e.prototype.getProgress=function(){var t=this.props.minValue||0,e=this.props.maxValue||100,r=this.props.value||100;return r<=t?0:r>=e?100:(r-t)/(e-t)*100},e}(o.a),nt=r(2),it=r(4),ot=r(8),st=r(5),at=function(){var t=function(e,r){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])})(e,r)};return function(e,r){function n(){this.constructor=e}t(e,r),e.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}(),lt=function(){return(lt=Object.assign||function(t){for(var e,r=1,n=arguments.length;r0&&!isNaN(parseInt(t))?parseInt(t):e}function o(t,e){return"number"==typeof t?t:"string"==typeof t&&t.length>0&&!isNaN(parseFloat(t))?parseFloat(t):e}function s(t){return null==t||0===t.length}function a(t,e){return"string"==typeof t&&t.length>0?t:e}function l(t){return"boolean"==typeof t?t:"number"==typeof t?t>0:"string"==typeof t&&("1"===t||"true"===t)}function c(t,e,r){void 0===r&&(r=" "),"number"==typeof t&&(t=""+t),"number"==typeof r&&(r=""+r);var n=e-t.length;if(0===n)return t;if(n<0)return t.substr(Math.abs(n));if(n===r.length)return""+r+t;if(n0?r:null},function(t){var e=t.metaconsoleId,r=t.agentId,o=t.agentName,s={agentId:i(r,null),agentName:"string"==typeof o&&o.length>0?o:null};return null!=e?n({metaconsoleId:e},s):s}(t))}function f(t){var e=t.metaconsoleId,r=t.linkedLayoutId,o=t.linkedLayoutAgentId,s={linkedLayoutStatusType:"default"};switch(t.linkedLayoutStatusType){case"weight":var a=i(t.linkedLayoutStatusTypeWeight,null);if(null==a)throw new TypeError("invalid status calculation properties.");t.linkedLayoutStatusTypeWeight&&(s={linkedLayoutStatusType:"weight",linkedLayoutStatusTypeWeight:a});break;case"service":var l=i(t.linkedLayoutStatusTypeWarningThreshold,null),c=i(t.linkedLayoutStatusTypeCriticalThreshold,null);if(null==l||null==c)throw new TypeError("invalid status calculation properties.");s={linkedLayoutStatusType:"service",linkedLayoutStatusTypeWarningThreshold:l,linkedLayoutStatusTypeCriticalThreshold:c}}var u=n({linkedLayoutId:i(r,null),linkedLayoutAgentId:i(o,null)},s);return null!=e?n({metaconsoleId:e},u):u}function d(t,e){var r=t+": "+e+";";return["-webkit-"+r,"-moz-"+r,"-ms-"+r,"-o-"+r,""+r]}function _(t){return decodeURIComponent(escape(window.atob(t)))}},function(t,e,r){"use strict";r.d(e,"b",function(){return a});var n=r(0),i=r(2),o=function(){return(o=Object.assign||function(t){for(var e,r=1,n=arguments.length;r0?t+"px":null,this.childElementRef.style.height=e>0?e+"px":null},t.prototype.resize=function(t,e){this.resizeElement(t,e),this.itemProps=o({},this.props,{width:t,height:e})},t.prototype.onClick=function(t){var e=this.clickEventManager.on(t);return this.disposables.push(e),e},t.prototype.onRemove=function(t){var e=this.removeEventManager.on(t);return this.disposables.push(e),e},t}();e.a=l},function(t,e,r){"use strict";var n=function(){return function(){var t=this;this.listeners=[],this.listenersOncer=[],this.on=function(e){return t.listeners.push(e),{dispose:function(){return t.off(e)}}},this.once=function(e){t.listenersOncer.push(e)},this.off=function(e){var r=t.listeners.indexOf(e);r>-1&&t.listeners.splice(r,1)},this.emit=function(e){t.listeners.forEach(function(t){return t(e)}),t.listenersOncer.forEach(function(t){return t(e)}),t.listenersOncer=[]},this.pipe=function(e){return t.on(function(t){return e.emit(t)})}}}();e.a=n},function(module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.d(__webpack_exports__,"b",function(){return eventsHistoryPropsDecoder});var _lib__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(0),_Item__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(1),__extends=(extendStatics=function(t,e){return(extendStatics=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])})(t,e)},function(t,e){function r(){this.constructor=t}extendStatics(t,e),t.prototype=null===e?Object.create(e):(r.prototype=e.prototype,new r)}),extendStatics,__assign=function(){return(__assign=Object.assign||function(t){for(var e,r=1,n=arguments.length;r0){var m=document.createElementNS(t,"text");m.setAttribute("text-anchor","middle"),m.setAttribute("font-size","8"),m.setAttribute("transform","translate(30 50) rotate(90)"),m.setAttribute("fill",n),m.textContent=_,f.append(m)}var b=document.createElementNS(t,"g");b.setAttribute("class","marks");var y=document.createElementNS(t,"g");y.setAttribute("class","mark"),y.setAttribute("transform","translate(50 50)");var g=document.createElementNS(t,"line");g.setAttribute("x1","36"),g.setAttribute("y1","0"),g.setAttribute("x2","46"),g.setAttribute("y2","0"),g.setAttribute("stroke",n),g.setAttribute("stroke-width","5");var v=document.createElementNS(t,"line");v.setAttribute("x1","36"),v.setAttribute("y1","0"),v.setAttribute("x2","46"),v.setAttribute("y2","0"),v.setAttribute("stroke",e),v.setAttribute("stroke-width","1"),y.append(g,v),b.append(y);for(var E=1;E<60;E++){var O=document.createElementNS(t,"line");O.setAttribute("y1","0"),O.setAttribute("y2","0"),O.setAttribute("stroke",n),O.setAttribute("transform","translate(50 50) rotate("+6*E+")"),E%5==0?(O.setAttribute("x1","38"),O.setAttribute("x2","46"),O.setAttribute("stroke-width",E%15==0?"2":"1")):(O.setAttribute("x1","42"),O.setAttribute("x2","46"),O.setAttribute("stroke-width","0.5")),b.append(O)}var w=document.createElementNS(t,"g");w.setAttribute("class","hour-hand"),w.setAttribute("transform","translate(50 50)");var A=document.createElementNS(t,"line");A.setAttribute("class","hour-hand-a"),A.setAttribute("x1","0"),A.setAttribute("y1","0"),A.setAttribute("x2","30"),A.setAttribute("y2","0"),A.setAttribute("stroke",s),A.setAttribute("stroke-width","4"),A.setAttribute("stroke-linecap","round");var j=document.createElementNS(t,"line");j.setAttribute("class","hour-hand-b"),j.setAttribute("x1","0"),j.setAttribute("y1","0"),j.setAttribute("x2","29.9"),j.setAttribute("y2","0"),j.setAttribute("stroke",o),j.setAttribute("stroke-width","3.1"),j.setAttribute("stroke-linecap","round"),w.append(A,j);var T=document.createElementNS(t,"g");T.setAttribute("class","minute-hand"),T.setAttribute("transform","translate(50 50)");var P=document.createElementNS(t,"line");P.setAttribute("class","minute-hand-a"),P.setAttribute("x1","0"),P.setAttribute("y1","0"),P.setAttribute("x2","40"),P.setAttribute("y2","0"),P.setAttribute("stroke",s),P.setAttribute("stroke-width","2"),P.setAttribute("stroke-linecap","round");var x=document.createElementNS(t,"line");x.setAttribute("class","minute-hand-b"),x.setAttribute("x1","0"),x.setAttribute("y1","0"),x.setAttribute("x2","39.9"),x.setAttribute("y2","0"),x.setAttribute("stroke",o),x.setAttribute("stroke-width","1.5"),x.setAttribute("stroke-linecap","round");var k=document.createElementNS(t,"circle");k.setAttribute("r","3"),k.setAttribute("fill",o),T.append(P,x,k);var I=document.createElementNS(t,"g");I.setAttribute("class","second-hand"),I.setAttribute("transform","translate(50 50)");var M=document.createElementNS(t,"line");M.setAttribute("x1","0"),M.setAttribute("y1","0"),M.setAttribute("x2","46"),M.setAttribute("y2","0"),M.setAttribute("stroke",a),M.setAttribute("stroke-width","1"),M.setAttribute("stroke-linecap","round");var D=document.createElementNS(t,"circle");D.setAttribute("r","2"),D.setAttribute("fill",a),I.append(M,D);var L=document.createElementNS(t,"circle");L.setAttribute("cx","50"),L.setAttribute("cy","50"),L.setAttribute("r","0.3"),L.setAttribute("fill",o);var S=this.getDate(),R=S.getSeconds(),C=S.getMinutes(),N=6*R,B=6*C+R/60*6,W=30*S.getHours()+C/60*30;return w.setAttribute("transform","translate(50 50) rotate("+W+")"),T.setAttribute("transform","translate(50 50) rotate("+B+")"),I.setAttribute("transform","translate(50 50) rotate("+N+")"),h.append(f,b,w,T,I,L),h.setAttribute("transform","rotate(-90)"),p.innerHTML="\n \n ",p.append(h),p},e.prototype.createDigitalClock=function(){var t=document.createElement("div");t.className="digital-clock";var e=this.getElementSize().width,r=6/this.props.clockTimezone.length,n=20*e/100,i=10*e/100,o=Math.min(20*r*e/100,e/100*10);if("datetime"===this.props.clockFormat){var s=document.createElement("span");s.className="date",s.textContent=this.getDigitalDate(),s.style.fontSize=i+"px",this.props.color&&(s.style.color=this.props.color),t.append(s)}var a=document.createElement("span");a.className="time",a.textContent=this.getDigitalTime(),a.style.fontSize=n+"px",this.props.color&&(a.style.color=this.props.color),t.append(a);var l=this.getHumanTimezone();if(l.length>0){var c=document.createElement("span");c.className="timezone",c.textContent=l,c.style.fontSize=o+"px",this.props.color&&(c.style.color=this.props.color),t.append(c)}return t},e.prototype.getDate=function(){var t=new Date,e=1e3*this.props.clockTimezoneOffset,r=60*t.getTimezoneOffset()*1e3,n=t.getTime()+e+r;return new Date(n)},e.prototype.getDigitalDate=function(t){void 0===t&&(t=null);var e=t||this.getDate();return Object(i.e)(e.getDate(),2,0)+"/"+Object(i.e)(e.getMonth()+1,2,0)+"/"+Object(i.e)(e.getFullYear(),4,0)},e.prototype.getDigitalTime=function(t){void 0===t&&(t=null);var e=t||this.getDate();return Object(i.e)(e.getHours(),2,0)+":"+Object(i.e)(e.getMinutes(),2,0)+":"+Object(i.e)(e.getSeconds(),2,0)},e.prototype.getHumanTimezone=function(t){void 0===t&&(t=this.props.clockTimezone);var e=t.split("/")[1];return(void 0===e?"":e).replace("_"," ")},e.prototype.getElementSize=function(t,e){switch(void 0===t&&(t=this.props.width),void 0===e&&(e=this.props.height),this.props.clockType){case"analogic":var r=100;return t>0&&e>0?r=Math.min(t,e):t>0?r=t:e>0&&(r=e),{width:r,height:r};case"digital":return t>0&&e>0?e=t/20?e=t/2:e>0?t=2*e:(t=100,e=50),{width:t,height:e};default:throw new Error("invalid clock type.")}},e.TICK_INTERVAL=1e3,e}(o.a),I=function(){var t=function(e,r){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])})(e,r)};return function(e,r){function n(){this.constructor=e}t(e,r),e.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}(),M=function(){return(M=Object.assign||function(t){for(var e,r=1,n=arguments.length;r0){t.style.borderStyle="solid";var e=Math.min(this.props.width,this.props.height)/2,r=Math.min(this.props.borderWidth,e);t.style.borderWidth=r+"px",this.props.borderColor&&(t.style.borderColor=this.props.borderColor)}return t},e}(o.a),S=function(){var t=function(e,r){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])})(e,r)};return function(e,r){function n(){this.constructor=e}t(e,r),e.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}(),R=function(){return(R=Object.assign||function(t){for(var e,r=1,n=arguments.length;r0){var c=document.createElementNS(et,"tspan");c.setAttribute("x","0"),c.setAttribute("dy","1em"),c.textContent=""+this.props.value;var u=document.createElementNS(et,"tspan");u.setAttribute("x","0"),u.setAttribute("dy","1em"),u.textContent=""+this.props.unit,a.append(c,u),a.setAttribute("transform","translate(50 33)")}else a.textContent=""+this.props.value,a.setAttribute("transform","translate(50 50)");else a.textContent=e+"%",a.setAttribute("transform","translate(50 50)");n.setAttribute("viewBox","0 0 100 100"),n.append(s,l,a)}return r.append(n),r},e.prototype.getProgress=function(){var t=this.props.minValue||0,e=this.props.maxValue||100,r=this.props.value||100;return r<=t?0:r>=e?100:(r-t)/(e-t)*100},e}(o.a),nt=r(2),it=r(4),ot=r(8),st=r(5),at=function(){var t=function(e,r){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])})(e,r)};return function(e,r){function n(){this.constructor=e}t(e,r),e.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}(),lt=function(){return(lt=Object.assign||function(t){for(var e,r=1,n=arguments.length;r(value: any, defaultValue: T): number | T {\n if (typeof value === \"number\") return value;\n if (typeof value === \"string\" && value.length > 0 && !isNaN(parseInt(value)))\n return parseInt(value);\n else return defaultValue;\n}\n\n/**\n * Return a number or a default value from a raw value.\n * @param value Raw value from which we will try to extract a valid number.\n * @param defaultValue Default value to use if we cannot extract a valid number.\n * @return A valid number or the default value.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function parseFloatOr(value: any, defaultValue: T): number | T {\n if (typeof value === \"number\") return value;\n if (\n typeof value === \"string\" &&\n value.length > 0 &&\n !isNaN(parseFloat(value))\n )\n return parseFloat(value);\n else return defaultValue;\n}\n\n/**\n * Check if a string exists and it's not empty.\n * @param value Value to check.\n * @return The check result.\n */\nexport function stringIsEmpty(value?: string | null): boolean {\n return value == null || value.length === 0;\n}\n\n/**\n * Return a not empty string or a default value from a raw value.\n * @param value Raw value from which we will try to extract a non empty string.\n * @param defaultValue Default value to use if we cannot extract a non empty string.\n * @return A non empty string or the default value.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function notEmptyStringOr(value: any, defaultValue: T): string | T {\n return typeof value === \"string\" && value.length > 0 ? value : defaultValue;\n}\n\n/**\n * Return a boolean from a raw value.\n * @param value Raw value from which we will try to extract the boolean.\n * @return A valid boolean value. false by default.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function parseBoolean(value: any): boolean {\n if (typeof value === \"boolean\") return value;\n else if (typeof value === \"number\") return value > 0;\n else if (typeof value === \"string\") return value === \"1\" || value === \"true\";\n else return false;\n}\n\n/**\n * Pad the current string with another string (multiple times, if needed)\n * until the resulting string reaches the given length.\n * The padding is applied from the start (left) of the current string.\n * @param value Text that needs to be padded.\n * @param length Length of the returned text.\n * @param pad Text to add.\n * @return Padded text.\n */\nexport function padLeft(\n value: string | number,\n length: number,\n pad: string | number = \" \"\n): string {\n if (typeof value === \"number\") value = `${value}`;\n if (typeof pad === \"number\") pad = `${pad}`;\n\n const diffLength = length - value.length;\n if (diffLength === 0) return value;\n if (diffLength < 0) return value.substr(Math.abs(diffLength));\n\n if (diffLength === pad.length) return `${pad}${value}`;\n if (diffLength < pad.length) return `${pad.substring(0, diffLength)}${value}`;\n\n const repeatTimes = Math.floor(diffLength / pad.length);\n const restLength = diffLength - pad.length * repeatTimes;\n\n let newPad = \"\";\n for (let i = 0; i < repeatTimes; i++) newPad += pad;\n\n if (restLength === 0) return `${newPad}${value}`;\n return `${newPad}${pad.substring(0, restLength)}${value}`;\n}\n\n/* Decoders */\n\n/**\n * Build a valid typed object from a raw object.\n * @param data Raw object.\n * @return An object representing the position.\n */\nexport function positionPropsDecoder(data: UnknownObject): Position {\n return {\n x: parseIntOr(data.x, 0),\n y: parseIntOr(data.y, 0)\n };\n}\n\n/**\n * Build a valid typed object from a raw object.\n * @param data Raw object.\n * @return An object representing the size.\n * @throws Will throw a TypeError if the width and height are not valid numbers.\n */\nexport function sizePropsDecoder(data: UnknownObject): Size | never {\n if (\n data.width == null ||\n isNaN(parseInt(data.width)) ||\n data.height == null ||\n isNaN(parseInt(data.height))\n ) {\n throw new TypeError(\"invalid size.\");\n }\n\n return {\n width: parseInt(data.width),\n height: parseInt(data.height)\n };\n}\n\n/**\n * Build a valid typed object from a raw object.\n * @param data Raw object.\n * @return An object representing the agent properties.\n */\nexport function agentPropsDecoder(data: UnknownObject): WithAgentProps {\n // Object destructuring: http://es6-features.org/#ObjectMatchingShorthandNotation\n const { metaconsoleId, agentId: id, agentName: name } = data;\n\n const agentProps: WithAgentProps = {\n agentId: parseIntOr(id, null),\n agentName: typeof name === \"string\" && name.length > 0 ? name : null\n };\n\n return metaconsoleId != null\n ? {\n metaconsoleId,\n ...agentProps // Object spread: http://es6-features.org/#SpreadOperator\n }\n : agentProps;\n}\n\n/**\n * Build a valid typed object from a raw object.\n * @param data Raw object.\n * @return An object representing the module and agent properties.\n */\nexport function modulePropsDecoder(data: UnknownObject): WithModuleProps {\n // Object destructuring: http://es6-features.org/#ObjectMatchingShorthandNotation\n const { moduleId: id, moduleName: name } = data;\n\n return {\n moduleId: parseIntOr(id, null),\n moduleName: typeof name === \"string\" && name.length > 0 ? name : null,\n ...agentPropsDecoder(data) // Object spread: http://es6-features.org/#SpreadOperator\n };\n}\n\n/**\n * Build a valid typed object from a raw object.\n * @param data Raw object.\n * @return An object representing the linked visual console properties.\n * @throws Will throw a TypeError if the status calculation properties are invalid.\n */\nexport function linkedVCPropsDecoder(\n data: UnknownObject\n): LinkedVisualConsoleProps | never {\n // Object destructuring: http://es6-features.org/#ObjectMatchingShorthandNotation\n const {\n metaconsoleId,\n linkedLayoutId: id,\n linkedLayoutAgentId: agentId\n } = data;\n\n let linkedLayoutStatusProps: LinkedVisualConsolePropsStatus = {\n linkedLayoutStatusType: \"default\"\n };\n switch (data.linkedLayoutStatusType) {\n case \"weight\": {\n const weight = parseIntOr(data.linkedLayoutStatusTypeWeight, null);\n if (weight == null)\n throw new TypeError(\"invalid status calculation properties.\");\n\n if (data.linkedLayoutStatusTypeWeight)\n linkedLayoutStatusProps = {\n linkedLayoutStatusType: \"weight\",\n linkedLayoutStatusTypeWeight: weight\n };\n break;\n }\n case \"service\": {\n const warningThreshold = parseIntOr(\n data.linkedLayoutStatusTypeWarningThreshold,\n null\n );\n const criticalThreshold = parseIntOr(\n data.linkedLayoutStatusTypeCriticalThreshold,\n null\n );\n if (warningThreshold == null || criticalThreshold == null) {\n throw new TypeError(\"invalid status calculation properties.\");\n }\n\n linkedLayoutStatusProps = {\n linkedLayoutStatusType: \"service\",\n linkedLayoutStatusTypeWarningThreshold: warningThreshold,\n linkedLayoutStatusTypeCriticalThreshold: criticalThreshold\n };\n break;\n }\n }\n\n const linkedLayoutBaseProps = {\n linkedLayoutId: parseIntOr(id, null),\n linkedLayoutAgentId: parseIntOr(agentId, null),\n ...linkedLayoutStatusProps // Object spread: http://es6-features.org/#SpreadOperator\n };\n\n return metaconsoleId != null\n ? {\n metaconsoleId,\n ...linkedLayoutBaseProps // Object spread: http://es6-features.org/#SpreadOperator\n }\n : linkedLayoutBaseProps;\n}\n\n/**\n * To get a CSS rule with the most used prefixes.\n * @param ruleName Name of the CSS rule.\n * @param ruleValue Value of the CSS rule.\n * @return An array of rules with the prefixes applied.\n */\nexport function prefixedCssRules(\n ruleName: string,\n ruleValue: string\n): string[] {\n const rule = `${ruleName}: ${ruleValue};`;\n return [\n `-webkit-${rule}`,\n `-moz-${rule}`,\n `-ms-${rule}`,\n `-o-${rule}`,\n `${rule}`\n ];\n}\n\n/**\n * Decode a base64 string.\n * @param input Data encoded using base64.\n * @return Decoded data.\n */\nexport function decodeBase64(input: string): string {\n return decodeURIComponent(escape(window.atob(input)));\n}\n","import { Position, Size, UnknownObject } from \"./types\";\nimport {\n sizePropsDecoder,\n positionPropsDecoder,\n parseIntOr,\n parseBoolean,\n notEmptyStringOr\n} from \"./lib\";\nimport TypedEvent, { Listener, Disposable } from \"./TypedEvent\";\n\n// Enum: https://www.typescriptlang.org/docs/handbook/enums.html.\nexport const enum ItemType {\n STATIC_GRAPH = 0,\n MODULE_GRAPH = 1,\n SIMPLE_VALUE = 2,\n PERCENTILE_BAR = 3,\n LABEL = 4,\n ICON = 5,\n SIMPLE_VALUE_MAX = 6,\n SIMPLE_VALUE_MIN = 7,\n SIMPLE_VALUE_AVG = 8,\n PERCENTILE_BUBBLE = 9,\n SERVICE = 10,\n GROUP_ITEM = 11,\n BOX_ITEM = 12,\n LINE_ITEM = 13,\n AUTO_SLA_GRAPH = 14,\n CIRCULAR_PROGRESS_BAR = 15,\n CIRCULAR_INTERIOR_PROGRESS_BAR = 16,\n DONUT_GRAPH = 17,\n BARS_GRAPH = 18,\n CLOCK = 19,\n COLOR_CLOUD = 20\n}\n\n// Base item properties. This interface should be extended by the item implementations.\nexport interface ItemProps extends Position, Size {\n readonly id: number;\n readonly type: ItemType;\n label: string | null;\n labelPosition: \"up\" | \"right\" | \"down\" | \"left\";\n isLinkEnabled: boolean;\n link: string | null;\n isOnTop: boolean;\n parentId: number | null;\n aclGroupId: number | null;\n}\n\n// FIXME: Fix type compatibility.\nexport interface ItemClickEvent {\n // data: Props;\n data: UnknownObject;\n nativeEvent: Event;\n}\n\n// FIXME: Fix type compatibility.\nexport interface ItemRemoveEvent {\n // data: Props;\n data: UnknownObject;\n}\n\n/**\n * Extract a valid enum value from a raw label positi9on value.\n * @param labelPosition Raw value.\n */\nconst parseLabelPosition = (\n labelPosition: any // eslint-disable-line @typescript-eslint/no-explicit-any\n): ItemProps[\"labelPosition\"] => {\n switch (labelPosition) {\n case \"up\":\n case \"right\":\n case \"down\":\n case \"left\":\n return labelPosition;\n default:\n return \"down\";\n }\n};\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the item props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function itemBasePropsDecoder(data: UnknownObject): ItemProps | never {\n if (data.id == null || isNaN(parseInt(data.id))) {\n throw new TypeError(\"invalid id.\");\n }\n if (data.type == null || isNaN(parseInt(data.type))) {\n throw new TypeError(\"invalid type.\");\n }\n\n return {\n id: parseInt(data.id),\n type: parseInt(data.type),\n label: notEmptyStringOr(data.label, null),\n labelPosition: parseLabelPosition(data.labelPosition),\n isLinkEnabled: parseBoolean(data.isLinkEnabled),\n link: notEmptyStringOr(data.link, null),\n isOnTop: parseBoolean(data.isOnTop),\n parentId: parseIntOr(data.parentId, null),\n aclGroupId: parseIntOr(data.aclGroupId, null),\n ...sizePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n ...positionPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\n/**\n * Base class of the visual console items. Should be extended to use its capabilities.\n */\nabstract class VisualConsoleItem {\n // Properties of the item.\n private itemProps: Props;\n // Reference to the DOM element which will contain the item.\n public elementRef: HTMLElement;\n public readonly labelElementRef: HTMLElement;\n // Reference to the DOM element which will contain the view of the item which extends this class.\n protected readonly childElementRef: HTMLElement;\n // Event manager for click events.\n private readonly clickEventManager = new TypedEvent>();\n // Event manager for remove events.\n private readonly removeEventManager = new TypedEvent<\n ItemRemoveEvent\n >();\n // List of references to clean the event listeners.\n private readonly disposables: Disposable[] = [];\n\n /**\n * To create a new element which will be inside the item box.\n * @return Item.\n */\n protected abstract createDomElement(): HTMLElement;\n\n public constructor(props: Props) {\n this.itemProps = props;\n\n /*\n * Get a HTMLElement which represents the container box\n * of the Visual Console item. This element will manage\n * all the common things like click events, show a border\n * when hovered, etc.\n */\n this.elementRef = this.createContainerDomElement();\n this.labelElementRef = this.createLabelDomElement();\n\n /*\n * Get a HTMLElement which represents the custom view\n * of the Visual Console item. This element will be\n * different depending on the item implementation.\n */\n this.childElementRef = this.createDomElement();\n\n // Insert the elements into the container.\n this.elementRef.append(this.childElementRef, this.labelElementRef);\n\n // Resize element.\n this.resizeElement(props.width, props.height);\n // Set label position.\n this.changeLabelPosition(props.labelPosition);\n }\n\n /**\n * To create a new box for the visual console item.\n * @return Item box.\n */\n private createContainerDomElement(): HTMLElement {\n let box;\n if (this.props.isLinkEnabled) {\n box = document.createElement(\"a\");\n box as HTMLAnchorElement;\n if (this.props.link) box.href = this.props.link;\n } else {\n box = document.createElement(\"div\");\n box as HTMLDivElement;\n }\n\n box.className = \"visual-console-item\";\n box.style.zIndex = this.props.isOnTop ? \"2\" : \"1\";\n box.style.left = `${this.props.x}px`;\n box.style.top = `${this.props.y}px`;\n box.onclick = e =>\n this.clickEventManager.emit({ data: this.props, nativeEvent: e });\n\n return box;\n }\n\n /**\n * To create a new label for the visual console item.\n * @return Item label.\n */\n protected createLabelDomElement(): HTMLElement {\n const element = document.createElement(\"div\");\n element.className = \"visual-console-item-label\";\n // Add the label if it exists.\n if (this.props.label && this.props.label.length) {\n element.innerHTML = this.props.label;\n }\n\n return element;\n }\n\n /**\n * To update the content element.\n * @return Item.\n */\n protected updateDomElement(element: HTMLElement): void {\n element.innerHTML = this.createDomElement().innerHTML;\n }\n\n /**\n * Public accessor of the `props` property.\n * @return Properties.\n */\n public get props(): Props {\n return { ...this.itemProps }; // Return a copy.\n }\n\n /**\n * Public setter of the `props` property.\n * If the new props are different enough than the\n * stored props, a render would be fired.\n * @param newProps\n */\n public set props(newProps: Props) {\n const prevProps = this.props;\n // Update the internal props.\n this.itemProps = newProps;\n\n // From this point, things which rely on this.props can access to the changes.\n\n // Check if we should re-render.\n if (this.shouldBeUpdated(prevProps, newProps)) this.render(prevProps);\n }\n\n /**\n * To compare the previous and the new props and returns a boolean value\n * in case the difference is meaningfull enough to perform DOM changes.\n *\n * Here, the only comparision is done by reference.\n *\n * Override this function to perform a different comparision depending on the item needs.\n *\n * @param prevProps\n * @param newProps\n * @return Whether the difference is meaningful enough to perform DOM changes or not.\n */\n protected shouldBeUpdated(prevProps: Props, newProps: Props): boolean {\n return prevProps !== newProps;\n }\n\n /**\n * To recreate or update the HTMLElement which represents the item into the DOM.\n * @param prevProps If exists it will be used to only perform DOM updates instead of a full replace.\n */\n public render(prevProps: Props | null = null): void {\n this.updateDomElement(this.childElementRef);\n\n // Move box.\n if (!prevProps || this.positionChanged(prevProps, this.props)) {\n this.moveElement(this.props.x, this.props.y);\n }\n // Resize box.\n if (!prevProps || this.sizeChanged(prevProps, this.props)) {\n this.resizeElement(this.props.width, this.props.height);\n }\n // Change label.\n if (!prevProps || prevProps.label !== this.props.label) {\n this.labelElementRef.innerHTML = this.createLabelDomElement().innerHTML;\n }\n // Change link.\n if (\n prevProps &&\n (prevProps.isLinkEnabled !== this.props.isLinkEnabled ||\n (this.props.isLinkEnabled && prevProps.link !== this.props.link))\n ) {\n const container = this.createContainerDomElement();\n container.innerHTML = this.elementRef.innerHTML;\n\n if (this.elementRef.parentNode !== null) {\n this.elementRef.parentNode.replaceChild(container, this.elementRef);\n }\n\n // Changed the reference to the main element. It's ugly, but needed.\n this.elementRef = container;\n }\n // Change label position.\n if (!prevProps || prevProps.labelPosition !== this.props.labelPosition) {\n this.changeLabelPosition(this.props.labelPosition);\n }\n }\n\n /**\n * To remove the event listeners and the elements from the DOM.\n */\n public remove(): void {\n // Call the remove event.\n this.removeEventManager.emit({ data: this.props });\n // Event listeners.\n this.disposables.forEach(disposable => {\n try {\n disposable.dispose();\n } catch (ignored) {} // eslint-disable-line no-empty\n });\n // VisualConsoleItem DOM element.\n this.elementRef.remove();\n }\n\n /**\n * Compare the previous and the new position and return\n * a boolean value in case the position changed.\n * @param prevPosition\n * @param newPosition\n * @return Whether the position changed or not.\n */\n protected positionChanged(\n prevPosition: Position,\n newPosition: Position\n ): boolean {\n return prevPosition.x !== newPosition.x || prevPosition.y !== newPosition.y;\n }\n\n /**\n * Move the label around the item content.\n * @param position Label position.\n */\n protected changeLabelPosition(position: Props[\"labelPosition\"]): void {\n switch (position) {\n case \"up\":\n this.elementRef.style.flexDirection = \"column-reverse\";\n break;\n case \"left\":\n this.elementRef.style.flexDirection = \"row-reverse\";\n break;\n case \"right\":\n this.elementRef.style.flexDirection = \"row\";\n break;\n case \"down\":\n default:\n this.elementRef.style.flexDirection = \"column\";\n break;\n }\n }\n\n /**\n * Move the DOM container.\n * @param x Horizontal axis position.\n * @param y Vertical axis position.\n */\n protected moveElement(x: number, y: number): void {\n this.elementRef.style.left = `${x}px`;\n this.elementRef.style.top = `${y}px`;\n }\n\n /**\n * Update the position into the properties and move the DOM container.\n * @param x Horizontal axis position.\n * @param y Vertical axis position.\n */\n public move(x: number, y: number): void {\n this.moveElement(x, y);\n this.itemProps = {\n ...this.props, // Object spread: http://es6-features.org/#SpreadOperator\n x,\n y\n };\n }\n\n /**\n * Compare the previous and the new size and return\n * a boolean value in case the size changed.\n * @param prevSize\n * @param newSize\n * @return Whether the size changed or not.\n */\n protected sizeChanged(prevSize: Size, newSize: Size): boolean {\n return (\n prevSize.width !== newSize.width || prevSize.height !== newSize.height\n );\n }\n\n /**\n * Resize the DOM content container.\n * @param width\n * @param height\n */\n protected resizeElement(width: number, height: number): void {\n // The most valuable size is the content size.\n this.childElementRef.style.width = width > 0 ? `${width}px` : null;\n this.childElementRef.style.height = height > 0 ? `${height}px` : null;\n }\n\n /**\n * Update the size into the properties and resize the DOM container.\n * @param width\n * @param height\n */\n public resize(width: number, height: number): void {\n this.resizeElement(width, height);\n this.itemProps = {\n ...this.props, // Object spread: http://es6-features.org/#SpreadOperator\n width,\n height\n };\n }\n\n /**\n * To add an event handler to the click of the linked visual console elements.\n * @param listener Function which is going to be executed when a linked console is clicked.\n */\n public onClick(listener: Listener>): Disposable {\n /*\n * The '.on' function returns a function which will clean the event\n * listener when executed. We store all the 'dispose' functions to\n * call them when the item should be cleared.\n */\n const disposable = this.clickEventManager.on(listener);\n this.disposables.push(disposable);\n\n return disposable;\n }\n\n /**\n * To add an event handler to the removal of the item.\n * @param listener Function which is going to be executed when a item is removed.\n */\n public onRemove(listener: Listener>): Disposable {\n /*\n * The '.on' function returns a function which will clean the event\n * listener when executed. We store all the 'dispose' functions to\n * call them when the item should be cleared.\n */\n const disposable = this.removeEventManager.on(listener);\n this.disposables.push(disposable);\n\n return disposable;\n }\n}\n\nexport default VisualConsoleItem;\n","export interface Listener {\n (event: T): void;\n}\n\nexport interface Disposable {\n dispose: () => void;\n}\n\n/** passes through events as they happen. You will not get events from before you start listening */\nexport default class TypedEvent {\n private listeners: Listener[] = [];\n private listenersOncer: Listener[] = [];\n\n public on = (listener: Listener): Disposable => {\n this.listeners.push(listener);\n return {\n dispose: () => this.off(listener)\n };\n };\n\n public once = (listener: Listener): void => {\n this.listenersOncer.push(listener);\n };\n\n public off = (listener: Listener): void => {\n const callbackIndex = this.listeners.indexOf(listener);\n if (callbackIndex > -1) this.listeners.splice(callbackIndex, 1);\n };\n\n public emit = (event: T): void => {\n /** Update any general listeners */\n this.listeners.forEach(listener => listener(event));\n\n /** Clear the `once` queue */\n this.listenersOncer.forEach(listener => listener(event));\n this.listenersOncer = [];\n };\n\n public pipe = (te: TypedEvent): Disposable => this.on(e => te.emit(e));\n}\n","import { UnknownObject, WithModuleProps } from \"../types\";\nimport {\n modulePropsDecoder,\n parseIntOr,\n decodeBase64,\n stringIsEmpty\n} from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\nexport type EventsHistoryProps = {\n type: ItemType.AUTO_SLA_GRAPH;\n maxTime: number | null;\n html: string;\n} & ItemProps &\n WithModuleProps;\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the events history props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function eventsHistoryPropsDecoder(\n data: UnknownObject\n): EventsHistoryProps | never {\n if (stringIsEmpty(data.html) && stringIsEmpty(data.encodedHtml)) {\n throw new TypeError(\"missing html content.\");\n }\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.AUTO_SLA_GRAPH,\n maxTime: parseIntOr(data.maxTime, null),\n html: !stringIsEmpty(data.html)\n ? data.html\n : decodeBase64(data.encodedHtml),\n ...modulePropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nexport default class EventsHistory extends Item {\n protected createDomElement(): HTMLElement {\n const element = document.createElement(\"div\");\n element.className = \"events-history\";\n element.innerHTML = this.props.html;\n\n // Hack to execute the JS after the HTML is added to the DOM.\n const scripts = element.getElementsByTagName(\"script\");\n for (let i = 0; i < scripts.length; i++) {\n if (scripts[i].src.length === 0) {\n setTimeout(() => {\n try {\n eval(scripts[i].innerHTML.trim());\n } catch (ignored) {} // eslint-disable-line no-empty\n }, 0);\n }\n }\n\n return element;\n }\n\n protected updateDomElement(element: HTMLElement): void {\n element.innerHTML = this.props.html;\n\n // Hack to execute the JS after the HTML is added to the DOM.\n const aux = document.createElement(\"div\");\n aux.innerHTML = this.props.html;\n const scripts = aux.getElementsByTagName(\"script\");\n for (let i = 0; i < scripts.length; i++) {\n if (scripts[i].src.length === 0) {\n eval(scripts[i].innerHTML.trim());\n }\n }\n }\n}\n","import {\n LinkedVisualConsoleProps,\n UnknownObject,\n WithModuleProps\n} from \"../types\";\nimport {\n linkedVCPropsDecoder,\n modulePropsDecoder,\n decodeBase64,\n stringIsEmpty\n} from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\nexport type DonutGraphProps = {\n type: ItemType.DONUT_GRAPH;\n html: string;\n} & ItemProps &\n WithModuleProps &\n LinkedVisualConsoleProps;\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the donut graph props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function donutGraphPropsDecoder(\n data: UnknownObject\n): DonutGraphProps | never {\n if (stringIsEmpty(data.html) && stringIsEmpty(data.encodedHtml)) {\n throw new TypeError(\"missing html content.\");\n }\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.DONUT_GRAPH,\n html: !stringIsEmpty(data.html)\n ? data.html\n : decodeBase64(data.encodedHtml),\n ...modulePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n ...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nexport default class DonutGraph extends Item {\n /**\n * @override Item.resizeElement\n * Resize the DOM content container.\n * @param width\n * @param height\n */\n protected resizeElement(width: number, height: number): void {\n if (width <= 0) width = 200;\n if (height <= 0) height = 200;\n super.resizeElement(width, height);\n }\n\n protected createDomElement(): HTMLElement {\n const element = document.createElement(\"div\");\n element.className = \"donut-graph\";\n element.innerHTML = this.props.html;\n\n // Hack to execute the JS after the HTML is added to the DOM.\n const scripts = element.getElementsByTagName(\"script\");\n for (let i = 0; i < scripts.length; i++) {\n setTimeout(() => {\n if (scripts[i].src.length === 0) eval(scripts[i].innerHTML.trim());\n }, 0);\n }\n\n return element;\n }\n\n protected updateDomElement(element: HTMLElement): void {\n element.innerHTML = this.props.html;\n\n // Hack to execute the JS after the HTML is added to the DOM.\n const aux = document.createElement(\"div\");\n aux.innerHTML = this.props.html;\n const scripts = aux.getElementsByTagName(\"script\");\n for (let i = 0; i < scripts.length; i++) {\n if (scripts[i].src.length === 0) {\n eval(scripts[i].innerHTML.trim());\n }\n }\n }\n}\n","import {\n LinkedVisualConsoleProps,\n UnknownObject,\n WithModuleProps\n} from \"../types\";\nimport {\n linkedVCPropsDecoder,\n modulePropsDecoder,\n decodeBase64,\n stringIsEmpty\n} from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\nexport type ModuleGraphProps = {\n type: ItemType.MODULE_GRAPH;\n html: string;\n} & ItemProps &\n WithModuleProps &\n LinkedVisualConsoleProps;\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the module graph props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function moduleGraphPropsDecoder(\n data: UnknownObject\n): ModuleGraphProps | never {\n if (stringIsEmpty(data.html) && stringIsEmpty(data.encodedHtml)) {\n throw new TypeError(\"missing html content.\");\n }\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.MODULE_GRAPH,\n html: !stringIsEmpty(data.html)\n ? data.html\n : decodeBase64(data.encodedHtml),\n ...modulePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n ...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nexport default class ModuleGraph extends Item {\n protected createDomElement(): HTMLElement {\n const element = document.createElement(\"div\");\n element.className = \"module-graph\";\n element.innerHTML = this.props.html;\n\n // Remove the overview graph.\n const legendP = element.getElementsByTagName(\"p\");\n for (let i = 0; i < legendP.length; i++) {\n legendP[i].style.margin = \"0px\";\n }\n\n // Remove the overview graph.\n const overviewGraphs = element.getElementsByClassName(\"overview_graph\");\n for (let i = 0; i < overviewGraphs.length; i++) {\n overviewGraphs[i].remove();\n }\n\n // Hack to execute the JS after the HTML is added to the DOM.\n const scripts = element.getElementsByTagName(\"script\");\n for (let i = 0; i < scripts.length; i++) {\n if (scripts[i].src.length === 0) {\n setTimeout(() => {\n try {\n eval(scripts[i].innerHTML.trim());\n } catch (ignored) {} // eslint-disable-line no-empty\n }, 0);\n }\n }\n\n return element;\n }\n\n protected updateDomElement(element: HTMLElement): void {\n element.innerHTML = this.props.html;\n\n // Remove the overview graph.\n const legendP = element.getElementsByTagName(\"p\");\n for (let i = 0; i < legendP.length; i++) {\n legendP[i].style.margin = \"0px\";\n }\n\n // Remove the overview graph.\n const overviewGraphs = element.getElementsByClassName(\"overview_graph\");\n for (let i = 0; i < overviewGraphs.length; i++) {\n overviewGraphs[i].remove();\n }\n\n // Hack to execute the JS after the HTML is added to the DOM.\n const aux = document.createElement(\"div\");\n aux.innerHTML = this.props.html;\n const scripts = aux.getElementsByTagName(\"script\");\n for (let i = 0; i < scripts.length; i++) {\n if (scripts[i].src.length === 0) {\n eval(scripts[i].innerHTML.trim());\n }\n }\n }\n}\n","import { UnknownObject, WithModuleProps } from \"../types\";\nimport { modulePropsDecoder, decodeBase64, stringIsEmpty } from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\nexport type BarsGraphProps = {\n type: ItemType.BARS_GRAPH;\n html: string;\n} & ItemProps &\n WithModuleProps;\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the bars graph props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function barsGraphPropsDecoder(\n data: UnknownObject\n): BarsGraphProps | never {\n if (stringIsEmpty(data.html) && stringIsEmpty(data.encodedHtml)) {\n throw new TypeError(\"missing html content.\");\n }\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.BARS_GRAPH,\n html: !stringIsEmpty(data.html)\n ? data.html\n : decodeBase64(data.encodedHtml),\n ...modulePropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nexport default class BarsGraph extends Item {\n protected createDomElement(): HTMLElement {\n const element = document.createElement(\"div\");\n element.className = \"bars-graph\";\n element.innerHTML = this.props.html;\n\n // Hack to execute the JS after the HTML is added to the DOM.\n const scripts = element.getElementsByTagName(\"script\");\n for (let i = 0; i < scripts.length; i++) {\n setTimeout(() => {\n if (scripts[i].src.length === 0) eval(scripts[i].innerHTML.trim());\n }, 0);\n }\n\n return element;\n }\n\n protected updateDomElement(element: HTMLElement): void {\n element.innerHTML = this.props.html;\n\n // Hack to execute the JS after the HTML is added to the DOM.\n const aux = document.createElement(\"div\");\n aux.innerHTML = this.props.html;\n const scripts = aux.getElementsByTagName(\"script\");\n for (let i = 0; i < scripts.length; i++) {\n if (scripts[i].src.length === 0) {\n eval(scripts[i].innerHTML.trim());\n }\n }\n }\n}\n","import {\n WithModuleProps,\n LinkedVisualConsoleProps,\n UnknownObject\n} from \"../types\";\n\nimport {\n modulePropsDecoder,\n linkedVCPropsDecoder,\n notEmptyStringOr\n} from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\nexport type StaticGraphProps = {\n type: ItemType.STATIC_GRAPH;\n imageSrc: string; // URL?\n showLastValueTooltip: \"default\" | \"enabled\" | \"disabled\";\n statusImageSrc: string | null; // URL?\n lastValue: string | null;\n} & ItemProps &\n (WithModuleProps | LinkedVisualConsoleProps);\n\n/**\n * Extract a valid enum value from a raw unknown value.\n * @param showLastValueTooltip Raw value.\n */\nconst parseShowLastValueTooltip = (\n showLastValueTooltip: any // eslint-disable-line @typescript-eslint/no-explicit-any\n): StaticGraphProps[\"showLastValueTooltip\"] => {\n switch (showLastValueTooltip) {\n case \"default\":\n case \"enabled\":\n case \"disabled\":\n return showLastValueTooltip;\n default:\n return \"default\";\n }\n};\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the static graph props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function staticGraphPropsDecoder(\n data: UnknownObject\n): StaticGraphProps | never {\n if (typeof data.imageSrc !== \"string\" || data.imageSrc.length === 0) {\n throw new TypeError(\"invalid image src.\");\n }\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.STATIC_GRAPH,\n imageSrc: data.imageSrc,\n showLastValueTooltip: parseShowLastValueTooltip(data.showLastValueTooltip),\n statusImageSrc: notEmptyStringOr(data.statusImageSrc, null),\n lastValue: notEmptyStringOr(data.lastValue, null),\n ...modulePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n ...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nexport default class StaticGraph extends Item {\n protected createDomElement(): HTMLElement {\n const img: HTMLImageElement = document.createElement(\"img\");\n img.className = \"static-graph\";\n img.src = this.props.statusImageSrc || this.props.imageSrc;\n\n // Show last value in a tooltip.\n if (\n this.props.lastValue !== null &&\n this.props.showLastValueTooltip !== \"disabled\"\n ) {\n img.className = \"static-graph image forced_title\";\n img.setAttribute(\"data-use_title_for_force_title\", \"1\");\n img.setAttribute(\"data-title\", this.props.lastValue);\n img.alt = this.props.lastValue;\n }\n\n return img;\n }\n}\n","import { LinkedVisualConsoleProps, UnknownObject } from \"../types\";\nimport { linkedVCPropsDecoder } from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\nexport type IconProps = {\n type: ItemType.ICON;\n imageSrc: string; // URL?\n} & ItemProps &\n LinkedVisualConsoleProps;\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the icon props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function iconPropsDecoder(data: UnknownObject): IconProps | never {\n if (typeof data.imageSrc !== \"string\" || data.imageSrc.length === 0) {\n throw new TypeError(\"invalid image src.\");\n }\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.ICON,\n imageSrc: data.imageSrc,\n ...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nexport default class Icon extends Item {\n protected createDomElement(): HTMLElement {\n const img: HTMLImageElement = document.createElement(\"img\");\n img.className = \"icon\";\n img.src = this.props.imageSrc;\n\n return img;\n }\n}\n","import {\n WithModuleProps,\n LinkedVisualConsoleProps,\n UnknownObject\n} from \"../types\";\nimport { modulePropsDecoder, linkedVCPropsDecoder } from \"../lib\";\nimport Item, { itemBasePropsDecoder, ItemType, ItemProps } from \"../Item\";\n\nexport type ColorCloudProps = {\n type: ItemType.COLOR_CLOUD;\n color: string;\n // TODO: Add the rest of the color cloud values?\n} & ItemProps &\n WithModuleProps &\n LinkedVisualConsoleProps;\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the static graph props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function colorCloudPropsDecoder(\n data: UnknownObject\n): ColorCloudProps | never {\n // TODO: Validate the color.\n if (typeof data.color !== \"string\" || data.color.length === 0) {\n throw new TypeError(\"invalid color.\");\n }\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.COLOR_CLOUD,\n color: data.color,\n ...modulePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n ...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nconst svgNS = \"http://www.w3.org/2000/svg\";\n\nexport default class ColorCloud extends Item {\n protected createDomElement(): HTMLElement {\n const container: HTMLDivElement = document.createElement(\"div\");\n container.className = \"color-cloud\";\n\n // Add the SVG.\n container.append(this.createSvgElement());\n\n return container;\n }\n\n public createSvgElement(): SVGSVGElement {\n const gradientId = `grad_${this.props.id}`;\n // SVG container.\n const svg = document.createElementNS(svgNS, \"svg\");\n // Auto resize SVG using the view box magic: https://css-tricks.com/scale-svg/\n svg.setAttribute(\"viewBox\", \"0 0 100 100\");\n\n // Defs.\n const defs = document.createElementNS(svgNS, \"defs\");\n // Radial gradient.\n const radialGradient = document.createElementNS(svgNS, \"radialGradient\");\n radialGradient.setAttribute(\"id\", gradientId);\n radialGradient.setAttribute(\"cx\", \"50%\");\n radialGradient.setAttribute(\"cy\", \"50%\");\n radialGradient.setAttribute(\"r\", \"50%\");\n radialGradient.setAttribute(\"fx\", \"50%\");\n radialGradient.setAttribute(\"fy\", \"50%\");\n // Stops.\n const stop0 = document.createElementNS(svgNS, \"stop\");\n stop0.setAttribute(\"offset\", \"0%\");\n stop0.setAttribute(\n \"style\",\n `stop-color:${this.props.color};stop-opacity:0.9`\n );\n const stop100 = document.createElementNS(svgNS, \"stop\");\n stop100.setAttribute(\"offset\", \"100%\");\n stop100.setAttribute(\n \"style\",\n `stop-color:${this.props.color};stop-opacity:0`\n );\n // Circle.\n const circle = document.createElementNS(svgNS, \"circle\");\n circle.setAttribute(\"fill\", `url(#${gradientId})`);\n circle.setAttribute(\"cx\", \"50%\");\n circle.setAttribute(\"cy\", \"50%\");\n circle.setAttribute(\"r\", \"50%\");\n\n // Append elements.\n radialGradient.append(stop0, stop100);\n defs.append(radialGradient);\n svg.append(defs, circle);\n\n return svg;\n }\n}\n","import { LinkedVisualConsoleProps, UnknownObject } from \"../types\";\nimport { linkedVCPropsDecoder, parseIntOr, notEmptyStringOr } from \"../lib\";\nimport Item, { ItemProps, itemBasePropsDecoder, ItemType } from \"../Item\";\n\nexport type GroupProps = {\n type: ItemType.GROUP_ITEM;\n imageSrc: string; // URL?\n groupId: number;\n statusImageSrc: string | null;\n} & ItemProps &\n LinkedVisualConsoleProps;\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the group props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function groupPropsDecoder(data: UnknownObject): GroupProps | never {\n if (typeof data.imageSrc !== \"string\" || data.imageSrc.length === 0) {\n throw new TypeError(\"invalid image src.\");\n }\n if (parseIntOr(data.groupId, null) === null) {\n throw new TypeError(\"invalid group Id.\");\n }\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.GROUP_ITEM,\n imageSrc: data.imageSrc,\n groupId: parseInt(data.groupId),\n statusImageSrc: notEmptyStringOr(data.statusImageSrc, null),\n ...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nexport default class Group extends Item {\n protected createDomElement(): HTMLElement {\n const img: HTMLImageElement = document.createElement(\"img\");\n img.className = \"group\";\n if (this.props.statusImageSrc != null) {\n img.src = this.props.statusImageSrc;\n }\n\n return img;\n }\n}\n","import \"./styles.css\";\n\nimport { LinkedVisualConsoleProps, UnknownObject, Size } from \"../../types\";\nimport {\n linkedVCPropsDecoder,\n parseIntOr,\n padLeft,\n parseBoolean,\n prefixedCssRules,\n notEmptyStringOr\n} from \"../../lib\";\nimport Item, { ItemProps, itemBasePropsDecoder, ItemType } from \"../../Item\";\n\nexport type ClockProps = {\n type: ItemType.CLOCK;\n clockType: \"analogic\" | \"digital\";\n clockFormat: \"datetime\" | \"time\";\n clockTimezone: string;\n clockTimezoneOffset: number; // Offset of the timezone to UTC in seconds.\n showClockTimezone: boolean;\n color?: string | null;\n} & ItemProps &\n LinkedVisualConsoleProps;\n\n/**\n * Extract a valid enum value from a raw unknown value.\n * @param clockType Raw value.\n */\nconst parseClockType = (\n clockType: any // eslint-disable-line @typescript-eslint/no-explicit-any\n): ClockProps[\"clockType\"] => {\n switch (clockType) {\n case \"analogic\":\n case \"digital\":\n return clockType;\n default:\n return \"analogic\";\n }\n};\n\n/**\n * Extract a valid enum value from a raw unknown value.\n * @param clockFormat Raw value.\n */\nconst parseClockFormat = (\n clockFormat: any // eslint-disable-line @typescript-eslint/no-explicit-any\n): ClockProps[\"clockFormat\"] => {\n switch (clockFormat) {\n case \"datetime\":\n case \"date\":\n case \"time\":\n return clockFormat;\n default:\n return \"datetime\";\n }\n};\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the clock props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function clockPropsDecoder(data: UnknownObject): ClockProps | never {\n if (\n typeof data.clockTimezone !== \"string\" ||\n data.clockTimezone.length === 0\n ) {\n throw new TypeError(\"invalid timezone.\");\n }\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.CLOCK,\n clockType: parseClockType(data.clockType),\n clockFormat: parseClockFormat(data.clockFormat),\n clockTimezone: data.clockTimezone,\n clockTimezoneOffset: parseIntOr(data.clockTimezoneOffset, 0),\n showClockTimezone: parseBoolean(data.showClockTimezone),\n color: notEmptyStringOr(data.color, null),\n ...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nexport default class Clock extends Item {\n public static readonly TICK_INTERVAL = 1000; // In ms.\n private intervalRef: number | null = null;\n\n public constructor(props: ClockProps) {\n // Call the superclass constructor.\n super(props);\n\n /* The item is already loaded and inserted into the DOM.\n * The class properties are now initialized.\n * Now you can modify the item, add event handlers, timers, etc.\n */\n\n /* The use of the arrow function is important here. startTick will\n * use the function passed as an argument to call the global setInterval\n * function. The interval, timeout or event functions, among other, are\n * called into another execution loop and using a different context.\n * The arrow functions, unlike the classic functions, doesn't create\n * their own context (this), so their context at execution time will be\n * use the current context at the declaration time.\n * http://es6-features.org/#Lexicalthis\n */\n this.startTick(\n () => {\n // Replace the old element with the updated date.\n this.childElementRef.innerHTML = this.createClock().innerHTML;\n },\n /* The analogic clock doesn't need to tick,\n * but it will be refreshed every 20 seconds\n * to avoid a desync caused by page freezes.\n */\n this.props.clockType === \"analogic\" ? 20000 : Clock.TICK_INTERVAL\n );\n }\n\n /**\n * Wrap a window.clearInterval call.\n */\n private stopTick(): void {\n if (this.intervalRef !== null) {\n window.clearInterval(this.intervalRef);\n this.intervalRef = null;\n }\n }\n\n /**\n * Wrap a window.setInterval call.\n * @param handler Function to be called every time the interval\n * timer is reached.\n * @param interval Number in milliseconds for the interval timer.\n */\n private startTick(\n handler: TimerHandler,\n interval: number = Clock.TICK_INTERVAL\n ): void {\n this.stopTick();\n this.intervalRef = window.setInterval(handler, interval);\n }\n\n /**\n * Create a element which contains the DOM representation of the item.\n * @return DOM Element.\n * @override\n */\n protected createDomElement(): HTMLElement | never {\n return this.createClock();\n }\n\n /**\n * To remove the event listeners and the elements from the DOM.\n * @override\n */\n public remove(): void {\n // Clear the interval.\n this.stopTick();\n // Call to the parent clean function.\n super.remove();\n }\n\n /**\n * @override Item.resizeElement\n * Resize the DOM content container.\n * @param width\n * @param height\n */\n protected resizeElement(width: number, height: number): void {\n const { width: newWidth, height: newHeight } = this.getElementSize(\n width,\n height\n ); // Destructuring assigment: http://es6-features.org/#ObjectMatchingShorthandNotation\n super.resizeElement(newWidth, newHeight);\n // Re-render the item to force it calculate a new font size.\n if (this.props.clockType === \"digital\") {\n // Replace the old element with the updated date.\n this.childElementRef.innerHTML = this.createClock().innerHTML;\n }\n }\n\n /**\n * Create a element which contains a representation of a clock.\n * It choose between the clock types.\n * @return DOM Element.\n * @throws Error.\n */\n private createClock(): HTMLElement | never {\n switch (this.props.clockType) {\n case \"analogic\":\n return this.createAnalogicClock();\n case \"digital\":\n return this.createDigitalClock();\n default:\n throw new Error(\"invalid clock type.\");\n }\n }\n\n /**\n * Create a element which contains a representation of an analogic clock.\n * @return DOM Element.\n */\n private createAnalogicClock(): HTMLElement {\n const svgNS = \"http://www.w3.org/2000/svg\";\n const colors = {\n watchFace: \"#FFFFF0\",\n watchFaceBorder: \"#242124\",\n mark: \"#242124\",\n handDark: \"#242124\",\n handLight: \"#525252\",\n secondHand: \"#DC143C\"\n };\n\n const { width, height } = this.getElementSize(); // Destructuring assigment: http://es6-features.org/#ObjectMatchingShorthandNotation\n\n const div = document.createElement(\"div\");\n div.className = \"analogic-clock\";\n div.style.width = `${width}px`;\n div.style.height = `${height}px`;\n\n // SVG container.\n const svg = document.createElementNS(svgNS, \"svg\");\n // Auto resize SVG using the view box magic: https://css-tricks.com/scale-svg/\n svg.setAttribute(\"viewBox\", \"0 0 100 100\");\n\n // Clock face.\n const clockFace = document.createElementNS(svgNS, \"g\");\n clockFace.setAttribute(\"class\", \"clockface\");\n const clockFaceBackground = document.createElementNS(svgNS, \"circle\");\n clockFaceBackground.setAttribute(\"cx\", \"50\");\n clockFaceBackground.setAttribute(\"cy\", \"50\");\n clockFaceBackground.setAttribute(\"r\", \"48\");\n clockFaceBackground.setAttribute(\"fill\", colors.watchFace);\n clockFaceBackground.setAttribute(\"stroke\", colors.watchFaceBorder);\n clockFaceBackground.setAttribute(\"stroke-width\", \"2\");\n clockFaceBackground.setAttribute(\"stroke-linecap\", \"round\");\n // Insert the clockface background into the clockface group.\n clockFace.append(clockFaceBackground);\n\n // Timezone complication.\n const city = this.getHumanTimezone();\n if (city.length > 0) {\n const timezoneComplication = document.createElementNS(svgNS, \"text\");\n timezoneComplication.setAttribute(\"text-anchor\", \"middle\");\n timezoneComplication.setAttribute(\"font-size\", \"8\");\n timezoneComplication.setAttribute(\n \"transform\",\n \"translate(30 50) rotate(90)\" // Rotate to counter the clock rotation.\n );\n timezoneComplication.setAttribute(\"fill\", colors.mark);\n timezoneComplication.textContent = city;\n clockFace.append(timezoneComplication);\n }\n\n // Marks group.\n const marksGroup = document.createElementNS(svgNS, \"g\");\n marksGroup.setAttribute(\"class\", \"marks\");\n // Build the 12 hours mark.\n const mainMarkGroup = document.createElementNS(svgNS, \"g\");\n mainMarkGroup.setAttribute(\"class\", \"mark\");\n mainMarkGroup.setAttribute(\"transform\", \"translate(50 50)\");\n const mark1a = document.createElementNS(svgNS, \"line\");\n mark1a.setAttribute(\"x1\", \"36\");\n mark1a.setAttribute(\"y1\", \"0\");\n mark1a.setAttribute(\"x2\", \"46\");\n mark1a.setAttribute(\"y2\", \"0\");\n mark1a.setAttribute(\"stroke\", colors.mark);\n mark1a.setAttribute(\"stroke-width\", \"5\");\n const mark1b = document.createElementNS(svgNS, \"line\");\n mark1b.setAttribute(\"x1\", \"36\");\n mark1b.setAttribute(\"y1\", \"0\");\n mark1b.setAttribute(\"x2\", \"46\");\n mark1b.setAttribute(\"y2\", \"0\");\n mark1b.setAttribute(\"stroke\", colors.watchFace);\n mark1b.setAttribute(\"stroke-width\", \"1\");\n // Insert the 12 mark lines into their group.\n mainMarkGroup.append(mark1a, mark1b);\n // Insert the main mark into the marks group.\n marksGroup.append(mainMarkGroup);\n // Build the rest of the marks.\n for (let i = 1; i < 60; i++) {\n const mark = document.createElementNS(svgNS, \"line\");\n mark.setAttribute(\"y1\", \"0\");\n mark.setAttribute(\"y2\", \"0\");\n mark.setAttribute(\"stroke\", colors.mark);\n mark.setAttribute(\"transform\", `translate(50 50) rotate(${i * 6})`);\n\n if (i % 5 === 0) {\n mark.setAttribute(\"x1\", \"38\");\n mark.setAttribute(\"x2\", \"46\");\n mark.setAttribute(\"stroke-width\", i % 15 === 0 ? \"2\" : \"1\");\n } else {\n mark.setAttribute(\"x1\", \"42\");\n mark.setAttribute(\"x2\", \"46\");\n mark.setAttribute(\"stroke-width\", \"0.5\");\n }\n\n // Insert the mark into the marks group.\n marksGroup.append(mark);\n }\n\n /* Clock hands */\n\n // Hour hand.\n const hourHand = document.createElementNS(svgNS, \"g\");\n hourHand.setAttribute(\"class\", \"hour-hand\");\n hourHand.setAttribute(\"transform\", \"translate(50 50)\");\n // This will go back and will act like a border.\n const hourHandA = document.createElementNS(svgNS, \"line\");\n hourHandA.setAttribute(\"class\", \"hour-hand-a\");\n hourHandA.setAttribute(\"x1\", \"0\");\n hourHandA.setAttribute(\"y1\", \"0\");\n hourHandA.setAttribute(\"x2\", \"30\");\n hourHandA.setAttribute(\"y2\", \"0\");\n hourHandA.setAttribute(\"stroke\", colors.handLight);\n hourHandA.setAttribute(\"stroke-width\", \"4\");\n hourHandA.setAttribute(\"stroke-linecap\", \"round\");\n // This will go in front of the previous line.\n const hourHandB = document.createElementNS(svgNS, \"line\");\n hourHandB.setAttribute(\"class\", \"hour-hand-b\");\n hourHandB.setAttribute(\"x1\", \"0\");\n hourHandB.setAttribute(\"y1\", \"0\");\n hourHandB.setAttribute(\"x2\", \"29.9\");\n hourHandB.setAttribute(\"y2\", \"0\");\n hourHandB.setAttribute(\"stroke\", colors.handDark);\n hourHandB.setAttribute(\"stroke-width\", \"3.1\");\n hourHandB.setAttribute(\"stroke-linecap\", \"round\");\n // Append the elements to finish the hour hand.\n hourHand.append(hourHandA, hourHandB);\n\n // Minute hand.\n const minuteHand = document.createElementNS(svgNS, \"g\");\n minuteHand.setAttribute(\"class\", \"minute-hand\");\n minuteHand.setAttribute(\"transform\", \"translate(50 50)\");\n // This will go back and will act like a border.\n const minuteHandA = document.createElementNS(svgNS, \"line\");\n minuteHandA.setAttribute(\"class\", \"minute-hand-a\");\n minuteHandA.setAttribute(\"x1\", \"0\");\n minuteHandA.setAttribute(\"y1\", \"0\");\n minuteHandA.setAttribute(\"x2\", \"40\");\n minuteHandA.setAttribute(\"y2\", \"0\");\n minuteHandA.setAttribute(\"stroke\", colors.handLight);\n minuteHandA.setAttribute(\"stroke-width\", \"2\");\n minuteHandA.setAttribute(\"stroke-linecap\", \"round\");\n // This will go in front of the previous line.\n const minuteHandB = document.createElementNS(svgNS, \"line\");\n minuteHandB.setAttribute(\"class\", \"minute-hand-b\");\n minuteHandB.setAttribute(\"x1\", \"0\");\n minuteHandB.setAttribute(\"y1\", \"0\");\n minuteHandB.setAttribute(\"x2\", \"39.9\");\n minuteHandB.setAttribute(\"y2\", \"0\");\n minuteHandB.setAttribute(\"stroke\", colors.handDark);\n minuteHandB.setAttribute(\"stroke-width\", \"1.5\");\n minuteHandB.setAttribute(\"stroke-linecap\", \"round\");\n const minuteHandPin = document.createElementNS(svgNS, \"circle\");\n minuteHandPin.setAttribute(\"r\", \"3\");\n minuteHandPin.setAttribute(\"fill\", colors.handDark);\n // Append the elements to finish the minute hand.\n minuteHand.append(minuteHandA, minuteHandB, minuteHandPin);\n\n // Second hand.\n const secondHand = document.createElementNS(svgNS, \"g\");\n secondHand.setAttribute(\"class\", \"second-hand\");\n secondHand.setAttribute(\"transform\", \"translate(50 50)\");\n const secondHandBar = document.createElementNS(svgNS, \"line\");\n secondHandBar.setAttribute(\"x1\", \"0\");\n secondHandBar.setAttribute(\"y1\", \"0\");\n secondHandBar.setAttribute(\"x2\", \"46\");\n secondHandBar.setAttribute(\"y2\", \"0\");\n secondHandBar.setAttribute(\"stroke\", colors.secondHand);\n secondHandBar.setAttribute(\"stroke-width\", \"1\");\n secondHandBar.setAttribute(\"stroke-linecap\", \"round\");\n const secondHandPin = document.createElementNS(svgNS, \"circle\");\n secondHandPin.setAttribute(\"r\", \"2\");\n secondHandPin.setAttribute(\"fill\", colors.secondHand);\n // Append the elements to finish the second hand.\n secondHand.append(secondHandBar, secondHandPin);\n\n // Pin.\n const pin = document.createElementNS(svgNS, \"circle\");\n pin.setAttribute(\"cx\", \"50\");\n pin.setAttribute(\"cy\", \"50\");\n pin.setAttribute(\"r\", \"0.3\");\n pin.setAttribute(\"fill\", colors.handDark);\n\n // Get the hand angles.\n const date = this.getDate();\n const seconds = date.getSeconds();\n const minutes = date.getMinutes();\n const hours = date.getHours();\n const secAngle = (360 / 60) * seconds;\n const minuteAngle = (360 / 60) * minutes + (360 / 60) * (seconds / 60);\n const hourAngle = (360 / 12) * hours + (360 / 12) * (minutes / 60);\n // Set the clock time by moving the hands.\n hourHand.setAttribute(\"transform\", `translate(50 50) rotate(${hourAngle})`);\n minuteHand.setAttribute(\n \"transform\",\n `translate(50 50) rotate(${minuteAngle})`\n );\n secondHand.setAttribute(\n \"transform\",\n `translate(50 50) rotate(${secAngle})`\n );\n\n // Build the clock\n svg.append(clockFace, marksGroup, hourHand, minuteHand, secondHand, pin);\n // Rotate the clock to its normal position.\n svg.setAttribute(\"transform\", \"rotate(-90)\");\n\n /* Add the animation declaration to the container.\n * Since the animation keyframes need to know the\n * start angle, this angle is dynamic (current time),\n * and we can't edit keyframes through javascript\n * safely and with backwards compatibility, we need\n * to inject it.\n */\n div.innerHTML = `\n \n `;\n // Add the clock to the container\n div.append(svg);\n\n return div;\n }\n\n /**\n * Create a element which contains a representation of a digital clock.\n * @return DOM Element.\n */\n private createDigitalClock(): HTMLElement {\n const element: HTMLDivElement = document.createElement(\"div\");\n element.className = \"digital-clock\";\n\n const { width } = this.getElementSize(); // Destructuring assigment: http://es6-features.org/#ObjectMatchingShorthandNotation\n\n // Calculate font size to adapt the font to the item size.\n const baseTimeFontSize = 20; // Per 100px of width.\n const dateFontSizeMultiplier = 0.5;\n const tzFontSizeMultiplier = 6 / this.props.clockTimezone.length;\n const timeFontSize = (baseTimeFontSize * width) / 100;\n const dateFontSize =\n (baseTimeFontSize * dateFontSizeMultiplier * width) / 100;\n const tzFontSize = Math.min(\n (baseTimeFontSize * tzFontSizeMultiplier * width) / 100,\n (width / 100) * 10\n );\n\n // Date.\n if (this.props.clockFormat === \"datetime\") {\n const dateElem: HTMLSpanElement = document.createElement(\"span\");\n dateElem.className = \"date\";\n dateElem.textContent = this.getDigitalDate();\n dateElem.style.fontSize = `${dateFontSize}px`;\n if (this.props.color) dateElem.style.color = this.props.color;\n element.append(dateElem);\n }\n\n // Time.\n const timeElem: HTMLSpanElement = document.createElement(\"span\");\n timeElem.className = \"time\";\n timeElem.textContent = this.getDigitalTime();\n timeElem.style.fontSize = `${timeFontSize}px`;\n if (this.props.color) timeElem.style.color = this.props.color;\n element.append(timeElem);\n\n // City name.\n const city = this.getHumanTimezone();\n if (city.length > 0) {\n const tzElem: HTMLSpanElement = document.createElement(\"span\");\n tzElem.className = \"timezone\";\n tzElem.textContent = city;\n tzElem.style.fontSize = `${tzFontSize}px`;\n if (this.props.color) tzElem.style.color = this.props.color;\n element.append(tzElem);\n }\n\n return element;\n }\n\n /**\n * Generate the current date using the timezone offset stored into the properties.\n * @return The current date.\n */\n private getDate(): Date {\n const d = new Date();\n const targetTZOffset = this.props.clockTimezoneOffset * 1000; // In ms.\n const localTZOffset = d.getTimezoneOffset() * 60 * 1000; // In ms.\n const utimestamp = d.getTime() + targetTZOffset + localTZOffset;\n\n return new Date(utimestamp);\n }\n\n /**\n * Generate a date representation with the format 'd/m/Y'.\n * @example 24/02/2020.\n * @return Date representation.\n */\n public getDigitalDate(initialDate: Date | null = null): string {\n const date = initialDate || this.getDate();\n // Use getDate, getDay returns the week day.\n const day = padLeft(date.getDate(), 2, 0);\n // The getMonth function returns the month starting by 0.\n const month = padLeft(date.getMonth() + 1, 2, 0);\n const year = padLeft(date.getFullYear(), 4, 0);\n\n // Format: 'd/m/Y'.\n return `${day}/${month}/${year}`;\n }\n\n /**\n * Generate a time representation with the format 'hh:mm:ss'.\n * @example 01:34:09.\n * @return Time representation.\n */\n public getDigitalTime(initialDate: Date | null = null): string {\n const date = initialDate || this.getDate();\n const hours = padLeft(date.getHours(), 2, 0);\n const minutes = padLeft(date.getMinutes(), 2, 0);\n const seconds = padLeft(date.getSeconds(), 2, 0);\n\n return `${hours}:${minutes}:${seconds}`;\n }\n\n /**\n * Extract a human readable city name from the timezone text.\n * @param timezone Timezone text.\n */\n public getHumanTimezone(timezone: string = this.props.clockTimezone): string {\n const [, city = \"\"] = timezone.split(\"/\");\n return city.replace(\"_\", \" \");\n }\n\n /**\n * Generate a element size using the current size and the default values.\n * @return The size.\n */\n private getElementSize(\n width: number = this.props.width,\n height: number = this.props.height\n ): Size {\n switch (this.props.clockType) {\n case \"analogic\": {\n let diameter = 100; // Default value.\n\n if (width > 0 && height > 0) {\n diameter = Math.min(width, height);\n } else if (width > 0) {\n diameter = width;\n } else if (height > 0) {\n diameter = height;\n }\n\n return {\n width: diameter,\n height: diameter\n };\n }\n case \"digital\": {\n if (width > 0 && height > 0) {\n // The proportion of the clock should be (width = height / 2) aproximately.\n height = width / 2 < height ? width / 2 : height;\n } else if (width > 0) {\n height = width / 2;\n } else if (height > 0) {\n // The proportion of the clock should be (height * 2 = width) aproximately.\n width = height * 2;\n } else {\n width = 100; // Default value.\n height = 50; // Default value.\n }\n\n return {\n width,\n height\n };\n }\n default:\n throw new Error(\"invalid clock type.\");\n }\n }\n}\n","import { UnknownObject } from \"../types\";\nimport { parseIntOr, notEmptyStringOr } from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\ninterface BoxProps extends ItemProps {\n // Overrided properties.\n readonly type: ItemType.BOX_ITEM;\n label: null;\n isLinkEnabled: false;\n parentId: null;\n aclGroupId: null;\n // Custom properties.\n borderWidth: number;\n borderColor: string | null;\n fillColor: string | null;\n}\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the item props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function boxPropsDecoder(data: UnknownObject): BoxProps | never {\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.BOX_ITEM,\n label: null,\n isLinkEnabled: false,\n parentId: null,\n aclGroupId: null,\n // Custom properties.\n borderWidth: parseIntOr(data.borderWidth, 0),\n borderColor: notEmptyStringOr(data.borderColor, null),\n fillColor: notEmptyStringOr(data.fillColor, null)\n };\n}\n\nexport default class Box extends Item {\n protected createDomElement(): HTMLElement {\n const box: HTMLDivElement = document.createElement(\"div\");\n box.className = \"box\";\n // To prevent this item to expand beyond its parent.\n box.style.boxSizing = \"border-box\";\n\n if (this.props.fillColor) {\n box.style.backgroundColor = this.props.fillColor;\n }\n\n // Border.\n if (this.props.borderWidth > 0) {\n box.style.borderStyle = \"solid\";\n // Control the max width to prevent this item to expand beyond its parent.\n const maxBorderWidth = Math.min(this.props.width, this.props.height) / 2;\n const borderWidth = Math.min(this.props.borderWidth, maxBorderWidth);\n box.style.borderWidth = `${borderWidth}px`;\n\n if (this.props.borderColor) {\n box.style.borderColor = this.props.borderColor;\n }\n }\n\n return box;\n }\n}\n","import { UnknownObject, Position, Size } from \"../types\";\nimport { parseIntOr, notEmptyStringOr } from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\ninterface LineProps extends ItemProps {\n // Overrided properties.\n readonly type: ItemType.LINE_ITEM;\n label: null;\n isLinkEnabled: false;\n parentId: null;\n aclGroupId: null;\n // Custom properties.\n startPosition: Position;\n endPosition: Position;\n lineWidth: number;\n color: string | null;\n}\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the item props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function linePropsDecoder(data: UnknownObject): LineProps | never {\n const props: LineProps = {\n ...itemBasePropsDecoder({ ...data, width: 1, height: 1 }), // Object spread. It will merge the properties of the two objects.\n type: ItemType.LINE_ITEM,\n label: null,\n isLinkEnabled: false,\n parentId: null,\n aclGroupId: null,\n // Initialize Position & Size.\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n // Custom properties.\n startPosition: {\n x: parseIntOr(data.startX, 0),\n y: parseIntOr(data.startY, 0)\n },\n endPosition: {\n x: parseIntOr(data.endX, 0),\n y: parseIntOr(data.endY, 0)\n },\n lineWidth: parseIntOr(data.lineWidth || data.borderWidth, 1),\n color: notEmptyStringOr(data.borderColor || data.color, null)\n };\n\n /*\n * We need to enhance the props with the extracted size and position\n * of the box cause there are missing at the props update. A better\n * solution would be overriding the props setter to do it there, but\n * the language doesn't allow it while targetting ES5.\n * TODO: We need to figure out a more consistent solution.\n */\n\n return {\n ...props,\n // Enhance the props extracting the box size and position.\n // eslint-disable-next-line @typescript-eslint/no-use-before-define\n ...Line.extractBoxSizeAndPosition(props)\n };\n}\n\nexport default class Line extends Item {\n /**\n * @override\n */\n public constructor(props: LineProps) {\n /*\n * We need to override the constructor cause we need to obtain\n * the\n * box size and position from the start and finish points\n * of the line.\n */\n super({\n ...props,\n ...Line.extractBoxSizeAndPosition(props)\n });\n }\n\n /**\n * @override\n * To create the item's DOM representation.\n * @return Item.\n */\n protected createDomElement(): HTMLElement {\n const element: HTMLDivElement = document.createElement(\"div\");\n element.className = \"line\";\n\n const svgNS = \"http://www.w3.org/2000/svg\";\n // SVG container.\n const svg = document.createElementNS(svgNS, \"svg\");\n // Set SVG size.\n svg.setAttribute(\n \"width\",\n (this.props.width + this.props.lineWidth).toString()\n );\n svg.setAttribute(\n \"height\",\n (this.props.height + this.props.lineWidth).toString()\n );\n const line = document.createElementNS(svgNS, \"line\");\n line.setAttribute(\n \"x1\",\n `${this.props.startPosition.x - this.props.x + this.props.lineWidth / 2}`\n );\n line.setAttribute(\n \"y1\",\n `${this.props.startPosition.y - this.props.y + this.props.lineWidth / 2}`\n );\n line.setAttribute(\n \"x2\",\n `${this.props.endPosition.x - this.props.x + this.props.lineWidth / 2}`\n );\n line.setAttribute(\n \"y2\",\n `${this.props.endPosition.y - this.props.y + this.props.lineWidth / 2}`\n );\n line.setAttribute(\"stroke\", this.props.color || \"black\");\n line.setAttribute(\"stroke-width\", this.props.lineWidth.toString());\n\n svg.append(line);\n element.append(svg);\n\n return element;\n }\n\n /**\n * Extract the size and position of the box from\n * the start and the finish of the line.\n * @param props Item properties.\n */\n public static extractBoxSizeAndPosition(props: LineProps): Size & Position {\n return {\n width: Math.abs(props.startPosition.x - props.endPosition.x),\n height: Math.abs(props.startPosition.y - props.endPosition.y),\n x: Math.min(props.startPosition.x, props.endPosition.x),\n y: Math.min(props.startPosition.y, props.endPosition.y)\n };\n }\n}\n","import { LinkedVisualConsoleProps, UnknownObject } from \"../types\";\nimport { linkedVCPropsDecoder } from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\nexport type LabelProps = {\n type: ItemType.LABEL;\n} & ItemProps &\n LinkedVisualConsoleProps;\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the label props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function labelPropsDecoder(data: UnknownObject): LabelProps | never {\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.LABEL,\n ...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nexport default class Label extends Item {\n protected createDomElement(): HTMLElement {\n const element = document.createElement(\"div\");\n element.className = \"label\";\n element.innerHTML = this.props.label || \"\";\n\n return element;\n }\n\n /**\n * @override Item.createLabelDomElement\n * Create a new label for the visual console item.\n * @return Item label.\n */\n public createLabelDomElement(): HTMLElement {\n const element = document.createElement(\"div\");\n element.className = \"visual-console-item-label\";\n // Always return an empty label.\n return element;\n }\n}\n","import {\n LinkedVisualConsoleProps,\n UnknownObject,\n WithModuleProps\n} from \"../types\";\nimport { linkedVCPropsDecoder, parseIntOr, modulePropsDecoder } from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\nexport type SimpleValueProps = {\n type: ItemType.SIMPLE_VALUE;\n valueType: \"string\" | \"image\";\n value: string;\n} & (\n | {\n processValue: \"none\";\n }\n | {\n processValue: \"avg\" | \"max\" | \"min\";\n period: number;\n }) &\n ItemProps &\n WithModuleProps &\n LinkedVisualConsoleProps;\n\n/**\n * Extract a valid enum value from a raw value type.\n * @param valueType Raw value.\n */\nconst parseValueType = (\n valueType: any // eslint-disable-line @typescript-eslint/no-explicit-any\n): SimpleValueProps[\"valueType\"] => {\n switch (valueType) {\n case \"string\":\n case \"image\":\n return valueType;\n default:\n return \"string\";\n }\n};\n\n/**\n * Extract a valid enum value from a raw process value.\n * @param processValue Raw value.\n */\nconst parseProcessValue = (\n processValue: any // eslint-disable-line @typescript-eslint/no-explicit-any\n): SimpleValueProps[\"processValue\"] => {\n switch (processValue) {\n case \"none\":\n case \"avg\":\n case \"max\":\n case \"min\":\n return processValue;\n default:\n return \"none\";\n }\n};\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the simple value props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function simpleValuePropsDecoder(\n data: UnknownObject\n): SimpleValueProps | never {\n if (typeof data.value !== \"string\" || data.value.length === 0) {\n throw new TypeError(\"invalid value\");\n }\n\n const processValue = parseProcessValue(data.processValue);\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.SIMPLE_VALUE,\n valueType: parseValueType(data.valueType),\n value: data.value,\n ...(processValue === \"none\"\n ? { processValue }\n : { processValue, period: parseIntOr(data.period, 0) }), // Object spread. It will merge the properties of the two objects.\n ...modulePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n ...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nexport default class SimpleValue extends Item {\n protected createDomElement(): HTMLElement {\n const element = document.createElement(\"div\");\n element.className = \"simple-value\";\n\n if (this.props.valueType === \"image\") {\n const img = document.createElement(\"img\");\n img.src = this.props.value;\n element.append(img);\n } else {\n // Add the value to the label and show it.\n let text = this.props.value;\n if (this.props.label) {\n text = this.props.label.replace(/\\(?_VALUE_\\)?/i, text);\n }\n\n element.innerHTML = text;\n }\n\n return element;\n }\n\n /**\n * @override Item.createLabelDomElement\n * Create a new label for the visual console item.\n * @return Item label.\n */\n protected createLabelDomElement(): HTMLElement {\n const element = document.createElement(\"div\");\n element.className = \"visual-console-item-label\";\n // Always return an empty label.\n return element;\n }\n}\n","import {\n LinkedVisualConsoleProps,\n UnknownObject,\n WithModuleProps\n} from \"../types\";\nimport {\n linkedVCPropsDecoder,\n modulePropsDecoder,\n notEmptyStringOr,\n parseIntOr,\n parseFloatOr\n} from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\nexport type PercentileProps = {\n type: ItemType.PERCENTILE_BAR;\n percentileType:\n | \"progress-bar\"\n | \"bubble\"\n | \"circular-progress-bar\"\n | \"circular-progress-bar-alt\";\n valueType: \"percent\" | \"value\";\n minValue: number | null;\n maxValue: number | null;\n color: string | null;\n labelColor: string | null;\n value: number | null;\n unit: string | null;\n} & ItemProps &\n WithModuleProps &\n LinkedVisualConsoleProps;\n\n/**\n * Extract a valid enum value from a raw type value.\n * @param type Raw value.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction extractPercentileType(type: any): PercentileProps[\"percentileType\"] {\n switch (type) {\n case \"progress-bar\":\n case \"bubble\":\n case \"circular-progress-bar\":\n case \"circular-progress-bar-alt\":\n return type;\n default:\n case ItemType.PERCENTILE_BAR:\n return \"progress-bar\";\n case ItemType.PERCENTILE_BUBBLE:\n return \"bubble\";\n case ItemType.CIRCULAR_PROGRESS_BAR:\n return \"circular-progress-bar\";\n case ItemType.CIRCULAR_INTERIOR_PROGRESS_BAR:\n return \"circular-progress-bar-alt\";\n }\n}\n\n/**\n * Extract a valid enum value from a raw value type value.\n * @param type Raw value.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction extractValueType(valueType: any): PercentileProps[\"valueType\"] {\n switch (valueType) {\n case \"percent\":\n case \"value\":\n return valueType;\n default:\n return \"percent\";\n }\n}\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the percentile props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function percentilePropsDecoder(\n data: UnknownObject\n): PercentileProps | never {\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.PERCENTILE_BAR,\n percentileType: extractPercentileType(data.percentileType || data.type),\n valueType: extractValueType(data.valueType),\n minValue: parseIntOr(data.minValue, null),\n maxValue: parseIntOr(data.maxValue, null),\n color: notEmptyStringOr(data.color, null),\n labelColor: notEmptyStringOr(data.labelColor, null),\n value: parseFloatOr(data.value, null),\n unit: notEmptyStringOr(data.unit, null),\n ...modulePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n ...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nconst svgNS = \"http://www.w3.org/2000/svg\";\n\nexport default class Percentile extends Item {\n protected createDomElement(): HTMLElement {\n const colors = {\n background: \"#000000\",\n progress: this.props.color || \"#F0F0F0\",\n text: this.props.labelColor || \"#444444\"\n };\n // Progress.\n const progress = this.getProgress();\n // Main element.\n const element = document.createElement(\"div\");\n // SVG container.\n const svg = document.createElementNS(svgNS, \"svg\");\n\n switch (this.props.percentileType) {\n case \"progress-bar\":\n {\n const backgroundRect = document.createElementNS(svgNS, \"rect\");\n backgroundRect.setAttribute(\"fill\", colors.background);\n backgroundRect.setAttribute(\"fill-opacity\", \"0.5\");\n backgroundRect.setAttribute(\"width\", \"100\");\n backgroundRect.setAttribute(\"height\", \"20\");\n backgroundRect.setAttribute(\"rx\", \"5\");\n backgroundRect.setAttribute(\"ry\", \"5\");\n const progressRect = document.createElementNS(svgNS, \"rect\");\n progressRect.setAttribute(\"fill\", colors.progress);\n progressRect.setAttribute(\"fill-opacity\", \"1\");\n progressRect.setAttribute(\"width\", `${progress}`);\n progressRect.setAttribute(\"height\", \"20\");\n progressRect.setAttribute(\"rx\", \"5\");\n progressRect.setAttribute(\"ry\", \"5\");\n const text = document.createElementNS(svgNS, \"text\");\n text.setAttribute(\"text-anchor\", \"middle\");\n text.setAttribute(\"alignment-baseline\", \"middle\");\n text.setAttribute(\"font-size\", \"12\");\n text.setAttribute(\"font-family\", \"arial\");\n text.setAttribute(\"font-weight\", \"bold\");\n text.setAttribute(\"transform\", \"translate(50 11)\");\n text.setAttribute(\"fill\", colors.text);\n\n if (this.props.valueType === \"value\") {\n text.textContent = this.props.unit\n ? `${this.props.value} ${this.props.unit}`\n : `${this.props.value}`;\n } else {\n text.textContent = `${progress}%`;\n }\n\n // Auto resize SVG using the view box magic: https://css-tricks.com/scale-svg/\n svg.setAttribute(\"viewBox\", \"0 0 100 20\");\n svg.append(backgroundRect, progressRect, text);\n }\n break;\n case \"bubble\":\n case \"circular-progress-bar\": // TODO: Add this chart.\n case \"circular-progress-bar-alt\": // TODO: Add this chart.\n {\n const backgroundCircle = document.createElementNS(svgNS, \"circle\");\n backgroundCircle.setAttribute(\"transform\", \"translate(50 50)\");\n backgroundCircle.setAttribute(\"fill\", colors.background);\n backgroundCircle.setAttribute(\"fill-opacity\", \"0.5\");\n backgroundCircle.setAttribute(\"r\", \"50\");\n const progressCircle = document.createElementNS(svgNS, \"circle\");\n progressCircle.setAttribute(\"transform\", \"translate(50 50)\");\n progressCircle.setAttribute(\"fill\", colors.progress);\n progressCircle.setAttribute(\"fill-opacity\", \"1\");\n progressCircle.setAttribute(\"r\", `${progress / 2}`);\n const text = document.createElementNS(svgNS, \"text\");\n text.setAttribute(\"text-anchor\", \"middle\");\n text.setAttribute(\"alignment-baseline\", \"middle\");\n text.setAttribute(\"font-size\", \"16\");\n text.setAttribute(\"font-family\", \"arial\");\n text.setAttribute(\"font-weight\", \"bold\");\n text.setAttribute(\"fill\", colors.text);\n\n if (this.props.valueType === \"value\") {\n if (this.props.unit && this.props.unit.length > 0) {\n const value = document.createElementNS(svgNS, \"tspan\");\n value.setAttribute(\"x\", \"0\");\n value.setAttribute(\"dy\", \"1em\");\n value.textContent = `${this.props.value}`;\n const unit = document.createElementNS(svgNS, \"tspan\");\n unit.setAttribute(\"x\", \"0\");\n unit.setAttribute(\"dy\", \"1em\");\n unit.textContent = `${this.props.unit}`;\n text.append(value, unit);\n text.setAttribute(\"transform\", \"translate(50 33)\");\n } else {\n text.textContent = `${this.props.value}`;\n text.setAttribute(\"transform\", \"translate(50 50)\");\n }\n } else {\n text.textContent = `${progress}%`;\n text.setAttribute(\"transform\", \"translate(50 50)\");\n }\n\n // Auto resize SVG using the view box magic: https://css-tricks.com/scale-svg/\n svg.setAttribute(\"viewBox\", \"0 0 100 100\");\n svg.append(backgroundCircle, progressCircle, text);\n }\n break;\n }\n\n element.append(svg);\n\n return element;\n }\n\n private getProgress(): number {\n const minValue = this.props.minValue || 0;\n const maxValue = this.props.maxValue || 100;\n const value = this.props.value || 100;\n\n if (value <= minValue) return 0;\n else if (value >= maxValue) return 100;\n else return ((value - minValue) / (maxValue - minValue)) * 100;\n }\n}\n","import { UnknownObject } from \"../types\";\nimport {\n stringIsEmpty,\n notEmptyStringOr,\n decodeBase64,\n parseIntOr\n} from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\nexport type ServiceProps = {\n type: ItemType.SERVICE;\n serviceId: number;\n imageSrc: string | null;\n statusImageSrc: string | null;\n encodedTitle: string | null;\n} & ItemProps;\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the service props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function servicePropsDecoder(data: UnknownObject): ServiceProps | never {\n if (data.imageSrc !== null) {\n if (\n typeof data.statusImageSrc !== \"string\" ||\n data.imageSrc.statusImageSrc === 0\n ) {\n throw new TypeError(\"invalid status image src.\");\n }\n } else {\n if (stringIsEmpty(data.encodedTitle)) {\n throw new TypeError(\"missing encode tittle content.\");\n }\n }\n\n if (parseIntOr(data.serviceId, null) === null) {\n throw new TypeError(\"invalid service id.\");\n }\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.SERVICE,\n serviceId: data.serviceId,\n imageSrc: notEmptyStringOr(data.imageSrc, null),\n statusImageSrc: notEmptyStringOr(data.statusImageSrc, null),\n encodedTitle: notEmptyStringOr(data.encodedTitle, null)\n };\n}\n\nexport default class Service extends Item {\n public createDomElement(): HTMLElement {\n const img: HTMLImageElement = document.createElement(\"img\");\n if (this.props.statusImageSrc !== null) {\n img.className = \"icon\";\n img.src = this.props.statusImageSrc;\n } else {\n if (this.props.encodedTitle !== null) {\n const element = document.createElement(\"div\");\n element.innerHTML = decodeBase64(this.props.encodedTitle);\n return element;\n }\n }\n return img;\n }\n}\n","import { UnknownObject, Size } from \"./types\";\nimport {\n parseBoolean,\n sizePropsDecoder,\n parseIntOr,\n notEmptyStringOr\n} from \"./lib\";\nimport Item, {\n ItemType,\n ItemProps,\n ItemClickEvent,\n ItemRemoveEvent\n} from \"./Item\";\nimport StaticGraph, { staticGraphPropsDecoder } from \"./items/StaticGraph\";\nimport Icon, { iconPropsDecoder } from \"./items/Icon\";\nimport ColorCloud, { colorCloudPropsDecoder } from \"./items/ColorCloud\";\nimport Group, { groupPropsDecoder } from \"./items/Group\";\nimport Clock, { clockPropsDecoder } from \"./items/Clock\";\nimport Box, { boxPropsDecoder } from \"./items/Box\";\nimport Line, { linePropsDecoder } from \"./items/Line\";\nimport Label, { labelPropsDecoder } from \"./items/Label\";\nimport SimpleValue, { simpleValuePropsDecoder } from \"./items/SimpleValue\";\nimport EventsHistory, {\n eventsHistoryPropsDecoder\n} from \"./items/EventsHistory\";\nimport Percentile, { percentilePropsDecoder } from \"./items/Percentile\";\nimport TypedEvent, { Disposable, Listener } from \"./TypedEvent\";\nimport DonutGraph, { donutGraphPropsDecoder } from \"./items/DonutGraph\";\nimport BarsGraph, { barsGraphPropsDecoder } from \"./items/BarsGraph\";\nimport ModuleGraph, { moduleGraphPropsDecoder } from \"./items/ModuleGraph\";\nimport Service, { servicePropsDecoder } from \"./items/Service\";\n\n// TODO: Document.\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nfunction itemInstanceFrom(data: UnknownObject) {\n const type = parseIntOr(data.type, null);\n if (type == null) throw new TypeError(\"missing item type.\");\n\n switch (type as ItemType) {\n case ItemType.STATIC_GRAPH:\n return new StaticGraph(staticGraphPropsDecoder(data));\n case ItemType.MODULE_GRAPH:\n return new ModuleGraph(moduleGraphPropsDecoder(data));\n case ItemType.SIMPLE_VALUE:\n case ItemType.SIMPLE_VALUE_MAX:\n case ItemType.SIMPLE_VALUE_MIN:\n case ItemType.SIMPLE_VALUE_AVG:\n return new SimpleValue(simpleValuePropsDecoder(data));\n case ItemType.PERCENTILE_BAR:\n case ItemType.PERCENTILE_BUBBLE:\n case ItemType.CIRCULAR_PROGRESS_BAR:\n case ItemType.CIRCULAR_INTERIOR_PROGRESS_BAR:\n return new Percentile(percentilePropsDecoder(data));\n case ItemType.LABEL:\n return new Label(labelPropsDecoder(data));\n case ItemType.ICON:\n return new Icon(iconPropsDecoder(data));\n case ItemType.SERVICE:\n return new Service(servicePropsDecoder(data));\n case ItemType.GROUP_ITEM:\n return new Group(groupPropsDecoder(data));\n case ItemType.BOX_ITEM:\n return new Box(boxPropsDecoder(data));\n case ItemType.LINE_ITEM:\n return new Line(linePropsDecoder(data));\n case ItemType.AUTO_SLA_GRAPH:\n return new EventsHistory(eventsHistoryPropsDecoder(data));\n case ItemType.DONUT_GRAPH:\n return new DonutGraph(donutGraphPropsDecoder(data));\n case ItemType.BARS_GRAPH:\n return new BarsGraph(barsGraphPropsDecoder(data));\n case ItemType.CLOCK:\n return new Clock(clockPropsDecoder(data));\n case ItemType.COLOR_CLOUD:\n return new ColorCloud(colorCloudPropsDecoder(data));\n default:\n throw new TypeError(\"item not found\");\n }\n}\n\n// TODO: Document.\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nfunction decodeProps(data: UnknownObject) {\n const type = parseIntOr(data.type, null);\n if (type == null) throw new TypeError(\"missing item type.\");\n\n switch (type as ItemType) {\n case ItemType.STATIC_GRAPH:\n return staticGraphPropsDecoder(data);\n case ItemType.MODULE_GRAPH:\n return moduleGraphPropsDecoder(data);\n case ItemType.SIMPLE_VALUE:\n case ItemType.SIMPLE_VALUE_MAX:\n case ItemType.SIMPLE_VALUE_MIN:\n case ItemType.SIMPLE_VALUE_AVG:\n return simpleValuePropsDecoder(data);\n case ItemType.PERCENTILE_BAR:\n case ItemType.PERCENTILE_BUBBLE:\n case ItemType.CIRCULAR_PROGRESS_BAR:\n case ItemType.CIRCULAR_INTERIOR_PROGRESS_BAR:\n return percentilePropsDecoder(data);\n case ItemType.LABEL:\n return labelPropsDecoder(data);\n case ItemType.ICON:\n return iconPropsDecoder(data);\n case ItemType.SERVICE:\n return servicePropsDecoder(data);\n case ItemType.GROUP_ITEM:\n return groupPropsDecoder(data);\n case ItemType.BOX_ITEM:\n return boxPropsDecoder(data);\n case ItemType.LINE_ITEM:\n return linePropsDecoder(data);\n case ItemType.AUTO_SLA_GRAPH:\n return eventsHistoryPropsDecoder(data);\n case ItemType.DONUT_GRAPH:\n return donutGraphPropsDecoder(data);\n case ItemType.BARS_GRAPH:\n return barsGraphPropsDecoder(data);\n case ItemType.CLOCK:\n return clockPropsDecoder(data);\n case ItemType.COLOR_CLOUD:\n return colorCloudPropsDecoder(data);\n default:\n throw new TypeError(\"decoder not found\");\n }\n}\n\n// Base properties.\nexport interface VisualConsoleProps extends Size {\n readonly id: number;\n name: string;\n groupId: number;\n backgroundURL: string | null; // URL?\n backgroundColor: string | null;\n isFavorite: boolean;\n relationLineWidth: number;\n}\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the Visual Console props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function visualConsolePropsDecoder(\n data: UnknownObject\n): VisualConsoleProps | never {\n // Object destructuring: http://es6-features.org/#ObjectMatchingShorthandNotation\n const {\n id,\n name,\n groupId,\n backgroundURL,\n backgroundColor,\n isFavorite,\n relationLineWidth\n } = data;\n\n if (id == null || isNaN(parseInt(id))) {\n throw new TypeError(\"invalid Id.\");\n }\n if (typeof name !== \"string\" || name.length === 0) {\n throw new TypeError(\"invalid name.\");\n }\n if (groupId == null || isNaN(parseInt(groupId))) {\n throw new TypeError(\"invalid group Id.\");\n }\n\n return {\n id: parseInt(id),\n name,\n groupId: parseInt(groupId),\n backgroundURL: notEmptyStringOr(backgroundURL, null),\n backgroundColor: notEmptyStringOr(backgroundColor, null),\n isFavorite: parseBoolean(isFavorite),\n relationLineWidth: parseIntOr(relationLineWidth, 0),\n ...sizePropsDecoder(data)\n };\n}\n\nexport default class VisualConsole {\n // Reference to the DOM element which will contain the items.\n private readonly containerRef: HTMLElement;\n // Properties.\n private _props: VisualConsoleProps;\n // Visual Console Item instances by their Id.\n private elementsById: {\n [key: number]: Item;\n } = {};\n // Visual Console Item Ids.\n private elementIds: ItemProps[\"id\"][] = [];\n // Dictionary which store the created lines.\n private relations: {\n [key: string]: Line;\n } = {};\n // Event manager for click events.\n private readonly clickEventManager = new TypedEvent<\n ItemClickEvent\n >();\n // List of references to clean the event listeners.\n private readonly disposables: Disposable[] = [];\n\n /**\n * React to a click on an element.\n * @param e Event object.\n */\n private handleElementClick: (e: ItemClickEvent) => void = e => {\n this.clickEventManager.emit(e);\n // console.log(`Clicked element #${e.data.id}`, e);\n };\n\n /**\n * Clear some element references.\n * @param e Event object.\n */\n private handleElementRemove: (e: ItemRemoveEvent) => void = e => {\n // Remove the element from the list and its relations.\n this.elementIds = this.elementIds.filter(id => id !== e.data.id);\n delete this.elementsById[e.data.id];\n this.clearRelations(e.data.id);\n };\n\n public constructor(\n container: HTMLElement,\n props: UnknownObject,\n items: UnknownObject[]\n ) {\n this.containerRef = container;\n this._props = visualConsolePropsDecoder(props);\n\n // Force the first render.\n this.render();\n\n // Sort by isOnTop, id ASC\n items = items.sort(function(a, b) {\n if (\n a.isOnTop == null ||\n b.isOnTop == null ||\n a.id == null ||\n b.id == null\n ) {\n return 0;\n }\n\n if (a.isOnTop && !b.isOnTop) return 1;\n else if (!a.isOnTop && b.isOnTop) return -1;\n else if (a.id < b.id) return 1;\n else return -1;\n });\n\n // Initialize the items.\n items.forEach(item => {\n try {\n const itemInstance = itemInstanceFrom(item);\n // Add the item to the list.\n this.elementsById[itemInstance.props.id] = itemInstance;\n this.elementIds.push(itemInstance.props.id);\n // Item event handlers.\n itemInstance.onClick(this.handleElementClick);\n itemInstance.onRemove(this.handleElementRemove);\n // Add the item to the DOM.\n this.containerRef.append(itemInstance.elementRef);\n } catch (error) {\n console.log(\"Error creating a new element:\", error.message);\n }\n });\n\n // Create lines.\n this.buildRelations();\n }\n\n /**\n * Public accessor of the `elements` property.\n * @return Properties.\n */\n public get elements(): Item[] {\n // Ensure the type cause Typescript doesn't know the filter removes null items.\n return this.elementIds\n .map(id => this.elementsById[id])\n .filter(_ => _ != null) as Item[];\n }\n\n /**\n * Public setter of the `elements` property.\n * @param items.\n */\n public updateElements(items: UnknownObject[]): void {\n const itemIds = items.map(item => item.id || null).filter(id => id != null);\n itemIds as number[]; // Tell the type system to rely on us.\n // Get the elements we should delete.\n const deletedIds: number[] = this.elementIds.filter(\n id => itemIds.indexOf(id) < 0\n );\n // Delete the elements.\n deletedIds.forEach(id => {\n if (this.elementsById[id] != null) {\n this.elementsById[id].remove();\n delete this.elementsById[id];\n }\n });\n // Replace the element ids.\n this.elementIds = itemIds;\n\n // Initialize the items.\n items.forEach(item => {\n if (item.id) {\n if (this.elementsById[item.id] == null) {\n // New item.\n try {\n const itemInstance = itemInstanceFrom(item);\n // Add the item to the list.\n this.elementsById[itemInstance.props.id] = itemInstance;\n // Item event handlers.\n itemInstance.onClick(this.handleElementClick);\n itemInstance.onRemove(this.handleElementRemove);\n // Add the item to the DOM.\n this.containerRef.append(itemInstance.elementRef);\n } catch (error) {\n console.log(\"Error creating a new element:\", error.message);\n }\n } else {\n // Update item.\n try {\n this.elementsById[item.id].props = decodeProps(item);\n } catch (error) {\n console.log(\"Error updating an element:\", error.message);\n }\n }\n }\n });\n\n // Re-build relations.\n this.buildRelations();\n }\n\n /**\n * Public accessor of the `props` property.\n * @return Properties.\n */\n public get props(): VisualConsoleProps {\n return { ...this._props }; // Return a copy.\n }\n\n /**\n * Public setter of the `props` property.\n * If the new props are different enough than the\n * stored props, a render would be fired.\n * @param newProps\n */\n public set props(newProps: VisualConsoleProps) {\n const prevProps = this.props;\n // Update the internal props.\n this._props = newProps;\n\n // From this point, things which rely on this.props can access to the changes.\n\n // Re-render.\n this.render(prevProps);\n }\n\n /**\n * Recreate or update the HTMLElement which represents the Visual Console into the DOM.\n * @param prevProps If exists it will be used to only DOM updates instead of a full replace.\n */\n public render(prevProps: VisualConsoleProps | null = null): void {\n if (prevProps) {\n if (prevProps.backgroundURL !== this.props.backgroundURL) {\n this.containerRef.style.backgroundImage =\n this.props.backgroundURL !== null\n ? `url(${this.props.backgroundURL})`\n : null;\n }\n if (prevProps.backgroundColor !== this.props.backgroundColor) {\n this.containerRef.style.backgroundColor = this.props.backgroundColor;\n }\n if (this.sizeChanged(prevProps, this.props)) {\n this.resizeElement(this.props.width, this.props.height);\n }\n } else {\n this.containerRef.style.backgroundImage =\n this.props.backgroundURL !== null\n ? `url(${this.props.backgroundURL})`\n : null;\n\n this.containerRef.style.backgroundColor = this.props.backgroundColor;\n this.resizeElement(this.props.width, this.props.height);\n }\n }\n\n /**\n * Compare the previous and the new size and return\n * a boolean value in case the size changed.\n * @param prevSize\n * @param newSize\n * @return Whether the size changed or not.\n */\n public sizeChanged(prevSize: Size, newSize: Size): boolean {\n return (\n prevSize.width !== newSize.width || prevSize.height !== newSize.height\n );\n }\n\n /**\n * Resize the DOM container.\n * @param width\n * @param height\n */\n public resizeElement(width: number, height: number): void {\n this.containerRef.style.width = `${width}px`;\n this.containerRef.style.height = `${height}px`;\n }\n\n /**\n * Update the size into the properties and resize the DOM container.\n * @param width\n * @param height\n */\n public resize(width: number, height: number): void {\n this.props = {\n ...this.props, // Object spread: http://es6-features.org/#SpreadOperator\n width,\n height\n };\n }\n\n /**\n * To remove the event listeners and the elements from the DOM.\n */\n public remove(): void {\n this.disposables.forEach(d => d.dispose()); // Arrow function.\n this.elements.forEach(e => e.remove()); // Arrow function.\n this.elementsById = {};\n this.elementIds = [];\n // Clear relations.\n this.clearRelations();\n // Clean container.\n this.containerRef.innerHTML = \"\";\n }\n\n /**\n * Create line elements which connect the elements with their parents.\n */\n private buildRelations(): void {\n // Clear relations.\n this.clearRelations();\n // Add relations.\n this.elements.forEach(item => {\n if (item.props.parentId !== null) {\n const parent = this.elementsById[item.props.parentId];\n const child = this.elementsById[item.props.id];\n if (parent && child) this.addRelationLine(parent, child);\n }\n });\n }\n\n /**\n * @param itemId Optional identifier of a parent or child item.\n * Remove the line elements which connect the elements with their parents.\n */\n private clearRelations(itemId?: number): void {\n if (itemId != null) {\n for (let key in this.relations) {\n const ids = key.split(\"|\");\n const parentId = Number.parseInt(ids[0]);\n const childId = Number.parseInt(ids[1]);\n\n if (itemId === parentId || itemId === childId) {\n this.relations[key].remove();\n delete this.relations[key];\n }\n }\n } else {\n for (let key in this.relations) {\n this.relations[key].remove();\n delete this.relations[key];\n }\n }\n }\n\n /**\n * Retrieve the line element which represent the relation between items.\n * @param parentId Identifier of the parent item.\n * @param childId Itentifier of the child item.\n * @return The line element or nothing.\n */\n private getRelationLine(parentId: number, childId: number): Line | null {\n const identifier = `${parentId}|${childId}`;\n return this.relations[identifier] || null;\n }\n\n /**\n * Add a new line item to represent a relation between the items.\n * @param parent Parent item.\n * @param child Child item.\n * @return Whether the line was added or not.\n */\n private addRelationLine(\n parent: Item,\n child: Item\n ): Line {\n const identifier = `${parent.props.id}|${child.props.id}`;\n if (this.relations[identifier] != null) {\n this.relations[identifier].remove();\n }\n\n // Get the items center.\n const startX = parent.props.x + parent.elementRef.clientWidth / 2;\n const startY =\n parent.props.y +\n (parent.elementRef.clientHeight - parent.labelElementRef.clientHeight) /\n 2;\n const endX = child.props.x + child.elementRef.clientWidth / 2;\n const endY =\n child.props.y +\n (child.elementRef.clientHeight - child.labelElementRef.clientHeight) / 2;\n\n const line = new Line(\n linePropsDecoder({\n id: 0,\n type: ItemType.LINE_ITEM,\n startX,\n startY,\n endX,\n endY,\n width: 0,\n height: 0,\n lineWidth: this.props.relationLineWidth,\n color: \"#CCCCCC\"\n })\n );\n // Save a reference to the line item.\n this.relations[identifier] = line;\n\n // Add the line to the DOM.\n line.elementRef.style.zIndex = \"0\";\n this.containerRef.append(line.elementRef);\n\n return line;\n }\n\n /**\n * Add an event handler to the click of the linked visual console elements.\n * @param listener Function which is going to be executed when a linked console is clicked.\n */\n public onClick(listener: Listener>): Disposable {\n /*\n * The '.on' function returns a function which will clean the event\n * listener when executed. We store all the 'dispose' functions to\n * call them when the item should be cleared.\n */\n const disposable = this.clickEventManager.on(listener);\n this.disposables.push(disposable);\n\n return disposable;\n }\n}\n","/*\n * Useful resources.\n * http://es6-features.org/\n * http://exploringjs.com/es6\n * https://www.typescriptlang.org/\n */\n\nimport \"./main.css\"; // CSS import.\nimport VisualConsole from \"./VisualConsole\";\n\n// Export the VisualConsole class to the global object.\n\n// eslint-disable-next-line\n(window as any).VisualConsole = VisualConsole;\n"],"sourceRoot":""} \ No newline at end of file diff --git a/pandora_console/include/visual-console-client/vc.main.e5acbc3b.min.js.map b/pandora_console/include/visual-console-client/vc.main.e5acbc3b.min.js.map deleted file mode 100644 index f188b78baa..0000000000 --- a/pandora_console/include/visual-console-client/vc.main.e5acbc3b.min.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/lib.ts","webpack:///./src/Item.ts","webpack:///./src/TypedEvent.ts","webpack:///./src/items/EventsHistory.ts","webpack:///./src/items/DonutGraph.ts","webpack:///./src/items/ModuleGraph.ts","webpack:///./src/items/BarsGraph.ts","webpack:///./src/items/StaticGraph.ts","webpack:///./src/items/Icon.ts","webpack:///./src/items/ColorCloud.ts","webpack:///./src/items/Group.ts","webpack:///./src/items/Clock/index.ts","webpack:///./src/items/Box.ts","webpack:///./src/items/Line.ts","webpack:///./src/items/Label.ts","webpack:///./src/items/SimpleValue.ts","webpack:///./src/items/Percentile.ts","webpack:///./src/items/Service.ts","webpack:///./src/VisualConsole.ts","webpack:///./src/index.ts"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","parseIntOr","defaultValue","length","isNaN","parseInt","parseFloatOr","parseFloat","stringIsEmpty","notEmptyStringOr","parseBoolean","padLeft","pad","diffLength","substr","Math","abs","substring","repeatTimes","floor","restLength","newPad","positionPropsDecoder","data","x","y","sizePropsDecoder","width","height","TypeError","modulePropsDecoder","id","moduleName","__assign","metaconsoleId","agentId","agentName","agentProps","agentPropsDecoder","linkedVCPropsDecoder","linkedLayoutId","linkedLayoutAgentId","linkedLayoutStatusProps","linkedLayoutStatusType","weight","linkedLayoutStatusTypeWeight","warningThreshold","linkedLayoutStatusTypeWarningThreshold","criticalThreshold","linkedLayoutStatusTypeCriticalThreshold","linkedLayoutBaseProps","prefixedCssRules","ruleName","ruleValue","rule","decodeBase64","input","decodeURIComponent","escape","window","atob","parseLabelPosition","labelPosition","itemBasePropsDecoder","type","label","_lib__WEBPACK_IMPORTED_MODULE_0__","isLinkEnabled","link","isOnTop","parentId","aclGroupId","VisualConsoleItem","props","this","clickEventManager","_TypedEvent__WEBPACK_IMPORTED_MODULE_1__","removeEventManager","disposables","itemProps","elementRef","createContainerDomElement","labelElementRef","createLabelDomElement","childElementRef","createDomElement","append","resizeElement","changeLabelPosition","box","_this","document","createElement","href","className","style","zIndex","left","top","onclick","e","emit","nativeEvent","element","innerHTML","updateDomElement","newProps","prevProps","shouldBeUpdated","render","positionChanged","moveElement","sizeChanged","container","parentNode","replaceChild","remove","forEach","disposable","dispose","ignored","prevPosition","newPosition","position","flexDirection","move","prevSize","newSize","resize","onClick","listener","on","push","onRemove","__webpack_exports__","TypedEvent","listeners","listenersOncer","off","once","callbackIndex","indexOf","splice","event","pipe","te","eventsHistoryPropsDecoder","html","encodedHtml","_Item__WEBPACK_IMPORTED_MODULE_1__","maxTime","EventsHistory","_super","__extends","scripts","getElementsByTagName","src","setTimeout","eval","trim","aux","donutGraphPropsDecoder","DonutGraph","moduleGraphPropsDecoder","ModuleGraph","legendP","margin","overviewGraphs","getElementsByClassName","barsGraphPropsDecoder","BarsGraph","parseShowLastValueTooltip","showLastValueTooltip","staticGraphPropsDecoder","imageSrc","Item","statusImageSrc","lib","lastValue","StaticGraph","img","setAttribute","alt","iconPropsDecoder","Icon_assign","Icon","Icon_extends","colorCloudPropsDecoder","color","ColorCloud_assign","ColorCloud_svgNS","ColorCloud","ColorCloud_extends","createSvgElement","gradientId","svg","createElementNS","defs","radialGradient","stop0","stop100","circle","groupPropsDecoder","groupId","Group_assign","Group","Group_extends","parseClockType","clockType","parseClockFormat","clockFormat","clockPropsDecoder","clockTimezone","Clock_assign","clockTimezoneOffset","showClockTimezone","items_Clock","Clock","intervalRef","startTick","createClock","TICK_INTERVAL","Clock_extends","stopTick","clearInterval","handler","interval","setInterval","_a","getElementSize","newWidth","newHeight","createAnalogicClock","createDigitalClock","Error","svgNS","colors","div","clockFace","clockFaceBackground","city","getHumanTimezone","timezoneComplication","textContent","marksGroup","mainMarkGroup","mark1a","mark1b","mark","hourHand","hourHandA","hourHandB","minuteHand","minuteHandA","minuteHandB","minuteHandPin","secondHand","secondHandBar","secondHandPin","pin","date","getDate","seconds","getSeconds","minutes","getMinutes","secAngle","minuteAngle","hourAngle","getHours","join","tzFontSizeMultiplier","timeFontSize","dateFontSize","baseTimeFontSize","tzFontSize","min","dateElem","getDigitalDate","fontSize","timeElem","getDigitalTime","tzElem","Date","targetTZOffset","localTZOffset","getTimezoneOffset","utimestamp","getTime","console","log","initialDate","getMonth","getFullYear","timezone","_b","split","replace","diameter","boxPropsDecoder","Box_assign","borderWidth","borderColor","fillColor","Box","Box_extends","boxSizing","backgroundColor","borderStyle","maxBorderWidth","linePropsDecoder","Line_assign","startPosition","startX","startY","endPosition","endX","endY","lineWidth","Line","extractBoxSizeAndPosition","Line_extends","toString","line","labelPropsDecoder","Label_assign","Label","Label_extends","parseValueType","valueType","parseProcessValue","processValue","simpleValuePropsDecoder","SimpleValue_assign","period","SimpleValue","SimpleValue_extends","text","extractPercentileType","extractValueType","percentilePropsDecoder","Percentile_assign","percentileType","minValue","maxValue","labelColor","unit","Percentile_svgNS","Percentile","Percentile_extends","background","progress","getProgress","backgroundRect","progressRect","backgroundCircle","progressCircle","servicePropsDecoder","encodedTitle","serviceId","Service_assign","Service","Service_extends","itemInstanceFrom","items_StaticGraph","items_SimpleValue","items_Percentile","items_Label","items_Icon","items_Service","items_Group","items_Box","items_Line","items_ColorCloud","VisualConsole","items","elementsById","elementIds","relations","handleElementClick","handleElementRemove","filter","clearRelations","containerRef","_props","backgroundURL","isFavorite","relationLineWidth","VisualConsole_assign","visualConsolePropsDecoder","sort","a","b","item","itemInstance","error","message","buildRelations","map","_","updateElements","itemIds","decodeProps","backgroundImage","elements","parent_1","child","addRelationLine","itemId","ids","Number","childId","getRelationLine","identifier","parent","clientWidth","clientHeight","src_VisualConsole"],"mappings":"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","file":"vc.main.e5acbc3b.min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 9);\n","import {\n UnknownObject,\n Position,\n Size,\n WithAgentProps,\n WithModuleProps,\n LinkedVisualConsoleProps,\n LinkedVisualConsolePropsStatus\n} from \"./types\";\n\n/**\n * Return a number or a default value from a raw value.\n * @param value Raw value from which we will try to extract a valid number.\n * @param defaultValue Default value to use if we cannot extract a valid number.\n * @return A valid number or the default value.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function parseIntOr(value: any, defaultValue: T): number | T {\n if (typeof value === \"number\") return value;\n if (typeof value === \"string\" && value.length > 0 && !isNaN(parseInt(value)))\n return parseInt(value);\n else return defaultValue;\n}\n\n/**\n * Return a number or a default value from a raw value.\n * @param value Raw value from which we will try to extract a valid number.\n * @param defaultValue Default value to use if we cannot extract a valid number.\n * @return A valid number or the default value.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function parseFloatOr(value: any, defaultValue: T): number | T {\n if (typeof value === \"number\") return value;\n if (\n typeof value === \"string\" &&\n value.length > 0 &&\n !isNaN(parseFloat(value))\n )\n return parseFloat(value);\n else return defaultValue;\n}\n\n/**\n * Check if a string exists and it's not empty.\n * @param value Value to check.\n * @return The check result.\n */\nexport function stringIsEmpty(value?: string | null): boolean {\n return value == null || value.length === 0;\n}\n\n/**\n * Return a not empty string or a default value from a raw value.\n * @param value Raw value from which we will try to extract a non empty string.\n * @param defaultValue Default value to use if we cannot extract a non empty string.\n * @return A non empty string or the default value.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function notEmptyStringOr(value: any, defaultValue: T): string | T {\n return typeof value === \"string\" && value.length > 0 ? value : defaultValue;\n}\n\n/**\n * Return a boolean from a raw value.\n * @param value Raw value from which we will try to extract the boolean.\n * @return A valid boolean value. false by default.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function parseBoolean(value: any): boolean {\n if (typeof value === \"boolean\") return value;\n else if (typeof value === \"number\") return value > 0;\n else if (typeof value === \"string\") return value === \"1\" || value === \"true\";\n else return false;\n}\n\n/**\n * Pad the current string with another string (multiple times, if needed)\n * until the resulting string reaches the given length.\n * The padding is applied from the start (left) of the current string.\n * @param value Text that needs to be padded.\n * @param length Length of the returned text.\n * @param pad Text to add.\n * @return Padded text.\n */\nexport function padLeft(\n value: string | number,\n length: number,\n pad: string | number = \" \"\n): string {\n if (typeof value === \"number\") value = `${value}`;\n if (typeof pad === \"number\") pad = `${pad}`;\n\n const diffLength = length - value.length;\n if (diffLength === 0) return value;\n if (diffLength < 0) return value.substr(Math.abs(diffLength));\n\n if (diffLength === pad.length) return `${pad}${value}`;\n if (diffLength < pad.length) return `${pad.substring(0, diffLength)}${value}`;\n\n const repeatTimes = Math.floor(diffLength / pad.length);\n const restLength = diffLength - pad.length * repeatTimes;\n\n let newPad = \"\";\n for (let i = 0; i < repeatTimes; i++) newPad += pad;\n\n if (restLength === 0) return `${newPad}${value}`;\n return `${newPad}${pad.substring(0, restLength)}${value}`;\n}\n\n/* Decoders */\n\n/**\n * Build a valid typed object from a raw object.\n * @param data Raw object.\n * @return An object representing the position.\n */\nexport function positionPropsDecoder(data: UnknownObject): Position {\n return {\n x: parseIntOr(data.x, 0),\n y: parseIntOr(data.y, 0)\n };\n}\n\n/**\n * Build a valid typed object from a raw object.\n * @param data Raw object.\n * @return An object representing the size.\n * @throws Will throw a TypeError if the width and height are not valid numbers.\n */\nexport function sizePropsDecoder(data: UnknownObject): Size | never {\n if (\n data.width == null ||\n isNaN(parseInt(data.width)) ||\n data.height == null ||\n isNaN(parseInt(data.height))\n ) {\n throw new TypeError(\"invalid size.\");\n }\n\n return {\n width: parseInt(data.width),\n height: parseInt(data.height)\n };\n}\n\n/**\n * Build a valid typed object from a raw object.\n * @param data Raw object.\n * @return An object representing the agent properties.\n */\nexport function agentPropsDecoder(data: UnknownObject): WithAgentProps {\n // Object destructuring: http://es6-features.org/#ObjectMatchingShorthandNotation\n const { metaconsoleId, agentId: id, agentName: name } = data;\n\n const agentProps: WithAgentProps = {\n agentId: parseIntOr(id, null),\n agentName: typeof name === \"string\" && name.length > 0 ? name : null\n };\n\n return metaconsoleId != null\n ? {\n metaconsoleId,\n ...agentProps // Object spread: http://es6-features.org/#SpreadOperator\n }\n : agentProps;\n}\n\n/**\n * Build a valid typed object from a raw object.\n * @param data Raw object.\n * @return An object representing the module and agent properties.\n */\nexport function modulePropsDecoder(data: UnknownObject): WithModuleProps {\n // Object destructuring: http://es6-features.org/#ObjectMatchingShorthandNotation\n const { moduleId: id, moduleName: name } = data;\n\n return {\n moduleId: parseIntOr(id, null),\n moduleName: typeof name === \"string\" && name.length > 0 ? name : null,\n ...agentPropsDecoder(data) // Object spread: http://es6-features.org/#SpreadOperator\n };\n}\n\n/**\n * Build a valid typed object from a raw object.\n * @param data Raw object.\n * @return An object representing the linked visual console properties.\n * @throws Will throw a TypeError if the status calculation properties are invalid.\n */\nexport function linkedVCPropsDecoder(\n data: UnknownObject\n): LinkedVisualConsoleProps | never {\n // Object destructuring: http://es6-features.org/#ObjectMatchingShorthandNotation\n const {\n metaconsoleId,\n linkedLayoutId: id,\n linkedLayoutAgentId: agentId\n } = data;\n\n let linkedLayoutStatusProps: LinkedVisualConsolePropsStatus = {\n linkedLayoutStatusType: \"default\"\n };\n switch (data.linkedLayoutStatusType) {\n case \"weight\": {\n const weight = parseIntOr(data.linkedLayoutStatusTypeWeight, null);\n if (weight == null)\n throw new TypeError(\"invalid status calculation properties.\");\n\n if (data.linkedLayoutStatusTypeWeight)\n linkedLayoutStatusProps = {\n linkedLayoutStatusType: \"weight\",\n linkedLayoutStatusTypeWeight: weight\n };\n break;\n }\n case \"service\": {\n const warningThreshold = parseIntOr(\n data.linkedLayoutStatusTypeWarningThreshold,\n null\n );\n const criticalThreshold = parseIntOr(\n data.linkedLayoutStatusTypeCriticalThreshold,\n null\n );\n if (warningThreshold == null || criticalThreshold == null) {\n throw new TypeError(\"invalid status calculation properties.\");\n }\n\n linkedLayoutStatusProps = {\n linkedLayoutStatusType: \"service\",\n linkedLayoutStatusTypeWarningThreshold: warningThreshold,\n linkedLayoutStatusTypeCriticalThreshold: criticalThreshold\n };\n break;\n }\n }\n\n const linkedLayoutBaseProps = {\n linkedLayoutId: parseIntOr(id, null),\n linkedLayoutAgentId: parseIntOr(agentId, null),\n ...linkedLayoutStatusProps // Object spread: http://es6-features.org/#SpreadOperator\n };\n\n return metaconsoleId != null\n ? {\n metaconsoleId,\n ...linkedLayoutBaseProps // Object spread: http://es6-features.org/#SpreadOperator\n }\n : linkedLayoutBaseProps;\n}\n\n/**\n * To get a CSS rule with the most used prefixes.\n * @param ruleName Name of the CSS rule.\n * @param ruleValue Value of the CSS rule.\n * @return An array of rules with the prefixes applied.\n */\nexport function prefixedCssRules(\n ruleName: string,\n ruleValue: string\n): string[] {\n const rule = `${ruleName}: ${ruleValue};`;\n return [\n `-webkit-${rule}`,\n `-moz-${rule}`,\n `-ms-${rule}`,\n `-o-${rule}`,\n `${rule}`\n ];\n}\n\n/**\n * Decode a base64 string.\n * @param input Data encoded using base64.\n * @return Decoded data.\n */\nexport function decodeBase64(input: string): string {\n return decodeURIComponent(escape(window.atob(input)));\n}\n","import { Position, Size, UnknownObject } from \"./types\";\nimport {\n sizePropsDecoder,\n positionPropsDecoder,\n parseIntOr,\n parseBoolean,\n notEmptyStringOr\n} from \"./lib\";\nimport TypedEvent, { Listener, Disposable } from \"./TypedEvent\";\n\n// Enum: https://www.typescriptlang.org/docs/handbook/enums.html.\nexport const enum ItemType {\n STATIC_GRAPH = 0,\n MODULE_GRAPH = 1,\n SIMPLE_VALUE = 2,\n PERCENTILE_BAR = 3,\n LABEL = 4,\n ICON = 5,\n SIMPLE_VALUE_MAX = 6,\n SIMPLE_VALUE_MIN = 7,\n SIMPLE_VALUE_AVG = 8,\n PERCENTILE_BUBBLE = 9,\n SERVICE = 10,\n GROUP_ITEM = 11,\n BOX_ITEM = 12,\n LINE_ITEM = 13,\n AUTO_SLA_GRAPH = 14,\n CIRCULAR_PROGRESS_BAR = 15,\n CIRCULAR_INTERIOR_PROGRESS_BAR = 16,\n DONUT_GRAPH = 17,\n BARS_GRAPH = 18,\n CLOCK = 19,\n COLOR_CLOUD = 20\n}\n\n// Base item properties. This interface should be extended by the item implementations.\nexport interface ItemProps extends Position, Size {\n readonly id: number;\n readonly type: ItemType;\n label: string | null;\n labelPosition: \"up\" | \"right\" | \"down\" | \"left\";\n isLinkEnabled: boolean;\n link: string | null;\n isOnTop: boolean;\n parentId: number | null;\n aclGroupId: number | null;\n}\n\n// FIXME: Fix type compatibility.\nexport interface ItemClickEvent {\n // data: Props;\n data: UnknownObject;\n nativeEvent: Event;\n}\n\n// FIXME: Fix type compatibility.\nexport interface ItemRemoveEvent {\n // data: Props;\n data: UnknownObject;\n}\n\n/**\n * Extract a valid enum value from a raw label positi9on value.\n * @param labelPosition Raw value.\n */\nconst parseLabelPosition = (\n labelPosition: any // eslint-disable-line @typescript-eslint/no-explicit-any\n): ItemProps[\"labelPosition\"] => {\n switch (labelPosition) {\n case \"up\":\n case \"right\":\n case \"down\":\n case \"left\":\n return labelPosition;\n default:\n return \"down\";\n }\n};\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the item props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function itemBasePropsDecoder(data: UnknownObject): ItemProps | never {\n if (data.id == null || isNaN(parseInt(data.id))) {\n throw new TypeError(\"invalid id.\");\n }\n if (data.type == null || isNaN(parseInt(data.type))) {\n throw new TypeError(\"invalid type.\");\n }\n\n return {\n id: parseInt(data.id),\n type: parseInt(data.type),\n label: notEmptyStringOr(data.label, null),\n labelPosition: parseLabelPosition(data.labelPosition),\n isLinkEnabled: parseBoolean(data.isLinkEnabled),\n link: notEmptyStringOr(data.link, null),\n isOnTop: parseBoolean(data.isOnTop),\n parentId: parseIntOr(data.parentId, null),\n aclGroupId: parseIntOr(data.aclGroupId, null),\n ...sizePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n ...positionPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\n/**\n * Base class of the visual console items. Should be extended to use its capabilities.\n */\nabstract class VisualConsoleItem {\n // Properties of the item.\n private itemProps: Props;\n // Reference to the DOM element which will contain the item.\n public elementRef: HTMLElement;\n public readonly labelElementRef: HTMLElement;\n // Reference to the DOM element which will contain the view of the item which extends this class.\n protected readonly childElementRef: HTMLElement;\n // Event manager for click events.\n private readonly clickEventManager = new TypedEvent>();\n // Event manager for remove events.\n private readonly removeEventManager = new TypedEvent<\n ItemRemoveEvent\n >();\n // List of references to clean the event listeners.\n private readonly disposables: Disposable[] = [];\n\n /**\n * To create a new element which will be inside the item box.\n * @return Item.\n */\n protected abstract createDomElement(): HTMLElement;\n\n public constructor(props: Props) {\n this.itemProps = props;\n\n /*\n * Get a HTMLElement which represents the container box\n * of the Visual Console item. This element will manage\n * all the common things like click events, show a border\n * when hovered, etc.\n */\n this.elementRef = this.createContainerDomElement();\n this.labelElementRef = this.createLabelDomElement();\n\n /*\n * Get a HTMLElement which represents the custom view\n * of the Visual Console item. This element will be\n * different depending on the item implementation.\n */\n this.childElementRef = this.createDomElement();\n\n // Insert the elements into the container.\n this.elementRef.append(this.childElementRef, this.labelElementRef);\n\n // Resize element.\n this.resizeElement(props.width, props.height);\n // Set label position.\n this.changeLabelPosition(props.labelPosition);\n }\n\n /**\n * To create a new box for the visual console item.\n * @return Item box.\n */\n private createContainerDomElement(): HTMLElement {\n let box;\n if (this.props.isLinkEnabled) {\n box = document.createElement(\"a\");\n box as HTMLAnchorElement;\n if (this.props.link) box.href = this.props.link;\n } else {\n box = document.createElement(\"div\");\n box as HTMLDivElement;\n }\n\n box.className = \"visual-console-item\";\n box.style.zIndex = this.props.isOnTop ? \"2\" : \"1\";\n box.style.left = `${this.props.x}px`;\n box.style.top = `${this.props.y}px`;\n box.onclick = e =>\n this.clickEventManager.emit({ data: this.props, nativeEvent: e });\n\n return box;\n }\n\n /**\n * To create a new label for the visual console item.\n * @return Item label.\n */\n protected createLabelDomElement(): HTMLElement {\n const element = document.createElement(\"div\");\n element.className = \"visual-console-item-label\";\n // Add the label if it exists.\n if (this.props.label && this.props.label.length) {\n element.innerHTML = this.props.label;\n }\n\n return element;\n }\n\n /**\n * To update the content element.\n * @return Item.\n */\n protected updateDomElement(element: HTMLElement): void {\n element.innerHTML = this.createDomElement().innerHTML;\n }\n\n /**\n * Public accessor of the `props` property.\n * @return Properties.\n */\n public get props(): Props {\n return { ...this.itemProps }; // Return a copy.\n }\n\n /**\n * Public setter of the `props` property.\n * If the new props are different enough than the\n * stored props, a render would be fired.\n * @param newProps\n */\n public set props(newProps: Props) {\n const prevProps = this.props;\n // Update the internal props.\n this.itemProps = newProps;\n\n // From this point, things which rely on this.props can access to the changes.\n\n // Check if we should re-render.\n if (this.shouldBeUpdated(prevProps, newProps)) this.render(prevProps);\n }\n\n /**\n * To compare the previous and the new props and returns a boolean value\n * in case the difference is meaningfull enough to perform DOM changes.\n *\n * Here, the only comparision is done by reference.\n *\n * Override this function to perform a different comparision depending on the item needs.\n *\n * @param prevProps\n * @param newProps\n * @return Whether the difference is meaningful enough to perform DOM changes or not.\n */\n protected shouldBeUpdated(prevProps: Props, newProps: Props): boolean {\n return prevProps !== newProps;\n }\n\n /**\n * To recreate or update the HTMLElement which represents the item into the DOM.\n * @param prevProps If exists it will be used to only perform DOM updates instead of a full replace.\n */\n public render(prevProps: Props | null = null): void {\n this.updateDomElement(this.childElementRef);\n\n // Move box.\n if (!prevProps || this.positionChanged(prevProps, this.props)) {\n this.moveElement(this.props.x, this.props.y);\n }\n // Resize box.\n if (!prevProps || this.sizeChanged(prevProps, this.props)) {\n this.resizeElement(this.props.width, this.props.height);\n }\n // Change label.\n if (!prevProps || prevProps.label !== this.props.label) {\n this.labelElementRef.innerHTML = this.createLabelDomElement().innerHTML;\n }\n // Change link.\n if (\n prevProps &&\n (prevProps.isLinkEnabled !== this.props.isLinkEnabled ||\n (this.props.isLinkEnabled && prevProps.link !== this.props.link))\n ) {\n const container = this.createContainerDomElement();\n container.innerHTML = this.elementRef.innerHTML;\n\n if (this.elementRef.parentNode !== null) {\n this.elementRef.parentNode.replaceChild(container, this.elementRef);\n }\n\n // Changed the reference to the main element. It's ugly, but needed.\n this.elementRef = container;\n }\n // Change label position.\n if (!prevProps || prevProps.labelPosition !== this.props.labelPosition) {\n this.changeLabelPosition(this.props.labelPosition);\n }\n }\n\n /**\n * To remove the event listeners and the elements from the DOM.\n */\n public remove(): void {\n // Call the remove event.\n this.removeEventManager.emit({ data: this.props });\n // Event listeners.\n this.disposables.forEach(disposable => {\n try {\n disposable.dispose();\n } catch (ignored) {} // eslint-disable-line no-empty\n });\n // VisualConsoleItem DOM element.\n this.elementRef.remove();\n }\n\n /**\n * Compare the previous and the new position and return\n * a boolean value in case the position changed.\n * @param prevPosition\n * @param newPosition\n * @return Whether the position changed or not.\n */\n protected positionChanged(\n prevPosition: Position,\n newPosition: Position\n ): boolean {\n return prevPosition.x !== newPosition.x || prevPosition.y !== newPosition.y;\n }\n\n /**\n * Move the label around the item content.\n * @param position Label position.\n */\n protected changeLabelPosition(position: Props[\"labelPosition\"]): void {\n switch (position) {\n case \"up\":\n this.elementRef.style.flexDirection = \"column-reverse\";\n break;\n case \"left\":\n this.elementRef.style.flexDirection = \"row-reverse\";\n break;\n case \"right\":\n this.elementRef.style.flexDirection = \"row\";\n break;\n case \"down\":\n default:\n this.elementRef.style.flexDirection = \"column\";\n break;\n }\n }\n\n /**\n * Move the DOM container.\n * @param x Horizontal axis position.\n * @param y Vertical axis position.\n */\n protected moveElement(x: number, y: number): void {\n this.elementRef.style.left = `${x}px`;\n this.elementRef.style.top = `${y}px`;\n }\n\n /**\n * Update the position into the properties and move the DOM container.\n * @param x Horizontal axis position.\n * @param y Vertical axis position.\n */\n public move(x: number, y: number): void {\n this.moveElement(x, y);\n this.itemProps = {\n ...this.props, // Object spread: http://es6-features.org/#SpreadOperator\n x,\n y\n };\n }\n\n /**\n * Compare the previous and the new size and return\n * a boolean value in case the size changed.\n * @param prevSize\n * @param newSize\n * @return Whether the size changed or not.\n */\n protected sizeChanged(prevSize: Size, newSize: Size): boolean {\n return (\n prevSize.width !== newSize.width || prevSize.height !== newSize.height\n );\n }\n\n /**\n * Resize the DOM content container.\n * @param width\n * @param height\n */\n protected resizeElement(width: number, height: number): void {\n // The most valuable size is the content size.\n this.childElementRef.style.width = width > 0 ? `${width}px` : null;\n this.childElementRef.style.height = height > 0 ? `${height}px` : null;\n }\n\n /**\n * Update the size into the properties and resize the DOM container.\n * @param width\n * @param height\n */\n public resize(width: number, height: number): void {\n this.resizeElement(width, height);\n this.itemProps = {\n ...this.props, // Object spread: http://es6-features.org/#SpreadOperator\n width,\n height\n };\n }\n\n /**\n * To add an event handler to the click of the linked visual console elements.\n * @param listener Function which is going to be executed when a linked console is clicked.\n */\n public onClick(listener: Listener>): Disposable {\n /*\n * The '.on' function returns a function which will clean the event\n * listener when executed. We store all the 'dispose' functions to\n * call them when the item should be cleared.\n */\n const disposable = this.clickEventManager.on(listener);\n this.disposables.push(disposable);\n\n return disposable;\n }\n\n /**\n * To add an event handler to the removal of the item.\n * @param listener Function which is going to be executed when a item is removed.\n */\n public onRemove(listener: Listener>): Disposable {\n /*\n * The '.on' function returns a function which will clean the event\n * listener when executed. We store all the 'dispose' functions to\n * call them when the item should be cleared.\n */\n const disposable = this.removeEventManager.on(listener);\n this.disposables.push(disposable);\n\n return disposable;\n }\n}\n\nexport default VisualConsoleItem;\n","export interface Listener {\n (event: T): void;\n}\n\nexport interface Disposable {\n dispose: () => void;\n}\n\n/** passes through events as they happen. You will not get events from before you start listening */\nexport default class TypedEvent {\n private listeners: Listener[] = [];\n private listenersOncer: Listener[] = [];\n\n public on = (listener: Listener): Disposable => {\n this.listeners.push(listener);\n return {\n dispose: () => this.off(listener)\n };\n };\n\n public once = (listener: Listener): void => {\n this.listenersOncer.push(listener);\n };\n\n public off = (listener: Listener): void => {\n const callbackIndex = this.listeners.indexOf(listener);\n if (callbackIndex > -1) this.listeners.splice(callbackIndex, 1);\n };\n\n public emit = (event: T): void => {\n /** Update any general listeners */\n this.listeners.forEach(listener => listener(event));\n\n /** Clear the `once` queue */\n this.listenersOncer.forEach(listener => listener(event));\n this.listenersOncer = [];\n };\n\n public pipe = (te: TypedEvent): Disposable => this.on(e => te.emit(e));\n}\n","import { UnknownObject, WithModuleProps } from \"../types\";\nimport {\n modulePropsDecoder,\n parseIntOr,\n decodeBase64,\n stringIsEmpty\n} from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\nexport type EventsHistoryProps = {\n type: ItemType.AUTO_SLA_GRAPH;\n maxTime: number | null;\n html: string;\n} & ItemProps &\n WithModuleProps;\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the events history props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function eventsHistoryPropsDecoder(\n data: UnknownObject\n): EventsHistoryProps | never {\n if (stringIsEmpty(data.html) && stringIsEmpty(data.encodedHtml)) {\n throw new TypeError(\"missing html content.\");\n }\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.AUTO_SLA_GRAPH,\n maxTime: parseIntOr(data.maxTime, null),\n html: !stringIsEmpty(data.html)\n ? data.html\n : decodeBase64(data.encodedHtml),\n ...modulePropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nexport default class EventsHistory extends Item {\n protected createDomElement(): HTMLElement {\n const element = document.createElement(\"div\");\n element.className = \"events-history\";\n element.innerHTML = this.props.html;\n\n // Hack to execute the JS after the HTML is added to the DOM.\n const scripts = element.getElementsByTagName(\"script\");\n for (let i = 0; i < scripts.length; i++) {\n if (scripts[i].src.length === 0) {\n setTimeout(() => {\n try {\n eval(scripts[i].innerHTML.trim());\n } catch (ignored) {} // eslint-disable-line no-empty\n }, 0);\n }\n }\n\n return element;\n }\n\n protected updateDomElement(element: HTMLElement): void {\n element.innerHTML = this.props.html;\n\n // Hack to execute the JS after the HTML is added to the DOM.\n const aux = document.createElement(\"div\");\n aux.innerHTML = this.props.html;\n const scripts = aux.getElementsByTagName(\"script\");\n for (let i = 0; i < scripts.length; i++) {\n if (scripts[i].src.length === 0) {\n eval(scripts[i].innerHTML.trim());\n }\n }\n }\n}\n","import {\n LinkedVisualConsoleProps,\n UnknownObject,\n WithModuleProps\n} from \"../types\";\nimport {\n linkedVCPropsDecoder,\n modulePropsDecoder,\n decodeBase64,\n stringIsEmpty\n} from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\nexport type DonutGraphProps = {\n type: ItemType.DONUT_GRAPH;\n html: string;\n} & ItemProps &\n WithModuleProps &\n LinkedVisualConsoleProps;\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the donut graph props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function donutGraphPropsDecoder(\n data: UnknownObject\n): DonutGraphProps | never {\n if (stringIsEmpty(data.html) && stringIsEmpty(data.encodedHtml)) {\n throw new TypeError(\"missing html content.\");\n }\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.DONUT_GRAPH,\n html: !stringIsEmpty(data.html)\n ? data.html\n : decodeBase64(data.encodedHtml),\n ...modulePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n ...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nexport default class DonutGraph extends Item {\n /**\n * @override Item.resizeElement\n * Resize the DOM content container.\n * @param width\n * @param height\n */\n protected resizeElement(width: number, height: number): void {\n if (width <= 0) width = 200;\n if (height <= 0) height = 200;\n super.resizeElement(width, height);\n }\n\n protected createDomElement(): HTMLElement {\n const element = document.createElement(\"div\");\n element.className = \"donut-graph\";\n element.innerHTML = this.props.html;\n\n // Hack to execute the JS after the HTML is added to the DOM.\n const scripts = element.getElementsByTagName(\"script\");\n for (let i = 0; i < scripts.length; i++) {\n setTimeout(() => {\n if (scripts[i].src.length === 0) eval(scripts[i].innerHTML.trim());\n }, 0);\n }\n\n return element;\n }\n\n protected updateDomElement(element: HTMLElement): void {\n element.innerHTML = this.props.html;\n\n // Hack to execute the JS after the HTML is added to the DOM.\n const aux = document.createElement(\"div\");\n aux.innerHTML = this.props.html;\n const scripts = aux.getElementsByTagName(\"script\");\n for (let i = 0; i < scripts.length; i++) {\n if (scripts[i].src.length === 0) {\n eval(scripts[i].innerHTML.trim());\n }\n }\n }\n}\n","import {\n LinkedVisualConsoleProps,\n UnknownObject,\n WithModuleProps\n} from \"../types\";\nimport {\n linkedVCPropsDecoder,\n modulePropsDecoder,\n decodeBase64,\n stringIsEmpty\n} from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\nexport type ModuleGraphProps = {\n type: ItemType.MODULE_GRAPH;\n html: string;\n} & ItemProps &\n WithModuleProps &\n LinkedVisualConsoleProps;\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the module graph props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function moduleGraphPropsDecoder(\n data: UnknownObject\n): ModuleGraphProps | never {\n if (stringIsEmpty(data.html) && stringIsEmpty(data.encodedHtml)) {\n throw new TypeError(\"missing html content.\");\n }\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.MODULE_GRAPH,\n html: !stringIsEmpty(data.html)\n ? data.html\n : decodeBase64(data.encodedHtml),\n ...modulePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n ...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nexport default class ModuleGraph extends Item {\n protected createDomElement(): HTMLElement {\n const element = document.createElement(\"div\");\n element.className = \"module-graph\";\n element.innerHTML = this.props.html;\n\n // Remove the overview graph.\n const legendP = element.getElementsByTagName(\"p\");\n for (let i = 0; i < legendP.length; i++) {\n legendP[i].style.margin = \"0px\";\n }\n\n // Remove the overview graph.\n const overviewGraphs = element.getElementsByClassName(\"overview_graph\");\n for (let i = 0; i < overviewGraphs.length; i++) {\n overviewGraphs[i].remove();\n }\n\n // Hack to execute the JS after the HTML is added to the DOM.\n const scripts = element.getElementsByTagName(\"script\");\n for (let i = 0; i < scripts.length; i++) {\n if (scripts[i].src.length === 0) {\n setTimeout(() => {\n try {\n eval(scripts[i].innerHTML.trim());\n } catch (ignored) {} // eslint-disable-line no-empty\n }, 0);\n }\n }\n\n return element;\n }\n\n protected updateDomElement(element: HTMLElement): void {\n element.innerHTML = this.props.html;\n\n // Remove the overview graph.\n const legendP = element.getElementsByTagName(\"p\");\n for (let i = 0; i < legendP.length; i++) {\n legendP[i].style.margin = \"0px\";\n }\n\n // Remove the overview graph.\n const overviewGraphs = element.getElementsByClassName(\"overview_graph\");\n for (let i = 0; i < overviewGraphs.length; i++) {\n overviewGraphs[i].remove();\n }\n\n // Hack to execute the JS after the HTML is added to the DOM.\n const aux = document.createElement(\"div\");\n aux.innerHTML = this.props.html;\n const scripts = aux.getElementsByTagName(\"script\");\n for (let i = 0; i < scripts.length; i++) {\n if (scripts[i].src.length === 0) {\n eval(scripts[i].innerHTML.trim());\n }\n }\n }\n}\n","import { UnknownObject, WithModuleProps } from \"../types\";\nimport { modulePropsDecoder, decodeBase64, stringIsEmpty } from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\nexport type BarsGraphProps = {\n type: ItemType.BARS_GRAPH;\n html: string;\n} & ItemProps &\n WithModuleProps;\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the bars graph props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function barsGraphPropsDecoder(\n data: UnknownObject\n): BarsGraphProps | never {\n if (stringIsEmpty(data.html) && stringIsEmpty(data.encodedHtml)) {\n throw new TypeError(\"missing html content.\");\n }\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.BARS_GRAPH,\n html: !stringIsEmpty(data.html)\n ? data.html\n : decodeBase64(data.encodedHtml),\n ...modulePropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nexport default class BarsGraph extends Item {\n protected createDomElement(): HTMLElement {\n const element = document.createElement(\"div\");\n element.className = \"bars-graph\";\n element.innerHTML = this.props.html;\n\n // Hack to execute the JS after the HTML is added to the DOM.\n const scripts = element.getElementsByTagName(\"script\");\n for (let i = 0; i < scripts.length; i++) {\n setTimeout(() => {\n if (scripts[i].src.length === 0) eval(scripts[i].innerHTML.trim());\n }, 0);\n }\n\n return element;\n }\n\n protected updateDomElement(element: HTMLElement): void {\n element.innerHTML = this.props.html;\n\n // Hack to execute the JS after the HTML is added to the DOM.\n const aux = document.createElement(\"div\");\n aux.innerHTML = this.props.html;\n const scripts = aux.getElementsByTagName(\"script\");\n for (let i = 0; i < scripts.length; i++) {\n if (scripts[i].src.length === 0) {\n eval(scripts[i].innerHTML.trim());\n }\n }\n }\n}\n","import {\n WithModuleProps,\n LinkedVisualConsoleProps,\n UnknownObject\n} from \"../types\";\n\nimport {\n modulePropsDecoder,\n linkedVCPropsDecoder,\n notEmptyStringOr\n} from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\nexport type StaticGraphProps = {\n type: ItemType.STATIC_GRAPH;\n imageSrc: string; // URL?\n showLastValueTooltip: \"default\" | \"enabled\" | \"disabled\";\n statusImageSrc: string | null; // URL?\n lastValue: string | null;\n} & ItemProps &\n (WithModuleProps | LinkedVisualConsoleProps);\n\n/**\n * Extract a valid enum value from a raw unknown value.\n * @param showLastValueTooltip Raw value.\n */\nconst parseShowLastValueTooltip = (\n showLastValueTooltip: any // eslint-disable-line @typescript-eslint/no-explicit-any\n): StaticGraphProps[\"showLastValueTooltip\"] => {\n switch (showLastValueTooltip) {\n case \"default\":\n case \"enabled\":\n case \"disabled\":\n return showLastValueTooltip;\n default:\n return \"default\";\n }\n};\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the static graph props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function staticGraphPropsDecoder(\n data: UnknownObject\n): StaticGraphProps | never {\n if (typeof data.imageSrc !== \"string\" || data.imageSrc.length === 0) {\n throw new TypeError(\"invalid image src.\");\n }\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.STATIC_GRAPH,\n imageSrc: data.imageSrc,\n showLastValueTooltip: parseShowLastValueTooltip(data.showLastValueTooltip),\n statusImageSrc: notEmptyStringOr(data.statusImageSrc, null),\n lastValue: notEmptyStringOr(data.lastValue, null),\n ...modulePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n ...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nexport default class StaticGraph extends Item {\n protected createDomElement(): HTMLElement {\n const img: HTMLImageElement = document.createElement(\"img\");\n img.className = \"static-graph\";\n img.src = this.props.statusImageSrc || this.props.imageSrc;\n\n // Show last value in a tooltip.\n if (\n this.props.lastValue !== null &&\n this.props.showLastValueTooltip !== \"disabled\"\n ) {\n img.className = \"static-graph image forced_title\";\n img.setAttribute(\"data-use_title_for_force_title\", \"1\");\n img.setAttribute(\"data-title\", this.props.lastValue);\n img.alt = this.props.lastValue;\n }\n\n return img;\n }\n}\n","import { LinkedVisualConsoleProps, UnknownObject } from \"../types\";\nimport { linkedVCPropsDecoder } from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\nexport type IconProps = {\n type: ItemType.ICON;\n imageSrc: string; // URL?\n} & ItemProps &\n LinkedVisualConsoleProps;\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the icon props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function iconPropsDecoder(data: UnknownObject): IconProps | never {\n if (typeof data.imageSrc !== \"string\" || data.imageSrc.length === 0) {\n throw new TypeError(\"invalid image src.\");\n }\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.ICON,\n imageSrc: data.imageSrc,\n ...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nexport default class Icon extends Item {\n protected createDomElement(): HTMLElement {\n const img: HTMLImageElement = document.createElement(\"img\");\n img.className = \"icon\";\n img.src = this.props.imageSrc;\n\n return img;\n }\n}\n","import {\n WithModuleProps,\n LinkedVisualConsoleProps,\n UnknownObject\n} from \"../types\";\nimport { modulePropsDecoder, linkedVCPropsDecoder } from \"../lib\";\nimport Item, { itemBasePropsDecoder, ItemType, ItemProps } from \"../Item\";\n\nexport type ColorCloudProps = {\n type: ItemType.COLOR_CLOUD;\n color: string;\n // TODO: Add the rest of the color cloud values?\n} & ItemProps &\n WithModuleProps &\n LinkedVisualConsoleProps;\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the static graph props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function colorCloudPropsDecoder(\n data: UnknownObject\n): ColorCloudProps | never {\n // TODO: Validate the color.\n if (typeof data.color !== \"string\" || data.color.length === 0) {\n throw new TypeError(\"invalid color.\");\n }\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.COLOR_CLOUD,\n color: data.color,\n ...modulePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n ...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nconst svgNS = \"http://www.w3.org/2000/svg\";\n\nexport default class ColorCloud extends Item {\n protected createDomElement(): HTMLElement {\n const container: HTMLDivElement = document.createElement(\"div\");\n container.className = \"color-cloud\";\n\n // Add the SVG.\n container.append(this.createSvgElement());\n\n return container;\n }\n\n public createSvgElement(): SVGSVGElement {\n const gradientId = `grad_${this.props.id}`;\n // SVG container.\n const svg = document.createElementNS(svgNS, \"svg\");\n // Auto resize SVG using the view box magic: https://css-tricks.com/scale-svg/\n svg.setAttribute(\"viewBox\", \"0 0 100 100\");\n\n // Defs.\n const defs = document.createElementNS(svgNS, \"defs\");\n // Radial gradient.\n const radialGradient = document.createElementNS(svgNS, \"radialGradient\");\n radialGradient.setAttribute(\"id\", gradientId);\n radialGradient.setAttribute(\"cx\", \"50%\");\n radialGradient.setAttribute(\"cy\", \"50%\");\n radialGradient.setAttribute(\"r\", \"50%\");\n radialGradient.setAttribute(\"fx\", \"50%\");\n radialGradient.setAttribute(\"fy\", \"50%\");\n // Stops.\n const stop0 = document.createElementNS(svgNS, \"stop\");\n stop0.setAttribute(\"offset\", \"0%\");\n stop0.setAttribute(\n \"style\",\n `stop-color:${this.props.color};stop-opacity:0.9`\n );\n const stop100 = document.createElementNS(svgNS, \"stop\");\n stop100.setAttribute(\"offset\", \"100%\");\n stop100.setAttribute(\n \"style\",\n `stop-color:${this.props.color};stop-opacity:0`\n );\n // Circle.\n const circle = document.createElementNS(svgNS, \"circle\");\n circle.setAttribute(\"fill\", `url(#${gradientId})`);\n circle.setAttribute(\"cx\", \"50%\");\n circle.setAttribute(\"cy\", \"50%\");\n circle.setAttribute(\"r\", \"50%\");\n\n // Append elements.\n radialGradient.append(stop0, stop100);\n defs.append(radialGradient);\n svg.append(defs, circle);\n\n return svg;\n }\n}\n","import { LinkedVisualConsoleProps, UnknownObject } from \"../types\";\nimport { linkedVCPropsDecoder, parseIntOr, notEmptyStringOr } from \"../lib\";\nimport Item, { ItemProps, itemBasePropsDecoder, ItemType } from \"../Item\";\n\nexport type GroupProps = {\n type: ItemType.GROUP_ITEM;\n imageSrc: string; // URL?\n groupId: number;\n statusImageSrc: string | null;\n} & ItemProps &\n LinkedVisualConsoleProps;\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the group props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function groupPropsDecoder(data: UnknownObject): GroupProps | never {\n if (typeof data.imageSrc !== \"string\" || data.imageSrc.length === 0) {\n throw new TypeError(\"invalid image src.\");\n }\n if (parseIntOr(data.groupId, null) === null) {\n throw new TypeError(\"invalid group Id.\");\n }\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.GROUP_ITEM,\n imageSrc: data.imageSrc,\n groupId: parseInt(data.groupId),\n statusImageSrc: notEmptyStringOr(data.statusImageSrc, null),\n ...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nexport default class Group extends Item {\n protected createDomElement(): HTMLElement {\n const img: HTMLImageElement = document.createElement(\"img\");\n img.className = \"group\";\n if (this.props.statusImageSrc != null) {\n img.src = this.props.statusImageSrc;\n }\n\n return img;\n }\n}\n","import \"./styles.css\";\n\nimport { LinkedVisualConsoleProps, UnknownObject, Size } from \"../../types\";\nimport {\n linkedVCPropsDecoder,\n parseIntOr,\n padLeft,\n parseBoolean,\n prefixedCssRules,\n notEmptyStringOr\n} from \"../../lib\";\nimport Item, { ItemProps, itemBasePropsDecoder, ItemType } from \"../../Item\";\n\nexport type ClockProps = {\n type: ItemType.CLOCK;\n clockType: \"analogic\" | \"digital\";\n clockFormat: \"datetime\" | \"time\";\n clockTimezone: string;\n clockTimezoneOffset: number; // Offset of the timezone to UTC in seconds.\n showClockTimezone: boolean;\n color?: string | null;\n} & ItemProps &\n LinkedVisualConsoleProps;\n\n/**\n * Extract a valid enum value from a raw unknown value.\n * @param clockType Raw value.\n */\nconst parseClockType = (\n clockType: any // eslint-disable-line @typescript-eslint/no-explicit-any\n): ClockProps[\"clockType\"] => {\n switch (clockType) {\n case \"analogic\":\n case \"digital\":\n return clockType;\n default:\n return \"analogic\";\n }\n};\n\n/**\n * Extract a valid enum value from a raw unknown value.\n * @param clockFormat Raw value.\n */\nconst parseClockFormat = (\n clockFormat: any // eslint-disable-line @typescript-eslint/no-explicit-any\n): ClockProps[\"clockFormat\"] => {\n switch (clockFormat) {\n case \"datetime\":\n case \"date\":\n case \"time\":\n return clockFormat;\n default:\n return \"datetime\";\n }\n};\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the clock props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function clockPropsDecoder(data: UnknownObject): ClockProps | never {\n if (\n typeof data.clockTimezone !== \"string\" ||\n data.clockTimezone.length === 0\n ) {\n throw new TypeError(\"invalid timezone.\");\n }\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.CLOCK,\n clockType: parseClockType(data.clockType),\n clockFormat: parseClockFormat(data.clockFormat),\n clockTimezone: data.clockTimezone,\n clockTimezoneOffset: parseIntOr(data.clockTimezoneOffset, 0),\n showClockTimezone: parseBoolean(data.showClockTimezone),\n color: notEmptyStringOr(data.color, null),\n ...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nexport default class Clock extends Item {\n public static readonly TICK_INTERVAL = 1000; // In ms.\n private intervalRef: number | null = null;\n\n public constructor(props: ClockProps) {\n // Call the superclass constructor.\n super(props);\n\n /* The item is already loaded and inserted into the DOM.\n * The class properties are now initialized.\n * Now you can modify the item, add event handlers, timers, etc.\n */\n\n /* The use of the arrow function is important here. startTick will\n * use the function passed as an argument to call the global setInterval\n * function. The interval, timeout or event functions, among other, are\n * called into another execution loop and using a different context.\n * The arrow functions, unlike the classic functions, doesn't create\n * their own context (this), so their context at execution time will be\n * use the current context at the declaration time.\n * http://es6-features.org/#Lexicalthis\n */\n this.startTick(\n () => {\n // Replace the old element with the updated date.\n this.childElementRef.innerHTML = this.createClock().innerHTML;\n },\n /* The analogic clock doesn't need to tick,\n * but it will be refreshed every 20 seconds\n * to avoid a desync caused by page freezes.\n */\n this.props.clockType === \"analogic\" ? 20000 : Clock.TICK_INTERVAL\n );\n }\n\n /**\n * Wrap a window.clearInterval call.\n */\n private stopTick(): void {\n if (this.intervalRef !== null) {\n window.clearInterval(this.intervalRef);\n this.intervalRef = null;\n }\n }\n\n /**\n * Wrap a window.setInterval call.\n * @param handler Function to be called every time the interval\n * timer is reached.\n * @param interval Number in milliseconds for the interval timer.\n */\n private startTick(\n handler: TimerHandler,\n interval: number = Clock.TICK_INTERVAL\n ): void {\n this.stopTick();\n this.intervalRef = window.setInterval(handler, interval);\n }\n\n /**\n * Create a element which contains the DOM representation of the item.\n * @return DOM Element.\n * @override\n */\n protected createDomElement(): HTMLElement | never {\n return this.createClock();\n }\n\n /**\n * To remove the event listeners and the elements from the DOM.\n * @override\n */\n public remove(): void {\n // Clear the interval.\n this.stopTick();\n // Call to the parent clean function.\n super.remove();\n }\n\n /**\n * @override Item.resizeElement\n * Resize the DOM content container.\n * @param width\n * @param height\n */\n protected resizeElement(width: number, height: number): void {\n const { width: newWidth, height: newHeight } = this.getElementSize(\n width,\n height\n ); // Destructuring assigment: http://es6-features.org/#ObjectMatchingShorthandNotation\n super.resizeElement(newWidth, newHeight);\n // Re-render the item to force it calculate a new font size.\n if (this.props.clockType === \"digital\") {\n // Replace the old element with the updated date.\n this.childElementRef.innerHTML = this.createClock().innerHTML;\n }\n }\n\n /**\n * Create a element which contains a representation of a clock.\n * It choose between the clock types.\n * @return DOM Element.\n * @throws Error.\n */\n private createClock(): HTMLElement | never {\n switch (this.props.clockType) {\n case \"analogic\":\n return this.createAnalogicClock();\n case \"digital\":\n return this.createDigitalClock();\n default:\n throw new Error(\"invalid clock type.\");\n }\n }\n\n /**\n * Create a element which contains a representation of an analogic clock.\n * @return DOM Element.\n */\n private createAnalogicClock(): HTMLElement {\n const svgNS = \"http://www.w3.org/2000/svg\";\n const colors = {\n watchFace: \"#FFFFF0\",\n watchFaceBorder: \"#242124\",\n mark: \"#242124\",\n handDark: \"#242124\",\n handLight: \"#525252\",\n secondHand: \"#DC143C\"\n };\n\n const { width, height } = this.getElementSize(); // Destructuring assigment: http://es6-features.org/#ObjectMatchingShorthandNotation\n\n const div = document.createElement(\"div\");\n div.className = \"analogic-clock\";\n div.style.width = `${width}px`;\n div.style.height = `${height}px`;\n\n // SVG container.\n const svg = document.createElementNS(svgNS, \"svg\");\n // Auto resize SVG using the view box magic: https://css-tricks.com/scale-svg/\n svg.setAttribute(\"viewBox\", \"0 0 100 100\");\n\n // Clock face.\n const clockFace = document.createElementNS(svgNS, \"g\");\n clockFace.setAttribute(\"class\", \"clockface\");\n const clockFaceBackground = document.createElementNS(svgNS, \"circle\");\n clockFaceBackground.setAttribute(\"cx\", \"50\");\n clockFaceBackground.setAttribute(\"cy\", \"50\");\n clockFaceBackground.setAttribute(\"r\", \"48\");\n clockFaceBackground.setAttribute(\"fill\", colors.watchFace);\n clockFaceBackground.setAttribute(\"stroke\", colors.watchFaceBorder);\n clockFaceBackground.setAttribute(\"stroke-width\", \"2\");\n clockFaceBackground.setAttribute(\"stroke-linecap\", \"round\");\n // Insert the clockface background into the clockface group.\n clockFace.append(clockFaceBackground);\n\n // Timezone complication.\n const city = this.getHumanTimezone();\n if (city.length > 0) {\n const timezoneComplication = document.createElementNS(svgNS, \"text\");\n timezoneComplication.setAttribute(\"text-anchor\", \"middle\");\n timezoneComplication.setAttribute(\"font-size\", \"8\");\n timezoneComplication.setAttribute(\n \"transform\",\n \"translate(30 50) rotate(90)\" // Rotate to counter the clock rotation.\n );\n timezoneComplication.setAttribute(\"fill\", colors.mark);\n timezoneComplication.textContent = city;\n clockFace.append(timezoneComplication);\n }\n\n // Marks group.\n const marksGroup = document.createElementNS(svgNS, \"g\");\n marksGroup.setAttribute(\"class\", \"marks\");\n // Build the 12 hours mark.\n const mainMarkGroup = document.createElementNS(svgNS, \"g\");\n mainMarkGroup.setAttribute(\"class\", \"mark\");\n mainMarkGroup.setAttribute(\"transform\", \"translate(50 50)\");\n const mark1a = document.createElementNS(svgNS, \"line\");\n mark1a.setAttribute(\"x1\", \"36\");\n mark1a.setAttribute(\"y1\", \"0\");\n mark1a.setAttribute(\"x2\", \"46\");\n mark1a.setAttribute(\"y2\", \"0\");\n mark1a.setAttribute(\"stroke\", colors.mark);\n mark1a.setAttribute(\"stroke-width\", \"5\");\n const mark1b = document.createElementNS(svgNS, \"line\");\n mark1b.setAttribute(\"x1\", \"36\");\n mark1b.setAttribute(\"y1\", \"0\");\n mark1b.setAttribute(\"x2\", \"46\");\n mark1b.setAttribute(\"y2\", \"0\");\n mark1b.setAttribute(\"stroke\", colors.watchFace);\n mark1b.setAttribute(\"stroke-width\", \"1\");\n // Insert the 12 mark lines into their group.\n mainMarkGroup.append(mark1a, mark1b);\n // Insert the main mark into the marks group.\n marksGroup.append(mainMarkGroup);\n // Build the rest of the marks.\n for (let i = 1; i < 60; i++) {\n const mark = document.createElementNS(svgNS, \"line\");\n mark.setAttribute(\"y1\", \"0\");\n mark.setAttribute(\"y2\", \"0\");\n mark.setAttribute(\"stroke\", colors.mark);\n mark.setAttribute(\"transform\", `translate(50 50) rotate(${i * 6})`);\n\n if (i % 5 === 0) {\n mark.setAttribute(\"x1\", \"38\");\n mark.setAttribute(\"x2\", \"46\");\n mark.setAttribute(\"stroke-width\", i % 15 === 0 ? \"2\" : \"1\");\n } else {\n mark.setAttribute(\"x1\", \"42\");\n mark.setAttribute(\"x2\", \"46\");\n mark.setAttribute(\"stroke-width\", \"0.5\");\n }\n\n // Insert the mark into the marks group.\n marksGroup.append(mark);\n }\n\n /* Clock hands */\n\n // Hour hand.\n const hourHand = document.createElementNS(svgNS, \"g\");\n hourHand.setAttribute(\"class\", \"hour-hand\");\n hourHand.setAttribute(\"transform\", \"translate(50 50)\");\n // This will go back and will act like a border.\n const hourHandA = document.createElementNS(svgNS, \"line\");\n hourHandA.setAttribute(\"class\", \"hour-hand-a\");\n hourHandA.setAttribute(\"x1\", \"0\");\n hourHandA.setAttribute(\"y1\", \"0\");\n hourHandA.setAttribute(\"x2\", \"30\");\n hourHandA.setAttribute(\"y2\", \"0\");\n hourHandA.setAttribute(\"stroke\", colors.handLight);\n hourHandA.setAttribute(\"stroke-width\", \"4\");\n hourHandA.setAttribute(\"stroke-linecap\", \"round\");\n // This will go in front of the previous line.\n const hourHandB = document.createElementNS(svgNS, \"line\");\n hourHandB.setAttribute(\"class\", \"hour-hand-b\");\n hourHandB.setAttribute(\"x1\", \"0\");\n hourHandB.setAttribute(\"y1\", \"0\");\n hourHandB.setAttribute(\"x2\", \"29.9\");\n hourHandB.setAttribute(\"y2\", \"0\");\n hourHandB.setAttribute(\"stroke\", colors.handDark);\n hourHandB.setAttribute(\"stroke-width\", \"3.1\");\n hourHandB.setAttribute(\"stroke-linecap\", \"round\");\n // Append the elements to finish the hour hand.\n hourHand.append(hourHandA, hourHandB);\n\n // Minute hand.\n const minuteHand = document.createElementNS(svgNS, \"g\");\n minuteHand.setAttribute(\"class\", \"minute-hand\");\n minuteHand.setAttribute(\"transform\", \"translate(50 50)\");\n // This will go back and will act like a border.\n const minuteHandA = document.createElementNS(svgNS, \"line\");\n minuteHandA.setAttribute(\"class\", \"minute-hand-a\");\n minuteHandA.setAttribute(\"x1\", \"0\");\n minuteHandA.setAttribute(\"y1\", \"0\");\n minuteHandA.setAttribute(\"x2\", \"40\");\n minuteHandA.setAttribute(\"y2\", \"0\");\n minuteHandA.setAttribute(\"stroke\", colors.handLight);\n minuteHandA.setAttribute(\"stroke-width\", \"2\");\n minuteHandA.setAttribute(\"stroke-linecap\", \"round\");\n // This will go in front of the previous line.\n const minuteHandB = document.createElementNS(svgNS, \"line\");\n minuteHandB.setAttribute(\"class\", \"minute-hand-b\");\n minuteHandB.setAttribute(\"x1\", \"0\");\n minuteHandB.setAttribute(\"y1\", \"0\");\n minuteHandB.setAttribute(\"x2\", \"39.9\");\n minuteHandB.setAttribute(\"y2\", \"0\");\n minuteHandB.setAttribute(\"stroke\", colors.handDark);\n minuteHandB.setAttribute(\"stroke-width\", \"1.5\");\n minuteHandB.setAttribute(\"stroke-linecap\", \"round\");\n const minuteHandPin = document.createElementNS(svgNS, \"circle\");\n minuteHandPin.setAttribute(\"r\", \"3\");\n minuteHandPin.setAttribute(\"fill\", colors.handDark);\n // Append the elements to finish the minute hand.\n minuteHand.append(minuteHandA, minuteHandB, minuteHandPin);\n\n // Second hand.\n const secondHand = document.createElementNS(svgNS, \"g\");\n secondHand.setAttribute(\"class\", \"second-hand\");\n secondHand.setAttribute(\"transform\", \"translate(50 50)\");\n const secondHandBar = document.createElementNS(svgNS, \"line\");\n secondHandBar.setAttribute(\"x1\", \"0\");\n secondHandBar.setAttribute(\"y1\", \"0\");\n secondHandBar.setAttribute(\"x2\", \"46\");\n secondHandBar.setAttribute(\"y2\", \"0\");\n secondHandBar.setAttribute(\"stroke\", colors.secondHand);\n secondHandBar.setAttribute(\"stroke-width\", \"1\");\n secondHandBar.setAttribute(\"stroke-linecap\", \"round\");\n const secondHandPin = document.createElementNS(svgNS, \"circle\");\n secondHandPin.setAttribute(\"r\", \"2\");\n secondHandPin.setAttribute(\"fill\", colors.secondHand);\n // Append the elements to finish the second hand.\n secondHand.append(secondHandBar, secondHandPin);\n\n // Pin.\n const pin = document.createElementNS(svgNS, \"circle\");\n pin.setAttribute(\"cx\", \"50\");\n pin.setAttribute(\"cy\", \"50\");\n pin.setAttribute(\"r\", \"0.3\");\n pin.setAttribute(\"fill\", colors.handDark);\n\n // Get the hand angles.\n const date = this.getDate();\n const seconds = date.getSeconds();\n const minutes = date.getMinutes();\n const hours = date.getHours();\n const secAngle = (360 / 60) * seconds;\n const minuteAngle = (360 / 60) * minutes + (360 / 60) * (seconds / 60);\n const hourAngle = (360 / 12) * hours + (360 / 12) * (minutes / 60);\n // Set the clock time by moving the hands.\n hourHand.setAttribute(\"transform\", `translate(50 50) rotate(${hourAngle})`);\n minuteHand.setAttribute(\n \"transform\",\n `translate(50 50) rotate(${minuteAngle})`\n );\n secondHand.setAttribute(\n \"transform\",\n `translate(50 50) rotate(${secAngle})`\n );\n\n // Build the clock\n svg.append(clockFace, marksGroup, hourHand, minuteHand, secondHand, pin);\n // Rotate the clock to its normal position.\n svg.setAttribute(\"transform\", \"rotate(-90)\");\n\n /* Add the animation declaration to the container.\n * Since the animation keyframes need to know the\n * start angle, this angle is dynamic (current time),\n * and we can't edit keyframes through javascript\n * safely and with backwards compatibility, we need\n * to inject it.\n */\n div.innerHTML = `\n \n `;\n // Add the clock to the container\n div.append(svg);\n\n return div;\n }\n\n /**\n * Create a element which contains a representation of a digital clock.\n * @return DOM Element.\n */\n private createDigitalClock(): HTMLElement {\n const element: HTMLDivElement = document.createElement(\"div\");\n element.className = \"digital-clock\";\n\n const { width } = this.getElementSize(); // Destructuring assigment: http://es6-features.org/#ObjectMatchingShorthandNotation\n\n // Calculate font size to adapt the font to the item size.\n const baseTimeFontSize = 20; // Per 100px of width.\n const dateFontSizeMultiplier = 0.5;\n const tzFontSizeMultiplier = 6 / this.props.clockTimezone.length;\n const timeFontSize = (baseTimeFontSize * width) / 100;\n const dateFontSize =\n (baseTimeFontSize * dateFontSizeMultiplier * width) / 100;\n const tzFontSize = Math.min(\n (baseTimeFontSize * tzFontSizeMultiplier * width) / 100,\n (width / 100) * 10\n );\n\n // Date.\n if (this.props.clockFormat === \"datetime\") {\n const dateElem: HTMLSpanElement = document.createElement(\"span\");\n dateElem.className = \"date\";\n dateElem.textContent = this.getDigitalDate();\n dateElem.style.fontSize = `${dateFontSize}px`;\n if (this.props.color) dateElem.style.color = this.props.color;\n element.append(dateElem);\n }\n\n // Time.\n const timeElem: HTMLSpanElement = document.createElement(\"span\");\n timeElem.className = \"time\";\n timeElem.textContent = this.getDigitalTime();\n timeElem.style.fontSize = `${timeFontSize}px`;\n if (this.props.color) timeElem.style.color = this.props.color;\n element.append(timeElem);\n\n // City name.\n const city = this.getHumanTimezone();\n if (city.length > 0) {\n const tzElem: HTMLSpanElement = document.createElement(\"span\");\n tzElem.className = \"timezone\";\n tzElem.textContent = city;\n tzElem.style.fontSize = `${tzFontSize}px`;\n if (this.props.color) tzElem.style.color = this.props.color;\n element.append(tzElem);\n }\n\n return element;\n }\n\n /**\n * Generate the current date using the timezone offset stored into the properties.\n * @return The current date.\n */\n private getDate(): Date {\n const d = new Date();\n const targetTZOffset = this.props.clockTimezoneOffset * 60 * 1000; // In ms.\n const localTZOffset = d.getTimezoneOffset() * 60 * 1000; // In ms.\n const utimestamp = d.getTime() + targetTZOffset + localTZOffset;\n console.log(targetTZOffset, localTZOffset);\n\n return new Date(utimestamp);\n }\n\n /**\n * Generate a date representation with the format 'd/m/Y'.\n * @example 24/02/2020.\n * @return Date representation.\n */\n public getDigitalDate(initialDate: Date | null = null): string {\n const date = initialDate || this.getDate();\n // Use getDate, getDay returns the week day.\n const day = padLeft(date.getDate(), 2, 0);\n // The getMonth function returns the month starting by 0.\n const month = padLeft(date.getMonth() + 1, 2, 0);\n const year = padLeft(date.getFullYear(), 4, 0);\n\n // Format: 'd/m/Y'.\n return `${day}/${month}/${year}`;\n }\n\n /**\n * Generate a time representation with the format 'hh:mm:ss'.\n * @example 01:34:09.\n * @return Time representation.\n */\n public getDigitalTime(initialDate: Date | null = null): string {\n const date = initialDate || this.getDate();\n const hours = padLeft(date.getHours(), 2, 0);\n const minutes = padLeft(date.getMinutes(), 2, 0);\n const seconds = padLeft(date.getSeconds(), 2, 0);\n\n return `${hours}:${minutes}:${seconds}`;\n }\n\n /**\n * Extract a human readable city name from the timezone text.\n * @param timezone Timezone text.\n */\n public getHumanTimezone(timezone: string = this.props.clockTimezone): string {\n const [, city = \"\"] = timezone.split(\"/\");\n return city.replace(\"_\", \" \");\n }\n\n /**\n * Generate a element size using the current size and the default values.\n * @return The size.\n */\n private getElementSize(\n width: number = this.props.width,\n height: number = this.props.height\n ): Size {\n switch (this.props.clockType) {\n case \"analogic\": {\n let diameter = 100; // Default value.\n\n if (width > 0 && height > 0) {\n diameter = Math.min(width, height);\n } else if (width > 0) {\n diameter = width;\n } else if (height > 0) {\n diameter = height;\n }\n\n return {\n width: diameter,\n height: diameter\n };\n }\n case \"digital\": {\n if (width > 0 && height > 0) {\n // The proportion of the clock should be (width = height / 2) aproximately.\n height = width / 2 < height ? width / 2 : height;\n } else if (width > 0) {\n height = width / 2;\n } else if (height > 0) {\n // The proportion of the clock should be (height * 2 = width) aproximately.\n width = height * 2;\n } else {\n width = 100; // Default value.\n height = 50; // Default value.\n }\n\n return {\n width,\n height\n };\n }\n default:\n throw new Error(\"invalid clock type.\");\n }\n }\n}\n","import { UnknownObject } from \"../types\";\nimport { parseIntOr, notEmptyStringOr } from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\ninterface BoxProps extends ItemProps {\n // Overrided properties.\n readonly type: ItemType.BOX_ITEM;\n label: null;\n isLinkEnabled: false;\n parentId: null;\n aclGroupId: null;\n // Custom properties.\n borderWidth: number;\n borderColor: string | null;\n fillColor: string | null;\n}\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the item props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function boxPropsDecoder(data: UnknownObject): BoxProps | never {\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.BOX_ITEM,\n label: null,\n isLinkEnabled: false,\n parentId: null,\n aclGroupId: null,\n // Custom properties.\n borderWidth: parseIntOr(data.borderWidth, 0),\n borderColor: notEmptyStringOr(data.borderColor, null),\n fillColor: notEmptyStringOr(data.fillColor, null)\n };\n}\n\nexport default class Box extends Item {\n protected createDomElement(): HTMLElement {\n const box: HTMLDivElement = document.createElement(\"div\");\n box.className = \"box\";\n // To prevent this item to expand beyond its parent.\n box.style.boxSizing = \"border-box\";\n\n if (this.props.fillColor) {\n box.style.backgroundColor = this.props.fillColor;\n }\n\n // Border.\n if (this.props.borderWidth > 0) {\n box.style.borderStyle = \"solid\";\n // Control the max width to prevent this item to expand beyond its parent.\n const maxBorderWidth = Math.min(this.props.width, this.props.height) / 2;\n const borderWidth = Math.min(this.props.borderWidth, maxBorderWidth);\n box.style.borderWidth = `${borderWidth}px`;\n\n if (this.props.borderColor) {\n box.style.borderColor = this.props.borderColor;\n }\n }\n\n return box;\n }\n}\n","import { UnknownObject, Position, Size } from \"../types\";\nimport { parseIntOr, notEmptyStringOr } from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\ninterface LineProps extends ItemProps {\n // Overrided properties.\n readonly type: ItemType.LINE_ITEM;\n label: null;\n isLinkEnabled: false;\n parentId: null;\n aclGroupId: null;\n // Custom properties.\n startPosition: Position;\n endPosition: Position;\n lineWidth: number;\n color: string | null;\n}\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the item props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function linePropsDecoder(data: UnknownObject): LineProps | never {\n const props: LineProps = {\n ...itemBasePropsDecoder({ ...data, width: 1, height: 1 }), // Object spread. It will merge the properties of the two objects.\n type: ItemType.LINE_ITEM,\n label: null,\n isLinkEnabled: false,\n parentId: null,\n aclGroupId: null,\n // Initialize Position & Size.\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n // Custom properties.\n startPosition: {\n x: parseIntOr(data.startX, 0),\n y: parseIntOr(data.startY, 0)\n },\n endPosition: {\n x: parseIntOr(data.endX, 0),\n y: parseIntOr(data.endY, 0)\n },\n lineWidth: parseIntOr(data.lineWidth || data.borderWidth, 1),\n color: notEmptyStringOr(data.borderColor || data.color, null)\n };\n\n /*\n * We need to enhance the props with the extracted size and position\n * of the box cause there are missing at the props update. A better\n * solution would be overriding the props setter to do it there, but\n * the language doesn't allow it while targetting ES5.\n * TODO: We need to figure out a more consistent solution.\n */\n\n return {\n ...props,\n // Enhance the props extracting the box size and position.\n // eslint-disable-next-line @typescript-eslint/no-use-before-define\n ...Line.extractBoxSizeAndPosition(props)\n };\n}\n\nexport default class Line extends Item {\n /**\n * @override\n */\n public constructor(props: LineProps) {\n /*\n * We need to override the constructor cause we need to obtain\n * the\n * box size and position from the start and finish points\n * of the line.\n */\n super({\n ...props,\n ...Line.extractBoxSizeAndPosition(props)\n });\n }\n\n /**\n * @override\n * To create the item's DOM representation.\n * @return Item.\n */\n protected createDomElement(): HTMLElement {\n const element: HTMLDivElement = document.createElement(\"div\");\n element.className = \"line\";\n\n const svgNS = \"http://www.w3.org/2000/svg\";\n // SVG container.\n const svg = document.createElementNS(svgNS, \"svg\");\n // Set SVG size.\n svg.setAttribute(\n \"width\",\n (this.props.width + this.props.lineWidth).toString()\n );\n svg.setAttribute(\n \"height\",\n (this.props.height + this.props.lineWidth).toString()\n );\n const line = document.createElementNS(svgNS, \"line\");\n line.setAttribute(\n \"x1\",\n `${this.props.startPosition.x - this.props.x + this.props.lineWidth / 2}`\n );\n line.setAttribute(\n \"y1\",\n `${this.props.startPosition.y - this.props.y + this.props.lineWidth / 2}`\n );\n line.setAttribute(\n \"x2\",\n `${this.props.endPosition.x - this.props.x + this.props.lineWidth / 2}`\n );\n line.setAttribute(\n \"y2\",\n `${this.props.endPosition.y - this.props.y + this.props.lineWidth / 2}`\n );\n line.setAttribute(\"stroke\", this.props.color || \"black\");\n line.setAttribute(\"stroke-width\", this.props.lineWidth.toString());\n\n svg.append(line);\n element.append(svg);\n\n return element;\n }\n\n /**\n * Extract the size and position of the box from\n * the start and the finish of the line.\n * @param props Item properties.\n */\n public static extractBoxSizeAndPosition(props: LineProps): Size & Position {\n return {\n width: Math.abs(props.startPosition.x - props.endPosition.x),\n height: Math.abs(props.startPosition.y - props.endPosition.y),\n x: Math.min(props.startPosition.x, props.endPosition.x),\n y: Math.min(props.startPosition.y, props.endPosition.y)\n };\n }\n}\n","import { LinkedVisualConsoleProps, UnknownObject } from \"../types\";\nimport { linkedVCPropsDecoder } from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\nexport type LabelProps = {\n type: ItemType.LABEL;\n} & ItemProps &\n LinkedVisualConsoleProps;\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the label props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function labelPropsDecoder(data: UnknownObject): LabelProps | never {\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.LABEL,\n ...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nexport default class Label extends Item {\n protected createDomElement(): HTMLElement {\n const element = document.createElement(\"div\");\n element.className = \"label\";\n element.innerHTML = this.props.label || \"\";\n\n return element;\n }\n\n /**\n * @override Item.createLabelDomElement\n * Create a new label for the visual console item.\n * @return Item label.\n */\n public createLabelDomElement(): HTMLElement {\n const element = document.createElement(\"div\");\n element.className = \"visual-console-item-label\";\n // Always return an empty label.\n return element;\n }\n}\n","import {\n LinkedVisualConsoleProps,\n UnknownObject,\n WithModuleProps\n} from \"../types\";\nimport { linkedVCPropsDecoder, parseIntOr, modulePropsDecoder } from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\nexport type SimpleValueProps = {\n type: ItemType.SIMPLE_VALUE;\n valueType: \"string\" | \"image\";\n value: string;\n} & (\n | {\n processValue: \"none\";\n }\n | {\n processValue: \"avg\" | \"max\" | \"min\";\n period: number;\n }) &\n ItemProps &\n WithModuleProps &\n LinkedVisualConsoleProps;\n\n/**\n * Extract a valid enum value from a raw value type.\n * @param valueType Raw value.\n */\nconst parseValueType = (\n valueType: any // eslint-disable-line @typescript-eslint/no-explicit-any\n): SimpleValueProps[\"valueType\"] => {\n switch (valueType) {\n case \"string\":\n case \"image\":\n return valueType;\n default:\n return \"string\";\n }\n};\n\n/**\n * Extract a valid enum value from a raw process value.\n * @param processValue Raw value.\n */\nconst parseProcessValue = (\n processValue: any // eslint-disable-line @typescript-eslint/no-explicit-any\n): SimpleValueProps[\"processValue\"] => {\n switch (processValue) {\n case \"none\":\n case \"avg\":\n case \"max\":\n case \"min\":\n return processValue;\n default:\n return \"none\";\n }\n};\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the simple value props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function simpleValuePropsDecoder(\n data: UnknownObject\n): SimpleValueProps | never {\n if (typeof data.value !== \"string\" || data.value.length === 0) {\n throw new TypeError(\"invalid value\");\n }\n\n const processValue = parseProcessValue(data.processValue);\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.SIMPLE_VALUE,\n valueType: parseValueType(data.valueType),\n value: data.value,\n ...(processValue === \"none\"\n ? { processValue }\n : { processValue, period: parseIntOr(data.period, 0) }), // Object spread. It will merge the properties of the two objects.\n ...modulePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n ...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nexport default class SimpleValue extends Item {\n protected createDomElement(): HTMLElement {\n const element = document.createElement(\"div\");\n element.className = \"simple-value\";\n\n if (this.props.valueType === \"image\") {\n const img = document.createElement(\"img\");\n img.src = this.props.value;\n element.append(img);\n } else {\n // Add the value to the label and show it.\n let text = this.props.value;\n if (this.props.label) {\n text = this.props.label.replace(/\\(?_VALUE_\\)?/i, text);\n }\n\n element.innerHTML = text;\n }\n\n return element;\n }\n\n /**\n * @override Item.createLabelDomElement\n * Create a new label for the visual console item.\n * @return Item label.\n */\n protected createLabelDomElement(): HTMLElement {\n const element = document.createElement(\"div\");\n element.className = \"visual-console-item-label\";\n // Always return an empty label.\n return element;\n }\n}\n","import {\n LinkedVisualConsoleProps,\n UnknownObject,\n WithModuleProps\n} from \"../types\";\nimport {\n linkedVCPropsDecoder,\n modulePropsDecoder,\n notEmptyStringOr,\n parseIntOr,\n parseFloatOr\n} from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\nexport type PercentileProps = {\n type: ItemType.PERCENTILE_BAR;\n percentileType:\n | \"progress-bar\"\n | \"bubble\"\n | \"circular-progress-bar\"\n | \"circular-progress-bar-alt\";\n valueType: \"percent\" | \"value\";\n minValue: number | null;\n maxValue: number | null;\n color: string | null;\n labelColor: string | null;\n value: number | null;\n unit: string | null;\n} & ItemProps &\n WithModuleProps &\n LinkedVisualConsoleProps;\n\n/**\n * Extract a valid enum value from a raw type value.\n * @param type Raw value.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction extractPercentileType(type: any): PercentileProps[\"percentileType\"] {\n switch (type) {\n case \"progress-bar\":\n case \"bubble\":\n case \"circular-progress-bar\":\n case \"circular-progress-bar-alt\":\n return type;\n default:\n case ItemType.PERCENTILE_BAR:\n return \"progress-bar\";\n case ItemType.PERCENTILE_BUBBLE:\n return \"bubble\";\n case ItemType.CIRCULAR_PROGRESS_BAR:\n return \"circular-progress-bar\";\n case ItemType.CIRCULAR_INTERIOR_PROGRESS_BAR:\n return \"circular-progress-bar-alt\";\n }\n}\n\n/**\n * Extract a valid enum value from a raw value type value.\n * @param type Raw value.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction extractValueType(valueType: any): PercentileProps[\"valueType\"] {\n switch (valueType) {\n case \"percent\":\n case \"value\":\n return valueType;\n default:\n return \"percent\";\n }\n}\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the percentile props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function percentilePropsDecoder(\n data: UnknownObject\n): PercentileProps | never {\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.PERCENTILE_BAR,\n percentileType: extractPercentileType(data.percentileType || data.type),\n valueType: extractValueType(data.valueType),\n minValue: parseIntOr(data.minValue, null),\n maxValue: parseIntOr(data.maxValue, null),\n color: notEmptyStringOr(data.color, null),\n labelColor: notEmptyStringOr(data.labelColor, null),\n value: parseFloatOr(data.value, null),\n unit: notEmptyStringOr(data.unit, null),\n ...modulePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n ...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.\n };\n}\n\nconst svgNS = \"http://www.w3.org/2000/svg\";\n\nexport default class Percentile extends Item {\n protected createDomElement(): HTMLElement {\n const colors = {\n background: \"#000000\",\n progress: this.props.color || \"#F0F0F0\",\n text: this.props.labelColor || \"#444444\"\n };\n // Progress.\n const progress = this.getProgress();\n // Main element.\n const element = document.createElement(\"div\");\n // SVG container.\n const svg = document.createElementNS(svgNS, \"svg\");\n\n switch (this.props.percentileType) {\n case \"progress-bar\":\n {\n const backgroundRect = document.createElementNS(svgNS, \"rect\");\n backgroundRect.setAttribute(\"fill\", colors.background);\n backgroundRect.setAttribute(\"fill-opacity\", \"0.5\");\n backgroundRect.setAttribute(\"width\", \"100\");\n backgroundRect.setAttribute(\"height\", \"20\");\n backgroundRect.setAttribute(\"rx\", \"5\");\n backgroundRect.setAttribute(\"ry\", \"5\");\n const progressRect = document.createElementNS(svgNS, \"rect\");\n progressRect.setAttribute(\"fill\", colors.progress);\n progressRect.setAttribute(\"fill-opacity\", \"1\");\n progressRect.setAttribute(\"width\", `${progress}`);\n progressRect.setAttribute(\"height\", \"20\");\n progressRect.setAttribute(\"rx\", \"5\");\n progressRect.setAttribute(\"ry\", \"5\");\n const text = document.createElementNS(svgNS, \"text\");\n text.setAttribute(\"text-anchor\", \"middle\");\n text.setAttribute(\"alignment-baseline\", \"middle\");\n text.setAttribute(\"font-size\", \"12\");\n text.setAttribute(\"font-family\", \"arial\");\n text.setAttribute(\"font-weight\", \"bold\");\n text.setAttribute(\"transform\", \"translate(50 11)\");\n text.setAttribute(\"fill\", colors.text);\n\n if (this.props.valueType === \"value\") {\n text.textContent = this.props.unit\n ? `${this.props.value} ${this.props.unit}`\n : `${this.props.value}`;\n } else {\n text.textContent = `${progress}%`;\n }\n\n // Auto resize SVG using the view box magic: https://css-tricks.com/scale-svg/\n svg.setAttribute(\"viewBox\", \"0 0 100 20\");\n svg.append(backgroundRect, progressRect, text);\n }\n break;\n case \"bubble\":\n case \"circular-progress-bar\": // TODO: Add this chart.\n case \"circular-progress-bar-alt\": // TODO: Add this chart.\n {\n const backgroundCircle = document.createElementNS(svgNS, \"circle\");\n backgroundCircle.setAttribute(\"transform\", \"translate(50 50)\");\n backgroundCircle.setAttribute(\"fill\", colors.background);\n backgroundCircle.setAttribute(\"fill-opacity\", \"0.5\");\n backgroundCircle.setAttribute(\"r\", \"50\");\n const progressCircle = document.createElementNS(svgNS, \"circle\");\n progressCircle.setAttribute(\"transform\", \"translate(50 50)\");\n progressCircle.setAttribute(\"fill\", colors.progress);\n progressCircle.setAttribute(\"fill-opacity\", \"1\");\n progressCircle.setAttribute(\"r\", `${progress / 2}`);\n const text = document.createElementNS(svgNS, \"text\");\n text.setAttribute(\"text-anchor\", \"middle\");\n text.setAttribute(\"alignment-baseline\", \"middle\");\n text.setAttribute(\"font-size\", \"16\");\n text.setAttribute(\"font-family\", \"arial\");\n text.setAttribute(\"font-weight\", \"bold\");\n text.setAttribute(\"fill\", colors.text);\n\n if (this.props.valueType === \"value\") {\n if (this.props.unit && this.props.unit.length > 0) {\n const value = document.createElementNS(svgNS, \"tspan\");\n value.setAttribute(\"x\", \"0\");\n value.setAttribute(\"dy\", \"1em\");\n value.textContent = `${this.props.value}`;\n const unit = document.createElementNS(svgNS, \"tspan\");\n unit.setAttribute(\"x\", \"0\");\n unit.setAttribute(\"dy\", \"1em\");\n unit.textContent = `${this.props.unit}`;\n text.append(value, unit);\n text.setAttribute(\"transform\", \"translate(50 33)\");\n } else {\n text.textContent = `${this.props.value}`;\n text.setAttribute(\"transform\", \"translate(50 50)\");\n }\n } else {\n text.textContent = `${progress}%`;\n text.setAttribute(\"transform\", \"translate(50 50)\");\n }\n\n // Auto resize SVG using the view box magic: https://css-tricks.com/scale-svg/\n svg.setAttribute(\"viewBox\", \"0 0 100 100\");\n svg.append(backgroundCircle, progressCircle, text);\n }\n break;\n }\n\n element.append(svg);\n\n return element;\n }\n\n private getProgress(): number {\n const minValue = this.props.minValue || 0;\n const maxValue = this.props.maxValue || 100;\n const value = this.props.value || 100;\n\n if (value <= minValue) return 0;\n else if (value >= maxValue) return 100;\n else return ((value - minValue) / (maxValue - minValue)) * 100;\n }\n}\n","import { UnknownObject } from \"../types\";\nimport {\n stringIsEmpty,\n notEmptyStringOr,\n decodeBase64,\n parseIntOr\n} from \"../lib\";\nimport Item, { ItemType, ItemProps, itemBasePropsDecoder } from \"../Item\";\n\nexport type ServiceProps = {\n type: ItemType.SERVICE;\n serviceId: number;\n imageSrc: string | null;\n statusImageSrc: string | null;\n encodedTitle: string | null;\n} & ItemProps;\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the service props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function servicePropsDecoder(data: UnknownObject): ServiceProps | never {\n if (data.imageSrc !== null) {\n if (\n typeof data.statusImageSrc !== \"string\" ||\n data.imageSrc.statusImageSrc === 0\n ) {\n throw new TypeError(\"invalid status image src.\");\n }\n } else {\n if (stringIsEmpty(data.encodedTitle)) {\n throw new TypeError(\"missing encode tittle content.\");\n }\n }\n\n if (parseIntOr(data.serviceId, null) === null) {\n throw new TypeError(\"invalid service id.\");\n }\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.SERVICE,\n serviceId: data.serviceId,\n imageSrc: notEmptyStringOr(data.imageSrc, null),\n statusImageSrc: notEmptyStringOr(data.statusImageSrc, null),\n encodedTitle: notEmptyStringOr(data.encodedTitle, null)\n };\n}\n\nexport default class Service extends Item {\n public createDomElement(): HTMLElement {\n const img: HTMLImageElement = document.createElement(\"img\");\n if (this.props.statusImageSrc !== null) {\n img.className = \"icon\";\n img.src = this.props.statusImageSrc;\n } else {\n if (this.props.encodedTitle !== null) {\n const element = document.createElement(\"div\");\n element.innerHTML = decodeBase64(this.props.encodedTitle);\n return element;\n }\n }\n return img;\n }\n}\n","import { UnknownObject, Size } from \"./types\";\nimport {\n parseBoolean,\n sizePropsDecoder,\n parseIntOr,\n notEmptyStringOr\n} from \"./lib\";\nimport Item, {\n ItemType,\n ItemProps,\n ItemClickEvent,\n ItemRemoveEvent\n} from \"./Item\";\nimport StaticGraph, { staticGraphPropsDecoder } from \"./items/StaticGraph\";\nimport Icon, { iconPropsDecoder } from \"./items/Icon\";\nimport ColorCloud, { colorCloudPropsDecoder } from \"./items/ColorCloud\";\nimport Group, { groupPropsDecoder } from \"./items/Group\";\nimport Clock, { clockPropsDecoder } from \"./items/Clock\";\nimport Box, { boxPropsDecoder } from \"./items/Box\";\nimport Line, { linePropsDecoder } from \"./items/Line\";\nimport Label, { labelPropsDecoder } from \"./items/Label\";\nimport SimpleValue, { simpleValuePropsDecoder } from \"./items/SimpleValue\";\nimport EventsHistory, {\n eventsHistoryPropsDecoder\n} from \"./items/EventsHistory\";\nimport Percentile, { percentilePropsDecoder } from \"./items/Percentile\";\nimport TypedEvent, { Disposable, Listener } from \"./TypedEvent\";\nimport DonutGraph, { donutGraphPropsDecoder } from \"./items/DonutGraph\";\nimport BarsGraph, { barsGraphPropsDecoder } from \"./items/BarsGraph\";\nimport ModuleGraph, { moduleGraphPropsDecoder } from \"./items/ModuleGraph\";\nimport Service, { servicePropsDecoder } from \"./items/Service\";\n\n// TODO: Document.\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nfunction itemInstanceFrom(data: UnknownObject) {\n const type = parseIntOr(data.type, null);\n if (type == null) throw new TypeError(\"missing item type.\");\n\n switch (type as ItemType) {\n case ItemType.STATIC_GRAPH:\n return new StaticGraph(staticGraphPropsDecoder(data));\n case ItemType.MODULE_GRAPH:\n return new ModuleGraph(moduleGraphPropsDecoder(data));\n case ItemType.SIMPLE_VALUE:\n case ItemType.SIMPLE_VALUE_MAX:\n case ItemType.SIMPLE_VALUE_MIN:\n case ItemType.SIMPLE_VALUE_AVG:\n return new SimpleValue(simpleValuePropsDecoder(data));\n case ItemType.PERCENTILE_BAR:\n case ItemType.PERCENTILE_BUBBLE:\n case ItemType.CIRCULAR_PROGRESS_BAR:\n case ItemType.CIRCULAR_INTERIOR_PROGRESS_BAR:\n return new Percentile(percentilePropsDecoder(data));\n case ItemType.LABEL:\n return new Label(labelPropsDecoder(data));\n case ItemType.ICON:\n return new Icon(iconPropsDecoder(data));\n case ItemType.SERVICE:\n return new Service(servicePropsDecoder(data));\n case ItemType.GROUP_ITEM:\n return new Group(groupPropsDecoder(data));\n case ItemType.BOX_ITEM:\n return new Box(boxPropsDecoder(data));\n case ItemType.LINE_ITEM:\n return new Line(linePropsDecoder(data));\n case ItemType.AUTO_SLA_GRAPH:\n return new EventsHistory(eventsHistoryPropsDecoder(data));\n case ItemType.DONUT_GRAPH:\n return new DonutGraph(donutGraphPropsDecoder(data));\n case ItemType.BARS_GRAPH:\n return new BarsGraph(barsGraphPropsDecoder(data));\n case ItemType.CLOCK:\n return new Clock(clockPropsDecoder(data));\n case ItemType.COLOR_CLOUD:\n return new ColorCloud(colorCloudPropsDecoder(data));\n default:\n throw new TypeError(\"item not found\");\n }\n}\n\n// TODO: Document.\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nfunction decodeProps(data: UnknownObject) {\n const type = parseIntOr(data.type, null);\n if (type == null) throw new TypeError(\"missing item type.\");\n\n switch (type as ItemType) {\n case ItemType.STATIC_GRAPH:\n return staticGraphPropsDecoder(data);\n case ItemType.MODULE_GRAPH:\n return moduleGraphPropsDecoder(data);\n case ItemType.SIMPLE_VALUE:\n case ItemType.SIMPLE_VALUE_MAX:\n case ItemType.SIMPLE_VALUE_MIN:\n case ItemType.SIMPLE_VALUE_AVG:\n return simpleValuePropsDecoder(data);\n case ItemType.PERCENTILE_BAR:\n case ItemType.PERCENTILE_BUBBLE:\n case ItemType.CIRCULAR_PROGRESS_BAR:\n case ItemType.CIRCULAR_INTERIOR_PROGRESS_BAR:\n return percentilePropsDecoder(data);\n case ItemType.LABEL:\n return labelPropsDecoder(data);\n case ItemType.ICON:\n return iconPropsDecoder(data);\n case ItemType.SERVICE:\n return servicePropsDecoder(data);\n case ItemType.GROUP_ITEM:\n return groupPropsDecoder(data);\n case ItemType.BOX_ITEM:\n return boxPropsDecoder(data);\n case ItemType.LINE_ITEM:\n return linePropsDecoder(data);\n case ItemType.AUTO_SLA_GRAPH:\n return eventsHistoryPropsDecoder(data);\n case ItemType.DONUT_GRAPH:\n return donutGraphPropsDecoder(data);\n case ItemType.BARS_GRAPH:\n return barsGraphPropsDecoder(data);\n case ItemType.CLOCK:\n return clockPropsDecoder(data);\n case ItemType.COLOR_CLOUD:\n return colorCloudPropsDecoder(data);\n default:\n throw new TypeError(\"decoder not found\");\n }\n}\n\n// Base properties.\nexport interface VisualConsoleProps extends Size {\n readonly id: number;\n name: string;\n groupId: number;\n backgroundURL: string | null; // URL?\n backgroundColor: string | null;\n isFavorite: boolean;\n relationLineWidth: number;\n}\n\n/**\n * Build a valid typed object from a raw object.\n * This will allow us to ensure the type safety.\n *\n * @param data Raw object.\n * @return An object representing the Visual Console props.\n * @throws Will throw a TypeError if some property\n * is missing from the raw object or have an invalid type.\n */\nexport function visualConsolePropsDecoder(\n data: UnknownObject\n): VisualConsoleProps | never {\n // Object destructuring: http://es6-features.org/#ObjectMatchingShorthandNotation\n const {\n id,\n name,\n groupId,\n backgroundURL,\n backgroundColor,\n isFavorite,\n relationLineWidth\n } = data;\n\n if (id == null || isNaN(parseInt(id))) {\n throw new TypeError(\"invalid Id.\");\n }\n if (typeof name !== \"string\" || name.length === 0) {\n throw new TypeError(\"invalid name.\");\n }\n if (groupId == null || isNaN(parseInt(groupId))) {\n throw new TypeError(\"invalid group Id.\");\n }\n\n return {\n id: parseInt(id),\n name,\n groupId: parseInt(groupId),\n backgroundURL: notEmptyStringOr(backgroundURL, null),\n backgroundColor: notEmptyStringOr(backgroundColor, null),\n isFavorite: parseBoolean(isFavorite),\n relationLineWidth: parseIntOr(relationLineWidth, 0),\n ...sizePropsDecoder(data)\n };\n}\n\nexport default class VisualConsole {\n // Reference to the DOM element which will contain the items.\n private readonly containerRef: HTMLElement;\n // Properties.\n private _props: VisualConsoleProps;\n // Visual Console Item instances by their Id.\n private elementsById: {\n [key: number]: Item;\n } = {};\n // Visual Console Item Ids.\n private elementIds: ItemProps[\"id\"][] = [];\n // Dictionary which store the created lines.\n private relations: {\n [key: string]: Line;\n } = {};\n // Event manager for click events.\n private readonly clickEventManager = new TypedEvent<\n ItemClickEvent\n >();\n // List of references to clean the event listeners.\n private readonly disposables: Disposable[] = [];\n\n /**\n * React to a click on an element.\n * @param e Event object.\n */\n private handleElementClick: (e: ItemClickEvent) => void = e => {\n this.clickEventManager.emit(e);\n // console.log(`Clicked element #${e.data.id}`, e);\n };\n\n /**\n * Clear some element references.\n * @param e Event object.\n */\n private handleElementRemove: (e: ItemRemoveEvent) => void = e => {\n // Remove the element from the list and its relations.\n this.elementIds = this.elementIds.filter(id => id !== e.data.id);\n delete this.elementsById[e.data.id];\n this.clearRelations(e.data.id);\n };\n\n public constructor(\n container: HTMLElement,\n props: UnknownObject,\n items: UnknownObject[]\n ) {\n this.containerRef = container;\n this._props = visualConsolePropsDecoder(props);\n\n // Force the first render.\n this.render();\n\n // Sort by isOnTop, id ASC\n items = items.sort(function(a, b) {\n if (\n a.isOnTop == null ||\n b.isOnTop == null ||\n a.id == null ||\n b.id == null\n ) {\n return 0;\n }\n\n if (a.isOnTop && !b.isOnTop) return 1;\n else if (!a.isOnTop && b.isOnTop) return -1;\n else if (a.id < b.id) return 1;\n else return -1;\n });\n\n // Initialize the items.\n items.forEach(item => {\n try {\n const itemInstance = itemInstanceFrom(item);\n // Add the item to the list.\n this.elementsById[itemInstance.props.id] = itemInstance;\n this.elementIds.push(itemInstance.props.id);\n // Item event handlers.\n itemInstance.onClick(this.handleElementClick);\n itemInstance.onRemove(this.handleElementRemove);\n // Add the item to the DOM.\n this.containerRef.append(itemInstance.elementRef);\n } catch (error) {\n console.log(\"Error creating a new element:\", error.message);\n }\n });\n\n // Create lines.\n this.buildRelations();\n }\n\n /**\n * Public accessor of the `elements` property.\n * @return Properties.\n */\n public get elements(): Item[] {\n // Ensure the type cause Typescript doesn't know the filter removes null items.\n return this.elementIds\n .map(id => this.elementsById[id])\n .filter(_ => _ != null) as Item[];\n }\n\n /**\n * Public setter of the `elements` property.\n * @param items.\n */\n public updateElements(items: UnknownObject[]): void {\n const itemIds = items.map(item => item.id || null).filter(id => id != null);\n itemIds as number[]; // Tell the type system to rely on us.\n // Get the elements we should delete.\n const deletedIds: number[] = this.elementIds.filter(\n id => itemIds.indexOf(id) < 0\n );\n // Delete the elements.\n deletedIds.forEach(id => {\n if (this.elementsById[id] != null) {\n this.elementsById[id].remove();\n delete this.elementsById[id];\n }\n });\n // Replace the element ids.\n this.elementIds = itemIds;\n\n // Initialize the items.\n items.forEach(item => {\n if (item.id) {\n if (this.elementsById[item.id] == null) {\n // New item.\n try {\n const itemInstance = itemInstanceFrom(item);\n // Add the item to the list.\n this.elementsById[itemInstance.props.id] = itemInstance;\n // Item event handlers.\n itemInstance.onClick(this.handleElementClick);\n itemInstance.onRemove(this.handleElementRemove);\n // Add the item to the DOM.\n this.containerRef.append(itemInstance.elementRef);\n } catch (error) {\n console.log(\"Error creating a new element:\", error.message);\n }\n } else {\n // Update item.\n try {\n this.elementsById[item.id].props = decodeProps(item);\n } catch (error) {\n console.log(\"Error updating an element:\", error.message);\n }\n }\n }\n });\n\n // Re-build relations.\n this.buildRelations();\n }\n\n /**\n * Public accessor of the `props` property.\n * @return Properties.\n */\n public get props(): VisualConsoleProps {\n return { ...this._props }; // Return a copy.\n }\n\n /**\n * Public setter of the `props` property.\n * If the new props are different enough than the\n * stored props, a render would be fired.\n * @param newProps\n */\n public set props(newProps: VisualConsoleProps) {\n const prevProps = this.props;\n // Update the internal props.\n this._props = newProps;\n\n // From this point, things which rely on this.props can access to the changes.\n\n // Re-render.\n this.render(prevProps);\n }\n\n /**\n * Recreate or update the HTMLElement which represents the Visual Console into the DOM.\n * @param prevProps If exists it will be used to only DOM updates instead of a full replace.\n */\n public render(prevProps: VisualConsoleProps | null = null): void {\n if (prevProps) {\n if (prevProps.backgroundURL !== this.props.backgroundURL) {\n this.containerRef.style.backgroundImage =\n this.props.backgroundURL !== null\n ? `url(${this.props.backgroundURL})`\n : null;\n }\n if (prevProps.backgroundColor !== this.props.backgroundColor) {\n this.containerRef.style.backgroundColor = this.props.backgroundColor;\n }\n if (this.sizeChanged(prevProps, this.props)) {\n this.resizeElement(this.props.width, this.props.height);\n }\n } else {\n this.containerRef.style.backgroundImage =\n this.props.backgroundURL !== null\n ? `url(${this.props.backgroundURL})`\n : null;\n\n this.containerRef.style.backgroundColor = this.props.backgroundColor;\n this.resizeElement(this.props.width, this.props.height);\n }\n }\n\n /**\n * Compare the previous and the new size and return\n * a boolean value in case the size changed.\n * @param prevSize\n * @param newSize\n * @return Whether the size changed or not.\n */\n public sizeChanged(prevSize: Size, newSize: Size): boolean {\n return (\n prevSize.width !== newSize.width || prevSize.height !== newSize.height\n );\n }\n\n /**\n * Resize the DOM container.\n * @param width\n * @param height\n */\n public resizeElement(width: number, height: number): void {\n this.containerRef.style.width = `${width}px`;\n this.containerRef.style.height = `${height}px`;\n }\n\n /**\n * Update the size into the properties and resize the DOM container.\n * @param width\n * @param height\n */\n public resize(width: number, height: number): void {\n this.props = {\n ...this.props, // Object spread: http://es6-features.org/#SpreadOperator\n width,\n height\n };\n }\n\n /**\n * To remove the event listeners and the elements from the DOM.\n */\n public remove(): void {\n this.disposables.forEach(d => d.dispose()); // Arrow function.\n this.elements.forEach(e => e.remove()); // Arrow function.\n this.elementsById = {};\n this.elementIds = [];\n // Clear relations.\n this.clearRelations();\n // Clean container.\n this.containerRef.innerHTML = \"\";\n }\n\n /**\n * Create line elements which connect the elements with their parents.\n */\n private buildRelations(): void {\n // Clear relations.\n this.clearRelations();\n // Add relations.\n this.elements.forEach(item => {\n if (item.props.parentId !== null) {\n const parent = this.elementsById[item.props.parentId];\n const child = this.elementsById[item.props.id];\n if (parent && child) this.addRelationLine(parent, child);\n }\n });\n }\n\n /**\n * @param itemId Optional identifier of a parent or child item.\n * Remove the line elements which connect the elements with their parents.\n */\n private clearRelations(itemId?: number): void {\n if (itemId != null) {\n for (let key in this.relations) {\n const ids = key.split(\"|\");\n const parentId = Number.parseInt(ids[0]);\n const childId = Number.parseInt(ids[1]);\n\n if (itemId === parentId || itemId === childId) {\n this.relations[key].remove();\n delete this.relations[key];\n }\n }\n } else {\n for (let key in this.relations) {\n this.relations[key].remove();\n delete this.relations[key];\n }\n }\n }\n\n /**\n * Retrieve the line element which represent the relation between items.\n * @param parentId Identifier of the parent item.\n * @param childId Itentifier of the child item.\n * @return The line element or nothing.\n */\n private getRelationLine(parentId: number, childId: number): Line | null {\n const identifier = `${parentId}|${childId}`;\n return this.relations[identifier] || null;\n }\n\n /**\n * Add a new line item to represent a relation between the items.\n * @param parent Parent item.\n * @param child Child item.\n * @return Whether the line was added or not.\n */\n private addRelationLine(\n parent: Item,\n child: Item\n ): Line {\n const identifier = `${parent.props.id}|${child.props.id}`;\n if (this.relations[identifier] != null) {\n this.relations[identifier].remove();\n }\n\n // Get the items center.\n const startX = parent.props.x + parent.elementRef.clientWidth / 2;\n const startY =\n parent.props.y +\n (parent.elementRef.clientHeight - parent.labelElementRef.clientHeight) /\n 2;\n const endX = child.props.x + child.elementRef.clientWidth / 2;\n const endY =\n child.props.y +\n (child.elementRef.clientHeight - child.labelElementRef.clientHeight) / 2;\n\n const line = new Line(\n linePropsDecoder({\n id: 0,\n type: ItemType.LINE_ITEM,\n startX,\n startY,\n endX,\n endY,\n width: 0,\n height: 0,\n lineWidth: this.props.relationLineWidth,\n color: \"#CCCCCC\"\n })\n );\n // Save a reference to the line item.\n this.relations[identifier] = line;\n\n // Add the line to the DOM.\n line.elementRef.style.zIndex = \"0\";\n this.containerRef.append(line.elementRef);\n\n return line;\n }\n\n /**\n * Add an event handler to the click of the linked visual console elements.\n * @param listener Function which is going to be executed when a linked console is clicked.\n */\n public onClick(listener: Listener>): Disposable {\n /*\n * The '.on' function returns a function which will clean the event\n * listener when executed. We store all the 'dispose' functions to\n * call them when the item should be cleared.\n */\n const disposable = this.clickEventManager.on(listener);\n this.disposables.push(disposable);\n\n return disposable;\n }\n}\n","/*\n * Useful resources.\n * http://es6-features.org/\n * http://exploringjs.com/es6\n * https://www.typescriptlang.org/\n */\n\nimport \"./main.css\"; // CSS import.\nimport VisualConsole from \"./VisualConsole\";\n\n// Export the VisualConsole class to the global object.\n\n// eslint-disable-next-line\n(window as any).VisualConsole = VisualConsole;\n"],"sourceRoot":""} \ No newline at end of file diff --git a/visual_console_client/src/items/Clock/index.ts b/visual_console_client/src/items/Clock/index.ts index 5cc939983d..f43c4e45a8 100644 --- a/visual_console_client/src/items/Clock/index.ts +++ b/visual_console_client/src/items/Clock/index.ts @@ -530,10 +530,9 @@ export default class Clock extends Item { */ private getDate(): Date { const d = new Date(); - const targetTZOffset = this.props.clockTimezoneOffset * 60 * 1000; // In ms. + const targetTZOffset = this.props.clockTimezoneOffset * 1000; // In ms. const localTZOffset = d.getTimezoneOffset() * 60 * 1000; // In ms. const utimestamp = d.getTime() + targetTZOffset + localTZOffset; - console.log(targetTZOffset, localTZOffset); return new Date(utimestamp); }