login is possible
This commit is contained in:
		@@ -1,10 +1,10 @@
 | 
			
		||||
/*! @file
 | 
			
		||||
 | 
			
		||||
    @id $Id$
 | 
			
		||||
   @id $Id$
 | 
			
		||||
 | 
			
		||||
    This is the main application as it is fully run in the user's browser.
 | 
			
		||||
   This is the main application as it is fully run in the user's browser.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 */
 | 
			
		||||
//       1         2         3         4         5         6         7         8
 | 
			
		||||
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
 | 
			
		||||
 | 
			
		||||
@@ -14,225 +14,247 @@ var focused = null;
 | 
			
		||||
var docker = new Docker();
 | 
			
		||||
 | 
			
		||||
function htmlenc(html) {
 | 
			
		||||
    return $('<div/>').text(html).html();
 | 
			
		||||
  return $('<div/>').text(html).html();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function htmldec(data) {
 | 
			
		||||
    return $('<div/>').html(data).text();
 | 
			
		||||
  return $('<div/>').html(data).text();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Show error messsage
 | 
			
		||||
/** Fades in an error message and logs to console.
 | 
			
		||||
    @param data (optional) The error can be a string or any structure.
 | 
			
		||||
                Strings are shown to the user, structures are logged only.
 | 
			
		||||
    @param stay (optional) If not given as @c true, reloads page after 5s. */
 | 
			
		||||
   @param data (optional) The error can be a string or any structure.
 | 
			
		||||
   Strings are shown to the user, structures are logged only.
 | 
			
		||||
   @param stay (optional) If not given as @c true, reloads page after 5s. */
 | 
			
		||||
function error(data) {
 | 
			
		||||
    $("#status").fadeOut("slow", function() {
 | 
			
		||||
        $("#status").addClass("error")
 | 
			
		||||
        $("#status").removeClass("notice")
 | 
			
		||||
        $("#status").removeClass("success")
 | 
			
		||||
        if (data) {
 | 
			
		||||
            if (typeof data == 'string') {
 | 
			
		||||
                $("#status").html(data);
 | 
			
		||||
                console.log("error: "+data);
 | 
			
		||||
            } else {
 | 
			
		||||
                $("#status").html('unknown error: '+JSON.stringify(data));
 | 
			
		||||
                console.log("error: ", data);
 | 
			
		||||
                console.log((new Error('stacktrace')));
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            $("#status").html('error');
 | 
			
		||||
            console.log("error");
 | 
			
		||||
        }
 | 
			
		||||
        $("#status").fadeIn("slow");
 | 
			
		||||
    });
 | 
			
		||||
  $("#status").fadeOut("slow", function() {
 | 
			
		||||
    $("#status").addClass("error")
 | 
			
		||||
    $("#status").removeClass("notice")
 | 
			
		||||
    $("#status").removeClass("success")
 | 
			
		||||
    if (data) {
 | 
			
		||||
      if (typeof data == 'string') {
 | 
			
		||||
        $("#status").html(data);
 | 
			
		||||
        console.log("error: "+data);
 | 
			
		||||
      } else {
 | 
			
		||||
        $("#status").html('unknown error: '+JSON.stringify(data));
 | 
			
		||||
        console.log("error: ", data);
 | 
			
		||||
        console.log((new Error('stacktrace')));
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      $("#status").html('error');
 | 
			
		||||
      console.log("error");
 | 
			
		||||
    }
 | 
			
		||||
    $("#status").fadeIn("slow");
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Show notice messsage
 | 
			
		||||
/** Fades in an notice message and logs to console.
 | 
			
		||||
    @param text (optional) The data is a string. */
 | 
			
		||||
   @param text (optional) The data is a string. */
 | 
			
		||||
function notice(text) {
 | 
			
		||||
    $("#status").fadeOut("slow", function() {
 | 
			
		||||
        $("#status").addClass("notice")
 | 
			
		||||
        $("#status").removeClass("error")
 | 
			
		||||
        $("#status").removeClass("success")
 | 
			
		||||
        if (text) {
 | 
			
		||||
            $("#status").html(text);
 | 
			
		||||
            console.log("notice: "+text);
 | 
			
		||||
        } else {
 | 
			
		||||
            $("#status").html('');
 | 
			
		||||
            console.log("notice");
 | 
			
		||||
        }
 | 
			
		||||
        $("#status").fadeIn("slow");
 | 
			
		||||
    });
 | 
			
		||||
  $("#status").fadeOut("slow", function() {
 | 
			
		||||
    $("#status").addClass("notice")
 | 
			
		||||
    $("#status").removeClass("error")
 | 
			
		||||
    $("#status").removeClass("success")
 | 
			
		||||
    if (text) {
 | 
			
		||||
      $("#status").html(text);
 | 
			
		||||
      console.log("notice: "+text);
 | 
			
		||||
    } else {
 | 
			
		||||
      $("#status").html('');
 | 
			
		||||
      console.log("notice");
 | 
			
		||||
    }
 | 
			
		||||
    $("#status").fadeIn("slow");
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Show notice messsage
 | 
			
		||||
/** Fades in an success message and logs to console.
 | 
			
		||||
    @param text (optional) The data is a string. */
 | 
			
		||||
   @param text (optional) The data is a string. */
 | 
			
		||||
function success(text) {
 | 
			
		||||
    $("#status").fadeOut("slow", function() {
 | 
			
		||||
        $("#status").addClass("success")
 | 
			
		||||
        $("#status").removeClass("error")
 | 
			
		||||
        $("#status").removeClass("notice")
 | 
			
		||||
        if (text) {
 | 
			
		||||
            $("#status").html(text);
 | 
			
		||||
            console.log("success: "+text);
 | 
			
		||||
        } else {
 | 
			
		||||
            $("#status").html('');
 | 
			
		||||
            console.log("success");
 | 
			
		||||
        }
 | 
			
		||||
        $("#status").fadeIn("slow");
 | 
			
		||||
    });
 | 
			
		||||
  $("#status").fadeOut("slow", function() {
 | 
			
		||||
    $("#status").addClass("success")
 | 
			
		||||
    $("#status").removeClass("error")
 | 
			
		||||
    $("#status").removeClass("notice")
 | 
			
		||||
    if (text) {
 | 
			
		||||
      $("#status").html(text);
 | 
			
		||||
      console.log("success: "+text);
 | 
			
		||||
    } else {
 | 
			
		||||
      $("#status").html('');
 | 
			
		||||
      console.log("success");
 | 
			
		||||
    }
 | 
			
		||||
    $("#status").fadeIn("slow");
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Show status message in the main screen area
 | 
			
		||||
/** @param text Text is a message or some complex HTML from the server.
 | 
			
		||||
    @param msg The success message text */
 | 
			
		||||
   @param msg The success message text */
 | 
			
		||||
function status(text, msg) {
 | 
			
		||||
    $("#main").hide();
 | 
			
		||||
    $("#main").html(text);
 | 
			
		||||
    if (msg) success(msg);
 | 
			
		||||
    else setTimeout("$('#status').fadeOut('slow')", 5000);
 | 
			
		||||
    zoom(0);
 | 
			
		||||
    stats();
 | 
			
		||||
    $("#main").show();
 | 
			
		||||
    $("form input:first-child").focus();
 | 
			
		||||
    docker.containers.contextmenu("#main");
 | 
			
		||||
  $("#main").hide();
 | 
			
		||||
  $("#main").html(text);
 | 
			
		||||
  if (msg) success(msg);
 | 
			
		||||
  else setTimeout("$('#status').fadeOut('slow')", 5000);
 | 
			
		||||
  zoom(0);
 | 
			
		||||
  $("#main").show();
 | 
			
		||||
  $("form input:first-child").focus();
 | 
			
		||||
  docker.containers.contextmenu("#main");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function emit(signal, data) {
 | 
			
		||||
    console.log("<-snd "+signal, data);
 | 
			
		||||
    socket.emit(signal, data);
 | 
			
		||||
  console.log("<-snd "+signal, data);
 | 
			
		||||
  socket.emit(signal, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function connected() {
 | 
			
		||||
    console.log("server connected");
 | 
			
		||||
    $("#connectionstatus #bad").hide();
 | 
			
		||||
    $("#connectionstatus #good").show();
 | 
			
		||||
    success("server connected");
 | 
			
		||||
function connect() {
 | 
			
		||||
  $("#server").html($("#username").val()+'@'+window.location.hostname)
 | 
			
		||||
  console.log("server connect");
 | 
			
		||||
  $("#connectionstatus #bad").hide();
 | 
			
		||||
  $("#connectionstatus #authentication").show();
 | 
			
		||||
  $("#connectionstatus #good").hide();
 | 
			
		||||
  success("login to server");
 | 
			
		||||
  socket.emit('authentication', {
 | 
			
		||||
    username: $("#username").val(),
 | 
			
		||||
    password: $("#password").val()
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function authenticated() {
 | 
			
		||||
  $("#server").html($("#username").val()+'@'+window.location.hostname)
 | 
			
		||||
  console.log("server authenticated");
 | 
			
		||||
  $("#connectionstatus #bad").hide();
 | 
			
		||||
  $("#connectionstatus #authentication").hide();
 | 
			
		||||
  $("#connectionstatus #good").show();
 | 
			
		||||
  success("server connected");
 | 
			
		||||
  start();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function unauthorized() {
 | 
			
		||||
  $("#server").html($("#username").val()+'@'+window.location.hostname)
 | 
			
		||||
  console.log("authentication failed");
 | 
			
		||||
  $("#connectionstatus #good").hide();
 | 
			
		||||
  $("#connectionstatus #authentication").hide();
 | 
			
		||||
  $("#connectionstatus #bad").show();
 | 
			
		||||
  error("authentication failed", true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function disconnected() {
 | 
			
		||||
    console.log("server disconnected");
 | 
			
		||||
    $("#connectionstatus #good").hide();
 | 
			
		||||
    $("#connectionstatus #bad").show();
 | 
			
		||||
    error("server disconnected", true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function connectionstatus() {
 | 
			
		||||
    if (socket.connected) connected(); else disconnected();
 | 
			
		||||
  $("#server").html($("#username").val()+'@'+window.location.hostname)
 | 
			
		||||
  console.log("server disconnected");
 | 
			
		||||
  $("#connectionstatus #good").hide();
 | 
			
		||||
  $("#connectionstatus #authentication").hide();
 | 
			
		||||
  $("#connectionstatus #bad").show();
 | 
			
		||||
  error("server disconnected", true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Toggle Menu Display
 | 
			
		||||
function togglemenu() {
 | 
			
		||||
    $("#menu").toggle();
 | 
			
		||||
  $("#menu").toggle();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Upload a configuration and send it to server
 | 
			
		||||
function upload(evt) {
 | 
			
		||||
    if (!window.FileReader)
 | 
			
		||||
        return error("your browser does not support file upload", true);
 | 
			
		||||
    for (var i=0, f; f=evt.target.files[i]; ++i) {
 | 
			
		||||
        var file = f;
 | 
			
		||||
        var reader = new FileReader();
 | 
			
		||||
        reader.onload = function(evt) {
 | 
			
		||||
            if (evt.target.error) return error("error reading file", true);
 | 
			
		||||
            if (evt.target.readyState==0) return notice("waiting for data …");
 | 
			
		||||
            if (evt.target.readyState==1) return notice("loading data …");
 | 
			
		||||
            tobecreated = JSON.parse(evt.target.result);
 | 
			
		||||
            showCreate();
 | 
			
		||||
        }
 | 
			
		||||
        reader.readAsText(file);
 | 
			
		||||
  if (!window.FileReader)
 | 
			
		||||
    return error("your browser does not support file upload", true);
 | 
			
		||||
  for (var i=0, f; f=evt.target.files[i]; ++i) {
 | 
			
		||||
    var file = f;
 | 
			
		||||
    var reader = new FileReader();
 | 
			
		||||
    reader.onload = function(evt) {
 | 
			
		||||
      if (evt.target.error) return error("error reading file", true);
 | 
			
		||||
      if (evt.target.readyState==0) return notice("waiting for data …");
 | 
			
		||||
      if (evt.target.readyState==1) return notice("loading data …");
 | 
			
		||||
      tobecreated = JSON.parse(evt.target.result);
 | 
			
		||||
      showCreate();
 | 
			
		||||
    }
 | 
			
		||||
    reader.readAsText(file);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var tobecreated = {};
 | 
			
		||||
function previewCreate() {
 | 
			
		||||
    var name = $('#name').val();
 | 
			
		||||
    var nodes = Object.create(tobecreated);
 | 
			
		||||
    if (name != '') {
 | 
			
		||||
        nodes[name] =  {
 | 
			
		||||
            status: docker.containers.Status.Preview,
 | 
			
		||||
            id: null,
 | 
			
		||||
            name: name,
 | 
			
		||||
            image: {
 | 
			
		||||
                name: $('#image').val(),
 | 
			
		||||
                id: null
 | 
			
		||||
            },
 | 
			
		||||
            ports: $('#createports option').map(function() {return $(this).data();}).get(),
 | 
			
		||||
            env: $('#createvars option').map(function() {return $(this).val();}).get(),
 | 
			
		||||
            volumes: $('#createvolumes option').map(function() {return $(this).data();}).get(),
 | 
			
		||||
            volumesfrom: $('#createvolumefroms option').map(function() {return $(this).val();}).get(),
 | 
			
		||||
            links: $('#createlinks option').map(function() {return $(this).data();}).get(),
 | 
			
		||||
            entrypoint: $('#createentrypoints option').map(function() {return $(this).val();}).get(),
 | 
			
		||||
            cmd: $('#createcommands option').map(function() {return $(this).val();}).get(),
 | 
			
		||||
        };
 | 
			
		||||
        $('#doappend').unbind().click(function() {
 | 
			
		||||
            tobecreated[name] = Object.create(nodes[name]);
 | 
			
		||||
            tobecreated[name].status = docker.containers.Status.Prepared;
 | 
			
		||||
            $('#createpreview').append('<option>'+name+'</option>');
 | 
			
		||||
            $('#create form input[type=text]').val('');
 | 
			
		||||
            $('#create form select.collect option').remove();
 | 
			
		||||
            previewCreate();
 | 
			
		||||
        });
 | 
			
		||||
        $('#doremove').unbind().click(function() {
 | 
			
		||||
            $(this).siblings('#createpreview').children('option:selected').each(function(a,b,c) {
 | 
			
		||||
                delete tobecreated[b.innerHTML];
 | 
			
		||||
            }).remove();
 | 
			
		||||
            previewCreate();
 | 
			
		||||
        });
 | 
			
		||||
        $('#dosend').unbind().click(function() {
 | 
			
		||||
            if (Object.keys(tobecreated).length>0) {
 | 
			
		||||
                emit("create", docker.containers.configuration(tobecreated));
 | 
			
		||||
                tobecreated = {};
 | 
			
		||||
                showImage();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
  var name = $('#name').val();
 | 
			
		||||
  var nodes = Object.create(tobecreated);
 | 
			
		||||
  if (name != '') {
 | 
			
		||||
    nodes[name] =  {
 | 
			
		||||
      status: docker.containers.Status.Preview,
 | 
			
		||||
      id: null,
 | 
			
		||||
      name: name,
 | 
			
		||||
      image: {
 | 
			
		||||
        name: $('#image').val(),
 | 
			
		||||
        id: null
 | 
			
		||||
      },
 | 
			
		||||
      ports: $('#createports option').map(function() {return $(this).data();}).get(),
 | 
			
		||||
      env: $('#createvars option').map(function() {return $(this).val();}).get(),
 | 
			
		||||
      volumes: $('#createvolumes option').map(function() {return $(this).data();}).get(),
 | 
			
		||||
      volumesfrom: $('#createvolumefroms option').map(function() {return $(this).val();}).get(),
 | 
			
		||||
      links: $('#createlinks option').map(function() {return $(this).data();}).get(),
 | 
			
		||||
      entrypoint: $('#createentrypoints option').map(function() {return $(this).val();}).get(),
 | 
			
		||||
      cmd: $('#createcommands option').map(function() {return $(this).val();}).get(),
 | 
			
		||||
    };
 | 
			
		||||
    $('#doappend').unbind().click(function() {
 | 
			
		||||
      tobecreated[name] = Object.create(nodes[name]);
 | 
			
		||||
      tobecreated[name].status = docker.containers.Status.Prepared;
 | 
			
		||||
      $('#createpreview').append('<option>'+name+'</option>');
 | 
			
		||||
      $('#create form input[type=text]').val('');
 | 
			
		||||
      $('#create form select.collect option').remove();
 | 
			
		||||
      previewCreate();
 | 
			
		||||
    });
 | 
			
		||||
    $('#doremove').unbind().click(function() {
 | 
			
		||||
      $(this).siblings('#createpreview').children('option:selected').each(function(a,b,c) {
 | 
			
		||||
        delete tobecreated[b.innerHTML];
 | 
			
		||||
      }).remove();
 | 
			
		||||
      previewCreate();
 | 
			
		||||
    });
 | 
			
		||||
    $('#dosend').unbind().click(function() {
 | 
			
		||||
      if (Object.keys(tobecreated).length>0) {
 | 
			
		||||
        emit("create", docker.containers.configuration(tobecreated));
 | 
			
		||||
        tobecreated = {};
 | 
			
		||||
        showImage();
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
  if ($('#image').val()!='') {
 | 
			
		||||
    var img = docker.images.get($('#image').val());
 | 
			
		||||
    if (img) {
 | 
			
		||||
      $('#portintdata').empty().append(img.ports.map(function(i) {
 | 
			
		||||
        var option =  document.createElement('option');
 | 
			
		||||
        option.value = i.replace(/\/.*/g, '');
 | 
			
		||||
        return option;
 | 
			
		||||
      }));
 | 
			
		||||
      $('#varnamedata').empty().append(img.env.map(function(i) {
 | 
			
		||||
        var option =  document.createElement('option');
 | 
			
		||||
        option.value = i.replace(/=.*/g, '');
 | 
			
		||||
        return option;
 | 
			
		||||
      }));
 | 
			
		||||
      $('#varvaluedata').empty().append(img.env.map(function(i) {
 | 
			
		||||
        var option =  document.createElement('option');
 | 
			
		||||
        option.value = i.replace(/^[^=]*=/g, '');
 | 
			
		||||
        return option;
 | 
			
		||||
      }));
 | 
			
		||||
      $('#volumeextdata').empty();
 | 
			
		||||
      $('#volumeintdata').empty();
 | 
			
		||||
      for (i in img.volumes) {
 | 
			
		||||
        var option =  document.createElement('option');
 | 
			
		||||
        option.value = i;
 | 
			
		||||
        $('#volumeextdata').append(option);
 | 
			
		||||
        $('#volumeintdata').append(option);
 | 
			
		||||
      }
 | 
			
		||||
      $('#volumesfromdata').empty().append(docker.containers.names(tobecreated).map(function(i) {
 | 
			
		||||
        var option =  document.createElement('option');
 | 
			
		||||
        option.value = i;
 | 
			
		||||
        return option;
 | 
			
		||||
      }));
 | 
			
		||||
      $('#linkcontainerdata').empty().append(docker.containers.names(tobecreated).map(function(i) {
 | 
			
		||||
        var option =  document.createElement('option');
 | 
			
		||||
        option.value = i;
 | 
			
		||||
        return option;
 | 
			
		||||
      }));
 | 
			
		||||
    }
 | 
			
		||||
    if ($('#image').val()!='') {
 | 
			
		||||
        var img = docker.images.get($('#image').val());
 | 
			
		||||
        if (img) {
 | 
			
		||||
            $('#portintdata').empty().append(img.ports.map(function(i) {
 | 
			
		||||
                var option =  document.createElement('option');
 | 
			
		||||
                option.value = i.replace(/\/.*/g, '');
 | 
			
		||||
                return option;
 | 
			
		||||
            }));
 | 
			
		||||
            $('#varnamedata').empty().append(img.env.map(function(i) {
 | 
			
		||||
                var option =  document.createElement('option');
 | 
			
		||||
                option.value = i.replace(/=.*/g, '');
 | 
			
		||||
                return option;
 | 
			
		||||
            }));
 | 
			
		||||
            $('#varvaluedata').empty().append(img.env.map(function(i) {
 | 
			
		||||
                var option =  document.createElement('option');
 | 
			
		||||
                option.value = i.replace(/^[^=]*=/g, '');
 | 
			
		||||
                return option;
 | 
			
		||||
            }));
 | 
			
		||||
            $('#volumeextdata').empty();
 | 
			
		||||
            $('#volumeintdata').empty();
 | 
			
		||||
            for (i in img.volumes) {
 | 
			
		||||
                var option =  document.createElement('option');
 | 
			
		||||
                option.value = i;
 | 
			
		||||
                $('#volumeextdata').append(option);
 | 
			
		||||
                $('#volumeintdata').append(option);
 | 
			
		||||
            }
 | 
			
		||||
            $('#volumesfromdata').empty().append(docker.containers.names(tobecreated).map(function(i) {
 | 
			
		||||
                var option =  document.createElement('option');
 | 
			
		||||
                option.value = i;
 | 
			
		||||
                return option;
 | 
			
		||||
            }));
 | 
			
		||||
            $('#linkcontainerdata').empty().append(docker.containers.names(tobecreated).map(function(i) {
 | 
			
		||||
                var option =  document.createElement('option');
 | 
			
		||||
                option.value = i;
 | 
			
		||||
                return option;
 | 
			
		||||
            }));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (name=='' && nodes) for (name in nodes) break;
 | 
			
		||||
    if (name && name!='') $('#preview').html(Viz("digraph {\n"+"  rankdir="+rankdir+";\n"
 | 
			
		||||
                                                 +docker.containers.subgraph(name, nodes)
 | 
			
		||||
                                                 +"\n}"));
 | 
			
		||||
    else $('#preview').html('');
 | 
			
		||||
  }
 | 
			
		||||
  if (name=='' && nodes) for (name in nodes) break;
 | 
			
		||||
  if (name && name!='') $('#preview').html(Viz("digraph {\n"+"  rankdir="+rankdir+";\n"
 | 
			
		||||
                                              +docker.containers.subgraph(name, nodes)
 | 
			
		||||
                                              +"\n}"));
 | 
			
		||||
  else $('#preview').html('');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function create() {
 | 
			
		||||
@@ -240,389 +262,401 @@ function create() {
 | 
			
		||||
 | 
			
		||||
var zoomlevel = 0;
 | 
			
		||||
function zoom(incr = 0) {
 | 
			
		||||
    zoomlevel = (zoomlevel+incr)%2;
 | 
			
		||||
    switch (zoomlevel) {
 | 
			
		||||
        case 0: {
 | 
			
		||||
            $("#main svg, #preview svg").css("width", "auto");
 | 
			
		||||
            $("#main svg, #preview svg").css("height", "auto");
 | 
			
		||||
            $("#main svg, #preview svg").css("max-width", "100%");
 | 
			
		||||
            $("#main svg, #preview svg").css("max-height", "100%");
 | 
			
		||||
        } break;
 | 
			
		||||
        case 1: {
 | 
			
		||||
            $("#main svg, #preview svg").css("width", "100%");
 | 
			
		||||
            $("#main svg, #preview svg").css("height", "auto");
 | 
			
		||||
            $("#main svg, #preview svg").css("max-width", "100%");
 | 
			
		||||
            $("#main svg, #preview svg").css("max-height", "none");
 | 
			
		||||
        } break;
 | 
			
		||||
        case 2: {
 | 
			
		||||
            $("#main.svg, #preview svg").css("width", "auto");
 | 
			
		||||
            $("#main.svg, #preview svg").css("height", "100%");
 | 
			
		||||
            $("#main.svg, #preview svg").css("max-width", "none");
 | 
			
		||||
            $("#main.svg, #preview svg").css("max-height", "100%");
 | 
			
		||||
        } break;
 | 
			
		||||
    }
 | 
			
		||||
  zoomlevel = (zoomlevel+incr)%2;
 | 
			
		||||
  switch (zoomlevel) {
 | 
			
		||||
    case 0: {
 | 
			
		||||
      $("#main svg, #preview svg").css("width", "auto");
 | 
			
		||||
      $("#main svg, #preview svg").css("height", "auto");
 | 
			
		||||
      $("#main svg, #preview svg").css("max-width", "100%");
 | 
			
		||||
      $("#main svg, #preview svg").css("max-height", "100%");
 | 
			
		||||
    } break;
 | 
			
		||||
    case 1: {
 | 
			
		||||
      $("#main svg, #preview svg").css("width", "100%");
 | 
			
		||||
      $("#main svg, #preview svg").css("height", "auto");
 | 
			
		||||
      $("#main svg, #preview svg").css("max-width", "100%");
 | 
			
		||||
      $("#main svg, #preview svg").css("max-height", "none");
 | 
			
		||||
    } break;
 | 
			
		||||
    case 2: {
 | 
			
		||||
      $("#main.svg, #preview svg").css("width", "auto");
 | 
			
		||||
      $("#main.svg, #preview svg").css("height", "100%");
 | 
			
		||||
      $("#main.svg, #preview svg").css("max-width", "none");
 | 
			
		||||
      $("#main.svg, #preview svg").css("max-height", "100%");
 | 
			
		||||
    } break;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var viz = null;
 | 
			
		||||
var vizmore = null;
 | 
			
		||||
var rankdir = "LR";
 | 
			
		||||
function rotateviz() {
 | 
			
		||||
    if (!viz) return;
 | 
			
		||||
    if (rankdir == "LR")
 | 
			
		||||
        rankdir = "TB";
 | 
			
		||||
    else
 | 
			
		||||
        rankdir = "LR";
 | 
			
		||||
    showviz();
 | 
			
		||||
    previewCreate();
 | 
			
		||||
  if (!viz) return;
 | 
			
		||||
  if (rankdir == "LR")
 | 
			
		||||
    rankdir = "TB";
 | 
			
		||||
  else
 | 
			
		||||
    rankdir = "LR";
 | 
			
		||||
  showviz();
 | 
			
		||||
  previewCreate();
 | 
			
		||||
}
 | 
			
		||||
function showviz(vizpath, more) {
 | 
			
		||||
    if (!vizpath) {
 | 
			
		||||
        vizpath = viz;
 | 
			
		||||
        more = vizmore;
 | 
			
		||||
    } else {
 | 
			
		||||
        viz = vizpath;
 | 
			
		||||
        vizmore = more;
 | 
			
		||||
    }
 | 
			
		||||
    res = "digraph {\n"+"  rankdir="+rankdir+";\n"+viz+"\n}";
 | 
			
		||||
    try {
 | 
			
		||||
        status(more?Viz(res)+more:Viz(res));
 | 
			
		||||
        $('#main a > ellipse + text').attr('font-size', '12');
 | 
			
		||||
        $('#main a > ellipse + text + text')
 | 
			
		||||
            .attr('font-weight', 'bold')
 | 
			
		||||
            .attr('font-size', '16')
 | 
			
		||||
            .each(function() {$(this).attr('y', parseFloat($(this).attr('y'))+1.0)});
 | 
			
		||||
        $('#main a > ellipse + text + text + text').attr('font-size', '12');
 | 
			
		||||
    } catch(e) {
 | 
			
		||||
        (res = res.split("\n")).forEach(function(v, i, a) {
 | 
			
		||||
            a[i] = ("000"+(i+1)).slice(-3)+": "+v;
 | 
			
		||||
        });
 | 
			
		||||
        status("<h2>Exception Caught:</h2><p>"+e+"<p><pre>"+res.join("\n")+"</pre>");
 | 
			
		||||
    }
 | 
			
		||||
  if (!vizpath) {
 | 
			
		||||
    vizpath = viz;
 | 
			
		||||
    more = vizmore;
 | 
			
		||||
  } else {
 | 
			
		||||
    viz = vizpath;
 | 
			
		||||
    vizmore = more;
 | 
			
		||||
  }
 | 
			
		||||
  res = "digraph {\n"+"  rankdir="+rankdir+";\n"+viz+"\n}";
 | 
			
		||||
  try {
 | 
			
		||||
    status(more?Viz(res)+more:Viz(res));
 | 
			
		||||
    $('#main a > ellipse + text').attr('font-size', '12');
 | 
			
		||||
    $('#main a > ellipse + text + text')
 | 
			
		||||
      .attr('font-weight', 'bold')
 | 
			
		||||
      .attr('font-size', '16')
 | 
			
		||||
      .each(function() {$(this).attr('y', parseFloat($(this).attr('y'))+1.0)});
 | 
			
		||||
    $('#main a > ellipse + text + text + text').attr('font-size', '12');
 | 
			
		||||
  } catch(e) {
 | 
			
		||||
    (res = res.split("\n")).forEach(function(v, i, a) {
 | 
			
		||||
      a[i] = ("000"+(i+1)).slice(-3)+": "+v;
 | 
			
		||||
    });
 | 
			
		||||
    status("<h2>Exception Caught:</h2><p>"+e+"<p><pre>"+res.join("\n")+"</pre>");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function details(name) {
 | 
			
		||||
    if (name) focused = name;
 | 
			
		||||
    else if (!focused) return overview();
 | 
			
		||||
    showviz(docker.containers.subgraph(focused));
 | 
			
		||||
  if (name) focused = name;
 | 
			
		||||
  else if (!focused) return overview();
 | 
			
		||||
  showviz(docker.containers.subgraph(focused));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Convert number of bytes to readable text
 | 
			
		||||
function size(num) {
 | 
			
		||||
    if (num>0.6*1024) {
 | 
			
		||||
        if (num>0.6*1024*1024) {
 | 
			
		||||
            if (num>0.6*1024*1024*1024) {
 | 
			
		||||
                if (num>0.6*1024*1024*1024*1024) {
 | 
			
		||||
                    return Math.round(num/1024/1024/1024/1024)+"TB";
 | 
			
		||||
                } else {
 | 
			
		||||
                    return Math.round(num/1024/1024/1024)+"GB";
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                return Math.round(num/1024/1024)+"MB";
 | 
			
		||||
            }
 | 
			
		||||
  if (num>0.6*1024) {
 | 
			
		||||
    if (num>0.6*1024*1024) {
 | 
			
		||||
      if (num>0.6*1024*1024*1024) {
 | 
			
		||||
        if (num>0.6*1024*1024*1024*1024) {
 | 
			
		||||
          return Math.round(num/1024/1024/1024/1024)+"TB";
 | 
			
		||||
        } else {
 | 
			
		||||
            return Math.round(num/1024)+"kB";
 | 
			
		||||
          return Math.round(num/1024/1024/1024)+"GB";
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        return Math.round(num/1024/1024)+"MB";
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
        return num+"B";
 | 
			
		||||
      return Math.round(num/1024)+"kB";
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    return num+"B";
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var oldoldstats = null;
 | 
			
		||||
var oldstats = null;
 | 
			
		||||
function stats(data) {
 | 
			
		||||
    console.log("->rcv stats");
 | 
			
		||||
    if (!data && oldstats && oldoldstats) {
 | 
			
		||||
        data = oldstats;
 | 
			
		||||
        oldstats = oldoldstats;
 | 
			
		||||
    }
 | 
			
		||||
    if (oldstats) for (name in data) {
 | 
			
		||||
        var s = data[name];
 | 
			
		||||
        var o = oldstats[name];
 | 
			
		||||
        if (!o|| !s) continue;
 | 
			
		||||
        $('#main text + text:contains("'+name+'") + text')
 | 
			
		||||
            .html('cpu: '
 | 
			
		||||
                  +(Math.round((s.cpuacct.usage.data-o.cpuacct.usage.data)
 | 
			
		||||
                               /(s.cpuacct.usage.date-o.cpuacct.usage.date)
 | 
			
		||||
                               /100)
 | 
			
		||||
                    /100)
 | 
			
		||||
                  +'% mem: '
 | 
			
		||||
                  +size(s.memory.usage_in_bytes.data));
 | 
			
		||||
    }
 | 
			
		||||
    oldoldstats = oldstats;
 | 
			
		||||
    oldstats = data;
 | 
			
		||||
  console.log("->rcv stats");
 | 
			
		||||
  if (!data && oldstats && oldoldstats) {
 | 
			
		||||
    data = oldstats;
 | 
			
		||||
    oldstats = oldoldstats;
 | 
			
		||||
  }
 | 
			
		||||
  if (oldstats) for (name in data) {
 | 
			
		||||
    var s = data[name];
 | 
			
		||||
    var o = oldstats[name];
 | 
			
		||||
    if (!o|| !s) continue;
 | 
			
		||||
    $('#main text + text:contains("'+name+'") + text')
 | 
			
		||||
      .html('cpu: '
 | 
			
		||||
           +(Math.round((s.cpuacct.usage.data-o.cpuacct.usage.data)
 | 
			
		||||
             /(s.cpuacct.usage.date-o.cpuacct.usage.date)
 | 
			
		||||
             /100)
 | 
			
		||||
             /100)
 | 
			
		||||
           +'% mem: '
 | 
			
		||||
           +size(s.memory.usage_in_bytes.data));
 | 
			
		||||
  }
 | 
			
		||||
  oldoldstats = oldstats;
 | 
			
		||||
  oldstats = data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function images(i) {
 | 
			
		||||
    console.log("->rcv images");
 | 
			
		||||
    docker.images.set(i);
 | 
			
		||||
    $('#imagedata').empty().append(docker.images.tags().map(function(i) {
 | 
			
		||||
        var option =  document.createElement('option');
 | 
			
		||||
        option.value = i;
 | 
			
		||||
        return option;
 | 
			
		||||
    }));
 | 
			
		||||
  console.log("->rcv images");
 | 
			
		||||
  docker.images.set(i);
 | 
			
		||||
  $('#imagedata').empty().append(docker.images.tags().map(function(i) {
 | 
			
		||||
    var option =  document.createElement('option');
 | 
			
		||||
    option.value = i;
 | 
			
		||||
    return option;
 | 
			
		||||
  }));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function containers(c) {
 | 
			
		||||
    console.log("->rcv containers");
 | 
			
		||||
    docker.containers.set(c);
 | 
			
		||||
    if (focused && docker.containers.exists(focused))
 | 
			
		||||
        details(focused);
 | 
			
		||||
    else
 | 
			
		||||
        overview();
 | 
			
		||||
  console.log("->rcv containers");
 | 
			
		||||
  docker.containers.set(c);
 | 
			
		||||
  if (focused && docker.containers.exists(focused))
 | 
			
		||||
    details(focused);
 | 
			
		||||
  else
 | 
			
		||||
    overview();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function showLogin() {
 | 
			
		||||
  $("#close").hide();
 | 
			
		||||
  $("#console").hide();
 | 
			
		||||
  $("#create").hide();
 | 
			
		||||
  $("#imagetools").hide();
 | 
			
		||||
  $("#login").show();
 | 
			
		||||
  $("#logs").hide();
 | 
			
		||||
  $("#main").hide();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function showImage() {
 | 
			
		||||
    $("#create").hide();
 | 
			
		||||
    $("#logs").hide();
 | 
			
		||||
    $("#console").hide();
 | 
			
		||||
    $("#close").hide();
 | 
			
		||||
    $("#imagetools").show();
 | 
			
		||||
    $("#main").show();
 | 
			
		||||
  $("#close").hide();
 | 
			
		||||
  $("#console").hide();
 | 
			
		||||
  $("#create").hide();
 | 
			
		||||
  $("#imagetools").show();
 | 
			
		||||
  $("#login").hide();
 | 
			
		||||
  $("#logs").hide();
 | 
			
		||||
  $("#main").show();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function showCreate() {
 | 
			
		||||
    $("#main").hide();
 | 
			
		||||
    $("#logs").hide();
 | 
			
		||||
    $("#console").hide();
 | 
			
		||||
    $("#imagetools").show();
 | 
			
		||||
    $("#close").show();
 | 
			
		||||
    $("#create").show();
 | 
			
		||||
    previewCreate();
 | 
			
		||||
  $("#close").show();
 | 
			
		||||
  $("#console").hide();
 | 
			
		||||
  $("#create").show();
 | 
			
		||||
  $("#imagetools").show();
 | 
			
		||||
  $("#login").hide();
 | 
			
		||||
  $("#logs").hide();
 | 
			
		||||
  $("#main").hide();
 | 
			
		||||
  previewCreate();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function showConsole() {
 | 
			
		||||
    $("#main").hide();
 | 
			
		||||
    $("#create").hide();
 | 
			
		||||
    $("#logs").hide();
 | 
			
		||||
    $("#imagetools").hide();
 | 
			
		||||
    $("#console").show();
 | 
			
		||||
    $("#close").show();
 | 
			
		||||
    // $("#command").focus();
 | 
			
		||||
    // $("#command").val("");
 | 
			
		||||
    // if ($("#screen").val()!="") $("#screen").append("\n");
 | 
			
		||||
  $("#close").show();
 | 
			
		||||
  $("#console").show();
 | 
			
		||||
  $("#create").hide();
 | 
			
		||||
  $("#imagetools").hide();
 | 
			
		||||
  $("#login").hide();
 | 
			
		||||
  $("#logs").hide();
 | 
			
		||||
  $("#main").hide();
 | 
			
		||||
  // $("#command").focus();
 | 
			
		||||
  // $("#command").val("");
 | 
			
		||||
  // if ($("#screen").val()!="") $("#screen").append("\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function showLogs() {
 | 
			
		||||
    $("#main").hide();
 | 
			
		||||
    $("#create").hide();
 | 
			
		||||
    $("#console").hide();
 | 
			
		||||
    $("#imagetools").hide();
 | 
			
		||||
    $("#close").show();
 | 
			
		||||
    $("#logs").show();
 | 
			
		||||
  $("#close").show();
 | 
			
		||||
  $("#console").hide();
 | 
			
		||||
  $("#create").hide();
 | 
			
		||||
  $("#imagetools").hide();
 | 
			
		||||
  $("#login").hide();
 | 
			
		||||
  $("#logs").show();
 | 
			
		||||
  $("#main").hide();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function logs(data) {
 | 
			
		||||
    console.log("->rcv logs("+data.name+")");
 | 
			
		||||
    if (data.type=='done') {
 | 
			
		||||
        $("#logs").append('<span class="'+data.type+'">\nDONE</span>');
 | 
			
		||||
    } else {
 | 
			
		||||
        $("#logs").append('<span class="'+data.type+'">'+htmlenc(data.text)+'</span>');
 | 
			
		||||
    }
 | 
			
		||||
  console.log("->rcv logs("+data.name+")");
 | 
			
		||||
  if (data.type=='done') {
 | 
			
		||||
    $("#logs").append('<span class="'+data.type+'">\nDONE</span>');
 | 
			
		||||
  } else {
 | 
			
		||||
    $("#logs").append('<span class="'+data.type+'">'+htmlenc(data.text)+'</span>');
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function strInsert(str, pos, txt) {
 | 
			
		||||
    return str.slice(0, pos)+txt+str.slice(pos);
 | 
			
		||||
  return str.slice(0, pos)+txt+str.slice(pos);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function ansifilter(data) {
 | 
			
		||||
    console.log("ansifilter");
 | 
			
		||||
    var res = data;
 | 
			
		||||
    var pos = -1;
 | 
			
		||||
    var spans = 0;
 | 
			
		||||
    while ((pos=res.indexOf("\x1B[")) >= 0) {
 | 
			
		||||
        var end = res.indexOf("m", pos+2);
 | 
			
		||||
        if (end>0) {
 | 
			
		||||
            var control= res.slice(pos+2, end);
 | 
			
		||||
            res = res.slice(0, pos)+res.slice(end+1);
 | 
			
		||||
            control.split(';').forEach(function(c) {
 | 
			
		||||
                switch (parseInt(c)) {
 | 
			
		||||
                    // set
 | 
			
		||||
                    case 1: res = strInsert(res, pos, '<span class="bold">'); ++spans; break;
 | 
			
		||||
                    case 2: res = strInsert(res, pos, '<span class="dim">'); ++spans; break;
 | 
			
		||||
                    case 4: res = strInsert(res, pos, '<span class="underlined">'); ++spans; break;
 | 
			
		||||
                    case 5: res = strInsert(res, pos, '<span class="blink">'); ++spans; break;
 | 
			
		||||
                    case 7: res = strInsert(res, pos, '<span class="reverse">'); ++spans; break;
 | 
			
		||||
                    case 8: res = strInsert(res, pos, '<span class="hidden">'); ++spans; break;
 | 
			
		||||
                    // reset
 | 
			
		||||
                    case 0: for (;spans;--spans) res = strInsert(res, pos, "</span>"); break;
 | 
			
		||||
                    case 21: if (spans) --spans; res = strInsert(res, pos, "</span>"); break;
 | 
			
		||||
                    case 22: if (spans) --spans; res = strInsert(res, pos, "</span>"); break;
 | 
			
		||||
                    case 23: if (spans) --spans; res = strInsert(res, pos, "</span>"); break;
 | 
			
		||||
                    case 25: if (spans) --spans; res = strInsert(res, pos, "</span>"); break;
 | 
			
		||||
                    case 27: if (spans) --spans; res = strInsert(res, pos, "</span>"); break;
 | 
			
		||||
                    case 28: if (spans) --spans; res = strInsert(res, pos, "</span>"); break;
 | 
			
		||||
                    // fg colors
 | 
			
		||||
                    case 39: res = strInsert(res, pos, '<span class="fgdefault">'); ++spans; break;
 | 
			
		||||
                    case 30: res = strInsert(res, pos, '<span class="fgblack">'); ++spans; break;
 | 
			
		||||
                    case 31: res = strInsert(res, pos, '<span class="fgred">'); ++spans; break;
 | 
			
		||||
                    case 32: res = strInsert(res, pos, '<span class="fggreen">'); ++spans; break;
 | 
			
		||||
                    case 33: res = strInsert(res, pos, '<span class="fgyellow">'); ++spans; break;
 | 
			
		||||
                    case 34: res = strInsert(res, pos, '<span class="fgblue">'); ++spans; break;
 | 
			
		||||
                    case 35: res = strInsert(res, pos, '<span class="fgmagenta">'); ++spans; break;
 | 
			
		||||
                    case 36: res = strInsert(res, pos, '<span class="fgcyan">'); ++spans; break;
 | 
			
		||||
                    case 37: res = strInsert(res, pos, '<span class="fglightgrey">'); ++spans; break;
 | 
			
		||||
                    case 90: res = strInsert(res, pos, '<span class="fgdarkgrey">'); ++spans; break;
 | 
			
		||||
                    case 91: res = strInsert(res, pos, '<span class="fglightred">'); ++spans; break;
 | 
			
		||||
                    case 92: res = strInsert(res, pos, '<span class="fglightgreen">'); ++spans; break;
 | 
			
		||||
                    case 93: res = strInsert(res, pos, '<span class="fglightyellow">'); ++spans; break;
 | 
			
		||||
                    case 94: res = strInsert(res, pos, '<span class="fglightblue">'); ++spans; break;
 | 
			
		||||
                    case 95: res = strInsert(res, pos, '<span class="fglightmagenta">'); ++spans; break;
 | 
			
		||||
                    case 96: res = strInsert(res, pos, '<span class="fglightcyan">'); ++spans; break;
 | 
			
		||||
                    case 97: res = strInsert(res, pos, '<span class="fgwhite">'); ++spans; break;
 | 
			
		||||
                    // bg colors
 | 
			
		||||
                    case 49: res = strInsert(res, pos, '<span class="bgdefault">'); ++spans; break;
 | 
			
		||||
                    case 40: res = strInsert(res, pos, '<span class="bgblack">'); ++spans; break;
 | 
			
		||||
                    case 41: res = strInsert(res, pos, '<span class="bgred">'); ++spans; break;
 | 
			
		||||
                    case 42: res = strInsert(res, pos, '<span class="bggreen">'); ++spans; break;
 | 
			
		||||
                    case 43: res = strInsert(res, pos, '<span class="bgyellow">'); ++spans; break;
 | 
			
		||||
                    case 44: res = strInsert(res, pos, '<span class="bgblue">'); ++spans; break;
 | 
			
		||||
                    case 45: res = strInsert(res, pos, '<span class="bgmagenta">'); ++spans; break;
 | 
			
		||||
                    case 46: res = strInsert(res, pos, '<span class="bgcyan">'); ++spans; break;
 | 
			
		||||
                    case 47: res = strInsert(res, pos, '<span class="bglightgrey">'); ++spans; break;
 | 
			
		||||
                    case 100: res = strInsert(res, pos, '<span class="bgdarkgrey">'); ++spans; break;
 | 
			
		||||
                    case 101: res = strInsert(res, pos, '<span class="bglightred">'); ++spans; break;
 | 
			
		||||
                    case 102: res = strInsert(res, pos, '<span class="bglightgreen">'); ++spans; break;
 | 
			
		||||
                    case 103: res = strInsert(res, pos, '<span class="bglightyellow">'); ++spans; break;
 | 
			
		||||
                    case 104: res = strInsert(res, pos, '<span class="bglightblue">'); ++spans; break;
 | 
			
		||||
                    case 105: res = strInsert(res, pos, '<span class="bglightmagenta">'); ++spans; break;
 | 
			
		||||
                    case 106: res = strInsert(res, pos, '<span class="bglightcyan">'); ++spans; break;
 | 
			
		||||
                    case 107: res = strInsert(res, pos, '<span class="bgwhite">'); ++spans; break;
 | 
			
		||||
                    
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            break;
 | 
			
		||||
  console.log("ansifilter");
 | 
			
		||||
  var res = data;
 | 
			
		||||
  var pos = -1;
 | 
			
		||||
  var spans = 0;
 | 
			
		||||
  while ((pos=res.indexOf("\x1B[")) >= 0) {
 | 
			
		||||
    var end = res.indexOf("m", pos+2);
 | 
			
		||||
    if (end>0) {
 | 
			
		||||
      var control= res.slice(pos+2, end);
 | 
			
		||||
      res = res.slice(0, pos)+res.slice(end+1);
 | 
			
		||||
      control.split(';').forEach(function(c) {
 | 
			
		||||
        switch (parseInt(c)) {
 | 
			
		||||
            // set
 | 
			
		||||
          case 1: res = strInsert(res, pos, '<span class="bold">'); ++spans; break;
 | 
			
		||||
          case 2: res = strInsert(res, pos, '<span class="dim">'); ++spans; break;
 | 
			
		||||
          case 4: res = strInsert(res, pos, '<span class="underlined">'); ++spans; break;
 | 
			
		||||
          case 5: res = strInsert(res, pos, '<span class="blink">'); ++spans; break;
 | 
			
		||||
          case 7: res = strInsert(res, pos, '<span class="reverse">'); ++spans; break;
 | 
			
		||||
          case 8: res = strInsert(res, pos, '<span class="hidden">'); ++spans; break;
 | 
			
		||||
            // reset
 | 
			
		||||
          case 0: for (;spans;--spans) res = strInsert(res, pos, "</span>"); break;
 | 
			
		||||
          case 21: if (spans) --spans; res = strInsert(res, pos, "</span>"); break;
 | 
			
		||||
          case 22: if (spans) --spans; res = strInsert(res, pos, "</span>"); break;
 | 
			
		||||
          case 23: if (spans) --spans; res = strInsert(res, pos, "</span>"); break;
 | 
			
		||||
          case 25: if (spans) --spans; res = strInsert(res, pos, "</span>"); break;
 | 
			
		||||
          case 27: if (spans) --spans; res = strInsert(res, pos, "</span>"); break;
 | 
			
		||||
          case 28: if (spans) --spans; res = strInsert(res, pos, "</span>"); break;
 | 
			
		||||
            // fg colors
 | 
			
		||||
          case 39: res = strInsert(res, pos, '<span class="fgdefault">'); ++spans; break;
 | 
			
		||||
          case 30: res = strInsert(res, pos, '<span class="fgblack">'); ++spans; break;
 | 
			
		||||
          case 31: res = strInsert(res, pos, '<span class="fgred">'); ++spans; break;
 | 
			
		||||
          case 32: res = strInsert(res, pos, '<span class="fggreen">'); ++spans; break;
 | 
			
		||||
          case 33: res = strInsert(res, pos, '<span class="fgyellow">'); ++spans; break;
 | 
			
		||||
          case 34: res = strInsert(res, pos, '<span class="fgblue">'); ++spans; break;
 | 
			
		||||
          case 35: res = strInsert(res, pos, '<span class="fgmagenta">'); ++spans; break;
 | 
			
		||||
          case 36: res = strInsert(res, pos, '<span class="fgcyan">'); ++spans; break;
 | 
			
		||||
          case 37: res = strInsert(res, pos, '<span class="fglightgrey">'); ++spans; break;
 | 
			
		||||
          case 90: res = strInsert(res, pos, '<span class="fgdarkgrey">'); ++spans; break;
 | 
			
		||||
          case 91: res = strInsert(res, pos, '<span class="fglightred">'); ++spans; break;
 | 
			
		||||
          case 92: res = strInsert(res, pos, '<span class="fglightgreen">'); ++spans; break;
 | 
			
		||||
          case 93: res = strInsert(res, pos, '<span class="fglightyellow">'); ++spans; break;
 | 
			
		||||
          case 94: res = strInsert(res, pos, '<span class="fglightblue">'); ++spans; break;
 | 
			
		||||
          case 95: res = strInsert(res, pos, '<span class="fglightmagenta">'); ++spans; break;
 | 
			
		||||
          case 96: res = strInsert(res, pos, '<span class="fglightcyan">'); ++spans; break;
 | 
			
		||||
          case 97: res = strInsert(res, pos, '<span class="fgwhite">'); ++spans; break;
 | 
			
		||||
            // bg colors
 | 
			
		||||
          case 49: res = strInsert(res, pos, '<span class="bgdefault">'); ++spans; break;
 | 
			
		||||
          case 40: res = strInsert(res, pos, '<span class="bgblack">'); ++spans; break;
 | 
			
		||||
          case 41: res = strInsert(res, pos, '<span class="bgred">'); ++spans; break;
 | 
			
		||||
          case 42: res = strInsert(res, pos, '<span class="bggreen">'); ++spans; break;
 | 
			
		||||
          case 43: res = strInsert(res, pos, '<span class="bgyellow">'); ++spans; break;
 | 
			
		||||
          case 44: res = strInsert(res, pos, '<span class="bgblue">'); ++spans; break;
 | 
			
		||||
          case 45: res = strInsert(res, pos, '<span class="bgmagenta">'); ++spans; break;
 | 
			
		||||
          case 46: res = strInsert(res, pos, '<span class="bgcyan">'); ++spans; break;
 | 
			
		||||
          case 47: res = strInsert(res, pos, '<span class="bglightgrey">'); ++spans; break;
 | 
			
		||||
          case 100: res = strInsert(res, pos, '<span class="bgdarkgrey">'); ++spans; break;
 | 
			
		||||
          case 101: res = strInsert(res, pos, '<span class="bglightred">'); ++spans; break;
 | 
			
		||||
          case 102: res = strInsert(res, pos, '<span class="bglightgreen">'); ++spans; break;
 | 
			
		||||
          case 103: res = strInsert(res, pos, '<span class="bglightyellow">'); ++spans; break;
 | 
			
		||||
          case 104: res = strInsert(res, pos, '<span class="bglightblue">'); ++spans; break;
 | 
			
		||||
          case 105: res = strInsert(res, pos, '<span class="bglightmagenta">'); ++spans; break;
 | 
			
		||||
          case 106: res = strInsert(res, pos, '<span class="bglightcyan">'); ++spans; break;
 | 
			
		||||
          case 107: res = strInsert(res, pos, '<span class="bgwhite">'); ++spans; break;
 | 
			
		||||
            
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    } else {
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    for (;spans;--spans) res += "</span>";
 | 
			
		||||
    console.log(res);
 | 
			
		||||
    return res.replace(/\r\r\n/g, '\n');
 | 
			
		||||
  }
 | 
			
		||||
  for (;spans;--spans) res += "</span>";
 | 
			
		||||
  console.log(res);
 | 
			
		||||
  return res.replace(/\r\r\n/g, '\n');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function ascii(txt) {
 | 
			
		||||
    var res = "";
 | 
			
		||||
    for (i=0; i<txt.length; ++i) {
 | 
			
		||||
        if (res) res += ",";
 | 
			
		||||
        res += txt.charCodeAt(i).toString();
 | 
			
		||||
    }
 | 
			
		||||
    return res;
 | 
			
		||||
  var res = "";
 | 
			
		||||
  for (i=0; i<txt.length; ++i) {
 | 
			
		||||
    if (res) res += ",";
 | 
			
		||||
    res += txt.charCodeAt(i).toString();
 | 
			
		||||
  }
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function bash_data(data) {
 | 
			
		||||
    console.log("->rcv bash-data("+data.name+")", data);
 | 
			
		||||
    if (data.type=='done') {
 | 
			
		||||
        $("#screen").append('<span class="'+data.type+'">\nDONE</span>');
 | 
			
		||||
    } else {
 | 
			
		||||
        var buff = "";
 | 
			
		||||
        console.log("ASCII: ", ascii(data.text));
 | 
			
		||||
        for (var i=0; i<data.text.length; ++i) {
 | 
			
		||||
            switch (data.text.charCodeAt(i)) {
 | 
			
		||||
            case 7:
 | 
			
		||||
            case 8:
 | 
			
		||||
                if (buff.length) $("#screen").append(ansifilter(htmlenc(buff)));
 | 
			
		||||
                buff = "";
 | 
			
		||||
                $('#screen').html(function (_,txt) {
 | 
			
		||||
                    return txt.slice(0, -1);
 | 
			
		||||
                });
 | 
			
		||||
                break;
 | 
			
		||||
            default: buff += data.text[i];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (buff.length) $("#screen").append(ansifilter(htmlenc(buff)));
 | 
			
		||||
  console.log("->rcv bash-data("+data.name+")", data);
 | 
			
		||||
  if (data.type=='done') {
 | 
			
		||||
    $("#screen").append('<span class="'+data.type+'">\nDONE</span>');
 | 
			
		||||
  } else {
 | 
			
		||||
    var buff = "";
 | 
			
		||||
    console.log("ASCII: ", ascii(data.text));
 | 
			
		||||
    for (var i=0; i<data.text.length; ++i) {
 | 
			
		||||
      switch (data.text.charCodeAt(i)) {
 | 
			
		||||
        case 7:
 | 
			
		||||
        case 8:
 | 
			
		||||
          if (buff.length) $("#screen").append(ansifilter(htmlenc(buff)));
 | 
			
		||||
          buff = "";
 | 
			
		||||
          $('#screen').html(function (_,txt) {
 | 
			
		||||
            return txt.slice(0, -1);
 | 
			
		||||
          });
 | 
			
		||||
          break;
 | 
			
		||||
        default: buff += data.text[i];
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    $("#screen").animate({
 | 
			
		||||
        scrollTop: $("#screen").prop('scrollHeight')
 | 
			
		||||
    }, 500);
 | 
			
		||||
    $("#screen").focus();
 | 
			
		||||
    if (buff.length) $("#screen").append(ansifilter(htmlenc(buff)));
 | 
			
		||||
  }
 | 
			
		||||
  $("#screen").animate({
 | 
			
		||||
    scrollTop: $("#screen").prop('scrollHeight')
 | 
			
		||||
  }, 500);
 | 
			
		||||
  $("#screen").focus();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function overview() {
 | 
			
		||||
    focused = null;
 | 
			
		||||
    showviz(docker.containers.graph());
 | 
			
		||||
  focused = null;
 | 
			
		||||
  showviz(docker.containers.graph());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Initial Function: Startup
 | 
			
		||||
/** Decide whether to login or to create a new user */
 | 
			
		||||
/** To be called after login */
 | 
			
		||||
function start() {
 | 
			
		||||
    $("#imagetools").hide();
 | 
			
		||||
    $("#close").hide();
 | 
			
		||||
    $("#popup").hide();
 | 
			
		||||
    $("#menu").hide();
 | 
			
		||||
    $("#username").html(window.location.hostname)
 | 
			
		||||
    try {
 | 
			
		||||
        status("Starting up ...");
 | 
			
		||||
        emit("images");
 | 
			
		||||
        emit("containers");
 | 
			
		||||
        showImage();
 | 
			
		||||
    } catch (m) {
 | 
			
		||||
        error(m);
 | 
			
		||||
    }
 | 
			
		||||
  $("#imagetools").hide();
 | 
			
		||||
  $("#close").hide();
 | 
			
		||||
  $("#popup").hide();
 | 
			
		||||
  $("#menu").hide();
 | 
			
		||||
  try {
 | 
			
		||||
    status("Starting up ...");
 | 
			
		||||
    emit("images");
 | 
			
		||||
    emit("containers");
 | 
			
		||||
    showImage();
 | 
			
		||||
  } catch (m) {
 | 
			
		||||
    error(m);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function initForms() {
 | 
			
		||||
    $('#create form *').change(previewCreate);
 | 
			
		||||
    $("#create form fieldset .add").unbind().click(function() {
 | 
			
		||||
        $(this).siblings("select.collect")
 | 
			
		||||
            .append('<option '+$(this).siblings("input")
 | 
			
		||||
                    .map(function() {
 | 
			
		||||
                        if (this.hasAttribute('data-name')) {
 | 
			
		||||
                            var res = "";
 | 
			
		||||
                            var obj = this;
 | 
			
		||||
                            this.getAttribute('data-name').split(' ').forEach(function(n) {
 | 
			
		||||
                                res += 'data-'+n+'="'+
 | 
			
		||||
                                    (obj.type!='checkbox'||obj.checked
 | 
			
		||||
  $('#create form *').change(previewCreate);
 | 
			
		||||
  $("#create form fieldset .add").unbind().click(function() {
 | 
			
		||||
    $(this).siblings("select.collect")
 | 
			
		||||
           .append('<option '+$(this).siblings("input")
 | 
			
		||||
                                     .map(function() {
 | 
			
		||||
                                       if (this.hasAttribute('data-name')) {
 | 
			
		||||
                                         var res = "";
 | 
			
		||||
                                         var obj = this;
 | 
			
		||||
                                         this.getAttribute('data-name').split(' ').forEach(function(n) {
 | 
			
		||||
                                           res += 'data-'+n+'="'+
 | 
			
		||||
                                     (obj.type!='checkbox'||obj.checked
 | 
			
		||||
                                     ?obj.value:obj.getAttribute('data-false'))
 | 
			
		||||
                                    .replace(/&/g, '&')
 | 
			
		||||
                                    .replace(/"/g, '"')
 | 
			
		||||
                                    +'"';
 | 
			
		||||
                            })
 | 
			
		||||
                            return res;
 | 
			
		||||
                        } else return '';
 | 
			
		||||
                    }).get().join(' ')+'>'+$(this).siblings("input")
 | 
			
		||||
                    .map(function() {
 | 
			
		||||
                        var val = this.value;
 | 
			
		||||
                        var sep = this.getAttribute('data-separator') || '';
 | 
			
		||||
                        if (this.type=='checkbox' && !this.checked) {
 | 
			
		||||
                            val=''; sep=''
 | 
			
		||||
                        }
 | 
			
		||||
                        return sep+val;
 | 
			
		||||
                    }).get().join('')+'</option>');
 | 
			
		||||
        $(this).siblings("input[type=text]").val('');
 | 
			
		||||
        previewCreate();
 | 
			
		||||
    });    
 | 
			
		||||
    $("#create form fieldset .remove").unbind().click(function() {
 | 
			
		||||
        $(this).siblings('select.collect').children('option:selected').remove();
 | 
			
		||||
        previewCreate();
 | 
			
		||||
    });
 | 
			
		||||
                                             .replace(/&/g, '&')
 | 
			
		||||
                                             .replace(/"/g, '"')
 | 
			
		||||
                                                 +'"';
 | 
			
		||||
                                         })
 | 
			
		||||
                                         return res;
 | 
			
		||||
                                       } else return '';
 | 
			
		||||
                                     }).get().join(' ')+'>'+$(this).siblings("input")
 | 
			
		||||
                                     .map(function() {
 | 
			
		||||
                                       var val = this.value;
 | 
			
		||||
                                       var sep = this.getAttribute('data-separator') || '';
 | 
			
		||||
                                       if (this.type=='checkbox' && !this.checked) {
 | 
			
		||||
                                         val=''; sep=''
 | 
			
		||||
                                       }
 | 
			
		||||
                                       return sep+val;
 | 
			
		||||
                                     }).get().join('')+'</option>');
 | 
			
		||||
    $(this).siblings("input[type=text]").val('');
 | 
			
		||||
    previewCreate();
 | 
			
		||||
  });    
 | 
			
		||||
  $("#create form fieldset .remove").unbind().click(function() {
 | 
			
		||||
    $(this).siblings('select.collect').children('option:selected').remove();
 | 
			
		||||
    previewCreate();
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function init() {
 | 
			
		||||
    $("#logout").attr("href",
 | 
			
		||||
                      window.location.protocol+"//X:X@"
 | 
			
		||||
                      +window.location.hostname
 | 
			
		||||
                      +(window.location.port?":":"")+window.location.port
 | 
			
		||||
                      +window.location.pathname);
 | 
			
		||||
    socket = io.connect();
 | 
			
		||||
    socket.io
 | 
			
		||||
        .on("connect", connected)
 | 
			
		||||
        .on("reconnect", connected)
 | 
			
		||||
        .on("disconnect", disconnected)
 | 
			
		||||
        .on("error", disconnected);
 | 
			
		||||
    socket
 | 
			
		||||
        .on("fail", error)
 | 
			
		||||
        .on("containers", containers)
 | 
			
		||||
        .on("images", images)
 | 
			
		||||
        .on("stats", stats)
 | 
			
		||||
        .on("logs", logs)
 | 
			
		||||
        .on("bash-data", bash_data);
 | 
			
		||||
    initForms();
 | 
			
		||||
    start();
 | 
			
		||||
  socket = io.connect();
 | 
			
		||||
  socket
 | 
			
		||||
    .io
 | 
			
		||||
    .on("connect", connect)
 | 
			
		||||
    .on("reconnect", connect)
 | 
			
		||||
    .on("disconnect", disconnected)
 | 
			
		||||
    .on("error", disconnected);
 | 
			
		||||
  socket
 | 
			
		||||
    .on("authenticated", authenticated)
 | 
			
		||||
    .on("unauthorized", unauthorized)
 | 
			
		||||
    .on("fail", error)
 | 
			
		||||
    .on("containers", containers)
 | 
			
		||||
    .on("images", images)
 | 
			
		||||
    .on("stats", stats)
 | 
			
		||||
    .on("logs", logs)
 | 
			
		||||
    .on("bash-data", bash_data);
 | 
			
		||||
  $("#server").html($("#username").value+'@'+window.location.hostname)
 | 
			
		||||
  initForms();
 | 
			
		||||
  showLogin();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// On Load, Call @ref start
 | 
			
		||||
/*
 | 
			
		||||
 $(window.onbeforeunload = function() {
 | 
			
		||||
    return "Are you sure you want to navigate away?";
 | 
			
		||||
});
 | 
			
		||||
   $(window.onbeforeunload = function() {
 | 
			
		||||
   return "Are you sure you want to navigate away?";
 | 
			
		||||
   });
 | 
			
		||||
 */
 | 
			
		||||
$(init);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user