<commit_before>'use strict';
var batchController = module.exports = {};

var mongoose = require('mongoose');
var Batch = mongoose.model('Batch');
var Greyhound = mongoose.model('Greyhound');
var greyhoundController = require('./greyhoundController');
var BatchRecord = mongoose.model('BatchRecord');
var Busboy = require('busboy');
var csv = require('csv');
var _ = require('lodash');
var helper = require('../helper');
var q = require('q');
var constants = require('../constants');

batchController.setBatch = function(req, res, next, id) {
    Batch.findById(id, function(err, model) {
        if (err) return next(err);
        if (!model) return next(new Error('Failed to load batch ' + id));
        req.model = model;
        req.previousModel = _.clone(model.toObject());
        return next();
    });
};

batchController.prepareBatchQuery = function(req, res, next) {
    req.searchQuery = {};
    var like = req.param('like');
    var name = req.param('name');
    if (like){
        req.searchQuery = {'name': {'$regex': like.toLowerCase()}};
    }
    if (name){
        req.searchQuery = {'name': name.toLowerCase()};
    }
    req.dao = Batch;
    next();
};

batchController.checkFields = function(req, res, next){
    if (req.previousModel.status == constants.batchTypes.awaitingProcessing && req.model.status == constants.batchTypes.cancelled){
        helper.pushChangeToFk(BatchRecord, 'batchRef', req.model._id, req.model.status, 'status');
        return next();
    } else {
        return res.jsonp(400, {'error':'you are only allowed edit a batch by cancelling it'});
    }
};

batchController.destroy = function(req, res) {
    //clean up references
    helper.killChildren(BatchRecord, 'batchRef', req.model._id, res);

    req.model.remove(function(err, removedModel) {
        if (err) {
            res.jsonp({'error':err.errors});
        } else {
            res.jsonp(removedModel);
        }
    });
};

batchController.createBatchFromFile = function(req, res){
    var busboy = new Busboy({ headers: req.headers });

    busboy.on('file', function(fieldname, file, filename) {
        batchController.createBatch(filename, fieldname, file, function(err, batch){
            if (err){
                file.resume();
                res.jsonp(400, {'error':err.errors});
            } else {
                csv()
                    .from.stream(file)
                    .on('record', function(row,index){
                        batchController.createBatchRecord(batch, index+1, row, function(err){
                            if (err){
                                res.jsonp(400, {'error':err});
                            }
                        });
                    })
                    .on('end', function(count){
                        res.jsonp(200, {'result':batch});
                        console.log('Finishing parsing file ' + filename + ' with lines ' + count);
                    })
                    .on('error', function(error){
                        res.jsonp(400, {'error':error});
                    });
            }
        });
    });

    req.pipe(busboy);
};

batchController.createBatch = function(name, type, recordStream, callback) {
    //generate the batch model
    var batch = new Batch({name:name, type:type, status: constants.batchTypes.awaitingProcessing});
    //then check the fields
    batch = batchController.cleanFields(batch);
    var error = batchController.hasError(batch);
    if (error){
        callback(error, batch);
    }
    //then parse the stream and generate the records

    //then save the batch and pass to call back
    batch.save(function(err, savedModel) {
        if (err) {
           callback(err, savedModel);
        } else {
           callback(null, savedModel);
        }
    });
};

batchController.createBatchRecord = function(batch, recordNumber, data, callback){
    var batchRecord = new BatchRecord({
        batchRef:batch._id,
        type:batch.type,
        recordNumber: recordNumber,
        status: constants.batchTypes.awaitingProcessing,
        rawData: data
    });
    batchRecord.save(function(err, savedModel) {
        if (err) {
            callback(err, savedModel);
        } else {
            callback(null, savedModel);
        }
    });
};

batchController.newBatchModel = function(json){
    return new Batch(json);
};

batchController.cleanFields = function(batch){
    if (batch.name){
        batch.name = batch.name.toLowerCase().trim();
    }
    if (batch.type){
        batch.type = batch.type.toLowerCase().trim();
    }
    return batch;
};

batchController.hasError = function(batch){
    var error;
    var nameValid = batch.name && batch.name.length > 0;
    var typeValid = batch.type && batch.type.length > 0;
    if (!nameValid){
        if (!error){
            error = {errors:[]};
        }
        error.message = 'invalid field';
        error.errors.push('name is required');
    }

    if (!typeValid){
        if (!error){
            error = {errors:[]};
        }
        error.message = 'invalid field';
        error.errors.push('type is required');
    }

    if (error){
        return error;
    } else {
        return null;
    }
};

//Main method for processing pending batches
//query for all pending batches and pass to process batch
batchController.processBatches = function(){
    //first query all batches that are waiting processing
    Batch.find({status: constants.batchTypes.awaitingProcessing}).exec(function(err, entities) {
        if (err) {
            console.log("error reading batch");
        } else {
            _.each(entities, function(entity){
                batchController.processBatch(entity);
            });
        }
    });
};

batchController.processSpecificBatch = function(req, res){
    batchController.processBatch(req.model);
    res.json(200, {'result':'Started batch'});
};

batchController.processBatch = function(batch){
    batchController.setToInProgress(batch)
        .then(batchController.processBatchRecords)
        .fail(function(err){
            console.log("had a batch error: " + err);
        });
};

batchController.setToInProgress = function(batch){
    batch.status = constants.batchTypes.inProgress;
    return helper.savePromise(batch);
};

batchController.processBatchRecords = function(batch){
    var query = BatchRecord.find({'batchRef': batch._id, 'status':constants.batchRecordTypes.awaitingProcessing });
    var batchRecordResultPromise = helper.findPromise(query).then(function(entities){
        var counters = {
            batch : batch,
            successCount: -1,
            failedCount : 0
        };

        var finalPromiseOfChain = _.reduce(entities, function(previousResult, currentValue) {
            return previousResult.then(function(){
                counters.successCount += 1;
                return batchController.processBatchRecord(currentValue);
            }).fail(function(){
                counters.failedCount += 1;
                return batchController.processBatchRecord(currentValue);
            });
        },
            q()
        );

        return finalPromiseOfChain.then(function(){
            return counters;
        }).fail(function(){return counters;});

    });

    //handle result
    return batchRecordResultPromise
        .then(batchController.saveBatchResult)
        .fail(batchController.saveBatchResult);
};

batchController.saveBatchResult = function(result){
    if (result.failedCount > 0){
        result.batch.status = constants.batchTypes.completedWithFailures;
    } else {
        result.batch.status = constants.batchTypes.completed;
    }

    result.batch.successCount = result.successCount;
    result.batch.failureCount = result.failedCount;

    return helper.savePromise(result.batch);
};

//find out the batch type then get the correct handler for that type
batchController.processBatchRecord = function(batchRecord){
    return batchController.setToInProgress(batchRecord)
        .then(batchController.convertBatchRecord);
};

batchController.convertBatchRecord = function(batchRecord){
    var handler = batchController.getBatchRecordHandler(batchRecord.type);
    if (handler){
        return handler.process(batchRecord.rawData)
            .then(function(result){
                batchRecord.status = constants.batchRecordTypes.success;
                batchRecord.resultRef = result._id;
                return helper.savePromise(batchRecord);
            }).fail(function(err){
                console.log('failed to create entity: ' + err);
                batchRecord.status = constants.batchRecordTypes.failed;
                return helper.savePromise(batchRecord).then(function(){
                    var deferred = q.defer();
                    deferred.reject('failed to create entity: ' + err);
                    return deferred.promise;
                });
            });
    } else {
        console.log('error processing batch record of type ' + batchRecord.type + ' cannot find handler');
        batchRecord.status = constants.batchRecordTypes.failed;
        return helper.savePromise(batchRecord);
    }
};

batchController.getBatchRecordHandler = function(batchRecordType){
    if (batchRecordType = 'csvToGreyhound'){
        return batchController.csvToGreyhoundProvider();
    }
    console.log("cannot load handler for type " + batchRecordType);
    return null;
};

batchController.handlerFactory = function(rawToObject, persistObject){
    var handler = {};
    handler.rawToObject = rawToObject;
    handler.persistObject = persistObject;
    handler.process = function(raw){
        var object = handler.rawToObject(raw);
        return handler.persistObject(object);
    };
    return handler;
};

batchController.csvToGreyhoundProvider = function(){
    return batchController.handlerFactory(
        greyhoundController.rawCsvArrayToGreyhound,
        greyhoundController.processGreyhoundImportObject
    );
};
<commit_msg>Changed the delete of batch records to happen in bulk<commit_after>'use strict';
var batchController = module.exports = {};

var mongoose = require('mongoose');
var Batch = mongoose.model('Batch');
var Greyhound = mongoose.model('Greyhound');
var greyhoundController = require('./greyhoundController');
var BatchRecord = mongoose.model('BatchRecord');
var Busboy = require('busboy');
var csv = require('csv');
var _ = require('lodash');
var helper = require('../helper');
var q = require('q');
var constants = require('../constants');

batchController.setBatch = function(req, res, next, id) {
    Batch.findById(id, function(err, model) {
        if (err) return next(err);
        if (!model) return next(new Error('Failed to load batch ' + id));
        req.model = model;
        req.previousModel = _.clone(model.toObject());
        return next();
    });
};

batchController.prepareBatchQuery = function(req, res, next) {
    req.searchQuery = {};
    var like = req.param('like');
    var name = req.param('name');
    if (like){
        req.searchQuery = {'name': {'$regex': like.toLowerCase()}};
    }
    if (name){
        req.searchQuery = {'name': name.toLowerCase()};
    }
    req.dao = Batch;
    next();
};

batchController.checkFields = function(req, res, next){
    if (req.previousModel.status == constants.batchTypes.awaitingProcessing && req.model.status == constants.batchTypes.cancelled){
        helper.pushChangeToFk(BatchRecord, 'batchRef', req.model._id, req.model.status, 'status');
        return next();
    } else {
        return res.jsonp(400, {'error':'you are only allowed edit a batch by cancelling it'});
    }
};

batchController.destroy = function(req, res) {
    //clean up batch records
    BatchRecord.remove({'batchRef': req.model._id}, function(childErr){
        if (childErr != null){
            res.jsonp({'error':childErr.errors});
        } else {
            req.model.remove(function(err, removedModel) {
                if (err) {
                    res.jsonp({'error':err.errors});
                } else {
                    res.jsonp(removedModel);
                }
            });
        }
    });
};

batchController.createBatchFromFile = function(req, res){
    var busboy = new Busboy({ headers: req.headers });

    busboy.on('file', function(fieldname, file, filename) {
        batchController.createBatch(filename, fieldname, file, function(err, batch){
            if (err){
                file.resume();
                res.jsonp(400, {'error':err.errors});
            } else {
                csv()
                    .from.stream(file)
                    .on('record', function(row,index){
                        batchController.createBatchRecord(batch, index+1, row, function(err){
                            if (err){
                                res.jsonp(400, {'error':err});
                            }
                        });
                    })
                    .on('end', function(count){
                        res.jsonp(200, {'result':batch});
                        console.log('Finishing parsing file ' + filename + ' with lines ' + count);
                    })
                    .on('error', function(error){
                        res.jsonp(400, {'error':error});
                    });
            }
        });
    });

    req.pipe(busboy);
};

