<commit_before>
function filterMachines(f) {
	$('.machines-buttons .quick-button').removeClass('active');
	$('.machines-buttons .btn-'+f).addClass('active');
	if (f === 'all') f = '*';
	else f = '.'+f;
	$('#machines-loader').isotope( { filter: f } );
}

var cloudlyVMSmanager  = {
    template: '',
    actualMachines: '',
    colors : {
		'#36a9e1':'lightBlue',
		'#78cd51':'green',
		'#333366':'darkGreen',
		'#eae874':'yellow',
		'#fa603d':'lightOrange',
		'#ff5454':'red',
		'#CBD4E4':'silver',
		'#e84c8a':'pink',
		'#000000':'black'
		},
    initAction: function(){
        var $this = this;
        $('#machines-loader').isotope({
            itemSelector: '.vms-machine'
        });
        $.ajax({
            type: 'GET',
            url: '/ajax/cloud/box-template/',
            data: '',
            success: function(res){
                $this.template = res;
                setInterval(function(){
                    $this.loadMachinesData();
                },1000);
            }
        });
    },
    loadMachinesData: function(){
        var actualMachines = $(".vms-machine");

        var $this = this;
        $.ajax({
            type: 'GET',
            url: '/ajax/cloud/vms/',
            data: '',
            success: function(res){
                var jsonData = $.parseJSON(res);
                $this.checkRemoved(jsonData,actualMachines);
                $this.parseMachinesData(jsonData);

            }
        });
    },
    parseMachinesData: function(jsonData){
        var $this = this;
        if(jsonData){
            $.each(jsonData,function(vms,data){
                //exist VMS
                if($('#'+vms).length){
                    $this.updateVMS(vms,data);
                }
                else {
                    $this.addVMS(vms,data);
                }
            });
        }
    },
    updateVMS: function(vms,data){
        chartStatElement($('#'+vms).find('.chart').html(data.averge));
        $('#'+vms).find('.value').html(data.state);

        var panel = $("#"+vms).find('.panel');
        $.each(this.colors,function(code,color){
                if(panel.hasClass(color) && panel.attr('class').indexOf(data.vmcolor) === -1){

                        $(panel).switchClass(color,data.vmcolor);

                        console.log('VM '+vms+' changed color: '+color+' to: '+data.vmcolor+' and actual has class: '+panel.attr('class'));
                        return;
                }
        });

    },
    addVMS: function(vms,data){
        var template = this.template;
        template = template.replace('{@vmlink@}',data.link);
        template = template.replace('{@vm@}',vms);
        template = template.replace('{@vm@}',vms);
        template = template.replace('{@vmtitle@}',data.vmtitle);
        template = template.replace('{@vmcolor@}',data.vmcolor);
        template = template.replace('{@averge@}',data.averge);
        template = template.replace("{@state@}", data.state);

        template = $(template);
//        console.log(template);
        var prepend = $('#machines-loader').prepend(template);
        chartStatElement($('#'+vms).find('.chart').html(data.averge));
        prepend.isotope( 'reloadItems' ).isotope({ sortBy: 'original-order' });

    },
    checkRemoved: function(machines,actualMachines){
        var machineIds = 'testVMS';
	var $container = $('#machines-loader');
        $.each(machines,function(vms,value){
            machineIds += vms+',';
        });

        $.each(actualMachines,function(index,item){
            var id = $(item).attr('id');
            if(machineIds.indexOf(id) < 0){
                $container.isotope( 'remove', item ).isotope('layout');
            }
        });

    },
    reloadPositions: function(){
            $('#machines-loader').isotope( 'reloadItems' ).isotope({ sortBy: 'original-order' });
    },
    addBlank: function(){
        this.addVMS('testVMS',{"averge":"0.0,0.0,0.0,0.0","state":"Running"});

    }
}

$(document).ready (function() {

	var btns = ['all','critical','offline', 'suspended', 'windows', 'linux', 'bsd', 'private'];
	for (var i = 0; i < btns.length; ++i) {
	    (function(){
		var type = btns[i];
		var btn = $('.machines-buttons .btn-'+type);
		btn.click(function() { filterMachines(type); });
	    })();
	}

        cloudlyVMSmanager.initAction();

});

<commit_msg>an attempt to fix long old kamil's bug<commit_after>
function filterMachines(f) {
	$('.machines-buttons .quick-button').removeClass('active');
	$('.machines-buttons .btn-'+f).addClass('active');
	if (f === 'all') f = '*';
	else f = '.'+f;
	$('#machines-loader').isotope( { filter: f } );
}

var cloudlyVMSmanager  = {
    template: '',
    actualMachines: '',
    colors : {
		'#36a9e1':'lightBlue',
		'#78cd51':'green',
		'#333366':'darkGreen',
		'#eae874':'yellow',
		'#fa603d':'lightOrange',
		'#ff5454':'red',
		'#CBD4E4':'silver',
		'#e84c8a':'pink',
		'#000000':'black'
		},
    initAction: function(){
        var $this = this;
        $('#machines-loader').isotope({
            itemSelector: '.vms-machine'
        });
        $.ajax({
            type: 'GET',
            url: '/ajax/cloud/box-template/',
            data: '',
            success: function(res){
                $this.template = res;
                setInterval(function(){
                    $this.loadMachinesData();
                },1000);
            }
        });
    },
    loadMachinesData: function(){
        var actualMachines = $(".vms-machine");

        var $this = this;
        $.ajax({
            type: 'GET',
            url: '/ajax/cloud/vms/',
            data: '',
            success: function(res){
                var jsonData = $.parseJSON(res);
                $this.checkRemoved(jsonData,actualMachines);
                $this.parseMachinesData(jsonData);

            }
        });
    },
    parseMachinesData: function(jsonData){
        var $this = this;
        if(jsonData){
            $.each(jsonData,function(vms,data){
                //exist VMS
                if($('#'+vms).length){
                    $this.updateVMS(vms,data);
                }
                else {
                    $this.addVMS(vms,data);
                }
            });
        }
    },
    updateVMS: function(vms,data){
        chartStatElement($('#'+vms).find('.chart').html(data.averge));
        $('#'+vms).find('.value').html(data.state);

        var panel = $("#"+vms).find('.panel');
        $.each(this.colors,function(code,color){

                        $(panel).switchClass(color,data.vmcolor);
                        console.log('VM '+vms+' changed color: '+color+' to: '+data.vmcolor+' and actual has class: '+panel.attr('class'));
                        return;
        });

    },
    addVMS: function(vms,data){
        var template = this.template;
        template = template.replace('{@vmlink@}',data.link);
        template = template.replace('{@vm@}',vms);
        template = template.replace('{@vm@}',vms);
        template = template.replace('{@vmtitle@}',data.vmtitle);
        template = template.replace('{@vmcolor@}',data.vmcolor);
        template = template.replace('{@averge@}',data.averge);
        template = template.replace("{@state@}", data.state);

        template = $(template);
//        console.log(template);
        var prepend = $('#machines-loader').prepend(template);
        chartStatElement($('#'+vms).find('.chart').html(data.averge));
        prepend.isotope( 'reloadItems' ).isotope({ sortBy: 'original-order' });

    },
    checkRemoved: function(machines,actualMachines){
        var machineIds = 'testVMS';
	var $container = $('#machines-loader');
        $.each(machines,function(vms,value){
            machineIds += vms+',';
        });

        $.each(actualMachines,function(index,item){
            var id = $(item).attr('id');
            if(machineIds.indexOf(id) < 0){
                $container.isotope( 'remove', item ).isotope('layout');
            }
        });

    },
    reloadPositions: function(){
            $('#machines-loader').isotope( 'reloadItems' ).isotope({ sortBy: 'original-order' });
    },
    addBlank: function(){
        this.addVMS('testVMS',{"averge":"0.0,0.0,0.0,0.0","state":"Running"});

    }
}

$(document).ready (function() {

	var btns = ['all','critical','offline', 'suspended', 'windows', 'linux', 'bsd', 'private'];
	for (var i = 0; i < btns.length; ++i) {
	    (function(){
		var type = btns[i];
		var btn = $('.machines-buttons .btn-'+type);
		btn.click(function() { filterMachines(type); });
	    })();
	}

        cloudlyVMSmanager.initAction();

});

<|endoftext|>


<commit_before>var async = require("async");
var fs = require('fs');
var statusUtility = {};
var path = require('path');
var status;
var DEPLOYMENTS_DIR = '/opt/data/deployments';
var AOI_DIR = '/opt/data/aoi';
var path = require('path');
var njds = require('nodejs-disks');
var recursive = require("recursive-readdir");

var POSM_CONFIG = process.env.POSM_CONFIG || "/etc/posm.json";
var PUBLIC_FILES_DIR = path.resolve("/opt/data/public");

/**
 * Look for status.json file on disk
 * If file doesn't exist, create new status object
 * Initialize status object that persists throughout application
 *
 */
statusUtility.init = function (cb) {
    try {
        var dir = path.join(DEPLOYMENTS_DIR, "status.json");
        fs.readFile(dir, function (err, data) {
            if (err) {
                console.log("status.json does not exist. Creating....");
            }
            // check for text, reset status if fail
            if(data && data.length > 0) {
                // check for valid json, reset status if fail
                try {
                    status = JSON.parse(data);
                } catch (err) {
                    status = {"activeAOI": '', "initialized": false, "error": false, "msg": '', "aoi-list":[], "hard-disks":[]};
                }
            } else {
                status = {"activeAOI": '', "initialized": false, "error": false, "msg": '', "aoi-list":[], "hard-disks":[]};
            }

            // reset any processes stopped midway through
            Object.keys(status).forEach(function(val){
                if (val == 'backup-data' || val == 'aoi-deploy' || val == 'atlas-deploy' || val == 'render-db' || val == 'network-config') {
                    if(status[val].initialized && !status[val].complete){
                        statusUtility.resetProcess(val);
                    }
                }
            });

            // get list of aois
            statusUtility.updateAOIList();

            // get list of hard disks
            statusUtility.getHardDisks();

            // write to disk
            writeStatusToDisk(function(){
                cb();
            });

        });
    } catch (err) {
        console.error('Had trouble reading status.json');
        console.error(err);
    }
};

/**
 * Register a specific admin process
 * @param name
 * @param childProcesses - Array of child processes
 */
statusUtility.registerProcess = function (name, childProcesses) {
    if (status) {
        if (!status[name]) {
            status[name] = {initialized: false, error: false, msg: '', complete: false};
            // check for child processes
            if (childProcesses) {
                childProcesses.forEach(function (n) {
                    status[name][n] = {initialized: false, error: false, msg: '', complete: false, value:""};
                });
            }
        } else if (status[name]){
            // check for child processes
            if (childProcesses) {
                childProcesses.forEach(function (n) {
                    // add child processes if they do not exist
                    if(!status[name][n]) {
                        status[name][n] = {initialized: false, error: false, msg: '', complete: false, value: ""};
                    }
                });
            }
        }
        writeStatusToDisk();
    }
};

/**
 * Update a parent (and child)  process
 * @param parent name
 * @param child name
 * @param obj
 */
