<commit_before>"use strict";

(function () {

    CRUDRoutes.$inject = ['$stateProvider'];
    function CRUDRoutes($stateProvider) {

        var defaultParentState="lateralmenu.";

        this.addAllRoutes = function (config) {
            //Al ser todas las rutas no permitimos la variable "route" ya que tendría valores distintos para cada una
            delete config.route;
            this.addSearchRoute(config);
            this.addNewRoute(config);
            this.addEditRoute(config);
            this.addDeleteRoute(config);
            this.addViewRoute(config);
        };

        this.addSearchRoute = function (config) {
            var entity = config.entity;
            var expand = config.expand;
            var route = config.route;
            var htmlBasePath = (config.htmlBasePath || ".");
            var parentState=(config.parentState?config.parentState+".":defaultParentState);

            if (!entity) {
                throw Error("El argumento 'entity' no puede estar vacio");
            }

            var lowerEntityName = entity.toLowerCase();
            var upperCamelEntityName = entity.charAt(0).toUpperCase() + entity.slice(1);

            var name1 = parentState + lowerEntityName + "search";
            var name2 = parentState + lowerEntityName + "searchParent";
            var path1 = '/' + lowerEntityName + '/search';
            var path2 = '/' + lowerEntityName + '/search/:parentProperty/:parentId';
            var definitiveRoute = {
                templateUrl: htmlBasePath + "/" + lowerEntityName + '/search.html',
                controller: upperCamelEntityName + 'SearchController'
            };
            var resolve = {
                controllerParams: ['$stateParams', function ($stateParams) {
                        return {
                            entity: entity,
                            parentProperty: $stateParams.parentProperty,
                            parentId: $stateParams.parentId,
                            expand: expand
                        };
                    }],
                metadata: ['metadataEntities', function (metadataEntities) {
                        return metadataEntities.load(entity, expand);
                    }]
            };

            angular.extend(definitiveRoute, route);
            definitiveRoute.resolve = definitiveRoute.resolve || {};
            angular.extend(definitiveRoute.resolve, resolve);

            var routeWithoutParent = angular.copy(definitiveRoute);
            routeWithoutParent.url = path1;
            $stateProvider.state(name1, routeWithoutParent);

            var routeWithParent = angular.copy(definitiveRoute);
            routeWithParent.url = path2;
            $stateProvider.state(name2, routeWithParent);
        };

        this.addNewRoute = function (config) {
            var entity = config.entity;
            var expand = config.expand;
            var route = config.route;
            var htmlBasePath = (config.htmlBasePath || ".");
            var parentState=(config.parentState?config.parentState+".":defaultParentState);

            if (!entity) {
                throw Error("El argumento 'entity' no puede estar vacio");
            }

            var lowerEntityName = entity.toLowerCase();
            var upperCamelEntityName = entity.charAt(0).toUpperCase() + entity.slice(1);

            var name1 = parentState + lowerEntityName + "new";
            var name2 = parentState + lowerEntityName + "newParent";
            var path1 = '/' + lowerEntityName + '/new';
            var path2 = '/' + lowerEntityName + '/new/:parentProperty/:parentId';

            var definitiveRoute = {
                templateUrl: htmlBasePath + "/" + lowerEntityName + '/detail.html',
                controller: upperCamelEntityName + 'NewEditController'
            };

            var resolve = {
                controllerParams: ['$stateParams', function ($stateParams) {
                        return {
                            entity: entity,
                            controllerAction: "NEW",
                            id: null,
                            parentProperty: $stateParams.parentProperty,
                            parentId: $stateParams.parentId,
                            expand: expand
                        };
                    }],
                metadata: ['metadataEntities', function (metadataEntities) {
                        return metadataEntities.load(entity, expand);
                    }]
            };

            angular.extend(definitiveRoute, route);
            definitiveRoute.resolve = definitiveRoute.resolve || {};
            angular.extend(definitiveRoute.resolve, resolve);

            var routeWithoutParent = angular.copy(definitiveRoute);
            routeWithoutParent.url = path1;
            $stateProvider.state(name1, routeWithoutParent);

            var routeWithParent = angular.copy(definitiveRoute);
            routeWithParent.url = path2;
            $stateProvider.state(name2, routeWithParent);

        };
        this.addViewRoute = function (config) {
            var entity = config.entity;
            var expand = config.expand;
            var route = config.route;
            var htmlBasePath = (config.htmlBasePath || ".");
            var parentState=(config.parentState?config.parentState+".":defaultParentState);

            if (!entity) {
                throw Error("El argumento 'entity' no puede estar vacio");
            }

            var lowerEntityName = entity.toLowerCase();
            var upperCamelEntityName = entity.charAt(0).toUpperCase() + entity.slice(1);

            var name1 = parentState + lowerEntityName + "view";
            var name2 = parentState + lowerEntityName + "viewParent";
            var path1 = '/' + lowerEntityName + '/view/:id';
            var path2 = '/' + lowerEntityName + '/view/:id/:parentProperty/:parentId';

            var definitiveRoute = {
                templateUrl: htmlBasePath + "/" + lowerEntityName + '/detail.html',
                controller: upperCamelEntityName + 'ViewController'
            }

            var resolve = {
                controllerParams: ['$stateParams', function ($stateParams) {
                        return {
                            entity: entity,
                            controllerAction: "VIEW",
                            id: $stateParams.id,
                            parentProperty: $stateParams.parentProperty,
                            parentId: $stateParams.parentId,
                            expand: expand
                        };
                    }],
                metadata: ['metadataEntities', function (metadataEntities) {
                        return metadataEntities.load(entity, expand);
                    }]
            };

            angular.extend(definitiveRoute, route);
            definitiveRoute.resolve = definitiveRoute.resolve || {};
            angular.extend(definitiveRoute.resolve, resolve);

            var routeWithoutParent = angular.copy(definitiveRoute);
            routeWithoutParent.url = path1;
            $stateProvider.state(name1, routeWithoutParent);

            var routeWithParent = angular.copy(definitiveRoute);
            routeWithParent.url = path2;
            $stateProvider.state(name2, routeWithParent);
        };
        this.addEditRoute = function (config) {
            var entity = config.entity;
            var expand = config.expand;
            var route = config.route;
            var htmlBasePath = (config.htmlBasePath || ".");
            var parentState=(config.parentState?config.parentState+".":defaultParentState);

            if (!entity) {
                throw Error("El argumento 'entity' no puede estar vacio");
            }

            var lowerEntityName = entity.toLowerCase();
            var upperCamelEntityName = entity.charAt(0).toUpperCase() + entity.slice(1);

            var name1 = parentState + lowerEntityName + "edit";
            var name2 = parentState + lowerEntityName + "editParent";
            var path1 = '/' + lowerEntityName + '/edit/:id';
            var path2 = '/' + lowerEntityName + '/edit/:id/:parentProperty/:parentId';

            var definitiveRoute = {
                templateUrl: htmlBasePath + "/" + lowerEntityName + '/detail.html',
                controller: upperCamelEntityName + 'NewEditController'

            }

            var resolve = {
                controllerParams: ['$stateParams', function ($stateParams) {
                        return {
                            entity: entity,
                            controllerAction: "EDIT",
                            id: $stateParams.id,
                            parentProperty: $stateParams.parentProperty,
                            parentId: $stateParams.parentId,
                            expand: expand
                        };
                    }],
                metadata: ['metadataEntities', function (metadataEntities) {
                        return metadataEntities.load(entity, expand);
                    }]
            };

            angular.extend(definitiveRoute, route);
            definitiveRoute.resolve = definitiveRoute.resolve || {};
            angular.extend(definitiveRoute.resolve, resolve);

            var routeWithoutParent = angular.copy(definitiveRoute);
            routeWithoutParent.url = path1;
            $stateProvider.state(name1, routeWithoutParent);

            var routeWithParent = angular.copy(definitiveRoute);
            routeWithParent.url = path2;
            $stateProvider.state(name2, routeWithParent);
        };
        this.addDeleteRoute = function (config) {
            var entity = config.entity;
            var expand = config.expand;
            var route = config.route;
            var htmlBasePath = (config.htmlBasePath || ".");
            var parentState=(config.parentState?config.parentState+".":defaultParentState);

            if (!entity) {
                throw Error("El argumento 'entity' no puede estar vacio");
            }

            var lowerEntityName = entity.toLowerCase();
            var upperCamelEntityName = entity.charAt(0).toUpperCase() + entity.slice(1);

            var name1 = parentState + lowerEntityName + "delete";
            var name2 = parentState + lowerEntityName + "deleteParent";
            var path1 = '/' + lowerEntityName + '/delete/:id';
            var path2 = '/' + lowerEntityName + '/delete/:id/:parentProperty/:parentId';

            var definitiveRoute = {
                templateUrl: htmlBasePath + "/" + lowerEntityName + '/detail.html',
                controller: upperCamelEntityName + 'DeleteController'
            };

            var resolve = {
                controllerParams: ['$stateParams', function ($stateParams) {
                        return {
                            entity: entity,
                            controllerAction: "DELETE",
                            id: $stateParams.id,
                            parentProperty: $stateParams.parentProperty,
                            parentId: $stateParams.parentId,
                            expand: expand
                        };
                    }],
                metadata: ['metadataEntities', function (metadataEntities) {
                        return metadataEntities.load(entity, expand);
                    }]
            };

            angular.extend(definitiveRoute, route);
            definitiveRoute.resolve = definitiveRoute.resolve || {};
            angular.extend(definitiveRoute.resolve, resolve);

            var routeWithoutParent = angular.copy(definitiveRoute);
            routeWithoutParent.url = path1;
            $stateProvider.state(name1, routeWithoutParent);

            var routeWithParent = angular.copy(definitiveRoute);
            routeWithParent.url = path2;
            $stateProvider.state(name2, routeWithParent);
        };
        this.$get = function () {
            //Realmente no queremos nada aqui pero angular nos obliga.
            return {};
        };

    }

    angular.module('es.logongas.ix3').provider("crudRoutes", CRUDRoutes);

})();<commit_msg>Permitir definir el estado por defecto del crudroutes<commit_after>"use strict";