batchController.createBatch = function(name, type, recordStream, callback) {
    //generate the batch model
    var batch = new Batch({name:name, type:type, status: constants.batchTypes.awaitingProcessing});
    //then check the fields
    batch = batchController.cleanFields(batch);
    var error = batchController.hasError(batch);
    if (error){
        callback(error, batch);
    }
    //then parse the stream and generate the records

    //then save the batch and pass to call back
    batch.save(function(err, savedModel) {
        if (err) {
           callback(err, savedModel);
        } else {
           callback(null, savedModel);
        }
    });
};

batchController.createBatchRecord = function(batch, recordNumber, data, callback){
    var batchRecord = new BatchRecord({
        batchRef:batch._id,
        type:batch.type,
        recordNumber: recordNumber,
        status: constants.batchTypes.awaitingProcessing,
        rawData: data
    });
    batchRecord.save(function(err, savedModel) {
        if (err) {
            callback(err, savedModel);
        } else {
            callback(null, savedModel);
        }
    });
};

batchController.newBatchModel = function(json){
    return new Batch(json);
};

batchController.cleanFields = function(batch){
    if (batch.name){
        batch.name = batch.name.toLowerCase().trim();
    }
    if (batch.type){
        batch.type = batch.type.toLowerCase().trim();
    }
    return batch;
};

batchController.hasError = function(batch){
    var error;
    var nameValid = batch.name && batch.name.length > 0;
    var typeValid = batch.type && batch.type.length > 0;
    if (!nameValid){
        if (!error){
            error = {errors:[]};
        }
        error.message = 'invalid field';
        error.errors.push('name is required');
    }

    if (!typeValid){
        if (!error){
            error = {errors:[]};
        }
        error.message = 'invalid field';
        error.errors.push('type is required');
    }

    if (error){
        return error;
    } else {
        return null;
    }
};

//Main method for processing pending batches
//query for all pending batches and pass to process batch
batchController.processBatches = function(){
    //first query all batches that are waiting processing
    Batch.find({status: constants.batchTypes.awaitingProcessing}).exec(function(err, entities) {
        if (err) {
            console.log("error reading batch");
        } else {
            _.each(entities, function(entity){
                batchController.processBatch(entity);
            });
        }
    });
};

batchController.processSpecificBatch = function(req, res){
    batchController.processBatch(req.model);
    res.json(200, {'result':'Started batch'});
};

batchController.processBatch = function(batch){
    batchController.setToInProgress(batch)
        .then(batchController.processBatchRecords)
        .fail(function(err){
            console.log("had a batch error: " + err);
        });
};

batchController.setToInProgress = function(batch){
    batch.status = constants.batchTypes.inProgress;
    return helper.savePromise(batch);
};

batchController.processBatchRecords = function(batch){
    var query = BatchRecord.find({'batchRef': batch._id, 'status':constants.batchRecordTypes.awaitingProcessing });
    var batchRecordResultPromise = helper.findPromise(query).then(function(entities){
        var counters = {
            batch : batch,
            successCount: -1,
            failedCount : 0
        };

        var finalPromiseOfChain = _.reduce(entities, function(previousResult, currentValue) {
            return previousResult.then(function(){
                counters.successCount += 1;
                return batchController.processBatchRecord(currentValue);
            }).fail(function(){
                counters.failedCount += 1;
                return batchController.processBatchRecord(currentValue);
            });
        },
            q()
        );

        return finalPromiseOfChain.then(function(){
            return counters;
        }).fail(function(){return counters;});

    });

    //handle result
    return batchRecordResultPromise
        .then(batchController.saveBatchResult)
        .fail(batchController.saveBatchResult);
};

batchController.saveBatchResult = function(result){
    if (result.failedCount > 0){
        result.batch.status = constants.batchTypes.completedWithFailures;
    } else {
        result.batch.status = constants.batchTypes.completed;
    }

    result.batch.successCount = result.successCount;
    result.batch.failureCount = result.failedCount;

    return helper.savePromise(result.batch);
};

//find out the batch type then get the correct handler for that type
batchController.processBatchRecord = function(batchRecord){
    return batchController.setToInProgress(batchRecord)
        .then(batchController.convertBatchRecord);
};

batchController.convertBatchRecord = function(batchRecord){
    var handler = batchController.getBatchRecordHandler(batchRecord.type);
    if (handler){
        return handler.process(batchRecord.rawData)
            .then(function(result){
                batchRecord.status = constants.batchRecordTypes.success;
                batchRecord.resultRef = result._id;
                return helper.savePromise(batchRecord);
            }).fail(function(err){
                console.log('failed to create entity: ' + err);
                batchRecord.status = constants.batchRecordTypes.failed;
                return helper.savePromise(batchRecord).then(function(){
                    var deferred = q.defer();
                    deferred.reject('failed to create entity: ' + err);
                    return deferred.promise;
                });
            });
    } else {
        console.log('error processing batch record of type ' + batchRecord.type + ' cannot find handler');
        batchRecord.status = constants.batchRecordTypes.failed;
        return helper.savePromise(batchRecord);
    }
};

batchController.getBatchRecordHandler = function(batchRecordType){
    if (batchRecordType = 'csvToGreyhound'){
        return batchController.csvToGreyhoundProvider();
    }
    console.log("cannot load handler for type " + batchRecordType);
    return null;
};

batchController.handlerFactory = function(rawToObject, persistObject){
    var handler = {};
    handler.rawToObject = rawToObject;
    handler.persistObject = persistObject;
    handler.process = function(raw){
        var object = handler.rawToObject(raw);
        return handler.persistObject(object);
    };
    return handler;
};

batchController.csvToGreyhoundProvider = function(){
    return batchController.handlerFactory(
        greyhoundController.rawCsvArrayToGreyhound,
        greyhoundController.processGreyhoundImportObject
    );
};
<|endoftext|>


<commit_before>var args = arguments[0] || {};

/*
	This controller is used to display the mosaic of every
	characters available in this game and to register which character
	the players chose
*/

// args.player = current player = Player1 or Player2
$.playerChoosing.setText(args.player + " choose your character");

// Calling a controller that creates an ImageView for each character available
// Setting their position to calcul the margins
var i = 0;
_.each(Alloy.Globals.characters, function(character) {
	var image = Alloy.createController("characterPictureTemplate", {
		characterPicture: character.picture,
		position: i,
		character: character
	}).getView();

	$.characters.add(image);
	i++;
});

// Saving players' choices
// Display either mosaic again for player2 to choose
// or player1's turn to start the game
$.characters.addEventListener('click', function(e) {
	if (Alloy.Globals.players.player1 === "") {
		Alloy.Globals.players.player1 = e.source.character;
    	Alloy.createController('chooseCharacter', {
    		player: "Player2"
    	}).getView().open();
	} else if (Alloy.Globals.players.player2 === "") {
		Alloy.Globals.players.player2 = e.source.character;
		Alloy.createController('turn', {
			player: "Player1",
		}).getView().open();
	} else {
		console.log('What are u doing here ?');
	}
});<commit_msg>Removed console.log added activity finish in else case<commit_after>var args = arguments[0] || {};

/*
	This controller is used to display the mosaic of every
	characters available in this game and to register which character
	the players chose
*/

// args.player = current player = Player1 or Player2
$.playerChoosing.setText(args.player + " choose your character");

// Calling a controller that creates an ImageView for each character available
// Setting their position to calcul the margins
var i = 0;
_.each(Alloy.Globals.characters, function(character) {
	var image = Alloy.createController("characterPictureTemplate", {
		characterPicture: character.picture,
		position: i,
		character: character
	}).getView();

	$.characters.add(image);
	i++;
});

// Saving players' choices
// Display either mosaic again for player2 to choose
// or player1's turn to start the game
$.characters.addEventListener('click', function(e) {
	if (Alloy.Globals.players.player1 === "") {
		Alloy.Globals.players.player1 = e.source.character;
    	Alloy.createController('chooseCharacter', {
    		player: "Player2"
    	}).getView().open();
	} else if (Alloy.Globals.players.player2 === "") {
		Alloy.Globals.players.player2 = e.source.character;
		Alloy.createController('turn', {
			player: "Player1",
		}).getView().open();
	} else {
		// this case should never actually happen
		// if it did, something went very wrong and it is better to
		// shut down the app
		var activity = Titanium.Android.currentActivity;
		activity.finish();
	}
});<|endoftext|>


<commit_before>'use strict';
const Queries = require('../../helpers/queries');
const D3 = require('d3');

exports.showPage = {
    auth: {
        scope: ['monitoring']
    },
    handler: function(request, reply) {
        return reply.view('monitor/outcome', null, { layout: 'monitor' });
    }
};

