<commit_before>define('app/controllers/backends', ['app/models/backend', 'ember'],
    //
    //  Backends Controller
    //
    //  @returns Class
    //
    function (Backend) {

        'use strict';

        return Ember.Controller.extend(Ember.Evented, {

            //
            //  Properties
            //

            model: [],
            imageCount: 0,
            machineCount: 0,
            networkCount: 0,
            machines: [],
            sortBy: 'state',
            displayCount: 30,
            selectedMachines: [],
            selectedNetworks: [],
            machineRequest: false,
            networkRequest: false,
            imageRequest: false,

            addingBackend: false,
            deletingBackend: false,
            togglingBackend: false,
            checkedMonitoring: false,
            checkingMonitoring: false,

            loading: true,
            loadingImages: false,
            loadingMachines: false,

            hasOpenStack: function () {
                return !!this.model.filterBy('enabled', true).findBy('isOpenStack', true);
            }.property('model.[].isOpenStack', 'model.[].enabled'),

            hasNetworks: function () {
                return !!this.model.findBy('hasNetworks', true);
            }.property('model.[].hasNetworks'),

<<<<<<< HEAD
            filteredMachines: Ember.computed('machines', 'searchMachinesTerm', function() {
                var filteredMachines = [];

                if (this.searchMachinesTerm) {
                    var that = this;
                    this.machines.forEach(function(machine) {
                        var regex = new RegExp(that.searchMachinesTerm, 'i');

                        if (regex.test(machine.name)) {
                            filteredMachines.push(machine);
                        } else {
                            if (machine.selected) {
                                machine.set('selected', false);
                            }
                        }
                    });
                } else {
                    filteredMachines = this.machines;
                }

                return filteredMachines;
            }),

            sortedMachines: Ember.computed('filteredMachines', 'filteredMachines.@each.stateWeight', 'filteredMachines.@each.name', 'filteredMachines.@each.backend.title', 'sortBy', function() {
                if(this.get('filteredMachines'))
                {
                    if (this.get('sortBy') == 'state')
                    {
                        return this.get('filteredMachines').sortBy('stateWeight').reverse();
                    }

                    if (this.get('sortBy') == 'name')
                    {
                        return this.get('filteredMachines').sortBy('name');
                    }

                    if (this.get('sortBy') == 'cloud')
                    {
                        return this.get('filteredMachines').sortBy('backend.title', 'name');
                    }
                }
            }),

            sortedMachines: Ember.computed.sort('machines', function(a, b){
                if (Mist.backendsController.sortBy == 'name')
                    return a.name.localeCompare(b.name);
                else
                    return b.get('stateWeight') - a.get('stateWeight');
            }).property('machines', 'sortBy', 'machines.@each.stateWeight', 'machines.@each.name'),

            //
            //  Initialization
            //

            load: function (backends) {
                this._updateModel(backends);
                this.set('loading', false);
            },

            //
            //  Methods
            //

            addBackend: function (args) {
                var key = Mist.keysController.keyExists(args.payload.key) ? args.payload.key : null;
                var that = this;
                this.set('addingBackend', true);
                Mist.ajax.POST('/backends', args.payload)
                .success(function (backend) {
                    that._addBackend(backend, key);
                }).error(function (message) {
                    Mist.notificationController.notify(
                        'Failed to add backend: ' + message);
                }).complete(function (success, backend) {
                    that.set('addingBackend', false);
                    if (args.callback) args.callback(success, backend);
                });
            },

            renameBackend: function (args) {
                var that = this;
                this.set('renamingBackend', true);
                Mist.ajax.PUT('/backends/' + args.backend.id, {
                    'new_name': args.newTitle
                }).success(function () {
                    that._renameBackend(args.backend, args.newTitle);
                }).error(function () {
                    Mist.notificationController.notify(
                        'Failed to rename backend');
                }).complete(function (success) {
                    that.set('renamingBackend', false);
                    Mist.backendEditController.set('editingBackend', false);
                    if (args.callback) args.callback(success);
                });
            },

            deleteBackend: function(args) {
                var that = this;
                this.set('deletingBackend', true);
                Mist.ajax.DELETE('/backends/' + args.backend.id, {
                }).success(function() {
                    that._deleteBackend(args.backend);
                }).error(function() {
                    Mist.notificationController.notify(
                        'Failed to delete backend');
                }).complete(function(success) {
                    that.set('deletingBackend', false);
                    if (args.callback) args.callback(success);
                });
            },

            toggleBackend: function(args) {
                var that = this;
                this.set('togglingBackend', true);
                Mist.ajax.POST('/backends/' + args.backend.id, {
                    'new_state': args.newState.toString()
                }).success(function () {
                    that._toggleBackend(args.backend, args.newState);
                }).error(function () {
                    Mist.notificationController.notify(
                        "Failed to change backend's state");
                }).complete(function (success) {
                    that.set('togglingBackend', false);
                    if (args.callback) args.callback(success);
                });
            },

            probeMachine: function(machine, keyId, callback) {
                // TODO: This should be moved inside machines controller

                if (!machine.id || machine.id == -1) return;
                if (!machine.state == 'running') return;

                var host = machine.getHost();
                if (!host) return;

                var key = Mist.keysController.getKey(keyId);
                if (key) {
                    machine.set('probing', keyId);
                    key.set('probing', machine);
                } else {
                    machine.set('probing', true);
                }
                var that = this;
                var uptime = null;
                Mist.ajax.POST('/backends/' + machine.backend.id + '/machines/' + machine.id + '/probe', {
                    'host': host,
                    'key': keyId
                }).success(function (data) {
                    machine.probeSuccess(data);
                }).error(function(message) {
                    console.log(message);
                    if (!machine.backend || !machine.backend.enabled) return;
                    if (key) Mist.notificationController.notify(message);
                }).complete(function(success, data) {
                    if (!machine.backend || !machine.backend.enabled) return;
                    if (key)
                        key.set('probing', false);
                    machine.set('probing', false);
                    that.trigger('onMachineProbe');
                    if (callback) callback(!!data.uptime, data);
                });
            },

            providerList: function() {
                return SUPPORTED_PROVIDERS.map(function (provider) {
                    provider.className = 'provider-';
                    if (provider.provider == 'bare_metal')
                        provider.className += 'baremetal';
                    else if (provider.provider == 'indonesian_vcloud')
                        provider.className += 'indonesian';
                    else
                        provider.className += provider.provider;
                    return provider;
                }).sort(function (a, b) {
                    if (a.provider == 'bare_metal')
                        return 1;
                    if (b.provider == 'bare_metal')
                        return -1;
                    if (a.title > b.title)
                        return 1;
                    if (a.title < b.title)
                        return -1
                    return 0;
                });
            }.property('providerList'),

            getRequestedMachine: function() {
                if (this.machineRequest) {
                    return this.getMachine(this.machineRequest);
                }
            },

            getRequestedNetwork: function () {
                if (this.networkRequest) {
                    return this.getNetwork(this.networkRequest);
                }
            },

            getRequestedImage: function () {
                if (this.imageRequest) {
                    return this.getImage(this.imageRequest);
                }
            },

            getBackend: function(backendId) {
                return this.model.findBy('id', backendId);
            },

            getMachine: function(machineId, backendId) {
                if (backendId) {
                    var backend = this.getBackend(backendId);
                    if (backend)
                        return backend.getMachine(machineId);
                    return null;
                }

                var machine = null;
                this.model.some(function(backend) {
                    return machine = backend.getMachine(machineId);
                });
                return machine;
            },

            getNetwork: function (networkId, backendId) {
                if (backendId) {
                    var backend = this.getBackend(backendId);
                    if (backend)
                        return backend.getNetwork(networkId);
                    return null;
                }

                var network = null;
                this.model.some(function(backend) {
                    return network = backend.getNetwork(networkId);
                });
                return network;
            },

            getImage: function(imageId, backendId) {
                if (backendId) {
                    var backend = this.getBackend(backendId);
                    if (backend)
                        return backend.getImage(imageId);
                    return null;
                }

                var image = null;
                this.model.some(function(backend) {
                    return image = backend.getImage(imageId);
                });
                return image;
            },

            machineExists: function(machineId, backendId) {
                return !!this.getMachine(machineId, backendId);
            },

            backendExists: function(backendId) {
                return !!this.getBackend(backendId);
            },

            networkExists: function (networkId, backendId) {
                return !!this.getNetwork(networkId, backendId);
            },

            //
            //  Psudo-Private Methods
            //

            _updateModel: function (backends) {
                Ember.run(this, function() {
                    // Remove deleted backends
                    this.model.forEach(function (backend) {
                        if (!backends.findBy('id', backend.id))
                            this.model.removeObject(backend);
                    }, this);

                    backends.forEach(function (backend) {

                        var oldBackend = this.getBackend(backend.id);

                        if (oldBackend)
                            // Update existing backends
                            forIn(backend, function (value, property) {
                                oldBackend.set(property, value);
                            });
                        else
                            // Add new backends
                            this._addBackend(backend);
                    }, this);

                    this.trigger('onBackendListChange');
                });
            },

            _addBackend: function(backend, keyId) {
                Ember.run(this, function() {
                    if (this.backendExists(backend.id)) return;
                    var backendModel = Backend.create(backend);
                    this.model.addObject(backendModel);
                    // <TODO (gtsop): move this code into backend model
                    if (keyId)
                        backendModel.one('onMachineListChange', function() {
                            if (backendModel.provider == 'bare_metal') {
                                Mist.keysController._associateKey(keyId,
                                    backendModel.machines.model[0]);
                            }
                        });
                    // />
                    this.trigger('onBackendAdd');
                });
            },

            _deleteBackend: function(backend) {
                Ember.run(this, function() {
                    this.model.removeObject(backend);
                    this.trigger('onBackendDelete');
                });
            },

            _renameBackend: function(backend, newTitle) {
                Ember.run(this, function() {
                    backend.set('title', newTitle);
                    this.trigger('onBackendRename');
                });
            },

            _toggleBackend: function(backend, newState) {
                Ember.run(this, function() {
                    backend.set('enabled', newState);
                    this.trigger('onBackendToggle');
                });
            },

            _updateImageCount: function() {
                Ember.run(this, function() {
                    var counter = 0;
                    this.model.forEach(function(backend) {
                        if (backend.enabled)
                            counter += backend.images.model.length;
                    });
                    if (counter != this.get('imageCount')){
                        this.set('imageCount', counter);
                        this.trigger('onImagesChange');
                    }
                });
            },

            _updateMachineCount: function() {
                Ember.run(this, function() {
                    var counter = 0;
                    this.model.forEach(function(backend) {
                        if (backend.enabled) counter += backend.machineCount;
                    });
                    this.set('machineCount', counter);
                    this.trigger('onMachineListChange');
                });
            },

            _updateNetworkCount: function() {
                Ember.run(this, function() {
                    var counter = 0;
                    this.model.forEach(function (backend) {
                        if (backend.enabled)
                            counter += backend.networkCount;
                    });
                    this.set('networkCount', counter);
                    this.trigger('onNetworkListChange');
                });
            },

            _updateLoadingImages: function() {
                this.set('loadingImages',
                    !!this.model.findBy('loadingImages', true));
            },

            _updateLoadingMachines: function() {
                this.set('loadingMachines',
                    !!this.model.findBy('loadingMachines', true));
            },

            _updateLoadingNetworks: function () {
                this.set('loadingNetworks',
                    !!this.model.findBy('loadingNetworks', true));
            },

            _updateSelectedMachines: function() {
                Ember.run(this, function() {
                    var newSelectedMachines = [];
                    this.model.forEach(function(backend) {
                        newSelectedMachines = newSelectedMachines.concat(backend.selectedMachines);
                    });
                    this.set('selectedMachines', newSelectedMachines);
                    this.trigger('onSelectedMachinesChange');
                });
            },

            _updateSelectedNetworks: function () {
                Ember.run(this, function () {
                    var newSelectedNetworks = [];
                    this.model.forEach(function (backend) {
                        newSelectedNetworks = newSelectedNetworks.concat(backend.selectedNetworks);
                    });
                    this.set('selectedNetworks', newSelectedNetworks);
                    this.trigger('onSelectedNetworksChange');
                });
            },

            _updateMachines: function () {
                var backends = Mist.backendsController.model;
                var machineList = [];
                backends.forEach(function (backend) {
                    machineList.pushObjects(backend.machines.model);
                });
                this.set('machines', machineList);
            },

            //
            //  Observers
            //

            machineObserver: function () {
                Ember.run.next(this, '_updateMachines');
            }.observes('model.@each.machines'),

            imageCountObserver: function() {
                Ember.run.once(this, '_updateImageCount');
            }.observes('model.@each.imageCount'),

            machineCountObserver: function() {
                Ember.run.once(this, '_updateMachineCount');
            }.observes('model.@each.machineCount'),

            networkCountObserver: function () {
                Ember.run.once(this, '_updateNetworkCount');
            }.observes('model.@each.networkCount'),

            loadingImagesObserver: function() {
                Ember.run.once(this, '_updateLoadingImages');
            }.observes('model.@each.loadingImages'),

            loadingMachinesObserver: function() {
                Ember.run.once(this, '_updateLoadingMachines');
            }.observes('model.@each.loadingMachines'),

            loadingNetworksObserver: function () {
                Ember.run.once(this, '_updateLoadingNetworks');
            }.observes('model.@each.loadingNetworks'),

            selectedMachinesObserver: function () {
                Ember.run.once(this, '_updateSelectedMachines');
            }.observes('model.@each.selectedMachines'),

            selectedNetworksObserver: function () {
                Ember.run.once(this, '_updateSelectedNetworks');
            }.observes('model.@each.selectedNetworks')
        });
    }
);
<commit_msg>fix parse error in template due to previous conflict<commit_after>define('app/controllers/backends', ['app/models/backend', 'ember'],
    //
    //  Backends Controller
    //
    //  @returns Class
    //
    function (Backend) {

        'use strict';

        return Ember.Controller.extend(Ember.Evented, {

            //
            //  Properties
            //

            model: [],
            imageCount: 0,
            machineCount: 0,
            networkCount: 0,
            machines: [],
            sortBy: 'state',
            displayCount: 30,
            selectedMachines: [],
            selectedNetworks: [],
            machineRequest: false,
            networkRequest: false,
            imageRequest: false,

            addingBackend: false,
            deletingBackend: false,
            togglingBackend: false,
            checkedMonitoring: false,
            checkingMonitoring: false,

            loading: true,
            loadingImages: false,
            loadingMachines: false,

            hasOpenStack: function () {
                return !!this.model.filterBy('enabled', true).findBy('isOpenStack', true);
            }.property('model.[].isOpenStack', 'model.[].enabled'),

            hasNetworks: function () {
                return !!this.model.findBy('hasNetworks', true);
            }.property('model.[].hasNetworks'),

            filteredMachines: Ember.computed('machines', 'searchMachinesTerm', function() {
                var filteredMachines = [];

                if (this.searchMachinesTerm) {
                    var that = this;
                    this.machines.forEach(function(machine) {
                        var regex = new RegExp(that.searchMachinesTerm, 'i');

                        if (regex.test(machine.name)) {
                            filteredMachines.push(machine);
                        } else {
                            if (machine.selected) {
                                machine.set('selected', false);
                            }
                        }
                    });
                } else {
                    filteredMachines = this.machines;
                }

                return filteredMachines;
            }),

            sortedMachines: Ember.computed('filteredMachines', 'filteredMachines.@each.stateWeight', 'filteredMachines.@each.name', 'filteredMachines.@each.backend.title', 'sortBy', function() {
                if(this.get('filteredMachines'))
                {
                    if (this.get('sortBy') == 'state')
                    {
                        return this.get('filteredMachines').sortBy('stateWeight').reverse();
                    }

                    if (this.get('sortBy') == 'name')
                    {
                        return this.get('filteredMachines').sortBy('name');
                    }

                    if (this.get('sortBy') == 'cloud')
                    {
                        return this.get('filteredMachines').sortBy('backend.title', 'name');
                    }
                }
            }),

            sortedMachines: Ember.computed.sort('machines', function(a, b){
                if (Mist.backendsController.sortBy == 'name')
                    return a.name.localeCompare(b.name);
                else
                    return b.get('stateWeight') - a.get('stateWeight');
            }).property('machines', 'sortBy', 'machines.@each.stateWeight', 'machines.@each.name'),

            //
            //  Initialization
            //

            load: function (backends) {
                this._updateModel(backends);
                this.set('loading', false);
            },

            //
            //  Methods
            //

            addBackend: function (args) {
                var key = Mist.keysController.keyExists(args.payload.key) ? args.payload.key : null;
                var that = this;
                this.set('addingBackend', true);
                Mist.ajax.POST('/backends', args.payload)
                .success(function (backend) {
                    that._addBackend(backend, key);
                }).error(function (message) {
                    Mist.notificationController.notify(
                        'Failed to add backend: ' + message);
                }).complete(function (success, backend) {
                    that.set('addingBackend', false);
                    if (args.callback) args.callback(success, backend);
                });
            },

            renameBackend: function (args) {
                var that = this;
                this.set('renamingBackend', true);
                Mist.ajax.PUT('/backends/' + args.backend.id, {
                    'new_name': args.newTitle
                }).success(function () {
                    that._renameBackend(args.backend, args.newTitle);
                }).error(function () {
                    Mist.notificationController.notify(
                        'Failed to rename backend');
                }).complete(function (success) {
                    that.set('renamingBackend', false);
                    Mist.backendEditController.set('editingBackend', false);
                    if (args.callback) args.callback(success);
                });
            },

            deleteBackend: function(args) {
                var that = this;
                this.set('deletingBackend', true);
                Mist.ajax.DELETE('/backends/' + args.backend.id, {
                }).success(function() {
                    that._deleteBackend(args.backend);
                }).error(function() {
                    Mist.notificationController.notify(
                        'Failed to delete backend');
                }).complete(function(success) {
                    that.set('deletingBackend', false);
                    if (args.callback) args.callback(success);
                });
            },

            toggleBackend: function(args) {
                var that = this;
                this.set('togglingBackend', true);
                Mist.ajax.POST('/backends/' + args.backend.id, {
                    'new_state': args.newState.toString()
                }).success(function () {
                    that._toggleBackend(args.backend, args.newState);
                }).error(function () {
                    Mist.notificationController.notify(
                        "Failed to change backend's state");
                }).complete(function (success) {
                    that.set('togglingBackend', false);
                    if (args.callback) args.callback(success);
                });
            },

            probeMachine: function(machine, keyId, callback) {
                // TODO: This should be moved inside machines controller

                if (!machine.id || machine.id == -1) return;
                if (!machine.state == 'running') return;

                var host = machine.getHost();
                if (!host) return;

                var key = Mist.keysController.getKey(keyId);
                if (key) {
                    machine.set('probing', keyId);
                    key.set('probing', machine);
                } else {
                    machine.set('probing', true);
                }
                var that = this;
                var uptime = null;
                Mist.ajax.POST('/backends/' + machine.backend.id + '/machines/' + machine.id + '/probe', {
                    'host': host,
                    'key': keyId
                }).success(function (data) {
                    machine.probeSuccess(data);
                }).error(function(message) {
                    console.log(message);
                    if (!machine.backend || !machine.backend.enabled) return;
                    if (key) Mist.notificationController.notify(message);
                }).complete(function(success, data) {
                    if (!machine.backend || !machine.backend.enabled) return;
                    if (key)
                        key.set('probing', false);
                    machine.set('probing', false);
                    that.trigger('onMachineProbe');
                    if (callback) callback(!!data.uptime, data);
                });
            },

            providerList: function() {
                return SUPPORTED_PROVIDERS.map(function (provider) {
                    provider.className = 'provider-';
                    if (provider.provider == 'bare_metal')
                        provider.className += 'baremetal';
                    else if (provider.provider == 'indonesian_vcloud')
                        provider.className += 'indonesian';
                    else
                        provider.className += provider.provider;
                    return provider;
                }).sort(function (a, b) {
                    if (a.provider == 'bare_metal')
                        return 1;
                    if (b.provider == 'bare_metal')
                        return -1;
                    if (a.title > b.title)
                        return 1;
                    if (a.title < b.title)
                        return -1
                    return 0;
                });
            }.property('providerList'),

            getRequestedMachine: function() {
                if (this.machineRequest) {
                    return this.getMachine(this.machineRequest);
                }
            },

            getRequestedNetwork: function () {
                if (this.networkRequest) {
                    return this.getNetwork(this.networkRequest);
                }
            },

            getRequestedImage: function () {
                if (this.imageRequest) {
                    return this.getImage(this.imageRequest);
                }
            },

            getBackend: function(backendId) {
                return this.model.findBy('id', backendId);
            },

            getMachine: function(machineId, backendId) {
                if (backendId) {
                    var backend = this.getBackend(backendId);
                    if (backend)
                        return backend.getMachine(machineId);
                    return null;
                }

                var machine = null;
                this.model.some(function(backend) {
                    return machine = backend.getMachine(machineId);
                });
                return machine;
            },

            getNetwork: function (networkId, backendId) {
                if (backendId) {
                    var backend = this.getBackend(backendId);
                    if (backend)
                        return backend.getNetwork(networkId);
                    return null;
                }

                var network = null;
                this.model.some(function(backend) {
                    return network = backend.getNetwork(networkId);
                });
                return network;
            },

            getImage: function(imageId, backendId) {
                if (backendId) {
                    var backend = this.getBackend(backendId);
                    if (backend)
                        return backend.getImage(imageId);
                    return null;
                }

                var image = null;
                this.model.some(function(backend) {
                    return image = backend.getImage(imageId);
                });
                return image;
            },

            machineExists: function(machineId, backendId) {
                return !!this.getMachine(machineId, backendId);
            },

            backendExists: function(backendId) {
                return !!this.getBackend(backendId);
            },

            networkExists: function (networkId, backendId) {
                return !!this.getNetwork(networkId, backendId);
            },

            //
            //  Psudo-Private Methods
            //

            _updateModel: function (backends) {
                Ember.run(this, function() {
                    // Remove deleted backends
                    this.model.forEach(function (backend) {
                        if (!backends.findBy('id', backend.id))
                            this.model.removeObject(backend);
                    }, this);

                    backends.forEach(function (backend) {

                        var oldBackend = this.getBackend(backend.id);

                        if (oldBackend)
                            // Update existing backends
                            forIn(backend, function (value, property) {
                                oldBackend.set(property, value);
                            });
                        else
                            // Add new backends
                            this._addBackend(backend);
                    }, this);

                    this.trigger('onBackendListChange');
                });
            },

            _addBackend: function(backend, keyId) {
                Ember.run(this, function() {
                    if (this.backendExists(backend.id)) return;
                    var backendModel = Backend.create(backend);
                    this.model.addObject(backendModel);
                    // <TODO (gtsop): move this code into backend model
                    if (keyId)
                        backendModel.one('onMachineListChange', function() {
                            if (backendModel.provider == 'bare_metal') {
                                Mist.keysController._associateKey(keyId,
                                    backendModel.machines.model[0]);
                            }
                        });
                    // />
                    this.trigger('onBackendAdd');
                });
            },

            _deleteBackend: function(backend) {
                Ember.run(this, function() {
                    this.model.removeObject(backend);
                    this.trigger('onBackendDelete');
                });
            },

            _renameBackend: function(backend, newTitle) {
                Ember.run(this, function() {
                    backend.set('title', newTitle);
                    this.trigger('onBackendRename');
                });
            },

            _toggleBackend: function(backend, newState) {
                Ember.run(this, function() {
                    backend.set('enabled', newState);
                    this.trigger('onBackendToggle');
                });
            },

            _updateImageCount: function() {
                Ember.run(this, function() {
                    var counter = 0;
                    this.model.forEach(function(backend) {
                        if (backend.enabled)
                            counter += backend.images.model.length;
                    });
                    if (counter != this.get('imageCount')){
                        this.set('imageCount', counter);
                        this.trigger('onImagesChange');
                    }
                });
            },

            _updateMachineCount: function() {
                Ember.run(this, function() {
                    var counter = 0;
                    this.model.forEach(function(backend) {
                        if (backend.enabled) counter += backend.machineCount;
                    });
                    this.set('machineCount', counter);
                    this.trigger('onMachineListChange');
                });
            },

            _updateNetworkCount: function() {
                Ember.run(this, function() {
                    var counter = 0;
                    this.model.forEach(function (backend) {
                        if (backend.enabled)
                            counter += backend.networkCount;
                    });
                    this.set('networkCount', counter);
                    this.trigger('onNetworkListChange');
                });
            },

            _updateLoadingImages: function() {
                this.set('loadingImages',
                    !!this.model.findBy('loadingImages', true));
            },

            _updateLoadingMachines: function() {
                this.set('loadingMachines',
                    !!this.model.findBy('loadingMachines', true));
            },

            _updateLoadingNetworks: function () {
                this.set('loadingNetworks',
                    !!this.model.findBy('loadingNetworks', true));
            },

            _updateSelectedMachines: function() {
                Ember.run(this, function() {
                    var newSelectedMachines = [];
                    this.model.forEach(function(backend) {
                        newSelectedMachines = newSelectedMachines.concat(backend.selectedMachines);
                    });
                    this.set('selectedMachines', newSelectedMachines);
                    this.trigger('onSelectedMachinesChange');
                });
            },

            _updateSelectedNetworks: function () {
                Ember.run(this, function () {
                    var newSelectedNetworks = [];
                    this.model.forEach(function (backend) {
                        newSelectedNetworks = newSelectedNetworks.concat(backend.selectedNetworks);
                    });
                    this.set('selectedNetworks', newSelectedNetworks);
                    this.trigger('onSelectedNetworksChange');
                });
            },

            _updateMachines: function () {
                var backends = Mist.backendsController.model;
                var machineList = [];
                backends.forEach(function (backend) {
                    machineList.pushObjects(backend.machines.model);
                });
                this.set('machines', machineList);
            },

            //
            //  Observers
            //

            machineObserver: function () {
                Ember.run.next(this, '_updateMachines');
            }.observes('model.@each.machines'),

            imageCountObserver: function() {
                Ember.run.once(this, '_updateImageCount');
            }.observes('model.@each.imageCount'),

            machineCountObserver: function() {
                Ember.run.once(this, '_updateMachineCount');
            }.observes('model.@each.machineCount'),

            networkCountObserver: function () {
                Ember.run.once(this, '_updateNetworkCount');
            }.observes('model.@each.networkCount'),

            loadingImagesObserver: function() {
                Ember.run.once(this, '_updateLoadingImages');
            }.observes('model.@each.loadingImages'),

            loadingMachinesObserver: function() {
                Ember.run.once(this, '_updateLoadingMachines');
            }.observes('model.@each.loadingMachines'),

            loadingNetworksObserver: function () {
                Ember.run.once(this, '_updateLoadingNetworks');
            }.observes('model.@each.loadingNetworks'),

            selectedMachinesObserver: function () {
                Ember.run.once(this, '_updateSelectedMachines');
            }.observes('model.@each.selectedMachines'),

            selectedNetworksObserver: function () {
                Ember.run.once(this, '_updateSelectedNetworks');
            }.observes('model.@each.selectedNetworks')
        });
    }
);
<|endoftext|>


