<commit_before>core.service("AbstractRepo", function ($q, WsApi, ValidationStore) {

	return function AbstractRepo(model, mapping) {

		var abstractRepo = this;

		abstractRepo.mapping = mapping;

		var list = [];

		var initialized = false;

		var defer = $q.defer();

		var listenCallbacks = [];

		var entityName = new model({}).getEntityName();

		var validations = ValidationStore.getValidations(entityName);

		var build = function(data) {
			initialized = false;
			return $q(function(resolve) {
				list.length = 0;
				angular.forEach(data, function(modelJson) {
					list.push(new model(modelJson));
				});
				initialized = true
				resolve();
			});
		};

		var unwrap = function(res) {
			var repoObj = {};
			var payload = angular.fromJson(res.body).payload;
			var keys = Object.keys(payload);
			angular.forEach(keys, function(key) {
				angular.extend(repoObj, payload[key]);
			})
			return repoObj;
		};

		var fetch = function() {
			if(abstractRepo.mapping.all !== undefined) {
				WsApi.fetch(abstractRepo.mapping.all).then(function(res) {
					build(unwrap(res)).then(function() {
						defer.resolve(res);
					});
				});
			}
		};

		WsApi.listen(abstractRepo.mapping.listen).then(null, null, function(res) {
			build(unwrap(res)).then(function() {
				angular.forEach(listenCallbacks, function(cb) {
					cb(res);
				});
			});
		});

		fetch();

		abstractRepo.ValidationResults = {};

		abstractRepo.getEntityName = function() {
			return entityName;
		};

		abstractRepo.getValidations = function() {
			return validations;
		};

		abstractRepo.count = function() {
			if(!initialized) {
				console.error('Repo not initialized!');
			}
			return list.length;
		};

		abstractRepo.getAll = function() {
			return list;
		};

		abstractRepo.saveAll = function() {
			angular.forEach(list, function(model) {
				model.save();
			});
		};

		abstractRepo.ready = function() {
			return defer.promise;
		};

		abstractRepo.reset = function() {
			defer = $q.defer();
			fetch();
		};

		abstractRepo.findById = function(id) {
			var match;

			var find = function(id) {
				for(var key in list) {
					if(list[key].id == id) {
						return list[key];
					}
				}
			}

			if(initialized) {
				match = find(id);
			}
			else {
				// TODO: think of a way to find after ready and have binding in list
				console.error("Repo not initialized!");
			}

			return match;
		};

		abstractRepo.delete = function(model) {
			abstractRepo.clearValidationResults();
			var promise = model.delete();
			promise.then(function(res) {
				if(angular.fromJson(res.body).meta.type == "INVALID") {
					angular.extend(abstractRepo, angular.fromJson(res.body).payload);
					console.log(abstractRepo);
				}
			});
			return promise;
		};

		abstractRepo.deleteById = function(id) {
			abstractRepo.clearValidationResults();
			var promise = abstractRepo.findById(id).delete();
			promise.then(function(res) {
				if(angular.fromJson(res.body).meta.type == "INVALID") {
					angular.extend(abstractRepo, angular.fromJson(res.body).payload);
					console.log(abstractRepo);
				}
			});
			return promise;
		};

		abstractRepo.create = function(model) {
			abstractRepo.clearValidationResults();
			angular.extend(abstractRepo.mapping.create, {'data': model});
			var promise = WsApi.fetch(abstractRepo.mapping.create);
			promise.then(function(res) {
				if(angular.fromJson(res.body).meta.type == "INVALID") {
					angular.extend(abstractRepo, angular.fromJson(res.body).payload);
					console.log(abstractRepo);
				}
			});
			return promise;
		};

		// TODO: remove
		abstractRepo.update = function(model) {
			abstractRepo.clearValidationResults();
           	var promise = model.save();
           	promise.then(function(res) {
				if(angular.fromJson(res.body).meta.type == "INVALID") {
					angular.extend(abstractRepo, angular.fromJson(res.body).payload);
					console.log(abstractRepo);
				}
			});
			return promise;
		};

		abstractRepo.listen = function(cb) {
			listenCallbacks.push(cb);
		};

		// additiona core level repo methods and variables

		// these should be added through decoration
		abstractRepo.sort = function(facet) {
			abstractRepo.clearValidationResults();
			angular.extend(abstractRepo.mapping.sort, {'method': 'sort/' + facet});
			var promise = WsApi.fetch(abstractRepo.mapping.sort);
			promise.then(function(res) {
				if(angular.fromJson(res.body).meta.type == "INVALID") {
					angular.extend(abstractRepo, angular.fromJson(res.body).payload);
					console.log(abstractRepo);
				}
			});
			return promise;
		};

		abstractRepo.reorder = function(src, dest) {
			abstractRepo.clearValidationResults();
			angular.extend(abstractRepo.mapping.reorder, {'method': 'reorder/' + src + '/' + dest});
			var promise = WsApi.fetch(abstractRepo.mapping.reorder);
			promise.then(function(res) {
				if(angular.fromJson(res.body).meta.type == "INVALID") {
					angular.extend(abstractRepo, angular.fromJson(res.body).payload);
					console.log(abstractRepo);
				}
			});
			return promise;
		};

		abstractRepo.getValidationResults = function() {
			return abstractRepo.ValidationResults;
		};

		abstractRepo.clearValidationResults = function() {
			if(abstractRepo.ValidationResults.messages !== undefined) {
				delete abstractRepo.ValidationResults.messages;
			}
		};

		return abstractRepo;
	}

});
<commit_msg>Repo can now lazy load by setting mapping.lazy to true<commit_after>core.service("AbstractRepo", function ($q, WsApi, ValidationStore) {

	return function AbstractRepo(model, mapping) {

		var abstractRepo = this;

		abstractRepo.mapping = mapping;

		var list = [];

		var initialized = false;

		var defer = $q.defer();

		var listenCallbacks = [];

		var entityName = new model({}).getEntityName();

		var validations = ValidationStore.getValidations(entityName);

		var build = function(data) {
			initialized = false;
			return $q(function(resolve) {
				list.length = 0;
				angular.forEach(data, function(modelJson) {
					list.push(new model(modelJson));
				});
				initialized = true
				resolve();
			});
		};

		var unwrap = function(res) {
			var repoObj = {};
			var payload = angular.fromJson(res.body).payload;
			var keys = Object.keys(payload);
			angular.forEach(keys, function(key) {
				angular.extend(repoObj, payload[key]);
			})
			return repoObj;
		};

		var fetch = function() {
			if(abstractRepo.mapping.all !== undefined) {
				WsApi.fetch(abstractRepo.mapping.all).then(function(res) {
					build(unwrap(res)).then(function() {
						defer.resolve(res);
					});
				});
			}
		};

		WsApi.listen(abstractRepo.mapping.listen).then(null, null, function(res) {
			build(unwrap(res)).then(function() {
				angular.forEach(listenCallbacks, function(cb) {
					cb(res);
				});
			});
		});

		if(!mapping.lazy) {
			fetch();
		}

		abstractRepo.ValidationResults = {};

		abstractRepo.getEntityName = function() {
			return entityName;
		};

		abstractRepo.getValidations = function() {
			return validations;
		};

		abstractRepo.count = function() {
			if(!initialized) {
				console.error('Repo not initialized!');
			}
			return list.length;
		};

		abstractRepo.getAll = function() {
			if(mapping.lazy) {
				fetch();
			}
			return list;
		};

		abstractRepo.saveAll = function() {
			angular.forEach(list, function(model) {
				model.save();
			});
		};

		abstractRepo.ready = function() {
			return defer.promise;
		};

		abstractRepo.reset = function() {
			defer = $q.defer();
			fetch();
		};

		abstractRepo.findById = function(id) {
			var match;

			var find = function(id) {
				for(var key in list) {
					if(list[key].id == id) {
						return list[key];
					}
				}
			}

			if(initialized) {
				match = find(id);
			}
			else {
				// TODO: think of a way to find after ready and have binding in list
				console.error("Repo not initialized!");
			}

			return match;
		};

		abstractRepo.delete = function(model) {
			abstractRepo.clearValidationResults();
			var promise = model.delete();
			promise.then(function(res) {
				if(angular.fromJson(res.body).meta.type == "INVALID") {
					angular.extend(abstractRepo, angular.fromJson(res.body).payload);
					console.log(abstractRepo);
				}
			});
			return promise;
		};

		abstractRepo.deleteById = function(id) {
			abstractRepo.clearValidationResults();
			var promise = abstractRepo.findById(id).delete();
			promise.then(function(res) {
				if(angular.fromJson(res.body).meta.type == "INVALID") {
					angular.extend(abstractRepo, angular.fromJson(res.body).payload);
					console.log(abstractRepo);
				}
			});
			return promise;
		};

		abstractRepo.create = function(model) {
			abstractRepo.clearValidationResults();
			angular.extend(abstractRepo.mapping.create, {'data': model});
			var promise = WsApi.fetch(abstractRepo.mapping.create);
			promise.then(function(res) {
				if(angular.fromJson(res.body).meta.type == "INVALID") {
					angular.extend(abstractRepo, angular.fromJson(res.body).payload);
					console.log(abstractRepo);
				}
			});
			return promise;
		};

		// TODO: remove
		abstractRepo.update = function(model) {
			abstractRepo.clearValidationResults();
           	var promise = model.save();
           	promise.then(function(res) {
				if(angular.fromJson(res.body).meta.type == "INVALID") {
					angular.extend(abstractRepo, angular.fromJson(res.body).payload);
					console.log(abstractRepo);
				}
			});
			return promise;
		};

		abstractRepo.listen = function(cb) {
			listenCallbacks.push(cb);
		};

		// additiona core level repo methods and variables

		// these should be added through decoration
		abstractRepo.sort = function(facet) {
			abstractRepo.clearValidationResults();
			angular.extend(abstractRepo.mapping.sort, {'method': 'sort/' + facet});
			var promise = WsApi.fetch(abstractRepo.mapping.sort);
			promise.then(function(res) {
				if(angular.fromJson(res.body).meta.type == "INVALID") {
					angular.extend(abstractRepo, angular.fromJson(res.body).payload);
					console.log(abstractRepo);
				}
			});
			return promise;
		};

		abstractRepo.reorder = function(src, dest) {
			abstractRepo.clearValidationResults();
			angular.extend(abstractRepo.mapping.reorder, {'method': 'reorder/' + src + '/' + dest});
			var promise = WsApi.fetch(abstractRepo.mapping.reorder);
			promise.then(function(res) {
				if(angular.fromJson(res.body).meta.type == "INVALID") {
					angular.extend(abstractRepo, angular.fromJson(res.body).payload);
					console.log(abstractRepo);
				}
			});
			return promise;
		};

		abstractRepo.getValidationResults = function() {
			return abstractRepo.ValidationResults;
		};

		abstractRepo.clearValidationResults = function() {
			if(abstractRepo.ValidationResults.messages !== undefined) {
				delete abstractRepo.ValidationResults.messages;
			}
		};

		return abstractRepo;
	}

});
<|endoftext|>


<commit_before>self.deprecationWorkflow = self.deprecationWorkflow || {};
self.deprecationWorkflow.config = {
    workflow: [
        // revert one liquid-fire and liquid-wormhole remove uses of `this.$()`
        {handler: 'silence', matchId: 'ember-views.curly-components.jquery-element'},
        // revert once ember-infinity removes usage of `isVisible`
        // https://github.com/ember-infinity/ember-infinity/pull/399
        {handler: 'silence', matchId: 'ember-component.is-visible'}
    ]
};
<commit_msg>Silenced Component#sendAction deprecation<commit_after>self.deprecationWorkflow = self.deprecationWorkflow || {};
self.deprecationWorkflow.config = {
    workflow: [
        // remove once ember-drag-drop removes usage of Component#sendAction
        // https://github.com/mharris717/ember-drag-drop/issues/155
        {handler: 'silence', matchId: 'ember-component.send-action'},

        // remove once liquid-fire and liquid-wormhole remove uses of `this.$()`
        {handler: 'silence', matchId: 'ember-views.curly-components.jquery-element'},

        // remove once ember-infinity removes usage of `isVisible`
        // https://github.com/ember-infinity/ember-infinity/pull/399
        {handler: 'silence', matchId: 'ember-component.is-visible'}
    ]
};
<|endoftext|>