exports.getData = {
    auth: {
        scope: ['monitoring']
    },
    handler: function(request, reply) {
        var sequelize = request.server.plugins.sequelize.db.sequelize;

        var queryString =
            'SELECT b.treatment_label, b.treatment, a.period, a.b, a.ci_u, a.ci_l, a.outcome FROM estimates_series a left join (SELECT DISTINCT treatment, treatment_label FROM treatment) b ON a.treat_arm=b.treatment inner join (SELECT * FROM outcomes WHERE `type`="payments") c ON a.outcome=c.outcome;SELECT * FROM outcomes WHERE `type`="payments";SELECT b.treatment_label, a.val_type, a.mrc_mre, a.mre_wlg, a.wlg_wls, a.wls_fto, a.fto_sn1, a.sn1_sn2, a.sn2_prc, a.mrc_prc FROM estimates_summary a left join (SELECT DISTINCT treatment, treatment_label FROM treatment) b ON a.treat_arm=b.treatment;';

        // var queryString = Queries.estimates(step);

        // API CODE
        sequelize
            .query(queryString, {
                type: sequelize.QueryTypes.SELECT
            })
            .then(function(rows) {
                var outcomes = D3.values(rows[1]).map(function(d) {
                    return {
                        value: d.outcome,
                        label: d.label
                    };
                });

                var estimates_series = D3.nest()
                    .key(function(d) {
                        return d.outcome;
                    })
                    .key(function(d) {
                        return d.treatment;
                    })
                    .rollup(function(v) {
                        return {
                            line_label: v[0].treatment_label,
                            line_data: v.map(function(d) {
                                return {
                                    x_val: d.period,
                                    y_val: d.b,
                                    y_upper: d.ci_u,
                                    y_lower: d.ci_l
                                };
                            })
                        };
                    })
                    .object(D3.values(rows[0]))

                Object.keys(estimates_series).forEach(function (d) { // need to convert the inner objects into arrays
                	estimates_series[d] = D3.values(estimates_series[d]);
                })

                var format = D3.format('.4f');
                var table_data = D3.values(rows[2]);
                table_data.forEach(function(d, i) {
                    if (d.val_type === 'b') {
                        outcomes.forEach(function(e, j) {
                            if (table_data[i + 1][e.value] <= 0.01) {
                                d[e.value] = format(d[e.value]) + '***';
                            } else if (
                                table_data[i + 1][e.value] > 0.01 &&
                                table_data[i + 1][e.value] <= 0.05
                            ) {
                                d[e.value] = format(d[e.value]) + '**';
                            } else if (
                                table_data[i + 1][e.value] > 0.05 &&
                                table_data[i + 1][e.value] <= 0.1
                            ) {
                                d[e.value] = format(d[e.value]) + '*';
                            } else {
                                d[e.value] = format(d[e.value]);
                            }
                        });
                    } else if (d.val_type === 'p') {
                        outcomes.forEach(function(e, j) {
                            d[e.value] = '(' + format(d[e.value]) + ')';
                        });

                        d.treatment_label = '';
                    }
                });

                var estimates_summary = [
                    ['', '(1)', '(2)', '(3)', '(4)', '(5)', '(6)', '(7)', '(8)'],
                    [
                        '',
                        'mrc_mre',
                        'mre_wlg',
                        'wlg_wls',
                        'wls_fto',
                        'fto_sn1',
                        'sn1_sn2',
                        'sn2_prc',
                        'mrc_prc'
                    ]
                ].concat(
                    table_data.map(function(d) {
                        return [
                            d.treatment_label,
                            d.mrc_mre,
                            d.mre_wlg,
                            d.wlg_wls,
                            d.wls_fto,
                            d.fto_sn1,
                            d.sn1_sn2,
                            d.sn2_prc,
                            d.mrc_prc
                        ];
                    })
                );

                var data = {
                    chart_menu: outcomes,
                    chart: estimates_series,
                    table: estimates_summary
                };

                reply(data);
            });
    }
};
<commit_msg>Update table * calculations<commit_after>'use strict';
const Queries = require('../../helpers/queries');
const D3 = require('d3');

exports.showPage = {
    auth: {
        scope: ['monitoring']
    },
    handler: function(request, reply) {
        return reply.view('monitor/outcome', null, { layout: 'monitor' });
    }
};

exports.getData = {
    auth: {
        scope: ['monitoring']
    },
    handler: function(request, reply) {
        var sequelize = request.server.plugins.sequelize.db.sequelize;

        var queryString =
            'SELECT b.treatment_label, b.treatment, a.period, a.b, a.ci_u, a.ci_l, a.outcome FROM estimates_series a left join (SELECT DISTINCT treatment, treatment_label FROM treatment) b ON a.treat_arm=b.treatment inner join (SELECT * FROM outcomes WHERE `type`="payments") c ON a.outcome=c.outcome;SELECT * FROM outcomes WHERE `type`="payments";SELECT b.treatment_label, a.val_type, a.mrc_mre, a.mre_wlg, a.wlg_wls, a.wls_fto, a.fto_sn1, a.sn1_sn2, a.sn2_prc, a.mrc_prc FROM estimates_summary a left join (SELECT DISTINCT treatment, treatment_label FROM treatment) b ON a.treat_arm=b.treatment;';

        // var queryString = Queries.estimates(step);

        // API CODE
        sequelize
            .query(queryString, {
                type: sequelize.QueryTypes.SELECT
            })
            .then(function(rows) {
                var outcomes = D3.values(rows[1]).map(function(d) {
                    return {
                        value: d.outcome,
                        label: d.label
                    };
                });

                var estimates_series = D3.nest()
                    .key(function(d) {
                        return d.outcome;
                    })
                    .key(function(d) {
                        return d.treatment;
                    })
                    .rollup(function(v) {
                        return {
                            line_label: v[0].treatment_label,
                            line_data: v.map(function(d) {
                                return {
                                    x_val: d.period,
                                    y_val: d.b,
                                    y_upper: d.ci_u,
                                    y_lower: d.ci_l
                                };
                            })
                        };
                    })
                    .object(D3.values(rows[0]))

                Object.keys(estimates_series).forEach(function (d) { // need to convert the inner objects into arrays
                	estimates_series[d] = D3.values(estimates_series[d]);
                })

                var format = D3.format('.4f');
                var table_data = D3.values(rows[2]);
                table_data.forEach(function(d, i) {
                    if (d.val_type === 'b') {
                        outcomes.forEach(function(e, j) {
                            if (table_data[i + 1][e.value] < 0.01) {
                                d[e.value] = format(d[e.value]) + '***';
                            } else if (
                                table_data[i + 1][e.value] >= 0.01 &&
                                table_data[i + 1][e.value] < 0.05
                            ) {
                                d[e.value] = format(d[e.value]) + '**';
                            } else if (
                                table_data[i + 1][e.value] >= 0.05 &&
                                table_data[i + 1][e.value] < 0.1
                            ) {
                                d[e.value] = format(d[e.value]) + '*';
                            } else {
                                d[e.value] = format(d[e.value]);
                            }
                        });
                    } else if (d.val_type === 'p') {
                        outcomes.forEach(function(e, j) {
                            d[e.value] = '(' + format(d[e.value]) + ')';
                        });

                        d.treatment_label = '';
                    }
                });

                var estimates_summary = [
                    ['', '(1)', '(2)', '(3)', '(4)', '(5)', '(6)', '(7)', '(8)'],
                    [
                        '',
                        'mrc_mre',
                        'mre_wlg',
                        'wlg_wls',
                        'wls_fto',
                        'fto_sn1',
                        'sn1_sn2',
                        'sn2_prc',
                        'mrc_prc'
                    ]
                ].concat(
                    table_data.map(function(d) {
                        return [
                            d.treatment_label,
                            d.mrc_mre,
                            d.mre_wlg,
                            d.wlg_wls,
                            d.wls_fto,
                            d.fto_sn1,
                            d.sn1_sn2,
                            d.sn2_prc,
                            d.mrc_prc
                        ];
                    })
                );

                var data = {
                    chart_menu: outcomes,
                    chart: estimates_series,
                    table: estimates_summary
                };

                reply(data);
            });
    }
};
<|endoftext|>


<commit_before>'use strict'

const fs = require('fs');
const glob = require('glob');
const isBuiltInModule = require('is-builtin-module');
const syncExec = require("sync-exec");
const ora = require('ora');
const logSymbols = require('log-symbols');

/* Get installed modules
 * Read dependencies array from package.json
 */

let getInstalledModules = () => {
    let content = JSON.parse(readFile('package.json'));
    let installedModules = [];
    for (let key in content.dependencies) installedModules.push(key);
    return installedModules;
};

/* Get used modules
 * Read all .js files and grep for modules
 */

let getUsedModules = () => {
    let files = getFiles();
    let usedModules = [];
    for (let i = 0; i < files.length; i++) {
        let modulesFromFile = getModulesFromFile(files[i]);
        usedModules = usedModules.concat(modulesFromFile);
    }
    // De-duplicate
    usedModules = usedModules.filter((item, pos) => {
        return usedModules.indexOf(item) == pos
    });
    return usedModules;
};

/* Install module
 * Install given module
 */

let installModule = (module) => {
    let spinner = startSpinner('Installing ' + module, 'green');
    let success = runCommand('npm install ' + module + ' --save');
    if (success) stopSpinner(spinner, module + ' installed', 'green');
    else stopSpinner(spinner, module + ' installation failed', 'yellow');
};

/* Uninstall module */

let uninstallModule = (module) => {
    let spinner = startSpinner('Uninstalling ' + module, 'red');
    runCommand('npm uninstall ' + module + ' --save');
    stopSpinner(spinner, module + ' removed', 'red');
};

/* Command runner
 * Run a given command
 */

let runCommand = (command) => {
    let response = syncExec(command);
    return !response.status; // status = 0 for success
};

/* Show pretty outputs
 * Use ora spinners to show what's going on
 */

let startSpinner = (message, type) => {
    let spinner = ora();
    spinner.text = message;
    spinner.color = type;
    spinner.start();
    return spinner;
};

let stopSpinner = (spinner, message, type) => {
    spinner.stop();
    if (!message) return;
    let symbol;
    if (type === 'red') symbol = logSymbols.error;
    else if (type === 'yellow') symbol = logSymbols.warning;
    else symbol = logSymbols.success;
    console.log(symbol, message);
};

/* Get all js files
 * Return path of all js files
 */
let getFiles = (path) => {
    return glob.sync("**/*.js", {'ignore': ['node_modules/**/*']});
};

/* File reader
 * Return contents of given file
 */
let readFile = (path) => {
    let content = fs.readFileSync(path, 'utf8');
    return content;
};

/* Find modules from file
 * Returns array of modules from a file
 */

let pattern = /require\((.*?)\)/g;

let getModulesFromFile = (path) => {
    let content = fs.readFileSync(path, 'utf8');
    let modules = [];
    let matches = content.match(pattern);
    if (!matches) return modules;
    for(let i = 0; i < matches.length; i++) {
        let match = matches[i];
        match = match.replace('require', '');
        match = match.substring(2)
        match = match.substring(0, match.length - 2);
        modules.push(match);
    }
    return modules;
};

/* Filter registry modules */

let filterRegistryModules = (modules) => {
    modules = removeBuiltInModules(modules);
    modules = removeLocalFiles(modules);
    return modules;
};

/* Remove built in/native modules */

let removeBuiltInModules = (modules) => {
    modules = modules.filter((module) => {
        return !isBuiltInModule(module);
    });
    return modules;
};

/* Remove local files that are required */

let removeLocalFiles = (modules) => {
    modules = modules.filter((module) => {
        return (module.indexOf('./') !== 0)
    });
    return modules;
};

/* Array diff prototype */

Array.prototype.diff = function(a) {
    return this.filter(function(i) {return a.indexOf(i) < 0;});
};

let reinstall = () => {
    let spinner = startSpinner('Cleaning up', 'green');
    runCommand('npm install');
    stopSpinner(spinner);
};

/* Public helper functions */

module.exports = {
    getInstalledModules,
    getUsedModules,
    filterRegistryModules,
    installModule,
    uninstallModule,
    reinstall
};

<commit_msg>Tiny bug risk removed :beetle:<commit_after>'use strict'

const fs = require('fs');
const glob = require('glob');
const isBuiltInModule = require('is-builtin-module');
const syncExec = require("sync-exec");
const ora = require('ora');
const logSymbols = require('log-symbols');

/* Get installed modules
 * Read dependencies array from package.json
 */

let getInstalledModules = () => {
    let content = JSON.parse(readFile('package.json'));
    let installedModules = [];
    for (let key in content.dependencies) installedModules.push(key);
    return installedModules;
};

/* Get used modules
 * Read all .js files and grep for modules
 */