<commit_before>angular.module("kitware.cmb.core")
    .controller('CmbSimulationController', ['$scope', 'kw.Girder', '$state', '$stateParams', '$mdDialog', '$templateCache', '$window', '$http', '$timeout', '$interval', function ($scope, $girder, $state, $stateParams, $mdDialog, $templateCache, $window, $http, $timeout, $interval) {
        var timeoutId = 0;

        $scope.template = null;
        $scope.viewModel = null;

        // BEGIN - Refresh simulation status base on task progress every 10s
        timeoutId = $interval(function() {
            if($scope.simulation.meta.task === 'terminated') {
                $girder.deleteTask($scope.simulation);
            } else if($scope.simulation.meta.taskId) {
                $girder.updateTaskStatus($scope.simulation);
            }
        }, 10000);

        $scope.$on('$destroy', function() {
            $interval.cancel(timeoutId);
        });
        // END - Refresh simulation status base on task progress every 10s

        $scope.taskCallback = function(simulationResponse) {
            // Move to the newly created simulation
            var simulation = simulationResponse[0];
            $state.go('project', { collectionName: $stateParams.collectionName, projectID: simulation.folderId });
        };

        $scope.runVisualizationCallback = function(args) {
            var simulation = args[0],
                clusterData = args[1],
                taskId = args[2],
                config = {
                    cluster: clusterData,
                    input: {
                        item: { id: simulation._id },
                        data: "data"
                    },
                    output: {
                        item: { id: simulation._id }
                    }
                };

            console.log(config);
            console.log('Task spec ' + taskId);
            console.log("Cluster provided for viz task");
            console.log(clusterData);

            if(clusterData.selectedIndex === 0) {
                $girder.startTask(simulation, taskId, clusterData, config);
            }

            // Move back to the project view
            $state.go('project', { collectionName: $stateParams.collectionName, projectID: simulation.folderId });
        };

        $scope.runSimulationCallback = function(args) {
            var simulation = args[0],
                clusterData = args[1],
                taskId = args[2],
                mesh = $scope.mesh;

            console.log(simulation);

            $girder.extractMeshInformationFromProject(simulation.folderId, function(meshItem, meshFile){
                var config = {
                    cluster: clusterData,
                    input: {
                        data: {
                            item: {
                                id: meshItem._id
                            }
                        },
                        config: {
                            item: {
                                id: simulation._id
                            }
                        }
                    },
                    mesh: {
                        name: meshFile.name
                    },
                    output: {
                        item: { id: simulation._id }
                    }
                };
                console.log('Task spec ' + taskId);
                console.log(config);
                $girder.startTask(simulation, taskId, clusterData, config);
            });

            // Move back to the project view
            $state.go('project', { collectionName: $stateParams.collectionName, projectID: simulation.folderId });
        };

        function fetchData() {
            if($scope.collection && $scope.collection.name && $scope.simulation) {
                $scope.template = SimPut.getTemplate($scope.collection.name);

                var fetchedId = $scope.simulation._id,
                    simName = $scope.simulation.name;

                $girder.downloadContentFromItem(fetchedId, 'hydra.json', function(dataModelFromServer) {
                    if(fetchedId !== $scope.simulation._id) {
                        fetchData();
                    } else {
                        $scope.viewModel = dataModelFromServer || { external: {} };
                        if($scope.external) {
                            $scope.viewModel.name = simName;
                            $scope.viewModel.external = $scope.external;
                        }
                    }
                });

                // Extract annotation
                $girder.listItems($scope.simulation.folderId)
                    .success(function (items) {
                        var count = items.length;
                        if (count === 0) {
                            console.error("no item found");
                        }

                        while(count--) {
                            if(items[count].name === 'mesh') {
                                var faces = items[count].meta.annotation,
                                    tagMap = {},
                                    processedTags = [],
                                    faceCount = faces.length,
                                    tagValues = [];

                                // loop over faces
                                while(faceCount--) {
                                    var tags = faces[faceCount].tags,
                                        tagCount = tags.length;

                                    while(tagCount--) {
                                        if(tagMap[tags[tagCount]]) {
                                            tagMap[tags[tagCount]].push(faces[faceCount].id);
                                        } else {
                                            tagMap[tags[tagCount]] = [ faces[faceCount].id ];
                                        }
                                    }
                                }

                                // Make enum structure
                                for(var tag in tagMap) {
                                    processedTags.push(tag);
                                }
                                processedTags.sort();
                                for(var idx = 0; idx < processedTags.length; ++idx) {
                                    tagValues.push(tagMap[processedTags[idx]]);
                                }

                                $scope.external = {
                                    'face-tags': { labels: processedTags, values: tagValues },
                                    'element-tags': { labels: ["Elements for Stats"], values: [ 3720242 ] },
                                    'block-tags': { labels: ["Water"], values: [1] } // FIXME specific to hydra
                                };

                                if($scope.viewModel) {
                                    $scope.viewModel.external = $scope.external;
                                }

                                count = 0;
                                console.log($scope.globals);
                            }
                        }
                    })
                    .error(function(err) {
                        console.log(err);
                    });
            } else {
                $timeout(fetchData, 500);
            }
        }

        $scope.$on('simput-error', function(event) {
            if($scope.simulation.meta.status === 'valid') {
                $girder.updateItemMetadata($scope.simulation, { status: 'incomplete' });

                // Move to the incomplete page
                $state.go('simulation', { collectionName: $stateParams.collectionName, projectID: $scope.simulation.folderId, mode: 'incomplete', simulationID: $scope.simulation._id });
            }
        });

        $scope.$on('save-file', function(event, arg) {
            if(arg.name.indexOf('.json') === -1) {
                // Update item state
                if($scope.simulation.meta.status !== 'valid') {
                    $girder.updateItemMetadata($scope.simulation, { status: 'valid' });
                }

                // Update input deck
                $girder.uploadContentToItem($scope.simulation._id, 'hydra.ctln', arg.content);

                // Move to the valid page
                $state.go('simulation', { collectionName: $stateParams.collectionName, projectID: $scope.simulation.folderId, mode: 'valid', simulationID: $scope.simulation._id });
            }
        });
        $scope.$on('simput-click', function(event, type) {
            if(type === 'save-output') {
                $girder.uploadContentToItem($scope.simulation._id, 'hydra.json', JSON.stringify($scope.viewModel, undefined, 3));
            }
        });

        if($girder.getUser() === null) {
            $state.go('login');
        } else {
            fetchData();
        }
    }]);