<commit_before>var scale, gridX, gridY, player;
var playerVector, playerDestination;
var offsetVector, offsetDestination;
var allPaths = new Array();
var customLayerPaths = new Array();
var customLayerObjects = {};
var layers = new Array();
var maxLayer = 3;
var currentLayer = 0;
var offset = new Point(0, 0);

for (var i = -maxLayer; i <= maxLayer; i++) {
    var layer = new Layer();
    layers.push(project.activeLayer);
}

var customLayer = new Layer();
var customLayerOffset = new Point(0, 0);
customLayer.visible = false;

function activateLayer(index) {
    showCustomLayer(false);
    layers[getLayerIndex(index)].activate();
    layers[getLayerIndex(index)].opacity = 1;
    if (currentLayer != index) {
        layers[getLayerIndex(currentLayer)].opacity = 0.2;
        currentLayer = index;
    }
}

function getLayerIndex(index) {
    if (index < -maxLayer || index > maxLayer) {
        alert("Layer out of bounds. Current layer range: -" + maxLayer + " to " + maxLayer);
    }
    // layers array represents z-indexes from -maxLayer to maxLayer
    return index + maxLayer;
}

activateLayer(currentLayer);

gridApi.setScale = function(newScale) {
    scale = newScale;
    gridX = new Point(scale, 0);
    gridY = new Point(0, scale);
};

gridApi.setZoom = function(zoom) {
    paper.view.zoom = zoom;
};

gridApi.zoomIn = function(amount) {
    paper.view.zoom = paper.view.zoom * (Math.pow(1.1, amount));
};

function onMouseDrag(event) {
    updateOffset(event.delta);
}

function onMouseUp(event) {
    var x = getGridSquareX(event.point);
    var y = getGridSquareY(event.point);
    ASLEvent("JS_GridSquareClick", x + ";" + y);
}

function updateOffset(delta) {
    setOffset(getOffset() + delta);
    var paths;
    if (project.activeLayer == customLayer) {
        paths = customLayerPaths;
    }
    else {
        paths = allPaths;
    }
    for (var i = 0; i < paths.length; i++) {
        paths[i].position += delta;
    }
    if (playerDestination && project.activeLayer != customLayer) {
        playerDestination += delta;
    }
}

function getOffset() {
    if (project.activeLayer == customLayer) {
        return customLayerOffset;
    }
    return offset;
}

function setOffset(value) {
    if (project.activeLayer == customLayer) {
        customLayerOffset = value;
    }
    else {
        offset = value;
    }
}

function onFrame(event) {
    if (playerVector) {
        var distance = player.position - playerDestination;
        if (distance.length > playerVector.length) {
            player.position += playerVector;
        }
        else {
            player.position = playerDestination;
            playerVector = null;
            playerDestination = null;

            playerPositionAbsolute = player.position - offset;
            offsetDestinationX = ($("#gridPanel").width() / 2) - playerPositionAbsolute.x;
            offsetDestinationY = ($("#gridPanel").height() / 2) - playerPositionAbsolute.y;

            offsetDestination = new Point(offsetDestinationX, offsetDestinationY);
            offsetVector = (offsetDestination-offset) / 10;
        }
    }
    if (offsetVector) {
        var distance = offset - offsetDestination;
        if (distance.length > offsetVector.length) {
            updateOffset(offsetVector);
        }
        else {
            updateOffset(offsetDestination-offset);
            offsetVector = null;
            offsetDestination = null;
        }
    }
}

gridApi.drawGrid = function(minX, minY, maxX, maxY, border) {

    function gridLine(start, end) {
        var path = new Path();
        path.strokeColor = border;
        path.add(start, end);
        addPathToCurrentLayerList(path);
    }

    // draw the vertical lines
    for (var x = minX; x <= maxX; x++) {
        var start = gridPoint(x, minY);
        var end = gridPoint(x, maxY);
        gridLine(start, end);
    }

    // draw the horizontal lines
    for (var y = minY; y <= maxY; y++) {
        var start = gridPoint(minX, y);
        var end = gridPoint(maxX, y);
        gridLine(start, end);
    }
};

function gridPoint(x, y) {
    return (gridX * x) + (gridY * y) + getOffset();
}

function getGridSquareX(point) {
    return Math.floor(((point - getOffset()) / gridX).x);
}

function getGridSquareY(point) {
    return Math.floor(((point - getOffset()) / gridY).y);
}

function gridPointNudge(x, y, nudgeX, nudgeY) {
    var result = gridPoint(x, y);
    result.x += nudgeX;
    result.y += nudgeY;
    return result;
}

var firstBox = true;

gridApi.drawBox = function(x, y, z, width, height, border, borderWidth, fill, sides) {
    activateLayer(z);
    // if this is the very first room, centre the canvas by updating the offset
    if (firstBox) {
        var centrePoint = gridPoint(x + width / 2, y + height / 2);
        var offsetX = ($("#gridPanel").width() / 2) - centrePoint.x;
        var offsetY = ($("#gridPanel").height() / 2) - centrePoint.y;
        updateOffset(new Point(offsetX, offsetY));
        firstBox = false;
    }
    var path = null;
    var points = [gridPoint(x, y), gridPoint(x + width, y), gridPoint(x + width, y + height), gridPoint(x, y + height)];
    // sides is encoded with bits to represent NESW
    var draw = [sides & 8, sides & 4, sides & 2, sides & 1];
    for (var i = 0; i < 4; i++) {
        var next = (i + 1) % 4;
        if (draw[i]) {
            if (path == null) {
                path = new Path();
                allPaths.push(path);
                if (borderWidth > 0) {
                    path.strokeColor = border;
                    path.strokeWidth = borderWidth;
                }
                path.add(points[i]);
            }
            path.add(points[next]);
        } else {
            path = null;
        }
    }
    var fillPath;
    if (sides == 15) {
        fillPath = path;
    } else {
        fillPath = new Path();
        fillPath.add(points[0], points[1], points[2], points[3]);
        allPaths.push(fillPath);
    }
    fillPath.fillColor = fill;
    fillPath.closed = true;
};

gridApi.drawLine = function(x1, y1, x2, y2, border, borderWidth) {
    var path = new Path;
    path.strokeColor = border;
    path.strokeWidth = borderWidth;
    path.add(gridPoint(x1, y1));
    path.add(gridPoint(x2, y2));
    addPathToCurrentLayerList(path);
};

function addPathToCurrentLayerList(path) {
    if (project.activeLayer == customLayer) {
        customLayerPaths.push(path);
    }
    else {
        allPaths.push(path);
    }
}

gridApi.drawPlayer = function(x, y, z, radius, border, borderWidth, fill) {
    activateLayer(z);
    if (!player) {
        player = new Path.Circle(gridPoint(x, y), radius);
        player.strokeColor = border;
        player.strokeWidth = borderWidth;
        player.fillColor = fill;
        player.fillColor = fill;
        allPaths.push(player);

        playerPositionAbsolute = player.position - offset;
        offsetDestinationX = ($("#gridPanel").width() / 2) - playerPositionAbsolute.x;
        offsetDestinationY = ($("#gridPanel").height() / 2) - playerPositionAbsolute.y;

        offsetDestination = new Point(offsetDestinationX, offsetDestinationY);
        offsetVector = (offsetDestination - offset);
    } else {
        playerDestination = gridPoint(x, y);
        playerVector = (playerDestination - player.position) / 10;
        paper.view.zoom = 1;
        // move player to the end of the activeLayer so it gets drawn on top
        project.activeLayer.addChild(player);
    }
};

gridApi.drawLabel = function(x, y, z, text) {
    activateLayer(z);
    var pointText = new PointText(gridPoint(x, y));
    pointText.justification = "center";
    pointText.fillColor = "black";
    pointText.content = text;
    allPaths.push(pointText);
};

function showCustomLayer(visible) {
    if (visible != customLayer.visible) {
        customLayer.visible = visible;
        for (var idx = 0; idx < layers.length; idx++) {
            layers[idx].visible = !visible;
        }
        if (visible) {
            customLayer.activate();
        }
        else {
            layers[getLayerIndex(currentLayer)].activate();
        }
    }
}

gridApi.showCustomLayer = function(visible) {
    showCustomLayer(visible);
};

gridApi.clearCustomLayer = function() {
    customLayer.removeChildren();
};

gridApi.clearAllLayers = function () {
    $.each(layers, function(idx, layer) {
        layer.removeChildren();
    });
};

gridApi.setCentre = function(x, y) {
    var centrePoint = gridPoint(x, y);
    var offsetX = ($("#gridPanel").width() / 2) - centrePoint.x;
    var offsetY = ($("#gridPanel").height() / 2) - centrePoint.y;
    var curOffset = getOffset();
    updateOffset(new Point(offsetX, offsetY));
};

gridApi.drawCustomLayerSquare = function(id, x, y, width, height, text, fill) {
    var existing = customLayerObjects[id];
    if (existing) {
        for (var idx in existing) {
            var path = existing[idx];
            // TO DO: Should remove path from layer and layerlist array
            path.visible = false;
        }
    }

    var paths = new Array();
    path = new Path();
    path.add(gridPointNudge(x, y, 1, 1), gridPointNudge(x + width, y, -1, 1), gridPointNudge(x + width, y + height, -1, -1), gridPointNudge(x, y + height, 1, -1));
    path.fillColor = fill;
    path.closed = true;
    addPathToCurrentLayerList(path);
    paths.push(path);

    var pointText = new PointText(gridPoint(x + width / 2, y + height / 2));
    pointText.justification = "center";
    pointText.fillColor = "black";
    pointText.content = text;
    addPathToCurrentLayerList(pointText);
    paths.push(pointText);

    customLayerObjects[id] = paths;
};

gridApi.onLoad();<commit_msg>Remove player when clearing map so it doesn't animate into other POV position<commit_after>var scale, gridX, gridY, player;
var playerVector, playerDestination;
var offsetVector, offsetDestination;
var allPaths = new Array();
var customLayerPaths = new Array();
var customLayerObjects = {};
var layers = new Array();
var maxLayer = 3;
var currentLayer = 0;
var offset = new Point(0, 0);

for (var i = -maxLayer; i <= maxLayer; i++) {
    var layer = new Layer();
    layers.push(project.activeLayer);
}

var customLayer = new Layer();
var customLayerOffset = new Point(0, 0);
customLayer.visible = false;

function activateLayer(index) {
    showCustomLayer(false);
    layers[getLayerIndex(index)].activate();
    layers[getLayerIndex(index)].opacity = 1;
    if (currentLayer != index) {
        layers[getLayerIndex(currentLayer)].opacity = 0.2;
        currentLayer = index;
    }
}

function getLayerIndex(index) {
    if (index < -maxLayer || index > maxLayer) {
        alert("Layer out of bounds. Current layer range: -" + maxLayer + " to " + maxLayer);
    }
    // layers array represents z-indexes from -maxLayer to maxLayer
    return index + maxLayer;
}

activateLayer(currentLayer);

gridApi.setScale = function(newScale) {
    scale = newScale;
    gridX = new Point(scale, 0);
    gridY = new Point(0, scale);
};

gridApi.setZoom = function(zoom) {
    paper.view.zoom = zoom;
};

gridApi.zoomIn = function(amount) {
    paper.view.zoom = paper.view.zoom * (Math.pow(1.1, amount));
};

function onMouseDrag(event) {
    updateOffset(event.delta);
}

function onMouseUp(event) {
    var x = getGridSquareX(event.point);
    var y = getGridSquareY(event.point);
    ASLEvent("JS_GridSquareClick", x + ";" + y);
}

function updateOffset(delta) {
    setOffset(getOffset() + delta);
    var paths;
    if (project.activeLayer == customLayer) {
        paths = customLayerPaths;
    }
    else {
        paths = allPaths;
    }
    for (var i = 0; i < paths.length; i++) {
        paths[i].position += delta;
    }
    if (playerDestination && project.activeLayer != customLayer) {
        playerDestination += delta;
    }
}

function getOffset() {
    if (project.activeLayer == customLayer) {
        return customLayerOffset;
    }
    return offset;
}

function setOffset(value) {
    if (project.activeLayer == customLayer) {
        customLayerOffset = value;
    }
    else {
        offset = value;
    }
}