let getUsedModules = () => {
    let files = getFiles();
    let usedModules = [];
    for (let i = 0; i < files.length; i++) {
        let modulesFromFile = getModulesFromFile(files[i]);
        usedModules = usedModules.concat(modulesFromFile);
    }
    // De-duplicate
    usedModules = usedModules.filter((module, position) => {
        return usedModules.indexOf(module) === position;
    });
    return usedModules;
};

/* Install module
 * Install given module
 */

let installModule = (module) => {
    let spinner = startSpinner('Installing ' + module, 'green');
    let success = runCommand('npm install ' + module + ' --save');
    if (success) stopSpinner(spinner, module + ' installed', 'green');
    else stopSpinner(spinner, module + ' installation failed', 'yellow');
};

/* Uninstall module */

let uninstallModule = (module) => {
    let spinner = startSpinner('Uninstalling ' + module, 'red');
    runCommand('npm uninstall ' + module + ' --save');
    stopSpinner(spinner, module + ' removed', 'red');
};

/* Command runner
 * Run a given command
 */

let runCommand = (command) => {
    let response = syncExec(command);
    return !response.status; // status = 0 for success
};

/* Show pretty outputs
 * Use ora spinners to show what's going on
 */

let startSpinner = (message, type) => {
    let spinner = ora();
    spinner.text = message;
    spinner.color = type;
    spinner.start();
    return spinner;
};

let stopSpinner = (spinner, message, type) => {
    spinner.stop();
    if (!message) return;
    let symbol;
    if (type === 'red') symbol = logSymbols.error;
    else if (type === 'yellow') symbol = logSymbols.warning;
    else symbol = logSymbols.success;
    console.log(symbol, message);
};

/* Get all js files
 * Return path of all js files
 */
let getFiles = (path) => {
    return glob.sync("**/*.js", {'ignore': ['node_modules/**/*']});
};

/* File reader
 * Return contents of given file
 */
let readFile = (path) => {
    let content = fs.readFileSync(path, 'utf8');
    return content;
};

/* Find modules from file
 * Returns array of modules from a file
 */

let pattern = /require\((.*?)\)/g;

let getModulesFromFile = (path) => {
    let content = fs.readFileSync(path, 'utf8');
    let modules = [];
    let matches = content.match(pattern);
    if (!matches) return modules;
    for(let i = 0; i < matches.length; i++) {
        let match = matches[i];
        match = match.replace('require', '');
        match = match.substring(2)
        match = match.substring(0, match.length - 2);
        modules.push(match);
    }
    return modules;
};

/* Filter registry modules */

let filterRegistryModules = (modules) => {
    modules = removeBuiltInModules(modules);
    modules = removeLocalFiles(modules);
    return modules;
};

/* Remove built in/native modules */

let removeBuiltInModules = (modules) => {
    modules = modules.filter((module) => {
        return !isBuiltInModule(module);
    });
    return modules;
};

/* Remove local files that are required */

let removeLocalFiles = (modules) => {
    modules = modules.filter((module) => {
        return (module.indexOf('./') !== 0)
    });
    return modules;
};

/* Array diff prototype */

Array.prototype.diff = function(a) {
    return this.filter(function(i) {return a.indexOf(i) < 0;});
};

let reinstall = () => {
    let spinner = startSpinner('Cleaning up', 'green');
    runCommand('npm install');
    stopSpinner(spinner);
};

/* Public helper functions */

module.exports = {
    getInstalledModules,
    getUsedModules,
    filterRegistryModules,
    installModule,
    uninstallModule,
    reinstall
};

<|endoftext|>


<commit_before>/*jshint esversion: 6,node: true,-W041: false */
"use strict";
const request = require('request'),
	converter = require('../util/converter'),
    moment = require('moment-timezone'),
	debug = require('debug')('homebridge-weather-plus');

class WundergroundAPI {
    constructor(apiKey, location, l, d) {
        this.attribution = 'Powered by Weather Underground';
        this.reportCharacteristics = [
            'ObservationStation',
            'ObservationTime',
            'WindDirection',
            'Humidity',
            'SolarRadiation',
            'UVIndex',
            'Temperature',
            'DewPoint',
            'AirPressure',
            'WindSpeed',
            'WindSpeedMax'
        ];

        this.debug = d;
        this.log = l;

        this.location = location;
        this.apiKey = apiKey;

		//Characteristic code expect all result in 'si'.
    	this.units = 's';
    }

    update(callback) {
        this.debug("Updating weather with weather underground");
        let weather = {};

        const queryUri = "https://api.weather.com/v2/pws/observations/current?apiKey="+this.apiKey+"&stationId="+this.location+"&format=json&units="+this.units;
        request(encodeURI(queryUri), function (err, response, body) {
            if (!err) {
                // Current weather report
                const jsonObj = JSON.parse(body);
				debug( JSON.stringify(jsonObj, null, 2));

                weather.report = this.parseReport(jsonObj, callback);
                callback(null, weather);
            } else {
                this.log.error("Error retrieving weather report and forecast");
                this.log.error("Error Message: " + err);
                callback(err);
            }
        }.bind(this));
    }

    parseReport(values) {

        let report = {};

        /* EXAMPLE values

		observations
			0
				stationID	"KCASANJO898"
				obsTimeUtc	"2019-09-01T19:03:41Z"
				obsTimeLocal	"2019-09-01 12:03:41"
				neighborhood	"West San Jose - Casa de la Niles"
				softwareType	"WS-1002 V2.4.6"
				country	"US"
				solarRadiation	719.2
				lon	-122.01569366
				realtimeFrequency	null
				epoch	1567364621
				lat	37.30566025
				uv	9
				winddir	326
				humidity	49
				qcStatus	1
				metric_si	# imperial(e) | metric(m) | metric_si(s) | uk_hybrid(h)
					temp	30
					heatIndex	31
					dewpt	18
					windChill	30
					windSpeed	3
					windGust	3
					pressure	1010.16
					precipRate	0
					precipTotal	0
					elev	105
		*/

        try {
        	var observation = values.observations[0]
            var metric;
			debug("Units:" + this.units);
            if (this.units=='s') {
            	metric = observation.metric_si;
            } else if (this.units=='m') {
            	metric = observation.metric;
            } else if (this.units=='e') {
            	metric = observation.imperial;
            } else { // 'h'
            	metric = observation.uk_hybrid;
            };

			debug("Station:" + observation.stationID + " : " + observation.neighborhood);
            report.ObservationStation = observation.stationID + " : " + observation.neighborhood;
            report.ObservationTime = moment(Date.parse(observation.obsTimeUtc));

			debug("WindDirection:" + observation.winddir);
			debug("Humidity:" + observation.humidity);
        	report.WindDirection = converter.getWindDirection(isNaN(parseInt(observation.winddir)) ? 0 : parseInt(observation.winddir));
            report.Humidity 		= isNaN(parseInt(observation.humidity)) ? 0 : parseInt(observation.humidity);
            report.SolarRadiation 	= isNaN(parseInt(observation.solarRadiation)) ? 0 : parseInt(observation.solarRadiation);
            report.UVIndex 			= isNaN(parseInt(observation.uv)) ? 0 : parseInt(observation.uv);

 			debug("Temperature:" + metric.temp);
            report.Temperature 		= isNaN(parseInt(metric.temp)) ? 0 : parseInt(metric.temp);
            report.DewPoint 		= isNaN(parseInt(metric.dewpt)) ? 0 : parseInt(metric.dewpt);
            report.AirPressure 		= isNaN(parseInt(metric.pressure)) ? 0 : parseInt(metric.pressure);
 			debug("AirPressure:" + report.AirPressure);
            report.WindSpeed 		= isNaN(parseInt(metric.windSpeed)) ? 0 : parseInt(metric.windSpeed);
 			debug("WindSpeed:" + report.WindSpeed);
            report.WindSpeedMax 	= isNaN(parseInt(metric.windGust)) ? 0 : parseInt(metric.windGust);
 			debug("WindSpeedMax:" + report.WindSpeedMax);
        }
        catch(error) {
            this.log.error("Error retrieving weather report for Weather Underground");
            this.log.error("Error Message: " + error);
        }

        return report;
    }

    parseForecasts(forecastObjs, timezone) {
        let forecasts = [];
        var observation = values.observations[0]

    /* NO FORCAST DATA FROM API*/
    /*
        for (let i = 0; i < forecastObjs.length; i++) {
            const values = forecastObjs[i];
            const forecast = {};
            forecast.Condition = values.text;
            forecast.ConditionCategory = converter.getConditionCategoryOwm(parseInt(values.code));
            forecast.ForecastDay = moment(values.date, "DD MMM YYYY").tz(timezone).format("dddd");
            forecast.Temperature = values.high;
            forecast.TemperatureMin = values.low;
            forecasts[forecasts.length] = forecast;
        }
    */
        return forecasts;
    }
}

module.exports = {
    WundergroundAPI: WundergroundAPI
};
<commit_msg>Update weatherunderground.js<commit_after>/*jshint esversion: 6,node: true,-W041: false */
"use strict";
const request = require('request'),
	converter = require('../util/converter'),
    moment = require('moment-timezone'),
	debug = require('debug')('homebridge-weather-plus');

class WundergroundAPI {
    constructor(apiKey, location, l, d) {
        this.attribution = 'Powered by Weather Underground';
        this.reportCharacteristics = [
            'ObservationStation',
            'ObservationTime',
            'WindDirection',
            'Humidity',
            'SolarRadiation',
            'UVIndex',
            'Temperature',
            'DewPoint',
            'AirPressure',
            'WindSpeed',
            'WindSpeedMax',
            'RainDay'
        ];

        this.debug = d;
        this.log = l;

        this.location = location;
        this.apiKey = apiKey;

		//Characteristic code expect all result in 'si'.
    	this.units = 's';
    }

    update(callback) {
        this.debug("Updating weather with weather underground");
        let weather = {};

        const queryUri = "https://api.weather.com/v2/pws/observations/current?apiKey="+this.apiKey+"&stationId="+this.location+"&format=json&units="+this.units;
        request(encodeURI(queryUri), function (err, response, body) {
            if (!err) {
                // Current weather report
                const jsonObj = JSON.parse(body);
				debug( JSON.stringify(jsonObj, null, 2));

                weather.report = this.parseReport(jsonObj, callback);
                callback(null, weather);
            } else {
                this.log.error("Error retrieving weather report and forecast");
                this.log.error("Error Message: " + err);
                callback(err);
            }
        }.bind(this));
    }

