571 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			571 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								head	1.1;
							 | 
						||
| 
								 | 
							
								access;
							 | 
						||
| 
								 | 
							
								symbols;
							 | 
						||
| 
								 | 
							
								locks
							 | 
						||
| 
								 | 
							
									sbosse:1.1; strict;
							 | 
						||
| 
								 | 
							
								comment	@# @;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								1.1
							 | 
						||
| 
								 | 
							
								date	2020.02.03.09.45.01;	author sbosse;	state Exp;
							 | 
						||
| 
								 | 
							
								branches;
							 | 
						||
| 
								 | 
							
								next	;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								desc
							 | 
						||
| 
								 | 
							
								@@
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								1.1
							 | 
						||
| 
								 | 
							
								log
							 | 
						||
| 
								 | 
							
								@.
							 | 
						||
| 
								 | 
							
								@
							 | 
						||
| 
								 | 
							
								text
							 | 
						||
| 
								 | 
							
								@/**
							 | 
						||
| 
								 | 
							
								 **      ==============================
							 | 
						||
| 
								 | 
							
								 **       O           O      O   OOOO
							 | 
						||
| 
								 | 
							
								 **       O           O     O O  O   O
							 | 
						||
| 
								 | 
							
								 **       O           O     O O  O   O
							 | 
						||
| 
								 | 
							
								 **       OOOO   OOOO O     OOO  OOOO
							 | 
						||
| 
								 | 
							
								 **       O   O       O    O   O O   O
							 | 
						||
| 
								 | 
							
								 **       O   O       O    O   O O   O
							 | 
						||
| 
								 | 
							
								 **       OOOO        OOOO O   O OOOO
							 | 
						||
| 
								 | 
							
								 **      ==============================
							 | 
						||
| 
								 | 
							
								 **      Dr. Stefan Bosse http://www.bsslab.de
							 | 
						||
| 
								 | 
							
								 **
							 | 
						||
| 
								 | 
							
								 **      COPYRIGHT: THIS SOFTWARE, EXECUTABLE AND SOURCE CODE IS OWNED
							 | 
						||
| 
								 | 
							
								 **                 BY THE AUTHOR(S).
							 | 
						||
| 
								 | 
							
								 **                 THIS SOURCE CODE MAY NOT BE COPIED, EXTRACTED,
							 | 
						||
| 
								 | 
							
								 **                 MODIFIED, OR OTHERWISE USED IN A CONTEXT
							 | 
						||
| 
								 | 
							
								 **                 OUTSIDE OF THE SOFTWARE SYSTEM.
							 | 
						||
| 
								 | 
							
								 **
							 | 
						||
| 
								 | 
							
								 **    $AUTHORS:     Stefan Bosse
							 | 
						||
| 
								 | 
							
								 **    $INITIAL:     (C) 2006-2019 bLAB
							 | 
						||
| 
								 | 
							
								 **    $CREATED:     5-12-18 by sbosse.
							 | 
						||
| 
								 | 
							
								 **    $VERSION:     1.1.12
							 | 
						||
| 
								 | 
							
								 **
							 | 
						||
| 
								 | 
							
								 **    $INFO:
							 | 
						||
| 
								 | 
							
								 **
							 | 
						||
| 
								 | 
							
								 **  JAM Shell with X11 GUI
							 | 
						||
| 
								 | 
							
								 **
							 | 
						||
| 
								 | 
							
								 **    $ENDOFINFO
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								var Io = Require('com/io');
							 | 
						||
| 
								 | 
							
								var Comp = Require('com/compat');
							 | 
						||
| 
								 | 
							
								var JamShell = Require('shell/shell');
							 | 
						||
| 
								 | 
							
								var X11 = Require('x11/core/x11');
							 | 
						||
| 
								 | 
							
								var Win = Require('x11/win/windows');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if (process.argv.indexOf('-h')>0) 
							 | 
						||
| 
								 | 
							
								  return print('usage: jamxw [-i(ndex) #num] [-p(airing)] [-po(rtoffset) #num] [-cli] [script] [-e(execute) "shell commands"]');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								String.prototype.chunk = function(size) {
							 | 
						||
| 
								 | 
							
								    return [].concat.apply([],
							 | 
						||
| 
								 | 
							
								        this.split('').map(function(x,i){ return i%size ? [] : this.slice(i,i+size) }, this)
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var options = {
							 | 
						||
| 
								 | 
							
								  version:'1.1.12',
							 | 
						||
| 
								 | 
							
								  config1:'config',
							 | 
						||
| 
								 | 
							
								  config2:'setup',
							 | 
						||
| 
								 | 
							
								  config3:'jam',
							 | 
						||
| 
								 | 
							
								  log: {
							 | 
						||
| 
								 | 
							
								    history:20,
							 | 
						||
| 
								 | 
							
								    columns:69,
							 | 
						||
| 
								 | 
							
								    lineheight:15,
							 | 
						||
| 
								 | 
							
								    width:500,
							 | 
						||
| 
								 | 
							
								    height:400,
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  number:'',
							 | 
						||
| 
								 | 
							
								  width: 200,
							 | 
						||
| 
								 | 
							
								  height: 360,
							 | 
						||
| 
								 | 
							
								  button: {
							 | 
						||
| 
								 | 
							
								    height:20,
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  margin : { left:5, right:5, top:5 },
							 | 
						||
| 
								 | 
							
								  shell : {
							 | 
						||
| 
								 | 
							
								    modules : {
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    nameopts : {length:8, memorable:true, lowercase:true},
							 | 
						||
| 
								 | 
							
								    Nameopts : {length:8, memorable:true, uppercase:true},
							 | 
						||
| 
								 | 
							
								    output : console.log,
							 | 
						||
| 
								 | 
							
								    type:'relay',
							 | 
						||
| 
								 | 
							
								    server : true,
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  portoff: 0,
							 | 
						||
| 
								 | 
							
								  pairing: false,
							 | 
						||
| 
								 | 
							
								  nowin  : false,
							 | 
						||
| 
								 | 
							
								  verbose:1,
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var stats = {
							 | 
						||
| 
								 | 
							
								  agents:0,
							 | 
						||
| 
								 | 
							
								  links:0,
							 | 
						||
| 
								 | 
							
								  log:[],
							 | 
						||
| 
								 | 
							
								  msg:[],
							 | 
						||
| 
								 | 
							
								  ports:[],
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if (process.argv.indexOf('-nowin')>0) options.nowin=true;
							 | 
						||
| 
								 | 
							
								if (process.argv.indexOf('-cli')>0) options.nowin=true;
							 | 
						||
| 
								 | 
							
								if (process.argv.indexOf('-p')>0) options.pairing=true;
							 | 
						||
| 
								 | 
							
								if (process.argv.indexOf('-i')>0) options.number=Number(process.argv[process.argv.indexOf('-i')+1]);
							 | 
						||
| 
								 | 
							
								if (process.argv.indexOf('-po')>0) options.portoff=Number(process.argv[process.argv.indexOf('-po')+1]);
							 | 
						||
| 
								 | 
							
								if (!process.env.DISPLAY) options.nowin=true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/** GUI
							 | 
						||
| 
								 | 
							
								  *
							 | 
						||
| 
								 | 
							
								  */
							 | 
						||