statusUtility.update = function (parent, child, obj) {
    if (status) {
        // update parent process object
        if (parent && !child.length) {
            if (status[parent]) {
                // get object properties
                Object.keys(obj).forEach(function (prop) {
                    // set parent property values
                    status[parent][prop] = obj[prop];
                });
            }
        }

        // update child process
        if (parent && child) {
            if (status[parent][child]) {
                // get object properties
                Object.keys(obj).forEach(function (prop) {
                    // set parent property values
                    status[parent][child][prop] = obj[prop];
                });
            }
        }

        // update global status object as apposed to a global status process object
        if (!parent.length && !child.length && obj) {
            Object.keys(obj).forEach(function (prop) {
                status[prop] = obj[prop];
            });
        }
        writeStatusToDisk();
    }
};

/**
 * Reset a parent process
 * @param name
 * @param childProcesses
 */
statusUtility.resetProcess = function (name, childProcesses) {
    if (status) {
        if (status[name]) {
            status[name] = {initialized: false, error: false, msg: '', complete: false};
            // check for child processes
            if (childProcesses) {
                childProcesses.forEach(function (n) {
                    status[name][n] = {initialized: false, error: false, msg: '', complete: false, value:""};
                });
            }
        }
        writeStatusToDisk();
    }
};

/**
 * Reset a child process
 * @param name
 * @param childProcess
 */
statusUtility.resetChildProcess = function (name, childProcess) {
    if (status) {
        if (status[name] && status[name][childProcess]) {
            // check for child processes
            status[name][childProcess] = {initialized: false, error: false, msg: '', complete: false, value:""};
        }
        writeStatusToDisk();
    }
};

/**
 * Get a specific processes status, if no process, just send the entire object
 * @param name
 * @returns {*}
 */
statusUtility.getStatus = function (name) {
    if (status) return (name && status[name]) ? status[name] : status;
};

function writeStatusToDisk(cb) {
    fs.writeFile(DEPLOYMENTS_DIR + '/status.json', JSON.stringify(status, null, 2), function (err) {
        if (err) {
            console.error('Had trouble writing status.json. ' + DEPLOYMENTS_DIR);
        }
        if(cb) cb();
    });
}

statusUtility.getAOIs = function(callback) {
  var parse = function(file, done) {
    return async.waterfall([
      async.apply(fs.readFile, file),
      async.asyncify(JSON.parse)
    ], done);
  };

  var ignoreFunc = function(file, stats) {
    return !stats.isDirectory() && path.basename(file) !== "manifest.json";
  };

  return async.waterfall([
    async.apply(recursive, AOI_DIR, [ignoreFunc]),
    function(paths, done) {
      return async.mapLimit(paths, 10, parse, done);
    }
  ], callback);
};

/**
 * Loop through aoi directory, open up manifest file, & add to aoi-list array in status
 */
statusUtility.updateAOIList = function() {
  return statusUtility.getAOIs(function(err, aois) {
    if (err) {
      return console.warn(err.stack);
    }

    // update status
    statusUtility.update('', '', {"aoi-list": aois});
  });
};

/**
 * Get active AOI directory
 */
statusUtility.getActiveAOI = function () {
    if (status) return status.activeAOI;
};

/**
 * get list of hard disks
 * @type {{}}
 */
statusUtility.getHardDisks = function (){
    njds.drives(function (err, drives) {
        njds.drivesDetail(drives, function (err, data) {
                // update status
                statusUtility.update('','',{"hard-disks": drives});
                writeStatusToDisk();
                return drives;
            }
        );
    });
};

statusUtility.getNetworkStatus = function(callback) {
    return fs.readFile(POSM_CONFIG, "utf-8", function(err, data) {
        if (err) {
            return callback(err);
        }

        var config;
        try {
            config = JSON.parse(data);
        } catch (err) {
            return callback(err);
        }

        const status = {
            wan: {
                iface: config.posm_wan_netif
            },
            lan: {
                iface: config.posm_lan_netif,
                ip: config.posm_lan_ip
            },
            wlan: {
                iface: config.posm_wlan_netif,
                ip: config.posm_wlan_ip
            },
            wifi: {
                ssid: config.posm_ssid,
                wpa_passphrase: config.posm_wpa_passphrase,
                channel: config.posm_wifi_channel,
                "80211n": config.posm_wifi_80211n === "1",
                wpa: parseInt(config.posm_wifi_wpa) === 2,
            },
            hostname: config.posm_hostname,
            fqdn: config.posm_fqdn,
            bridged: config.posm_network_bridged === "1"
        };

        status.osm = {
            fqdn: config.osm_fqdn
        };

        return callback(null, status);
    });
};

statusUtility.getOSMStatus = function(callback) {
  return fs.readFile(POSM_CONFIG, "utf-8", function(err, data) {
      if (err) {
          return callback(err);
      }

      var config;
      try {
          config = JSON.parse(data);
      } catch (err) {
          return callback(err);
      }

      const status = {
          fqdn: config.osm_fqdn
      };

      return callback(null, status);
  });
};

statusUtility.getDeployments = function(callback) {
    return fs.readdir(DEPLOYMENTS_DIR, function(err, entries) {
        if (err) {
            return callback(err);
        }

        return async.filterLimit(entries, 10, function(entry, done) {
            return fs.stat(path.join(DEPLOYMENTS_DIR, entry), function(err, stats) {
              if (err) {
                  return done(err);
              }

                return done(null, stats.isDirectory());
            })
        }, function(err, results) {
            if (err) {
              return callback(err);
            }

            return async.mapLimit(results, 10, function(deployment, done) {
                return fs.readFile(path.join(DEPLOYMENTS_DIR, deployment, "manifest.json"), "utf-8", function(err, data) {
                    if (err) {
                        return callback(err);
                    }

                    try {
                        return done(null, JSON.parse(data));
                    } catch (err) {
                        return done(err);
                    }
                });
            }, callback);
        });
    });
};

statusUtility.getPublicFiles = function(callback) {
  var ignoreFunc = function(file, stats) {
    return path.basename(file)[0] === ".";
  };

  return recursive(PUBLIC_FILES_DIR, [ignoreFunc], function(err, paths) {
    if (err) {
      return callback(err);
    }

    return callback(null, paths.map(function(x) {
      return x.replace(PUBLIC_FILES_DIR + "/", "");
    }).sort());
  });
}

/**
 * Get POSM status.
 */
statusUtility.getPOSMStatus = function(callback) {
    var status = statusUtility.getStatus();

    return async.parallel({
        deployments: statusUtility.getDeployments,
        network: statusUtility.getNetworkStatus,
        osm: statusUtility.getOSMStatus,
        publicFiles: statusUtility.getPublicFiles
    }, function(err, statuses) {
        if (err) {
            return callback(err);
        }

        status.deployments = statuses.deployments;
        status.network = statuses.network;
        status.osm = statuses.osm;
        status.publicFiles = statuses.publicFiles;

        return callback(null, status);
    });
};

module.exports = statusUtility;
<commit_msg>Return an empty list if PUBLIC_FILES_DIR doesn't exist<commit_after>var async = require("async");
var fs = require('fs');
var statusUtility = {};
var path = require('path');
var status;
var DEPLOYMENTS_DIR = '/opt/data/deployments';
var AOI_DIR = '/opt/data/aoi';
var path = require('path');
var njds = require('nodejs-disks');
var recursive = require("recursive-readdir");

var POSM_CONFIG = process.env.POSM_CONFIG || "/etc/posm.json";
var PUBLIC_FILES_DIR = path.resolve("/opt/data/public");

/**
 * Look for status.json file on disk
 * If file doesn't exist, create new status object
 * Initialize status object that persists throughout application
 *
 */
statusUtility.init = function (cb) {
    try {
        var dir = path.join(DEPLOYMENTS_DIR, "status.json");
        fs.readFile(dir, function (err, data) {
            if (err) {
                console.log("status.json does not exist. Creating....");
            }
            // check for text, reset status if fail
            if(data && data.length > 0) {
                // check for valid json, reset status if fail
                try {
                    status = JSON.parse(data);
                } catch (err) {
                    status = {"activeAOI": '', "initialized": false, "error": false, "msg": '', "aoi-list":[], "hard-disks":[]};
                }
            } else {
                status = {"activeAOI": '', "initialized": false, "error": false, "msg": '', "aoi-list":[], "hard-disks":[]};
            }

            // reset any processes stopped midway through
            Object.keys(status).forEach(function(val){
                if (val == 'backup-data' || val == 'aoi-deploy' || val == 'atlas-deploy' || val == 'render-db' || val == 'network-config') {
                    if(status[val].initialized && !status[val].complete){
                        statusUtility.resetProcess(val);
                    }
                }
            });

            // get list of aois
            statusUtility.updateAOIList();

            // get list of hard disks
            statusUtility.getHardDisks();

            // write to disk
            writeStatusToDisk(function(){
                cb();
            });

        });
    } catch (err) {
        console.error('Had trouble reading status.json');
        console.error(err);
    }
};

/**
 * Register a specific admin process
 * @param name
 * @param childProcesses - Array of child processes
 */
statusUtility.registerProcess = function (name, childProcesses) {
    if (status) {
        if (!status[name]) {
            status[name] = {initialized: false, error: false, msg: '', complete: false};
            // check for child processes
            if (childProcesses) {
                childProcesses.forEach(function (n) {
                    status[name][n] = {initialized: false, error: false, msg: '', complete: false, value:""};
                });
            }
        } else if (status[name]){
            // check for child processes
            if (childProcesses) {
                childProcesses.forEach(function (n) {
                    // add child processes if they do not exist
                    if(!status[name][n]) {
                        status[name][n] = {initialized: false, error: false, msg: '', complete: false, value: ""};
                    }
                });
            }
        }
        writeStatusToDisk();
    }
};

/**
 * Update a parent (and child)  process
 * @param parent name
 * @param child name
 * @param obj
 */
statusUtility.update = function (parent, child, obj) {
    if (status) {
        // update parent process object
        if (parent && !child.length) {
            if (status[parent]) {
                // get object properties
                Object.keys(obj).forEach(function (prop) {
                    // set parent property values
                    status[parent][prop] = obj[prop];
                });
            }
        }

        // update child process
        if (parent && child) {
            if (status[parent][child]) {
                // get object properties
                Object.keys(obj).forEach(function (prop) {
                    // set parent property values
                    status[parent][child][prop] = obj[prop];
                });
            }
        }

        // update global status object as apposed to a global status process object
        if (!parent.length && !child.length && obj) {
            Object.keys(obj).forEach(function (prop) {
                status[prop] = obj[prop];
            });
        }
        writeStatusToDisk();
    }
};

/**
 * Reset a parent process
 * @param name
 * @param childProcesses
 */
statusUtility.resetProcess = function (name, childProcesses) {
    if (status) {
        if (status[name]) {
            status[name] = {initialized: false, error: false, msg: '', complete: false};
            // check for child processes
            if (childProcesses) {
                childProcesses.forEach(function (n) {
                    status[name][n] = {initialized: false, error: false, msg: '', complete: false, value:""};
                });
            }
        }
        writeStatusToDisk();
    }
};