function onFrame(event) {
    if (playerVector) {
        var distance = player.position - playerDestination;
        if (distance.length > playerVector.length) {
            player.position += playerVector;
        }
        else {
            player.position = playerDestination;
            playerVector = null;
            playerDestination = null;

            var playerPositionAbsolute = player.position - offset;
            var offsetDestinationX = ($("#gridPanel").width() / 2) - playerPositionAbsolute.x;
            var offsetDestinationY = ($("#gridPanel").height() / 2) - playerPositionAbsolute.y;

            offsetDestination = new Point(offsetDestinationX, offsetDestinationY);
            offsetVector = (offsetDestination-offset) / 10;
        }
    }
    if (offsetVector) {
        var distance = offset - offsetDestination;
        if (distance.length > offsetVector.length) {
            updateOffset(offsetVector);
        }
        else {
            updateOffset(offsetDestination-offset);
            offsetVector = null;
            offsetDestination = null;
        }
    }
}

gridApi.drawGrid = function(minX, minY, maxX, maxY, border) {

    function gridLine(start, end) {
        var path = new Path();
        path.strokeColor = border;
        path.add(start, end);
        addPathToCurrentLayerList(path);
    }

    // draw the vertical lines
    for (var x = minX; x <= maxX; x++) {
        var start = gridPoint(x, minY);
        var end = gridPoint(x, maxY);
        gridLine(start, end);
    }

    // draw the horizontal lines
    for (var y = minY; y <= maxY; y++) {
        var start = gridPoint(minX, y);
        var end = gridPoint(maxX, y);
        gridLine(start, end);
    }
};

function gridPoint(x, y) {
    return (gridX * x) + (gridY * y) + getOffset();
}

function getGridSquareX(point) {
    return Math.floor(((point - getOffset()) / gridX).x);
}

function getGridSquareY(point) {
    return Math.floor(((point - getOffset()) / gridY).y);
}

function gridPointNudge(x, y, nudgeX, nudgeY) {
    var result = gridPoint(x, y);
    result.x += nudgeX;
    result.y += nudgeY;
    return result;
}

var firstBox = true;

gridApi.drawBox = function(x, y, z, width, height, border, borderWidth, fill, sides) {
    activateLayer(z);
    // if this is the very first room, centre the canvas by updating the offset
    if (firstBox) {
        var centrePoint = gridPoint(x + width / 2, y + height / 2);
        var offsetX = ($("#gridPanel").width() / 2) - centrePoint.x;
        var offsetY = ($("#gridPanel").height() / 2) - centrePoint.y;
        updateOffset(new Point(offsetX, offsetY));
        firstBox = false;
    }
    var path = null;
    var points = [gridPoint(x, y), gridPoint(x + width, y), gridPoint(x + width, y + height), gridPoint(x, y + height)];
    // sides is encoded with bits to represent NESW
    var draw = [sides & 8, sides & 4, sides & 2, sides & 1];
    for (var i = 0; i < 4; i++) {
        var next = (i + 1) % 4;
        if (draw[i]) {
            if (path == null) {
                path = new Path();
                allPaths.push(path);
                if (borderWidth > 0) {
                    path.strokeColor = border;
                    path.strokeWidth = borderWidth;
                }
                path.add(points[i]);
            }
            path.add(points[next]);
        } else {
            path = null;
        }
    }
    var fillPath;
    if (sides == 15) {
        fillPath = path;
    } else {
        fillPath = new Path();
        fillPath.add(points[0], points[1], points[2], points[3]);
        allPaths.push(fillPath);
    }
    fillPath.fillColor = fill;
    fillPath.closed = true;
};

gridApi.drawLine = function(x1, y1, x2, y2, border, borderWidth) {
    var path = new Path;
    path.strokeColor = border;
    path.strokeWidth = borderWidth;
    path.add(gridPoint(x1, y1));
    path.add(gridPoint(x2, y2));
    addPathToCurrentLayerList(path);
};

function addPathToCurrentLayerList(path) {
    if (project.activeLayer == customLayer) {
        customLayerPaths.push(path);
    }
    else {
        allPaths.push(path);
    }
}

gridApi.drawPlayer = function(x, y, z, radius, border, borderWidth, fill) {
    activateLayer(z);
    if (!player) {
        player = new Path.Circle(gridPoint(x, y), radius);
        player.strokeColor = border;
        player.strokeWidth = borderWidth;
        player.fillColor = fill;
        player.fillColor = fill;
        allPaths.push(player);

        var playerPositionAbsolute = player.position - offset;
        var offsetDestinationX = ($("#gridPanel").width() / 2) - playerPositionAbsolute.x;
        var offsetDestinationY = ($("#gridPanel").height() / 2) - playerPositionAbsolute.y;

        offsetDestination = new Point(offsetDestinationX, offsetDestinationY);
        offsetVector = (offsetDestination - offset);
    } else {
        playerDestination = gridPoint(x, y);
        playerVector = (playerDestination - player.position) / 10;
        paper.view.zoom = 1;
        // move player to the end of the activeLayer so it gets drawn on top
        project.activeLayer.addChild(player);
    }
};

gridApi.drawLabel = function(x, y, z, text) {
    activateLayer(z);
    var pointText = new PointText(gridPoint(x, y));
    pointText.justification = "center";
    pointText.fillColor = "black";
    pointText.content = text;
    allPaths.push(pointText);
};

function showCustomLayer(visible) {
    if (visible != customLayer.visible) {
        customLayer.visible = visible;
        for (var idx = 0; idx < layers.length; idx++) {
            layers[idx].visible = !visible;
        }
        if (visible) {
            customLayer.activate();
        }
        else {
            layers[getLayerIndex(currentLayer)].activate();
        }
    }
}

gridApi.showCustomLayer = function(visible) {
    showCustomLayer(visible);
};

gridApi.clearCustomLayer = function() {
    customLayer.removeChildren();
};

gridApi.clearAllLayers = function () {
    player = null;
    $.each(layers, function(idx, layer) {
        layer.removeChildren();
    });
};

gridApi.setCentre = function(x, y) {
    var centrePoint = gridPoint(x, y);
    var offsetX = ($("#gridPanel").width() / 2) - centrePoint.x;
    var offsetY = ($("#gridPanel").height() / 2) - centrePoint.y;
    var curOffset = getOffset();
    updateOffset(new Point(offsetX, offsetY));
};

gridApi.drawCustomLayerSquare = function(id, x, y, width, height, text, fill) {
    var existing = customLayerObjects[id];
    if (existing) {
        for (var idx in existing) {
            var path = existing[idx];
            // TO DO: Should remove path from layer and layerlist array
            path.visible = false;
        }
    }

    var paths = new Array();
    path = new Path();
    path.add(gridPointNudge(x, y, 1, 1), gridPointNudge(x + width, y, -1, 1), gridPointNudge(x + width, y + height, -1, -1), gridPointNudge(x, y + height, 1, -1));
    path.fillColor = fill;
    path.closed = true;
    addPathToCurrentLayerList(path);
    paths.push(path);

    var pointText = new PointText(gridPoint(x + width / 2, y + height / 2));
    pointText.justification = "center";
    pointText.fillColor = "black";
    pointText.content = text;
    addPathToCurrentLayerList(pointText);
    paths.push(pointText);

    customLayerObjects[id] = paths;
};

gridApi.onLoad();<|endoftext|>


<commit_before>var Class = require('../../utils/Class');
var BaseSound = require('../BaseSound');
//  Phaser.Sound.WebAudioSound
// TODO support webkitAudioContext implementation differences
// https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Porting_webkitAudioContext_code_to_standards_based_AudioContext
var WebAudioSound = new Class({
    Extends: BaseSound,
    initialize: function WebAudioSound(manager, key, config) {
        /**
         * [description]
         *
         * @property {AudioBuffer} audioBuffer
         */
        this.audioBuffer = manager.game.cache.audio.get(key);
        if (!this.audioBuffer) {
            console.error('No audio loaded in cache with key: \'' + key + '\'!');
            return;
        }
        /**
         * [description]
         *
         * @property {AudioBufferSourceNode} source
         */
        this.source = null;
        /**
         * [description]
         *
         * @property {GainNode} muteNode
         */
        this.muteNode = manager.context.createGain();
        /**
         * [description]
         *
         * @property {GainNode} volumeNode
         */
        this.volumeNode = manager.context.createGain();
        /**
         * The time the previous playback started at based on
         * BaseAudioContext.currentTime value.
         *
         * @property {number} startTime
         */
        this.startTime = 0;
        /**
         * Relative time when sound was paused.
         * Corresponds to the seek value at the time when pause() method was called on this sound.
         *
         * @property {number} pausedTime
         */
        this.pausedTime = 0;
        // TODO add duration and total duration
        this.muteNode.connect(this.volumeNode);
        this.volumeNode.connect(manager.destination);
        if (config === void 0) {
            config = {};
        }
        config.duration = this.audioBuffer.duration;
        BaseSound.call(this, manager, key, config);
    },
    play: function (marker, config) {
        if (!BaseSound.prototype.play.call(this, marker, config)) {
            return null;
        }
        if (this.source) {
            this.source.stop();
        }
        // TODO include config offset and marker start
        this.createAndStartBufferSource(0, this.currentConfig.duration);
        this.startTime = this.manager.context.currentTime;
        this.pausedTime = 0;
        return this;
    },
    pause: function () {
        BaseSound.prototype.pause.call(this);
        this.stopAndRemoveBufferSource();
        this.pausedTime = this.manager.context.currentTime - this.startTime;
        return this;
    },
    resume: function () {
        BaseSound.prototype.resume.call(this);
        var offset = this.pausedTime; // TODO include marker start time
        var duration = this.currentConfig.duration - this.pausedTime;
        this.createAndStartBufferSource(offset, duration);
        this.startTime = this.manager.context.currentTime - this.pausedTime;
        this.pausedTime = 0;
        return this;
    },
    stop: function () {
        BaseSound.prototype.stop.call(this);
        this.stopAndRemoveBufferSource();
        this.startTime = 0;
        this.pausedTime = 0;
        return this;
    },
    /**
     * Used internally to do what the name says.
     *
     * @private
     * @param {number} offset
     * @param {number} duration
     */
    createAndStartBufferSource: function (offset, duration) {
        this.source = this.manager.context.createBufferSource();
        this.source.buffer = this.audioBuffer;
        this.source.connect(this.muteNode);
        this.applyConfig();
        this.source.start(0, offset, duration);
    },
    /**
     * Used internally to do what the name says.
     *
     * @private
     */
    stopAndRemoveBufferSource: function () {
        this.source.stop();
        this.source = null;
    },
    update: function () {
    },
    destroy: function () {
    }
});
/**
 * Mute setting.
 * @property {boolean} mute
 */
Object.defineProperty(WebAudioSound.prototype, 'mute', {
    get: function () {
        return this.muteNode.gain.value === 0;
    },
    set: function (value) {
        this.currentConfig.mute = value;
        this.muteNode.gain.value = value ? 0 : 1;
    }
});
/**
 * Volume setting.
 * @property {number} volume
 */
Object.defineProperty(WebAudioSound.prototype, 'volume', {
    get: function () {
        return this.volumeNode.gain.value;
    },
    set: function (value) {
        this.currentConfig.volume = value;
        this.volumeNode.gain.value = value;
    }
});
/**
 * Playback rate.
 * @property {number} rate
 */
Object.defineProperty(WebAudioSound.prototype, 'rate', {
    get: function () {
        return this.currentConfig.rate;
    },
    set: function (value) {
        this.currentConfig.rate = value;
        if (this.source) {
            this.source.playbackRate.value = value * this.manager.rate;
        }
    }
});
/**
 * Detuning of sound.
 * @property {number} detune
 */