(function () {

    CRUDRoutes.$inject = ['$stateProvider'];
    function CRUDRoutes($stateProvider) {

        this.defaultParentState="lateralmenu";

        this.addAllRoutes = function (config) {
            //Al ser todas las rutas no permitimos la variable "route" ya que tendría valores distintos para cada una
            delete config.route;
            this.addSearchRoute(config);
            this.addNewRoute(config);
            this.addEditRoute(config);
            this.addDeleteRoute(config);
            this.addViewRoute(config);
        };

        this.addSearchRoute = function (config) {
            var entity = config.entity;
            var expand = config.expand;
            var route = config.route;
            var htmlBasePath = (config.htmlBasePath || ".");
            var parentState=(config.parentState?config.parentState:this.defaultParentState);

            if (!entity) {
                throw Error("El argumento 'entity' no puede estar vacio");
            }

            var lowerEntityName = entity.toLowerCase();
            var upperCamelEntityName = entity.charAt(0).toUpperCase() + entity.slice(1);

            var name1 = parentState + "." + lowerEntityName + "_search";
            var name2 = parentState + "." + lowerEntityName + "_search_parent";
            var path1 = '/' + lowerEntityName + '/search';
            var path2 = '/' + lowerEntityName + '/search/:parentProperty/:parentId';
            var definitiveRoute = {
                templateUrl: htmlBasePath + "/" + lowerEntityName + '/search.html',
                controller: upperCamelEntityName + 'SearchController'
            };
            var resolve = {
                controllerParams: ['$stateParams', function ($stateParams) {
                        return {
                            entity: entity,
                            parentProperty: $stateParams.parentProperty,
                            parentId: $stateParams.parentId,
                            expand: expand
                        };
                    }],
                metadata: ['metadataEntities', function (metadataEntities) {
                        return metadataEntities.load(entity, expand);
                    }]
            };

            angular.extend(definitiveRoute, route);
            definitiveRoute.resolve = definitiveRoute.resolve || {};
            angular.extend(definitiveRoute.resolve, resolve);

            var routeWithoutParent = angular.copy(definitiveRoute);
            routeWithoutParent.url = path1;
            $stateProvider.state(name1, routeWithoutParent);

            var routeWithParent = angular.copy(definitiveRoute);
            routeWithParent.url = path2;
            $stateProvider.state(name2, routeWithParent);
        };

        this.addNewRoute = function (config) {
            var entity = config.entity;
            var expand = config.expand;
            var route = config.route;
            var htmlBasePath = (config.htmlBasePath || ".");
            var parentState=(config.parentState?config.parentState+".":this.defaultParentState+".");

            if (!entity) {
                throw Error("El argumento 'entity' no puede estar vacio");
            }

            var lowerEntityName = entity.toLowerCase();
            var upperCamelEntityName = entity.charAt(0).toUpperCase() + entity.slice(1);

            var name1 = parentState + "." + lowerEntityName + "_new";
            var name2 = parentState + "." + lowerEntityName + "_new_parent";
            var path1 = '/' + lowerEntityName + '/new';
            var path2 = '/' + lowerEntityName + '/new/:parentProperty/:parentId';

            var definitiveRoute = {
                templateUrl: htmlBasePath + "/" + lowerEntityName + '/detail.html',
                controller: upperCamelEntityName + 'NewEditController'
            };

            var resolve = {
                controllerParams: ['$stateParams', function ($stateParams) {
                        return {
                            entity: entity,
                            controllerAction: "NEW",
                            id: null,
                            parentProperty: $stateParams.parentProperty,
                            parentId: $stateParams.parentId,
                            expand: expand
                        };
                    }],
                metadata: ['metadataEntities', function (metadataEntities) {
                        return metadataEntities.load(entity, expand);
                    }]
            };

            angular.extend(definitiveRoute, route);
            definitiveRoute.resolve = definitiveRoute.resolve || {};
            angular.extend(definitiveRoute.resolve, resolve);

            var routeWithoutParent = angular.copy(definitiveRoute);
            routeWithoutParent.url = path1;
            $stateProvider.state(name1, routeWithoutParent);

            var routeWithParent = angular.copy(definitiveRoute);
            routeWithParent.url = path2;
            $stateProvider.state(name2, routeWithParent);

        };
        this.addViewRoute = function (config) {
            var entity = config.entity;
            var expand = config.expand;
            var route = config.route;
            var htmlBasePath = (config.htmlBasePath || ".");
            var parentState=(config.parentState?config.parentState+".":this.defaultParentState+".");

            if (!entity) {
                throw Error("El argumento 'entity' no puede estar vacio");
            }

            var lowerEntityName = entity.toLowerCase();
            var upperCamelEntityName = entity.charAt(0).toUpperCase() + entity.slice(1);

            var name1 = parentState + "." + lowerEntityName + "_view_";
            var name2 = parentState + "." + lowerEntityName + "_view_parent";
            var path1 = '/' + lowerEntityName + '/view/:id';
            var path2 = '/' + lowerEntityName + '/view/:id/:parentProperty/:parentId';

            var definitiveRoute = {
                templateUrl: htmlBasePath + "/" + lowerEntityName + '/detail.html',
                controller: upperCamelEntityName + 'ViewController'
            }

            var resolve = {
                controllerParams: ['$stateParams', function ($stateParams) {
                        return {
                            entity: entity,
                            controllerAction: "VIEW",
                            id: $stateParams.id,
                            parentProperty: $stateParams.parentProperty,
                            parentId: $stateParams.parentId,
                            expand: expand
                        };
                    }],
                metadata: ['metadataEntities', function (metadataEntities) {
                        return metadataEntities.load(entity, expand);
                    }]
            };

            angular.extend(definitiveRoute, route);
            definitiveRoute.resolve = definitiveRoute.resolve || {};
            angular.extend(definitiveRoute.resolve, resolve);

            var routeWithoutParent = angular.copy(definitiveRoute);
            routeWithoutParent.url = path1;
            $stateProvider.state(name1, routeWithoutParent);

            var routeWithParent = angular.copy(definitiveRoute);
            routeWithParent.url = path2;
            $stateProvider.state(name2, routeWithParent);
        };
        this.addEditRoute = function (config) {
            var entity = config.entity;
            var expand = config.expand;
            var route = config.route;
            var htmlBasePath = (config.htmlBasePath || ".");
            var parentState=(config.parentState?config.parentState+".":this.defaultParentState+".");

            if (!entity) {
                throw Error("El argumento 'entity' no puede estar vacio");
            }

            var lowerEntityName = entity.toLowerCase();
            var upperCamelEntityName = entity.charAt(0).toUpperCase() + entity.slice(1);

            var name1 = parentState + "." + lowerEntityName + "_edit_";
            var name2 = parentState + "." + lowerEntityName + "_edit_parent";
            var path1 = '/' + lowerEntityName + '/edit/:id';
            var path2 = '/' + lowerEntityName + '/edit/:id/:parentProperty/:parentId';

            var definitiveRoute = {
                templateUrl: htmlBasePath + "/" + lowerEntityName + '/detail.html',
                controller: upperCamelEntityName + 'NewEditController'

            }

            var resolve = {
                controllerParams: ['$stateParams', function ($stateParams) {
                        return {
                            entity: entity,
                            controllerAction: "EDIT",
                            id: $stateParams.id,
                            parentProperty: $stateParams.parentProperty,
                            parentId: $stateParams.parentId,
                            expand: expand
                        };
                    }],
                metadata: ['metadataEntities', function (metadataEntities) {
                        return metadataEntities.load(entity, expand);
                    }]
            };

            angular.extend(definitiveRoute, route);
            definitiveRoute.resolve = definitiveRoute.resolve || {};
            angular.extend(definitiveRoute.resolve, resolve);

            var routeWithoutParent = angular.copy(definitiveRoute);
            routeWithoutParent.url = path1;
            $stateProvider.state(name1, routeWithoutParent);

            var routeWithParent = angular.copy(definitiveRoute);
            routeWithParent.url = path2;
            $stateProvider.state(name2, routeWithParent);
        };
        this.addDeleteRoute = function (config) {
            var entity = config.entity;
            var expand = config.expand;
            var route = config.route;
            var htmlBasePath = (config.htmlBasePath || ".");
            var parentState=(config.parentState?config.parentState+".":this.defaultParentState+".");

            if (!entity) {
                throw Error("El argumento 'entity' no puede estar vacio");
            }

            var lowerEntityName = entity.toLowerCase();
            var upperCamelEntityName = entity.charAt(0).toUpperCase() + entity.slice(1);

            var name1 = parentState + "." + lowerEntityName + "_delete_";
            var name2 = parentState + "." + lowerEntityName + "_delete_parent";
            var path1 = '/' + lowerEntityName + '/delete/:id';
            var path2 = '/' + lowerEntityName + '/delete/:id/:parentProperty/:parentId';

            var definitiveRoute = {
                templateUrl: htmlBasePath + "/" + lowerEntityName + '/detail.html',
                controller: upperCamelEntityName + 'DeleteController'
            };

            var resolve = {
                controllerParams: ['$stateParams', function ($stateParams) {
                        return {
                            entity: entity,
                            controllerAction: "DELETE",
                            id: $stateParams.id,
                            parentProperty: $stateParams.parentProperty,
                            parentId: $stateParams.parentId,
                            expand: expand
                        };
                    }],
                metadata: ['metadataEntities', function (metadataEntities) {
                        return metadataEntities.load(entity, expand);
                    }]
            };

            angular.extend(definitiveRoute, route);
            definitiveRoute.resolve = definitiveRoute.resolve || {};
            angular.extend(definitiveRoute.resolve, resolve);

            var routeWithoutParent = angular.copy(definitiveRoute);
            routeWithoutParent.url = path1;
            $stateProvider.state(name1, routeWithoutParent);

            var routeWithParent = angular.copy(definitiveRoute);
            routeWithParent.url = path2;
            $stateProvider.state(name2, routeWithParent);
        };
        this.$get = function () {
            //Realmente no queremos nada aqui pero angular nos obliga.
            return {};
        };

    }

    angular.module('es.logongas.ix3').provider("crudRoutes", CRUDRoutes);

})();<|endoftext|>


