<commit_before>import { Meteor } from 'meteor/meteor';
import { Session } from 'meteor/session';
import { FlowRouter } from 'meteor/kadira:flow-router';
import { BlazeLayout } from 'meteor/kadira:blaze-layout';
import moment from 'moment';

import { doIfLoggedIn } from '/imports/framework/Managers/RouteManager.Helpers';
import RouteManager from '/imports/framework/Managers/RouteManager';

RouteManager.registerTranslatedPage('dashboard', {
  details: ''
});
RouteManager.registerTranslatedPage('dashboard.myProjects', {
  details: 'myProjects'
});
RouteManager.registerTranslatedPage('dashboard.missingShiftReports', {
  details: 'missingShiftReports'
});
RouteManager.registerTranslatedPage('dashboard.upcomingShifts', {
  details: 'upcomingShifts'
});
RouteManager.registerTranslatedPage('project', {
  search: 'projects'
});
RouteManager.registerTranslatedPage('users.online', {
  details: 'users/online'
});
RouteManager.registerTranslatedPage('user', {
  search: 'users',
  details: 'user/:userId'
});
RouteManager.registerTranslatedPage('language', {
  details: 'language',
  update: 'language/:key'
});
RouteManager.registerEntity('project', {
  details: ''
});
RouteManager.registerEntity('publisher.password', {
  insert: 'publishers/:userId/password',
  forwarding: {
    route: 'publishers/:userId/password/forwarding',
    name: 'publisher.password.details',
    link: 'publisher.details'
  }
});
RouteManager.registerEntity('publisher.profile.availability', {
  insert: 'publishers/:userId/availability/:key/new',
  details: 'publishers/:userId/availability/:key'
});
RouteManager.registerEntity('publisher.profile.vacation', {
  insert: 'publishers/:userId/vacation/new',
  forwarding: {
    route: 'publishers/:userId/vacation/forwarding',
    name: 'publisher.profile.vacation.details',
    link: 'publisher.details'
  }
});
RouteManager.registerEntity('publisher', {
  search: 'publishers',
  insert: 'publishers/new',
  details: 'publishers/:userId',
  update: 'publishers/:userId/:key'
});
RouteManager.registerEntity('vessel', {
  search: 'vessels',
  insert: 'vessels/new',
  details: 'vessels/:vesselId',
  update: 'vessels/:vesselId/:key'
});
RouteManager.registerEntity('vessel.visit', {
  insert: 'vessels/:vesselId/visits/new',
  details: 'vessels/:vesselId/visits/:visitId',
  update: 'vessels/:vesselId/visits/:visitId/:key'
});
RouteManager.registerEntity('vessel.visit.language', {
  insert: 'vessels/:vesselId/visits/:visitId/languages/new',
  forwarding: {
    route: 'vessels/:vesselId/visits/:visitId/language/forwarding',
    name: 'vessel.visit.language.details',
    link: 'vessel.visit.details'
  }
});
RouteManager.registerEntity('note', {
  search: 'notes',
  insert: 'notes/new',
  details: 'notes/:noteId',
  update: 'notes/:noteId/:key'
});

FlowRouter.route('/:projectId/publisherActions', {
  name: 'publisherActions',
  action: () => {
    doIfLoggedIn(() => {
      Session.set('parent', 'project.details');
      BlazeLayout.render('mainLayout', { content: 'publisherActions' });
    });
  }
});

FlowRouter.route('/:projectId/calendar/:year?/:month?/:day?', {
  name: 'calendar',
  action: () => {
    doIfLoggedIn(() => {
      Session.set('parent', 'project.details');
      BlazeLayout.render('mainLayout', { content: 'calendar' });
    });
  }
});

FlowRouter.route('/:projectId/kb', {
  name: 'wiki',
  action: () => {
    doIfLoggedIn(() => {
      Session.set('parent', 'project.details');
      BlazeLayout.render('mainLayout', { content: 'wiki' });
    });
  }
});

FlowRouter.route('/:projectId/shifts', {
  name: 'shifts',
  action: () => {
    doIfLoggedIn(() => {
      let parent = Session.get('parent');

      if (parent != 'settings') {
        Session.set('parent', 'project.details');
        Session.set('target', null);
      }

      BlazeLayout.render('mainLayout', { content: 'shifts' });
    });
  }
});

FlowRouter.route('/goToShift/:shiftId', {
  name: 'shift.details',
  action: () => {
    doIfLoggedIn(() => {
      Meteor.call('shift.getShiftOverview', {
        shiftId: FlowRouter.getParam('shiftId')
      }, (e, shift) => {
        const momentObj = moment(shift.date, 'YYYYDDD');
        const year = parseInt(momentObj.format('YYYY'), 10);
        const month = parseInt(momentObj.format('MM'), 10);
        const day = parseInt(momentObj.format('DD'), 10);

        FlowRouter.go('calendar', {
          projectId: shift.projectId,
          year: year,
          month: month,
          day: day
        }, {
          showShift: FlowRouter.getParam('shiftId')
        });
      });
    });
  }
});

FlowRouter.route('/:projectId/settings', {
  name: 'settings',
  action: () => {
    doIfLoggedIn(() => {
      Session.set('parent', 'project.details');
      BlazeLayout.render('mainLayout', { content: 'settings' });
    });
  }
});

FlowRouter.route('/:projectId/reports', {
  name: 'reports',
  action: () => {
    doIfLoggedIn(() => {
      Session.set('parent', 'project.details');
      BlazeLayout.render('mainLayout', { content: 'reports' });
    });
  }
});

FlowRouter.route('/:projectId/store', {
  name: 'store',
  action: () => {
    doIfLoggedIn(() => {
      Session.set('parent', 'project.details');
      BlazeLayout.render('mainLayout', { content: 'store' });
    });
  }
});
<commit_msg>add todo about renaming the registration methods<commit_after>import { Meteor } from 'meteor/meteor';
import { Session } from 'meteor/session';
import { FlowRouter } from 'meteor/kadira:flow-router';
import { BlazeLayout } from 'meteor/kadira:blaze-layout';
import moment from 'moment';

import { doIfLoggedIn } from '/imports/framework/Managers/RouteManager.Helpers';
import RouteManager from '/imports/framework/Managers/RouteManager';

// TODO: rename registerTranslatedPage to registerEntity
// TODO: rename registerEntity to registerProjectEntity

RouteManager.registerTranslatedPage('dashboard', {
  details: ''
});
RouteManager.registerTranslatedPage('dashboard.myProjects', {
  details: 'myProjects'
});
RouteManager.registerTranslatedPage('dashboard.missingShiftReports', {
  details: 'missingShiftReports'
});
RouteManager.registerTranslatedPage('dashboard.upcomingShifts', {
  details: 'upcomingShifts'
});
RouteManager.registerTranslatedPage('project', {
  search: 'projects'
});
RouteManager.registerTranslatedPage('users.online', {
  details: 'users/online'
});
RouteManager.registerTranslatedPage('user', {
  search: 'users',
  details: 'user/:userId'
});
RouteManager.registerTranslatedPage('language', {
  details: 'language',
  update: 'language/:key'
});
RouteManager.registerEntity('project', {
  details: ''
});
RouteManager.registerEntity('publisher.password', {
  insert: 'publishers/:userId/password',
  forwarding: {
    route: 'publishers/:userId/password/forwarding',
    name: 'publisher.password.details',
    link: 'publisher.details'
  }
});
RouteManager.registerEntity('publisher.profile.availability', {
  insert: 'publishers/:userId/availability/:key/new',
  details: 'publishers/:userId/availability/:key'
});
RouteManager.registerEntity('publisher.profile.vacation', {
  insert: 'publishers/:userId/vacation/new',
  forwarding: {
    route: 'publishers/:userId/vacation/forwarding',
    name: 'publisher.profile.vacation.details',
    link: 'publisher.details'
  }
});
RouteManager.registerEntity('publisher', {
  search: 'publishers',
  insert: 'publishers/new',
  details: 'publishers/:userId',
  update: 'publishers/:userId/:key'
});
RouteManager.registerEntity('vessel', {
  search: 'vessels',
  insert: 'vessels/new',
  details: 'vessels/:vesselId',
  update: 'vessels/:vesselId/:key'
});
RouteManager.registerEntity('vessel.visit', {
  insert: 'vessels/:vesselId/visits/new',
  details: 'vessels/:vesselId/visits/:visitId',
  update: 'vessels/:vesselId/visits/:visitId/:key'
});
RouteManager.registerEntity('vessel.visit.language', {
  insert: 'vessels/:vesselId/visits/:visitId/languages/new',
  forwarding: {
    route: 'vessels/:vesselId/visits/:visitId/language/forwarding',
    name: 'vessel.visit.language.details',
    link: 'vessel.visit.details'
  }
});
RouteManager.registerEntity('note', {
  search: 'notes',
  insert: 'notes/new',
  details: 'notes/:noteId',
  update: 'notes/:noteId/:key'
});

FlowRouter.route('/:projectId/publisherActions', {
  name: 'publisherActions',
  action: () => {
    doIfLoggedIn(() => {
      Session.set('parent', 'project.details');
      BlazeLayout.render('mainLayout', { content: 'publisherActions' });
    });
  }
});

FlowRouter.route('/:projectId/calendar/:year?/:month?/:day?', {
  name: 'calendar',
  action: () => {
    doIfLoggedIn(() => {
      Session.set('parent', 'project.details');
      BlazeLayout.render('mainLayout', { content: 'calendar' });
    });
  }
});

FlowRouter.route('/:projectId/kb', {
  name: 'wiki',
  action: () => {
    doIfLoggedIn(() => {
      Session.set('parent', 'project.details');
      BlazeLayout.render('mainLayout', { content: 'wiki' });
    });
  }
});

FlowRouter.route('/:projectId/shifts', {
  name: 'shifts',
  action: () => {
    doIfLoggedIn(() => {
      let parent = Session.get('parent');

      if (parent != 'settings') {
        Session.set('parent', 'project.details');
        Session.set('target', null);
      }

      BlazeLayout.render('mainLayout', { content: 'shifts' });
    });
  }
});

FlowRouter.route('/goToShift/:shiftId', {
  name: 'shift.details',
  action: () => {
    doIfLoggedIn(() => {
      Meteor.call('shift.getShiftOverview', {
        shiftId: FlowRouter.getParam('shiftId')
      }, (e, shift) => {
        const momentObj = moment(shift.date, 'YYYYDDD');
        const year = parseInt(momentObj.format('YYYY'), 10);
        const month = parseInt(momentObj.format('MM'), 10);
        const day = parseInt(momentObj.format('DD'), 10);

        FlowRouter.go('calendar', {
          projectId: shift.projectId,
          year: year,
          month: month,
          day: day
        }, {
          showShift: FlowRouter.getParam('shiftId')
        });
      });
    });
  }
});

FlowRouter.route('/:projectId/settings', {
  name: 'settings',
  action: () => {
    doIfLoggedIn(() => {
      Session.set('parent', 'project.details');
      BlazeLayout.render('mainLayout', { content: 'settings' });
    });
  }
});

FlowRouter.route('/:projectId/reports', {
  name: 'reports',
  action: () => {
    doIfLoggedIn(() => {
      Session.set('parent', 'project.details');
      BlazeLayout.render('mainLayout', { content: 'reports' });
    });
  }
});