    parseReport(values) {

        let report = {};

        /* EXAMPLE : Weather Underground payload

		   {
		     "observations": [
		       {
		         "stationID": "KCASANJO898",
		         "obsTimeUtc": "2019-09-03T01:15:59Z",
		         "obsTimeLocal": "2019-09-02 18:15:59",
		         "neighborhood": "West San Jose - Casa de la Niles",
		         "softwareType": "WS-1002 V2.4.6",
		         "country": "US",
		         "solarRadiation": 451.7,
		         "lon": -122.01569366,
		         "realtimeFrequency": null,
		         "epoch": 1567473359,
		         "lat": 37.30566025,
		         "uv": 1,
		         "winddir": 0,
		         "humidity": 67,
		         "qcStatus": 1,
		         "metric_si": { // other variants based on request: imperial(e) | metric(m) | metric_si(s) | uk_hybrid(h)
		           "temp": 23,
		           "heatIndex": 23,
		           "dewpt": 16,
		           "windChill": 23,
		           "windSpeed": 3,
		           "windGust": 3,
		           "pressure": 1010.84,
		           "precipRate": 0,
		           "precipTotal": 0,
		           "elev": 105
		         }
		       }
		     ]
		   }

		*/

        try {
        	var observation = values.observations[0]
            var metric;
			debug("Units:" + this.units);
			/*always just get metric_si...but if we ever change that.*/
            if (this.units=='s') {
            	metric = observation.metric_si;
            } else if (this.units=='m') {
            	metric = observation.metric;
            } else if (this.units=='e') {
            	metric = observation.imperial;
            } else { // 'h'
            	metric = observation.uk_hybrid;
            };

			debug("Station:" + observation.stationID + " : " + observation.neighborhood);
            report.ObservationStation = observation.stationID + " : " + observation.neighborhood;
            report.ObservationTime = moment(Date.parse(observation.obsTimeUtc));

			debug("WindDirection:" + observation.winddir);
			debug("Humidity:" + observation.humidity);
        	report.WindDirection = converter.getWindDirection(isNaN(parseInt(observation.winddir)) ? 0 : parseInt(observation.winddir));
            report.Humidity 		= isNaN(parseInt(observation.humidity)) ? 0 : parseInt(observation.humidity);
            report.SolarRadiation 	= isNaN(parseInt(observation.solarRadiation)) ? 0 : parseInt(observation.solarRadiation);
            report.UVIndex 			= isNaN(parseInt(observation.uv)) ? 0 : parseInt(observation.uv);

 			debug("Temperature:" + metric.temp);
            report.Temperature 		= isNaN(parseInt(metric.temp)) ? 0 : parseInt(metric.temp);
            report.DewPoint 		= isNaN(parseInt(metric.dewpt)) ? 0 : parseInt(metric.dewpt);
            report.AirPressure 		= isNaN(parseInt(metric.pressure)) ? 0 : parseInt(metric.pressure);
 			debug("AirPressure:" + report.AirPressure);
            report.WindSpeed 		= isNaN(parseInt(metric.windSpeed)) ? 0 : parseInt(metric.windSpeed);
 			debug("WindSpeed:" + report.WindSpeed);
            report.WindSpeedMax 	= isNaN(parseInt(metric.windGust)) ? 0 : parseInt(metric.windGust);
 			debug("WindSpeedMax:" + report.WindSpeedMax);
            report.RainDay 	= isNaN(metric.precipTotal) ? 0 : metric.precipTotal;
 			debug("RainDay:" + report.RainDay);

        }
        catch(error) {
            this.log.error("Error retrieving weather report for Weather Underground");
            this.log.error("Error Message: " + error);
        }

        return report;
    }

    parseForecasts(forecastObjs, timezone) {
        /* NO FORCAST DATA FROM API*/
        return [];
    }
}

module.exports = {
    WundergroundAPI: WundergroundAPI
};
<|endoftext|>


<commit_before>var EOL = require('os').EOL
  , fs = require('fs')
  , assert = require('assert')
  , path = require('path')
  , touch = require('touch')
  , util = require('util')
  , events = require('events')
  , utils = require('cli-util')
  , uniq = utils.uniq;

var stores = {};

function noop(){};

var HistoryStore = function(parent, options, lines) {
  options = options || {};
  lines = this.readLines(lines);
  options.flush = options.flush !== undefined ? options.flush : true;
  options.duplicates = options.duplicates !== undefined
    ? options.duplicates : false;
  options.limit = options.limit === 'number' ? options.limit : 2048;
  this.file = options.file;
  this.options = options;
  this._parent = parent;
  this._history = lines;
  this._checkpoint = this._history.length;
  this._stream = fs.createWriteStream(this.file, {flags: 'a+'});
  this._stats = null;
}

HistoryStore.prototype.history = function() {
  return this._history;
}

HistoryStore.prototype.readLines = function(lines) {
  if(!lines) return [];
  if(lines instanceof Buffer) lines = '' + lines;
  lines = lines.split('\n');
  lines = lines.filter(function(line) {
    line = line.replace(/\r$/, '');
    line = line.trim();
    return line;
  })
  if(!this.options.duplicates) {
    lines = uniq(lines);
  }
  return lines;
}

HistoryStore.prototype.import = function(content, cb) {
  var scope = this;
  // no content so read the file and import the data
  if(typeof content === 'function') {
    cb = content;
    return fs.readFile(this.file, function(err, content) {
      if(err) return cb(err, null, scope);
      scope._history = scope.readLines(content);
      scope._checkpoint = scope._history.length;
      cb(null, content, scope);
    })
  }
  // got string content, convert to an array
  if(typeof content === 'string') content = this.readLines(content);
  assert(Array.isArray(content),
    'invalid history content type, must be array or string');

  // update internal representation
  this._history = content;
  // write out if we have callback
  if(typeof cb === 'function') {
    this._checkpoint = 0;
    this._write(this.getLines(), cb);
  // assuming we just read in from the file
  }else{
    this._checkpoint = this._history.length;
  }
}

HistoryStore.prototype.isFlushed = function() {
  return this._checkpoint === this._history.length;
}

HistoryStore.prototype._write = function(flush, cb) {
  var scope = this
    , contents = typeof flush === 'string' || flush instanceof Buffer
      ? flush : null;
  if(!flush || this._checkpoint === this._history.length) return cb(null, scope);
  //console.log('write to disc %s %s', this._checkpoint, this._history.length);
  var append = !contents;
  if(append) {
    contents = this.getLines();
  }

  function write(stream, cb) {
    //console.log('writing contents...%s', contents);
    stream.write(contents, function onwrite(err) {
      if(err) return cb(err, scope);
      fs.stat(scope.file, function(err, stats) {
        if(err) return cb(err, scope);
        stats.file = scope.file;
        scope._stats = stats;
        if(!err) scope._checkpoint = scope._history.length;
        //console.log('write complete %s', cb);
        return cb(err, scope);
      });
    });
  }
  //console.log('write to disc %j', append);
  if(!append) {
    var st = fs.createWriteStream(this.file, {flags: 'w+'});
    write.call(scope, st, function(err) {
      st.end();
      if(err) return cb(err, scope);
      cb(null, scope);
    });
  }else{
    write.call(scope, this._stream, cb);
  }
}

HistoryStore.prototype.getLines = function(checkpoint, length) {
  var lines = this._history.slice(
    checkpoint || this._checkpoint, length || this._history.length);
  // add trailing newline
  if(lines[lines.length - 1]) {
    lines.push('');
  }
  return lines.join(EOL);
}

HistoryStore.prototype.read = function(options, cb) {
  if(typeof options === 'function') {
    cb = options;
    options = null;
  }
  options = options || {};
  cb = typeof cb === 'function' ? cb : noop;
  return this.import(cb);
}

HistoryStore.prototype.add = function(line, options, cb) {
  if(typeof options === 'function') {
    cb = options;
    options = null;
  }
  options = options || {};
  cb = typeof cb === 'function' ? cb : noop;
  var scope = this
    , flush = options.flush || this.options.flush;
  if(!this.options.duplicates && ~this._history.indexOf(line)) {
    return cb(null, scope);
  }
  //console.log('flush %s', flush);
  assert(typeof line === 'string', 'history entry must be a string')
  line = '' + line;
  line = line.replace(/\r?\n$/, '');
  this._history.push(line);
  this._write(flush, cb);
}

HistoryStore.prototype.pop = function(options, cb) {
  if(typeof options === 'function') {
    cb = options;
    options = null;
  }
  options = options || {};
  var scope = this
    , flush = options.flush || this.options.flush;
  var item = this._history.pop();
  var contents = this.getLines();
  var len = Buffer.byteLength(item + EOL);
  cb = typeof cb === 'function' ? cb : noop;
  if(!flush) {
    // not flushing to disc, so this acts more like peek()
    this._history.push(item);
    return cb(null, item, scope);
  }
  var length = this._stats.size - len;
  fs.ftruncate(this._stream.fd, length, function(err) {
    if(err) {
      // TODO: we need to re-initialize from the state on disc
    }else{
      scope._checkpoint = scope._history.length;
    }
    cb(err, item, scope);
  })
}

HistoryStore.prototype.clear = function(cb) {
  var scope = this;
  fs.writeFile(this.file, '', function(err) {
    if(err) return cb(err, scope);
    scope._history = [];
    scope._checkpoint = 0;
    cb(null, scope);
  })
}

HistoryStore.prototype.close = function(cb) {
  if(this._stream) {
    this._stream.once('finish', cb);
    this._stream.end();
    this._stream = null;
  }
}

var History = function(options) {
  options = options || {};
  options.create = options.create !== undefined ? options.create : true;
  this.options = options;
}

util.inherits(History, events.EventEmitter);

History.prototype.load = function(options, cb) {
  var scope = this;
  if(typeof options === 'function') {
    cb = options;
    options = null;
  }
  options = options || {};
  var file = options.file || this.options.file
    , create = options.create !== undefined
      ? options.create : this.options.create;
  assert(file, 'cannot load history with no file');
  file = path.normalize(file);
  if(stores[file] && !options.force) {
    return cb(null, stores[file]);
  }
  //console.log('loading %s', file);
  fs.readFile(file, function(err, contents) {
    if(err && err.code === 'ENOENT' && create) {
      return touch(file, function(err) {
        if(err) return cb(err, scope);
        scope.load(options, cb);
      });
    }
    if(err) return cb(err, null, scope);
    var store = new HistoryStore(scope, scope.options, '' + contents);
    stores[file] = store;
    cb(null, store, scope);
  })
}

/**
 *  Get a history store by file path or all stores.
 */
History.prototype.getStore = function(file) {
  if(file) return stores[file];
  return stores;
}

function history(options, cb) {
  if(typeof options === 'function') {
    cb = options;
    options = null;
  }
  options = options || {};
  var h = new History(options);
  if(cb) {
    h.load(options, cb);
  }
  return h;
}

history.History = History;

module.exports = history;
<commit_msg>Expose stats() method on HistoryStore.<commit_after>var EOL = require('os').EOL
  , fs = require('fs')
  , assert = require('assert')
  , path = require('path')
  , touch = require('touch')
  , util = require('util')
  , events = require('events')
  , utils = require('cli-util')
  , uniq = utils.uniq;

var stores = {};

function noop(){};