<commit_msg>fix name<commit_after>angular.module("kitware.cmb.core")
    .controller('CmbSimulationController', ['$scope', 'kw.Girder', '$state', '$stateParams', '$mdDialog', '$templateCache', '$window', '$http', '$timeout', '$interval', function ($scope, $girder, $state, $stateParams, $mdDialog, $templateCache, $window, $http, $timeout, $interval) {
        var timeoutId = 0;

        $scope.template = null;
        $scope.viewModel = null;

        // BEGIN - Refresh simulation status base on task progress every 10s
        timeoutId = $interval(function() {
            if($scope.simulation.meta.task === 'terminated') {
                $girder.deleteTask($scope.simulation);
            } else if($scope.simulation.meta.taskId) {
                $girder.updateTaskStatus($scope.simulation);
            }
        }, 10000);

        $scope.$on('$destroy', function() {
            $interval.cancel(timeoutId);
        });
        // END - Refresh simulation status base on task progress every 10s

        $scope.taskCallback = function(simulationResponse) {
            // Move to the newly created simulation
            var simulation = simulationResponse[0];
            $state.go('project', { collectionName: $stateParams.collectionName, projectID: simulation.folderId });
        };

        $scope.runVisualizationCallback = function(args) {
            var simulation = args[0],
                clusterData = args[1],
                taskId = args[2],
                config = {
                    cluster: clusterData,
                    input: {
                        item: { id: simulation._id },
                        data: "data"
                    },
                    output: {
                        item: { id: simulation._id }
                    }
                };

            console.log(config);
            console.log('Task spec ' + taskId);
            console.log("Cluster provided for viz task");
            console.log(clusterData);

            if(clusterData.selectedIndex === 0) {
                $girder.startTask(simulation, taskId, clusterData, config);
            }

            // Move back to the project view
            $state.go('project', { collectionName: $stateParams.collectionName, projectID: simulation.folderId });
        };

        $scope.runSimulationCallback = function(args) {
            var simulation = args[0],
                clusterData = args[1],
                taskId = args[2],
                mesh = $scope.mesh;

            console.log(simulation);

            $girder.extractMeshInformationFromProject(simulation.folderId, function(meshItem, meshFile){
                var config = {
                    cluster: clusterData,
                    input: {
                        data: {
                            item: {
                                id: meshItem._id
                            }
                        },
                        config: {
                            item: {
                                id: simulation._id
                            }
                        }
                    },
                    mesh: {
                        name: meshFile.name
                    },
                    output: {
                        item: { id: simulation._id }
                    }
                };
                console.log('Task spec ' + taskId);
                console.log(config);
                $girder.startTask(simulation, taskId, clusterData, config);
            });

            // Move back to the project view
            $state.go('project', { collectionName: $stateParams.collectionName, projectID: simulation.folderId });
        };

        function fetchData() {
            if($scope.collection && $scope.collection.name && $scope.simulation) {
                $scope.template = SimPut.getTemplate($scope.collection.name);

                var fetchedId = $scope.simulation._id,
                    simName = $scope.simulation.name;

                $girder.downloadContentFromItem(fetchedId, 'hydra.json', function(dataModelFromServer) {
                    if(fetchedId !== $scope.simulation._id) {
                        fetchData();
                    } else {
                        $scope.viewModel = dataModelFromServer || { external: {} };
                        if($scope.external) {
                            $scope.viewModel.name = simName;
                            $scope.viewModel.external = $scope.external;
                        }
                    }
                });

                // Extract annotation
                $girder.listItems($scope.simulation.folderId)
                    .success(function (items) {
                        var count = items.length;
                        if (count === 0) {
                            console.error("no item found");
                        }

                        while(count--) {
                            if(items[count].name === 'mesh') {
                                var faces = items[count].meta.annotation,
                                    tagMap = {},
                                    processedTags = [],
                                    faceCount = faces.length,
                                    tagValues = [];

                                // loop over faces
                                while(faceCount--) {
                                    var tags = faces[faceCount].tags,
                                        tagCount = tags.length;

                                    while(tagCount--) {
                                        if(tagMap[tags[tagCount]]) {
                                            tagMap[tags[tagCount]].push(faces[faceCount].id);
                                        } else {
                                            tagMap[tags[tagCount]] = [ faces[faceCount].id ];
                                        }
                                    }
                                }

                                // Make enum structure
                                for(var tag in tagMap) {
                                    processedTags.push(tag);
                                }
                                processedTags.sort();
                                for(var idx = 0; idx < processedTags.length; ++idx) {
                                    tagValues.push(tagMap[processedTags[idx]]);
                                }

                                $scope.external = {
                                    'face-tags': { labels: processedTags, values: tagValues },
                                    'element-tags': { labels: ["Elements for Stats"], values: [ 3720242 ] },
                                    'block-tags': { labels: ["Water"], values: [1] } // FIXME specific to hydra
                                };

                                if($scope.viewModel) {
                                    $scope.viewModel.external = $scope.external;
                                }

                                count = 0;
                                console.log($scope.globals);
                            }
                        }
                    })
                    .error(function(err) {
                        console.log(err);
                    });
            } else {
                $timeout(fetchData, 500);
            }
        }

        $scope.$on('simput-error', function(event) {
            if($scope.simulation.meta.status === 'valid') {
                $girder.updateItemMetadata($scope.simulation, { status: 'incomplete' });

                // Move to the incomplete page
                $state.go('simulation', { collectionName: $stateParams.collectionName, projectID: $scope.simulation.folderId, mode: 'incomplete', simulationID: $scope.simulation._id });
            }
        });

        $scope.$on('save-file', function(event, arg) {
            if(arg.name.indexOf('.json') === -1) {
                // Update item state
                if($scope.simulation.meta.status !== 'valid') {
                    $girder.updateItemMetadata($scope.simulation, { status: 'valid' });
                }

                // Update input deck
                $girder.uploadContentToItem($scope.simulation._id, arg.name, arg.content);

                // Move to the valid page
                $state.go('simulation', { collectionName: $stateParams.collectionName, projectID: $scope.simulation.folderId, mode: 'valid', simulationID: $scope.simulation._id });
            }
        });
        $scope.$on('simput-click', function(event, type) {
            if(type === 'save-output') {
                $girder.uploadContentToItem($scope.simulation._id, 'hydra.json', JSON.stringify($scope.viewModel, undefined, 3));
            }
        });

        if($girder.getUser() === null) {
            $state.go('login');
        } else {
            fetchData();
        }
    }]);