Object.defineProperty(WebAudioSound.prototype, 'detune', {
    get: function () {
        return this.currentConfig.detune;
    },
    set: function (value) {
        this.currentConfig.detune = value;
        if (this.source) {
            this.source.detune.value =
                Math.max(-1200, Math.min(value + this.manager.detune, 1200));
        }
    }
});
module.exports = WebAudioSound;
<commit_msg>added checks to playback control methods for WebAudioSound<commit_after>var Class = require('../../utils/Class');
var BaseSound = require('../BaseSound');
//  Phaser.Sound.WebAudioSound
// TODO support webkitAudioContext implementation differences
// https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Porting_webkitAudioContext_code_to_standards_based_AudioContext
var WebAudioSound = new Class({
    Extends: BaseSound,
    initialize: function WebAudioSound(manager, key, config) {
        /**
         * [description]
         *
         * @property {AudioBuffer} audioBuffer
         */
        this.audioBuffer = manager.game.cache.audio.get(key);
        if (!this.audioBuffer) {
            console.error('No audio loaded in cache with key: \'' + key + '\'!');
            return;
        }
        /**
         * [description]
         *
         * @property {AudioBufferSourceNode} source
         */
        this.source = null;
        /**
         * [description]
         *
         * @property {GainNode} muteNode
         */
        this.muteNode = manager.context.createGain();
        /**
         * [description]
         *
         * @property {GainNode} volumeNode
         */
        this.volumeNode = manager.context.createGain();
        /**
         * The time the previous playback started at based on
         * BaseAudioContext.currentTime value.
         *
         * @property {number} startTime
         */
        this.startTime = 0;
        /**
         * Relative time when sound was paused.
         * Corresponds to the seek value at the time when pause() method was called on this sound.
         *
         * @property {number} pausedTime
         */
        this.pausedTime = 0;
        // TODO add duration and total duration
        this.muteNode.connect(this.volumeNode);
        this.volumeNode.connect(manager.destination);
        if (config === void 0) {
            config = {};
        }
        config.duration = this.audioBuffer.duration;
        BaseSound.call(this, manager, key, config);
    },
    play: function (marker, config) {
        if (!BaseSound.prototype.play.call(this, marker, config)) {
            return null;
        }
        if (this.source) {
            this.source.stop();
        }
        // TODO include config offset and marker start
        this.createAndStartBufferSource(0, this.currentConfig.duration);
        this.startTime = this.manager.context.currentTime;
        this.pausedTime = 0;
        return this;
    },
    pause: function () {
        if (!BaseSound.prototype.pause.call(this)) {
            return false;
        }
        this.stopAndRemoveBufferSource();
        this.pausedTime = this.manager.context.currentTime - this.startTime;
        return true;
    },
    resume: function () {
        if (!BaseSound.prototype.resume.call(this)) {
            return false;
        }
        var offset = this.pausedTime; // TODO include marker start time
        var duration = this.currentConfig.duration - this.pausedTime;
        this.createAndStartBufferSource(offset, duration);
        this.startTime = this.manager.context.currentTime - this.pausedTime;
        this.pausedTime = 0;
        return true;
    },
    stop: function () {
        if (!BaseSound.prototype.stop.call(this)) {
            return false;
        }
        this.stopAndRemoveBufferSource();
        this.startTime = 0;
        this.pausedTime = 0;
        return true;
    },
    /**
     * Used internally to do what the name says.
     *
     * @private
     * @param {number} offset
     * @param {number} duration
     */
    createAndStartBufferSource: function (offset, duration) {
        this.source = this.manager.context.createBufferSource();
        this.source.buffer = this.audioBuffer;
        this.source.connect(this.muteNode);
        this.applyConfig();
        this.source.start(0, offset, duration);
    },
    /**
     * Used internally to do what the name says.
     *
     * @private
     */
    stopAndRemoveBufferSource: function () {
        this.source.stop();
        this.source = null;
    },
    update: function () {
    },
    destroy: function () {
    }
});
/**
 * Mute setting.
 * @property {boolean} mute
 */
Object.defineProperty(WebAudioSound.prototype, 'mute', {
    get: function () {
        return this.muteNode.gain.value === 0;
    },
    set: function (value) {
        this.currentConfig.mute = value;
        this.muteNode.gain.value = value ? 0 : 1;
    }
});
/**
 * Volume setting.
 * @property {number} volume
 */
Object.defineProperty(WebAudioSound.prototype, 'volume', {
    get: function () {
        return this.volumeNode.gain.value;
    },
    set: function (value) {
        this.currentConfig.volume = value;
        this.volumeNode.gain.value = value;
    }
});
/**
 * Playback rate.
 * @property {number} rate
 */
Object.defineProperty(WebAudioSound.prototype, 'rate', {
    get: function () {
        return this.currentConfig.rate;
    },
    set: function (value) {
        this.currentConfig.rate = value;
        if (this.source) {
            this.source.playbackRate.value = value * this.manager.rate;
        }
    }
});
/**
 * Detuning of sound.
 * @property {number} detune
 */
Object.defineProperty(WebAudioSound.prototype, 'detune', {
    get: function () {
        return this.currentConfig.detune;
    },
    set: function (value) {
        this.currentConfig.detune = value;
        if (this.source) {
            this.source.detune.value =
                Math.max(-1200, Math.min(value + this.manager.detune, 1200));
        }
    }
});
module.exports = WebAudioSound;
<|endoftext|>


<commit_before>angular.module('emission.splash.startprefs', ['emission.plugin.logger',
                                              'emission.splash.referral',
                                              'angularLocalStorage'])

.factory('StartPrefs', function($window, $state, $interval, $rootScope, $ionicPlatform,
      $ionicPopup, storage, $http, Logger, ReferralHandler) {
    var logger = Logger;
    var nTimesCalled = 0;
    var startprefs = {};
    var DEFAULT_THEME_KEY = 'curr_theme';
     // Boolean: represents that the "intro" - the one page summary
     // and the login are done
    var INTRO_DONE_KEY = 'intro_done';
    // data collection consented protocol: string, represents the date on
    // which the consented protocol was approved by the IRB
    var DATA_COLLECTION_CONSENTED_PROTOCOL = 'data_collection_consented_protocol';

    var CONSENTED_KEY = "config/consent";

    startprefs.CONSENTED_EVENT = "data_collection_consented";
    startprefs.INTRO_DONE_EVENT = "intro_done";

    startprefs.setDefaultTheme = function(new_theme) {
      storage.set(DEFAULT_THEME_KEY, new_theme);
    }

    startprefs.getDefaultTheme = function() {
      return storage.get(DEFAULT_THEME_KEY);
    }

    startprefs.loadDefaultTheme = function() {
        logger.log("About to set theme from preference");
        var curr_theme = startprefs.getDefaultTheme();
        logger.log("preferred theme = "+curr_theme);

        if (curr_theme == 'dark_theme') {
            $rootScope.dark_theme = true;
        } else {
            $rootScope.dark_theme = false;
        }
        logger.log("set dark_theme = "+$rootScope.dark_theme);
    };

    var writeConsentToNative = function() {
      return $window.cordova.plugins.BEMDataCollection.markConsented($rootScope.req_consent);
    };

    startprefs.markConsented = function() {
      logger.log("changing consent from "+
        $rootScope.curr_consented+" -> "+$rootScope.req_consent);
      // mark in native storage
      return startprefs.readConsentState().then(writeConsentToNative).then(function(response) {
          // mark in local storage
          storage.set(DATA_COLLECTION_CONSENTED_PROTOCOL,
            $rootScope.req_consent);
          // mark in local variable as well
          $rootScope.curr_consented = angular.copy($rootScope.req_consent);
          $rootScope.$emit(startprefs.CONSENTED_EVENT, $rootScope.req_consent);
      });
    };

    startprefs.markIntroDone = function() {
      storage.set(INTRO_DONE_KEY, true);
      $window.cordova.plugins.BEMUserCache.putLocalStorage(INTRO_DONE_KEY,
        {INTRO_DONE_KEY: moment().format()});
      $rootScope.$emit(startprefs.INTRO_DONE_EVENT, $rootScope.req_consent);
    }

    // returns boolean
    startprefs.isIntroDone = function() {
      var read_val = storage.get(INTRO_DONE_KEY);
      logger.log("in isIntroDone, read_val = "+read_val);
      if (read_val == null || read_val == "") {
        logger.log("in isIntroDone, returning false");
        return false;
      } else {
        logger.log("in isIntroDone, returning "+read_val);
        return read_val;
      }
    }

    startprefs.isConsented = function() {
      logger.log("curr_consented = "+$rootScope.curr_consented+
            "isIntroDone = " + startprefs.isIntroDone());
      if (startprefs.isIntroDone() &&
            ($rootScope.curr_consented == null || $rootScope.curr_consented == "")) {
        alert("intro is done, but consent not found, re-consenting...");
      }
      if ($rootScope.curr_consented == null || $rootScope.curr_consented == "" ||
            $rootScope.curr_consented.approval_date != $rootScope.req_consent.approval_date) {
        console.log("Not consented in local storage, need to show consent");
        return false;
      } else {
        console.log("Consented in local storage, no need to show consent");
        return true;
      }
    }

    startprefs.readConsentState = function() {
      /*
       * Read from local storage and move on so that we don't depend on native code.
       * Native code will be checked once the plugins are ready
       */
      if (angular.isDefined($rootScope.req_consent) &&
          angular.isDefined($rootScope.curr_consented) &&
          $rootScope.curr_consented != null) {
          // consent state is all populated
          logger.log("req_consent = "+$rootScope.req_consent
                        +" curr_consented = " + $rootScope.curr_consented);
          return new Promise(function(resolve, reject) {
            logger.log("resolving with empty information");
            resolve();
          });
      } else {
          // read consent state from the file and populate it
          return $http.get("json/startupConfig.json")
              .then(function(startupConfigResult) {
                  $rootScope.req_consent = startupConfigResult.data.emSensorDataCollectionProtocol;
                  logger.log("required consent version = " + JSON.stringify($rootScope.req_consent));
                  $rootScope.curr_consented = storage.get(
                    DATA_COLLECTION_CONSENTED_PROTOCOL);
          });
      }
    }

    /*
     * getNextState() returns a promise, since reading the startupConfig is
     * async. The promise returns an onboarding state to navigate to, or
     * null for the default state
     */

    startprefs.getPendingOnboardingState = function() {
      if (!startprefs.isIntroDone()) {
        // Since we must return a promise when the intro is done,
        // we create and return one here even though we don't need it
        return new Promise(function(resolve, reject) {
          resolve('root.intro');
        });
      } else {
        // intro is done. Now, let's read and check the current version
        // of the startup config
        return $http.get("json/startupConfig.json")
          .then(startprefs.readConsentState)
          .then(startprefs.isConsented)
          .then(function(result) {
            if (result) {
              return null;
            } else {
              return 'root.reconsent';
            }
          });
      }
    };

    startprefs.getConsentDocument = function() {
      return $window.cordova.plugins.BEMUserCache.getDocument("config/consent", false)
            .then(function(resultDoc) {
                if ($window.cordova.plugins.BEMUserCache.isEmptyDoc(resultDoc)) {
                    return null;
                } else {
                    return resultDoc;
                }
            });
    };

    startprefs.checkNativeConsent = function() {
        startprefs.getConsentDocument().then(function(resultDoc) {
            if (resultDoc == null) {
                startprefs.readConsentState()
                    .then(startprefs.isConsented)
                    .then(function(consentState) {
                        if (consentState == true) {
                            $ionicPopup.alert({template: "Local consent found, native consent missing, writing consent to native"});
                            return writeConsentToNative();
                        }
                    });
            }
        });
    }

    startprefs.getNextState = function() {
      return startprefs.getPendingOnboardingState().then(function(result){
        if (result == null) {
          var temp = ReferralHandler.getReferralNavigation();
          if (temp == 'goals') {
            return 'root.main.goals';
          } else if ($rootScope.displayingIncident == true) {
            $rootScope.displayingIncident = false;
            return 'root.main.diary';
          } else if (angular.isDefined($rootScope.redirectTo)) {
            var redirState = $rootScope.redirectTo;
            $rootScope.redirectTo = undefined;
            return redirState;
          } else {
            return 'root.main.metrics';
          }
        } else {
          return result;
        }
      });
    };

    var changeState = function(destState) {
        logger.log('changing state to '+destState);
        console.log("loading "+destState);
        // TODO: Fix this the right way when we fix the FSM
        // https://github.com/e-mission/e-mission-phone/issues/146#issuecomment-251061736
        var reload = false;
        if (($state.$current == destState) && ($state.$current.name == 'root.main.goals')) {
          reload = true;
        }
        $state.go(destState).then(function() {
            if (reload) {
              $rootScope.$broadcast("RELOAD_GOAL_PAGE_FOR_REFERRAL")
            }
        });
    };

    // Currently loads main or intro based on whether onboarding is complete.
    // But easily extensible to storing the last screen that the user was on,
    // or the users' preferred screen

    startprefs.loadPreferredScreen = function() {
      logger.log("About to navigate to preferred tab");
      startprefs.getNextState().then(changeState).catch(function(error) {
        logger.log("error "+error+" loading finding tab, loading root.intro");
        changeState('root.intro');
      });
    };

    startprefs.loadWithPrefs = function() {
      // alert("attach debugger!");
      console.log("Checking to see whether we are ready to load the screen");
      if (!angular.isDefined($window.Logger)) {
          alert("ionic is ready, but logger not present?");
      }
      logger = Logger;
      startprefs.loadDefaultTheme();
      startprefs.loadPreferredScreen();
    };

    startprefs.startWithPrefs = function() {
      startprefs.loadWithPrefs();
    }

    $ionicPlatform.ready().then(function() {
      Logger.log("ionicPlatform.ready() called " + nTimesCalled+" times!");
      nTimesCalled = nTimesCalled + 1;
      startprefs.startWithPrefs();
      startprefs.checkNativeConsent();
      Logger.log("startprefs startup done");
    });

    return startprefs;
});
<commit_msg>Handle more native usercache <-> local storage mismatch<commit_after>angular.module('emission.splash.startprefs', ['emission.plugin.logger',
                                              'emission.splash.referral',
                                              'angularLocalStorage'])

