<commit_before>'use strict';
/**
 * Controller for the admin page.
 */

const co = require('co');
const _ = require('lodash');
const api = require('../services/api-proxy');
const Promise = require('bluebird');
const logger = require('../services/logger');
const config = require('../config/config');
const axios = require('axios');

let admin = {};

const defaultOptions = (req) => {
  return {
    error: req.flash('error'),
    success: req.flash('success'),
    layout: 'master',
    isLoggedIn: req.user,
    language: req.language
  };
};

admin.showDashboard = (req, res) => {
  let options = defaultOptions(req);
  options.view = 'admin-dashboard';
  options.data = {};
  res.render('static/admin/dashboard', options);
};

admin.showDashboardEmails = function*(req, res) {
  let options = defaultOptions(req);
  options.view = 'admin-emails';
  let emailAddress = req.query.emailAddress;

  if(emailAddress) {
    options.data = {};
    const emails = yield admin.getAllEmailsTo(emailAddress);

    // Date in JS is in ms but api response is in s
    options.data.emails = emails.map(email => {
      email.create_date = email.create_date * 1000;
      return email;
    });
  }

  res.render('static/admin/dashboard', options);
};

admin.showDashboardPayment = function*(req, res) {
  let options = defaultOptions(req);
  options.view = 'admin-payment';
  options.data = yield admin.getInvoices(req);
  options.data = options.data
    .filter(invoice => invoice.event.isCurrent)
    .sort(invoice => invoice.event.id)
    .reverse();
  res.render('static/admin/dashboard', options);
};

admin.showDashboardCheckin = function*(req, res) {
  let options = defaultOptions(req);
  options.view = 'admin-checkin';
  options.data = yield admin.getAllTeams(req);
  res.render('static/admin/dashboard', options);
};

admin.showOverview = function*(req, res) {

  if (!req.query.sortBy) {
    req.query.sortBy = 'lastContact';
    req.query.direction = 'up';
  }

  function compare(a,b) {
    if(a[req.query.sortBy]){
      if(req.query.direction === 'up'){
        if (a[req.query.sortBy].timestamp< b[req.query.sortBy].timestamp)
          return -1;
        if (a[req.query.sortBy].timestamp > b[req.query.sortBy].timestamp)
          return 1;
        return 0;
      }
      else if(req.query.direction === 'down'){
        if (a[req.query.sortBy].timestamp> b[req.query.sortBy].timestamp)
          return -1;
        if (a[req.query.sortBy].timestamp < b[req.query.sortBy].timestamp)
          return 1;
        return 0;
      }
    }
  }

  let options = defaultOptions(req);
  options.view = 'admin-teamoverview';                 // TODO: .then should be moved to api layer
  options.data = yield api.getTeamOverview(getAccessTokenFromRequest(req)).then(resp => resp.data);

  let callReasons = [
    'Technical Problem',
    '5h Update',
    'New Transport',
    'Finished BreakOut',
    'Sickness',
    'Emergency',
    'Other'
  ];

  options.data = options.data.map(function(team){
    team.lastContact = {};
    team.callReasons = callReasons;

    let validInfo = [team.lastContactWithHeadquarters, team.lastPosting, team.lastLocation].filter(function(elem){
      return elem;
    });

    let validTimestamps = validInfo.map(function(info){
      return info.timestamp;
    }).filter(function(elem){
      return elem;
    });

    if(validTimestamps.length != 0){
      team.lastContact.timestamp = Math.max.apply(Math, validTimestamps);
    } else {
      team.lastContact.timestamp = null;
    }

    if(!team.lastContactWithHeadquarters) {
      team.lastContactWithHeadquarters = {};
      team.lastContactWithHeadquarters.timestamp = null;
    }

    if(!team.lastPosting) {
      team.lastPosting = {};
      team.lastPosting.timestamp = null;
    }

    if(!team.lastLocation) {
      team.lastLocation = {};
      team.lastLocation.timestamp = null;
    }

    return team;
  });

  if(req.query.sortBy){
    options.data = options.data.sort(compare);
  }

  res.render('static/admin/dashboard', options);
};

function getAccessTokenFromRequest(req) {
  return req.user.access_token;
}

admin.showDashboardInvoice = function*(req, res) {
  let options = defaultOptions(req);
  options.view = 'admin-invoice';
  if(req.query.eventId) {
    options.data = yield admin.getSponsoringInvoicesByEventId(req.user, req.query.eventId);
  }

  res.render('static/admin/dashboard', options);
};

admin.getSponsoringInvoicesByEventId = function(tokens, eventId) {
  return api.getModel(`/sponsoringinvoice/${eventId}/`, tokens);
};

admin.addPayment = function *(req, res) {
  logger.info(`Trying to add payment for invoice ${req.body.invoice}`);

  let body = {
    amount: req.body.amount,
    fidorId: req.body.fidorId,
    date: Math.round(new Date().getTime() / 1000)
  };

  try {
    yield api.postModel(`invoice/${req.body.invoice}/payment/`, req.user, body);
    res.sendStatus(200);
  } catch (err) {
    res.status(500);
    logger.error(`An error occured while trying to add a payment to invoice ${req.body.invoice}: `, err);
    if (err.message) {
      res.json({message: err.message});
    } else {
      res.json({message: 'An unknown error occured'});
    }

  }
};

admin.setTeamSleepStatus = function *(req, res) {

  try {
    let team = yield api.putModel(`event/${req.body.eventid}/team`, req.body.teamid, req.user, { asleep: req.body.asleep });
    res.redirect('/admin/teamoverview/');
  } catch (err) {
    res.status(500);
    logger.error(`An error occured while trying to update the last contact ${req.body.update}: `, err);
    if (err.message) {
      res.json({message: err.message});
    } else {
      res.json({message: 'An unknown error occured'});
    }
  }

}

admin.updateLastContact = function *(req, res) {

  try {
    let comment = yield api.postModel(`teamoverview/${req.body.teamid}/lastContactWithHeadquarters/`, req.user, { comment: req.body.update, reason: req.body.reason });
    res.redirect('/admin/teamoverview/');
  } catch (err) {
    res.status(500);
    logger.error(`An error occured while trying to update the last contact ${req.body.update}: `, err);
    if (err.message) {
      res.json({message: err.message});
    } else {
      res.json({message: 'An unknown error occured'});
    }

  }
};

admin.getAllEmailsTo = function(emailAddress) {
  return axios.get(`https://mail.break-out.org/get/to/${emailAddress}`, {
    headers: {
      'X-AUTH-TOKEN': config.mailer.x_auth_token
    }
  }).then(resp => resp.data);
};

admin.getInvoices = (req) => co(function*() {
  const events = yield api.getModel('event', req.user);

  let teamsByEvent = yield events.map((e) => api.getModel(`event/${e.id}/team`, req.user));
  let allTeams = _.flatten(teamsByEvent);

  let allInvoices = [];

  for (let i = 0; i < allTeams.length; i++) {
    let t = allTeams[i];
    if (t.members.length > 1) {
      let invoice = yield api.getModel('invoice/teamfee', req.user, t.invoiceId);
      // TODO: This logic is very fragile b.c. it merges together two requests
      invoice.event = events.find(event => event.id === t.event);
      invoice.members = t.members;
      invoice.teamName = t.name;
      invoice.id = t.invoiceId;
      invoice.teamId = t.id;
      if (invoice.payments.length) {
        invoice.open = invoice.amount - invoice.payments.reduce((prev, curr) => {
          return prev + curr.amount;
        }, 0);
      } else {
        invoice.open = invoice.amount;
      }
      invoice.datesFidorIds = invoice.payments.map((payment) => `${new Date(payment.date * 1000).toLocaleDateString()} (id: ${payment.fidorId})`).join(', ');
      allInvoices.push(invoice);
    }
  }

  return allInvoices;
}).catch((ex) => {
  throw ex;
});

admin.getAllTeams = function () {
  return Promise.resolve(api.event.all())
    .map(event => api.team.getAllByEvent(event.id))
    .reduce((a, b) => a.concat(b), [])
    .filter(team => team.hasFullyPaid);
};

admin.checkinTeam = function *(req, res) {

  const tokens = req.user;
  const update = {hasStarted: true};

  let checkin = yield api.putModel(`event/${req.body.event}/team`, req.body.team, tokens, update);

  if (!checkin) return res.sendStatus(500);

  return res.sendStatus(200);
};

admin.getAllInvoices = (req) => co(function*() {

  let rawInvoices = yield api.invoice.getAll(req.user);

  var teams = [];

  var invoices = rawInvoices.map(i => {
    if (i.payments.length) {
      i.payed = i.payments.reduce((prev, curr) => {
        return prev + curr.amount;
      }, 0);
      i.open = i.amount - i.payed;
      if (i.open < 0) i.open = 0;
    } else {
      i.payed = 0;
      i.open = i.amount;
    }
    return i;
  });

  invoices.forEach(i => {
    if (!teams[i.teamId]) teams[i.teamId] = 0;
    teams[i.teamId] += i.payed;
  });

  // TODO: This is unused, what is the reason?
  var depositTeams = teams.map((t, index) => {
    if (t > 100) {
      return {
        teamId: index,
        amount: t
      };
    }
  });

  return invoices;

}).catch((ex) => {
  throw ex;
});

admin.addAmountToInvoice = function *(req, res) {

  let addAmount = yield api.invoice.addAmount(req.user, req.body.invoiceId, req.body.amount);

  if (!addAmount) return res.sendStatus(500);

  return res.sendStatus(200);
};

admin.addInvoice = function *(req, res) {

  var body = {
    firstname: req.body.firstname,
    lastname: req.body.lastname,
    company: req.body.company,
    teamId: parseFloat(req.body.teamId),
    amount: parseFloat(req.body.amount)
  };

  let addAmount = yield api.invoice.create(req.user, body);

  if (!addAmount) return res.sendStatus(500);

  return res.status(200).send(addAmount);

};

module.exports = admin;
<commit_msg>Adding missing semi colon<commit_after>'use strict';
/**
 * Controller for the admin page.
 */

const co = require('co');
const _ = require('lodash');
const api = require('../services/api-proxy');
const Promise = require('bluebird');
const logger = require('../services/logger');
const config = require('../config/config');
const axios = require('axios');

let admin = {};

const defaultOptions = (req) => {
  return {
    error: req.flash('error'),
    success: req.flash('success'),
    layout: 'master',
    isLoggedIn: req.user,
    language: req.language
  };
};

admin.showDashboard = (req, res) => {
  let options = defaultOptions(req);
  options.view = 'admin-dashboard';
  options.data = {};
  res.render('static/admin/dashboard', options);
};

admin.showDashboardEmails = function*(req, res) {
  let options = defaultOptions(req);
  options.view = 'admin-emails';
  let emailAddress = req.query.emailAddress;

  if(emailAddress) {
    options.data = {};
    const emails = yield admin.getAllEmailsTo(emailAddress);

    // Date in JS is in ms but api response is in s
    options.data.emails = emails.map(email => {
      email.create_date = email.create_date * 1000;
      return email;
    });
  }

  res.render('static/admin/dashboard', options);
};

admin.showDashboardPayment = function*(req, res) {
  let options = defaultOptions(req);
  options.view = 'admin-payment';
  options.data = yield admin.getInvoices(req);
  options.data = options.data
    .filter(invoice => invoice.event.isCurrent)
    .sort(invoice => invoice.event.id)
    .reverse();
  res.render('static/admin/dashboard', options);
};

admin.showDashboardCheckin = function*(req, res) {
  let options = defaultOptions(req);
  options.view = 'admin-checkin';
  options.data = yield admin.getAllTeams(req);
  res.render('static/admin/dashboard', options);
};

admin.showOverview = function*(req, res) {

  if (!req.query.sortBy) {
    req.query.sortBy = 'lastContact';
    req.query.direction = 'up';
  }

  function compare(a,b) {
    if(a[req.query.sortBy]){
      if(req.query.direction === 'up'){
        if (a[req.query.sortBy].timestamp< b[req.query.sortBy].timestamp)
          return -1;
        if (a[req.query.sortBy].timestamp > b[req.query.sortBy].timestamp)
          return 1;
        return 0;
      }
      else if(req.query.direction === 'down'){
        if (a[req.query.sortBy].timestamp> b[req.query.sortBy].timestamp)
          return -1;
        if (a[req.query.sortBy].timestamp < b[req.query.sortBy].timestamp)
          return 1;
        return 0;
      }
    }
  }

  let options = defaultOptions(req);
  options.view = 'admin-teamoverview';                 // TODO: .then should be moved to api layer
  options.data = yield api.getTeamOverview(getAccessTokenFromRequest(req)).then(resp => resp.data);

  let callReasons = [
    'Technical Problem',
    '5h Update',
    'New Transport',
    'Finished BreakOut',
    'Sickness',
    'Emergency',
    'Other'
  ];

  options.data = options.data.map(function(team){
    team.lastContact = {};
    team.callReasons = callReasons;

    let validInfo = [team.lastContactWithHeadquarters, team.lastPosting, team.lastLocation].filter(function(elem){
      return elem;
    });

    let validTimestamps = validInfo.map(function(info){
      return info.timestamp;
    }).filter(function(elem){
      return elem;
    });

    if(validTimestamps.length != 0){
      team.lastContact.timestamp = Math.max.apply(Math, validTimestamps);
    } else {
      team.lastContact.timestamp = null;
    }

    if(!team.lastContactWithHeadquarters) {
      team.lastContactWithHeadquarters = {};
      team.lastContactWithHeadquarters.timestamp = null;
    }

    if(!team.lastPosting) {
      team.lastPosting = {};
      team.lastPosting.timestamp = null;
    }

    if(!team.lastLocation) {
      team.lastLocation = {};
      team.lastLocation.timestamp = null;
    }

    return team;
  });

  if(req.query.sortBy){
    options.data = options.data.sort(compare);
  }

  res.render('static/admin/dashboard', options);
};