/**
 * Reset a child process
 * @param name
 * @param childProcess
 */
statusUtility.resetChildProcess = function (name, childProcess) {
    if (status) {
        if (status[name] && status[name][childProcess]) {
            // check for child processes
            status[name][childProcess] = {initialized: false, error: false, msg: '', complete: false, value:""};
        }
        writeStatusToDisk();
    }
};

/**
 * Get a specific processes status, if no process, just send the entire object
 * @param name
 * @returns {*}
 */
statusUtility.getStatus = function (name) {
    if (status) return (name && status[name]) ? status[name] : status;
};

function writeStatusToDisk(cb) {
    fs.writeFile(DEPLOYMENTS_DIR + '/status.json', JSON.stringify(status, null, 2), function (err) {
        if (err) {
            console.error('Had trouble writing status.json. ' + DEPLOYMENTS_DIR);
        }
        if(cb) cb();
    });
}

statusUtility.getAOIs = function(callback) {
  var parse = function(file, done) {
    return async.waterfall([
      async.apply(fs.readFile, file),
      async.asyncify(JSON.parse)
    ], done);
  };

  var ignoreFunc = function(file, stats) {
    return !stats.isDirectory() && path.basename(file) !== "manifest.json";
  };

  return async.waterfall([
    async.apply(recursive, AOI_DIR, [ignoreFunc]),
    function(paths, done) {
      return async.mapLimit(paths, 10, parse, done);
    }
  ], callback);
};

/**
 * Loop through aoi directory, open up manifest file, & add to aoi-list array in status
 */
statusUtility.updateAOIList = function() {
  return statusUtility.getAOIs(function(err, aois) {
    if (err) {
      return console.warn(err.stack);
    }

    // update status
    statusUtility.update('', '', {"aoi-list": aois});
  });
};

/**
 * Get active AOI directory
 */
statusUtility.getActiveAOI = function () {
    if (status) return status.activeAOI;
};

/**
 * get list of hard disks
 * @type {{}}
 */
statusUtility.getHardDisks = function (){
    njds.drives(function (err, drives) {
        njds.drivesDetail(drives, function (err, data) {
                // update status
                statusUtility.update('','',{"hard-disks": drives});
                writeStatusToDisk();
                return drives;
            }
        );
    });
};

statusUtility.getNetworkStatus = function(callback) {
    return fs.readFile(POSM_CONFIG, "utf-8", function(err, data) {
        if (err) {
            return callback(err);
        }

        var config;
        try {
            config = JSON.parse(data);
        } catch (err) {
            return callback(err);
        }

        const status = {
            wan: {
                iface: config.posm_wan_netif
            },
            lan: {
                iface: config.posm_lan_netif,
                ip: config.posm_lan_ip
            },
            wlan: {
                iface: config.posm_wlan_netif,
                ip: config.posm_wlan_ip
            },
            wifi: {
                ssid: config.posm_ssid,
                wpa_passphrase: config.posm_wpa_passphrase,
                channel: config.posm_wifi_channel,
                "80211n": config.posm_wifi_80211n === "1",
                wpa: parseInt(config.posm_wifi_wpa) === 2,
            },
            hostname: config.posm_hostname,
            fqdn: config.posm_fqdn,
            bridged: config.posm_network_bridged === "1"
        };

        status.osm = {
            fqdn: config.osm_fqdn
        };

        return callback(null, status);
    });
};

statusUtility.getOSMStatus = function(callback) {
  return fs.readFile(POSM_CONFIG, "utf-8", function(err, data) {
      if (err) {
          return callback(err);
      }

      var config;
      try {
          config = JSON.parse(data);
      } catch (err) {
          return callback(err);
      }

      const status = {
          fqdn: config.osm_fqdn
      };

      return callback(null, status);
  });
};

statusUtility.getDeployments = function(callback) {
    return fs.readdir(DEPLOYMENTS_DIR, function(err, entries) {
        if (err) {
            return callback(err);
        }

        return async.filterLimit(entries, 10, function(entry, done) {
            return fs.stat(path.join(DEPLOYMENTS_DIR, entry), function(err, stats) {
              if (err) {
                  return done(err);
              }

                return done(null, stats.isDirectory());
            })
        }, function(err, results) {
            if (err) {
              return callback(err);
            }

            return async.mapLimit(results, 10, function(deployment, done) {
                return fs.readFile(path.join(DEPLOYMENTS_DIR, deployment, "manifest.json"), "utf-8", function(err, data) {
                    if (err) {
                        return callback(err);
                    }

                    try {
                        return done(null, JSON.parse(data));
                    } catch (err) {
                        return done(err);
                    }
                });
            }, callback);
        });
    });
};

statusUtility.getPublicFiles = function(callback) {
  var ignoreFunc = function(file, stats) {
    return path.basename(file)[0] === ".";
  };

  return recursive(PUBLIC_FILES_DIR, [ignoreFunc], function(err, paths) {
    if (err) {
      return callback(null, []);
    }

    return callback(null, paths.map(function(x) {
      return x.replace(PUBLIC_FILES_DIR + "/", "");
    }).sort());
  });
}

/**
 * Get POSM status.
 */
statusUtility.getPOSMStatus = function(callback) {
    var status = statusUtility.getStatus();

    return async.parallel({
        deployments: statusUtility.getDeployments,
        network: statusUtility.getNetworkStatus,
        osm: statusUtility.getOSMStatus,
        publicFiles: statusUtility.getPublicFiles
    }, function(err, statuses) {
        if (err) {
            return callback(err);
        }

        status.deployments = statuses.deployments;
        status.network = statuses.network;
        status.osm = statuses.osm;
        status.publicFiles = statuses.publicFiles;

        return callback(null, status);
    });
};

module.exports = statusUtility;
<|endoftext|>


<commit_before>module.exports = function (room) {
    room.url = "http://localhost:9020/api/rooms/"+room.getOwner() + "/" + room.getName();
    return room;
};<commit_msg>use toJSON for room<commit_after>module.exports = function (room) {

    var json = room.toJSON();
    json.url = "http://localhost:9030/api/rooms/"+room.getOwner() + "/" + room.getName();
    return json;
};<|endoftext|>


<commit_before>/* ©Copyright Utrecht University (Department of Information and Computing Sciences) */

var KeyControl;