<commit_before>var app = angular.module('GhFp', ['ngRoute']);

app.config(function ($routeProvider) {
   $routeProvider
      .when('/', {
    	  controller:  'main',
          templateUrl: 'src/html/views/main.html'
      })
      .when('/test', {
    	  controller:  'test',
          templateUrl: 'src/html/views/test.html'
      })
      .otherwise({redirectTo: '/'});
});

app.controller('main', function($scope) {
     $scope.accounts = [{ name: "Linkedin", url: "http://pl.linkedin.com/pub/rados%C5%82aw-go%C5%82%C4%99biewski/70/832/35/"},
                        { name: "G+", url: "https://google.com/+RadoslawGolebiewski"},
                        { name: "local test", url: "#/test"}];
});

app.controller('test', function($scope, $location, $route) {
     $scope.data = [{ urlName: 'test'}];
});
<commit_msg>Not used params removed.<commit_after>var app = angular.module('GhFp', ['ngRoute']);

app.config(function ($routeProvider) {
   $routeProvider
      .when('/', {
    	  controller:  'main',
          templateUrl: 'src/html/views/main.html'
      })
      .when('/test', {
    	  controller:  'test',
          templateUrl: 'src/html/views/test.html'
      })
      .otherwise({redirectTo: '/'});
});

app.controller('main', function($scope) {
     $scope.accounts = [{ name: "Linkedin", url: "http://pl.linkedin.com/pub/rados%C5%82aw-go%C5%82%C4%99biewski/70/832/35/"},
                        { name: "G+", url: "https://google.com/+RadoslawGolebiewski"},
                        { name: "local test", url: "#/test"}];
});

app.controller('test', function($scope) {
     $scope.data = [{ urlName: 'test'}];
});
<|endoftext|>


<commit_before>const gulp = require('gulp');
const config = require('./config');
const Server = require('karma').Server;

gulp.task('karma:start', function(done) {
  new Server({
    configFile: config.PATHS.root + '/karma.conf.js',
    singleRun: true,
    browsers: ['Chrome']
  }, function() {
    done();
  }).start();
});

gulp.task('karma:start:watch', function(done) {
  new Server({
    configFile: config.PATHS.root + '/karma.conf.js',
    singleRun: false,
    browsers: ['Chrome']
  }, function() {
    done();
  }).start();
});
<commit_msg>chore(karma): do not override browser for karma on travis-ci<commit_after>const gulp = require('gulp');
const config = require('./config');
const Server = require('karma').Server;

gulp.task('karma:start', function(done) {
  new Server({
    configFile: config.PATHS.root + '/karma.conf.js',
    singleRun: true
  }, function() {
    done();
  }).start();
});

gulp.task('karma:start:watch', function(done) {
  new Server({
    configFile: config.PATHS.root + '/karma.conf.js',
    singleRun: false,
    browsers: ['Chrome']
  }, function() {
    done();
  }).start();
});
<|endoftext|>


<commit_before>/**
 * DEPRECATED - NOT USED
 */

'use strict';

module.exports = (function () {
  var _             = require('../lib/helper')._,
      Q             = require('q'),
      path          = require('path'),
      spawn         = require('child_process').spawn,
      // running       = require('is-running'),
      binPath       = path.join(process.env.PWD, 'bin'),
      db            = require('./../lib/db'),
      eventEmitter_ = new (require('events').EventEmitter)(),
      proxyChilds   = {},
      mockChilds    = {};

  var Proxy = function (properties) {
    var self = this;

    this._id =
    this._port =
    this._target =
    this._isRecording;

    _.privateMerge(this, properties);

    // set to true if some childs are started
    this._isRunning = _.has(proxyChilds, this._id);
    this._isMocked = _.has(mockChilds, this._id);

    // enable the proxy if proxy or mock is running
    this._isEnabled = this._isRunning || this._isMocked;

    // update the disable flag in DB
    db.model('Proxy').get(this._id, function (err, Proxy) {
      if (Proxy) {
        Proxy.isEnabled = self._isEnabled;
        Proxy.save(db.log);
      }
    });
  };

  /**
   * Add a proxy in DB.
   */
  Proxy.prototype.add = function (callback) {
    db.model('Proxy').create([_.publicProperties(this)], callback);
  };

  /**
   * Stop all child processes and remove a proxy from DB.
   */
  Proxy.prototype.remove = function (callback) {
    var self = this;

    this.stopAll().then(function () {
      db.model('Proxy').find({id: self._id}).remove(callback);
    });
  };

  /**
   * Start the proxy.
   */
  Proxy.prototype.startProxy = function () {
    proxyChilds[this._id] = spawn('node', [
      path.join(binPath, 'proxy.js'),
      '--target=' + this._target,
      '--port=' + this._port,
      '--proxyId=' + this._id
    ]);

    this.bindEvent('Proxy', proxyChilds, this._id);
  };

  /**
   * Stop the child process.
   */
  Proxy.prototype.stopProxy = function () {
    var deferred = Q.defer();

    if (proxyChilds[this._id]) {
      proxyChilds[this._id].kill('SIGHUP');
      proxyChilds[this._id].on('exit', function () {
        deferred.resolve();
      });
    }

    return deferred.promise;
  };

  /**
   * Start the mock
   */
  Proxy.prototype.startMock = function () {
    mockChilds[this._id] = spawn('node', [
      path.join(binPath, 'mock.js'),
      '--port=' + this._port,
      '--proxyId=' + this._id
    ]);

    this.bindEvent('Mock', mockChilds, this._id);
  };

  /**
   * Stop the child process.
   */
  Proxy.prototype.stopMock = function () {
    var deferred = Q.defer();

    if (mockChilds[this._id]) {
      mockChilds[this._id].kill('SIGHUP');
      mockChilds[this._id].on('exit', function () {
        deferred.resolve();
      });
    }

    return deferred.promise;
  };

  /**
   * Stop all processes.
   */
  Proxy.prototype.stopAll = function () {
    var promises = [];

    if (this._isMocked) {
      promises.push(this.stopMock());
    }

    if (this._isRunning) {
      promises.push(this.stopProxy());
    }

    return Q.all(promises);
  };

  /**
   * Bind child events to websocket / logging.
   */
  Proxy.prototype.bindEvent = function (label, childs, id) {
    var self = this,
        child = childs[id];

    console.log(label + ' PID', child.pid);

    child.on('exit', function () {
      delete childs[self._id];
      self['_log' + label](label + ' has been stopped.');
    });

    child.on('error', function () {
      console.log('error', arguments);
    });

    // log stdout
    child.stdout.on('data', function (data) {
      self['_log' + label](data);
    });

    // log stderr
    child.stderr.on('data', function (data) {
      self['_log' + label](data, 'error');
    });
  };

  /**
   * Disable/enable the recording for the proxy.
   */
  Proxy.prototype.toggleRecording = function (callback) {
    var self = this;
    db.model('Proxy').get(this._id, function (err, Proxy) {
      Proxy.isRecording = self._isRecording;
      Proxy.save(function (err) {
        callback(err);
      });
    });
  };

  /**
   * Disable/enable the mock for the proxy.
   */
  Proxy.prototype.toggleMock = function () {
    var self = this,
        promises = [];

    if (this._isMocked) {
      promises.push(
        this.stopMock().then(function () {
          self.startProxy();
        })
      );
    }

    if (this._isRunning) {
      promises.push(
        this.stopProxy().then(function () {
          self.startMock();
        })
      );
    }

    return Q.all(promises);
  };

  /**
   * Enable/disable the proxy.
   */
  Proxy.prototype.toggleEnable = function (callback) {
    var self = this;

    db.model('Proxy').get(this._id, function (err, Proxy) {
      Proxy.isEnabled = self._isEnabled;

      // when adding a proxy, we don't run the proxy by default,
      // we run the mock => the proxy is "mocked" by default.
      if (!Proxy.isEnabled) {
        self.startMock();
      } else {
        // when disabling the Proxy, we stop all
        self.stopAll();
      }

      Proxy.save(function (err) {
        callback(err);
      });
    });
  };

  /**
   * Log proxy event.
   */
  Proxy.prototype._logProxy = function (message, type) {
    this._log(message, type || 'infoProxy');
  };

  /**
   * Log mock event.
   */
  Proxy.prototype._logMock = function (message, type) {
    this._log(message, type || 'infoMock');
  };

  /**
   * Log error.
   * Prefix the message by "Error:" to pass the filter in Angular.
   * See LogsCtrl.
   */
  Proxy.prototype._logError = function (message) {
    this._log('Error: ' + message, 'error');
  };

  /**
   * Emit an event for mock logging.
   * @param  {String|Buffer}  message   Message
   * @param  {String}         type      A choice between ['info', 'error']
   */
  Proxy.prototype._log = function (message, type) {
    if (message instanceof Buffer) {
      message = message.toString('utf8');
    }

    eventEmitter_.emit('log', {
      message: message,
      type: (type || 'info')
    });
  };

  /**
   * Return the event emitter for the outside communication.
   */
  Proxy.eventEmitter = function () {
    return eventEmitter_;
  };

  /**
   * List all proxies from DB.
   */
  Proxy.list = function (callback) {
    db.model('Proxy').find({}, function (err, proxies) {
      callback(err, _.map(proxies, function (properties) {
        return new Proxy(properties);
      }));
    });
  };

  return Proxy;
})();
<commit_msg>Remove deprecated file.<commit_after><|endoftext|>