.factory('StartPrefs', function($window, $state, $interval, $rootScope, $ionicPlatform,
      $ionicPopup, storage, $http, Logger, ReferralHandler) {
    var logger = Logger;
    var nTimesCalled = 0;
    var startprefs = {};
    var DEFAULT_THEME_KEY = 'curr_theme';
     // Boolean: represents that the "intro" - the one page summary
     // and the login are done
    var INTRO_DONE_KEY = 'intro_done';
    // data collection consented protocol: string, represents the date on
    // which the consented protocol was approved by the IRB
    var DATA_COLLECTION_CONSENTED_PROTOCOL = 'data_collection_consented_protocol';

    var CONSENTED_KEY = "config/consent";

    startprefs.CONSENTED_EVENT = "data_collection_consented";
    startprefs.INTRO_DONE_EVENT = "intro_done";

    startprefs.setDefaultTheme = function(new_theme) {
      storage.set(DEFAULT_THEME_KEY, new_theme);
    }

    startprefs.getDefaultTheme = function() {
      return storage.get(DEFAULT_THEME_KEY);
    }

    startprefs.loadDefaultTheme = function() {
        logger.log("About to set theme from preference");
        var curr_theme = startprefs.getDefaultTheme();
        logger.log("preferred theme = "+curr_theme);

        if (curr_theme == 'dark_theme') {
            $rootScope.dark_theme = true;
        } else {
            $rootScope.dark_theme = false;
        }
        logger.log("set dark_theme = "+$rootScope.dark_theme);
    };

    var writeConsentToNative = function() {
      return $window.cordova.plugins.BEMDataCollection.markConsented($rootScope.req_consent);
    };

    startprefs.markConsented = function() {
      logger.log("changing consent from "+
        $rootScope.curr_consented+" -> "+$rootScope.req_consent);
      // mark in native storage
      return startprefs.readConsentState().then(writeConsentToNative).then(function(response) {
          // mark in local storage
          storage.set(DATA_COLLECTION_CONSENTED_PROTOCOL,
            $rootScope.req_consent);
          // mark in local variable as well
          $rootScope.curr_consented = angular.copy($rootScope.req_consent);
          $rootScope.$emit(startprefs.CONSENTED_EVENT, $rootScope.req_consent);
      });
    };

    startprefs.markIntroDone = function() {
      storage.set(INTRO_DONE_KEY, true);
      $window.cordova.plugins.BEMUserCache.putLocalStorage(INTRO_DONE_KEY,
        {INTRO_DONE_KEY: moment().format()});
      $rootScope.$emit(startprefs.INTRO_DONE_EVENT, $rootScope.req_consent);
    }

    // returns boolean
    startprefs.isIntroDone = function() {
      var read_val = storage.get(INTRO_DONE_KEY);
      logger.log("in isIntroDone, read_val = "+read_val);
      if (read_val == null || read_val == "") {
        logger.log("in isIntroDone, returning false");
        return false;
      } else {
        logger.log("in isIntroDone, returning "+read_val);
        return read_val;
      }
    }

    startprefs.isConsented = function() {
      logger.log("curr_consented = "+$rootScope.curr_consented+
            "isIntroDone = " + startprefs.isIntroDone());
      if (startprefs.isIntroDone() &&
            ($rootScope.curr_consented == null || $rootScope.curr_consented == "")) {
        alert("intro is done, but consent not found, re-consenting...");
      }
      if ($rootScope.curr_consented == null || $rootScope.curr_consented == "" ||
            $rootScope.curr_consented.approval_date != $rootScope.req_consent.approval_date) {
        console.log("Not consented in local storage, need to show consent");
        return false;
      } else {
        console.log("Consented in local storage, no need to show consent");
        return true;
      }
    }

    startprefs.readConsentState = function() {
      /*
       * Read from local storage and move on so that we don't depend on native code.
       * Native code will be checked once the plugins are ready
       */
      if (angular.isDefined($rootScope.req_consent) &&
          angular.isDefined($rootScope.curr_consented) &&
          $rootScope.curr_consented != null) {
          // consent state is all populated
          logger.log("req_consent = "+$rootScope.req_consent
                        +" curr_consented = " + $rootScope.curr_consented);
          return new Promise(function(resolve, reject) {
            logger.log("resolving with empty information");
            resolve();
          });
      } else {
          // read consent state from the file and populate it
          return $http.get("json/startupConfig.json")
              .then(function(startupConfigResult) {
                  $rootScope.req_consent = startupConfigResult.data.emSensorDataCollectionProtocol;
                  logger.log("required consent version = " + JSON.stringify($rootScope.req_consent));
                  $rootScope.curr_consented = storage.get(
                    DATA_COLLECTION_CONSENTED_PROTOCOL);
          });
      }
    }

    /*
     * getNextState() returns a promise, since reading the startupConfig is
     * async. The promise returns an onboarding state to navigate to, or
     * null for the default state
     */

    startprefs.getPendingOnboardingState = function() {
      if (!startprefs.isIntroDone()) {
        // Since we must return a promise when the intro is done,
        // we create and return one here even though we don't need it
        return new Promise(function(resolve, reject) {
          resolve('root.intro');
        });
      } else {
        // intro is done. Now, let's read and check the current version
        // of the startup config
        return $http.get("json/startupConfig.json")
          .then(startprefs.readConsentState)
          .then(startprefs.isConsented)
          .then(function(result) {
            if (result) {
              return null;
            } else {
              return 'root.reconsent';
            }
          });
      }
    };

    startprefs.getConsentDocument = function() {
      return $window.cordova.plugins.BEMUserCache.getDocument("config/consent", false)
            .then(function(resultDoc) {
                if ($window.cordova.plugins.BEMUserCache.isEmptyDoc(resultDoc)) {
                    return null;
                } else {
                    return resultDoc;
                }
            });
    };

    startprefs.checkNativeConsent = function() {
        startprefs.getConsentDocument().then(function(resultDoc) {
            if (resultDoc == null) {
                startprefs.readConsentState()
                    .then(startprefs.isConsented)
                    .then(function(consentState) {
                        if (consentState == true) {
                            $ionicPopup.alert({template: "Local consent found, native consent missing, writing consent to native"});
                            return writeConsentToNative();
                        }
                    });
            }
        });
    }

    startprefs.checkUsercacheStorage = function(key) {
        // console.log("checkUsercacheStorage called");
        var ls_stored_val = storage.get(key);
        $window.cordova.plugins.BEMUserCache.getLocalStorage(key, false).then(function(uc_stored_val) {
            logger.log("uc_stored_val = "+JSON.stringify(uc_stored_val)+" ls_stored_val = "+ls_stored_val);
            if(angular.isDefined(uc_stored_val) && (uc_stored_val != null)
                && (key in uc_stored_val) && angular.isDefined(uc_stored_val[key])) {
                if (ls_stored_val == true) {
                    logger.log("local intro_done true, remote intro_done "+uc_stored_val[key]+", already synced");
                } else {
                    logger.log("local intro_done false, remote intro_done "+uc_stored_val[key]+", setting local");
                    $ionicPopup.alert({template: "Local "+key+" not found, native "+key+" found, writing "+key+" to local"})
                    storage.put(key, true);
                }
            } else {
                if (ls_stored_val == true) {
                    logger.log("local intro_done found, remote intro_done not found, setting remote");

                    // Need to initialize this first because if we try to
                    // create it inlike with {key: value}, the key becomes the
                    // word "key" and the stored object is
                    // {"key":"2018-01-31T06:26:02+00:00"}
                    var to_put = {};
                    to_put[key] = moment().format();
                    $window.cordova.plugins.BEMUserCache.putLocalStorage(key, to_put);
                    $ionicPopup.alert({template: "Local "+key+" found, native "+key+" missing, writing "+key+" to native"})
                } else {
                    logger.log("local intro_done false, remote intro_done not found, already synced");
                }
            }
        }).catch(function(error) {
            var display_msg = error.message + "\n" + error.stack;
            logger.log("error in checkUsercacheStorage = "+display_msg);
            $ionicPopup.alert({template: display_msg});
        });
    }

    startprefs.checkStorageConsistency = function() {
        // console.log("checkStorageConsistency called");
        startprefs.checkNativeConsent();
        startprefs.checkUsercacheStorage(INTRO_DONE_KEY);
    }

    startprefs.getNextState = function() {
      return startprefs.getPendingOnboardingState().then(function(result){
        if (result == null) {
          var temp = ReferralHandler.getReferralNavigation();
          if (temp == 'goals') {
            return 'root.main.goals';
          } else if ($rootScope.displayingIncident == true) {
            $rootScope.displayingIncident = false;
            return 'root.main.diary';
          } else if (angular.isDefined($rootScope.redirectTo)) {
            var redirState = $rootScope.redirectTo;
            $rootScope.redirectTo = undefined;
            return redirState;
          } else {
            return 'root.main.metrics';
          }
        } else {
          return result;
        }
      });
    };

    var changeState = function(destState) {
        logger.log('changing state to '+destState);
        console.log("loading "+destState);
        // TODO: Fix this the right way when we fix the FSM
        // https://github.com/e-mission/e-mission-phone/issues/146#issuecomment-251061736
        var reload = false;
        if (($state.$current == destState) && ($state.$current.name == 'root.main.goals')) {
          reload = true;
        }
        $state.go(destState).then(function() {
            if (reload) {
              $rootScope.$broadcast("RELOAD_GOAL_PAGE_FOR_REFERRAL")
            }
        });
    };

    // Currently loads main or intro based on whether onboarding is complete.
    // But easily extensible to storing the last screen that the user was on,
    // or the users' preferred screen

    startprefs.loadPreferredScreen = function() {
      logger.log("About to navigate to preferred tab");
      startprefs.getNextState().then(changeState).catch(function(error) {
        logger.log("error "+error+" loading finding tab, loading root.intro");
        changeState('root.intro');
      });
    };

    startprefs.loadWithPrefs = function() {
      // alert("attach debugger!");
      console.log("Checking to see whether we are ready to load the screen");
      if (!angular.isDefined($window.Logger)) {
          alert("ionic is ready, but logger not present?");
      }
      logger = Logger;
      startprefs.loadDefaultTheme();
      startprefs.loadPreferredScreen();
    };

    startprefs.startWithPrefs = function() {
      startprefs.loadWithPrefs();
    }

    $ionicPlatform.ready().then(function() {
      Logger.log("ionicPlatform.ready() called " + nTimesCalled+" times!");
      nTimesCalled = nTimesCalled + 1;
      startprefs.startWithPrefs();
      startprefs.checkStorageConsistency();
      Logger.log("startprefs startup done");
    });

    return startprefs;
});
<|endoftext|>


<commit_before>import ghostPaths from 'ghost/utils/ghost-paths';

var Ghost = ghostPaths();