(function()
{
    var hotKeysActive;

    KeyControl =
    {
        ctrlClickOnElement: ctrlClickOnElement,
        selectExtraElement: selectExtraElement,
        hotKeysActive  : hotKeysActive
    };

    $(document).ready(function()
    {
        //activate the hotkeys
        KeyControl.hotKeysActive = true;

        // Event handlers.
        $("#main").on('keydown', function(e)
        {
            // check if hotkeys are active
            if(KeyControl.hotKeysActive)
            {
                var ch = String.fromCharCode(e.keyCode);
                //Check if the ctrl key is pressed
                if(e.ctrlKey && !e.shiftKey)
                {
                    if(e.keyCode in ctrlNumberControl)
                    {
                        Utils.ensurePreventDefault(this, e, ctrlNumberControl[e.keyCode]);
                    }
                    else if(ch in ctrlLetterControl)
                    {
                        Utils.ensurePreventDefault(this, e, ctrlLetterControl[ch]);
                    }

                    $("#main").focus();
                }
                else if(!e.ctrlKey && !e.shiftKey && e.keyCode in numberControl)
                {
                    Utils.ensurePreventDefault(this, e, numberControl[e.keyCode]);
                    $("#main").focus();
                }
                else if (!e.ctrlKey && !e.shiftKey && ch in letterControl)
                {
                    Utils.ensurePreventDefault(this, e, letterControl[ch]);
                }
            }
        });
    });

    //All events for keyboard controls with normal letters.
    var letterControl = {
        Q: function()
        {
            if(Zoom.isZoomed())
                Main.addNewNode(Main.playerType);
        },
        W: function()
        {
            if(Zoom.isZoomed())
                Main.addNewNode(Main.computerType);
        },
        E: function()
        {
            if(Zoom.isZoomed())
                Main.addNewNode(Main.conversationType);
        },
        R: function()
        {
            if(Zoom.isZoomed())
                Main.createChildNode();
        },
        T: function()
        {
            if(!Zoom.isZoomed())
                Main.addNewTree(null, true, 0, 0);
        },
        M: function()
        {
            Media.mediaDialog();
        },
        B: function()
        {
            Metadata.metadataDialog();
        },
        V: function()
        {
            var errors = Validator.validate();
            Validator.show(errors);
        }
    };

    //All events for keyboard controls with special characters.
    var numberControl = {
        46: function()
        {
            Main.deleteAllSelected();
        },
        38: function()
        {
            selectParent();
        },
        40: function()
        {
            selectChild();
        },
        39: function()
        {
            selectRightBrother();
        },
        37: function()
        {
            selectLeftBrother();
        },
        27: function()
        {
            DragBox.cancel();
        }
    };

    //All events for keyboard controls with normal letters and ctrl pressed.
    var ctrlLetterControl = {
        A: function()
        {
            selectAll();
        },
        C: function()
        {
            Clipboard.copyElement();
        },
        X: function()
        {
            Clipboard.cutElement();
        },
        V: function()
        {
            Clipboard.pasteElement();
        },
        S: function()
        {
            Media.downloadFile();
        },
        L: function()
        {
            location.reload();
        },
        P: function()
        {
            printScript();
        }
    };

    //All events for keyboard controls with special characters and ctrl pressed.
    var ctrlNumberControl = {
        38: function()
        {
            moveNodeUp();
        },
        40: function()
        {
            moveNodeDown();
        },
        39: function()
        {
            moveNodeRight();
        },
        37: function()
        {
            moveNodeLeft();
        }
    };

    /*
     ** Public Functions
     */

    //If the user clicked on a node while ctrl is pressed, check if he need to be selected or deselected.
    function ctrlClickOnElement(node)
    {
        if ($("#" + node).hasClass("multiSelected"))
            deselectElement(node);
        else selectExtraElement(node);
    }

    // Multiselect an extra element
    function selectExtraElement(elementID)
    {
        if (Main.selectedElements.length === 0)
        {
            Main.selectElement(elementID);
        }
        else
        {
            if (Main.selectedElements.length === 1)
            {
                var selectedElementID = Main.selectedElement;
                Main.selectElement(null);
                Main.selectedElements.push(selectedElementID);
                $("#" + selectedElementID).addClass("multiSelected");
            }

            Main.selectedElements.push(elementID);
            $("#" + elementID).addClass("multiSelected");
        }

        if(elementID !== null && elementID !== undefined && !(elementID in Main.trees))
            Main.trees[Main.nodes[elementID].parent].plumbInstance.addToDragSelection($("#"+elementID)[0]);
    }

    /*
     ** Private Functions
     */

    //If the user clicked on a selected node while ctrl is pressed, deselect the node.
    function deselectElement(node)
    {
        if(node !== null && node !== undefined && !(node in Main.trees))
            Main.trees[Main.nodes[node].parent].plumbInstance.removeFromDragSelection($("#"+node)[0]);

        if (Main.selectedElement !== null)
            Main.selectElement(null);
        else
        {
            $("#" + node).removeClass("multiSelected");
            Main.selectedElements = jQuery.grep(Main.selectedElements,
                function(value)
                {
                    return value != node;
                });
            if (Main.selectedElements.length == 1)
                Main.selectElement(Main.selectedElements[0]);
        }
    }

    //If a node is selected and arrow up is pressed, move the node up.
    function moveNodeUp()
    {
        // Check if none of the selected nodes are out of the upper bound
        var outOfUpperBound = false;
        var plumbInstance = Main.trees[Main.selectedElements[0].parent].plumbInstance
        for (var i = 0; i < Main.selectedElements.length; i++)
        {
            var upperBound = $('#main').position().top + 50;

            var newTop = $("#" + Main.selectedElements[i]).offset().top - 5;

            outOfUpperBound = newTop < upperBound - 1;
        }

        // If none of the nodes is moving outside of the canvas, move and repaint them
        if (!outOfUpperBound)
        {
            for (var j = 0; j < Main.selectedElements.length; j++)
            {
                $("#" + Main.selectedElements[j]).offset(
                {
                    top: $("#" + Main.selectedElements[j]).offset().top - 5
                });
            }

            plumbInstance.repaintEverything();
        }
    }

    //If a node is selected and arrow up is pressed, move the node down.
    function moveNodeDown()
    {
        var plumbInstance = Main.trees[Main.selectedElements[0].parent].plumbInstance
        for (var i = 0; i < Main.selectedElements.length; i++)
        {
            $("#" + Main.selectedElements[i]).offset(
            {
                top: $("#" + Main.selectedElements[i]).offset()
                    .top + 5
            });
        }

        plumbInstance.repaintEverything();
    }

    //If a node is selected and arrow up is pressed, move the node to the left.
    function moveNodeLeft()
    {
        // Check if none of the nodes will move out of the canvas
        var plumbInstance = Main.trees[Main.selectedElements[0].parent].plumbInstance
        var outOfLeftBound = false;
        for (var i = 0; i < Main.selectedElements.length; i++)
        {
            plumbInstance = Main.trees[Main.selectedElements[i].parent].plumbInstance

            var leftBound = $('#main').position().left;

            var newLeft = $("#" + Main.selectedElements[i]).offset().left - 5;

            outOfLeftBound = newLeft < leftBound - 1;

            if (outOfLeftBound)
                break;
        }

        // If none of the nodes will move out of the canvas, move and repaint them
        if (!outOfLeftBound)
        {
            for (var j = 0; j < Main.selectedElements.length; j++)
            {
                $("#" + Main.selectedElements[j]).offset(
                {
                    left: $("#" + Main.selectedElements[j]).offset().left - 5
                });
            }
            plumbInstance.repaintEverything();
        }
    }

    //If a node is selected and arrow up is pressed, move the node to the right.
    function moveNodeRight()
    {
        var plumbInstance = Main.trees[Main.selectedElements[0].parent].plumbInstance
        for (var i = 0; i < Main.selectedElements.length; i++)
        {
            $("#" + Main.selectedElements[i]).offset(
            {
                left: $("#" + Main.selectedElements[i]).offset()
                    .left + 5
            });
        }

        plumbInstance.repaintEverything();
    }

    function selectAll()
    {
        Main.selectElement(null);
        Main.selectedElements = [];

        if (Zoom.isZoomed())
        {
            Zoom.getZoomed().nodes.forEach(function(nodeID)
            {
                selectExtraElement(nodeID);
            });
        }
        else
        {
            $('.treeContainer').each(function(i, tree)
            {
                selectExtraElement(tree.id);
            });
        }
    }

    //Select the lowest parent from the current selected node.
    function selectParent()
    {
        if (Main.selectedElement === null) return;

        var plumbInstance = Main.trees[Main.nodes[Main.selectedElement].parent].plumbInstance;

        var connections = plumbInstance.getConnections(
        {
            target: Main.selectedElement
        });
        var closestNode;
        var top = -Infinity;
        for (var i = 0; i < connections.length; i++)
        {
            if ($("#" + connections[i].sourceId).offset().top > top)
            {
                closestNode = connections[i].sourceId;
                top = $("#" + closestNode).offset().top;
            }
        }
        if (top !== -Infinity)
            Main.selectElement(closestNode);
    }

    //Select the highest child from the current selected node.
    function selectChild()
    {
        if (Main.selectedElement === null) return;

        var plumbInstance = Main.trees[Main.nodes[Main.selectedElement].parent].plumbInstance;

        var connections = plumbInstance.getConnections(
        {
            source: Main.selectedElement
        });
        var closestNode;
        var top = Infinity;
        for (var i = 0; i < connections.length; i++)
        {
            if ($("#" + connections[i].targetId).offset().top < top)
            {
                closestNode = connections[i].targetId;
                top = $("#" + closestNode).offset().top;
            }
        }
        if (top !== Infinity)
            Main.selectElement(closestNode);
    }

    //Select the closest brother on the right from the current selected node.
    function selectRightBrother()
    {
        if (Main.selectedElement === null) return;

        var plumbInstance = Main.trees[Main.nodes[Main.selectedElement].parent].plumbInstance;

        var connections = plumbInstance.getConnections(
        {
            target: Main.selectedElement
        });
        var closestNode;
        var left = Infinity;
        var leftCurrent = $("#" + Main.selectedElement).offset().left;
        for (var i = 0; i < connections.length; i++)
        {
            var connections2 = plumbInstance.getConnections(
            {
                source: connections[i].sourceId
            });
            for (var j = 0; j < connections2.length; j++)
            {
                var nodeLookedAt = connections2[j].targetId;
                var leftLookedAt = $("#" + nodeLookedAt).offset().left;

                if ((nodeLookedAt != Main.selectedElement) && (
                        leftLookedAt > leftCurrent) && (left >
                        leftLookedAt))
                {
                    closestNode = nodeLookedAt;
                    left = leftLookedAt;
                }
            }
        }
        if (left !== Infinity)
            Main.selectElement(closestNode);
    }

    //Select the closest brother on the left from the current selected node.
    function selectLeftBrother()
    {
        if (Main.selectedElement === null) return;

        var plumbInstance = Main.trees[Main.nodes[Main.selectedElement].parent].plumbInstance;

        var connections = plumbInstance.getConnections(
        {
            target: Main.selectedElement
        });

        var closestNode;
        var right = -Infinity;
        var rightCurrent = $("#" + Main.selectedElement).offset().left;
        for (var i = 0; i < connections.length; i++)
        {
            var sourceConnections = plumbInstance.getConnections(
            {
                source: connections[i].sourceId
            });

            for (var j = 0; j < sourceConnections.length; j++)
            {
                var nodeLookedAt = sourceConnections[j].targetId;
                var rightLookedAt = $("#" + nodeLookedAt).offset().left;

                if ((nodeLookedAt != Main.selectedElement) &&
                    (rightLookedAt < rightCurrent) &&
                    (right < rightLookedAt))
                {
                    closestNode = nodeLookedAt;
                    right = rightLookedAt;
                }
            }
        }

        if (right !== -Infinity)
            Main.selectElement(closestNode);
    }
})();
<commit_msg>Fixed bug in moving nodes upwards<commit_after>/* ©Copyright Utrecht University (Department of Information and Computing Sciences) */

var KeyControl;