<commit_before>module.exports = function(grunt) {
  var _ = (grunt.utils || grunt.util)._,
    request = require('request'),
    SauceTunnel = require('sauce-tunnel'),
    Q = require('q'),
    rqst = request.defaults({
      jar: false
    });

  //these result parsers return true if the tests all passed
  var resultParsers = {
    jasmine: function(result){
      if (result.passed === undefined){ return undefined; }
      return result.passed;
    },
    qunit: function(result){
      if (result.passed === undefined){ return undefined; }
      return result.passed == result.total;
    },
    mocha: function(result){
      if (result.passes === undefined){ return undefined; }
      return result.tests == result.passes;
    },
    'YUI Test': function(result){
      if (result.passed === undefined){ return undefined; }
      return result.passed == result.total;
    }
  };

  var TestResult = function(jobId, user, key, framework, testInterval){
    var url = 'https://saucelabs.com/rest/v1/' + user + '/js-tests/status';
    var deferred = Q.defer();

    var requestParams = {
      method: 'post',
      url: url,
      auth: {
        user: user,
        pass: key
      },
      json: true,
      body: {
        "js tests": [jobId],
      }
    };

    var checkStatus = function(){

      rqst(requestParams, function(error, response, body){

        if (error){
          deferred.resolve({
            passed: undefined,
            result: {
              message: "Error connecting to api to get test status: " + error.toString()
            }
          });
          return;
        }

        if (!body.completed){
          setTimeout(checkStatus ,testInterval);
        } else {
          var testInfo = body['js tests'][0];
          testInfo.passed = testInfo.result ? resultParsers[framework](testInfo.result) : false;
          deferred.resolve(testInfo);
        }

      });
    };

    checkStatus();

    return deferred.promise;
  };

  var TestRunner = function(user, key, testInterval) {
    this.user = user;
    this.key = key;
    this.url = 'https://saucelabs.com/rest/v1/' + this.user + '/js-tests';
    this.testInterval = testInterval;
    this.results = [];
  };

  TestRunner.prototype.runTests = function(browsers, urls, framework, tunnelIdentifier, testname, tags, build, onTestComplete, callback){

    var me = this;
    var numberOfJobs = browsers.length * urls.length;

    var addResultPromise = function(promise){
      me.results.push(promise);
      grunt.log.writeln(me.results.length, "/", numberOfJobs, 'tests started');
      if (me.results.length == numberOfJobs){

        Q.all(me.results).then(function(results){
          results = results.map(function(result){
            return result.valueOf().passed;
          });

          callback(results);
        });
      }
    };

    urls.forEach(function(url){
      me.runTest(browsers, url, framework, tunnelIdentifier, testname, tags, build, function(taskIds){

        taskIds.forEach(function(taskId){
          var resultPromise = new TestResult(taskId, me.user, me.key, framework, me.testInterval);
          addResultPromise(resultPromise);
          resultPromise.then(function(result){

            var alteredResult = onTestComplete(result);
            if (alteredResult !== undefined){
              result.passed = alteredResult;
            }

            grunt.log.subhead("\nTested %s", url);
            grunt.log.writeln("Platform: %s", result.platform);
            if (result.passed === undefined){
              grunt.log.error(result.result.message);
            } else {
              grunt.log.writeln("Passed: %s", result.passed);
            }
            grunt.log.writeln("Url %s", result.url);

            //onTestComplete(result);

          }, function(e){
            grunt.log.error('some error? %s', e);
          });
        });
      });
    });
  };

  TestRunner.prototype.runTest = function(browsers, url, framework, tunnelIdentifier, testname, tags, build, callback){

    var parsePlatforms = function(browsers){
      return browsers.map(function(browser){
        return [browser.platform, browser.browserName, browser.version || ""];
      });
    };

    var requestParams = {
      method: 'post',
      url: this.url,
      auth: {
        user: this.user,
        pass: this.key
      },
      json: true,
      body: {
        platforms: parsePlatforms(browsers),
        url: url,
        framework: framework,
        tunnel: "tunnel-identifier:" + tunnelIdentifier,
        name: testname,
        tags: tags,
        build: build
      }
    };

    rqst(requestParams, function(error, response, body){

      if (error){
        grunt.log.error("Could not connect to Sauce Labs api: %s", error);
        throw error;
      }

      if (!body['js tests'] || !body['js tests'].length){
          grunt.log.error('Error starting tests through Sauce API: %s', JSON.stringify(body));
          throw new Error('Could not start tests through Sauce API');
      }

      callback(body['js tests']);

    });
  };

  var defaultsObj = {
    username: process.env.SAUCE_USERNAME,
    key: process.env.SAUCE_ACCESS_KEY,
    identifier: Math.floor((new Date()).getTime() / 1000 - 1230768000).toString(),
    tunneled: true,
    tunnelTimeout: 120,
    testInterval: 1000 * 5,
    testReadyTimeout: 1000 * 5,
    onTestComplete: function() {

    },
    testname: "",
    tags: [],
    browsers: [{}]
  };

  function defaults(data) {
    var result = data;
    result.pages = result.url || result.urls;
    if (!_.isArray(result.pages)) {
      result.pages = [result.pages];
    }

    return result;
  }

  function configureLogEvents(tunnel) {
    var methods = ['write', 'writeln', 'error', 'ok', 'debug'];
    methods.forEach(function (method) {
      tunnel.on('log:'+method, function (text) {
        grunt.log[method](text);
      });
      tunnel.on('verbose:'+method, function (text) {
        grunt.verbose[method](text);
      });
    });
  }

  function runTask(arg, framework, callback){

    var test = new TestRunner(arg.username, arg.key, arg.testInterval);

    if (arg.tunneled){
      var tunnel = new SauceTunnel(arg.username, arg.key, arg.identifier, arg.tunneled, arg.tunnelTimeout);
      grunt.log.writeln("=> Starting Tunnel to Sauce Labs".inverse.bold);
      configureLogEvents(tunnel);

      tunnel.start(function(isCreated) {
        if (!isCreated) {
          grunt.log.error("Could not create tunnel to Sauce Labs");
          callback(false);
          return;
        }
        grunt.log.ok("Connected to Saucelabs");

        test.runTests(arg.browsers, arg.pages, framework, arg.identifier, arg.testname, arg.tags, arg.build, arg.onTestComplete, function(status){
          status = status.every(function(passed){ return passed; });
          grunt.log[status ? 'ok' : 'error']("All tests completed with status %s", status);
          grunt.log.writeln("=> Stopping Tunnel to Sauce Labs".inverse.bold);
          tunnel.stop(function() {
            callback(status);
          });
        });
      });

    } else {
      test.runTests(arg.browsers, arg.pages, framework, arg.identifier, arg.testname, arg.tags, arg.build, arg.onTestComplete, function(status){
        status = status.every(function(passed){ return passed; });
        grunt.log[status ? 'ok' : 'error']("All tests completed with status %s", status);
        callback(status);
      });
    }

  }

  grunt.registerMultiTask('saucelabs-jasmine', 'Run Jasmine test cases using Sauce Labs browsers', function() {
    var done = this.async(),
      arg = defaults(this.options(defaultsObj));

    runTask(arg, 'jasmine', done);

  });

  grunt.registerMultiTask('saucelabs-qunit', 'Run Qunit test cases using Sauce Labs browsers', function() {
    var done = this.async(),
      arg = defaults(this.options(defaultsObj));

    runTask(arg, 'qunit', done);

  });

  grunt.registerMultiTask('saucelabs-yui', 'Run YUI test cases using Sauce Labs browsers', function() {
    var done = this.async(),
    arg = defaults(this.options(defaultsObj));

    runTask(arg, 'YUI Test', done);

  });

  grunt.registerMultiTask('saucelabs-mocha', 'Run Mocha test cases using Sauce Labs browsers', function() {
    var done = this.async(),
      arg = defaults(this.options(defaultsObj));

    runTask(arg, 'mocha', done);

  });
};
<commit_msg>correct parsing of platforms parameter to deal with null OS and browser<commit_after>module.exports = function(grunt) {
  var _ = (grunt.utils || grunt.util)._,
    request = require('request'),
    SauceTunnel = require('sauce-tunnel'),
    Q = require('q'),
    rqst = request.defaults({
      jar: false
    });

  //these result parsers return true if the tests all passed
  var resultParsers = {
    jasmine: function(result){
      if (result.passed === undefined){ return undefined; }
      return result.passed;
    },
    qunit: function(result){
      if (result.passed === undefined){ return undefined; }
      return result.passed == result.total;
    },
    mocha: function(result){
      if (result.passes === undefined){ return undefined; }
      return result.tests == result.passes;
    },
    'YUI Test': function(result){
      if (result.passed === undefined){ return undefined; }
      return result.passed == result.total;
    }
  };

  var TestResult = function(jobId, user, key, framework, testInterval){
    var url = 'https://saucelabs.com/rest/v1/' + user + '/js-tests/status';
    var deferred = Q.defer();

    var requestParams = {
      method: 'post',
      url: url,
      auth: {
        user: user,
        pass: key
      },
      json: true,
      body: {
        "js tests": [jobId],
      }
    };

    var checkStatus = function(){

      rqst(requestParams, function(error, response, body){

        if (error){
          deferred.resolve({
            passed: undefined,
            result: {
              message: "Error connecting to api to get test status: " + error.toString()
            }
          });
          return;
        }

        if (!body.completed){
          setTimeout(checkStatus ,testInterval);
        } else {
          var testInfo = body['js tests'][0];
          testInfo.passed = testInfo.result ? resultParsers[framework](testInfo.result) : false;
          deferred.resolve(testInfo);
        }

      });
    };

    checkStatus();

    return deferred.promise;
  };

  var TestRunner = function(user, key, testInterval) {
    this.user = user;
    this.key = key;
    this.url = 'https://saucelabs.com/rest/v1/' + this.user + '/js-tests';
    this.testInterval = testInterval;
    this.results = [];
  };

  TestRunner.prototype.runTests = function(browsers, urls, framework, tunnelIdentifier, testname, tags, build, onTestComplete, callback){

    var me = this;
    var numberOfJobs = browsers.length * urls.length;

    var addResultPromise = function(promise){
      me.results.push(promise);
      grunt.log.writeln(me.results.length, "/", numberOfJobs, 'tests started');
      if (me.results.length == numberOfJobs){

        Q.all(me.results).then(function(results){
          results = results.map(function(result){
            return result.valueOf().passed;
          });

          callback(results);
        });
      }
    };

    urls.forEach(function(url){
      me.runTest(browsers, url, framework, tunnelIdentifier, testname, tags, build, function(taskIds){

        taskIds.forEach(function(taskId){
          var resultPromise = new TestResult(taskId, me.user, me.key, framework, me.testInterval);
          addResultPromise(resultPromise);
          resultPromise.then(function(result){

            var alteredResult = onTestComplete(result);
            if (alteredResult !== undefined){
              result.passed = alteredResult;
            }

            grunt.log.subhead("\nTested %s", url);
            grunt.log.writeln("Platform: %s", result.platform);
            if (result.passed === undefined){
              grunt.log.error(result.result.message);
            } else {
              grunt.log.writeln("Passed: %s", result.passed);
            }
            grunt.log.writeln("Url %s", result.url);

            //onTestComplete(result);

          }, function(e){
            grunt.log.error('some error? %s', e);
          });
        });
      });
    });
  };

  TestRunner.prototype.runTest = function(browsers, url, framework, tunnelIdentifier, testname, tags, build, callback){

    var parsePlatforms = function(browsers){
      return browsers.map(function(browser){
        return [browser.platform || "", browser.browserName || "", browser.version || ""];
      });
    };

    var requestParams = {
      method: 'post',
      url: this.url,
      auth: {
        user: this.user,
        pass: this.key
      },
      json: true,
      body: {
        platforms: parsePlatforms(browsers),
        url: url,
        framework: framework,
        tunnel: "tunnel-identifier:" + tunnelIdentifier,
        name: testname,
        tags: tags,
        build: build
      }
    };

    rqst(requestParams, function(error, response, body){

      if (error){
        grunt.log.error("Could not connect to Sauce Labs api: %s", error);
        throw error;
      }

      if (!body['js tests'] || !body['js tests'].length){
          grunt.log.error('Error starting tests through Sauce API: %s', JSON.stringify(body));
          throw new Error('Could not start tests through Sauce API');
      }

      callback(body['js tests']);

    });
  };

  var defaultsObj = {
    username: process.env.SAUCE_USERNAME,
    key: process.env.SAUCE_ACCESS_KEY,
    identifier: Math.floor((new Date()).getTime() / 1000 - 1230768000).toString(),
    tunneled: true,
    tunnelTimeout: 120,
    testInterval: 1000 * 5,
    testReadyTimeout: 1000 * 5,
    onTestComplete: function() {

    },
    testname: "",
    tags: [],
    browsers: [{}]
  };

  function defaults(data) {
    var result = data;
    result.pages = result.url || result.urls;
    if (!_.isArray(result.pages)) {
      result.pages = [result.pages];
    }

    return result;
  }

  function configureLogEvents(tunnel) {
    var methods = ['write', 'writeln', 'error', 'ok', 'debug'];
    methods.forEach(function (method) {
      tunnel.on('log:'+method, function (text) {
        grunt.log[method](text);
      });
      tunnel.on('verbose:'+method, function (text) {
        grunt.verbose[method](text);
      });
    });
  }

  function runTask(arg, framework, callback){

    var test = new TestRunner(arg.username, arg.key, arg.testInterval);

    if (arg.tunneled){
      var tunnel = new SauceTunnel(arg.username, arg.key, arg.identifier, arg.tunneled, arg.tunnelTimeout);
      grunt.log.writeln("=> Starting Tunnel to Sauce Labs".inverse.bold);
      configureLogEvents(tunnel);

      tunnel.start(function(isCreated) {
        if (!isCreated) {
          grunt.log.error("Could not create tunnel to Sauce Labs");
          callback(false);
          return;
        }
        grunt.log.ok("Connected to Saucelabs");

        test.runTests(arg.browsers, arg.pages, framework, arg.identifier, arg.testname, arg.tags, arg.build, arg.onTestComplete, function(status){
          status = status.every(function(passed){ return passed; });
          grunt.log[status ? 'ok' : 'error']("All tests completed with status %s", status);
          grunt.log.writeln("=> Stopping Tunnel to Sauce Labs".inverse.bold);
          tunnel.stop(function() {
            callback(status);
          });
        });
      });

    } else {
      test.runTests(arg.browsers, arg.pages, framework, arg.identifier, arg.testname, arg.tags, arg.build, arg.onTestComplete, function(status){
        status = status.every(function(passed){ return passed; });
        grunt.log[status ? 'ok' : 'error']("All tests completed with status %s", status);
        callback(status);
      });
    }

  }

  grunt.registerMultiTask('saucelabs-jasmine', 'Run Jasmine test cases using Sauce Labs browsers', function() {
    var done = this.async(),
      arg = defaults(this.options(defaultsObj));

    runTask(arg, 'jasmine', done);

  });

  grunt.registerMultiTask('saucelabs-qunit', 'Run Qunit test cases using Sauce Labs browsers', function() {
    var done = this.async(),
      arg = defaults(this.options(defaultsObj));

    runTask(arg, 'qunit', done);

  });

  grunt.registerMultiTask('saucelabs-yui', 'Run YUI test cases using Sauce Labs browsers', function() {
    var done = this.async(),
    arg = defaults(this.options(defaultsObj));

    runTask(arg, 'YUI Test', done);

  });

  grunt.registerMultiTask('saucelabs-mocha', 'Run Mocha test cases using Sauce Labs browsers', function() {
    var done = this.async(),
      arg = defaults(this.options(defaultsObj));

    runTask(arg, 'mocha', done);

  });
};
<|endoftext|>