FlowRouter.route('/:projectId/store', {
  name: 'store',
  action: () => {
    doIfLoggedIn(() => {
      Session.set('parent', 'project.details');
      BlazeLayout.render('mainLayout', { content: 'store' });
    });
  }
});
<|endoftext|>


<commit_before>const master = require("cluster");
const cluster = require("./cluster.js");
const numCPUs = require('os').cpus().length;
const logger = require("../utils/logger.js");
const EventEmitter = require("events");
const Eris = require("eris");
let Queue = require("../utils/queue.js");

/**
 *
 *
 * @class ClusterManager
 * @extends {EventEmitter}
 */
class ClusterManager extends EventEmitter {
    /**
     * Creates an instance of ClusterManager.
     * @param {any} token
     * @param {any} mainFile
     * @param {any} options
     * @memberof ClusterManager
     */
    constructor(token, mainFile, options) {
        super();
        this.shardCount = 0;
        this.token = token;
        this.clusters = new Map();
        this.maxShards = 0;
        this.queue = new Queue();
        this.eris = new Eris(token);
        this.options = {
            stats: options.stats || false
        };
        this.mainFile = mainFile;
        this.name = options.name || "Eris-Sharder";
        this.firstShardID = 0;
        this.shardSetupStart = 0;
        this.webhooks = {
            cluster: options.webhooks.cluster || null,
            shard: options.webhooks.shard || null
        };
        this.options.debug = options.debug || false;
        this.clientOptions = options.clientOptions || {};
        if (options.stats === true) {
            this.stats = {
                stats: {
                    guilds: 0,
                    users: 0,
                    totalRam: 0,
                    clusters: []
                },
                clustersCounted: 0
            }
        }

        this.launch();
    }

    startStats() {

        let self = this;
        setInterval(function () {
            self.stats.stats.guilds = 0;
            self.stats.stats.users = 0;
            self.stats.stats.totalRam = 0;
            self.stats.stats.clusters = [];
            self.stats.clustersCounted = 0;
            self.executeStats(1);
        }, 10 * 1000);
    }

    /**
     *
     *
     * @param {any} start
     * @memberof ClusterManager
     */
    executeStats(start) {
        let cluster = this.clusters.get(start);
        if (cluster) {
            cluster.worker.send({ message: "stats" });
            this.executeStats(start + 1)
        }
    }

    /**
     *
     *
     * @param {any} amount
     * @param {any} numSpawned
     * @memberof ClusterManager
     */
    start(amount, numSpawned) {
        if (numSpawned === amount) {
            logger.info("Cluster Manager", "Clusters have been launched!");
            let self = this;
            setTimeout(function () {
                self.roundRobinParser(master.workers);
            }, 5000);
        } else {
            let worker = master.fork();
            this.clusters.set(worker.id, { worker: worker, shardCount: 0 });
            logger.info("Cluster Manager", `Launching cluster ${worker.id}`);
            numSpawned = numSpawned + 1;
            let self = this;
            setTimeout(function () {
                self.start(amount, numSpawned);
            }, 100);
        }
    }

    /**
     *
     *
     * @memberof ClusterManager
     */
    async launch() {
        if (master.isMaster) {
            this.printLogo();
            setTimeout(() => {
                logger.info("\nGeneral", "Cluster Manager has started!");
                this.eris.getBotGateway().then(result => {
                    this.shardCount = result.shards;
                    this.maxShards = this.shardCount;
                    logger.info("Cluster Manager", `Starting ${this.shardCount} shards in ${numCPUs} clusters`);
                    let embed = {
                        title: `Starting ${this.shardCount} shards in ${numCPUs} clusters`
                    }
                    this.sendWebhook("cluster", embed);

                    master.setupMaster({
                        silent: true
                    });
                    // Fork workers.
                    this.start(numCPUs, 0);
                });
            }, 50);
        } else if (master.isWorker) {
            const Cluster = new cluster(master.worker.id);
            Cluster.spawn();
        }

        master.on('message', (worker, message, handle) => {
            switch (message.type) {
                case "log":

                    logger.log(`Cluster ${worker.id}`, `${message.msg}`);
                    break;
                case "debug":
                    if (this.options.debug) {
                        logger.debug(`Cluster ${worker.id}`, `${message.msg}`);
                    }
                    break;
                case "info":
                    logger.info(`Cluster ${worker.id}`, `${message.msg}`);
                    break;
                case "warn":
                    logger.warn(`Cluster ${worker.id}`, `${message.msg}`);
                    break;
                case "error":
                    logger.error(`Cluster ${worker.id}`, `${message.msg}`);
                    break;
                case "shardsStarted":
                    if (this.queue.queue.length > 0) {
                        this.queue.executeQueue();
                    } else {
                        this.queue.mode = "waiting";
                    }
                    break;
                case "reload":
                    this.reloadCode(1);
                    break;
                case "cluster":
                    this.sendWebhook("cluster", message.embed);
                    break;
                case "shard":
                    this.sendWebhook("shard", message.embed);
                    break;
                case "stats":
                    this.stats.stats.guilds += message.stats.guilds;
                    this.stats.stats.users += message.stats.users;
                    this.stats.stats.totalRam += message.stats.ram;
                    let ram = message.stats.ram / 1000000;
                    this.stats.stats.clusters.push({ cluster: worker.id, shards: message.stats.shards, ram: ram, uptime: message.stats.uptime });
                    this.stats.clustersCounted += 1;
                    if (this.stats.clustersCounted === (this.clusters.size - 1)) {
                        this.emit("stats", {
                            guilds: this.stats.stats.guilds,
                            users: this.stats.stats.users,
                            totalRam: this.stats.stats.totalRam / 1000000,
                            clusters: this.stats.stats.clusters
                        });
                    }
                    break;
            }
        });

        master.on('exit', (worker, code, signal) => {
            logger.warn("Cluster Manager", `cluster ${worker.id} died. Restarting.`);
            let id = worker.id;
            let cluster = this.clusters.get(id);
            let embed = {
                title: `Cluster ${id} died with code ${code}. Restarting...`,
                description: `Shards ${cluster.firstShardID} - ${cluster.lastShardID}`
            }
            this.sendWebhook("cluster", embed);
            let shards = cluster.shardCount;
            let worker1 = master.fork();
            this.clusters.delete(worker1.id);
            this.clusters.set(worker1.id, worker1);
            let newCluster = this.clusters.get(worker1.id);
            newCluster.shardCount = shards;
            newCluster.firstShardID = cluster.firstShardID;
            newCluster.lastShardID = cluster.lastShardID;
            this.queue.queueItem({
                item: worker.id, value: {
                    message: "shards",
                    type: "reboot",
                    shards: shards,
                    firstShardID: cluster.firstShardID,
                    lastShardID: cluster.lastShardID,
                    maxShards: this.maxShards,
                    token: this.token,
                    file: this.mainFile,
                    clientOptions: this.clientOptions
                }
            });
        });

        this.queue.on("execute", item => {
            let cluster = this.clusters.get(item.item);
            if (cluster) {
                cluster.worker.send(item.value);
            }
        });
    }

    /**
     *
     *
     * @param {any} clusters
     * @memberof ClusterManager
     */
    roundRobinParser(clusters) {
        let clusters1 = Object.entries(clusters);
        this.roundRobin(clusters1, 0);
    }

    /**
     *
     *
     * @param {any} clusters
     * @param {any} start
     * @memberof ClusterManager
     */
    roundRobin(clusters, start) {
        if (this.shardCount > 0) {
            let cluster = clusters[start];
            if (!cluster) {
                start = 0
                let cluster = clusters[start];
                let c = cluster[1];
                //ic = internal cluster
                let ic = this.clusters.get(c.id);
                let shards = this.shardCount;
                c.send({
                    message: "shards",
                    type: "round-robin",
                    shards: 1
                });
                if (ic.shardCount) {
                    ic.shardCount = ic.shardCount + 1;
                } else {
                    ic.shardCount = 1;
                }
                this.shardCount = shards - 1;
                let self = this;
                setTimeout(function () {
                    self.roundRobin(clusters, start + 1);
                }, 100)

            } else {
                let c = cluster[1];
                let shards = this.shardCount
                let ic = this.clusters.get(c.id);
                c.send({
                    message: "shards",
                    type: "round-robin",
                    shards: 1
                });
                if (ic.shardCount) {
                    ic.shardCount = ic.shardCount + 1;
                } else {
                    ic.shardCount = 1;
                }
                this.shardCount = shards - 1;
                let self = this;
                setTimeout(function () {
                    start = start + 1
                    self.roundRobin(clusters, this.shardSetupStart);
                }, 100)
            }
        } else {
            this.startupShards(1);
        }
    }

    /**
     *
     *
     * @param {any} start
     * @memberof ClusterManager
     */
    startupShards(start) {
        let cluster = this.clusters.get(start);
        if (cluster) {
            if (cluster.shardCount && cluster.shardCount < 1) {
                this.startupShards(start + 1);
            } else {
                let firstShardID = this.firstShardID;
                let lastShardID = (firstShardID + cluster.shardCount) - 1;
                this.queue.queueItem({
                    item: cluster.worker.id,
                    value: {
                        message: "connect",
                        firstShardID: firstShardID,
                        lastShardID: lastShardID,
                        maxShards: this.maxShards,
                        token: this.token,
                        file: this.mainFile,
                        clientOptions: this.clientOptions
                    }
                });
                this.firstShardID = lastShardID + 1;
                this.shardSetupStart += 1;
                cluster.firstShardID = firstShardID;
                cluster.lastShardID = lastShardID;
                this.startupShards(start + 1);
            }

        } else {
            logger.info("Cluster Manager", `All shards spread`);
            this.queue.executeQueue();
            if (this.stats) {
                this.startStats();
            }
        }
    }

    /**
     *
     *
     * @param {any} type
     * @param {any} embed
     * @memberof ClusterManager
     */
    sendWebhook(type, embed) {
        let id = this.webhooks[type].id;
        let token = this.webhooks[type].token;
        if (id && token) {
            this.eris.executeWebhook(id, token, { embeds: [embed] });
        }
    }

    printLogo() {
        let art = require("ascii-art");
        console.log("_______________________________________________________________________________");
        art.font(this.name, 'Doom', function (rendered) {
            console.log(rendered);
            console.log("_______________________________________________________________________________");
        });
    }
    reloadCode(start) {
        let cluster = this.clusters.get(start);
        if (cluster) {
            cluster.worker.send({message: "reload"});
            this.reloadCode(start + 1);
        }
    }
}

module.exports = ClusterManager;<commit_msg>stats fix and sorting<commit_after>const master = require("cluster");
const cluster = require("./cluster.js");
const numCPUs = require('os').cpus().length;
const logger = require("../utils/logger.js");
const EventEmitter = require("events");
const Eris = require("eris");
let Queue = require("../utils/queue.js");

/**
 *
 *
 * @class ClusterManager
 * @extends {EventEmitter}
 */