var HistoryStore = function(parent, options, lines) {
  options = options || {};
  lines = this.readLines(lines);
  options.flush = options.flush !== undefined ? options.flush : true;
  options.duplicates = options.duplicates !== undefined
    ? options.duplicates : false;
  options.limit = options.limit === 'number' ? options.limit : 2048;
  this.file = options.file;
  this.options = options;
  this._parent = parent;
  this._history = lines;
  this._checkpoint = this._history.length;
  this._stream = fs.createWriteStream(this.file, {flags: 'a+'});
  this._stats = null;
}

/**
 *  Get the underlying history array.
 */
HistoryStore.prototype.history = function() {
  return this._history;
}

/**
 *  Get the underlying file stats.
 */
HistoryStore.prototype.stats = function() {
  return this._stats;
}

/**
 *  Read lines into an array.
 *
 *  @param lines A string or buffer.
 *
 *  @return An array of lines.
 */
HistoryStore.prototype.readLines = function(lines) {
  if(!lines) return [];
  if(lines instanceof Buffer) lines = '' + lines;
  lines = lines.split('\n');
  lines = lines.filter(function(line) {
    line = line.replace(/\r$/, '');
    line = line.trim();
    return line;
  })
  if(!this.options.duplicates) {
    lines = uniq(lines);
  }
  return lines;
}

/**
 *  Import into this history store.
 *
 *  If content is a callback function all data is read from disc,
 *  otherwise content should be a string or array to import.
 *
 *  When content is specified the and this instance is flushing
 *  the file is written to disc.
 *
 *  If content is specified but no callback then the internal representation
 *  is updated but content is not flushed to disc.
 *
 *  @param content String or array to import.
 *  @param cb A callback function invoked when the history
 *  has been synced to disc or on error.
 */
HistoryStore.prototype.import = function(content, cb) {
  var scope = this;
  // no content so read the file and import the data
  if(typeof content === 'function') {
    cb = content;
    return fs.readFile(this.file, function(err, content) {
      if(err) return cb(err, null, scope);
      scope._history = scope.readLines(content);
      scope._checkpoint = scope._history.length;
      cb(null, content, scope);
    })
  }
  // got string content, convert to an array
  if(typeof content === 'string') content = this.readLines(content);
  assert(Array.isArray(content),
    'invalid history content type, must be array or string');

  // update internal representation
  this._history = content;
  this._checkpoint = 0;
  // write out if we have callback
  if(typeof cb === 'function') {
    this._write(this.getLines(), cb);
  }
}

/**
 *  Determine if the stored checkpoint is synchronized
 *  with the history array.
 *
 *  @return A boolean indicating if the internal checkpoint is at
 *  the end of the history array.
 */
HistoryStore.prototype.isFlushed = function() {
  return this._checkpoint === this._history.length;
}

/**
 *  Get a string of lines from the underlying arrat of lines.
 *
 *  Includes a trailing newline.
 *
 *  @param checkpoint The start index into the history array.
 *  @param length The end index into the history array.
 */
HistoryStore.prototype.getLines = function(checkpoint, length) {
  var lines = this._history.slice(
    checkpoint || this._checkpoint, length || this._history.length);
  // add trailing newline
  if(lines[lines.length - 1]) {
    lines.push('');
  }
  return lines.join(EOL);
}

/**
 *  Read the history file from disc and load it into
 *  this instance.
 *
 *  @param cb A callback function invoked when the history
 *  has been read from disc or on error.
 */
HistoryStore.prototype.read = function(cb) {
  cb = typeof cb === 'function' ? cb : noop;
  return this.import(cb);
}

/**
 *  Add a line to this history store.
 *
 *  @param line The line to append.
 *  @param options The append options.
 *  @param cb A callback function invoked when the history
 *  has been synced to disc or on error.
 */
HistoryStore.prototype.add = function(line, options, cb) {
  if(typeof options === 'function') {
    cb = options;
    options = null;
  }
  options = options || {};
  cb = typeof cb === 'function' ? cb : noop;
  var scope = this
    , flush = options.flush || this.options.flush;
  if(!this.options.duplicates && ~this._history.indexOf(line)) {
    return cb(null, scope);
  }
  //console.log('flush %s', flush);
  assert(typeof line === 'string', 'history entry must be a string')
  line = '' + line;
  line = line.replace(/\r?\n$/, '');
  this._history.push(line);
  this._write(flush, cb);
}

/**
 *  Remove the last history item.
 *
 *  If this store is not set to flush to disc then this method
 *  acts like peek.
 *
 *  Truncates the history file when flushing to disc.
 *
 *  @param options The options.
 *  @param cb A callback function invoked when the history
 *  has been synced to disc or on error.
 */
HistoryStore.prototype.pop = function(options, cb) {
  if(typeof options === 'function') {
    cb = options;
    options = null;
  }
  options = options || {};
  var scope = this
    , flush = options.flush || this.options.flush;
  var item = this._history.pop();
  var contents = this.getLines();
  var len = Buffer.byteLength(item + EOL);
  cb = typeof cb === 'function' ? cb : noop;
  if(!flush) {
    // not flushing to disc, so this acts more like peek()
    this._history.push(item);
    return cb(null, item, scope);
  }
  var length = this._stats.size - len;
  fs.ftruncate(this._stream.fd, length, function(err) {
    if(err) {
      // TODO: we need to re-initialize from the state on disc
    }else{
      scope._checkpoint = scope._history.length;
    }
    cb(err, item, scope);
  })
}

/**
 *  Remove all history items.
 *
 *  @param cb A callback function invoked when the history
 *  has been synced to disc or on error.
 */
HistoryStore.prototype.clear = function(cb) {
  var scope = this;
  fs.writeFile(this.file, '', function(err) {
    if(err) return cb(err, scope);
    scope._history = [];
    scope._checkpoint = 0;
    cb(null, scope);
  })
}

/**
 *  Closes the underlying stream.
 *
 *  @param cb A callback function invoked when the
 *  stream has finished or on error.
 */
HistoryStore.prototype.close = function(cb) {
  if(this._stream) {
    this._stream.once('finish', cb);
    this._stream.end();
    this._stream = null;
  }
}

/**
 *  @private
 *
 *  Write to disc and update the internal stats upon successful write.
 */
HistoryStore.prototype._write = function(flush, cb) {
  var scope = this
    , contents = typeof flush === 'string' || flush instanceof Buffer
      ? flush : null;
  if(!flush || this._checkpoint === this._history.length) return cb(null, scope);
  //console.log('write to disc %s %s', this._checkpoint, this._history.length);
  var append = !contents;
  if(append) {
    contents = this.getLines();
  }
  function write(stream, cb) {
    stream.write(contents, function onwrite(err) {
      if(err) return cb(err, scope);
      fs.stat(scope.file, function(err, stats) {
        if(err) return cb(err, scope);
        stats.file = scope.file;
        scope._stats = stats;
        scope._checkpoint = scope._history.length;
        return cb(err, scope);
      });
    });
  }
  if(!append) {
    var st = fs.createWriteStream(this.file, {flags: 'w+'});
    write.call(scope, st, function(err) {
      st.end();
      if(err) return cb(err, scope);
      cb(null, scope);
    });
  }else{
    write.call(scope, this._stream, cb);
  }
}

var History = function(options) {
  options = options || {};
  options.create = options.create !== undefined ? options.create : true;
  this.options = options;
}

util.inherits(History, events.EventEmitter);

History.prototype.load = function(options, cb) {
  var scope = this;
  if(typeof options === 'function') {
    cb = options;
    options = null;
  }
  options = options || {};
  var file = options.file || this.options.file
    , create = options.create !== undefined
      ? options.create : this.options.create;
  assert(file, 'cannot load history with no file');
  file = path.normalize(file);
  if(stores[file] && !options.force) {
    return cb(null, stores[file]);
  }
  //console.log('loading %s', file);
  fs.readFile(file, function(err, contents) {
    if(err && err.code === 'ENOENT' && create) {
      return touch(file, function(err) {
        if(err) return cb(err, scope);
        scope.load(options, cb);
      });
    }
    if(err) return cb(err, null, scope);
    var store = new HistoryStore(scope, scope.options, '' + contents);
    stores[file] = store;
    cb(null, store, scope);
  })
}

/**
 *  Get a history store by file path or all stores.
 */
History.prototype.getStore = function(file) {
  if(file) return stores[file];
  return stores;
}

function history(options, cb) {
  if(typeof options === 'function') {
    cb = options;
    options = null;
  }
  options = options || {};
  var h = new History(options);
  if(cb) {
    h.load(options, cb);
  }
  return h;
}

history.History = History;

module.exports = history;
<|endoftext|>


<commit_before>import d3 from 'd3';
import topojson from 'mbostock/topojson';

import us from './us.json!';
import usStateNames from './us-state-names.tsv!text';
import template from './template.html!text';

export default class USMap {

  static get directiveName() { return 'usMap'; }

  constructor() {
    this.restrict = 'E';
    this.replace = false;
    this.template = template;
    this.scope = {
      recallsByState: '=',
      selected: '='
    };
  }

  link(scope, element, attrs) {

    let projection = d3.geo.albersUsa()
        .scale(1000);

    let path = d3.geo.path()
        .projection(projection);

    let svgElement = element[0].querySelector('svg');
    let tooltipElement = element[0].querySelector('.tooltip');

    let width = svgElement.viewBox.baseVal.width;
    let height = svgElement.viewBox.baseVal.height;

    let svg = d3.select(svgElement);

    svg.append('rect')
        .attr('class', 'background')
        .attr('width', '100%')
        .attr('height', '100%')
        .on('click', onClick); // eslint-disable-line no-use-before-define

    let map = svg.append('g');

    let statesNamesById = d3.tsv.parse(usStateNames);
    let stateFeatures = topojson.feature(us, us.objects.states).features;

    // Omit any states that do not fit on the projection (ex. Puerto Rico and Virgin Islands)
    stateFeatures = stateFeatures.filter(f => (path.centroid(f)[0]));

    // Append "metadata" (abbreviation, name, and recalls) to each state
    stateFeatures.forEach(f => {
      let stateName = statesNamesById.filter(s => parseInt(s.id) === f.id);
      if (stateName.length) {
        var abbr = stateName[0].code;
        f.metadata = {
          abbreviation: abbr,
          name: stateName[0].name,
          recalls: (abbr in scope.recallsByState) ? scope.recallsByState[abbr].recalls : []
        };
      }
    });

    let states = map.append('g')
        .attr('class', 'states')
      .selectAll('path')
        .data(stateFeatures)
      .enter().append('path')
        .attr('class', 'state')
        .attr('d', path)
        .style('fill', d => {
          let value = d.metadata.recalls.length / 100;
          return d3.interpolate('#FFEB3B', '#F44336')(value);
        })
        .on('click', onClick) // eslint-disable-line no-use-before-define
        .on('mouseover', function(d) {
          d3.select(tooltipElement)
              .html(`${d.metadata.name} (${d.metadata.recalls.length})`)
              .transition().duration(200).style('opacity', 1);
        })
        .on('mousemove', function(d) {
          d3.select(tooltipElement)
            .style('left', `${d3.event.pageX + 30}px`)
            .style('top', `${d3.event.pageY - 30}px`);
        })
        .on('mouseout', function(d) {
            d3.select(tooltipElement)
              .transition().duration(200).style('opacity', 0);
        });

    map.append('path')
      .datum(topojson.mesh(us, us.objects.states, (a, b) => a !== b ))
      .attr('class', 'state-borders')
      .attr('d', path);

    map.append('path')
      .datum(topojson.feature(us, us.objects.land))
      .attr('class', 'country-border')
      .attr('d', path);

    map.selectAll('text')
        .data(stateFeatures)
      .enter().append('svg:text')
        .text(d => d.metadata.abbreviation)
        .attr('class', 'state-labels')
        .attr('x', d => path.centroid(d)[0])
        .attr('y', d => path.centroid(d)[1]);

    function onClick(d) {
      let x, y, k;

      if (d && d !== scope.selected) {
        var centroid = path.centroid(d);
        [x, y] = centroid;
        k = 2.5;
        scope.selected = d.metadata;
      } else {
        x = width / 2;
        y = height / 2;
        k = 1;
        scope.selected = null;
      }
      scope.$apply();

      states.classed('selected', scope.selected && (d2 => d2.metadata === scope.selected));

      map.transition()
          .duration(750)
          .attr('transform', `translate(${width / 2}, ${height / 2}) scale(${k}) translate(${-x}, ${-y})`);
    }
  }