<commit_before>
var canvas; var ctx; var saveButton;
var pos = {x: 0, y: 0};
var rawImage;
var model;

function getModel(Layers, Params) {
  try {
    model = tf.sequential({
      layers: Layers,
    });
  } catch (error) {
    alert(error);
  }

  try {
    model.compile({
      optimizer: Params.optimizer,
      loss: 'categoricalCrossentropy',
      metrics: ['accuracy'],
    });
  } catch (error) {}

  return model;
}

async function train(model, data, Params) {
  const metrics = ['loss', 'val_loss', 'acc', 'val_acc'];
  const container = {name: 'Model Training', styles: {height: '640px'}};
  const fitCallbacks = tfvis.show.fitCallbacks(container, metrics);

  // const BATCH_SIZE = 512;
  let TRAIN_DATA_SIZE = Params.trainDataSize;
  let TEST_DATA_SIZE = Params.testDataSize;
  // let WIDTH = Params.width;
  // let HEIGHT = Params.height;
  let WIDTH = 60;
  let HEIGHT = 60;

  const [trainXs, trainYs] = tf.tidy(() => {
    const d = data.nextTrainBatch(TRAIN_DATA_SIZE);
    return [d.xs.reshape([TRAIN_DATA_SIZE, HEIGHT, WIDTH, NUM_CHANNELS]), d.labels];
  });

  const [testXs, testYs] = tf.tidy(() => {
    const d = data.nextTestBatch(TEST_DATA_SIZE);
    return [d.xs.reshape([TEST_DATA_SIZE, HEIGHT, WIDTH, NUM_CHANNELS]), d.labels];
  });

  return model.fit(trainXs, trainYs, {
    batchSize: Number(Params.batchSize),
    validationData: [testXs, testYs],
    epochs: Number(Params.epochs),
    shuffle: Params.shuffle,
    callbacks: fitCallbacks,
  });
}

function save(rawImage1) {
  try {
    var raw = tf.browser.fromPixels(rawImage1, 1);
    var resized = tf.image.resizeBilinear(raw, [HEIGHT, WIDTH]);
    var tensor = resized.expandDims(0);
    var prediction = model.predict(tensor);
    var pIndex = tf.argMax(prediction, 1).dataSync();

    alert(pIndex);
  } catch (error) {
    // alert(error);
  }
}

async function run(Layers, Params) {
  // console.log(Params);
  try {
    const data = new Data();
    localforage.getItem('labels').then(async function(content) {
      let urlCreator = window.URL || window.webkitURL;
      let labelsURL = urlCreator.createObjectURL(content);
      LABELS_PATH = labelsURL;
      try {
        await data.load();
        const model = getModel(Layers, Params);
        tfvis.show.modelSummary({name: 'Model Architecture'}, model);
        await train(model, data, Params);
        alert('Training is done');
        await model.save('downloads://my-model');
      } catch (error) {
        alert(error);
        console.log(error);
      };
    });
  } catch (error) {
    alert(error);
    console.log(error);
  }
}

<commit_msg>custom_width_silly_bug_fixed<commit_after>
var canvas; var ctx; var saveButton;
var pos = {x: 0, y: 0};
var rawImage;
var model;

function getModel(Layers, Params) {
  try {
    model = tf.sequential({
      layers: Layers,
    });
  } catch (error) {
    alert(error);
  }

  try {
    model.compile({
      optimizer: Params.optimizer,
      loss: 'categoricalCrossentropy',
      metrics: ['accuracy'],
    });
  } catch (error) {}

  return model;
}

async function train(model, data, Params) {
  const metrics = ['loss', 'val_loss', 'acc', 'val_acc'];
  const container = {name: 'Model Training', styles: {height: '640px'}};
  const fitCallbacks = tfvis.show.fitCallbacks(container, metrics);

  // const BATCH_SIZE = 512;
  let TRAIN_DATA_SIZE = Params.trainDataSize;
  let TEST_DATA_SIZE = Params.testDataSize;
  let WIDTH = Params.width;
  let HEIGHT = Params.height;

  const [trainXs, trainYs] = tf.tidy(() => {
    const d = data.nextTrainBatch(TRAIN_DATA_SIZE);
    return [d.xs.reshape([TRAIN_DATA_SIZE, HEIGHT, WIDTH, NUM_CHANNELS]), d.labels];
  });

  const [testXs, testYs] = tf.tidy(() => {
    const d = data.nextTestBatch(TEST_DATA_SIZE);
    return [d.xs.reshape([TEST_DATA_SIZE, HEIGHT, WIDTH, NUM_CHANNELS]), d.labels];
  });

  return model.fit(trainXs, trainYs, {
    batchSize: Number(Params.batchSize),
    validationData: [testXs, testYs],
    epochs: Number(Params.epochs),
    shuffle: Params.shuffle,
    callbacks: fitCallbacks,
  });
}