class ClusterManager extends EventEmitter {
    /**
     * Creates an instance of ClusterManager.
     * @param {any} token
     * @param {any} mainFile
     * @param {any} options
     * @memberof ClusterManager
     */
    constructor(token, mainFile, options) {
        super();
        this.shardCount = 0;
        this.token = token;
        this.clusters = new Map();
        this.maxShards = 0;
        this.queue = new Queue();
        this.eris = new Eris(token);
        this.options = {
            stats: options.stats || false
        };
        this.mainFile = mainFile;
        this.name = options.name || "Eris-Sharder";
        this.firstShardID = 0;
        this.shardSetupStart = 0;
        this.webhooks = {
            cluster: options.webhooks.cluster || null,
            shard: options.webhooks.shard || null
        };
        this.options.debug = options.debug || false;
        this.clientOptions = options.clientOptions || {};
        if (options.stats === true) {
            this.stats = {
                stats: {
                    guilds: 0,
                    users: 0,
                    totalRam: 0,
                    clusters: []
                },
                clustersCounted: 0
            }
        }

        this.launch();
    }

    startStats() {

        let self = this;
        setInterval(function () {
            self.stats.stats.guilds = 0;
            self.stats.stats.users = 0;
            self.stats.stats.totalRam = 0;
            self.stats.stats.clusters = [];
            self.stats.clustersCounted = 0;
            self.executeStats(1);
        }, 10 * 1000);
    }

    /**
     *
     *
     * @param {any} start
     * @memberof ClusterManager
     */
    executeStats(start) {
        let cluster = this.clusters.get(start);
        if (cluster) {
            cluster.worker.send({ message: "stats" });
            this.executeStats(start + 1)
        }
    }

    /**
     *
     *
     * @param {any} amount
     * @param {any} numSpawned
     * @memberof ClusterManager
     */
    start(amount, numSpawned) {
        if (numSpawned === amount) {
            logger.info("Cluster Manager", "Clusters have been launched!");
            let self = this;
            setTimeout(function () {
                self.roundRobinParser(master.workers);
            }, 5000);
        } else {
            let worker = master.fork();
            this.clusters.set(worker.id, { worker: worker, shardCount: 0 });
            logger.info("Cluster Manager", `Launching cluster ${worker.id}`);
            numSpawned = numSpawned + 1;
            let self = this;
            setTimeout(function () {
                self.start(amount, numSpawned);
            }, 100);
        }
    }

    /**
     *
     *
     * @memberof ClusterManager
     */
    async launch() {
        if (master.isMaster) {
            this.printLogo();
            setTimeout(() => {
                logger.info("\nGeneral", "Cluster Manager has started!");
                this.eris.getBotGateway().then(result => {
                    this.shardCount = result.shards;
                    this.maxShards = this.shardCount;
                    logger.info("Cluster Manager", `Starting ${this.shardCount} shards in ${numCPUs} clusters`);
                    let embed = {
                        title: `Starting ${this.shardCount} shards in ${numCPUs} clusters`
                    }
                    this.sendWebhook("cluster", embed);

                    master.setupMaster({
                        silent: true
                    });
                    // Fork workers.
                    this.start(numCPUs, 0);
                });
            }, 50);
        } else if (master.isWorker) {
            const Cluster = new cluster(master.worker.id);
            Cluster.spawn();
        }

        master.on('message', (worker, message, handle) => {
            switch (message.type) {
                case "log":

                    logger.log(`Cluster ${worker.id}`, `${message.msg}`);
                    break;
                case "debug":
                    if (this.options.debug) {
                        logger.debug(`Cluster ${worker.id}`, `${message.msg}`);
                    }
                    break;
                case "info":
                    logger.info(`Cluster ${worker.id}`, `${message.msg}`);
                    break;
                case "warn":
                    logger.warn(`Cluster ${worker.id}`, `${message.msg}`);
                    break;
                case "error":
                    logger.error(`Cluster ${worker.id}`, `${message.msg}`);
                    break;
                case "shardsStarted":
                    if (this.queue.queue.length > 0) {
                        this.queue.executeQueue();
                    } else {
                        this.queue.mode = "waiting";
                    }
                    break;
                case "reload":
                    this.reloadCode(1);
                    break;
                case "cluster":
                    this.sendWebhook("cluster", message.embed);
                    break;
                case "shard":
                    this.sendWebhook("shard", message.embed);
                    break;
                case "stats":
                    this.stats.stats.guilds += message.stats.guilds;
                    this.stats.stats.users += message.stats.users;
                    this.stats.stats.totalRam += message.stats.ram;
                    let ram = message.stats.ram / 1000000;
                    this.stats.stats.clusters.push({ cluster: worker.id, shards: message.stats.shards, ram: ram, uptime: message.stats.uptime });
                    this.stats.clustersCounted += 1;
                    if (this.stats.clustersCounted === this.clusters.size) {
                        function compare(a, b) {
                            if (a.id < b.id)
                                return -1;
                            if (a.id > b.id)
                                return 1;
                            return 0;
                        }

                        this.emit("stats", {
                            guilds: this.stats.stats.guilds,
                            users: this.stats.stats.users,
                            totalRam: this.stats.stats.totalRam / 1000000,
                            clusters: this.stats.stats.clusters.sort(compare);
                        });
                    }
                    break;
            }
        });

        master.on('exit', (worker, code, signal) => {
            logger.warn("Cluster Manager", `cluster ${worker.id} died. Restarting.`);
            let id = worker.id;
            let cluster = this.clusters.get(id);
            let embed = {
                title: `Cluster ${id} died with code ${code}. Restarting...`,
                description: `Shards ${cluster.firstShardID} - ${cluster.lastShardID}`
            }
            this.sendWebhook("cluster", embed);
            let shards = cluster.shardCount;
            let worker1 = master.fork();
            this.clusters.delete(worker1.id);
            this.clusters.set(worker1.id, worker1);
            let newCluster = this.clusters.get(worker1.id);
            newCluster.shardCount = shards;
            newCluster.firstShardID = cluster.firstShardID;
            newCluster.lastShardID = cluster.lastShardID;
            this.queue.queueItem({
                item: worker.id, value: {
                    message: "shards",
                    type: "reboot",
                    shards: shards,
                    firstShardID: cluster.firstShardID,
                    lastShardID: cluster.lastShardID,
                    maxShards: this.maxShards,
                    token: this.token,
                    file: this.mainFile,
                    clientOptions: this.clientOptions
                }
            });
        });

        this.queue.on("execute", item => {
            let cluster = this.clusters.get(item.item);
            if (cluster) {
                cluster.worker.send(item.value);
            }
        });
    }

    /**
     *
     *
     * @param {any} clusters
     * @memberof ClusterManager
     */
    roundRobinParser(clusters) {
        let clusters1 = Object.entries(clusters);
        this.roundRobin(clusters1, 0);
    }

    /**
     *
     *
     * @param {any} clusters
     * @param {any} start
     * @memberof ClusterManager
     */
    roundRobin(clusters, start) {
        if (this.shardCount > 0) {
            let cluster = clusters[start];
            if (!cluster) {
                start = 0
                let cluster = clusters[start];
                let c = cluster[1];
                //ic = internal cluster
                let ic = this.clusters.get(c.id);
                let shards = this.shardCount;
                c.send({
                    message: "shards",
                    type: "round-robin",
                    shards: 1
                });
                if (ic.shardCount) {
                    ic.shardCount = ic.shardCount + 1;
                } else {
                    ic.shardCount = 1;
                }
                this.shardCount = shards - 1;
                let self = this;
                setTimeout(function () {
                    self.roundRobin(clusters, start + 1);
                }, 100)

            } else {
                let c = cluster[1];
                let shards = this.shardCount
                let ic = this.clusters.get(c.id);
                c.send({
                    message: "shards",
                    type: "round-robin",
                    shards: 1
                });
                if (ic.shardCount) {
                    ic.shardCount = ic.shardCount + 1;
                } else {
                    ic.shardCount = 1;
                }
                this.shardCount = shards - 1;
                let self = this;
                setTimeout(function () {
                    start = start + 1
                    self.roundRobin(clusters, this.shardSetupStart);
                }, 100)
            }
        } else {
            this.startupShards(1);
        }
    }

    /**
     *
     *
     * @param {any} start
     * @memberof ClusterManager
     */
    startupShards(start) {
        let cluster = this.clusters.get(start);
        if (cluster) {
            if (cluster.shardCount && cluster.shardCount < 1) {
                this.startupShards(start + 1);
            } else {
                let firstShardID = this.firstShardID;
                let lastShardID = (firstShardID + cluster.shardCount) - 1;
                this.queue.queueItem({
                    item: cluster.worker.id,
                    value: {
                        message: "connect",
                        firstShardID: firstShardID,
                        lastShardID: lastShardID,
                        maxShards: this.maxShards,
                        token: this.token,
                        file: this.mainFile,
                        clientOptions: this.clientOptions
                    }
                });
                this.firstShardID = lastShardID + 1;
                this.shardSetupStart += 1;
                cluster.firstShardID = firstShardID;
                cluster.lastShardID = lastShardID;
                this.startupShards(start + 1);
            }

        } else {
            logger.info("Cluster Manager", `All shards spread`);
            this.queue.executeQueue();
            if (this.stats) {
                this.startStats();
            }
        }
    }

    /**
     *
     *
     * @param {any} type
     * @param {any} embed
     * @memberof ClusterManager
     */
    sendWebhook(type, embed) {
        let id = this.webhooks[type].id;
        let token = this.webhooks[type].token;
        if (id && token) {
            this.eris.executeWebhook(id, token, { embeds: [embed] });
        }
    }

    printLogo() {
        let art = require("ascii-art");
        console.log("_______________________________________________________________________________");
        art.font(this.name, 'Doom', function (rendered) {
            console.log(rendered);
            console.log("_______________________________________________________________________________");
        });
    }
    reloadCode(start) {
        let cluster = this.clusters.get(start);
        if (cluster) {
            cluster.worker.send({ message: "reload" });
            this.reloadCode(start + 1);
        }
    }
}

module.exports = ClusterManager;<|endoftext|>


<commit_before>(function(){
  'use strict';
  angular.module('CoreFrontend.Config', []).constant('CONFIG', window.CONFIG);
})();<commit_msg>docs(config): doc for config component<commit_after>(function(){
  'use strict';
  /**
   * Application config.
   * The purpose of this module is to store all app-level configuration,
   * for instance REST endpoints. We assume that application will embed
   * this configuration as a script in the html page that loads the application
   * assigning JSON object to the `window.CONFIG` property, which we read
   * and assign it to the CONFIG constant.
   */
  angular.module('CoreFrontend.Config', []).constant('CONFIG', window.CONFIG);
})();<|endoftext|>


<commit_before>export { Base };

import * as Pool from "../util/Pool.js";
import * as Recyclable from "../util/Recyclable.js";
import * as ActivationEscaping from "./ActivationEscaping.js";

/**
 * A placeholder for tensor.
 *
 *   - In Operation.TwinArray.operation_append_Xxx(), it is used for tracking a tensor's final operation which should be responsible
 *       for destroying the tensor.
 *
 *   - In operation's .apply(), it is used for transferring tensor to the next sub operation.
 *
 *
 *
 * @member {Operation.Base} finalOperation
 *   The operation uses this tensor at final. It should be responsible for destroying this tensor. If null, this tensor is
 * not used by any operation.
 *
 * @member {tf.tensor} realTensor
 *   The real tensor represented by this placeholder. It is filled dynamically in an operation's apply() method.
 *
 * @member {ActivationEscaping.ScaleBoundsArray} scaleBoundsArray
 *   The element value bounds (per channel) of the tensor. Usually, it is from the output of the previous operation's value bounds
 * set. It will be kept (not cloned) directly. So caller should use them carefully.
 *
 */