(function()
{
    var hotKeysActive;

    KeyControl =
    {
        ctrlClickOnElement: ctrlClickOnElement,
        selectExtraElement: selectExtraElement,
        hotKeysActive  : hotKeysActive
    };

    $(document).ready(function()
    {
        //activate the hotkeys
        KeyControl.hotKeysActive = true;

        // Event handlers.
        $("#main").on('keydown', function(e)
        {
            // check if hotkeys are active
            if(KeyControl.hotKeysActive)
            {
                var ch = String.fromCharCode(e.keyCode);
                //Check if the ctrl key is pressed
                if(e.ctrlKey && !e.shiftKey)
                {
                    if(e.keyCode in ctrlNumberControl)
                    {
                        Utils.ensurePreventDefault(this, e, ctrlNumberControl[e.keyCode]);
                    }
                    else if(ch in ctrlLetterControl)
                    {
                        Utils.ensurePreventDefault(this, e, ctrlLetterControl[ch]);
                    }

                    $("#main").focus();
                }
                else if(!e.ctrlKey && !e.shiftKey && e.keyCode in numberControl)
                {
                    Utils.ensurePreventDefault(this, e, numberControl[e.keyCode]);
                    $("#main").focus();
                }
                else if (!e.ctrlKey && !e.shiftKey && ch in letterControl)
                {
                    Utils.ensurePreventDefault(this, e, letterControl[ch]);
                }
            }
        });
    });

    //All events for keyboard controls with normal letters.
    var letterControl = {
        Q: function()
        {
            if(Zoom.isZoomed())
                Main.addNewNode(Main.playerType);
        },
        W: function()
        {
            if(Zoom.isZoomed())
                Main.addNewNode(Main.computerType);
        },
        E: function()
        {
            if(Zoom.isZoomed())
                Main.addNewNode(Main.conversationType);
        },
        R: function()
        {
            if(Zoom.isZoomed())
                Main.createChildNode();
        },
        T: function()
        {
            if(!Zoom.isZoomed())
                Main.addNewTree(null, true, 0, 0);
        },
        M: function()
        {
            Media.mediaDialog();
        },
        B: function()
        {
            Metadata.metadataDialog();
        },
        V: function()
        {
            var errors = Validator.validate();
            Validator.show(errors);
        }
    };

    //All events for keyboard controls with special characters.
    var numberControl = {
        46: function()
        {
            Main.deleteAllSelected();
        },
        38: function()
        {
            selectParent();
        },
        40: function()
        {
            selectChild();
        },
        39: function()
        {
            selectRightBrother();
        },
        37: function()
        {
            selectLeftBrother();
        },
        27: function()
        {
            DragBox.cancel();
        }
    };

    //All events for keyboard controls with normal letters and ctrl pressed.
    var ctrlLetterControl = {
        A: function()
        {
            selectAll();
        },
        C: function()
        {
            Clipboard.copyElement();
        },
        X: function()
        {
            Clipboard.cutElement();
        },
        V: function()
        {
            Clipboard.pasteElement();
        },
        S: function()
        {
            Media.downloadFile();
        },
        L: function()
        {
            location.reload();
        },
        P: function()
        {
            printScript();
        }
    };

    //All events for keyboard controls with special characters and ctrl pressed.
    var ctrlNumberControl = {
        38: function()
        {
            moveNodeUp();
        },
        40: function()
        {
            moveNodeDown();
        },
        39: function()
        {
            moveNodeRight();
        },
        37: function()
        {
            moveNodeLeft();
        }
    };

    /*
     ** Public Functions
     */

    //If the user clicked on a node while ctrl is pressed, check if he need to be selected or deselected.
    function ctrlClickOnElement(node)
    {
        if ($("#" + node).hasClass("multiSelected"))
            deselectElement(node);
        else selectExtraElement(node);
    }

    // Multiselect an extra element
    function selectExtraElement(elementID)
    {
        if (Main.selectedElements.length === 0)
        {
            Main.selectElement(elementID);
        }
        else
        {
            if (Main.selectedElements.length === 1)
            {
                var selectedElementID = Main.selectedElement;
                Main.selectElement(null);
                Main.selectedElements.push(selectedElementID);
                $("#" + selectedElementID).addClass("multiSelected");
            }

            Main.selectedElements.push(elementID);
            $("#" + elementID).addClass("multiSelected");
        }

        if(elementID !== null && elementID !== undefined && !(elementID in Main.trees))
            Main.trees[Main.nodes[elementID].parent].plumbInstance.addToDragSelection($("#"+elementID)[0]);
    }

    /*
     ** Private Functions
     */

    //If the user clicked on a selected node while ctrl is pressed, deselect the node.
    function deselectElement(node)
    {
        if(node !== null && node !== undefined && !(node in Main.trees))
            Main.trees[Main.nodes[node].parent].plumbInstance.removeFromDragSelection($("#"+node)[0]);

        if (Main.selectedElement !== null)
            Main.selectElement(null);
        else
        {
            $("#" + node).removeClass("multiSelected");
            Main.selectedElements = jQuery.grep(Main.selectedElements,
                function(value)
                {
                    return value != node;
                });
            if (Main.selectedElements.length == 1)
                Main.selectElement(Main.selectedElements[0]);
        }
    }

    //If a node is selected and arrow up is pressed, move the node up.
    function moveNodeUp()
    {
        // Check if none of the selected nodes are out of the upper bound
        var outOfUpperBound = false;
        var plumbInstance = Main.trees[Main.selectedElements[0].parent].plumbInstance
        for (var i = 0; i < Main.selectedElements.length; i++)
        {
            var upperBound = $('#main').position().top + 50;

            var newTop = $("#" + Main.selectedElements[i]).offset().top - 5;

            outOfUpperBound = newTop < upperBound - 1;

            if (outOfUpperBound)
                break;
        }

        // If none of the nodes is moving outside of the canvas, move and repaint them
        if (!outOfUpperBound)
        {
            for (var j = 0; j < Main.selectedElements.length; j++)
            {
                $("#" + Main.selectedElements[j]).offset(
                {
                    top: $("#" + Main.selectedElements[j]).offset().top - 5
                });
            }

            plumbInstance.repaintEverything();
        }
    }

    //If a node is selected and arrow up is pressed, move the node down.
    function moveNodeDown()
    {
        var plumbInstance = Main.trees[Main.selectedElements[0].parent].plumbInstance
        for (var i = 0; i < Main.selectedElements.length; i++)
        {
            $("#" + Main.selectedElements[i]).offset(
            {
                top: $("#" + Main.selectedElements[i]).offset()
                    .top + 5
            });
        }

        plumbInstance.repaintEverything();
    }

    //If a node is selected and arrow up is pressed, move the node to the left.
    function moveNodeLeft()
    {
        // Check if none of the nodes will move out of the canvas
        var plumbInstance = Main.trees[Main.selectedElements[0].parent].plumbInstance
        var outOfLeftBound = false;
        for (var i = 0; i < Main.selectedElements.length; i++)
        {
            plumbInstance = Main.trees[Main.selectedElements[i].parent].plumbInstance

            var leftBound = $('#main').position().left;

            var newLeft = $("#" + Main.selectedElements[i]).offset().left - 5;

            outOfLeftBound = newLeft < leftBound - 1;

            if (outOfLeftBound)
                break;
        }

        // If none of the nodes will move out of the canvas, move and repaint them
        if (!outOfLeftBound)
        {
            for (var j = 0; j < Main.selectedElements.length; j++)
            {
                $("#" + Main.selectedElements[j]).offset(
                {
                    left: $("#" + Main.selectedElements[j]).offset().left - 5
                });
            }
            plumbInstance.repaintEverything();
        }
    }

    //If a node is selected and arrow up is pressed, move the node to the right.
    function moveNodeRight()
    {
        var plumbInstance = Main.trees[Main.selectedElements[0].parent].plumbInstance
        for (var i = 0; i < Main.selectedElements.length; i++)
        {
            $("#" + Main.selectedElements[i]).offset(
            {
                left: $("#" + Main.selectedElements[i]).offset()
                    .left + 5
            });
        }

        plumbInstance.repaintEverything();
    }

    function selectAll()
    {
        Main.selectElement(null);
        Main.selectedElements = [];

        if (Zoom.isZoomed())
        {
            Zoom.getZoomed().nodes.forEach(function(nodeID)
            {
                selectExtraElement(nodeID);
            });
        }
        else
        {
            $('.treeContainer').each(function(i, tree)
            {
                selectExtraElement(tree.id);
            });
        }
    }

    //Select the lowest parent from the current selected node.
    function selectParent()
    {
        if (Main.selectedElement === null) return;

        var plumbInstance = Main.trees[Main.nodes[Main.selectedElement].parent].plumbInstance;

        var connections = plumbInstance.getConnections(
        {
            target: Main.selectedElement
        });
        var closestNode;
        var top = -Infinity;
        for (var i = 0; i < connections.length; i++)
        {
            if ($("#" + connections[i].sourceId).offset().top > top)
            {
                closestNode = connections[i].sourceId;
                top = $("#" + closestNode).offset().top;
            }
        }
        if (top !== -Infinity)
            Main.selectElement(closestNode);
    }

    //Select the highest child from the current selected node.
    function selectChild()
    {
        if (Main.selectedElement === null) return;

        var plumbInstance = Main.trees[Main.nodes[Main.selectedElement].parent].plumbInstance;

        var connections = plumbInstance.getConnections(
        {
            source: Main.selectedElement
        });
        var closestNode;
        var top = Infinity;
        for (var i = 0; i < connections.length; i++)
        {
            if ($("#" + connections[i].targetId).offset().top < top)
            {
                closestNode = connections[i].targetId;
                top = $("#" + closestNode).offset().top;
            }
        }
        if (top !== Infinity)
            Main.selectElement(closestNode);
    }

    //Select the closest brother on the right from the current selected node.
    function selectRightBrother()
    {
        if (Main.selectedElement === null) return;

        var plumbInstance = Main.trees[Main.nodes[Main.selectedElement].parent].plumbInstance;

        var connections = plumbInstance.getConnections(
        {
            target: Main.selectedElement
        });
        var closestNode;
        var left = Infinity;
        var leftCurrent = $("#" + Main.selectedElement).offset().left;
        for (var i = 0; i < connections.length; i++)
        {
            var connections2 = plumbInstance.getConnections(
            {
                source: connections[i].sourceId
            });
            for (var j = 0; j < connections2.length; j++)
            {
                var nodeLookedAt = connections2[j].targetId;
                var leftLookedAt = $("#" + nodeLookedAt).offset().left;

                if ((nodeLookedAt != Main.selectedElement) && (
                        leftLookedAt > leftCurrent) && (left >
                        leftLookedAt))
                {
                    closestNode = nodeLookedAt;
                    left = leftLookedAt;
                }
            }
        }
        if (left !== Infinity)
            Main.selectElement(closestNode);
    }

    //Select the closest brother on the left from the current selected node.
    function selectLeftBrother()
    {
        if (Main.selectedElement === null) return;

        var plumbInstance = Main.trees[Main.nodes[Main.selectedElement].parent].plumbInstance;

        var connections = plumbInstance.getConnections(
        {
            target: Main.selectedElement
        });

        var closestNode;
        var right = -Infinity;
        var rightCurrent = $("#" + Main.selectedElement).offset().left;
        for (var i = 0; i < connections.length; i++)
        {
            var sourceConnections = plumbInstance.getConnections(
            {
                source: connections[i].sourceId
            });

            for (var j = 0; j < sourceConnections.length; j++)
            {
                var nodeLookedAt = sourceConnections[j].targetId;
                var rightLookedAt = $("#" + nodeLookedAt).offset().left;

                if ((nodeLookedAt != Main.selectedElement) &&
                    (rightLookedAt < rightCurrent) &&
                    (right < rightLookedAt))
                {
                    closestNode = nodeLookedAt;
                    right = rightLookedAt;
                }
            }
        }

        if (right !== -Infinity)
            Main.selectElement(closestNode);
    }
})();
<|endoftext|>


<commit_before>/**
 * bh-server
 * =========
 *
 * Склеивает *bh*-файлы по deps'ам с помощью набора `require` в виде `?.bh.js`.
 * Предназначен для сборки серверного BH-кода. После сборки требуется наличия всех файлов,
 * подключённых с помощью набора `require`.
 *
 * **Опции**
 *
 * * *String* **target** — Результирующий таргет. По умолчанию — `?.bh.js`.
 * * *String* **filesTarget** — files-таргет, на основе которого получается список исходных файлов
 *   (его предоставляет технология `files`). По умолчанию — `?.files`.
 * * *String* **sourceSuffixes** — суффиксы файлов, по которым строится `files`-таргет. По умолчанию — ['bh.js'].
 * * *String* **jsAttrName** — атрибут блока с параметрами инициализации. По умолчанию — `onclick`.
 * * *String* **jsAttrScheme** — Cхема данных для параметров инициализации. По умолчанию — `js`.
 * *                             Форматы:
 * *                                `js` — значение по умолчанию. Получаем `return { ... }`.
 * *                                `json` — JSON-формат. Получаем `{ ... }`.
 *
 * **Пример**
 *
 * ```javascript
 * nodeConfig.addTech(require('enb-bh/techs/bh-server'));
 * ```
 */

var path = require('path');

module.exports = require('enb/lib/build-flow').create()
    .name('bh-server')
    .target('target', '?.bh.js')
    .defineOption('bhFile', '')
    .defineOption('jsAttrName', 'onclick')
    .defineOption('jsAttrScheme', 'js')
    .useFileList(['bh.js'])
    .needRebuild(function (cache) {
        this._bhFile = this._bhFile ? path.join(this.node._root, this._bhFile) : require.resolve('bh/lib/bh.js');

        return cache.needRebuildFile('bh-file', this._bhFile);
    })
    .saveCache(function (cache) {
        cache.cacheFileInfo('bh-file', this._bhFile);
    })
    .builder(function (bhFiles) {
        var node = this.node;
        /**
         * Генерирует `require`-строку для подключения исходных bh-файлов.
         *
         * @param {String} absPath
         * @param {String} pre
         * @param {String} post
         */
        function buildRequire(absPath, pre, post) {
            var relPath = node.relativePath(absPath);

            return [
                'dropRequireCache(require, require.resolve("' + relPath + '"));',
                (pre || '') + 'require("' + relPath + '")' + (post || '') + ';'
            ].join('\n');
        }

        var dropRequireCacheFunc = [
            'function dropRequireCache(requireFunc, filename) {',
            '    var module = requireFunc.cache[filename];',
            '    if (module) {',
            '        if (module.parent) {',
            '            if (module.parent.children) {',
            '                var moduleIndex = module.parent.children.indexOf(module);',
            '                if (moduleIndex !== -1) {',
            '                    module.parent.children.splice(moduleIndex, 1);',
            '                }',
            '            }',
            '            delete module.parent;',
            '        }',
            '        delete module.children;',
            '        delete requireFunc.cache[filename];',
            '    }',
            '};'
        ].join('\n');

        return [
            dropRequireCacheFunc,
            buildRequire(this._bhFile, 'var BH = '),
            'var bh = new BH();',
            'bh.setOptions({',
            '   jsAttrName: \'' + this._jsAttrName + '\',',
            '   jsAttrScheme: \'' + this._jsAttrScheme + '\'',
            '});',
            '',
            bhFiles.map(function (file) {
                return buildRequire(file.fullname, '', '(bh)');
            }).join('\n'),
            '',
            'module.exports = bh;'
        ].join('\n');
    })
    .createTech();