function getAccessTokenFromRequest(req) {
  return req.user.access_token;
}

admin.showDashboardInvoice = function*(req, res) {
  let options = defaultOptions(req);
  options.view = 'admin-invoice';
  if(req.query.eventId) {
    options.data = yield admin.getSponsoringInvoicesByEventId(req.user, req.query.eventId);
  }

  res.render('static/admin/dashboard', options);
};

admin.getSponsoringInvoicesByEventId = function(tokens, eventId) {
  return api.getModel(`/sponsoringinvoice/${eventId}/`, tokens);
};

admin.addPayment = function *(req, res) {
  logger.info(`Trying to add payment for invoice ${req.body.invoice}`);

  let body = {
    amount: req.body.amount,
    fidorId: req.body.fidorId,
    date: Math.round(new Date().getTime() / 1000)
  };

  try {
    yield api.postModel(`invoice/${req.body.invoice}/payment/`, req.user, body);
    res.sendStatus(200);
  } catch (err) {
    res.status(500);
    logger.error(`An error occured while trying to add a payment to invoice ${req.body.invoice}: `, err);
    if (err.message) {
      res.json({message: err.message});
    } else {
      res.json({message: 'An unknown error occured'});
    }

  }
};

admin.setTeamSleepStatus = function *(req, res) {
  try {
    let team = yield api.putModel(`event/${req.body.eventid}/team`, req.body.teamid, req.user, { asleep: req.body.asleep });
    res.redirect('/admin/teamoverview/');
  } catch (err) {
    res.status(500);
    logger.error(`An error occured while trying to update the last contact ${req.body.update}: `, err);
    if (err.message) {
      res.json({message: err.message});
    } else {
      res.json({message: 'An unknown error occured'});
    }
  }
};

admin.updateLastContact = function *(req, res) {

  try {
    let comment = yield api.postModel(`teamoverview/${req.body.teamid}/lastContactWithHeadquarters/`, req.user, { comment: req.body.update, reason: req.body.reason });
    res.redirect('/admin/teamoverview/');
  } catch (err) {
    res.status(500);
    logger.error(`An error occured while trying to update the last contact ${req.body.update}: `, err);
    if (err.message) {
      res.json({message: err.message});
    } else {
      res.json({message: 'An unknown error occured'});
    }

  }
};

admin.getAllEmailsTo = function(emailAddress) {
  return axios.get(`https://mail.break-out.org/get/to/${emailAddress}`, {
    headers: {
      'X-AUTH-TOKEN': config.mailer.x_auth_token
    }
  }).then(resp => resp.data);
};

admin.getInvoices = (req) => co(function*() {
  const events = yield api.getModel('event', req.user);

  let teamsByEvent = yield events.map((e) => api.getModel(`event/${e.id}/team`, req.user));
  let allTeams = _.flatten(teamsByEvent);

  let allInvoices = [];

  for (let i = 0; i < allTeams.length; i++) {
    let t = allTeams[i];
    if (t.members.length > 1) {
      let invoice = yield api.getModel('invoice/teamfee', req.user, t.invoiceId);
      // TODO: This logic is very fragile b.c. it merges together two requests
      invoice.event = events.find(event => event.id === t.event);
      invoice.members = t.members;
      invoice.teamName = t.name;
      invoice.id = t.invoiceId;
      invoice.teamId = t.id;
      if (invoice.payments.length) {
        invoice.open = invoice.amount - invoice.payments.reduce((prev, curr) => {
          return prev + curr.amount;
        }, 0);
      } else {
        invoice.open = invoice.amount;
      }
      invoice.datesFidorIds = invoice.payments.map((payment) => `${new Date(payment.date * 1000).toLocaleDateString()} (id: ${payment.fidorId})`).join(', ');
      allInvoices.push(invoice);
    }
  }

  return allInvoices;
}).catch((ex) => {
  throw ex;
});

admin.getAllTeams = function () {
  return Promise.resolve(api.event.all())
    .map(event => api.team.getAllByEvent(event.id))
    .reduce((a, b) => a.concat(b), [])
    .filter(team => team.hasFullyPaid);
};

admin.checkinTeam = function *(req, res) {

  const tokens = req.user;
  const update = {hasStarted: true};

  let checkin = yield api.putModel(`event/${req.body.event}/team`, req.body.team, tokens, update);

  if (!checkin) return res.sendStatus(500);

  return res.sendStatus(200);
};

admin.getAllInvoices = (req) => co(function*() {

  let rawInvoices = yield api.invoice.getAll(req.user);

  var teams = [];

  var invoices = rawInvoices.map(i => {
    if (i.payments.length) {
      i.payed = i.payments.reduce((prev, curr) => {
        return prev + curr.amount;
      }, 0);
      i.open = i.amount - i.payed;
      if (i.open < 0) i.open = 0;
    } else {
      i.payed = 0;
      i.open = i.amount;
    }
    return i;
  });

  invoices.forEach(i => {
    if (!teams[i.teamId]) teams[i.teamId] = 0;
    teams[i.teamId] += i.payed;
  });

  // TODO: This is unused, what is the reason?
  var depositTeams = teams.map((t, index) => {
    if (t > 100) {
      return {
        teamId: index,
        amount: t
      };
    }
  });

  return invoices;

}).catch((ex) => {
  throw ex;
});

admin.addAmountToInvoice = function *(req, res) {

  let addAmount = yield api.invoice.addAmount(req.user, req.body.invoiceId, req.body.amount);

  if (!addAmount) return res.sendStatus(500);

  return res.sendStatus(200);
};

admin.addInvoice = function *(req, res) {

  var body = {
    firstname: req.body.firstname,
    lastname: req.body.lastname,
    company: req.body.company,
    teamId: parseFloat(req.body.teamId),
    amount: parseFloat(req.body.amount)
  };

  let addAmount = yield api.invoice.create(req.user, body);

  if (!addAmount) return res.sendStatus(500);

  return res.status(200).send(addAmount);

};

module.exports = admin;
<|endoftext|>


<commit_before>// @flow
import { observable, action } from 'mobx';
import AppStore from './AppStore';
import SettingsStore from './SettingsStore';
import WalletsStore from './WalletsStore';
import TransactionsStore from './TransactionsStore';
import SidebarStore from './SidebarStore';
import WindowStore from './WindowStore';
import WalletBackupStore from './WalletBackupStore';
import NetworkStatusStore from './NetworkStatusStore';
import AdaRedemptionStore from './AdaRedemptionStore';
import NodeUpdateStore from './NodeUpdateStore';

const storeClasses = {
  app: AppStore,
  settings: SettingsStore,
  wallets: WalletsStore,
  transactions: TransactionsStore,
  sidebar: SidebarStore,
  window: WindowStore,
  walletBackup: WalletBackupStore,
  networkStatus: NetworkStatusStore,
  adaRedemption: AdaRedemptionStore,
  nodeUpdate: NodeUpdateStore,
};

// Constant that does never change during lifetime
const stores = observable({
  router: null,
  app: null,
  settings: null,
  wallets: null,
  transactions: null,
  sidebar: null,
  window: null,
  walletBackup: null,
  networkStatus: null,
  adaRedemption: null,
  nodeUpdate: null,
});

// Set up and return the stores for this app -> also used to reset all stores to defaults
export default action((api, actions, router): storesType => {
  // Assign mobx-react-router only once
  if (stores.router == null) stores.router = router;
  // All other stores have our lifecycle
  const storeNames = Object.keys(storeClasses);
  storeNames.forEach(name => { if (stores[name]) stores[name].teardown(); });
  storeNames.forEach(name => { stores[name] = new storeClasses[name](stores, api, actions); });
  storeNames.forEach(name => { if (stores[name]) stores[name].initialize(); });
  return stores;
});

export type storesType = {
  app: Object,
  settings: Object,
  wallets: Object,
  transactions: Object,
  sidebar: Object,
  window: Object,
  walletBackup: Object,
  networkStatus: Object,
  adaRedemption: Object,
  nodeUpdate: Object,
};
<commit_msg>[DAEF-99] add proper fix for store flow types declarations<commit_after>// @flow
import { observable, action } from 'mobx';
import AppStore from './AppStore';
import SettingsStore from './SettingsStore';
import WalletsStore from './WalletsStore';
import TransactionsStore from './TransactionsStore';
import SidebarStore from './SidebarStore';
import WindowStore from './WindowStore';
import WalletBackupStore from './WalletBackupStore';
import NetworkStatusStore from './NetworkStatusStore';
import AdaRedemptionStore from './AdaRedemptionStore';
import NodeUpdateStore from './NodeUpdateStore';

const storeClasses = {
  app: AppStore,
  settings: SettingsStore,
  wallets: WalletsStore,
  transactions: TransactionsStore,
  sidebar: SidebarStore,
  window: WindowStore,
  walletBackup: WalletBackupStore,
  networkStatus: NetworkStatusStore,
  adaRedemption: AdaRedemptionStore,
  nodeUpdate: NodeUpdateStore,
};

// Constant that does never change during lifetime
const stores = observable({
  router: null,
  app: null,
  settings: null,
  wallets: null,
  transactions: null,
  sidebar: null,
  window: null,
  walletBackup: null,
  networkStatus: null,
  adaRedemption: null,
  nodeUpdate: null,
});

// Set up and return the stores for this app -> also used to reset all stores to defaults
export default action((api, actions, router): storesType => {
  // Assign mobx-react-router only once
  if (stores.router == null) stores.router = router;
  // All other stores have our lifecycle
  const storeNames = Object.keys(storeClasses);
  storeNames.forEach(name => { if (stores[name]) stores[name].teardown(); });
  storeNames.forEach(name => { stores[name] = new storeClasses[name](stores, api, actions); });
  storeNames.forEach(name => { if (stores[name]) stores[name].initialize(); });
  return stores;
});

export type storesType = {
  app: AppStore,
  settings: SettingsStore,
  wallets: WalletsStore,
  transactions: TransactionsStore,
  sidebar: SidebarStore,
  window: WindowStore,
  walletBackup: WalletBackupStore,
  networkStatus: NetworkStatusStore,
  adaRedemption: AdaRedemptionStore,
  nodeUpdate: NodeUpdateStore,
};
<|endoftext|>


<commit_before>/*
Display scroll progress bar across bottom of image.
 */
(function($, cornerstone, cornerstoneTools) {

    'use strict';

    var scrollBarHeight = 6;

    var configuration = {
        backgroundColor: 'rgb(19, 63, 141)',
        fillColor: 'white'
    };

    function onImageRendered(e, eventData){
        var element = eventData.element;
        var width = eventData.enabledElement.canvas.width;
        var height = eventData.enabledElement.canvas.height;

        if (!width || !height) {
            return false;
        }

        var context = eventData.enabledElement.canvas.getContext('2d');
        context.setTransform(1, 0, 0, 1, 0, 0);
        context.save();

        var config = cornerstoneTools.scrollIndicator.getConfiguration();

        // draw indicator background
        context.fillStyle = config.backgroundColor;
        context.fillRect(0, height - scrollBarHeight, width, scrollBarHeight);

        // get current image index
        var stackData = cornerstoneTools.getToolState(element, 'stack');
        if (!stackData || !stackData.data || !stackData.data.length) {
            return;
        }

        var imageIds = stackData.data[0].imageIds;
        var currentImageIdIndex = stackData.data[0].currentImageIdIndex;

        // draw current image cursor
        var cursorWidth = width / imageIds.length;
        var xPosition = cursorWidth * currentImageIdIndex;

        context.fillStyle = config.fillColor;
        context.fillRect(xPosition, height - scrollBarHeight, cursorWidth, scrollBarHeight);

        context.restore();
    }

    cornerstoneTools.scrollIndicator = cornerstoneTools.displayTool(onImageRendered);
    cornerstoneTools.scrollIndicator.setConfiguration(configuration);

})($, cornerstone, cornerstoneTools);
<commit_msg>Make scrollbar position configurable<commit_after>/*
Display scroll progress bar across bottom of image.
 */