<|endoftext|>


<commit_before>import {listen} from 'socket.io'
import {getMemberByToken, getAllMembers, deleteMember, getMembersCount} from './members'

export const killMember = (id) => {
    const members = getAllMembers();

    members.forEach(member => {
        if(member.socket){
            member.socket.emit('KILL', {
                id: id
            })
        }
    })
};

function registerEvents(socket){

    const getDataAndMember = (request) =>{
        const token = request.sess_token;
        const member = getMemberByToken(token);

        const data = request.data;

        return {
            "member": member,
            "data": data
        }
    };

    const raiseError = () => {
        socket.send("Invalid token!");
    };

    socket.on('HILO', function(request){
        const { data , member } = getDataAndMember(request);

        if(!member){
            return raiseError();
        }
        member.socket = socket;

        getAllMembers().forEach((loopMember) => {
            if (loopMember != member && loopMember.socket){
                loopMember.socket.emit('HILO', {
                    'id': member.id,
                    'admin': member.admin,
                    'name': member.name
                });
            }
        });

    });

    socket.on('SET_NAME', function(request){
        const { data , member } = getDataAndMember(request);

        if(member == null){
            return raiseError();
        }

        member.name = data.name;
        getAllMembers().forEach((loopMember) => {
            if (loopMember != member && loopMember.socket){
                loopMember.socket.emit('SET_NAME', {
                    'id': member.id,
                    'name': member.name
                });
            }
        });

    });

    socket.on('KILL', function(request) {
        const {data, member} = getDataAndMember(request);

        if (member == null) {
            return raiseError();
        }

        if (member.admin) {
            getAllMembers().forEach((loopMember) => {
                if (true || loopMember != member) {
                    member.socket.emit('KILL', {
                        'id': request.data
                    });
                }
            });
        }
        else {
            throw new Error ('Only the admin can kick others');
        }
    });

    socket.on('CLEAR_BOARD', function (request) {
        const {data, member} = getDataAndMember(request);
        member.socket = socket;

        if (!member.admin) {
                return raiseError();
            }

        getAllMembers().forEach((loopMember) => {
                if (loopMember.id !== member.id && loopMember.socket) {

                    loopMember.socket.emit('CLEAR_BOARD', {
                        'data': request.data
                    });

                }
            });
    });

    socket.on('DRAW_EVENT', function(request) {
        const { data , member } = getDataAndMember(request);

        if (member == null) {
            return raiseError();
        }
        getAllMembers().forEach((loopMember) => {
            if (loopMember != member && loopMember.socket) {
                loopMember.socket.emit('DRAW_EVENT', {
                    'data': request.data
                });
            }
        });
    });

}