function save(rawImage1) {
  try {
    var raw = tf.browser.fromPixels(rawImage1, 1);
    var resized = tf.image.resizeBilinear(raw, [HEIGHT, WIDTH]);
    var tensor = resized.expandDims(0);
    var prediction = model.predict(tensor);
    var pIndex = tf.argMax(prediction, 1).dataSync();

    alert(pIndex);
  } catch (error) {
    // alert(error);
  }
}

async function run(Layers, Params) {
  // console.log(Params);
  try {
    const data = new Data();
    localforage.getItem('labels').then(async function(content) {
      let urlCreator = window.URL || window.webkitURL;
      let labelsURL = urlCreator.createObjectURL(content);
      LABELS_PATH = labelsURL;
      try {
        await data.load();
        const model = getModel(Layers, Params);
        tfvis.show.modelSummary({name: 'Model Architecture'}, model);
        await train(model, data, Params);
        alert('Training is done');
        await model.save('downloads://my-model');
      } catch (error) {
        alert(error);
        console.log(error);
      };
    });
  } catch (error) {
    alert(error);
    console.log(error);
  }
}

<|endoftext|>


<commit_before>/**
 * Make data requests using events, but wrapped in promise interface
 * Depends on document level component to respond, or times out
 */
define(['util/promise', 'underscore'], function(Promise, _) {
    'use strict';

    var NO_DATA_RESPONSE_TIMEOUT_SECONDS = 4,
        currentDataRequestId = 0,
        requests = {};

    $(function() {
        $(document)
            .on('dataRequestStarted', function(event, data) {
                var request = requests[data.requestId];
                if (request) {
                    clearTimeout(request.timeoutTimer);
                }
            })
            .on('dataRequestCompleted', function(event, data) {
                var request = cleanRequest(data.requestId);
                if (request) {
                    if (data.success) {
                        request.promiseFulfill(data.result);
                    } else {
                        request.promiseReject(data.error);
                    }
                }
            });
    });

    function cleanRequest(requestId) {
        var request = requests[requestId];
        if (request) {
            clearTimeout(request.timeoutTimer);
            delete requests[requestId];
            return request;
        }
    }

    function dataRequestFromNode(node, service, method /*, args */) {
        if (!service || !method) {
            throw new Error('Service and method parameters required for dataRequest');
        }

        var argsStartIndex = 3,
            thisRequestId = currentDataRequestId++,
            $node = $(node),
            nodeEl = $node[0],
            $nodeInDom = $.contains(document.documentElement, nodeEl) ? $node : $(document),
            args = arguments.length > argsStartIndex ? _.rest(arguments, argsStartIndex) : [];
            promise = Promise.require('util/requirejs/promise!util/service/dataPromise')
                .then(function() {
                    var promise = new Promise(function(fulfill, reject) {
                        requests[thisRequestId] = {
                            promiseFulfill: fulfill,
                            promiseReject: reject,
                            timeoutTimer: _.delay(function() {
                                console.error('Data request went unhandled', service + '->' + method);
                                $nodeInDom.trigger('dataRequestCompleted', {
                                    requestId: thisRequestId,
                                    success: false,
                                    error: 'No data request handler responded'
                                })
                            }, NO_DATA_RESPONSE_TIMEOUT_SECONDS * 1000)
                        };
                    });

                    $nodeInDom.trigger('dataRequest', {
                        requestId: thisRequestId,
                        service: service,
                        method: method,
                        parameters: args
                    });

                    return promise;
                })

        promise.cancel = function() {
            var request = cleanRequest(thisRequestId);
            if (request) {
                $nodeInDom.trigger('dataRequestCancel', {
                    requestId: thisRequestId
                });
            }
        };

        return promise;
    }

    withDataRequest.dataRequest = _.partial(dataRequestFromNode, document);

    return withDataRequest;

    function withDataRequest() {

        if (!('dataRequest' in this)) {
            this.dataRequest = function(service, method /*, args */) {
                Array.prototype.splice.call(arguments, 0, 0, this.$node);
                return dataRequestFromNode.apply(this, arguments);
            }
        }
    }
});
<commit_msg>Fix data request dep<commit_after>/**
 * Make data requests using events, but wrapped in promise interface
 * Depends on document level component to respond, or times out
 */
define(['util/promise', 'underscore', 'jquery'], function(Promise, _, $) {
    'use strict';

    var NO_DATA_RESPONSE_TIMEOUT_SECONDS = 4,
        currentDataRequestId = 0,
        requests = {};

    $(function() {
        $(document)
            .on('dataRequestStarted', function(event, data) {
                var request = requests[data.requestId];
                if (request) {
                    clearTimeout(request.timeoutTimer);
                }
            })
            .on('dataRequestCompleted', function(event, data) {
                var request = cleanRequest(data.requestId);
                if (request) {
                    if (data.success) {
                        request.promiseFulfill(data.result);
                    } else {
                        request.promiseReject(data.error);
                    }
                }
            });
    });

    function cleanRequest(requestId) {
        var request = requests[requestId];
        if (request) {
            clearTimeout(request.timeoutTimer);
            delete requests[requestId];
            return request;
        }
    }

    function dataRequestFromNode(node, service, method /*, args */) {
        if (!service || !method) {
            throw new Error('Service and method parameters required for dataRequest');
        }

        var argsStartIndex = 3,
            thisRequestId = currentDataRequestId++,
            $node = $(node),
            nodeEl = $node[0],
            $nodeInDom = $.contains(document.documentElement, nodeEl) ? $node : $(document),
            args = arguments.length > argsStartIndex ? _.rest(arguments, argsStartIndex) : [];
            promise = Promise.require('util/requirejs/promise!util/service/dataPromise')
                .then(function() {
                    var promise = new Promise(function(fulfill, reject) {
                        requests[thisRequestId] = {
                            promiseFulfill: fulfill,
                            promiseReject: reject,
                            timeoutTimer: _.delay(function() {
                                console.error('Data request went unhandled', service + '->' + method);
                                $nodeInDom.trigger('dataRequestCompleted', {
                                    requestId: thisRequestId,
                                    success: false,
                                    error: 'No data request handler responded'
                                })
                            }, NO_DATA_RESPONSE_TIMEOUT_SECONDS * 1000)
                        };
                    });

                    $nodeInDom.trigger('dataRequest', {
                        requestId: thisRequestId,
                        service: service,
                        method: method,
                        parameters: args
                    });

                    return promise;
                })

        promise.cancel = function() {
            var request = cleanRequest(thisRequestId);
            if (request) {
                $nodeInDom.trigger('dataRequestCancel', {
                    requestId: thisRequestId
                });
            }
        };

        return promise;
    }

    withDataRequest.dataRequest = _.partial(dataRequestFromNode, document);

    return withDataRequest;

    function withDataRequest() {

        if (!('dataRequest' in this)) {
            this.dataRequest = function(service, method /*, args */) {
                Array.prototype.splice.call(arguments, 0, 0, this.$node);
                return dataRequestFromNode.apply(this, arguments);
            }
        }
    }
});
<|endoftext|>


<commit_before><commit_msg>removed test data<commit_after><|endoftext|>


<commit_before>// Copyright 2015, University of Colorado Boulder