class Base extends Recyclable.Root {

  /**
   * Used as default TensorPlaceholder.Base provider for conforming to Recyclable interface.
   */
  static Pool = new Pool.Root( "TensorPlaceholder.Base.Pool", Base, Base.setAsConstructor );

  /**
   *
   */
  constructor() {
    super();
    Base.setAsConstructor_self.call( this );
  }

  /** @override */
  static setAsConstructor() {
    super.setAsConstructor();
    Base.setAsConstructor_self.call( this );
    return this;
  }

  /** @override */
  static setAsConstructor_self() {
    this.finalOperation = null;
    this.realTensor = null;
    this.set_height_width_channelCount_scaleBoundsArray_byTensorPlaceholder( null );
  }

  /**
   * Release the .scaleBoundsArray
   *
   * Usually, this method is not responsible for releasing .finalOperation and .realTensor. They should be handled
   * by the caller of apply().
   *
   * @override
   */
  disposeResources() {
    if ( this.scaleBoundsArray ) {
      this.scaleBoundsArray.disposeResources_and_recycleToPool();
      this.scaleBoundsArray = null;
    }

    this.finalOperation = null;
    this.realTensor = null;
    this.set_height_width_channelCount_scaleBoundsArray_byTensorPlaceholder( null );

    super.disposeResources();
  }

  /**
   *
   * @param {ActivationEscaping.ScaleBoundsArray} scaleBoundsArray  The tensor placeholder's ScaleBoundsArray.
   */
  set_height_width_channelCount_scaleBoundsArray(
    height, width, channelCount, channelCount_lowerHalf, channelCount_higherHalf, scaleBoundsArray ) {
    this.height = height;
    this.width = width;
    this.channelCount = channelCount;
    this.channelCount_lowerHalf = channelCount_lowerHalf;
    this.channelCount_higherHalf = channelCount_higherHalf;
    this.scaleBoundsArray = scaleBoundsArray;
  }

  /**
   * Note: The .finalOperation and .realTensor are not modified by this method.
   *
   * @param {TensorPlaceholder} aTensorPlaceholder
   *   The tensor placeholder's height, width, channelCount, scaleBoundsArray will be used directly (i.e. not cloned) by this
   * tensor placeholder. If null, these properties will be set to undefined.
   */
  set_height_width_channelCount_scaleBoundsArray_byTensorPlaceholder( aTensorPlaceholder ) {
    if ( aTensorPlaceholder ) {
      this.set_height_width_channelCount_scaleBoundsArray(
        aTensorPlaceholder.height, aTensorPlaceholder.width,
        aTensorPlaceholder.channelCount, aTensorPlaceholder.channelCount_lowerHalf, aTensorPlaceholder.channelCount_higherHalf,
        aTensorPlaceholder.scaleBoundsArray );
    } else {
      this.set_height_width_channelCount_scaleBoundsArray(
        undefined, undefined,
        undefined, undefined, undefined,
        undefined );
    }
  }

  /**
   *
   * @param {TensorPlaceholder} aTensorPlaceholder  The tensor placeholder to be comapred.
   *
   * @return {boolean}
   *   Return true, if this tensor placeholder's height, width, channelCount are the same as aTensorPlaceholder. Note: the
   * .channelCount_lowerHalf and .channelCount_higherHalf are not compared.
   */
  is_height_width_channelCount_same_byTensorPlaceholder( aTensorPlaceholder ) {
    if (   ( this.height != aTensorPlaceholder.height )
        || ( this.width != aTensorPlaceholder.width )
        || ( this.channelCount != aTensorPlaceholder.channelCount )

        //|| ( this.channelCount_lowerHalf != aTensorPlaceholder.channelCount_lowerHalf )
        //|| ( this.channelCount_higherHalf != aTensorPlaceholder.channelCount_higherHalf )
       )
      return false;

    return true;
  }

}

<commit_msg>Update TensorPlaceholder.js<commit_after>export { Base };

import * as Pool from "../util/Pool.js";
import * as Recyclable from "../util/Recyclable.js";
import * as ActivationEscaping from "./ActivationEscaping.js";

/**
 * A placeholder for tensor.
 *
 *   - In Operation.TwinArray.operation_append_Xxx(), it is used for tracking a tensor's final operation which should be responsible
 *       for destroying the tensor.
 *
 *   - In operation's .apply(), it is used for transferring tensor to the next sub operation.
 *
 *
 *
 * @member {Operation.Base} finalOperation
 *   The operation uses this tensor at final. It should be responsible for destroying this tensor. If null, this tensor is
 * not used by any operation.
 *
 * @member {tf.tensor} realTensor
 *   The real tensor represented by this placeholder. It is filled dynamically in an operation's apply() method.
 *
 * @member {ActivationEscaping.ScaleBoundsArray} scaleBoundsArray
 *   The element value bounds (per channel) of the tensor. Usually, it is from the output of the previous operation's value bounds
 * set. It will be kept (not cloned) directly. So caller should use them carefully.
 *
 */
class Base extends Recyclable.Root {

  /**
   * Used as default TensorPlaceholder.Base provider for conforming to Recyclable interface.
   */
  static Pool = new Pool.Root( "TensorPlaceholder.Base.Pool", Base, Base.setAsConstructor );

  /**
   *
   */
  constructor() {
    super();
    Base.setAsConstructor_self.call( this );
  }

  /** @override */
  static setAsConstructor() {
    super.setAsConstructor();
    Base.setAsConstructor_self.call( this );
    return this;
  }

  /** @override */
  static setAsConstructor_self() {
    this.finalOperation = null;
    this.realTensor = null;
    this.set_height_width_channelCount_scaleBoundsArray_byTensorPlaceholder( null );
  }

  /**
   * Release the .scaleBoundsArray
   *
   * Usually, this method is not responsible for releasing .finalOperation and .realTensor. They should be handled
   * by the caller of apply().
   *
   * @override
   */
  disposeResources() {
    this.ScaleBoundsArray_dispose();

    this.finalOperation = null;
    this.realTensor = null;
    this.set_height_width_channelCount_scaleBoundsArray_byTensorPlaceholder( null );

    super.disposeResources();
  }

  /**
   * Release (and recycle) .scaleBoundsArray (if exists).
   */
  ScaleBoundsArray_dispose() {
    if ( this.scaleBoundsArray ) {
      this.scaleBoundsArray.disposeResources_and_recycleToPool();
      this.scaleBoundsArray = null;
    }
  }

  /**
   *
   * @param {ActivationEscaping.ScaleBoundsArray} scaleBoundsArray  The tensor placeholder's ScaleBoundsArray.
   */
  set_height_width_channelCount_scaleBoundsArray(
    height, width, channelCount, channelCount_lowerHalf, channelCount_higherHalf, scaleBoundsArray ) {
    this.height = height;
    this.width = width;
    this.channelCount = channelCount;
    this.channelCount_lowerHalf = channelCount_lowerHalf;
    this.channelCount_higherHalf = channelCount_higherHalf;
    this.scaleBoundsArray = scaleBoundsArray;
  }

  /**
   * Note: The .finalOperation and .realTensor are not modified by this method.
   *
   * @param {TensorPlaceholder} aTensorPlaceholder
   *   The tensor placeholder's height, width, channelCount, scaleBoundsArray will be used directly (i.e. not cloned) by this
   * tensor placeholder. If null, these properties will be set to undefined.
   */
  set_height_width_channelCount_scaleBoundsArray_byTensorPlaceholder( aTensorPlaceholder ) {
    if ( aTensorPlaceholder ) {
      this.set_height_width_channelCount_scaleBoundsArray(
        aTensorPlaceholder.height, aTensorPlaceholder.width,
        aTensorPlaceholder.channelCount, aTensorPlaceholder.channelCount_lowerHalf, aTensorPlaceholder.channelCount_higherHalf,
        aTensorPlaceholder.scaleBoundsArray );
    } else {
      this.set_height_width_channelCount_scaleBoundsArray(
        undefined, undefined,
        undefined, undefined, undefined,
        undefined );
    }
  }

  /**
   *
   * @param {TensorPlaceholder} aTensorPlaceholder  The tensor placeholder to be comapred.
   *
   * @return {boolean}
   *   Return true, if this tensor placeholder's height, width, channelCount are the same as aTensorPlaceholder. Note: the
   * .channelCount_lowerHalf and .channelCount_higherHalf are not compared.
   */
  is_height_width_channelCount_same_byTensorPlaceholder( aTensorPlaceholder ) {
    if (   ( this.height != aTensorPlaceholder.height )
        || ( this.width != aTensorPlaceholder.width )
        || ( this.channelCount != aTensorPlaceholder.channelCount )

        //|| ( this.channelCount_lowerHalf != aTensorPlaceholder.channelCount_lowerHalf )
        //|| ( this.channelCount_higherHalf != aTensorPlaceholder.channelCount_higherHalf )
       )
      return false;

    return true;
  }

}

<|endoftext|>


<commit_before>import 'babel-polyfill';
require('babel-register')();
const through = require("through2");
const child_process = require('child_process');
const Mocha = require('mocha');
const pm2 = require('pm2');

module.exports = function (gulp, config, plugins) {
  return function(done) {

    var mocha = new Mocha();
    return gulp.src(config.webpage.test)
      .pipe(through.obj(
        function(file, enc, cb) {
          mocha.addFile(file.path);
          cb(null, file);
        },
        function() {

          pm2.connect(function(err) {
            if (err) {
              console.error(err)
              process.exit(2)
            }

            pm2.start({
              name: 'jsbattle-test',
              script: config.dist + '/jsbattle.js',
              args: "start -h localhost -p 8070 -d " + config.tmp + "/jsbattle-test-data",
              wait_ready: true
            }, (err, apps) => {
              if (err) {
                console.error(err);
                done("Starting PM2 failed. " + err);
              }

              mocha.run(function(failures){
                pm2.stop('jsbattle-test', (err, apps) => {
                  if(err) {
                    console.log("cannot stop PM2 process");
                    console.log(err);
                  }
                  pm2.delete('jsbattle-test', (err, apps) => {
                    if(err) {
                      console.log("cannot delete PM2 process");
                      console.log(err);
                    }
                    pm2.disconnect();
                    if(failures) {
                      done("Tests failed");
                    } else {
                      done();
                    }
                    process.exit();
                  });
                });
              });
            })
          })
        }
      ))
      .on('error', function(){
        process.emit('exit');
        process.exit();
      })
  }
};
<commit_msg>debuging travisci<commit_after>import 'babel-polyfill';
require('babel-register')();
const through = require("through2");
const child_process = require('child_process');
const Mocha = require('mocha');
const pm2 = require('pm2');