export const activate = function(server){
    const io = listen(server);

    io.on('connection', function(socket) {
        registerEvents(socket);
    });
};<commit_msg>draw previous events on new members connect implemented<commit_after>import {listen} from 'socket.io'
import {getMemberByToken, getAllMembers, deleteMember, getMembersCount} from './members'

let allDrawEvents = [];

export const killMember = (id) => {
    const members = getAllMembers();

    members.forEach(member => {
        if(member.socket){
            member.socket.emit('KILL', {
                id: id
            })
        }
    })
};

function registerEvents(socket){

    const getDataAndMember = (request) =>{
        const token = request.sess_token;
        const member = getMemberByToken(token);

        const data = request.data;

        return {
            "member": member,
            "data": data
        }
    };

    const raiseError = () => {
        socket.send("Invalid token!");
    };

    socket.on('HILO', function(request){
        const { data , member } = getDataAndMember(request);

        if(!member){
            return raiseError();
        }
        member.socket = socket;

        getAllMembers().forEach((loopMember) => {
            if (loopMember != member && loopMember.socket){
                loopMember.socket.emit('HILO', {
                    'id': member.id,
                    'admin': member.admin,
                    'name': member.name
                });
            }else if(loopMember.socket && loopMember.id == member.id){
                loopMember.socket.emit('ALL_DATA', {
                    data: allDrawEvents
                });

            }
        });

    });

    socket.on('SET_NAME', function(request){
        const { data , member } = getDataAndMember(request);

        if(member == null){
            return raiseError();
        }

        member.name = data.name;
        getAllMembers().forEach((loopMember) => {
            if (loopMember != member && loopMember.socket){
                loopMember.socket.emit('SET_NAME', {
                    'id': member.id,
                    'name': member.name
                });
            }
        });

    });

    socket.on('KILL', function(request) {
        const {data, member} = getDataAndMember(request);

        if (member == null) {
            return raiseError();
        }

        if (member.admin) {
            getAllMembers().forEach((loopMember) => {
                if (true || loopMember != member) {
                    member.socket.emit('KILL', {
                        'id': request.data
                    });
                }
            });
        }
        else {
            throw new Error ('Only the admin can kick others');
        }
    });

    socket.on('CLEAR_BOARD', function (request) {
        const {data, member} = getDataAndMember(request);
        member.socket = socket;

        if (!member.admin) {
                return raiseError();
            }

        allDrawEvents = [];
        getAllMembers().forEach((loopMember) => {
                if (loopMember.id !== member.id && loopMember.socket) {

                    loopMember.socket.emit('CLEAR_BOARD', {
                        'data': request.data
                    });

                }
            });
    });

    socket.on('DRAW_EVENT', function(request) {
        const { data , member } = getDataAndMember(request);

        if (member == null) {
            return raiseError();
        }
        allDrawEvents.push(request.data);
        getAllMembers().forEach((loopMember) => {
            if (loopMember != member && loopMember.socket) {
                loopMember.socket.emit('DRAW_EVENT', {
                    'data': request.data
                });
            }
        });
    });

}

export const activate = function(server){
    const io = listen(server);

    io.on('connection', function(socket) {
        registerEvents(socket);
    });
};<|endoftext|>


<commit_before>import Phaser from 'phaser'

export default class extends Phaser.Sprite {
    constructor ({ game, x, y, asset }) {
        super(game, x, y, asset);
        this.mapnodes = [
            [-1200,-300], [-900,300], [-300,100], [150,300], [800,-100],
            [600,-600], [900,-1000], [700,-1300], [-200,-1000],
            [-300,-300], [-700,-300], [-600,-1000], [-800,-1200],
            [-1100,-1200], [-1200,-700], [-1200,-300]
        ]
        this.outline = [];
    }

    initialize () {
        this.game.physics.p2.enable(this, true);
        this.body.static = true;
        this.anchor.set(0);
        this.body.clearShapes();
        this.outline = this.generateRoadBoundaries(this.mapnodes);
        var err = this.body.addPolygon({skipSimpleCheck: true, removeCollinearPoints: 0.1}, this.outline);
        this.body.setCollisionGroup(this.game.physics.p2.nothingCollisionGroup);
    }

    getXCoordinates () {
        return this.mapnodes.map( c=> c[0] );
    }

    getYCoordinates () {
        return this.mapnodes.map( c=> c[1] );
    }