<commit_msg>Fixed bug with wrong windows paths for `require`<commit_after>/**
 * bh-server
 * =========
 *
 * Склеивает *bh*-файлы по deps'ам с помощью набора `require` в виде `?.bh.js`.
 * Предназначен для сборки серверного BH-кода. После сборки требуется наличия всех файлов,
 * подключённых с помощью набора `require`.
 *
 * **Опции**
 *
 * * *String* **target** — Результирующий таргет. По умолчанию — `?.bh.js`.
 * * *String* **filesTarget** — files-таргет, на основе которого получается список исходных файлов
 *   (его предоставляет технология `files`). По умолчанию — `?.files`.
 * * *String* **sourceSuffixes** — суффиксы файлов, по которым строится `files`-таргет. По умолчанию — ['bh.js'].
 * * *String* **jsAttrName** — атрибут блока с параметрами инициализации. По умолчанию — `onclick`.
 * * *String* **jsAttrScheme** — Cхема данных для параметров инициализации. По умолчанию — `js`.
 * *                             Форматы:
 * *                                `js` — значение по умолчанию. Получаем `return { ... }`.
 * *                                `json` — JSON-формат. Получаем `{ ... }`.
 *
 * **Пример**
 *
 * ```javascript
 * nodeConfig.addTech(require('enb-bh/techs/bh-server'));
 * ```
 */

var path = require('path');

module.exports = require('enb/lib/build-flow').create()
    .name('bh-server')
    .target('target', '?.bh.js')
    .defineOption('bhFile', '')
    .defineOption('jsAttrName', 'onclick')
    .defineOption('jsAttrScheme', 'js')
    .useFileList(['bh.js'])
    .needRebuild(function (cache) {
        this._bhFile = this._bhFile ? path.join(this.node._root, this._bhFile) : require.resolve('bh/lib/bh.js');

        return cache.needRebuildFile('bh-file', this._bhFile);
    })
    .saveCache(function (cache) {
        cache.cacheFileInfo('bh-file', this._bhFile);
    })
    .builder(function (bhFiles) {
        var node = this.node;
        /**
         * Генерирует `require`-строку для подключения исходных bh-файлов.
         *
         * @param {String} absPath
         * @param {String} pre
         * @param {String} post
         */
        function buildRequire(absPath, pre, post) {
            var relPath = node.relativePath(absPath);

            // Replace slashes with backslashes for windows paths for correct require work.
            if (relPath.indexOf('\\') !== -1) {
                relPath = relPath.replace(/\\/g, '/');
            }

            return [
                'dropRequireCache(require, require.resolve("' + relPath + '"));',
                (pre || '') + 'require("' + relPath + '")' + (post || '') + ';'
            ].join('\n');
        }

        var dropRequireCacheFunc = [
            'function dropRequireCache(requireFunc, filename) {',
            '    var module = requireFunc.cache[filename];',
            '    if (module) {',
            '        if (module.parent) {',
            '            if (module.parent.children) {',
            '                var moduleIndex = module.parent.children.indexOf(module);',
            '                if (moduleIndex !== -1) {',
            '                    module.parent.children.splice(moduleIndex, 1);',
            '                }',
            '            }',
            '            delete module.parent;',
            '        }',
            '        delete module.children;',
            '        delete requireFunc.cache[filename];',
            '    }',
            '};'
        ].join('\n');

        return [
            dropRequireCacheFunc,
            buildRequire(this._bhFile, 'var BH = '),
            'var bh = new BH();',
            'bh.setOptions({',
            '   jsAttrName: \'' + this._jsAttrName + '\',',
            '   jsAttrScheme: \'' + this._jsAttrScheme + '\'',
            '});',
            '',
            bhFiles.map(function (file) {
                return buildRequire(file.fullname, '', '(bh)');
            }).join('\n'),
            '',
            'module.exports = bh;'
        ].join('\n');
    })
    .createTech();
<|endoftext|>


<commit_before>function XLSExtension(viewer, options) {
  Autodesk.Viewing.Extension.call(this, viewer, options);
}

XLSExtension.prototype = Object.create(Autodesk.Viewing.Extension.prototype);
XLSExtension.prototype.constructor = XLSExtension;

  function statusCallback(completed, message) {
    $.notify(message, { className: "info", position:"bottom right" });
    $('#downloadExcel').prop("disabled", !completed);
  }

XLSExtension.prototype.load = function () {
  var _viewer = this.viewer;

  // get Forge token (use your data:read endpoint here)
  // this sample is using client-side JavaScript only, so no
  // back-end that authenticate with Forge nor files, therefore
  // is using files from another sample. On your implementation,
  // you should replace this with your own Token endpoint
  function getForgeToken(callback) {
    jQuery.ajax({
      url: '/forge/oauth/token',
      success: function (oauth) {
        if (callback)
          callback(oauth.access_token, oauth.expires_in);
      }
    });
  }

  createUI = function () {
    // Button 1
    var button1 = new Autodesk.Viewing.UI.Button('toolbarXLS');
    button1.onClick = function (e) {
        ForgeXLS.downloadXLSX(documentId, fileName + ".xlsx", token, statusCallback, fileType );/*Optional*/
    };
    button1.addClass('toolbarXLSButton');
    button1.setToolTip('Export to .XLSX');

    // Button 2
    var button2 = new Autodesk.Viewing.UI.Button('toolbarXLS');
    button1.onClick = function (e) {
       status('just like it');
    };
    button2.addClass('toolbarXLSButton');
    button2.setToolTip(':-)');

    // SubToolbar
    this.subToolbar = new Autodesk.Viewing.UI.ControlGroup('myAppGroup1');
    this.subToolbar.addControl(button1);
    this.subToolbar.addControl(button2);

    _viewer.toolbar.addControl(this.subToolbar);
  };

  createUI();

  return true;
};

XLSExtension.prototype.unload = function () {
  alert('XLSExtension is now unloaded!');
  return true;
};

Autodesk.Viewing.theExtensionManager.registerExtension('Autodesk.Sample.XLSExtension', XLSExtension);
<commit_msg>Update xlsextension.js<commit_after>function XLSExtension(viewer, options) {
  Autodesk.Viewing.Extension.call(this, viewer, options);
}

XLSExtension.prototype = Object.create(Autodesk.Viewing.Extension.prototype);
XLSExtension.prototype.constructor = XLSExtension;

  function statusCallback(completed, message) {
    $.notify(message, { className: "info", position:"bottom right" });
    $('#downloadExcel').prop("disabled", !completed);
  }

XLSExtension.prototype.load = function () {
  var _viewer = this.viewer;

  // get Forge token (use your data:read endpoint here)
  // this sample is using client-side JavaScript only, so no
  // back-end that authenticate with Forge nor files, therefore
  // is using files from another sample. On your implementation,
  // you should replace this with your own Token endpoint
  function getForgeToken(callback) {
    jQuery.ajax({
      url: '/forge/oauth/token',
      success: function (oauth) {
        if (callback)
          callback(oauth.access_token, oauth.expires_in);
      }
    });
  }

  createUI = function () {
    // Button 1
 /*   var button1 = new Autodesk.Viewing.UI.Button('toolbarXLS');
    button1.onClick = function (e) {
        ForgeXLS.downloadXLSX(documentId, fileName + ".xlsx", token, statusCallback, fileType );/*Optional*/
    };
  /*  button1.addClass('toolbarXLSButton');
    button1.setToolTip('Export to .XLSX');*/

    // Button 2
    var button2 = new Autodesk.Viewing.UI.Button('toolbarXLS');
    button1.onClick = function (e) {
       alert('just like it');
    };
    button2.addClass('toolbarXLSButton');
    button2.setToolTip(':-)');

    // SubToolbar
    this.subToolbar = new Autodesk.Viewing.UI.ControlGroup('myAppGroup1');
   // this.subToolbar.addControl(button1);
    this.subToolbar.addControl(button2);

    _viewer.toolbar.addControl(this.subToolbar);
  };

  createUI();

  return true;
};

XLSExtension.prototype.unload = function () {
  alert('XLSExtension is now unloaded!');
  return true;
};

Autodesk.Viewing.theExtensionManager.registerExtension('Autodesk.Sample.XLSExtension', XLSExtension);
<|endoftext|>


<commit_before>/*
  Event Handlers
*/
$('document').ready(function() {
  /*
    Navigation Buttons
  */
  $('a#save').click(function() {
    saveWeek(getAssignmentValues());
  });
  $('a#back').click(function() {
    // animation
    $('#sidebar').slide($(window).width(), 200);
    $("#planner").slide($(window).width(), 200, function() {
      saveWeek(getAssignmentValues()); // save the current state
      ref.monday = new Date(ref.monday.getFullYear(), ref.monday.getMonth(), ref.monday.getDate() - 7); // decrement by 1 week
      getWeek(setAssignmentValues);
      drawDates();
    });
  });
  $('a#next').click(function() {
    $('#sidebar').slide(-$(window).width(), 200);
    $("#planner").slide(-$(window).width(), 200, function() {
      saveWeek(getAssignmentValues());
      ref.monday = new Date(ref.monday.getFullYear(), ref.monday.getMonth(), ref.monday.getDate() + 7);
      getWeek(setAssignmentValues);
      drawDates();
    });
  });

  // add subject
  $('button#add').click(function() {
    r = ref.settings.rows;
    // r.push(["Class", r[r.length-1][1]+1]);
    // add row to subjects
    r.push("Class");
    ref.settings.rows = r;
    // save
    db.put(ref.settings, function(err, response) {
      if (err) {
        alert("there's been an error. try again.");
        console.log(err);
      } else {
        db.get("settings").then(function(s) {
          ref.settings = s;
          renderRows(s.rows);
          // select the new row
          $('span#'+String(s.rows.length)).prop('contenteditable', true);
          $('span#'+String(s.rows.length)).focus().selectText();
          // $('span#'+String(s.rows.length)).select();
        });
      }
    });
  });

  /*
    Form buttons for AJAX
  */
  $("form#login").submit(function(e) {
    e.preventDefault();
    login($('#loginUsername').val().toLowerCase(), $('#loginPassword').val(), function(data) {
      $('.loginModal').modal('hide');
      $('li#username').children('a').text(data.user);
      $('.loggedIn').show();
      $('.loggedOut').hide();
      $('#403').hide();
      $('textarea').each(function(index, element) {
        element.removeAttribute('disabled');
      });
    }, function(data) {
      $('li#username').children('a').text('');
      $('#403').text('The username and password entered does not match.');
      $('#403').show();
    });
  });

  $("form#signup").submit(function(e) {
    e.preventDefault();
    if ($('#signupPasswordVerify').val() == $('#signupPassword').val()) {
      signup($('#signupUsername').val().toLowerCase(), $('#signupPassword').val(), function(data) {
        $('.signupModal').modal('hide');
        $('li#username').children('a').text(data.user);
        $('.loggedIn').show();
        $('.loggedOut').hide();
        $('#403').hide();
        $('textarea').each(function(index, element) {
          element.removeAttribute('disabled');
        });
      }, function(data) {
        $('li#username').children('a').text('');
        $('#403-1').text('This user already exists');
        $('#403-1').show();
      });
    } else {
      $('#403-1').text('The password you entered must match.');
      $('#403-1').show();
    }
  });

  $('#goToLogin').click(function() {
    $('.choiceModal').modal('hide');
    $('.loginModal').modal('show');
  });

  $('#goToSignup').click(function() {
    $('.choiceModal').modal('hide');
    $('.signupModal').modal('show');
  });

  $('.signupModal').on('hidden.bs.modal', function() {
    if ($('li#username').children('a').text() == "")
      $('.choiceModal').modal('show');
  });

  $('.loginModal').on('hidden.bs.modal', function() {
    if ($('li#username').children('a').text() == "")
      $('.choiceModal').modal('show');
  });
  taListen();
  subjectListen();
});