module.exports = function (gulp, config, plugins) {
  return function(done) {

    var mocha = new Mocha();
    return gulp.src(config.webpage.test)
      .pipe(through.obj(
        function(file, enc, cb) {
          mocha.addFile(file.path);
          cb(null, file);
        },
        function() {

          pm2.connect(function(err) {
            if (err) {
              console.error(err)
              process.exit(2)
            }

            pm2.start({
              name: 'jsbattle-test',
              script: config.dist + '/jsbattle.js',
              args: "start -h localhost -p 8070 -d " + config.tmp + "/jsbattle-test-data",
              wait_ready: true
            }, (err, apps) => {
              if (err) {
                console.error(err);
                done("Starting PM2 failed. " + err);
              }

              mocha.run(function(failures){
                pm2.stop('jsbattle-test', (err, apps) => {
                  if(err) {
                    console.log("cannot stop PM2 process");
                    console.log(err);
                  }
                  pm2.delete('jsbattle-test', (err, apps) => {
                    if(err) {
                      console.log("cannot delete PM2 process");
                      console.log(err);
                    }
                    pm2.disconnect();
                    if(failures) {
                      done("Tests failed");
                    } else {
                      done();
                    }
                  });
                });
              });
            })
          })
        }
      ))
      .on('error', function(){
        process.emit('exit');
      })
  }
};
<|endoftext|>


<commit_before>/*! PageResize for DataTables v1.0.0
 * 2014 SpryMedia Ltd - datatables.net/license
 */

/**
 * @summary     PageResize
 * @description Automatically alter the DataTables page length to fit the table
     into a container
 * @version     1.0.0
 * @file        dataTables.pageResize.js
 * @author      SpryMedia Ltd (www.sprymedia.co.uk)
 * @contact     www.sprymedia.co.uk/contact
 * @copyright   Copyright 2015 SpryMedia Ltd.
 *
 * License      MIT - http://datatables.net/license/mit
 *
 * This feature plug-in for DataTables will automatically change the DataTables
 * page length in order to fit inside its container. This can be particularly
 * useful for control panels and other interfaces which resize dynamically with
 * the user's browser window instead of scrolling.
 *
 * Page resizing in DataTables can be enabled by using any one of the following
 * options:
 *
 * * Adding the class `pageResize` to the HTML table
 * * Setting the `pageResize` parameter in the DataTables initialisation to
 *   be true - i.e. `pageResize: true`
 * * Setting the `pageResize` parameter to be true in the DataTables
 *   defaults (thus causing all tables to have this feature) - i.e.
 *   `$.fn.dataTable.defaults.pageResize = true`.
 * * Creating a new instance: `new $.fn.dataTable.PageResize( table );` where
 *   `table` is a DataTable's API instance.
 *
 * For more detailed information please see:
 *     http://datatables.net/blog/
 */

(function($){

var PageResize = function ( dt )
{
	var table = dt.table();

	this.s = {
		dt:        dt,
		host:      $(table.container()).parent(),
		header:    $(table.header()),
		footer:    $(table.footer()),
		body:      $(table.body()),
		container: $(table.container()),
		table:     $(table.node())
	};

	var host = this.s.host;
	if ( host.css('position') === 'static' ) {
		host.css( 'position', 'relative' );
	}

	this._attach();
	this._size();
};

PageResize.prototype = {
	_size: function ()
	{
		var settings = this.s;
		var dt = settings.dt;
		var t = dt.table();
		var offsetTop = $( settings.table ).offset().top;
		var rowHeight = $( 'tr', settings.body ).eq(0).height();
		var availableHeight = settings.host.height();

		// Subtract the height of the header, footer and the elements
		// surrounding the table
		availableHeight -= settings.header.height();
		availableHeight -= settings.footer.height();
		availableHeight -= offsetTop;
		availableHeight -= settings.container.height() - ( offsetTop + settings.table.height() );

		var drawRows = Math.floor( availableHeight / rowHeight );

		if ( drawRows !== dt.page.len() ) {
			dt.page.len( drawRows ).draw();
		}
	},

	_attach: function () {
		// There is no `resize` event for elements, so to trigger this effect,
		// create an empty HTML document using an <object> which will issue a
		// resize event inside itself when the document resizes. Since it is
		// 100% x 100% that will occur whenever the host element is resized.
		var that = this;
		var obj = $('<object/>')
			.css( {
				position: 'absolute',
				top: 0,
				left: 0,
				height: '100%',
				width: '100%',
				zIndex: -1
			} )
			.attr( 'type', 'text/html' );

		obj[0].onload = function () {
			var body = this.contentDocument.body;
			var height = body.offsetHeight;

			this.contentDocument.defaultView.onresize = function () {
				var newHeight = body.offsetHeight;

				if ( newHeight !== height ) {
					height = newHeight;

					that._size();
				}
			}
		};

		obj
			.appendTo( this.s.host )
			.attr( 'data', 'about:blank' );
	}
};

$.fn.dataTable.PageResize = PageResize;
$.fn.DataTable.PageResize = PageResize;

// Automatic initialisation listener
$(document).on( 'init.dt', function ( e, settings ) {
	if ( e.namespace !== 'dt' ) {
		return;
	}

	var api = new $.fn.dataTable.Api( settings );

	if ( $( api.table().node() ).hasClass( 'pageResize' ) ||
		 settings.oInit.pageResize ||
		 $.fn.dataTable.defaults.pageResize )
	{
		new PageResize( api );
	}
} );

}(jQuery));

<commit_msg>Fix - feature: Correct copyright date for pageResize<commit_after>/*! PageResize for DataTables v1.0.0
 * 2015 SpryMedia Ltd - datatables.net/license
 */

/**
 * @summary     PageResize
 * @description Automatically alter the DataTables page length to fit the table
     into a container
 * @version     1.0.0
 * @file        dataTables.pageResize.js
 * @author      SpryMedia Ltd (www.sprymedia.co.uk)
 * @contact     www.sprymedia.co.uk/contact
 * @copyright   Copyright 2015 SpryMedia Ltd.
 *
 * License      MIT - http://datatables.net/license/mit
 *
 * This feature plug-in for DataTables will automatically change the DataTables
 * page length in order to fit inside its container. This can be particularly
 * useful for control panels and other interfaces which resize dynamically with
 * the user's browser window instead of scrolling.
 *
 * Page resizing in DataTables can be enabled by using any one of the following
 * options:
 *
 * * Adding the class `pageResize` to the HTML table
 * * Setting the `pageResize` parameter in the DataTables initialisation to
 *   be true - i.e. `pageResize: true`
 * * Setting the `pageResize` parameter to be true in the DataTables
 *   defaults (thus causing all tables to have this feature) - i.e.
 *   `$.fn.dataTable.defaults.pageResize = true`.
 * * Creating a new instance: `new $.fn.dataTable.PageResize( table );` where
 *   `table` is a DataTable's API instance.
 *
 * For more detailed information please see:
 *     http://datatables.net/blog/
 */

(function($){

var PageResize = function ( dt )
{
	var table = dt.table();

	this.s = {
		dt:        dt,
		host:      $(table.container()).parent(),
		header:    $(table.header()),
		footer:    $(table.footer()),
		body:      $(table.body()),
		container: $(table.container()),
		table:     $(table.node())
	};

	var host = this.s.host;
	if ( host.css('position') === 'static' ) {
		host.css( 'position', 'relative' );
	}

	this._attach();
	this._size();
};

PageResize.prototype = {
	_size: function ()
	{
		var settings = this.s;
		var dt = settings.dt;
		var t = dt.table();
		var offsetTop = $( settings.table ).offset().top;
		var rowHeight = $( 'tr', settings.body ).eq(0).height();
		var availableHeight = settings.host.height();

		// Subtract the height of the header, footer and the elements
		// surrounding the table
		availableHeight -= settings.header.height();
		availableHeight -= settings.footer.height();
		availableHeight -= offsetTop;
		availableHeight -= settings.container.height() - ( offsetTop + settings.table.height() );

		var drawRows = Math.floor( availableHeight / rowHeight );

		if ( drawRows !== dt.page.len() ) {
			dt.page.len( drawRows ).draw();
		}
	},

	_attach: function () {
		// There is no `resize` event for elements, so to trigger this effect,
		// create an empty HTML document using an <object> which will issue a
		// resize event inside itself when the document resizes. Since it is
		// 100% x 100% that will occur whenever the host element is resized.
		var that = this;
		var obj = $('<object/>')
			.css( {
				position: 'absolute',
				top: 0,
				left: 0,
				height: '100%',
				width: '100%',
				zIndex: -1
			} )
			.attr( 'type', 'text/html' );

		obj[0].onload = function () {
			var body = this.contentDocument.body;
			var height = body.offsetHeight;

			this.contentDocument.defaultView.onresize = function () {
				var newHeight = body.offsetHeight;

				if ( newHeight !== height ) {
					height = newHeight;

					that._size();
				}
			}
		};

		obj
			.appendTo( this.s.host )
			.attr( 'data', 'about:blank' );
	}
};

$.fn.dataTable.PageResize = PageResize;
$.fn.DataTable.PageResize = PageResize;

// Automatic initialisation listener
$(document).on( 'init.dt', function ( e, settings ) {
	if ( e.namespace !== 'dt' ) {
		return;
	}

	var api = new $.fn.dataTable.Api( settings );

	if ( $( api.table().node() ).hasClass( 'pageResize' ) ||
		 settings.oInit.pageResize ||
		 $.fn.dataTable.defaults.pageResize )
	{
		new PageResize( api );
	}
} );

}(jQuery));

<|endoftext|>


<commit_before>const Core = require('./core');

class MinecraftBedrock extends Core {
    constructor() {
        super();
        this.byteorder = 'be';
    }

    async run(state) {
        const bufs = [
            Buffer.from([0x01]), // Message ID, ID_UNCONNECTED_PING
            Buffer.from('0000000000000000', 'hex'), // Nonce / timestamp
            Buffer.from('00ffff00fefefefefdfdfdfd12345678', 'hex'), // Magic
            Buffer.from('0000000000000000', 'hex') // Cliend GUID
        ];

        return await this.udpSend(Buffer.concat(bufs), buffer => {
            const reader = this.reader(buffer);

            const messageId = reader.uint(1);
            if (messageId !== 0x1c) {
                throw new Error('Invalid message id');
            }

            const nonce = reader.part(8).toString('hex'); // should match the nonce we sent
            this.logger.debug('Nonce: ' + nonce);

            state.raw.guid = reader.part(8).toString('hex');

            const magic = reader.part(16).toString('hex');
            this.logger.debug('Magic value: ' + magic);

            const statusLen = reader.uint(2);
            if (reader.remaining() !== statusLen) {
                throw new Error('Invalid status length: ' + reader.remaining() + ' vs ' + statusLen);
            }

            const statusStr = reader.rest().toString('utf8');
            this.logger.debug('Raw status str: ' + statusStr);

            const split = statusStr.split(';');
            if (split.length < 12) {
                throw new Error('Missing enough chunks in status str');
            }

            let i = 0;
            state.raw.edition = split[i++];
            state.name = split[i++];
            state.raw.protocolVersion = split[i++];
            state.raw.mcVersion = split[i++];
            state.players = parseInt(split[i++]);
            state.maxplayers = parseInt(split[i++]);
            state.raw.serverId = split[i++];
            state.map = split[i++];
            state.raw.gameMode = split[i++];
            state.raw.nintendoOnly = !!parseInt(split[i++]);
            state.raw.ipv4Port = split[i++];
            state.raw.ipv6Port = split[i++];

            return true;
        });

    }

}