    generateRoadBoundaries () {
        // At certain (uniform) points along the Catmull Rom curve of these points,
        //   - Find the current slope of curve
        //   - Generate collision points perpendicular to this slope

        // In order to get a decent distribution of sample points, we need
        //   to find the distance of the track
        var distance = 0;
        for ( var i = 0; i < this.mapnodes.length - 1; i++ ) {
            var x = this.mapnodes[i][0];
            var y = this.mapnodes[i][1];
            var nx = this.mapnodes[i+1][0];
            var ny = this.mapnodes[i+1][1];
            distance += this.game.math.distance(x, y, nx, ny);
        }

        const DISTANCE_BETWEEN_SAMPLES = 70; // Measured in pixels
        const ROAD_WIDTH_FROM_CENTER = 100;   // Measured in pixels

        const STEP = 1/(distance/DISTANCE_BETWEEN_SAMPLES);
        const DELTA = STEP/10;

        var pointsx = this.getXCoordinates();
        var pointsy = this.getYCoordinates();
        var polygon = [];
        for ( var j = 0; j < 1; j += STEP ) {
            var leftx = 0;
            var lefty = 0;
            var rightx = 0;
            var righty = 0;

            var plusx  = this.game.math.catmullRomInterpolation(pointsx, j+DELTA);
            var x      = this.game.math.catmullRomInterpolation(pointsx, j);
            var minusx = this.game.math.catmullRomInterpolation(pointsx, j-DELTA);
            var dx = plusx - minusx;

            var plusy  = this.game.math.catmullRomInterpolation(pointsy, j+DELTA);
            var y      = this.game.math.catmullRomInterpolation(pointsy, j);
            var minusy = this.game.math.catmullRomInterpolation(pointsy, j-DELTA);
            var dy = plusy - minusy;

            var inv_vec = new Phaser.Point(-dy, dx);
            inv_vec.normalize()
                .multiply(ROAD_WIDTH_FROM_CENTER, ROAD_WIDTH_FROM_CENTER);
            leftx = x + inv_vec.x;
            lefty = y + inv_vec.y;

            inv_vec.multiply(-1,-1);
            rightx = x + inv_vec.x;
            righty = y + inv_vec.y;

            // Splice the points into the middle of the array
            polygon.splice(polygon.length/2, 0, leftx, lefty, rightx, righty);
        }

        // Add on the initial coordinates to create a closed loop
        var leftx = polygon[0];
        var lefty = polygon[1];
        var rightx = polygon[polygon.length - 2];
        var righty = polygon[polygon.length - 1];
        polygon.splice(polygon.length/2, 0, leftx, lefty, rightx, righty);

        return polygon;
    }

    update () {

    }
}
<commit_msg>Add getPointOnTrack function<commit_after>import Phaser from 'phaser'

export default class extends Phaser.Sprite {
    constructor ({ game, x, y, asset }) {
        super(game, x, y, asset);
        this.mapnodes = [
            [-1200,-300], [-900,300], [-300,100], [150,300], [800,-100],
            [600,-600], [900,-1000], [700,-1300], [-200,-1000],
            [-300,-300], [-700,-300], [-600,-1000], [-800,-1200],
            [-1100,-1200], [-1200,-700], [-1200,-300]
        ]
        this.outline = [];
    }

    initialize () {
        this.game.physics.p2.enable(this, true);
        this.body.static = true;
        this.anchor.set(0);
        this.body.clearShapes();
        this.outline = this.generateRoadBoundaries(this.mapnodes);
        var err = this.body.addPolygon({skipSimpleCheck: true, removeCollinearPoints: 0.1}, this.outline);
        this.body.setCollisionGroup(this.game.physics.p2.nothingCollisionGroup);
    }

    getXCoordinates () {
        return this.mapnodes.map( c => c[0] );
    }

    getYCoordinates () {
        return this.mapnodes.map( c => c[1] );
    }

    getPointOnTrack ( percent ) {
        var pointsx = this.getXCoordinates();
        var pointsy = this.getYCoordinates();

        var xpos = this.game.math.catmullRomInterpolation(pointsx, percent);
        var ypos = this.game.math.catmullRomInterpolation(pointsy, percent);

        var dx = this.game.math.catmullRomInterpolation(pointsx, percent+0.001) - xpos;
        var dy = this.game.math.catmullRomInterpolation(pointsy, percent+0.001) - ypos;
        var angle = Math.atan(dy/dx) + Math.PI/2;
        console.log(dx, dy);

        xpos += this.x;
        ypos += this.y;

        return {x: xpos, y: ypos, a: angle};
    }

    generateRoadBoundaries () {
        // At certain (uniform) points along the Catmull Rom curve of these points,
        //   - Find the current slope of curve
        //   - Generate collision points perpendicular to this slope

        // In order to get a decent distribution of sample points, we need
        //   to find the distance of the track
        var distance = 0;
        for ( var i = 0; i < this.mapnodes.length - 1; i++ ) {
            var x = this.mapnodes[i][0];
            var y = this.mapnodes[i][1];
            var nx = this.mapnodes[i+1][0];
            var ny = this.mapnodes[i+1][1];
            distance += this.game.math.distance(x, y, nx, ny);
        }

        const DISTANCE_BETWEEN_SAMPLES = 70; // Measured in pixels
        const ROAD_WIDTH_FROM_CENTER = 100;   // Measured in pixels

        const STEP = 1/(distance/DISTANCE_BETWEEN_SAMPLES);
        const DELTA = STEP/10;

        var pointsx = this.getXCoordinates();
        var pointsy = this.getYCoordinates();
        var polygon = [];
        for ( var j = 0; j < 1; j += STEP ) {
            var leftx = 0;
            var lefty = 0;
            var rightx = 0;
            var righty = 0;

            var plusx  = this.game.math.catmullRomInterpolation(pointsx, j+DELTA);
            var x      = this.game.math.catmullRomInterpolation(pointsx, j);
            var minusx = this.game.math.catmullRomInterpolation(pointsx, j-DELTA);
            var dx = plusx - minusx;

            var plusy  = this.game.math.catmullRomInterpolation(pointsy, j+DELTA);
            var y      = this.game.math.catmullRomInterpolation(pointsy, j);
            var minusy = this.game.math.catmullRomInterpolation(pointsy, j-DELTA);
            var dy = plusy - minusy;

            var inv_vec = new Phaser.Point(-dy, dx);
            inv_vec.normalize()
                .multiply(ROAD_WIDTH_FROM_CENTER, ROAD_WIDTH_FROM_CENTER);
            leftx = x + inv_vec.x;
            lefty = y + inv_vec.y;

            inv_vec.multiply(-1,-1);
            rightx = x + inv_vec.x;
            righty = y + inv_vec.y;

            // Splice the points into the middle of the array
            polygon.splice(polygon.length/2, 0, leftx, lefty, rightx, righty);
        }

        // Add on the initial coordinates to create a closed loop
        var leftx = polygon[0];
        var lefty = polygon[1];
        var rightx = polygon[polygon.length - 2];
        var righty = polygon[polygon.length - 1];
        polygon.splice(polygon.length/2, 0, leftx, lefty, rightx, righty);

        return polygon;
    }

    update () {

    }
}
<|endoftext|>