var AuthenticationInitializer = {

    name: 'authentication',
    before: 'simple-auth',
    after: 'registerTrailingLocationHistory',

    initialize: function (container) {
        window.ENV = window.ENV || {};
        window.ENV['simple-auth'] = {
            authenticationRoute: 'signin',
            routeAfterAuthentication: 'content',
            authorizer: 'simple-auth-authorizer:oauth2-bearer'
        };
        SimpleAuth.Session.reopen({
            user: Ember.computed(function () {
                return container.lookup('store:main').find('user', 'me');
            })
        });
        SimpleAuth.Authenticators.OAuth2.reopen({
            serverTokenEndpoint: Ghost.apiRoot + '/authentication/token',
            refreshAccessTokens: true,
            makeRequest: function (url, data) {
                data.client_id = 'ghost-admin';
                return this._super(url, data);
            }
        });
    }
};

export default AuthenticationInitializer;
<commit_msg>Add authentication scope.<commit_after>import ghostPaths from 'ghost/utils/ghost-paths';

var Ghost = ghostPaths();

var AuthenticationInitializer = {

    name: 'authentication',
    before: 'simple-auth',
    after: 'registerTrailingLocationHistory',

    initialize: function (container) {
        window.ENV = window.ENV || {};
        window.ENV['simple-auth'] = {
            authenticationRoute: 'signin',
            routeAfterAuthentication: 'content',
            authorizer: 'simple-auth-authorizer:oauth2-bearer'
        };
        SimpleAuth.Session.reopen({
            user: Ember.computed(function () {
                return container.lookup('store:main').find('user', 'me');
            })
        });
        SimpleAuth.Authenticators.OAuth2.reopen({
            serverTokenEndpoint: Ghost.apiRoot + '/authentication/token',
            refreshAccessTokens: true,
            makeRequest: function (url, data) {
                data.client_id = 'ghost-admin';
                return this._super(url, data);
            }
        });
        SimpleAuth.Stores.LocalStorage.reopen({
            key: 'ghost' + (Ghost.subdir.indexOf('/') === 0 ? '-' + Ghost.subdir.substr(1) : '') + ':session'
        });
    }
};

export default AuthenticationInitializer;
<|endoftext|>


<commit_before>'use strict';

require('./routeStatsBox.less');

var Numeral = require('numeral');
var React = require('react');

var RouteElevationProfile = require('app/routeElevationProfile/routeElevationProfile');
var Route = require('common/route');

class RouteStatsBox extends React.Component {
  render() {
    if (!this.props.route) {
      return (

No route

      );
    }

    return (

Distance:

{this.formatDistanceInKilometers(this.props.route.stats.distance)}

Lowest point:

{this.formatDistanceInMeters(this.props.route.stats.minElevation)}

Highest point:

{this.formatDistanceInMeters(this.props.route.stats.maxElevation)}

Ascend:

{this.formatDistanceInMeters(this.props.route.stats.ascend)}

Descend:

{this.formatDistanceInMeters(this.props.route.stats.descend)}

Distance time:

{this.formatTime(this.props.route.stats.distanceTime)}

Total time:

{this.formatTime(this.props.route.stats.time)}

        <RouteElevationProfile elevationProfile={this.props.route.elevationProfile} />

    );
  }

  formatDistanceInKilometers(value = 0) {
    return Numeral(value).format('0.0') + ' km';
  }

  formatDistanceInMeters(value = 0) {
    return Numeral(value).format('0,0') + ' m';
  }

  formatTime(value = 0) {
    return Numeral(value * 60 * 60).format('00:00:00').replace(/^0?(\d+):0?(\d+):0?(\d+)$/, '$1 h $2 m');
  }
}

module.exports = RouteStatsBox;
<commit_msg>small visual improvement<commit_after>'use strict';

require('./routeStatsBox.less');

var Numeral = require('numeral');
var React = require('react');

var RouteElevationProfile = require('app/routeElevationProfile/routeElevationProfile');
var Route = require('common/route');

class RouteStatsBox extends React.Component {
  render() {
    if (!this.props.route) {
      return (

No route

      );
    }

    return (

Lowest point:

{this.formatDistanceInMeters(this.props.route.stats.minElevation)}

Highest point:

{this.formatDistanceInMeters(this.props.route.stats.maxElevation)}

Distance:

{this.formatDistanceInKilometers(this.props.route.stats.distance)}

Ascend:

{this.formatDistanceInMeters(this.props.route.stats.ascend)}

Descend:

{this.formatDistanceInMeters(this.props.route.stats.descend)}

Distance time:

{this.formatTime(this.props.route.stats.distanceTime)}

Total time:

{this.formatTime(this.props.route.stats.time)}

        <RouteElevationProfile elevationProfile={this.props.route.elevationProfile} />

    );
  }

  formatDistanceInKilometers(value = 0) {
    return Numeral(value).format('0.0') + ' km';
  }

  formatDistanceInMeters(value = 0) {
    return Numeral(value).format('0,0') + ' m';
  }

  formatTime(value = 0) {
    return Numeral(value * 60 * 60).format('00:00:00').replace(/^0?(\d+):0?(\d+):0?(\d+)$/, '$1 h $2 m');
  }
}

module.exports = RouteStatsBox;
<|endoftext|>


<commit_before>"use strict";
const options = require("@bcgov/pipeline-cli").Util.parseArguments();
const changeId = options.pr; //aka pull-request
const version = "1.0.0";
const name = "hets";

const phases = {
  build: {
    namespace: "e0cee6-tools",
    name: `${name}`,
    phase: "build",
    changeId: changeId,
    suffix: `-build-${changeId}`,
    instance: `${name}-build-${changeId}`,
    version: `${version}-${changeId}`,
    tag: `build-${version}-${changeId}`,
    transient: true,
  },
  dev: {
    namespace: "e0cee6-dev",
    name: `${name}`,
    phase: "dev",
    changeId: changeId,
    suffix: `-dev-${changeId}`,
    instance: `${name}-dev-${changeId}`,
    version: `${version}-${changeId}`,
    tag: `dev-${version}-${changeId}`,
    host: `hets-${changeId}-e0cee6-dev.apps.silver.devops.gov.bc.ca`,
    dotnet_env: "Development",
    dbUser: "trdbhetd",
    dbSize: "1Gi",
    transient: true,
    backupVolume: "hets",
    backupVolumeSize: "1Gi",
    verificationVolumeSize: "1Gi",
    db_cpu: "500m",
    db_memory: "512Mi",
    api_cpu: "500m",
    api_memory: "512Mi",
    client_cpu: "100m",
    client_memory: "100Mi",
  },
  test: {
    namespace: "e0cee6-dev",
    name: `${name}`,
    phase: "test",
    changeId: changeId,
    suffix: `-test`,
    instance: `${name}-test`,
    version: `${version}`,
    tag: `test-${version}`,
    host: `hets-e0cee6-test.apps.silver.devops.gov.bc.ca`,
    dbUser: "trdbhett",
    dbSize: "1Gi",
    dotnet_env: "Staging",
    backupVolume: "hets",
    backupVolumeSize: "1Gi",
    verificationVolumeSize: "1Gi",
    db_cpu: "500m",
    db_memory: "512Mi",
    api_cpu: "500m",
    api_memory: "512Mi",
    client_cpu: "100m",
    client_memory: "100Mi",
  },
  uat: {
    namespace: "e0cee6-test",
    name: `${name}`,
    phase: "uat",
    changeId: changeId,
    suffix: `-uat`,
    instance: `${name}-uat`,
    version: `${version}`,
    tag: `test-${version}`,
    host: `hets-e0cee6-uat.apps.silver.devops.gov.bc.ca`,
    dbUser: "trdbhett",
    dbSize: "1Gi",
    dotnet_env: "UAT",
    backupVolume: "hets",
    backupVolumeSize: "1Gi",
    verificationVolumeSize: "1Gi",
    db_cpu: "500m",
    db_memory: "512Mi",
    api_cpu: "500m",
    api_memory: "512Mi",
    client_cpu: "100m",
    client_memory: "100Mi",
  },
  train: {
    namespace: "e0cee6-test",
    name: `${name}`,
    phase: "train",
    changeId: changeId,
    suffix: `-train`,
    instance: `${name}-train`,
    version: `${version}`,
    tag: `train-${version}`,
    host: `hets-e0cee6-train.apps.silver.devops.gov.bc.ca`,
    dbUser: "trdbhett",
    dbSize: "1Gi",
    dotnet_env: "Training",
    backupVolume: "hets",
    backupVolumeSize: "1Gi",
    verificationVolumeSize: "1Gi",
    db_cpu: "500m",
    db_memory: "512Mi",
    api_cpu: "500m",
    api_memory: "512Mi",
    client_cpu: "100m",
    client_memory: "100Mi",
  },
  prod: {
    namespace: "e0cee6-prod",
    name: `${name}`,
    phase: "prod",
    changeId: changeId,
    suffix: `-prod`,
    instance: `${name}-prod`,
    version: `${version}`,
    tag: `prod-${version}`,
    host: `hets-e0cee6-prod.apps.silver.devops.gov.bc.ca`,
    dbUser: "trdbhetp",
    dbSize: "10Gi",
    dotnet_env: "Production",
    backupVolume: "hets",
    backupVolumeSize: "10Gi",
    verificationVolumeSize: "10Gi",
    db_cpu: "1",
    db_memory: "1Gi",
    api_cpu: "1",
    api_memory: "1.5Gi",
    client_cpu: "200m",
    client_memory: "200Mi",
  },
};

// This callback forces the node process to exit as failure.
process.on("unhandledRejection", (reason) => {
  console.log(reason);
  process.exit(1);
});

module.exports = exports = { phases, options };
<commit_msg>move test env to ocp test space<commit_after>"use strict";
const options = require("@bcgov/pipeline-cli").Util.parseArguments();
const changeId = options.pr; //aka pull-request
const version = "1.0.0";
const name = "hets";

const phases = {
  build: {
    namespace: "e0cee6-tools",
    name: `${name}`,
    phase: "build",
    changeId: changeId,
    suffix: `-build-${changeId}`,
    instance: `${name}-build-${changeId}`,
    version: `${version}-${changeId}`,
    tag: `build-${version}-${changeId}`,
    transient: true,
  },
  dev: {
    namespace: "e0cee6-dev",
    name: `${name}`,
    phase: "dev",
    changeId: changeId,
    suffix: `-dev-${changeId}`,
    instance: `${name}-dev-${changeId}`,
    version: `${version}-${changeId}`,
    tag: `dev-${version}-${changeId}`,
    host: `hets-${changeId}-e0cee6-dev.apps.silver.devops.gov.bc.ca`,
    dotnet_env: "Development",
    dbUser: "trdbhetd",
    dbSize: "1Gi",
    transient: true,
    backupVolume: "hets",
    backupVolumeSize: "1Gi",
    verificationVolumeSize: "1Gi",
    db_cpu: "500m",
    db_memory: "512Mi",
    api_cpu: "500m",
    api_memory: "512Mi",
    client_cpu: "100m",
    client_memory: "100Mi",
  },
  test: {
    namespace: "e0cee6-test",
    name: `${name}`,
    phase: "test",
    changeId: changeId,
    suffix: `-test`,
    instance: `${name}-test`,
    version: `${version}`,
    tag: `test-${version}`,
    host: `hets-e0cee6-test.apps.silver.devops.gov.bc.ca`,
    dbUser: "trdbhett",
    dbSize: "1Gi",
    dotnet_env: "Staging",
    backupVolume: "hets",
    backupVolumeSize: "1Gi",
    verificationVolumeSize: "1Gi",
    db_cpu: "500m",
    db_memory: "512Mi",
    api_cpu: "500m",
    api_memory: "512Mi",
    client_cpu: "100m",
    client_memory: "100Mi",
  },
  uat: {
    namespace: "e0cee6-test",
    name: `${name}`,
    phase: "uat",
    changeId: changeId,
    suffix: `-uat`,
    instance: `${name}-uat`,
    version: `${version}`,
    tag: `test-${version}`,
    host: `hets-e0cee6-uat.apps.silver.devops.gov.bc.ca`,
    dbUser: "trdbhett",
    dbSize: "1Gi",
    dotnet_env: "UAT",
    backupVolume: "hets",
    backupVolumeSize: "1Gi",
    verificationVolumeSize: "1Gi",
    db_cpu: "500m",
    db_memory: "512Mi",
    api_cpu: "500m",
    api_memory: "512Mi",
    client_cpu: "100m",
    client_memory: "100Mi",
  },
  train: {
    namespace: "e0cee6-test",
    name: `${name}`,
    phase: "train",
    changeId: changeId,
    suffix: `-train`,
    instance: `${name}-train`,
    version: `${version}`,
    tag: `train-${version}`,
    host: `hets-e0cee6-train.apps.silver.devops.gov.bc.ca`,
    dbUser: "trdbhett",
    dbSize: "1Gi",
    dotnet_env: "Training",
    backupVolume: "hets",
    backupVolumeSize: "1Gi",
    verificationVolumeSize: "1Gi",
    db_cpu: "500m",
    db_memory: "512Mi",
    api_cpu: "500m",
    api_memory: "512Mi",
    client_cpu: "100m",
    client_memory: "100Mi",
  },
  prod: {
    namespace: "e0cee6-prod",
    name: `${name}`,
    phase: "prod",
    changeId: changeId,
    suffix: `-prod`,
    instance: `${name}-prod`,
    version: `${version}`,
    tag: `prod-${version}`,
    host: `hets-e0cee6-prod.apps.silver.devops.gov.bc.ca`,
    dbUser: "trdbhetp",
    dbSize: "10Gi",
    dotnet_env: "Production",
    backupVolume: "hets",
    backupVolumeSize: "10Gi",
    verificationVolumeSize: "10Gi",
    db_cpu: "1",
    db_memory: "1Gi",
    api_cpu: "1",
    api_memory: "1.5Gi",
    client_cpu: "200m",
    client_memory: "200Mi",
  },
};