function taListen() {
  $("textarea").unbind();
  /*
    Keypress listener, for parsing and using inputs to different textareas.
    Will get quite large as features such as lab requests are added.
  */
  $("textarea").keydown(function(e) {
    if (e.which == 13) {
      var value = $(this).val().toLowerCase();
      if (value.indexOf("test") != -1) {
        var d = new Date(ref.monday.getFullYear(), ref.monday.getMonth(), ref.monday.getDate() + (this.id[1]-1));
        var today = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()).toISOString();
        console.log(((d.getMonth()+1) + '/' + d.getDate() + '/' + d.getYear() % 100) + " " + ref.settings.rows[this.id[0]-1]);
      }
    }
  });

  /*
    Double tap/Double click for setting assignments as completed.
  */
  var isiOS = false;
  var agent = navigator.userAgent.toLowerCase();
  if(agent.indexOf('iphone') >= 0 || agent.indexOf('ipad') >= 0) {
    isiOS = true;
  }

  if (!isiOS){
    $('textarea').dblclick(function() { // toggle between strikethrough and no styling on textareas
      if ($(this).css("text-decoration") == "none solid rgb(0, 0, 0)")
        $(this).css("text-decoration", "line-through");
      else
        $(this).css("text-decoration", "none solid rgb(0, 0, 0)");
    });
  } else {
    var action;
    $('textarea').bind('touchend', function(event){
      var now = new Date().getTime();
      var lastTouch = $(this).data('lastTouch') || now + 1 /** the first time this will make delta a negative number */;
      var delta = now - lastTouch;
      clearTimeout(action);
      if (delta<500 && delta>0){
        if ($(this).css("text-decoration") == "none solid rgb(0, 0, 0)")
          $(this).css("text-decoration", "line-through");
        else
          $(this).css("text-decoration", "none solid rgb(0, 0, 0)");
      } else {
        $(this).data('lastTouch', now);
        action = setTimeout(function(e){
         // If this runs you can invoke your 'click/touchend' code
         clearTimeout(action);   // clear the timeout
        }, 500, [event]);
      }
      $(this).data('lastTouch', now);
    });
  }
}

function subjectListen() {
  $('.subj').unbind(); // When you add a subject, need to re-add all the listeners

  $('.subj').on('dblclick', '.subjectspan', function () {
    var input = $('<input />', {
      'type': 'text',
      'name': 'unique',
      'value': $(this).html()
    });
    $(this).parent().prepend(input);
    $(this).remove();
    input.focus();
  });

   $('.subj').on('blur', 'input', function () {
      $(this).parent().prepend($('<span />', {'class':'.subjectspan'}).html($(this).val()));
      var id = $(this).parent().get(0).id;
      var subj = $(this).val();
      $(this).remove();

      if (id != 0) {
        $(this).prop('contenteditable', false); // make it not editable
        ref.settings.rows[id-1] = subj; // actually change the name
        // Save the new settings
        db.put(ref.settings, function(err, response) {
          if (err) {
            alert("there's been an error. try again.");
            console.log(err);
          } else {
            db.get("settings").then(function(s) {
              ref.settings = s;
            });
          }
        });
      }

  });

  // mouseover logic
  $('.subj').mouseenter(function() {
    $(this).children(".subjbtns").show();
  });
  $('.subj').mouseleave(function() {
     $(this).children(".subjbtns").hide();
  });

  $('button.delete').unbind();
  // delete subject
  $('button.delete').click(function() {
    var id = $(this).parent().parent()[0].id;
    if (confirm("Are you sure you want to delete " + ref.settings.rows[id-1] + "?")){
      ref.settings.rows.splice(id-1, 1); // splice out the row from settings
      // save
      db.put(ref.settings, function(err, response) {
        if (err) {
          alert("there's been an error. try again.");
          console.log(err);
        } else {
          db.get("settings").then(function(s) {
            ref.settings = s;
            renderRows(s.rows);
          });
        }
      });
    }
  });
  $('button.edit').unbind();
  $('button.edit').click(function() {
      var t = $(this).parent().parent().children('.subjectspan');
      var input = $('<input />', {
        'type': 'text',
        'name': 'unique',
        'value': $(t).html()
      });
      $(t).parent().prepend(input);
      $(t).remove();
      input.focus();
  });
}<commit_msg>fixed add button<commit_after>/*
  Event Handlers
*/
$('document').ready(function() {
  /*
    Navigation Buttons
  */
  $('a#save').click(function() {
    saveWeek(getAssignmentValues());
  });
  $('a#back').click(function() {
    // animation
    $('#sidebar').slide($(window).width(), 200);
    $("#planner").slide($(window).width(), 200, function() {
      saveWeek(getAssignmentValues()); // save the current state
      ref.monday = new Date(ref.monday.getFullYear(), ref.monday.getMonth(), ref.monday.getDate() - 7); // decrement by 1 week
      getWeek(setAssignmentValues);
      drawDates();
    });
  });
  $('a#next').click(function() {
    $('#sidebar').slide(-$(window).width(), 200);
    $("#planner").slide(-$(window).width(), 200, function() {
      saveWeek(getAssignmentValues());
      ref.monday = new Date(ref.monday.getFullYear(), ref.monday.getMonth(), ref.monday.getDate() + 7);
      getWeek(setAssignmentValues);
      drawDates();
    });
  });

  // add subject
  $('button#add').click(function() {
    r = ref.settings.rows;
    // r.push(["Class", r[r.length-1][1]+1]);
    // add row to subjects
    r.push("Class");
    ref.settings.rows = r;
    // save
    db.put(ref.settings, function(err, response) {
      if (err) {
        alert("there's been an error. try again.");
        console.log(err);
      } else {
        db.get("settings").then(function(s) {
          ref.settings = s;
          renderRows(s.rows);
          // select the new row
          $('.subj#'+String(s.rows.length)).children('.subjectspan').trigger('dblclick');
        });
      }
    });
  });

  /*
    Form buttons for AJAX
  */
  $("form#login").submit(function(e) {
    e.preventDefault();
    login($('#loginUsername').val().toLowerCase(), $('#loginPassword').val(), function(data) {
      $('.loginModal').modal('hide');
      $('li#username').children('a').text(data.user);
      $('.loggedIn').show();
      $('.loggedOut').hide();
      $('#403').hide();
      $('textarea').each(function(index, element) {
        element.removeAttribute('disabled');
      });
    }, function(data) {
      $('li#username').children('a').text('');
      $('#403').text('The username and password entered does not match.');
      $('#403').show();
    });
  });

  $("form#signup").submit(function(e) {
    e.preventDefault();
    if ($('#signupPasswordVerify').val() == $('#signupPassword').val()) {
      signup($('#signupUsername').val().toLowerCase(), $('#signupPassword').val(), function(data) {
        $('.signupModal').modal('hide');
        $('li#username').children('a').text(data.user);
        $('.loggedIn').show();
        $('.loggedOut').hide();
        $('#403').hide();
        $('textarea').each(function(index, element) {
          element.removeAttribute('disabled');
        });
      }, function(data) {
        $('li#username').children('a').text('');
        $('#403-1').text('This user already exists');
        $('#403-1').show();
      });
    } else {
      $('#403-1').text('The password you entered must match.');
      $('#403-1').show();
    }
  });

  $('#goToLogin').click(function() {
    $('.choiceModal').modal('hide');
    $('.loginModal').modal('show');
  });

  $('#goToSignup').click(function() {
    $('.choiceModal').modal('hide');
    $('.signupModal').modal('show');
  });

  $('.signupModal').on('hidden.bs.modal', function() {
    if ($('li#username').children('a').text() == "")
      $('.choiceModal').modal('show');
  });

  $('.loginModal').on('hidden.bs.modal', function() {
    if ($('li#username').children('a').text() == "")
      $('.choiceModal').modal('show');
  });
  taListen();
  subjectListen();
});

function taListen() {
  $("textarea").unbind();
  /*
    Keypress listener, for parsing and using inputs to different textareas.
    Will get quite large as features such as lab requests are added.
  */
  $("textarea").keydown(function(e) {
    if (e.which == 13) {
      var value = $(this).val().toLowerCase();
      if (value.indexOf("test") != -1) {
        var d = new Date(ref.monday.getFullYear(), ref.monday.getMonth(), ref.monday.getDate() + (this.id[1]-1));
        var today = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()).toISOString();
        console.log(((d.getMonth()+1) + '/' + d.getDate() + '/' + d.getYear() % 100) + " " + ref.settings.rows[this.id[0]-1]);
      }
    }
  });

  /*
    Double tap/Double click for setting assignments as completed.
  */
  var isiOS = false;
  var agent = navigator.userAgent.toLowerCase();
  if(agent.indexOf('iphone') >= 0 || agent.indexOf('ipad') >= 0) {
    isiOS = true;
  }

  if (!isiOS){
    $('textarea').dblclick(function() { // toggle between strikethrough and no styling on textareas
      if ($(this).css("text-decoration") == "none solid rgb(0, 0, 0)")
        $(this).css("text-decoration", "line-through");
      else
        $(this).css("text-decoration", "none solid rgb(0, 0, 0)");
    });
  } else {
    var action;
    $('textarea').bind('touchend', function(event){
      var now = new Date().getTime();
      var lastTouch = $(this).data('lastTouch') || now + 1 /** the first time this will make delta a negative number */;
      var delta = now - lastTouch;
      clearTimeout(action);
      if (delta<500 && delta>0){
        if ($(this).css("text-decoration") == "none solid rgb(0, 0, 0)")
          $(this).css("text-decoration", "line-through");
        else
          $(this).css("text-decoration", "none solid rgb(0, 0, 0)");
      } else {
        $(this).data('lastTouch', now);
        action = setTimeout(function(e){
         // If this runs you can invoke your 'click/touchend' code
         clearTimeout(action);   // clear the timeout
        }, 500, [event]);
      }
      $(this).data('lastTouch', now);
    });
  }
}