  static directiveFactory() {
    USMap.instance = new USMap();
    return USMap.instance;
  }
}
<commit_msg>Fix centering and zooming on state selection.  Fix deselecting state by clicking on it again<commit_after>import d3 from 'd3';
import topojson from 'mbostock/topojson';

import us from './us.json!';
import usStateNames from './us-state-names.tsv!text';
import template from './template.html!text';

export default class USMap {

  static get directiveName() { return 'usMap'; }

  constructor() {
    this.restrict = 'E';
    this.replace = false;
    this.template = template;
    this.scope = {
      recallsByState: '=',
      selected: '='
    };
  }

  link(scope, element, attrs) {

    let projection = d3.geo.albersUsa()
        .scale(1000);

    let path = d3.geo.path()
        .projection(projection);

    let svgElement = element[0].querySelector('svg');
    let tooltipElement = element[0].querySelector('.tooltip');

    let width = svgElement.viewBox.baseVal.width;
    let height = svgElement.viewBox.baseVal.height;

    let svg = d3.select(svgElement);

    svg.append('rect')
        .attr('class', 'background')
        .attr('width', '100%')
        .attr('height', '100%')
        .on('click', onClick); // eslint-disable-line no-use-before-define

    let map = svg.append('g');

    let statesNamesById = d3.tsv.parse(usStateNames);
    let stateFeatures = topojson.feature(us, us.objects.states).features;

    // Omit any states that do not fit on the projection (ex. Puerto Rico and Virgin Islands)
    stateFeatures = stateFeatures.filter(f => (path.centroid(f)[0]));

    // Append "metadata" (abbreviation, name, and recalls) to each state
    stateFeatures.forEach(f => {
      let stateName = statesNamesById.filter(s => parseInt(s.id) === f.id);
      if (stateName.length) {
        var abbr = stateName[0].code;
        f.metadata = {
          abbreviation: abbr,
          name: stateName[0].name,
          recalls: (abbr in scope.recallsByState) ? scope.recallsByState[abbr].recalls : []
        };
      }
    });

    let states = map.append('g')
        .attr('class', 'states')
      .selectAll('path')
        .data(stateFeatures)
      .enter().append('path')
        .attr('class', 'state')
        .attr('d', path)
        .style('fill', d => {
          let value = d.metadata.recalls.length / 100;
          return d3.interpolate('#FFEB3B', '#F44336')(value);
        })
        .on('click', onClick) // eslint-disable-line no-use-before-define
        .on('mouseover', function(d) {
          d3.select(tooltipElement)
              .html(`${d.metadata.name} (${d.metadata.recalls.length})`)
              .transition().duration(200).style('opacity', 1);
        })
        .on('mousemove', function(d) {
          d3.select(tooltipElement)
            .style('left', `${d3.event.pageX + 30}px`)
            .style('top', `${d3.event.pageY - 30}px`);
        })
        .on('mouseout', function(d) {
            d3.select(tooltipElement)
              .transition().duration(200).style('opacity', 0);
        });

    map.append('path')
      .datum(topojson.mesh(us, us.objects.states, (a, b) => a !== b ))
      .attr('class', 'state-borders')
      .attr('d', path);

    map.append('path')
      .datum(topojson.feature(us, us.objects.land))
      .attr('class', 'country-border')
      .attr('d', path);

    map.selectAll('text')
        .data(stateFeatures)
      .enter().append('svg:text')
        .text(d => d.metadata.abbreviation)
        .attr('class', 'state-labels')
        .attr('x', d => path.centroid(d)[0])
        .attr('y', d => path.centroid(d)[1]);

    function onClick(d) {
      let translate, scale;

      if (d && d.metadata !== scope.selected) {
        let [leftTop, rightBottom] = path.bounds(d);
        let [left, top] = leftTop;
        let [right, bottom] = rightBottom;
        let dx = right - left;
        let dy = bottom - top;
        let x = (left + right) / 2;
        let y = (top + bottom) / 2;

        scale = .9 / Math.max(dx / width, dy / height);
        translate = [width / 2 - scale * x, height / 2 - scale * y];
        scope.selected = d.metadata;
      } else {
        translate = 0;
        scale = 1;
        scope.selected = null;
      }
      scope.$apply();

      states.classed('selected', scope.selected && (d2 => d2.metadata === scope.selected));

      map.transition()
        .duration(750)
        .style('stroke-width', 1.5 / scale + 'px')
        .attr('transform', `translate(${translate}) scale(${scale})`);
    }
  }

  static directiveFactory() {
    USMap.instance = new USMap();
    return USMap.instance;
  }
}
<|endoftext|>


<commit_before>"use strict";

angular.module("ehelseEditor").factory("DocumentExtractor",
    ["Document", "Status", "Topic", "TargetGroup", "Mandatory", "Action", "DocumentField", "LinkCategory", "ContactAddress", "Heading",
        function (Document, Status, Topic, TargetGroup, Mandatory, Action, DocumentField, LinkCategory, ContactAddress, Heading) {

            function getDocumentAsJSON(doc) {
                if(doc){
                    var output_dict = {};
                    output_dict["title"] = doc.title;
                    if(doc.description){
                        output_dict["description"] = doc.description;
                    }else{
                        output_dict["description"] = null;
                    }
                    if(Status.getById(doc.statusId)){
                        output_dict["status"] = Status.getById(doc.statusId).name;
                    }else{
                        output_dict["status"] = null;
                    }
                    output_dict["topic"] = Topic.getById(doc.topicId).title;
                    if(doc.internalId){
                        output_dict["internalId"] = doc.internalId;
                    }else{
                        output_dict["internalId"] = null;
                    }
                    if(doc.hisNumber){
                        output_dict["his"] = doc.hisNumber;
                    }else{
                        output_dict["his"] = null;
                    }
                    output_dict["contactAddress"] = getContactAddressRelatedToDocumentAsJSON(doc);
                    output_dict["fields"] = getDocumentFieldsRelatedToDocumentAsJSON(doc);
                    output_dict["targetGroups"] = getTargetGroupsRelatedToDocumentAsJSON(doc);
                    output_dict["linkCategories"] = getLinksRelatedToDocumentAsJSON(doc);
                    output_dict["paragraphs"] = getParagraphsRelatedToDocumentAsJSON(doc);

                    return output_dict;
                }
            }

            function getParagraphsRelatedToDocumentAsJSON(doc){
                var output_list = [];
                var headingContent = doc.headingContent;
                if(headingContent){
                    for (var i = 0; i < headingContent.length; i++) {
                        var heading = {};

                        heading["title"] = Heading.getById(headingContent[i].headingId).name;
                        if(headingContent[i].text){
                            heading["text"] = headingContent[i].text;
                        }else{
                            heading["text"] = null;
                        }

                        output_list.push(heading);
                    }
                }
                return output_list;
            }

            function getContactAddressRelatedToDocumentAsJSON(doc){
                var output = {};
                if(doc.contactAddressId){
                    output["email"] = ContactAddress.getById(doc.contactAddressId).name;
                    if(ContactAddress.getById(doc.contactAddressId).description){
                        output["description"] = ContactAddress.getById(doc.contactAddressId).description;
                    }else{
                        output["description"] = null;
                    }
                }
                return output;
            }

            function getDocumentFieldsRelatedToDocumentAsJSON(doc){
                var output_list = [];
                var fields = doc.fields;
                for (var i = 0; i < fields.length; i++) {
                    var field = {};

                    field["name"] = DocumentField.getById(fields[i].fieldId).name;
                    field["text"] = fields[i].value;

                    output_list.push(field);
                }
                return output_list;
            }

            function getTargetGroupsRelatedToDocumentAsJSON(doc) {
                var output_dict = {};
                if(doc.targetGroups){
                    var mandatoryIdList = [];
                    for (var i = 0; i < doc.targetGroups.length; i++){
                        if(!mandatoryIdList.includes(doc.targetGroups[i].targetGroupId)){
                            mandatoryIdList.push(doc.targetGroups[i].mandatoryId);
                        }
                    }
                    for (var x = 0; x < mandatoryIdList.length; x++){
                        output_dict[Mandatory.getById(mandatoryIdList[x]).name] = getTargetGroupsByMandatoryId(doc, mandatoryIdList[x]);
                    }
                }

                return output_dict;
            }

            function getTargetGroupsByMandatoryId(doc, id){
                var output_dict = {};
                var targetGroupsList = [];
                if(id == "1"){
                    if(doc.targetGroupLegalBases){
                        output_dict["targetGroupLegalBases"] = doc.targetGroupLegalBases;
                    }else{
                        output_dict["targetGroupLegalBases"] = null;
                    }

                    if(doc.decidedBy){
                        output_dict["decidedBy"] = doc.decidedBy;
                    }else{
                        output_dict["decidedBy"] = null;
                    }

                    if(doc.replacedBy){
                        output_dict["replacedBy"] = doc.replacedBy;
                    }else{
                        output_dict["replacedBy"] = null;
                    }
                }
                if(doc.mandatoryNotices){
                    for (var i = 0; i < doc.mandatoryNotices.length; i++) {
                        if(doc.mandatoryNotices[i].mandatoryId == id){
                            if(doc.mandatoryNotices[i].notice){
                                output_dict["notice"] = doc.mandatoryNotices[i].notice;
                            }else{
                                output_dict["notice"] = null;
                            }
                        }
                    }
                }
                if(doc.targetGroups){
                    for (var x = 0; x < doc.targetGroups.length; x++) {
                        if(doc.targetGroups[x].mandatoryId == id){
                            var targetGroup = {};
                            targetGroup["name"] = TargetGroup.getById(doc.targetGroups[x].targetGroupId).name;
                            if(doc.targetGroups[x].deadline){
                                targetGroup["deadline"] = doc.targetGroups[x].deadline;
                            }else{
                                targetGroup["deadline"] = null;
                            }
                            if(doc.targetGroups[x].description){
                                targetGroup["description"] = doc.targetGroups[x].description;
                            }else{
                                targetGroup["description"] = null;
                            }
                            if(doc.targetGroups[x].actionId){
                                targetGroup["action"] = Action.getById(doc.targetGroups[x].actionId).name;
                            }else{
                                targetGroup["action"] = null;
                            }
                            if(TargetGroup.getById(doc.targetGroups[x].targetGroupId).abbreviation){
                                targetGroup["abbreviation"] = TargetGroup.getById(doc.targetGroups[x].targetGroupId).abbreviation;
                            }else{
                                targetGroup["abbreviation"] = null;
                            }
                            if(TargetGroup.getById(doc.targetGroups[x].targetGroupId).parentId){
                                targetGroup["parentTargetGroup"] = TargetGroup.getById(TargetGroup.getById(doc.targetGroups[x].targetGroupId).parentId).name;
                            }else{
                                targetGroup["parentTargetGroup"] = null;
                            }
                            targetGroupsList.push(targetGroup);
                        }
                    }
                }
                output_dict["targetGroupsList"] = targetGroupsList;

                return output_dict;
            }

            function getLinksRelatedToDocumentAsJSON(doc){
                var temp_dict = {};
                if(doc.links){
                    for (var i = 0; i < doc.links.length; i++) {
                        if(!temp_dict[LinkCategory.getById(doc.links[i].linkCategoryId).name]){
                            temp_dict[LinkCategory.getById(doc.links[i].linkCategoryId).name] = [];
                        }
                        var link = {};
                        link["text"] = doc.links[i].text;
                        link["url"] = doc.links[i].url;

                        temp_dict[LinkCategory.getById(doc.links[i].linkCategoryId).name].push(link);
                    }
                }

                var output_list = [];
                if(temp_dict){
                    for(var item in temp_dict){
                        if (!temp_dict.hasOwnProperty(item)) continue;
                        var linkCat = {};
                        linkCat["name"] = item;
                        linkCat["links"] = temp_dict[item];
                        output_list.push(linkCat);
                    }
                }
                return output_list;

            }

            function getAllDocumentsAsJSON(){
                var output = {
                    allDocuments: []
                };
                var documents = Document.getAll();

                for (var i = 0; i < documents.length; i++) {
                    output["allDocuments"].push(getDocumentAsJSON(documents[i]));
                }

                return output;
            }

            return {
                getDocumentAsJSON: getDocumentAsJSON,
                getAllDocumentsAsJSON: getAllDocumentsAsJSON
            };
        }
    ]
);<commit_msg>Added document type to JSON-export file<commit_after>"use strict";