/**
 * Initializes phet globals that are used by all simulations, including assertions, togetherEvents and query-parameters.
 * See https://github.com/phetsims/phetcommon/issues/23
 *
 * PhET Simulations can be launched with query parameters which enable certain features.  To use a query parameter,
 * provide the full URL of the simulation and append a question mark (?) then the query parameter (and optionally its
 * value assignment).  For instance:
 * http://www.colorado.edu/physics/phet/dev/html/reactants-products-and-leftovers/1.0.0-dev.13/reactants-products-and-leftovers_en.html?dev
 *
 * Here is an example of a value assignment:
 * http://www.colorado.edu/physics/phet/dev/html/reactants-products-and-leftovers/1.0.0-dev.13/reactants-products-and-leftovers_en.html?webgl=false
 *
 * To use multiple query parameters, specify the question mark before the first query parameter, then ampersands (&)
 * between other query parameters.  Here is an example of multiple query parameters:
 * http://www.colorado.edu/physics/phet/dev/html/reactants-products-and-leftovers/1.0.0-dev.13/reactants-products-and-leftovers_en.html?dev&showPointerAreas&webgl=false
 *
 * For more on query parameters, please see http://en.wikipedia.org/wiki/Query_string
 *
 * Query parameters most useful for QA Testing:
 *
 * dev - enable developer-only features, such as showing the layout bounds
 * ea - enable assertions, internal code error checks
 * qrCode - adds a menu item that will open a window with a QR code with the URL of the simulation
 * fuzzMouse - randomly sends mouse events to sim
 * profiler - shows profiling information for the sim
 * showPointerAreas - touch areas in red, mouse areas in blue, both dotted outlines
 * webgl - can be set to false with ?webgl=false to turn off WebGL rendering, see https://github.com/phetsims/scenery/issues/289
 * stringTest - if set to "double", duplicates all of the translated strings which will allow to see (a) if all strings
 *              are translated and (b) whether the layout can accommodate longer strings from other languages.
 *              Note this is a heuristic rule that does not cover all cases.
 *            - if set to "long", then an exceptionally long string will be substituted for all strings
 *            - if set to "rtl", then a string that tests RTL (right-to-left) capabilities will be substituted for all strings
 *            - if set to "none" or omitted, then the normal translated string will be shown
 *            - if set to anything else, it will use that string everywhere.  This will allow testing specific cases, like
 *                  whether the word 'vitesse' would substitute for 'speed' well.  Also, using "/u20" it will show whitespace for all
 *                  of the strings, making it easy to identify non-translated strings
 *
 * Other query parameters:
 *
 * checkNamespaces - Currently a debugging aid that will add assertions to make sure all of the namespaces are created for
 *                   modules that match the normal namespace patterns. See https://github.com/phetsims/tasks/issues/378
 * component - when running the scenery-phet example, select a particular component in the components screen
 * datamite.actionHistogram - when running with together.js + togetherEvents, display a histogram of the action types, see togetherEvents.jsadded action
 * accessibility - enable accessibility features, such as keyboard navigation (mileage may vary!)
 * eall - enable all assertions, as above but with more time consuming checks
 * emitEmptyDeltas - when emitting states using together.js (see emitStates below) emit deltas that are empty, to simplify playback in some systems like Metacog.
 * emitStates - when running a simulation using together.js, outputs states and deltas within the togetherEvents data stream, see together.js
 * rootRenderer - specify a renderer for the Sim's rootNode to use, such as 'svg', 'webgl' or 'canvas'
 * locale - test with a specific locale
 * phet-io-standalone - query parameter will cause a phet-io simulation to launch, even without a wrapper "go-ahead" step, see together#181
 * playbackInputEventLog - plays event logging back from the server, provide an optional name for the session
 * recordInputEventLog - enables input event logging, provide an optional name for the session, log is available via PhET menu
 * sceneryLog - list of one or more logs to enable in scenery 0.2+, delimited with .
 *                          - For example: ?sceneryLog=Display.Drawable.WebGLBlock
 * sceneryStringLog - Scenery logs will be output to a string instead of the window
 * screens - select one or more screens (with a 1-based index) to run in the sim, with a dot instead of a comma delimiter.
 *                          - For example ?screens=3.1 will launch with screen 1 and 3 with 3 first and 1 second.
 *                          - ?screens=2 would launch with just screen 2.
 *                          - Note that launching with a subset of screens can speed up the startup time significantly
 *                          - because only the selected screens are initialized
 * showHomeScreen - if false, go immediate to screenIndex, defaults to screenIndex=0
 * strings - override strings, value is JSON that is identical to string.json files
 * togetherEvents.log - if set to console, will stream togetherEvents to console
 * together.expressions - evaluate expressions on together wrapper objects, like: http://localhost/faradays-law/faradays-law_en.html?ea&brand=phet-io&togetherEvents.log=console&together.expressions=faradaysLaw.faradaysLawScreen.resetAllButton_setVisible_true
 * together.docs      - will output type documentation to the console, see https://github.com/phetsims/together/issues/218
 * webglContextLossTimeout - if enabled, will create WebGL contexts that can simulate context loss
 *                         - if a value is specified, it will also simulate a context loss after the specified number
 *                         - of milliseconds has elapsed.
 *                         - The value can be omitted to manually simulate the context loss with simScene.simulateWebGLContextLoss()
 * webglContextLossIncremental - if this option is present, it will put the WebGLLayer into a testing mode which
 *                             - simulates context loss between successively increasing gl calls (starting at 1)
 *                             - this option should be used in conjunction with webglContextLossTimeout since
 *                             - it only triggers upon the first context loss.
 * buildCompatible - When present, will trigger changes that are more similar to the build environment. Right now, this
 *                   includes computing higher-resolution mipmaps for the mipmap plugin.
 * showCanvasNodeBounds - Displays an overlay of the current bounds of each CanvasNode
 * showFittedBlockBounds - Displays an overlay of the current bounds of each scenery.FittedBlock
 * showPointers - Displays a semi-transparent cursor indicator for the location of each active pointer on the screen.
 *
 * This file reads query parameters from browser window's URL.
 * This file must be loaded before requirejs is started up, and this file cannot be loaded as an AMD module.
 * The easiest way to do this is via a <script> tag in your HTML file.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 * @author Chris Malley (PixelZoom, Inc.)
 */
(function() {
  'use strict';

  // If togetherEvents has already been preloaded, then this script does nothing.
  // If togetherEvents has not been preloaded, then this will assign window.togetherEvents = null
  // This will enable us to use a pattern like `togetherEvents && togetherEvents.method`
  window.togetherEvents = window.togetherEvents || null;

  // If together has been preloaded, this line does nothing.  If together needs to be loaded, it will
  // overwrite this value with the together global.
  window.together = window.together || null;

// Initialize query parameters, see docs above
  (function() {

    // Create the attachment point for all PhET globals
    window.phet = window.phet || {};
    window.phet.chipper = window.phet.chipper || {};

    //Pre-populate the query parameters map so that multiple subsequent look-ups are fast
    var queryParamsMap = {};

    if ( typeof window !== 'undefined' && window.location.search ) {
      var params = window.location.search.slice( 1 ).split( '&' );
      for ( var i = 0; i < params.length; i++ ) {
        var nameValuePair = params[ i ].split( '=' );
        queryParamsMap[ nameValuePair[ 0 ] ] = decodeURIComponent( nameValuePair[ 1 ] );
      }
    }

    /**
     * Retrieves the first occurrence of a query parameter based on its key.
     * Returns undefined if the query parameter is not found.
     * @param {string} key
     * @return {string}
     */
    window.phet.chipper.getQueryParameter = function( key ) {
      return queryParamsMap[ key ];
    };

    /**
     * Retrieves the entire map of query parameters (may be empty)
     * @return {object} map from string->string
     */
    window.phet.chipper.getQueryParameters = function() {
      return queryParamsMap;
    };

    /**
     * Gets the cache buster args based on the provided query parameters.  Dy default it is:
     * ?bust=<number>
     * But this can be omitted if ?cacheBuster=false is provided
     * See https://github.com/phetsims/joist/issues/196
     * @returns {string}
     */
    window.phet.chipper.getCacheBusterArgs = function() {
      return (phet.chipper.getQueryParameter( 'cacheBuster' ) !== 'false') ? ('bust=' + Date.now()) : '';
    };

    /**
     * Gets the name of brand to use, which determines which logo to show in the navbar as well as what options
     * to show in the PhET menu and what text to show in the About dialog.
     * See https://github.com/phetsims/brand/issues/11
     * @returns {string}
     */
    window.phet.chipper.brand = window.phet.chipper.brand || phet.chipper.getQueryParameter( 'brand' ) || 'adapted-from-phet';

    /**
     * Maps an input string to a final string, accommodating tricks like doubleStrings.
     * This function is used to modify all strings in a sim when the stringTest query parameter is used.
     * The stringTest query parameter and its options are documented in the query parameter docs above.
     * It is used in string.js and sim.html.
     * @param string - the string to be mapped
     * @param stringTest - the value of the stringTest query parameter
     * @returns {*}
     */
    window.phet.chipper.mapString = function( string, stringTest ) {
      return stringTest === null ? string :
             stringTest === 'double' ? string + ':' + string :
             stringTest === 'long' ? '12345678901234567890123456789012345678901234567890' :
             stringTest === 'rtl' ? '\u202b\u062a\u0633\u062a (\u0632\u0628\u0627\u0646)\u202c' :
             stringTest === 'none' ? string :

               //In the fallback case, supply whatever string was given in the query parameter value
             stringTest;
    };
  }());
  /**
   * Enables or disables assertions in common libraries using query parameters.
   * There are two types of assertions: basic and slow. Enabling slow assertions will adversely impact performance.
   * 'ea' enables basic assertions, 'eall' enables basic and slow assertions.
   * Must be run before RequireJS, and assumes that assert.js and query-parameters.js has been run.
   */
  (function() {

    // TODO: separate this logic out into a more common area?
    var isProduction = $( 'meta[name=phet-sim-level]' ).attr( 'content' ) === 'production';

    var enableAllAssertions = !isProduction && !!phet.chipper.getQueryParameter( 'eall' ); // enables all assertions (basic and slow)
    var enableBasicAssertions = enableAllAssertions || ( !isProduction && !!phet.chipper.getQueryParameter( 'ea' ) );  // enables basic assertions

    if ( enableBasicAssertions ) {
      window.assertions.enableAssert();
    }
    if ( enableAllAssertions ) {
      window.assertions.enableAssertSlow();
    }

    // Communicate sim errors to joist/tests/test-sims.html
    if ( phet.chipper.getQueryParameter( 'postMessageOnError' ) ) {
      window.addEventListener( 'error', function( a, b, c, d, e ) {
        var message = '';
        var stack = '';
        if ( a && a.message ) {
          message = a.message;
        }
        if ( a && a.error && a.error.stack ) {
          stack = a.error.stack;
        }
        window.parent && window.parent.postMessage( JSON.stringify( {
          type: 'error',
          url: window.location.href,
          message: message,
          stack: stack
        } ), '*' );
      } );
    }
  }());
}());
<commit_msg>Export/import and use random seeds, see https://github.com/phetsims/together/issues/274<commit_after>// Copyright 2015, University of Colorado Boulder