function subjectListen() {
  $('.subj').unbind(); // When you add a subject, need to re-add all the listeners

  $('.subj').on('dblclick', '.subjectspan', function () {
    var input = $('<input />', {
      'type': 'text',
      'name': 'unique',
      'value': $(this).html()
    });
    $(this).parent().prepend(input);
    $(this).remove();
    input.focus();
  });

   $('.subj').on('blur', 'input', function () {
      $(this).parent().prepend($('<span />', {'class':'.subjectspan'}).html($(this).val()));
      var id = $(this).parent().get(0).id;
      var subj = $(this).val();
      $(this).remove();

      if (id != 0) {
        $(this).prop('contenteditable', false); // make it not editable
        ref.settings.rows[id-1] = subj; // actually change the name
        // Save the new settings
        db.put(ref.settings, function(err, response) {
          if (err) {
            alert("there's been an error. try again.");
            console.log(err);
          } else {
            db.get("settings").then(function(s) {
              ref.settings = s;
            });
          }
        });
      }

  });

  // mouseover logic
  $('.subj').mouseenter(function() {
    $(this).children(".subjbtns").show();
  });
  $('.subj').mouseleave(function() {
     $(this).children(".subjbtns").hide();
  });

  $('button.delete').unbind();
  // delete subject
  $('button.delete').click(function() {
    var id = $(this).parent().parent()[0].id;
    if (confirm("Are you sure you want to delete " + ref.settings.rows[id-1] + "?")){
      ref.settings.rows.splice(id-1, 1); // splice out the row from settings
      // save
      db.put(ref.settings, function(err, response) {
        if (err) {
          alert("there's been an error. try again.");
          console.log(err);
        } else {
          db.get("settings").then(function(s) {
            ref.settings = s;
            renderRows(s.rows);
          });
        }
      });
    }
  });
  $('button.edit').unbind();
  $('button.edit').click(function() {
      var t = $(this).parent().parent().children('.subjectspan');
      var input = $('<input />', {
        'type': 'text',
        'name': 'unique',
        'value': $(t).html()
      });
      $(t).parent().prepend(input);
      $(t).remove();
      input.focus();
  });
}<|endoftext|>


<commit_before>import { set } from 'lodash';
import faker from 'faker';
import { getDirectiveValue } from '../utils';

export default {
  name: 'fake',
  description: 'Fakes a field.',
  resolveStatic: {
    enter(node, directive, { ast, resolvers, ancestors }) {
      if (process.env.FAKE) {
        return;
      }
      if (node.kind === 'ObjectTypeDefinition') {
        const isMany = getDirectiveValue(node, 'fake', 'many');
        const isOne = getDirectiveValue(node, 'fake', 'one');
        if (isMany) {
          set(resolvers, `RootQuery.${isMany}`, (source, args) =>
            Array(...{ length: 100 }).map(Number.call, Number),
          );
        }
        if (isOne) {
          set(resolvers, `RootQuery.${isOne}`, (source, args) => ({}));
        }
      } else {
        const isList = node.type.kind === 'ListType';
        const name = getDirectiveValue(node, 'fake', 'type');
        const leftType = ancestors[ancestors.length - 1].name.value;
        const leftField = node.name.value;
        if (name) {
          const [category, field] = name.split('.');
          set(resolvers, `${leftType}.${leftField}`, (source, args) =>
            faker[category][field](),
          );
        } else if (isList) {
          set(resolvers, `${leftType}.${leftField}`, (source, args) =>
            Array(...{ length: 10 }).map(Number.call, Number),
          );
        } else {
          set(resolvers, `${leftType}.${leftField}`, (source, args) => ({}));
        }
      }
    },
  },
};
<commit_msg>random items in faker<commit_after>import { set } from 'lodash';
import faker from 'faker';
import { getDirectiveValue } from '../utils';

export default {
  name: 'fake',
  description: 'Fakes a field.',
  resolveStatic: {
    enter(node, directive, { ast, resolvers, ancestors }) {
      if (process.env.FAKE) {
        return;
      }
      if (node.kind === 'ObjectTypeDefinition') {
        const isMany = getDirectiveValue(node, 'fake', 'many');
        const isOne = getDirectiveValue(node, 'fake', 'one');
        if (isMany) {
          set(resolvers, `RootQuery.${isMany}`, (source, args) =>
            Array(...{ length: Math.random() * (100 - 20) + 20 }).map(
              Number.call,
              Number,
            ),
          );
        }
        if (isOne) {
          set(resolvers, `RootQuery.${isOne}`, (source, args) => ({}));
        }
      } else {
        const isList = node.type.kind === 'ListType';
        const name = getDirectiveValue(node, 'fake', 'type');
        const leftType = ancestors[ancestors.length - 1].name.value;
        const leftField = node.name.value;
        if (name) {
          const [category, field] = name.split('.');
          set(resolvers, `${leftType}.${leftField}`, (source, args) =>
            faker[category][field](),
          );
        } else if (isList) {
          set(resolvers, `${leftType}.${leftField}`, (source, args) =>
            Array(...{ length: Math.random() * (10 - 3) + 3 }).map(
              Number.call,
              Number,
            ),
          );
        } else {
          set(resolvers, `${leftType}.${leftField}`, (source, args) => ({}));
        }
      }
    },
  },
};
<|endoftext|>


<commit_before>/**
 * file-copy
 * =========
 *
 * Копирует один таргет в другой.
 * Может, например, использоваться для построения `_?.css` из `?.css` для development-режима.
 *
 * **Опции**
 *
 * * *String* **source** — Исходный таргет. Обязательная опция.
 * * *String* **sourceNode** — Путь ноды с исходным таргетом.
 * * *String* **target** — Результирующий таргет. Обязательная опция.
 *
 * **Пример**
 *
 * ```javascript
 * nodeConfig.addTech([ require('enb/techs/file-copy'), {
 *   source: '?.css',
 *   target: '_?.css'
 * } ]);
 * ```
 */
var inherit = require('inherit'),
    enb = require('../lib/api'),
    vfs = enb.asyncFs;

module.exports = inherit(enb.BaseTech, {
    getName: function () {
        return 'file-copy';
    },

    configure: function () {
        this._source = this.getOption('sourceTarget');
        if (!this._source) {
            this._source = this.getRequiredOption('source');
        }

        this._sourceNode = this.getOption('sourceNode');

        this._target = this.getOption('destTarget');
        if (!this._target) {
            this._target = this.getRequiredOption('target');
        }
    },

    getTargets: function () {
        return [this.node.unmaskTargetName(this._target)];
    },

    build: function () {
        var _this = this;
        var node = this.node;
        var cache = node.getNodeCache(target);
        var target = node.unmaskTargetName(this._target);
        var targetPath = node.resolvePath(target);
        var sourceNode = this._sourceNode;
        var source;
        var sourcePath;
        var requirements = {};
        var requireSources;

        if (sourceNode) {
            source = node.unmaskNodeTargetName(sourceNode, this._source);
            sourcePath = node.resolveNodePath(sourceNode, source);
            requirements[sourceNode] = [source];
            requireSources = node.requireNodeSources(requirements);
        } else {
            source = node.unmaskTargetName(this._source);
            sourcePath = node.resolvePath(source);
            requireSources = node.requireSources([source]);
        }

        return requireSources.then(function () {
            if (cache.needRebuildFile('source-file', sourcePath) ||
                cache.needRebuildFile('target-file', targetPath)
            ) {
                return vfs.read(sourcePath, 'utf8').then(function (data) {
                    return vfs.write(targetPath, data, 'utf8').then(function () {
                        cache.cacheFileInfo('source-file', sourcePath);
                        cache.cacheFileInfo('target-file', targetPath);
                        _this.node.resolveTarget(target);
                    });
                });
            } else {
                _this.node.isValidTarget(target);
                _this.node.resolveTarget(target);
                return null;
            }
        });
    }
});
<commit_msg>Fix `file-copy` caching<commit_after>/**
 * file-copy
 * =========
 *
 * Копирует один таргет в другой.
 * Может, например, использоваться для построения `_?.css` из `?.css` для development-режима.
 *
 * **Опции**
 *
 * * *String* **source** — Исходный таргет. Обязательная опция.
 * * *String* **sourceNode** — Путь ноды с исходным таргетом.
 * * *String* **target** — Результирующий таргет. Обязательная опция.
 *
 * **Пример**
 *
 * ```javascript
 * nodeConfig.addTech([ require('enb/techs/file-copy'), {
 *   source: '?.css',
 *   target: '_?.css'
 * } ]);
 * ```
 */
var inherit = require('inherit'),
    enb = require('../lib/api'),
    vfs = enb.asyncFs;

module.exports = inherit(enb.BaseTech, {
    getName: function () {
        return 'file-copy';
    },

    configure: function () {
        this._source = this.getOption('sourceTarget');
        if (!this._source) {
            this._source = this.getRequiredOption('source');
        }

        this._sourceNode = this.getOption('sourceNode');

        this._target = this.getOption('destTarget');
        if (!this._target) {
            this._target = this.getRequiredOption('target');
        }
    },

    getTargets: function () {
        return [this.node.unmaskTargetName(this._target)];
    },

    build: function () {
        var _this = this;
        var node = this.node;
        var target = node.unmaskTargetName(this._target);
        var cache = node.getNodeCache(target);
        var targetPath = node.resolvePath(target);
        var sourceNode = this._sourceNode;
        var source;
        var sourcePath;
        var requirements = {};
        var requireSources;

        if (sourceNode) {
            source = node.unmaskNodeTargetName(sourceNode, this._source);
            sourcePath = node.resolveNodePath(sourceNode, source);
            requirements[sourceNode] = [source];
            requireSources = node.requireNodeSources(requirements);
        } else {
            source = node.unmaskTargetName(this._source);
            sourcePath = node.resolvePath(source);
            requireSources = node.requireSources([source]);
        }

        return requireSources.then(function () {
            if (cache.needRebuildFile('source-file', sourcePath) ||
                cache.needRebuildFile('target-file', targetPath)
            ) {
                return vfs.read(sourcePath, 'utf8').then(function (data) {
                    return vfs.write(targetPath, data, 'utf8').then(function () {
                        cache.cacheFileInfo('source-file', sourcePath);
                        cache.cacheFileInfo('target-file', targetPath);
                        _this.node.resolveTarget(target);
                    });
                });
            } else {
                _this.node.isValidTarget(target);
                _this.node.resolveTarget(target);
                return null;
            }
        });
    }
});
<|endoftext|>