<commit_before>!function() {
    if ( !jar.prefixes.indexedDB ) {
        return;
    }

    var proto, idb,
        self = this,
        database = {},
        indexOf = [].indexOf,

        cantStore = {
            xml: true,
            html: true
        },

        // Prefixes
        indexedDB = jar.prefixes.indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB,
        IDBTransaction = jar.prefixes.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction,
        IDBKeyRange = jar.prefixes.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange;

    this.storages.push( "idb" );

    this.idb = function( name ) {
        return new proto.init( name, this );
    };

    idb = jar.idb = {};

    proto = this.idb.prototype = {
        constructor: this.idb,

        init: function( name, instance ) {
            var db, request, def,
                self = this;

            this.instance = instance;
            this.def = jar.Deferred();
            this.name = name;

            return this.setup().def;
        },

        setup: function() {
            var request,
                self = this,
                name = this.name;

            function reject() {
                self.def.reject();
            }

            // If db already initialized don't try to create another one
            if ( !idb.open ) {

                // Open connection for database
                idb.open = indexedDB.open( "jar", new Date().getTime() );
            }

            // In case we create instance without reopening connection to database
            if ( idb.db ) {
                self.instance.stores.idb = idb.db;
            }

            // New way to do it
            if ( idb.open.onupgradeneeded === null ) {

                request = setVersion(function() {
                    self.instance.stores.idb = idb.db = this.result;
                    createObjectStore( name );
                }, this.instance );

                request.addEventListener( "success", function() {
                    self.def.resolve();
                });

                request.addEventListener( "error", reject );

            // Old way
            } else {

                // If db exist than just update it
                if ( idb.db ) {
                    update( this );
                }

                // This will not be executed if db already exist
                idb.open.addEventListener( "success", function() {

                    // Create link in jar for new db
                    self.instance.stores.idb = idb.db = this.result;
                    update( self );
                });
            }

            idb.open.addEventListener( "error", reject );

            return this;
        },
    };

    proto.init.prototype = proto;

    this.idb.set = function( name, data, type, id ) {

        // Reject request if store is not exist
        if ( !contains( this.name ) ) {
            jar.reject( id );
            return this;
        }

        var request,
            self = this,
            store = idb.db.transaction([ this.name ], IDBTransaction.READ_WRITE ).objectStore( this.name );

        // We can't store DOM nodes
        if ( cantStore[ type ] ) {
            data = jar.text[ type ]( data );
        }

        data = {
            name: name,
            data: data
        };

        // Use "put", so we can rewrite data
        request = store.put( data );

        request.onsuccess = function() {
            jar.resolve( id, type, "idb" );
        };

        request.onerror = function() {
            jar.reject( id );
        };

        return this;
    };

    this.idb.get = function( name, type, id ) {

        // Reject request if store is not exist
        if ( !contains( this.name ) ) {
            jar.reject( id );
            return this;
        }

        var self = this,
            store = idb.db.transaction([ this.name ], IDBTransaction.READ_ONLY ).objectStore( this.name ),
            index = store.index( "name" ),
            request = index.get( name );

        request.onsuccess = function() {
            var data = this.result && this.result.data;

            // When data isn't there its still succesfull operation for this api, but not for jar
            if ( !data ) {
                return jar.reject( id );
            }

            // IndexedDB can't store some types of data in it original type
            // we need to serialize it to right type
            if ( cantStore[ type ] ) {
                data = jar.filters[ type ]( data );
            }

            // Some types of data can't be serialize to right type
            // like javascript code, so instead we return it like text
            // and execute it
            if ( jar.executable[ type ] ) {
                jar.filters[ type ]( data );
            }

            jar.resolve( id, data, type, "idb" );
        };

        request.onerror = function() {
            jar.reject( id );
        };

        return this;
    };

    this.idb.remove = function( name, id ) {

        // Reject request if store is not exist
        if ( !contains( this.name ) ) {
            jar.reject( id );
            return this;
        }

        var self = this,
            store = idb.db.transaction([ this.name ], IDBTransaction.READ_WRITE ).objectStore( this.name ),
            request = store.delete( name );

        request.onsuccess = function() {
            jar.resolve( id );
        };

        request.onerror = function() {
            jar.reject( id );
        };

        return this;
    };

    this.idb.clear = function( id, destroy /* internal */ ) {
        var request, store,
            stores = this.stores,
            name = this.name;

        function resolve() {
            jar.resolve( id );
        }

        function reject() {
            jar.reject( id );
        }

        // Either clear or destroy
        if ( destroy ) {
            request = setVersion(function() {
                idb.db.deleteObjectStore( name );
            }, this );

        } else {
            store = idb.db.transaction([ name ], IDBTransaction.READ_WRITE ).objectStore( name );
            request = store.clear();
        }

        request.onsuccess = resolve;
        request.onerror = reject;

        return this;
    };

    function setVersion( fn, instance ) {

        // Old way to set database version
        if ( idb.db && idb.db.setVersion ) {

            // If we have active request attach to it, if not create new one
            if ( !idb.setVersion || idb.setVersion.readyState == 2 /* done */ ) {
                idb.setVersion = idb.db.setVersion( new Date().getTime() );
            }

            idb.setVersion.addEventListener( "success", fn );

        } else {
            if ( idb.open.readyState == "pending" ) {
                idb.setVersion = idb.open;

            } else {
                idb.db.close();
                idb.setVersion = indexedDB.open( "jar", new Date().getTime() );
            }

            idb.setVersion.addEventListener( "upgradeneeded", function() {
                instance.stores.idb = idb.db = this.result;
                fn.apply( this, arguments );
            });
        }

        return idb.setVersion;
    }

    function update( instance ) {
        var request = setVersion(function() {
            createObjectStore( instance.name );
        });

        request.addEventListener( "success", function() {
            instance.def.resolve();
        });

        request.addEventListener( "error", function() {
            instance.def.reject();
        });
    }

    function contains( name ) {
        return idb.db.objectStoreNames.contains( name );
    }

    function createObjectStore( name ) {
        if ( !idb.db.objectStoreNames.contains( name ) ) {
            idb.db.createObjectStore( name, {
                keyPath: "name"
            }).createIndex( "name", "name", {
                unique: true
            });
        }
    }

}.call( jar.fn );<commit_msg>Add full Firefox support<commit_after>!function() {
    if ( !jar.prefixes.indexedDB ) {
        return;
    }

    var proto, idb,
        self = this,
        database = {},
        indexOf = [].indexOf,

        cantStore = {
            xml: true,
            html: true
        },

        // Prefixes
        indexedDB = jar.prefixes.indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB,
        IDBTransaction = jar.prefixes.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction,
        IDBKeyRange = jar.prefixes.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange;

    this.storages.push( "idb" );

    this.idb = function( name ) {
        return new proto.init( name, this );
    };

    idb = jar.idb = {};

    proto = this.idb.prototype = {
        constructor: this.idb,

        init: function( name, instance ) {
            var db, request, def,
                self = this;

            this.instance = instance;
            this.def = jar.Deferred();
            this.name = name;

            return this.setup().def;
        },

        setup: function() {
            var request,
                self = this,
                name = this.name;

            function reject() {
                self.def.reject();
            }

            // If db already initialized don't try to create another one
            if ( !idb.open ) {

                // Open connection for database
                idb.open = indexedDB.open( "jar", jar.version = new Date().getTime() );
            }

            // In case we create instance without reopening connection to database
            if ( idb.db ) {
                self.instance.stores.idb = idb.db;
            }

            // New way to do it
            if ( idb.open.onupgradeneeded === null ) {

                request = setVersion(function() {
                    self.instance.stores.idb = idb.db = this.result;
                    createObjectStore( name );
                }, this.instance );

                request.addEventListener( "success", function() {
                    self.def.resolve();
                });

            // Old way
            } else {

                // If db exist than just update it
                if ( idb.db ) {
                    update( this );
                }

                // This will not be executed if db already exist
                (request = idb.open).addEventListener( "success", function() {

                    // Create link in jar for new db
                    self.instance.stores.idb = idb.db = this.result;

                    update( self );
                });
            }

            request.addEventListener( "error", reject );
            request.addEventListener( "blocked", reject );

            return this;
        },
    };

    proto.init.prototype = proto;

    this.idb.set = function( name, data, type, id ) {

        // Reject request if store is not exist
        if ( !contains( this.name ) ) {
            jar.reject( id );
            return this;
        }

        var request,
            self = this,
            store = idb.db.transaction([ this.name ], IDBTransaction.READ_WRITE ).objectStore( this.name );

        // We can't store DOM nodes
        if ( cantStore[ type ] ) {
            data = jar.text[ type ]( data );
        }

        data = {
            name: name,
            data: data
        };

        // Use "put", so we can rewrite data
        request = store.put( data );

        request.onsuccess = function() {
            jar.resolve( id, type, "idb" );
        };

        request.onerror = function() {
            jar.reject( id );
        };

        return this;
    };

    this.idb.get = function( name, type, id ) {

        // Reject request if store is not exist
        if ( !contains( this.name ) ) {
            jar.reject( id );
            return this;
        }

        var self = this,
            store = idb.db.transaction([ this.name ], IDBTransaction.READ_ONLY ).objectStore( this.name ),
            index = store.index( "name" ),
            request = index.get( name );

        request.onsuccess = function() {
            var data = this.result && this.result.data;

            // When data isn't there its still succesfull operation for this api, but not for jar
            if ( !data ) {
                return jar.reject( id );
            }

            // IndexedDB can't store some types of data in it original type
            // we need to serialize it to right type
            if ( cantStore[ type ] ) {
                data = jar.filters[ type ]( data );
            }

            // Some types of data can't be serialize to right type
            // like javascript code, so instead we return it like text
            // and execute it
            if ( jar.executable[ type ] ) {
                jar.filters[ type ]( data );
            }

            jar.resolve( id, data, type, "idb" );
        };

        request.onerror = function() {
            jar.reject( id );
        };

        return this;
    };

    this.idb.remove = function( name, id ) {

        // Reject request if store is not exist
        if ( !contains( this.name ) ) {
            jar.reject( id );
            return this;
        }

        var self = this,
            store = idb.db.transaction([ this.name ], IDBTransaction.READ_WRITE ).objectStore( this.name ),
            request = store.delete( name );

        request.onsuccess = function() {
            jar.resolve( id );
        };

        request.onerror = function() {
            jar.reject( id );
        };

        return this;
    };

    this.idb.clear = function( id, destroy /* internal */ ) {
        var request, store,
            stores = this.stores,
            name = this.name;

        function resolve() {
            jar.resolve( id );
        }

        function reject() {
            jar.reject( id );
        }

        // Either clear or destroy
        if ( destroy ) {
            request = setVersion(function() {
                idb.db.deleteObjectStore( name );
            }, this );

        } else {
            store = idb.db.transaction([ name ], IDBTransaction.READ_WRITE ).objectStore( name );
            request = store.clear();
        }

        request.onsuccess = resolve;
        request.onerror = reject;

        return this;
    };

    var test = [];

    function setVersion( fn, instance ) {

        // Old way to set database version
        if ( idb.db && idb.db.setVersion ) {

            // If we have active request attach to it, if not create new one
            if ( !idb.setVersion || idb.setVersion.readyState == 2 /* done */ ) {
                idb.setVersion = idb.db.setVersion( new Date().getTime() );
            }

            idb.setVersion.addEventListener( "success", fn );

        } else {
            if ( idb.open.readyState == "pending" ) {
                idb.setVersion = idb.open;

            } else {
                idb.db.close();
                idb.setVersion = indexedDB.open( "jar", jar.version = new Date().getTime() );
            }

            idb.setVersion.addEventListener( "upgradeneeded", function() {
                instance.stores.idb = idb.db = this.result;
                fn.apply( this, arguments );
            });
        }

        idb.setVersion.addEventListener( "success", function() {
            this.result.onversionchange = function() {
                this.close();
            };
        });

        return idb.setVersion;
    }

    function update( instance ) {
        var request = setVersion(function() {
            createObjectStore( instance.name );
        });

        request.addEventListener( "success", function() {
            instance.def.resolve();
        });

        request.addEventListener( "error", function() {
            instance.def.reject();
        });
    }

    function contains( name ) {
        return idb.db.objectStoreNames.contains( name );
    }

    function createObjectStore( name ) {
        if ( !idb.db.objectStoreNames.contains( name ) ) {
            idb.db.createObjectStore( name, {
                keyPath: "name"
            }).createIndex( "name", "name", {
                unique: true
            });
        }
    }

}.call( jar.fn );<|endoftext|>


<commit_before>const { createStore, applyMiddleware, compose} = require('redux');
const reducers = require('../reducers');

