From faee7b7b14ab699b5e9674d7fb17515c37d8f60a Mon Sep 17 00:00:00 2001 From: "marcos.alconada" Date: Wed, 13 Mar 2019 16:32:58 +0100 Subject: [PATCH 01/92] Pending Q&A Former-commit-id: f41aafc6077f1b725cf7c9f360974ba62609eedd --- pandora_console/godmode/agentes/modificar_agente.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/godmode/agentes/modificar_agente.php b/pandora_console/godmode/agentes/modificar_agente.php index 4673bf2f46..dfaf6bcba8 100644 --- a/pandora_console/godmode/agentes/modificar_agente.php +++ b/pandora_console/godmode/agentes/modificar_agente.php @@ -162,7 +162,7 @@ echo ''; echo __('Group').' '; $own_info = get_user_info($config['id_user']); -if (!$own_info['is_admin'] && !check_acl($config['id_user'], 0, 'AW')) { +if (!$own_info['is_admin'] && !check_acl($config['id_user'], 0, 'AR')) { $return_all_group = false; } else { $return_all_group = true; From 97df41245e4b77efedd6659faa6b249b1698a3d9 Mon Sep 17 00:00:00 2001 From: "marcos.alconada" Date: Wed, 13 Mar 2019 16:36:30 +0100 Subject: [PATCH 02/92] Para revision Former-commit-id: 5823cfd9976382ad8074d2ed8cf0340e24181693 --- pandora_console/godmode/agentes/modificar_agente.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/godmode/agentes/modificar_agente.php b/pandora_console/godmode/agentes/modificar_agente.php index dfaf6bcba8..3094c2fdc8 100644 --- a/pandora_console/godmode/agentes/modificar_agente.php +++ b/pandora_console/godmode/agentes/modificar_agente.php @@ -162,7 +162,7 @@ echo ''; echo __('Group').' '; $own_info = get_user_info($config['id_user']); -if (!$own_info['is_admin'] && !check_acl($config['id_user'], 0, 'AR')) { +if (!$own_info['is_admin'] && check_acl($config['id_user'], 0, 'AW')) { $return_all_group = false; } else { $return_all_group = true; From 4c95a160defd8039fa345c36e361537b29c867bf Mon Sep 17 00:00:00 2001 From: Luis Calvo Date: Mon, 1 Apr 2019 17:57:22 +0200 Subject: [PATCH 03/92] Changed Jquery .text for .html for html conversion Former-commit-id: 9dd9c63e637e504ff51e38165687bacfae59ed38 --- pandora_console/godmode/alerts/configure_alert_action.php | 4 ++-- pandora_console/include/javascript/pandora_alerts.js | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/pandora_console/godmode/alerts/configure_alert_action.php b/pandora_console/godmode/alerts/configure_alert_action.php index c29cda623b..e7927a2a3a 100644 --- a/pandora_console/godmode/alerts/configure_alert_action.php +++ b/pandora_console/godmode/alerts/configure_alert_action.php @@ -318,9 +318,9 @@ $(document).ready (function () { jQuery.post (, values, function (data, status) { - original_command = js_html_entity_decode (data["command"]); + original_command = data["command"]; render_command_preview (original_command); - command_description = js_html_entity_decode (data["description"]); + command_description = data["description"]; render_command_description(command_description); var max_fields = parseInt(''); diff --git a/pandora_console/include/javascript/pandora_alerts.js b/pandora_console/include/javascript/pandora_alerts.js index 41f8d20ad8..668950ce9c 100644 --- a/pandora_console/include/javascript/pandora_alerts.js +++ b/pandora_console/include/javascript/pandora_alerts.js @@ -1,5 +1,4 @@ var original_command = ""; - function parse_alert_command(command, classs) { if (classs == "recovery") { classs = "fields_recovery"; @@ -28,13 +27,13 @@ function parse_alert_command(command, classs) { } function render_command_preview(original_command) { - $("#textarea_command_preview").text( + $("#textarea_command_preview").html( parse_alert_command(original_command, "") ); } function render_command_recovery_preview(original_command) { - $("#textarea_command_recovery_preview").text( + $("#textarea_command_recovery_preview").html( parse_alert_command(original_command, "recovery") ); } From 9c3d26f12030f683f8e7e32a13fe3aafd819ec22 Mon Sep 17 00:00:00 2001 From: Luis Calvo Date: Wed, 3 Apr 2019 11:22:20 +0200 Subject: [PATCH 04/92] Deleted Servers menu option for operator(read) Former-commit-id: 89723d23cb2199152cfc9f3d72997ddcd7b31796 --- pandora_console/godmode/menu.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/godmode/menu.php b/pandora_console/godmode/menu.php index ac3154b657..6224d361c9 100644 --- a/pandora_console/godmode/menu.php +++ b/pandora_console/godmode/menu.php @@ -208,7 +208,7 @@ if (!empty($sub)) { } -if (check_acl($config['id_user'], 0, 'AW') || check_acl($config['id_user'], 0, 'PM') || check_acl($config['id_user'], 0, 'RR')) { +if (check_acl($config['id_user'], 0, 'AW') || check_acl($config['id_user'], 0, 'PM')) { // Servers $menu_godmode['gservers']['text'] = __('Servers'); $menu_godmode['gservers']['sec2'] = 'godmode/servers/modificar_server'; From 9df4cb86dc496c8aecd56be96f785695da16b25d Mon Sep 17 00:00:00 2001 From: Luis Calvo Date: Thu, 4 Apr 2019 09:45:29 +0200 Subject: [PATCH 05/92] Added inline-block and fixed size to label Former-commit-id: 40c1ca6d5c06fb771eb7e8d1ac81dde6e7012cfb --- pandora_console/include/styles/login.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pandora_console/include/styles/login.css b/pandora_console/include/styles/login.css index bffcda19d5..648eadb503 100644 --- a/pandora_console/include/styles/login.css +++ b/pandora_console/include/styles/login.css @@ -407,6 +407,8 @@ div.form_message_alert ul li input { } div.form_message_alert ul li label { + display: inline-block; + width: 145px; font-size: 10pt; padding-right: 20px; } From 1b6a01cfd5ac0f97266abd35471788ef32cca8fb Mon Sep 17 00:00:00 2001 From: Luis Calvo Date: Thu, 4 Apr 2019 14:11:44 +0200 Subject: [PATCH 06/92] Changed modal size to fit err. msg Former-commit-id: 2676ac1d217cc5245ce09277b8b76d1d562cdf5f --- .../include/javascript/jquery.pandora.js | 697 +++++++++--------- 1 file changed, 358 insertions(+), 339 deletions(-) diff --git a/pandora_console/include/javascript/jquery.pandora.js b/pandora_console/include/javascript/jquery.pandora.js index 9e0b3447af..ed75400386 100644 --- a/pandora_console/include/javascript/jquery.pandora.js +++ b/pandora_console/include/javascript/jquery.pandora.js @@ -1,386 +1,405 @@ (function($) { - $.fn.check = function () { - return this.each (function () { - this.checked = true; - });}; + $.fn.check = function() { + return this.each(function() { + this.checked = true; + }); + }; - $.fn.uncheck = function () { - return this.each (function () { - this.checked = false; - });}; + $.fn.uncheck = function() { + return this.each(function() { + this.checked = false; + }); + }; - $.fn.enable = function () { - return $(this).removeAttr ("disabled"); - }; + $.fn.enable = function() { + return $(this).removeAttr("disabled"); + }; - $.fn.disable = function () { - return $(this).attr ("disabled", "disabled"); - }; + $.fn.disable = function() { + return $(this).attr("disabled", "disabled"); + }; - $.fn.pulsate = function () { - var i = 0; - for (i = 0; i <= 2; i++) { - $(this).fadeOut ("slow").fadeIn ("slow"); - } - }; + $.fn.pulsate = function() { + var i = 0; + for (i = 0; i <= 2; i++) { + $(this) + .fadeOut("slow") + .fadeIn("slow"); + } + }; - $.fn.showMessage = function (msg) { - return $(this).hide ().empty () - // here, previously .text (msg) - .html (msg) - .slideDown (); - }; -}) (jQuery); + $.fn.showMessage = function(msg) { + return ( + $(this) + .hide() + .empty() + // here, previously .text (msg) + .html(msg) + .slideDown() + ); + }; +})(jQuery); -$(document).ready (function () { - $("a#show_messages_dialog").click (function () { - jQuery.post ("ajax.php", - { - "page": "operation/messages/message_list" - }, - function (data, status) { - $("#dialog_messages").hide () - .empty () - .append (data) - .dialog ({ - title: $("a#show_messages_dialog").attr ("title"), - resizable: false, - modal: true, - overlay: { - opacity: 0.5, - background: "black" - }, - width: 700, - height: 300 - }).show (); - }, - "html" - ); +$(document).ready(function() { + $("a#show_messages_dialog").click(function() { + jQuery.post( + "ajax.php", + { + page: "operation/messages/message_list" + }, + function(data, status) { + $("#dialog_messages") + .hide() + .empty() + .append(data) + .dialog({ + title: $("a#show_messages_dialog").attr("title"), + resizable: false, + modal: true, + overlay: { + opacity: 0.5, + background: "black" + }, + width: 700, + height: 300 + }) + .show(); + }, + "html" + ); - return false; - }); + return false; + }); - $("a.show_systemalert_dialog").click (function () { - $('body').append( "
" ); - $("#opacidad").css('opacity', 0.5); + $("a.show_systemalert_dialog").click(function() { + $("body").append( + "
" + ); + $("#opacidad").css("opacity", 0.5); - jQuery.post ("ajax.php", - { - "page": "operation/system_alert"}, - function (data, status) { - $("#alert_messages").show(); - $("#alert_messages").empty ().append (data); - $("#alert_messages").css('opacity', 1); + jQuery.post( + "ajax.php", + { + page: "operation/system_alert" + }, + function(data, status) { + $("#alert_messages").show(); + $("#alert_messages") + .empty() + .append(data); + $("#alert_messages").css("opacity", 1); + }, + "html" + ); + }); - }, - "html" - ); - }); - - $("a.modalpopup").click (function () { - var elem = $(this).attr("id"); - $('body').append( "
" ); - $("#opacidad").css('opacity', 0.5); + $("a.modalpopup").click(function() { + var elem = $(this).attr("id"); + $("body").append( + "
" + ); + $("#opacidad").css("opacity", 0.5); - jQuery.post ("ajax.php", - { - "page": "general/alert_enterprise", - "message": elem - }, - function (data, status) { - $("#alert_messages").show(); - $("#alert_messages").empty ().append (data); - $("#alert_messages").css('opacity', 1); - }, - "html" - ); - return false; - }); + jQuery.post( + "ajax.php", + { + page: "general/alert_enterprise", + message: elem + }, + function(data, status) { + $("#alert_messages").show(); + $("#alert_messages") + .empty() + .append(data); + $("#alert_messages").css("opacity", 1); + }, + "html" + ); + return false; + }); - // Creacion de ventana modal y botones - $(".publienterprise").click (function () { - var elem = $(this).attr("id"); - $('body').append( "
" ); - $("#opacidad").css('opacity', 0.5); + // Creacion de ventana modal y botones + $(".publienterprise").click(function() { + var elem = $(this).attr("id"); + $("body").append( + "
" + ); + $("#opacidad").css("opacity", 0.5); - jQuery.post ("ajax.php", - { - "page": "general/alert_enterprise", - "message": elem - }, - function (data, status) { - $("#alert_messages").show(); - $("#alert_messages").empty ().append (data); - $("#alert_messages").css('opacity', 1); - }, - "html" - ); - return false; - }); - - - $(".publienterprisehide").click (function () { - var elem = $(this).attr("id"); - $('body').append( "
" ); - $("#opacidad").css('opacity', 0.5); + jQuery.post( + "ajax.php", + { + page: "general/alert_enterprise", + message: elem + }, + function(data, status) { + $("#alert_messages").show(); + $("#alert_messages") + .empty() + .append(data); + $("#alert_messages").css("opacity", 1); + }, + "html" + ); + return false; + }); - jQuery.post ("ajax.php", - { - "page": "general/alert_enterprise", - "message": elem - }, - function (data, status) { - $("#alert_messages").show(); - $("#alert_messages").empty ().append (data); - $("#alert_messages").css('opacity', 1); - }, - "html" - ); - return false; - }); + $(".publienterprisehide").click(function() { + var elem = $(this).attr("id"); + $("body").append( + "
" + ); + $("#opacidad").css("opacity", 0.5); + jQuery.post( + "ajax.php", + { + page: "general/alert_enterprise", + message: elem + }, + function(data, status) { + $("#alert_messages").show(); + $("#alert_messages") + .empty() + .append(data); + $("#alert_messages").css("opacity", 1); + }, + "html" + ); + return false; + }); + if ($("#license_error_msg_dialog").length) { + if (typeof process_login_ok == "undefined") process_login_ok = 0; - if ($('#license_error_msg_dialog').length) { - if (typeof(process_login_ok) == "undefined") - process_login_ok = 0; + if (typeof show_error_license == "undefined") show_error_license = 0; - if (typeof(show_error_license) == "undefined") - show_error_license = 0; + if (process_login_ok || show_error_license) { + $("#license_error_msg_dialog").dialog({ + dialogClass: "no-close", + closeOnEscape: false, + resizable: false, + draggable: true, + modal: true, + height: 470, + width: 850, + overlay: { + opacity: 0.5, + background: "black" + }, + open: function() { + var remaining = 30; - if (process_login_ok || show_error_license) { + // Timeout counter. + var count = function() { + if (remaining > 0) { + $("#license_error_remaining").text(remaining); + remaining -= 1; + } else { + $("#license_error_remaining").hide(); + $("#ok_buttom").show(); + clearInterval(count); + } + }; - $( "#license_error_msg_dialog" ).dialog({ - dialogClass: "no-close", - closeOnEscape: false, - resizable: false, - draggable: true, - modal: true, - height: 450, - width: 850, - overlay: { - opacity: 0.5, - background: "black" - }, - open: function() { - var remaining = 30; + setInterval(count, 1000); + } + }); - // Timeout counter. - var count = function() { - if (remaining > 0) { - $("#license_error_remaining").text(remaining); - remaining -= 1; - } else { - $("#license_error_remaining").hide(); - $("#ok_buttom").show(); - clearInterval(count); - } - } + $("#submit-hide-license-error-msg").click(function() { + $("#license_error_msg_dialog").dialog("close"); + }); + } + } - setInterval(count, 1000); - } - }); + if ($("#msg_change_password").length) { + $("#msg_change_password").dialog({ + resizable: false, + draggable: true, + modal: true, + height: 450, + width: 620, + overlay: { + opacity: 0.5, + background: "black" + } + }); + } - $("#submit-hide-license-error-msg").click (function () { - $("#license_error_msg_dialog" ).dialog('close') - }); + if ($("#login_blocked").length) { + $("#login_blocked").dialog({ + resizable: true, + draggable: true, + modal: true, + height: 200, + width: 520, + overlay: { + opacity: 0.5, + background: "black" + } + }); + } - } - } + if ($("#login_correct_pass").length) { + $("#login_correct_pass").dialog({ + resizable: true, + draggable: true, + modal: true, + height: 200, + width: 520, + overlay: { + opacity: 0.5, + background: "black" + } + }); + } + forced_title_callback(); - if ($('#msg_change_password').length) { + $(document).on("scroll", function() { + if ( + document.documentElement.scrollTop != 0 || + document.body.scrollTop != 0 + ) { + if ($("#head").css("position") == "fixed") { + if ($("#menu").css("position") == "fixed") { + $("#menu").css("top", "80px"); + } else { + $("#menu").css("top", "60px"); + } + } else { + if ($("#menu").css("position") == "fixed") { + $("#menu").css("top", "20px"); + } else { + $("#menu").css("top", "80px"); + } + } + } else { + if ($("#head").css("position") == "fixed") { + if ($("#menu").css("position") == "fixed") { + $("#menu").css("top", "80px"); + } else { + $("#menu").css("top", "60px"); + } + } else { + if ($("#menu").css("position") == "fixed") { + $("#menu").css("top", "80px"); + } else { + $("#menu").css("top", "80px"); + } + } + } - $( "#msg_change_password" ).dialog({ - resizable: false, - draggable: true, - modal: true, - height: 350, - width: 620, - overlay: { - opacity: 0.5, - background: "black" - } - }); + // if((document.documentElement.scrollTop != 0 || document.body.scrollTop != 0) && $('#menu').css('position') =='fixed'){ + // if($('#head').css('position') =='fixed'){ + // $('#menu').css('top','80px'); + // } + // else{ + // $('#menu').css('top','20px'); + // } + // } + // else{ + // if($('#head').css('position') =='fixed'){ + // if(document.documentElement.scrollTop != 0 || document.body.scrollTop != 0){ + // $('#menu').css('top','60px'); + // }else{ + // $('#menu').css('top','80px'); + // } + // + // } + // else{ + // $('#menu').css('top','60px'); + // } + // } + }); - } - - if ($('#login_blocked').length) { - - $( "#login_blocked" ).dialog({ - resizable: true, - draggable: true, - modal: true, - height: 200, - width: 520, - overlay: { - opacity: 0.5, - background: "black" - } - }); - - } - - if ($('#login_correct_pass').length) { - - $( "#login_correct_pass" ).dialog({ - resizable: true, - draggable: true, - modal: true, - height: 200, - width: 520, - overlay: { - opacity: 0.5, - background: "black" - } - }); - - } - - forced_title_callback(); - - - $(document).on("scroll", function(){ - - if(document.documentElement.scrollTop != 0 || document.body.scrollTop != 0){ - if($('#head').css('position') =='fixed'){ - if($('#menu').css('position') =='fixed'){ - $('#menu').css('top','80px'); - } else { - $('#menu').css('top','60px'); - } - } else { - if($('#menu').css('position') =='fixed'){ - $('#menu').css('top','20px'); - } else { - $('#menu').css('top','80px'); - } - } - } else { - if($('#head').css('position') =='fixed'){ - if($('#menu').css('position') =='fixed'){ - $('#menu').css('top','80px'); - } else { - $('#menu').css('top','60px'); - } - } else { - if($('#menu').css('position') =='fixed'){ - $('#menu').css('top','80px'); - } else { - $('#menu').css('top','80px'); - } - } - } - - // if((document.documentElement.scrollTop != 0 || document.body.scrollTop != 0) && $('#menu').css('position') =='fixed'){ - // if($('#head').css('position') =='fixed'){ - // $('#menu').css('top','80px'); - // } - // else{ - // $('#menu').css('top','20px'); - // } - // } - // else{ - // if($('#head').css('position') =='fixed'){ - // if(document.documentElement.scrollTop != 0 || document.body.scrollTop != 0){ - // $('#menu').css('top','60px'); - // }else{ - // $('#menu').css('top','80px'); - // } - // - // } - // else{ - // $('#menu').css('top','60px'); - // } - // } - }); - - $("#alert_messages").draggable(); - $("#alert_messages").css({'left':+parseInt(screen.width/2)-parseInt($("#alert_messages").css('width'))/2+'px'}); - + $("#alert_messages").draggable(); + $("#alert_messages").css({ + left: + +parseInt(screen.width / 2) - + parseInt($("#alert_messages").css("width")) / 2 + + "px" + }); }); - - - function forced_title_callback() { - // Forced title code - $('body').on('mouseenter', '.forced_title', function() { - /////////////////////////////////////////// - // Put the layer in the left-top corner to fill it - /////////////////////////////////////////// - $('#forced_title_layer').css('left', 0); - $('#forced_title_layer').css('top', 0); + // Forced title code + $("body").on("mouseenter", ".forced_title", function() { + /////////////////////////////////////////// + // Put the layer in the left-top corner to fill it + /////////////////////////////////////////// + $("#forced_title_layer").css("left", 0); + $("#forced_title_layer").css("top", 0); - /////////////////////////////////////////// - // Get info of the image - /////////////////////////////////////////// + /////////////////////////////////////////// + // Get info of the image + /////////////////////////////////////////// - var img_top = $(this).offset().top; - var img_width = $(this).width(); - var img_height = $(this).height(); - var img_id = $(this).attr('id'); - var img_left_mid = $(this).offset().left + (img_width / 2); + var img_top = $(this).offset().top; + var img_width = $(this).width(); + var img_height = $(this).height(); + var img_id = $(this).attr("id"); + var img_left_mid = $(this).offset().left + img_width / 2; - /////////////////////////////////////////// - // Put title in the layer - /////////////////////////////////////////// + /////////////////////////////////////////// + // Put title in the layer + /////////////////////////////////////////// - // If the '.forced_title' element has 'use_title_for_force_title' = 1 - // into their 'data' prop, the element title will be used for the - // content. - if ($(this).data("use_title_for_force_title")) { - var title = $(this).data("title"); - } - else { - var title = $('#forced_title_'+img_id).html(); - } + // If the '.forced_title' element has 'use_title_for_force_title' = 1 + // into their 'data' prop, the element title will be used for the + // content. + if ($(this).data("use_title_for_force_title")) { + var title = $(this).data("title"); + } else { + var title = $("#forced_title_" + img_id).html(); + } - $('#forced_title_layer').html(title); + $("#forced_title_layer").html(title); - /////////////////////////////////////////// - // Get info of the layer - /////////////////////////////////////////// + /////////////////////////////////////////// + // Get info of the layer + /////////////////////////////////////////// - var layer_width = $('#forced_title_layer').width(); - var layer_height = $('#forced_title_layer').height(); + var layer_width = $("#forced_title_layer").width(); + var layer_height = $("#forced_title_layer").height(); - /////////////////////////////////////////// - // Obtain the new position of the layer - /////////////////////////////////////////// + /////////////////////////////////////////// + // Obtain the new position of the layer + /////////////////////////////////////////// - // Jquery doesnt know the padding of the layer - var layer_padding = 4; + // Jquery doesnt know the padding of the layer + var layer_padding = 4; - // Deduct padding of both sides - var layer_top = img_top - layer_height - (layer_padding * 2) - 5; - if (layer_top < 0) { - layer_top = img_top + img_height + (layer_padding * 2); - } + // Deduct padding of both sides + var layer_top = img_top - layer_height - layer_padding * 2 - 5; + if (layer_top < 0) { + layer_top = img_top + img_height + layer_padding * 2; + } - // Deduct padding of one side - var layer_left = img_left_mid - (layer_width / 2) - layer_padding; - if (layer_left < 0) { - layer_left = 0; - } + // Deduct padding of one side + var layer_left = img_left_mid - layer_width / 2 - layer_padding; + if (layer_left < 0) { + layer_left = 0; + } - var real_layer_width = layer_width + (layer_padding * 2) + 5; - var layer_right = layer_left + real_layer_width; - var screen_width = $(window).width(); - if (screen_width < layer_right) { - layer_left = screen_width - real_layer_width; - } + var real_layer_width = layer_width + layer_padding * 2 + 5; + var layer_right = layer_left + real_layer_width; + var screen_width = $(window).width(); + if (screen_width < layer_right) { + layer_left = screen_width - real_layer_width; + } - /////////////////////////////////////////// - // Set the layer position and show - /////////////////////////////////////////// + /////////////////////////////////////////// + // Set the layer position and show + /////////////////////////////////////////// - $('#forced_title_layer').css('left', layer_left); - $('#forced_title_layer').css('top', layer_top); - $('#forced_title_layer').show(); - }); - $('body').on('mouseout', '.forced_title', function () { - $('#forced_title_layer').hide().empty(); - }); + $("#forced_title_layer").css("left", layer_left); + $("#forced_title_layer").css("top", layer_top); + $("#forced_title_layer").show(); + }); + $("body").on("mouseout", ".forced_title", function() { + $("#forced_title_layer") + .hide() + .empty(); + }); } - From 5998b30a161d95cac697f43084e17f405ea2d7b3 Mon Sep 17 00:00:00 2001 From: Luis Calvo Date: Wed, 10 Apr 2019 17:30:35 +0200 Subject: [PATCH 07/92] Added css hint to discovery tasks when task list is empty Former-commit-id: 1da71cda1b1ed376bb6bae0281b0dd882dbfbeff --- pandora_console/general/firts_task/recon_view.php | 1 + pandora_console/godmode/servers/discovery.php | 5 +++++ pandora_console/include/styles/discovery-hint.css | 10 ++++++++++ 3 files changed, 16 insertions(+) create mode 100644 pandora_console/include/styles/discovery-hint.css diff --git a/pandora_console/general/firts_task/recon_view.php b/pandora_console/general/firts_task/recon_view.php index 282a6b75be..8c59b23f64 100755 --- a/pandora_console/general/firts_task/recon_view.php +++ b/pandora_console/general/firts_task/recon_view.php @@ -35,6 +35,7 @@ ui_require_css_file('firts_task');

+
diff --git a/pandora_console/godmode/servers/discovery.php b/pandora_console/godmode/servers/discovery.php index d9e19abdff..e20588b97d 100755 --- a/pandora_console/godmode/servers/discovery.php +++ b/pandora_console/godmode/servers/discovery.php @@ -130,5 +130,10 @@ if ($classname_selected === null) { } } + // Show hints if there is no task + if (get_parameter('discovery_hint', 0)) { + ui_require_css_file('discovery-hint'); + } + Wizard::printBigButtonsList($wiz_data); } diff --git a/pandora_console/include/styles/discovery-hint.css b/pandora_console/include/styles/discovery-hint.css new file mode 100644 index 0000000000..8247b26c96 --- /dev/null +++ b/pandora_console/include/styles/discovery-hint.css @@ -0,0 +1,10 @@ +/* + * Discovery show help css + */ +li.discovery:not(:first-child) > a:hover { + color: #000; +} + +li.discovery:not(:first-child) div.data_container:not(:hover) { + box-shadow: 2px 2px 10px #80ba27; +} From 6276936e1d30fffe29cb4e2e0fa1122e0d7d247e Mon Sep 17 00:00:00 2001 From: Luis Calvo Date: Wed, 10 Apr 2019 17:51:50 +0200 Subject: [PATCH 08/92] Added info message Former-commit-id: 11f4c9c8b52f6ef3bed2236534010f2caa3bb8e0 --- pandora_console/godmode/servers/discovery.php | 1 + 1 file changed, 1 insertion(+) diff --git a/pandora_console/godmode/servers/discovery.php b/pandora_console/godmode/servers/discovery.php index e20588b97d..a2c0abd5d6 100755 --- a/pandora_console/godmode/servers/discovery.php +++ b/pandora_console/godmode/servers/discovery.php @@ -133,6 +133,7 @@ if ($classname_selected === null) { // Show hints if there is no task if (get_parameter('discovery_hint', 0)) { ui_require_css_file('discovery-hint'); + ui_print_info_message(__('You must create a task first')); } Wizard::printBigButtonsList($wiz_data); From 553ec48f5451a331f33e292ee37ff14bbe88bc57 Mon Sep 17 00:00:00 2001 From: "marcos.alconada" Date: Mon, 15 Apr 2019 15:21:07 +0200 Subject: [PATCH 09/92] changed title plugin creation to plugin registration Former-commit-id: bd5ee299d91c52d3064eafa85b092b525b70381a --- pandora_console/godmode/servers/plugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/godmode/servers/plugin.php b/pandora_console/godmode/servers/plugin.php index b04643e1c3..5ff8022afa 100644 --- a/pandora_console/godmode/servers/plugin.php +++ b/pandora_console/godmode/servers/plugin.php @@ -281,7 +281,7 @@ if (($create != '') || ($view != '')) { } else { if ($create != '') { ui_print_page_header( - __('Plugin creation'), + __('Plugin registration'), 'images/gm_servers.png', false, 'plugin_definition', From d5ac57064bf3deceef1c99cdcc229afe7029c480 Mon Sep 17 00:00:00 2001 From: "marcos.alconada" Date: Wed, 29 May 2019 11:34:23 +0200 Subject: [PATCH 10/92] Condition is added to keep the selection color in the main menu --- pandora_console/include/functions_menu.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pandora_console/include/functions_menu.php b/pandora_console/include/functions_menu.php index 0dbe1049bc..e26acd5cac 100644 --- a/pandora_console/include/functions_menu.php +++ b/pandora_console/include/functions_menu.php @@ -50,6 +50,12 @@ function menu_print_menu(&$menu) $sec = (string) get_parameter('sec'); $sec2 = (string) get_parameter('sec2'); + if ($sec2 == 'operation/agentes/ver_agente') { + $sec2 = 'godmode/agentes/configurar_agente'; + } else { + $sec2 = (string) get_parameter('sec2'); + } + $menu_selected = false; $allsec2 = explode('sec2=', $_SERVER['REQUEST_URI']); From 78e01d9c7dfde80a2416bfdc836824fa9d768202 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Mon, 10 Jun 2019 13:04:52 +0200 Subject: [PATCH 11/92] Added encode --- .../rest-api/models/VisualConsole/Item.php | 471 +++++++++++++++++- 1 file changed, 464 insertions(+), 7 deletions(-) diff --git a/pandora_console/include/rest-api/models/VisualConsole/Item.php b/pandora_console/include/rest-api/models/VisualConsole/Item.php index 617b48e517..ebb6fd10f0 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Item.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Item.php @@ -240,7 +240,7 @@ class Item extends CachedModel private static function extractX(array $data): int { return static::parseIntOr( - static::issetInArray($data, ['x', 'pos_x']), + static::issetInArray($data, ['x', 'pos_x', 'posX']), 0 ); } @@ -256,7 +256,7 @@ class Item extends CachedModel private static function extractY(array $data): int { return static::parseIntOr( - static::issetInArray($data, ['y', 'pos_y']), + static::issetInArray($data, ['y', 'pos_y', 'posY']), 0 ); } @@ -272,7 +272,7 @@ class Item extends CachedModel private static function extractAclGroupId(array $data) { return static::parseIntOr( - static::issetInArray($data, ['id_group', 'aclGroupId']), + static::issetInArray($data, ['id_group', 'aclGroupId', 'idGroup']), null ); } @@ -288,7 +288,7 @@ class Item extends CachedModel private static function extractParentId(array $data) { return static::parseIntOr( - static::issetInArray($data, ['parentId', 'parent_item']), + static::issetInArray($data, ['parentId', 'parent_item', 'parentItem']), null ); } @@ -304,7 +304,7 @@ class Item extends CachedModel private static function extractIsOnTop(array $data): bool { return static::parseBool( - static::issetInArray($data, ['isOnTop', 'show_on_top']) + static::issetInArray($data, ['isOnTop', 'show_on_top', 'showOnTop']) ); } @@ -319,7 +319,7 @@ class Item extends CachedModel private static function extractIsLinkEnabled(array $data): bool { return static::parseBool( - static::issetInArray($data, ['isLinkEnabled', 'enable_link']) + static::issetInArray($data, ['isLinkEnabled', 'enable_link', 'enableLink']) ); } @@ -376,7 +376,23 @@ class Item extends CachedModel private static function extractAgentId(array $data) { return static::parseIntOr( - static::issetInArray($data, ['agentId', 'id_agent', 'id_agente']), + static::issetInArray($data, ['agentId', 'id_agent', 'id_agente', 'idAgent', 'idAgente']), + null + ); + } + + + /** + * Extract a custom id graph value. + * + * @param array $data Unknown input data structure. + * + * @return integer Valid identifier of an agent. + */ + private static function extractIdCustomGraph(array $data) + { + return static::parseIntOr( + static::issetInArray($data, ['id_custom_graph', 'idCustomGraph', 'customGraphId']), null ); } @@ -398,6 +414,9 @@ class Item extends CachedModel 'moduleId', 'id_agente_modulo', 'id_modulo', + 'idModulo', + 'idAgenteModulo', + 'idAgentModule', ] ), null @@ -1187,4 +1206,442 @@ class Item extends CachedModel } + /** + * Return a valid representation of a record in database. + * + * @param array $data Input data. + * + * @return array Data structure representing a record in database. + */ + protected function encode(array $data): array + { + $result = []; + + $id = static::extractId($data); + if ($id) { + $result['id'] = $id; + } + + $id_layout = static::extractIdLayout($data); + if ($id_layout) { + $result['id_layout'] = $id_layout; + } + + $pos_x = static::parseIntOr( + static::issetInArray($data, ['x', 'pos_x', 'posX']), + null + ); + if ($pos_x !== null) { + $result['pos_x'] = $pos_x; + } + + $pos_y = static::parseIntOr( + static::issetInArray($data, ['y', 'pos_y', 'posY']), + null + ); + if ($pos_y !== null) { + $result['pos_y'] = $pos_y; + } + + $height = static::extractHeight($data); + if ($height !== null) { + $result['height'] = $height; + } + + $width = static::extractWidth($data); + if ($width !== null) { + $result['width'] = $width; + } + + $label = static::extractLabel($data); + if ($label !== null) { + $result['label'] = $label; + } + + $image = static::extractImageSrc($data); + if ($image !== null) { + $result['image'] = $image; + } + + $type = static::parseIntOr( + static::issetInArray($data, ['type']), + null + ); + if ($type !== null) { + $result['type'] = $type; + } + + $period = static::parseIntOr( + static::issetInArray($data, ['period']), + null + ); + if ($period !== null) { + $result['period'] = $period; + } + + $id_agente_modulo = static::extractModuleId($data); + if ($id_agente_modulo !== null) { + $result['id_agente_modulo'] = $id_agente_modulo; + } + + $id_agent = static::extractAgentId($data); + if ($id_agent !== null) { + $result['id_agent'] = $id_agent; + } + + $id_layout_linked = static::parseIntOr( + static::issetInArray($data, ['linkedLayoutId', 'id_layout_linked', 'idLayoutLinked']), + null + ); + if ($id_layout_linked !== null) { + $result['id_layout_linked'] = $id_layout_linked; + } + + $parent_item = static::extractParentId($data); + if ($parent_item !== null) { + $result['parent_item'] = $parent_item; + } + + $enable_link = static::issetInArray($data, ['isLinkEnabled', 'enable_link', 'enableLink']); + if ($enable_link !== null) { + $result['enable_link'] = static::parseBool($enable_link); + } + + $id_metaconsole = static::extractMetaconsoleId($data); + if ($id_metaconsole !== null) { + $result['id_metaconsole'] = $id_metaconsole; + } + + $id_group = static::extractAclGroupId($data); + if ($id_group !== null) { + $result['id_group'] = $id_group; + } + + $id_custom_graph = static::extractIdCustomGraph($data); + if ($id_custom_graph !== null) { + $result['id_custom_graph'] = $id_custom_graph; + } + + $border_width = static::extractBorderWidth($data); + if ($border_width !== null) { + $result['border_width'] = $border_width; + } + + $type_graph = static::extractTypeGraph($data); + if ($type_graph !== null) { + $result['type_graph'] = $type_graph; + } + + $label_position = static::notEmptyStringOr( + static::issetInArray($data, ['labelPosition', 'label_position']), + null + ); + if ($label_position !== null) { + $result['label_position'] = $label_position; + } + + $border_color = static::extractBorderColor($data); + if ($border_color !== null) { + $result['border_color'] = $border_color; + } + + $fill_color = static::extractFillColor($data); + if ($fill_color !== null) { + $result['fill_color'] = $fill_color; + } + + $show_statistics = static::issetInArray($data, ['showStatistics', 'show_statistics']); + if ($show_statistics !== null) { + $result['show_statistics'] = static::parseBool($show_statistics); + } + + $linked_layout_node_id = static::parseIntOr( + static::issetInArray( + $data, + [ + 'linkedLayoutAgentId', + 'linked_layout_node_id', + ] + ), + null + ); + if ($linked_layout_node_id !== null) { + $result['linked_layout_node_id'] = $linked_layout_node_id; + } + + $linked_layout_status_type = static::notEmptyStringOr( + static::issetInArray($data, ['linkedLayoutStatusType', 'linked_layout_status_type']), + null + ); + if ($linked_layout_status_type !== null) { + $result['linked_layout_status_type'] = $linked_layout_status_type; + } + + $id_layout_linked_weight = static::parseIntOr( + static::issetInArray($data, ['linkedLayoutStatusTypeWeight', 'id_layout_linked_weight']), + null + ); + if ($id_layout_linked_weight !== null) { + $result['id_layout_linked_weight'] = $id_layout_linked_weight; + } + + $linked_layout_status_as_service_warning = static::parseIntOr( + static::issetInArray( + $data, + [ + 'linkedLayoutStatusTypeWarningThreshold', + 'linked_layout_status_as_service_warning', + ] + ), + null + ); + if ($linked_layout_status_as_service_warning !== null) { + $result['linked_layout_status_as_service_warning'] = $linked_layout_status_as_service_warning; + } + + $linked_layout_status_as_service_critical = static::parseIntOr( + static::issetInArray( + $data, + [ + 'linkedLayoutStatusTypeCriticalThreshold', + 'linked_layout_status_as_service_critical', + ] + ), + null + ); + if ($linked_layout_status_as_service_critical !== null) { + $result['linked_layout_status_as_service_critical'] = $linked_layout_status_as_service_critical; + } + + $element_group = static::parseIntOr( + static::issetInArray($data, ['elementGroup', 'element_group']), + null + ); + if ($element_group !== null) { + $result['element_group'] = $element_group; + } + + $show_on_top = static::issetInArray($data, ['isOnTop', 'show_on_top', 'showOnTop']); + if ($show_on_top !== null) { + $result['show_on_top'] = static::parseBool($show_on_top); + } + + $clock_animation = static::notEmptyStringOr( + static::issetInArray($data, ['clockType', 'clock_animation', 'clockAnimation']), + null + ); + if ($clock_animation !== null) { + $result['clock_animation'] = $clock_animation; + } + + $time_format = static::notEmptyStringOr( + static::issetInArray($data, ['clockFormat', 'time_format', 'timeFormat']), + null + ); + if ($time_format !== null) { + $result['time_format'] = $time_format; + } + + $timezone = static::notEmptyStringOr( + static::issetInArray($data, ['timezone', 'timeZone', 'time_zone']), + null + ); + if ($timezone !== null) { + $result['timezone'] = $timezone; + } + + $show_last_value = static::parseIntOr( + static::issetInArray($data, ['show_last_value', 'showLastValue']), + null + ); + if ($show_last_value !== null) { + $result['show_last_value'] = $show_last_value; + } + + $cache_expiration = static::parseIntOr( + static::issetInArray($data, ['cache_expiration', 'cacheExpiration']), + null + ); + if ($cache_expiration !== null) { + $result['cache_expiration'] = $cache_expiration; + } + + return $result; + } + + + /** + * Extract item id. + * + * @param array $data Unknown input data structure. + * + * @return integer Item id. 0 by default. + */ + private static function extractId(array $data): integer + { + return static::parseIntOr( + static::issetInArray($data, ['id', 'itemId']), + 0 + ); + } + + + /** + * Extract layout id. + * + * @param array $data Unknown input data structure. + * + * @return integer Item id. 0 by default. + */ + private static function extractIdLayout(array $data): integer + { + return static::parseIntOr( + static::issetInArray($data, ['id_layout', 'idLayout', 'layoutId']), + 0 + ); + } + + + /** + * Extract item width. + * + * @param array $data Unknown input data structure. + * + * @return integer Item width. 0 by default. + */ + private static function extractWidth(array $data): integer + { + return static::parseIntOr( + static::issetInArray($data, ['width']), + null + ); + } + + + /** + * Extract item height. + * + * @param array $data Unknown input data structure. + * + * @return integer Item height. 0 by default. + */ + private static function extractHeight(array $data): integer + { + return static::parseIntOr( + static::issetInArray($data, ['height']), + null + ); + } + + + /** + * Extract a image src value. + * + * @param array $data Unknown input data structure. + * + * @return mixed String representing the image url (not empty) or null. + */ + private static function extractImageSrc(array $data): string + { + $imageSrc = static::notEmptyStringOr( + static::issetInArray($data, ['imageSrc', 'image']), + null + ); + + return $imageSrc; + } + + + /** + * Extract a border width value. + * + * @param array $data Unknown input data structure. + * + * @return integer Valid border width. + */ + private static function extractBorderWidth(array $data) + { + return static::parseIntOr( + static::issetInArray($data, ['border_width', 'borderWidth']), + null + ); + } + + + /** + * Extract a type graph value. + * + * @param array $data Unknown input data structure. + * + * @return string One of 'vertical' or 'horizontal'. 'vertical' by default. + */ + private static function extractTypeGraph(array $data): string + { + return static::notEmptyStringOr( + static::issetInArray($data, ['typeGraph', 'type_graph']), + null + ); + } + + + /** + * Extract a border color value. + * + * @param array $data Unknown input data structure. + * + * @return mixed String representing the border color (not empty) or null. + */ + private function extractBorderColor(array $data) + { + return static::notEmptyStringOr( + static::issetInArray($data, ['borderColor', 'border_color']), + null + ); + } + + + /** + * Extract a fill color value. + * + * @param array $data Unknown input data structure. + * + * @return mixed String representing the fill color (not empty) or null. + */ + private function extractFillColor(array $data) + { + return static::notEmptyStringOr( + static::issetInArray($data, ['fillColor', 'fill_color']), + null + ); + } + + + /** + * . + * + * @param array $data Unknown input data structure. + * + * @return boolean The modeled element data structure stored into the DB. + */ + public function save(array $data=[]): boolean + { + $mergedData = \array_merge(static::data, $data); + + $save = static::encode($mergedData); + + if (empty($save['id'])) { + // Insert. + $result = db_process_sql_insert('tlayout_data', $save); + } else { + // Update. + $result = db_process_sql_update('tlayout_data', $save, ['id' => $save['id']]); + } + + if ($result) { + } + + return $result; + } + + } From 2b17953e419ae3deed604c510eaf25185ed628ab Mon Sep 17 00:00:00 2001 From: Alejandro Gallardo Escobar Date: Tue, 11 Jun 2019 15:08:10 +0200 Subject: [PATCH 12/92] Added a move cursor to the editing state style --- visual_console_client/src/main.css | 1 + 1 file changed, 1 insertion(+) diff --git a/visual_console_client/src/main.css b/visual_console_client/src/main.css index 95217070c2..b737d1768a 100644 --- a/visual_console_client/src/main.css +++ b/visual_console_client/src/main.css @@ -18,4 +18,5 @@ .visual-console-item.is-editing { border: 2px dashed #33ccff; transform: translateX(-2px) translateY(-2px); + cursor: move; } From 8868c64f3dd3f349c933366c3ffdd8384bcd65b9 Mon Sep 17 00:00:00 2001 From: Alejandro Gallardo Escobar Date: Tue, 11 Jun 2019 15:19:27 +0200 Subject: [PATCH 13/92] Minor change --- visual_console_client/src/VisualConsole.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/visual_console_client/src/VisualConsole.ts b/visual_console_client/src/VisualConsole.ts index 091cc08f92..63e46771c0 100644 --- a/visual_console_client/src/VisualConsole.ts +++ b/visual_console_client/src/VisualConsole.ts @@ -571,6 +571,7 @@ export default class VisualConsole { this.elements.forEach(item => { item.meta = { ...item.meta, editMode: true }; }); + this.containerRef.classList.add("is-editing"); } /** @@ -580,5 +581,6 @@ export default class VisualConsole { this.elements.forEach(item => { item.meta = { ...item.meta, editMode: false }; }); + this.containerRef.classList.remove("is-editing"); } } From f1ed4bddb292f31328496d0dbdf67e688e89a1c8 Mon Sep 17 00:00:00 2001 From: Alejandro Gallardo Escobar Date: Tue, 11 Jun 2019 15:25:04 +0200 Subject: [PATCH 14/92] Added a throttle and debounce utils. Added a function to move an element --- visual_console_client/src/lib/index.ts | 184 +++++++++++++++++++++++++ 1 file changed, 184 insertions(+) diff --git a/visual_console_client/src/lib/index.ts b/visual_console_client/src/lib/index.ts index 65f0a1ab86..6a7bf89909 100644 --- a/visual_console_client/src/lib/index.ts +++ b/visual_console_client/src/lib/index.ts @@ -374,3 +374,187 @@ export function replaceMacros(macros: Macro[], text: string): string { text ); } + +/** + * Create a function which will limit the rate of execution of + * the selected function to one time for the selected interval. + * @param delay Interval. + * @param fn Function to be executed at a limited rate. + */ +export function throttle(delay: number, fn: (...args: T[]) => R) { + let last = 0; + return (...args: T[]) => { + const now = Date.now(); + if (now - last < delay) return; + last = now; + return fn(...args); + }; +} + +/** + * Create a function which will call the selected function only + * after the interval time has passed after its last execution. + * @param delay Interval. + * @param fn Function to be executed after the last call. + */ +export function debounce(delay: number, fn: (...args: T[]) => void) { + let timerRef: number | null = null; + return (...args: T[]) => { + if (timerRef !== null) window.clearTimeout(timerRef); + timerRef = window.setTimeout(() => { + fn(...args); + timerRef = null; + }, delay); + }; +} + +/** + * Retrieve the offset of an element relative to the page. + * @param el Node used to calculate the offset. + */ +function getOffset(el: HTMLElement | null) { + let x = 0; + let y = 0; + while (el && !Number.isNaN(el.offsetLeft) && !Number.isNaN(el.offsetTop)) { + x += el.offsetLeft - el.scrollLeft; + y += el.offsetTop - el.scrollTop; + el = el.offsetParent as HTMLElement | null; + } + return { top: y, left: x }; +} + +/** + * Add the grab & move functionality to a certain element inside it's container. + * + * @param element Element to move. + * @param onMoved Function to execute when the element moves. + * + * @return A function which will clean the event handlers when executed. + */ +export function addMovementListener( + element: HTMLElement, + onMoved: (x: Position["x"], y: Position["y"]) => void +): Function { + const container = element.parentElement as HTMLElement; + // Store the initial draggable state. + const isDraggable = element.draggable; + // Init the coordinates. + let lastX: Position["x"] = 0; + let lastY: Position["y"] = 0; + let lastMouseX: Position["x"] = 0; + let lastMouseY: Position["y"] = 0; + let mouseElementOffsetX: Position["x"] = 0; + let mouseElementOffsetY: Position["y"] = 0; + // Bounds. + let containerBounds = container.getBoundingClientRect(); + let containerTop = getOffset(container).top; + let containerBottom = containerTop + containerBounds.height; + let containerLeft = getOffset(container).left; + let containerRight = containerLeft + containerBounds.width; + let elementBounds = element.getBoundingClientRect(); + let borderWidth = window.getComputedStyle(element).borderWidth || "0"; + let borderFix = Number.parseInt(borderWidth) * 2; + + // Will run onMoved 32ms after its last execution. + const debouncedMovement = debounce(32, (x: Position["x"], y: Position["y"]) => + onMoved(x, y) + ); + // Will run onMoved one time max every 16ms. + const throttledMovement = throttle(16, (x: Position["x"], y: Position["y"]) => + onMoved(x, y) + ); + + const handleMove = (e: MouseEvent) => { + // Calculate the new element coordinates. + let x = 0; + let y = 0; + + // TODO: Document. + + if (e.pageX < containerLeft) x = 0; + else if (e.pageX > containerRight) x = containerBounds.width; + else x = e.pageX - lastMouseX + lastX; + + if (e.pageY < containerTop) y = 0; + else if (e.pageY > containerBottom) + y = containerBounds.height - elementBounds.height + borderFix; + else y = e.pageY - lastMouseY + lastY; + + if (x < 0) x = 0; + else if (x + elementBounds.width - borderFix > containerBounds.width) + x = containerBounds.width - elementBounds.width + borderFix; + + if (y < 0) y = 0; + else if (y + elementBounds.height - borderFix > containerBounds.height) + y = containerBounds.height - elementBounds.height + borderFix; + + // Run the movement events. + throttledMovement(x, y); + debouncedMovement(x, y); + + // Store the coordinates of the element. + lastX = x; + lastY = y; + // Store the last mouse coordinates. + lastMouseX = e.pageX; + lastMouseY = e.pageY; + }; + const handleEnd = () => { + // Reset the positions. + lastX = 0; + lastY = 0; + lastMouseX = 0; + lastMouseY = 0; + // Remove the move event. + document.removeEventListener("mousemove", handleMove); + // Clean itself. + document.removeEventListener("mouseup", handleEnd); + // Reset the draggable property to its initial state. + element.draggable = isDraggable; + // Reset the body selection property to a default state. + document.body.style.userSelect = "auto"; + }; + const handleStart = (e: MouseEvent) => { + e.stopPropagation(); + + // Disable the drag temporarily. + element.draggable = false; + + // Store the difference between the cursor and + // the initial coordinates of the element. + lastX = element.offsetLeft; + lastY = element.offsetTop; + // Store the mouse position. + lastMouseX = e.pageX; + lastMouseY = e.pageY; + // Store the relative position between the mouse and the element. + mouseElementOffsetX = e.offsetX; + mouseElementOffsetY = e.offsetY; + + // Initialize the bounds. + containerBounds = container.getBoundingClientRect(); + containerTop = getOffset(container).top; + containerBottom = containerTop + containerBounds.height; + containerLeft = getOffset(container).left; + containerRight = containerLeft + containerBounds.width; + elementBounds = element.getBoundingClientRect(); + borderWidth = window.getComputedStyle(element).borderWidth || "0"; + borderFix = Number.parseInt(borderWidth) * 2; + + // Listen to the mouse movement. + document.addEventListener("mousemove", handleMove); + // Listen to the moment when the mouse click is not pressed anymore. + document.addEventListener("mouseup", handleEnd); + // Limit the mouse selection of the body. + document.body.style.userSelect = "none"; + }; + + // Event to listen the init of the movement. + element.addEventListener("mousedown", handleStart); + + // Returns a function to clean the event listeners. + return () => { + element.removeEventListener("mousedown", handleStart); + handleEnd(); + }; +} From 4815d73149a555374ebc8774cfc0deff210100ee Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Tue, 11 Jun 2019 15:26:10 +0200 Subject: [PATCH 15/92] Update --- .../rest-api/models/VisualConsole/Item.php | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/pandora_console/include/rest-api/models/VisualConsole/Item.php b/pandora_console/include/rest-api/models/VisualConsole/Item.php index ebb6fd10f0..373afe5f37 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Item.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Item.php @@ -240,7 +240,7 @@ class Item extends CachedModel private static function extractX(array $data): int { return static::parseIntOr( - static::issetInArray($data, ['x', 'pos_x', 'posX']), + static::issetInArray($data, ['x', 'pos_x', 'posX', 'startX']), 0 ); } @@ -256,7 +256,7 @@ class Item extends CachedModel private static function extractY(array $data): int { return static::parseIntOr( - static::issetInArray($data, ['y', 'pos_y', 'posY']), + static::issetInArray($data, ['y', 'pos_y', 'posY', 'startY']), 0 ); } @@ -1272,7 +1272,7 @@ class Item extends CachedModel } $period = static::parseIntOr( - static::issetInArray($data, ['period']), + static::issetInArray($data, ['period', 'maxTime']), null ); if ($period !== null) { @@ -1443,7 +1443,7 @@ class Item extends CachedModel } $timezone = static::notEmptyStringOr( - static::issetInArray($data, ['timezone', 'timeZone', 'time_zone']), + static::issetInArray($data, ['timezone', 'timeZone', 'time_zone', 'clockTimezone']), null ); if ($timezone !== null) { @@ -1512,7 +1512,7 @@ class Item extends CachedModel private static function extractWidth(array $data): integer { return static::parseIntOr( - static::issetInArray($data, ['width']), + static::issetInArray($data, ['width', 'endX']), null ); } @@ -1528,7 +1528,7 @@ class Item extends CachedModel private static function extractHeight(array $data): integer { return static::parseIntOr( - static::issetInArray($data, ['height']), + static::issetInArray($data, ['height', 'endY']), null ); } @@ -1544,7 +1544,7 @@ class Item extends CachedModel private static function extractImageSrc(array $data): string { $imageSrc = static::notEmptyStringOr( - static::issetInArray($data, ['imageSrc', 'image']), + static::issetInArray($data, ['imageSrc', 'image', 'backgroundColor', 'backgroundType', 'valueType']), null ); @@ -1578,7 +1578,7 @@ class Item extends CachedModel private static function extractTypeGraph(array $data): string { return static::notEmptyStringOr( - static::issetInArray($data, ['typeGraph', 'type_graph']), + static::issetInArray($data, ['typeGraph', 'type_graph', 'graphType']), null ); } @@ -1594,7 +1594,7 @@ class Item extends CachedModel private function extractBorderColor(array $data) { return static::notEmptyStringOr( - static::issetInArray($data, ['borderColor', 'border_color']), + static::issetInArray($data, ['borderColor', 'border_color', 'gridColor', 'color', 'legendBackgroundColor']), null ); } @@ -1610,14 +1610,14 @@ class Item extends CachedModel private function extractFillColor(array $data) { return static::notEmptyStringOr( - static::issetInArray($data, ['fillColor', 'fill_color']), + static::issetInArray($data, ['fillColor', 'fill_color', 'labelColor']), null ); } /** - * . + * Insert or update an item in the database * * @param array $data Unknown input data structure. * @@ -1625,19 +1625,16 @@ class Item extends CachedModel */ public function save(array $data=[]): boolean { - $mergedData = \array_merge(static::data, $data); - - $save = static::encode($mergedData); + $save = static::encode($data); if (empty($save['id'])) { // Insert. - $result = db_process_sql_insert('tlayout_data', $save); + $result = \db_process_sql_insert('tlayout_data', $save); + // static = static::fromDB(['id' => $result]); } else { // Update. - $result = db_process_sql_update('tlayout_data', $save, ['id' => $save['id']]); - } - - if ($result) { + $result = \db_process_sql_update('tlayout_data', $save, ['id' => $save['id']]); + // static = static::fromDB(['id' => $save['id']]); } return $result; From aaa1917fce5dbd14ed61230f4b179b3d5969cd7c Mon Sep 17 00:00:00 2001 From: Alejandro Gallardo Escobar Date: Tue, 11 Jun 2019 15:27:06 +0200 Subject: [PATCH 16/92] Added movement to the visual console items --- visual_console_client/src/Item.ts | 66 ++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/visual_console_client/src/Item.ts b/visual_console_client/src/Item.ts index b7c44f8c12..a21a8db6ce 100644 --- a/visual_console_client/src/Item.ts +++ b/visual_console_client/src/Item.ts @@ -13,7 +13,9 @@ import { notEmptyStringOr, replaceMacros, humanDate, - humanTime + humanTime, + addMovementListener, + debounce } from "./lib"; import TypedEvent, { Listener, Disposable } from "./lib/TypedEvent"; @@ -140,6 +142,46 @@ abstract class VisualConsoleItem { // List of references to clean the event listeners. private readonly disposables: Disposable[] = []; + // This function will only run the 2nd arg function after the time + // of the first arg have passed after its last execution. + private debouncedMovementSave = debounce( + 500, // ms. + (x: Position["x"], y: Position["y"]) => { + // Save the new position to the props. + this.move(x, y); + // TODO: start an async task to persist the change. + console.log("SAVED", x, y); + } + ); + // This property will store the function + // to clean the movement listener. + private removeMovement: Function | null = null; + + /** + * Start the movement funtionality. + * @param element Element to move inside its container. + */ + private initMovementListener(element: HTMLElement): void { + this.removeMovement = addMovementListener( + element, + (x: Position["x"], y: Position["y"]) => { + // Move the DOM element. + this.moveElement(x, y); + // Run the save function. + this.debouncedMovementSave(x, y); + } + ); + } + /** + * Stop the movement fun + */ + private stopMovementListener(): void { + if (this.removeMovement) { + this.removeMovement(); + this.removeMovement = null; + } + } + /** * To create a new element which will be inside the item box. * @return Item. @@ -182,18 +224,17 @@ abstract class VisualConsoleItem { private createContainerDomElement(): HTMLElement { let box; if (this.props.isLinkEnabled) { - box = document.createElement("a"); - box as HTMLAnchorElement; + box = document.createElement("a") as HTMLAnchorElement; if (this.props.link) box.href = this.props.link; } else { - box = document.createElement("div"); - box as HTMLDivElement; + box = document.createElement("div") as HTMLDivElement; } box.className = "visual-console-item"; box.style.zIndex = this.props.isOnTop ? "2" : "1"; box.style.left = `${this.props.x}px`; box.style.top = `${this.props.y}px`; + // Init the click listener. box.addEventListener("click", e => { if (this.meta.editMode) { e.preventDefault(); @@ -203,6 +244,19 @@ abstract class VisualConsoleItem { } }); + // Metadata state. + if (this.meta.editMode) { + box.classList.add("is-editing"); + // Init the movement listener. + this.initMovementListener(box); + } + if (this.meta.isFetching) { + box.classList.add("is-fetching"); + } + if (this.meta.isUpdating) { + box.classList.add("is-updating"); + } + return box; } @@ -428,8 +482,10 @@ abstract class VisualConsoleItem { if (!prevMeta || prevMeta.editMode !== this.meta.editMode) { if (this.meta.editMode) { this.elementRef.classList.add("is-editing"); + this.initMovementListener(this.elementRef); } else { this.elementRef.classList.remove("is-editing"); + this.stopMovementListener(); } } if (!prevMeta || prevMeta.isFetching !== this.meta.isFetching) { From 9d15ece41a07bc7bad3bc21a5d183686fe98ea7d Mon Sep 17 00:00:00 2001 From: Alejandro Gallardo Escobar Date: Tue, 11 Jun 2019 16:44:19 +0200 Subject: [PATCH 17/92] Added an event handler for move events of the visual console items --- .../javascript/pandora_visual_console.js | 10 +++++- visual_console_client/src/Item.ts | 26 ++++++++++++-- visual_console_client/src/VisualConsole.ts | 35 +++++++++++++++++-- 3 files changed, 66 insertions(+), 5 deletions(-) diff --git a/pandora_console/include/javascript/pandora_visual_console.js b/pandora_console/include/javascript/pandora_visual_console.js index bedc6538f4..d2e197a69d 100755 --- a/pandora_console/include/javascript/pandora_visual_console.js +++ b/pandora_console/include/javascript/pandora_visual_console.js @@ -123,7 +123,7 @@ function createVisualConsole( try { visualConsole = new VisualConsole(container, props, items); // VC Item clicked. - visualConsole.onClick(function(e) { + visualConsole.onItemClick(function(e) { // Override the link to another VC if it isn't on remote console. if ( e.data && @@ -139,6 +139,14 @@ function createVisualConsole( updateVisualConsole(e.data.linkedLayoutId, updateInterval); } }); + // VC Item moved. + visualConsole.onItemMoved(function(e) { + // TODO: Run an async task to update the position here. + // TODO: Recover the previous position if the update task fails. + console.log( + "Moved item #" + e.item.props.id + " (x: " + e.x + ", y: " + e.y + ")" + ); + }); if (updateInterval != null && updateInterval > 0) { // Start an interval to update the Visual Console. diff --git a/visual_console_client/src/Item.ts b/visual_console_client/src/Item.ts index a21a8db6ce..0ce681ae23 100644 --- a/visual_console_client/src/Item.ts +++ b/visual_console_client/src/Item.ts @@ -70,6 +70,10 @@ export interface ItemRemoveEvent { data: AnyObject; } +export interface ItemMovedEvent extends Position { + item: VisualConsoleItem; +} + /** * Extract a valid enum value from a raw label positi9on value. * @param labelPosition Raw value. @@ -135,6 +139,8 @@ abstract class VisualConsoleItem { protected readonly childElementRef: HTMLElement; // Event manager for click events. private readonly clickEventManager = new TypedEvent>(); + // Event manager for moved events. + private readonly movedEventManager = new TypedEvent(); // Event manager for remove events. private readonly removeEventManager = new TypedEvent< ItemRemoveEvent @@ -149,8 +155,8 @@ abstract class VisualConsoleItem { (x: Position["x"], y: Position["y"]) => { // Save the new position to the props. this.move(x, y); - // TODO: start an async task to persist the change. - console.log("SAVED", x, y); + // Emit the movement event. + this.movedEventManager.emit({ item: this, x, y }); } ); // This property will store the function @@ -657,6 +663,22 @@ abstract class VisualConsoleItem { return disposable; } + /** + * To add an event handler to the movement of visual console elements. + * @param listener Function which is going to be executed when a linked console is moved. + */ + public onMoved(listener: Listener): Disposable { + /* + * The '.on' function returns a function which will clean the event + * listener when executed. We store all the 'dispose' functions to + * call them when the item should be cleared. + */ + const disposable = this.movedEventManager.on(listener); + this.disposables.push(disposable); + + return disposable; + } + /** * To add an event handler to the removal of the item. * @param listener Function which is going to be executed when a item is removed. diff --git a/visual_console_client/src/VisualConsole.ts b/visual_console_client/src/VisualConsole.ts index 63e46771c0..868342b44b 100644 --- a/visual_console_client/src/VisualConsole.ts +++ b/visual_console_client/src/VisualConsole.ts @@ -10,7 +10,8 @@ import Item, { ItemType, ItemProps, ItemClickEvent, - ItemRemoveEvent + ItemRemoveEvent, + ItemMovedEvent } from "./Item"; import StaticGraph, { staticGraphPropsDecoder } from "./items/StaticGraph"; import Icon, { iconPropsDecoder } from "./items/Icon"; @@ -204,6 +205,8 @@ export default class VisualConsole { private readonly clickEventManager = new TypedEvent< ItemClickEvent >(); + // Event manager for move events. + private readonly movedEventManager = new TypedEvent(); // List of references to clean the event listeners. private readonly disposables: Disposable[] = []; @@ -216,6 +219,15 @@ export default class VisualConsole { // console.log(`Clicked element #${e.data.id}`, e); }; + /** + * React to a movement on an element. + * @param e Event object. + */ + private handleElementMovement: (e: ItemMovedEvent) => void = e => { + this.movedEventManager.emit(e); + // console.log(`Moved element #${e.item.props.id}`, e); + }; + /** * Clear some element references. * @param e Event object. @@ -264,6 +276,7 @@ export default class VisualConsole { this.elementIds.push(itemInstance.props.id); // Item event handlers. itemInstance.onClick(this.handleElementClick); + itemInstance.onMoved(this.handleElementMovement); itemInstance.onRemove(this.handleElementRemove); // Add the item to the DOM. this.containerRef.append(itemInstance.elementRef); @@ -552,7 +565,9 @@ export default class VisualConsole { * Add an event handler to the click of the linked visual console elements. * @param listener Function which is going to be executed when a linked console is clicked. */ - public onClick(listener: Listener>): Disposable { + public onItemClick( + listener: Listener> + ): Disposable { /* * The '.on' function returns a function which will clean the event * listener when executed. We store all the 'dispose' functions to @@ -564,6 +579,22 @@ export default class VisualConsole { return disposable; } + /** + * Add an event handler to the movement of the visual console elements. + * @param listener Function which is going to be executed when a linked console is moved. + */ + public onItemMoved(listener: Listener): Disposable { + /* + * The '.on' function returns a function which will clean the event + * listener when executed. We store all the 'dispose' functions to + * call them when the item should be cleared. + */ + const disposable = this.movedEventManager.on(listener); + this.disposables.push(disposable); + + return disposable; + } + /** * Enable the edition mode. */ From 5735326430f7ad577f993c41001d6309132d9c4d Mon Sep 17 00:00:00 2001 From: Alejandro Gallardo Escobar Date: Tue, 11 Jun 2019 17:27:22 +0200 Subject: [PATCH 18/92] Added an async task to persist the visual console item movement to the database --- .../javascript/pandora_visual_console.js | 113 +++++++++++++++++- visual_console_client/src/Item.ts | 18 ++- 2 files changed, 124 insertions(+), 7 deletions(-) diff --git a/pandora_console/include/javascript/pandora_visual_console.js b/pandora_console/include/javascript/pandora_visual_console.js index d2e197a69d..7337bae8bf 100755 --- a/pandora_console/include/javascript/pandora_visual_console.js +++ b/pandora_console/include/javascript/pandora_visual_console.js @@ -141,11 +141,45 @@ function createVisualConsole( }); // VC Item moved. visualConsole.onItemMoved(function(e) { - // TODO: Run an async task to update the position here. - // TODO: Recover the previous position if the update task fails. - console.log( - "Moved item #" + e.item.props.id + " (x: " + e.x + ", y: " + e.y + ")" - ); + var id = e.item.props.id; + var data = { + x: e.newPosition.x, + y: e.newPosition.y + }; + var taskId = "visual-console-item-move-" + id; + + asyncTaskManager + .add(taskId, function(done) { + var abortable = updateVisualConsoleItem( + baseUrl, + visualConsole.props.id, + id, + data, + function(error, data) { + if (error && error.request.statusText === "abort") return; + if (error || !data) { + console.log( + "[ERROR]", + "[VISUAL-CONSOLE-CLIENT]", + "[API]", + error ? error.message : "Invalid response" + ); + + // Move the element to its initial position. + e.item.move(e.prevPosition.x, e.prevPosition.y); + } + + done(); + } + ); + + return { + cancel: function() { + abortable.abort(); + } + }; + }) + .init(); }); if (updateInterval != null && updateInterval > 0) { @@ -274,6 +308,75 @@ function loadVisualConsoleData(baseUrl, vcId, callback) { }; } +/** + * Fetch a Visual Console's structure and its items. + * @param {string} baseUrl Base URL to build the API path. + * @param {number} vcId Identifier of the Visual Console. + * @param {number} vcItemId Identifier of the Visual Console's item. + * @param {Object} data Data we want to save. + * @param {function} callback Function to be executed on request success or fail. + * @return {Object} Cancellable. Object which include and .abort([statusText]) function. + */ +// eslint-disable-next-line no-unused-vars +function updateVisualConsoleItem(baseUrl, vcId, vcItemId, data, callback) { + // var apiPath = baseUrl + "/include/rest-api"; + var apiPath = baseUrl + "/ajax.php"; + var jqXHR = null; + + // Cancel the ajax requests. + var abort = function(textStatus) { + if (textStatus == null) textStatus = "abort"; + + // -- XMLHttpRequest.readyState -- + // Value State Description + // 0 UNSENT Client has been created. open() not called yet. + // 4 DONE The operation is complete. + + if (jqXHR.readyState !== 0 && jqXHR.readyState !== 4) + jqXHR.abort(textStatus); + }; + + // Failed request handler. + var handleFail = function(jqXHR, textStatus, errorThrown) { + abort(); + // Manually aborted or not. + if (textStatus === "abort") { + callback(); + } else { + var error = new Error(errorThrown); + error.request = jqXHR; + callback(error); + } + }; + + // Function which handle success case. + var handleSuccess = function(data) { + callback(null, data); + }; + + // Visual Console container request. + jqXHR = jQuery + // .get(apiPath + "/visual-consoles/" + vcId, null, "json") + .get( + apiPath, + { + page: "include/rest-api/index", + updateVisualConsoleItem: 1, + visualConsoleId: vcId, + visualConsoleItemId: vcItemId, + data: data + }, + "json" + ) + .done(handleSuccess) + .fail(handleFail); + + // Abortable. + return { + abort: abort + }; +} + // TODO: Delete the functions below when you can. /************************************** These functions require jQuery library diff --git a/visual_console_client/src/Item.ts b/visual_console_client/src/Item.ts index 0ce681ae23..aa60913796 100644 --- a/visual_console_client/src/Item.ts +++ b/visual_console_client/src/Item.ts @@ -70,8 +70,10 @@ export interface ItemRemoveEvent { data: AnyObject; } -export interface ItemMovedEvent extends Position { +export interface ItemMovedEvent { item: VisualConsoleItem; + prevPosition: Position; + newPosition: Position; } /** @@ -153,10 +155,22 @@ abstract class VisualConsoleItem { private debouncedMovementSave = debounce( 500, // ms. (x: Position["x"], y: Position["y"]) => { + const prevPosition = { + x: this.props.x, + y: this.props.y + }; + const newPosition = { + x: x, + y: y + }; // Save the new position to the props. this.move(x, y); // Emit the movement event. - this.movedEventManager.emit({ item: this, x, y }); + this.movedEventManager.emit({ + item: this, + prevPosition: prevPosition, + newPosition: newPosition + }); } ); // This property will store the function From 7307d34c7518aa4a06850bddd1cf43184664954d Mon Sep 17 00:00:00 2001 From: Alejandro Gallardo Escobar Date: Tue, 11 Jun 2019 17:39:46 +0200 Subject: [PATCH 19/92] Minor fix --- pandora_console/include/javascript/pandora_visual_console.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandora_console/include/javascript/pandora_visual_console.js b/pandora_console/include/javascript/pandora_visual_console.js index 7337bae8bf..ca1fed6e79 100755 --- a/pandora_console/include/javascript/pandora_visual_console.js +++ b/pandora_console/include/javascript/pandora_visual_console.js @@ -156,8 +156,8 @@ function createVisualConsole( id, data, function(error, data) { - if (error && error.request.statusText === "abort") return; - if (error || !data) { + if (!error && !data) return; + if (error) { console.log( "[ERROR]", "[VISUAL-CONSOLE-CLIENT]", From e4139874dd7eb71007476656a5b7278e6b61d788 Mon Sep 17 00:00:00 2001 From: Tatiana Llorente Date: Tue, 11 Jun 2019 18:00:41 +0200 Subject: [PATCH 20/92] Removed option to show qr code in header - #4196 --- pandora_console/godmode/setup/setup_visuals.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/pandora_console/godmode/setup/setup_visuals.php b/pandora_console/godmode/setup/setup_visuals.php index bcaff54d95..8b0b2d5486 100755 --- a/pandora_console/godmode/setup/setup_visuals.php +++ b/pandora_console/godmode/setup/setup_visuals.php @@ -1113,15 +1113,6 @@ $row++; - $table_other->data[$row][0] = __('Show QR Code icon in the header'); - $table_other->data[$row][1] = html_print_checkbox_switch( - 'show_qr_code_header', - 1, - $config['show_qr_code_header'], - true - ); - $row++; - $table_other->data[$row][0] = __('Custom graphviz directory').ui_print_help_tip(__('Custom directory where the graphviz binaries are stored.'), true); $table_other->data[$row][1] = html_print_input_text( 'graphviz_bin_dir', From f1787c7920a54bd04b2cf4235184d11868291ddd Mon Sep 17 00:00:00 2001 From: Tatiana Llorente Date: Thu, 13 Jun 2019 10:11:03 +0200 Subject: [PATCH 21/92] Removed empty help in unknown modules - #4208 --- pandora_console/include/help/clippy/module_unknow.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/include/help/clippy/module_unknow.php b/pandora_console/include/help/clippy/module_unknow.php index 28656c9ba2..d3a6245032 100644 --- a/pandora_console/include/help/clippy/module_unknow.php +++ b/pandora_console/include/help/clippy/module_unknow.php @@ -32,7 +32,7 @@ function clippy_module_unknow() $return_tours['tours']['module_unknow']['steps'] = []; $return_tours['tours']['module_unknow']['steps'][] = [ 'init_step_context' => true, - 'intro' => ''.''.''.''.''.''.''.'
'.__('You have unknown modules in this agent.').'
'.__('Unknown modules are modules which receive data normally at least in one occassion, but at this time are not receving data. Please check our troubleshoot help page to help you determine why you have unknown modules.').ui_print_help_icon('context_module_unknow', true, '', 'images/help.png').'
', + 'intro' => ''.''.''.''.''.''.''.'
'.__('You have unknown modules in this agent.').'
'.__('Unknown modules are modules which receive data normally at least in one occassion, but at this time are not receving data. Please check our troubleshoot help page to help you determine why you have unknown modules.').'
', ]; $return_tours['tours']['module_unknow']['conf'] = []; $return_tours['tours']['module_unknow']['conf']['autostart'] = false; From e9b4dea6c59f387e08547a8d5858c15abb6aebc7 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Thu, 13 Jun 2019 14:51:27 +0200 Subject: [PATCH 22/92] update --- .../include/rest-api/models/Model.php | 24 ++++++++++++ .../models/VisualConsole/Container.php | 32 ++++++++++++++++ .../rest-api/models/VisualConsole/Item.php | 37 +++++++++++-------- .../models/VisualConsole/Items/Line.php | 31 ++++++++++++++++ 4 files changed, 109 insertions(+), 15 deletions(-) diff --git a/pandora_console/include/rest-api/models/Model.php b/pandora_console/include/rest-api/models/Model.php index 78ef90468e..44e4f8b3e8 100644 --- a/pandora_console/include/rest-api/models/Model.php +++ b/pandora_console/include/rest-api/models/Model.php @@ -47,6 +47,30 @@ abstract class Model abstract protected function decode(array $data): array; + /** + * Return a valid representation of a record in database. + * + * @param array $data Input data. + * + * @return array Data structure representing a record in database. + * + * @abstract + */ + abstract protected function encode(array $data): array; + + + /** + * Insert or update an item in the database + * + * @param array $data Unknown input data structure. + * + * @return boolean The modeled element data structure stored into the DB. + * + * @abstract + */ + abstract public function save(array $data=[]): bool; + + /** * Constructor of the model. It won't be public. The instances * will be created through factories which start with from*. diff --git a/pandora_console/include/rest-api/models/VisualConsole/Container.php b/pandora_console/include/rest-api/models/VisualConsole/Container.php index ad1f34a2ff..653b33d5c4 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Container.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Container.php @@ -92,6 +92,37 @@ final class Container extends Model } + /** + * Return a valid representation of a record in database. + * + * @param array $data Input data. + * + * @return array Data structure representing a record in database. + * + * @overrides Model::encode. + */ + protected function encode(array $data): array + { + $result = []; + return $result; + } + + + /** + * Insert or update an item in the database + * + * @param array $data Unknown input data structure. + * + * @return boolean The modeled element data structure stored into the DB. + * + * @overrides Model::save. + */ + public function save(array $data=[]): bool + { + return true; + } + + /** * Extract a group Id value. * @@ -365,6 +396,7 @@ final class Container extends Model try { array_push($items, $class::fromDB($data)); + hd($class::save($data), true); } catch (\Throwable $e) { // TODO: Log this? } diff --git a/pandora_console/include/rest-api/models/VisualConsole/Item.php b/pandora_console/include/rest-api/models/VisualConsole/Item.php index 373afe5f37..c368e855cb 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Item.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Item.php @@ -1212,17 +1212,19 @@ class Item extends CachedModel * @param array $data Input data. * * @return array Data structure representing a record in database. + * + * @overrides Model::encode. */ protected function encode(array $data): array { $result = []; - $id = static::extractId($data); + $id = static::getId($data); if ($id) { $result['id'] = $id; } - $id_layout = static::extractIdLayout($data); + $id_layout = static::getIdLayout($data); if ($id_layout) { $result['id_layout'] = $id_layout; } @@ -1243,12 +1245,12 @@ class Item extends CachedModel $result['pos_y'] = $pos_y; } - $height = static::extractHeight($data); + $height = static::getHeight($data); if ($height !== null) { $result['height'] = $height; } - $width = static::extractWidth($data); + $width = static::getWidth($data); if ($width !== null) { $result['width'] = $width; } @@ -1258,7 +1260,7 @@ class Item extends CachedModel $result['label'] = $label; } - $image = static::extractImageSrc($data); + $image = static::getImageSrc($data); if ($image !== null) { $result['image'] = $image; } @@ -1322,12 +1324,12 @@ class Item extends CachedModel $result['id_custom_graph'] = $id_custom_graph; } - $border_width = static::extractBorderWidth($data); + $border_width = static::getBorderWidth($data); if ($border_width !== null) { $result['border_width'] = $border_width; } - $type_graph = static::extractTypeGraph($data); + $type_graph = static::getTypeGraph($data); if ($type_graph !== null) { $result['type_graph'] = $type_graph; } @@ -1477,7 +1479,7 @@ class Item extends CachedModel * * @return integer Item id. 0 by default. */ - private static function extractId(array $data): integer + private static function getId(array $data): int { return static::parseIntOr( static::issetInArray($data, ['id', 'itemId']), @@ -1493,7 +1495,7 @@ class Item extends CachedModel * * @return integer Item id. 0 by default. */ - private static function extractIdLayout(array $data): integer + private static function getIdLayout(array $data): int { return static::parseIntOr( static::issetInArray($data, ['id_layout', 'idLayout', 'layoutId']), @@ -1509,7 +1511,7 @@ class Item extends CachedModel * * @return integer Item width. 0 by default. */ - private static function extractWidth(array $data): integer + private static function getWidth(array $data) { return static::parseIntOr( static::issetInArray($data, ['width', 'endX']), @@ -1525,7 +1527,7 @@ class Item extends CachedModel * * @return integer Item height. 0 by default. */ - private static function extractHeight(array $data): integer + private static function getHeight(array $data) { return static::parseIntOr( static::issetInArray($data, ['height', 'endY']), @@ -1541,7 +1543,7 @@ class Item extends CachedModel * * @return mixed String representing the image url (not empty) or null. */ - private static function extractImageSrc(array $data): string + protected static function getImageSrc(array $data) { $imageSrc = static::notEmptyStringOr( static::issetInArray($data, ['imageSrc', 'image', 'backgroundColor', 'backgroundType', 'valueType']), @@ -1559,7 +1561,7 @@ class Item extends CachedModel * * @return integer Valid border width. */ - private static function extractBorderWidth(array $data) + private static function getBorderWidth(array $data) { return static::parseIntOr( static::issetInArray($data, ['border_width', 'borderWidth']), @@ -1575,7 +1577,7 @@ class Item extends CachedModel * * @return string One of 'vertical' or 'horizontal'. 'vertical' by default. */ - private static function extractTypeGraph(array $data): string + private static function getTypeGraph(array $data) { return static::notEmptyStringOr( static::issetInArray($data, ['typeGraph', 'type_graph', 'graphType']), @@ -1622,8 +1624,10 @@ class Item extends CachedModel * @param array $data Unknown input data structure. * * @return boolean The modeled element data structure stored into the DB. + * + * @overrides Model::save. */ - public function save(array $data=[]): boolean + public function save(array $data=[]): bool { $save = static::encode($data); @@ -1637,6 +1641,9 @@ class Item extends CachedModel // static = static::fromDB(['id' => $save['id']]); } + if ($result) { + } + return $result; } diff --git a/pandora_console/include/rest-api/models/VisualConsole/Items/Line.php b/pandora_console/include/rest-api/models/VisualConsole/Items/Line.php index fd6f64b4cb..73887827d5 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Items/Line.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Items/Line.php @@ -206,4 +206,35 @@ final class Line extends Model } + /** + * Return a valid representation of a record in database. + * + * @param array $data Input data. + * + * @return array Data structure representing a record in database. + * + * @overrides Model::encode. + */ + protected function encode(array $data): array + { + $result = []; + return $result; + } + + + /** + * Insert or update an item in the database + * + * @param array $data Unknown input data structure. + * + * @return boolean The modeled element data structure stored into the DB. + * + * @overrides Model::save. + */ + public function save(array $data=[]): bool + { + return true; + } + + } From 018c942ecb0e84f94f5e90008a5ac6c100ad3978 Mon Sep 17 00:00:00 2001 From: Tatiana Llorente Date: Thu, 13 Jun 2019 15:04:39 +0200 Subject: [PATCH 23/92] Added meta option in function ui_print_os_icon - #3999 --- pandora_console/include/functions_ui.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index c81148b9c9..f9a8e784e3 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -760,6 +760,12 @@ function ui_print_os_icon( $subfolder .= '/so_big_icons'; } + if (is_metaconsole()) { + $no_in_meta = true; + } else { + $no_in_meta = false; + } + $icon = (string) db_get_value('icon_name', 'tconfig_os', 'id_os', (int) $id_os); $os_name = get_os_name($id_os); if (empty($icon)) { @@ -770,7 +776,7 @@ function ui_print_os_icon( $options, true, $relative, - false, + $no_in_meta, true ); } else { @@ -778,13 +784,13 @@ function ui_print_os_icon( } } else if ($apply_skin) { if ($only_src) { - $output = html_print_image('images/'.$subfolder.'/'.$icon, true, $options, true, $relative, false, true); + $output = html_print_image('images/'.$subfolder.'/'.$icon, true, $options, true, $relative, $no_in_meta, true); } else { if (!isset($options['title'])) { $options['title'] = $os_name; } - $output = html_print_image('images/'.$subfolder.'/'.$icon, true, $options, false, $relative, false, true); + $output = html_print_image('images/'.$subfolder.'/'.$icon, true, $options, false, $relative, $no_in_meta, true); } } else { // $output = "" . $os_name . ""; From 3c1336d298347bbf20b6a81d8fad7925bf3a35fd Mon Sep 17 00:00:00 2001 From: "marcos.alconada" Date: Thu, 13 Jun 2019 18:27:51 +0200 Subject: [PATCH 24/92] Fixed problem to edit custom graphs on search --- pandora_console/include/functions_custom_graphs.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/include/functions_custom_graphs.php b/pandora_console/include/functions_custom_graphs.php index f98084f808..4a1c5df11c 100644 --- a/pandora_console/include/functions_custom_graphs.php +++ b/pandora_console/include/functions_custom_graphs.php @@ -184,7 +184,7 @@ function custom_graphs_search($id_group, $search) FROM tgraph_source WHERE id_graph = '.$graph['id_graph'].'' ); - + $graphs[$graph['id_graph']]['id_graph'] = $graph['id_graph']; $graphs[$graph['id_graph']]['graphs_count'] = $graphsCount; $graphs[$graph['id_graph']]['name'] = $graph['name']; $graphs[$graph['id_graph']]['description'] = $graph['description']; From dbf15a759f074d230c4531963e4372b440f0e1f8 Mon Sep 17 00:00:00 2001 From: Alejandro Gallardo Escobar Date: Mon, 17 Jun 2019 12:22:55 +0200 Subject: [PATCH 25/92] Added a functionality to allows the live vc item resizement --- .../javascript/pandora_visual_console.js | 48 +++++++- visual_console_client/src/Item.ts | 89 +++++++++++++- visual_console_client/src/VisualConsole.ts | 31 ++++- visual_console_client/src/lib/index.ts | 112 ++++++++++++++++++ visual_console_client/src/main.css | 13 +- visual_console_client/src/resize-handle.svg | 24 ++++ 6 files changed, 312 insertions(+), 5 deletions(-) create mode 100644 visual_console_client/src/resize-handle.svg diff --git a/pandora_console/include/javascript/pandora_visual_console.js b/pandora_console/include/javascript/pandora_visual_console.js index ca1fed6e79..13d7f899e4 100755 --- a/pandora_console/include/javascript/pandora_visual_console.js +++ b/pandora_console/include/javascript/pandora_visual_console.js @@ -148,6 +148,7 @@ function createVisualConsole( }; var taskId = "visual-console-item-move-" + id; + // Persist the new position. asyncTaskManager .add(taskId, function(done) { var abortable = updateVisualConsoleItem( @@ -156,8 +157,8 @@ function createVisualConsole( id, data, function(error, data) { - if (!error && !data) return; - if (error) { + // if (!error && !data) return; + if (error || !data) { console.log( "[ERROR]", "[VISUAL-CONSOLE-CLIENT]", @@ -181,6 +182,49 @@ function createVisualConsole( }) .init(); }); + // VC Item resized. + visualConsole.onItemResized(function(e) { + var id = e.item.props.id; + var data = { + width: e.newSize.width, + height: e.newSize.height + }; + var taskId = "visual-console-item-resize-" + id; + + // Persist the new size. + asyncTaskManager + .add(taskId, function(done) { + var abortable = updateVisualConsoleItem( + baseUrl, + visualConsole.props.id, + id, + data, + function(error, data) { + // if (!error && !data) return; + if (error || !data) { + console.log( + "[ERROR]", + "[VISUAL-CONSOLE-CLIENT]", + "[API]", + error ? error.message : "Invalid response" + ); + + // Resize the element to its initial Size. + e.item.resize(e.prevSize.width, e.prevSize.height); + } + + done(); + } + ); + + return { + cancel: function() { + abortable.abort(); + } + }; + }) + .init(); + }); if (updateInterval != null && updateInterval > 0) { // Start an interval to update the Visual Console. diff --git a/visual_console_client/src/Item.ts b/visual_console_client/src/Item.ts index aa60913796..8d8bd08027 100644 --- a/visual_console_client/src/Item.ts +++ b/visual_console_client/src/Item.ts @@ -15,7 +15,8 @@ import { humanDate, humanTime, addMovementListener, - debounce + debounce, + addResizementListener } from "./lib"; import TypedEvent, { Listener, Disposable } from "./lib/TypedEvent"; @@ -76,6 +77,12 @@ export interface ItemMovedEvent { newPosition: Position; } +export interface ItemResizedEvent { + item: VisualConsoleItem; + prevSize: Size; + newSize: Size; +} + /** * Extract a valid enum value from a raw label positi9on value. * @param labelPosition Raw value. @@ -143,6 +150,8 @@ abstract class VisualConsoleItem { private readonly clickEventManager = new TypedEvent>(); // Event manager for moved events. private readonly movedEventManager = new TypedEvent(); + // Event manager for resized events. + private readonly resizedEventManager = new TypedEvent(); // Event manager for remove events. private readonly removeEventManager = new TypedEvent< ItemRemoveEvent @@ -163,6 +172,9 @@ abstract class VisualConsoleItem { x: x, y: y }; + + if (!this.positionChanged(prevPosition, newPosition)) return; + // Save the new position to the props. this.move(x, y); // Emit the movement event. @@ -202,6 +214,61 @@ abstract class VisualConsoleItem { } } + // This function will only run the 2nd arg function after the time + // of the first arg have passed after its last execution. + private debouncedResizementSave = debounce( + 500, // ms. + (width: Size["width"], height: Size["height"]) => { + const prevSize = { + width: this.props.width, + height: this.props.height + }; + const newSize = { + width: width, + height: height + }; + + if (!this.sizeChanged(prevSize, newSize)) return; + + // Save the new position to the props. + this.resize(width, height); + // Emit the resizement event. + this.resizedEventManager.emit({ + item: this, + prevSize: prevSize, + newSize: newSize + }); + } + ); + // This property will store the function + // to clean the resizement listener. + private removeResizement: Function | null = null; + + /** + * Start the resizement funtionality. + * @param element Element to move inside its container. + */ + private initResizementListener(element: HTMLElement): void { + this.removeResizement = addResizementListener( + element, + (width: Size["width"], height: Size["height"]) => { + // Move the DOM element. + this.resizeElement(width, height); + // Run the save function. + this.debouncedResizementSave(width, height); + } + ); + } + /** + * Stop the resizement functionality. + */ + private stopResizementListener(): void { + if (this.removeResizement) { + this.removeResizement(); + this.removeResizement = null; + } + } + /** * To create a new element which will be inside the item box. * @return Item. @@ -269,6 +336,8 @@ abstract class VisualConsoleItem { box.classList.add("is-editing"); // Init the movement listener. this.initMovementListener(box); + // Init the resizement listener. + this.initResizementListener(box); } if (this.meta.isFetching) { box.classList.add("is-fetching"); @@ -503,9 +572,11 @@ abstract class VisualConsoleItem { if (this.meta.editMode) { this.elementRef.classList.add("is-editing"); this.initMovementListener(this.elementRef); + this.initResizementListener(this.elementRef); } else { this.elementRef.classList.remove("is-editing"); this.stopMovementListener(); + this.stopResizementListener(); } } if (!prevMeta || prevMeta.isFetching !== this.meta.isFetching) { @@ -693,6 +764,22 @@ abstract class VisualConsoleItem { return disposable; } + /** + * To add an event handler to the resizement of visual console elements. + * @param listener Function which is going to be executed when a linked console is moved. + */ + public onResized(listener: Listener): Disposable { + /* + * The '.on' function returns a function which will clean the event + * listener when executed. We store all the 'dispose' functions to + * call them when the item should be cleared. + */ + const disposable = this.resizedEventManager.on(listener); + this.disposables.push(disposable); + + return disposable; + } + /** * To add an event handler to the removal of the item. * @param listener Function which is going to be executed when a item is removed. diff --git a/visual_console_client/src/VisualConsole.ts b/visual_console_client/src/VisualConsole.ts index 868342b44b..2dbdcd3a09 100644 --- a/visual_console_client/src/VisualConsole.ts +++ b/visual_console_client/src/VisualConsole.ts @@ -11,7 +11,8 @@ import Item, { ItemProps, ItemClickEvent, ItemRemoveEvent, - ItemMovedEvent + ItemMovedEvent, + ItemResizedEvent } from "./Item"; import StaticGraph, { staticGraphPropsDecoder } from "./items/StaticGraph"; import Icon, { iconPropsDecoder } from "./items/Icon"; @@ -207,6 +208,8 @@ export default class VisualConsole { >(); // Event manager for move events. private readonly movedEventManager = new TypedEvent(); + // Event manager for resize events. + private readonly resizedEventManager = new TypedEvent(); // List of references to clean the event listeners. private readonly disposables: Disposable[] = []; @@ -228,6 +231,15 @@ export default class VisualConsole { // console.log(`Moved element #${e.item.props.id}`, e); }; + /** + * React to a resizement on an element. + * @param e Event object. + */ + private handleElementResizement: (e: ItemResizedEvent) => void = e => { + this.resizedEventManager.emit(e); + // console.log(`Resized element #${e.item.props.id}`, e); + }; + /** * Clear some element references. * @param e Event object. @@ -277,6 +289,7 @@ export default class VisualConsole { // Item event handlers. itemInstance.onClick(this.handleElementClick); itemInstance.onMoved(this.handleElementMovement); + itemInstance.onResized(this.handleElementResizement); itemInstance.onRemove(this.handleElementRemove); // Add the item to the DOM. this.containerRef.append(itemInstance.elementRef); @@ -595,6 +608,22 @@ export default class VisualConsole { return disposable; } + /** + * Add an event handler to the resizement of the visual console elements. + * @param listener Function which is going to be executed when a linked console is moved. + */ + public onItemResized(listener: Listener): Disposable { + /* + * The '.on' function returns a function which will clean the event + * listener when executed. We store all the 'dispose' functions to + * call them when the item should be cleared. + */ + const disposable = this.resizedEventManager.on(listener); + this.disposables.push(disposable); + + return disposable; + } + /** * Enable the edition mode. */ diff --git a/visual_console_client/src/lib/index.ts b/visual_console_client/src/lib/index.ts index 6a7bf89909..eaad5bbab6 100644 --- a/visual_console_client/src/lib/index.ts +++ b/visual_console_client/src/lib/index.ts @@ -558,3 +558,115 @@ export function addMovementListener( handleEnd(); }; } + +/** + * Add the grab & resize functionality to a certain element. + * + * @param element Element to move. + * @param onResized Function to execute when the element is resized. + * + * @return A function which will clean the event handlers when executed. + */ +export function addResizementListener( + element: HTMLElement, + onResized: (x: Position["x"], y: Position["y"]) => void +): Function { + const resizeDraggable = document.createElement("div"); + resizeDraggable.className = "resize-draggable"; + element.appendChild(resizeDraggable); + + // Store the initial draggable state. + const isDraggable = element.draggable; + // Init the coordinates. + let lastWidth: Size["width"] = 0; + let lastHeight: Size["height"] = 0; + let lastMouseX: Position["x"] = 0; + let lastMouseY: Position["y"] = 0; + let mouseElementOffsetX: Position["x"] = 0; + let mouseElementOffsetY: Position["y"] = 0; + + // Will run onResized 32ms after its last execution. + const debouncedResizement = debounce( + 32, + (width: Size["width"], height: Size["height"]) => onResized(width, height) + ); + // Will run onResized one time max every 16ms. + const throttledResizement = throttle( + 16, + (width: Size["width"], height: Size["height"]) => onResized(width, height) + ); + + const handleResize = (e: MouseEvent) => { + // Calculate the new element coordinates. + let width = lastWidth + (e.pageX - lastMouseX); + let height = lastHeight + (e.pageY - lastMouseY); + + // TODO: Document. + + // Minimum value. + if (width <= 0) width = 10; + if (height <= 0) height = 10; + + // Run the movement events. + throttledResizement(width, height); + debouncedResizement(width, height); + + // Store the coordinates of the element. + lastWidth = width; + lastHeight = height; + // Store the last mouse coordinates. + lastMouseX = e.pageX; + lastMouseY = e.pageY; + }; + const handleEnd = () => { + // Reset the positions. + lastWidth = 0; + lastHeight = 0; + lastMouseX = 0; + lastMouseY = 0; + mouseElementOffsetX = 0; + mouseElementOffsetY = 0; + // Remove the move event. + document.removeEventListener("mousemove", handleResize); + // Clean itself. + document.removeEventListener("mouseup", handleEnd); + // Reset the draggable property to its initial state. + element.draggable = isDraggable; + // Reset the body selection property to a default state. + document.body.style.userSelect = "auto"; + }; + const handleStart = (e: MouseEvent) => { + e.stopPropagation(); + + // Disable the drag temporarily. + element.draggable = false; + + // Store the difference between the cursor and + // the initial coordinates of the element. + const { width, height } = element.getBoundingClientRect(); + lastWidth = width; + lastHeight = height; + // Store the mouse position. + lastMouseX = e.pageX; + lastMouseY = e.pageY; + // Store the relative position between the mouse and the element. + mouseElementOffsetX = e.offsetX; + mouseElementOffsetY = e.offsetY; + + // Listen to the mouse movement. + document.addEventListener("mousemove", handleResize); + // Listen to the moment when the mouse click is not pressed anymore. + document.addEventListener("mouseup", handleEnd); + // Limit the mouse selection of the body. + document.body.style.userSelect = "none"; + }; + + // Event to listen the init of the movement. + resizeDraggable.addEventListener("mousedown", handleStart); + + // Returns a function to clean the event listeners. + return () => { + resizeDraggable.remove(); + handleEnd(); + }; +} diff --git a/visual_console_client/src/main.css b/visual_console_client/src/main.css index b737d1768a..99df3bb925 100644 --- a/visual_console_client/src/main.css +++ b/visual_console_client/src/main.css @@ -16,7 +16,18 @@ } .visual-console-item.is-editing { - border: 2px dashed #33ccff; + border: 2px dashed #b2b2b2; transform: translateX(-2px) translateY(-2px); cursor: move; } + +.visual-console-item.is-editing > .resize-draggable { + float: right; + position: absolute; + right: 0; + bottom: 0; + width: 15px; + height: 15px; + background: url(./resize-handle.svg); + cursor: se-resize; +} diff --git a/visual_console_client/src/resize-handle.svg b/visual_console_client/src/resize-handle.svg new file mode 100644 index 0000000000..b851b85377 --- /dev/null +++ b/visual_console_client/src/resize-handle.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + From a75acb75fc9597897452c2616a26135dca2932ba Mon Sep 17 00:00:00 2001 From: Alejandro Gallardo Escobar Date: Mon, 17 Jun 2019 12:46:35 +0200 Subject: [PATCH 26/92] Minor fix --- visual_console_client/src/main.css | 1 + 1 file changed, 1 insertion(+) diff --git a/visual_console_client/src/main.css b/visual_console_client/src/main.css index 99df3bb925..c69a486c8f 100644 --- a/visual_console_client/src/main.css +++ b/visual_console_client/src/main.css @@ -19,6 +19,7 @@ border: 2px dashed #b2b2b2; transform: translateX(-2px) translateY(-2px); cursor: move; + user-select: none; } .visual-console-item.is-editing > .resize-draggable { From 589000fb6cc9c3cc014f4a5cfdc256758292e8fe Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Tue, 18 Jun 2019 10:13:56 +0200 Subject: [PATCH 27/92] Added save in onItemMoved --- .../javascript/pandora_visual_console.js | 3 +- pandora_console/include/rest-api/index.php | 16 ++++++++++ .../include/rest-api/models/Model.php | 4 +-- .../models/VisualConsole/Container.php | 3 +- .../rest-api/models/VisualConsole/Item.php | 31 ++++++++++++------- .../models/VisualConsole/Items/Line.php | 2 +- 6 files changed, 42 insertions(+), 17 deletions(-) diff --git a/pandora_console/include/javascript/pandora_visual_console.js b/pandora_console/include/javascript/pandora_visual_console.js index ca1fed6e79..6958fdae7f 100755 --- a/pandora_console/include/javascript/pandora_visual_console.js +++ b/pandora_console/include/javascript/pandora_visual_console.js @@ -144,7 +144,8 @@ function createVisualConsole( var id = e.item.props.id; var data = { x: e.newPosition.x, - y: e.newPosition.y + y: e.newPosition.y, + type: e.item.props.type }; var taskId = "visual-console-item-move-" + id; diff --git a/pandora_console/include/rest-api/index.php b/pandora_console/include/rest-api/index.php index 10f87488c7..a49667670b 100644 --- a/pandora_console/include/rest-api/index.php +++ b/pandora_console/include/rest-api/index.php @@ -13,6 +13,7 @@ use Models\VisualConsole\Container as VisualConsole; $visualConsoleId = (int) get_parameter('visualConsoleId'); $getVisualConsole = (bool) get_parameter('getVisualConsole'); $getVisualConsoleItems = (bool) get_parameter('getVisualConsoleItems'); +$updateVisualConsoleItem = (bool) get_parameter('updateVisualConsoleItem'); // Check groups can access user. $aclUserGroups = []; @@ -44,6 +45,21 @@ if ($getVisualConsole === true) { } else if ($getVisualConsoleItems === true) { $vcItems = VisualConsole::getItemsFromDB($visualConsoleId, $aclUserGroups); echo '['.implode($vcItems, ',').']'; +} else if ($updateVisualConsoleItem === true) { + $visualConsoleId = (integer) get_parameter('visualConsoleId'); + $visualConsoleItemId = (integer) get_parameter('visualConsoleItemId'); + $data = get_parameter('data'); + + $class = VisualConsole::getItemClass($data['type']); + + $item_data = []; + $item_data['id'] = $visualConsoleItemId; + $item_data['id_layout'] = $visualConsoleId; + $item_data['type'] = $data['type']; + + $item = $class::fromDB($item_data); + + $item->save($item->toArray(), $data); } exit; diff --git a/pandora_console/include/rest-api/models/Model.php b/pandora_console/include/rest-api/models/Model.php index 44e4f8b3e8..1cc8564603 100644 --- a/pandora_console/include/rest-api/models/Model.php +++ b/pandora_console/include/rest-api/models/Model.php @@ -68,7 +68,7 @@ abstract class Model * * @abstract */ - abstract public function save(array $data=[]): bool; + abstract public function save(array $data=[], array $newdata=[]); /** @@ -93,7 +93,7 @@ abstract class Model * * @return self Instance of the model. */ - public static function fromArray(array $data) + public static function fromArray(array $data): self { // The reserved word static refers to the invoked class at runtime. return new static($data); diff --git a/pandora_console/include/rest-api/models/VisualConsole/Container.php b/pandora_console/include/rest-api/models/VisualConsole/Container.php index 653b33d5c4..1f013cc28f 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Container.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Container.php @@ -117,7 +117,7 @@ final class Container extends Model * * @overrides Model::save. */ - public function save(array $data=[]): bool + public function save(array $data=[], array $newdata=[]): bool { return true; } @@ -396,7 +396,6 @@ final class Container extends Model try { array_push($items, $class::fromDB($data)); - hd($class::save($data), true); } catch (\Throwable $e) { // TODO: Log this? } diff --git a/pandora_console/include/rest-api/models/VisualConsole/Item.php b/pandora_console/include/rest-api/models/VisualConsole/Item.php index c368e855cb..56b349db54 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Item.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Item.php @@ -1627,24 +1627,33 @@ class Item extends CachedModel * * @overrides Model::save. */ - public function save(array $data=[]): bool + public function save(array $data=[], array $newdata=[]) { - $save = static::encode($data); + $save = self::encode($data); + $newSave = self::encode($newdata); - if (empty($save['id'])) { - // Insert. - $result = \db_process_sql_insert('tlayout_data', $save); - // static = static::fromDB(['id' => $result]); - } else { - // Update. - $result = \db_process_sql_update('tlayout_data', $save, ['id' => $save['id']]); - // static = static::fromDB(['id' => $save['id']]); + $save = \array_merge($save, $newSave); + + if (!empty($save)) { + if (empty($save['id'])) { + // Insert. + $result = \db_process_sql_insert('tlayout_data', $save); + } else { + // Update. + $result = \db_process_sql_update('tlayout_data', $save, ['id' => $save['id']]); + } } + // Update the model. if ($result) { + if (empty($save['id'])) { + $item = static::fromDB(['id' => $result]); + } else { + $item = static::fromDB(['id' => $save['id']]); + } } - return $result; + return $item; } diff --git a/pandora_console/include/rest-api/models/VisualConsole/Items/Line.php b/pandora_console/include/rest-api/models/VisualConsole/Items/Line.php index 73887827d5..465a264459 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Items/Line.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Items/Line.php @@ -231,7 +231,7 @@ final class Line extends Model * * @overrides Model::save. */ - public function save(array $data=[]): bool + public function save(array $data=[], array $newdata=[]): bool { return true; } From 649689b1a19326e0a7ddd00e186c60a329b6500c Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Tue, 18 Jun 2019 17:28:36 +0200 Subject: [PATCH 28/92] Update --- pandora_console/include/rest-api/index.php | 4 +- .../include/rest-api/models/Model.php | 8 +- .../models/VisualConsole/Container.php | 2 +- .../rest-api/models/VisualConsole/Item.php | 33 ++-- .../models/VisualConsole/Items/Line.php | 172 +++++++++++++++++- 5 files changed, 198 insertions(+), 21 deletions(-) diff --git a/pandora_console/include/rest-api/index.php b/pandora_console/include/rest-api/index.php index a49667670b..46cc756545 100644 --- a/pandora_console/include/rest-api/index.php +++ b/pandora_console/include/rest-api/index.php @@ -55,11 +55,9 @@ if ($getVisualConsole === true) { $item_data = []; $item_data['id'] = $visualConsoleItemId; $item_data['id_layout'] = $visualConsoleId; - $item_data['type'] = $data['type']; $item = $class::fromDB($item_data); - - $item->save($item->toArray(), $data); + $item->save($data); } exit; diff --git a/pandora_console/include/rest-api/models/Model.php b/pandora_console/include/rest-api/models/Model.php index 1cc8564603..cebdb3d0d7 100644 --- a/pandora_console/include/rest-api/models/Model.php +++ b/pandora_console/include/rest-api/models/Model.php @@ -68,7 +68,7 @@ abstract class Model * * @abstract */ - abstract public function save(array $data=[], array $newdata=[]); + abstract public function save(array $data=[]); /** @@ -86,6 +86,12 @@ abstract class Model } + public function setData(array $data) + { + $this->data = $data; + } + + /** * Instance the class with the unknown input data. * diff --git a/pandora_console/include/rest-api/models/VisualConsole/Container.php b/pandora_console/include/rest-api/models/VisualConsole/Container.php index 1f013cc28f..0353b8c44a 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Container.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Container.php @@ -117,7 +117,7 @@ final class Container extends Model * * @overrides Model::save. */ - public function save(array $data=[], array $newdata=[]): bool + public function save(array $data=[]): bool { return true; } diff --git a/pandora_console/include/rest-api/models/VisualConsole/Item.php b/pandora_console/include/rest-api/models/VisualConsole/Item.php index 56b349db54..da9290bade 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Item.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Item.php @@ -1627,33 +1627,38 @@ class Item extends CachedModel * * @overrides Model::save. */ - public function save(array $data=[], array $newdata=[]) + public function save(array $data=[]): bool { - $save = self::encode($data); - $newSave = self::encode($newdata); + if (empty($data)) { + return false; + } - $save = \array_merge($save, $newSave); + $dataModelEncode = $this->encode($this->toArray()); + $dataEncode = $this->encode($data); + hd(self::toArray(), true); + $save = \array_merge($dataModelEncode, $dataEncode); if (!empty($save)) { if (empty($save['id'])) { // Insert. $result = \db_process_sql_insert('tlayout_data', $save); + if ($result) { + $item = static::fromDB(['id' => $result]); + } } else { // Update. $result = \db_process_sql_update('tlayout_data', $save, ['id' => $save['id']]); + if ($result) { + $item = static::fromDB(['id' => $save['id']]); + // Update the model. + if (!empty($item)) { + $this->setData($item->toArray()); + } + } } } - // Update the model. - if ($result) { - if (empty($save['id'])) { - $item = static::fromDB(['id' => $result]); - } else { - $item = static::fromDB(['id' => $save['id']]); - } - } - - return $item; + return (bool) $result; } diff --git a/pandora_console/include/rest-api/models/VisualConsole/Items/Line.php b/pandora_console/include/rest-api/models/VisualConsole/Items/Line.php index 465a264459..4b177c30b2 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Items/Line.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Items/Line.php @@ -218,10 +218,150 @@ final class Line extends Model protected function encode(array $data): array { $result = []; + + $id = static::getId($data); + if ($id) { + $result['id'] = $id; + } + + $id_layout = static::getIdLayout($data); + if ($id_layout) { + $result['id_layout'] = $id_layout; + } + + $pos_x = static::parseIntOr( + static::issetInArray($data, ['x', 'pos_x', 'posX']), + null + ); + if ($pos_x !== null) { + $result['pos_x'] = $pos_x; + } + + $pos_y = static::parseIntOr( + static::issetInArray($data, ['y', 'pos_y', 'posY']), + null + ); + if ($pos_y !== null) { + $result['pos_y'] = $pos_y; + } + + $height = static::getHeight($data); + if ($height !== null) { + $result['height'] = $height; + } + + $width = static::getWidth($data); + if ($width !== null) { + $result['width'] = $width; + } + + $type = static::parseIntOr( + static::issetInArray($data, ['type']), + null + ); + if ($type !== null) { + $result['type'] = $type; + } + + $border_width = static::getBorderWidth($data); + if ($border_width !== null) { + $result['border_width'] = $border_width; + } + + $border_color = static::extractBorderColor($data); + if ($border_color !== null) { + $result['border_color'] = $border_color; + } + + $show_on_top = static::issetInArray($data, ['isOnTop', 'show_on_top', 'showOnTop']); + if ($show_on_top !== null) { + $result['show_on_top'] = static::parseBool($show_on_top); + } + return $result; } + /** + * Extract item id. + * + * @param array $data Unknown input data structure. + * + * @return integer Item id. 0 by default. + */ + private static function getId(array $data): int + { + return static::parseIntOr( + static::issetInArray($data, ['id', 'itemId']), + 0 + ); + } + + + /** + * Extract layout id. + * + * @param array $data Unknown input data structure. + * + * @return integer Item id. 0 by default. + */ + private static function getIdLayout(array $data): int + { + return static::parseIntOr( + static::issetInArray($data, ['id_layout', 'idLayout', 'layoutId']), + 0 + ); + } + + + /** + * Extract item width. + * + * @param array $data Unknown input data structure. + * + * @return integer Item width. 0 by default. + */ + private static function getWidth(array $data) + { + return static::parseIntOr( + static::issetInArray($data, ['width', 'endX']), + null + ); + } + + + /** + * Extract item height. + * + * @param array $data Unknown input data structure. + * + * @return integer Item height. 0 by default. + */ + private static function getHeight(array $data) + { + return static::parseIntOr( + static::issetInArray($data, ['height', 'endY']), + null + ); + } + + + /** + * Extract a border width value. + * + * @param array $data Unknown input data structure. + * + * @return integer Valid border width. + */ + private static function getBorderWidth(array $data) + { + return static::parseIntOr( + static::issetInArray($data, ['border_width', 'borderWidth']), + null + ); + } + + /** * Insert or update an item in the database * @@ -231,9 +371,37 @@ final class Line extends Model * * @overrides Model::save. */ - public function save(array $data=[], array $newdata=[]): bool + public function save(array $data=[]): bool { - return true; + $data_model = $this->encode($this->toArray()); + $newData = $this->encode($data); + + $save = \array_merge($data_model, $newData); + + if (!empty($save)) { + if (empty($save['id'])) { + // Insert. + $result = \db_process_sql_insert('tlayout_data', $save); + } else { + // Update. + $result = \db_process_sql_update('tlayout_data', $save, ['id' => $save['id']]); + } + } + + // Update the model. + if ($result) { + if (empty($save['id'])) { + $item = static::fromDB(['id' => $result]); + } else { + $item = static::fromDB(['id' => $save['id']]); + } + + if (!empty($item)) { + $this->setData($item->toArray()); + } + } + + return (bool) $result; } From 50b05728b7bd4bc4b4c4a2dc654736e8ea8a0196 Mon Sep 17 00:00:00 2001 From: Alejandro Gallardo Escobar Date: Tue, 18 Jun 2019 18:08:52 +0200 Subject: [PATCH 29/92] Limited the vc item resizement to its container --- visual_console_client/src/lib/index.ts | 47 +++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/visual_console_client/src/lib/index.ts b/visual_console_client/src/lib/index.ts index eaad5bbab6..69b58d3732 100644 --- a/visual_console_client/src/lib/index.ts +++ b/visual_console_client/src/lib/index.ts @@ -571,10 +571,15 @@ export function addResizementListener( element: HTMLElement, onResized: (x: Position["x"], y: Position["y"]) => void ): Function { + const minWidth = 15; + const minHeight = 15; + const resizeDraggable = document.createElement("div"); resizeDraggable.className = "resize-draggable"; element.appendChild(resizeDraggable); + // Container of the resizable element. + const container = element.parentElement as HTMLElement; // Store the initial draggable state. const isDraggable = element.draggable; // Init the coordinates. @@ -584,6 +589,18 @@ export function addResizementListener( let lastMouseY: Position["y"] = 0; let mouseElementOffsetX: Position["x"] = 0; let mouseElementOffsetY: Position["y"] = 0; + // Init the bounds. + let containerBounds = container.getBoundingClientRect(); + let containerOffset = getOffset(container); + let containerTop = containerOffset.top; + let containerBottom = containerTop + containerBounds.height; + let containerLeft = containerOffset.left; + let containerRight = containerLeft + containerBounds.width; + let elementOffset = getOffset(element); + let elementTop = elementOffset.top; + let elementLeft = elementOffset.left; + let borderWidth = window.getComputedStyle(element).borderWidth || "0"; + let borderFix = Number.parseInt(borderWidth); // Will run onResized 32ms after its last execution. const debouncedResizement = debounce( @@ -601,11 +618,20 @@ export function addResizementListener( let width = lastWidth + (e.pageX - lastMouseX); let height = lastHeight + (e.pageY - lastMouseY); - // TODO: Document. - - // Minimum value. - if (width <= 0) width = 10; - if (height <= 0) height = 10; + if (width < minWidth) { + // Minimum value. + width = minWidth; + } else if (width + elementLeft - borderFix / 2 >= containerRight) { + // Limit the size to the container. + width = containerRight - elementLeft; + } + if (height < minHeight) { + // Minimum value. + height = minHeight; + } else if (height + elementTop - borderFix / 2 >= containerBottom) { + // Limit the size to the container. + height = containerBottom - elementTop; + } // Run the movement events. throttledResizement(width, height); @@ -653,6 +679,17 @@ export function addResizementListener( mouseElementOffsetX = e.offsetX; mouseElementOffsetY = e.offsetY; + // Initialize the bounds. + containerBounds = container.getBoundingClientRect(); + containerOffset = getOffset(container); + containerTop = containerOffset.top; + containerBottom = containerTop + containerBounds.height; + containerLeft = containerOffset.left; + containerRight = containerLeft + containerBounds.width; + elementOffset = getOffset(element); + elementTop = elementOffset.top; + elementLeft = elementOffset.left; + // Listen to the mouse movement. document.addEventListener("mousemove", handleResize); // Listen to the moment when the mouse click is not pressed anymore. From 524575171a8360968cf28fdca5ea1b8a6917aef8 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 19 Jun 2019 12:56:16 +0200 Subject: [PATCH 30/92] event history viewer --- pandora_console/include/functions_ui.php | 6 +- pandora_console/operation/events/events.php | 73 ++++++++++++--------- 2 files changed, 45 insertions(+), 34 deletions(-) diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index ea07c20d6a..c18ef5a52b 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -2936,15 +2936,15 @@ function ui_print_datatable(array $parameters) } if (!isset($parameters['order']['field'])) { - $order = 1; + $order = 0; } else { $order = array_search( $parameters['order']['field'], $parameters['columns'] ); - if (empty($order)) { - $order = 1; + if ($order === false) { + $order = 0; } } diff --git a/pandora_console/operation/events/events.php b/pandora_console/operation/events/events.php index 7e8ce16ec3..88621b7711 100644 --- a/pandora_console/operation/events/events.php +++ b/pandora_console/operation/events/events.php @@ -109,6 +109,8 @@ $date_to = get_parameter('filter[date_to]'); $source = get_parameter('filter[source]'); $id_extra = get_parameter('filter[id_extra]'); $user_comment = get_parameter('filter[user_comment]'); +$history = get_parameter('history', false); +$section = get_parameter('section', false); // Ajax responses. if (is_ajax()) { @@ -155,7 +157,9 @@ if (is_ajax()) { } $events = events_get_all( + // Fields. $fields, + // Filter. $filter, // Offset. $start, @@ -164,7 +168,9 @@ if (is_ajax()) { // Order. $order['direction'], // Sort field. - $order['field'] + $order['field'], + // History. + $history ); $count = events_get_all( 'count', @@ -1227,7 +1233,10 @@ try { 'class' => 'info_table events', 'style' => 'width: 100%;', 'ajax_url' => 'operation/events/events', - 'ajax_data' => ['get_events' => 1], + 'ajax_data' => [ + 'get_events' => 1, + 'history' => (int) $history, + ], 'form' => [ 'id' => 'events_form', 'class' => 'flex-row', @@ -1280,39 +1289,41 @@ try { $sql_event_resp = "SELECT id, name FROM tevent_response WHERE type LIKE 'command'"; $event_responses = db_get_all_rows_sql($sql_event_resp); -if (check_acl($config['id_user'], 0, 'EW') == 1 && !$readonly) { - $array_events_actions['in_progress_selected'] = __('In progress selected'); - $array_events_actions['validate_selected'] = __('Validate selected'); -} +if ($config['event_replication'] != 1) { + if (check_acl($config['id_user'], 0, 'EW') == 1 && !$readonly) { + $array_events_actions['in_progress_selected'] = __('In progress selected'); + $array_events_actions['validate_selected'] = __('Validate selected'); + } -if (check_acl($config['id_user'], 0, 'EM') == 1 && !$readonly) { - $array_events_actions['delete_selected'] = __('Delete selected'); + if (check_acl($config['id_user'], 0, 'EM') == 1 && !$readonly) { + $array_events_actions['delete_selected'] = __('Delete selected'); + } } foreach ($event_responses as $val) { $array_events_actions[$val['id']] = $val['name']; } -if ($config['event_replication'] != 1) { - echo '
'; - echo '
'; - echo ''; - html_print_select($array_events_actions, 'response_id', '', '', '', 0, false, false, false); - echo '  '; - html_print_button(__('Execute event response'), 'submit_event_response', false, 'execute_event_response(true);', 'class="sub next"'); - echo "'; - echo '
'; - echo ''; - echo ''; - echo '
'; -} + +echo '
'; +echo '
'; +echo ''; +html_print_select($array_events_actions, 'response_id', '', '', '', 0, false, false, false); +echo '  '; +html_print_button(__('Execute event response'), 'submit_event_response', false, 'execute_event_response(true);', 'class="sub next"'); +echo "'; +echo '
'; +echo ''; +echo ''; +echo '
'; + // Close viewer. enterprise_hook('close_meta_frame'); @@ -1658,6 +1669,9 @@ function process_datatables_item(item) { item.options += ' __('Delete event')]); ?>'; } } + // Multi select. item.m = ' /* Status */ img = ' __('Unknown'), 'class' => 'forced-title']); ?>'; From 44d8b977cbc8948867eb1573ea57a6d1d178a2a8 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 19 Jun 2019 16:52:14 +0200 Subject: [PATCH 31/92] event advanced filter fixes --- pandora_console/include/ajax/events.php | 24 +++++--- pandora_console/include/functions_events.php | 56 +++++++++++------ pandora_console/include/functions_groups.php | 47 ++++++++++++++ pandora_console/operation/events/events.php | 64 ++++++++++---------- 4 files changed, 131 insertions(+), 60 deletions(-) diff --git a/pandora_console/include/ajax/events.php b/pandora_console/include/ajax/events.php index ce173898b2..12f86c4852 100644 --- a/pandora_console/include/ajax/events.php +++ b/pandora_console/include/ajax/events.php @@ -1079,29 +1079,37 @@ if ($get_extended_event) { } // Check ACLs. + $access = false; if (is_user_admin($config['id_user'])) { // Do nothing if you're admin, you get full access. - $__ignored_line = 0; + $access = true; } else if ($config['id_user'] == $event['owner_user']) { // Do nothing if you're the owner user, you get access. - $__ignored_line = 0; + $access = true; } else if ($event['id_grupo'] == 0) { // If the event has access to all groups, you get access. - $__ignored_line = 0; + $access = true; } else { // Get your groups. $groups = users_get_groups($config['id_user'], 'ER'); if (in_array($event['id_grupo'], array_keys($groups))) { // If event group is among the groups of the user, you get access. - $__ignored_line = 0; - } else { - // If all the access types fail, abort. - echo 'Access denied'; - return false; + $access = true; + } else if ($event['id_agente'] + && agents_check_access_agent($event['id_agente'], 'ER') + ) { + // Secondary group, indirect access. + $access = true; } } + if (!$access) { + // If all the access types fail, abort. + echo 'Access denied'; + return false; + } + // Print group_rep in a hidden field to recover it from javascript. html_print_input_hidden('group_rep', (int) $group_rep); diff --git a/pandora_console/include/functions_events.php b/pandora_console/include/functions_events.php index 9339322a7d..da2efa1bd1 100644 --- a/pandora_console/include/functions_events.php +++ b/pandora_console/include/functions_events.php @@ -641,32 +641,37 @@ function events_get_all( } } - if (isset($filter['id_group_filter']) && $filter['id_group_filter'] > 0) { + $groups = $filter['id_group_filter']; + if (isset($groups) && $groups > 0) { $propagate = db_get_value( 'propagate', 'tgrupo', 'id_grupo', - $filter['id_group_filter'] + $groups ); if (!$propagate) { $sql_filters[] = sprintf( - ' AND te.id_grupo = %d ', - $filter['id_group_filter'] + ' AND (te.id_grupo = %d OR tasg.id_group = %d)', + $groups ); } else { - $groups = [ $filter['id_group_filter'] ]; - $childrens = groups_get_childrens($id_group, null, true); - if (!empty($childrens)) { - foreach ($childrens as $child) { - $groups[] = (int) $child['id_grupo']; + $children = groups_get_children($groups); + $_groups = []; + if (!empty($children)) { + foreach ($children as $child) { + $_groups[] = (int) $child['id_grupo']; } + + $groups = $_groups; + } else { + $groups = [ $groups ]; } - $filter['id_group_filter'] = $groups; $sql_filters[] = sprintf( - ' AND id_group IN (%s) ', - join(',', $filter['id_group_filter']) + ' AND (te.id_grupo IN (%s) OR tasg.id_group IN (%s)', + join(',', array_keys($groups)), + join(',', array_keys($groups)) ); } } @@ -702,8 +707,6 @@ function events_get_all( } } - $sg_active = enterprise_hook('agents_is_using_secondary_groups'); - if (!$user_is_admin) { $ER_groups = users_get_groups($config['id_user'], 'ER', false); $EM_groups = users_get_groups($config['id_user'], 'EM', false, true); @@ -713,7 +716,8 @@ function events_get_all( if (!$user_is_admin && !users_can_manage_group_all('ER')) { // Get groups where user have ER grants. $sql_filters[] = sprintf( - ' AND te.id_grupo IN ( %s )', + ' AND (te.id_grupo IN ( %s ) OR tasg.id_group IN (%s))', + join(', ', array_keys($ER_groups)), join(', ', array_keys($ER_groups)) ); } @@ -1036,12 +1040,24 @@ function events_get_all( $tgrupo_join = 'LEFT'; $tgrupo_join_filters = []; - if (isset($filter['id_group_filter']) && $filter['id_group_filter'] > 0) { + if (isset($groups) + && (is_array($groups) + || $groups > 0) + ) { $tgrupo_join = 'INNER'; - $tgrupo_join_filters[] = sprintf( - ' AND tg.id_grupo = %s', - $filter['id_group_filter'] - ); + if (is_array($groups)) { + $tgrupo_join_filters[] = sprintf( + ' AND (tg.id_grupo IN (%s) OR tasg.id_group IN (%s))', + join(', ', array_keys($groups)), + join(', ', array_keys($groups)) + ); + } else { + $tgrupo_join_filters[] = sprintf( + ' AND (tg.id_grupo = %s OR tasg.id_group = %s)', + $groups, + $groups + ); + } } // Secondary groups. diff --git a/pandora_console/include/functions_groups.php b/pandora_console/include/functions_groups.php index 8fe37c0e48..0e88d86004 100644 --- a/pandora_console/include/functions_groups.php +++ b/pandora_console/include/functions_groups.php @@ -298,6 +298,53 @@ function groups_get_childrens_ids($parent, $groups=null) /** + * Return a array of id_group of children of given parent. + * + * @param integer $parent The id_grupo parent to search its children. + * @param array $ignorePropagate Ignore propagate. + */ +function groups_get_children($parent, $ignorePropagate=false) +{ + static $groups; + + if (empty($groups)) { + $groups = db_get_all_rows_in_table('tgrupo'); + $groups = array_reduce( + $groups, + function ($carry, $item) { + $carry[$item['id_grupo']] = $item; + return $carry; + } + ); + } + + $return = []; + foreach ($groups as $key => $g) { + if ($g['id_grupo'] == 0) { + continue; + } + + if ($ignorePropagate || $parent == 0 || $groups[$parent]['propagate']) { + if ($g['parent'] == $parent) { + $return += [$g['id_grupo'] => $g]; + if ($g['propagate'] || $ignorePropagate) { + $return += groups_get_children( + $g['id_grupo'], + $ignorePropagate + ) + ); + } + } + } + } + + return $return; +} + + +/** + * XXX: This is not working. Expects 'propagate' on CHILD not on PARENT!!! + * * Return a array of id_group of childrens (to branches down) * * @param integer $parent The id_group parent to search the childrens. diff --git a/pandora_console/operation/events/events.php b/pandora_console/operation/events/events.php index 88621b7711..95ac221164 100644 --- a/pandora_console/operation/events/events.php +++ b/pandora_console/operation/events/events.php @@ -1591,38 +1591,6 @@ function process_datatables_item(item) { module_status = '
' + text + "
"; - - /* Agent name link */ - if (item.id_agente > 0) { - item.agent_name = '' + item.agent_name + ''; - } else { - item.agent_name = ''; - } - - /* Agent ID link */ - if (item.id_agente > 0) { - - item.id_agente = '' + item.id_agente + ''; - - item.id_agente = '' + item.agent_name + ''; - - } else { - item.id_agente = ''; - } - - /* Group name */ - if (item.id_grupo == "0") { - item.id_grupo = ""; - } else { - item.id_grupo = item.group_name; - } - /* Options */ // Show more. item.options = '' +item.id_agente+'">' + item.agent_name + ''; + } else { + item.agent_name = ''; + } + + /* Agent ID link */ + if (item.id_agente > 0) { + + item.id_agente = '' + item.id_agente + ''; + + item.id_agente = '' + item.agent_name + ''; + + } else { + item.id_agente = ''; + } + item.estado = '
'; item.estado += img; item.estado += '
'; @@ -1719,6 +1712,13 @@ function process_datatables_item(item) { // Add event severity format to itself. item.evento = evn; + /* Group name */ + if (item.id_grupo == "0") { + item.id_grupo = ""; + } else { + item.id_grupo = item.group_name; + } + } /* Datatables auxiliary functions ends */ From 6b944ead9735241fa50e550f816f0691708fe9c6 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 19 Jun 2019 17:08:18 +0200 Subject: [PATCH 32/92] minor fix --- pandora_console/include/functions_groups.php | 1 - 1 file changed, 1 deletion(-) diff --git a/pandora_console/include/functions_groups.php b/pandora_console/include/functions_groups.php index 0e88d86004..a1448e37f2 100644 --- a/pandora_console/include/functions_groups.php +++ b/pandora_console/include/functions_groups.php @@ -331,7 +331,6 @@ function groups_get_children($parent, $ignorePropagate=false) $return += groups_get_children( $g['id_grupo'], $ignorePropagate - ) ); } } From 275261e6b3ce2777f7c19eea5419de706dffd3be Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 19 Jun 2019 17:30:32 +0200 Subject: [PATCH 33/92] wip csv export events --- pandora_console/operation/events/events.php | 26 ++++++++++++++----- .../operation/events/export_csv.php | 15 +++++++++++ 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/pandora_console/operation/events/events.php b/pandora_console/operation/events/events.php index 95ac221164..400f3e9d6d 100644 --- a/pandora_console/operation/events/events.php +++ b/pandora_console/operation/events/events.php @@ -111,11 +111,11 @@ $id_extra = get_parameter('filter[id_extra]'); $user_comment = get_parameter('filter[user_comment]'); $history = get_parameter('history', false); $section = get_parameter('section', false); +$filter = get_parameter('filter', []); // Ajax responses. if (is_ajax()) { $get_events = get_parameter('get_events', 0); - $filter = get_parameter('filter', []); // Datatables offset, limit. $start = get_parameter('start', 0); $length = get_parameter('length', $config['block_size']); @@ -493,27 +493,27 @@ if ($pure) { // Fullscreen. $fullscreen['active'] = false; - $fullscreen['text'] = ''.html_print_image('images/full_screen.png', true, ['title' => __('Full screen')]).''; + $fullscreen['text'] = ''.html_print_image('images/full_screen.png', true, ['title' => __('Full screen')]).''; // Event list. $list['active'] = false; - $list['text'] = ''.html_print_image('images/events_list.png', true, ['title' => __('Event list')]).''; + $list['text'] = ''.html_print_image('images/events_list.png', true, ['title' => __('Event list')]).''; // History event list. $history_list['active'] = false; - $history_list['text'] = ''.html_print_image('images/books.png', true, ['title' => __('History event list')]).''; + $history_list['text'] = ''.html_print_image('images/books.png', true, ['title' => __('History event list')]).''; // RSS. $rss['active'] = false; - $rss['text'] = ''.html_print_image('images/rss.png', true, ['title' => __('RSS Events')]).''; + $rss['text'] = ''.html_print_image('images/rss.png', true, ['title' => __('RSS Events')]).''; // Marquee. $marquee['active'] = false; - $marquee['text'] = ''.html_print_image('images/heart.png', true, ['title' => __('Marquee display')]).''; + $marquee['text'] = ''.html_print_image('images/heart.png', true, ['title' => __('Marquee display')]).''; // CSV. $csv['active'] = false; - $csv['text'] = ''.html_print_image('images/csv_mc.png', true, ['title' => __('Export to CSV file')]).''; + $csv['text'] = ''.html_print_image('images/csv_mc.png', true, ['title' => __('Export to CSV file')]).''; // Sound events. $sound_event['active'] = false; @@ -1969,6 +1969,18 @@ function reorder_tags_inputs() { /* Tag management ends */ $(document).ready( function() { + /* Filter to a href */ + $('.events_link').on('click', function(e) { + e.preventDefault(); + + console.log(e.currentTarget); + + + + + + }); + /* Multi select handler */ $('#checkbox-all_validate_box').on('change', function() { if($('#checkbox-all_validate_box').is(":checked")) { diff --git a/pandora_console/operation/events/export_csv.php b/pandora_console/operation/events/export_csv.php index dbc20abb6a..be0bb52b71 100644 --- a/pandora_console/operation/events/export_csv.php +++ b/pandora_console/operation/events/export_csv.php @@ -27,6 +27,21 @@ if (! check_acl($config['id_user'], 0, 'ER') && ! check_acl($config['id_user'], exit; } +hd($_REQUEST); + +$fb64 = get_parameter('fb64', ''); + + +try { + $filter = json_decode(base64_decode($fb64), true); +} catch (Exception $e) { + echo $e; + exit; +} + +hd($filter); + +die(); global $config; // loading l10n tables, because of being invoked not through index.php. From ac8efd2befb62a56caaccec7bbea42f5e4143098 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Wed, 19 Jun 2019 18:00:53 +0200 Subject: [PATCH 34/92] delete cache item when updating --- .../include/rest-api/models/VisualConsole/Item.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pandora_console/include/rest-api/models/VisualConsole/Item.php b/pandora_console/include/rest-api/models/VisualConsole/Item.php index da9290bade..c1c2c3664c 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Item.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Item.php @@ -1635,7 +1635,7 @@ class Item extends CachedModel $dataModelEncode = $this->encode($this->toArray()); $dataEncode = $this->encode($data); - hd(self::toArray(), true); + $save = \array_merge($dataModelEncode, $dataEncode); if (!empty($save)) { @@ -1648,7 +1648,15 @@ class Item extends CachedModel } else { // Update. $result = \db_process_sql_update('tlayout_data', $save, ['id' => $save['id']]); - if ($result) { + // Invalidate the item's cache. + if ($result !== false && $result > 0) { + db_process_sql_delete( + 'tvisual_console_elements_cache', + [ + 'vc_item_id' => (int) $save['id'], + ] + ); + $item = static::fromDB(['id' => $save['id']]); // Update the model. if (!empty($item)) { From e828fd6690f744b46b5efa021dff247a69658364 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Thu, 20 Jun 2019 09:49:54 +0200 Subject: [PATCH 35/92] Fixed Advanced Permissions LDAP --- pandora_console/include/auth/mysql.php | 109 ++++++++++--------------- 1 file changed, 42 insertions(+), 67 deletions(-) diff --git a/pandora_console/include/auth/mysql.php b/pandora_console/include/auth/mysql.php index 5ef2fed828..ed5e56782a 100644 --- a/pandora_console/include/auth/mysql.php +++ b/pandora_console/include/auth/mysql.php @@ -1257,11 +1257,8 @@ function fill_permissions_ldap($sr) global $config; $permissions = []; $permissions_profile = []; - if (defined('METACONSOLE')) { - $meta = true; - } - if ($meta && (bool) $config['ldap_save_profile'] === false && $config['ldap_advanced_config'] == 0) { + if ((bool) $config['ldap_save_profile'] === false && ($config['ldap_advanced_config'] == 0 || $config['ldap_advanced_config'] == '')) { $result = 0; $result = db_get_all_rows_filter( 'tusuario_perfil', @@ -1287,43 +1284,9 @@ function fill_permissions_ldap($sr) return $permissions_profile; } - if ((bool) $config['ldap_save_profile'] === false && $config['ldap_advanced_config'] == '') { - $result = db_get_all_rows_filter( - 'tusuario_perfil', - ['id_usuario' => $sr['uid'][0]] - ); - if ($result == false) { - $permissions[0]['profile'] = $config['default_remote_profile']; - $permissions[0]['groups'][] = $config['default_remote_group']; - $permissions[0]['tags'] = $config['default_assign_tags']; - $permissions[0]['no_hierarchy'] = $config['default_no_hierarchy']; - return $permissions; - } - - foreach ($result as $perms) { - $permissions_profile[] = [ - 'profile' => $perms['id_perfil'], - 'groups' => [$perms['id_grupo']], - 'tags' => $perms['tags'], - 'no_hierarchy' => (bool) $perms['no_hierarchy'] ? 1 : 0, - ]; - } - - return $permissions_profile; - } - if ($config['ldap_advanced_config'] == 1 && $config['ldap_save_profile'] == 1) { $ldap_adv_perms = json_decode(io_safe_output($config['ldap_adv_perms']), true); - foreach ($ldap_adv_perms as $ldap_adv_perm) { - $permissions[] = [ - 'profile' => $ldap_adv_perm['profile'], - 'groups' => $ldap_adv_perm['group'], - 'tags' => implode(',', $ldap_adv_perm['tags']), - 'no_hierarchy' => (bool) $ldap_adv_perm['no_hierarchy'] ? 1 : 0, - ]; - } - - return $permissions; + return get_advanced_permissions($ldap_adv_perms, $sr); } if ($config['ldap_advanced_config'] == 1 && $config['ldap_save_profile'] == 0) { @@ -1333,25 +1296,16 @@ function fill_permissions_ldap($sr) ); if ($result == false) { $ldap_adv_perms = json_decode(io_safe_output($config['ldap_adv_perms']), true); - foreach ($ldap_adv_perms as $ldap_adv_perm) { - $permissions[] = [ - 'profile' => $ldap_adv_perm['profile'], - 'groups' => $ldap_adv_perm['group'], - 'tags' => implode(',', $ldap_adv_perm['tags']), - 'no_hierarchy' => (bool) $ldap_adv_perm['no_hierarchy'] ? 1 : 0, - ]; - } - - return $permissions; + return get_advanced_permissions($ldap_adv_perms, $sr); } foreach ($result as $perms) { - $permissions_profile[] = [ - 'profile' => $perms['id_perfil'], - 'groups' => [$perms['id_grupo']], - 'tags' => $perms['tags'], - 'no_hierarchy' => (bool) $perms['no_hierarchy'] ? 1 : 0, - ]; + $permissions_profile[] = [ + 'profile' => $perms['id_perfil'], + 'groups' => [$perms['id_grupo']], + 'tags' => $perms['tags'], + 'no_hierarchy' => (bool) $perms['no_hierarchy'] ? 1 : 0, + ]; }; return $permissions_profile; @@ -1365,22 +1319,43 @@ function fill_permissions_ldap($sr) return $permissions; } - // Decode permissions in advanced mode - $ldap_adv_perms = json_decode(io_safe_output($config['ldap_adv_perms']), true); + return $permissions; +} + + +/** + * Get permissions in advanced mode. + * + * @param array ldap_adv_perms + * + * @return array + */ +function get_advanced_permissions($ldap_adv_perms, $sr) +{ + $permissions = []; foreach ($ldap_adv_perms as $ldap_adv_perm) { $attributes = $ldap_adv_perm['groups_ldap']; - foreach ($attributes as $attr) { - $attr = explode('=', $attr, 2); - foreach ($sr[$attr[0]] as $s_attr) { - if (preg_match('/'.$attr[1].'/', $s_attr)) { - $permissions[] = [ - 'profile' => $ldap_adv_perm['profile'], - 'groups' => $ldap_adv_perm['group'], - 'tags' => implode(',', $ldap_adv_perm['tags']), - 'no_hierarchy' => (bool) $ldap_adv_perm['no_hierarchy'] ? 1 : 0, - ]; + if (!empty($attributes[0])) { + foreach ($attributes as $attr) { + $attr = explode('=', $attr, 2); + foreach ($sr[$attr[0]] as $s_attr) { + if (preg_match('/'.$attr[1].'/', $s_attr)) { + $permissions[] = [ + 'profile' => $ldap_adv_perm['profile'], + 'groups' => $ldap_adv_perm['group'], + 'tags' => implode(',', $ldap_adv_perm['tags']), + 'no_hierarchy' => (bool) $ldap_adv_perm['no_hierarchy'] ? 1 : 0, + ]; + } } } + } else { + $permissions[] = [ + 'profile' => $ldap_adv_perm['profile'], + 'groups' => $ldap_adv_perm['group'], + 'tags' => implode(',', $ldap_adv_perm['tags']), + 'no_hierarchy' => (bool) $ldap_adv_perm['no_hierarchy'] ? 1 : 0, + ]; } } From 7a932aceecd0e2020adca573098b3058ca5b50de Mon Sep 17 00:00:00 2001 From: Alejandro Gallardo Escobar Date: Thu, 20 Jun 2019 11:27:08 +0200 Subject: [PATCH 36/92] Fixed the resizement of a vc item when it has a label --- visual_console_client/src/Item.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/visual_console_client/src/Item.ts b/visual_console_client/src/Item.ts index 8d8bd08027..bc4c1d2566 100644 --- a/visual_console_client/src/Item.ts +++ b/visual_console_client/src/Item.ts @@ -252,6 +252,29 @@ abstract class VisualConsoleItem { this.removeResizement = addResizementListener( element, (width: Size["width"], height: Size["height"]) => { + // The label it's outside the item's size, so we need + // to get rid of its size to get the real size of the + // item's content. + if (this.props.label && this.props.label.length > 0) { + const { + width: labelWidth, + height: labelHeight + } = this.labelElementRef.getBoundingClientRect(); + + switch (this.props.labelPosition) { + case "up": + case "down": + height -= labelHeight; + if (width < labelWidth) width = labelWidth; + break; + case "left": + case "right": + width -= labelWidth; + if (height < labelHeight) height = labelHeight; + break; + } + } + // Move the DOM element. this.resizeElement(width, height); // Run the save function. From cfe16ee8c342564934bbba50c130bc0776450fd1 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 20 Jun 2019 11:46:01 +0200 Subject: [PATCH 37/92] minor fixes --- pandora_console/include/functions_events.php | 141 +++++++- pandora_console/operation/events/events.php | 39 ++- .../operation/events/export_csv.php | 312 ++++++++++-------- 3 files changed, 331 insertions(+), 161 deletions(-) diff --git a/pandora_console/include/functions_events.php b/pandora_console/include/functions_events.php index da2efa1bd1..a958a3a957 100644 --- a/pandora_console/include/functions_events.php +++ b/pandora_console/include/functions_events.php @@ -34,6 +34,143 @@ enterprise_include_once('meta/include/functions_agents_meta.php'); enterprise_include_once('meta/include/functions_modules_meta.php'); +/** + * Translates a numeric value module_status into descriptive text. + * + * @param integer $status Module status. + * + * @return string Descriptive text. + */ +function events_translate_module_status($status) +{ + switch ($status) { + case AGENT_MODULE_STATUS_NORMAL: + return __('NORMAL'); + + case AGENT_MODULE_STATUS_CRITICAL_BAD: + return __('CRITICAL'); + + case AGENT_MODULE_STATUS_NO_DATA: + return __('NOT INIT'); + + case AGENT_MODULE_STATUS_CRITICAL_ALERT: + case AGENT_MODULE_STATUS_NORMAL_ALERT: + case AGENT_MODULE_STATUS_WARNING_ALERT: + return __('ALERT'); + + case AGENT_MODULE_STATUS_WARNING: + return __('WARNING'); + + default: + return __('UNKNOWN'); + } +} + + +/** + * Translates a numeric value event_type into descriptive text. + * + * @param integer $event_type Event type. + * + * @return string Descriptive text. + */ +function events_translate_event_type($event_type) +{ + // Event type prepared. + switch ($event_type) { + case EVENTS_ALERT_FIRED: + case EVENTS_ALERT_RECOVERED: + case EVENTS_ALERT_CEASED: + case EVENTS_ALERT_MANUAL_VALIDATION: + return __('ALERT'); + + case EVENTS_RECON_HOST_DETECTED: + case EVENTS_SYSTEM: + case EVENTS_ERROR: + case EVENTS_NEW_AGENT: + case EVENTS_CONFIGURATION_CHANGE: + return __('SYSTEM'); + + case EVENTS_GOING_UP_WARNING: + case EVENTS_GOING_DOWN_WARNING: + return __('WARNING'); + + case EVENTS_GOING_DOWN_NORMAL: + case EVENTS_GOING_UP_NORMAL: + return __('NORMAL'); + + case EVENTS_GOING_DOWN_CRITICAL: + case EVENTS_GOING_UP_CRITICAL: + return __('CRITICAL'); + + case EVENTS_UNKNOWN: + case EVENTS_GOING_UNKNOWN: + default: + return __('UNKNOWN'); + } +} + + +/** + * Translates a numeric value event_status into descriptive text. + * + * @param integer $status Event status. + * + * @return string Descriptive text. + */ +function events_translate_event_status($status) +{ + switch ($status) { + case EVENT_STATUS_NEW: + default: + return __('NEW'); + + case EVENT_STATUS_INPROCESS: + return __('IN PROCESS'); + + case EVENT_STATUS_VALIDATED: + return __('VALIDATED'); + } +} + + +/** + * Translates a numeric value criticity into descriptive text. + * + * @param integer $criticity Event criticity. + * + * @return string Descriptive text. + */ +function events_translate_event_criticity($criticity) +{ + switch ($criticity) { + case EVENT_CRIT_CRITICAL: + return __('CRITICAL'); + + case EVENT_CRIT_MAINTENANCE: + return __('MAINTENANCE'); + + case EVENT_CRIT_INFORMATIONAL: + return __('INFORMATIONAL'); + + case EVENT_CRIT_MAJOR: + return __('MAJOR'); + + case EVENT_CRIT_MINOR: + return __('MINOR'); + + case EVENT_CRIT_NORMAL: + return __('NORMAL'); + + case EVENT_CRIT_WARNING: + return __('WARNING'); + + default: + return __('UNKNOWN'); + } +} + + /** * Return all header string for each event field. * @@ -6465,10 +6602,6 @@ function events_get_sql_order($sort_field='timestamp', $sort='DESC', $group_rep= */ function events_get_secondary_groups_left_join($table) { - if (users_is_admin()) { - return ''; - } - if ($table == 'tevento') { return 'LEFT JOIN tagent_secondary_group tasg ON te.id_agente = tasg.id_agent'; } diff --git a/pandora_console/operation/events/events.php b/pandora_console/operation/events/events.php index 400f3e9d6d..ec073082bf 100644 --- a/pandora_console/operation/events/events.php +++ b/pandora_console/operation/events/events.php @@ -1,7 +1,6 @@ '.html_print_image('images/full_screen.png', true, ['title' => __('Full screen')]).''; + $fullscreen['text'] = ''.html_print_image('images/full_screen.png', true, ['title' => __('Full screen')]).''; // Event list. $list['active'] = false; - $list['text'] = ''.html_print_image('images/events_list.png', true, ['title' => __('Event list')]).''; + $list['text'] = ''.html_print_image('images/events_list.png', true, ['title' => __('Event list')]).''; // History event list. $history_list['active'] = false; - $history_list['text'] = ''.html_print_image('images/books.png', true, ['title' => __('History event list')]).''; + $history_list['text'] = ''.html_print_image('images/books.png', true, ['title' => __('History event list')]).''; // RSS. $rss['active'] = false; - $rss['text'] = ''.html_print_image('images/rss.png', true, ['title' => __('RSS Events')]).''; + $rss['text'] = ''.html_print_image('images/rss.png', true, ['title' => __('RSS Events')]).''; // Marquee. $marquee['active'] = false; - $marquee['text'] = ''.html_print_image('images/heart.png', true, ['title' => __('Marquee display')]).''; + $marquee['text'] = ''.html_print_image('images/heart.png', true, ['title' => __('Marquee display')]).''; // CSV. $csv['active'] = false; - $csv['text'] = ''.html_print_image('images/csv_mc.png', true, ['title' => __('Export to CSV file')]).''; + $csv['text'] = ''.html_print_image('images/csv_mc.png', true, ['title' => __('Export to CSV file')]).''; // Sound events. $sound_event['active'] = false; @@ -1225,6 +1224,7 @@ try { $active_filters_div .= ''; $table_id = 'events'; + $form_id = 'events_form'; // Print datatable. ui_print_datatable( @@ -1238,7 +1238,7 @@ try { 'history' => (int) $history, ], 'form' => [ - 'id' => 'events_form', + 'id' => $form_id, 'class' => 'flex-row', 'html' => $filter, 'inputs' => [], @@ -1528,7 +1528,7 @@ function process_datatables_item(item) { case "": case "": - $tex = ""; + text = ""; color = ""; break; @@ -1654,15 +1654,15 @@ function process_datatables_item(item) { /* Status */ img = ' __('Unknown'), 'class' => 'forced-title']); ?>'; switch (item.estado) { - case "0": + case "": img = ' __('New event'), 'class' => 'forced-title']); ?>'; break; - case "1": + case "": img = ' __('Event validated'), 'class' => 'forced-title']); ?>'; break; - case "2": + case "": img = ' __('Event in process'), 'class' => 'forced-title']); ?>'; break; } @@ -1968,16 +1968,21 @@ function reorder_tags_inputs() { } /* Tag management ends */ $(document).ready( function() { - /* Filter to a href */ $('.events_link').on('click', function(e) { e.preventDefault(); - console.log(e.currentTarget); - - + inputs = $("# :input"); + values = {}; + inputs.each(function() { + values[this.name] = $(this).val(); + }) + values['history'] = ""; + var url = e.currentTarget.href; + url += 'fb64=' + btoa(JSON.stringify(values)); + document.location = url; }); diff --git a/pandora_console/operation/events/export_csv.php b/pandora_console/operation/events/export_csv.php index be0bb52b71..0c16a16f9d 100644 --- a/pandora_console/operation/events/export_csv.php +++ b/pandora_console/operation/events/export_csv.php @@ -1,18 +1,34 @@ load_tables(); } -$offset = (int) get_parameter('offset'); -$id_group = (int) get_parameter('id_group'); -// group -$event_type = (string) get_parameter('event_type', 'all'); -// 0 all -$severity = (int) get_parameter('severity', -1); -// -1 all -$status = (int) get_parameter('status', -1); -// -1 all, 0 only red, 1 only green -$id_agent = (int) get_parameter('id_agent', -1); +$column_names = [ + 'id_evento', + 'evento', + 'timestamp', + 'estado', + 'event_type', + 'utimestamp', + 'id_agente', + 'agent_name', + 'id_usuario', + 'id_grupo', + 'id_agentmodule', + 'id_alert_am', + 'criticity', + 'user_comment', + 'tags', + 'source', + 'id_extra', + 'critical_instructions', + 'warning_instructions', + 'unknown_instructions', + 'owner_user', + 'ack_utimestamp', + 'custom_data', + 'data', + 'module_status', +]; -$id_event = (int) get_parameter('id_event', -1); -$event_view_hr = (int) get_parameter('event_view_hr', $config['event_view_hr']); -$id_user_ack = get_parameter('id_user_ack', 0); -$search = io_safe_output(preg_replace('/&([A-Za-z]{0,4}\w{2,3};|#[0-9]{2,3};)/', '&', rawurldecode(get_parameter('search')))); -$text_agent = (string) get_parameter('text_agent', __('All')); - -$tag_with_json = base64_decode(get_parameter('tag_with', '')); -$tag_with_json_clean = io_safe_output($tag_with_json); -$tag_with_base64 = base64_encode($tag_with_json_clean); -$tag_with = json_decode($tag_with_json_clean, true); -if (empty($tag_with)) { - $tag_with = []; -} - -$tag_with = array_diff($tag_with, [0 => 0]); - -$tag_without_json = base64_decode(get_parameter('tag_without', '')); -$tag_without_json_clean = io_safe_output($tag_without_json); -$tag_without_base64 = base64_encode($tag_without_json_clean); -$tag_without = json_decode($tag_without_json_clean, true); -if (empty($tag_without)) { - $tag_without = []; -} - -$tag_without = array_diff($tag_without, [0 => 0]); - -$filter_only_alert = (int) get_parameter('filter_only_alert', -1); - -// -// Build the condition of the events query -$sql_post = ''; -$meta = false; - -$id_user = $config['id_user']; - -require 'events.build_query.php'; - -// Now $sql_post have all the where condition -// -switch ($config['dbtype']) { - case 'mysql': - case 'postgresql': - case 'oracle': - $sql = 'SELECT * - FROM tevento te - LEFT JOIN tagent_secondary_group tasg - ON te.id_grupo = tasg.id_group - WHERE 1=1 '.$sql_post.' - ORDER BY utimestamp DESC'; - break; -} +$fields = [ + 'te.id_evento', + 'te.evento', + 'te.timestamp', + 'te.estado', + 'te.event_type', + 'te.utimestamp', + 'te.id_agente', + 'ta.alias as agent_name', + 'te.id_usuario', + 'te.id_grupo', + 'te.id_agentmodule', + 'am.nombre as module_name', + 'te.id_alert_am', + 'te.criticity', + 'te.user_comment', + 'te.tags', + 'te.source', + 'te.id_extra', + 'te.critical_instructions', + 'te.warning_instructions', + 'te.unknown_instructions', + 'te.owner_user', + 'te.ack_utimestamp', + 'te.custom_data', + 'te.data', + 'te.module_status', + 'tg.nombre as group_name', +]; $now = date('Y-m-d'); -// Show contentype header +// Download header. header('Content-type: text/txt'); header('Content-Disposition: attachment; filename="pandora_export_event'.$now.'.csv"'); -echo 'timestamp'; -echo $config['csv_divider']; -echo 'agent'; -echo $config['csv_divider']; -echo 'group'; -echo $config['csv_divider']; -echo 'event'; -echo $config['csv_divider']; -echo 'status'; -echo $config['csv_divider']; -echo 'user'; -echo $config['csv_divider']; -echo 'event_type'; -echo $config['csv_divider']; -echo 'severity'; -echo $config['csv_divider']; -echo 'id'; -echo chr(13); - -$new = true; -while ($event = db_get_all_row_by_steps_sql($new, $result, $sql)) { - $new = false; - $alias = db_get_value('alias', 'tagente', 'id_agente', $event['id_agente']); - if ((!check_acl($config['id_user'], $event['id_grupo'], 'ER') - && !check_acl($config['id_user'], $event['id_grupo'], 'EW') && !check_acl($config['id_user'], $event['id_grupo'], 'EM') ) - || (!check_acl($config['id_user'], 0, 'PM') && $event['event_type'] == 'system') - ) { - continue; +try { + $fb64 = get_parameter('fb64', null); + $plain_filter = base64_decode($fb64); + $filter = json_decode($plain_filter, true); + if (json_last_error() != JSON_ERROR_NONE) { + throw new Exception('Invalid filter. ['.$plain_filter.']'); + } + + $names = events_get_column_names($column_names); + + // Dump headers. + foreach ($names as $n) { + echo io_safe_output($n).$config['csv_divider']; } - echo date($config['date_format'], $event['utimestamp']); - echo $config['csv_divider']; - echo io_safe_output($alias); - echo $config['csv_divider']; - echo io_safe_output(groups_get_name($event['id_grupo'])); - echo $config['csv_divider']; - echo io_safe_output($event['evento']); - echo $config['csv_divider']; - echo io_safe_output($event['estado']); - echo $config['csv_divider']; - echo io_safe_output($event['id_usuario']); - echo $config['csv_divider']; - echo io_safe_output($event['event_type']); - echo $config['csv_divider']; - echo $event['criticity']; - echo $config['csv_divider']; - echo $event['id_evento']; echo chr(13); + + // Dump events. + $events_per_step = 1000; + $step = 0; + while (1) { + $events = events_get_all( + $fields, + $filter, + (($step++) * $events_per_step), + $events_per_step, + 'desc', + 'timestamp', + $filter['history'] + ); + + if ($events === false) { + break; + } + + foreach ($events as $row) { + foreach ($column_names as $val) { + $key = $val; + if ($val == 'id_grupo') { + $key = 'group_name'; + } else if ($val == 'id_agentmodule') { + $key = 'module_name'; + } + + switch ($key) { + case 'module_status': + echo events_translate_module_status( + $row[$key] + ); + break; + + case 'event_type': + echo events_translate_event_type( + $row[$key] + ); + break; + + case 'criticity': + echo events_translate_event_criticity( + $row[$key] + ); + break; + + default: + echo io_safe_output($row[$key]); + break; + } + + echo $config['csv_divider']; + } + + echo chr(13); + } + } +} catch (Exception $e) { + echo 'ERROR'.chr(13); + echo $e->getMessage(); + exit; } + +exit; From aa238165d97964a67047dda592e9f56bae9a0735 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 20 Jun 2019 13:33:37 +0200 Subject: [PATCH 38/92] events rss --- .../operation/events/events_rss.php | 492 +++++++++++------- 1 file changed, 299 insertions(+), 193 deletions(-) diff --git a/pandora_console/operation/events/events_rss.php b/pandora_console/operation/events/events_rss.php index 2a38643a9c..95ce7cd07b 100644 --- a/pandora_console/operation/events/events_rss.php +++ b/pandora_console/operation/events/events_rss.php @@ -1,18 +1,37 @@ '; + $output .= ''; + $output .= ''; + return $output."\n"; } -// Check user credentials -$user = get_parameter('user'); -$hashup = get_parameter('hashup'); -$pss = get_user_info($user); -$hashup2 = md5($user.$pss['password']); +/** + * Escape entities for XML. + * + * @param string $str String. + * + * @return string Escaped string. + */ +function xml_entities($str) +{ + if (!is_string($str)) { + return ''; + } -if ($hashup != $hashup2) { - rss_error_handler( - null, - null, - null, - null, - __('The URL of your feed has bad hash.') - ); + if (preg_match_all('/(&[^;]+;)/', $str, $matches) != 0) { + $matches = $matches[0]; - exit; + foreach ($matches as $entity) { + $char = html_entity_decode($entity, (ENT_COMPAT | ENT_HTML401), 'UTF-8'); + + $html_entity_numeric = '&#'.uniord($char).';'; + + $str = str_replace($entity, $html_entity_numeric, $str); + } + } + + return $str; } -header('Content-Type: application/xml; charset=UTF-8'); -// Send header before starting to output + +/** + * Undocumented function. + * + * @param string $u U. + * + * @return integer Ord. + */ +function uniord($u) +{ + $k = mb_convert_encoding($u, 'UCS-2LE', 'UTF-8'); + $k1 = ord(substr($k, 0, 1)); + $k2 = ord(substr($k, 1, 1)); + + return ($k2 * 256 + $k1); +} + + +/** + * Generate RSS header. + * + * @param integer $lastbuild Date, last build. + * + * @return string RSS header. + */ +function rss_header($lastbuild=0) +{ + $selfurl = ui_get_full_url('?'.$_SERVER['QUERY_STRING'], false, true); + + // ' '."\n"; + $rss_feed .= ''."\n"; + $rss_feed .= ''."\n"; + $rss_feed .= ''.io_safe_output(get_product_name()).' Events Feed'."\n"; + $rss_feed .= 'Latest events on '.get_product_name().''."\n"; + $rss_feed .= ''.date(DATE_RFC822, $lastbuild).''."\n"; + // Last build date is the last event - that way readers won't mark it as having new posts. + $rss_feed .= ''.$url.''."\n"; + // Link back to the main Pandora page. + $rss_feed .= ''."\n"; + + return $rss_feed; +} + + +/** + * RSS error handler. + * + * @param string $errno Errno. + * @param string $errstr Errstr. + * @param string $errfile Errfile. + * @param string $errline Errline. + * @param string $error_human_description Error_human_description. + * + * @return void + */ function rss_error_handler($errno, $errstr, $errfile, $errline, $error_human_description=null) { $url = ui_get_full_url(false); $selfurl = ui_get_full_url('?'.$_SERVER['QUERY_STRING'], false, true); - $rss_feed = ''; - // ' Fixes certain highlighters freaking out on the PHP closing tag - $rss_feed .= "\n"; - $rss_feed .= ''; - $rss_feed .= "\n"; - $rss_feed .= ''; - $rss_feed .= "\n"; - $rss_feed .= ''.get_product_name().' RSS Feed'; - $rss_feed .= "\n"; - $rss_feed .= 'Latest events on '.get_product_name().''; - $rss_feed .= "\n"; - $rss_feed .= ''.date(DATE_RFC822, 0).''; - $rss_feed .= "\n"; - $rss_feed .= ''.$url.''; - // Link back to the main Pandora page - $rss_feed .= "\n"; - $rss_feed .= ''; - // Alternative for Atom feeds. It's the same. + // ' Fixes certain highlighters freaking out on the PHP closing tag. + $rss_feed = rss_header(0); $rss_feed .= "\n"; $rss_feed .= ''; $rss_feed .= "\n"; @@ -104,169 +173,206 @@ function rss_error_handler($errno, $errstr, $errfile, $errline, $error_human_des $rss_feed .= "\n"; $rss_feed .= ''; - exit($rss_feed); - // Exit by displaying the feed + echo $rss_feed; } +// Errors output as RSS. set_error_handler('rss_error_handler', E_ERROR); -// Errors output as RSS -$id_group = get_parameter('id_group', 0); -// group -$event_type = get_parameter('event_type', ''); -// 0 all -$severity = (int) get_parameter('severity', -1); -// -1 all -$status = (int) get_parameter('status', 0); -// -1 all, 0 only red, 1 only green -$id_agent = (int) get_parameter('id_agent', -1); -$id_event = (int) get_parameter('id_event', -1); -// This will allow to select only 1 event (eg. RSS) -$event_view_hr = (int) get_parameter('event_view_hr', 0); -$id_user_ack = get_parameter('id_user_ack', 0); -$search = io_safe_output(preg_replace('/&([A-Za-z]{0,4}\w{2,3};|#[0-9]{2,3};)/', '&', rawurldecode(get_parameter('search')))); -$text_agent = (string) get_parameter('text_agent', __('All')); +// Send header before starting to output. +header('Content-Type: application/xml; charset=UTF-8'); -$tag_with_json = base64_decode(get_parameter('tag_with', '')); -$tag_with_json_clean = io_safe_output($tag_with_json); -$tag_with_base64 = base64_encode($tag_with_json_clean); -$tag_with = json_decode($tag_with_json_clean, true); -if (empty($tag_with)) { - $tag_with = []; +$ipOrigin = $_SERVER['REMOTE_ADDR']; + +// Uncoment this to activate ACL on RSS Events. +if (!isInACL($ipOrigin)) { + rss_error_handler( + null, + null, + null, + null, + __('Your IP is not into the IP list with API access.') + ); + + exit; } -$tag_with = array_diff($tag_with, [0 => 0]); +// Check user credentials. +$user = get_parameter('user'); +$hashup = get_parameter('hashup'); -$tag_without_json = base64_decode(get_parameter('tag_without', '')); -$tag_without_json_clean = io_safe_output($tag_without_json); -$tag_without_base64 = base64_encode($tag_without_json_clean); -$tag_without = json_decode($tag_without_json_clean, true); -if (empty($tag_without)) { - $tag_without = []; +$pss = get_user_info($user); +$hashup2 = md5($user.$pss['password']); + +if ($hashup != $hashup2) { + rss_error_handler( + null, + null, + null, + null, + __('The URL of your feed has bad hash.') + ); + + exit; } -$tag_without = array_diff($tag_without, [0 => 0]); - -$filter_only_alert = (int) get_parameter('filter_only_alert', -1); - -// -// Build the condition of the events query -$sql_post = ''; -$meta = false; - -$id_user = $user; - -require 'events.build_query.php'; - -// Now $sql_post have all the where condition -// -$sql = 'SELECT * - FROM tevento te LEFT JOIN tagent_secondary_group tasg - ON te.id_grupo = tasg.id_group - WHERE 1=1 '.$sql_post.' - ORDER BY utimestamp DESC'; - -$result = db_get_all_rows_sql($sql); - -$url = ui_get_full_url(false); -$selfurl = ui_get_full_url('?'.$_SERVER['QUERY_STRING'], false, true); - -if (empty($result)) { - $lastbuild = 0; - // Last build in 1970 -} else { - $lastbuild = (int) $result[0]['utimestamp']; +$reset_session = false; +if (empty($config['id_user'])) { + $config['id_user'] = $user; + $reset_session = true; } -$rss_feed = ''."\n"; -// ' '."\n"; -$rss_feed .= ''."\n"; -$rss_feed .= ''.get_product_name().' RSS Feed'."\n"; -$rss_feed .= 'Latest events on '.get_product_name().''."\n"; -$rss_feed .= ''.date(DATE_RFC822, $lastbuild).''."\n"; -// Last build date is the last event - that way readers won't mark it as having new posts -$rss_feed .= ''.$url.''."\n"; -// Link back to the main Pandora page -$rss_feed .= ''."\n"; -; -// Alternative for Atom feeds. It's the same. -if (empty($result)) { - $result = []; - $rss_feed .= ''.xml_entities(io_safe_input($url.'/index.php?sec=eventos&sec2=operation/events/events')).'No results'; - $rss_feed .= 'There are no results. Click on the link to see all Pending events'; - $rss_feed .= ''.xml_entities(io_safe_input($url.'/index.php?sec=eventos&sec2=operation/events/events')).''."\n"; -} +$column_names = [ + 'id_evento', + 'evento', + 'timestamp', + 'estado', + 'event_type', + 'utimestamp', + 'id_agente', + 'agent_name', + 'id_usuario', + 'id_grupo', + 'id_agentmodule', + 'id_alert_am', + 'criticity', + 'user_comment', + 'tags', + 'source', + 'id_extra', + 'critical_instructions', + 'warning_instructions', + 'unknown_instructions', + 'owner_user', + 'ack_utimestamp', + 'custom_data', + 'data', + 'module_status', +]; -foreach ($result as $row) { - if (!check_acl($user, $row['id_grupo'], 'ER')) { - continue; +$fields = [ + 'te.id_evento', + 'te.evento', + 'te.timestamp', + 'te.estado', + 'te.event_type', + 'te.utimestamp', + 'te.id_agente', + 'ta.alias as agent_name', + 'te.id_usuario', + 'te.id_grupo', + 'te.id_agentmodule', + 'am.nombre as module_name', + 'te.id_alert_am', + 'te.criticity', + 'te.user_comment', + 'te.tags', + 'te.source', + 'te.id_extra', + 'te.critical_instructions', + 'te.warning_instructions', + 'te.unknown_instructions', + 'te.owner_user', + 'te.ack_utimestamp', + 'te.custom_data', + 'te.data', + 'te.module_status', + 'tg.nombre as group_name', +]; + + +try { + $fb64 = get_parameter('fb64', null); + $plain_filter = base64_decode($fb64); + $filter = json_decode($plain_filter, true); + if (json_last_error() != JSON_ERROR_NONE) { + throw new Exception('Invalid filter. ['.$plain_filter.']'); } - if ($row['event_type'] == 'system') { - $agent_name = __('System'); - } else if ($row['id_agente'] > 0) { - // Agent name - $agent_name = agents_get_alias($row['id_agente']); - } else { - $agent_name = __('Alert').__('SNMP'); + // Dump events. + $limit = get_parameter('limit', 20); + $offset = get_parameter('offset', 0); + $events = events_get_all( + $fields, + $filter, + $offset, + $limit, + 'desc', + 'timestamp', + $filter['history'] + ); + + $last_timestamp = 0; + if (is_array($events)) { + $last_timestamp = $events[0]['utimestamp']; } - // This is mandatory - $rss_feed .= ''; - $rss_feed .= xml_entities(io_safe_input($url.'/index.php?sec=eventos&sec2=operation/events/events&id_event='.$row['id_evento'])); - $rss_feed .= ''; - $rss_feed .= xml_entities($agent_name); - $rss_feed .= ''; - $rss_feed .= xml_entities($row['evento']); - if ($row['estado'] == 1) { - $rss_feed .= xml_entities(io_safe_input('

'.'Validated by '.$row['id_usuario'])); - } + // Dump headers. + $rss = rss_header($last_timestamp); + $url = ui_get_full_url(false); - $rss_feed .= '
'; - $rss_feed .= xml_entities(io_safe_input($url.'/index.php?sec=eventos&sec2=operation/events/events&id_event='.$row['id_evento'])); - $rss_feed .= ''; + if (is_array($events)) { + foreach ($events as $row) { + $rss .= ''; + $rss .= xml_entry('title', $row['evento']); + if (!empty($row['id_agente'])) { + $rss .= xml_entry('link', $url.'index.php?sec=estado&sec2=operation/agentes/ver_agente&id_agente='.$row['id_agente']); + } - // The rest is optional - $rss_feed .= ''.date(DATE_RFC822, $row['utimestamp']).''; + $rss .= xml_entry('comments', $row['']); + $rss .= xml_entry('pubDate', $row['timestamp']); + $rss .= xml_entry('category', $row['source']); + foreach ($column_names as $val) { + $key = $val; + if ($val == 'id_grupo') { + $key = 'group_name'; + } else if ($val == 'id_agentmodule') { + $key = 'module_name'; + } - // This is mandatory again - $rss_feed .= ''."\n"; -} + switch ($key) { + case 'module_status': + $value = events_translate_module_status( + $row[$key] + ); + break; -$rss_feed .= "
\n
\n"; + case 'event_type': + $value = events_translate_event_type( + $row[$key] + ); + break; -echo $rss_feed; + case 'criticity': + $value = events_translate_event_criticity( + $row[$key] + ); + break; + default: + $value = $row[$key]; + break; + } -function xml_entities($str) -{ - if (!is_string($str)) { - return ''; - } + $rss .= xml_entry($key, $value); + } - if (preg_match_all('/(&[^;]+;)/', $str, $matches) != 0) { - $matches = $matches[0]; - - foreach ($matches as $entity) { - $char = html_entity_decode($entity, (ENT_COMPAT | ENT_HTML401), 'UTF-8'); - - $html_entity_numeric = '&#'.uniord($char).';'; - - $str = str_replace($entity, $html_entity_numeric, $str); + $rss .= ''; } + } else { + $rss .= ''.xml_entities(io_safe_input($url.'/index.php?sec=eventos&sec2=operation/events/events')).'No results'; + $rss .= 'There are no results. Click on the link to see all Pending events'; + $rss .= ''.xml_entities(io_safe_input($url.'/index.php?sec=eventos&sec2=operation/events/events')).''."\n"; } - return $str; + $rss .= "\n\n"; + + echo $rss; +} catch (Exception $e) { + echo rss_error_handler(200, 'Controlled error', '', '', $e->getMessage()); } - -function uniord($u) -{ - $k = mb_convert_encoding($u, 'UCS-2LE', 'UTF-8'); - $k1 = ord(substr($k, 0, 1)); - $k2 = ord(substr($k, 1, 1)); - - return ($k2 * 256 + $k1); +if ($reset_session) { + unset($config['id_user']); } From 2c5cd007d247bcc1e275f4b38acb7d58c7fbf5db Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 20 Jun 2019 14:18:49 +0200 Subject: [PATCH 39/92] reset form on load filter none --- pandora_console/include/ajax/events.php | 11 ++ pandora_console/operation/events/events.php | 130 ++++++++++++++++---- 2 files changed, 118 insertions(+), 23 deletions(-) diff --git a/pandora_console/include/ajax/events.php b/pandora_console/include/ajax/events.php index 12f86c4852..d6b4e61eaa 100644 --- a/pandora_console/include/ajax/events.php +++ b/pandora_console/include/ajax/events.php @@ -267,6 +267,17 @@ if ($get_filter_values) { $event_filter = events_get_event_filter($id_filter); + if ($event_filter === false) { + $event_filter = [ + 'status' => EVENT_NO_VALIDATED, + 'event_view_hr' => $config['event_view_hr'], + 'group_rep' => 1, + 'tag_with' => [], + 'tag_without' => [], + 'history' => false, + ]; + } + $event_filter['search'] = io_safe_output($event_filter['search']); $event_filter['id_name'] = io_safe_output($event_filter['id_name']); $event_filter['tag_with'] = base64_encode( diff --git a/pandora_console/operation/events/events.php b/pandora_console/operation/events/events.php index ec073082bf..3f730325d8 100644 --- a/pandora_console/operation/events/events.php +++ b/pandora_console/operation/events/events.php @@ -87,30 +87,114 @@ if (is_metaconsole()) { ui_require_javascript_file('pandora_events'); // Get requests. -$id_group = get_parameter('filter[id_group]'); -$event_type = get_parameter('filter[event_type]'); -$severity = get_parameter('filter[severity]'); -$status = get_parameter('filter[status]', EVENT_NO_VALIDATED); -$search = get_parameter('filter[search]'); -$text_agent = get_parameter('filter[text_agent]'); -$id_agent = get_parameter('filter[id_agent]'); -$id_agent_module = get_parameter('filter[id_agent_module]'); -$pagination = get_parameter('filter[pagination]'); -$event_view_hr = get_parameter('filter[event_view_hr]', $config['event_view_hr']); -$id_user_ack = get_parameter('filter[id_user_ack]'); -$group_rep = get_parameter('filter[group_rep]', 1); -$tag_with = get_parameter('filter[tag_with]', []); -$tag_without = get_parameter('filter[tag_without]', []); -$filter_only_alert = get_parameter('filter[filter_only_alert]'); -$id_group_filter = get_parameter('filter[id_group_filter]'); -$date_from = get_parameter('filter[date_from]'); -$date_to = get_parameter('filter[date_to]'); -$source = get_parameter('filter[source]'); -$id_extra = get_parameter('filter[id_extra]'); -$user_comment = get_parameter('filter[user_comment]'); -$history = get_parameter('history', false); +$default_filter = [ + 'status' => EVENT_NO_VALIDATED, + 'event_view_hr' => $config['event_view_hr'], + 'group_rep' => 1, + 'tag_with' => [], + 'tag_without' => [], + 'history' => false, +]; + +$fb64 = get_parameter('fb64', null); +if (isset($fb64)) { + $filter = json_decode(base64_decode($fb64), true); +} else { + $filter = get_parameter( + 'filter', + $default_filter + ); +} + +$id_group = get_parameter( + 'filter[id_group]', + $filter['id_group'] +); +$event_type = get_parameter( + 'filter[event_type]', + $filter['event_type'] +); +$severity = get_parameter( + 'filter[severity]', + $filter['severity'] +); +$status = get_parameter( + 'filter[status]', + $filter['status'] +); +$search = get_parameter( + 'filter[search]', + $filter['search'] +); +$text_agent = get_parameter( + 'filter[text_agent]', + $filter['text_agent'] +); +$id_agent = get_parameter( + 'filter[id_agent]', + $filter['id_agent'] +); +$id_agent_module = get_parameter( + 'filter[id_agent_module]', + $filter['id_agent_module'] +); +$pagination = get_parameter( + 'filter[pagination]', + $filter['pagination'] +); +$event_view_hr = get_parameter( + 'filter[event_view_hr]', + $filter['event_view_hr'] +); +$id_user_ack = get_parameter( + 'filter[id_user_ack]', + $filter['id_user_ack'] +); +$group_rep = get_parameter( + 'filter[group_rep]', + $filter['group_rep'] +); +$tag_with = get_parameter( + 'filter[tag_with]', + $filter['tag_with'] +); +$tag_without = get_parameter( + 'filter[tag_without]', + $filter['tag_without'] +); +$filter_only_alert = get_parameter( + 'filter[filter_only_alert]', + $filter['filter_only_alert'] +); +$id_group_filter = get_parameter( + 'filter[id_group_filter]', + $filter['id_group_filter'] +); +$date_from = get_parameter( + 'filter[date_from]', + $filter['date_from'] +); +$date_to = get_parameter( + 'filter[date_to]', + $filter['date_to'] +); +$source = get_parameter( + 'filter[source]', + $filter['source'] +); +$id_extra = get_parameter( + 'filter[id_extra]', + $filter['id_extra'] +); +$user_comment = get_parameter( + 'filter[user_comment]', + $filter['user_comment'] +); +$history = get_parameter( + 'history', + $filter['history'] +); $section = get_parameter('section', false); -$filter = get_parameter('filter', []); // Ajax responses. if (is_ajax()) { From 71ea94eea3dbc1b355dd686e85fbb1ffe99f4245 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Thu, 20 Jun 2019 16:36:24 +0200 Subject: [PATCH 40/92] Fixed item save --- pandora_console/include/javascript/pandora_visual_console.js | 3 ++- pandora_console/include/rest-api/index.php | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pandora_console/include/javascript/pandora_visual_console.js b/pandora_console/include/javascript/pandora_visual_console.js index 8491d46786..6a726a1d8e 100755 --- a/pandora_console/include/javascript/pandora_visual_console.js +++ b/pandora_console/include/javascript/pandora_visual_console.js @@ -188,7 +188,8 @@ function createVisualConsole( var id = e.item.props.id; var data = { width: e.newSize.width, - height: e.newSize.height + height: e.newSize.height, + type: e.item.props.type }; var taskId = "visual-console-item-resize-" + id; diff --git a/pandora_console/include/rest-api/index.php b/pandora_console/include/rest-api/index.php index 46cc756545..1aa8bfb5a9 100644 --- a/pandora_console/include/rest-api/index.php +++ b/pandora_console/include/rest-api/index.php @@ -57,7 +57,9 @@ if ($getVisualConsole === true) { $item_data['id_layout'] = $visualConsoleId; $item = $class::fromDB($item_data); - $item->save($data); + $result = $item->save($data); + + echo json_encode($result); } exit; From cd5ad59f5682f593e41a435a3cd027688c8d16d1 Mon Sep 17 00:00:00 2001 From: Alejandro Gallardo Escobar Date: Thu, 20 Jun 2019 18:19:10 +0200 Subject: [PATCH 41/92] WIP: VC items movement --- visual_console_client/src/lib/index.ts | 57 ++++++++++++++++++++------ 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/visual_console_client/src/lib/index.ts b/visual_console_client/src/lib/index.ts index 69b58d3732..d1925188ee 100644 --- a/visual_console_client/src/lib/index.ts +++ b/visual_console_client/src/lib/index.ts @@ -447,11 +447,15 @@ export function addMovementListener( let mouseElementOffsetY: Position["y"] = 0; // Bounds. let containerBounds = container.getBoundingClientRect(); - let containerTop = getOffset(container).top; + let containerOffset = getOffset(container); + let containerTop = containerOffset.top; let containerBottom = containerTop + containerBounds.height; - let containerLeft = getOffset(container).left; + let containerLeft = containerOffset.left; let containerRight = containerLeft + containerBounds.width; let elementBounds = element.getBoundingClientRect(); + let elementOffset = getOffset(element); + let elementLeft = elementOffset.left; + let elementTop = elementOffset.top; let borderWidth = window.getComputedStyle(element).borderWidth || "0"; let borderFix = Number.parseInt(borderWidth) * 2; @@ -471,14 +475,17 @@ export function addMovementListener( // TODO: Document. - if (e.pageX < containerLeft) x = 0; - else if (e.pageX > containerRight) x = containerBounds.width; - else x = e.pageX - lastMouseX + lastX; + const mouseX = e.pageX; + const mouseY = e.pageY; - if (e.pageY < containerTop) y = 0; - else if (e.pageY > containerBottom) + if (mouseX < containerLeft) x = 0; + else if (mouseX > containerRight) x = containerBounds.width; + else x = mouseX - lastMouseX + lastX; + + if (mouseY < containerTop) y = 0; + else if (mouseY > containerBottom) y = containerBounds.height - elementBounds.height + borderFix; - else y = e.pageY - lastMouseY + lastY; + else y = mouseY - lastMouseY + lastY; if (x < 0) x = 0; else if (x + elementBounds.width - borderFix > containerBounds.width) @@ -488,6 +495,17 @@ export function addMovementListener( else if (y + elementBounds.height - borderFix > containerBounds.height) y = containerBounds.height - elementBounds.height + borderFix; + if (x === lastX && y === lastY) return; + + // Store the last mouse coordinates. + lastMouseX = mouseX; + lastMouseY = mouseY; + + // if (x < lastX && mouseX > elementLeft + mouseElementOffsetX) return; + // if (x > lastX && mouseX < elementLeft + mouseElementOffsetX) return; + // if (y < lastY && mouseY > elementTop + mouseElementOffsetY) return; + // if (y > lastY && mouseY < elementTop + mouseElementOffsetY) return; + // Run the movement events. throttledMovement(x, y); debouncedMovement(x, y); @@ -495,9 +513,6 @@ export function addMovementListener( // Store the coordinates of the element. lastX = x; lastY = y; - // Store the last mouse coordinates. - lastMouseX = e.pageX; - lastMouseY = e.pageY; }; const handleEnd = () => { // Reset the positions. @@ -533,11 +548,15 @@ export function addMovementListener( // Initialize the bounds. containerBounds = container.getBoundingClientRect(); - containerTop = getOffset(container).top; + containerOffset = getOffset(container); + containerTop = containerOffset.top; containerBottom = containerTop + containerBounds.height; - containerLeft = getOffset(container).left; + containerLeft = containerOffset.left; containerRight = containerLeft + containerBounds.width; elementBounds = element.getBoundingClientRect(); + elementOffset = getOffset(element); + elementLeft = elementOffset.left; + elementTop = elementOffset.top; borderWidth = window.getComputedStyle(element).borderWidth || "0"; borderFix = Number.parseInt(borderWidth) * 2; @@ -618,6 +637,18 @@ export function addResizementListener( let width = lastWidth + (e.pageX - lastMouseX); let height = lastHeight + (e.pageY - lastMouseY); + if (width === lastWidth && height === lastHeight) return; + + console.log( + width - lastWidth, + e.pageX - elementLeft + (lastWidth - mouseElementOffsetX) + ); + if ( + width < lastWidth && + e.pageX > elementLeft + (lastWidth - mouseElementOffsetX) + ) + return; + if (width < minWidth) { // Minimum value. width = minWidth; From 8671c7c88c97b9793b1d20e46ee7b5b956dbbcfa Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 20 Jun 2019 19:23:13 +0200 Subject: [PATCH 42/92] events qa adjustments --- pandora_console/godmode/events/events.php | 15 +++----- pandora_console/include/ajax/events.php | 15 +++++--- pandora_console/include/functions_events.php | 15 ++++++++ pandora_console/operation/events/events.php | 36 ++++++++++++-------- 4 files changed, 51 insertions(+), 30 deletions(-) diff --git a/pandora_console/godmode/events/events.php b/pandora_console/godmode/events/events.php index c937ad281c..72ae001fe1 100644 --- a/pandora_console/godmode/events/events.php +++ b/pandora_console/godmode/events/events.php @@ -50,17 +50,10 @@ if (check_acl($config['id_user'], 0, 'PM')) { 'text' => ''.html_print_image('images/event_responses.png', true, ['title' => __('Event responses')]).'', ]; - if (!is_metaconsole()) { - $buttons['fields'] = [ - 'active' => false, - 'text' => ''.html_print_image('images/custom_columns.png', true, ['title' => __('Custom fields')]).'', - ]; - } else { - $buttons['fields'] = [ - 'active' => false, - 'text' => ''.html_print_image('images/custom_columns.png', true, ['title' => __('Custom fields')]).'', - ]; - } + $buttons['fields'] = [ + 'active' => false, + 'text' => ''.html_print_image('images/custom_columns.png', true, ['title' => __('Custom fields')]).'', + ]; } switch ($section) { diff --git a/pandora_console/include/ajax/events.php b/pandora_console/include/ajax/events.php index d6b4e61eaa..05a6e3ad07 100644 --- a/pandora_console/include/ajax/events.php +++ b/pandora_console/include/ajax/events.php @@ -75,13 +75,20 @@ $graphic_event_group = (bool) get_parameter('graphic_event_group'); $get_table_response_command = (bool) get_parameter('get_table_response_command'); $save_filter_modal = get_parameter('save_filter_modal', 0); $load_filter_modal = get_parameter('load_filter_modal', 0); -$save_filter = get_parameter('save_filter', 0); $get_filter_values = get_parameter('get_filter_values', 0); $update_event_filter = get_parameter('update_event_filter', 0); $save_event_filter = get_parameter('save_event_filter', 0); $in_process_event = get_parameter('in_process_event', 0); $validate_event = get_parameter('validate_event', 0); $delete_event = get_parameter('delete_event', 0); +$get_event_filters = get_parameter('get_event_filters', 0); + + +if ($get_event_filters) { + $event_filter = events_get_event_filter_select(); + + echo io_json_mb_encode($event_filter); +} // Delete event (filtered or not). if ($delete_event) { @@ -601,7 +608,7 @@ function save_new_filter() { jQuery.post ("", { - "page" : "operation/events/events_list", + "page" : "include/ajax/events", "save_event_filter" : 1, "id_name" : $("#text-id_name").val(), "id_group" : $("select#id_group").val(), @@ -670,7 +677,7 @@ function save_update_filter() { var name_filter_update = $("#overwrite_filter option[value='"+id_filter_update+"']").text(); jQuery.post ("", - {"page" : "operation/events/events_list", + {"page" : "include/ajax/events", "update_event_filter" : 1, "id" : $("#overwrite_filter").val(), "id_group" : $("select#id_group").val(), @@ -723,7 +730,7 @@ function save_update_filter() { $('#filter_id').append ($('').html ( ).attr ("value", 0)); // Reload filters select jQuery.post ("", - {"page" : "operation/events/events_list", + {"page" : "include/ajax/events", "get_event_filters" : 1 }, function (data) { diff --git a/pandora_console/include/functions_events.php b/pandora_console/include/functions_events.php index a958a3a957..0f72e0b55c 100644 --- a/pandora_console/include/functions_events.php +++ b/pandora_console/include/functions_events.php @@ -1197,6 +1197,19 @@ function events_get_all( } } + $server_join = ''; + if (is_metaconsole()) { + $server_join = ' LEFT JOIN tmetaconsole_setup ts + ON ts.id = te.server_id'; + if (!empty($filter['server_id'])) { + $server_join = sprintf( + ' LEFT JOIN tmetaconsole_setup ts + ON ts.id = te.server_id AND ts.id= %d', + $filter['server_id'] + ); + } + } + // Secondary groups. db_process_sql('SET group_concat_max_len = 9999999'); $event_lj = events_get_secondary_groups_left_join($table); @@ -1229,6 +1242,7 @@ function events_get_all( %s JOIN tgrupo tg ON te.id_grupo = tg.id_grupo %s + %s WHERE 1=1 %s %s @@ -1247,6 +1261,7 @@ function events_get_all( join(' ', $agent_join_filters), $tgrupo_join, join(' ', $tgrupo_join_filters), + $server_join, join(' ', $sql_filters), $group_by, $order_by, diff --git a/pandora_console/operation/events/events.php b/pandora_console/operation/events/events.php index 3f730325d8..2ee276c820 100644 --- a/pandora_console/operation/events/events.php +++ b/pandora_console/operation/events/events.php @@ -44,9 +44,13 @@ require_once $config['homedir'].'/include/functions_ui.php'; // Check access. check_login(); -if (! check_acl($config['id_user'], 0, 'ER') - && ! check_acl($config['id_user'], 0, 'EW') - && ! check_acl($config['id_user'], 0, 'EM') +$event_a = check_acl($config['id_user'], 0, 'ER'); +$event_w = check_acl($config['id_user'], 0, 'EW'); +$event_m = check_acl($config['id_user'], 0, 'EM'); + +if (! $event_a + && ! $event_w + && ! $event_m ) { db_pandora_audit( 'ACL Violation', @@ -61,9 +65,6 @@ if (! check_acl($config['id_user'], 0, 'ER') } -$event_a = check_acl($config['id_user'], 0, 'ER'); -$event_w = check_acl($config['id_user'], 0, 'EW'); -$event_m = check_acl($config['id_user'], 0, 'EM'); $access = ($event_a == true) ? 'ER' : (($event_w == true) ? 'EW' : (($event_m == true) ? 'EM' : 'ER')); @@ -237,6 +238,9 @@ if (is_ajax()) { ]; if (!is_metaconsole()) { $fields[] = 'am.nombre as id_agentmodule'; + $fields[] = 'ta.server_name as server_name'; + } else { + $fields[] = 'ts.server_name as server_name'; } $events = events_get_all( @@ -603,7 +607,7 @@ if ($pure) { $sound_event['text'] = ''.html_print_image('images/sound.png', true, ['title' => __('Sound events')]).''; // If the user has administrator permission display manage tab. - if (check_acl($config['id_user'], 0, 'EW') || check_acl($config['id_user'], 0, 'EM')) { + if ($event_w || $event_m) { // Manage events. $manage_events['active'] = false; $manage_events['text'] = ''.html_print_image('images/setup.png', true, ['title' => __('Manage events')]).''; @@ -880,12 +884,14 @@ $buttons[] = [ 'onclick' => '', ]; -$buttons[] = [ - 'id' => 'save-filter', - 'class' => 'float-left margin-right-2 sub wand', - 'text' => __('Save filter'), - 'onclick' => '', -]; +if ($event_w || $event_m) { + $buttons[] = [ + 'id' => 'save-filter', + 'class' => 'float-left margin-right-2 sub wand', + 'text' => __('Save filter'), + 'onclick' => '', + ]; +} /* * Advanced filter. @@ -1374,12 +1380,12 @@ $sql_event_resp = "SELECT id, name FROM tevent_response WHERE type LIKE 'command $event_responses = db_get_all_rows_sql($sql_event_resp); if ($config['event_replication'] != 1) { - if (check_acl($config['id_user'], 0, 'EW') == 1 && !$readonly) { + if ($event_w && !$readonly) { $array_events_actions['in_progress_selected'] = __('In progress selected'); $array_events_actions['validate_selected'] = __('Validate selected'); } - if (check_acl($config['id_user'], 0, 'EM') == 1 && !$readonly) { + if ($event_m == 1 && !$readonly) { $array_events_actions['delete_selected'] = __('Delete selected'); } } From 526ebdebd9f2ca8dc1f0008245b4af84ad81bb26 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 20 Jun 2019 21:11:56 +0200 Subject: [PATCH 43/92] ajax comments --- pandora_console/include/ajax/events.php | 100 +++++++++- pandora_console/include/functions_events.php | 178 +++++++++--------- .../include/javascript/pandora_events.js | 5 +- pandora_console/operation/events/events.php | 10 +- 4 files changed, 194 insertions(+), 99 deletions(-) diff --git a/pandora_console/include/ajax/events.php b/pandora_console/include/ajax/events.php index 05a6e3ad07..a7d23ca015 100644 --- a/pandora_console/include/ajax/events.php +++ b/pandora_console/include/ajax/events.php @@ -82,12 +82,65 @@ $in_process_event = get_parameter('in_process_event', 0); $validate_event = get_parameter('validate_event', 0); $delete_event = get_parameter('delete_event', 0); $get_event_filters = get_parameter('get_event_filters', 0); +$get_comments = get_parameter('get_comments', 0); +if ($get_comments) { + $event = get_parameter('event', false); + $filter = get_parameter('filter', false); + + if ($event === false) { + return __('Failed to retrieve comments'); + } + + if ($filter['group_rep'] == 1) { + $events = events_get_all( + ['te.*'], + // Filter. + $filter, + // Offset. + null, + // Limit. + null, + // Order. + null, + // Sort_field. + null, + // History. + $filter['history'], + // Return_sql. + false, + // Having. + sprintf( + ' HAVING max_id_evento = %d', + $event['id_evento'] + ) + ); + if ($events !== false) { + $event = $events[0]; + } + } else { + $events = events_get_event( + $event['id_evento'], + false, + $meta, + $history + ); + + if ($events !== false) { + $event = $events[0]; + } + } + + echo events_page_comments($event, true); + + return; +} if ($get_event_filters) { $event_filter = events_get_event_filter_select(); echo io_json_mb_encode($event_filter); + return; } // Delete event (filtered or not). @@ -1058,6 +1111,7 @@ if ($get_extended_event) { global $config; $event = get_parameter('event', false); + $filter = get_parameter('filter', false); if ($event === false) { return; @@ -1253,7 +1307,7 @@ if ($get_extended_event) { $general = events_page_general($event); - $comments = events_page_comments($event); + $comments = '
'; $notifications = ''; $notifications .= ''; @@ -1264,6 +1318,18 @@ if ($get_extended_event) { $loading = ''; + $i = 0; + $tab['general'] = $i++; + $tab['details'] = $i++; + if (!empty($related)) { + $tab['related'] = $i++; + } + + $tab['custom_fields'] = $i++; + $tab['comments'] = $i++; + $tab['responses'] = $i++; + $tab['custom_data'] = $i++; + $out = '
'.$tabs.$notifications.$loading.$general.$details.$related.$custom_fields.$comments.$responses.$custom_data.html_print_input_hidden('id_event', $event['id_evento']).'
'; $js = ' diff --git a/pandora_console/godmode/groups/group_list.php b/pandora_console/godmode/groups/group_list.php index ee61cdaf79..8cb3c106c1 100644 --- a/pandora_console/godmode/groups/group_list.php +++ b/pandora_console/godmode/groups/group_list.php @@ -1,20 +1,36 @@ $v) { $agents[$keys_prefix.$k] = $v; unset($agents[$k]); if ($all_agents) { - // Unserialize to get the status + // Unserialize to get the status. if ($serialized && is_metaconsole()) { $agent_info = explode($serialized_separator, $k); $agent_disabled = db_get_value_filter( @@ -174,7 +193,8 @@ if (is_ajax()) { ['id_agente' => $agent_info[1]] ); } else if (!$serialized && is_metaconsole()) { - // Cannot retrieve the disabled status. Mark all as not disabled + // Cannot retrieve the disabled status. + // Mark all as not disabled. $agent_disabled = 0; } else { $agent_disabled = db_get_value_filter( @@ -226,11 +246,13 @@ if (! check_acl($config['id_user'], 0, 'PM')) { } $sec = defined('METACONSOLE') ? 'advanced' : 'gagente'; -$url_tree = "index.php?sec=$sec&sec2=godmode/groups/group_list&tab=tree"; -$url_groups = "index.php?sec=$sec&sec2=godmode/groups/group_list&tab=groups"; +$url_credbox = 'index.php?sec='.$sec.'&sec2=godmode/groups/group_list&tab=credbox'; +$url_tree = 'index.php?sec='.$sec.'&sec2=godmode/groups/group_list&tab=tree'; +$url_groups = 'index.php?sec='.$sec.'&sec2=godmode/groups/group_list&tab=groups'; + $buttons['tree'] = [ 'active' => false, - 'text' => "".html_print_image( + 'text' => ''.html_print_image( 'images/gm_massive_operations.png', true, [ @@ -241,7 +263,7 @@ $buttons['tree'] = [ $buttons['groups'] = [ 'active' => false, - 'text' => "".html_print_image( + 'text' => ''.html_print_image( 'images/group.png', true, [ @@ -250,21 +272,38 @@ $buttons['groups'] = [ ).'', ]; +$buttons['credbox'] = [ + 'active' => false, + 'text' => ''.html_print_image( + 'images/key.png', + true, + [ + 'title' => __('Credential Store'), + ] + ).'', +]; + $tab = (string) get_parameter('tab', 'groups'); -// Marks correct tab +$title = __('Groups defined in %s', get_product_name()); +// Marks correct tab. switch ($tab) { case 'tree': $buttons['tree']['active'] = true; break; + case 'credbox': + $buttons['credbox']['active'] = true; + $title = __('Credential store'); + break; + case 'groups': default: $buttons['groups']['active'] = true; break; } -// Header +// Header. if (defined('METACONSOLE')) { agents_meta_print_header(); echo '
'; @@ -272,7 +311,7 @@ if (defined('METACONSOLE')) { echo '
'; } else { ui_print_page_header( - __('Groups defined in %s', get_product_name()), + $title, 'images/group.png', false, 'group_list_tab', @@ -281,12 +320,19 @@ if (defined('METACONSOLE')) { ); } +// Load credential store view before parse list-tree forms. +if ($tab == 'credbox') { + include_once __DIR__.'/credential_store.php'; + // Stop script. + return; +} + $create_group = (bool) get_parameter('create_group'); $update_group = (bool) get_parameter('update_group'); $delete_group = (bool) get_parameter('delete_group'); $pure = get_parameter('pure', 0); -// Create group +// Create group. if (($create_group) && (check_acl($config['id_user'], 0, 'PM'))) { $name = (string) get_parameter('name'); $icon = (string) get_parameter('icon'); @@ -301,7 +347,7 @@ if (($create_group) && (check_acl($config['id_user'], 0, 'PM'))) { $check = db_get_value('nombre', 'tgrupo', 'nombre', $name); $propagate = (bool) get_parameter('propagate'); - // Check if name field is empty + // Check if name field is empty. if ($name != '') { if (!$check) { $values = [ @@ -328,12 +374,11 @@ if (($create_group) && (check_acl($config['id_user'], 0, 'PM'))) { ui_print_error_message(__('Each group must have a different name')); } } else { - // $result = false; ui_print_error_message(__('Group must have a name')); } } -// Update group +// Update group. if ($update_group) { $id_group = (int) get_parameter('id_group'); $name = (string) get_parameter('name'); @@ -349,49 +394,35 @@ if ($update_group) { $contact = (string) get_parameter('contact'); $other = (string) get_parameter('other'); - // Check if name field is empty + // Check if name field is empty. if ($name != '') { - switch ($config['dbtype']) { - case 'mysql': - $sql = sprintf( - 'UPDATE tgrupo SET nombre = "%s", - icon = "%s", disabled = %d, parent = %d, custom_id = "%s", propagate = %d, id_skin = %d, description = "%s", contact = "%s", other = "%s", password = "%s" - WHERE id_grupo = %d', - $name, - empty($icon) ? '' : substr($icon, 0, -4), - !$alerts_enabled, - $id_parent, - $custom_id, - $propagate, - $skin, - $description, - $contact, - $other, - $group_pass, - $id_group - ); - break; - - case 'postgresql': - case 'oracle': - $sql = sprintf( - 'UPDATE tgrupo SET nombre = \'%s\', - icon = \'%s\', disabled = %d, parent = %d, custom_id = \'%s\', propagate = %d, id_skin = %d, description = \'%s\', contact = \'%s\', other = \'%s\' - WHERE id_grupo = %d', - $name, - substr($icon, 0, -4), - !$alerts_enabled, - $id_parent, - $custom_id, - $propagate, - $skin, - $description, - $contact, - $other, - $id_group - ); - break; - } + $sql = sprintf( + 'UPDATE tgrupo + SET nombre = "%s", + icon = "%s", + disabled = %d, + parent = %d, + custom_id = "%s", + propagate = %d, + id_skin = %d, + description = "%s", + contact = "%s", + other = "%s", + password = "%s" + WHERE id_grupo = %d', + $name, + empty($icon) ? '' : substr($icon, 0, -4), + !$alerts_enabled, + $id_parent, + $custom_id, + $propagate, + $skin, + $description, + $contact, + $other, + $group_pass, + $id_group + ); $result = db_process_sql($sql); } else { @@ -405,7 +436,7 @@ if ($update_group) { } } -// Delete group +// Delete group. if (($delete_group) && (check_acl($config['id_user'], 0, 'PM'))) { $id_group = (int) get_parameter('id_group'); @@ -445,7 +476,14 @@ if (($delete_group) && (check_acl($config['id_user'], 0, 'PM'))) { } } + +// Credential store is loaded previously in this document to avoid +// process group tree - list forms. if ($tab == 'tree') { + /* + * Group tree view. + */ + echo html_print_image( 'images/spinner.gif', true, @@ -456,6 +494,10 @@ if ($tab == 'tree') { ); echo "
"; } else { + /* + * Group list view. + */ + $acl = ''; $search_name = ''; $offset = (int) get_parameter('offset', 0); @@ -463,17 +505,22 @@ if ($tab == 'tree') { $block_size = $config['block_size']; if (!empty($search)) { - $search_name = "AND t.nombre LIKE '%$search%'"; + $search_name = 'AND t.nombre LIKE "%'.$search.'%"'; } if (!users_can_manage_group_all('AR')) { $user_groups_acl = users_get_groups(false, 'AR'); $groups_acl = implode(',', $user_groups_ACL); if (empty($groups_acl)) { - return ui_print_info_message(['no_close' => true, 'message' => __('There are no defined groups') ]); + return ui_print_info_message( + [ + 'no_close' => true, + 'message' => __('There are no defined groups'), + ] + ); } - $acl = "AND t.id_grupo IN ($groups_acl)"; + $acl = 'AND t.id_grupo IN ('.$groups_acl.')'; } $form = "
"; @@ -488,29 +535,37 @@ if ($tab == 'tree') { echo $form; - $groups_sql = "SELECT t.*, + $groups_sql = sprintf( + 'SELECT t.*, p.nombre AS parent_name, IF(t.parent=p.id_grupo, 1, 0) AS has_child - FROM tgrupo t - LEFT JOIN tgrupo p + FROM tgrupo t + LEFT JOIN tgrupo p ON t.parent=p.id_grupo - WHERE 1=1 - $acl - $search_name + WHERE 1=1 + %s + %s ORDER BY nombre - LIMIT $offset, $block_size - "; + LIMIT %d, %d', + $acl, + $search_name, + $offset, + $block_size + ); $groups = db_get_all_rows_sql($groups_sql); if (!empty($groups)) { - // Count all groups for pagination only saw user and filters - $groups_sql_count = "SELECT count(*) + // Count all groups for pagination only saw user and filters. + $groups_sql_count = sprintf( + 'SELECT count(*) FROM tgrupo t WHERE 1=1 - $acl - $search_name - "; + %s + %s', + $acl, + $search_name + ); $groups_count = db_get_value_sql($groups_sql_count); $table = new StdClass(); @@ -545,7 +600,7 @@ if ($tab == 'tree') { $url = 'index.php?sec=gagente&sec2=godmode/groups/configure_group&id_group='.$group['id_grupo']; $url_delete = 'index.php?sec=gagente&sec2=godmode/groups/group_list&delete_group=1&id_group='.$group['id_grupo']; $table->data[$key][0] = $group['id_grupo']; - $table->data[$key][1] = "".$group['nombre'].''; + $table->data[$key][1] = ''.$group['nombre'].''; if ($group['icon'] != '') { $table->data[$key][2] = html_print_image( 'images/groups_small/'.$group['icon'].'.png', @@ -553,22 +608,25 @@ if ($tab == 'tree') { [ 'style' => '', 'class' => 'bot', - 'alt' => $group['nombre'], + 'alt' => $group['nombre'], 'title' => $group['nombre'], - false, false, false, true - ] + ], + false, + false, + false, + true ); } else { $table->data[$key][2] = ''; } - // reporting_get_group_stats - $table->data[$key][3] = $group['disabled'] ? __('Disabled') : __('Enabled'); + // Reporting_get_group_stats. + $table->data[$key][3] = ($group['disabled']) ? __('Disabled') : __('Enabled'); $table->data[$key][4] = $group['parent_name']; $table->data[$key][5] = $group['description']; $table->cellclass[$key][6] = 'action_buttons'; - $table->data[$key][6] = "".html_print_image( + $table->data[$key][6] = ''.html_print_image( 'images/config.png', true, [ diff --git a/pandora_console/include/functions_credential_store.php b/pandora_console/include/functions_credential_store.php new file mode 100644 index 0000000000..acf15bb6be --- /dev/null +++ b/pandora_console/include/functions_credential_store.php @@ -0,0 +1,97 @@ + $v) { - $js .= $k.':'.json_encode($v).",\n"; + if (is_array($parameters['ajax_data'])) { + foreach ($parameters['ajax_data'] as $k => $v) { + $js .= $k.':'.json_encode($v).",\n"; + } } $js .= 'page: "'.$parameters['ajax_url'].'" diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index b30295bba6..bdd1bca841 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -693,6 +693,20 @@ CREATE TABLE IF NOT EXISTS `tgrupo` ( KEY `parent_index` (`parent`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +-- --------------------------------------------------------------------- +-- Table `tcredential_store` +-- --------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS `tcredential_store` ( + `identifier` varchar(100) NOT NULL, + `id_group` mediumint(4) unsigned NOT NULL DEFAULT 0, + `product` text, + `username` text, + `password` text, + `extra_1` text, + `extra_2` text, + PRIMARY KEY (`identifier`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + -- --------------------------------------------------------------------- -- Table `tincidencia` -- --------------------------------------------------------------------- From 379a0039aed08e7d82c526f2555bc1c8cbd3b598 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Fri, 21 Jun 2019 12:41:05 +0200 Subject: [PATCH 46/92] Fixed vc-control --- pandora_console/include/styles/pandora.css | 3 +-- pandora_console/operation/visual_console/view.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 0596f5bf41..4b2a761e4c 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -1390,7 +1390,6 @@ div.title_line { #menu_tab { margin-right: 10px; - min-width: 510px; } #menu_tab .mn, @@ -3711,7 +3710,7 @@ div#vc-controls { div#vc-controls div.vc-title, div#vc-controls div.vc-refr { - margin-top: 6px; + margin-top: 15px; margin-left: 3px; margin-right: 3px; } diff --git a/pandora_console/operation/visual_console/view.php b/pandora_console/operation/visual_console/view.php index 61633b1fc6..3b0707036b 100644 --- a/pandora_console/operation/visual_console/view.php +++ b/pandora_console/operation/visual_console/view.php @@ -172,7 +172,7 @@ if ($pure === true) { echo '
'; echo ''; // Add event severity to end of text. - evn = '' + evn += item.evento+''; + + item.mini_severity = '
'; + item.mini_severity += output; + item.mini_severity += '
'; criticity = '
' + text + "
"; From c24d7dbbda0ca29a991f81feb67726458137317e Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 24 Jun 2019 19:28:19 +0200 Subject: [PATCH 72/92] new hearbeat designs --- pandora_console/images/heartbeat_green.gif | Bin 395899 -> 18812 bytes pandora_console/images/heartbeat_red.gif | Bin 29598 -> 16965 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/pandora_console/images/heartbeat_green.gif b/pandora_console/images/heartbeat_green.gif index 49697adbc7bdfbaffad79d6190ed61bd54483371..a985013064126fd40007cf3e524bf61cfc920675 100644 GIT binary patch literal 18812 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 literal 395899 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�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 diff --git a/pandora_console/images/heartbeat_red.gif b/pandora_console/images/heartbeat_red.gif index e0c4b24ccdb5257f1011cca1c46ef6e1b42c22c4..abc8d8383255412da7d4ea24645737d3d602fea9 100644 GIT binary patch literal 16965 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 Y=ZmqHj645$H1W2vM41-Q{N4S306*jS#sB~S literal 29598 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 From 180948c51c7a33b385471072603650cc55fe4486 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 24 Jun 2019 19:36:50 +0200 Subject: [PATCH 73/92] Import previous aws account --- pandora_console/extras/mr/29.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pandora_console/extras/mr/29.sql b/pandora_console/extras/mr/29.sql index 033165d085..a1e966a0e3 100644 --- a/pandora_console/extras/mr/29.sql +++ b/pandora_console/extras/mr/29.sql @@ -14,4 +14,7 @@ CREATE TABLE IF NOT EXISTS `tcredential_store` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +INSERT INTO `tcredential_store` (`identifier`, `id_group`, `product`, `username`, `password`) VALUES ("imported_aws_account", 0, "AWS", (SELECT `value` FROM `tconfig` WHERE `token` = "aws_access_key_id" LIMIT 1), (SELECT `value` FROM `tconfig` WHERE `token` = "aws_secret_access_key" LIMIT 1)); + + COMMIT; From 882aa67b3abfbd19028195f1a106683562727d0d Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 24 Jun 2019 20:35:24 +0200 Subject: [PATCH 74/92] aws multi account viewer rc1 --- pandora_console/include/styles/firts_task.css | 4 ++++ pandora_console/include/styles/pandora.css | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/pandora_console/include/styles/firts_task.css b/pandora_console/include/styles/firts_task.css index c3650d2a8e..be75dd632d 100755 --- a/pandora_console/include/styles/firts_task.css +++ b/pandora_console/include/styles/firts_task.css @@ -78,3 +78,7 @@ div.new_task_cluster > div { #fuerte { font-size: 12px; } + +.flex-row-baseline * { + margin-right: 1em; +} diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 015d465993..965714c7d4 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -524,6 +524,12 @@ select:-internal-list-box { justify-content: space-between; align-content: center; } +.flex-row-baseline { + display: flex; + flex-direction: row; + flex-wrap: wrap; + align-items: baseline; +} .nowrap { flex-wrap: nowrap; From a469ff29daf2b8f4ce88b1e4cf140e88e9341ec4 Mon Sep 17 00:00:00 2001 From: artica Date: Tue, 25 Jun 2019 00:01:09 +0200 Subject: [PATCH 75/92] Auto-updated build strings. --- pandora_agents/unix/DEBIAN/control | 2 +- pandora_agents/unix/DEBIAN/make_deb_package.sh | 2 +- pandora_agents/unix/pandora_agent | 2 +- pandora_agents/unix/pandora_agent.redhat.spec | 2 +- pandora_agents/unix/pandora_agent.spec | 2 +- pandora_agents/unix/pandora_agent_installer | 2 +- pandora_agents/win32/installer/pandora.mpi | 2 +- pandora_agents/win32/pandora.cc | 2 +- pandora_agents/win32/versioninfo.rc | 2 +- pandora_console/DEBIAN/control | 2 +- pandora_console/DEBIAN/make_deb_package.sh | 2 +- pandora_console/include/config_process.php | 2 +- pandora_console/install.php | 2 +- pandora_console/pandora_console.redhat.spec | 2 +- pandora_console/pandora_console.rhel7.spec | 2 +- pandora_console/pandora_console.spec | 2 +- pandora_server/DEBIAN/control | 2 +- pandora_server/DEBIAN/make_deb_package.sh | 2 +- pandora_server/lib/PandoraFMS/Config.pm | 2 +- pandora_server/lib/PandoraFMS/PluginTools.pm | 2 +- pandora_server/pandora_server.redhat.spec | 2 +- pandora_server/pandora_server.spec | 2 +- pandora_server/pandora_server_installer | 2 +- pandora_server/util/pandora_db.pl | 2 +- pandora_server/util/pandora_manage.pl | 2 +- 25 files changed, 25 insertions(+), 25 deletions(-) diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index 740ea789c5..6771606f50 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.735-190624 +Version: 7.0NG.735-190625 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index 170c5bcee5..fe7628e999 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.735-190624" +pandora_version="7.0NG.735-190625" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 8b00991b4a..6bbb463b49 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -42,7 +42,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.735'; -use constant AGENT_BUILD => '190624'; +use constant AGENT_BUILD => '190625'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index fabb18238b..8f580504eb 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.735 -%define release 190624 +%define release 190625 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index 9a8f15d4f6..28023a28f3 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.735 -%define release 190624 +%define release 190625 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index d315e8ea8f..879ff79eac 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.735" -PI_BUILD="190624" +PI_BUILD="190625" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index 0bfbced120..21e38fb13b 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{190624} +{190625} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index 44997b04a5..2194b622ac 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.735(Build 190624)") +#define PANDORA_VERSION ("7.0NG.735(Build 190625)") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index 3ad4771da2..f328ab299c 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Artica ST" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.735(Build 190624))" + VALUE "ProductVersion", "(7.0NG.735(Build 190625))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index 532200a913..8a166990ab 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.735-190624 +Version: 7.0NG.735-190625 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index 17b872cf03..2d45e0aa49 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.735-190624" +pandora_version="7.0NG.735-190625" package_pear=0 package_pandora=1 diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index de7af03832..60a348e138 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC190624'; +$build_version = 'PC190625'; $pandora_version = 'v7.0NG.735'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/install.php b/pandora_console/install.php index 56e6c61d3c..2e3074241c 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -129,7 +129,7 @@
[ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index 4536349a29..d6b4578521 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.735 -%define release 190624 +%define release 190625 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index 7f9d84c9d3..f3758822ff 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.735 -%define release 190624 +%define release 190625 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index 5b6f79452d..b63386d7df 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.735" -PI_BUILD="190624" +PI_BUILD="190625" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index a8bcb0e5f5..875f8f51dd 100644 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -34,7 +34,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.735 PS190624"; +my $version = "7.0NG.735 PS190625"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 49beaa79bb..e00e964276 100644 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.735 PS190624"; +my $version = "7.0NG.735 PS190625"; # save program name for logging my $progname = basename($0); From a507d28c1f38e02fa187fea9150f5967ca077044 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Tue, 25 Jun 2019 10:12:25 +0200 Subject: [PATCH 76/92] Update Aws agent names --- pandora_console/extras/mr/29.sql | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/pandora_console/extras/mr/29.sql b/pandora_console/extras/mr/29.sql index a1e966a0e3..ca88b34fff 100644 --- a/pandora_console/extras/mr/29.sql +++ b/pandora_console/extras/mr/29.sql @@ -3,18 +3,23 @@ START TRANSACTION; DELETE FROM `ttipo_modulo` WHERE `nombre` LIKE 'log4x'; CREATE TABLE IF NOT EXISTS `tcredential_store` ( - `identifier` varchar(100) NOT NULL, - `id_group` mediumint(4) unsigned NOT NULL DEFAULT 0, - `product` enum('CUSTOM', 'AWS', 'AZURE', 'GOOGLE') default 'CUSTOM', - `username` text, - `password` text, - `extra_1` text, - `extra_2` text, - PRIMARY KEY (`identifier`) + `identifier` varchar(100) NOT NULL, + `id_group` mediumint(4) unsigned NOT NULL DEFAULT 0, + `product` enum('CUSTOM', 'AWS', 'AZURE', 'GOOGLE') default 'CUSTOM', + `username` text, + `password` text, + `extra_1` text, + `extra_2` text, + PRIMARY KEY (`identifier`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `tcredential_store` (`identifier`, `id_group`, `product`, `username`, `password`) VALUES ("imported_aws_account", 0, "AWS", (SELECT `value` FROM `tconfig` WHERE `token` = "aws_access_key_id" LIMIT 1), (SELECT `value` FROM `tconfig` WHERE `token` = "aws_secret_access_key" LIMIT 1)); +DELETE FROM `tcredential_store` WHERE `username` IS NULL AND `password` IS NULL; + +UPDATE `tagente` ta INNER JOIN `tagente` taa on ta.`id_parent` = taa.`id_agente` AND taa.`nombre` IN ("us-east-1", "us-east-2", "us-west-1", "us-west-2", "ca-central-1", "eu-central-1", "eu-west-1", "eu-west-2", "eu-west-3", "ap-northeast-1", "ap-northeast-2", "ap-southeast-1", "ap-southeast-2", "ap-south-1", "sa-east-1") SET ta.nombre = md5(concat((SELECT `username` FROM `tcredential_store` WHERE `identifier` = "imported_aws_account" LIMIT 1), ta.`nombre`)); + +UPDATE `tagente` SET `nombre` = md5(concat((SELECT `username` FROM `tcredential_store` WHERE `identifier` = "imported_aws_account" LIMIT 1), `nombre`)) WHERE `nombre` IN ("Aws", "us-east-1", "us-east-2", "us-west-1", "us-west-2", "ca-central-1", "eu-central-1", "eu-west-1", "eu-west-2", "eu-west-3", "ap-northeast-1", "ap-northeast-2", "ap-southeast-1", "ap-southeast-2", "ap-south-1", "sa-east-1"); COMMIT; From 86600ca4542fa3fff050c51f2783140ffe5f0be0 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Tue, 25 Jun 2019 12:21:18 +0200 Subject: [PATCH 77/92] RSS menu filter loaded --- pandora_console/operation/menu.php | 32 +++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/pandora_console/operation/menu.php b/pandora_console/operation/menu.php index 5daf40d310..936cb6a814 100644 --- a/pandora_console/operation/menu.php +++ b/pandora_console/operation/menu.php @@ -373,10 +373,36 @@ if (check_acl($config['id_user'], 0, 'ER') $pss = get_user_info($config['id_user']); $hashup = md5($config['id_user'].$pss['password']); + $user_filter = db_get_row_sql( + sprintf( + 'SELECT f.id_filter, f.id_name + FROM tevent_filter f + INNER JOIN tusuario u + ON u.default_event_filter=f.id_filter + WHERE u.id_user = "%s" ', + $config['id_user'] + ) + ); + if ($user_filter !== false) { + $filter = events_get_event_filter($user_filter['id_filter']); + } else { + // Default. + $filter = [ + 'status' => EVENT_NO_VALIDATED, + 'event_view_hr' => $config['event_view_hr'], + 'group_rep' => 1, + 'tag_with' => [], + 'tag_without' => [], + 'history' => false, + ]; + } + + $fb64 = base64_encode(json_encode($filter)); + // RSS. - $sub['operation/events/events_rss.php?user='.$config['id_user'].'&hashup='.$hashup.'&search=&event_type=&severity=-1&status=3&id_group=0&refr=0&id_agent=0&pagination=20&group_rep=1&event_view_hr=8&id_user_ack=0&tag_with=&tag_without=&filter_only_alert-1&offset=0&toogle_filter=no&filter_id=0&id_name=&id_group=0&history=0§ion=list&open_filter=0&pure=']['text'] = __('RSS'); - $sub['operation/events/events_rss.php?user='.$config['id_user'].'&hashup='.$hashup.'&search=&event_type=&severity=-1&status=3&id_group=0&refr=0&id_agent=0&pagination=20&group_rep=1&event_view_hr=8&id_user_ack=0&tag_with=&tag_without=&filter_only_alert-1&offset=0&toogle_filter=no&filter_id=0&id_name=&id_group=0&history=0§ion=list&open_filter=0&pure=']['id'] = 'RSS'; - $sub['operation/events/events_rss.php?user='.$config['id_user'].'&hashup='.$hashup.'&search=&event_type=&severity=-1&status=3&id_group=0&refr=0&id_agent=0&pagination=20&group_rep=1&event_view_hr=8&id_user_ack=0&tag_with=&tag_without=&filter_only_alert-1&offset=0&toogle_filter=no&filter_id=0&id_name=&id_group=0&history=0§ion=list&open_filter=0&pure=']['type'] = 'direct'; + $sub['operation/events/events_rss.php?user='.$config['id_user'].'&hashup='.$hashup.'&fb64='.$fb64]['text'] = __('RSS'); + $sub['operation/events/events_rss.php?user='.$config['id_user'].'&hashup='.$hashup.'&fb64='.$fb64]['id'] = 'RSS'; + $sub['operation/events/events_rss.php?user='.$config['id_user'].'&hashup='.$hashup.'&fb64='.$fb64]['type'] = 'direct'; // Marquee. $sub['operation/events/events_marquee.php']['text'] = __('Marquee'); From 674c68bd2bb6dac2bc4c6f520bd33871c01565b6 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Tue, 25 Jun 2019 12:49:17 +0200 Subject: [PATCH 78/92] avoided issue latin1 btoa javascript event transfer --- pandora_console/operation/events/events.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pandora_console/operation/events/events.php b/pandora_console/operation/events/events.php index ee44713385..da7123e728 100644 --- a/pandora_console/operation/events/events.php +++ b/pandora_console/operation/events/events.php @@ -294,6 +294,9 @@ if (is_ajax()) { ); $tmp->data = format_numeric($tmp->data, 1); + + $tmp->b64 = base64_encode(json_encode($tmp)); + $carry[] = $tmp; return $carry; } @@ -1599,7 +1602,7 @@ function process_datatables_item(item) { // Add event severity to end of text. evn = ''; + evn += item.b64+'\','+$("#group_rep").val()+');">'; // Grouped events. if(item.event_rep && item.event_rep > 1) { evn += '('+item.event_rep+') '; @@ -1705,7 +1708,7 @@ function process_datatables_item(item) { /* Options */ // Show more. item.options = ' __('Show more')]); ?>'; Date: Tue, 25 Jun 2019 13:37:44 +0200 Subject: [PATCH 79/92] Changed variable that modify min values --- pandora_console/godmode/agentes/configurar_agente.php | 2 +- pandora_console/godmode/agentes/module_manager_editor.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pandora_console/godmode/agentes/configurar_agente.php b/pandora_console/godmode/agentes/configurar_agente.php index 22410b0e23..d5f6f1fcfd 100644 --- a/pandora_console/godmode/agentes/configurar_agente.php +++ b/pandora_console/godmode/agentes/configurar_agente.php @@ -1213,7 +1213,7 @@ if ($update_module || $create_module) { $max_timeout = (int) get_parameter('max_timeout'); $max_retries = (int) get_parameter('max_retries'); - $min = (int) get_parameter_post('min'); + $min = (int) get_parameter('min'); $max = (int) get_parameter('max'); $interval = (int) get_parameter('module_interval', $intervalo); $ff_interval = (int) get_parameter('module_ff_interval'); diff --git a/pandora_console/godmode/agentes/module_manager_editor.php b/pandora_console/godmode/agentes/module_manager_editor.php index b340761265..13c313892a 100644 --- a/pandora_console/godmode/agentes/module_manager_editor.php +++ b/pandora_console/godmode/agentes/module_manager_editor.php @@ -267,10 +267,10 @@ if ($id_agent_module) { $cron_interval = explode(' ', $module['cron_interval']); if (isset($cron_interval[4])) { $minute_from = $cron_interval[0]; - $min = explode('-', $minute_from); - $minute_from = $min[0]; - if (isset($min[1])) { - $minute_to = $min[1]; + $minute = explode('-', $minute_from); + $minute_from = $minute[0]; + if (isset($minute[1])) { + $minute_to = $minute[1]; } $hour_from = $cron_interval[1]; From 004eb1104897c3bad1bcc169c4eb53d92ff8ca0b Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Tue, 25 Jun 2019 15:24:15 +0200 Subject: [PATCH 80/92] MR29 --- pandora_console/extras/mr/29.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pandora_console/extras/mr/29.sql b/pandora_console/extras/mr/29.sql index 032dd407b1..5b88329fbf 100644 --- a/pandora_console/extras/mr/29.sql +++ b/pandora_console/extras/mr/29.sql @@ -1,5 +1,7 @@ START TRANSACTION; +ALTER TABLE `tmetaconsole_agent` ADD INDEX `id_tagente_idx` (`id_tagente`); + DELETE FROM `ttipo_modulo` WHERE `nombre` LIKE 'log4x'; From c5675ded4c4a24c3fcb482a2716f40eb45ab7cfa Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Tue, 25 Jun 2019 15:24:42 +0200 Subject: [PATCH 81/92] fixed alert color --- pandora_console/include/constants.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/include/constants.php b/pandora_console/include/constants.php index 8a67ba1111..69e867bb40 100644 --- a/pandora_console/include/constants.php +++ b/pandora_console/include/constants.php @@ -146,7 +146,7 @@ define('COL_NOTINIT', '#4a83f3'); define('COL_UNKNOWN', '#B2B2B2'); define('COL_DOWNTIME', '#976DB1'); define('COL_IGNORED', '#DDD'); -define('COL_ALERTFIRED', '#FFA631'); +define('COL_ALERTFIRED', '#F36201'); define('COL_MINOR', '#B2B2B2'); define('COL_MAJOR', '#C97A4A'); define('COL_INFORMATIONAL', '#E4E4E4'); From ae4a9dc32457f544ebb8ea39bc3095994e00869e Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Tue, 25 Jun 2019 15:33:19 +0200 Subject: [PATCH 82/92] Fixed uninitialized value in pattern match --- pandora_server/lib/PandoraFMS/Core.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_server/lib/PandoraFMS/Core.pm b/pandora_server/lib/PandoraFMS/Core.pm index ee66b5ca68..2020abd5d4 100644 --- a/pandora_server/lib/PandoraFMS/Core.pm +++ b/pandora_server/lib/PandoraFMS/Core.pm @@ -3866,7 +3866,7 @@ sub subst_alert_macros ($$;$$$$) { my $macro_regexp = join('|', keys %{$macros}); my $subst_func; - if ($string =~ m/^(?:(")(?:.*)"|(')(?:.*)')$/) { + if (defined($string) && $string =~ m/^(?:(")(?:.*)"|(')(?:.*)')$/) { my $quote = $1 ? $1 : $2; $subst_func = sub { my $macro = on_demand_macro($pa_config, $dbh, shift, $macros, $agent, $module); From 96ca26dc97e9cb47c524b1feff9de7d136f98e7a Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Tue, 25 Jun 2019 16:05:56 +0200 Subject: [PATCH 83/92] minor fix in event mass response process --- .../include/javascript/pandora_events.js | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/pandora_console/include/javascript/pandora_events.js b/pandora_console/include/javascript/pandora_events.js index 406cffe243..afd9fbe573 100644 --- a/pandora_console/include/javascript/pandora_events.js +++ b/pandora_console/include/javascript/pandora_events.js @@ -231,7 +231,6 @@ function get_response(response_id) { type: "POST", url: $("#hidden-ajax_file").val(), async: false, - timeout: 10000, dataType: "json", success: function(data) { response = data; @@ -255,7 +254,6 @@ function get_response_params(response_id) { type: "POST", url: $("#hidden-ajax_file").val(), async: false, - timeout: 10000, dataType: "json", success: function(data) { response_params = data; @@ -279,7 +277,6 @@ function get_response_description(response_id) { type: "POST", url: $("#hidden-ajax_file").val(), async: false, - timeout: 10000, dataType: "html", success: function(data) { response_description = data; @@ -305,7 +302,6 @@ function get_event_name(event_id, meta, history) { type: "POST", url: $("#hidden-ajax_file").val(), async: false, - timeout: 10000, dataType: "html", success: function(data) { name = data; @@ -349,7 +345,6 @@ function get_response_target( type: "POST", url: $("#hidden-ajax_file").val(), async: false, - timeout: 10000, dataType: "html", success: function(data) { target = data; @@ -394,7 +389,6 @@ function perform_response(target, response_id) { type: "POST", url: $("#hidden-ajax_file").val(), async: true, - timeout: 10000, dataType: "html", success: function(data) { var out = data.replace(/[\n|\r]/g, "
"); @@ -424,7 +418,6 @@ function perform_response_massive(target, response_id, out_iterator) { type: "POST", url: $("#hidden-ajax_file").val(), async: true, - timeout: 10000, dataType: "html", success: function(data) { var out = data.replace(/[\n|\r]/g, "
"); @@ -460,7 +453,6 @@ function event_change_status(event_ids) { type: "POST", url: $("#hidden-ajax_file").val(), async: true, - timeout: 10000, dataType: "html", success: function(data) { $("#button-status_button").removeAttr("disabled"); @@ -499,7 +491,6 @@ function event_change_owner() { type: "POST", url: $("#hidden-ajax_file").val(), async: true, - timeout: 10000, dataType: "html", success: function(data) { $("#button-owner_button").removeAttr("disabled"); @@ -553,7 +544,6 @@ function event_comment() { type: "POST", url: $("#hidden-ajax_file").val(), async: true, - timeout: 10000, dataType: "html", success: function(data) { $("#button-comment_button").removeAttr("disabled"); @@ -680,7 +670,6 @@ function update_event(table, id_evento, type, event_rep, row) { // Update events matching current filters and id_evento selected. $.ajax({ async: true, - timeout: 10000, type: "POST", url: $("#hidden-ajax_file").val(), data: { @@ -721,6 +710,7 @@ function validate_event(table, id_evento, event_rep, row) { var button = document.getElementById("val-" + id_evento); if (!button) { // Button does not exist. Ignore. + processed += 1; return; } @@ -733,6 +723,7 @@ function in_process_event(table, id_evento, event_rep, row) { var button = document.getElementById("proc-" + id_evento); if (!button) { // Button does not exist. Ignore. + processed += 1; return; } @@ -751,6 +742,7 @@ function delete_event(table, id_evento, event_rep, row) { var button = document.getElementById("del-" + id_evento); if (!button) { // Button does not exist. Ignore. + processed += 1; return; } From 22d936d4f3bb2675ec9019e83963a6185167ed46 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Tue, 25 Jun 2019 16:43:38 +0200 Subject: [PATCH 84/92] credential store some js controls --- pandora_console/godmode/groups/credential_store.php | 4 ++++ pandora_console/include/functions_credential_store.php | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pandora_console/godmode/groups/credential_store.php b/pandora_console/godmode/groups/credential_store.php index 729a2ff7bd..01e7f11bfa 100644 --- a/pandora_console/godmode/groups/credential_store.php +++ b/pandora_console/godmode/groups/credential_store.php @@ -386,6 +386,7 @@ echo '
'; if (!failed) { dt_.draw(0); $(".ui-dialog-content").dialog("close"); + $('.ui-dialog-content').remove(); } else { $(this).dialog('close'); } @@ -406,6 +407,7 @@ echo '
'; text: '', click: function(e) { $(this).dialog('close'); + $(this).remove(); } }, { @@ -462,6 +464,7 @@ echo ''; text: '', click: function(e) { $(this).dialog('close'); + $(this).remove(); } }, { @@ -552,6 +555,7 @@ echo ''; text: "", click: function(e) { $(this).dialog('close'); + $(this).remove(); } }, { diff --git a/pandora_console/include/functions_credential_store.php b/pandora_console/include/functions_credential_store.php index acc6a2c09f..accc9348fd 100644 --- a/pandora_console/include/functions_credential_store.php +++ b/pandora_console/include/functions_credential_store.php @@ -277,7 +277,7 @@ function print_inputs($values=null) 'id' => 'id_group', 'input_class' => 'flex-row', 'type' => 'select_groups', - 'selected' => $values['id_grupo'], + 'selected' => $values['id_group'], 'return' => true, 'class' => 'w50p', ] @@ -288,6 +288,7 @@ function print_inputs($values=null) 'name' => 'product', 'input_class' => 'flex-row', 'type' => 'select', + 'script' => 'calculate_inputs()', 'fields' => [ 'CUSTOM' => __('Custom'), 'AWS' => __('Aws'), From 8f914b69a601538b76954c61d4644e3c16e2fe19 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Tue, 25 Jun 2019 17:24:16 +0200 Subject: [PATCH 85/92] Minor fixes --- pandora_console/include/javascript/pandora_events.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/include/javascript/pandora_events.js b/pandora_console/include/javascript/pandora_events.js index afd9fbe573..94dadb6fbb 100644 --- a/pandora_console/include/javascript/pandora_events.js +++ b/pandora_console/include/javascript/pandora_events.js @@ -688,7 +688,7 @@ function update_event(table, id_evento, type, event_rep, row) { var diff_s = diff_g / 1000; if (processed >= $(".chk_val:checked").length) { // If operation takes less than 2 seconds, redraw. - if (diff_s < 2) { + if (diff_s < 2 || $(".chk_val:checked").length > 1) { redraw = true; } if (redraw) { From e1bf12a1fb9c8fc8c1bb2166063c1be902d4c421 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Tue, 25 Jun 2019 18:21:23 +0200 Subject: [PATCH 86/92] Credential store --- .../godmode/groups/credential_store.php | 157 +++++++++++------- .../include/functions_credential_store.php | 7 +- 2 files changed, 99 insertions(+), 65 deletions(-) diff --git a/pandora_console/godmode/groups/credential_store.php b/pandora_console/godmode/groups/credential_store.php index 01e7f11bfa..9a822dc986 100644 --- a/pandora_console/godmode/groups/credential_store.php +++ b/pandora_console/godmode/groups/credential_store.php @@ -49,16 +49,21 @@ if (! check_acl($config['id_user'], 0, 'PM')) { // Required files. ui_require_css_file('credential_store'); require_once $config['homedir'].'/include/functions_credential_store.php'; - +require_once $config['homedir'].'/include/functions_io.php'; if (is_ajax()) { $draw = get_parameter('draw', 0); $filter = get_parameter('filter', []); $get_key = get_parameter('get_key', 0); + $new_form = get_parameter('new_form', 0); $new_key = get_parameter('new_key', 0); $update_key = get_parameter('update_key', 0); $delete_key = get_parameter('delete_key', 0); + if ($new_form) { + echo print_inputs(); + exit; + } if ($delete_key) { $identifier = get_parameter('identifier', null); @@ -130,6 +135,9 @@ if (is_ajax()) { $values = []; foreach ($data as $key => $value) { $values[$key] = base64_decode($value); + if ($key == 'identifier') { + $values[$key] = preg_replace('/\s+/', '-', trim($values[$key])); + } } $identifier = $values['identifier']; @@ -318,8 +326,7 @@ try { // Auxiliar div. $new = ''; +$new .= ''; $details = ''; $aux = ''; @@ -386,7 +393,7 @@ echo ''; if (!failed) { dt_.draw(0); $(".ui-dialog-content").dialog("close"); - $('.ui-dialog-content').remove(); + cleanupDOM(); } else { $(this).dialog('close'); } @@ -407,7 +414,8 @@ echo ''; text: '', click: function(e) { $(this).dialog('close'); - $(this).remove(); + cleanupDOM(); + } }, { @@ -464,7 +472,7 @@ echo ''; text: '', click: function(e) { $(this).dialog('close'); - $(this).remove(); + cleanupDOM(); } }, { @@ -503,6 +511,15 @@ echo ''; }) } + function cleanupDOM() { + $('#div-identifier').empty(); + $('#div-product').empty(); + $('#div-username').empty(); + $('#div-password').empty(); + $('#div-extra_1').empty(); + $('#div-extra_2').empty(); + } + function calculate_inputs() { if ($('#product :selected').val() == "CUSTOM") { $('#div-username label').text(''); @@ -528,66 +545,82 @@ echo ''; function add_key() { // Clear form. - $('#form_new :input').each(function() { - $(this).val('') - }); - $('#id_group').val(0); - $('#product').val('CUSTOM'); - - $('#product').on('change', function() { - calculate_inputs() - }); - - // Show form. - $('#new_key').dialog({ - width: 580, - height: 400, - position: { - my: 'center', - at: 'center', - of: window, - collision: 'fit' + $('#form_update').empty(); + $('#form_update').html('Loading...'); + $.ajax({ + method: 'post', + url: '', + data: { + page: 'godmode/groups/credential_store', + new_form: 1 }, - title: "", - buttons: [ - { - class: 'ui-widget ui-state-default ui-corner-all ui-button-text-only sub upd submit-cancel', - text: "", - click: function(e) { - $(this).dialog('close'); - $(this).remove(); - } - }, - { - class: 'ui-widget ui-state-default ui-corner-all ui-button-text-only sub ok submit-next', - text: 'OK', - click: function(e) { - var values = {}; + success: function(data) { + $('#form_new').html(data); + $('#id_group').val(0); + // By default AWS. + $('#product').val('AWS'); + calculate_inputs(); - $('#form_new :input').each(function() { - values[this.name] = btoa($(this).val()); - }); + $('#product').on('change', function() { + calculate_inputs() + }); - $.ajax({ - method: 'post', - url: '', - data: { - page: 'godmode/groups/credential_store', - new_key: 1, - values: values - }, - datatype: "json", - success: function (data) { - handle_response(data); - }, - error: function(e) { - handle_response(e); + // Show form. + $('#new_key').dialog({ + width: 580, + height: 400, + position: { + my: 'center', + at: 'center', + of: window, + collision: 'fit' + }, + title: "", + buttons: [ + { + class: 'ui-widget ui-state-default ui-corner-all ui-button-text-only sub upd submit-cancel', + text: "", + click: function(e) { + $(this).dialog('close'); + cleanupDOM(); } - }); - } - }, - ] - }); + }, + { + class: 'ui-widget ui-state-default ui-corner-all ui-button-text-only sub ok submit-next', + text: 'OK', + click: function(e) { + var values = {}; + + console.log($('#form_new')); + + $('#form_new :input').each(function() { + values[this.name] = btoa($(this).val()); + }); + + $.ajax({ + method: 'post', + url: '', + data: { + page: 'godmode/groups/credential_store', + new_key: 1, + values: values + }, + datatype: "json", + success: function (data) { + handle_response(data); + }, + error: function(e) { + handle_response(e); + } + }); + } + }, + ] + }); + } + }) + + } $(document).ready(function(){ diff --git a/pandora_console/include/functions_credential_store.php b/pandora_console/include/functions_credential_store.php index accc9348fd..e49bd71399 100644 --- a/pandora_console/include/functions_credential_store.php +++ b/pandora_console/include/functions_credential_store.php @@ -268,6 +268,7 @@ function print_inputs($values=null) 'value' => $values['identifier'], 'disabled' => (bool) $values['identifier'], 'return' => true, + 'script' => 'alert(\'puta\')', ] ); $return .= html_print_input( @@ -290,9 +291,9 @@ function print_inputs($values=null) 'type' => 'select', 'script' => 'calculate_inputs()', 'fields' => [ - 'CUSTOM' => __('Custom'), - 'AWS' => __('Aws'), - 'AZURE' => __('Azure'), + // 'CUSTOM' => __('Custom'), + 'AWS' => __('Aws'), + // 'AZURE' => __('Azure'), // 'GOOGLE' => __('Google'), ], 'selected' => $values['product'], From 9a65d8188a2cc67375a46a8e552e859524d0aad5 Mon Sep 17 00:00:00 2001 From: artica Date: Wed, 26 Jun 2019 00:01:09 +0200 Subject: [PATCH 87/92] Auto-updated build strings. --- pandora_agents/unix/DEBIAN/control | 2 +- pandora_agents/unix/DEBIAN/make_deb_package.sh | 2 +- pandora_agents/unix/pandora_agent | 2 +- pandora_agents/unix/pandora_agent.redhat.spec | 2 +- pandora_agents/unix/pandora_agent.spec | 2 +- pandora_agents/unix/pandora_agent_installer | 2 +- pandora_agents/win32/installer/pandora.mpi | 2 +- pandora_agents/win32/pandora.cc | 2 +- pandora_agents/win32/versioninfo.rc | 2 +- pandora_console/DEBIAN/control | 2 +- pandora_console/DEBIAN/make_deb_package.sh | 2 +- pandora_console/include/config_process.php | 2 +- pandora_console/install.php | 2 +- pandora_console/pandora_console.redhat.spec | 2 +- pandora_console/pandora_console.rhel7.spec | 2 +- pandora_console/pandora_console.spec | 2 +- pandora_server/DEBIAN/control | 2 +- pandora_server/DEBIAN/make_deb_package.sh | 2 +- pandora_server/lib/PandoraFMS/Config.pm | 2 +- pandora_server/lib/PandoraFMS/PluginTools.pm | 2 +- pandora_server/pandora_server.redhat.spec | 2 +- pandora_server/pandora_server.spec | 2 +- pandora_server/pandora_server_installer | 2 +- pandora_server/util/pandora_db.pl | 2 +- pandora_server/util/pandora_manage.pl | 2 +- 25 files changed, 25 insertions(+), 25 deletions(-) diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index 6771606f50..2faf21c47a 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.735-190625 +Version: 7.0NG.735-190626 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index fe7628e999..7521094eba 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.735-190625" +pandora_version="7.0NG.735-190626" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 6bbb463b49..3cf1d22126 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -42,7 +42,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.735'; -use constant AGENT_BUILD => '190625'; +use constant AGENT_BUILD => '190626'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index 8f580504eb..725d5abaa2 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.735 -%define release 190625 +%define release 190626 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index 28023a28f3..970291a4c3 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.735 -%define release 190625 +%define release 190626 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index 879ff79eac..2b9cf3b68c 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.735" -PI_BUILD="190625" +PI_BUILD="190626" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index 21e38fb13b..7aecb7cff2 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{190625} +{190626} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index 2194b622ac..f655faabc6 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.735(Build 190625)") +#define PANDORA_VERSION ("7.0NG.735(Build 190626)") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index f328ab299c..3d3a2ebf4a 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Artica ST" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.735(Build 190625))" + VALUE "ProductVersion", "(7.0NG.735(Build 190626))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index 8a166990ab..5fc2731073 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.735-190625 +Version: 7.0NG.735-190626 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index 2d45e0aa49..44d78e12ac 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.735-190625" +pandora_version="7.0NG.735-190626" package_pear=0 package_pandora=1 diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 60a348e138..95f6595032 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC190625'; +$build_version = 'PC190626'; $pandora_version = 'v7.0NG.735'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/install.php b/pandora_console/install.php index 2e3074241c..00a940965b 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -129,7 +129,7 @@
[ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index d6b4578521..14abd0603d 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.735 -%define release 190625 +%define release 190626 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index f3758822ff..3e53f83626 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.735 -%define release 190625 +%define release 190626 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index b63386d7df..97459cff2f 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.735" -PI_BUILD="190625" +PI_BUILD="190626" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 875f8f51dd..b9f0bfa2d2 100644 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -34,7 +34,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.735 PS190625"; +my $version = "7.0NG.735 PS190626"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index e00e964276..c6c88c7139 100644 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.735 PS190625"; +my $version = "7.0NG.735 PS190626"; # save program name for logging my $progname = basename($0); From fdf2a983d291ca0e49d374da458f2797b712566a Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 26 Jun 2019 10:39:18 +0200 Subject: [PATCH 88/92] general review credential store --- pandora_console/include/functions_credential_store.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/include/functions_credential_store.php b/pandora_console/include/functions_credential_store.php index e49bd71399..cf09e6d67b 100644 --- a/pandora_console/include/functions_credential_store.php +++ b/pandora_console/include/functions_credential_store.php @@ -403,7 +403,7 @@ function credentials_list_accounts($product) if (!isset($user_groups)) { $user_groups = users_get_groups( $config['id_user'], - 'AW' + 'AR' ); // Always add group 'ALL' because 'ALL' group credentials From f66e5b5ef8434cf55989c8bfc6d3776363de823b Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 26 Jun 2019 11:11:21 +0200 Subject: [PATCH 89/92] Fix class names to avoid addblock hide them --- pandora_console/godmode/agentes/agent_manager.php | 4 ++-- pandora_console/include/styles/agent_manager.css | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pandora_console/godmode/agentes/agent_manager.php b/pandora_console/godmode/agentes/agent_manager.php index 7c6a3ab03b..3ea3a7f0c2 100644 --- a/pandora_console/godmode/agentes/agent_manager.php +++ b/pandora_console/godmode/agentes/agent_manager.php @@ -777,7 +777,7 @@ $table_adv_options = ' '.$adv_secondary_groups_right.'
-
+
'.$table_adv_parent.$table_adv_module_mode.$table_adv_cascade; if ($new_agent) { @@ -788,7 +788,7 @@ if ($new_agent) { $table_adv_options .= '
'; $table_adv_options .= ' -
+
'.$table_adv_gis.$table_adv_agent_icon.$table_adv_url.$table_adv_quiet.$table_adv_status.$table_adv_remote.$table_adv_safe.'
'; diff --git a/pandora_console/include/styles/agent_manager.css b/pandora_console/include/styles/agent_manager.css index a5e80a64ee..8b3e0db4f7 100644 --- a/pandora_console/include/styles/agent_manager.css +++ b/pandora_console/include/styles/agent_manager.css @@ -119,8 +119,8 @@ a#qr_code_agent_view { border-bottom-right-radius: 0px; } -.adv_right, -.adv_left, +.agent_av_opt_right, +.agent_av_opt_left, .secondary_groups_list { flex: 1; } @@ -150,8 +150,8 @@ a#qr_code_agent_view { margin: 1em; } -.adv_left input, -.adv_left select { +.agent_av_opt_left input, +.agent_av_opt_left select { width: 100%; } From 29932781781789d4200b06473c51028772e98b16 Mon Sep 17 00:00:00 2001 From: Alejandro Gallardo Escobar Date: Wed, 26 Jun 2019 11:33:45 +0200 Subject: [PATCH 90/92] Removed the resize functionality of the module graph vc item --- .../include/visual-console-client/vc.main.min.js | 2 +- .../include/visual-console-client/vc.main.min.js.map | 2 +- visual_console_client/src/Item.ts | 2 +- visual_console_client/src/items/ModuleGraph.ts | 9 +++++++++ 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/pandora_console/include/visual-console-client/vc.main.min.js b/pandora_console/include/visual-console-client/vc.main.min.js index 29b551979c..915f2deaaf 100644 --- a/pandora_console/include/visual-console-client/vc.main.min.js +++ b/pandora_console/include/visual-console-client/vc.main.min.js @@ -1,2 +1,2 @@ -!function(t){var e={};function n(i){if(e[i])return e[i].exports;var r=e[i]={i:i,l:!1,exports:{}};return t[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)n.d(i,r,function(e){return t[e]}.bind(null,r));return i},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=9)}([function(t,e,n){"use strict";n.d(e,"m",function(){return r}),n.d(e,"l",function(){return s}),n.d(e,"r",function(){return o}),n.d(e,"j",function(){return a}),n.d(e,"k",function(){return c}),n.d(e,"n",function(){return u}),n.d(e,"q",function(){return h}),n.d(e,"i",function(){return p}),n.d(e,"h",function(){return _}),n.d(e,"g",function(){return f}),n.d(e,"o",function(){return d}),n.d(e,"d",function(){return m}),n.d(e,"e",function(){return y}),n.d(e,"f",function(){return b}),n.d(e,"p",function(){return v}),n.d(e,"c",function(){return x}),n.d(e,"a",function(){return w}),n.d(e,"b",function(){return O});var i=function(){return(i=Object.assign||function(t){for(var e,n=1,i=arguments.length;n0&&!isNaN(parseInt(t))?parseInt(t):e}function s(t,e){return"number"==typeof t?t:"string"==typeof t&&t.length>0&&!isNaN(parseFloat(t))?parseFloat(t):e}function o(t){return null==t||0===t.length}function a(t,e){return"string"==typeof t&&t.length>0?t:e}function c(t){return"boolean"==typeof t?t:"number"==typeof t?t>0:"string"==typeof t&&("1"===t||"true"===t)}function l(t,e,n){void 0===n&&(n=" "),"number"==typeof t&&(t=""+t),"number"==typeof n&&(n=""+n);var i=e-t.length;if(0===i)return t;if(i<0)return t.substr(Math.abs(i));if(i===n.length)return""+n+t;if(i0&&id||y+r+m.width-b>u.width||r===x&&y<0&&i>f+x+c,A=h0&&h_||g+s+m.height-b>u.height||s===E&&g<0&&h>p+E+l;(e=O?0:T?x:y+r)<0&&(e=0),(n=A?0:k?E:g+s)<0&&(n=0),o=i,a=h,e===r&&n===s||(w(e,n),v(e,n),r=e,s=n)},T=function(){r=0,s=0,o=0,a=0,document.removeEventListener("mousemove",O),document.removeEventListener("mouseup",T),t.draggable=i,document.body.style.userSelect="auto"},A=function(e){e.stopPropagation(),t.draggable=!1,r=t.offsetLeft,s=t.offsetTop,o=e.pageX,a=e.pageY,c=e.offsetX,l=e.offsetY,u=n.getBoundingClientRect(),h=E(n),p=h.top,_=p+u.height,f=h.left,d=f+u.width,m=t.getBoundingClientRect(),y=window.getComputedStyle(t).borderWidth||"0",b=2*Number.parseInt(y),document.addEventListener("mousemove",O),document.addEventListener("mouseup",T),document.body.style.userSelect="none"};return t.addEventListener("mousedown",A),function(){t.removeEventListener("mousedown",A),T()}}function O(t,e){var n=document.createElement("div");n.className="resize-draggable",t.appendChild(n);var i=t.parentElement,r=t.draggable,s=0,o=0,a=0,c=0,l=0,u=i.getBoundingClientRect(),h=E(i),p=h.top,_=p+u.height,f=h.left,d=f+u.width,m=E(t),y=m.top,b=m.left,v=window.getComputedStyle(t).borderWidth||"0",w=Number.parseInt(v),O=x(32,function(t,n){return e(t,n)}),T=g(16,function(t,n){return e(t,n)}),A=function(t){var e=s+(t.pageX-a),n=o+(t.pageY-c);e===s&&n===o||eb+(s-l)||(e<15?e=15:e+b-w/2>=d&&(e=d-b),n<15?n=15:n+y-w/2>=_&&(n=_-y),T(e,n),O(e,n),s=e,o=n,a=t.pageX,c=t.pageY)},k=function(){s=0,o=0,a=0,c=0,l=0,0,document.removeEventListener("mousemove",A),document.removeEventListener("mouseup",k),t.draggable=r,document.body.style.userSelect="auto"};return n.addEventListener("mousedown",function(e){e.stopPropagation(),t.draggable=!1;var n=t.getBoundingClientRect(),r=n.width,v=n.height;s=r,o=v,a=e.pageX,c=e.pageY,l=e.offsetX,e.offsetY,u=i.getBoundingClientRect(),h=E(i),p=h.top,_=p+u.height,f=h.left,d=f+u.width,m=E(t),y=m.top,b=m.left,document.addEventListener("mousemove",A),document.addEventListener("mouseup",k),document.body.style.userSelect="none"}),function(){n.remove(),k()}}},function(t,e,n){"use strict";n.d(e,"b",function(){return a});var i=n(0),r=n(2),s=function(){return(s=Object.assign||function(t){for(var e,n=1,i=arguments.length;n0){var i=e.labelElementRef.getBoundingClientRect(),r=i.width,s=i.height;switch(e.props.labelPosition){case"up":case"down":n-=s;break;case"left":case"right":t-=r}}e.resizeElement(t,n),e.debouncedResizementSave(t,n)})},t.prototype.stopResizementListener=function(){this.removeResizement&&(this.removeResizement(),this.removeResizement=null)},t.prototype.createContainerDomElement=function(){var t,e=this;return this.props.isLinkEnabled?(t=document.createElement("a"),this.props.link&&(t.href=this.props.link)):t=document.createElement("div"),t.className="visual-console-item",t.style.zIndex=this.props.isOnTop?"2":"1",t.style.left=this.props.x+"px",t.style.top=this.props.y+"px",t.addEventListener("click",function(t){e.meta.editMode?(t.preventDefault(),t.stopPropagation()):e.clickEventManager.emit({data:e.props,nativeEvent:t})}),this.meta.editMode&&(t.classList.add("is-editing"),this.initMovementListener(t),this.initResizementListener(t)),this.meta.isFetching&&t.classList.add("is-fetching"),this.meta.isUpdating&&t.classList.add("is-updating"),t},t.prototype.createLabelDomElement=function(){var t=document.createElement("div");t.className="visual-console-item-label";var e=this.getLabelWithMacrosReplaced();if(e.length>0){var n=document.createElement("table"),i=document.createElement("tr"),r=document.createElement("tr"),s=document.createElement("tr"),o=document.createElement("td");switch(o.innerHTML=e,i.append(o),n.append(r,i,s),n.style.textAlign="center",this.props.labelPosition){case"up":case"down":this.props.width>0&&(n.style.width=this.props.width+"px",n.style.height=null);break;case"left":case"right":this.props.height>0&&(n.style.width=null,n.style.height=this.props.height+"px")}t.append(n)}return t},t.prototype.getLabelWithMacrosReplaced=function(){var t=this.props;return Object(i.p)([{macro:"_date_",value:Object(i.e)(new Date)},{macro:"_time_",value:Object(i.f)(new Date)},{macro:"_agent_",value:null!=t.agentAlias?t.agentAlias:""},{macro:"_agentdescription_",value:null!=t.agentDescription?t.agentDescription:""},{macro:"_address_",value:null!=t.agentAddress?t.agentAddress:""},{macro:"_module_",value:null!=t.moduleName?t.moduleName:""},{macro:"_moduledescription_",value:null!=t.moduleDescription?t.moduleDescription:""}],this.props.label||"")},t.prototype.updateDomElement=function(t){t.innerHTML=this.createDomElement().innerHTML},Object.defineProperty(t.prototype,"props",{get:function(){return s({},this.itemProps)},set:function(t){var e=this.props;this.itemProps=t,this.shouldBeUpdated(e,t)&&this.render(e,this._metadata)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"meta",{get:function(){return s({},this._metadata)},set:function(t){this.setMeta(t)},enumerable:!0,configurable:!0}),t.prototype.setMeta=function(t){var e=this._metadata;this._metadata=t,this.render(this.itemProps,e)},t.prototype.shouldBeUpdated=function(t,e){return t!==e},t.prototype.render=function(t,e){void 0===t&&(t=null),void 0===e&&(e=null),this.updateDomElement(this.childElementRef),t&&!this.positionChanged(t,this.props)||this.moveElement(this.props.x,this.props.y),t&&!this.sizeChanged(t,this.props)||this.resizeElement(this.props.width,this.props.height);var n=this.labelElementRef.innerHTML,i=this.createLabelDomElement().innerHTML;if(n!==i&&(this.labelElementRef.innerHTML=i),t&&t.labelPosition===this.props.labelPosition||this.changeLabelPosition(this.props.labelPosition),t&&(t.isLinkEnabled!==this.props.isLinkEnabled||this.props.isLinkEnabled&&t.link!==this.props.link)){var r=this.createContainerDomElement();r.innerHTML=this.elementRef.innerHTML;for(var s=this.elementRef.attributes,o=0;o0?e.item(0):null;if(n)switch(this.props.labelPosition){case"up":case"down":this.props.width>0&&(n.style.width=this.props.width+"px",n.style.height=null);break;case"left":case"right":this.props.height>0&&(n.style.width=null,n.style.height=this.props.height+"px")}},t.prototype.moveElement=function(t,e){this.elementRef.style.left=t+"px",this.elementRef.style.top=e+"px"},t.prototype.move=function(t,e){this.moveElement(t,e),this.itemProps=s({},this.props,{x:t,y:e})},t.prototype.sizeChanged=function(t,e){return t.width!==e.width||t.height!==e.height},t.prototype.resizeElement=function(t,e){if(this.childElementRef.style.width=t>0?t+"px":null,this.childElementRef.style.height=e>0?e+"px":null,this.props.label&&this.props.label.length>0){var n=this.labelElementRef.getElementsByTagName("table"),i=n.length>0?n.item(0):null;if(i)switch(this.props.labelPosition){case"up":case"down":i.style.width=t>0?t+"px":null;break;case"left":case"right":i.style.height=e>0?e+"px":null}}},t.prototype.resize=function(t,e){this.resizeElement(t,e),this.itemProps=s({},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.onMoved=function(t){var e=this.movedEventManager.on(t);return this.disposables.push(e),e},t.prototype.onResized=function(t){var e=this.resizedEventManager.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=c},function(t,e,n){"use strict";var i=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 n=t.listeners.indexOf(e);n>-1&&t.listeners.splice(n,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=i},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 n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(t,e)},function(t,e){function n(){this.constructor=t}extendStatics(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)}),extendStatics,__assign=function(){return(__assign=Object.assign||function(t){for(var e,n=1,i=arguments.length;n0){var y=document.createElementNS(t,"text");y.setAttribute("text-anchor","middle"),y.setAttribute("font-size","8"),y.setAttribute("transform","translate(30 50) rotate(90)"),y.setAttribute("fill",i),y.textContent=m,f.append(y)}var b=document.createElementNS(t,"g");b.setAttribute("class","marks");var v=document.createElementNS(t,"g");v.setAttribute("class","mark"),v.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",i),g.setAttribute("stroke-width","5");var x=document.createElementNS(t,"line");x.setAttribute("x1","36"),x.setAttribute("y1","0"),x.setAttribute("x2","46"),x.setAttribute("y2","0"),x.setAttribute("stroke",e),x.setAttribute("stroke-width","1"),v.append(g,x),b.append(v);for(var E=1;E<60;E++){var w=document.createElementNS(t,"line");w.setAttribute("y1","0"),w.setAttribute("y2","0"),w.setAttribute("stroke",i),w.setAttribute("transform","translate(50 50) rotate("+6*E+")"),E%5==0?(w.setAttribute("x1","38"),w.setAttribute("x2","46"),w.setAttribute("stroke-width",E%15==0?"2":"1")):(w.setAttribute("x1","42"),w.setAttribute("x2","46"),w.setAttribute("stroke-width","0.5")),b.append(w)}var O=document.createElementNS(t,"g");O.setAttribute("class","hour-hand"),O.setAttribute("transform","translate(50 50)");var T=document.createElementNS(t,"line");T.setAttribute("class","hour-hand-a"),T.setAttribute("x1","0"),T.setAttribute("y1","0"),T.setAttribute("x2","30"),T.setAttribute("y2","0"),T.setAttribute("stroke",o),T.setAttribute("stroke-width","4"),T.setAttribute("stroke-linecap","round");var A=document.createElementNS(t,"line");A.setAttribute("class","hour-hand-b"),A.setAttribute("x1","0"),A.setAttribute("y1","0"),A.setAttribute("x2","29.9"),A.setAttribute("y2","0"),A.setAttribute("stroke",s),A.setAttribute("stroke-width","3.1"),A.setAttribute("stroke-linecap","round"),O.append(T,A);var k=document.createElementNS(t,"g");k.setAttribute("class","minute-hand"),k.setAttribute("transform","translate(50 50)");var M=document.createElementNS(t,"line");M.setAttribute("class","minute-hand-a"),M.setAttribute("x1","0"),M.setAttribute("y1","0"),M.setAttribute("x2","40"),M.setAttribute("y2","0"),M.setAttribute("stroke",o),M.setAttribute("stroke-width","2"),M.setAttribute("stroke-linecap","round");var j=document.createElementNS(t,"line");j.setAttribute("class","minute-hand-b"),j.setAttribute("x1","0"),j.setAttribute("y1","0"),j.setAttribute("x2","39.9"),j.setAttribute("y2","0"),j.setAttribute("stroke",s),j.setAttribute("stroke-width","1.5"),j.setAttribute("stroke-linecap","round");var P=document.createElementNS(t,"circle");P.setAttribute("r","3"),P.setAttribute("fill",s),k.append(M,j,P);var S=document.createElementNS(t,"g");S.setAttribute("class","second-hand"),S.setAttribute("transform","translate(50 50)");var L=document.createElementNS(t,"line");L.setAttribute("x1","0"),L.setAttribute("y1","0"),L.setAttribute("x2","46"),L.setAttribute("y2","0"),L.setAttribute("stroke",a),L.setAttribute("stroke-width","1"),L.setAttribute("stroke-linecap","round");var R=document.createElementNS(t,"circle");R.setAttribute("r","2"),R.setAttribute("fill",a),S.append(L,R);var N=document.createElementNS(t,"circle");N.setAttribute("cx","50"),N.setAttribute("cy","50"),N.setAttribute("r","0.3"),N.setAttribute("fill",s);var I=this.getOriginDate(),D=I.getSeconds(),C=I.getMinutes(),z=6*D,B=6*C+D/60*6,W=30*I.getHours()+C/60*30;if(O.setAttribute("transform","translate(50 50) rotate("+W+")"),k.setAttribute("transform","translate(50 50) rotate("+B+")"),S.setAttribute("transform","translate(50 50) rotate("+z+")"),_.append(f,b,O,k,S,N),_.setAttribute("transform","rotate(-90)"),p.innerHTML="\n \n ",p.append(_),"datetime"===this.props.clockFormat){var H=document.createElement("span");H.className="date",H.textContent=Object(r.e)(I,"default"),H.style.fontSize=h+"px",this.props.color&&(H.style.color=this.props.color),p.append(H)}return p},e.prototype.createDigitalClock=function(){var t=document.createElement("div");t.className="digital-clock";var e=this.getElementSize().width,n=6/this.props.clockTimezone.length,i=20*e/100,s=10*e/100,o=Math.min(20*n*e/100,e/100*10),a=this.getOriginDate();if("datetime"===this.props.clockFormat){var c=document.createElement("span");c.className="date",c.textContent=Object(r.e)(a,"default"),c.style.fontSize=s+"px",this.props.color&&(c.style.color=this.props.color),t.append(c)}var l=document.createElement("span");l.className="time",l.textContent=Object(r.f)(a),l.style.fontSize=i+"px",this.props.color&&(l.style.color=this.props.color),t.append(l);var u=this.getHumanTimezone();if(u.length>0){var h=document.createElement("span");h.className="timezone",h.textContent=u,h.style.fontSize=o+"px",this.props.color&&(h.style.color=this.props.color),t.append(h)}return t},e.prototype.getOriginDate=function(t){void 0===t&&(t=null);var e=t||new Date,n=1e3*this.props.clockTimezoneOffset,i=60*e.getTimezoneOffset()*1e3,r=e.getTime()+n+i;return new Date(r)},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 n=100;return t>0&&e>0?n=Math.min(t,e):t>0?n=t:e>0&&(n=e),{width:n,height:n};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}(s.a),P=function(){var t=function(e,n){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(e,n)};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}(),S=function(){return(S=Object.assign||function(t){for(var e,n=1,i=arguments.length;n0){t.style.borderStyle="solid";var e=Math.min(this.props.width,this.props.height)/2,n=Math.min(this.props.borderWidth,e);t.style.borderWidth=n+"px",this.props.borderColor&&(t.style.borderColor=this.props.borderColor)}return t},e}(s.a),N=function(){var t=function(e,n){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(e,n)};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}(),I=function(){return(I=Object.assign||function(t){for(var e,n=1,i=arguments.length;n0&&(n=Object(r.p)([{macro:/\(?_VALUE_\)?/i,value:n}],i)),t.innerHTML=n}return t},e.prototype.createLabelDomElement=function(){var t=document.createElement("div");return t.className="visual-console-item-label",t},e}(s.a),Y=n(3),Z=Math.PI,Q=2*Z,J=Q-1e-6;function $(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function tt(){return new $}$.prototype=tt.prototype={constructor:$,moveTo:function(t,e){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)},closePath:function(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(t,e){this._+="L"+(this._x1=+t)+","+(this._y1=+e)},quadraticCurveTo:function(t,e,n,i){this._+="Q"+ +t+","+ +e+","+(this._x1=+n)+","+(this._y1=+i)},bezierCurveTo:function(t,e,n,i,r,s){this._+="C"+ +t+","+ +e+","+ +n+","+ +i+","+(this._x1=+r)+","+(this._y1=+s)},arcTo:function(t,e,n,i,r){t=+t,e=+e,n=+n,i=+i,r=+r;var s=this._x1,o=this._y1,a=n-t,c=i-e,l=s-t,u=o-e,h=l*l+u*u;if(r<0)throw new Error("negative radius: "+r);if(null===this._x1)this._+="M"+(this._x1=t)+","+(this._y1=e);else if(h>1e-6)if(Math.abs(u*a-c*l)>1e-6&&r){var p=n-s,_=i-o,f=a*a+c*c,d=p*p+_*_,m=Math.sqrt(f),y=Math.sqrt(h),b=r*Math.tan((Z-Math.acos((f+h-d)/(2*m*y)))/2),v=b/y,g=b/m;Math.abs(v-1)>1e-6&&(this._+="L"+(t+v*l)+","+(e+v*u)),this._+="A"+r+","+r+",0,0,"+ +(u*p>l*_)+","+(this._x1=t+g*a)+","+(this._y1=e+g*c)}else this._+="L"+(this._x1=t)+","+(this._y1=e);else;},arc:function(t,e,n,i,r,s){t=+t,e=+e;var o=(n=+n)*Math.cos(i),a=n*Math.sin(i),c=t+o,l=e+a,u=1^s,h=s?i-r:r-i;if(n<0)throw new Error("negative radius: "+n);null===this._x1?this._+="M"+c+","+l:(Math.abs(this._x1-c)>1e-6||Math.abs(this._y1-l)>1e-6)&&(this._+="L"+c+","+l),n&&(h<0&&(h=h%Q+Q),h>J?this._+="A"+n+","+n+",0,1,"+u+","+(t-o)+","+(e-a)+"A"+n+","+n+",0,1,"+u+","+(this._x1=c)+","+(this._y1=l):h>1e-6&&(this._+="A"+n+","+n+",0,"+ +(h>=Z)+","+u+","+(this._x1=t+n*Math.cos(r))+","+(this._y1=e+n*Math.sin(r))))},rect:function(t,e,n,i){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)+"h"+ +n+"v"+ +i+"h"+-n+"Z"},toString:function(){return this._}};var et=tt,nt=function(t){return function(){return t}},it=Math.abs,rt=Math.atan2,st=Math.cos,ot=Math.max,at=Math.min,ct=Math.sin,lt=Math.sqrt,ut=1e-12,ht=Math.PI,pt=ht/2,_t=2*ht;function ft(t){return t>=1?pt:t<=-1?-pt:Math.asin(t)}function dt(t){return t.innerRadius}function mt(t){return t.outerRadius}function yt(t){return t.startAngle}function bt(t){return t.endAngle}function vt(t){return t&&t.padAngle}function gt(t,e,n,i,r,s,o){var a=t-n,c=e-i,l=(o?s:-s)/lt(a*a+c*c),u=l*c,h=-l*a,p=t+u,_=e+h,f=n+u,d=i+h,m=(p+f)/2,y=(_+d)/2,b=f-p,v=d-_,g=b*b+v*v,x=r-s,E=p*d-f*_,w=(v<0?-1:1)*lt(ot(0,x*x*g-E*E)),O=(E*v-b*w)/g,T=(-E*b-v*w)/g,A=(E*v+b*w)/g,k=(-E*b+v*w)/g,M=O-m,j=T-y,P=A-m,S=k-y;return M*M+j*j>P*P+S*S&&(O=A,T=k),{cx:O,cy:T,x01:-u,y01:-h,x11:O*(r/x-1),y11:T*(r/x-1)}}var xt=function(){var t=dt,e=mt,n=nt(0),i=null,r=yt,s=bt,o=vt,a=null;function c(){var c,l,u,h=+t.apply(this,arguments),p=+e.apply(this,arguments),_=r.apply(this,arguments)-pt,f=s.apply(this,arguments)-pt,d=it(f-_),m=f>_;if(a||(a=c=et()),put)if(d>_t-ut)a.moveTo(p*st(_),p*ct(_)),a.arc(0,0,p,_,f,!m),h>ut&&(a.moveTo(h*st(f),h*ct(f)),a.arc(0,0,h,f,_,m));else{var y,b,v=_,g=f,x=_,E=f,w=d,O=d,T=o.apply(this,arguments)/2,A=T>ut&&(i?+i.apply(this,arguments):lt(h*h+p*p)),k=at(it(p-h)/2,+n.apply(this,arguments)),M=k,j=k;if(A>ut){var P=ft(A/h*ct(T)),S=ft(A/p*ct(T));(w-=2*P)>ut?(x+=P*=m?1:-1,E-=P):(w=0,x=E=(_+f)/2),(O-=2*S)>ut?(v+=S*=m?1:-1,g-=S):(O=0,v=g=(_+f)/2)}var L=p*st(v),R=p*ct(v),N=h*st(E),I=h*ct(E);if(k>ut){var D,C=p*st(g),z=p*ct(g),B=h*st(x),W=h*ct(x);if(d1?0:u<-1?ht:Math.acos(u))/2),F=lt(D[0]*D[0]+D[1]*D[1]);M=at(k,(h-F)/(q-1)),j=at(k,(p-F)/(q+1))}}O>ut?j>ut?(y=gt(B,W,L,R,p,j,m),b=gt(C,z,N,I,p,j,m),a.moveTo(y.cx+y.x01,y.cy+y.y01),jut&&w>ut?M>ut?(y=gt(N,I,C,z,h,-M,m),b=gt(L,R,B,W,h,-M,m),a.lineTo(y.cx+y.x01,y.cy+y.y01),M0)for(var i,r=t[0],s=e[0],o=t[n]-r,a=e[n]-s,c=-1;++c<=n;)i=c/n,this._basis.point(this._beta*t[c]+(1-this._beta)*(r+i*o),this._beta*e[c]+(1-this._beta)*(s+i*a));this._x=this._y=null,this._basis.lineEnd()},point:function(t,e){this._x.push(+t),this._y.push(+e)}};(function t(e){function n(t){return 1===e?new jt(t):new Lt(t,e)}return n.beta=function(e){return t(+e)},n})(.85);function Rt(t,e,n){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-e),t._y2+t._k*(t._y1-n),t._x2,t._y2)}function Nt(t,e){this._context=t,this._k=(1-e)/6}Nt.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:Rt(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2,this._x1=t,this._y1=e;break;case 2:this._point=3;default:Rt(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};(function t(e){function n(t){return new Nt(t,e)}return n.tension=function(e){return t(+e)},n})(0);function It(t,e){this._context=t,this._k=(1-e)/6}It.prototype={areaStart:kt,areaEnd:kt,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Rt(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};(function t(e){function n(t){return new It(t,e)}return n.tension=function(e){return t(+e)},n})(0);function Dt(t,e){this._context=t,this._k=(1-e)/6}Dt.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Rt(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};(function t(e){function n(t){return new Dt(t,e)}return n.tension=function(e){return t(+e)},n})(0);function Ct(t,e,n){var i=t._x1,r=t._y1,s=t._x2,o=t._y2;if(t._l01_a>ut){var a=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,c=3*t._l01_a*(t._l01_a+t._l12_a);i=(i*a-t._x0*t._l12_2a+t._x2*t._l01_2a)/c,r=(r*a-t._y0*t._l12_2a+t._y2*t._l01_2a)/c}if(t._l23_a>ut){var l=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,u=3*t._l23_a*(t._l23_a+t._l12_a);s=(s*l+t._x1*t._l23_2a-e*t._l12_2a)/u,o=(o*l+t._y1*t._l23_2a-n*t._l12_2a)/u}t._context.bezierCurveTo(i,r,s,o,t._x2,t._y2)}function zt(t,e){this._context=t,this._alpha=e}zt.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,i=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+i*i,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3;default:Ct(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};(function t(e){function n(t){return e?new zt(t,e):new Nt(t,0)}return n.alpha=function(e){return t(+e)},n})(.5);function Bt(t,e){this._context=t,this._alpha=e}Bt.prototype={areaStart:kt,areaEnd:kt,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,i=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+i*i,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Ct(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};(function t(e){function n(t){return e?new Bt(t,e):new It(t,0)}return n.alpha=function(e){return t(+e)},n})(.5);function Wt(t,e){this._context=t,this._alpha=e}Wt.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,i=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+i*i,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Ct(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};(function t(e){function n(t){return e?new Wt(t,e):new Dt(t,0)}return n.alpha=function(e){return t(+e)},n})(.5);function Ht(t){this._context=t}Ht.prototype={areaStart:kt,areaEnd:kt,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(t,e){t=+t,e=+e,this._point?this._context.lineTo(t,e):(this._point=1,this._context.moveTo(t,e))}};function Ut(t){return t<0?-1:1}function Kt(t,e,n){var i=t._x1-t._x0,r=e-t._x1,s=(t._y1-t._y0)/(i||r<0&&-0),o=(n-t._y1)/(r||i<0&&-0),a=(s*r+o*i)/(i+r);return(Ut(s)+Ut(o))*Math.min(Math.abs(s),Math.abs(o),.5*Math.abs(a))||0}function Gt(t,e){var n=t._x1-t._x0;return n?(3*(t._y1-t._y0)/n-e)/2:e}function qt(t,e,n){var i=t._x0,r=t._y0,s=t._x1,o=t._y1,a=(s-i)/3;t._context.bezierCurveTo(i+a,r+a*e,s-a,o-a*n,s,o)}function Ft(t){this._context=t}function Vt(t){this._context=new Xt(t)}function Xt(t){this._context=t}function Yt(t){this._context=t}function Zt(t){var e,n,i=t.length-1,r=new Array(i),s=new Array(i),o=new Array(i);for(r[0]=0,s[0]=2,o[0]=t[0]+2*t[1],e=1;e=0;--e)r[e]=(o[e]-r[e+1])/s[e];for(s[i-1]=(t[i]+r[i-1])/2,e=0;e=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var n=this._x*(1-this._t)+t*this._t;this._context.lineTo(n,this._y),this._context.lineTo(n,e)}}this._x=t,this._y=e}};var Jt=function(){var t=function(e,n){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(e,n)};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}(),$t=function(){return($t=Object.assign||function(t){for(var e,n=1,i=arguments.length;n0){var p=document.createElementNS(ie,"tspan");p.setAttribute("x","0"),p.setAttribute("dy","1em"),p.textContent=""+t,p.style.fontSize="8pt";var _=document.createElementNS(ie,"tspan");_.setAttribute("x","0"),_.setAttribute("dy","1em"),_.textContent=""+this.props.unit,_.style.fontSize="8pt",h.append(p,_),h.setAttribute("transform","translate(50 33)")}else h.textContent=""+t,h.style.fontSize="8pt",h.setAttribute("transform","translate(50 50)");else h.textContent=n+"%",h.setAttribute("transform","translate(50 50)");r.append(h)}return i.append(r),i},e.prototype.getProgress=function(){var t=this.props.minValue||0,e=this.props.maxValue||100,n=null==this.props.value?0:this.props.value;return n<=t?0:n>=e?100:Math.trunc((n-t)/(e-t)*100)},e}(s.a),se=n(2),oe=n(4),ae=n(5),ce=n(6),le=function(){var t=function(e,n){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(e,n)};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}(),ue=function(){return(ue=Object.assign||function(t){for(var e,n=1,i=arguments.length;ne.id?1:-1})).forEach(function(t){try{var e=fe(t);i.elementsById[e.props.id]=e,i.elementIds.push(e.props.id),e.onClick(i.handleElementClick),e.onMoved(i.handleElementMovement),e.onResized(i.handleElementResizement),e.onRemove(i.handleElementRemove),i.containerRef.append(e.elementRef)}catch(t){console.log("Error creating a new element:",t.message)}}),this.buildRelations()}return Object.defineProperty(t.prototype,"elements",{get:function(){var t=this;return this.elementIds.map(function(e){return t.elementsById[e]}).filter(function(t){return null!=t})},enumerable:!0,configurable:!0}),t.prototype.updateElements=function(t){var e=this,n=t.map(function(t){return t.id||null}).filter(function(t){return null!=t});this.elementIds.filter(function(t){return n.indexOf(t)<0}).forEach(function(t){null!=e.elementsById[t]&&(e.elementsById[t].remove(),delete e.elementsById[t])}),this.elementIds=n,t.forEach(function(t){if(t.id)if(null==e.elementsById[t.id])try{var n=fe(t);e.elementsById[n.props.id]=n,n.onClick(e.handleElementClick),n.onRemove(e.handleElementRemove),e.containerRef.append(n.elementRef)}catch(t){console.log("Error creating a new element:",t.message)}else try{e.elementsById[t.id].props=function(t){var e=Object(r.m)(t.type,null);if(null==e)throw new TypeError("missing item type.");switch(e){case 0:return l(t);case 1:return Object(ce.b)(t);case 2:case 6:case 7:case 8:return V(t);case 3:case 9:case 15:case 16:return ne(t);case 4:return H(t);case 5:return _(t);case 10:return he(t);case 11:return E(t);case 12:return L(t);case 13:return D(t);case 14:return Object(Y.b)(t);case 17:return Object(oe.b)(t);case 18:return Object(ae.a)(t);case 19:return M(t);case 20:return y(t);default:throw new TypeError("decoder not found")}}(t)}catch(t){console.log("Error updating an element:",t.message)}}),this.buildRelations()},Object.defineProperty(t.prototype,"props",{get:function(){return _e({},this._props)},set:function(t){var e=this.props;this._props=t,this.render(e)},enumerable:!0,configurable:!0}),t.prototype.render=function(t){void 0===t&&(t=null),t?(t.backgroundURL!==this.props.backgroundURL&&(this.containerRef.style.backgroundImage=null!==this.props.backgroundURL?"url("+this.props.backgroundURL+")":null),t.backgroundColor!==this.props.backgroundColor&&(this.containerRef.style.backgroundColor=this.props.backgroundColor),this.sizeChanged(t,this.props)&&this.resizeElement(this.props.width,this.props.height)):(this.containerRef.style.backgroundImage=null!==this.props.backgroundURL?"url("+this.props.backgroundURL+")":null,this.containerRef.style.backgroundColor=this.props.backgroundColor,this.resizeElement(this.props.width,this.props.height))},t.prototype.sizeChanged=function(t,e){return t.width!==e.width||t.height!==e.height},t.prototype.resizeElement=function(t,e){this.containerRef.style.width=t+"px",this.containerRef.style.height=e+"px"},t.prototype.resize=function(t,e){this.props=_e({},this.props,{width:t,height:e})},t.prototype.remove=function(){this.disposables.forEach(function(t){return t.dispose()}),this.elements.forEach(function(t){return t.remove()}),this.elementsById={},this.elementIds=[],this.clearRelations(),this.containerRef.innerHTML=""},t.prototype.buildRelations=function(){var t=this;this.clearRelations(),this.elements.forEach(function(e){if(null!==e.props.parentId){var n=t.elementsById[e.props.parentId],i=t.elementsById[e.props.id];n&&i&&t.addRelationLine(n,i)}})},t.prototype.clearRelations=function(t){if(null!=t)for(var e in this.relations){var n=e.split("|"),i=Number.parseInt(n[0]),r=Number.parseInt(n[1]);t!==i&&t!==r||(this.relations[e].remove(),delete this.relations[e])}else for(var e in this.relations)this.relations[e].remove(),delete this.relations[e]},t.prototype.getRelationLine=function(t,e){var n=t+"|"+e;return this.relations[n]||null},t.prototype.addRelationLine=function(t,e){var n=t.props.id+"|"+e.props.id;null!=this.relations[n]&&this.relations[n].remove();var i=t.props.x+t.elementRef.clientWidth/2,s=t.props.y+(t.elementRef.clientHeight-t.labelElementRef.clientHeight)/2,o=e.props.x+e.elementRef.clientWidth/2,a=e.props.y+(e.elementRef.clientHeight-e.labelElementRef.clientHeight)/2,c=new z(D({id:0,type:13,startX:i,startY:s,endX:o,endY:a,width:0,height:0,lineWidth:this.props.relationLineWidth,color:"#CCCCCC"}),Object(r.g)({receivedAt:new Date}));return this.relations[n]=c,c.elementRef.style.zIndex="0",this.containerRef.append(c.elementRef),c},t.prototype.onItemClick=function(t){var e=this.clickEventManager.on(t);return this.disposables.push(e),e},t.prototype.onItemMoved=function(t){var e=this.movedEventManager.on(t);return this.disposables.push(e),e},t.prototype.onItemResized=function(t){var e=this.resizedEventManager.on(t);return this.disposables.push(e),e},t.prototype.enableEditMode=function(){this.elements.forEach(function(t){t.meta=_e({},t.meta,{editMode:!0})}),this.containerRef.classList.add("is-editing")},t.prototype.disableEditMode=function(){this.elements.forEach(function(t){t.meta=_e({},t.meta,{editMode:!1})}),this.containerRef.classList.remove("is-editing")},t}(),me=function(){function t(t){this.cancellable={cancel:function(){}},this._status="waiting",this.statusChangeEventManager=new se.a,this.disposables=[],this.taskInitiator=t}return Object.defineProperty(t.prototype,"status",{get:function(){return this._status},set:function(t){this._status=t,this.statusChangeEventManager.emit(t)},enumerable:!0,configurable:!0}),t.prototype.init=function(){var t=this;this.cancellable=this.taskInitiator(function(){t.status="finished"}),this.status="started"},t.prototype.cancel=function(){this.cancellable.cancel(),this.status="cancelled"},t.prototype.onStatusChange=function(t){var e=this.statusChangeEventManager.on(t);return this.disposables.push(e),e},t}();var ye=function(){function t(){this.tasks={}}return t.prototype.add=function(t,e,n){void 0===n&&(n=0),this.tasks[t]&&"started"===this.tasks[t].status&&this.tasks[t].cancel();var i=n>0?function(t,e){return new me(function(){var n=null;return t.onStatusChange(function(i){"finished"===i&&(n=window.setTimeout(function(){t.init()},e))}),t.init(),{cancel:function(){n&&clearTimeout(n),t.cancel()}}})}(new me(e),n):new me(e);return this.tasks[t]=i,this.tasks[t]},t.prototype.init=function(t){!this.tasks[t]||"waiting"!==this.tasks[t].status&&"cancelled"!==this.tasks[t].status&&"finished"!==this.tasks[t].status||this.tasks[t].init()},t.prototype.cancel=function(t){this.tasks[t]&&"started"===this.tasks[t].status&&this.tasks[t].cancel()},t}();window.VisualConsole=de,window.AsyncTaskManager=ye}]); +!function(t){var e={};function n(i){if(e[i])return e[i].exports;var r=e[i]={i:i,l:!1,exports:{}};return t[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)n.d(i,r,function(e){return t[e]}.bind(null,r));return i},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=9)}([function(t,e,n){"use strict";n.d(e,"m",function(){return r}),n.d(e,"l",function(){return s}),n.d(e,"r",function(){return o}),n.d(e,"j",function(){return a}),n.d(e,"k",function(){return c}),n.d(e,"n",function(){return u}),n.d(e,"q",function(){return h}),n.d(e,"i",function(){return p}),n.d(e,"h",function(){return _}),n.d(e,"g",function(){return f}),n.d(e,"o",function(){return d}),n.d(e,"d",function(){return m}),n.d(e,"e",function(){return y}),n.d(e,"f",function(){return b}),n.d(e,"p",function(){return v}),n.d(e,"c",function(){return x}),n.d(e,"a",function(){return w}),n.d(e,"b",function(){return O});var i=function(){return(i=Object.assign||function(t){for(var e,n=1,i=arguments.length;n0&&!isNaN(parseInt(t))?parseInt(t):e}function s(t,e){return"number"==typeof t?t:"string"==typeof t&&t.length>0&&!isNaN(parseFloat(t))?parseFloat(t):e}function o(t){return null==t||0===t.length}function a(t,e){return"string"==typeof t&&t.length>0?t:e}function c(t){return"boolean"==typeof t?t:"number"==typeof t?t>0:"string"==typeof t&&("1"===t||"true"===t)}function l(t,e,n){void 0===n&&(n=" "),"number"==typeof t&&(t=""+t),"number"==typeof n&&(n=""+n);var i=e-t.length;if(0===i)return t;if(i<0)return t.substr(Math.abs(i));if(i===n.length)return""+n+t;if(i0&&id||y+r+m.width-b>u.width||r===x&&y<0&&i>f+x+c,A=h0&&h_||g+s+m.height-b>u.height||s===E&&g<0&&h>p+E+l;(e=O?0:T?x:y+r)<0&&(e=0),(n=A?0:k?E:g+s)<0&&(n=0),o=i,a=h,e===r&&n===s||(w(e,n),v(e,n),r=e,s=n)},T=function(){r=0,s=0,o=0,a=0,document.removeEventListener("mousemove",O),document.removeEventListener("mouseup",T),t.draggable=i,document.body.style.userSelect="auto"},A=function(e){e.stopPropagation(),t.draggable=!1,r=t.offsetLeft,s=t.offsetTop,o=e.pageX,a=e.pageY,c=e.offsetX,l=e.offsetY,u=n.getBoundingClientRect(),h=E(n),p=h.top,_=p+u.height,f=h.left,d=f+u.width,m=t.getBoundingClientRect(),y=window.getComputedStyle(t).borderWidth||"0",b=2*Number.parseInt(y),document.addEventListener("mousemove",O),document.addEventListener("mouseup",T),document.body.style.userSelect="none"};return t.addEventListener("mousedown",A),function(){t.removeEventListener("mousedown",A),T()}}function O(t,e){var n=document.createElement("div");n.className="resize-draggable",t.appendChild(n);var i=t.parentElement,r=t.draggable,s=0,o=0,a=0,c=0,l=0,u=i.getBoundingClientRect(),h=E(i),p=h.top,_=p+u.height,f=h.left,d=f+u.width,m=E(t),y=m.top,b=m.left,v=window.getComputedStyle(t).borderWidth||"0",w=Number.parseInt(v),O=x(32,function(t,n){return e(t,n)}),T=g(16,function(t,n){return e(t,n)}),A=function(t){var e=s+(t.pageX-a),n=o+(t.pageY-c);e===s&&n===o||eb+(s-l)||(e<15?e=15:e+b-w/2>=d&&(e=d-b),n<15?n=15:n+y-w/2>=_&&(n=_-y),T(e,n),O(e,n),s=e,o=n,a=t.pageX,c=t.pageY)},k=function(){s=0,o=0,a=0,c=0,l=0,0,document.removeEventListener("mousemove",A),document.removeEventListener("mouseup",k),t.draggable=r,document.body.style.userSelect="auto"};return n.addEventListener("mousedown",function(e){e.stopPropagation(),t.draggable=!1;var n=t.getBoundingClientRect(),r=n.width,v=n.height;s=r,o=v,a=e.pageX,c=e.pageY,l=e.offsetX,e.offsetY,u=i.getBoundingClientRect(),h=E(i),p=h.top,_=p+u.height,f=h.left,d=f+u.width,m=E(t),y=m.top,b=m.left,document.addEventListener("mousemove",A),document.addEventListener("mouseup",k),document.body.style.userSelect="none"}),function(){n.remove(),k()}}},function(t,e,n){"use strict";n.d(e,"b",function(){return a});var i=n(0),r=n(2),s=function(){return(s=Object.assign||function(t){for(var e,n=1,i=arguments.length;n0){var i=e.labelElementRef.getBoundingClientRect(),r=i.width,s=i.height;switch(e.props.labelPosition){case"up":case"down":n-=s;break;case"left":case"right":t-=r}}e.resizeElement(t,n),e.debouncedResizementSave(t,n)})},t.prototype.stopResizementListener=function(){this.removeResizement&&(this.removeResizement(),this.removeResizement=null)},t.prototype.createContainerDomElement=function(){var t,e=this;return this.props.isLinkEnabled?(t=document.createElement("a"),this.props.link&&(t.href=this.props.link)):t=document.createElement("div"),t.className="visual-console-item",t.style.zIndex=this.props.isOnTop?"2":"1",t.style.left=this.props.x+"px",t.style.top=this.props.y+"px",t.addEventListener("click",function(t){e.meta.editMode?(t.preventDefault(),t.stopPropagation()):e.clickEventManager.emit({data:e.props,nativeEvent:t})}),this.meta.editMode&&(t.classList.add("is-editing"),this.initMovementListener(t),this.initResizementListener(t)),this.meta.isFetching&&t.classList.add("is-fetching"),this.meta.isUpdating&&t.classList.add("is-updating"),t},t.prototype.createLabelDomElement=function(){var t=document.createElement("div");t.className="visual-console-item-label";var e=this.getLabelWithMacrosReplaced();if(e.length>0){var n=document.createElement("table"),i=document.createElement("tr"),r=document.createElement("tr"),s=document.createElement("tr"),o=document.createElement("td");switch(o.innerHTML=e,i.append(o),n.append(r,i,s),n.style.textAlign="center",this.props.labelPosition){case"up":case"down":this.props.width>0&&(n.style.width=this.props.width+"px",n.style.height=null);break;case"left":case"right":this.props.height>0&&(n.style.width=null,n.style.height=this.props.height+"px")}t.append(n)}return t},t.prototype.getLabelWithMacrosReplaced=function(){var t=this.props;return Object(i.p)([{macro:"_date_",value:Object(i.e)(new Date)},{macro:"_time_",value:Object(i.f)(new Date)},{macro:"_agent_",value:null!=t.agentAlias?t.agentAlias:""},{macro:"_agentdescription_",value:null!=t.agentDescription?t.agentDescription:""},{macro:"_address_",value:null!=t.agentAddress?t.agentAddress:""},{macro:"_module_",value:null!=t.moduleName?t.moduleName:""},{macro:"_moduledescription_",value:null!=t.moduleDescription?t.moduleDescription:""}],this.props.label||"")},t.prototype.updateDomElement=function(t){t.innerHTML=this.createDomElement().innerHTML},Object.defineProperty(t.prototype,"props",{get:function(){return s({},this.itemProps)},set:function(t){var e=this.props;this.itemProps=t,this.shouldBeUpdated(e,t)&&this.render(e,this._metadata)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"meta",{get:function(){return s({},this._metadata)},set:function(t){this.setMeta(t)},enumerable:!0,configurable:!0}),t.prototype.setMeta=function(t){var e=this._metadata;this._metadata=t,this.render(this.itemProps,e)},t.prototype.shouldBeUpdated=function(t,e){return t!==e},t.prototype.render=function(t,e){void 0===t&&(t=null),void 0===e&&(e=null),this.updateDomElement(this.childElementRef),t&&!this.positionChanged(t,this.props)||this.moveElement(this.props.x,this.props.y),t&&!this.sizeChanged(t,this.props)||this.resizeElement(this.props.width,this.props.height);var n=this.labelElementRef.innerHTML,i=this.createLabelDomElement().innerHTML;if(n!==i&&(this.labelElementRef.innerHTML=i),t&&t.labelPosition===this.props.labelPosition||this.changeLabelPosition(this.props.labelPosition),t&&(t.isLinkEnabled!==this.props.isLinkEnabled||this.props.isLinkEnabled&&t.link!==this.props.link)){var r=this.createContainerDomElement();r.innerHTML=this.elementRef.innerHTML;for(var s=this.elementRef.attributes,o=0;o0?e.item(0):null;if(n)switch(this.props.labelPosition){case"up":case"down":this.props.width>0&&(n.style.width=this.props.width+"px",n.style.height=null);break;case"left":case"right":this.props.height>0&&(n.style.width=null,n.style.height=this.props.height+"px")}},t.prototype.moveElement=function(t,e){this.elementRef.style.left=t+"px",this.elementRef.style.top=e+"px"},t.prototype.move=function(t,e){this.moveElement(t,e),this.itemProps=s({},this.props,{x:t,y:e})},t.prototype.sizeChanged=function(t,e){return t.width!==e.width||t.height!==e.height},t.prototype.resizeElement=function(t,e){if(this.childElementRef.style.width=t>0?t+"px":null,this.childElementRef.style.height=e>0?e+"px":null,this.props.label&&this.props.label.length>0){var n=this.labelElementRef.getElementsByTagName("table"),i=n.length>0?n.item(0):null;if(i)switch(this.props.labelPosition){case"up":case"down":i.style.width=t>0?t+"px":null;break;case"left":case"right":i.style.height=e>0?e+"px":null}}},t.prototype.resize=function(t,e){this.resizeElement(t,e),this.itemProps=s({},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.onMoved=function(t){var e=this.movedEventManager.on(t);return this.disposables.push(e),e},t.prototype.onResized=function(t){var e=this.resizedEventManager.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=c},function(t,e,n){"use strict";var i=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 n=t.listeners.indexOf(e);n>-1&&t.listeners.splice(n,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=i},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 n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(t,e)},function(t,e){function n(){this.constructor=t}extendStatics(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)}),extendStatics,__assign=function(){return(__assign=Object.assign||function(t){for(var e,n=1,i=arguments.length;n0){var y=document.createElementNS(t,"text");y.setAttribute("text-anchor","middle"),y.setAttribute("font-size","8"),y.setAttribute("transform","translate(30 50) rotate(90)"),y.setAttribute("fill",i),y.textContent=m,f.append(y)}var b=document.createElementNS(t,"g");b.setAttribute("class","marks");var v=document.createElementNS(t,"g");v.setAttribute("class","mark"),v.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",i),g.setAttribute("stroke-width","5");var x=document.createElementNS(t,"line");x.setAttribute("x1","36"),x.setAttribute("y1","0"),x.setAttribute("x2","46"),x.setAttribute("y2","0"),x.setAttribute("stroke",e),x.setAttribute("stroke-width","1"),v.append(g,x),b.append(v);for(var E=1;E<60;E++){var w=document.createElementNS(t,"line");w.setAttribute("y1","0"),w.setAttribute("y2","0"),w.setAttribute("stroke",i),w.setAttribute("transform","translate(50 50) rotate("+6*E+")"),E%5==0?(w.setAttribute("x1","38"),w.setAttribute("x2","46"),w.setAttribute("stroke-width",E%15==0?"2":"1")):(w.setAttribute("x1","42"),w.setAttribute("x2","46"),w.setAttribute("stroke-width","0.5")),b.append(w)}var O=document.createElementNS(t,"g");O.setAttribute("class","hour-hand"),O.setAttribute("transform","translate(50 50)");var T=document.createElementNS(t,"line");T.setAttribute("class","hour-hand-a"),T.setAttribute("x1","0"),T.setAttribute("y1","0"),T.setAttribute("x2","30"),T.setAttribute("y2","0"),T.setAttribute("stroke",o),T.setAttribute("stroke-width","4"),T.setAttribute("stroke-linecap","round");var A=document.createElementNS(t,"line");A.setAttribute("class","hour-hand-b"),A.setAttribute("x1","0"),A.setAttribute("y1","0"),A.setAttribute("x2","29.9"),A.setAttribute("y2","0"),A.setAttribute("stroke",s),A.setAttribute("stroke-width","3.1"),A.setAttribute("stroke-linecap","round"),O.append(T,A);var k=document.createElementNS(t,"g");k.setAttribute("class","minute-hand"),k.setAttribute("transform","translate(50 50)");var M=document.createElementNS(t,"line");M.setAttribute("class","minute-hand-a"),M.setAttribute("x1","0"),M.setAttribute("y1","0"),M.setAttribute("x2","40"),M.setAttribute("y2","0"),M.setAttribute("stroke",o),M.setAttribute("stroke-width","2"),M.setAttribute("stroke-linecap","round");var j=document.createElementNS(t,"line");j.setAttribute("class","minute-hand-b"),j.setAttribute("x1","0"),j.setAttribute("y1","0"),j.setAttribute("x2","39.9"),j.setAttribute("y2","0"),j.setAttribute("stroke",s),j.setAttribute("stroke-width","1.5"),j.setAttribute("stroke-linecap","round");var P=document.createElementNS(t,"circle");P.setAttribute("r","3"),P.setAttribute("fill",s),k.append(M,j,P);var S=document.createElementNS(t,"g");S.setAttribute("class","second-hand"),S.setAttribute("transform","translate(50 50)");var L=document.createElementNS(t,"line");L.setAttribute("x1","0"),L.setAttribute("y1","0"),L.setAttribute("x2","46"),L.setAttribute("y2","0"),L.setAttribute("stroke",a),L.setAttribute("stroke-width","1"),L.setAttribute("stroke-linecap","round");var R=document.createElementNS(t,"circle");R.setAttribute("r","2"),R.setAttribute("fill",a),S.append(L,R);var N=document.createElementNS(t,"circle");N.setAttribute("cx","50"),N.setAttribute("cy","50"),N.setAttribute("r","0.3"),N.setAttribute("fill",s);var I=this.getOriginDate(),D=I.getSeconds(),C=I.getMinutes(),z=6*D,B=6*C+D/60*6,W=30*I.getHours()+C/60*30;if(O.setAttribute("transform","translate(50 50) rotate("+W+")"),k.setAttribute("transform","translate(50 50) rotate("+B+")"),S.setAttribute("transform","translate(50 50) rotate("+z+")"),_.append(f,b,O,k,S,N),_.setAttribute("transform","rotate(-90)"),p.innerHTML="\n \n ",p.append(_),"datetime"===this.props.clockFormat){var H=document.createElement("span");H.className="date",H.textContent=Object(r.e)(I,"default"),H.style.fontSize=h+"px",this.props.color&&(H.style.color=this.props.color),p.append(H)}return p},e.prototype.createDigitalClock=function(){var t=document.createElement("div");t.className="digital-clock";var e=this.getElementSize().width,n=6/this.props.clockTimezone.length,i=20*e/100,s=10*e/100,o=Math.min(20*n*e/100,e/100*10),a=this.getOriginDate();if("datetime"===this.props.clockFormat){var c=document.createElement("span");c.className="date",c.textContent=Object(r.e)(a,"default"),c.style.fontSize=s+"px",this.props.color&&(c.style.color=this.props.color),t.append(c)}var l=document.createElement("span");l.className="time",l.textContent=Object(r.f)(a),l.style.fontSize=i+"px",this.props.color&&(l.style.color=this.props.color),t.append(l);var u=this.getHumanTimezone();if(u.length>0){var h=document.createElement("span");h.className="timezone",h.textContent=u,h.style.fontSize=o+"px",this.props.color&&(h.style.color=this.props.color),t.append(h)}return t},e.prototype.getOriginDate=function(t){void 0===t&&(t=null);var e=t||new Date,n=1e3*this.props.clockTimezoneOffset,i=60*e.getTimezoneOffset()*1e3,r=e.getTime()+n+i;return new Date(r)},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 n=100;return t>0&&e>0?n=Math.min(t,e):t>0?n=t:e>0&&(n=e),{width:n,height:n};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}(s.a),P=function(){var t=function(e,n){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(e,n)};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}(),S=function(){return(S=Object.assign||function(t){for(var e,n=1,i=arguments.length;n0){t.style.borderStyle="solid";var e=Math.min(this.props.width,this.props.height)/2,n=Math.min(this.props.borderWidth,e);t.style.borderWidth=n+"px",this.props.borderColor&&(t.style.borderColor=this.props.borderColor)}return t},e}(s.a),N=function(){var t=function(e,n){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(e,n)};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}(),I=function(){return(I=Object.assign||function(t){for(var e,n=1,i=arguments.length;n0&&(n=Object(r.p)([{macro:/\(?_VALUE_\)?/i,value:n}],i)),t.innerHTML=n}return t},e.prototype.createLabelDomElement=function(){var t=document.createElement("div");return t.className="visual-console-item-label",t},e}(s.a),Y=n(3),Z=Math.PI,Q=2*Z,J=Q-1e-6;function $(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function tt(){return new $}$.prototype=tt.prototype={constructor:$,moveTo:function(t,e){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)},closePath:function(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(t,e){this._+="L"+(this._x1=+t)+","+(this._y1=+e)},quadraticCurveTo:function(t,e,n,i){this._+="Q"+ +t+","+ +e+","+(this._x1=+n)+","+(this._y1=+i)},bezierCurveTo:function(t,e,n,i,r,s){this._+="C"+ +t+","+ +e+","+ +n+","+ +i+","+(this._x1=+r)+","+(this._y1=+s)},arcTo:function(t,e,n,i,r){t=+t,e=+e,n=+n,i=+i,r=+r;var s=this._x1,o=this._y1,a=n-t,c=i-e,l=s-t,u=o-e,h=l*l+u*u;if(r<0)throw new Error("negative radius: "+r);if(null===this._x1)this._+="M"+(this._x1=t)+","+(this._y1=e);else if(h>1e-6)if(Math.abs(u*a-c*l)>1e-6&&r){var p=n-s,_=i-o,f=a*a+c*c,d=p*p+_*_,m=Math.sqrt(f),y=Math.sqrt(h),b=r*Math.tan((Z-Math.acos((f+h-d)/(2*m*y)))/2),v=b/y,g=b/m;Math.abs(v-1)>1e-6&&(this._+="L"+(t+v*l)+","+(e+v*u)),this._+="A"+r+","+r+",0,0,"+ +(u*p>l*_)+","+(this._x1=t+g*a)+","+(this._y1=e+g*c)}else this._+="L"+(this._x1=t)+","+(this._y1=e);else;},arc:function(t,e,n,i,r,s){t=+t,e=+e;var o=(n=+n)*Math.cos(i),a=n*Math.sin(i),c=t+o,l=e+a,u=1^s,h=s?i-r:r-i;if(n<0)throw new Error("negative radius: "+n);null===this._x1?this._+="M"+c+","+l:(Math.abs(this._x1-c)>1e-6||Math.abs(this._y1-l)>1e-6)&&(this._+="L"+c+","+l),n&&(h<0&&(h=h%Q+Q),h>J?this._+="A"+n+","+n+",0,1,"+u+","+(t-o)+","+(e-a)+"A"+n+","+n+",0,1,"+u+","+(this._x1=c)+","+(this._y1=l):h>1e-6&&(this._+="A"+n+","+n+",0,"+ +(h>=Z)+","+u+","+(this._x1=t+n*Math.cos(r))+","+(this._y1=e+n*Math.sin(r))))},rect:function(t,e,n,i){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)+"h"+ +n+"v"+ +i+"h"+-n+"Z"},toString:function(){return this._}};var et=tt,nt=function(t){return function(){return t}},it=Math.abs,rt=Math.atan2,st=Math.cos,ot=Math.max,at=Math.min,ct=Math.sin,lt=Math.sqrt,ut=1e-12,ht=Math.PI,pt=ht/2,_t=2*ht;function ft(t){return t>=1?pt:t<=-1?-pt:Math.asin(t)}function dt(t){return t.innerRadius}function mt(t){return t.outerRadius}function yt(t){return t.startAngle}function bt(t){return t.endAngle}function vt(t){return t&&t.padAngle}function gt(t,e,n,i,r,s,o){var a=t-n,c=e-i,l=(o?s:-s)/lt(a*a+c*c),u=l*c,h=-l*a,p=t+u,_=e+h,f=n+u,d=i+h,m=(p+f)/2,y=(_+d)/2,b=f-p,v=d-_,g=b*b+v*v,x=r-s,E=p*d-f*_,w=(v<0?-1:1)*lt(ot(0,x*x*g-E*E)),O=(E*v-b*w)/g,T=(-E*b-v*w)/g,A=(E*v+b*w)/g,k=(-E*b+v*w)/g,M=O-m,j=T-y,P=A-m,S=k-y;return M*M+j*j>P*P+S*S&&(O=A,T=k),{cx:O,cy:T,x01:-u,y01:-h,x11:O*(r/x-1),y11:T*(r/x-1)}}var xt=function(){var t=dt,e=mt,n=nt(0),i=null,r=yt,s=bt,o=vt,a=null;function c(){var c,l,u,h=+t.apply(this,arguments),p=+e.apply(this,arguments),_=r.apply(this,arguments)-pt,f=s.apply(this,arguments)-pt,d=it(f-_),m=f>_;if(a||(a=c=et()),put)if(d>_t-ut)a.moveTo(p*st(_),p*ct(_)),a.arc(0,0,p,_,f,!m),h>ut&&(a.moveTo(h*st(f),h*ct(f)),a.arc(0,0,h,f,_,m));else{var y,b,v=_,g=f,x=_,E=f,w=d,O=d,T=o.apply(this,arguments)/2,A=T>ut&&(i?+i.apply(this,arguments):lt(h*h+p*p)),k=at(it(p-h)/2,+n.apply(this,arguments)),M=k,j=k;if(A>ut){var P=ft(A/h*ct(T)),S=ft(A/p*ct(T));(w-=2*P)>ut?(x+=P*=m?1:-1,E-=P):(w=0,x=E=(_+f)/2),(O-=2*S)>ut?(v+=S*=m?1:-1,g-=S):(O=0,v=g=(_+f)/2)}var L=p*st(v),R=p*ct(v),N=h*st(E),I=h*ct(E);if(k>ut){var D,C=p*st(g),z=p*ct(g),B=h*st(x),W=h*ct(x);if(d1?0:u<-1?ht:Math.acos(u))/2),F=lt(D[0]*D[0]+D[1]*D[1]);M=at(k,(h-F)/(q-1)),j=at(k,(p-F)/(q+1))}}O>ut?j>ut?(y=gt(B,W,L,R,p,j,m),b=gt(C,z,N,I,p,j,m),a.moveTo(y.cx+y.x01,y.cy+y.y01),jut&&w>ut?M>ut?(y=gt(N,I,C,z,h,-M,m),b=gt(L,R,B,W,h,-M,m),a.lineTo(y.cx+y.x01,y.cy+y.y01),M0)for(var i,r=t[0],s=e[0],o=t[n]-r,a=e[n]-s,c=-1;++c<=n;)i=c/n,this._basis.point(this._beta*t[c]+(1-this._beta)*(r+i*o),this._beta*e[c]+(1-this._beta)*(s+i*a));this._x=this._y=null,this._basis.lineEnd()},point:function(t,e){this._x.push(+t),this._y.push(+e)}};(function t(e){function n(t){return 1===e?new jt(t):new Lt(t,e)}return n.beta=function(e){return t(+e)},n})(.85);function Rt(t,e,n){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-e),t._y2+t._k*(t._y1-n),t._x2,t._y2)}function Nt(t,e){this._context=t,this._k=(1-e)/6}Nt.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:Rt(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2,this._x1=t,this._y1=e;break;case 2:this._point=3;default:Rt(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};(function t(e){function n(t){return new Nt(t,e)}return n.tension=function(e){return t(+e)},n})(0);function It(t,e){this._context=t,this._k=(1-e)/6}It.prototype={areaStart:kt,areaEnd:kt,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Rt(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};(function t(e){function n(t){return new It(t,e)}return n.tension=function(e){return t(+e)},n})(0);function Dt(t,e){this._context=t,this._k=(1-e)/6}Dt.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Rt(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};(function t(e){function n(t){return new Dt(t,e)}return n.tension=function(e){return t(+e)},n})(0);function Ct(t,e,n){var i=t._x1,r=t._y1,s=t._x2,o=t._y2;if(t._l01_a>ut){var a=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,c=3*t._l01_a*(t._l01_a+t._l12_a);i=(i*a-t._x0*t._l12_2a+t._x2*t._l01_2a)/c,r=(r*a-t._y0*t._l12_2a+t._y2*t._l01_2a)/c}if(t._l23_a>ut){var l=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,u=3*t._l23_a*(t._l23_a+t._l12_a);s=(s*l+t._x1*t._l23_2a-e*t._l12_2a)/u,o=(o*l+t._y1*t._l23_2a-n*t._l12_2a)/u}t._context.bezierCurveTo(i,r,s,o,t._x2,t._y2)}function zt(t,e){this._context=t,this._alpha=e}zt.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,i=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+i*i,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3;default:Ct(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};(function t(e){function n(t){return e?new zt(t,e):new Nt(t,0)}return n.alpha=function(e){return t(+e)},n})(.5);function Bt(t,e){this._context=t,this._alpha=e}Bt.prototype={areaStart:kt,areaEnd:kt,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,i=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+i*i,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Ct(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};(function t(e){function n(t){return e?new Bt(t,e):new It(t,0)}return n.alpha=function(e){return t(+e)},n})(.5);function Wt(t,e){this._context=t,this._alpha=e}Wt.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,i=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+i*i,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Ct(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};(function t(e){function n(t){return e?new Wt(t,e):new Dt(t,0)}return n.alpha=function(e){return t(+e)},n})(.5);function Ht(t){this._context=t}Ht.prototype={areaStart:kt,areaEnd:kt,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(t,e){t=+t,e=+e,this._point?this._context.lineTo(t,e):(this._point=1,this._context.moveTo(t,e))}};function Ut(t){return t<0?-1:1}function Kt(t,e,n){var i=t._x1-t._x0,r=e-t._x1,s=(t._y1-t._y0)/(i||r<0&&-0),o=(n-t._y1)/(r||i<0&&-0),a=(s*r+o*i)/(i+r);return(Ut(s)+Ut(o))*Math.min(Math.abs(s),Math.abs(o),.5*Math.abs(a))||0}function Gt(t,e){var n=t._x1-t._x0;return n?(3*(t._y1-t._y0)/n-e)/2:e}function qt(t,e,n){var i=t._x0,r=t._y0,s=t._x1,o=t._y1,a=(s-i)/3;t._context.bezierCurveTo(i+a,r+a*e,s-a,o-a*n,s,o)}function Ft(t){this._context=t}function Vt(t){this._context=new Xt(t)}function Xt(t){this._context=t}function Yt(t){this._context=t}function Zt(t){var e,n,i=t.length-1,r=new Array(i),s=new Array(i),o=new Array(i);for(r[0]=0,s[0]=2,o[0]=t[0]+2*t[1],e=1;e=0;--e)r[e]=(o[e]-r[e+1])/s[e];for(s[i-1]=(t[i]+r[i-1])/2,e=0;e=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var n=this._x*(1-this._t)+t*this._t;this._context.lineTo(n,this._y),this._context.lineTo(n,e)}}this._x=t,this._y=e}};var Jt=function(){var t=function(e,n){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(e,n)};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}(),$t=function(){return($t=Object.assign||function(t){for(var e,n=1,i=arguments.length;n0){var p=document.createElementNS(ie,"tspan");p.setAttribute("x","0"),p.setAttribute("dy","1em"),p.textContent=""+t,p.style.fontSize="8pt";var _=document.createElementNS(ie,"tspan");_.setAttribute("x","0"),_.setAttribute("dy","1em"),_.textContent=""+this.props.unit,_.style.fontSize="8pt",h.append(p,_),h.setAttribute("transform","translate(50 33)")}else h.textContent=""+t,h.style.fontSize="8pt",h.setAttribute("transform","translate(50 50)");else h.textContent=n+"%",h.setAttribute("transform","translate(50 50)");r.append(h)}return i.append(r),i},e.prototype.getProgress=function(){var t=this.props.minValue||0,e=this.props.maxValue||100,n=null==this.props.value?0:this.props.value;return n<=t?0:n>=e?100:Math.trunc((n-t)/(e-t)*100)},e}(s.a),se=n(2),oe=n(4),ae=n(5),ce=n(6),le=function(){var t=function(e,n){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(e,n)};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}(),ue=function(){return(ue=Object.assign||function(t){for(var e,n=1,i=arguments.length;ne.id?1:-1})).forEach(function(t){try{var e=fe(t);i.elementsById[e.props.id]=e,i.elementIds.push(e.props.id),e.onClick(i.handleElementClick),e.onMoved(i.handleElementMovement),e.onResized(i.handleElementResizement),e.onRemove(i.handleElementRemove),i.containerRef.append(e.elementRef)}catch(t){console.log("Error creating a new element:",t.message)}}),this.buildRelations()}return Object.defineProperty(t.prototype,"elements",{get:function(){var t=this;return this.elementIds.map(function(e){return t.elementsById[e]}).filter(function(t){return null!=t})},enumerable:!0,configurable:!0}),t.prototype.updateElements=function(t){var e=this,n=t.map(function(t){return t.id||null}).filter(function(t){return null!=t});this.elementIds.filter(function(t){return n.indexOf(t)<0}).forEach(function(t){null!=e.elementsById[t]&&(e.elementsById[t].remove(),delete e.elementsById[t])}),this.elementIds=n,t.forEach(function(t){if(t.id)if(null==e.elementsById[t.id])try{var n=fe(t);e.elementsById[n.props.id]=n,n.onClick(e.handleElementClick),n.onRemove(e.handleElementRemove),e.containerRef.append(n.elementRef)}catch(t){console.log("Error creating a new element:",t.message)}else try{e.elementsById[t.id].props=function(t){var e=Object(r.m)(t.type,null);if(null==e)throw new TypeError("missing item type.");switch(e){case 0:return l(t);case 1:return Object(ce.b)(t);case 2:case 6:case 7:case 8:return V(t);case 3:case 9:case 15:case 16:return ne(t);case 4:return H(t);case 5:return _(t);case 10:return he(t);case 11:return E(t);case 12:return L(t);case 13:return D(t);case 14:return Object(Y.b)(t);case 17:return Object(oe.b)(t);case 18:return Object(ae.a)(t);case 19:return M(t);case 20:return y(t);default:throw new TypeError("decoder not found")}}(t)}catch(t){console.log("Error updating an element:",t.message)}}),this.buildRelations()},Object.defineProperty(t.prototype,"props",{get:function(){return _e({},this._props)},set:function(t){var e=this.props;this._props=t,this.render(e)},enumerable:!0,configurable:!0}),t.prototype.render=function(t){void 0===t&&(t=null),t?(t.backgroundURL!==this.props.backgroundURL&&(this.containerRef.style.backgroundImage=null!==this.props.backgroundURL?"url("+this.props.backgroundURL+")":null),t.backgroundColor!==this.props.backgroundColor&&(this.containerRef.style.backgroundColor=this.props.backgroundColor),this.sizeChanged(t,this.props)&&this.resizeElement(this.props.width,this.props.height)):(this.containerRef.style.backgroundImage=null!==this.props.backgroundURL?"url("+this.props.backgroundURL+")":null,this.containerRef.style.backgroundColor=this.props.backgroundColor,this.resizeElement(this.props.width,this.props.height))},t.prototype.sizeChanged=function(t,e){return t.width!==e.width||t.height!==e.height},t.prototype.resizeElement=function(t,e){this.containerRef.style.width=t+"px",this.containerRef.style.height=e+"px"},t.prototype.resize=function(t,e){this.props=_e({},this.props,{width:t,height:e})},t.prototype.remove=function(){this.disposables.forEach(function(t){return t.dispose()}),this.elements.forEach(function(t){return t.remove()}),this.elementsById={},this.elementIds=[],this.clearRelations(),this.containerRef.innerHTML=""},t.prototype.buildRelations=function(){var t=this;this.clearRelations(),this.elements.forEach(function(e){if(null!==e.props.parentId){var n=t.elementsById[e.props.parentId],i=t.elementsById[e.props.id];n&&i&&t.addRelationLine(n,i)}})},t.prototype.clearRelations=function(t){if(null!=t)for(var e in this.relations){var n=e.split("|"),i=Number.parseInt(n[0]),r=Number.parseInt(n[1]);t!==i&&t!==r||(this.relations[e].remove(),delete this.relations[e])}else for(var e in this.relations)this.relations[e].remove(),delete this.relations[e]},t.prototype.getRelationLine=function(t,e){var n=t+"|"+e;return this.relations[n]||null},t.prototype.addRelationLine=function(t,e){var n=t.props.id+"|"+e.props.id;null!=this.relations[n]&&this.relations[n].remove();var i=t.props.x+t.elementRef.clientWidth/2,s=t.props.y+(t.elementRef.clientHeight-t.labelElementRef.clientHeight)/2,o=e.props.x+e.elementRef.clientWidth/2,a=e.props.y+(e.elementRef.clientHeight-e.labelElementRef.clientHeight)/2,c=new z(D({id:0,type:13,startX:i,startY:s,endX:o,endY:a,width:0,height:0,lineWidth:this.props.relationLineWidth,color:"#CCCCCC"}),Object(r.g)({receivedAt:new Date}));return this.relations[n]=c,c.elementRef.style.zIndex="0",this.containerRef.append(c.elementRef),c},t.prototype.onItemClick=function(t){var e=this.clickEventManager.on(t);return this.disposables.push(e),e},t.prototype.onItemMoved=function(t){var e=this.movedEventManager.on(t);return this.disposables.push(e),e},t.prototype.onItemResized=function(t){var e=this.resizedEventManager.on(t);return this.disposables.push(e),e},t.prototype.enableEditMode=function(){this.elements.forEach(function(t){t.meta=_e({},t.meta,{editMode:!0})}),this.containerRef.classList.add("is-editing")},t.prototype.disableEditMode=function(){this.elements.forEach(function(t){t.meta=_e({},t.meta,{editMode:!1})}),this.containerRef.classList.remove("is-editing")},t}(),me=function(){function t(t){this.cancellable={cancel:function(){}},this._status="waiting",this.statusChangeEventManager=new se.a,this.disposables=[],this.taskInitiator=t}return Object.defineProperty(t.prototype,"status",{get:function(){return this._status},set:function(t){this._status=t,this.statusChangeEventManager.emit(t)},enumerable:!0,configurable:!0}),t.prototype.init=function(){var t=this;this.cancellable=this.taskInitiator(function(){t.status="finished"}),this.status="started"},t.prototype.cancel=function(){this.cancellable.cancel(),this.status="cancelled"},t.prototype.onStatusChange=function(t){var e=this.statusChangeEventManager.on(t);return this.disposables.push(e),e},t}();var ye=function(){function t(){this.tasks={}}return t.prototype.add=function(t,e,n){void 0===n&&(n=0),this.tasks[t]&&"started"===this.tasks[t].status&&this.tasks[t].cancel();var i=n>0?function(t,e){return new me(function(){var n=null;return t.onStatusChange(function(i){"finished"===i&&(n=window.setTimeout(function(){t.init()},e))}),t.init(),{cancel:function(){n&&clearTimeout(n),t.cancel()}}})}(new me(e),n):new me(e);return this.tasks[t]=i,this.tasks[t]},t.prototype.init=function(t){!this.tasks[t]||"waiting"!==this.tasks[t].status&&"cancelled"!==this.tasks[t].status&&"finished"!==this.tasks[t].status||this.tasks[t].init()},t.prototype.cancel=function(t){this.tasks[t]&&"started"===this.tasks[t].status&&this.tasks[t].cancel()},t}();window.VisualConsole=de,window.AsyncTaskManager=ye}]); //# sourceMappingURL=vc.main.min.js.map \ No newline at end of file diff --git a/pandora_console/include/visual-console-client/vc.main.min.js.map b/pandora_console/include/visual-console-client/vc.main.min.js.map index 5fae8d74d0..10f1309b68 100644 --- a/pandora_console/include/visual-console-client/vc.main.min.js.map +++ b/pandora_console/include/visual-console-client/vc.main.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/lib/index.ts","webpack:///./src/Item.ts","webpack:///./src/lib/TypedEvent.ts","webpack:///./src/items/EventsHistory.ts","webpack:///./src/items/DonutGraph.ts","webpack:///./src/items/BarsGraph.ts","webpack:///./src/items/ModuleGraph.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:///./node_modules/d3-path/src/path.js","webpack:///./node_modules/d3-shape/src/constant.js","webpack:///./node_modules/d3-shape/src/math.js","webpack:///./node_modules/d3-shape/src/arc.js","webpack:///./node_modules/d3-shape/src/curve/linear.js","webpack:///./node_modules/d3-shape/src/curve/radial.js","webpack:///./node_modules/d3-shape/src/array.js","webpack:///./node_modules/d3-shape/src/symbol/diamond.js","webpack:///./node_modules/d3-shape/src/symbol/circle.js","webpack:///./node_modules/d3-shape/src/symbol/star.js","webpack:///./node_modules/d3-shape/src/noop.js","webpack:///./node_modules/d3-shape/src/symbol/triangle.js","webpack:///./node_modules/d3-shape/src/symbol/wye.js","webpack:///./node_modules/d3-shape/src/curve/basis.js","webpack:///./node_modules/d3-shape/src/curve/basisClosed.js","webpack:///./node_modules/d3-shape/src/curve/basisOpen.js","webpack:///./node_modules/d3-shape/src/curve/bundle.js","webpack:///./node_modules/d3-shape/src/curve/cardinal.js","webpack:///./node_modules/d3-shape/src/curve/cardinalClosed.js","webpack:///./node_modules/d3-shape/src/curve/cardinalOpen.js","webpack:///./node_modules/d3-shape/src/curve/catmullRom.js","webpack:///./node_modules/d3-shape/src/curve/catmullRomClosed.js","webpack:///./node_modules/d3-shape/src/curve/catmullRomOpen.js","webpack:///./node_modules/d3-shape/src/curve/linearClosed.js","webpack:///./node_modules/d3-shape/src/curve/monotone.js","webpack:///./node_modules/d3-shape/src/curve/natural.js","webpack:///./node_modules/d3-shape/src/curve/step.js","webpack:///./node_modules/d3-shape/src/order/descending.js","webpack:///./src/items/Percentile.ts","webpack:///./src/items/Service.ts","webpack:///./src/VisualConsole.ts","webpack:///./src/lib/AsyncTaskManager.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","leftPad","pad","diffLength","substr","Math","abs","substring","repeatTimes","floor","restLength","newPad","positionPropsDecoder","data","x","y","sizePropsDecoder","width","height","TypeError","modulePropsDecoder","__assign","moduleName","moduleDescription","agentProps","agentId","agent","agentName","agentAlias","agentDescription","agentAddress","metaconsoleId","agentPropsDecoder","linkedVCPropsDecoder","id","linkedLayoutId","linkedLayoutAgentId","linkedLayoutStatusProps","linkedLayoutStatusType","weight","linkedLayoutStatusTypeWeight","warningThreshold","linkedLayoutStatusTypeWarningThreshold","criticalThreshold","linkedLayoutStatusTypeCriticalThreshold","linkedLayoutBaseProps","itemMetaDecoder","receivedAt","Date","Number","getTime","error","Error","editMode","isFromCache","isFetching","isUpdating","prefixedCssRules","ruleName","ruleValue","rule","decodeBase64","input","decodeURIComponent","escape","window","atob","humanDate","date","locale","Intl","DateTimeFormat","day","month","year","format","getDate","getMonth","getFullYear","humanTime","getHours","getMinutes","getSeconds","replaceMacros","macros","text","reduce","acc","_a","macro","replace","throttle","delay","fn","last","args","_i","arguments","now","apply","debounce","timerRef","clearTimeout","setTimeout","getOffset","el","offsetLeft","offsetTop","scrollLeft","scrollTop","offsetParent","top","left","addMovementListener","element","onMoved","container","parentElement","isDraggable","draggable","lastX","lastY","lastMouseX","lastMouseY","mouseElementOffsetX","mouseElementOffsetY","containerBounds","getBoundingClientRect","containerOffset","containerTop","containerBottom","containerLeft","containerRight","elementBounds","borderWidth","getComputedStyle","borderFix","debouncedMovement","throttledMovement","handleMove","e","mouseX","pageX","mouseY","pageY","mouseDeltaX","mouseDeltaY","maxX","maxY","outOfBoundsLeft","outOfBoundsRight","outOfBoundsTop","outOfBoundsBottom","handleEnd","document","removeEventListener","body","style","userSelect","handleStart","stopPropagation","offsetX","offsetY","addEventListener","addResizementListener","onResized","resizeDraggable","createElement","className","appendChild","lastWidth","lastHeight","elementOffset","elementTop","elementLeft","debouncedResizement","throttledResizement","handleResize","remove","parseLabelPosition","labelPosition","itemBasePropsDecoder","type","label","_lib__WEBPACK_IMPORTED_MODULE_0__","isLinkEnabled","link","isOnTop","parentId","aclGroupId","VisualConsoleItem","props","metadata","_this","this","clickEventManager","_lib_TypedEvent__WEBPACK_IMPORTED_MODULE_1__","movedEventManager","resizedEventManager","removeEventManager","disposables","debouncedMovementSave","prevPosition","newPosition","positionChanged","move","emit","item","removeMovement","debouncedResizementSave","prevSize","newSize","sizeChanged","resize","removeResizement","itemProps","_metadata","elementRef","createContainerDomElement","labelElementRef","createLabelDomElement","childElementRef","createDomElement","append","resizeElement","changeLabelPosition","initMovementListener","moveElement","stopMovementListener","initResizementListener","labelWidth","labelHeight","stopResizementListener","box","href","zIndex","meta","preventDefault","nativeEvent","classList","add","getLabelWithMacrosReplaced","table","row","emptyRow1","emptyRow2","cell","innerHTML","textAlign","updateDomElement","newProps","prevProps","shouldBeUpdated","render","newMetadata","setMeta","prevMetadata","prevMeta","oldLabelHtml","newLabelHtml","attrs","attributes","nodeName","setAttributeNode","parentNode","replaceChild","forEach","disposable","dispose","ignored","position","flexDirection","tables","getElementsByTagName","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","src","eval","trim","aux","donutGraphPropsDecoder","DonutGraph","barsGraphPropsDecoder","BarsGraph","moduleGraphPropsDecoder","ModuleGraph","legendP","margin","overviewGraphs","getElementsByClassName","parseShowLastValueTooltip","showLastValueTooltip","staticGraphPropsDecoder","imageSrc","Item","statusImageSrc","lib","lastValue","StaticGraph","imgSrc","background","backgroundSize","backgroundPosition","setAttribute","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","showStatistics","extractHtml","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","getElementSize","newWidth","newHeight","createAnalogicClock","createDigitalClock","svgNS","colors","dateFontSize","baseTimeFontSize","div","clockFace","clockFaceBackground","city","getHumanTimezone","timezoneComplication","textContent","marksGroup","mainMarkGroup","mark1a","mark1b","mark","hourHand","hourHandA","hourHandB","minuteHand","minuteHandA","minuteHandB","minuteHandPin","secondHand","secondHandBar","secondHandPin","pin","getOriginDate","seconds","minutes","secAngle","minuteAngle","hourAngle","join","dateElem","fontSize","tzFontSizeMultiplier","timeFontSize","tzFontSize","min","timeElem","tzElem","initialDate","targetTZOffset","localTZOffset","getTimezoneOffset","utimestamp","timezone","_b","split","diameter","boxPropsDecoder","Box_assign","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","img","pi","PI","tau","tauEpsilon","Path","_x0","_y0","_x1","_y1","_","path","constructor","moveTo","closePath","lineTo","quadraticCurveTo","x1","y1","bezierCurveTo","x2","y2","arcTo","x0","y0","x21","y21","x01","y01","l01_2","x20","y20","l21_2","l20_2","l21","sqrt","l01","tan","acos","t01","t21","arc","a0","a1","ccw","dx","cos","dy","sin","cw","da","rect","w","h","src_path","constant","atan2","max","math_epsilon","math_pi","halfPi","math_tau","asin","arcInnerRadius","innerRadius","arcOuterRadius","outerRadius","arcStartAngle","startAngle","arcEndAngle","endAngle","arcPadAngle","padAngle","cornerTangents","r1","rc","lo","ox","oy","x11","y11","x10","y10","x00","y00","d2","D","cx0","cy0","cx1","cy1","dx0","dy0","dx1","dy1","cx","cy","src_arc","cornerRadius","padRadius","context","buffer","r0","t0","t1","a01","a11","a00","a10","da0","da1","ap","rp","rc0","rc1","p0","p1","oc","x3","y3","x32","y32","intersect","ax","ay","bx","by","kc","lc","centroid","a","Linear","_context","areaStart","_line","areaEnd","NaN","lineStart","_point","lineEnd","point","linear","curveRadial","Radial","curve","_curve","radial","Array","slice","kr","noop","that","Basis","BasisClosed","_x2","_x3","_x4","_y2","_y3","_y4","BasisOpen","Bundle","beta","_basis","_beta","_x","_y","j","custom","bundle","cardinal_point","_k","Cardinal","tension","cardinal","CardinalClosed","_x5","_y5","CardinalOpen","catmullRom_point","_l01_a","_l01_2a","_l12_a","_l12_2a","_l23_a","b","_l23_2a","CatmullRom","alpha","_alpha","x23","y23","pow","catmullRom","CatmullRomClosed","CatmullRomOpen","LinearClosed","sign","slope3","h0","h1","s0","s1","slope2","monotone_point","MonotoneX","MonotoneY","ReflectContext","Natural","controlPoints","_t0","px","py","i0","i1","Step","_t","extractPercentileType","extractValueType","percentilePropsDecoder","Percentile_assign","percentileType","minValue","maxValue","labelColor","unit","Percentile_svgNS","Percentile","Percentile_extends","formatValue","progress","getProgress","NumberFormat","backgroundRect","progressRect","backgroundCircle","progressCircle","arcProps","trunc","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","handleElementMovement","handleElementResizement","handleElementRemove","filter","clearRelations","containerRef","_props","backgroundURL","isFavorite","relationLineWidth","VisualConsole_assign","visualConsolePropsDecoder","sort","itemInstance","console","log","message","buildRelations","map","updateElements","itemIds","decodeProps","backgroundImage","elements","parent_1","child","addRelationLine","itemId","ids","childId","getRelationLine","identifier","parent","clientWidth","clientHeight","onItemClick","onItemMoved","onItemResized","enableEditMode","disableEditMode","AsyncTaskManager_AsyncTask","AsyncTask","taskInitiator","cancellable","cancel","_status","statusChangeEventManager","status","init","onStatusChange","AsyncTaskManager","tasks","asyncTask","task","ref","asyncPeriodic","src_VisualConsole","lib_AsyncTaskManager"],"mappings":"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","file":"vc.main.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 AnyObject,\n Position,\n Size,\n WithAgentProps,\n WithModuleProps,\n LinkedVisualConsoleProps,\n LinkedVisualConsolePropsStatus,\n UnknownObject,\n ItemMeta\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 */\nexport function parseIntOr(value: unknown, 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 */\nexport function parseFloatOr(value: unknown, 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 */\nexport function notEmptyStringOr(\n value: unknown,\n defaultValue: T\n): 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 */\nexport function parseBoolean(value: unknown): 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 * Return a valid date or a default value from a raw value.\n * @param value Raw value from which we will try to extract a valid date.\n * @param defaultValue Default value to use if we cannot extract a valid date.\n * @return A valid date or the default value.\n */\nexport function parseDateOr(value: unknown, defaultValue: T): Date | T {\n if (value instanceof Date) return value;\n else if (typeof value === \"number\") return new Date(value * 1000);\n else if (\n typeof value === \"string\" &&\n !Number.isNaN(new Date(value).getTime())\n )\n return new Date(value);\n else return defaultValue;\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 leftPad(\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: AnyObject): 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: AnyObject): 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: AnyObject): WithAgentProps {\n const agentProps: WithAgentProps = {\n agentId: parseIntOr(data.agent, null),\n agentName: notEmptyStringOr(data.agentName, null),\n agentAlias: notEmptyStringOr(data.agentAlias, null),\n agentDescription: notEmptyStringOr(data.agentDescription, null),\n agentAddress: notEmptyStringOr(data.agentAddress, null)\n };\n\n return data.metaconsoleId != null\n ? {\n metaconsoleId: data.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: AnyObject): WithModuleProps {\n return {\n moduleId: parseIntOr(data.moduleId, null),\n moduleName: notEmptyStringOr(data.moduleName, null),\n moduleDescription: notEmptyStringOr(data.moduleDescription, 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: AnyObject\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 * Build a valid typed object from a raw object.\n * @param data Raw object.\n * @return An object representing the item's meta properties.\n */\nexport function itemMetaDecoder(data: UnknownObject): ItemMeta | never {\n const receivedAt = parseDateOr(data.receivedAt, null);\n if (receivedAt === null) throw new TypeError(\"invalid meta structure\");\n\n let error = null;\n if (data.error instanceof Error) error = data.error;\n else if (typeof data.error === \"string\") error = new Error(data.error);\n\n return {\n receivedAt,\n error,\n editMode: parseBoolean(data.editMode),\n isFromCache: parseBoolean(data.isFromCache),\n isFetching: false,\n isUpdating: false\n };\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\n/**\n * Generate a date representation with the format 'd/m/Y'.\n * @param initialDate Date to be used instead of a generated one.\n * @param locale Locale to use if localization is required and available.\n * @example 24/02/2020.\n * @return Date representation.\n */\nexport function humanDate(date: Date, locale: string | null = null): string {\n if (locale && Intl && Intl.DateTimeFormat) {\n // Format using the user locale.\n const options: Intl.DateTimeFormatOptions = {\n day: \"2-digit\",\n month: \"2-digit\",\n year: \"numeric\"\n };\n return Intl.DateTimeFormat(locale, options).format(date);\n } else {\n // Use getDate, getDay returns the week day.\n const day = leftPad(date.getDate(), 2, 0);\n // The getMonth function returns the month starting by 0.\n const month = leftPad(date.getMonth() + 1, 2, 0);\n const year = leftPad(date.getFullYear(), 4, 0);\n\n // Format: 'd/m/Y'.\n return `${day}/${month}/${year}`;\n }\n}\n\n/**\n * Generate a time representation with the format 'hh:mm:ss'.\n * @param initialDate Date to be used instead of a generated one.\n * @example 01:34:09.\n * @return Time representation.\n */\nexport function humanTime(date: Date): string {\n const hours = leftPad(date.getHours(), 2, 0);\n const minutes = leftPad(date.getMinutes(), 2, 0);\n const seconds = leftPad(date.getSeconds(), 2, 0);\n\n return `${hours}:${minutes}:${seconds}`;\n}\n\ninterface Macro {\n macro: string | RegExp;\n value: string;\n}\n/**\n * Replace the macros of a text.\n * @param macros List of macros and their replacements.\n * @param text Text in which we need to replace the macros.\n */\nexport function replaceMacros(macros: Macro[], text: string): string {\n return macros.reduce(\n (acc, { macro, value }) => acc.replace(macro, value),\n text\n );\n}\n\n/**\n * Create a function which will limit the rate of execution of\n * the selected function to one time for the selected interval.\n * @param delay Interval.\n * @param fn Function to be executed at a limited rate.\n */\nexport function throttle(delay: number, fn: (...args: T[]) => R) {\n let last = 0;\n return (...args: T[]) => {\n const now = Date.now();\n if (now - last < delay) return;\n last = now;\n return fn(...args);\n };\n}\n\n/**\n * Create a function which will call the selected function only\n * after the interval time has passed after its last execution.\n * @param delay Interval.\n * @param fn Function to be executed after the last call.\n */\nexport function debounce(delay: number, fn: (...args: T[]) => void) {\n let timerRef: number | null = null;\n return (...args: T[]) => {\n if (timerRef !== null) window.clearTimeout(timerRef);\n timerRef = window.setTimeout(() => {\n fn(...args);\n timerRef = null;\n }, delay);\n };\n}\n\n/**\n * Retrieve the offset of an element relative to the page.\n * @param el Node used to calculate the offset.\n */\nfunction getOffset(el: HTMLElement | null) {\n let x = 0;\n let y = 0;\n while (el && !Number.isNaN(el.offsetLeft) && !Number.isNaN(el.offsetTop)) {\n x += el.offsetLeft - el.scrollLeft;\n y += el.offsetTop - el.scrollTop;\n el = el.offsetParent as HTMLElement | null;\n }\n return { top: y, left: x };\n}\n\n/**\n * Add the grab & move functionality to a certain element inside it's container.\n *\n * @param element Element to move.\n * @param onMoved Function to execute when the element moves.\n *\n * @return A function which will clean the event handlers when executed.\n */\nexport function addMovementListener(\n element: HTMLElement,\n onMoved: (x: Position[\"x\"], y: Position[\"y\"]) => void\n): Function {\n const container = element.parentElement as HTMLElement;\n // Store the initial draggable state.\n const isDraggable = element.draggable;\n // Init the coordinates.\n let lastX: Position[\"x\"] = 0;\n let lastY: Position[\"y\"] = 0;\n let lastMouseX: Position[\"x\"] = 0;\n let lastMouseY: Position[\"y\"] = 0;\n let mouseElementOffsetX: Position[\"x\"] = 0;\n let mouseElementOffsetY: Position[\"y\"] = 0;\n // Bounds.\n let containerBounds = container.getBoundingClientRect();\n let containerOffset = getOffset(container);\n let containerTop = containerOffset.top;\n let containerBottom = containerTop + containerBounds.height;\n let containerLeft = containerOffset.left;\n let containerRight = containerLeft + containerBounds.width;\n let elementBounds = element.getBoundingClientRect();\n let borderWidth = window.getComputedStyle(element).borderWidth || \"0\";\n let borderFix = Number.parseInt(borderWidth) * 2;\n\n // Will run onMoved 32ms after its last execution.\n const debouncedMovement = debounce(32, (x: Position[\"x\"], y: Position[\"y\"]) =>\n onMoved(x, y)\n );\n // Will run onMoved one time max every 16ms.\n const throttledMovement = throttle(16, (x: Position[\"x\"], y: Position[\"y\"]) =>\n onMoved(x, y)\n );\n\n const handleMove = (e: MouseEvent) => {\n // Calculate the new element coordinates.\n let x = 0;\n let y = 0;\n\n const mouseX = e.pageX;\n const mouseY = e.pageY;\n const mouseDeltaX = mouseX - lastMouseX;\n const mouseDeltaY = mouseY - lastMouseY;\n\n const minX = 0;\n const maxX = containerBounds.width - elementBounds.width + borderFix;\n const minY = 0;\n const maxY = containerBounds.height - elementBounds.height + borderFix;\n\n const outOfBoundsLeft =\n mouseX < containerLeft ||\n (lastX === 0 &&\n mouseDeltaX > 0 &&\n mouseX < containerLeft + mouseElementOffsetX);\n const outOfBoundsRight =\n mouseX > containerRight ||\n mouseDeltaX + lastX + elementBounds.width - borderFix >\n containerBounds.width ||\n (lastX === maxX &&\n mouseDeltaX < 0 &&\n mouseX > containerLeft + maxX + mouseElementOffsetX);\n const outOfBoundsTop =\n mouseY < containerTop ||\n (lastY === 0 &&\n mouseDeltaY > 0 &&\n mouseY < containerTop + mouseElementOffsetY);\n const outOfBoundsBottom =\n mouseY > containerBottom ||\n mouseDeltaY + lastY + elementBounds.height - borderFix >\n containerBounds.height ||\n (lastY === maxY &&\n mouseDeltaY < 0 &&\n mouseY > containerTop + maxY + mouseElementOffsetY);\n\n if (outOfBoundsLeft) x = minX;\n else if (outOfBoundsRight) x = maxX;\n else x = mouseDeltaX + lastX;\n\n if (outOfBoundsTop) y = minY;\n else if (outOfBoundsBottom) y = maxY;\n else y = mouseDeltaY + lastY;\n\n if (x < 0) x = minX;\n if (y < 0) y = minY;\n\n // Store the last mouse coordinates.\n lastMouseX = mouseX;\n lastMouseY = mouseY;\n\n if (x === lastX && y === lastY) return;\n\n // Run the movement events.\n throttledMovement(x, y);\n debouncedMovement(x, y);\n\n // Store the coordinates of the element.\n lastX = x;\n lastY = y;\n };\n const handleEnd = () => {\n // Reset the positions.\n lastX = 0;\n lastY = 0;\n lastMouseX = 0;\n lastMouseY = 0;\n // Remove the move event.\n document.removeEventListener(\"mousemove\", handleMove);\n // Clean itself.\n document.removeEventListener(\"mouseup\", handleEnd);\n // Reset the draggable property to its initial state.\n element.draggable = isDraggable;\n // Reset the body selection property to a default state.\n document.body.style.userSelect = \"auto\";\n };\n const handleStart = (e: MouseEvent) => {\n e.stopPropagation();\n\n // Disable the drag temporarily.\n element.draggable = false;\n\n // Store the difference between the cursor and\n // the initial coordinates of the element.\n lastX = element.offsetLeft;\n lastY = element.offsetTop;\n // Store the mouse position.\n lastMouseX = e.pageX;\n lastMouseY = e.pageY;\n // Store the relative position between the mouse and the element.\n mouseElementOffsetX = e.offsetX;\n mouseElementOffsetY = e.offsetY;\n\n // Initialize the bounds.\n containerBounds = container.getBoundingClientRect();\n containerOffset = getOffset(container);\n containerTop = containerOffset.top;\n containerBottom = containerTop + containerBounds.height;\n containerLeft = containerOffset.left;\n containerRight = containerLeft + containerBounds.width;\n elementBounds = element.getBoundingClientRect();\n borderWidth = window.getComputedStyle(element).borderWidth || \"0\";\n borderFix = Number.parseInt(borderWidth) * 2;\n\n // Listen to the mouse movement.\n document.addEventListener(\"mousemove\", handleMove);\n // Listen to the moment when the mouse click is not pressed anymore.\n document.addEventListener(\"mouseup\", handleEnd);\n // Limit the mouse selection of the body.\n document.body.style.userSelect = \"none\";\n };\n\n // Event to listen the init of the movement.\n element.addEventListener(\"mousedown\", handleStart);\n\n // Returns a function to clean the event listeners.\n return () => {\n element.removeEventListener(\"mousedown\", handleStart);\n handleEnd();\n };\n}\n\n/**\n * Add the grab & resize functionality to a certain element.\n *\n * @param element Element to move.\n * @param onResized Function to execute when the element is resized.\n *\n * @return A function which will clean the event handlers when executed.\n */\nexport function addResizementListener(\n element: HTMLElement,\n onResized: (x: Position[\"x\"], y: Position[\"y\"]) => void\n): Function {\n const minWidth = 15;\n const minHeight = 15;\n\n const resizeDraggable = document.createElement(\"div\");\n resizeDraggable.className = \"resize-draggable\";\n element.appendChild(resizeDraggable);\n\n // Container of the resizable element.\n const container = element.parentElement as HTMLElement;\n // Store the initial draggable state.\n const isDraggable = element.draggable;\n // Init the coordinates.\n let lastWidth: Size[\"width\"] = 0;\n let lastHeight: Size[\"height\"] = 0;\n let lastMouseX: Position[\"x\"] = 0;\n let lastMouseY: Position[\"y\"] = 0;\n let mouseElementOffsetX: Position[\"x\"] = 0;\n let mouseElementOffsetY: Position[\"y\"] = 0;\n // Init the bounds.\n let containerBounds = container.getBoundingClientRect();\n let containerOffset = getOffset(container);\n let containerTop = containerOffset.top;\n let containerBottom = containerTop + containerBounds.height;\n let containerLeft = containerOffset.left;\n let containerRight = containerLeft + containerBounds.width;\n let elementOffset = getOffset(element);\n let elementTop = elementOffset.top;\n let elementLeft = elementOffset.left;\n let borderWidth = window.getComputedStyle(element).borderWidth || \"0\";\n let borderFix = Number.parseInt(borderWidth);\n\n // Will run onResized 32ms after its last execution.\n const debouncedResizement = debounce(\n 32,\n (width: Size[\"width\"], height: Size[\"height\"]) => onResized(width, height)\n );\n // Will run onResized one time max every 16ms.\n const throttledResizement = throttle(\n 16,\n (width: Size[\"width\"], height: Size[\"height\"]) => onResized(width, height)\n );\n\n const handleResize = (e: MouseEvent) => {\n // Calculate the new element coordinates.\n let width = lastWidth + (e.pageX - lastMouseX);\n let height = lastHeight + (e.pageY - lastMouseY);\n\n if (width === lastWidth && height === lastHeight) return;\n\n if (\n width < lastWidth &&\n e.pageX > elementLeft + (lastWidth - mouseElementOffsetX)\n )\n return;\n\n if (width < minWidth) {\n // Minimum value.\n width = minWidth;\n } else if (width + elementLeft - borderFix / 2 >= containerRight) {\n // Limit the size to the container.\n width = containerRight - elementLeft;\n }\n if (height < minHeight) {\n // Minimum value.\n height = minHeight;\n } else if (height + elementTop - borderFix / 2 >= containerBottom) {\n // Limit the size to the container.\n height = containerBottom - elementTop;\n }\n\n // Run the movement events.\n throttledResizement(width, height);\n debouncedResizement(width, height);\n\n // Store the coordinates of the element.\n lastWidth = width;\n lastHeight = height;\n // Store the last mouse coordinates.\n lastMouseX = e.pageX;\n lastMouseY = e.pageY;\n };\n const handleEnd = () => {\n // Reset the positions.\n lastWidth = 0;\n lastHeight = 0;\n lastMouseX = 0;\n lastMouseY = 0;\n mouseElementOffsetX = 0;\n mouseElementOffsetY = 0;\n // Remove the move event.\n document.removeEventListener(\"mousemove\", handleResize);\n // Clean itself.\n document.removeEventListener(\"mouseup\", handleEnd);\n // Reset the draggable property to its initial state.\n element.draggable = isDraggable;\n // Reset the body selection property to a default state.\n document.body.style.userSelect = \"auto\";\n };\n const handleStart = (e: MouseEvent) => {\n e.stopPropagation();\n\n // Disable the drag temporarily.\n element.draggable = false;\n\n // Store the difference between the cursor and\n // the initial coordinates of the element.\n const { width, height } = element.getBoundingClientRect();\n lastWidth = width;\n lastHeight = height;\n // Store the mouse position.\n lastMouseX = e.pageX;\n lastMouseY = e.pageY;\n // Store the relative position between the mouse and the element.\n mouseElementOffsetX = e.offsetX;\n mouseElementOffsetY = e.offsetY;\n\n // Initialize the bounds.\n containerBounds = container.getBoundingClientRect();\n containerOffset = getOffset(container);\n containerTop = containerOffset.top;\n containerBottom = containerTop + containerBounds.height;\n containerLeft = containerOffset.left;\n containerRight = containerLeft + containerBounds.width;\n elementOffset = getOffset(element);\n elementTop = elementOffset.top;\n elementLeft = elementOffset.left;\n\n // Listen to the mouse movement.\n document.addEventListener(\"mousemove\", handleResize);\n // Listen to the moment when the mouse click is not pressed anymore.\n document.addEventListener(\"mouseup\", handleEnd);\n // Limit the mouse selection of the body.\n document.body.style.userSelect = \"none\";\n };\n\n // Event to listen the init of the movement.\n resizeDraggable.addEventListener(\"mousedown\", handleStart);\n\n // Returns a function to clean the event listeners.\n return () => {\n resizeDraggable.remove();\n handleEnd();\n };\n}\n","import {\n Position,\n Size,\n AnyObject,\n WithModuleProps,\n ItemMeta\n} from \"./lib/types\";\nimport {\n sizePropsDecoder,\n positionPropsDecoder,\n parseIntOr,\n parseBoolean,\n notEmptyStringOr,\n replaceMacros,\n humanDate,\n humanTime,\n addMovementListener,\n debounce,\n addResizementListener\n} from \"./lib\";\nimport TypedEvent, { Listener, Disposable } from \"./lib/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: AnyObject;\n nativeEvent: Event;\n}\n\n// FIXME: Fix type compatibility.\nexport interface ItemRemoveEvent {\n // data: Props;\n data: AnyObject;\n}\n\nexport interface ItemMovedEvent {\n item: VisualConsoleItem;\n prevPosition: Position;\n newPosition: Position;\n}\n\nexport interface ItemResizedEvent {\n item: VisualConsoleItem;\n prevSize: Size;\n newSize: Size;\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: unknown\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: AnyObject): 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 // Metadata of the item.\n private _metadata: ItemMeta;\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 moved events.\n private readonly movedEventManager = new TypedEvent();\n // Event manager for resized events.\n private readonly resizedEventManager = 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 // This function will only run the 2nd arg function after the time\n // of the first arg have passed after its last execution.\n private debouncedMovementSave = debounce(\n 500, // ms.\n (x: Position[\"x\"], y: Position[\"y\"]) => {\n const prevPosition = {\n x: this.props.x,\n y: this.props.y\n };\n const newPosition = {\n x: x,\n y: y\n };\n\n if (!this.positionChanged(prevPosition, newPosition)) return;\n\n // Save the new position to the props.\n this.move(x, y);\n // Emit the movement event.\n this.movedEventManager.emit({\n item: this,\n prevPosition: prevPosition,\n newPosition: newPosition\n });\n }\n );\n // This property will store the function\n // to clean the movement listener.\n private removeMovement: Function | null = null;\n\n /**\n * Start the movement funtionality.\n * @param element Element to move inside its container.\n */\n private initMovementListener(element: HTMLElement): void {\n this.removeMovement = addMovementListener(\n element,\n (x: Position[\"x\"], y: Position[\"y\"]) => {\n // Move the DOM element.\n this.moveElement(x, y);\n // Run the save function.\n this.debouncedMovementSave(x, y);\n }\n );\n }\n /**\n * Stop the movement fun\n */\n private stopMovementListener(): void {\n if (this.removeMovement) {\n this.removeMovement();\n this.removeMovement = null;\n }\n }\n\n // This function will only run the 2nd arg function after the time\n // of the first arg have passed after its last execution.\n private debouncedResizementSave = debounce(\n 500, // ms.\n (width: Size[\"width\"], height: Size[\"height\"]) => {\n const prevSize = {\n width: this.props.width,\n height: this.props.height\n };\n const newSize = {\n width: width,\n height: height\n };\n\n if (!this.sizeChanged(prevSize, newSize)) return;\n\n // Save the new position to the props.\n this.resize(width, height);\n // Emit the resizement event.\n this.resizedEventManager.emit({\n item: this,\n prevSize: prevSize,\n newSize: newSize\n });\n }\n );\n // This property will store the function\n // to clean the resizement listener.\n private removeResizement: Function | null = null;\n\n /**\n * Start the resizement funtionality.\n * @param element Element to move inside its container.\n */\n private initResizementListener(element: HTMLElement): void {\n this.removeResizement = addResizementListener(\n element,\n (width: Size[\"width\"], height: Size[\"height\"]) => {\n // The label it's outside the item's size, so we need\n // to get rid of its size to get the real size of the\n // item's content.\n if (this.props.label && this.props.label.length > 0) {\n const {\n width: labelWidth,\n height: labelHeight\n } = this.labelElementRef.getBoundingClientRect();\n\n switch (this.props.labelPosition) {\n case \"up\":\n case \"down\":\n height -= labelHeight;\n break;\n case \"left\":\n case \"right\":\n width -= labelWidth;\n break;\n }\n }\n\n // Move the DOM element.\n this.resizeElement(width, height);\n // Run the save function.\n this.debouncedResizementSave(width, height);\n }\n );\n }\n /**\n * Stop the resizement functionality.\n */\n private stopResizementListener(): void {\n if (this.removeResizement) {\n this.removeResizement();\n this.removeResizement = null;\n }\n }\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, metadata: ItemMeta) {\n this.itemProps = props;\n this._metadata = metadata;\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\") as HTMLAnchorElement;\n if (this.props.link) box.href = this.props.link;\n } else {\n box = document.createElement(\"div\") 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 // Init the click listener.\n box.addEventListener(\"click\", e => {\n if (this.meta.editMode) {\n e.preventDefault();\n e.stopPropagation();\n } else {\n this.clickEventManager.emit({ data: this.props, nativeEvent: e });\n }\n });\n\n // Metadata state.\n if (this.meta.editMode) {\n box.classList.add(\"is-editing\");\n // Init the movement listener.\n this.initMovementListener(box);\n // Init the resizement listener.\n this.initResizementListener(box);\n }\n if (this.meta.isFetching) {\n box.classList.add(\"is-fetching\");\n }\n if (this.meta.isUpdating) {\n box.classList.add(\"is-updating\");\n }\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 const label = this.getLabelWithMacrosReplaced();\n if (label.length > 0) {\n // Ugly table we need to use to replicate the legacy style.\n const table = document.createElement(\"table\");\n const row = document.createElement(\"tr\");\n const emptyRow1 = document.createElement(\"tr\");\n const emptyRow2 = document.createElement(\"tr\");\n const cell = document.createElement(\"td\");\n\n cell.innerHTML = label;\n row.append(cell);\n table.append(emptyRow1, row, emptyRow2);\n table.style.textAlign = \"center\";\n\n // Change the table size depending on its position.\n switch (this.props.labelPosition) {\n case \"up\":\n case \"down\":\n if (this.props.width > 0) {\n table.style.width = `${this.props.width}px`;\n table.style.height = null;\n }\n break;\n case \"left\":\n case \"right\":\n if (this.props.height > 0) {\n table.style.width = null;\n table.style.height = `${this.props.height}px`;\n }\n break;\n }\n\n // element.innerHTML = this.props.label;\n element.append(table);\n }\n\n return element;\n }\n\n /**\n * Return the label stored into the props with some macros replaced.\n */\n protected getLabelWithMacrosReplaced(): string {\n // We assert that the props may have some needed properties.\n const props = this.props as Partial;\n\n return replaceMacros(\n [\n {\n macro: \"_date_\",\n value: humanDate(new Date())\n },\n {\n macro: \"_time_\",\n value: humanTime(new Date())\n },\n {\n macro: \"_agent_\",\n value: props.agentAlias != null ? props.agentAlias : \"\"\n },\n {\n macro: \"_agentdescription_\",\n value: props.agentDescription != null ? props.agentDescription : \"\"\n },\n {\n macro: \"_address_\",\n value: props.agentAddress != null ? props.agentAddress : \"\"\n },\n {\n macro: \"_module_\",\n value: props.moduleName != null ? props.moduleName : \"\"\n },\n {\n macro: \"_moduledescription_\",\n value: props.moduleDescription != null ? props.moduleDescription : \"\"\n }\n ],\n this.props.label || \"\"\n );\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))\n this.render(prevProps, this._metadata);\n }\n\n /**\n * Public accessor of the `meta` property.\n * @return Properties.\n */\n public get meta(): ItemMeta {\n return { ...this._metadata }; // Return a copy.\n }\n\n /**\n * Public setter of the `meta` property.\n * If the new meta are different enough than the\n * stored meta, a render would be fired.\n * @param newProps\n */\n public set meta(newMetadata: ItemMeta) {\n this.setMeta(newMetadata);\n }\n\n /**\n * Clasic and protected version of the setter of the `meta` property.\n * Useful to override it from children classes.\n * @param newProps\n */\n protected setMeta(newMetadata: ItemMeta) {\n const prevMetadata = this._metadata;\n // Update the internal meta.\n this._metadata = newMetadata;\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(prevMetadata, newMetadata))\n this.render(this.itemProps, prevMetadata);\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(\n prevProps: Props | null = null,\n prevMeta: ItemMeta | null = null\n ): 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 const oldLabelHtml = this.labelElementRef.innerHTML;\n const newLabelHtml = this.createLabelDomElement().innerHTML;\n if (oldLabelHtml !== newLabelHtml) {\n this.labelElementRef.innerHTML = newLabelHtml;\n }\n // Change label position.\n if (!prevProps || prevProps.labelPosition !== this.props.labelPosition) {\n this.changeLabelPosition(this.props.labelPosition);\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 // Add the children of the old element.\n container.innerHTML = this.elementRef.innerHTML;\n // Copy the attributes.\n const attrs = this.elementRef.attributes;\n for (let i = 0; i < attrs.length; i++) {\n if (attrs[i].nodeName !== \"id\") {\n container.setAttributeNode(attrs[i]);\n }\n }\n // Replace the reference.\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\n // Change metadata related things.\n if (!prevMeta || prevMeta.editMode !== this.meta.editMode) {\n if (this.meta.editMode) {\n this.elementRef.classList.add(\"is-editing\");\n this.initMovementListener(this.elementRef);\n this.initResizementListener(this.elementRef);\n } else {\n this.elementRef.classList.remove(\"is-editing\");\n this.stopMovementListener();\n this.stopResizementListener();\n }\n }\n if (!prevMeta || prevMeta.isFetching !== this.meta.isFetching) {\n if (this.meta.isFetching) {\n this.elementRef.classList.add(\"is-fetching\");\n } else {\n this.elementRef.classList.remove(\"is-fetching\");\n }\n }\n if (!prevMeta || prevMeta.isUpdating !== this.meta.isUpdating) {\n if (this.meta.isUpdating) {\n this.elementRef.classList.add(\"is-updating\");\n } else {\n this.elementRef.classList.remove(\"is-updating\");\n }\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 // Ugly table to show the label as its legacy counterpart.\n const tables = this.labelElementRef.getElementsByTagName(\"table\");\n const table = tables.length > 0 ? tables.item(0) : null;\n // Change the table size depending on its position.\n if (table) {\n switch (this.props.labelPosition) {\n case \"up\":\n case \"down\":\n if (this.props.width > 0) {\n table.style.width = `${this.props.width}px`;\n table.style.height = null;\n }\n break;\n case \"left\":\n case \"right\":\n if (this.props.height > 0) {\n table.style.width = null;\n table.style.height = `${this.props.height}px`;\n }\n break;\n }\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 if (this.props.label && this.props.label.length > 0) {\n // Ugly table to show the label as its legacy counterpart.\n const tables = this.labelElementRef.getElementsByTagName(\"table\");\n const table = tables.length > 0 ? tables.item(0) : null;\n\n if (table) {\n switch (this.props.labelPosition) {\n case \"up\":\n case \"down\":\n table.style.width = width > 0 ? `${width}px` : null;\n break;\n case \"left\":\n case \"right\":\n table.style.height = height > 0 ? `${height}px` : null;\n break;\n }\n }\n }\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 movement of visual console elements.\n * @param listener Function which is going to be executed when a linked console is moved.\n */\n public onMoved(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.movedEventManager.on(listener);\n this.disposables.push(disposable);\n\n return disposable;\n }\n\n /**\n * To add an event handler to the resizement of visual console elements.\n * @param listener Function which is going to be executed when a linked console is moved.\n */\n public onResized(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.resizedEventManager.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 { AnyObject, WithModuleProps } from \"../lib/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: AnyObject\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 AnyObject,\n WithModuleProps\n} from \"../lib/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: AnyObject\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 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 { AnyObject, WithModuleProps } from \"../lib/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(data: AnyObject): 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 LinkedVisualConsoleProps,\n AnyObject,\n WithModuleProps\n} from \"../lib/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: AnyObject\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 /**\n * @override Item.resizeElement.\n * Resize the DOM content container.\n * We need to override the resize function cause this item's height\n * is larger than the configured and the graph is over the label.\n * @param width\n * @param height\n */\n protected resizeElement(width: number): void {\n super.resizeElement(width, 0);\n }\n\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 {\n WithModuleProps,\n LinkedVisualConsoleProps,\n AnyObject\n} from \"../lib/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: unknown\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: AnyObject\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 imgSrc = this.props.statusImageSrc || this.props.imageSrc;\n const element = document.createElement(\"div\");\n element.className = \"static-graph\";\n element.style.background = `url(${imgSrc}) no-repeat`;\n element.style.backgroundSize = \"contain\";\n element.style.backgroundPosition = \"center\";\n\n // Show last value in a tooltip.\n if (\n this.props.lastValue !== null &&\n this.props.showLastValueTooltip !== \"disabled\"\n ) {\n element.className = \"static-graph image forced_title\";\n element.setAttribute(\"data-use_title_for_force_title\", \"1\");\n element.setAttribute(\"data-title\", this.props.lastValue);\n }\n\n return element;\n }\n}\n","import { LinkedVisualConsoleProps, AnyObject } from \"../lib/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: AnyObject): 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 element = document.createElement(\"div\");\n element.className = \"icon\";\n element.style.background = `url(${this.props.imageSrc}) no-repeat`;\n element.style.backgroundSize = \"contain\";\n element.style.backgroundPosition = \"center\";\n\n return element;\n }\n}\n","import {\n WithModuleProps,\n LinkedVisualConsoleProps,\n AnyObject\n} from \"../lib/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: AnyObject\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 protected resizeElement(width: number): void {\n super.resizeElement(width, width);\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, AnyObject } from \"../lib/types\";\nimport {\n linkedVCPropsDecoder,\n parseIntOr,\n notEmptyStringOr,\n stringIsEmpty,\n decodeBase64,\n parseBoolean\n} from \"../lib\";\nimport Item, { ItemProps, itemBasePropsDecoder, ItemType } from \"../Item\";\n\nexport type GroupProps = {\n type: ItemType.GROUP_ITEM;\n groupId: number;\n imageSrc: string | null; // URL?\n statusImageSrc: string | null;\n showStatistics: boolean;\n html?: string | null;\n} & ItemProps &\n LinkedVisualConsoleProps;\n\nfunction extractHtml(data: AnyObject): string | null {\n if (!stringIsEmpty(data.html)) return data.html;\n if (!stringIsEmpty(data.encodedHtml)) return decodeBase64(data.encodedHtml);\n return 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 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: AnyObject): GroupProps | never {\n if (\n (typeof data.imageSrc !== \"string\" || data.imageSrc.length === 0) &&\n data.encodedHtml === null\n ) {\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 const showStatistics = parseBoolean(data.showStatistics);\n const html = showStatistics ? extractHtml(data) : null;\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.GROUP_ITEM,\n groupId: parseInt(data.groupId),\n imageSrc: notEmptyStringOr(data.imageSrc, null),\n statusImageSrc: notEmptyStringOr(data.statusImageSrc, null),\n showStatistics,\n html,\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 element = document.createElement(\"div\");\n element.className = \"group\";\n\n if (!this.props.showStatistics && this.props.statusImageSrc !== null) {\n // Icon with status.\n element.style.background = `url(${this.props.statusImageSrc}) no-repeat`;\n element.style.backgroundSize = \"contain\";\n element.style.backgroundPosition = \"center\";\n } else if (this.props.showStatistics && this.props.html != null) {\n // Stats table.\n element.innerHTML = this.props.html;\n }\n\n return element;\n }\n}\n","import \"./styles.css\";\n\nimport {\n LinkedVisualConsoleProps,\n AnyObject,\n Size,\n ItemMeta\n} from \"../../lib/types\";\nimport {\n linkedVCPropsDecoder,\n parseIntOr,\n parseBoolean,\n prefixedCssRules,\n notEmptyStringOr,\n humanDate,\n humanTime\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 = (clockType: unknown): 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 = (clockFormat: unknown): ClockProps[\"clockFormat\"] => {\n switch (clockFormat) {\n case \"datetime\":\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: AnyObject): 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, meta: ItemMeta) {\n // Call the superclass constructor.\n super(props, meta);\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 // 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 dateFontSize =\n (baseTimeFontSize * dateFontSizeMultiplier * width) / 100;\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.getOriginDate();\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 // Date.\n if (this.props.clockFormat === \"datetime\") {\n const dateElem: HTMLSpanElement = document.createElement(\"span\");\n dateElem.className = \"date\";\n dateElem.textContent = humanDate(date, \"default\");\n dateElem.style.fontSize = `${dateFontSize}px`;\n if (this.props.color) dateElem.style.color = this.props.color;\n div.append(dateElem);\n }\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 calculated using the original timezone.\n const date = this.getOriginDate();\n\n // Date.\n if (this.props.clockFormat === \"datetime\") {\n const dateElem: HTMLSpanElement = document.createElement(\"span\");\n dateElem.className = \"date\";\n dateElem.textContent = humanDate(date, \"default\");\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 = humanTime(date);\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 getOriginDate(initialDate: Date | null = null): Date {\n const d = initialDate ? initialDate : 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 * 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 { AnyObject } from \"../lib/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: AnyObject): 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 { AnyObject, Position, Size, ItemMeta } from \"../lib/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: AnyObject): 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, meta: ItemMeta) {\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 {\n ...props,\n ...Line.extractBoxSizeAndPosition(props)\n },\n {\n ...meta,\n editMode: false\n }\n );\n }\n\n /**\n * Clasic and protected version of the setter of the `meta` property.\n * Useful to override it from children classes.\n * @param newProps\n * @override Item.setMeta\n */\n public setMeta(newMetadata: ItemMeta) {\n super.setMeta({\n ...newMetadata,\n editMode: false\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, AnyObject } from \"../lib/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: AnyObject): 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.getLabelWithMacrosReplaced();\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 AnyObject,\n WithModuleProps\n} from \"../lib/types\";\nimport {\n linkedVCPropsDecoder,\n parseIntOr,\n modulePropsDecoder,\n replaceMacros\n} 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 = (valueType: unknown): 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: unknown\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: AnyObject\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 let label = this.getLabelWithMacrosReplaced();\n if (label.length > 0) {\n text = replaceMacros([{ macro: /\\(?_VALUE_\\)?/i, value: text }], label);\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","var pi = Math.PI,\n tau = 2 * pi,\n epsilon = 1e-6,\n tauEpsilon = tau - epsilon;\n\nfunction Path() {\n this._x0 = this._y0 = // start of current subpath\n this._x1 = this._y1 = null; // end of current subpath\n this._ = \"\";\n}\n\nfunction path() {\n return new Path;\n}\n\nPath.prototype = path.prototype = {\n constructor: Path,\n moveTo: function(x, y) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y);\n },\n closePath: function() {\n if (this._x1 !== null) {\n this._x1 = this._x0, this._y1 = this._y0;\n this._ += \"Z\";\n }\n },\n lineTo: function(x, y) {\n this._ += \"L\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n quadraticCurveTo: function(x1, y1, x, y) {\n this._ += \"Q\" + (+x1) + \",\" + (+y1) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) {\n this._ += \"C\" + (+x1) + \",\" + (+y1) + \",\" + (+x2) + \",\" + (+y2) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n arcTo: function(x1, y1, x2, y2, r) {\n x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;\n var x0 = this._x1,\n y0 = this._y1,\n x21 = x2 - x1,\n y21 = y2 - y1,\n x01 = x0 - x1,\n y01 = y0 - y1,\n l01_2 = x01 * x01 + y01 * y01;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x1,y1).\n if (this._x1 === null) {\n this._ += \"M\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.\n else if (!(l01_2 > epsilon));\n\n // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?\n // Equivalently, is (x1,y1) coincident with (x2,y2)?\n // Or, is the radius zero? Line to (x1,y1).\n else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {\n this._ += \"L\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Otherwise, draw an arc!\n else {\n var x20 = x2 - x0,\n y20 = y2 - y0,\n l21_2 = x21 * x21 + y21 * y21,\n l20_2 = x20 * x20 + y20 * y20,\n l21 = Math.sqrt(l21_2),\n l01 = Math.sqrt(l01_2),\n l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),\n t01 = l / l01,\n t21 = l / l21;\n\n // If the start tangent is not coincident with (x0,y0), line to.\n if (Math.abs(t01 - 1) > epsilon) {\n this._ += \"L\" + (x1 + t01 * x01) + \",\" + (y1 + t01 * y01);\n }\n\n this._ += \"A\" + r + \",\" + r + \",0,0,\" + (+(y01 * x20 > x01 * y20)) + \",\" + (this._x1 = x1 + t21 * x21) + \",\" + (this._y1 = y1 + t21 * y21);\n }\n },\n arc: function(x, y, r, a0, a1, ccw) {\n x = +x, y = +y, r = +r;\n var dx = r * Math.cos(a0),\n dy = r * Math.sin(a0),\n x0 = x + dx,\n y0 = y + dy,\n cw = 1 ^ ccw,\n da = ccw ? a0 - a1 : a1 - a0;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x0,y0).\n if (this._x1 === null) {\n this._ += \"M\" + x0 + \",\" + y0;\n }\n\n // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).\n else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {\n this._ += \"L\" + x0 + \",\" + y0;\n }\n\n // Is this arc empty? We’re done.\n if (!r) return;\n\n // Does the angle go the wrong way? Flip the direction.\n if (da < 0) da = da % tau + tau;\n\n // Is this a complete circle? Draw two arcs to complete the circle.\n if (da > tauEpsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (x - dx) + \",\" + (y - dy) + \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (this._x1 = x0) + \",\" + (this._y1 = y0);\n }\n\n // Is this arc non-empty? Draw an arc!\n else if (da > epsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,\" + (+(da >= pi)) + \",\" + cw + \",\" + (this._x1 = x + r * Math.cos(a1)) + \",\" + (this._y1 = y + r * Math.sin(a1));\n }\n },\n rect: function(x, y, w, h) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y) + \"h\" + (+w) + \"v\" + (+h) + \"h\" + (-w) + \"Z\";\n },\n toString: function() {\n return this._;\n }\n};\n\nexport default path;\n","export default function(x) {\n return function constant() {\n return x;\n };\n}\n","export var abs = Math.abs;\nexport var atan2 = Math.atan2;\nexport var cos = Math.cos;\nexport var max = Math.max;\nexport var min = Math.min;\nexport var sin = Math.sin;\nexport var sqrt = Math.sqrt;\n\nexport var epsilon = 1e-12;\nexport var pi = Math.PI;\nexport var halfPi = pi / 2;\nexport var tau = 2 * pi;\n\nexport function acos(x) {\n return x > 1 ? 0 : x < -1 ? pi : Math.acos(x);\n}\n\nexport function asin(x) {\n return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x);\n}\n","import {path} from \"d3-path\";\nimport constant from \"./constant\";\nimport {abs, acos, asin, atan2, cos, epsilon, halfPi, max, min, pi, sin, sqrt, tau} from \"./math\";\n\nfunction arcInnerRadius(d) {\n return d.innerRadius;\n}\n\nfunction arcOuterRadius(d) {\n return d.outerRadius;\n}\n\nfunction arcStartAngle(d) {\n return d.startAngle;\n}\n\nfunction arcEndAngle(d) {\n return d.endAngle;\n}\n\nfunction arcPadAngle(d) {\n return d && d.padAngle; // Note: optional!\n}\n\nfunction intersect(x0, y0, x1, y1, x2, y2, x3, y3) {\n var x10 = x1 - x0, y10 = y1 - y0,\n x32 = x3 - x2, y32 = y3 - y2,\n t = y32 * x10 - x32 * y10;\n if (t * t < epsilon) return;\n t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / t;\n return [x0 + t * x10, y0 + t * y10];\n}\n\n// Compute perpendicular offset line of length rc.\n// http://mathworld.wolfram.com/Circle-LineIntersection.html\nfunction cornerTangents(x0, y0, x1, y1, r1, rc, cw) {\n var x01 = x0 - x1,\n y01 = y0 - y1,\n lo = (cw ? rc : -rc) / sqrt(x01 * x01 + y01 * y01),\n ox = lo * y01,\n oy = -lo * x01,\n x11 = x0 + ox,\n y11 = y0 + oy,\n x10 = x1 + ox,\n y10 = y1 + oy,\n x00 = (x11 + x10) / 2,\n y00 = (y11 + y10) / 2,\n dx = x10 - x11,\n dy = y10 - y11,\n d2 = dx * dx + dy * dy,\n r = r1 - rc,\n D = x11 * y10 - x10 * y11,\n d = (dy < 0 ? -1 : 1) * sqrt(max(0, r * r * d2 - D * D)),\n cx0 = (D * dy - dx * d) / d2,\n cy0 = (-D * dx - dy * d) / d2,\n cx1 = (D * dy + dx * d) / d2,\n cy1 = (-D * dx + dy * d) / d2,\n dx0 = cx0 - x00,\n dy0 = cy0 - y00,\n dx1 = cx1 - x00,\n dy1 = cy1 - y00;\n\n // Pick the closer of the two intersection points.\n // TODO Is there a faster way to determine which intersection to use?\n if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;\n\n return {\n cx: cx0,\n cy: cy0,\n x01: -ox,\n y01: -oy,\n x11: cx0 * (r1 / r - 1),\n y11: cy0 * (r1 / r - 1)\n };\n}\n\nexport default function() {\n var innerRadius = arcInnerRadius,\n outerRadius = arcOuterRadius,\n cornerRadius = constant(0),\n padRadius = null,\n startAngle = arcStartAngle,\n endAngle = arcEndAngle,\n padAngle = arcPadAngle,\n context = null;\n\n function arc() {\n var buffer,\n r,\n r0 = +innerRadius.apply(this, arguments),\n r1 = +outerRadius.apply(this, arguments),\n a0 = startAngle.apply(this, arguments) - halfPi,\n a1 = endAngle.apply(this, arguments) - halfPi,\n da = abs(a1 - a0),\n cw = a1 > a0;\n\n if (!context) context = buffer = path();\n\n // Ensure that the outer radius is always larger than the inner radius.\n if (r1 < r0) r = r1, r1 = r0, r0 = r;\n\n // Is it a point?\n if (!(r1 > epsilon)) context.moveTo(0, 0);\n\n // Or is it a circle or annulus?\n else if (da > tau - epsilon) {\n context.moveTo(r1 * cos(a0), r1 * sin(a0));\n context.arc(0, 0, r1, a0, a1, !cw);\n if (r0 > epsilon) {\n context.moveTo(r0 * cos(a1), r0 * sin(a1));\n context.arc(0, 0, r0, a1, a0, cw);\n }\n }\n\n // Or is it a circular or annular sector?\n else {\n var a01 = a0,\n a11 = a1,\n a00 = a0,\n a10 = a1,\n da0 = da,\n da1 = da,\n ap = padAngle.apply(this, arguments) / 2,\n rp = (ap > epsilon) && (padRadius ? +padRadius.apply(this, arguments) : sqrt(r0 * r0 + r1 * r1)),\n rc = min(abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),\n rc0 = rc,\n rc1 = rc,\n t0,\n t1;\n\n // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.\n if (rp > epsilon) {\n var p0 = asin(rp / r0 * sin(ap)),\n p1 = asin(rp / r1 * sin(ap));\n if ((da0 -= p0 * 2) > epsilon) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;\n else da0 = 0, a00 = a10 = (a0 + a1) / 2;\n if ((da1 -= p1 * 2) > epsilon) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;\n else da1 = 0, a01 = a11 = (a0 + a1) / 2;\n }\n\n var x01 = r1 * cos(a01),\n y01 = r1 * sin(a01),\n x10 = r0 * cos(a10),\n y10 = r0 * sin(a10);\n\n // Apply rounded corners?\n if (rc > epsilon) {\n var x11 = r1 * cos(a11),\n y11 = r1 * sin(a11),\n x00 = r0 * cos(a00),\n y00 = r0 * sin(a00),\n oc;\n\n // Restrict the corner radius according to the sector angle.\n if (da < pi && (oc = intersect(x01, y01, x00, y00, x11, y11, x10, y10))) {\n var ax = x01 - oc[0],\n ay = y01 - oc[1],\n bx = x11 - oc[0],\n by = y11 - oc[1],\n kc = 1 / sin(acos((ax * bx + ay * by) / (sqrt(ax * ax + ay * ay) * sqrt(bx * bx + by * by))) / 2),\n lc = sqrt(oc[0] * oc[0] + oc[1] * oc[1]);\n rc0 = min(rc, (r0 - lc) / (kc - 1));\n rc1 = min(rc, (r1 - lc) / (kc + 1));\n }\n }\n\n // Is the sector collapsed to a line?\n if (!(da1 > epsilon)) context.moveTo(x01, y01);\n\n // Does the sector’s outer ring have rounded corners?\n else if (rc1 > epsilon) {\n t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);\n t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);\n\n context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);\n\n // Have the corners merged?\n if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);\n\n // Otherwise, draw the two corners and the ring.\n else {\n context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);\n context.arc(0, 0, r1, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw);\n context.arc(t1.cx, t1.cy, rc1, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);\n }\n }\n\n // Or is the outer ring just a circular arc?\n else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);\n\n // Is there no inner ring, and it’s a circular sector?\n // Or perhaps it’s an annular sector collapsed due to padding?\n if (!(r0 > epsilon) || !(da0 > epsilon)) context.lineTo(x10, y10);\n\n // Does the sector’s inner ring (or point) have rounded corners?\n else if (rc0 > epsilon) {\n t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);\n t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);\n\n context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);\n\n // Have the corners merged?\n if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);\n\n // Otherwise, draw the two corners and the ring.\n else {\n context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);\n context.arc(0, 0, r0, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw);\n context.arc(t1.cx, t1.cy, rc0, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);\n }\n }\n\n // Or is the inner ring just a circular arc?\n else context.arc(0, 0, r0, a10, a00, cw);\n }\n\n context.closePath();\n\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n arc.centroid = function() {\n var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,\n a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi / 2;\n return [cos(a) * r, sin(a) * r];\n };\n\n arc.innerRadius = function(_) {\n return arguments.length ? (innerRadius = typeof _ === \"function\" ? _ : constant(+_), arc) : innerRadius;\n };\n\n arc.outerRadius = function(_) {\n return arguments.length ? (outerRadius = typeof _ === \"function\" ? _ : constant(+_), arc) : outerRadius;\n };\n\n arc.cornerRadius = function(_) {\n return arguments.length ? (cornerRadius = typeof _ === \"function\" ? _ : constant(+_), arc) : cornerRadius;\n };\n\n arc.padRadius = function(_) {\n return arguments.length ? (padRadius = _ == null ? null : typeof _ === \"function\" ? _ : constant(+_), arc) : padRadius;\n };\n\n arc.startAngle = function(_) {\n return arguments.length ? (startAngle = typeof _ === \"function\" ? _ : constant(+_), arc) : startAngle;\n };\n\n arc.endAngle = function(_) {\n return arguments.length ? (endAngle = typeof _ === \"function\" ? _ : constant(+_), arc) : endAngle;\n };\n\n arc.padAngle = function(_) {\n return arguments.length ? (padAngle = typeof _ === \"function\" ? _ : constant(+_), arc) : padAngle;\n };\n\n arc.context = function(_) {\n return arguments.length ? ((context = _ == null ? null : _), arc) : context;\n };\n\n return arc;\n}\n","function Linear(context) {\n this._context = context;\n}\n\nLinear.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; // proceed\n default: this._context.lineTo(x, y); break;\n }\n }\n};\n\nexport default function(context) {\n return new Linear(context);\n}\n","import curveLinear from \"./linear\";\n\nexport var curveRadialLinear = curveRadial(curveLinear);\n\nfunction Radial(curve) {\n this._curve = curve;\n}\n\nRadial.prototype = {\n areaStart: function() {\n this._curve.areaStart();\n },\n areaEnd: function() {\n this._curve.areaEnd();\n },\n lineStart: function() {\n this._curve.lineStart();\n },\n lineEnd: function() {\n this._curve.lineEnd();\n },\n point: function(a, r) {\n this._curve.point(r * Math.sin(a), r * -Math.cos(a));\n }\n};\n\nexport default function curveRadial(curve) {\n\n function radial(context) {\n return new Radial(curve(context));\n }\n\n radial._curve = curve;\n\n return radial;\n}\n","export var slice = Array.prototype.slice;\n","var tan30 = Math.sqrt(1 / 3),\n tan30_2 = tan30 * 2;\n\nexport default {\n draw: function(context, size) {\n var y = Math.sqrt(size / tan30_2),\n x = y * tan30;\n context.moveTo(0, -y);\n context.lineTo(x, 0);\n context.lineTo(0, y);\n context.lineTo(-x, 0);\n context.closePath();\n }\n};\n","import {pi, tau} from \"../math\";\n\nexport default {\n draw: function(context, size) {\n var r = Math.sqrt(size / pi);\n context.moveTo(r, 0);\n context.arc(0, 0, r, 0, tau);\n }\n};\n","import {pi, tau} from \"../math\";\n\nvar ka = 0.89081309152928522810,\n kr = Math.sin(pi / 10) / Math.sin(7 * pi / 10),\n kx = Math.sin(tau / 10) * kr,\n ky = -Math.cos(tau / 10) * kr;\n\nexport default {\n draw: function(context, size) {\n var r = Math.sqrt(size * ka),\n x = kx * r,\n y = ky * r;\n context.moveTo(0, -r);\n context.lineTo(x, y);\n for (var i = 1; i < 5; ++i) {\n var a = tau * i / 5,\n c = Math.cos(a),\n s = Math.sin(a);\n context.lineTo(s * r, -c * r);\n context.lineTo(c * x - s * y, s * x + c * y);\n }\n context.closePath();\n }\n};\n","export default function() {}\n","var sqrt3 = Math.sqrt(3);\n\nexport default {\n draw: function(context, size) {\n var y = -Math.sqrt(size / (sqrt3 * 3));\n context.moveTo(0, y * 2);\n context.lineTo(-sqrt3 * y, -y);\n context.lineTo(sqrt3 * y, -y);\n context.closePath();\n }\n};\n","var c = -0.5,\n s = Math.sqrt(3) / 2,\n k = 1 / Math.sqrt(12),\n a = (k / 2 + 1) * 3;\n\nexport default {\n draw: function(context, size) {\n var r = Math.sqrt(size / a),\n x0 = r / 2,\n y0 = r * k,\n x1 = x0,\n y1 = r * k + r,\n x2 = -x1,\n y2 = y1;\n context.moveTo(x0, y0);\n context.lineTo(x1, y1);\n context.lineTo(x2, y2);\n context.lineTo(c * x0 - s * y0, s * x0 + c * y0);\n context.lineTo(c * x1 - s * y1, s * x1 + c * y1);\n context.lineTo(c * x2 - s * y2, s * x2 + c * y2);\n context.lineTo(c * x0 + s * y0, c * y0 - s * x0);\n context.lineTo(c * x1 + s * y1, c * y1 - s * x1);\n context.lineTo(c * x2 + s * y2, c * y2 - s * x2);\n context.closePath();\n }\n};\n","export function point(that, x, y) {\n that._context.bezierCurveTo(\n (2 * that._x0 + that._x1) / 3,\n (2 * that._y0 + that._y1) / 3,\n (that._x0 + 2 * that._x1) / 3,\n (that._y0 + 2 * that._y1) / 3,\n (that._x0 + 4 * that._x1 + x) / 6,\n (that._y0 + 4 * that._y1 + y) / 6\n );\n}\n\nexport function Basis(context) {\n this._context = context;\n}\n\nBasis.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 3: point(this, this._x1, this._y1); // proceed\n case 2: this._context.lineTo(this._x1, this._y1); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nexport default function(context) {\n return new Basis(context);\n}\n","import noop from \"../noop\";\nimport {point} from \"./basis\";\n\nfunction BasisClosed(context) {\n this._context = context;\n}\n\nBasisClosed.prototype = {\n areaStart: noop,\n areaEnd: noop,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x2, this._y2);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);\n this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x2, this._y2);\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._x2 = x, this._y2 = y; break;\n case 1: this._point = 2; this._x3 = x, this._y3 = y; break;\n case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break;\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nexport default function(context) {\n return new BasisClosed(context);\n}\n","import {point} from \"./basis\";\n\nfunction BasisOpen(context) {\n this._context = context;\n}\n\nBasisOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break;\n case 3: this._point = 4; // proceed\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nexport default function(context) {\n return new BasisOpen(context);\n}\n","import {Basis} from \"./basis\";\n\nfunction Bundle(context, beta) {\n this._basis = new Basis(context);\n this._beta = beta;\n}\n\nBundle.prototype = {\n lineStart: function() {\n this._x = [];\n this._y = [];\n this._basis.lineStart();\n },\n lineEnd: function() {\n var x = this._x,\n y = this._y,\n j = x.length - 1;\n\n if (j > 0) {\n var x0 = x[0],\n y0 = y[0],\n dx = x[j] - x0,\n dy = y[j] - y0,\n i = -1,\n t;\n\n while (++i <= j) {\n t = i / j;\n this._basis.point(\n this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),\n this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)\n );\n }\n }\n\n this._x = this._y = null;\n this._basis.lineEnd();\n },\n point: function(x, y) {\n this._x.push(+x);\n this._y.push(+y);\n }\n};\n\nexport default (function custom(beta) {\n\n function bundle(context) {\n return beta === 1 ? new Basis(context) : new Bundle(context, beta);\n }\n\n bundle.beta = function(beta) {\n return custom(+beta);\n };\n\n return bundle;\n})(0.85);\n","export function point(that, x, y) {\n that._context.bezierCurveTo(\n that._x1 + that._k * (that._x2 - that._x0),\n that._y1 + that._k * (that._y2 - that._y0),\n that._x2 + that._k * (that._x1 - x),\n that._y2 + that._k * (that._y1 - y),\n that._x2,\n that._y2\n );\n}\n\nexport function Cardinal(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinal.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x2, this._y2); break;\n case 3: point(this, this._x1, this._y1); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; this._x1 = x, this._y1 = y; break;\n case 2: this._point = 3; // proceed\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(tension) {\n\n function cardinal(context) {\n return new Cardinal(context, tension);\n }\n\n cardinal.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal;\n})(0);\n","import noop from \"../noop\";\nimport {point} from \"./cardinal\";\n\nexport function CardinalClosed(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinalClosed.prototype = {\n areaStart: noop,\n areaEnd: noop,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.lineTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n this.point(this._x5, this._y5);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._x3 = x, this._y3 = y; break;\n case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;\n case 2: this._point = 3; this._x5 = x, this._y5 = y; break;\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(tension) {\n\n function cardinal(context) {\n return new CardinalClosed(context, tension);\n }\n\n cardinal.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal;\n})(0);\n","import {point} from \"./cardinal\";\n\nexport function CardinalOpen(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinalOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;\n case 3: this._point = 4; // proceed\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(tension) {\n\n function cardinal(context) {\n return new CardinalOpen(context, tension);\n }\n\n cardinal.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal;\n})(0);\n","import {epsilon} from \"../math\";\nimport {Cardinal} from \"./cardinal\";\n\nexport function point(that, x, y) {\n var x1 = that._x1,\n y1 = that._y1,\n x2 = that._x2,\n y2 = that._y2;\n\n if (that._l01_a > epsilon) {\n var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,\n n = 3 * that._l01_a * (that._l01_a + that._l12_a);\n x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;\n y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;\n }\n\n if (that._l23_a > epsilon) {\n var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,\n m = 3 * that._l23_a * (that._l23_a + that._l12_a);\n x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;\n y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;\n }\n\n that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);\n}\n\nfunction CatmullRom(context, alpha) {\n this._context = context;\n this._alpha = alpha;\n}\n\nCatmullRom.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._l01_a = this._l12_a = this._l23_a =\n this._l01_2a = this._l12_2a = this._l23_2a =\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x2, this._y2); break;\n case 3: this.point(this._x2, this._y2); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n\n if (this._point) {\n var x23 = this._x2 - x,\n y23 = this._y2 - y;\n this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n }\n\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; // proceed\n default: point(this, x, y); break;\n }\n\n this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(alpha) {\n\n function catmullRom(context) {\n return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0);\n }\n\n catmullRom.alpha = function(alpha) {\n return custom(+alpha);\n };\n\n return catmullRom;\n})(0.5);\n","import {CardinalClosed} from \"./cardinalClosed\";\nimport noop from \"../noop\";\nimport {point} from \"./catmullRom\";\n\nfunction CatmullRomClosed(context, alpha) {\n this._context = context;\n this._alpha = alpha;\n}\n\nCatmullRomClosed.prototype = {\n areaStart: noop,\n areaEnd: noop,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;\n this._l01_a = this._l12_a = this._l23_a =\n this._l01_2a = this._l12_2a = this._l23_2a =\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.lineTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n this.point(this._x5, this._y5);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n\n if (this._point) {\n var x23 = this._x2 - x,\n y23 = this._y2 - y;\n this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n }\n\n switch (this._point) {\n case 0: this._point = 1; this._x3 = x, this._y3 = y; break;\n case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;\n case 2: this._point = 3; this._x5 = x, this._y5 = y; break;\n default: point(this, x, y); break;\n }\n\n this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(alpha) {\n\n function catmullRom(context) {\n return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);\n }\n\n catmullRom.alpha = function(alpha) {\n return custom(+alpha);\n };\n\n return catmullRom;\n})(0.5);\n","import {CardinalOpen} from \"./cardinalOpen\";\nimport {point} from \"./catmullRom\";\n\nfunction CatmullRomOpen(context, alpha) {\n this._context = context;\n this._alpha = alpha;\n}\n\nCatmullRomOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._l01_a = this._l12_a = this._l23_a =\n this._l01_2a = this._l12_2a = this._l23_2a =\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n\n if (this._point) {\n var x23 = this._x2 - x,\n y23 = this._y2 - y;\n this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n }\n\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;\n case 3: this._point = 4; // proceed\n default: point(this, x, y); break;\n }\n\n this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(alpha) {\n\n function catmullRom(context) {\n return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);\n }\n\n catmullRom.alpha = function(alpha) {\n return custom(+alpha);\n };\n\n return catmullRom;\n})(0.5);\n","import noop from \"../noop\";\n\nfunction LinearClosed(context) {\n this._context = context;\n}\n\nLinearClosed.prototype = {\n areaStart: noop,\n areaEnd: noop,\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._point) this._context.closePath();\n },\n point: function(x, y) {\n x = +x, y = +y;\n if (this._point) this._context.lineTo(x, y);\n else this._point = 1, this._context.moveTo(x, y);\n }\n};\n\nexport default function(context) {\n return new LinearClosed(context);\n}\n","function sign(x) {\n return x < 0 ? -1 : 1;\n}\n\n// Calculate the slopes of the tangents (Hermite-type interpolation) based on\n// the following paper: Steffen, M. 1990. A Simple Method for Monotonic\n// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.\n// NOV(II), P. 443, 1990.\nfunction slope3(that, x2, y2) {\n var h0 = that._x1 - that._x0,\n h1 = x2 - that._x1,\n s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),\n s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),\n p = (s0 * h1 + s1 * h0) / (h0 + h1);\n return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;\n}\n\n// Calculate a one-sided slope.\nfunction slope2(that, t) {\n var h = that._x1 - that._x0;\n return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;\n}\n\n// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations\n// \"you can express cubic Hermite interpolation in terms of cubic Bézier curves\n// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1\".\nfunction point(that, t0, t1) {\n var x0 = that._x0,\n y0 = that._y0,\n x1 = that._x1,\n y1 = that._y1,\n dx = (x1 - x0) / 3;\n that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);\n}\n\nfunction MonotoneX(context) {\n this._context = context;\n}\n\nMonotoneX.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 =\n this._t0 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x1, this._y1); break;\n case 3: point(this, this._t0, slope2(this, this._t0)); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n var t1 = NaN;\n\n x = +x, y = +y;\n if (x === this._x1 && y === this._y1) return; // Ignore coincident points.\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; point(this, slope2(this, t1 = slope3(this, x, y)), t1); break;\n default: point(this, this._t0, t1 = slope3(this, x, y)); break;\n }\n\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n this._t0 = t1;\n }\n}\n\nfunction MonotoneY(context) {\n this._context = new ReflectContext(context);\n}\n\n(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {\n MonotoneX.prototype.point.call(this, y, x);\n};\n\nfunction ReflectContext(context) {\n this._context = context;\n}\n\nReflectContext.prototype = {\n moveTo: function(x, y) { this._context.moveTo(y, x); },\n closePath: function() { this._context.closePath(); },\n lineTo: function(x, y) { this._context.lineTo(y, x); },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }\n};\n\nexport function monotoneX(context) {\n return new MonotoneX(context);\n}\n\nexport function monotoneY(context) {\n return new MonotoneY(context);\n}\n","function Natural(context) {\n this._context = context;\n}\n\nNatural.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x = [];\n this._y = [];\n },\n lineEnd: function() {\n var x = this._x,\n y = this._y,\n n = x.length;\n\n if (n) {\n this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);\n if (n === 2) {\n this._context.lineTo(x[1], y[1]);\n } else {\n var px = controlPoints(x),\n py = controlPoints(y);\n for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {\n this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);\n }\n }\n }\n\n if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();\n this._line = 1 - this._line;\n this._x = this._y = null;\n },\n point: function(x, y) {\n this._x.push(+x);\n this._y.push(+y);\n }\n};\n\n// See https://www.particleincell.com/2012/bezier-splines/ for derivation.\nfunction controlPoints(x) {\n var i,\n n = x.length - 1,\n m,\n a = new Array(n),\n b = new Array(n),\n r = new Array(n);\n a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];\n for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];\n a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];\n for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];\n a[n - 1] = r[n - 1] / b[n - 1];\n for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];\n b[n - 1] = (x[n] + a[n - 1]) / 2;\n for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];\n return [a, b];\n}\n\nexport default function(context) {\n return new Natural(context);\n}\n","function Step(context, t) {\n this._context = context;\n this._t = t;\n}\n\nStep.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x = this._y = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; // proceed\n default: {\n if (this._t <= 0) {\n this._context.lineTo(this._x, y);\n this._context.lineTo(x, y);\n } else {\n var x1 = this._x * (1 - this._t) + x * this._t;\n this._context.lineTo(x1, this._y);\n this._context.lineTo(x1, y);\n }\n break;\n }\n }\n this._x = x, this._y = y;\n }\n};\n\nexport default function(context) {\n return new Step(context, 0.5);\n}\n\nexport function stepBefore(context) {\n return new Step(context, 0);\n}\n\nexport function stepAfter(context) {\n return new Step(context, 1);\n}\n","import ascending from \"./ascending\";\n\nexport default function(series) {\n return ascending(series).reverse();\n}\n","import { arc as arcFactory } from \"d3-shape\";\n\nimport {\n LinkedVisualConsoleProps,\n AnyObject,\n WithModuleProps\n} from \"../lib/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 */\nfunction extractPercentileType(\n type: unknown\n): 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 */\nfunction extractValueType(valueType: unknown): 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: AnyObject\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 var formatValue;\n if (this.props.value != null) {\n if (Intl) {\n formatValue = Intl.NumberFormat(\"en-EN\").format(this.props.value);\n } else {\n formatValue = this.props.value;\n }\n }\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.style.fontSize = \"6pt\";\n\n text.textContent = this.props.unit\n ? `${formatValue} ${this.props.unit}`\n : `${formatValue}`;\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\":\n case \"circular-progress-bar-alt\":\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\n if (this.props.percentileType === \"bubble\") {\n // Create and append the circles.\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\n svg.append(backgroundCircle, progressCircle);\n } else {\n // Create and append the circles.\n const arcProps = {\n innerRadius:\n this.props.percentileType === \"circular-progress-bar\" ? 30 : 0,\n outerRadius: 50,\n startAngle: 0,\n endAngle: Math.PI * 2\n };\n const arc = arcFactory();\n\n const backgroundCircle = document.createElementNS(svgNS, \"path\");\n backgroundCircle.setAttribute(\"transform\", \"translate(50 50)\");\n backgroundCircle.setAttribute(\"fill\", colors.background);\n backgroundCircle.setAttribute(\"fill-opacity\", \"0.5\");\n backgroundCircle.setAttribute(\"d\", `${arc(arcProps)}`);\n const progressCircle = document.createElementNS(svgNS, \"path\");\n progressCircle.setAttribute(\"transform\", \"translate(50 50)\");\n progressCircle.setAttribute(\"fill\", colors.progress);\n progressCircle.setAttribute(\"fill-opacity\", \"1\");\n progressCircle.setAttribute(\n \"d\",\n `${arc({\n ...arcProps,\n endAngle: arcProps.endAngle * (progress / 100)\n })}`\n );\n\n svg.append(backgroundCircle, progressCircle);\n }\n\n // Create and append the text.\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\" && this.props.value != null) {\n // Show value and unit in 1 (no unit) or 2 lines.\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 = `${formatValue}`;\n value.style.fontSize = \"8pt\";\n const unit = document.createElementNS(svgNS, \"tspan\");\n unit.setAttribute(\"x\", \"0\");\n unit.setAttribute(\"dy\", \"1em\");\n unit.textContent = `${this.props.unit}`;\n unit.style.fontSize = \"8pt\";\n text.append(value, unit);\n text.setAttribute(\"transform\", \"translate(50 33)\");\n } else {\n text.textContent = `${formatValue}`;\n text.style.fontSize = \"8pt\";\n text.setAttribute(\"transform\", \"translate(50 50)\");\n }\n } else {\n // Percentage.\n text.textContent = `${progress}%`;\n text.setAttribute(\"transform\", \"translate(50 50)\");\n }\n\n svg.append(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 == null ? 0 : this.props.value;\n\n if (value <= minValue) return 0;\n else if (value >= maxValue) return 100;\n else return Math.trunc(((value - minValue) / (maxValue - minValue)) * 100);\n }\n}\n","import { AnyObject } from \"../lib/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: AnyObject): 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 element = document.createElement(\"div\");\n element.className = \"service\";\n\n if (this.props.statusImageSrc !== null) {\n element.style.background = `url(${this.props.statusImageSrc}) no-repeat`;\n element.style.backgroundSize = \"contain\";\n element.style.backgroundPosition = \"center\";\n } else if (this.props.encodedTitle !== null) {\n element.innerHTML = decodeBase64(this.props.encodedTitle);\n }\n\n return element;\n }\n}\n","import { AnyObject, Size } from \"./lib/types\";\nimport {\n parseBoolean,\n sizePropsDecoder,\n parseIntOr,\n notEmptyStringOr,\n itemMetaDecoder\n} from \"./lib\";\nimport Item, {\n ItemType,\n ItemProps,\n ItemClickEvent,\n ItemRemoveEvent,\n ItemMovedEvent,\n ItemResizedEvent\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 \"./lib/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: AnyObject) {\n const type = parseIntOr(data.type, null);\n if (type == null) throw new TypeError(\"missing item type.\");\n\n const meta = itemMetaDecoder(data);\n\n switch (type as ItemType) {\n case ItemType.STATIC_GRAPH:\n return new StaticGraph(staticGraphPropsDecoder(data), meta);\n case ItemType.MODULE_GRAPH:\n return new ModuleGraph(moduleGraphPropsDecoder(data), meta);\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), meta);\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), meta);\n case ItemType.LABEL:\n return new Label(labelPropsDecoder(data), meta);\n case ItemType.ICON:\n return new Icon(iconPropsDecoder(data), meta);\n case ItemType.SERVICE:\n return new Service(servicePropsDecoder(data), meta);\n case ItemType.GROUP_ITEM:\n return new Group(groupPropsDecoder(data), meta);\n case ItemType.BOX_ITEM:\n return new Box(boxPropsDecoder(data), meta);\n case ItemType.LINE_ITEM:\n return new Line(linePropsDecoder(data), meta);\n case ItemType.AUTO_SLA_GRAPH:\n return new EventsHistory(eventsHistoryPropsDecoder(data), meta);\n case ItemType.DONUT_GRAPH:\n return new DonutGraph(donutGraphPropsDecoder(data), meta);\n case ItemType.BARS_GRAPH:\n return new BarsGraph(barsGraphPropsDecoder(data), meta);\n case ItemType.CLOCK:\n return new Clock(clockPropsDecoder(data), meta);\n case ItemType.COLOR_CLOUD:\n return new ColorCloud(colorCloudPropsDecoder(data), meta);\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: AnyObject) {\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: AnyObject\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 // Event manager for move events.\n private readonly movedEventManager = new TypedEvent();\n // Event manager for resize events.\n private readonly resizedEventManager = new TypedEvent();\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 * React to a movement on an element.\n * @param e Event object.\n */\n private handleElementMovement: (e: ItemMovedEvent) => void = e => {\n this.movedEventManager.emit(e);\n // console.log(`Moved element #${e.item.props.id}`, e);\n };\n\n /**\n * React to a resizement on an element.\n * @param e Event object.\n */\n private handleElementResizement: (e: ItemResizedEvent) => void = e => {\n this.resizedEventManager.emit(e);\n // console.log(`Resized element #${e.item.props.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: AnyObject,\n items: AnyObject[]\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.onMoved(this.handleElementMovement);\n itemInstance.onResized(this.handleElementResizement);\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: AnyObject[]): void {\n // Ensure the type cause Typescript doesn't know the filter removes null items.\n const itemIds = items\n .map(item => item.id || null)\n .filter(id => id != null) as number[];\n // Get the elements we should delete.\n const deletedIds = this.elementIds.filter(id => itemIds.indexOf(id) < 0);\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 itemMetaDecoder({\n receivedAt: new Date()\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 onItemClick(\n listener: Listener>\n ): 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 * Add an event handler to the movement of the visual console elements.\n * @param listener Function which is going to be executed when a linked console is moved.\n */\n public onItemMoved(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.movedEventManager.on(listener);\n this.disposables.push(disposable);\n\n return disposable;\n }\n\n /**\n * Add an event handler to the resizement of the visual console elements.\n * @param listener Function which is going to be executed when a linked console is moved.\n */\n public onItemResized(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.resizedEventManager.on(listener);\n this.disposables.push(disposable);\n\n return disposable;\n }\n\n /**\n * Enable the edition mode.\n */\n public enableEditMode(): void {\n this.elements.forEach(item => {\n item.meta = { ...item.meta, editMode: true };\n });\n this.containerRef.classList.add(\"is-editing\");\n }\n\n /**\n * Disable the edition mode.\n */\n public disableEditMode(): void {\n this.elements.forEach(item => {\n item.meta = { ...item.meta, editMode: false };\n });\n this.containerRef.classList.remove(\"is-editing\");\n }\n}\n","import TypedEvent, { Disposable, Listener } from \"./TypedEvent\";\n\ninterface Cancellable {\n cancel(): void;\n}\n\ntype AsyncTaskStatus = \"waiting\" | \"started\" | \"cancelled\" | \"finished\";\ntype AsyncTaskInitiator = (done: () => void) => Cancellable;\n\n/**\n * Defines an async task which can be started and cancelled.\n * It's possible to observe the status changes of the task.\n */\nclass AsyncTask {\n private readonly taskInitiator: AsyncTaskInitiator;\n private cancellable: Cancellable = { cancel: () => {} };\n private _status: AsyncTaskStatus = \"waiting\";\n\n // Event manager for status change events.\n private readonly statusChangeEventManager = new TypedEvent();\n // List of references to clean the event listeners.\n private readonly disposables: Disposable[] = [];\n\n public constructor(taskInitiator: AsyncTaskInitiator) {\n this.taskInitiator = taskInitiator;\n }\n\n /**\n * Public setter of the `status` property.\n * @param status.\n */\n public set status(status: AsyncTaskStatus) {\n this._status = status;\n this.statusChangeEventManager.emit(status);\n }\n\n /**\n * Public accessor of the `status` property.\n * @return status.\n */\n public get status() {\n return this._status;\n }\n\n /**\n * Start the async task.\n */\n public init(): void {\n this.cancellable = this.taskInitiator(() => {\n this.status = \"finished\";\n });\n this.status = \"started\";\n }\n\n /**\n * Cancel the async task.\n */\n public cancel(): void {\n this.cancellable.cancel();\n this.status = \"cancelled\";\n }\n\n /**\n * Add an event handler to the status change.\n * @param listener Function which is going to be executed when the status changes.\n */\n public onStatusChange(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.statusChangeEventManager.on(listener);\n this.disposables.push(disposable);\n\n return disposable;\n }\n}\n\n/**\n * Wrap an async task into another which will execute that task indefinitely\n * every time the tash finnish and the chosen period ends.\n * Will last until cancellation.\n *\n * @param task Async task to execute.\n * @param period Time in milliseconds to wait until the next async esecution.\n *\n * @return A new async task.\n */\nfunction asyncPeriodic(task: AsyncTask, period: number): AsyncTask {\n return new AsyncTask(() => {\n let ref: number | null = null;\n\n task.onStatusChange(status => {\n if (status === \"finished\") {\n ref = window.setTimeout(() => {\n task.init();\n }, period);\n }\n });\n\n task.init();\n\n return {\n cancel: () => {\n if (ref) clearTimeout(ref);\n task.cancel();\n }\n };\n });\n}\n\n/**\n * Manages a list of async tasks.\n */\nexport default class AsyncTaskManager {\n private tasks: { [identifier: string]: AsyncTask } = {};\n\n /**\n * Adds an async task to the manager.\n *\n * @param identifier Unique identifier.\n * @param taskInitiator Function to initialize the async task.\n * Should return a structure to cancel the task.\n * @param period Optional period to repeat the task indefinitely.\n */\n public add(\n identifier: string,\n taskInitiator: AsyncTaskInitiator,\n period: number = 0\n ): AsyncTask {\n if (this.tasks[identifier] && this.tasks[identifier].status === \"started\") {\n this.tasks[identifier].cancel();\n }\n\n const asyncTask =\n period > 0\n ? asyncPeriodic(new AsyncTask(taskInitiator), period)\n : new AsyncTask(taskInitiator);\n\n this.tasks[identifier] = asyncTask;\n\n return this.tasks[identifier];\n }\n\n /**\n * Starts an async task.\n *\n * @param identifier Unique identifier.\n */\n public init(identifier: string) {\n if (\n this.tasks[identifier] &&\n (this.tasks[identifier].status === \"waiting\" ||\n this.tasks[identifier].status === \"cancelled\" ||\n this.tasks[identifier].status === \"finished\")\n ) {\n this.tasks[identifier].init();\n }\n }\n\n /**\n * Cancel a running async task.\n *\n * @param identifier Unique identifier.\n */\n public cancel(identifier: string) {\n if (this.tasks[identifier] && this.tasks[identifier].status === \"started\") {\n this.tasks[identifier].cancel();\n }\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\";\nimport AsyncTaskManager from \"./lib/AsyncTaskManager\";\n\n// Export the VisualConsole class to the global object.\n// eslint-disable-next-line\n(window as any).VisualConsole = VisualConsole;\n\n// Export the AsyncTaskManager class to the global object.\n// eslint-disable-next-line\n(window as any).AsyncTaskManager = AsyncTaskManager;\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/lib/index.ts","webpack:///./src/Item.ts","webpack:///./src/lib/TypedEvent.ts","webpack:///./src/items/EventsHistory.ts","webpack:///./src/items/DonutGraph.ts","webpack:///./src/items/BarsGraph.ts","webpack:///./src/items/ModuleGraph.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:///./node_modules/d3-path/src/path.js","webpack:///./node_modules/d3-shape/src/constant.js","webpack:///./node_modules/d3-shape/src/math.js","webpack:///./node_modules/d3-shape/src/arc.js","webpack:///./node_modules/d3-shape/src/curve/linear.js","webpack:///./node_modules/d3-shape/src/curve/radial.js","webpack:///./node_modules/d3-shape/src/array.js","webpack:///./node_modules/d3-shape/src/symbol/diamond.js","webpack:///./node_modules/d3-shape/src/symbol/circle.js","webpack:///./node_modules/d3-shape/src/symbol/star.js","webpack:///./node_modules/d3-shape/src/noop.js","webpack:///./node_modules/d3-shape/src/symbol/triangle.js","webpack:///./node_modules/d3-shape/src/symbol/wye.js","webpack:///./node_modules/d3-shape/src/curve/basis.js","webpack:///./node_modules/d3-shape/src/curve/basisClosed.js","webpack:///./node_modules/d3-shape/src/curve/basisOpen.js","webpack:///./node_modules/d3-shape/src/curve/bundle.js","webpack:///./node_modules/d3-shape/src/curve/cardinal.js","webpack:///./node_modules/d3-shape/src/curve/cardinalClosed.js","webpack:///./node_modules/d3-shape/src/curve/cardinalOpen.js","webpack:///./node_modules/d3-shape/src/curve/catmullRom.js","webpack:///./node_modules/d3-shape/src/curve/catmullRomClosed.js","webpack:///./node_modules/d3-shape/src/curve/catmullRomOpen.js","webpack:///./node_modules/d3-shape/src/curve/linearClosed.js","webpack:///./node_modules/d3-shape/src/curve/monotone.js","webpack:///./node_modules/d3-shape/src/curve/natural.js","webpack:///./node_modules/d3-shape/src/curve/step.js","webpack:///./node_modules/d3-shape/src/order/descending.js","webpack:///./src/items/Percentile.ts","webpack:///./src/items/Service.ts","webpack:///./src/VisualConsole.ts","webpack:///./src/lib/AsyncTaskManager.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","leftPad","pad","diffLength","substr","Math","abs","substring","repeatTimes","floor","restLength","newPad","positionPropsDecoder","data","x","y","sizePropsDecoder","width","height","TypeError","modulePropsDecoder","__assign","moduleName","moduleDescription","agentProps","agentId","agent","agentName","agentAlias","agentDescription","agentAddress","metaconsoleId","agentPropsDecoder","linkedVCPropsDecoder","id","linkedLayoutId","linkedLayoutAgentId","linkedLayoutStatusProps","linkedLayoutStatusType","weight","linkedLayoutStatusTypeWeight","warningThreshold","linkedLayoutStatusTypeWarningThreshold","criticalThreshold","linkedLayoutStatusTypeCriticalThreshold","linkedLayoutBaseProps","itemMetaDecoder","receivedAt","Date","Number","getTime","error","Error","editMode","isFromCache","isFetching","isUpdating","prefixedCssRules","ruleName","ruleValue","rule","decodeBase64","input","decodeURIComponent","escape","window","atob","humanDate","date","locale","Intl","DateTimeFormat","day","month","year","format","getDate","getMonth","getFullYear","humanTime","getHours","getMinutes","getSeconds","replaceMacros","macros","text","reduce","acc","_a","macro","replace","throttle","delay","fn","last","args","_i","arguments","now","apply","debounce","timerRef","clearTimeout","setTimeout","getOffset","el","offsetLeft","offsetTop","scrollLeft","scrollTop","offsetParent","top","left","addMovementListener","element","onMoved","container","parentElement","isDraggable","draggable","lastX","lastY","lastMouseX","lastMouseY","mouseElementOffsetX","mouseElementOffsetY","containerBounds","getBoundingClientRect","containerOffset","containerTop","containerBottom","containerLeft","containerRight","elementBounds","borderWidth","getComputedStyle","borderFix","debouncedMovement","throttledMovement","handleMove","e","mouseX","pageX","mouseY","pageY","mouseDeltaX","mouseDeltaY","maxX","maxY","outOfBoundsLeft","outOfBoundsRight","outOfBoundsTop","outOfBoundsBottom","handleEnd","document","removeEventListener","body","style","userSelect","handleStart","stopPropagation","offsetX","offsetY","addEventListener","addResizementListener","onResized","resizeDraggable","createElement","className","appendChild","lastWidth","lastHeight","elementOffset","elementTop","elementLeft","debouncedResizement","throttledResizement","handleResize","remove","parseLabelPosition","labelPosition","itemBasePropsDecoder","type","label","_lib__WEBPACK_IMPORTED_MODULE_0__","isLinkEnabled","link","isOnTop","parentId","aclGroupId","VisualConsoleItem","props","metadata","_this","this","clickEventManager","_lib_TypedEvent__WEBPACK_IMPORTED_MODULE_1__","movedEventManager","resizedEventManager","removeEventManager","disposables","debouncedMovementSave","prevPosition","newPosition","positionChanged","move","emit","item","removeMovement","debouncedResizementSave","prevSize","newSize","sizeChanged","resize","removeResizement","itemProps","_metadata","elementRef","createContainerDomElement","labelElementRef","createLabelDomElement","childElementRef","createDomElement","append","resizeElement","changeLabelPosition","initMovementListener","moveElement","stopMovementListener","initResizementListener","labelWidth","labelHeight","stopResizementListener","box","href","zIndex","meta","preventDefault","nativeEvent","classList","add","getLabelWithMacrosReplaced","table","row","emptyRow1","emptyRow2","cell","innerHTML","textAlign","updateDomElement","newProps","prevProps","shouldBeUpdated","render","newMetadata","setMeta","prevMetadata","prevMeta","oldLabelHtml","newLabelHtml","attrs","attributes","nodeName","setAttributeNode","parentNode","replaceChild","forEach","disposable","dispose","ignored","position","flexDirection","tables","getElementsByTagName","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","src","eval","trim","aux","donutGraphPropsDecoder","DonutGraph","barsGraphPropsDecoder","BarsGraph","moduleGraphPropsDecoder","ModuleGraph","legendP","margin","overviewGraphs","getElementsByClassName","parseShowLastValueTooltip","showLastValueTooltip","staticGraphPropsDecoder","imageSrc","Item","statusImageSrc","lib","lastValue","StaticGraph","imgSrc","background","backgroundSize","backgroundPosition","setAttribute","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","showStatistics","extractHtml","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","getElementSize","newWidth","newHeight","createAnalogicClock","createDigitalClock","svgNS","colors","dateFontSize","baseTimeFontSize","div","clockFace","clockFaceBackground","city","getHumanTimezone","timezoneComplication","textContent","marksGroup","mainMarkGroup","mark1a","mark1b","mark","hourHand","hourHandA","hourHandB","minuteHand","minuteHandA","minuteHandB","minuteHandPin","secondHand","secondHandBar","secondHandPin","pin","getOriginDate","seconds","minutes","secAngle","minuteAngle","hourAngle","join","dateElem","fontSize","tzFontSizeMultiplier","timeFontSize","tzFontSize","min","timeElem","tzElem","initialDate","targetTZOffset","localTZOffset","getTimezoneOffset","utimestamp","timezone","_b","split","diameter","boxPropsDecoder","Box_assign","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","img","pi","PI","tau","tauEpsilon","Path","_x0","_y0","_x1","_y1","_","path","constructor","moveTo","closePath","lineTo","quadraticCurveTo","x1","y1","bezierCurveTo","x2","y2","arcTo","x0","y0","x21","y21","x01","y01","l01_2","x20","y20","l21_2","l20_2","l21","sqrt","l01","tan","acos","t01","t21","arc","a0","a1","ccw","dx","cos","dy","sin","cw","da","rect","w","h","src_path","constant","atan2","max","math_epsilon","math_pi","halfPi","math_tau","asin","arcInnerRadius","innerRadius","arcOuterRadius","outerRadius","arcStartAngle","startAngle","arcEndAngle","endAngle","arcPadAngle","padAngle","cornerTangents","r1","rc","lo","ox","oy","x11","y11","x10","y10","x00","y00","d2","D","cx0","cy0","cx1","cy1","dx0","dy0","dx1","dy1","cx","cy","src_arc","cornerRadius","padRadius","context","buffer","r0","t0","t1","a01","a11","a00","a10","da0","da1","ap","rp","rc0","rc1","p0","p1","oc","x3","y3","x32","y32","intersect","ax","ay","bx","by","kc","lc","centroid","a","Linear","_context","areaStart","_line","areaEnd","NaN","lineStart","_point","lineEnd","point","linear","curveRadial","Radial","curve","_curve","radial","Array","slice","kr","noop","that","Basis","BasisClosed","_x2","_x3","_x4","_y2","_y3","_y4","BasisOpen","Bundle","beta","_basis","_beta","_x","_y","j","custom","bundle","cardinal_point","_k","Cardinal","tension","cardinal","CardinalClosed","_x5","_y5","CardinalOpen","catmullRom_point","_l01_a","_l01_2a","_l12_a","_l12_2a","_l23_a","b","_l23_2a","CatmullRom","alpha","_alpha","x23","y23","pow","catmullRom","CatmullRomClosed","CatmullRomOpen","LinearClosed","sign","slope3","h0","h1","s0","s1","slope2","monotone_point","MonotoneX","MonotoneY","ReflectContext","Natural","controlPoints","_t0","px","py","i0","i1","Step","_t","extractPercentileType","extractValueType","percentilePropsDecoder","Percentile_assign","percentileType","minValue","maxValue","labelColor","unit","Percentile_svgNS","Percentile","Percentile_extends","formatValue","progress","getProgress","NumberFormat","backgroundRect","progressRect","backgroundCircle","progressCircle","arcProps","trunc","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","handleElementMovement","handleElementResizement","handleElementRemove","filter","clearRelations","containerRef","_props","backgroundURL","isFavorite","relationLineWidth","VisualConsole_assign","visualConsolePropsDecoder","sort","itemInstance","console","log","message","buildRelations","map","updateElements","itemIds","decodeProps","backgroundImage","elements","parent_1","child","addRelationLine","itemId","ids","childId","getRelationLine","identifier","parent","clientWidth","clientHeight","onItemClick","onItemMoved","onItemResized","enableEditMode","disableEditMode","AsyncTaskManager_AsyncTask","AsyncTask","taskInitiator","cancellable","cancel","_status","statusChangeEventManager","status","init","onStatusChange","AsyncTaskManager","tasks","asyncTask","task","ref","asyncPeriodic","src_VisualConsole","lib_AsyncTaskManager"],"mappings":"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","file":"vc.main.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 AnyObject,\n Position,\n Size,\n WithAgentProps,\n WithModuleProps,\n LinkedVisualConsoleProps,\n LinkedVisualConsolePropsStatus,\n UnknownObject,\n ItemMeta\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 */\nexport function parseIntOr(value: unknown, 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 */\nexport function parseFloatOr(value: unknown, 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 */\nexport function notEmptyStringOr(\n value: unknown,\n defaultValue: T\n): 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 */\nexport function parseBoolean(value: unknown): 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 * Return a valid date or a default value from a raw value.\n * @param value Raw value from which we will try to extract a valid date.\n * @param defaultValue Default value to use if we cannot extract a valid date.\n * @return A valid date or the default value.\n */\nexport function parseDateOr(value: unknown, defaultValue: T): Date | T {\n if (value instanceof Date) return value;\n else if (typeof value === \"number\") return new Date(value * 1000);\n else if (\n typeof value === \"string\" &&\n !Number.isNaN(new Date(value).getTime())\n )\n return new Date(value);\n else return defaultValue;\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 leftPad(\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: AnyObject): 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: AnyObject): 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: AnyObject): WithAgentProps {\n const agentProps: WithAgentProps = {\n agentId: parseIntOr(data.agent, null),\n agentName: notEmptyStringOr(data.agentName, null),\n agentAlias: notEmptyStringOr(data.agentAlias, null),\n agentDescription: notEmptyStringOr(data.agentDescription, null),\n agentAddress: notEmptyStringOr(data.agentAddress, null)\n };\n\n return data.metaconsoleId != null\n ? {\n metaconsoleId: data.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: AnyObject): WithModuleProps {\n return {\n moduleId: parseIntOr(data.moduleId, null),\n moduleName: notEmptyStringOr(data.moduleName, null),\n moduleDescription: notEmptyStringOr(data.moduleDescription, 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: AnyObject\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 * Build a valid typed object from a raw object.\n * @param data Raw object.\n * @return An object representing the item's meta properties.\n */\nexport function itemMetaDecoder(data: UnknownObject): ItemMeta | never {\n const receivedAt = parseDateOr(data.receivedAt, null);\n if (receivedAt === null) throw new TypeError(\"invalid meta structure\");\n\n let error = null;\n if (data.error instanceof Error) error = data.error;\n else if (typeof data.error === \"string\") error = new Error(data.error);\n\n return {\n receivedAt,\n error,\n editMode: parseBoolean(data.editMode),\n isFromCache: parseBoolean(data.isFromCache),\n isFetching: false,\n isUpdating: false\n };\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\n/**\n * Generate a date representation with the format 'd/m/Y'.\n * @param initialDate Date to be used instead of a generated one.\n * @param locale Locale to use if localization is required and available.\n * @example 24/02/2020.\n * @return Date representation.\n */\nexport function humanDate(date: Date, locale: string | null = null): string {\n if (locale && Intl && Intl.DateTimeFormat) {\n // Format using the user locale.\n const options: Intl.DateTimeFormatOptions = {\n day: \"2-digit\",\n month: \"2-digit\",\n year: \"numeric\"\n };\n return Intl.DateTimeFormat(locale, options).format(date);\n } else {\n // Use getDate, getDay returns the week day.\n const day = leftPad(date.getDate(), 2, 0);\n // The getMonth function returns the month starting by 0.\n const month = leftPad(date.getMonth() + 1, 2, 0);\n const year = leftPad(date.getFullYear(), 4, 0);\n\n // Format: 'd/m/Y'.\n return `${day}/${month}/${year}`;\n }\n}\n\n/**\n * Generate a time representation with the format 'hh:mm:ss'.\n * @param initialDate Date to be used instead of a generated one.\n * @example 01:34:09.\n * @return Time representation.\n */\nexport function humanTime(date: Date): string {\n const hours = leftPad(date.getHours(), 2, 0);\n const minutes = leftPad(date.getMinutes(), 2, 0);\n const seconds = leftPad(date.getSeconds(), 2, 0);\n\n return `${hours}:${minutes}:${seconds}`;\n}\n\ninterface Macro {\n macro: string | RegExp;\n value: string;\n}\n/**\n * Replace the macros of a text.\n * @param macros List of macros and their replacements.\n * @param text Text in which we need to replace the macros.\n */\nexport function replaceMacros(macros: Macro[], text: string): string {\n return macros.reduce(\n (acc, { macro, value }) => acc.replace(macro, value),\n text\n );\n}\n\n/**\n * Create a function which will limit the rate of execution of\n * the selected function to one time for the selected interval.\n * @param delay Interval.\n * @param fn Function to be executed at a limited rate.\n */\nexport function throttle(delay: number, fn: (...args: T[]) => R) {\n let last = 0;\n return (...args: T[]) => {\n const now = Date.now();\n if (now - last < delay) return;\n last = now;\n return fn(...args);\n };\n}\n\n/**\n * Create a function which will call the selected function only\n * after the interval time has passed after its last execution.\n * @param delay Interval.\n * @param fn Function to be executed after the last call.\n */\nexport function debounce(delay: number, fn: (...args: T[]) => void) {\n let timerRef: number | null = null;\n return (...args: T[]) => {\n if (timerRef !== null) window.clearTimeout(timerRef);\n timerRef = window.setTimeout(() => {\n fn(...args);\n timerRef = null;\n }, delay);\n };\n}\n\n/**\n * Retrieve the offset of an element relative to the page.\n * @param el Node used to calculate the offset.\n */\nfunction getOffset(el: HTMLElement | null) {\n let x = 0;\n let y = 0;\n while (el && !Number.isNaN(el.offsetLeft) && !Number.isNaN(el.offsetTop)) {\n x += el.offsetLeft - el.scrollLeft;\n y += el.offsetTop - el.scrollTop;\n el = el.offsetParent as HTMLElement | null;\n }\n return { top: y, left: x };\n}\n\n/**\n * Add the grab & move functionality to a certain element inside it's container.\n *\n * @param element Element to move.\n * @param onMoved Function to execute when the element moves.\n *\n * @return A function which will clean the event handlers when executed.\n */\nexport function addMovementListener(\n element: HTMLElement,\n onMoved: (x: Position[\"x\"], y: Position[\"y\"]) => void\n): Function {\n const container = element.parentElement as HTMLElement;\n // Store the initial draggable state.\n const isDraggable = element.draggable;\n // Init the coordinates.\n let lastX: Position[\"x\"] = 0;\n let lastY: Position[\"y\"] = 0;\n let lastMouseX: Position[\"x\"] = 0;\n let lastMouseY: Position[\"y\"] = 0;\n let mouseElementOffsetX: Position[\"x\"] = 0;\n let mouseElementOffsetY: Position[\"y\"] = 0;\n // Bounds.\n let containerBounds = container.getBoundingClientRect();\n let containerOffset = getOffset(container);\n let containerTop = containerOffset.top;\n let containerBottom = containerTop + containerBounds.height;\n let containerLeft = containerOffset.left;\n let containerRight = containerLeft + containerBounds.width;\n let elementBounds = element.getBoundingClientRect();\n let borderWidth = window.getComputedStyle(element).borderWidth || \"0\";\n let borderFix = Number.parseInt(borderWidth) * 2;\n\n // Will run onMoved 32ms after its last execution.\n const debouncedMovement = debounce(32, (x: Position[\"x\"], y: Position[\"y\"]) =>\n onMoved(x, y)\n );\n // Will run onMoved one time max every 16ms.\n const throttledMovement = throttle(16, (x: Position[\"x\"], y: Position[\"y\"]) =>\n onMoved(x, y)\n );\n\n const handleMove = (e: MouseEvent) => {\n // Calculate the new element coordinates.\n let x = 0;\n let y = 0;\n\n const mouseX = e.pageX;\n const mouseY = e.pageY;\n const mouseDeltaX = mouseX - lastMouseX;\n const mouseDeltaY = mouseY - lastMouseY;\n\n const minX = 0;\n const maxX = containerBounds.width - elementBounds.width + borderFix;\n const minY = 0;\n const maxY = containerBounds.height - elementBounds.height + borderFix;\n\n const outOfBoundsLeft =\n mouseX < containerLeft ||\n (lastX === 0 &&\n mouseDeltaX > 0 &&\n mouseX < containerLeft + mouseElementOffsetX);\n const outOfBoundsRight =\n mouseX > containerRight ||\n mouseDeltaX + lastX + elementBounds.width - borderFix >\n containerBounds.width ||\n (lastX === maxX &&\n mouseDeltaX < 0 &&\n mouseX > containerLeft + maxX + mouseElementOffsetX);\n const outOfBoundsTop =\n mouseY < containerTop ||\n (lastY === 0 &&\n mouseDeltaY > 0 &&\n mouseY < containerTop + mouseElementOffsetY);\n const outOfBoundsBottom =\n mouseY > containerBottom ||\n mouseDeltaY + lastY + elementBounds.height - borderFix >\n containerBounds.height ||\n (lastY === maxY &&\n mouseDeltaY < 0 &&\n mouseY > containerTop + maxY + mouseElementOffsetY);\n\n if (outOfBoundsLeft) x = minX;\n else if (outOfBoundsRight) x = maxX;\n else x = mouseDeltaX + lastX;\n\n if (outOfBoundsTop) y = minY;\n else if (outOfBoundsBottom) y = maxY;\n else y = mouseDeltaY + lastY;\n\n if (x < 0) x = minX;\n if (y < 0) y = minY;\n\n // Store the last mouse coordinates.\n lastMouseX = mouseX;\n lastMouseY = mouseY;\n\n if (x === lastX && y === lastY) return;\n\n // Run the movement events.\n throttledMovement(x, y);\n debouncedMovement(x, y);\n\n // Store the coordinates of the element.\n lastX = x;\n lastY = y;\n };\n const handleEnd = () => {\n // Reset the positions.\n lastX = 0;\n lastY = 0;\n lastMouseX = 0;\n lastMouseY = 0;\n // Remove the move event.\n document.removeEventListener(\"mousemove\", handleMove);\n // Clean itself.\n document.removeEventListener(\"mouseup\", handleEnd);\n // Reset the draggable property to its initial state.\n element.draggable = isDraggable;\n // Reset the body selection property to a default state.\n document.body.style.userSelect = \"auto\";\n };\n const handleStart = (e: MouseEvent) => {\n e.stopPropagation();\n\n // Disable the drag temporarily.\n element.draggable = false;\n\n // Store the difference between the cursor and\n // the initial coordinates of the element.\n lastX = element.offsetLeft;\n lastY = element.offsetTop;\n // Store the mouse position.\n lastMouseX = e.pageX;\n lastMouseY = e.pageY;\n // Store the relative position between the mouse and the element.\n mouseElementOffsetX = e.offsetX;\n mouseElementOffsetY = e.offsetY;\n\n // Initialize the bounds.\n containerBounds = container.getBoundingClientRect();\n containerOffset = getOffset(container);\n containerTop = containerOffset.top;\n containerBottom = containerTop + containerBounds.height;\n containerLeft = containerOffset.left;\n containerRight = containerLeft + containerBounds.width;\n elementBounds = element.getBoundingClientRect();\n borderWidth = window.getComputedStyle(element).borderWidth || \"0\";\n borderFix = Number.parseInt(borderWidth) * 2;\n\n // Listen to the mouse movement.\n document.addEventListener(\"mousemove\", handleMove);\n // Listen to the moment when the mouse click is not pressed anymore.\n document.addEventListener(\"mouseup\", handleEnd);\n // Limit the mouse selection of the body.\n document.body.style.userSelect = \"none\";\n };\n\n // Event to listen the init of the movement.\n element.addEventListener(\"mousedown\", handleStart);\n\n // Returns a function to clean the event listeners.\n return () => {\n element.removeEventListener(\"mousedown\", handleStart);\n handleEnd();\n };\n}\n\n/**\n * Add the grab & resize functionality to a certain element.\n *\n * @param element Element to move.\n * @param onResized Function to execute when the element is resized.\n *\n * @return A function which will clean the event handlers when executed.\n */\nexport function addResizementListener(\n element: HTMLElement,\n onResized: (x: Position[\"x\"], y: Position[\"y\"]) => void\n): Function {\n const minWidth = 15;\n const minHeight = 15;\n\n const resizeDraggable = document.createElement(\"div\");\n resizeDraggable.className = \"resize-draggable\";\n element.appendChild(resizeDraggable);\n\n // Container of the resizable element.\n const container = element.parentElement as HTMLElement;\n // Store the initial draggable state.\n const isDraggable = element.draggable;\n // Init the coordinates.\n let lastWidth: Size[\"width\"] = 0;\n let lastHeight: Size[\"height\"] = 0;\n let lastMouseX: Position[\"x\"] = 0;\n let lastMouseY: Position[\"y\"] = 0;\n let mouseElementOffsetX: Position[\"x\"] = 0;\n let mouseElementOffsetY: Position[\"y\"] = 0;\n // Init the bounds.\n let containerBounds = container.getBoundingClientRect();\n let containerOffset = getOffset(container);\n let containerTop = containerOffset.top;\n let containerBottom = containerTop + containerBounds.height;\n let containerLeft = containerOffset.left;\n let containerRight = containerLeft + containerBounds.width;\n let elementOffset = getOffset(element);\n let elementTop = elementOffset.top;\n let elementLeft = elementOffset.left;\n let borderWidth = window.getComputedStyle(element).borderWidth || \"0\";\n let borderFix = Number.parseInt(borderWidth);\n\n // Will run onResized 32ms after its last execution.\n const debouncedResizement = debounce(\n 32,\n (width: Size[\"width\"], height: Size[\"height\"]) => onResized(width, height)\n );\n // Will run onResized one time max every 16ms.\n const throttledResizement = throttle(\n 16,\n (width: Size[\"width\"], height: Size[\"height\"]) => onResized(width, height)\n );\n\n const handleResize = (e: MouseEvent) => {\n // Calculate the new element coordinates.\n let width = lastWidth + (e.pageX - lastMouseX);\n let height = lastHeight + (e.pageY - lastMouseY);\n\n if (width === lastWidth && height === lastHeight) return;\n\n if (\n width < lastWidth &&\n e.pageX > elementLeft + (lastWidth - mouseElementOffsetX)\n )\n return;\n\n if (width < minWidth) {\n // Minimum value.\n width = minWidth;\n } else if (width + elementLeft - borderFix / 2 >= containerRight) {\n // Limit the size to the container.\n width = containerRight - elementLeft;\n }\n if (height < minHeight) {\n // Minimum value.\n height = minHeight;\n } else if (height + elementTop - borderFix / 2 >= containerBottom) {\n // Limit the size to the container.\n height = containerBottom - elementTop;\n }\n\n // Run the movement events.\n throttledResizement(width, height);\n debouncedResizement(width, height);\n\n // Store the coordinates of the element.\n lastWidth = width;\n lastHeight = height;\n // Store the last mouse coordinates.\n lastMouseX = e.pageX;\n lastMouseY = e.pageY;\n };\n const handleEnd = () => {\n // Reset the positions.\n lastWidth = 0;\n lastHeight = 0;\n lastMouseX = 0;\n lastMouseY = 0;\n mouseElementOffsetX = 0;\n mouseElementOffsetY = 0;\n // Remove the move event.\n document.removeEventListener(\"mousemove\", handleResize);\n // Clean itself.\n document.removeEventListener(\"mouseup\", handleEnd);\n // Reset the draggable property to its initial state.\n element.draggable = isDraggable;\n // Reset the body selection property to a default state.\n document.body.style.userSelect = \"auto\";\n };\n const handleStart = (e: MouseEvent) => {\n e.stopPropagation();\n\n // Disable the drag temporarily.\n element.draggable = false;\n\n // Store the difference between the cursor and\n // the initial coordinates of the element.\n const { width, height } = element.getBoundingClientRect();\n lastWidth = width;\n lastHeight = height;\n // Store the mouse position.\n lastMouseX = e.pageX;\n lastMouseY = e.pageY;\n // Store the relative position between the mouse and the element.\n mouseElementOffsetX = e.offsetX;\n mouseElementOffsetY = e.offsetY;\n\n // Initialize the bounds.\n containerBounds = container.getBoundingClientRect();\n containerOffset = getOffset(container);\n containerTop = containerOffset.top;\n containerBottom = containerTop + containerBounds.height;\n containerLeft = containerOffset.left;\n containerRight = containerLeft + containerBounds.width;\n elementOffset = getOffset(element);\n elementTop = elementOffset.top;\n elementLeft = elementOffset.left;\n\n // Listen to the mouse movement.\n document.addEventListener(\"mousemove\", handleResize);\n // Listen to the moment when the mouse click is not pressed anymore.\n document.addEventListener(\"mouseup\", handleEnd);\n // Limit the mouse selection of the body.\n document.body.style.userSelect = \"none\";\n };\n\n // Event to listen the init of the movement.\n resizeDraggable.addEventListener(\"mousedown\", handleStart);\n\n // Returns a function to clean the event listeners.\n return () => {\n resizeDraggable.remove();\n handleEnd();\n };\n}\n","import {\n Position,\n Size,\n AnyObject,\n WithModuleProps,\n ItemMeta\n} from \"./lib/types\";\nimport {\n sizePropsDecoder,\n positionPropsDecoder,\n parseIntOr,\n parseBoolean,\n notEmptyStringOr,\n replaceMacros,\n humanDate,\n humanTime,\n addMovementListener,\n debounce,\n addResizementListener\n} from \"./lib\";\nimport TypedEvent, { Listener, Disposable } from \"./lib/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: AnyObject;\n nativeEvent: Event;\n}\n\n// FIXME: Fix type compatibility.\nexport interface ItemRemoveEvent {\n // data: Props;\n data: AnyObject;\n}\n\nexport interface ItemMovedEvent {\n item: VisualConsoleItem;\n prevPosition: Position;\n newPosition: Position;\n}\n\nexport interface ItemResizedEvent {\n item: VisualConsoleItem;\n prevSize: Size;\n newSize: Size;\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: unknown\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: AnyObject): 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 // Metadata of the item.\n private _metadata: ItemMeta;\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 moved events.\n private readonly movedEventManager = new TypedEvent();\n // Event manager for resized events.\n private readonly resizedEventManager = 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 // This function will only run the 2nd arg function after the time\n // of the first arg have passed after its last execution.\n private debouncedMovementSave = debounce(\n 500, // ms.\n (x: Position[\"x\"], y: Position[\"y\"]) => {\n const prevPosition = {\n x: this.props.x,\n y: this.props.y\n };\n const newPosition = {\n x: x,\n y: y\n };\n\n if (!this.positionChanged(prevPosition, newPosition)) return;\n\n // Save the new position to the props.\n this.move(x, y);\n // Emit the movement event.\n this.movedEventManager.emit({\n item: this,\n prevPosition: prevPosition,\n newPosition: newPosition\n });\n }\n );\n // This property will store the function\n // to clean the movement listener.\n private removeMovement: Function | null = null;\n\n /**\n * Start the movement funtionality.\n * @param element Element to move inside its container.\n */\n private initMovementListener(element: HTMLElement): void {\n this.removeMovement = addMovementListener(\n element,\n (x: Position[\"x\"], y: Position[\"y\"]) => {\n // Move the DOM element.\n this.moveElement(x, y);\n // Run the save function.\n this.debouncedMovementSave(x, y);\n }\n );\n }\n /**\n * Stop the movement fun\n */\n private stopMovementListener(): void {\n if (this.removeMovement) {\n this.removeMovement();\n this.removeMovement = null;\n }\n }\n\n // This function will only run the 2nd arg function after the time\n // of the first arg have passed after its last execution.\n private debouncedResizementSave = debounce(\n 500, // ms.\n (width: Size[\"width\"], height: Size[\"height\"]) => {\n const prevSize = {\n width: this.props.width,\n height: this.props.height\n };\n const newSize = {\n width: width,\n height: height\n };\n\n if (!this.sizeChanged(prevSize, newSize)) return;\n\n // Save the new position to the props.\n this.resize(width, height);\n // Emit the resizement event.\n this.resizedEventManager.emit({\n item: this,\n prevSize: prevSize,\n newSize: newSize\n });\n }\n );\n // This property will store the function\n // to clean the resizement listener.\n private removeResizement: Function | null = null;\n\n /**\n * Start the resizement funtionality.\n * @param element Element to move inside its container.\n */\n protected initResizementListener(element: HTMLElement): void {\n this.removeResizement = addResizementListener(\n element,\n (width: Size[\"width\"], height: Size[\"height\"]) => {\n // The label it's outside the item's size, so we need\n // to get rid of its size to get the real size of the\n // item's content.\n if (this.props.label && this.props.label.length > 0) {\n const {\n width: labelWidth,\n height: labelHeight\n } = this.labelElementRef.getBoundingClientRect();\n\n switch (this.props.labelPosition) {\n case \"up\":\n case \"down\":\n height -= labelHeight;\n break;\n case \"left\":\n case \"right\":\n width -= labelWidth;\n break;\n }\n }\n\n // Move the DOM element.\n this.resizeElement(width, height);\n // Run the save function.\n this.debouncedResizementSave(width, height);\n }\n );\n }\n /**\n * Stop the resizement functionality.\n */\n private stopResizementListener(): void {\n if (this.removeResizement) {\n this.removeResizement();\n this.removeResizement = null;\n }\n }\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, metadata: ItemMeta) {\n this.itemProps = props;\n this._metadata = metadata;\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\") as HTMLAnchorElement;\n if (this.props.link) box.href = this.props.link;\n } else {\n box = document.createElement(\"div\") 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 // Init the click listener.\n box.addEventListener(\"click\", e => {\n if (this.meta.editMode) {\n e.preventDefault();\n e.stopPropagation();\n } else {\n this.clickEventManager.emit({ data: this.props, nativeEvent: e });\n }\n });\n\n // Metadata state.\n if (this.meta.editMode) {\n box.classList.add(\"is-editing\");\n // Init the movement listener.\n this.initMovementListener(box);\n // Init the resizement listener.\n this.initResizementListener(box);\n }\n if (this.meta.isFetching) {\n box.classList.add(\"is-fetching\");\n }\n if (this.meta.isUpdating) {\n box.classList.add(\"is-updating\");\n }\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 const label = this.getLabelWithMacrosReplaced();\n if (label.length > 0) {\n // Ugly table we need to use to replicate the legacy style.\n const table = document.createElement(\"table\");\n const row = document.createElement(\"tr\");\n const emptyRow1 = document.createElement(\"tr\");\n const emptyRow2 = document.createElement(\"tr\");\n const cell = document.createElement(\"td\");\n\n cell.innerHTML = label;\n row.append(cell);\n table.append(emptyRow1, row, emptyRow2);\n table.style.textAlign = \"center\";\n\n // Change the table size depending on its position.\n switch (this.props.labelPosition) {\n case \"up\":\n case \"down\":\n if (this.props.width > 0) {\n table.style.width = `${this.props.width}px`;\n table.style.height = null;\n }\n break;\n case \"left\":\n case \"right\":\n if (this.props.height > 0) {\n table.style.width = null;\n table.style.height = `${this.props.height}px`;\n }\n break;\n }\n\n // element.innerHTML = this.props.label;\n element.append(table);\n }\n\n return element;\n }\n\n /**\n * Return the label stored into the props with some macros replaced.\n */\n protected getLabelWithMacrosReplaced(): string {\n // We assert that the props may have some needed properties.\n const props = this.props as Partial;\n\n return replaceMacros(\n [\n {\n macro: \"_date_\",\n value: humanDate(new Date())\n },\n {\n macro: \"_time_\",\n value: humanTime(new Date())\n },\n {\n macro: \"_agent_\",\n value: props.agentAlias != null ? props.agentAlias : \"\"\n },\n {\n macro: \"_agentdescription_\",\n value: props.agentDescription != null ? props.agentDescription : \"\"\n },\n {\n macro: \"_address_\",\n value: props.agentAddress != null ? props.agentAddress : \"\"\n },\n {\n macro: \"_module_\",\n value: props.moduleName != null ? props.moduleName : \"\"\n },\n {\n macro: \"_moduledescription_\",\n value: props.moduleDescription != null ? props.moduleDescription : \"\"\n }\n ],\n this.props.label || \"\"\n );\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))\n this.render(prevProps, this._metadata);\n }\n\n /**\n * Public accessor of the `meta` property.\n * @return Properties.\n */\n public get meta(): ItemMeta {\n return { ...this._metadata }; // Return a copy.\n }\n\n /**\n * Public setter of the `meta` property.\n * If the new meta are different enough than the\n * stored meta, a render would be fired.\n * @param newProps\n */\n public set meta(newMetadata: ItemMeta) {\n this.setMeta(newMetadata);\n }\n\n /**\n * Clasic and protected version of the setter of the `meta` property.\n * Useful to override it from children classes.\n * @param newProps\n */\n protected setMeta(newMetadata: ItemMeta) {\n const prevMetadata = this._metadata;\n // Update the internal meta.\n this._metadata = newMetadata;\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(prevMetadata, newMetadata))\n this.render(this.itemProps, prevMetadata);\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(\n prevProps: Props | null = null,\n prevMeta: ItemMeta | null = null\n ): 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 const oldLabelHtml = this.labelElementRef.innerHTML;\n const newLabelHtml = this.createLabelDomElement().innerHTML;\n if (oldLabelHtml !== newLabelHtml) {\n this.labelElementRef.innerHTML = newLabelHtml;\n }\n // Change label position.\n if (!prevProps || prevProps.labelPosition !== this.props.labelPosition) {\n this.changeLabelPosition(this.props.labelPosition);\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 // Add the children of the old element.\n container.innerHTML = this.elementRef.innerHTML;\n // Copy the attributes.\n const attrs = this.elementRef.attributes;\n for (let i = 0; i < attrs.length; i++) {\n if (attrs[i].nodeName !== \"id\") {\n container.setAttributeNode(attrs[i]);\n }\n }\n // Replace the reference.\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\n // Change metadata related things.\n if (!prevMeta || prevMeta.editMode !== this.meta.editMode) {\n if (this.meta.editMode) {\n this.elementRef.classList.add(\"is-editing\");\n this.initMovementListener(this.elementRef);\n this.initResizementListener(this.elementRef);\n } else {\n this.elementRef.classList.remove(\"is-editing\");\n this.stopMovementListener();\n this.stopResizementListener();\n }\n }\n if (!prevMeta || prevMeta.isFetching !== this.meta.isFetching) {\n if (this.meta.isFetching) {\n this.elementRef.classList.add(\"is-fetching\");\n } else {\n this.elementRef.classList.remove(\"is-fetching\");\n }\n }\n if (!prevMeta || prevMeta.isUpdating !== this.meta.isUpdating) {\n if (this.meta.isUpdating) {\n this.elementRef.classList.add(\"is-updating\");\n } else {\n this.elementRef.classList.remove(\"is-updating\");\n }\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 // Ugly table to show the label as its legacy counterpart.\n const tables = this.labelElementRef.getElementsByTagName(\"table\");\n const table = tables.length > 0 ? tables.item(0) : null;\n // Change the table size depending on its position.\n if (table) {\n switch (this.props.labelPosition) {\n case \"up\":\n case \"down\":\n if (this.props.width > 0) {\n table.style.width = `${this.props.width}px`;\n table.style.height = null;\n }\n break;\n case \"left\":\n case \"right\":\n if (this.props.height > 0) {\n table.style.width = null;\n table.style.height = `${this.props.height}px`;\n }\n break;\n }\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 if (this.props.label && this.props.label.length > 0) {\n // Ugly table to show the label as its legacy counterpart.\n const tables = this.labelElementRef.getElementsByTagName(\"table\");\n const table = tables.length > 0 ? tables.item(0) : null;\n\n if (table) {\n switch (this.props.labelPosition) {\n case \"up\":\n case \"down\":\n table.style.width = width > 0 ? `${width}px` : null;\n break;\n case \"left\":\n case \"right\":\n table.style.height = height > 0 ? `${height}px` : null;\n break;\n }\n }\n }\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 movement of visual console elements.\n * @param listener Function which is going to be executed when a linked console is moved.\n */\n public onMoved(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.movedEventManager.on(listener);\n this.disposables.push(disposable);\n\n return disposable;\n }\n\n /**\n * To add an event handler to the resizement of visual console elements.\n * @param listener Function which is going to be executed when a linked console is moved.\n */\n public onResized(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.resizedEventManager.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 { AnyObject, WithModuleProps } from \"../lib/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: AnyObject\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 AnyObject,\n WithModuleProps\n} from \"../lib/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: AnyObject\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 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 { AnyObject, WithModuleProps } from \"../lib/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(data: AnyObject): 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 LinkedVisualConsoleProps,\n AnyObject,\n WithModuleProps\n} from \"../lib/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: AnyObject\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 /**\n * @override Item.resizeElement.\n * Resize the DOM content container.\n * We need to override the resize function cause this item's height\n * is larger than the configured and the graph is over the label.\n * @param width\n * @param height\n */\n protected resizeElement(width: number): void {\n super.resizeElement(width, 0);\n }\n\n /**\n * @override Item.initResizementListener. To disable the functionality.\n * Start the resizement funtionality.\n * @param element Element to move inside its container.\n */\n protected initResizementListener(): void {\n // No-Op. Disable the resizement functionality for this item.\n }\n\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 {\n WithModuleProps,\n LinkedVisualConsoleProps,\n AnyObject\n} from \"../lib/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: unknown\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: AnyObject\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 imgSrc = this.props.statusImageSrc || this.props.imageSrc;\n const element = document.createElement(\"div\");\n element.className = \"static-graph\";\n element.style.background = `url(${imgSrc}) no-repeat`;\n element.style.backgroundSize = \"contain\";\n element.style.backgroundPosition = \"center\";\n\n // Show last value in a tooltip.\n if (\n this.props.lastValue !== null &&\n this.props.showLastValueTooltip !== \"disabled\"\n ) {\n element.className = \"static-graph image forced_title\";\n element.setAttribute(\"data-use_title_for_force_title\", \"1\");\n element.setAttribute(\"data-title\", this.props.lastValue);\n }\n\n return element;\n }\n}\n","import { LinkedVisualConsoleProps, AnyObject } from \"../lib/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: AnyObject): 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 element = document.createElement(\"div\");\n element.className = \"icon\";\n element.style.background = `url(${this.props.imageSrc}) no-repeat`;\n element.style.backgroundSize = \"contain\";\n element.style.backgroundPosition = \"center\";\n\n return element;\n }\n}\n","import {\n WithModuleProps,\n LinkedVisualConsoleProps,\n AnyObject\n} from \"../lib/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: AnyObject\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 protected resizeElement(width: number): void {\n super.resizeElement(width, width);\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, AnyObject } from \"../lib/types\";\nimport {\n linkedVCPropsDecoder,\n parseIntOr,\n notEmptyStringOr,\n stringIsEmpty,\n decodeBase64,\n parseBoolean\n} from \"../lib\";\nimport Item, { ItemProps, itemBasePropsDecoder, ItemType } from \"../Item\";\n\nexport type GroupProps = {\n type: ItemType.GROUP_ITEM;\n groupId: number;\n imageSrc: string | null; // URL?\n statusImageSrc: string | null;\n showStatistics: boolean;\n html?: string | null;\n} & ItemProps &\n LinkedVisualConsoleProps;\n\nfunction extractHtml(data: AnyObject): string | null {\n if (!stringIsEmpty(data.html)) return data.html;\n if (!stringIsEmpty(data.encodedHtml)) return decodeBase64(data.encodedHtml);\n return 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 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: AnyObject): GroupProps | never {\n if (\n (typeof data.imageSrc !== \"string\" || data.imageSrc.length === 0) &&\n data.encodedHtml === null\n ) {\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 const showStatistics = parseBoolean(data.showStatistics);\n const html = showStatistics ? extractHtml(data) : null;\n\n return {\n ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.\n type: ItemType.GROUP_ITEM,\n groupId: parseInt(data.groupId),\n imageSrc: notEmptyStringOr(data.imageSrc, null),\n statusImageSrc: notEmptyStringOr(data.statusImageSrc, null),\n showStatistics,\n html,\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 element = document.createElement(\"div\");\n element.className = \"group\";\n\n if (!this.props.showStatistics && this.props.statusImageSrc !== null) {\n // Icon with status.\n element.style.background = `url(${this.props.statusImageSrc}) no-repeat`;\n element.style.backgroundSize = \"contain\";\n element.style.backgroundPosition = \"center\";\n } else if (this.props.showStatistics && this.props.html != null) {\n // Stats table.\n element.innerHTML = this.props.html;\n }\n\n return element;\n }\n}\n","import \"./styles.css\";\n\nimport {\n LinkedVisualConsoleProps,\n AnyObject,\n Size,\n ItemMeta\n} from \"../../lib/types\";\nimport {\n linkedVCPropsDecoder,\n parseIntOr,\n parseBoolean,\n prefixedCssRules,\n notEmptyStringOr,\n humanDate,\n humanTime\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 = (clockType: unknown): 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 = (clockFormat: unknown): ClockProps[\"clockFormat\"] => {\n switch (clockFormat) {\n case \"datetime\":\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: AnyObject): 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, meta: ItemMeta) {\n // Call the superclass constructor.\n super(props, meta);\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 // 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 dateFontSize =\n (baseTimeFontSize * dateFontSizeMultiplier * width) / 100;\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.getOriginDate();\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 // Date.\n if (this.props.clockFormat === \"datetime\") {\n const dateElem: HTMLSpanElement = document.createElement(\"span\");\n dateElem.className = \"date\";\n dateElem.textContent = humanDate(date, \"default\");\n dateElem.style.fontSize = `${dateFontSize}px`;\n if (this.props.color) dateElem.style.color = this.props.color;\n div.append(dateElem);\n }\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 calculated using the original timezone.\n const date = this.getOriginDate();\n\n // Date.\n if (this.props.clockFormat === \"datetime\") {\n const dateElem: HTMLSpanElement = document.createElement(\"span\");\n dateElem.className = \"date\";\n dateElem.textContent = humanDate(date, \"default\");\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 = humanTime(date);\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 getOriginDate(initialDate: Date | null = null): Date {\n const d = initialDate ? initialDate : 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 * 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 { AnyObject } from \"../lib/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: AnyObject): 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 { AnyObject, Position, Size, ItemMeta } from \"../lib/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: AnyObject): 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, meta: ItemMeta) {\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 {\n ...props,\n ...Line.extractBoxSizeAndPosition(props)\n },\n {\n ...meta,\n editMode: false\n }\n );\n }\n\n /**\n * Clasic and protected version of the setter of the `meta` property.\n * Useful to override it from children classes.\n * @param newProps\n * @override Item.setMeta\n */\n public setMeta(newMetadata: ItemMeta) {\n super.setMeta({\n ...newMetadata,\n editMode: false\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, AnyObject } from \"../lib/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: AnyObject): 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.getLabelWithMacrosReplaced();\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 AnyObject,\n WithModuleProps\n} from \"../lib/types\";\nimport {\n linkedVCPropsDecoder,\n parseIntOr,\n modulePropsDecoder,\n replaceMacros\n} 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 = (valueType: unknown): 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: unknown\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: AnyObject\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 let label = this.getLabelWithMacrosReplaced();\n if (label.length > 0) {\n text = replaceMacros([{ macro: /\\(?_VALUE_\\)?/i, value: text }], label);\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","var pi = Math.PI,\n tau = 2 * pi,\n epsilon = 1e-6,\n tauEpsilon = tau - epsilon;\n\nfunction Path() {\n this._x0 = this._y0 = // start of current subpath\n this._x1 = this._y1 = null; // end of current subpath\n this._ = \"\";\n}\n\nfunction path() {\n return new Path;\n}\n\nPath.prototype = path.prototype = {\n constructor: Path,\n moveTo: function(x, y) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y);\n },\n closePath: function() {\n if (this._x1 !== null) {\n this._x1 = this._x0, this._y1 = this._y0;\n this._ += \"Z\";\n }\n },\n lineTo: function(x, y) {\n this._ += \"L\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n quadraticCurveTo: function(x1, y1, x, y) {\n this._ += \"Q\" + (+x1) + \",\" + (+y1) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) {\n this._ += \"C\" + (+x1) + \",\" + (+y1) + \",\" + (+x2) + \",\" + (+y2) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n arcTo: function(x1, y1, x2, y2, r) {\n x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;\n var x0 = this._x1,\n y0 = this._y1,\n x21 = x2 - x1,\n y21 = y2 - y1,\n x01 = x0 - x1,\n y01 = y0 - y1,\n l01_2 = x01 * x01 + y01 * y01;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x1,y1).\n if (this._x1 === null) {\n this._ += \"M\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.\n else if (!(l01_2 > epsilon));\n\n // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?\n // Equivalently, is (x1,y1) coincident with (x2,y2)?\n // Or, is the radius zero? Line to (x1,y1).\n else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {\n this._ += \"L\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Otherwise, draw an arc!\n else {\n var x20 = x2 - x0,\n y20 = y2 - y0,\n l21_2 = x21 * x21 + y21 * y21,\n l20_2 = x20 * x20 + y20 * y20,\n l21 = Math.sqrt(l21_2),\n l01 = Math.sqrt(l01_2),\n l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),\n t01 = l / l01,\n t21 = l / l21;\n\n // If the start tangent is not coincident with (x0,y0), line to.\n if (Math.abs(t01 - 1) > epsilon) {\n this._ += \"L\" + (x1 + t01 * x01) + \",\" + (y1 + t01 * y01);\n }\n\n this._ += \"A\" + r + \",\" + r + \",0,0,\" + (+(y01 * x20 > x01 * y20)) + \",\" + (this._x1 = x1 + t21 * x21) + \",\" + (this._y1 = y1 + t21 * y21);\n }\n },\n arc: function(x, y, r, a0, a1, ccw) {\n x = +x, y = +y, r = +r;\n var dx = r * Math.cos(a0),\n dy = r * Math.sin(a0),\n x0 = x + dx,\n y0 = y + dy,\n cw = 1 ^ ccw,\n da = ccw ? a0 - a1 : a1 - a0;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x0,y0).\n if (this._x1 === null) {\n this._ += \"M\" + x0 + \",\" + y0;\n }\n\n // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).\n else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {\n this._ += \"L\" + x0 + \",\" + y0;\n }\n\n // Is this arc empty? We’re done.\n if (!r) return;\n\n // Does the angle go the wrong way? Flip the direction.\n if (da < 0) da = da % tau + tau;\n\n // Is this a complete circle? Draw two arcs to complete the circle.\n if (da > tauEpsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (x - dx) + \",\" + (y - dy) + \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (this._x1 = x0) + \",\" + (this._y1 = y0);\n }\n\n // Is this arc non-empty? Draw an arc!\n else if (da > epsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,\" + (+(da >= pi)) + \",\" + cw + \",\" + (this._x1 = x + r * Math.cos(a1)) + \",\" + (this._y1 = y + r * Math.sin(a1));\n }\n },\n rect: function(x, y, w, h) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y) + \"h\" + (+w) + \"v\" + (+h) + \"h\" + (-w) + \"Z\";\n },\n toString: function() {\n return this._;\n }\n};\n\nexport default path;\n","export default function(x) {\n return function constant() {\n return x;\n };\n}\n","export var abs = Math.abs;\nexport var atan2 = Math.atan2;\nexport var cos = Math.cos;\nexport var max = Math.max;\nexport var min = Math.min;\nexport var sin = Math.sin;\nexport var sqrt = Math.sqrt;\n\nexport var epsilon = 1e-12;\nexport var pi = Math.PI;\nexport var halfPi = pi / 2;\nexport var tau = 2 * pi;\n\nexport function acos(x) {\n return x > 1 ? 0 : x < -1 ? pi : Math.acos(x);\n}\n\nexport function asin(x) {\n return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x);\n}\n","import {path} from \"d3-path\";\nimport constant from \"./constant\";\nimport {abs, acos, asin, atan2, cos, epsilon, halfPi, max, min, pi, sin, sqrt, tau} from \"./math\";\n\nfunction arcInnerRadius(d) {\n return d.innerRadius;\n}\n\nfunction arcOuterRadius(d) {\n return d.outerRadius;\n}\n\nfunction arcStartAngle(d) {\n return d.startAngle;\n}\n\nfunction arcEndAngle(d) {\n return d.endAngle;\n}\n\nfunction arcPadAngle(d) {\n return d && d.padAngle; // Note: optional!\n}\n\nfunction intersect(x0, y0, x1, y1, x2, y2, x3, y3) {\n var x10 = x1 - x0, y10 = y1 - y0,\n x32 = x3 - x2, y32 = y3 - y2,\n t = y32 * x10 - x32 * y10;\n if (t * t < epsilon) return;\n t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / t;\n return [x0 + t * x10, y0 + t * y10];\n}\n\n// Compute perpendicular offset line of length rc.\n// http://mathworld.wolfram.com/Circle-LineIntersection.html\nfunction cornerTangents(x0, y0, x1, y1, r1, rc, cw) {\n var x01 = x0 - x1,\n y01 = y0 - y1,\n lo = (cw ? rc : -rc) / sqrt(x01 * x01 + y01 * y01),\n ox = lo * y01,\n oy = -lo * x01,\n x11 = x0 + ox,\n y11 = y0 + oy,\n x10 = x1 + ox,\n y10 = y1 + oy,\n x00 = (x11 + x10) / 2,\n y00 = (y11 + y10) / 2,\n dx = x10 - x11,\n dy = y10 - y11,\n d2 = dx * dx + dy * dy,\n r = r1 - rc,\n D = x11 * y10 - x10 * y11,\n d = (dy < 0 ? -1 : 1) * sqrt(max(0, r * r * d2 - D * D)),\n cx0 = (D * dy - dx * d) / d2,\n cy0 = (-D * dx - dy * d) / d2,\n cx1 = (D * dy + dx * d) / d2,\n cy1 = (-D * dx + dy * d) / d2,\n dx0 = cx0 - x00,\n dy0 = cy0 - y00,\n dx1 = cx1 - x00,\n dy1 = cy1 - y00;\n\n // Pick the closer of the two intersection points.\n // TODO Is there a faster way to determine which intersection to use?\n if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;\n\n return {\n cx: cx0,\n cy: cy0,\n x01: -ox,\n y01: -oy,\n x11: cx0 * (r1 / r - 1),\n y11: cy0 * (r1 / r - 1)\n };\n}\n\nexport default function() {\n var innerRadius = arcInnerRadius,\n outerRadius = arcOuterRadius,\n cornerRadius = constant(0),\n padRadius = null,\n startAngle = arcStartAngle,\n endAngle = arcEndAngle,\n padAngle = arcPadAngle,\n context = null;\n\n function arc() {\n var buffer,\n r,\n r0 = +innerRadius.apply(this, arguments),\n r1 = +outerRadius.apply(this, arguments),\n a0 = startAngle.apply(this, arguments) - halfPi,\n a1 = endAngle.apply(this, arguments) - halfPi,\n da = abs(a1 - a0),\n cw = a1 > a0;\n\n if (!context) context = buffer = path();\n\n // Ensure that the outer radius is always larger than the inner radius.\n if (r1 < r0) r = r1, r1 = r0, r0 = r;\n\n // Is it a point?\n if (!(r1 > epsilon)) context.moveTo(0, 0);\n\n // Or is it a circle or annulus?\n else if (da > tau - epsilon) {\n context.moveTo(r1 * cos(a0), r1 * sin(a0));\n context.arc(0, 0, r1, a0, a1, !cw);\n if (r0 > epsilon) {\n context.moveTo(r0 * cos(a1), r0 * sin(a1));\n context.arc(0, 0, r0, a1, a0, cw);\n }\n }\n\n // Or is it a circular or annular sector?\n else {\n var a01 = a0,\n a11 = a1,\n a00 = a0,\n a10 = a1,\n da0 = da,\n da1 = da,\n ap = padAngle.apply(this, arguments) / 2,\n rp = (ap > epsilon) && (padRadius ? +padRadius.apply(this, arguments) : sqrt(r0 * r0 + r1 * r1)),\n rc = min(abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),\n rc0 = rc,\n rc1 = rc,\n t0,\n t1;\n\n // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.\n if (rp > epsilon) {\n var p0 = asin(rp / r0 * sin(ap)),\n p1 = asin(rp / r1 * sin(ap));\n if ((da0 -= p0 * 2) > epsilon) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;\n else da0 = 0, a00 = a10 = (a0 + a1) / 2;\n if ((da1 -= p1 * 2) > epsilon) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;\n else da1 = 0, a01 = a11 = (a0 + a1) / 2;\n }\n\n var x01 = r1 * cos(a01),\n y01 = r1 * sin(a01),\n x10 = r0 * cos(a10),\n y10 = r0 * sin(a10);\n\n // Apply rounded corners?\n if (rc > epsilon) {\n var x11 = r1 * cos(a11),\n y11 = r1 * sin(a11),\n x00 = r0 * cos(a00),\n y00 = r0 * sin(a00),\n oc;\n\n // Restrict the corner radius according to the sector angle.\n if (da < pi && (oc = intersect(x01, y01, x00, y00, x11, y11, x10, y10))) {\n var ax = x01 - oc[0],\n ay = y01 - oc[1],\n bx = x11 - oc[0],\n by = y11 - oc[1],\n kc = 1 / sin(acos((ax * bx + ay * by) / (sqrt(ax * ax + ay * ay) * sqrt(bx * bx + by * by))) / 2),\n lc = sqrt(oc[0] * oc[0] + oc[1] * oc[1]);\n rc0 = min(rc, (r0 - lc) / (kc - 1));\n rc1 = min(rc, (r1 - lc) / (kc + 1));\n }\n }\n\n // Is the sector collapsed to a line?\n if (!(da1 > epsilon)) context.moveTo(x01, y01);\n\n // Does the sector’s outer ring have rounded corners?\n else if (rc1 > epsilon) {\n t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);\n t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);\n\n context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);\n\n // Have the corners merged?\n if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);\n\n // Otherwise, draw the two corners and the ring.\n else {\n context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);\n context.arc(0, 0, r1, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw);\n context.arc(t1.cx, t1.cy, rc1, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);\n }\n }\n\n // Or is the outer ring just a circular arc?\n else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);\n\n // Is there no inner ring, and it’s a circular sector?\n // Or perhaps it’s an annular sector collapsed due to padding?\n if (!(r0 > epsilon) || !(da0 > epsilon)) context.lineTo(x10, y10);\n\n // Does the sector’s inner ring (or point) have rounded corners?\n else if (rc0 > epsilon) {\n t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);\n t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);\n\n context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);\n\n // Have the corners merged?\n if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);\n\n // Otherwise, draw the two corners and the ring.\n else {\n context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);\n context.arc(0, 0, r0, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw);\n context.arc(t1.cx, t1.cy, rc0, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);\n }\n }\n\n // Or is the inner ring just a circular arc?\n else context.arc(0, 0, r0, a10, a00, cw);\n }\n\n context.closePath();\n\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n arc.centroid = function() {\n var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,\n a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi / 2;\n return [cos(a) * r, sin(a) * r];\n };\n\n arc.innerRadius = function(_) {\n return arguments.length ? (innerRadius = typeof _ === \"function\" ? _ : constant(+_), arc) : innerRadius;\n };\n\n arc.outerRadius = function(_) {\n return arguments.length ? (outerRadius = typeof _ === \"function\" ? _ : constant(+_), arc) : outerRadius;\n };\n\n arc.cornerRadius = function(_) {\n return arguments.length ? (cornerRadius = typeof _ === \"function\" ? _ : constant(+_), arc) : cornerRadius;\n };\n\n arc.padRadius = function(_) {\n return arguments.length ? (padRadius = _ == null ? null : typeof _ === \"function\" ? _ : constant(+_), arc) : padRadius;\n };\n\n arc.startAngle = function(_) {\n return arguments.length ? (startAngle = typeof _ === \"function\" ? _ : constant(+_), arc) : startAngle;\n };\n\n arc.endAngle = function(_) {\n return arguments.length ? (endAngle = typeof _ === \"function\" ? _ : constant(+_), arc) : endAngle;\n };\n\n arc.padAngle = function(_) {\n return arguments.length ? (padAngle = typeof _ === \"function\" ? _ : constant(+_), arc) : padAngle;\n };\n\n arc.context = function(_) {\n return arguments.length ? ((context = _ == null ? null : _), arc) : context;\n };\n\n return arc;\n}\n","function Linear(context) {\n this._context = context;\n}\n\nLinear.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; // proceed\n default: this._context.lineTo(x, y); break;\n }\n }\n};\n\nexport default function(context) {\n return new Linear(context);\n}\n","import curveLinear from \"./linear\";\n\nexport var curveRadialLinear = curveRadial(curveLinear);\n\nfunction Radial(curve) {\n this._curve = curve;\n}\n\nRadial.prototype = {\n areaStart: function() {\n this._curve.areaStart();\n },\n areaEnd: function() {\n this._curve.areaEnd();\n },\n lineStart: function() {\n this._curve.lineStart();\n },\n lineEnd: function() {\n this._curve.lineEnd();\n },\n point: function(a, r) {\n this._curve.point(r * Math.sin(a), r * -Math.cos(a));\n }\n};\n\nexport default function curveRadial(curve) {\n\n function radial(context) {\n return new Radial(curve(context));\n }\n\n radial._curve = curve;\n\n return radial;\n}\n","export var slice = Array.prototype.slice;\n","var tan30 = Math.sqrt(1 / 3),\n tan30_2 = tan30 * 2;\n\nexport default {\n draw: function(context, size) {\n var y = Math.sqrt(size / tan30_2),\n x = y * tan30;\n context.moveTo(0, -y);\n context.lineTo(x, 0);\n context.lineTo(0, y);\n context.lineTo(-x, 0);\n context.closePath();\n }\n};\n","import {pi, tau} from \"../math\";\n\nexport default {\n draw: function(context, size) {\n var r = Math.sqrt(size / pi);\n context.moveTo(r, 0);\n context.arc(0, 0, r, 0, tau);\n }\n};\n","import {pi, tau} from \"../math\";\n\nvar ka = 0.89081309152928522810,\n kr = Math.sin(pi / 10) / Math.sin(7 * pi / 10),\n kx = Math.sin(tau / 10) * kr,\n ky = -Math.cos(tau / 10) * kr;\n\nexport default {\n draw: function(context, size) {\n var r = Math.sqrt(size * ka),\n x = kx * r,\n y = ky * r;\n context.moveTo(0, -r);\n context.lineTo(x, y);\n for (var i = 1; i < 5; ++i) {\n var a = tau * i / 5,\n c = Math.cos(a),\n s = Math.sin(a);\n context.lineTo(s * r, -c * r);\n context.lineTo(c * x - s * y, s * x + c * y);\n }\n context.closePath();\n }\n};\n","export default function() {}\n","var sqrt3 = Math.sqrt(3);\n\nexport default {\n draw: function(context, size) {\n var y = -Math.sqrt(size / (sqrt3 * 3));\n context.moveTo(0, y * 2);\n context.lineTo(-sqrt3 * y, -y);\n context.lineTo(sqrt3 * y, -y);\n context.closePath();\n }\n};\n","var c = -0.5,\n s = Math.sqrt(3) / 2,\n k = 1 / Math.sqrt(12),\n a = (k / 2 + 1) * 3;\n\nexport default {\n draw: function(context, size) {\n var r = Math.sqrt(size / a),\n x0 = r / 2,\n y0 = r * k,\n x1 = x0,\n y1 = r * k + r,\n x2 = -x1,\n y2 = y1;\n context.moveTo(x0, y0);\n context.lineTo(x1, y1);\n context.lineTo(x2, y2);\n context.lineTo(c * x0 - s * y0, s * x0 + c * y0);\n context.lineTo(c * x1 - s * y1, s * x1 + c * y1);\n context.lineTo(c * x2 - s * y2, s * x2 + c * y2);\n context.lineTo(c * x0 + s * y0, c * y0 - s * x0);\n context.lineTo(c * x1 + s * y1, c * y1 - s * x1);\n context.lineTo(c * x2 + s * y2, c * y2 - s * x2);\n context.closePath();\n }\n};\n","export function point(that, x, y) {\n that._context.bezierCurveTo(\n (2 * that._x0 + that._x1) / 3,\n (2 * that._y0 + that._y1) / 3,\n (that._x0 + 2 * that._x1) / 3,\n (that._y0 + 2 * that._y1) / 3,\n (that._x0 + 4 * that._x1 + x) / 6,\n (that._y0 + 4 * that._y1 + y) / 6\n );\n}\n\nexport function Basis(context) {\n this._context = context;\n}\n\nBasis.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 3: point(this, this._x1, this._y1); // proceed\n case 2: this._context.lineTo(this._x1, this._y1); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nexport default function(context) {\n return new Basis(context);\n}\n","import noop from \"../noop\";\nimport {point} from \"./basis\";\n\nfunction BasisClosed(context) {\n this._context = context;\n}\n\nBasisClosed.prototype = {\n areaStart: noop,\n areaEnd: noop,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x2, this._y2);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);\n this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x2, this._y2);\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._x2 = x, this._y2 = y; break;\n case 1: this._point = 2; this._x3 = x, this._y3 = y; break;\n case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break;\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nexport default function(context) {\n return new BasisClosed(context);\n}\n","import {point} from \"./basis\";\n\nfunction BasisOpen(context) {\n this._context = context;\n}\n\nBasisOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break;\n case 3: this._point = 4; // proceed\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nexport default function(context) {\n return new BasisOpen(context);\n}\n","import {Basis} from \"./basis\";\n\nfunction Bundle(context, beta) {\n this._basis = new Basis(context);\n this._beta = beta;\n}\n\nBundle.prototype = {\n lineStart: function() {\n this._x = [];\n this._y = [];\n this._basis.lineStart();\n },\n lineEnd: function() {\n var x = this._x,\n y = this._y,\n j = x.length - 1;\n\n if (j > 0) {\n var x0 = x[0],\n y0 = y[0],\n dx = x[j] - x0,\n dy = y[j] - y0,\n i = -1,\n t;\n\n while (++i <= j) {\n t = i / j;\n this._basis.point(\n this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),\n this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)\n );\n }\n }\n\n this._x = this._y = null;\n this._basis.lineEnd();\n },\n point: function(x, y) {\n this._x.push(+x);\n this._y.push(+y);\n }\n};\n\nexport default (function custom(beta) {\n\n function bundle(context) {\n return beta === 1 ? new Basis(context) : new Bundle(context, beta);\n }\n\n bundle.beta = function(beta) {\n return custom(+beta);\n };\n\n return bundle;\n})(0.85);\n","export function point(that, x, y) {\n that._context.bezierCurveTo(\n that._x1 + that._k * (that._x2 - that._x0),\n that._y1 + that._k * (that._y2 - that._y0),\n that._x2 + that._k * (that._x1 - x),\n that._y2 + that._k * (that._y1 - y),\n that._x2,\n that._y2\n );\n}\n\nexport function Cardinal(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinal.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x2, this._y2); break;\n case 3: point(this, this._x1, this._y1); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; this._x1 = x, this._y1 = y; break;\n case 2: this._point = 3; // proceed\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(tension) {\n\n function cardinal(context) {\n return new Cardinal(context, tension);\n }\n\n cardinal.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal;\n})(0);\n","import noop from \"../noop\";\nimport {point} from \"./cardinal\";\n\nexport function CardinalClosed(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinalClosed.prototype = {\n areaStart: noop,\n areaEnd: noop,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.lineTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n this.point(this._x5, this._y5);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._x3 = x, this._y3 = y; break;\n case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;\n case 2: this._point = 3; this._x5 = x, this._y5 = y; break;\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(tension) {\n\n function cardinal(context) {\n return new CardinalClosed(context, tension);\n }\n\n cardinal.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal;\n})(0);\n","import {point} from \"./cardinal\";\n\nexport function CardinalOpen(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinalOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;\n case 3: this._point = 4; // proceed\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(tension) {\n\n function cardinal(context) {\n return new CardinalOpen(context, tension);\n }\n\n cardinal.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal;\n})(0);\n","import {epsilon} from \"../math\";\nimport {Cardinal} from \"./cardinal\";\n\nexport function point(that, x, y) {\n var x1 = that._x1,\n y1 = that._y1,\n x2 = that._x2,\n y2 = that._y2;\n\n if (that._l01_a > epsilon) {\n var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,\n n = 3 * that._l01_a * (that._l01_a + that._l12_a);\n x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;\n y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;\n }\n\n if (that._l23_a > epsilon) {\n var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,\n m = 3 * that._l23_a * (that._l23_a + that._l12_a);\n x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;\n y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;\n }\n\n that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);\n}\n\nfunction CatmullRom(context, alpha) {\n this._context = context;\n this._alpha = alpha;\n}\n\nCatmullRom.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._l01_a = this._l12_a = this._l23_a =\n this._l01_2a = this._l12_2a = this._l23_2a =\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x2, this._y2); break;\n case 3: this.point(this._x2, this._y2); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n\n if (this._point) {\n var x23 = this._x2 - x,\n y23 = this._y2 - y;\n this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n }\n\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; // proceed\n default: point(this, x, y); break;\n }\n\n this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(alpha) {\n\n function catmullRom(context) {\n return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0);\n }\n\n catmullRom.alpha = function(alpha) {\n return custom(+alpha);\n };\n\n return catmullRom;\n})(0.5);\n","import {CardinalClosed} from \"./cardinalClosed\";\nimport noop from \"../noop\";\nimport {point} from \"./catmullRom\";\n\nfunction CatmullRomClosed(context, alpha) {\n this._context = context;\n this._alpha = alpha;\n}\n\nCatmullRomClosed.prototype = {\n areaStart: noop,\n areaEnd: noop,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;\n this._l01_a = this._l12_a = this._l23_a =\n this._l01_2a = this._l12_2a = this._l23_2a =\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.lineTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n this.point(this._x5, this._y5);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n\n if (this._point) {\n var x23 = this._x2 - x,\n y23 = this._y2 - y;\n this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n }\n\n switch (this._point) {\n case 0: this._point = 1; this._x3 = x, this._y3 = y; break;\n case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;\n case 2: this._point = 3; this._x5 = x, this._y5 = y; break;\n default: point(this, x, y); break;\n }\n\n this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(alpha) {\n\n function catmullRom(context) {\n return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);\n }\n\n catmullRom.alpha = function(alpha) {\n return custom(+alpha);\n };\n\n return catmullRom;\n})(0.5);\n","import {CardinalOpen} from \"./cardinalOpen\";\nimport {point} from \"./catmullRom\";\n\nfunction CatmullRomOpen(context, alpha) {\n this._context = context;\n this._alpha = alpha;\n}\n\nCatmullRomOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._l01_a = this._l12_a = this._l23_a =\n this._l01_2a = this._l12_2a = this._l23_2a =\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n\n if (this._point) {\n var x23 = this._x2 - x,\n y23 = this._y2 - y;\n this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n }\n\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;\n case 3: this._point = 4; // proceed\n default: point(this, x, y); break;\n }\n\n this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(alpha) {\n\n function catmullRom(context) {\n return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);\n }\n\n catmullRom.alpha = function(alpha) {\n return custom(+alpha);\n };\n\n return catmullRom;\n})(0.5);\n","import noop from \"../noop\";\n\nfunction LinearClosed(context) {\n this._context = context;\n}\n\nLinearClosed.prototype = {\n areaStart: noop,\n areaEnd: noop,\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._point) this._context.closePath();\n },\n point: function(x, y) {\n x = +x, y = +y;\n if (this._point) this._context.lineTo(x, y);\n else this._point = 1, this._context.moveTo(x, y);\n }\n};\n\nexport default function(context) {\n return new LinearClosed(context);\n}\n","function sign(x) {\n return x < 0 ? -1 : 1;\n}\n\n// Calculate the slopes of the tangents (Hermite-type interpolation) based on\n// the following paper: Steffen, M. 1990. A Simple Method for Monotonic\n// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.\n// NOV(II), P. 443, 1990.\nfunction slope3(that, x2, y2) {\n var h0 = that._x1 - that._x0,\n h1 = x2 - that._x1,\n s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),\n s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),\n p = (s0 * h1 + s1 * h0) / (h0 + h1);\n return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;\n}\n\n// Calculate a one-sided slope.\nfunction slope2(that, t) {\n var h = that._x1 - that._x0;\n return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;\n}\n\n// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations\n// \"you can express cubic Hermite interpolation in terms of cubic Bézier curves\n// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1\".\nfunction point(that, t0, t1) {\n var x0 = that._x0,\n y0 = that._y0,\n x1 = that._x1,\n y1 = that._y1,\n dx = (x1 - x0) / 3;\n that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);\n}\n\nfunction MonotoneX(context) {\n this._context = context;\n}\n\nMonotoneX.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 =\n this._t0 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x1, this._y1); break;\n case 3: point(this, this._t0, slope2(this, this._t0)); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n var t1 = NaN;\n\n x = +x, y = +y;\n if (x === this._x1 && y === this._y1) return; // Ignore coincident points.\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; point(this, slope2(this, t1 = slope3(this, x, y)), t1); break;\n default: point(this, this._t0, t1 = slope3(this, x, y)); break;\n }\n\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n this._t0 = t1;\n }\n}\n\nfunction MonotoneY(context) {\n this._context = new ReflectContext(context);\n}\n\n(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {\n MonotoneX.prototype.point.call(this, y, x);\n};\n\nfunction ReflectContext(context) {\n this._context = context;\n}\n\nReflectContext.prototype = {\n moveTo: function(x, y) { this._context.moveTo(y, x); },\n closePath: function() { this._context.closePath(); },\n lineTo: function(x, y) { this._context.lineTo(y, x); },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }\n};\n\nexport function monotoneX(context) {\n return new MonotoneX(context);\n}\n\nexport function monotoneY(context) {\n return new MonotoneY(context);\n}\n","function Natural(context) {\n this._context = context;\n}\n\nNatural.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x = [];\n this._y = [];\n },\n lineEnd: function() {\n var x = this._x,\n y = this._y,\n n = x.length;\n\n if (n) {\n this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);\n if (n === 2) {\n this._context.lineTo(x[1], y[1]);\n } else {\n var px = controlPoints(x),\n py = controlPoints(y);\n for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {\n this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);\n }\n }\n }\n\n if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();\n this._line = 1 - this._line;\n this._x = this._y = null;\n },\n point: function(x, y) {\n this._x.push(+x);\n this._y.push(+y);\n }\n};\n\n// See https://www.particleincell.com/2012/bezier-splines/ for derivation.\nfunction controlPoints(x) {\n var i,\n n = x.length - 1,\n m,\n a = new Array(n),\n b = new Array(n),\n r = new Array(n);\n a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];\n for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];\n a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];\n for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];\n a[n - 1] = r[n - 1] / b[n - 1];\n for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];\n b[n - 1] = (x[n] + a[n - 1]) / 2;\n for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];\n return [a, b];\n}\n\nexport default function(context) {\n return new Natural(context);\n}\n","function Step(context, t) {\n this._context = context;\n this._t = t;\n}\n\nStep.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x = this._y = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; // proceed\n default: {\n if (this._t <= 0) {\n this._context.lineTo(this._x, y);\n this._context.lineTo(x, y);\n } else {\n var x1 = this._x * (1 - this._t) + x * this._t;\n this._context.lineTo(x1, this._y);\n this._context.lineTo(x1, y);\n }\n break;\n }\n }\n this._x = x, this._y = y;\n }\n};\n\nexport default function(context) {\n return new Step(context, 0.5);\n}\n\nexport function stepBefore(context) {\n return new Step(context, 0);\n}\n\nexport function stepAfter(context) {\n return new Step(context, 1);\n}\n","import ascending from \"./ascending\";\n\nexport default function(series) {\n return ascending(series).reverse();\n}\n","import { arc as arcFactory } from \"d3-shape\";\n\nimport {\n LinkedVisualConsoleProps,\n AnyObject,\n WithModuleProps\n} from \"../lib/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 */\nfunction extractPercentileType(\n type: unknown\n): 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 */\nfunction extractValueType(valueType: unknown): 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: AnyObject\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 var formatValue;\n if (this.props.value != null) {\n if (Intl) {\n formatValue = Intl.NumberFormat(\"en-EN\").format(this.props.value);\n } else {\n formatValue = this.props.value;\n }\n }\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.style.fontSize = \"6pt\";\n\n text.textContent = this.props.unit\n ? `${formatValue} ${this.props.unit}`\n : `${formatValue}`;\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\":\n case \"circular-progress-bar-alt\":\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\n if (this.props.percentileType === \"bubble\") {\n // Create and append the circles.\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\n svg.append(backgroundCircle, progressCircle);\n } else {\n // Create and append the circles.\n const arcProps = {\n innerRadius:\n this.props.percentileType === \"circular-progress-bar\" ? 30 : 0,\n outerRadius: 50,\n startAngle: 0,\n endAngle: Math.PI * 2\n };\n const arc = arcFactory();\n\n const backgroundCircle = document.createElementNS(svgNS, \"path\");\n backgroundCircle.setAttribute(\"transform\", \"translate(50 50)\");\n backgroundCircle.setAttribute(\"fill\", colors.background);\n backgroundCircle.setAttribute(\"fill-opacity\", \"0.5\");\n backgroundCircle.setAttribute(\"d\", `${arc(arcProps)}`);\n const progressCircle = document.createElementNS(svgNS, \"path\");\n progressCircle.setAttribute(\"transform\", \"translate(50 50)\");\n progressCircle.setAttribute(\"fill\", colors.progress);\n progressCircle.setAttribute(\"fill-opacity\", \"1\");\n progressCircle.setAttribute(\n \"d\",\n `${arc({\n ...arcProps,\n endAngle: arcProps.endAngle * (progress / 100)\n })}`\n );\n\n svg.append(backgroundCircle, progressCircle);\n }\n\n // Create and append the text.\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\" && this.props.value != null) {\n // Show value and unit in 1 (no unit) or 2 lines.\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 = `${formatValue}`;\n value.style.fontSize = \"8pt\";\n const unit = document.createElementNS(svgNS, \"tspan\");\n unit.setAttribute(\"x\", \"0\");\n unit.setAttribute(\"dy\", \"1em\");\n unit.textContent = `${this.props.unit}`;\n unit.style.fontSize = \"8pt\";\n text.append(value, unit);\n text.setAttribute(\"transform\", \"translate(50 33)\");\n } else {\n text.textContent = `${formatValue}`;\n text.style.fontSize = \"8pt\";\n text.setAttribute(\"transform\", \"translate(50 50)\");\n }\n } else {\n // Percentage.\n text.textContent = `${progress}%`;\n text.setAttribute(\"transform\", \"translate(50 50)\");\n }\n\n svg.append(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 == null ? 0 : this.props.value;\n\n if (value <= minValue) return 0;\n else if (value >= maxValue) return 100;\n else return Math.trunc(((value - minValue) / (maxValue - minValue)) * 100);\n }\n}\n","import { AnyObject } from \"../lib/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: AnyObject): 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 element = document.createElement(\"div\");\n element.className = \"service\";\n\n if (this.props.statusImageSrc !== null) {\n element.style.background = `url(${this.props.statusImageSrc}) no-repeat`;\n element.style.backgroundSize = \"contain\";\n element.style.backgroundPosition = \"center\";\n } else if (this.props.encodedTitle !== null) {\n element.innerHTML = decodeBase64(this.props.encodedTitle);\n }\n\n return element;\n }\n}\n","import { AnyObject, Size } from \"./lib/types\";\nimport {\n parseBoolean,\n sizePropsDecoder,\n parseIntOr,\n notEmptyStringOr,\n itemMetaDecoder\n} from \"./lib\";\nimport Item, {\n ItemType,\n ItemProps,\n ItemClickEvent,\n ItemRemoveEvent,\n ItemMovedEvent,\n ItemResizedEvent\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 \"./lib/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: AnyObject) {\n const type = parseIntOr(data.type, null);\n if (type == null) throw new TypeError(\"missing item type.\");\n\n const meta = itemMetaDecoder(data);\n\n switch (type as ItemType) {\n case ItemType.STATIC_GRAPH:\n return new StaticGraph(staticGraphPropsDecoder(data), meta);\n case ItemType.MODULE_GRAPH:\n return new ModuleGraph(moduleGraphPropsDecoder(data), meta);\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), meta);\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), meta);\n case ItemType.LABEL:\n return new Label(labelPropsDecoder(data), meta);\n case ItemType.ICON:\n return new Icon(iconPropsDecoder(data), meta);\n case ItemType.SERVICE:\n return new Service(servicePropsDecoder(data), meta);\n case ItemType.GROUP_ITEM:\n return new Group(groupPropsDecoder(data), meta);\n case ItemType.BOX_ITEM:\n return new Box(boxPropsDecoder(data), meta);\n case ItemType.LINE_ITEM:\n return new Line(linePropsDecoder(data), meta);\n case ItemType.AUTO_SLA_GRAPH:\n return new EventsHistory(eventsHistoryPropsDecoder(data), meta);\n case ItemType.DONUT_GRAPH:\n return new DonutGraph(donutGraphPropsDecoder(data), meta);\n case ItemType.BARS_GRAPH:\n return new BarsGraph(barsGraphPropsDecoder(data), meta);\n case ItemType.CLOCK:\n return new Clock(clockPropsDecoder(data), meta);\n case ItemType.COLOR_CLOUD:\n return new ColorCloud(colorCloudPropsDecoder(data), meta);\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: AnyObject) {\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: AnyObject\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 // Event manager for move events.\n private readonly movedEventManager = new TypedEvent();\n // Event manager for resize events.\n private readonly resizedEventManager = new TypedEvent();\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 * React to a movement on an element.\n * @param e Event object.\n */\n private handleElementMovement: (e: ItemMovedEvent) => void = e => {\n this.movedEventManager.emit(e);\n // console.log(`Moved element #${e.item.props.id}`, e);\n };\n\n /**\n * React to a resizement on an element.\n * @param e Event object.\n */\n private handleElementResizement: (e: ItemResizedEvent) => void = e => {\n this.resizedEventManager.emit(e);\n // console.log(`Resized element #${e.item.props.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: AnyObject,\n items: AnyObject[]\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.onMoved(this.handleElementMovement);\n itemInstance.onResized(this.handleElementResizement);\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: AnyObject[]): void {\n // Ensure the type cause Typescript doesn't know the filter removes null items.\n const itemIds = items\n .map(item => item.id || null)\n .filter(id => id != null) as number[];\n // Get the elements we should delete.\n const deletedIds = this.elementIds.filter(id => itemIds.indexOf(id) < 0);\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 itemMetaDecoder({\n receivedAt: new Date()\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 onItemClick(\n listener: Listener>\n ): 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 * Add an event handler to the movement of the visual console elements.\n * @param listener Function which is going to be executed when a linked console is moved.\n */\n public onItemMoved(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.movedEventManager.on(listener);\n this.disposables.push(disposable);\n\n return disposable;\n }\n\n /**\n * Add an event handler to the resizement of the visual console elements.\n * @param listener Function which is going to be executed when a linked console is moved.\n */\n public onItemResized(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.resizedEventManager.on(listener);\n this.disposables.push(disposable);\n\n return disposable;\n }\n\n /**\n * Enable the edition mode.\n */\n public enableEditMode(): void {\n this.elements.forEach(item => {\n item.meta = { ...item.meta, editMode: true };\n });\n this.containerRef.classList.add(\"is-editing\");\n }\n\n /**\n * Disable the edition mode.\n */\n public disableEditMode(): void {\n this.elements.forEach(item => {\n item.meta = { ...item.meta, editMode: false };\n });\n this.containerRef.classList.remove(\"is-editing\");\n }\n}\n","import TypedEvent, { Disposable, Listener } from \"./TypedEvent\";\n\ninterface Cancellable {\n cancel(): void;\n}\n\ntype AsyncTaskStatus = \"waiting\" | \"started\" | \"cancelled\" | \"finished\";\ntype AsyncTaskInitiator = (done: () => void) => Cancellable;\n\n/**\n * Defines an async task which can be started and cancelled.\n * It's possible to observe the status changes of the task.\n */\nclass AsyncTask {\n private readonly taskInitiator: AsyncTaskInitiator;\n private cancellable: Cancellable = { cancel: () => {} };\n private _status: AsyncTaskStatus = \"waiting\";\n\n // Event manager for status change events.\n private readonly statusChangeEventManager = new TypedEvent();\n // List of references to clean the event listeners.\n private readonly disposables: Disposable[] = [];\n\n public constructor(taskInitiator: AsyncTaskInitiator) {\n this.taskInitiator = taskInitiator;\n }\n\n /**\n * Public setter of the `status` property.\n * @param status.\n */\n public set status(status: AsyncTaskStatus) {\n this._status = status;\n this.statusChangeEventManager.emit(status);\n }\n\n /**\n * Public accessor of the `status` property.\n * @return status.\n */\n public get status() {\n return this._status;\n }\n\n /**\n * Start the async task.\n */\n public init(): void {\n this.cancellable = this.taskInitiator(() => {\n this.status = \"finished\";\n });\n this.status = \"started\";\n }\n\n /**\n * Cancel the async task.\n */\n public cancel(): void {\n this.cancellable.cancel();\n this.status = \"cancelled\";\n }\n\n /**\n * Add an event handler to the status change.\n * @param listener Function which is going to be executed when the status changes.\n */\n public onStatusChange(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.statusChangeEventManager.on(listener);\n this.disposables.push(disposable);\n\n return disposable;\n }\n}\n\n/**\n * Wrap an async task into another which will execute that task indefinitely\n * every time the tash finnish and the chosen period ends.\n * Will last until cancellation.\n *\n * @param task Async task to execute.\n * @param period Time in milliseconds to wait until the next async esecution.\n *\n * @return A new async task.\n */\nfunction asyncPeriodic(task: AsyncTask, period: number): AsyncTask {\n return new AsyncTask(() => {\n let ref: number | null = null;\n\n task.onStatusChange(status => {\n if (status === \"finished\") {\n ref = window.setTimeout(() => {\n task.init();\n }, period);\n }\n });\n\n task.init();\n\n return {\n cancel: () => {\n if (ref) clearTimeout(ref);\n task.cancel();\n }\n };\n });\n}\n\n/**\n * Manages a list of async tasks.\n */\nexport default class AsyncTaskManager {\n private tasks: { [identifier: string]: AsyncTask } = {};\n\n /**\n * Adds an async task to the manager.\n *\n * @param identifier Unique identifier.\n * @param taskInitiator Function to initialize the async task.\n * Should return a structure to cancel the task.\n * @param period Optional period to repeat the task indefinitely.\n */\n public add(\n identifier: string,\n taskInitiator: AsyncTaskInitiator,\n period: number = 0\n ): AsyncTask {\n if (this.tasks[identifier] && this.tasks[identifier].status === \"started\") {\n this.tasks[identifier].cancel();\n }\n\n const asyncTask =\n period > 0\n ? asyncPeriodic(new AsyncTask(taskInitiator), period)\n : new AsyncTask(taskInitiator);\n\n this.tasks[identifier] = asyncTask;\n\n return this.tasks[identifier];\n }\n\n /**\n * Starts an async task.\n *\n * @param identifier Unique identifier.\n */\n public init(identifier: string) {\n if (\n this.tasks[identifier] &&\n (this.tasks[identifier].status === \"waiting\" ||\n this.tasks[identifier].status === \"cancelled\" ||\n this.tasks[identifier].status === \"finished\")\n ) {\n this.tasks[identifier].init();\n }\n }\n\n /**\n * Cancel a running async task.\n *\n * @param identifier Unique identifier.\n */\n public cancel(identifier: string) {\n if (this.tasks[identifier] && this.tasks[identifier].status === \"started\") {\n this.tasks[identifier].cancel();\n }\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\";\nimport AsyncTaskManager from \"./lib/AsyncTaskManager\";\n\n// Export the VisualConsole class to the global object.\n// eslint-disable-next-line\n(window as any).VisualConsole = VisualConsole;\n\n// Export the AsyncTaskManager class to the global object.\n// eslint-disable-next-line\n(window as any).AsyncTaskManager = AsyncTaskManager;\n"],"sourceRoot":""} \ No newline at end of file diff --git a/visual_console_client/src/Item.ts b/visual_console_client/src/Item.ts index 7809b5b29d..0b23c8c26a 100644 --- a/visual_console_client/src/Item.ts +++ b/visual_console_client/src/Item.ts @@ -248,7 +248,7 @@ abstract class VisualConsoleItem { * Start the resizement funtionality. * @param element Element to move inside its container. */ - private initResizementListener(element: HTMLElement): void { + protected initResizementListener(element: HTMLElement): void { this.removeResizement = addResizementListener( element, (width: Size["width"], height: Size["height"]) => { diff --git a/visual_console_client/src/items/ModuleGraph.ts b/visual_console_client/src/items/ModuleGraph.ts index ce23785d36..a2882d6c97 100644 --- a/visual_console_client/src/items/ModuleGraph.ts +++ b/visual_console_client/src/items/ModuleGraph.ts @@ -58,6 +58,15 @@ export default class ModuleGraph extends Item { super.resizeElement(width, 0); } + /** + * @override Item.initResizementListener. To disable the functionality. + * Start the resizement funtionality. + * @param element Element to move inside its container. + */ + protected initResizementListener(): void { + // No-Op. Disable the resizement functionality for this item. + } + protected createDomElement(): HTMLElement { const element = document.createElement("div"); element.className = "module-graph"; From 006e0cd4ece0d801522c172e11ae9e4e3f7c5bb0 Mon Sep 17 00:00:00 2001 From: "marcos.alconada" Date: Wed, 26 Jun 2019 12:31:47 +0200 Subject: [PATCH 91/92] Changed js --- .../godmode/reporting/visual_console_builder.editor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/godmode/reporting/visual_console_builder.editor.js b/pandora_console/godmode/reporting/visual_console_builder.editor.js index 85cbd9be5e..ad78900be2 100755 --- a/pandora_console/godmode/reporting/visual_console_builder.editor.js +++ b/pandora_console/godmode/reporting/visual_console_builder.editor.js @@ -254,7 +254,7 @@ function update_button_palette_callback() { var values = {}; values = readFields(); - if (values["map_linked"] == 0) { + if (selectedItem == "static_graph") { if (values["agent"] == "" || values["agent"] == "none") { dialog_message("#message_alert_no_agent"); return false; From c223e0bdad0c11d00d4a5a4bcd2a583b7e0142a3 Mon Sep 17 00:00:00 2001 From: "marcos.alconada" Date: Wed, 26 Jun 2019 12:50:19 +0200 Subject: [PATCH 92/92] Changed js --- .../godmode/reporting/visual_console_builder.editor.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pandora_console/godmode/reporting/visual_console_builder.editor.js b/pandora_console/godmode/reporting/visual_console_builder.editor.js index ad78900be2..a4c18d3737 100755 --- a/pandora_console/godmode/reporting/visual_console_builder.editor.js +++ b/pandora_console/godmode/reporting/visual_console_builder.editor.js @@ -255,9 +255,11 @@ function update_button_palette_callback() { values = readFields(); if (selectedItem == "static_graph") { - if (values["agent"] == "" || values["agent"] == "none") { - dialog_message("#message_alert_no_agent"); - return false; + if (values["map_linked"] == 0) { + if (values["agent"] == "" || values["agent"] == "none") { + dialog_message("#message_alert_no_agent"); + return false; + } } } // TODO VALIDATE DATA