| 
								 | 
							
								function gui () {
							 | 
						||
| 
								 | 
							
								  function info (msg) {
							 | 
						||
| 
								 | 
							
								    if (options.verbose) Io.out(msg);
							 | 
						||
| 
								 | 
							
								    var lines = msg.split('\n'); 
							 | 
						||
| 
								 | 
							
								    lines.forEach(function (line) { 
							 | 
						||
| 
								 | 
							
								      if (line.length > options.log.columns) {
							 | 
						||
| 
								 | 
							
								        var first=true;
							 | 
						||
| 
								 | 
							
								        line.chunk(options.log.columns).forEach(function (line2) { stats.log.push(first?line2:" "+line2); first=false; }); 
							 | 
						||
| 
								 | 
							
								      } else stats.log.push(line); 
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    while (stats.log.length > options.log.history) stats.log.shift();
							 | 
						||
| 
								 | 
							
								    if (win2 && win2.visible) updateInfo(win2);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function speak(msg) {
							 | 
						||
| 
								 | 
							
								    if (options.verbose) Io.out(msg);
							 | 
						||
| 
								 | 
							
								    var lines = msg.split('\n'); 
							 | 
						||
| 
								 | 
							
								    lines.forEach(function (line) { stats.msg.push(line) });
							 | 
						||
| 
								 | 
							
								    while (stats.msg.length > options.msg.history) stats.msg.shift();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function updateInfo(win) {
							 | 
						||
| 
								 | 
							
								    var x=options.margin.left, y = win._data.y0, linesW=win._data.lines, i=1;
							 | 
						||
| 
								 | 
							
								    for (i=0;i<options.log.history;i++) {
							 | 
						||
| 
								 | 
							
								      win.modify(linesW[i],{text:stats.log[i]?stats.log[i]:'  '});
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  options.shell.output=info;
							 | 
						||
| 
								 | 
							
								  options.shell.outputAgent=info;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (options.number != '') info('[JXW] I am node number '+options.number)+'.';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var root = Win.windows({});
							 | 
						||
| 
								 | 
							
								  var state = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  root.start(function (err) {
							 | 
						||
| 
								 | 
							
								    info('[JXW] Root windows instance created');
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  if (options.pairing) options.height += 90;
							 | 
						||
| 
								 | 
							
								  var win1 = root.window({width:options.width,height:options.height,title:'JAM'}, function () {
							 | 
						||
| 
								 | 
							
								   info('[JXW] Window 1 exposed');
							 | 
						||
| 
								 | 
							
								   win1.emit('expose');
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  win1.on('keypress',function (key) {
							 | 
						||
| 
								 | 
							
								    if (key=='XK_q') process.exit();
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  var win2
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var width = options.width-options.margin.left-options.margin.right;
							 | 
						||
| 
								 | 
							
								  var y = options.button.height/2+options.margin.top;
							 | 
						||
| 
								 | 
							
								  var WNodeName = win1.add({id:'NodeName',shape:'text',
							 | 
						||
| 
								 | 
							
								            x:options.width/2+options.margin.left*2,
							 | 
						||
| 
								 | 
							
								            y:y,
							 | 
						||
| 
								 | 
							
								            text:"",
							 | 
						||
| 
								 | 
							
								            style:{color:'blue',align:'center',size:14}
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  y += options.button.height+options.margin.top*2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  win1.add({id:'ButtonExit', shape:'button',
							 | 
						||
| 
								 | 
							
								            width:width,
							 | 
						||
| 
								 | 
							
								            height:options.button.height,
							 | 
						||
| 
								 | 
							
								            x:width/2+options.margin.left,
							 | 
						||
| 
								 | 
							
								            y:y,
							 | 
						||
| 
								 | 
							
								            label:{text:'Exit',color:'white'},
							 | 
						||
| 
								 | 
							
								            line: {width: 1,color: 'black'},fill : {color: 'black'},  
							 | 
						||
| 
								 | 
							
								            handler:function () {process.exit()}
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  y += options.button.height+options.margin.top*2;
							 | 
						||
| 
								 | 
							
								  var ButtonStart = win1.add({id:'ButtonStart', shape:'button',
							 | 
						||
| 
								 | 
							
								            width:width,
							 | 
						||
| 
								 | 
							
								            height:options.button.height,
							 | 
						||
| 
								 | 
							
								            x:width/2+options.margin.left,
							 | 
						||
| 
								 | 
							
								            y:y,
							 | 
						||
| 
								 | 
							
								            label:{text:'Start',color:'white'},
							 | 
						||
| 
								 | 
							
								            line: {width: 1,color: 'green'},fill : {color: 'green'},  
							 | 
						||
| 
								 | 
							
								            handler:function () {
							 | 
						||
| 
								 | 
							
								              switch (state) {
							 | 
						||
| 
								 | 
							
								                case 0: 
							 | 
						||
| 
								 | 
							
								                  win1.modify(ButtonStart,
							 | 
						||
| 
								 | 
							
								                    {line: {width: 1,color: 'gray10'},fill : {color: 'gray10'}});
							 | 
						||
| 
								 | 
							
								                  win1.modify(ButtonStop,
							 | 
						||
| 
								 | 
							
								                    {line: {width: 1,color: 'red'},fill : {color: 'red'}});
							 | 
						||
| 
								 | 
							
								                  win1.modify(WStatus1,
							 | 
						||
| 
								 | 
							
								                    {text:"Status:      ON",style:{color:'green'}});
							 | 
						||
| 
								 | 
							
								                  state=1;
							 | 
						||
| 
								 | 
							
								                  cmd.start();
							 | 
						||
| 
								 | 
							
								                  break;
							 | 
						||
| 
								 | 
							
								              }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  y += options.button.height+options.margin.top*2;
							 | 
						||
| 
								 | 
							
								  var ButtonStop = win1.add({id:'ButtonStop', shape:'button',
							 | 
						||
| 
								 | 
							
								            width:width,
							 | 
						||
| 
								 | 
							
								            height:options.button.height,
							 | 
						||
| 
								 | 
							
								            x:width/2+options.margin.left,
							 | 
						||
| 
								 | 
							
								            y:y,
							 | 
						||
| 
								 | 
							
								            label:{text:'Stop',color:'white'},
							 | 
						||
| 
								 | 
							
								            line: {width: 1,color: 'gray10'},fill : {color: 'gray10'},  
							 | 
						||
| 
								 | 
							
								            handler:function () {
							 | 
						||
| 
								 | 
							
								              switch (state) {
							 | 
						||
| 
								 | 
							
								                case 1: 
							 | 
						||
| 
								 | 
							
								                  win1.modify(ButtonStart,
							 | 
						||
| 
								 | 
							
								                    {line: {width: 1,color: 'green'},fill : {color: 'green'}});
							 | 
						||
| 
								 | 
							
								                  win1.modify(ButtonStop,
							 | 
						||
| 
								 | 
							
								                    {line: {width: 1,color: 'gray10'},fill : {color: 'gray10'}});
							 | 
						||
| 
								 | 
							
								                  win1.modify(WStatus1,
							 | 
						||
| 
								 | 
							
								                    {text:"Status:      OFF",style:{color:'red'}});
							 | 
						||
| 
								 | 
							
								                  state=0;
							 | 
						||
| 
								 | 
							
								                  // kill all agents
							 | 
						||
| 
								 | 
							
								                  cmd.kill('*');
							 | 
						||
| 
								 | 
							
								                  cmd.stop();
							 | 
						||
| 
								 | 
							
								                  break;
							 | 
						||
| 
								 | 
							
								              }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  y += options.button.height+options.margin.top*2;
							 | 
						||
| 
								 | 
							
								  var WButtonInfo = win1.add({id:'ButtonInfo', shape:'button',
							 | 
						||
| 
								 | 
							
								            width:width,
							 | 
						||
| 
								 | 
							
								            height:options.button.height,
							 | 
						||
| 
								 | 
							
								            x:width/2+options.margin.left,
							 | 
						||
| 
								 | 
							
								            y:y,
							 | 
						||
| 
								 | 
							
								            label:{text:'Info',color:'white'},
							 | 
						||
| 
								 | 
							
								            line: {width: 1,color: 'gray40'},fill : {color: 'gray40'},  
							 | 
						||
| 
								 | 
							
								            handler:function () {
							 | 
						||
| 
								 | 
							
								              if (!win2) {
							 | 
						||
| 
								 | 
							
								                win2 = root.window({width:options.log.width,height:options.log.height,title:'JAM-'+cmd.name('node')+' LOG'}, function () {
							 | 
						||
| 
								 | 
							
								                  win2.emit('expose');
							 | 
						||
| 
								 | 
							
								                });
							 | 
						||
| 
								 | 
							
								                var x=options.margin.left,y=options.button.height+options.margin.top*2;
							 | 
						||
| 
								 | 
							
								                win2.add({id:'ButtonClose', shape:'button',
							 | 
						||
| 
								 | 
							
								                  width:options.log.width-options.margin.left*2,
							 | 
						||
| 
								 | 
							
								                  height:options.button.height,
							 | 
						||
| 
								 | 
							
								                  x:options.log.width/2,
							 | 
						||
| 
								 | 
							
								                  y:y,
							 | 
						||
| 
								 | 
							
								                  label:{text:'Close',color:'white'},
							 | 
						||
| 
								 | 
							
								                  line: {width: 1,color: 'green'},fill : {color: 'green'},  
							 | 
						||
| 
								 | 
							
								                  handler:function () {
							 | 
						||
| 
								 | 
							
								                    win2.hide();
							 | 
						||
| 
								 | 
							
								                  }
							 | 
						||
| 
								 | 
							
								                });
							 | 
						||
| 
								 | 
							
								                y += options.button.height+options.margin.top*2;
							 | 
						||
| 
								 | 
							
								                win2.add({id:'ButtonClear', shape:'button',
							 | 
						||
| 
								 | 
							
								                  width:options.log.width-options.margin.left*2,
							 | 
						||
| 
								 | 
							
								                  height:options.button.height,
							 | 
						||
| 
								 | 
							
								                  x:options.log.width/2,
							 | 
						||
| 
								 | 
							
								                  y:y,
							 | 
						||
| 
								 | 
							
								                  label:{text:'Clear',color:'white'},
							 | 
						||
| 
								 | 
							
								                  line: {width: 1,color: 'orange'},fill : {color: 'orange'},  
							 | 
						||
| 
								 | 
							
								                  handler:function () {
							 | 
						||
| 
								 | 
							
								                    stats.log=[];
							 | 
						||
| 
								 | 
							
								                    updateInfo(win2);
							 | 
						||
| 
								 | 
							
								                  }
							 | 
						||
| 
								 | 
							
								                });
							 | 
						||
| 
								 | 
							
								                y += options.button.height+options.margin.top*2;
							 | 
						||
| 
								 | 
							
								                var linesW=[];
							 | 
						||
| 
								 | 
							
								                for (var i=0;i<options.log.history;i++) {
							 | 
						||
| 
								 | 
							
								                  linesW.push(win2.add({id:'LogLine'+i,shape:'text',x:x,y:y,text:""}));
							 | 
						||
| 
								 | 
							
								                  y += options.log.lineheight;
							 | 
						||
| 
								 | 
							
								                };
							 | 
						||
| 
								 | 
							
								                win2.on('expose', function () { updateInfo(win2) });
							 | 
						||
| 
								 | 
							
								                win2._data={lines:linesW};
							 | 
						||
| 
								 | 
							
								              } else {
							 | 
						||
| 
								 | 
							
								                win2.show(); updateInfo(win2)
							 | 
						||
| 
								 | 
							
								              }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /********** Status and Stats ***********/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  y += options.button.height+options.margin.top*2;
							 | 
						||
| 
								 | 
							
								  var WStatus1=win1.add({id:'Status1',shape:'text',
							 | 
						||
| 
								 | 
							
								            x:options.margin.left,
							 | 
						||
| 
								 | 
							
								            y:y,
							 | 
						||
| 
								 | 
							
								            text:"Status:      OFF",
							 | 
						||
| 
								 | 
							
								            style:{color:'red',align:'left',size:14}
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  y += options.button.height+options.margin.top;
							 | 
						||
| 
								 | 
							
								  var WStatsLink=win1.add({id:'StatsLink',shape:'text',
							 | 
						||
| 
								 | 
							
								            x:options.margin.left,
							 | 
						||
| 
								 | 
							
								            y:y,
							 | 
						||
| 
								 | 
							
								            text:"Links:       0",
							 | 
						||
| 
								 | 
							
								            style:{color:'black',align:'left',size:14}
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  y += options.button.height+options.margin.top;
							 | 
						||
| 
								 | 
							
								  var WStatsAgent=win1.add({id:'StatsAgent',shape:'text',
							 | 
						||
| 
								 | 
							
								            x:options.margin.left,
							 | 
						||
| 
								 | 
							
								            y:y,
							 | 
						||
| 
								 | 
							
								            text:"Agents:      0",
							 | 
						||
| 
								 | 
							
								            style:{color:'black',align:'left',size:14}
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  y += options.button.height+options.margin.top;
							 | 
						||
| 
								 | 
							
								  var WTime=win1.add({id:'Time',shape:'text',
							 | 
						||
| 
								 | 
							
								            x:options.margin.left,
							 | 
						||
| 
								 | 
							
								            y:y,
							 | 
						||
| 
								 | 
							
								            text:"Time:        0",
							 | 
						||
| 
								 | 
							
								            style:{color:'gray40',align:'left',size:14}
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /************ Ports Info **************/
							 | 
						||
| 
								 | 
							
								  function portinfo(index,proto,port) {
							 | 
						||
| 
								 | 
							
								    // proto = UDP TCP HTP PIP SOC
							 | 
						||
| 
								 | 
							
								    win1.modify('Port'+index,{text:proto+' '+port})
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  function addport(proto,port) {
							 | 
						||
| 
								 | 
							
								    var index = stats.ports.length;
							 | 
						||
| 
								 | 
							
								    stats.ports[index]={proto:proto,port:port};
							 | 
						||
| 
								 | 
							
								    portinfo(index,proto,port);
							 | 
						||
| 
								 | 
							
								    win1.modify('StatsPort',{text:"Ports:       "+(index+1)})
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  function delport(proto,port) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  y += options.button.height+options.margin.top;
							 | 
						||
| 
								 | 
							
								  var WStatsPort=win1.add({id:'StatsPort',shape:'text',
							 | 
						||
| 
								 | 
							
								            x:options.margin.left,
							 | 
						||
| 
								 | 
							
								            y:y,
							 | 
						||
| 
								 | 
							
								            text:"Ports:       0",
							 | 
						||
| 
								 | 
							
								            style:{color:'blue',align:'left',size:14}
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  y += options.button.height;
							 | 
						||
| 
								 | 
							
								  var WPort0=win1.add({id:'Port0',shape:'text',
							 | 
						||
| 
								 | 
							
								            x:options.margin.left,
							 | 
						||
| 
								 | 
							
								            y:y,
							 | 
						||
| 
								 | 
							
								            text:"",
							 | 
						||
| 
								 | 
							
								            style:{color:'blue',align:'left',size:14}
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  var WPort1=win1.add({id:'Port1',shape:'text',
							 | 
						||
| 
								 | 
							
								            x:options.width/2-options.margin.left,
							 | 
						||
| 
								 | 
							
								            y:y,
							 | 
						||
| 
								 | 
							
								            text:"",
							 | 
						||
| 
								 | 
							
								            style:{color:'blue',align:'left',size:14}
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  y += options.button.height;
							 | 
						||
| 
								 | 
							
								  var WPort2=win1.add({id:'Port2',shape:'text',
							 | 
						||
| 
								 | 
							
								            x:options.margin.left,
							 | 
						||
| 
								 | 
							
								            y:y,
							 | 
						||
| 
								 | 
							
								            text:"",
							 | 
						||
| 
								 | 
							
								            style:{color:'blue',align:'left',size:14}
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  var WPort3=win1.add({id:'Port3',shape:'text',
							 | 
						||
| 
								 | 
							
								            x:options.width/2-options.margin.left,
							 | 
						||
| 
								 | 
							
								            y:y,
							 | 
						||
| 
								 | 
							
								            text:"",
							 | 
						||
| 
								 | 
							
								            style:{color:'blue',align:'left',size:14}
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  y += options.button.height;
							 | 
						||
| 
								 | 
							
								  var WPort4=win1.add({id:'Port4',shape:'text',
							 | 
						||
| 
								 | 
							
								            x:options.margin.left,
							 | 
						||
| 
								 | 
							
								            y:y,
							 | 
						||
| 
								 | 
							
								            text:"",
							 | 
						||
| 
								 | 
							
								            style:{color:'blue',align:'left',size:14}
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  var WPort5=win1.add({id:'Port5',shape:'text',
							 | 
						||
| 
								 | 
							
								            x:options.width/2-options.margin.left,
							 | 
						||
| 
								 | 
							
								            y:y,
							 | 
						||
| 
								 | 
							
								            text:"",
							 | 
						||
| 
								 | 
							
								            style:{color:'blue',align:'left',size:14}
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  y += options.button.height;
							 | 
						||
| 
								 | 
							
								  var WPort6=win1.add({id:'Port6',shape:'text',
							 | 
						||
| 
								 | 
							
								            x:options.margin.left,
							 | 
						||
| 
								 | 
							
								            y:y,
							 | 
						||
| 
								 | 
							
								            text:"",
							 | 
						||
| 
								 | 
							
								            style:{color:'blue',align:'left',size:14}
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  var WPort7=win1.add({id:'Port7',shape:'text',
							 | 
						||
| 
								 | 
							
								            x:options.width/2-options.margin.left,
							 | 
						||
| 
								 | 
							
								            y:y,
							 | 
						||
| 
								 | 
							
								            text:"",
							 | 
						||
| 
								 | 
							
								            style:{color:'blue',align:'left',size:14}
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /********** Ports Pairing **********/
							 | 
						||
| 
								 | 
							
								  if (options.pairing) {
							 | 
						||
| 
								 | 
							
								    var PairStates=[]
							 | 
						||
| 
								 | 
							
								    var pairing = false;
							 | 
						||
| 
								 | 
							
								    function pair(dir) {
							 | 
						||
| 
								 | 
							
								      if (pairing) return;
							 | 
						||
| 
								 | 
							
								      switch (PairStates[dir]) {
							 | 
						||
| 
								 | 
							
								        case 0:
							 | 
						||
| 
								 | 
							
								          win1.modify("ButtonPair"+dir,{label:{text:"?"}});
							 | 
						||
| 
								 | 
							
								          PairStates[dir]=1;
							 | 
						||
| 
								 | 
							
								          pairing=true;
							 | 
						||
| 
								 | 
							
								          console.log('Pairing with '+dir+' ..');
							 | 
						||
| 
								 | 
							
								          break;
							 | 
						||
| 
								 | 
							
								        case 1:
							 | 
						||
| 
								 | 
							
								          break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    y += options.button.height+options.margin.top;
							 | 
						||
| 
								 | 
							
								    var WButtonPairNorth = win1.add({id:'ButtonPairNorth', shape:'button',
							 | 
						||
| 
								 | 
							
								              width:40,
							 | 
						||
| 
								 | 
							
								              height:options.button.height,
							 | 
						||
| 
								 | 
							
								              x:width/2,
							 | 
						||
| 
								 | 
							
								              y:y,
							 | 
						||
| 
								 | 
							
								              label:{text:'P',color:'gray40'},
							 | 
						||
| 
								 | 
							
								              line: {width: 1,color: 'gray40'},  
							 | 
						||
| 
								 | 
							
								              handler:function () {pair('North') },
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    PairStates['North']=0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    y += options.button.height+options.margin.top;
							 | 
						||
| 
								 | 
							
								    win1.add({id:'LabelPair',shape:'text',
							 | 
						||
| 
								 | 
							
								              x:options.width/2,
							 | 
						||
| 
								 | 
							
								              y:y,
							 | 
						||
| 
								 | 
							
								              text:"Pair",
							 | 
						||
| 
								 | 
							
								              style:{color:'green',align:'center',size:14}
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    var WButtonPairWest = win1.add({id:'ButtonPairWest', shape:'button',
							 | 
						||
| 
								 | 
							
								              width:40,
							 | 
						||
| 
								 | 
							
								              height:options.button.height,
							 | 
						||
| 
								 | 
							
								              x:40,
							 | 
						||
| 
								 | 
							
								              y:y,
							 | 
						||
| 
								 | 
							
								              label:{text:'P',color:'gray40'},
							 | 
						||
| 
								 | 
							
								              line: {width: 1,color: 'gray40'},  
							 | 
						||
| 
								 | 
							
								              handler:function () {pair('West') },
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    PairStates['West']=0;
							 | 
						||
| 
								 | 
							
								    var WButtonPairEast = win1.add({id:'ButtonPairEast', shape:'button',
							 | 
						||
| 
								 | 
							
								              width:40,
							 | 
						||
| 
								 | 
							
								              height:options.button.height,
							 | 
						||
| 
								 | 
							
								              x:options.width-40,
							 | 
						||
| 
								 | 
							
								              y:y,
							 | 
						||
| 
								 | 
							
								              label:{text:'P',color:'gray40'},
							 | 
						||
| 
								 | 
							
								              line: {width: 1,color: 'gray40'},  
							 | 
						||
| 
								 | 
							
								              handler:function () {pair('East') },
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    PairStates['East']=0;
							 | 
						||
| 
								 | 
							
								    y += options.button.height+options.margin.top*2;
							 | 
						||
| 
								 | 
							
								    var WButtonPairSouth = win1.add({id:'ButtonPairSouth', shape:'button',
							 | 
						||
| 
								 | 
							
								              width:40,
							 | 
						||
| 
								 | 
							
								              height:options.button.height,
							 | 
						||
| 
								 | 
							
								              x:width/2,
							 | 
						||
| 
								 | 
							
								              y:y,
							 | 
						||
| 
								 | 
							
								              label:{text:'P',color:'gray40'},
							 | 
						||
| 
								 | 
							
								              line: {width: 1,color: 'gray40'},  
							 | 
						||
| 
								 | 
							
								              handler:function () {pair('South') },
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    PairStates['South']=0;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var clock=0;
							 | 
						||
| 
								 | 
							
								  setInterval(function () {
							 | 
						||
| 
								 | 
							
								    clock++;
							 | 
						||
| 
								 | 
							
								    win1.modify(WTime,{text:"Time:        "+clock});
							 | 
						||
| 
								 | 
							
								  },1000)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var shell = JamShell(options.shell).init(function () {})
							 | 
						||
| 
								 | 
							
								  shell.on('port', function (dir,addr) {
							 | 
						||
| 
								 | 
							
								    var proto='UDP';
							 | 
						||
| 
								 | 
							
								    switch (addr && addr.proto) {
							 | 
						||
| 
								 | 
							
								      case 'http': proto='HTP'; break;
							 | 
						||
| 
								 | 
							
								      case 'udp':  proto='UDP'; break;
							 | 
						||
| 
								 | 
							
								      case 'tcp':  proto='TCP'; break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    addport(proto,dir.ip)
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  shell.on('link+', function (addr) {
							 | 
						||
| 
								 | 
							
								    stats.links++;
							 | 
						||
| 
								 | 
							
								    win1.modify(WStatsLink,{text:"Links:       "+stats.links});
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  shell.on('link-', function (addr) {
							 | 
						||
| 
								 | 
							
								    stats.links--;
							 | 
						||
| 
								 | 
							
								    win1.modify(WStatsLink,{text:"Links:       "+stats.links});
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  shell.on('agent+', function (addr) {
							 | 
						||
| 
								 | 
							
								    stats.agents++;
							 | 
						||
| 
								 | 
							
								    win1.modify(WStatsAgent,{text:"Agents:      "+stats.agents});
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  shell.on('agent-', function (addr) {
							 | 
						||
| 
								 | 
							
								    stats.agents--;
							 | 
						||
| 
								 | 
							
								    win1.modify(WStatsAgent,{text:"Agents:      "+stats.agents});
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  var cmd = shell.cmd();
							 | 
						||
| 
								 | 
							
								  win1.on('expose',function () {
							 | 
						||
| 
								 | 
							
								    var configured=false;
							 | 
						||
| 
								 | 
							
								    win1.modify(WNodeName,{text:'[ '+cmd.name('node')+' ]'});
							 | 
						||
| 
								 | 
							
								    win1.title('JAM-'+cmd.name('node'));
							 | 
						||
| 
								 | 
							
								    [
							 | 
						||
| 
								 | 
							
								      options.config1+options.number+'.js',
							 | 
						||
| 
								 | 
							
								      options.config2+options.number+'.js',
							 | 
						||
| 
								 | 
							
								      options.config3+options.number+'.js'
							 | 
						||
| 
								 | 
							
								    ].forEach(function (file) {
							 | 
						||
| 
								 | 
							
								      var exists= Io.exists(file);
							 | 
						||
| 
								 | 
							
								      configured |= exists;
							 | 
						||
| 
								 | 
							
								      if (exists) {
							 | 
						||
| 
								 | 
							
								        info('[JXW] Reading configuration script '+file)
							 | 
						||
| 
								 | 
							
								        cmd.script(file);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    if (!configured) {
							 | 
						||
| 
								 | 
							
								      cmd.port(DIR.IP(options.portoff+10001),{proto:'http'})
							 | 
						||
| 
								 | 
							
								      cmd.port(DIR.IP(options.portoff+10002),{proto:'udp'})
							 | 
						||
| 
								 | 
							
								      cmd.port(DIR.IP(options.portoff+10003),{proto:'tcp'})
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  // Linmit number of scheduler loop iterations per one run to give GUI control and update a chance
							 | 
						||
| 
								 | 
							
								  cmd.config({iterations:100})
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/** CLI
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								function cli() {
							 | 
						||
| 
								 | 
							
								  var configured=false;
							 | 
						||
| 
								 | 
							
								  var info = console.log;
							 | 
						||
| 
								 | 
							
								  var shell = JamShell(options.shell).init(function () {})
							 | 
						||
| 
								 | 
							
								  shell.on('port', function (dir,addr) {
							 | 
						||
| 
								 | 
							
								    var proto='UDP';
							 | 
						||
| 
								 | 
							
								    switch (addr && addr.proto) {
							 | 
						||
| 
								 | 
							
								      case 'http': proto='HTP'; break;
							 | 
						||
| 
								 | 
							
								      case 'udp':  proto='UDP'; break;
							 | 
						||
| 
								 | 
							
								      case 'tcp':  proto='TDP'; break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  var cmd = shell.cmd();
							 | 
						||
| 
								 | 
							
								  [
							 | 
						||
| 
								 | 
							
								    options.config1+options.number+'.js',
							 | 
						||
| 
								 | 
							
								    options.config2+options.number+'.js',
							 | 
						||
| 
								 | 
							
								    options.config3+options.number+'.js'
							 | 
						||
| 
								 | 
							
								  ].forEach(function (file) {
							 | 
						||
| 
								 | 
							
								    var exists= Io.exists(file);
							 | 
						||
| 
								 | 
							
								    configured |= exists;
							 | 
						||
| 
								 | 
							
								    if (exists) {
							 | 
						||
| 
								 | 
							
								      info('[JXW] Reading configuration script '+file)
							 | 
						||
| 
								 | 
							
								      cmd.script(file);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  if (!configured) {
							 | 
						||
| 
								 | 
							
								    cmd.port(DIR.IP(options.portoff+10001),{proto:'http'})
							 | 
						||
| 
								 | 
							
								    cmd.port(DIR.IP(options.portoff+10002),{proto:'udp'})
							 | 
						||
| 
								 | 
							
								    cmd.port(DIR.IP(options.portoff+10003),{proto:'tcp'})
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  // Linmit number of scheduler loop iterations per one run to give GUI control and update a chance
							 | 
						||
| 
								 | 
							
								  cmd.config({iterations:100})
							 | 
						||
| 
								 | 
							
								  cmd.start();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if (options.nowin) cli();
							 | 
						||
| 
								 | 
							
								else gui();
							 | 
						||
| 
								 | 
							
								@
							 |