(function($, cornerstone, cornerstoneTools) {

    'use strict';

    var scrollBarHeight = 6;

    var configuration = {
        backgroundColor: 'rgb(19, 63, 141)',
        fillColor: 'white',
        orientation: 'horizontal'
    };

    function onImageRendered(e, eventData){
        var element = eventData.element;
        var width = eventData.enabledElement.canvas.width;
        var height = eventData.enabledElement.canvas.height;

        if (!width || !height) {
            return false;
        }

        var context = eventData.enabledElement.canvas.getContext('2d');
        context.setTransform(1, 0, 0, 1, 0, 0);
        context.save();

        var config = cornerstoneTools.scrollIndicator.getConfiguration();

        // draw indicator background
        context.fillStyle = config.backgroundColor;
        if(config.orientation === 'horizontal')
            context.fillRect(0, height - scrollBarHeight, width, scrollBarHeight);
        else
            context.fillRect(0, 0, scrollBarHeight, height);

        // get current image index
        var stackData = cornerstoneTools.getToolState(element, 'stack');
        if (!stackData || !stackData.data || !stackData.data.length) {
            return;
        }

        var imageIds = stackData.data[0].imageIds;
        var currentImageIdIndex = stackData.data[0].currentImageIdIndex;

        // draw current image cursor
        var cursorWidth = width / imageIds.length;
        var xPosition = cursorWidth * currentImageIdIndex;

        context.fillStyle = config.fillColor;
        if(config.orientation === 'horizontal')
            context.fillRect(xPosition, height - scrollBarHeight, cursorWidth, scrollBarHeight);
        else
            context.fillRect(0, yPosition, scrollBarHeight, cursorHeight);

        context.restore();
    }

    cornerstoneTools.scrollIndicator = cornerstoneTools.displayTool(onImageRendered);
    cornerstoneTools.scrollIndicator.setConfiguration(configuration);

})($, cornerstone, cornerstoneTools);
<|endoftext|>


<commit_before>// native modules
const path = require('path');
// 3rd party modules
const fs = require('fs-extra');
const nconf = require('nconf');

const getDefaultDb = () => {
  const url = process.env.MONGO_PORT_27017_TCP_ADDR || '127.0.0.1';
  const port = process.env.MONGO_PORT_27017_TCP_PORT || 27017;
  const collection = process.env.MONGO_PORT_27017_TCP_ADDR ? 'opentmi_dev' : 'opentmi_test';
  return `mongodb://${url}:${port}/${collection}`;
};

// read configurations
const args = {
  listen: {
    alias: 'l',
    type: 'string',
    describe: 'set binding interface',
    nargs: 1
  },
  https: {
    describe: 'use https',
    type: 'bool'
  },
  port: {
    describe: 'set listen port',
    type: 'number',
    nargs: 1
  },
  verbose: {
    alias: 'v',
    type: 'number',
    describe: 'verbose level',
    count: 'v'
  },
  silent: {
    alias: 's',
    type: 'bool',
    describe: 'Silent mode'
  },
  config: {
    alias: 'c',
    default: 'config.json',
    type: 'string',
    describe: 'config file'
  },
  db: {
    type: 'string',
    describe: 'mongodb connection string'
  },
  'auto-reload': {
    alias: 'r',
    type: 'bool',
    describe: 'Automatically restart workers when changes detected in server directory'
  }
};

const sampleFile = path.resolve(__dirname, '../../config.example.json');
const defaults = JSON.parse(fs.readFileSync(sampleFile));
defaults.db = getDefaultDb();
nconf
  .argv(args, 'Usage: npm start -- (options)')
  .env()
  .file(path.resolve(process.cwd(), nconf.get('config')))
  .defaults(defaults);

const cfgFileName = path.resolve(process.cwd(), nconf.get('config'));
if (!fs.existsSync(cfgFileName)) {
  fs.copyFileSync(sampleFile, cfgFileName);
}