module.exports = MinecraftBedrock;
<commit_msg>Remove redundant guid field from minecraftbedrock<commit_after>const Core = require('./core');

class MinecraftBedrock extends Core {
    constructor() {
        super();
        this.byteorder = 'be';
    }

    async run(state) {
        const bufs = [
            Buffer.from([0x01]), // Message ID, ID_UNCONNECTED_PING
            Buffer.from('0000000000000000', 'hex'), // Nonce / timestamp
            Buffer.from('00ffff00fefefefefdfdfdfd12345678', 'hex'), // Magic
            Buffer.from('0000000000000000', 'hex') // Cliend GUID
        ];

        return await this.udpSend(Buffer.concat(bufs), buffer => {
            const reader = this.reader(buffer);

            const messageId = reader.uint(1);
            if (messageId !== 0x1c) {
                throw new Error('Invalid message id');
            }

            const nonce = reader.part(8).toString('hex'); // should match the nonce we sent
            this.logger.debug('Nonce: ' + nonce);

            // These 8 bytes are identical to the serverId string we receive in decimal below
            reader.skip(8);

            const magic = reader.part(16).toString('hex');
            this.logger.debug('Magic value: ' + magic);

            const statusLen = reader.uint(2);
            if (reader.remaining() !== statusLen) {
                throw new Error('Invalid status length: ' + reader.remaining() + ' vs ' + statusLen);
            }

            const statusStr = reader.rest().toString('utf8');
            this.logger.debug('Raw status str: ' + statusStr);

            const split = statusStr.split(';');
            if (split.length < 12) {
                throw new Error('Missing enough chunks in status str');
            }

            let i = 0;
            state.raw.edition = split[i++];
            state.name = split[i++];
            state.raw.protocolVersion = split[i++];
            state.raw.mcVersion = split[i++];
            state.players = parseInt(split[i++]);
            state.maxplayers = parseInt(split[i++]);
            state.raw.serverId = split[i++];
            state.map = split[i++];
            state.raw.gameMode = split[i++];
            state.raw.nintendoOnly = !!parseInt(split[i++]);
            state.raw.ipv4Port = split[i++];
            state.raw.ipv6Port = split[i++];

            return true;
        });

    }

}

module.exports = MinecraftBedrock;
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';

// Shapes
import * as propTypeShapes from '../../../core/prop-type-shapes';

// Import Components
import Icon from '../icon';
import SnapshotImage from '../snapshot-image';
import SnapshotGraph from '../snapshot-graph';

// Import store
import { changeMainNavigation, MAIN_NAVIGATION_ITEMS } from '../../../store/app';

// Import ui
import {
  Outer,
  Inner,
  IconMenu
} from './ui';

class SnapshotsNavigator extends Component {

  static propTypes = {
    selectedMainNavigation: PropTypes.string.isRequired,
    snapshots: PropTypes.arrayOf(propTypeShapes.snapshot).isRequired,
    place: propTypeShapes.place.isRequired,
    changeMainNavigation: PropTypes.func.isRequired
  }

  static mapStateToProps = (state) => ({
    selectedMainNavigation: state.app.mainNavigation,
    snapshots: state.snapshots.data,
    place: state.place
  })

  static mapDispatchToProps = (dispatch) => ({
    changeMainNavigation: itemName => dispatch(changeMainNavigation(itemName))
  })

  changeMainNavigation (e, itemName) {
    e.preventDefault();
    changeMainNavigation(itemName);
  }

  render () {

    let child;

    const {
      place,
      snapshots,
      selectedMainNavigation,
      changeMainNavigation
    } = this.props;

    switch (selectedMainNavigation) {
      case 'image' :
        child = <SnapshotImage snapshots={snapshots} place={place} key='image' />;
        break;

      case 'graph' :
        child = <SnapshotGraph snapshots={snapshots} place={place} key='graph' />;
        break;

      default :
        child = '404';
    }

    return (
      <Outer>
        <Inner>
          {child}
        </Inner>
        <IconMenu>
          {MAIN_NAVIGATION_ITEMS.map((itemName) => (
            <Icon
              selected={selectedMainNavigation === itemName}
              key={itemName}
              type={itemName}
              onClick={(e) => this.changeMainNavigation(e, itemName)}
            />
          ))}
        </IconMenu>
      </Outer>
    );
  }
}

export default connect(SnapshotsNavigator.mapStateToProps, SnapshotsNavigator.mapDispatchToProps)(SnapshotsNavigator);
<commit_msg>Bugfix<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';

// Shapes
import * as propTypeShapes from '../../../core/prop-type-shapes';

// Import Components
import Icon from '../icon';
import SnapshotImage from '../snapshot-image';
import SnapshotGraph from '../snapshot-graph';

// Import store
import { changeMainNavigation, MAIN_NAVIGATION_ITEMS } from '../../../store/app';

// Import ui
import {
  Outer,
  Inner,
  IconMenu
} from './ui';

class SnapshotsNavigator extends Component {

  static propTypes = {
    selectedMainNavigation: PropTypes.string.isRequired,
    snapshots: PropTypes.arrayOf(propTypeShapes.snapshot).isRequired,
    place: propTypeShapes.place.isRequired,
    changeMainNavigation: PropTypes.func.isRequired
  }

  static mapStateToProps = (state) => ({
    selectedMainNavigation: state.app.mainNavigation,
    snapshots: state.snapshots.data,
    place: state.place
  })

  static mapDispatchToProps = (dispatch) => ({
    changeMainNavigation: itemName => dispatch(changeMainNavigation(itemName))
  })

  changeMainNavigation (e, itemName) {
    e.preventDefault();
    this.props.changeMainNavigation(itemName);
  }

  render () {

    let child;

    const {
      place,
      snapshots,
      selectedMainNavigation
    } = this.props;

    switch (selectedMainNavigation) {
      case 'image' :
        child = <SnapshotImage snapshots={snapshots} place={place} key='image' />;
        break;

      case 'graph' :
        child = <SnapshotGraph snapshots={snapshots} place={place} key='graph' />;
        break;

      default :
        child = '404';
    }

    return (
      <Outer>
        <Inner>
          {child}
        </Inner>
        <IconMenu>
          {MAIN_NAVIGATION_ITEMS.map((itemName) => (
            <Icon
              selected={selectedMainNavigation === itemName}
              key={itemName}
              type={itemName}
              onClick={(e) => this.changeMainNavigation(e, itemName)}
            />
          ))}
        </IconMenu>
      </Outer>
    );
  }
}

export default connect(SnapshotsNavigator.mapStateToProps, SnapshotsNavigator.mapDispatchToProps)(SnapshotsNavigator);
<|endoftext|>


<commit_before>
  $(function(w){
    /** Tools geolocalisation global functions **/
      function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
        var R = 6371; // Radius of the earth in km
        var dLat = deg2rad(lat2-lat1);  // deg2rad below
        var dLon = deg2rad(lon2-lon1);
        var a =
          Math.sin(dLat/2) * Math.sin(dLat/2) +
          Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
          Math.sin(dLon/2) * Math.sin(dLon/2)
          ;
        var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
        var d = R * c; // Distance in km
        return d;
      }

      function deg2rad(deg) {
        return deg * (Math.PI/180)
      }

      // // find the nearest Point refer to the current position

      // function nearestPosition(array){
      //   var  clat = $.cookie('currentLat'),
      //        clong = $.cookie('currentLong'),
      //        cindex = 0,
      //        distance = getDistanceFromLatLonInKm(clat , clong , array[0].lat , array[0].lon);

      //  for(var i=1; i<array.length ; i++){
      //     var cdistane = getDistanceFromLatLonInKm(clat , clong , array[i].lat , array[i].lon);
      //     if(cdistane < distance){
      //       distance = cdistane;
      //       cindex = i;
      //     }
      //  }

      // return {km : distance , index : cindex};

      // }
    /** End function  tools geolocalisation **/

    // callback function
      function stockCurrentLatAndLong(position) {

        var currentLat = position.coords.latitude ,
            currentLong = position.coords.longitude;

        // stock this on coockies

        if( $.cookie ){
          $.cookie('currentLong' , currentLong);
          $.cookie('currentLat' , currentLat);

          // send the request Ajax to get the nearest point
          $.ajax({
                      url: Routing.generate('wbb_nearest_city', { latitude : $.cookie('currentLat') , longitude : $.cookie('currentLong') }) ,
                      success: function( data )
                      {
                        if(data){
                          if(data.id)
                            $.cookie('near_id', data.id)
                          if(data.slug)
                            $.cookie('near_islug', data.slug)
                          if(data.latitude)
                            $.cookie('near_latitude', data.latitude)
                          if(data.longitude)
                            $.cookie('near_longitude' , data.longitude);
                        }
                        // init near Location
                        initNearPositions(data);
                      }
          });
        }

      }

      // init theLocation near
      function initNearPositions(data){
          // TODO : where the user is accept geolocalisation
          // And the nearest Lat lon is stocked
          var directionRoote = Routing.generate('city_homepage' , {slug : data.slug});

          var getBaseURL = function(){
            var bs = window.location.href,
                split = bs.split('/'),
                bbase = split[2];
            return bbase;
          }
          if(data.slug && window.homepage)
            window.location.href =  directionRoote;
      }

    // if the current navigator support geolocalisation
    // if the geolocalisation is aleady stocked

    //if(navigator.geolocation && ( ! $.cookie('currentLat') || $.cookie('currentLat') == '' ))
    navigator.geolocation.getCurrentPosition(stockCurrentLatAndLong);
  })

<commit_msg> commit the local change<commit_after>
  $(function(w){
    /** Tools geolocalisation global functions **/
      function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
        var R = 6371; // Radius of the earth in km
        var dLat = deg2rad(lat2-lat1);  // deg2rad below
        var dLon = deg2rad(lon2-lon1);
        var a =
          Math.sin(dLat/2) * Math.sin(dLat/2) +
          Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
          Math.sin(dLon/2) * Math.sin(dLon/2)
          ;
        var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
        var d = R * c; // Distance in km
        return d;
      }

      function deg2rad(deg) {
        return deg * (Math.PI/180)
      }

      // // find the nearest Point refer to the current position

      // function nearestPosition(array){
      //   var  clat = $.cookie('currentLat'),
      //        clong = $.cookie('currentLong'),
      //        cindex = 0,
      //        distance = getDistanceFromLatLonInKm(clat , clong , array[0].lat , array[0].lon);

      //  for(var i=1; i<array.length ; i++){
      //     var cdistane = getDistanceFromLatLonInKm(clat , clong , array[i].lat , array[i].lon);
      //     if(cdistane < distance){
      //       distance = cdistane;
      //       cindex = i;
      //     }
      //  }

      // return {km : distance , index : cindex};

      // }
    /** End function  tools geolocalisation **/

    // callback function
      function stockCurrentLatAndLong(position) {

        var currentLat = position.coords.latitude ,
            currentLong = position.coords.longitude;

        // stock this on coockies

        if( $.cookie ){
          $.cookie('currentLong' , currentLong);
          $.cookie('currentLat' , currentLat);

          // send the request Ajax to get the nearest point
          $.ajax({
                      url: Routing.generate('wbb_nearest_city', { latitude : $.cookie('currentLat') , longitude : $.cookie('currentLong') }) ,
                      success: function( data )
                      {
                        if(data){
                          if(data.id)
                            $.cookie('near_id', data.id)
                          if(data.slug)
                            $.cookie('near_islug', data.slug)
                          if(data.latitude)
                            $.cookie('near_latitude', data.latitude)
                          if(data.longitude)
                            $.cookie('near_longitude' , data.longitude);
                        }
                        // init near Location
                        initNearPositions(data);
                      }
          });
        }

      }

      // init theLocation near
      function initNearPositions(data){
          // TODO : where the user is accept geolocalisation
          // And the nearest Lat lon is stocked
          var directionRoote = Routing.generate('city_homepage' , {slug : data.slug});

          var getBaseURL = function(){
            var bs = window.location.href,
                split = bs.split('/'),
                bbase = split[2];
            return bbase;
          }
          if(data.slug && window.homepage)
            window.location.href =  directionRoote;
      }

    // if the current navigator support geolocalisation
    // if the geolocalisation is aleady stocked

    //if(navigator.geolocation && ( ! $.cookie('currentLat') || $.cookie('currentLat') == '' ))
    if(window.homepage)
      navigator.geolocation.getCurrentPosition(stockCurrentLatAndLong);
  })