angular.module("ehelseEditor").factory("DocumentExtractor",
    ["Document", "Status", "Topic", "TargetGroup", "Mandatory", "Action", "DocumentField", "LinkCategory", "ContactAddress", "Heading", "DocumentType",
        function (Document, Status, Topic, TargetGroup, Mandatory, Action, DocumentField, LinkCategory, ContactAddress, Heading, DocumentType) {

            function getDocumentAsJSON(doc) {
                if(doc){
                    var output_dict = {};
                    output_dict["title"] = doc.title;
                    if(doc.description){
                        output_dict["description"] = doc.description;
                    }else{
                        output_dict["description"] = null;
                    }
                    if(Status.getById(doc.statusId)){
                        output_dict["status"] = Status.getById(doc.statusId).name;
                    }else{
                        output_dict["status"] = null;
                    }
                    output_dict["topic"] = Topic.getById(doc.topicId).title;
                    if(doc.internalId){
                        output_dict["internalId"] = doc.internalId;
                    }else{
                        output_dict["internalId"] = null;
                    }
                    if(doc.hisNumber){
                        output_dict["his"] = doc.hisNumber;
                    }else{
                        output_dict["his"] = null;
                    }
                    output_dict["documentType"] = DocumentType.getById(doc.documentTypeId).name;
                    output_dict["contactAddress"] = getContactAddressRelatedToDocumentAsJSON(doc);
                    output_dict["fields"] = getDocumentFieldsRelatedToDocumentAsJSON(doc);
                    output_dict["targetGroups"] = getTargetGroupsRelatedToDocumentAsJSON(doc);
                    output_dict["linkCategories"] = getLinksRelatedToDocumentAsJSON(doc);
                    output_dict["paragraphs"] = getParagraphsRelatedToDocumentAsJSON(doc);

                    return output_dict;
                }
            }

            function getParagraphsRelatedToDocumentAsJSON(doc){
                var output_list = [];
                var headingContent = doc.headingContent;
                if(headingContent){
                    for (var i = 0; i < headingContent.length; i++) {
                        var heading = {};

                        heading["title"] = Heading.getById(headingContent[i].headingId).name;
                        if(headingContent[i].text){
                            heading["text"] = headingContent[i].text;
                        }else{
                            heading["text"] = null;
                        }

                        output_list.push(heading);
                    }
                }
                return output_list;
            }

            function getContactAddressRelatedToDocumentAsJSON(doc){
                var output = {};
                if(doc.contactAddressId){
                    output["email"] = ContactAddress.getById(doc.contactAddressId).name;
                    if(ContactAddress.getById(doc.contactAddressId).description){
                        output["description"] = ContactAddress.getById(doc.contactAddressId).description;
                    }else{
                        output["description"] = null;
                    }
                }
                return output;
            }

            function getDocumentFieldsRelatedToDocumentAsJSON(doc){
                var output_list = [];
                var fields = doc.fields;
                for (var i = 0; i < fields.length; i++) {
                    var field = {};

                    field["name"] = DocumentField.getById(fields[i].fieldId).name;
                    field["text"] = fields[i].value;

                    output_list.push(field);
                }
                return output_list;
            }

            function getTargetGroupsRelatedToDocumentAsJSON(doc) {
                var output_dict = {};
                if(doc.targetGroups){
                    var mandatoryIdList = [];
                    for (var i = 0; i < doc.targetGroups.length; i++){
                        if(!mandatoryIdList.includes(doc.targetGroups[i].targetGroupId)){
                            mandatoryIdList.push(doc.targetGroups[i].mandatoryId);
                        }
                    }
                    for (var x = 0; x < mandatoryIdList.length; x++){
                        output_dict[Mandatory.getById(mandatoryIdList[x]).name] = getTargetGroupsByMandatoryId(doc, mandatoryIdList[x]);
                    }
                }

                return output_dict;
            }

            function getTargetGroupsByMandatoryId(doc, id){
                var output_dict = {};
                var targetGroupsList = [];
                if(id == "1"){
                    if(doc.targetGroupLegalBases){
                        output_dict["targetGroupLegalBases"] = doc.targetGroupLegalBases;
                    }else{
                        output_dict["targetGroupLegalBases"] = null;
                    }

                    if(doc.decidedBy){
                        output_dict["decidedBy"] = doc.decidedBy;
                    }else{
                        output_dict["decidedBy"] = null;
                    }

                    if(doc.replacedBy){
                        output_dict["replacedBy"] = doc.replacedBy;
                    }else{
                        output_dict["replacedBy"] = null;
                    }
                }
                if(doc.mandatoryNotices){
                    for (var i = 0; i < doc.mandatoryNotices.length; i++) {
                        if(doc.mandatoryNotices[i].mandatoryId == id){
                            if(doc.mandatoryNotices[i].notice){
                                output_dict["notice"] = doc.mandatoryNotices[i].notice;
                            }else{
                                output_dict["notice"] = null;
                            }
                        }
                    }
                }
                if(doc.targetGroups){
                    for (var x = 0; x < doc.targetGroups.length; x++) {
                        if(doc.targetGroups[x].mandatoryId == id){
                            var targetGroup = {};
                            targetGroup["name"] = TargetGroup.getById(doc.targetGroups[x].targetGroupId).name;
                            if(doc.targetGroups[x].deadline){
                                targetGroup["deadline"] = doc.targetGroups[x].deadline;
                            }else{
                                targetGroup["deadline"] = null;
                            }
                            if(doc.targetGroups[x].description){
                                targetGroup["description"] = doc.targetGroups[x].description;
                            }else{
                                targetGroup["description"] = null;
                            }
                            if(doc.targetGroups[x].actionId){
                                targetGroup["action"] = Action.getById(doc.targetGroups[x].actionId).name;
                            }else{
                                targetGroup["action"] = null;
                            }
                            if(TargetGroup.getById(doc.targetGroups[x].targetGroupId).abbreviation){
                                targetGroup["abbreviation"] = TargetGroup.getById(doc.targetGroups[x].targetGroupId).abbreviation;
                            }else{
                                targetGroup["abbreviation"] = null;
                            }
                            if(TargetGroup.getById(doc.targetGroups[x].targetGroupId).parentId){
                                targetGroup["parentTargetGroup"] = TargetGroup.getById(TargetGroup.getById(doc.targetGroups[x].targetGroupId).parentId).name;
                            }else{
                                targetGroup["parentTargetGroup"] = null;
                            }
                            targetGroupsList.push(targetGroup);
                        }
                    }
                }
                output_dict["targetGroupsList"] = targetGroupsList;

                return output_dict;
            }

            function getLinksRelatedToDocumentAsJSON(doc){
                var temp_dict = {};
                if(doc.links){
                    for (var i = 0; i < doc.links.length; i++) {
                        if(!temp_dict[LinkCategory.getById(doc.links[i].linkCategoryId).name]){
                            temp_dict[LinkCategory.getById(doc.links[i].linkCategoryId).name] = [];
                        }
                        var link = {};
                        link["text"] = doc.links[i].text;
                        link["url"] = doc.links[i].url;

                        temp_dict[LinkCategory.getById(doc.links[i].linkCategoryId).name].push(link);
                    }
                }

                var output_list = [];
                if(temp_dict){
                    for(var item in temp_dict){
                        if (!temp_dict.hasOwnProperty(item)) continue;
                        var linkCat = {};
                        linkCat["name"] = item;
                        linkCat["links"] = temp_dict[item];
                        output_list.push(linkCat);
                    }
                }
                return output_list;

            }

            function getAllDocumentsAsJSON(){
                var output = {
                    allDocuments: []
                };
                var documents = Document.getAll();

                for (var i = 0; i < documents.length; i++) {
                    output["allDocuments"].push(getDocumentAsJSON(documents[i]));
                }

                return output;
            }

            return {
                getDocumentAsJSON: getDocumentAsJSON,
                getAllDocumentsAsJSON: getAllDocumentsAsJSON
            };
        }
    ]
);<|endoftext|>