module.exports = nconf;
<commit_msg>use fs.copySync instead - copyFileSync does not exists until node 8.x (#202)<commit_after>// native modules
const path = require('path');
// 3rd party modules
const fs = require('fs-extra');
const nconf = require('nconf');

const getDefaultDb = () => {
  const url = process.env.MONGO_PORT_27017_TCP_ADDR || '127.0.0.1';
  const port = process.env.MONGO_PORT_27017_TCP_PORT || 27017;
  const collection = process.env.MONGO_PORT_27017_TCP_ADDR ? 'opentmi_dev' : 'opentmi_test';
  return `mongodb://${url}:${port}/${collection}`;
};

// read configurations
const args = {
  listen: {
    alias: 'l',
    type: 'string',
    describe: 'set binding interface',
    nargs: 1
  },
  https: {
    describe: 'use https',
    type: 'bool'
  },
  port: {
    describe: 'set listen port',
    type: 'number',
    nargs: 1
  },
  verbose: {
    alias: 'v',
    type: 'number',
    describe: 'verbose level',
    count: 'v'
  },
  silent: {
    alias: 's',
    type: 'bool',
    describe: 'Silent mode'
  },
  config: {
    alias: 'c',
    default: 'config.json',
    type: 'string',
    describe: 'config file'
  },
  db: {
    type: 'string',
    describe: 'mongodb connection string'
  },
  'auto-reload': {
    alias: 'r',
    type: 'bool',
    describe: 'Automatically restart workers when changes detected in server directory'
  }
};

const sampleFile = path.resolve(__dirname, '../../config.example.json');
const defaults = JSON.parse(fs.readFileSync(sampleFile));
defaults.db = getDefaultDb();
nconf
  .argv(args, 'Usage: npm start -- (options)')
  .env()
  .file(path.resolve(process.cwd(), nconf.get('config')))
  .defaults(defaults);

const cfgFileName = path.resolve(process.cwd(), nconf.get('config'));
if (!fs.existsSync(cfgFileName)) {
  fs.copySync(sampleFile, cfgFileName);
}

module.exports = nconf;
<|endoftext|>


<commit_before>const Collection = require('../util/Collection');
const GuildMember = require('./GuildMember');

/**
 * Keeps track of mentions in a {@link Message}.
 */
class MessageMentions {
  constructor(message, users, roles, everyone) {
    /**
     * Whether `@everyone` or `@here` were mentioned
     * @type {boolean}
     */
    this.everyone = Boolean(everyone);

    if (users) {
      if (users instanceof Collection) {
        /**
         * Any users that were mentioned
         * @type {Collection<Snowflake, User>}
         */
        this.users = new Collection(users);
      } else {
        this.users = new Collection();
        for (const mention of users) {
          let user = message.client.users.create(mention);
          this.users.set(user.id, user);
        }
      }
    } else {
      this.users = new Collection();
    }

    if (roles) {
      if (roles instanceof Collection) {
        /**
         * Any roles that were mentioned
         * @type {Collection<Snowflake, Role>}
         */
        this.roles = new Collection(roles);
      } else {
        this.roles = new Collection();
        for (const mention of roles) {
          const role = message.channel.guild.roles.get(mention);
          if (role) this.roles.set(role.id, role);
        }
      }
    } else {
      this.roles = new Collection();
    }

    /**
     * Content of the message
     * @type {Message}
     * @private
     */
    this._content = message.content;

    /**
     * The client the message is from
     * @type {Client}
     * @private
     */
    this._client = message.client;

    /**
     * The guild the message is in
     * @type {?Guild}
     * @private
     */
    this._guild = message.channel.guild;

    /**
     * Cached members for {@MessageMention#members}
     * @type {?Collection<Snowflake, GuildMember>}
     * @private
     */
    this._members = null;

    /**
     * Cached channels for {@MessageMention#channels}
     * @type {?Collection<Snowflake, GuildChannel>}
     * @private
     */
    this._channels = null;
  }

  /**
   * Any members that were mentioned (only in {@link TextChannel}s)
   * @type {?Collection<Snowflake, GuildMember>}
   * @readonly
   */
  get members() {
    if (this._members) return this._members;
    if (!this._guild) return null;
    this._members = new Collection();
    this.users.forEach(user => {
      const member = this._guild.member(user);
      if (member) this._members.set(member.user.id, member);
    });
    return this._members;
  }

  /**
   * Any channels that were mentioned
   * @type {Collection<Snowflake, GuildChannel>}
   * @readonly
   */
  get channels() {
    if (this._channels) return this._channels;
    this._channels = new Collection();
    let matches;
    while ((matches = this.constructor.CHANNELS_PATTERN.exec(this._content)) !== null) {
      const chan = this._client.channels.get(matches[1]);
      if (chan) this._channels.set(chan.id, chan);
    }
    return this._channels;
  }

  /**
   * Check if a user is mentioned.
   * Takes into account user mentions, role mentions, and @everyone/@here mentions.
   * @param {UserResolvable|GuildMember|Role|GuildChannel} data User/GuildMember/Role/Channel to check
   * @param {boolean} [strict=true] If role mentions and everyone/here mentions should be included
   * @returns {boolean}
   */
  has(data, strict = true) {
    if (strict && this.everyone) return true;
    if (strict && data instanceof GuildMember) {
      for (const role of this.roles.values()) if (data.roles.has(role.id)) return true;
    }
    const id = data.id || data;
    return this.users.has(id) || this.channels.has(id) || this.roles.has(id);
  }
}

/**
 * Regular expression that globally matches `@everyone` and `@here`
 * @type {RegExp}
 */
MessageMentions.EVERYONE_PATTERN = /@(everyone|here)/g;

/**
 * Regular expression that globally matches user mentions like `<@81440962496172032>`
 * @type {RegExp}
 */
MessageMentions.USERS_PATTERN = /<@!?(1|\d{17,19})>/g;

/**
 * Regular expression that globally matches role mentions like `<@&297577916114403338>`
 * @type {RegExp}
 */
MessageMentions.ROLES_PATTERN = /<@&(\d{17,19})>/g;

/**
 * Regular expression that globally matches channel mentions like `<#222079895583457280>`
 * @type {RegExp}
 */
MessageMentions.CHANNELS_PATTERN = /<#(\d{17,19})>/g;

module.exports = MessageMentions;
<commit_msg>Add more options to MessageMentions#has (#2131)<commit_after>const Collection = require('../util/Collection');
const GuildMember = require('./GuildMember');

/**
 * Keeps track of mentions in a {@link Message}.
 */
class MessageMentions {
  constructor(message, users, roles, everyone) {
    /**
     * Whether `@everyone` or `@here` were mentioned
     * @type {boolean}
     */
    this.everyone = Boolean(everyone);

    if (users) {
      if (users instanceof Collection) {
        /**
         * Any users that were mentioned
         * @type {Collection<Snowflake, User>}
         */
        this.users = new Collection(users);
      } else {
        this.users = new Collection();
        for (const mention of users) {
          let user = message.client.users.create(mention);
          this.users.set(user.id, user);
        }
      }
    } else {
      this.users = new Collection();
    }

    if (roles) {
      if (roles instanceof Collection) {
        /**
         * Any roles that were mentioned
         * @type {Collection<Snowflake, Role>}
         */
        this.roles = new Collection(roles);
      } else {
        this.roles = new Collection();
        for (const mention of roles) {
          const role = message.channel.guild.roles.get(mention);
          if (role) this.roles.set(role.id, role);
        }
      }
    } else {
      this.roles = new Collection();
    }

    /**
     * Content of the message
     * @type {Message}
     * @private
     */
    this._content = message.content;

    /**
     * The client the message is from
     * @type {Client}
     * @private
     */
    this._client = message.client;

    /**
     * The guild the message is in
     * @type {?Guild}
     * @private
     */
    this._guild = message.channel.guild;

    /**
     * Cached members for {@MessageMention#members}
     * @type {?Collection<Snowflake, GuildMember>}
     * @private
     */
    this._members = null;

    /**
     * Cached channels for {@MessageMention#channels}
     * @type {?Collection<Snowflake, GuildChannel>}
     * @private
     */
    this._channels = null;
  }

  /**
   * Any members that were mentioned (only in {@link TextChannel}s)
   * @type {?Collection<Snowflake, GuildMember>}
   * @readonly
   */
  get members() {
    if (this._members) return this._members;
    if (!this._guild) return null;
    this._members = new Collection();
    this.users.forEach(user => {
      const member = this._guild.member(user);
      if (member) this._members.set(member.user.id, member);
    });
    return this._members;
  }

  /**
   * Any channels that were mentioned
   * @type {Collection<Snowflake, GuildChannel>}
   * @readonly
   */
  get channels() {
    if (this._channels) return this._channels;
    this._channels = new Collection();
    let matches;
    while ((matches = this.constructor.CHANNELS_PATTERN.exec(this._content)) !== null) {
      const chan = this._client.channels.get(matches[1]);
      if (chan) this._channels.set(chan.id, chan);
    }
    return this._channels;
  }

  /**
   * Checks if a user, guild member, role, or channel is mentioned.
   * Takes into account user mentions, role mentions, and @everyone/@here mentions.
   * @param {UserResolvable|GuildMember|Role|GuildChannel} data User/GuildMember/Role/Channel to check
   * @param {Object} [options] Options
   * @param {boolean} [options.ignoreDirect=false] - Whether to ignore direct mentions to the item
   * @param {boolean} [options.ignoreRoles=false] - Whether to ignore role mentions to a guild member
   * @param {boolean} [options.ignoreEveryone=false] - Whether to ignore everyone/here mentions
   * @returns {boolean}
   */
  has(data, { ignoreDirect = false, ignoreRoles = false, ignoreEveryone = false } = {}) {
    if (!ignoreEveryone && this.everyone) return true;
    if (!ignoreRoles && data instanceof GuildMember) {
      for (const role of this.roles.values()) if (data.roles.has(role.id)) return true;
    }

    if (!ignoreDirect) {
      const id = data.id || data;
      return this.users.has(id) || this.channels.has(id) || this.roles.has(id);
    }

    return false;
  }
}

/**
 * Regular expression that globally matches `@everyone` and `@here`
 * @type {RegExp}
 */
MessageMentions.EVERYONE_PATTERN = /@(everyone|here)/g;

/**
 * Regular expression that globally matches user mentions like `<@81440962496172032>`
 * @type {RegExp}
 */
MessageMentions.USERS_PATTERN = /<@!?(1|\d{17,19})>/g;

/**
 * Regular expression that globally matches role mentions like `<@&297577916114403338>`
 * @type {RegExp}
 */
MessageMentions.ROLES_PATTERN = /<@&(\d{17,19})>/g;

/**
 * Regular expression that globally matches channel mentions like `<#222079895583457280>`
 * @type {RegExp}
 */
MessageMentions.CHANNELS_PATTERN = /<#(\d{17,19})>/g;

module.exports = MessageMentions;
<|endoftext|>


<commit_before>module.exports = Object.freeze({
  CONFIG: {
    COMMAND_COOLDOWN_TIME: 1.0
  },
  MESSAGE: {
    TOP_TEN_TITLE: 'Top 10 冗員s in the last 7 days (last 上水 time):\n\n',
    ALL_JUNG_TITLE: 'All 冗員s in the last 7 days (last 上水 time):\n\n'
  },
  HELP: {
    MESSAGE: '冗員[jung2jyun4] Excess personnel in Cantonese' + '\n' +
    '\n' +
    'This bot is created for counting the number of message per participant in the group.' + '\n' +
    '\n' +
    'Rules:' + '\n' +
    '1. Repeated messages will only be counted as ONE message.' + '\n' +
    '2. Commands can only be used for ONCE per minute.' + '\n' +
    '\n' +
    'Commands:' + '\n' +
    '/topten  show top ten 冗員s' + '\n' +
    '/alljung  show all 冗員s' + '\n' +
    '/junghelp      show help message' + '\n' +
    '\n' +
    'Issue/Suggestion: https://github.com/siutsin/telegram-jung2-bot/issues' + '\n' +
    '\n' +
    'May your 冗 power powerful -- Simon'
  }
});

<commit_msg>Remove extra space<commit_after>module.exports = Object.freeze({
  CONFIG: {
    COMMAND_COOLDOWN_TIME: 1.0
  },
  MESSAGE: {
    TOP_TEN_TITLE: 'Top 10 冗員s in the last 7 days (last 上水 time):\n\n',
    ALL_JUNG_TITLE: 'All 冗員s in the last 7 days (last 上水 time):\n\n'
  },
  HELP: {
    MESSAGE: '冗員[jung2jyun4] Excess personnel in Cantonese' + '\n' +
    '\n' +
    'This bot is created for counting the number of message per participant in the group.' + '\n' +
    '\n' +
    'Rules:' + '\n' +
    '1. Repeated messages will only be counted as ONE message.' + '\n' +
    '2. Commands can only be used for ONCE per minute.' + '\n' +
    '\n' +
    'Commands:' + '\n' +
    '/topten  show top ten 冗員s' + '\n' +
    '/alljung  show all 冗員s' + '\n' +
    '/junghelp  show help message' + '\n' +
    '\n' +
    'Issue/Suggestion: https://github.com/siutsin/telegram-jung2-bot/issues' + '\n' +
    '\n' +
    'May your 冗 power powerful -- Simon'
  }
});

<|endoftext|>


<commit_before>
var RegularInjectionTime;
var PostDataTreatmentFunction;// (Person[Array], Time, TimeStep)

// Put the following into the console
// RunSettings2={};
// RunSettings2.FunctionName="RunFullModel";
// RunSettings2.Common={};
// RunSettings2.Common.HCVTretmentFunctionID=Settings.HCVTreatmentScenario;
// RunSettings2.SimDataArray=[1];
// SimulationHolder.Run(RunSettings2);

function FullModelTest(Stuff1){

	// Globals that need to be run before code will work
	RegularInjectionTime=new RegularInjectionTimeObject();

	// This should go into the outer loop
	console.log(Data);
	// Notification data
	var Notifications={};
	Notifications.Year=Data.MaleNotifications.Year;
	Notifications.Age=Data.MaleNotifications.Age;
	Notifications.Count=[];
	Notifications.Count[0]=[];
	Notifications.Count[0]=Data.MaleNotifications.Table;
	Notifications.Count[1]=[];
	Notifications.Count[1]=Data.FemaleNotifications.Table;
	Notifications.FirstYearOfData=Notifications.Year[0];
	Notifications.LastYearOfData=Notifications.Year[Notifications.Year.length-1];
	console.log(Notifications);
	//throw("stopping");

	// Set up the treatment function
	PostDataTreatmentFunction=HCVTreatmentScenario[Settings.HCVTreatmentScenario].Function;

	var Intervention=function(){};

	// This needs to be established by the optimisation
	Param.HCV.ProbabilityOfTransmission=0.1;
	console.error("The above is hard set and poorly defined");

	// OptimisedValues that need to be set by an external function
	Param.IDU.RateOfCesssation=0.25;

	Param.IDU.Entry.A=2500;
	Param.IDU.Entry.B=0.20;
	Param.IDU.Entry.Logk2=0.3;
	Param.IDU.Entry.Logk1=0.8;

	var FullModelResults=FullModel(Param, Notifications, Param.Time.EndSimulation, Intervention);

	var Person=FullModelResults.Population;

	var StatsTime={};
	StatsTime.StartTime=1980;
	StatsTime.EndTime=2030;
	StatsTime.StepSize=1;

	var ReturnResults={};
	ReturnResults.LivingWithHCVInfection=LivingWithHCVInfectionStats(Person, StatsTime);
	ReturnResults.CurrentIDU=CurrentIDUStats(Person, StatsTime);
	ReturnResults.EverIDU=EverIDUStats(Person, StatsTime);
	ReturnResults.EverIDUHCVAntibody=EverIDUHCVAntibodyStats(Person, StatsTime);
	ReturnResults.PWIDAge=PWIDAgeStats(Person, StatsTime);

	// console.log(SimulationHolder.Result[0].LivingWithHCVInfection.Count);
	// console.log(SimulationHolder.Result[0].CurrentIDU.Count);
	// console.log(SimulationHolder.Result[0].EverIDU.Count);
	// console.log(SimulationHolder.Result[0].EverIDUHCVAntibody.Count);
	// console.log(Divide(SimulationHolder.Result[0].EverIDUHCVAntibody.Count, SimulationHolder.Result[0].EverIDU.Count));

	// Note: number of people living with HCV is somewhat lower thant the people who have ever IDU
	// console.log(Divide(SimulationHolder.Result[0].LivingWithHCVInfection.Count, SimulationHolder.Result[0].EverIDU.Count));

	console.log(Person);

	return ReturnResults;
}

function FullModel(Param, Notifications, EndSimulation, Intervention){

	// Intervention[No]=function(Time){
	// 	   if (Time<2016){
	//         Param.HCV.TreatmentRate=1000;
	//     }else{
	//         Param.HCV.TreatmentRate=Min(1000+Time*5000, 20000);// increase at a rate of 5000 per year until reaching a max of 20000
	//     }
	// };

	// Set up some of the parameters
	RegularInjectionTime=new RegularInjectionTimeObject();

	// var PWIDPopulation=DistributePWIDPopulationExponential(Param.IDU.EntryParams);//Returns PWIDPopulation as defined to the MaxYear
	// this is probably antiquated var PWIDEntry=DeterminePWIDEntryRateExponential2(Param.IDU.EntryParams);//Returns PWIDPopulation as defined to the MaxYear

	// Add proportions as mentioned in Greg's paper
	// Determine how many end up as PWID
	// Run MSM
	// Run migrants
	// Determine proportion of each that end up PWID

	// Create a very basic early population that has a set distribution of IDU and HCV
	var Person=InitialDistribution();

	// Run HCV blood recipients
	console.error("Below is not running but should be implemented prior to creating results");
	//var HCVInfectedBloodRecipients=CreateHCVInfectedBloodRecipients();
	// Join populations
	// Person=Person.concat(HCVInfectedBloodRecipients);// Later add MSM and migrants

	var SimulationHistory=[];
	SimulationHistory.DiagnosisResults=[];
	var StepCount=-1;

	console.error("fix times below");

	// Timers functions
	function RecordingTimer(){
		this.TimerStart;
		this.TimerFinish;
		this.Time=0;
		this.Increase=0;
	};

	RecordingTimer.prototype.Start= function (){
		this.TimerStart = new Date().getTime() / 1000;
	}

	RecordingTimer.prototype.Stop= function (){
		this.TimerStop = new Date().getTime() / 1000;
		var Current=this.TimerStop-this.TimerStart;
		this.Increase=Current/this.Time;
		this.Time=Current;
	}

	// Set up timers
	var TimerStart, TimerFinish;
	var Timers={};
	Timers.CreatePWID=new RecordingTimer();
	Timers.AssignSexualPartner=new RecordingTimer();
	Timers.DetermineHCVTransmissions=new RecordingTimer();

	for (var Time=Param.Time.StartDynamicModel; Time<EndSimulation; Time+=Param.TimeStep){// each time step
		StepCount++;
		// RunInterventions(Time);

		// this is a function that will be called "AdvanceModel(YearLast, YearCurrent, Param, Population)
		// determine number of individuals added the population of PWID
		// Param.IDU.Add

		// this is probably antiquated var NumberOfPeopleToAddThisStep=DeterminePWIDEntryRateExponential2(Param.IDU.EntryParams, Time, Param.TimeStep);

		// Add new people to the IDU population for this time step
		console.log("looking at param inside full model");
		console.log(Param);

    	Timers.CreatePWID.Start();

		var PWIDToAdd=CreatePWID(Param.IDU.Entry, Time, Param.TimeStep);

		Timers.CreatePWID.Stop();
		console.log("CreatePWID time " + Timers.CreatePWID.Time + " Increase " +Timers.CreatePWID.Increase);

		if (Settings.ModelNetwork){
			if (false){// add once this section is complete
				// Match some of the PWID, in particular females, to existing PWID sexual partners
				// select by finding ProportionOfFirstInjectionsSexualPartner
				// determine the number that will inject the first time with a sexual partners
				var RemainderToAdd=JoinToSexualPartners(Person, PWIDToAdd, Data.FirstExperienceSexualPartner.Male, Data.FirstExperienceSexualPartner.Female);
					// determine number with regular sex partners (approximately 50%, NSP survey)
					// determine number with casual sex partners
					// Determine when the sexual partners begin their partnership (could be before starting injecting or after)
					// what proportion had partners who did not inject drugs

				// not the above should add the correct number of PWID to Person

				// All new people are joined to "friends" in the model
				JoinToFriends(Person, RemainderToAdd);
			}
		}

		Person=Person.concat(PWIDToAdd);

		if (Settings.ModelNetwork){
			// Balance sexual partnerships
			Timers.AssignSexualPartner.Start();
			AssignSexualPartner(Person, Time);
			Timers.AssignSexualPartner.Stop();
			console.log("AssignSexualPartner time " + Timers.AssignSexualPartner.Time + " Increase " +Timers.AssignSexualPartner.Increase);
		}
		else {
			//
		}

		// Determine transmissions that occur
		//if (Settings.ModelNetwork){
			Timers.DetermineHCVTransmissions.Start();
			DetermineHCVTransmissions(Person, Time, Param.TimeStep);
			Timers.DetermineHCVTransmissions.Stop();
			console.log("DetermineHCVTransmissions time " + Timers.DetermineHCVTransmissions.Time + " Increase " +Timers.DetermineHCVTransmissions.Increase);
		//}
		//else {

		//}

		// Testing
		if (Notifications.FirstYearOfData<=Time && Time<Notifications.LastYearOfData){ // only if there is data
			SimulationHistory.DiagnosisResults[StepCount]=HCVDataDiagnosis(Person, Notifications, Time, Param.TimeStep);
		}
		else if (Notifications.LastYearOfData < Time){
			if (typeof(PerStepProbOfDiagnosis)=="undefined"){
				var PerStepProbOfDiagnosis=DeterminePostDataDiagnosisDataRate(SimulationHistory.DiagnosisResults, Notifications.LastYearOfData-Param.Time.DurationToAverageOver);
			}
			HCVRateDiagnosis(Person, Notifications.Age, PerStepProbOfDiagnosis, Time, Param.TimeStep);
		}

		// Determine treatment
			// X number per year are treated out of those who are diagnosed
		if (Time<Param.Time.EndTreatmentData){
			DetermineHistoricalTreatment(Person, Time, Param.TimeStep, Data.TreatmentNumbers);//Treatment rates is an array of each of the treatment types
		}
		else{
			PostDataTreatmentFunction(Person, Time, Param.TimeStep);
		}

		console.log("Time: "+Time);
		console.log("People "+Person.length);

		// lots of points are lost for insufficient people to draw from diagnoses

		// If the year is the first year of the simulation
			// Give the injecting

		// HCV testing
		// Param.HCV.TestingRate from NSP survey

		// Treatment

		// HCV mortality

	}

	//

	// Create HCV notification population

	// Match to population (including choosing individuals that are not diagnosed by the end of the data)
	// Assign dates to those with diagnoses
	// In the first year that you have results
		// Find the number of diagnoses in the earlier model
		// For every diagnosis,

	console.error("This is where the diagnoses are displayed");
	console.log(SimulationHistory.DiagnosisResults);

	var Results={};
	Results.Population=Person;
	Results.SimulationHistory=SimulationHistory;

	return Results;
}

function InitialDistribution() {
	console.log("Starting InitialDistribution");

	// Run CreatePWID multiple times
	var Person = [];

	for (var Time = Param.Time.StartNonDynamicModel; Time < Param.Time.StartDynamicModel; Time += Param.TimeStep) {
		console.log(Param.IDU.Entry);
		var PWIDToAdd = CreatePWID(Param.IDU.Entry, Time, Param.TimeStep);
		Person = Person.concat(PWIDToAdd);

		console.log("Year " + Time + " N " + PWIDToAdd.length);
	}
	console.log(Time);
	console.log("exitted the loop");

	console.log(Person);

	SetInitialHCVLevels(Person);
	//InitialiseNetwork(Person, Param.Time.StartDynamicModel);// we only need it to be a correct network at the end of this period because this is the start of the dynamic period

	return Person;
}

//function PWIDInitialDistribution(){
//	var Population=[];

//	Param.InitialDistribution.AgePWID.Median=35;
//	Param.InitialDistribution.AgePWID.LogSD=0.17;

//	Param.InitialDistribution.AgeInitiatePWID.Median=20;
//	Param.InitialDistribution.AgeInitiatePWID.Median=20;

//	Param.InitialDistribution.TimeUntilHCV.Median=3.5;
//	Param.InitialDistribution.TimeUntilHCV.LogSD=1;

//	Param.InitialDistribution.Year=1980;// this can vary too!
//	return Population;
//}

function CreateHCVInfectedBloodRecipients(){
	Param.Haemophilia.Total2013;
	// Data.Population.Total
	// Data.Population.Migration
	// Data.Population.Deaths
	// Data.Population.Births

	// THIS MUST BE MOVED TO THE INTERFACE
	Data.GeneralPopulation={};
	Data.GeneralPopulation.Year=DataFile.GeneralPopulation.GetColumn(0, 1, 43);
	Data.GeneralPopulation.Size=DataFile.GeneralPopulation.GetColumn(1, 1, 43);
	Data.GeneralPopulation.Births=DataFile.GeneralPopulation.GetColumn(2, 1, 43);
	Data.GeneralPopulation.Migration=DataFile.GeneralPopulation.GetColumn(2, 1, 43);
	Data.GeneralPopulation.Deaths=DataFile.GeneralPopulation.GetColumn(3, 1, 43);

	//Determine total population by year

	//Interpolate to get number of new cases per year

	// Create a distribution which is based on 10000 samples
	// Roughly add to the
	// Age them
	// This is the starting age distribution
	// Randomly assign people with HCV or not

	//

	Param.Haemophilia.HCV.Prevalence1973;
	Param.Haemophilia.HCV.Prevalence1980;
	Param.Haemophilia.HCV.Prevalence1990;

	Param.HCV.Prevalence.Haemophiliacs1960;

	return

}

function ErrorOfFullModel(){
	// Error categories:
	// Ever injected
	// Recently injected
	// Ratio of standard deviation to the mean is basically the same in recent injectors over time (last x years)
	// Error of difference between diagnosed data and undiagnosed
	//
}

function RunAndLink(){
	// this is the final step before a normal run of the model occurs

	// Run the model with optimised parameters, but this time with double (?) the number of individuals
		// starting injecting
		// treatment numbers
		//

	// Create a table that determines the diagnoses by year, age and sex (later state)
		// Store this table for error analyses later

	// sort the diagnoses by year, age and sex (later state)
	// Initialise object
		// Ind=DetermineIndicies(SimPerson);
		// determine sexindex
		// determine yearindex
		// determine ageindex
		PopRef[Ind.Sex][Ind.Year][Ind.Age].listpeople.push(i);

	// Convert ALL diagnoses in the model to real diagnoses
	// i.e. notification cases
	// for each notification
		Ind=DetermineIndicies(NotificationPerson);
		// choose a diagnosis that matches it in terms of sex and age
		NumInArray=PopRef[Ind.Sex][Ind.Year][Ind.Age].listpeople.length;
		// If no available individual remaining
		// may choose the same diagnosis multiple times but it MUST be duplicated using DeepCopy

		// If none available in category of diagnoses
			// may choose nearest neighbour

	// determine difference

	// Delete all un-matched diagnoses

	// Randomly remove undiagnosed individuals in the model at the same proportion as
}

<commit_msg>Reducing entry rates to be relatively more realistic<commit_after>
var RegularInjectionTime;
var PostDataTreatmentFunction;// (Person[Array], Time, TimeStep)

// Put the following into the console
// RunSettings2={};
// RunSettings2.FunctionName="RunFullModel";
// RunSettings2.Common={};
// RunSettings2.Common.HCVTretmentFunctionID=Settings.HCVTreatmentScenario;
// RunSettings2.SimDataArray=[1];
// SimulationHolder.Run(RunSettings2);

function FullModelTest(Stuff1){

	// Globals that need to be run before code will work
	RegularInjectionTime=new RegularInjectionTimeObject();

	// This should go into the outer loop
	console.log(Data);
	// Notification data
	var Notifications={};
	Notifications.Year=Data.MaleNotifications.Year;
	Notifications.Age=Data.MaleNotifications.Age;
	Notifications.Count=[];
	Notifications.Count[0]=[];
	Notifications.Count[0]=Data.MaleNotifications.Table;
	Notifications.Count[1]=[];
	Notifications.Count[1]=Data.FemaleNotifications.Table;
	Notifications.FirstYearOfData=Notifications.Year[0];
	Notifications.LastYearOfData=Notifications.Year[Notifications.Year.length-1];
	console.log(Notifications);
	//throw("stopping");

	// Set up the treatment function
	PostDataTreatmentFunction=HCVTreatmentScenario[Settings.HCVTreatmentScenario].Function;

	var Intervention=function(){};

	// This needs to be established by the optimisation
	Param.HCV.ProbabilityOfTransmission=0.1;
	console.error("The above is hard set and poorly defined");

	// OptimisedValues that need to be set by an external function
	Param.IDU.RateOfCesssation=0.25;

	Param.IDU.Entry.A=100;
	Param.IDU.Entry.B=0.20;
	Param.IDU.Entry.Logk2=0.3;
	Param.IDU.Entry.Logk1=0.8;

	var FullModelResults=FullModel(Param, Notifications, Param.Time.EndSimulation, Intervention);

	var Person=FullModelResults.Population;

	var StatsTime={};
	StatsTime.StartTime=1980;
	StatsTime.EndTime=2030;
	StatsTime.StepSize=1;

	var ReturnResults={};
	ReturnResults.LivingWithHCVInfection=LivingWithHCVInfectionStats(Person, StatsTime);
	ReturnResults.CurrentIDU=CurrentIDUStats(Person, StatsTime);
	ReturnResults.EverIDU=EverIDUStats(Person, StatsTime);
	ReturnResults.EverIDUHCVAntibody=EverIDUHCVAntibodyStats(Person, StatsTime);
	ReturnResults.PWIDAge=PWIDAgeStats(Person, StatsTime);

	// console.log(SimulationHolder.Result[0].LivingWithHCVInfection.Count);
	// console.log(SimulationHolder.Result[0].CurrentIDU.Count);
	// console.log(SimulationHolder.Result[0].EverIDU.Count);
	// console.log(SimulationHolder.Result[0].EverIDUHCVAntibody.Count);
	// console.log(Divide(SimulationHolder.Result[0].EverIDUHCVAntibody.Count, SimulationHolder.Result[0].EverIDU.Count));

	// Note: number of people living with HCV is somewhat lower thant the people who have ever IDU
	// console.log(Divide(SimulationHolder.Result[0].LivingWithHCVInfection.Count, SimulationHolder.Result[0].EverIDU.Count));

	console.log(Person);

	return ReturnResults;
}

function FullModel(Param, Notifications, EndSimulation, Intervention){

	// Intervention[No]=function(Time){
	// 	   if (Time<2016){
	//         Param.HCV.TreatmentRate=1000;
	//     }else{
	//         Param.HCV.TreatmentRate=Min(1000+Time*5000, 20000);// increase at a rate of 5000 per year until reaching a max of 20000
	//     }
	// };

	// Set up some of the parameters
	RegularInjectionTime=new RegularInjectionTimeObject();

	// var PWIDPopulation=DistributePWIDPopulationExponential(Param.IDU.EntryParams);//Returns PWIDPopulation as defined to the MaxYear
	// this is probably antiquated var PWIDEntry=DeterminePWIDEntryRateExponential2(Param.IDU.EntryParams);//Returns PWIDPopulation as defined to the MaxYear

	// Add proportions as mentioned in Greg's paper
	// Determine how many end up as PWID
	// Run MSM
	// Run migrants
	// Determine proportion of each that end up PWID

	// Create a very basic early population that has a set distribution of IDU and HCV
	var Person=InitialDistribution();

	// Run HCV blood recipients
	console.error("Below is not running but should be implemented prior to creating results");
	//var HCVInfectedBloodRecipients=CreateHCVInfectedBloodRecipients();
	// Join populations
	// Person=Person.concat(HCVInfectedBloodRecipients);// Later add MSM and migrants

	var SimulationHistory=[];
	SimulationHistory.DiagnosisResults=[];
	var StepCount=-1;

	console.error("fix times below");

	// Timers functions
	function RecordingTimer(){
		this.TimerStart;
		this.TimerFinish;
		this.Time=0;
		this.Increase=0;
	};

	RecordingTimer.prototype.Start= function (){
		this.TimerStart = new Date().getTime() / 1000;
	}

	RecordingTimer.prototype.Stop= function (){
		this.TimerStop = new Date().getTime() / 1000;
		var Current=this.TimerStop-this.TimerStart;
		this.Increase=Current/this.Time;
		this.Time=Current;
	}

	// Set up timers
	var TimerStart, TimerFinish;
	var Timers={};
	Timers.CreatePWID=new RecordingTimer();
	Timers.AssignSexualPartner=new RecordingTimer();
	Timers.DetermineHCVTransmissions=new RecordingTimer();

	for (var Time=Param.Time.StartDynamicModel; Time<EndSimulation; Time+=Param.TimeStep){// each time step
		StepCount++;
		// RunInterventions(Time);

		// this is a function that will be called "AdvanceModel(YearLast, YearCurrent, Param, Population)
		// determine number of individuals added the population of PWID
		// Param.IDU.Add

		// this is probably antiquated var NumberOfPeopleToAddThisStep=DeterminePWIDEntryRateExponential2(Param.IDU.EntryParams, Time, Param.TimeStep);

		// Add new people to the IDU population for this time step
		console.log("looking at param inside full model");
		console.log(Param);

    	Timers.CreatePWID.Start();

		var PWIDToAdd=CreatePWID(Param.IDU.Entry, Time, Param.TimeStep);

		Timers.CreatePWID.Stop();
		console.log("CreatePWID time " + Timers.CreatePWID.Time + " Increase " +Timers.CreatePWID.Increase);

		if (Settings.ModelNetwork){
			if (false){// add once this section is complete
				// Match some of the PWID, in particular females, to existing PWID sexual partners
				// select by finding ProportionOfFirstInjectionsSexualPartner
				// determine the number that will inject the first time with a sexual partners
				var RemainderToAdd=JoinToSexualPartners(Person, PWIDToAdd, Data.FirstExperienceSexualPartner.Male, Data.FirstExperienceSexualPartner.Female);
					// determine number with regular sex partners (approximately 50%, NSP survey)
					// determine number with casual sex partners
					// Determine when the sexual partners begin their partnership (could be before starting injecting or after)
					// what proportion had partners who did not inject drugs

				// not the above should add the correct number of PWID to Person

				// All new people are joined to "friends" in the model
				JoinToFriends(Person, RemainderToAdd);
			}
		}

		Person=Person.concat(PWIDToAdd);

		if (Settings.ModelNetwork){
			// Balance sexual partnerships
			Timers.AssignSexualPartner.Start();
			AssignSexualPartner(Person, Time);
			Timers.AssignSexualPartner.Stop();
			console.log("AssignSexualPartner time " + Timers.AssignSexualPartner.Time + " Increase " +Timers.AssignSexualPartner.Increase);
		}
		else {
			//
		}

		// Determine transmissions that occur
		//if (Settings.ModelNetwork){
			Timers.DetermineHCVTransmissions.Start();
			DetermineHCVTransmissions(Person, Time, Param.TimeStep);
			Timers.DetermineHCVTransmissions.Stop();
			console.log("DetermineHCVTransmissions time " + Timers.DetermineHCVTransmissions.Time + " Increase " +Timers.DetermineHCVTransmissions.Increase);
		//}
		//else {

		//}

		// Testing
		if (Notifications.FirstYearOfData<=Time && Time<Notifications.LastYearOfData){ // only if there is data
			SimulationHistory.DiagnosisResults[StepCount]=HCVDataDiagnosis(Person, Notifications, Time, Param.TimeStep);
		}
		else if (Notifications.LastYearOfData < Time){
			if (typeof(PerStepProbOfDiagnosis)=="undefined"){
				var PerStepProbOfDiagnosis=DeterminePostDataDiagnosisDataRate(SimulationHistory.DiagnosisResults, Notifications.LastYearOfData-Param.Time.DurationToAverageOver);
			}
			HCVRateDiagnosis(Person, Notifications.Age, PerStepProbOfDiagnosis, Time, Param.TimeStep);
		}

		// Determine treatment
			// X number per year are treated out of those who are diagnosed
		if (Time<Param.Time.EndTreatmentData){
			DetermineHistoricalTreatment(Person, Time, Param.TimeStep, Data.TreatmentNumbers);//Treatment rates is an array of each of the treatment types
		}
		else{
			PostDataTreatmentFunction(Person, Time, Param.TimeStep);
		}

		console.log("Time: "+Time);
		console.log("People "+Person.length);

		// lots of points are lost for insufficient people to draw from diagnoses

		// If the year is the first year of the simulation
			// Give the injecting

		// HCV testing
		// Param.HCV.TestingRate from NSP survey

		// Treatment

		// HCV mortality

	}

	//

	// Create HCV notification population

	// Match to population (including choosing individuals that are not diagnosed by the end of the data)
	// Assign dates to those with diagnoses
	// In the first year that you have results
		// Find the number of diagnoses in the earlier model
		// For every diagnosis,

	console.error("This is where the diagnoses are displayed");
	console.log(SimulationHistory.DiagnosisResults);

	var Results={};
	Results.Population=Person;
	Results.SimulationHistory=SimulationHistory;

	return Results;
}

function InitialDistribution() {
	console.log("Starting InitialDistribution");

	// Run CreatePWID multiple times
	var Person = [];

	for (var Time = Param.Time.StartNonDynamicModel; Time < Param.Time.StartDynamicModel; Time += Param.TimeStep) {
		console.log(Param.IDU.Entry);
		var PWIDToAdd = CreatePWID(Param.IDU.Entry, Time, Param.TimeStep);
		Person = Person.concat(PWIDToAdd);

		console.log("Year " + Time + " N " + PWIDToAdd.length);
	}
	console.log(Time);
	console.log("exitted the loop");

	console.log(Person);

	SetInitialHCVLevels(Person);
	//InitialiseNetwork(Person, Param.Time.StartDynamicModel);// we only need it to be a correct network at the end of this period because this is the start of the dynamic period

	return Person;
}

//function PWIDInitialDistribution(){
//	var Population=[];

//	Param.InitialDistribution.AgePWID.Median=35;
//	Param.InitialDistribution.AgePWID.LogSD=0.17;

//	Param.InitialDistribution.AgeInitiatePWID.Median=20;
//	Param.InitialDistribution.AgeInitiatePWID.Median=20;

//	Param.InitialDistribution.TimeUntilHCV.Median=3.5;
//	Param.InitialDistribution.TimeUntilHCV.LogSD=1;

//	Param.InitialDistribution.Year=1980;// this can vary too!
//	return Population;
//}

function CreateHCVInfectedBloodRecipients(){
	Param.Haemophilia.Total2013;
	// Data.Population.Total
	// Data.Population.Migration
	// Data.Population.Deaths
	// Data.Population.Births

	// THIS MUST BE MOVED TO THE INTERFACE
	Data.GeneralPopulation={};
	Data.GeneralPopulation.Year=DataFile.GeneralPopulation.GetColumn(0, 1, 43);
	Data.GeneralPopulation.Size=DataFile.GeneralPopulation.GetColumn(1, 1, 43);
	Data.GeneralPopulation.Births=DataFile.GeneralPopulation.GetColumn(2, 1, 43);
	Data.GeneralPopulation.Migration=DataFile.GeneralPopulation.GetColumn(2, 1, 43);
	Data.GeneralPopulation.Deaths=DataFile.GeneralPopulation.GetColumn(3, 1, 43);

	//Determine total population by year

	//Interpolate to get number of new cases per year

	// Create a distribution which is based on 10000 samples
	// Roughly add to the
	// Age them
	// This is the starting age distribution
	// Randomly assign people with HCV or not

	//

	Param.Haemophilia.HCV.Prevalence1973;
	Param.Haemophilia.HCV.Prevalence1980;
	Param.Haemophilia.HCV.Prevalence1990;

	Param.HCV.Prevalence.Haemophiliacs1960;

	return

}

function ErrorOfFullModel(){
	// Error categories:
	// Ever injected
	// Recently injected
	// Ratio of standard deviation to the mean is basically the same in recent injectors over time (last x years)
	// Error of difference between diagnosed data and undiagnosed
	//
}

function RunAndLink(){
	// this is the final step before a normal run of the model occurs

	// Run the model with optimised parameters, but this time with double (?) the number of individuals
		// starting injecting
		// treatment numbers
		//

	// Create a table that determines the diagnoses by year, age and sex (later state)
		// Store this table for error analyses later

	// sort the diagnoses by year, age and sex (later state)
	// Initialise object
		// Ind=DetermineIndicies(SimPerson);
		// determine sexindex
		// determine yearindex
		// determine ageindex
		PopRef[Ind.Sex][Ind.Year][Ind.Age].listpeople.push(i);

	// Convert ALL diagnoses in the model to real diagnoses
	// i.e. notification cases
	// for each notification
		Ind=DetermineIndicies(NotificationPerson);
		// choose a diagnosis that matches it in terms of sex and age
		NumInArray=PopRef[Ind.Sex][Ind.Year][Ind.Age].listpeople.length;
		// If no available individual remaining
		// may choose the same diagnosis multiple times but it MUST be duplicated using DeepCopy

		// If none available in category of diagnoses
			// may choose nearest neighbour

	// determine difference

	// Delete all un-matched diagnoses

	// Randomly remove undiagnosed individuals in the model at the same proportion as
}

<|endoftext|>


<commit_before>import Ember from "ember";

export default Ember.Object.extend(Ember.Evented, {
  url: null,
  socket: null,
  autoReconnect: true,
  connected: false,
  tries: 0,
  disconnectedAt: null,

  connect: function() {
    var self = this;
    var socket = self.get('socket');
    if ( socket )
    {
      this.disconnect();
    }

    var url = this.get('url');
    console.log('Socket connect to',url);
    socket = new WebSocket(url);
    self.set('socket', socket);

    socket.onmessage = function(event) {
      Ember.run(function() {
        self.trigger('message',event);
      });
    };

    socket.onopen = function() {
      //console.log('Socket Open');
      var now = (new Date()).getTime();
      self.set('connected',true);

      var at = self.get('disconnectedAt');
      var after = null;
      if ( at )
      {
        after = now - at;
      }

      self.trigger('connected', self.get('tries'), after);
      self.set('tries',0);
      self.set('disconnectedAt', null);
    };

    socket.onclose = function() {
      //console.log('Socket Closed');
      var wasConnected = self.get('connected');

      self.set('connected',false);
      self.incrementProperty('tries');

      if ( self.get('disconnectedAt') === null )
      {
        self.set('disconnectedAt', (new Date()).getTime());
      }

      socket.close();
      if ( wasConnected && self.get('autoReconnect') )
      {
        var delay = Math.max(1000, Math.min(1000 * self.get('tries'), 30000));
        setTimeout(self.connect.bind(self), delay);
      }

      self.trigger('disconnected', self.get('tries'));
    };
  },

  disconnect: function() {
    var self = this;
    //console.log('Socket disconnect');
    this.set('connected', false);
    this.set('autoReconnect',false);
    var socket = this.get('socket');
    if ( socket )
    {
      try {
        socket.close();
        self.set('socket',null);
      }
      catch (e)
      {
        // Meh..
      }
    }
  }
});
<commit_msg>Force WebSockets to SSL if the page is<commit_after>import Ember from "ember";

export default Ember.Object.extend(Ember.Evented, {
  url: null,
  socket: null,
  autoReconnect: true,
  connected: false,
  tries: 0,
  disconnectedAt: null,

  connect: function() {
    var self = this;
    var socket = self.get('socket');
    if ( socket )
    {
      this.disconnect();
    }

    var url = this.get('url');
    // If the site is SSL, the WebSocket should be too...
    if ( window.location.protocol === 'https:' && url.indexOf('ws://') === 0 )
    {
      url = 'wss://' + url.substr(5);
    }

    console.log('Socket connect to',url);
    socket = new WebSocket(url);
    self.set('socket', socket);

    socket.onmessage = function(event) {
      Ember.run(function() {
        self.trigger('message',event);
      });
    };

    socket.onopen = function() {
      //console.log('Socket Open');
      var now = (new Date()).getTime();
      self.set('connected',true);

      var at = self.get('disconnectedAt');
      var after = null;
      if ( at )
      {
        after = now - at;
      }

      self.trigger('connected', self.get('tries'), after);
      self.set('tries',0);
      self.set('disconnectedAt', null);
    };

    socket.onclose = function() {
      //console.log('Socket Closed');
      var wasConnected = self.get('connected');

      self.set('connected',false);
      self.incrementProperty('tries');

      if ( self.get('disconnectedAt') === null )
      {
        self.set('disconnectedAt', (new Date()).getTime());
      }

      socket.close();
      if ( wasConnected && self.get('autoReconnect') )
      {
        var delay = Math.max(1000, Math.min(1000 * self.get('tries'), 30000));
        setTimeout(self.connect.bind(self), delay);
      }

      self.trigger('disconnected', self.get('tries'));
    };
  },

  disconnect: function() {
    var self = this;
    //console.log('Socket disconnect');
    this.set('connected', false);
    this.set('autoReconnect',false);
    var socket = this.get('socket');
    if ( socket )
    {
      try {
        socket.close();
        self.set('socket',null);
      }
      catch (e)
      {
        // Meh..
      }
    }
  }
});
<|endoftext|>


<commit_before>// This library requires mathtools.js to work

function ParameterClass(ParameterID, GroupName){// InterfacePrefix

this.ParameterID=ParameterID;// e.g. LFHCCProbability
this.InterfaceID="";// e.g. HCV_LFHCCProbability
// Note that GroupName is primarily used for interface design. It is updated at load to represent the true structure of the objects in which it resides, so it cannot be relied upon to be consistent between builds.
this.GroupName="";//e.g. HCV, or in the case of it being a struct of a struct, Param.HCV
//GroupName+'.'+ParameterID gives the full name that the function can call.

this.DistributionType="uniform";
//0: uniform
//1: normal
//2: lognormal
//3: optimisedsample //used in a case where the parameters is unknown and an algorithm decides the sample chosen based on the outcome of an optimisation routine

// The following are used for inside the simulations
//4: exponential
//5: logitnormal   // used for probability distributions (on [0,1]). Note sigma<1 to avoid strange edge effects
//6: poisson
//7: sqrnormal

this.Median=NaN;
this.StandardError=NaN;
this.LowerBound=NaN;//used for uniform distributions
this.UpperBound=NaN;//used for uniform distributions

this.Upper95Range=NaN;// These values are calculated on the fly by the program, and are displayed in the interface
this.Lower95Range=NaN;

this.NumberOfSamples=NaN;
this.Val=[];//This is the array of the samples

this.MinValue="";// These values are used to put a bound on the values, e.g. many values must not be less than zero.
this.MaxValue="";

//These variables are used to describe what the variables are and where they are from
this.Description=[];//
this.RefText=[];//Text to be displayed in lieu of the
this.URL=[];//An array of URLs that are sources for the parameter in question [Link] Jansson et al., 2013, Title of paper

}

//Load the parameter from text
	//or maybe simply bind a JSON object
ParameterClass.prototype.Load= function (InputStructure){
	for (var Key in this){
		if (typeof(InputStructure[Key])!='undefined'){
			this[key]=InputStructure[Key];
		}
	}
}

ParameterClass.prototype.Name= function (){
	return (this.GroupName+'.'+this.ParameterID);
}

ParameterClass.prototype.UpdateTypeDisplay= function (){
	// Set up the name and parameter type
	var ParameterHTML=""+
	"<input type='text' name='ParameterID' value='" + this.ParameterID + "'>\n"+
	"<select name='DistributionType'  onchange='"+this.Name()+".DistributionType=this.value;"+this.Name()+".UpdateTypeDisplay();'>\n"+//change the type, then redisplay

	"	<option value='normal'>Normal</option>\n"+
	"	<option value='lognormal'>Log Normal</option>\n"+
	"	<option value='uniform'>Uniform</option>\n"+
	"	<option value='optimisedsample'>Optimised Sample</option>\n"+

	"</select>\n ";

	if (this.DistributionType=="normal"){
		ParameterHTML+="Median <input type='text' name='Median' value='" + this.Median + " '>\n"+
		" Standard error <input type='text' name='StandardError' value='" + this.StandardError + " '>\n";
	}
	else if (this.DistributionType=="lognormal"){
		ParameterHTML+="Median <input type='text' name='Median' value='" + this.Median + " '>\n"+
		" Standard error of log <input type='text' name='StandardError' value='" + this.StandardError + " '>\n";
	}
	else if (this.DistributionType=="uniform"){
		ParameterHTML+="Lower Bound <input type='text' name='LowerBound' value='" + this.LowerBound + " '>\n"+
		" Upper Bound <input type='text' name='UpperBound' value='" + this.UpperBound + " '>\n";
	}
	else if (this.DistributionType=="optimisedsample"){
		ParameterHTML+="Lower Bound <input type='text' name='LowerBound' value='" + this.LowerBound + " '>\n"+
		" Upper Bound <input type='text' name='UpperBound' value='" + this.UpperBound + " '>\n";
	}

	// onchange="Settings.NumberOfSimulations=Number(this.value);SaveSettings();"
	// onchange="ID.Change(this.Name, this.value)";
	// in the function Number(this.value); SaveParameterFile();

	//
	//
	//
	//
	//		Median <input type="text" name="Median">
	//		SD <input type="text" name="SD">
	//		+ More info
	//
 Some info to display

	//

	// Determine estimated value of the mean, IQR and 95% range of the parameters
	this.CalculateUncertaintyBounds();
	// Display this information to the user

	// Save button
		// When pressed,
		// Get the values from all the fields
		// save the value to Param
		// Save Param

	// This information exists for all parameters
	ParameterHTML=ParameterHTML+
		" Save  \n"+
		" + More info \n"+
		"
\n"+
		"
\n"+
		"    Median <input type='text' name='' value='" + this.Median + " '>\n"+
		"    Lower 95%CI <input type='text' name='' value='" + this.Lower95Range + " '>\n"+
		"    Upper 95%CI <input type='text' name='' value='" + this.Upper95Range + " '>\n"+
		"
Description
"+
		"    <textarea name='Description' cols='100' rows='5'>"+this.Description+"</textarea>";
	//For each of the references, add a link, a box for the title, and the link
	//
	//Add a "add ref button"
	//

	//Close off the references div
	ParameterHTML=ParameterHTML+"
";

	// Set the parameter
	document.getElementById(this.InterfaceID).innerHTML=ParameterHTML;
	document.getElementById(this.InterfaceID).DistributionType.value=this.DistributionType;
}

ParameterClass.prototype.Save=function(){
	console.log("Button pressing works");

	// Go through each of the possible elements

	// See if it exists

	// if it exists, set to the value in the Param

	// if the name in the display is different to the name in the

	// if the name changes, update the InterfaceID
	var OldId=this.InterfaceID;
	// DetermineInterfaceID(this.Name);

	this.UpdateTypeDisplay();
}

//Load the parameter from interface
	//This requires that the
//Save this interface as

ParameterClass.prototype.CalculateUncertaintyBounds= function (){
	if (this.DistributionType=="normal"){
		this.Upper95Range=this.Median+1.96*this.StandardError;
		this.Lower95Range=this.Median-1.96*this.StandardError;
	}
	else if (this.DistributionType=="lognormal"){
		//log
		var LogMean=Log(this.Median);
		//calculate //delog
		this.Upper95Range=Exp(LogMean+1.96*this.StandardError);
		this.Lower95Range=Exp(LogMean-1.96*this.StandardError);
	}
}

ParameterClass.prototype.CreateDistribution= function (){

	if (this.distributionType=="lognormal"){
		//log
		var logmedian=Math.log(this.Median);
		//calculate
		Rand.Value();
		//some code here https://gist.github.com/Protonk/5367430
		//Linear congruential generator

		//http://stackoverflow.com/questions/20160827/when-generating-normally-distributed-random-values-what-is-the-most-efficient-w
		// To get approximately normally distributed random numbers, add 12 rands, minus 6, divide
		//

		//delog
	}

}

//**************************************************************************************************************************
// From this point, the code is no longer dealing with individual parameters, but with displaying groups of parameters in a page

function BuildParameterPage(ParamGroup, ParamGroupDivId, GroupName){

	//Firstly, ensure that each of the parameters in the group have the proper GroupName e.g. Param.HIV
	//This allows the object to be able to write code that allows it to execute itself, e.g. Param.HIV.CalculateAndDisplayMedian()
	for (var key in ParamGroup) {// Code inspired by http://stackoverflow.com/questions/208016/how-to-list-the-properties-of-a-javascript-object
		if (ParamGroup.hasOwnProperty(key)) {
			ParamGroup[key].GroupName=GroupName;
		}
	}

	var BuildText="";
	for (var key in ParamGroup) {// Code inspired by http://stackoverflow.com/questions/208016/how-to-list-the-properties-of-a-javascript-object
		if (ParamGroup.hasOwnProperty(key)) {
			//maybe also check here that the parameter is not an array, other wise use a different function
			ParamGroup[key].InterfaceID=ParamGroupDivId+key;
			BuildText=BuildText+"                <form class=\"ParamContainer\" id=\""+ParamGroup[key].InterfaceID+"\"></form>\n";
		}
	}

	//This next section is very naughty, because it breaks the div by setting the inner HTML. It will probably break.
	BuildText=BuildText+"
Add parameter
"
	BuildText=BuildText+"
Unsaved parameters <\p>";
	document.getElementById(ParamGroupDivId).innerHTML = BuildText;

	//Load each of the holders with the parameters that should be held
	for (var key in ParamGroup) {
		if (ParamGroup.hasOwnProperty(key)) {
			//Update display of parameter
			ParamGroup[key].UpdateTypeDisplay();
		}
	}
}

function AddNewParameter(ParamGroup, GroupName, ParamGroupDivId){
	//Count number of current
	var NumParams=1;
	for (var key in ParamGroup) {
		NumParams++;
	}
	var ParamName="NewParam"+NumParams;//The new parameter will be called e.g. NewParam12
	ParamGroup[ParamName]=new ParameterClass(ParamName);
	// Add the GroupName
	ParamGroup[ParamName].GroupName=GroupName;

	// Name the interface
	ParamGroup[ParamName].InterfaceID=ParamGroupDivId+ParamName;
	HTMLToAdd="\n                <form class=\"ParamContainer\" id=\""+ParamGroup[ParamName].InterfaceID+"\"></form>";
	document.getElementById(ParamGroupDivId).innerHTML = document.getElementById(ParamGroupDivId).innerHTML + HTMLToAdd;

	console.log(ParamGroup[ParamName].Name());
	console.log(ParamGroup[ParamName].GroupName);

	ParamGroup[ParamName].UpdateTypeDisplay();
}

//   create a new 'form' element

// Renaming a key for an object
//if (old_key !== new_key) {
//    Object.defineProperty(o, new_key, Object.getOwnPropertyDescriptor(o, old_key));
//    delete o[old_key];
//}

// Load parameters from a file
function LoadParameters(ParameterFileName){
	// Open the file
	var ParamStruct=fs.readFileSync("./model/parameters.json", 'utf8');
	console.log(ParamStruct);

	console.error("Note that file error handling has not yet been implemented. Maybe use a try/catch system. Determine how to use readFileSync properly to ensure that the lack of the file is handled properly.");
	var ParamStruct=fs.readFileSync("./model/parameters.json", 'utf8', function (err, data) {
		console.log("1");
		if (err){
			console.error("The file " + ParameterFileName+" could not be loaded. Error: ");
			console.error(err);
			var ParsedStruct={};
			ParsedStruct.ParamLoadingError=err;
			return ParsedStruct;
		}
		else{
			// Parse the JSON
			var ParsedStruct= JSON.parse(data);
			return ParsedStruct;
		}
	});
	console.log(ParamStruct);
	// Check for error
	if (typeof(ParamStruct.ParamLoadingError)!='undefined'){
		return ParamStruct;
	}

	// Check for problems

	var Param={};
	// Parse into each subgroup
	for (var Key in ParamStruct){
		// Create a new parameter for each value in the group
		Param[Key]={};
		for (var Key2 in ParamStruct[Key]){
			Param[Key][Key2]=new ParameterClass(Key2);
			Param[Key][Key2].Load(ParamStruct[Key][Key2]);
		}
	}
	return Param;
}

// Save parameters to file
<commit_msg>Reading in the new info into Param<commit_after>// This library requires mathtools.js to work

function ParameterClass(ParameterID, GroupName){// InterfacePrefix

this.ParameterID=ParameterID;// e.g. LFHCCProbability
this.InterfaceID="";// e.g. HCV_LFHCCProbability
// Note that GroupName is primarily used for interface design. It is updated at load to represent the true structure of the objects in which it resides, so it cannot be relied upon to be consistent between builds.
this.GroupName="";//e.g. HCV, or in the case of it being a struct of a struct, Param.HCV
//GroupName+'.'+ParameterID gives the full name that the function can call.

this.DistributionType="uniform";
//0: uniform
//1: normal
//2: lognormal
//3: optimisedsample //used in a case where the parameters is unknown and an algorithm decides the sample chosen based on the outcome of an optimisation routine

// The following are used for inside the simulations
//4: exponential
//5: logitnormal   // used for probability distributions (on [0,1]). Note sigma<1 to avoid strange edge effects
//6: poisson
//7: sqrnormal

this.Median=NaN;
this.StandardError=NaN;
this.LowerBound=NaN;//used for uniform distributions
this.UpperBound=NaN;//used for uniform distributions

this.Upper95Range=NaN;// These values are calculated on the fly by the program, and are displayed in the interface
this.Lower95Range=NaN;

this.NumberOfSamples=NaN;
this.Val=[];//This is the array of the samples

this.MinValue="";// These values are used to put a bound on the values, e.g. many values must not be less than zero.
this.MaxValue="";

//The Description is used to describe what the variables are and where they are from including URLs and any other calculation
this.Description=[];//
}

//Load the parameter from text
	//or maybe simply bind a JSON object
ParameterClass.prototype.Load= function (InputStructure){
	for (var Key in this){
		if (typeof(InputStructure[Key])!='undefined'){
			this[key]=InputStructure[Key];
		}
	}
}

ParameterClass.prototype.Name= function (){
	return (this.GroupName+'.'+this.ParameterID);
}

ParameterClass.prototype.UpdateTypeDisplay= function (){
	// Set up the name and parameter type
	var ParameterHTML=""+
	"<input type='text' name='ParameterID' value='" + this.ParameterID + "'>\n"+
	"<select name='DistributionType'  onchange='"+this.Name()+".DistributionType=this.value;"+this.Name()+".UpdateTypeDisplay();'>\n"+//change the type, then redisplay

	"	<option value='normal'>Normal</option>\n"+
	"	<option value='lognormal'>Log Normal</option>\n"+
	"	<option value='uniform'>Uniform</option>\n"+
	"	<option value='optimisedsample'>Optimised Sample</option>\n"+

	"</select>\n ";

	if (this.DistributionType=="normal"){
		ParameterHTML+="Median <input type='text' name='Median' value='" + this.Median + " '>\n"+
		" Standard error <input type='text' name='StandardError' value='" + this.StandardError + " '>\n";
	}
	else if (this.DistributionType=="lognormal"){
		ParameterHTML+="Median <input type='text' name='Median' value='" + this.Median + " '>\n"+
		" Standard error of log <input type='text' name='StandardError' value='" + this.StandardError + " '>\n";
	}
	else if (this.DistributionType=="uniform"){
		ParameterHTML+="Lower Bound <input type='text' name='LowerBound' value='" + this.LowerBound + " '>\n"+
		" Upper Bound <input type='text' name='UpperBound' value='" + this.UpperBound + " '>\n";
	}
	else if (this.DistributionType=="optimisedsample"){
		ParameterHTML+="Lower Bound <input type='text' name='LowerBound' value='" + this.LowerBound + " '>\n"+
		" Upper Bound <input type='text' name='UpperBound' value='" + this.UpperBound + " '>\n";
	}

	// onchange="Settings.NumberOfSimulations=Number(this.value);SaveSettings();"
	// onchange="ID.Change(this.Name, this.value)";
	// in the function Number(this.value); SaveParameterFile();

	//
	//
	//
	//
	//		Median <input type="text" name="Median">
	//		SD <input type="text" name="SD">
	//		+ More info
	//
 Some info to display

	//

	// Determine estimated value of the mean, IQR and 95% range of the parameters
	this.CalculateUncertaintyBounds();
	// Display this information to the user

	// Save button
		// When pressed,
		// Get the values from all the fields
		// save the value to Param
		// Save Param

	// This information exists for all parameters
	ParameterHTML=ParameterHTML+
		" Save  \n"+
		" + More info \n"+
		"
\n"+
		"
\n"+
		"    Median <input type='text' name='' value='" + this.Median + " '>\n"+
		"    Lower 95%CI <input type='text' name='' value='" + this.Lower95Range + " '>\n"+
		"    Upper 95%CI <input type='text' name='' value='" + this.Upper95Range + " '>\n"+
		"
Description
"+
		"    <textarea name='Description' cols='100' rows='5'>"+this.Description+"</textarea>";
	//For each of the references, add a link, a box for the title, and the link
	//
	//Add a "add ref button"
	//

	//Close off the references div
	ParameterHTML=ParameterHTML+"
";

	// Set the parameter
	document.getElementById(this.InterfaceID).innerHTML=ParameterHTML;
	document.getElementById(this.InterfaceID).DistributionType.value=this.DistributionType;
}

ParameterClass.prototype.Save=function(){
	console.log("Button pressing works");

	// Go through each of the possible elements
	var FieldNames=['ParameterID',
					'InterfaceID',
					'DistributionType',
					'Median',
					'StandardError',
					'LowerBound',
					'UpperBound',
					'Upper95Range',
					'Lower95Range',
					'MinValue',
					'MaxValue',
					'Description'];
	// See if it exists
	var ParamElement = document.getElementById(this.InterfaceID);
	// if it exists, set to the value in the Param
	for (var Field in FieldNames){
		console.log(FieldNames[Field]);
		if (typeof(ParamElement[FieldNames[Field]])!='undefined'){
			this[FieldNames[Field]]=ParamElement[FieldNames[Field]].value;

			console.log(this[FieldNames[Field]]);
		}

	}

	console.error('Need to convert to numbers before this will work. Spaces making your life tough');

	// if the name in the display is different to the name in the

	// if the name changes, update the InterfaceID
	var OldId=this.InterfaceID;
	// DetermineInterfaceID(this.Name);

	this.UpdateTypeDisplay();
}

//Load the parameter from interface
	//This requires that the
//Save this interface as

ParameterClass.prototype.CalculateUncertaintyBounds= function (){
	if (this.DistributionType=="normal"){
		this.Upper95Range=this.Median+1.96*this.StandardError;
		this.Lower95Range=this.Median-1.96*this.StandardError;
	}
	else if (this.DistributionType=="lognormal"){
		//log
		var LogMean=Log(this.Median);
		//calculate //delog
		this.Upper95Range=Exp(LogMean+1.96*this.StandardError);
		this.Lower95Range=Exp(LogMean-1.96*this.StandardError);
	}
}

ParameterClass.prototype.CreateDistribution= function (){

	if (this.distributionType=="lognormal"){
		//log
		var logmedian=Math.log(this.Median);
		//calculate
		Rand.Value();
		//some code here https://gist.github.com/Protonk/5367430
		//Linear congruential generator

		//http://stackoverflow.com/questions/20160827/when-generating-normally-distributed-random-values-what-is-the-most-efficient-w
		// To get approximately normally distributed random numbers, add 12 rands, minus 6, divide
		//

		//delog
	}

}

//**************************************************************************************************************************
// From this point, the code is no longer dealing with individual parameters, but with displaying groups of parameters in a page

function BuildParameterPage(ParamGroup, ParamGroupDivId, GroupName){

	//Firstly, ensure that each of the parameters in the group have the proper GroupName e.g. Param.HIV
	//This allows the object to be able to write code that allows it to execute itself, e.g. Param.HIV.CalculateAndDisplayMedian()
	for (var key in ParamGroup) {// Code inspired by http://stackoverflow.com/questions/208016/how-to-list-the-properties-of-a-javascript-object
		if (ParamGroup.hasOwnProperty(key)) {
			ParamGroup[key].GroupName=GroupName;
		}
	}

	var BuildText="";
	for (var key in ParamGroup) {// Code inspired by http://stackoverflow.com/questions/208016/how-to-list-the-properties-of-a-javascript-object
		if (ParamGroup.hasOwnProperty(key)) {
			//maybe also check here that the parameter is not an array, other wise use a different function
			ParamGroup[key].InterfaceID=ParamGroupDivId+key;
			BuildText=BuildText+"                <form class=\"ParamContainer\" id=\""+ParamGroup[key].InterfaceID+"\"></form>\n";
		}
	}

	//This next section is very naughty, because it breaks the div by setting the inner HTML. It will probably break.
	BuildText=BuildText+"
Add parameter
"
	BuildText=BuildText+"
Unsaved parameters <\p>";
	document.getElementById(ParamGroupDivId).innerHTML = BuildText;

	//Load each of the holders with the parameters that should be held
	for (var key in ParamGroup) {
		if (ParamGroup.hasOwnProperty(key)) {
			//Update display of parameter
			ParamGroup[key].UpdateTypeDisplay();
		}
	}
}

function AddNewParameter(ParamGroup, GroupName, ParamGroupDivId){
	//Count number of current
	var NumParams=1;
	for (var key in ParamGroup) {
		NumParams++;
	}
	var ParamName="NewParam"+NumParams;//The new parameter will be called e.g. NewParam12
	ParamGroup[ParamName]=new ParameterClass(ParamName);
	// Add the GroupName
	ParamGroup[ParamName].GroupName=GroupName;

	// Name the interface
	ParamGroup[ParamName].InterfaceID=ParamGroupDivId+ParamName;
	HTMLToAdd="\n                <form class=\"ParamContainer\" id=\""+ParamGroup[ParamName].InterfaceID+"\"></form>";
	document.getElementById(ParamGroupDivId).innerHTML = document.getElementById(ParamGroupDivId).innerHTML + HTMLToAdd;

	console.log(ParamGroup[ParamName].Name());
	console.log(ParamGroup[ParamName].GroupName);

	ParamGroup[ParamName].UpdateTypeDisplay();
}

//   create a new 'form' element

// Renaming a key for an object
//if (old_key !== new_key) {
//    Object.defineProperty(o, new_key, Object.getOwnPropertyDescriptor(o, old_key));
//    delete o[old_key];
//}

// Load parameters from a file
function LoadParameters(ParameterFileName){
	// Open the file
	var ParamStruct=fs.readFileSync("./model/parameters.json", 'utf8');
	console.log(ParamStruct);

	console.error("Note that file error handling has not yet been implemented. Maybe use a try/catch system. Determine how to use readFileSync properly to ensure that the lack of the file is handled properly.");
	var ParamStruct=fs.readFileSync("./model/parameters.json", 'utf8', function (err, data) {
		console.log("1");
		if (err){
			console.error("The file " + ParameterFileName+" could not be loaded. Error: ");
			console.error(err);
			var ParsedStruct={};
			ParsedStruct.ParamLoadingError=err;
			return ParsedStruct;
		}
		else{
			// Parse the JSON
			var ParsedStruct= JSON.parse(data);
			return ParsedStruct;
		}
	});
	console.log(ParamStruct);
	// Check for error
	if (typeof(ParamStruct.ParamLoadingError)!='undefined'){
		return ParamStruct;
	}

	// Check for problems

	var Param={};
	// Parse into each subgroup
	for (var Key in ParamStruct){
		// Create a new parameter for each value in the group
		Param[Key]={};
		for (var Key2 in ParamStruct[Key]){
			Param[Key][Key2]=new ParameterClass(Key2);
			Param[Key][Key2].Load(ParamStruct[Key][Key2]);
		}
	}
	return Param;
}

// Save parameters to file
<|endoftext|>


<commit_before>//
// Generate SQL users for Directum
//

var $={Dir:{	// Global variable
 Server:'Dir9',		// Directum server
 DB:	'Directum'	// Directum database
}};

//WScript.Interactive=false;
goDB();
readUsers();
WScript.Echo($.U.join(', '));

//--[Functions]

function goSQL()
{
 WScript.Echo("Connecting to MS SQL...");

 var SQL=new ActiveXObject("ADODB.Connection");
 SQL.Provider='SQLOLEDB';
 SQL.Open("Integrated Security=SSPI;Data Source="+$.Dir.Server);
 SQL.DefaultDatabase='['+$.Dir.DB+']';
 $.SQL=new ActiveXObject("ADODB.Command");
 $.SQL.ActiveConnection=SQL;
}

function goAD()
{
 WScript.Echo("Connecting to Active Directory...");

 $.AD={Domain: (new ActiveXObject("ADSystemInfo")).DomainShortName};
 $.AD.rootDSE=GetObject("LDAP://rootDSE");
 $.AD.baseDN=$.AD.rootDSE.Get('rootDomainNamingContext');

 $.AD.h=new ActiveXObject("ADODB.Connection");
 $.AD.h.Provider = "ADsDSOObject";
 $.AD.h.Open("Active Directory Provider");

 $.AD.cmd=new ActiveXObject("ADODB.Command");
 $.AD.cmd.ActiveConnection=$.AD.h;
 $.AD.cmd.Properties("Page Size")=1000;
 $.AD.cmd.Properties("Searchscope")=2; // ADS_SCOPE_SUBTREE
}

function goDB()
{
 goSQL();
 goAD();
}

//
function readSnippet(name)
{
 var f=WScript.CreateObject("Scripting.FileSystemObject").
    OpenTextFile(WScript.ScriptFullName, 1);	//ForReading
 var on, R='';
 while(!f.AtEndOfStream)
 {
  var s=f.ReadLine();
  if(!on)
  {
   if(s.match(/^\s*\/\*[-\s]*\[([.\w]+)\][-\s]+$/i) && (RegExp.$1==name)) on=1;
   continue;
  }
  if(s.match(/^[-\s]+\*\/\s*$/)) break;
  R+=s+'\n';
 }
 f.Close();
 return R;
}

function readUsers()
{
/*--[List]-----------------------------------------------------------
Select UserLogin
From MBUser
Where
 UserType=''
 And NeedEncode='W'
 And UserCategory=''
Order By 1
-------------------------------------------------------------------*/
 WScript.Echo("Getting user list...");

 $.U=[];
 $.SQL.CommandText=readSnippet('List');
 for(var Rs=$.SQL.Execute(); !Rs.EOF; Rs.MoveNext())
  $.U.push(Rs(0).value);
}

//--[EOF]------------------------------------------------------------
<commit_msg>Go thru user list<commit_after>//
// Generate SQL users for Directum
//

var $={Dir:{	// Global variable
 Server:'Dir9',		// Directum server
 DB:	'Directum'	// Directum database
}};

//WScript.Interactive=false;
goDB();
readUsers();
Process();

//--[Functions]

function goSQL()
{
 WScript.Echo("Connecting to MS SQL...");

 var SQL=new ActiveXObject("ADODB.Connection");
 SQL.Provider='SQLOLEDB';
 SQL.Open("Integrated Security=SSPI;Data Source="+$.Dir.Server);
 SQL.DefaultDatabase='['+$.Dir.DB+']';
 $.SQL=new ActiveXObject("ADODB.Command");
 $.SQL.ActiveConnection=SQL;
}

function goAD()
{
 WScript.Echo("Connecting to Active Directory...");

 $.AD={Domain: (new ActiveXObject("ADSystemInfo")).DomainShortName};
 $.AD.rootDSE=GetObject("LDAP://rootDSE");
 $.AD.baseDN=$.AD.rootDSE.Get('rootDomainNamingContext');

 $.AD.h=new ActiveXObject("ADODB.Connection");
 $.AD.h.Provider = "ADsDSOObject";
 $.AD.h.Open("Active Directory Provider");

 $.AD.cmd=new ActiveXObject("ADODB.Command");
 $.AD.cmd.ActiveConnection=$.AD.h;
 $.AD.cmd.Properties("Page Size")=1000;
 $.AD.cmd.Properties("Searchscope")=2; // ADS_SCOPE_SUBTREE
}

function goDB()
{
 goSQL();
 goAD();
}

//
function readSnippet(name)
{
 var f=WScript.CreateObject("Scripting.FileSystemObject").
    OpenTextFile(WScript.ScriptFullName, 1);	//ForReading
 var on, R='';
 while(!f.AtEndOfStream)
 {
  var s=f.ReadLine();
  if(!on)
  {
   if(s.match(/^\s*\/\*[-\s]*\[([.\w]+)\][-\s]+$/i) && (RegExp.$1==name)) on=1;
   continue;
  }
  if(s.match(/^[-\s]+\*\/\s*$/)) break;
  R+=s+'\n';
 }
 f.Close();
 return R;
}

function readUsers()
{
/*--[List]-----------------------------------------------------------
Select UserLogin
From MBUser
Where
 UserType=''
 And NeedEncode='W'
 And UserCategory=''
Order By 1
-------------------------------------------------------------------*/
 WScript.Echo("Getting user list...");

 $.U=[];
 $.SQL.CommandText=readSnippet('List');
 for(var Rs=$.SQL.Execute(); !Rs.EOF; Rs.MoveNext())
  $.U.push(Rs(0).value);
}

//      AD
function u2obj(u)
{
 $.AD.cmd.CommandText="<LDAP://"+$.AD.baseDN+
    ">;(&(objectCategory=user)(sAMAccountName="+
    u.replace(/[()*\\]/g, '\\$&')+"));*;subTree";
 var Rs=$.AD.cmd.Execute();
 if(!Rs.EOF) return GetObject(Rs(0).Value);
}

function Process()
{
 for(var i in $.U)
 {
  var u=$.U[i];
  if(!u2obj(u)) continue;
  WScript.Echo(u);
 }
}

//--[EOF]------------------------------------------------------------
<|endoftext|>