/**
 * Initializes phet globals that are used by all simulations, including assertions, togetherEvents and query-parameters.
 * See https://github.com/phetsims/phetcommon/issues/23
 *
 * PhET Simulations can be launched with query parameters which enable certain features.  To use a query parameter,
 * provide the full URL of the simulation and append a question mark (?) then the query parameter (and optionally its
 * value assignment).  For instance:
 * http://www.colorado.edu/physics/phet/dev/html/reactants-products-and-leftovers/1.0.0-dev.13/reactants-products-and-leftovers_en.html?dev
 *
 * Here is an example of a value assignment:
 * http://www.colorado.edu/physics/phet/dev/html/reactants-products-and-leftovers/1.0.0-dev.13/reactants-products-and-leftovers_en.html?webgl=false
 *
 * To use multiple query parameters, specify the question mark before the first query parameter, then ampersands (&)
 * between other query parameters.  Here is an example of multiple query parameters:
 * http://www.colorado.edu/physics/phet/dev/html/reactants-products-and-leftovers/1.0.0-dev.13/reactants-products-and-leftovers_en.html?dev&showPointerAreas&webgl=false
 *
 * For more on query parameters, please see http://en.wikipedia.org/wiki/Query_string
 *
 * Query parameters most useful for QA Testing:
 *
 * dev - enable developer-only features, such as showing the layout bounds
 * ea - enable assertions, internal code error checks
 * qrCode - adds a menu item that will open a window with a QR code with the URL of the simulation
 * fuzzMouse - randomly sends mouse events to sim
 * profiler - shows profiling information for the sim
 * showPointerAreas - touch areas in red, mouse areas in blue, both dotted outlines
 * webgl - can be set to false with ?webgl=false to turn off WebGL rendering, see https://github.com/phetsims/scenery/issues/289
 * stringTest - if set to "double", duplicates all of the translated strings which will allow to see (a) if all strings
 *              are translated and (b) whether the layout can accommodate longer strings from other languages.
 *              Note this is a heuristic rule that does not cover all cases.
 *            - if set to "long", then an exceptionally long string will be substituted for all strings
 *            - if set to "rtl", then a string that tests RTL (right-to-left) capabilities will be substituted for all strings
 *            - if set to "none" or omitted, then the normal translated string will be shown
 *            - if set to anything else, it will use that string everywhere.  This will allow testing specific cases, like
 *                  whether the word 'vitesse' would substitute for 'speed' well.  Also, using "/u20" it will show whitespace for all
 *                  of the strings, making it easy to identify non-translated strings
 *
 * Other query parameters:
 *
 * checkNamespaces - Currently a debugging aid that will add assertions to make sure all of the namespaces are created for
 *                   modules that match the normal namespace patterns. See https://github.com/phetsims/tasks/issues/378
 * component - when running the scenery-phet example, select a particular component in the components screen
 * datamite.actionHistogram - when running with together.js + togetherEvents, display a histogram of the action types, see togetherEvents.jsadded action
 * accessibility - enable accessibility features, such as keyboard navigation (mileage may vary!)
 * eall - enable all assertions, as above but with more time consuming checks
 * emitEmptyDeltas - when emitting states using together.js (see emitStates below) emit deltas that are empty, to simplify playback in some systems like Metacog.
 * emitStates - when running a simulation using together.js, outputs states and deltas within the togetherEvents data stream, see together.js
 * rootRenderer - specify a renderer for the Sim's rootNode to use, such as 'svg', 'webgl' or 'canvas'
 * locale - test with a specific locale
 * phet-io-standalone - query parameter will cause a phet-io simulation to launch, even without a wrapper "go-ahead" step, see together#181
 * playbackInputEventLog - plays event logging back from the server, provide an optional name for the session
 * recordInputEventLog - enables input event logging, provide an optional name for the session, log is available via PhET menu
 * sceneryLog - list of one or more logs to enable in scenery 0.2+, delimited with .
 *                          - For example: ?sceneryLog=Display.Drawable.WebGLBlock
 * sceneryStringLog - Scenery logs will be output to a string instead of the window
 * screens - select one or more screens (with a 1-based index) to run in the sim, with a dot instead of a comma delimiter.
 *                          - For example ?screens=3.1 will launch with screen 1 and 3 with 3 first and 1 second.
 *                          - ?screens=2 would launch with just screen 2.
 *                          - Note that launching with a subset of screens can speed up the startup time significantly
 *                          - because only the selected screens are initialized
 * showHomeScreen - if false, go immediate to screenIndex, defaults to screenIndex=0
 * strings - override strings, value is JSON that is identical to string.json files
 * togetherEvents.log - if set to console, will stream togetherEvents to console
 * together.expressions - evaluate expressions on together wrapper objects, like: http://localhost/faradays-law/faradays-law_en.html?ea&brand=phet-io&togetherEvents.log=console&together.expressions=faradaysLaw.faradaysLawScreen.resetAllButton_setVisible_true
 * together.docs      - will output type documentation to the console, see https://github.com/phetsims/together/issues/218
 * webglContextLossTimeout - if enabled, will create WebGL contexts that can simulate context loss
 *                         - if a value is specified, it will also simulate a context loss after the specified number
 *                         - of milliseconds has elapsed.
 *                         - The value can be omitted to manually simulate the context loss with simScene.simulateWebGLContextLoss()
 * webglContextLossIncremental - if this option is present, it will put the WebGLLayer into a testing mode which
 *                             - simulates context loss between successively increasing gl calls (starting at 1)
 *                             - this option should be used in conjunction with webglContextLossTimeout since
 *                             - it only triggers upon the first context loss.
 * buildCompatible - When present, will trigger changes that are more similar to the build environment. Right now, this
 *                   includes computing higher-resolution mipmaps for the mipmap plugin.
 * showCanvasNodeBounds - Displays an overlay of the current bounds of each CanvasNode
 * showFittedBlockBounds - Displays an overlay of the current bounds of each scenery.FittedBlock
 * showPointers - Displays a semi-transparent cursor indicator for the location of each active pointer on the screen.
 *
 * This file reads query parameters from browser window's URL.
 * This file must be loaded before requirejs is started up, and this file cannot be loaded as an AMD module.
 * The easiest way to do this is via a <script> tag in your HTML file.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 * @author Chris Malley (PixelZoom, Inc.)
 */
(function() {
  'use strict';

  // If togetherEvents has already been preloaded, then this script does nothing.
  // If togetherEvents has not been preloaded, then this will assign window.togetherEvents = null
  // This will enable us to use a pattern like `togetherEvents && togetherEvents.method`
  window.togetherEvents = window.togetherEvents || null;

  // If together has been preloaded, this line does nothing.  If together needs to be loaded, it will
  // overwrite this value with the together global.
  window.together = window.together || null;

// Initialize query parameters, see docs above
  (function() {

    // Create the attachment point for all PhET globals
    window.phet = window.phet || {};
    window.phet.chipper = window.phet.chipper || {};

    // Create a random seed in the preload code that can be used to make sure playback simulations use the same seed
    // See Random.js
    // @public (writeable by phet-io) can be overwritten for replicable playback in phet-io.
    window.phet.chipper.randomSeed = Math.random();

    //Pre-populate the query parameters map so that multiple subsequent look-ups are fast
    var queryParamsMap = {};

    if ( typeof window !== 'undefined' && window.location.search ) {
      var params = window.location.search.slice( 1 ).split( '&' );
      for ( var i = 0; i < params.length; i++ ) {
        var nameValuePair = params[ i ].split( '=' );
        queryParamsMap[ nameValuePair[ 0 ] ] = decodeURIComponent( nameValuePair[ 1 ] );
      }
    }

    /**
     * Retrieves the first occurrence of a query parameter based on its key.
     * Returns undefined if the query parameter is not found.
     * @param {string} key
     * @return {string}
     */
    window.phet.chipper.getQueryParameter = function( key ) {
      return queryParamsMap[ key ];
    };

    /**
     * Retrieves the entire map of query parameters (may be empty)
     * @return {object} map from string->string
     */
    window.phet.chipper.getQueryParameters = function() {
      return queryParamsMap;
    };

    /**
     * Gets the cache buster args based on the provided query parameters.  Dy default it is:
     * ?bust=<number>
     * But this can be omitted if ?cacheBuster=false is provided
     * See https://github.com/phetsims/joist/issues/196
     * @returns {string}
     */
    window.phet.chipper.getCacheBusterArgs = function() {
      return (phet.chipper.getQueryParameter( 'cacheBuster' ) !== 'false') ? ('bust=' + Date.now()) : '';
    };

    /**
     * Gets the name of brand to use, which determines which logo to show in the navbar as well as what options
     * to show in the PhET menu and what text to show in the About dialog.
     * See https://github.com/phetsims/brand/issues/11
     * @returns {string}
     */
    window.phet.chipper.brand = window.phet.chipper.brand || phet.chipper.getQueryParameter( 'brand' ) || 'adapted-from-phet';

    /**
     * Maps an input string to a final string, accommodating tricks like doubleStrings.
     * This function is used to modify all strings in a sim when the stringTest query parameter is used.
     * The stringTest query parameter and its options are documented in the query parameter docs above.
     * It is used in string.js and sim.html.
     * @param string - the string to be mapped
     * @param stringTest - the value of the stringTest query parameter
     * @returns {*}
     */
    window.phet.chipper.mapString = function( string, stringTest ) {
      return stringTest === null ? string :
             stringTest === 'double' ? string + ':' + string :
             stringTest === 'long' ? '12345678901234567890123456789012345678901234567890' :
             stringTest === 'rtl' ? '\u202b\u062a\u0633\u062a (\u0632\u0628\u0627\u0646)\u202c' :
             stringTest === 'none' ? string :

               //In the fallback case, supply whatever string was given in the query parameter value
             stringTest;
    };
  }());
  /**
   * Enables or disables assertions in common libraries using query parameters.
   * There are two types of assertions: basic and slow. Enabling slow assertions will adversely impact performance.
   * 'ea' enables basic assertions, 'eall' enables basic and slow assertions.
   * Must be run before RequireJS, and assumes that assert.js and query-parameters.js has been run.
   */
  (function() {

    // TODO: separate this logic out into a more common area?
    var isProduction = $( 'meta[name=phet-sim-level]' ).attr( 'content' ) === 'production';

    var enableAllAssertions = !isProduction && !!phet.chipper.getQueryParameter( 'eall' ); // enables all assertions (basic and slow)
    var enableBasicAssertions = enableAllAssertions || ( !isProduction && !!phet.chipper.getQueryParameter( 'ea' ) );  // enables basic assertions

    if ( enableBasicAssertions ) {
      window.assertions.enableAssert();
    }
    if ( enableAllAssertions ) {
      window.assertions.enableAssertSlow();
    }

    // Communicate sim errors to joist/tests/test-sims.html
    if ( phet.chipper.getQueryParameter( 'postMessageOnError' ) ) {
      window.addEventListener( 'error', function( a, b, c, d, e ) {
        var message = '';
        var stack = '';
        if ( a && a.message ) {
          message = a.message;
        }
        if ( a && a.error && a.error.stack ) {
          stack = a.error.stack;
        }
        window.parent && window.parent.postMessage( JSON.stringify( {
          type: 'error',
          url: window.location.href,
          message: message,
          stack: stack
        } ), '*' );
      } );
    }
  }());
}());
<|endoftext|>