<|endoftext|>


<commit_before>/*
Copyright 2013 OCAD University
Copyright 2013 CERTH/HIT

Licensed under the Educational Community License (ECL), Version 2.0 or the New
BSD license. You may not use this file except in compliance with one these
Licenses.

You may obtain a copy of the ECL 2.0 License and BSD License at
https://github.com/fluid-project/infusion/raw/master/Infusion-LICENSE.txt
*/

// Declare dependencies
/*global demo:true, fluid, gpii, jQuery, window*/

// JSLint options
/*jslint white: true, funcinvoke: true, undef: true, newcap: true, nomen: true, regexp: true, bitwise: true, browser: true, forin: true, maxerr: 100, indent: 4 */

// GPII store is for connecting the preference tools with the GPII server.
// The preference tools uses the cookie store by default, rather than the
// GPII store.
// To activate the GPII store in the preference tools, refer to comments in
// http://issues.gpii.net/browse/GPII-185

(function ($, fluid) {

    fluid.registerNamespace("gpii.prefs");

    var rules = {
        "http://registry\\.gpii\\.org/common/magnification": [{
            transform: {
                type: "fluid.transforms.linearScale",
                valuePath: "gpii_primarySchema_magnification",
                factor: 0.01,
                outputPath: "value"
            }
        }],
        "http://registry\\.gpii\\.org/common/fontSize": [{
            value: "gpii_primarySchema_fontSize"
        }],
        "http://registry\\.gpii\\.org/common/highContrastTheme": [{
            value: "gpii_primarySchema_contrast_theme"
        }],
        "http://registry\\.gpii\\.org/common/cursorSize": [{
            transform: {
                type: "fluid.transforms.linearScale",
                valuePath: "gpii_primarySchema_cursorSize",
                factor: 0.2,
                outputPath: "value"
            }
        }],
        "http://registry\\.gpii\\.org/common/magnifierEnabled": [{
            value: "gpii_primarySchema_magnifierEnabled"
        }],
        "http://registry\\.gpii\\.org/common/tracking": [{
            value: "gpii_primarySchema_tracking"
        }],
        "http://registry\\.gpii\\.org/common/magnifierPosition": [{
            value: "gpii_primarySchema_magnificationPosition"
        }],
        "http://registry\\.gpii\\.org/common/showCrosshairs": [{
            value: "gpii_primarySchema_showCrosshairs"
        }]
    };

    /**
     * gpiiStore Subcomponent that uses GPII server for persistence.
     * It sends request to the GPII server to save and retrieve model information
     * @param {Object} options
     */
    fluid.defaults("gpii.prefs.gpiiStore", {
        gradeNames: ["fluid.prefs.dataSource", "autoInit"],
        // instantiate the gpiiSession component
        components: {
            gpiiSession: {
                type: "gpii.prefs.gpiiSession"
            }
        },
        gpiiEntry: "http://registry.gpii.org/applications/gpii.prefs",
        invokers: {
            get: {
                funcName: "gpii.prefs.gpiiStore.get",
                args: ["{that}.options", "{gpiiSession}.options"]
            },
            set: {
                funcName: "gpii.prefs.gpiiStore.set",
                args: ["{arguments}.0", "{that}.options", "{gpiiSession}"]
            }
        }
    });

    gpii.prefs.gpiiStore.get = function (settings, sessionSettings) {
        var gpiiModel;

        if (sessionSettings.loggedUser != null) {

            var urlToPost = sessionSettings.loggedUser ? (sessionSettings.url + sessionSettings.loggedUser) : (sessionSettings.url);

            $.ajax({
                url: urlToPost,
                type: "GET",
                dataType: "json",
                async: false,
                success: function (data) {
                    gpiiModel = fluid.get(data, ["preferences", settings.gpiiEntry, 0, "value"]);
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    fluid.log("GET: Error at retrieving from GPII! Test status: " + textStatus);
                    fluid.log(errorThrown);
                }
            });
        }

        return gpiiModel;
    };

    gpii.prefs.gpiiStore.set = function (model, settings, session) {
        var transformedModel = fluid.model.transform(model, rules);

        var urlToPost = session.options.loggedUser ? (session.options.url + session.options.loggedUser) : (session.options.url);
        $.ajax({
            url: urlToPost,
            type: "POST",
            dataType: "json",
            contentType: "application/json",
            data: JSON.stringify(transformedModel),
            success: function (data) {
                if (session.options.loggedUser != data.token) {
                    // new user, login
                    session.login(data.token);
                }
                fluid.log("POST: Saved to GPII server");
            },
            error: function () {
                fluid.log("POST: Error at saving to GPII server");
            }
        });
    };

    gpii.prefs.gpiiStore.convertUIOSchemaToGPIISchema = function (model) {
        var common_model_part = "gpii_primarySchema_";
        var size_common = common_model_part.length;

        var keys_in_model = $.grep(Object.keys(model), function (el) {return el.substring(0, size_common) === common_model_part; });
        var keys_for_post = $.map(keys_in_model, function (el) {return "http://registry.gpii.org/common/" + el.substring(size_common, el.length); });
        var saved_settings = {};

        for (var i = 0; i < keys_for_post.length; i++) {
            saved_settings[keys_for_post[i]] = [{value: model[keys_in_model[i]]}];
        }

        return saved_settings;
    }

    fluid.defaults("gpii.prefs.gpiiSettingsStore", {
        gradeNames: ["fluid.globalSettingsStore", "autoInit"],
        settingsStoreType: "gpii.prefs.gpiiStore",
        distributeOptions: [{
            source: "{that}.options.settingsStoreType",
            removeSource: true,
            target: "{that > settingsStore}.type"
        }]
    });

})(jQuery, fluid);
<commit_msg>GPII-226: Transformations for balance of the model<commit_after>/*
Copyright 2013 OCAD University
Copyright 2013 CERTH/HIT

Licensed under the Educational Community License (ECL), Version 2.0 or the New
BSD license. You may not use this file except in compliance with one these
Licenses.

You may obtain a copy of the ECL 2.0 License and BSD License at
https://github.com/fluid-project/infusion/raw/master/Infusion-LICENSE.txt
*/

// Declare dependencies
/*global demo:true, fluid, gpii, jQuery, window*/

// JSLint options
/*jslint white: true, funcinvoke: true, undef: true, newcap: true, nomen: true, regexp: true, bitwise: true, browser: true, forin: true, maxerr: 100, indent: 4 */

// GPII store is for connecting the preference tools with the GPII server.
// The preference tools uses the cookie store by default, rather than the
// GPII store.
// To activate the GPII store in the preference tools, refer to comments in
// http://issues.gpii.net/browse/GPII-185