// This callback forces the node process to exit as failure.
process.on("unhandledRejection", (reason) => {
  console.log(reason);
  process.exit(1);
});

module.exports = exports = { phases, options };
<|endoftext|>


<commit_before>// For token sale holders:
// 1. Add the address users are sending to
// 2. Add the gas limit users should use to send successfully (this avoids OOG errors)
// 3. Add any data if applicable
// 4. Add a message if you want.
// Token Calendar: If you aren't on the above, you should get on it.
// http://www.tokensalecalendar.com/

module.exports = [{
// Accord (ARD) Token sale
to:         '0x75aa7b0d02532f3833b66c7f0ad35376d373ddf8',
gasLimit:   300000,
data:       '',
msg:        ' Accord (ARD) ERC20 token with life time buy back guarantee: http://accordtoken.com'
},{
// MNT Token Sale
to:         '0xA9877b1e05D035899131DBd1e403825166D09f92',
gasLimit:   200000,
data:       '',
msg:        'MNT Token Sale - http://mnt.coinjoker.com'
},{
// PUC Token Sale
to:         '0xEf6B4cE8C9Bc83744fbcdE2657b32eC18790458A',
gasLimit:   930000,
data:       '',
msg:        'MNT Token Sale - http://price-s.info'
},{
// DIVX Token Sale
to:         '0x13f11C9905A08ca76e3e853bE63D4f0944326C72',
gasLimit:   300000,
data:       '0xb4427263',
msg:        'DIVX Token Sale - www.diviproject.org'
},{
// NOX Token Sale
to:         '0x4b0712de9b75bc68a566215acca876ea5e55c172',
gasLimit:   114293,
data:       '',
msg:        'NOX Token Sale'
},{
// GEE Token Sale
to:         '0xF5DFFdEAEA54bB56156B47de1C7b4346c7dBa69C',
gasLimit:   180000,
data:       '',
msg:        'GEE Token Sale'
},{
// STORM tokens
to:         '0xc88c7e1AEbd89187d13bD42e1ff814d32f492BF6',
gasLimit:   250000,
data:       '',
msg:        'STORM token sale: gamified micro-tasks - Earn anywhere, anytime, from any device. https://www.stormtoken.com, NOV 7, 2017'
},{
// RVL tokens
to:         '0xDd64EF0c8a41d8a17F09ce2279D79b3397184A10',
gasLimit:   200000,
data:       '',
msg:        'RVL token sale: PRE-ICO SUPER SALE, SHARING ECONOMY PIATTAFORM,  https://www.R-EVOLUTIONCOIN.COM.com, DIC 15, 2017'
},{
// Aigang (AIX) ICO Sale
to:         ' 0xeA0c348A297084BFFbddad7f89216F24a2106E58',
gasLimit:   300000,
data:       '',
msg:        'Aigang token sale contract. Autonomous insurance network - fully automated insurance for IoT devices and a platform for insurance innovation built around data: https://aigang.network . Ends 12/15/2017'
},{
// Confideal (CDL)
to:         '0x17681500757628C7AA56d7E6546E119f94Dd9479',
gasLimit:   170000,
data:       '',
msg:        'Confideal token sale. Confideal is a platform for making deals. https://confideal.io, ends Jan 31, 2018'
},{
// Vibehub (VIBEX) ICO Sale
to:         '0x5454af9d2ba75a60fa5b0419c251810544cea21d',
gasLimit:   200000,
data:       '',
msg:        'WeBetCrypto ICO Sale. Thank you for your support!'
},{
// Vibehub (VIBEX) ICO Sale
to:         '0x882448f83d90b2bf477af2ea79327fdea1335d93',
gasLimit:   200000,
data:       '',
msg:        'Vibehub ICO Sale. Thank you for your support!'
},{
// Trade.io (TIO) ICO Sale
to:         '0xdea6d29da64bba5ab86a7424ca894756e7ae8ed3',
gasLimit:   200000,
data:       '',
msg:        'Trade.io ICO Sale. Thank you for your support!'
},{
// Substratum (SUB) Network ICO Sale
to:         '0xaf518d65f84e4695a4da0450ec02c1248f56b668',
gasLimit:   200000,
data:       '',
msg:        'Substratum Network ICO Sale. Thank you for your support!'
},{
// YUPIE (YUPIE)
to:         '0x0F33bb20a282A7649C7B3AFf644F084a9348e933',
gasLimit:   400000,
data:       '',
msg:        'YUPIE (YUPIE) ICO'
},{
// horizonstate.com Horizon State Token Sale
to:         '0xbD2ED3E85faa3433c068c7B3f9C8C7d839CE88d7',
gasLimit:   69153,
data:       '',
msg:        'Horizon State Token Sale. Thank you for your support. '
},{
// DataBrokerDAO
to:         '0x8aec8f09a840faea966f4b0e29a497d8f5b5a6b4',
gasLimit:   200000,
data:       '',
msg:        'DataBrokerDAO. https://databrokerdao.com'
},{
// BattleDrome
to:         '0xeaAf270436a0ed397ED23BBF64DF7b1DCAfF142F',
gasLimit:   85000,
data:       '',
msg:        'BattleDrome ICO/Crowdsale. Thanks for your support!'
},{
// Simple Token (ST)
to:         '0x58b7056DeB51eD292614F0DA1E94E7e9c589828d',
gasLimit:   150000,
data:       '',
msg:        'Simple Token — the cryptocurrency that powers digital communities.'
},{
// SunContract
to:         '0x5fb3D432bae33FCd418edE263D98D7440E7fA3ea',
gasLimit:   200000,
data:       '',
msg:        'SunContract ICO address - suncontract.org'
},{
// NVC
to:         '0xd88755197e107603C139df6E709ed09EEC6b6bB3',
gasLimit:   200000,
data:       '',
msg:        'NVC Fund'
},{
// Ohni
to:         '0x2a8a7afa955d8616e2e60e454e5a9c6b6c0a60fc',
gasLimit:   200000,
data:       '',
msg:        'OHNI ICO. Restoration of our communities!'
},{
// Easy Homes Token (EHT)
to:         '0xf9F0FC7167c311Dd2F1e21E9204F87EBA9012fB2',
gasLimit:   200000,
data:       '',
msg:        'Easy Homes ICO. Thank you!'
},{
// Mitrav (MTR) ICO Sale
to:         '0x7FC408011165760eE31bE2BF20dAf450356692Af',
gasLimit:   200000,
data:       '',
msg:        'Mitrav ICO Sale. Thank you for your support!'
},{
// WinBitcoin (WBC) ICO Sale
to:         '0xA5DD8cDe486436F0Cfd62652952E1fcEC5A61CAe',
gasLimit:   300000,
data:       '',
msg:        'WinBitcoin ICO Sale. Thank you for your support!'
},{
// BMCHAIN ICO
to:         '0x19d7a9ad3b49252fd2ef640d0e43dfd651168499',
gasLimit:   100000,
data:       '',
msg:        'BMChain ICO - Platform of digital reputation - Official site https://bmchain.io'
},{
// TBOT Token Sale
to:         '0xAFe60511341a37488de25Bef351952562E31fCc1',
gasLimit:   200000,
data:       '',
msg:        'Tbot ICO Sale.'
},{
// Zeus exchange token sale
to:         '0xe386B139Ed3715Ca4B18Fd52671bDcea1cdFE4b1',
gasLimit:   200000,
data:       '',
msg:        'Zeus Exchange - The First Hybrid Trading Platform for Traditional Stock Investors and Crypto Traders. Official site https://zeus.exchange'
},{
// Game Token Sale
to:         '0xB70835D7822eBB9426B56543E391846C107bd32C',
gasLimit:   200000,
data:       '',
msg:        'Game Token Sale'
},{
// Rebellious Token
to:         '0x5f53f7a8075614b699baad0bc2c899f4bad8fbbf',
gasLimit:   200000,
data:       '',
msg:        'Rebellious Token'
},{
  // Ethereum High Token Sale
to:         '0xd5E3036d5CE7eC222379D16f6ffC38C38c55BF7f',
gasLimit:   200000,
data:       '',
msg:        'Ethereum High HIG is a robust and feather-light cryptocurrency designed to hedge the risk of your portfolio'
},{
to:         '0x2a3Aa9ECA41E720Ed46B5A70D6C37EfA47f768Ac',
gasLimit:   200000,
data:       '',
msg:        'REAL CHAIN TOKEN!'
},{
// Artex Token Sale (ARX)
to:         '0x7705FaA34B16EB6d77Dfc7812be2367ba6B0248e',
gasLimit:   200000,
data:       '',
msg:        'Artex - Art Provenance Blockchain. Official site https://artex.global'
},
{
// Sirin Token Sale (SRN)
to:         '0x29AfA3443f752eb29d814d9042Fd88A4a2dc0F1e',
gasLimit:   200000,
data:       '',
msg:        'SIRIN LABS official crowdsale address. Official website https://sirinlabs.com'
},{
// TRV Token Sale
to:         '0xA671f2914Ba0e73979FFc47cD350801d1714b18f',
gasLimit:   150000,
data:       '',
msg:        'TRV Ongoing Sale.'
},{
// Bitlle Token Sale (BTL)
to:         '0x92685E93956537c25Bb75D5d47fca4266dd628B8',
gasLimit:   200000,
data:       '',
msg:        'Bitlle Token. Official website https://bitlle.com'
},{
// EDU Token Sale (LiveEdu.tv)
to:         '0x2097175d0abb8258f2468E3487F8db776E29D076',
gasLimit:   200000,
data:       '',
msg:        'LiveEdu EDU token sale. Official website: https://tokensale.liveedu.tv/'
},{
// HEdpAY (Hdp.ф) Sale (hedpay.com)
to:         '0x4F8B6cA78711207E1B281DB63e8d6EAA1ce2F63E',
gasLimit:   230000,
data:       '',
msg:        'HEdpAY (Hdp.ф) sale. Official sale website: https://ibiginvestments.com/hedpay'
}]
<commit_msg>Update customGas.js<commit_after>// For token sale holders:
// 1. Add the address users are sending to
// 2. Add the gas limit users should use to send successfully (this avoids OOG errors)
// 3. Add any data if applicable
// 4. Add a message if you want.
// Token Calendar: If you aren't on the above, you should get on it.
// http://www.tokensalecalendar.com/