import {persistStore, autoRehydrate} from 'redux-persist'
import localForage from 'localforage'
import PouchMiddleware from 'pouch-redux-middleware'
import PouchDB from 'pouchdb';
import PouchDBAuthentication from 'pouchdb-authentication';
PouchDB.plugin(PouchDBAuthentication);

import injectTapEventPlugin from 'react-tap-event-plugin';
injectTapEventPlugin();

function getURLParameter(name) {
  return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [null, ''])[1].replace(/\+/g, '%20')) || undefined;
}

module.exports = function(initialState) {

  const db = new PouchDB('slides');

  const pouchMiddleware = PouchMiddleware({
    path: '/slides',
    db,
    actions: {
      remove: doc => store.dispatch({type: 'DELETE_SLIDE', id: doc._id}),
      insert: doc => store.dispatch({type: 'INSERT_SLIDE', slide: doc}),
      update: doc => store.dispatch({type: 'UPDATE_SLIDE', slide: doc})
    }
  })

  const finalCreateStore = compose(
    applyMiddleware(pouchMiddleware),
    autoRehydrate(),
    window.devToolsExtension ? window.devToolsExtension() : f => f
  )(createStore);

  const store = finalCreateStore(reducers, initialState);

  const persistStoreConfig = {
    whitelist: ['settings'],
    storage: localForage
  }
  persistStore(store, persistStoreConfig,() => {
    const remoteDbSettingsFromStore = store.getState().settings;

    const remoteDbSettingsFromUrl = {
      remoteDbUrl: getURLParameter('remoteDbUrl'),
      remoteDbUser: parseInt(getURLParameter('remoteDbUser')),
      remoteDbPassowrd: parseInt(getURLParameter('remoteDbPassword')),
      syncMode: parseInt(getURLParameter('syncMode')),
      enabled: true
    }

    let remoteDbSettings = remoteDbSettingsFromStore;

    // Checking if there are url parameters in order to override the remote database settings from the store
    // Note: Only url and syncMode need to be set, as user and password are optional and only be used with remote
    // databases with restricted access
    if (typeof remoteDbSettingsFromUrl.remoteDbUrl !== 'undefined' &&
        typeof remoteDbSettingsFromUrl.syncMode !== 'undefined' ) {
      remoteDbSettings = remoteDbSettingsFromUrl;
    }

    const remoteDb = new PouchDB(remoteDbSettings.remoteDbUrl, {skipSetup: true});
    // Clearing a previously created session
    remoteDb.logout();

    //var db = new PouchDB('http://localhost:5984/mydb', {skipSetup: true});
    // Trying to authenticate against the remote database if necessary
    if (typeof remoteDbSettings.remoteDbUser !== 'undefined' &&
        typeof remoteDbSettings.remoteDbPassword !== 'undefined' ) {
      remoteDb.login(remoteDbSettings.remoteDbUser, remoteDbSettings.remoteDbPassword, function (err, response) {
        if (err) {
          if (err.name === 'unauthorized') {
            // name or password incorrect
          } else {
            // cosmic rays, a meteor, etc.
          }
        }
      });
    }

    if (remoteDbSettings.enabled) {
      switch (remoteDbSettings.syncMode) {
        case 1:
          db.replicate.from(remoteDb, {
            live: true,
            retry: true
          })
          /*
            .on('change', function (change) {
            console.log('yo, something changed!');
          }).on('paused', function (info) {
            console.log('replication was paused, usually because of a lost connection');
          }).on('active', function (info) {
            console.log('replication was resumed');
          }).on('error', function (err) {
            console.log('totally unhandled error (shouldn\'t happen)');
          })
          */
          ;
          break;
        case 2:
          db.replicate.to(remoteDb, {
            live: true,
            retry: true
          })
          /*
            .on('change', function (change) {
            console.log('yo, something changed!');
          }).on('paused', function (info) {
            console.log('replication was paused, usually because of a lost connection');
          }).on('active', function (info) {
            console.log('replication was resumed');
          }).on('error', function (err) {
            console.log('totally unhandled error (shouldn\'t happen)');
          })
          */
          ;
          break;
        case 3:
          db.sync(remoteDb, {
            live: true,
            retry: true
          })
          /*
          .on('change', function (change) {
            console.log('yo, something changed!');
          }).on('paused', function (info) {
            console.log('replication was paused, usually because of a lost connection');
          }).on('active', function (info) {
            console.log('replication was resumed');
          }).on('error', function (err) {
            console.log('totally unhandled error (shouldn\'t happen)');
          })
          */
          ;
          break;
      }
    }
  });

  if (module.hot) {
    // Enable Webpack hot module replacement for reducers
    module.hot.accept('../reducers', () => {
      const nextReducer = require('../reducers');
      store.replaceReducer(nextReducer)
    })
  }

  return store
}
<commit_msg>Fixes an error regarding uninitialized remote databases<commit_after>const { createStore, applyMiddleware, compose} = require('redux');
const reducers = require('../reducers');

import {persistStore, autoRehydrate} from 'redux-persist'
import localForage from 'localforage'
import PouchMiddleware from 'pouch-redux-middleware'
import PouchDB from 'pouchdb';
import PouchDBAuthentication from 'pouchdb-authentication';
PouchDB.plugin(PouchDBAuthentication);

import injectTapEventPlugin from 'react-tap-event-plugin';
injectTapEventPlugin();

function getURLParameter(name) {
  return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [null, ''])[1].replace(/\+/g, '%20')) || undefined;
}

module.exports = function(initialState) {

  const db = new PouchDB('slides');

  const pouchMiddleware = PouchMiddleware({
    path: '/slides',
    db,
    actions: {
      remove: doc => store.dispatch({type: 'DELETE_SLIDE', id: doc._id}),
      insert: doc => store.dispatch({type: 'INSERT_SLIDE', slide: doc}),
      update: doc => store.dispatch({type: 'UPDATE_SLIDE', slide: doc})
    }
  })

  const finalCreateStore = compose(
    applyMiddleware(pouchMiddleware),
    autoRehydrate(),
    window.devToolsExtension ? window.devToolsExtension() : f => f
  )(createStore);

  const store = finalCreateStore(reducers, initialState);

  const persistStoreConfig = {
    whitelist: ['settings'],
    storage: localForage
  }
  persistStore(store, persistStoreConfig,() => {
    const remoteDbSettingsFromStore = store.getState().settings;

    const remoteDbSettingsFromUrl = {
      remoteDbUrl: getURLParameter('remoteDbUrl'),
      remoteDbUser: parseInt(getURLParameter('remoteDbUser')),
      remoteDbPassowrd: parseInt(getURLParameter('remoteDbPassword')),
      syncMode: parseInt(getURLParameter('syncMode')),
      enabled: true
    }

    let remoteDbSettings = remoteDbSettingsFromStore;

    // Checking if there are url parameters in order to override the remote database settings from the store
    // Note: Only url and syncMode need to be set, as user and password are optional and only be used with remote
    // databases with restricted access
    if (typeof remoteDbSettingsFromUrl.remoteDbUrl !== 'undefined' &&
        typeof remoteDbSettingsFromUrl.syncMode !== 'undefined' ) {
      remoteDbSettings = remoteDbSettingsFromUrl;
    }

    if (remoteDbSettings.enabled) {
      const remoteDb = new PouchDB(remoteDbSettings.remoteDbUrl, {skipSetup: true});
      // Clearing a previously created session
      remoteDb.logout();

      //var db = new PouchDB('http://localhost:5984/mydb', {skipSetup: true});
      // Trying to authenticate against the remote database if necessary
      if (typeof remoteDbSettings.remoteDbUser !== 'undefined' &&
        typeof remoteDbSettings.remoteDbPassword !== 'undefined' ) {
        remoteDb.login(remoteDbSettings.remoteDbUser, remoteDbSettings.remoteDbPassword, function (err, response) {
          if (err) {
            if (err.name === 'unauthorized') {
              // name or password incorrect
            } else {
              // cosmic rays, a meteor, etc.
            }
          }
        });
      }

      switch (remoteDbSettings.syncMode) {
        case 1:
          db.replicate.from(remoteDb, {
            live: true,
            retry: true
          })
            .on('change', function (change) {
            console.log('yo, something changed!');
          }).on('paused', function (info) {
            console.log('replication was paused, usually because of a lost connection');
          }).on('active', function (info) {
            console.log('replication was resumed');
          }).on('error', function (err) {
            console.log('totally unhandled error (shouldn\'t happen)');
          });
          break;
        case 2:
          db.replicate.to(remoteDb, {
            live: true,
            retry: true
          })
            .on('change', function (change) {
            console.log('yo, something changed!');
          }).on('paused', function (info) {
            console.log('replication was paused, usually because of a lost connection');
          }).on('active', function (info) {
            console.log('replication was resumed');
          }).on('error', function (err) {
            console.log('totally unhandled error (shouldn\'t happen)');
          });
          break;
        case 3:
          db.sync(remoteDb, {
            live: true,
            retry: true
          })
          .on('change', function (change) {
            console.log('yo, something changed!');
          }).on('paused', function (info) {
            console.log('replication was paused, usually because of a lost connection');
          }).on('active', function (info) {
            console.log('replication was resumed');
          }).on('error', function (err) {
            console.log('totally unhandled error (shouldn\'t happen)');
          });
          break;
      }
    }
  });

  if (module.hot) {
    // Enable Webpack hot module replacement for reducers
    module.hot.accept('../reducers', () => {
      const nextReducer = require('../reducers');
      store.replaceReducer(nextReducer)
    })
  }

  return store
}
<|endoftext|>