(function ($, fluid) {

    fluid.registerNamespace("gpii.prefs");

    var rules = {
        "http://registry\\.gpii\\.org/common/announceCapitals": [{
            value: "gpii_primarySchema_announceCapitals"
        }],
        "http://registry\\.gpii\\.org/common/keyEcho": [{
            value: "gpii_primarySchema_keyEcho"
        }],
        "http://registry\\.gpii\\.org/common/punctuationVerbosity": [{
            value: "gpii_primarySchema_punctuationVerbosity"
        }],
        "http://registry\\.gpii\\.org/common/screenReaderBrailleOutput": [{
            vale: "gpii_primarySchema_screenReaderBrailleOutput"
        }],
        "http://registry\\.gpii\\.org/common/auditoryOutLanguage": [{
            value: "gpii_primarySchema_screenReaderLanguage"
        }],
        "http://registry\\.gpii\\.org/common/screenReaderTTSEnabled": [{
            value: "gpii_primarySchema_speakText"
        }],
        "http://registry\\.gpii\\.org/common/speakTutorialMessages": [{
            value: "gpii_primarySchema_speakTutorialMessages"
        }],
        "http://registry\\.gpii\\.org/common/readingUnit": [{
            value: "gpii_primarySchema_textHighlighting"
        }],
        "http://registry\\.gpii\\.org/common/language": [{
            value: "gpii_primarySchema_universalLanguage"
        }],
        "http://registry\\.gpii\\.org/common/volume": [{
            transform: {
                type: "fluid.transforms.linearScale",
                valuePath: "gpii_primarySchema_universalVolume",
                factor: 0.01,
                outputPath: "value"
            }
        }],
        "http://registry\\.gpii\\.org/common/pitch": [{
            transform: {
                type: "fluid.transforms.linearScale",
                valuePath: "gpii_primarySchema_voicePitch",
                factor: 0.01,
                outputPath: "value"
            }
        }],
        "http://registry\\.gpii\\.org/common/volumeTTS": [{
            transform: {
                type: "fluid.transforms.linearScale",
                valuePath: "gpii_primarySchema_volume",
                factor: 0.01,
                outputPath: "value"
            }
        }],
        "http://registry\\.gpii\\.org/common/wordEcho": [{
            value: "gpii_primarySchema_wordEcho"
        }],
        "http://registry\\.gpii\\.org/common/speechRate": [{
            value: "gpii_primarySchema_wordsSpokenPerMinute"
        }],
        "http://registry\\.gpii\\.org/common/magnification": [{
            transform: {
                type: "fluid.transforms.linearScale",
                valuePath: "gpii_primarySchema_magnification",
                factor: 0.01,
                outputPath: "value"
            }
        }],
        "http://registry\\.gpii\\.org/common/fontSize": [{
            value: "gpii_primarySchema_fontSize"
        }],
        "http://registry\\.gpii\\.org/common/highContrastTheme": [{
            value: "gpii_primarySchema_contrast_theme"
        }],
        "http://registry\\.gpii\\.org/common/cursorSize": [{
            transform: {
                type: "fluid.transforms.linearScale",
                valuePath: "gpii_primarySchema_cursorSize",
                factor: 0.2,
                outputPath: "value"
            }
        }],
        "http://registry\\.gpii\\.org/common/magnifierEnabled": [{
            value: "gpii_primarySchema_magnifierEnabled"
        }],
        "http://registry\\.gpii\\.org/common/tracking": [{
            value: "gpii_primarySchema_tracking"
        }],
        "http://registry\\.gpii\\.org/common/magnifierPosition": [{
            value: "gpii_primarySchema_magnificationPosition"
        }],
        "http://registry\\.gpii\\.org/common/showCrosshairs": [{
            value: "gpii_primarySchema_showCrosshairs"
        }]
    };

    /**
     * gpiiStore Subcomponent that uses GPII server for persistence.
     * It sends request to the GPII server to save and retrieve model information
     * @param {Object} options
     */
    fluid.defaults("gpii.prefs.gpiiStore", {
        gradeNames: ["fluid.prefs.dataSource", "autoInit"],
        // instantiate the gpiiSession component
        components: {
            gpiiSession: {
                type: "gpii.prefs.gpiiSession"
            }
        },
        gpiiEntry: "http://registry.gpii.org/applications/gpii.prefs",
        invokers: {
            get: {
                funcName: "gpii.prefs.gpiiStore.get",
                args: ["{that}.options", "{gpiiSession}.options"]
            },
            set: {
                funcName: "gpii.prefs.gpiiStore.set",
                args: ["{arguments}.0", "{that}.options", "{gpiiSession}"]
            }
        }
    });

    gpii.prefs.gpiiStore.get = function (settings, sessionSettings) {
        var gpiiModel;

        if (sessionSettings.loggedUser != null) {

            var urlToPost = sessionSettings.loggedUser ? (sessionSettings.url + sessionSettings.loggedUser) : (sessionSettings.url);

            $.ajax({
                url: urlToPost,
                type: "GET",
                dataType: "json",
                async: false,
                success: function (data) {
                    gpiiModel = fluid.get(data, ["preferences", settings.gpiiEntry, 0, "value"]);
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    fluid.log("GET: Error at retrieving from GPII! Test status: " + textStatus);
                    fluid.log(errorThrown);
                }
            });
        }

        return gpiiModel;
    };

    gpii.prefs.gpiiStore.set = function (model, settings, session) {
        var transformedModel = fluid.model.transform(model, rules);

        var urlToPost = session.options.loggedUser ? (session.options.url + session.options.loggedUser) : (session.options.url);
        $.ajax({
            url: urlToPost,
            type: "POST",
            dataType: "json",
            contentType: "application/json",
            data: JSON.stringify(transformedModel),
            success: function (data) {
                if (session.options.loggedUser != data.token) {
                    // new user, login
                    session.login(data.token);
                }
                fluid.log("POST: Saved to GPII server");
            },
            error: function () {
                fluid.log("POST: Error at saving to GPII server");
            }
        });
    };

    gpii.prefs.gpiiStore.convertUIOSchemaToGPIISchema = function (model) {
        var common_model_part = "gpii_primarySchema_";
        var size_common = common_model_part.length;

        var keys_in_model = $.grep(Object.keys(model), function (el) {return el.substring(0, size_common) === common_model_part; });
        var keys_for_post = $.map(keys_in_model, function (el) {return "http://registry.gpii.org/common/" + el.substring(size_common, el.length); });
        var saved_settings = {};

        for (var i = 0; i < keys_for_post.length; i++) {
            saved_settings[keys_for_post[i]] = [{value: model[keys_in_model[i]]}];
        }

        return saved_settings;
    }

    fluid.defaults("gpii.prefs.gpiiSettingsStore", {
        gradeNames: ["fluid.globalSettingsStore", "autoInit"],
        settingsStoreType: "gpii.prefs.gpiiStore",
        distributeOptions: [{
            source: "{that}.options.settingsStoreType",
            removeSource: true,
            target: "{that > settingsStore}.type"
        }]
    });

})(jQuery, fluid);
<|endoftext|>


<commit_before>import React, { Component } from "react";
import PropTypes from "prop-types";
import { css, cx } from "emotion";
import { ThemeContext } from "@hig/theme-context";
import { CheckmarkSUI, CheckmarkXsUI } from "@hig/icons";
import { createCustomClassNames } from "@hig/utils";

import stylesheet from "./stylesheet";
import { AVAILABLE_ROLES } from "../constants";

export default class OptionPresenter extends Component {
  static propTypes = {
    asset: PropTypes.node,
    checkmark: PropTypes.bool,
    children: PropTypes.node,
    disabled: PropTypes.bool,
    highlighted: PropTypes.bool,
    id: PropTypes.string,
    isPressed: PropTypes.bool,
    role: PropTypes.oneOf(AVAILABLE_ROLES),
    selected: PropTypes.bool,
    shortcut: PropTypes.node,
    stylesheet: PropTypes.func,
    unselect: PropTypes.bool
  };

  render() {
    const {
      asset,
      checkmark,
      children,
      optionRef,
      disabled,
      highlighted,
      id,
      isPressed,
      role,
      selected,
      shortcut,
      stylesheet: customStylesheet,
      unselect,
      ...otherProps
    } = this.props;
    const { className } = otherProps;
    const menuOptionClassName = createCustomClassNames(
      className,
      `menu-option`
    );
    const checkmarkWrapperClassName = createCustomClassNames(
      className,
      `checkmark-wrapper`
    );
    const assetWrapperClassName = createCustomClassNames(
      className,
      `asset-wrapper`
    );
    const optionContentWrapperClassName = createCustomClassNames(
      className,
      `option-content-wrapper`
    );
    const shortcutWrapperClassName = createCustomClassNames(
      className,
      `shortcut-wrapper`
    );
    const payload = { ...otherProps };
    delete payload.getActiveOption;
    delete payload.getHighlightIndex;
    delete payload.getOptionsInfo;
    delete payload.getPreviousEvent;
    delete payload.setActiveOption;
    delete payload.setHighlightIndex;

    const ariaPayload = role === `option` ? { "aria-selected": selected } : {};

    return (
      <ThemeContext.Consumer>
        {({ resolvedRoles, metadata }) => {
          const styles = stylesheet(
            {
              disabled,
              highlighted,
              isPressed,
              role,
              selected,
              shortcut,
              stylesheet: customStylesheet,
              unselect,
            },
            resolvedRoles
          );
          const Checkmark =
            metadata.densityId === `medium-density`
              ? CheckmarkSUI
              : CheckmarkXsUI;
          return (
            <li
              // conditional payload for aria-selected
              {...ariaPayload}
              {...payload}
              className={cx([menuOptionClassName, css(styles.menuOption)])}
              disabled={disabled}
              id={id}
              ref={optionRef}
              role={role}
              selected={selected}
            >
              {checkmark && role !== `presentation` ? (
                <div
                  className={cx([
                    checkmarkWrapperClassName,
                    css(styles.checkmarkWrapper)
                  ])}
                >
                  <Checkmark />
                </div>
              ) : null}
              {asset ? (
                <div
                  className={cx([
                    assetWrapperClassName,
                    css(styles.assetWrapper)
                  ])}
                >
                  {asset}
                </div>
              ) : null}
              <div
                className={cx([
                  optionContentWrapperClassName,
                  css(styles.optionContentWrapper)
                ])}
              >
                {children}
                {shortcut ? (
                  <span
                    className={cx([
                      shortcutWrapperClassName,
                      css(styles.shortcutWrapper)
                    ])}
                  >
                    {shortcut}
                  </span>
                ) : null}
              </div>
            </li>
          );
        }}
      </ThemeContext.Consumer>
    );
  }
}
<commit_msg>Prettier fix<commit_after>import React, { Component } from "react";
import PropTypes from "prop-types";
import { css, cx } from "emotion";
import { ThemeContext } from "@hig/theme-context";
import { CheckmarkSUI, CheckmarkXsUI } from "@hig/icons";
import { createCustomClassNames } from "@hig/utils";

import stylesheet from "./stylesheet";
import { AVAILABLE_ROLES } from "../constants";

export default class OptionPresenter extends Component {
  static propTypes = {
    asset: PropTypes.node,
    checkmark: PropTypes.bool,
    children: PropTypes.node,
    disabled: PropTypes.bool,
    highlighted: PropTypes.bool,
    id: PropTypes.string,
    isPressed: PropTypes.bool,
    role: PropTypes.oneOf(AVAILABLE_ROLES),
    selected: PropTypes.bool,
    shortcut: PropTypes.node,
    stylesheet: PropTypes.func,
    unselect: PropTypes.bool
  };

  render() {
    const {
      asset,
      checkmark,
      children,
      optionRef,
      disabled,
      highlighted,
      id,
      isPressed,
      role,
      selected,
      shortcut,
      stylesheet: customStylesheet,
      unselect,
      ...otherProps
    } = this.props;
    const { className } = otherProps;
    const menuOptionClassName = createCustomClassNames(
      className,
      `menu-option`
    );
    const checkmarkWrapperClassName = createCustomClassNames(
      className,
      `checkmark-wrapper`
    );
    const assetWrapperClassName = createCustomClassNames(
      className,
      `asset-wrapper`
    );
    const optionContentWrapperClassName = createCustomClassNames(
      className,
      `option-content-wrapper`
    );
    const shortcutWrapperClassName = createCustomClassNames(
      className,
      `shortcut-wrapper`
    );
    const payload = { ...otherProps };
    delete payload.getActiveOption;
    delete payload.getHighlightIndex;
    delete payload.getOptionsInfo;
    delete payload.getPreviousEvent;
    delete payload.setActiveOption;
    delete payload.setHighlightIndex;

    const ariaPayload = role === `option` ? { "aria-selected": selected } : {};

    return (
      <ThemeContext.Consumer>
        {({ resolvedRoles, metadata }) => {
          const styles = stylesheet(
            {
              disabled,
              highlighted,
              isPressed,
              role,
              selected,
              shortcut,
              stylesheet: customStylesheet,
              unselect
            },
            resolvedRoles
          );
          const Checkmark =
            metadata.densityId === `medium-density`
              ? CheckmarkSUI
              : CheckmarkXsUI;
          return (
            <li
              // conditional payload for aria-selected
              {...ariaPayload}
              {...payload}
              className={cx([menuOptionClassName, css(styles.menuOption)])}
              disabled={disabled}
              id={id}
              ref={optionRef}
              role={role}
              selected={selected}
            >
              {checkmark && role !== `presentation` ? (
                <div
                  className={cx([
                    checkmarkWrapperClassName,
                    css(styles.checkmarkWrapper)
                  ])}
                >
                  <Checkmark />
                </div>
              ) : null}
              {asset ? (
                <div
                  className={cx([
                    assetWrapperClassName,
                    css(styles.assetWrapper)
                  ])}
                >
                  {asset}
                </div>
              ) : null}
              <div
                className={cx([
                  optionContentWrapperClassName,
                  css(styles.optionContentWrapper)
                ])}
              >
                {children}
                {shortcut ? (
                  <span
                    className={cx([
                      shortcutWrapperClassName,
                      css(styles.shortcutWrapper)
                    ])}
                  >
                    {shortcut}
                  </span>
                ) : null}
              </div>
            </li>
          );
        }}
      </ThemeContext.Consumer>
    );
  }
}
<|endoftext|>