module.exports = [{
// Accord (ARD) Token sale
to:         '0x75aa7b0d02532f3833b66c7f0ad35376d373ddf8',
gasLimit:   300000,
data:       '',
msg:        ' Accord (ARD) ERC20 token sale - http://accordtoken.com'
},{
// MNT Token Sale
to:         '0xA9877b1e05D035899131DBd1e403825166D09f92',
gasLimit:   200000,
data:       '',
msg:        'MNT Token Sale - http://mnt.coinjoker.com'
},{
// PUC Token Sale
to:         '0xEf6B4cE8C9Bc83744fbcdE2657b32eC18790458A',
gasLimit:   930000,
data:       '',
msg:        'MNT Token Sale - http://price-s.info'
},{
// DIVX Token Sale
to:         '0x13f11C9905A08ca76e3e853bE63D4f0944326C72',
gasLimit:   300000,
data:       '0xb4427263',
msg:        'DIVX Token Sale - www.diviproject.org'
},{
// NOX Token Sale
to:         '0x4b0712de9b75bc68a566215acca876ea5e55c172',
gasLimit:   114293,
data:       '',
msg:        'NOX Token Sale'
},{
// GEE Token Sale
to:         '0xF5DFFdEAEA54bB56156B47de1C7b4346c7dBa69C',
gasLimit:   180000,
data:       '',
msg:        'GEE Token Sale'
},{
// STORM tokens
to:         '0xc88c7e1AEbd89187d13bD42e1ff814d32f492BF6',
gasLimit:   250000,
data:       '',
msg:        'STORM token sale: gamified micro-tasks - Earn anywhere, anytime, from any device. https://www.stormtoken.com, NOV 7, 2017'
},{
// RVL tokens
to:         '0xDd64EF0c8a41d8a17F09ce2279D79b3397184A10',
gasLimit:   200000,
data:       '',
msg:        'RVL token sale: PRE-ICO SUPER SALE, SHARING ECONOMY PIATTAFORM,  https://www.R-EVOLUTIONCOIN.COM.com, DIC 15, 2017'
},{
// Aigang (AIX) ICO Sale
to:         ' 0xeA0c348A297084BFFbddad7f89216F24a2106E58',
gasLimit:   300000,
data:       '',
msg:        'Aigang token sale contract. Autonomous insurance network - fully automated insurance for IoT devices and a platform for insurance innovation built around data: https://aigang.network . Ends 12/15/2017'
},{
// Confideal (CDL)
to:         '0x17681500757628C7AA56d7E6546E119f94Dd9479',
gasLimit:   170000,
data:       '',
msg:        'Confideal token sale. Confideal is a platform for making deals. https://confideal.io, ends Jan 31, 2018'
},{
// Vibehub (VIBEX) ICO Sale
to:         '0x5454af9d2ba75a60fa5b0419c251810544cea21d',
gasLimit:   200000,
data:       '',
msg:        'WeBetCrypto ICO Sale. Thank you for your support!'
},{
// Vibehub (VIBEX) ICO Sale
to:         '0x882448f83d90b2bf477af2ea79327fdea1335d93',
gasLimit:   200000,
data:       '',
msg:        'Vibehub ICO Sale. Thank you for your support!'
},{
// Trade.io (TIO) ICO Sale
to:         '0xdea6d29da64bba5ab86a7424ca894756e7ae8ed3',
gasLimit:   200000,
data:       '',
msg:        'Trade.io ICO Sale. Thank you for your support!'
},{
// Substratum (SUB) Network ICO Sale
to:         '0xaf518d65f84e4695a4da0450ec02c1248f56b668',
gasLimit:   200000,
data:       '',
msg:        'Substratum Network ICO Sale. Thank you for your support!'
},{
// YUPIE (YUPIE)
to:         '0x0F33bb20a282A7649C7B3AFf644F084a9348e933',
gasLimit:   400000,
data:       '',
msg:        'YUPIE (YUPIE) ICO'
},{
// horizonstate.com Horizon State Token Sale
to:         '0xbD2ED3E85faa3433c068c7B3f9C8C7d839CE88d7',
gasLimit:   69153,
data:       '',
msg:        'Horizon State Token Sale. Thank you for your support. '
},{
// DataBrokerDAO
to:         '0x8aec8f09a840faea966f4b0e29a497d8f5b5a6b4',
gasLimit:   200000,
data:       '',
msg:        'DataBrokerDAO. https://databrokerdao.com'
},{
// BattleDrome
to:         '0xeaAf270436a0ed397ED23BBF64DF7b1DCAfF142F',
gasLimit:   85000,
data:       '',
msg:        'BattleDrome ICO/Crowdsale. Thanks for your support!'
},{
// Simple Token (ST)
to:         '0x58b7056DeB51eD292614F0DA1E94E7e9c589828d',
gasLimit:   150000,
data:       '',
msg:        'Simple Token — the cryptocurrency that powers digital communities.'
},{
// SunContract
to:         '0x5fb3D432bae33FCd418edE263D98D7440E7fA3ea',
gasLimit:   200000,
data:       '',
msg:        'SunContract ICO address - suncontract.org'
},{
// NVC
to:         '0xd88755197e107603C139df6E709ed09EEC6b6bB3',
gasLimit:   200000,
data:       '',
msg:        'NVC Fund'
},{
// Ohni
to:         '0x2a8a7afa955d8616e2e60e454e5a9c6b6c0a60fc',
gasLimit:   200000,
data:       '',
msg:        'OHNI ICO. Restoration of our communities!'
},{
// Easy Homes Token (EHT)
to:         '0xf9F0FC7167c311Dd2F1e21E9204F87EBA9012fB2',
gasLimit:   200000,
data:       '',
msg:        'Easy Homes ICO. Thank you!'
},{
// Mitrav (MTR) ICO Sale
to:         '0x7FC408011165760eE31bE2BF20dAf450356692Af',
gasLimit:   200000,
data:       '',
msg:        'Mitrav ICO Sale. Thank you for your support!'
},{
// WinBitcoin (WBC) ICO Sale
to:         '0xA5DD8cDe486436F0Cfd62652952E1fcEC5A61CAe',
gasLimit:   300000,
data:       '',
msg:        'WinBitcoin ICO Sale. Thank you for your support!'
},{
// BMCHAIN ICO
to:         '0x19d7a9ad3b49252fd2ef640d0e43dfd651168499',
gasLimit:   100000,
data:       '',
msg:        'BMChain ICO - Platform of digital reputation - Official site https://bmchain.io'
},{
// TBOT Token Sale
to:         '0xAFe60511341a37488de25Bef351952562E31fCc1',
gasLimit:   200000,
data:       '',
msg:        'Tbot ICO Sale.'
},{
// Zeus exchange token sale
to:         '0xe386B139Ed3715Ca4B18Fd52671bDcea1cdFE4b1',
gasLimit:   200000,
data:       '',
msg:        'Zeus Exchange - The First Hybrid Trading Platform for Traditional Stock Investors and Crypto Traders. Official site https://zeus.exchange'
},{
// Game Token Sale
to:         '0xB70835D7822eBB9426B56543E391846C107bd32C',
gasLimit:   200000,
data:       '',
msg:        'Game Token Sale'
},{
// Rebellious Token
to:         '0x5f53f7a8075614b699baad0bc2c899f4bad8fbbf',
gasLimit:   200000,
data:       '',
msg:        'Rebellious Token'
},{
  // Ethereum High Token Sale
to:         '0xd5E3036d5CE7eC222379D16f6ffC38C38c55BF7f',
gasLimit:   200000,
data:       '',
msg:        'Ethereum High HIG is a robust and feather-light cryptocurrency designed to hedge the risk of your portfolio'
},{
to:         '0x2a3Aa9ECA41E720Ed46B5A70D6C37EfA47f768Ac',
gasLimit:   200000,
data:       '',
msg:        'REAL CHAIN TOKEN!'
},{
// Artex Token Sale (ARX)
to:         '0x7705FaA34B16EB6d77Dfc7812be2367ba6B0248e',
gasLimit:   200000,
data:       '',
msg:        'Artex - Art Provenance Blockchain. Official site https://artex.global'
},
{
// Sirin Token Sale (SRN)
to:         '0x29AfA3443f752eb29d814d9042Fd88A4a2dc0F1e',
gasLimit:   200000,
data:       '',
msg:        'SIRIN LABS official crowdsale address. Official website https://sirinlabs.com'
},{
// TRV Token Sale
to:         '0xA671f2914Ba0e73979FFc47cD350801d1714b18f',
gasLimit:   150000,
data:       '',
msg:        'TRV Ongoing Sale.'
},{
// Bitlle Token Sale (BTL)
to:         '0x92685E93956537c25Bb75D5d47fca4266dd628B8',
gasLimit:   200000,
data:       '',
msg:        'Bitlle Token. Official website https://bitlle.com'
},{
// EDU Token Sale (LiveEdu.tv)
to:         '0x2097175d0abb8258f2468E3487F8db776E29D076',
gasLimit:   200000,
data:       '',
msg:        'LiveEdu EDU token sale. Official website: https://tokensale.liveedu.tv/'
},{
// HEdpAY (Hdp.ф) Sale (hedpay.com)
to:         '0x4F8B6cA78711207E1B281DB63e8d6EAA1ce2F63E',
gasLimit:   230000,
data:       '',
msg:        'HEdpAY (Hdp.ф) sale. Official sale website: https://ibiginvestments.com/hedpay'
}]
<|endoftext|>


<commit_before>import {
    findIndexes,
    getIndex,
    getUnbuilt,
    createIndex,
    getIndexHistory
} from "./actions";
import {
    FIND_INDEXES,
    GET_INDEX,
    GET_UNBUILT,
    CREATE_INDEX,
    GET_INDEX_HISTORY
} from "../actionTypes";

describe("Indexes Action Creators:", () => {

    it("findIndexes: returns simple action", () => {
        const result = findIndexes();
        const expected = {
            type: "FIND_INDEXES_REQUESTED"
        };

        expect(result).toEqual(expected);
    });

    it("getIndex: returns action to get specific index version", () => {
        const indexVersion = "3";
        const result = getIndex(indexVersion);
        const expected = {
            type: "GET_INDEX_REQUESTED",
            indexVersion
        };

        expect(result).toEqual(expected);
    });

    it("getUnbuilt: returns simple action", () => {
        const result = getUnbuilt();
        const expected = {
            type: "GET_UNBUILT_REQUESTED"
        };

        expect(result).toEqual(expected);
    });

    it("createIndex: returns simple action", () => {
        const result = createIndex();
        const expected = {
            type: "CREATE_INDEX_REQUESTED"
        };

        expect(result).toEqual(expected);
    });

    it("getIndexHistory: returns action to retrieve the index changes history", () => {
        const indexVersion = "3";
        const page = "1";
        const result = getIndexHistory(indexVersion, page);
        const expected = {
            type: "GET_INDEX_HISTORY_REQUESTED",
            indexVersion,
            page
        };

        expect(result).toEqual(expected);
    });

});
<commit_msg>Update index action test<commit_after>import {
    findIndexes,
    getIndex,
    getUnbuilt,
    createIndex,
    getIndexHistory
} from "./actions";
import {
    FIND_INDEXES,
    GET_INDEX,
    GET_UNBUILT,
    CREATE_INDEX,
    GET_INDEX_HISTORY
} from "../actionTypes";

describe("Indexes Action Creators:", () => {

    it("findIndexes: returns simple action", () => {
        const result = findIndexes();
        const expected = {
            type: "FIND_INDEXES_REQUESTED"
        };

        expect(result).toEqual(expected);
    });

    it("getIndex: returns action to get specific index version", () => {
        const indexId = "abc123";
        const result = getIndex(indexId);
        const expected = {
            type: "GET_INDEX_REQUESTED",
            indexId
        };

        expect(result).toEqual(expected);
    });

    it("getUnbuilt: returns simple action", () => {
        const result = getUnbuilt();
        const expected = {
            type: "GET_UNBUILT_REQUESTED"
        };

        expect(result).toEqual(expected);
    });

    it("createIndex: returns simple action", () => {
        const result = createIndex();
        const expected = {
            type: "CREATE_INDEX_REQUESTED"
        };

        expect(result).toEqual(expected);
    });

    it("getIndexHistory: returns action to retrieve the index changes history", () => {
        const indexVersion = "3";
        const page = "1";
        const result = getIndexHistory(indexVersion, page);
        const expected = {
            type: "GET_INDEX_HISTORY_REQUESTED",
            indexVersion,
            page
        };

        expect(result).toEqual(expected);
    });

});
<|endoftext|>


<commit_before>'use strict';

var querystring = require('querystring');

module.exports = function(req, res, next){
	if((req.method === 'POST' || req.method === 'PATCH') && req.body){
		req.body = querystring.stringify(req.body);
	}
	next();
};<commit_msg>Removed files<commit_after><|endoftext|>