<commit_before>/*function pageViewModel(gvm) {
    // projecttitle
    gvm.projecttitle = ko.observable("");
    gvm.projectId = $("#projectHeader").data('value');

    // Page specific i18n bindings
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("ProjectTitle") + ": " + gvm.projecttitle();}, gvm);
    gvm.pageHeader = ko.observable("Project");
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);

    gvm.indicators = ko.observableArray();

    gvm.getProjectInfo = function() {
        $.getJSON('/api/project/' + gvm.projectId, function(data) {
            gvm.pageHeader(data[0].code + ' - ' + data[0].name);
        });
    };

    gvm.getAllData = function() {
         $.getJSON('/api/project/getAllData/' + gvm.projectId, function(data) {
            console.log(data);
         });
    }

    gvm.updateIndicator = function(id,subcompetenceId,competenceId,name,description) {
        gvm.indicators.push(new Indicator(this,id,subcompetenceId,competenceId,name,description));
    };
}

function initPage() {
    viewModel.getProjectInfo();
    viewModel.getAllData();
}*/

/**
 * Competence class
 */
function Competence(viewmodel, id, code, name, weight, locked, subcompetences) {
    return {
        id: ko.observable(id),
        code: ko.observable(code),
        name: ko.observable(name),
        weight: ko.observable(weight),
        locked: false,
        subcompetences: ko.observableArray(subcompetences),

        addSubCompetence: function() {
            this.subcompetences.push(new SubCompetence(this));
            automatedWeightCalculation(this.subcompetences());
        },

        removeThis: function() {
            viewmodel.removeCompetence(this);
        },

        toggleLock: function(data, event){
            if(this.locked == true)
            {
                $(event.target).addClass("icon-unlock").removeClass("icon-lock");
                this.locked = false;
            }
            else
            {
                $(event.target).addClass("icon-lock").removeClass("icon-unlock");
                this.locked = true;
            }
        },

        removeSubCompetence: function(subCompetence) {
            this.subcompetences.remove(subCompetence);
            automatedWeightCalculation(this.subcompetences());
        }
    };

}

/**
 * SubCompetence class
 */
function SubCompetence(parent, id, code, name, weight, locked, indicators) {
    return {
        id: ko.observable(id),
        code: ko.observable(code),
        name: ko.observable(name),
        weight: ko.observable(weight),
        locked: false,
        indicators: ko.observableArray(indicators),

        addIndicator: function() {
            this.indicators.push(new Indicator(this));
            automatedWeightCalculation(this.indicators());
        },

        /*calculateWeight: function(total){
         this.weight = total;
         },*/

        removeThis: function() {
            parent.removeSubCompetence(this);

        },

        toggleLock: function(data, event){
            if(this.locked == true)
            {
                $(event.target).addClass("icon-unlock").removeClass("icon-lock");
                this.locked = false;
            }
            else
            {
                $(event.target).addClass("icon-lock").removeClass("icon-unlock");
                this.locked = true;
            }
        },

        removeIndicator: function(indicator) {
            this.indicators.remove(indicator);
            automatedWeightCalculation(this.indicators());
        }

    };
}

/**
 * Indicator class
 */
function Indicator(parent, id, name, weight, locked, description) {
    return {
        id: ko.observable(id),
        name: ko.observable(name),
        weight: ko.observable(weight),
        locked: false,
        description : ko.observable(description),

        removeThis: function() {
            parent.removeIndicator(this);
        },

        toggleLock: function(data, event){
            if(this.locked == true)
            {
                $(event.target).addClass("icon-unlock").removeClass("icon-lock");
                this.locked = false;
            }
            else
            {
                $(event.target).addClass("icon-lock").removeClass("icon-unlock");
                this.locked = true;
            }
        }
    };
}

// View model for the courses page
function pageViewModel(gvm) {
    // projecttitle
    gvm.projecttitle = ko.observable("");
    //gvm.competences = 0;
    gvm.subcomp = 0;

    // Page specific i18n bindings
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("ProjectTitle") + ": " + gvm.projecttitle();}, gvm);
    gvm.pageHeader = ko.observable("Project");
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);

    gvm.addCompetenceBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddCompetence");}, gvm);
    gvm.savePage = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SaveBtn");}, gvm);

    gvm.competences = ko.observableArray([]);

    gvm.addCompetence = function() {
        gvm.competences.push(new Competence(this));

        // Update automated weight calculation
        ko.utils.arrayForEach(gvm.competences, function(competence){
            console.log(competence.weight);
            competence.weight(percent);
        });
    };

    gvm.removeCompetence = function(competence) {
        gvm.competences.remove(competence);
        automatedWeightCalculation(this.competences());
    }

    gvm.updateCompetence = function(id, code, description, max, weight) {
        var comp = new Competence(this, id, code, description, weight);
        gvm.competences.push(comp);
        return comp;
    }

    gvm.clearStructure = function() {
        gvm.competences.destroyAll();
    }
}

function fetchProjectStructure() {
    viewModel.clearStructure();

    $.getJSON("/api/projectstructure/" + projectid, function(data){
        $.each(data, function(i, item){
            var competence = viewModel.updateCompetence(item.id, item.code, item.description, item.max, item.weight);

            $.each(item.subcompetences, function(i, subcomp){
                var subcompetence = new SubCompetence(competence, subcomp.id, subcomp.code, subcomp.description, subcomp.weight);
                competence.subcompetences.push(subcompetence);

                $.each(subcomp.indicators, function(i, indic){
                    subcompetence.indicators.push(new Indicator(subcompetence, indic.id, indic.name, indic.description));
                });
            });
        })
    });
}

function initPage() {
    console.log("Test");
    fetchProjectStructure();

}

<commit_msg>assess score<commit_after>/*function pageViewModel(gvm) {
    // projecttitle
    gvm.projecttitle = ko.observable("");
    gvm.projectId = $("#projectHeader").data('value');

    // Page specific i18n bindings
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("ProjectTitle") + ": " + gvm.projecttitle();}, gvm);
    gvm.pageHeader = ko.observable("Project");
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);

    gvm.indicators = ko.observableArray();

    gvm.getProjectInfo = function() {
        $.getJSON('/api/project/' + gvm.projectId, function(data) {
            gvm.pageHeader(data[0].code + ' - ' + data[0].name);
        });
    };

    gvm.getAllData = function() {
         $.getJSON('/api/project/getAllData/' + gvm.projectId, function(data) {
            console.log(data);
         });
    }

    gvm.updateIndicator = function(id,subcompetenceId,competenceId,name,description) {
        gvm.indicators.push(new Indicator(this,id,subcompetenceId,competenceId,name,description));
    };
}

function initPage() {
    viewModel.getProjectInfo();
    viewModel.getAllData();
}*/

/**
 * Competence class
 */
function Competence(viewmodel, id, code, name, weight, locked) {
    return {
        id: ko.observable(id),
        code: ko.observable(code),
        name: ko.observable(name),
        weight: ko.observable(weight),
        locked: false,
        subcompetences: ko.observableArray()
    };

}

/**
 * SubCompetence class
 */
function SubCompetence(parent, id, code, name, weight, locked) {
    return {
        id: ko.observable(id),
        code: ko.observable(code),
        name: ko.observable(name),
        weight: ko.observable(weight),
        locked: false,
        indicators: ko.observableArray()
    };
}

/**
 * Indicator class
 */
function Indicator(parent, id, name, weight, locked, description) {
    return {
        id: ko.observable(id),
        name: ko.observable(name),
        weight: ko.observable(weight),
        locked: false,
        description : ko.observable(description)
    };
}

// View model for the courses page
function pageViewModel(gvm) {
    // projecttitle
    gvm.projecttitle = ko.observable("");
    //gvm.competences = 0;
    gvm.subcomp = 0;

    // Page specific i18n bindings
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("ProjectTitle") + ": " + gvm.projecttitle();}, gvm);
    gvm.pageHeader = ko.observable("Project");
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);

    gvm.addCompetenceBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddCompetence");}, gvm);
    gvm.savePage = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SaveBtn");}, gvm);

    gvm.competences = ko.observableArray([]);

    gvm.addCompetence = function() {
        gvm.competences.push(new Competence(this));

        // Update automated weight calculation
        ko.utils.arrayForEach(gvm.competences, function(competence){
            console.log(competence.weight);
            competence.weight(percent);
        });
    };

    gvm.removeCompetence = function(competence) {
        gvm.competences.remove(competence);
        automatedWeightCalculation(this.competences());
    }

    gvm.updateCompetence = function(id, code, description, max, weight) {
        var comp = new Competence(this, id, code, description, weight);
        gvm.competences.push(comp);
        return comp;
    }

    gvm.clearStructure = function() {
        gvm.competences.destroyAll();
    }
}

function fetchProjectStructure() {
    viewModel.clearStructure();

    $.getJSON("/api/projectstructure/" + projectid, function(data){
        $.each(data, function(i, item){
            var competence = viewModel.updateCompetence(item.id, item.code, item.description, item.max, item.weight);

            $.each(item.subcompetences, function(i, subcomp){
                var subcompetence = new SubCompetence(competence, subcomp.id, subcomp.code, subcomp.description, subcomp.weight);
                competence.subcompetences.push(subcompetence);

                $.each(subcomp.indicators, function(i, indic){
                    subcompetence.indicators.push(new Indicator(subcompetence, indic.id, indic.name, indic.description));
                });
            });
        })
    });
}

function initPage() {
    console.log("Test");
    fetchProjectStructure();

}

<|endoftext|>


<commit_before>var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var routes = require('./routes/index');
var users = require('./routes/users');
var auction = require('./routes/auction');
var bid = require('./routes/auction');

//Load Mustache Template Engine
var mustachex = require('mustachex');

var multer = require('multer');

var app = express();

//Set Global App Settings
app.engine('html', mustachex.express);

app.use(multer({
    dest: __dirname + '/public/images'
}));

app.use(express.static(__dirname + '/public'));
app.set('view engine', 'html');
app.set('views', __dirname + '/public/scripts/views');

app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);
app.use('/auction', auction);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});

module.exports = app;
<commit_msg>add barebones error view<commit_after>var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var routes = require('./routes/index');
var users = require('./routes/users');
var auction = require('./routes/auction');
var bid = require('./routes/auction');

//Load Mustache Template Engine
var mustachex = require('mustachex');

var multer = require('multer');

var app = express();

//Set Global App Settings
app.engine('html', mustachex.express);

app.use(multer({
    dest: __dirname + '/public/images'
}));

app.use(express.static(__dirname + '/public'));
app.set('view engine', 'html');
app.set('views', __dirname + '/public/scripts/views');

app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);
app.use('/auction', auction);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    console.log(err);
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: err
  });
});

module.exports = app;
<|endoftext|>


<commit_before>/** @jsx React.DOM */
/**
 * Copyright (c) 2014, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 */

var React = window.React;
var bows = window.bows;
var _ = window._;
var config = window.config;

var router = require('./router');
var auth = require('./core/auth');
var api = require('./core/api');
var user = require('./core/user');
var patient = require('./core/patient');
var tideline = require('./core/tideline');
var chartUtil = require('./core/chartutil');

var detectTouchScreen = require('./core/notouch');

var Navbar = require('./components/navbar');
var LogoutOverlay = require('./components/logoutoverlay');
var Notification = require('./components/notification');

var Login = require('./pages/login');
var Signup = require('./pages/signup');
var Profile = require('./pages/profile');
var Patients = require('./pages/patients');
var Patient = require('./pages/patient');
var PatientEdit = require('./pages/patientedit');
var PatientData = require('./pages/patientdata');

var DEBUG = window.localStorage && window.localStorage.debug;

// Override with mock services if necessary
if (config.MOCK) {
  var mock = window.mock;
  var mockData = window.data || {};
  api = mock.api(api, {data: mockData});
  auth = mock.auth(auth);
} else {
  tidepoolPlatform(config.API_HOST, api, auth);
}

var app = {
  log: bows('App'),
  auth: auth,
  api: api,
  user: user,
  patient: patient,
  router: router
};

window.app = app;

var routes = {
  '/': 'redirectToDefaultRoute',
  '/login': 'showLogin',
  '/signup': 'showSignup',
  '/profile': 'showProfile',
  '/patients': 'showPatients',
  '/patients/:id': 'showPatient',
  '/patients/:id/edit': 'showPatientEdit',
  '/patients/:id/data': 'showPatientData'
};

var noAuthRoutes = ['/login', '/signup'];

var defaultNotAuthenticatedRoute = '/login';
var defaultAuthenticatedRoute = '/patients';

// Shallow difference of two objects
// Returns all attributes and their values in `destination`
// that have different values from `source`
function objectDifference(destination, source) {
  var result = {};

  _.forEach(source, function(sourceValue, key) {
    var destinactionValue = destination[key];
    if (!_.isEqual(sourceValue, destinactionValue)) {
      result[key] = destinactionValue;
    }
  });

  return result;
}

var AppComponent = React.createClass({
  getInitialState: function() {
    return {
      authenticated: app.auth.isAuthenticated(),
      notification: null,
      page: null,
      user: null,
      fetchingUser: true,
      loggingOut: false,
      patients: null,
      fetchingPatients: true,
      patient: null,
      fetchingPatient: true,
      patientData: null,
      fetchingPatientData: true
    };
  },

  componentDidMount: function() {
    if (this.state.authenticated) {
      this.fetchUser();
    }

    this.setupAndStartRouter();
  },

  setupAndStartRouter: function() {
    var self = this;

    var routingTable = {};
    _.forEach(routes, function(handlerName, route) {
      routingTable[route] = self[handlerName];
    });

    var isAuthenticated = function() {
      return self.state.authenticated;
    };

    app.router.setup(routingTable, {
      isAuthenticated: isAuthenticated,
      noAuthRoutes: noAuthRoutes,
      defaultNotAuthenticatedRoute: defaultNotAuthenticatedRoute,
      defaultAuthenticatedRoute: defaultAuthenticatedRoute
    });
    app.router.start();
  },

  componentWillUpdate: function(nextProps, nextState) {
    // Called on props or state changes
    // Since app main component has no props,
    // this will be called on a state change
    app.log('State changed');
    if (DEBUG) {
      var stateDiff = objectDifference(nextState, this.state);
      app.log(stateDiff);
    }
  },

  render: function() {
    var overlay = this.renderOverlay();
    var navbar = this.renderNavbar();
    var notification = this.renderNotification();
    var page = this.renderPage();

    return (
      /* jshint ignore:start */
      <div className="app">
        {overlay}
        {navbar}
        {notification}
        {page}
      </div>
      /* jshint ignore:end */
    );
  },

  renderOverlay: function() {
    if (this.state.loggingOut) {
      return (
        /* jshint ignore:start */
        <LogoutOverlay ref="logoutOverlay" />
        /* jshint ignore:end */
      );
    }

    return null;
  },

  renderNavbar: function() {
    if (this.state.authenticated) {
      var patient;

      if (this.isPatientVisibleInNavbar()) {
        patient = this.state.patient;
      }

      return (
        /* jshint ignore:start */
        <Navbar
          version={config.VERSION}
          user={this.state.user}
          fetchingUser={this.state.fetchingUser}
          patient={patient}
          fetchingPatient={this.state.fetchingPatient}
          onLogout={this.logout}
          imagesEndpoint={config.IMAGES_ENDPOINT + '/navbar'} />
        /* jshint ignore:end */
      );
    }

    return null;
  },

  isPatientVisibleInNavbar: function() {
    // Only show patient name in navbar on certain pages
    var page = this.state.page;
    var result = page && page.match(/^patients\//);
    return Boolean(result);
  },

  renderNotification: function() {
    if (this.state.notification) {
      return (
        /* jshint ignore:start */
        <Notification
          message={this.state.notification}
          onClose={this.closeNotification} />
        /* jshint ignore:end */
      );
    }

    return null;
  },

  // Override on route change
  renderPage: function() {
    return null;
  },

  redirectToDefaultRoute: function() {
    app.router.setRoute(defaultAuthenticatedRoute);
  },

  showLogin: function() {
    this.renderPage = this.renderLogin;
    this.setState({page: 'login'});
  },

  renderLogin: function() {
    return (
      /* jshint ignore:start */
      <Login
        onValidate={this.validateUser}
        onSubmit={app.auth.login.bind(app.auth)}
        onSubmitSuccess={this.handleLoginSuccess} />
      /* jshint ignore:end */
    );
  },

  showSignup: function() {
    this.renderPage = this.renderSignup;
    this.setState({page: 'signup'});
  },

  renderSignup: function() {
    return (
      /* jshint ignore:start */
      <Signup
        onValidate={this.validateUser}
        onSubmit={app.auth.signup.bind(app.auth)}
        onSubmitSuccess={this.handleSignupSuccess} />
      /* jshint ignore:end */
    );
  },

  showProfile: function() {
    this.renderPage = this.renderProfile;
    this.setState({page: 'profile'});
  },

  renderProfile: function() {
    return (
      /* jshint ignore:start */
      <Profile
          user={this.state.user}
          fetchingUser={this.state.fetchingUser}
          onValidate={this.validateUser}
          onSubmit={this.updateUser}/>
      /* jshint ignore:end */
    );
  },

  showPatients: function() {
    this.renderPage = this.renderPatients;
    this.setState({page: 'patients'});
    this.fetchPatients();
  },

  renderPatients: function() {
    /* jshint ignore:start */
    return (
      <Patients
          user={this.state.user}
          fetchingUser={this.state.fetchingUser}
          patients={this.state.patients}
          fetchingPatients={this.state.fetchingPatients}/>
    );
    /* jshint ignore:end */
  },

  showPatient: function(patientId) {
    this.renderPage = this.renderPatient;
    this.setState({
      page: 'patients/' + patientId,
      // Reset patient object to avoid showing previous one
      patient: null,
      // Indicate renderPatient() that we are fetching the patient
      // (important to have this on next render)
      fetchingPatient: true
    });
    this.fetchPatient(patientId);
  },

  renderPatient: function() {
    // On each state change check if patient object was returned from server
    if (this.isDoneFetchingAndNotFoundPatient()) {
      app.log('Patient not found');
      this.redirectToDefaultRoute();
      return;
    }

    /* jshint ignore:start */
    return (
      <Patient
          user={this.state.user}
          fetchingUser={this.state.fetchingUser}
          patient={this.state.patient}
          fetchingPatient={this.state.fetchingPatient}/>
    );
    /* jshint ignore:end */
  },

  isDoneFetchingAndNotFoundPatient: function() {
    // Wait for patient object to come back from server
    if (this.state.fetchingPatient) {
      return false;
    }

    return !this.state.patient;
  },

  showPatientEdit: function(patientId) {
    this.renderPage = this.renderPatientEdit;
    this.setState({
      page: 'patients/' + patientId + '/edit',
      // Reset patient object to avoid showing previous one
      patient: null,
      // Indicate renderPatientEdit() that we are fetching the patient
      // (important to have this on next render)
      fetchingPatient: true
    });
    this.fetchPatient(patientId);
  },

  renderPatientEdit: function() {
    // On each state change check if user can edit this patient
    if (this.isDoneFetchingAndNotUserPatient()) {
      var patientId = this.state.patient && this.state.patient.id;
      var route = '/patients';
      if (patientId) {
        route = route + '/' + patientId;
      }
      app.log('Not allowed to edit patient with id ' + patientId);
      app.router.setRoute(route);
      return;
    }

    /* jshint ignore:start */
    return (
      <PatientEdit
          user={this.state.user}
          fetchingUser={this.state.fetchingUser}
          patient={this.state.patient}
          fetchingPatient={this.state.fetchingPatient}
          onValidate={this.validatePatient}
          onSubmit={this.updatePatient}/>
    );
    /* jshint ignore:end */
  },

  isDoneFetchingAndNotUserPatient: function(patientId) {
    // Wait to have both user and patient objects back from server
    if (this.state.fetchingUser || this.state.fetchingPatient) {
      return false;
    }

    return !user.isUserPatient(this.state.user, this.state.patient);
  },

  showPatientData: function(patientId) {
    this.renderPage = this.renderPatientData;
    this.setState({
      page: 'patients/' + patientId + '/data',
      patient: null,
      fetchingPatient: true,
      patientData: null,
      fetchingPatientData: true
    });
    this.fetchPatient(patientId);
    this.fetchPatientData(patientId);
  },

  renderPatientData: function() {
    // On each state change check if patient object was returned from server
    if (this.isDoneFetchingAndNotFoundPatient()) {
      app.log('Patient not found');
      this.redirectToDefaultRoute();
      return;
    }

    /* jshint ignore:start */
    return (
      <PatientData
          patientData={this.state.patientData}
          fetchingPatientData={this.state.fetchingPatientData}/>
    );
    /* jshint ignore:end */
  },

  handleLoginSuccess: function() {
    this.fetchUser();
    this.setState({authenticated: true});
    this.redirectToDefaultRoute();
  },

  handleSignupSuccess: function(user) {
    this.setState({
      authenticated: true,
      user: user,
      fetchingUser: false
    });
    this.redirectToDefaultRoute();
  },

  logout: function() {
    var self = this;

    if (this.state.loggingOut) {
      return;
    }

    this.setState({loggingOut: true});

    app.auth.logout(function(err) {
      if (err) {
        self.setState({
          loggingOut: false,
          notification: err.message || 'An error occured while logging out.'
        });
        return;
      }
      self.refs.logoutOverlay.fadeOut(function() {
        self.setState({loggingOut: false});
      });
      self.handleLogoutSuccess();
    });
  },

  handleLogoutSuccess: function() {
    this.setState({authenticated: false});
    this.clearUserData();
    router.setRoute('/login');
  },

  closeNotification: function() {
    this.setState({notification: null});
  },

  fetchUser: function() {
    var self = this;

    self.setState({fetchingUser: true});

    app.api.user.get(function(err, user) {
      self.setState({
        user: user,
        fetchingUser: false
      });
    });
  },

  fetchPatients: function() {
    var self = this;

    self.setState({fetchingPatients: true});

    app.api.patient.getAll(function(err, patients) {
      self.setState({
        patients: patients,
        fetchingPatients: false
      });
    });
  },

  fetchPatient: function(patientId) {
    var self = this;

    self.setState({fetchingPatient: true});

    app.api.patient.get(patientId, function(err, patient) {
      if (err) {
        // Unauthorized, or not found
        app.log('Error fetching patient with id ' + patientId);
        self.setState({fetchingPatient: false});
        return;
      }

      self.setState({
        patient: patient,
        fetchingPatient: false
      });
    });
  },

  fetchPatientData: function(patientId) {
    var self = this;

    self.setState({fetchingPatientData: true});

    app.api.patientData.get(patientId, function(err, patientData) {
      if (err) {
        app.log('Error fetching data for patient with id ' + patientId);
        self.setState({fetchingPatientData: false});
        return;
      }

      patientData = self.processPatientData(patientData);

      self.setState({
        patientData: patientData,
        fetchingPatientData: false
      });
    });
  },

  processPatientData: function(data) {
    return chartUtil.processData(data);
  },

  clearUserData: function() {
    this.setState({
      user: null,
      patients: null,
      patient: null,
      patientData: null
    });
  },

  validateUser: function(user) {
    return app.user.validate(user);
  },

  updateUser: function(user) {
    var self = this;
    var previousUser = this.state.user;

    user = _.assign(_.cloneDeep(this.state.user), user);

    // Optimistic update
    self.setState({user: user});

    app.api.user.put(user, function(err, user) {
      if (err) {
        self.setState({
          notification: err.message || 'An error occured while saving user.'
        });
        // Rollback
        self.setState({user: previousUser});
        return;
      }
      self.setState({user: user});
    });
  },

  validatePatient: function(patient) {
    return app.patient.validate(patient);
  },

  updatePatient: function(patient) {
    var self = this;
    var previousPatient = this.state.patient;

    patient = _.assign(_.cloneDeep(this.state.patient), patient);

    // Optimistic update
    self.setState({patient: patient});

    app.api.patient.put(patient.id, patient, function(err, patient) {
      if (err) {
        self.setState({
          notification: err.message || 'An error occured while saving patient.'
        });
        // Rollback
        self.setState({patient: previousPatient});
        return;
      }
      self.setState({patient: patient});
    });
  }
});

app.start = function() {
  var self = this;

  this.init(function() {
    self.component = React.renderComponent(
      /* jshint ignore:start */
      <AppComponent />,
      /* jshint ignore:end */
      document.getElementById('app')
    );

    self.log('App started');

    if (config.MOCK) {
      self.log('App running with mock services');
    }
  });
};

app.init = function(callback) {
  var self = this;

  function beginInit() {
    initNoTouch();
  }

  function initNoTouch() {
    detectTouchScreen();
    initAuth();
  }

  function initAuth() {
    self.auth.init(callback);
  }

  beginInit();
};

module.exports = app;<commit_msg>Add patient data info in debug logs<commit_after>/** @jsx React.DOM */
/**
 * Copyright (c) 2014, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 */

var React = window.React;
var bows = window.bows;
var _ = window._;
var config = window.config;

var router = require('./router');
var auth = require('./core/auth');
var api = require('./core/api');
var user = require('./core/user');
var patient = require('./core/patient');
var tideline = require('./core/tideline');
var chartUtil = require('./core/chartutil');

var detectTouchScreen = require('./core/notouch');

var Navbar = require('./components/navbar');
var LogoutOverlay = require('./components/logoutoverlay');
var Notification = require('./components/notification');

var Login = require('./pages/login');
var Signup = require('./pages/signup');
var Profile = require('./pages/profile');
var Patients = require('./pages/patients');
var Patient = require('./pages/patient');
var PatientEdit = require('./pages/patientedit');
var PatientData = require('./pages/patientdata');

var DEBUG = window.localStorage && window.localStorage.debug;

// Override with mock services if necessary
if (config.MOCK) {
  var mock = window.mock;
  var mockData = window.data || {};
  api = mock.api(api, {data: mockData});
  auth = mock.auth(auth);
} else {
  tidepoolPlatform(config.API_HOST, api, auth);
}

var app = {
  log: bows('App'),
  auth: auth,
  api: api,
  user: user,
  patient: patient,
  router: router
};

window.app = app;

var routes = {
  '/': 'redirectToDefaultRoute',
  '/login': 'showLogin',
  '/signup': 'showSignup',
  '/profile': 'showProfile',
  '/patients': 'showPatients',
  '/patients/:id': 'showPatient',
  '/patients/:id/edit': 'showPatientEdit',
  '/patients/:id/data': 'showPatientData'
};

var noAuthRoutes = ['/login', '/signup'];

var defaultNotAuthenticatedRoute = '/login';
var defaultAuthenticatedRoute = '/patients';

// Shallow difference of two objects
// Returns all attributes and their values in `destination`
// that have different values from `source`
function objectDifference(destination, source) {
  var result = {};

  _.forEach(source, function(sourceValue, key) {
    var destinactionValue = destination[key];
    if (!_.isEqual(sourceValue, destinactionValue)) {
      result[key] = destinactionValue;
    }
  });

  return result;
}

var AppComponent = React.createClass({
  getInitialState: function() {
    return {
      authenticated: app.auth.isAuthenticated(),
      notification: null,
      page: null,
      user: null,
      fetchingUser: true,
      loggingOut: false,
      patients: null,
      fetchingPatients: true,
      patient: null,
      fetchingPatient: true,
      patientData: null,
      fetchingPatientData: true
    };
  },

  componentDidMount: function() {
    if (this.state.authenticated) {
      this.fetchUser();
    }

    this.setupAndStartRouter();
  },

  setupAndStartRouter: function() {
    var self = this;

    var routingTable = {};
    _.forEach(routes, function(handlerName, route) {
      routingTable[route] = self[handlerName];
    });

    var isAuthenticated = function() {
      return self.state.authenticated;
    };

    app.router.setup(routingTable, {
      isAuthenticated: isAuthenticated,
      noAuthRoutes: noAuthRoutes,
      defaultNotAuthenticatedRoute: defaultNotAuthenticatedRoute,
      defaultAuthenticatedRoute: defaultAuthenticatedRoute
    });
    app.router.start();
  },

  componentWillUpdate: function(nextProps, nextState) {
    // Called on props or state changes
    // Since app main component has no props,
    // this will be called on a state change
    app.log('State changed');
    if (DEBUG) {
      var stateDiff = objectDifference(nextState, this.state);
      app.log(stateDiff);
    }
  },

  render: function() {
    var overlay = this.renderOverlay();
    var navbar = this.renderNavbar();
    var notification = this.renderNotification();
    var page = this.renderPage();

    return (
      /* jshint ignore:start */
      <div className="app">
        {overlay}
        {navbar}
        {notification}
        {page}
      </div>
      /* jshint ignore:end */
    );
  },

  renderOverlay: function() {
    if (this.state.loggingOut) {
      return (
        /* jshint ignore:start */
        <LogoutOverlay ref="logoutOverlay" />
        /* jshint ignore:end */
      );
    }

    return null;
  },

  renderNavbar: function() {
    if (this.state.authenticated) {
      var patient;

      if (this.isPatientVisibleInNavbar()) {
        patient = this.state.patient;
      }

      return (
        /* jshint ignore:start */
        <Navbar
          version={config.VERSION}
          user={this.state.user}
          fetchingUser={this.state.fetchingUser}
          patient={patient}
          fetchingPatient={this.state.fetchingPatient}
          onLogout={this.logout}
          imagesEndpoint={config.IMAGES_ENDPOINT + '/navbar'} />
        /* jshint ignore:end */
      );
    }

    return null;
  },

  isPatientVisibleInNavbar: function() {
    // Only show patient name in navbar on certain pages
    var page = this.state.page;
    var result = page && page.match(/^patients\//);
    return Boolean(result);
  },

  renderNotification: function() {
    if (this.state.notification) {
      return (
        /* jshint ignore:start */
        <Notification
          message={this.state.notification}
          onClose={this.closeNotification} />
        /* jshint ignore:end */
      );
    }

    return null;
  },

  // Override on route change
  renderPage: function() {
    return null;
  },

  redirectToDefaultRoute: function() {
    app.router.setRoute(defaultAuthenticatedRoute);
  },

  showLogin: function() {
    this.renderPage = this.renderLogin;
    this.setState({page: 'login'});
  },

  renderLogin: function() {
    return (
      /* jshint ignore:start */
      <Login
        onValidate={this.validateUser}
        onSubmit={app.auth.login.bind(app.auth)}
        onSubmitSuccess={this.handleLoginSuccess} />
      /* jshint ignore:end */
    );
  },

  showSignup: function() {
    this.renderPage = this.renderSignup;
    this.setState({page: 'signup'});
  },

  renderSignup: function() {
    return (
      /* jshint ignore:start */
      <Signup
        onValidate={this.validateUser}
        onSubmit={app.auth.signup.bind(app.auth)}
        onSubmitSuccess={this.handleSignupSuccess} />
      /* jshint ignore:end */
    );
  },

  showProfile: function() {
    this.renderPage = this.renderProfile;
    this.setState({page: 'profile'});
  },

  renderProfile: function() {
    return (
      /* jshint ignore:start */
      <Profile
          user={this.state.user}
          fetchingUser={this.state.fetchingUser}
          onValidate={this.validateUser}
          onSubmit={this.updateUser}/>
      /* jshint ignore:end */
    );
  },

  showPatients: function() {
    this.renderPage = this.renderPatients;
    this.setState({page: 'patients'});
    this.fetchPatients();
  },

  renderPatients: function() {
    /* jshint ignore:start */
    return (
      <Patients
          user={this.state.user}
          fetchingUser={this.state.fetchingUser}
          patients={this.state.patients}
          fetchingPatients={this.state.fetchingPatients}/>
    );
    /* jshint ignore:end */
  },

  showPatient: function(patientId) {
    this.renderPage = this.renderPatient;
    this.setState({
      page: 'patients/' + patientId,
      // Reset patient object to avoid showing previous one
      patient: null,
      // Indicate renderPatient() that we are fetching the patient
      // (important to have this on next render)
      fetchingPatient: true
    });
    this.fetchPatient(patientId);
  },

  renderPatient: function() {
    // On each state change check if patient object was returned from server
    if (this.isDoneFetchingAndNotFoundPatient()) {
      app.log('Patient not found');
      this.redirectToDefaultRoute();
      return;
    }

    /* jshint ignore:start */
    return (
      <Patient
          user={this.state.user}
          fetchingUser={this.state.fetchingUser}
          patient={this.state.patient}
          fetchingPatient={this.state.fetchingPatient}/>
    );
    /* jshint ignore:end */
  },

  isDoneFetchingAndNotFoundPatient: function() {
    // Wait for patient object to come back from server
    if (this.state.fetchingPatient) {
      return false;
    }

    return !this.state.patient;
  },

  showPatientEdit: function(patientId) {
    this.renderPage = this.renderPatientEdit;
    this.setState({
      page: 'patients/' + patientId + '/edit',
      // Reset patient object to avoid showing previous one
      patient: null,
      // Indicate renderPatientEdit() that we are fetching the patient
      // (important to have this on next render)
      fetchingPatient: true
    });
    this.fetchPatient(patientId);
  },

  renderPatientEdit: function() {
    // On each state change check if user can edit this patient
    if (this.isDoneFetchingAndNotUserPatient()) {
      var patientId = this.state.patient && this.state.patient.id;
      var route = '/patients';
      if (patientId) {
        route = route + '/' + patientId;
      }
      app.log('Not allowed to edit patient with id ' + patientId);
      app.router.setRoute(route);
      return;
    }

    /* jshint ignore:start */
    return (
      <PatientEdit
          user={this.state.user}
          fetchingUser={this.state.fetchingUser}
          patient={this.state.patient}
          fetchingPatient={this.state.fetchingPatient}
          onValidate={this.validatePatient}
          onSubmit={this.updatePatient}/>
    );
    /* jshint ignore:end */
  },

  isDoneFetchingAndNotUserPatient: function(patientId) {
    // Wait to have both user and patient objects back from server
    if (this.state.fetchingUser || this.state.fetchingPatient) {
      return false;
    }

    return !user.isUserPatient(this.state.user, this.state.patient);
  },

  showPatientData: function(patientId) {
    this.renderPage = this.renderPatientData;
    this.setState({
      page: 'patients/' + patientId + '/data',
      patient: null,
      fetchingPatient: true,
      patientData: null,
      fetchingPatientData: true
    });
    this.fetchPatient(patientId);
    this.fetchPatientData(patientId);
  },

  renderPatientData: function() {
    // On each state change check if patient object was returned from server
    if (this.isDoneFetchingAndNotFoundPatient()) {
      app.log('Patient not found');
      this.redirectToDefaultRoute();
      return;
    }

    /* jshint ignore:start */
    return (
      <PatientData
          patientData={this.state.patientData}
          fetchingPatientData={this.state.fetchingPatientData}/>
    );
    /* jshint ignore:end */
  },

  handleLoginSuccess: function() {
    this.fetchUser();
    this.setState({authenticated: true});
    this.redirectToDefaultRoute();
  },

  handleSignupSuccess: function(user) {
    this.setState({
      authenticated: true,
      user: user,
      fetchingUser: false
    });
    this.redirectToDefaultRoute();
  },

  logout: function() {
    var self = this;

    if (this.state.loggingOut) {
      return;
    }

    this.setState({loggingOut: true});

    app.auth.logout(function(err) {
      if (err) {
        self.setState({
          loggingOut: false,
          notification: err.message || 'An error occured while logging out.'
        });
        return;
      }
      self.refs.logoutOverlay.fadeOut(function() {
        self.setState({loggingOut: false});
      });
      self.handleLogoutSuccess();
    });
  },

  handleLogoutSuccess: function() {
    this.setState({authenticated: false});
    this.clearUserData();
    router.setRoute('/login');
  },

  closeNotification: function() {
    this.setState({notification: null});
  },

  fetchUser: function() {
    var self = this;

    self.setState({fetchingUser: true});

    app.api.user.get(function(err, user) {
      self.setState({
        user: user,
        fetchingUser: false
      });
    });
  },

  fetchPatients: function() {
    var self = this;

    self.setState({fetchingPatients: true});

    app.api.patient.getAll(function(err, patients) {
      self.setState({
        patients: patients,
        fetchingPatients: false
      });
    });
  },

  fetchPatient: function(patientId) {
    var self = this;

    self.setState({fetchingPatient: true});

    app.api.patient.get(patientId, function(err, patient) {
      if (err) {
        // Unauthorized, or not found
        app.log('Error fetching patient with id ' + patientId);
        self.setState({fetchingPatient: false});
        return;
      }

      self.setState({
        patient: patient,
        fetchingPatient: false
      });
    });
  },

  fetchPatientData: function(patientId) {
    var self = this;

    self.setState({fetchingPatientData: true});

    app.api.patientData.get(patientId, function(err, patientData) {
      if (err) {
        app.log('Error fetching data for patient with id ' + patientId);
        self.setState({fetchingPatientData: false});
        return;
      }

      patientData = self.processPatientData(patientData);

      self.logPatientDataInfo(patientData);

      self.setState({
        patientData: patientData,
        fetchingPatientData: false
      });
    });
  },

  processPatientData: function(data) {
    return chartUtil.processData(data);
  },

  logPatientDataInfo: function(data) {
    data = data || [];
    app.log('Patient data total count', data.length);
    app.log('Patient data count by type', _.countBy(data, 'type'));
  },

  clearUserData: function() {
    this.setState({
      user: null,
      patients: null,
      patient: null,
      patientData: null
    });
  },

  validateUser: function(user) {
    return app.user.validate(user);
  },

  updateUser: function(user) {
    var self = this;
    var previousUser = this.state.user;

    user = _.assign(_.cloneDeep(this.state.user), user);

    // Optimistic update
    self.setState({user: user});

    app.api.user.put(user, function(err, user) {
      if (err) {
        self.setState({
          notification: err.message || 'An error occured while saving user.'
        });
        // Rollback
        self.setState({user: previousUser});
        return;
      }
      self.setState({user: user});
    });
  },

  validatePatient: function(patient) {
    return app.patient.validate(patient);
  },

  updatePatient: function(patient) {
    var self = this;
    var previousPatient = this.state.patient;

    patient = _.assign(_.cloneDeep(this.state.patient), patient);

    // Optimistic update
    self.setState({patient: patient});

    app.api.patient.put(patient.id, patient, function(err, patient) {
      if (err) {
        self.setState({
          notification: err.message || 'An error occured while saving patient.'
        });
        // Rollback
        self.setState({patient: previousPatient});
        return;
      }
      self.setState({patient: patient});
    });
  }
});

app.start = function() {
  var self = this;

  this.init(function() {
    self.component = React.renderComponent(
      /* jshint ignore:start */
      <AppComponent />,
      /* jshint ignore:end */
      document.getElementById('app')
    );

    self.log('App started');

    if (config.MOCK) {
      self.log('App running with mock services');
    }
  });
};

app.init = function(callback) {
  var self = this;

  function beginInit() {
    initNoTouch();
  }

  function initNoTouch() {
    detectTouchScreen();
    initAuth();
  }

  function initAuth() {
    self.auth.init(callback);
  }

  beginInit();
};

module.exports = app;<|endoftext|>


<commit_before>const expect = require("chai").expect;
const periodTimes = require("../src/periodTimes");
const Period = require("../src/Period");
const Time = require("../src/Time");
const Ratings = require("../src/Ratings");
const Seed = require("../src/Seed");
const times = require("../src/times");
const Match = require("../src/Match");
const TimeScaler = require("../src/TimeScaler");
const stubs = require("./stubs");
const findMatch = require("./findMatch");

describe("#periodTimes()", () => {
    const seed = "testing".toSeed();
    const time = new Time().setMinutes(45);
    const ratings = [1200, 1100].toRatings();
    const timeScaler = new TimeScaler();

    context("given no goals period", () => {
        const period = findMatch(stubs.teams, isNilNil).firstHalf;

        it("returns no times", () => {
            const result = periodTimes(period, timeScaler);

            expect(result).to.deep.equal([[], []]);
        });
    });
});

function isNilNil(match) {
    const result = match.firstHalf.goals.value;

    return result[0] === 0 && result[1] === 0;
}
<commit_msg>Fixing period times to return generic, needs a rethink to accommodate shots on target etc<commit_after>const expect = require("chai").expect;
const periodTimes = require("../src/periodTimes");
const Period = require("../src/Period");
const Time = require("../src/Time");
const Ratings = require("../src/Ratings");
const Seed = require("../src/Seed");
const times = require("../src/times");
const Match = require("../src/Match");
const TimeScaler = require("../src/TimeScaler");
const stubs = require("./stubs");
const findMatch = require("./findMatch");

describe("#periodTimes()", () => {
    const seed = "testing".toSeed();
    const time = new Time().setMinutes(45);
    const ratings = [1200, 1100].toRatings();
    const timeScaler = new TimeScaler();

    context("given no goals period", () => {
        const period = findMatch(stubs.teams, isScore(0, 0)).firstHalf;

        it("returns no times", () => {
            const result = periodTimes(period, timeScaler);

            expect(result).to.deep.equal([[], []]);
        });
    });

    context("given a 2-1 period", () => {
        const period = findMatch(stubs.teams, isTwoOne).firstHalf;

        it("returns equivalent of times function", () => {
            const result = periodTimes(period, timeScaler);
            const expectedHome = times([2, 1])

            expect(result).to.deep.equal();
        });
    });
});

function isNilNil(match) {
    const result = match.firstHalf.goals.value;

    return result[0] === 0 && result[1] === 0;
}

function isTwoOne(match) {
    const result = match.firstHalf.goals.value;

    return result[0] === 2 && result[1] === 1;
}

function isScore(home, away) {
    return match => {
        const score = match.firstHalf.goals.value;

        return score[0] === home && score[1] === away;
    };
}
<|endoftext|>


<commit_before>var request = require("request");
var express = require('express');
var pg = require('pg');
var fs = require('fs');
var reproject = require('reproject');
var terraformer = require('terraformer-wkt-parser');
var jsts = require('jsts');
var path = require('path');
var bodyParser = require('body-parser');
var moment = require('moment');
var nodeConfig = require('./config/nodeConfig');
var http = require('http');
var exec = require('child_process').exec;
var gc2i18n = require('./config/localModules/' + nodeConfig.locale);
var cors = require('cors');

// Define the i18n function
var __ = function (string) {
    if (typeof gc2i18n !== 'undefined') {
        if (gc2i18n.dict[string]) {
            return gc2i18n.dict[string];
        }
    }
    return string;
};
// Set locale for date/time string
moment.locale(nodeConfig.locale);

// Setup Express
var app = express();
app.use(cors());
app.use(bodyParser.urlencoded({extended: true, limit: '50mb'}));
app.use(bodyParser.json({extended: true, limit: '50mb'}));
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.static(path.join(__dirname, 'public')));

// Setup routes
app.get('/geoserver', function (req, response) {
    var url = "http://" + nodeConfig.print.host + ":" + nodeConfig.print.port + "/geoserver/pdf/info.json?var=printConfig";
    http.get(url, function (res) {
        var chunks = [];
        res.on('data', function (chunk) {
            chunks.push(chunk);
        });
        res.on("end", function () {
            var jsfile = new Buffer.concat(chunks);
            response.header('content-type', 'text/javascript');
            response.send(jsfile);
        });
    }).on("error", function () {
        callback(null);
    });
});
app.get('/static', function (req, response) {
    response.setHeader('Content-Type', 'application/json');
    response.sendFile(__dirname + '/tmp/' + req.query.id);
});
app.get('/pdf', function (req, response) {
    var url = "http://localhost:8090/?url=127.0.0.1:80/html?id=" + req.query.id;
    http.get(url, function (res) {
        var chunks = [];
        res.on('data', function (chunk) {
            chunks.push(chunk);
        });
        res.on("end", function () {
            var jsfile = new Buffer.concat(chunks);
            response.header('content-type', 'application/pdf');
            response.send(jsfile);
        });
    }).on("error", function () {
        callback(null);
    });
});
app.post('/geomatic', function (req, response) {
    console.log(terraformer.convert(req.body.json));
    var postData = "wkt=" + terraformer.convert(req.body.json) + "&Username=" + nodeConfig.geomatic.user + "&Password=" + nodeConfig.geomatic.pw, id = req.body.id,
        options = {
            method: 'POST',
            host: "apps.conzoom.eu",
            port: "80",
            path: '/analysis/86F8A64F-1E22-4970-AD58-C808763CF61F/restreport/Pdf',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded ',
                'Content-Length': postData.length
            }
        },
        reqGeomatic = http.request(options, function (res) {
            var chunks = [];
            res.on('data', function (chunk) {
                chunks.push(chunk);
            });
            res.on('end', function () {
                var jsfile = new Buffer.concat(chunks);
                fs.writeFile(__dirname + "/public/tmp/geomatic_" + id + ".pdf", jsfile, 'binary', function (err) {
                    if (err) throw err;
                    console.log('Geomatic PDF saved.');
                });
                response.send({success: true});
            });
        });
    reqGeomatic.write(postData);
    reqGeomatic.end();
});
app.get('/html', function (req, res) {
    var addr;
    fs.readFile(__dirname + '/tmp/' + req.query.id, 'utf8', function (err, data) {
        if (err) {
            return console.log(err);
        }
        var obj = JSON.parse(data), hits = [], noHits = [], json, metaData, metaDataKeys = [];
        metaData = obj.metaData;
        for (var i = 0; i < metaData.data.length; i++) {
            metaDataKeys[metaData.data[i].f_table_name] = metaData.data[i];
        }
        for (var prop in obj.hits) {
            if (obj.hits.hasOwnProperty(prop)) {
                if (obj.hits[prop].hits > 0) {
                    hits.push(obj.hits[prop]);
                } else {
                    noHits.push(obj.hits[prop]);
                }
            }
        }
        json = {
            hits: hits,
            noHits: noHits,
            text: obj.text,
            dateTime: obj.dateTime,
            metaDataKeys: metaDataKeys,
            id: req.query.id,
            addr: addr
        };
        var input = json;
        input.i18n = gc2i18n;
        res.render('static', {layout: 'layout', json: input});
    });
});
app.post('/print', function (req, response) {
    var postData = JSON.stringify(req.body.json), id = req.body.id,
        options = {
            method: 'POST',
            host: nodeConfig.print.host,
            port: nodeConfig.print.port,
            path: '/geoserver/pdf/create.json',
            headers: {
                'Content-Type': 'application/json',
                'Content-Length': postData.length
            }
        },
        staticMapReq = http.request(options, function (res) {
            var str = '';
            res.setEncoding('binary');
            res.on('data', function (chunk) {
                str += chunk
            });
            res.on('end', function () {
                http.get(JSON.parse(str).getURL, function (res) {
                    var chunks = [];
                    res.on('data', function (chunk) {
                        chunks.push(chunk);
                    });
                    res.on("end", function () {
                        var jsfile = new Buffer.concat(chunks);
                        fs.writeFile(__dirname + "/public/tmp/" + id + ".pdf", jsfile, 'binary', function (err) {
                            if (err) throw err;
                            console.log('PDF saved.');
                            exec("gs -dQUIET -dPARANOIDSAFER -dBATCH -dNOPAUSE -dNOPROMPT -sDEVICE=png16m -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -r190 -dFirstPage=1 -dLastPage=1 -sOutputFile=" + __dirname + "/public/tmp/" + id + ".png " + __dirname + "/public/tmp/" + id + ".pdf", function (error, stdout, stderr) {
                                if (error !== null) {
                                    console.log(error);
                                }
                                response.send({success: true});
                            });
                        });
                    });
                }).on("error", function () {
                    callback(null);
                });
            });
            res.on('error', function () {
                console.log("Static map error");
            });
        });
    staticMapReq.write(postData);
    staticMapReq.end();
});
app.post('/intersection', function (req, response) {
    var socketId, fileName, baseLayer, layers, buffer, db, schema, text;
    if (!req.body.wkt) {
        response.status(400);
        response.send({
            success: false,
            message: "WKT is required"
        });
        return;
    }
    db = req.body.db;
    schema = req.body.schema;
    buffer = req.body.buffer;
    socketId = req.body.socketid;
    text = req.body.text;
    baseLayer = req.body.baselayer;
    layers = req.body.layers;
    var conString = "postgres://" + nodeConfig.pg.user + ":" + nodeConfig.pg.pw + "@" + nodeConfig.pg.host + "/" + db;
    var url = "http://" + nodeConfig.host + "/api/v1/meta/" + db + "/" + schema;
    var wkt = req.body.wkt;
    var buffer4326 = null;
    var primitive = JSON.parse(terraformer.parse(wkt).toJson());
    if (buffer > 0) {
        // Get the UTM zone
        var log = primitive.bbox[0], lat = primitive.bbox[1],
            zoneNumber = Math.floor((log + 180) / 6) + 1;

        if (lat >= 56.0 && lat < 64.0 && log >= 3.0 && log < 12.0) {
            zoneNumber = 32;
        }
        //Special zones for Svalbard
        if (lat >= 72.0 && lat < 84.0) {
            if (log >= 0.0 && log < 9.0) {
                zoneNumber = 31;
            }
            else if (log >= 9.0 && log < 21.0) {
                zoneNumber = 33;
            }
            else if (log >= 21.0 && log < 33.0) {
                zoneNumber = 35;
            }
            else if (log >= 33.0 && log < 42.0) {
                zoneNumber = 37;
            }
        }
        console.log("Zone:" + zoneNumber);
        var crss = {
            "proj": "+proj=utm +zone=" + zoneNumber + " +ellps=WGS84 +datum=WGS84 +units=m +no_defs",
            "unproj": "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"
        };

        var reader = new jsts.io.GeoJSONParser();
        var writer = new jsts.io.GeoJSONWriter();

        var geom = reader.read(reproject.reproject(primitive, "unproj", "proj", crss));
        buffer4326 = reproject.reproject(writer.write(geom.buffer(buffer)), "proj", "unproj", crss);
    }
    fileName = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
    pg.connect(conString, function (err, client, done) {
        if (err) {
            return console.error('error fetching client from pool', err);
        }
        request.get(url, function (err, res, body) {
            if (!err) {
                var metaData = JSON.parse(body), count = 0, table, sql, geomField, bindings, startTime, hits = {}, hit, metaDataFinal = {data: []}, metaDataKeys = [];
                // Count layers
                for (var i = 0; i < metaData.data.length; i = i + 1) {
                    if (metaData.data[i].type !== "RASTER" &&
                        metaData.data[i].baselayer !== true &&
                        metaData.data[i].skipconflict !== true) {
                        metaDataFinal.data.push(metaData.data[i]);
                        metaDataKeys[metaData.data[i].f_table_name] = metaData.data[i];
                    }
                }
                (function iter() {
                    geomField = metaDataFinal.data[count].f_geometry_column;
                    table = metaDataFinal.data[count].f_table_schema + "." + metaDataFinal.data[count].f_table_name;
                    if (buffer > 0) {
                        sql = "SELECT geography(ST_transform(" + geomField + ",4326)) as _gc2_geom, * FROM " + table + " WHERE ST_DWithin(ST_GeogFromText($1), geography(ST_transform(" + geomField + ",4326)), $2);";
                        bindings = [wkt, buffer];
                    } else {
                        sql = "SELECT * FROM " + table + " WHERE ST_transform(" + geomField + ",900913) && ST_transform(ST_geomfromtext($1,4326),900913) AND ST_intersects(ST_transform(" + geomField + ",900913),ST_transform(ST_geomfromtext($1,4326),900913))";
                        bindings = [wkt];
                    }
                    startTime = new Date().getTime();
                    client.query(sql, bindings, function (err, result) {
                        var time = new Date().getTime() - startTime, queryables, data = [], tmp = [];
                        count++;
                        if (!err) {
                            // Get values if queryable
                            queryables = JSON.parse(metaDataKeys[table.split(".")[1]].fieldconf);
                            for (var i = 0; i < result.rows.length; i++) {
                                for (var prop in queryables) {
                                    if (queryables.hasOwnProperty(prop)) {
                                        if (queryables[prop].conflict) {
                                            tmp.push({
                                                name: prop,
                                                alias: queryables[prop].alias || prop,
                                                value: result.rows[i][prop],
                                                sort_id: queryables[prop].sort_id,
                                                key: false
                                            })
                                        }
                                    }
                                }
                                if (tmp.length > 0) {
                                    tmp.push({
                                        name: metaDataKeys[table.split(".")[1]].pkey,
                                        alias: null,
                                        value: result.rows[i][metaDataKeys[table.split(".")[1]].pkey],
                                        sort_id: null,
                                        key: true
                                    });
                                    data.push(tmp);
                                }
                                tmp = [];
                            }
                            hit = {
                                table: table,
                                title: metaDataKeys[table.split(".")[1]].f_table_title,
                                group: metaDataKeys[table.split(".")[1]].layergroup,
                                hits: result.rows.length,
                                data: data,
                                num: count + "/" + metaDataFinal.data.length,
                                time: time,
                                id: socketId,
                                error: null
                            };
                        } else {
                            hit = {
                                table: table,
                                title: metaDataKeys[table.split(".")[1]].f_table_title,
                                group: metaDataKeys[table.split(".")[1]].layergroup,
                                hits: null,
                                num: null,
                                time: time,
                                id: socketId,
                                error: err.severity,
                                hint: err.hint
                            };
                        }
                        hits[table] = hit;
                        io.emit(socketId, hit);
                        if (metaDataFinal.data.length === count) {
                            client.end();
                            var report = {
                                hits: hits,
                                file: fileName,
                                geom: buffer4326 || primitive,
                                primitive: primitive,
                                text: text
                            };
                            response.send(report);
                            // Add meta data and date/time to report before writing to file
                            report.metaData = metaDataFinal;
                            report.dateTime = moment().format('MMMM Do YYYY, hh:mm');
                            fs.writeFile(__dirname + "/tmp/" + fileName, JSON.stringify(report, null, 4), function (err) {
                                if (err) {
                                    console.log(err);
                                } else {
                                    console.log("Repport saved");
                                }
                            });
                            return;
                        }
                        iter();
                    });

                })();
                //winston.log('info', resultsObj.message, resultsObj);
            } else {
                console.log(err);
                //winston.log('error', err);
            }
        });
    });
});

var server = app.listen(8080, function () {
    var host = server.address().address;
    var port = server.address().port;
    console.log('App listening at http://%s:%s', host, port);
});
var io = require('socket.io')(server);
io.on('connection', function (socket) {
    console.log(socket.id);
});

<commit_msg>no message<commit_after>var request = require("request");
var express = require('express');
var pg = require('pg');
var fs = require('fs');
var reproject = require('reproject');
var terraformer = require('terraformer-wkt-parser');
var jsts = require('jsts');
var path = require('path');
var bodyParser = require('body-parser');
var moment = require('moment');
var nodeConfig = require('./config/nodeConfig');
var http = require('http');
var exec = require('child_process').exec;
var gc2i18n = require('./config/localModules/' + nodeConfig.locale);
var cors = require('cors');

// Define the i18n function
var __ = function (string) {
    if (typeof gc2i18n !== 'undefined') {
        if (gc2i18n.dict[string]) {
            return gc2i18n.dict[string];
        }
    }
    return string;
};
// Set locale for date/time string
moment.locale(nodeConfig.locale);

// Setup Express
var app = express();
app.use(cors());
app.use(bodyParser.urlencoded({extended: true, limit: '50mb'}));
app.use(bodyParser.json({extended: true, limit: '50mb'}));
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.static(path.join(__dirname, 'public')));

// Setup routes
app.get('/geoserver', function (req, response) {
    var url = "http://" + nodeConfig.print.host + ":" + nodeConfig.print.port + "/geoserver/pdf/info.json?var=printConfig";
    http.get(url, function (res) {
        var chunks = [];
        res.on('data', function (chunk) {
            chunks.push(chunk);
        });
        res.on("end", function () {
            var jsfile = new Buffer.concat(chunks);
            response.header('content-type', 'text/javascript');
            response.send(jsfile);
        });
    }).on("error", function () {
        callback(null);
    });
});
app.get('/static', function (req, response) {
    response.setHeader('Content-Type', 'application/json');
    response.sendFile(__dirname + '/tmp/' + req.query.id);
});
app.get('/pdf', function (req, response) {
    var url = "http://localhost:8090/?url=127.0.0.1:8080/html?id=" + req.query.id;
    http.get(url, function (res) {
        var chunks = [];
        res.on('data', function (chunk) {
            chunks.push(chunk);
        });
        res.on("end", function () {
            var jsfile = new Buffer.concat(chunks);
            response.header('content-type', 'application/pdf');
            response.send(jsfile);
        });
    }).on("error", function () {
        callback(null);
    });
});
app.post('/geomatic', function (req, response) {
    console.log(terraformer.convert(req.body.json));
    var postData = "wkt=" + terraformer.convert(req.body.json) + "&Username=" + nodeConfig.geomatic.user + "&Password=" + nodeConfig.geomatic.pw, id = req.body.id,
        options = {
            method: 'POST',
            host: "apps.conzoom.eu",
            port: "80",
            path: '/analysis/86F8A64F-1E22-4970-AD58-C808763CF61F/restreport/Pdf',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded ',
                'Content-Length': postData.length
            }
        },
        reqGeomatic = http.request(options, function (res) {
            var chunks = [];
            res.on('data', function (chunk) {
                chunks.push(chunk);
            });
            res.on('end', function () {
                var jsfile = new Buffer.concat(chunks);
                fs.writeFile(__dirname + "/public/tmp/geomatic_" + id + ".pdf", jsfile, 'binary', function (err) {
                    if (err) throw err;
                    console.log('Geomatic PDF saved.');
                });
                response.send({success: true});
            });
        });
    reqGeomatic.write(postData);
    reqGeomatic.end();
});
app.get('/html', function (req, res) {
    var addr;
    fs.readFile(__dirname + '/tmp/' + req.query.id, 'utf8', function (err, data) {
        if (err) {
            return console.log(err);
        }
        var obj = JSON.parse(data), hits = [], noHits = [], json, metaData, metaDataKeys = [];
        metaData = obj.metaData;
        for (var i = 0; i < metaData.data.length; i++) {
            metaDataKeys[metaData.data[i].f_table_name] = metaData.data[i];
        }
        for (var prop in obj.hits) {
            if (obj.hits.hasOwnProperty(prop)) {
                if (obj.hits[prop].hits > 0) {
                    hits.push(obj.hits[prop]);
                } else {
                    noHits.push(obj.hits[prop]);
                }
            }
        }
        json = {
            hits: hits,
            noHits: noHits,
            text: obj.text,
            dateTime: obj.dateTime,
            metaDataKeys: metaDataKeys,
            id: req.query.id,
            addr: addr
        };
        var input = json;
        input.i18n = gc2i18n;
        res.render('static', {layout: 'layout', json: input});
    });
});
app.post('/print', function (req, response) {
    var postData = JSON.stringify(req.body.json), id = req.body.id,
        options = {
            method: 'POST',
            host: nodeConfig.print.host,
            port: nodeConfig.print.port,
            path: '/geoserver/pdf/create.json',
            headers: {
                'Content-Type': 'application/json',
                'Content-Length': postData.length
            }
        },
        staticMapReq = http.request(options, function (res) {
            var str = '';
            res.setEncoding('binary');
            res.on('data', function (chunk) {
                str += chunk
            });
            res.on('end', function () {
                http.get(JSON.parse(str).getURL, function (res) {
                    var chunks = [];
                    res.on('data', function (chunk) {
                        chunks.push(chunk);
                    });
                    res.on("end", function () {
                        var jsfile = new Buffer.concat(chunks);
                        fs.writeFile(__dirname + "/public/tmp/" + id + ".pdf", jsfile, 'binary', function (err) {
                            if (err) throw err;
                            console.log('PDF saved.');
                            exec("gs -dQUIET -dPARANOIDSAFER -dBATCH -dNOPAUSE -dNOPROMPT -sDEVICE=png16m -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -r190 -dFirstPage=1 -dLastPage=1 -sOutputFile=" + __dirname + "/public/tmp/" + id + ".png " + __dirname + "/public/tmp/" + id + ".pdf", function (error, stdout, stderr) {
                                if (error !== null) {
                                    console.log(error);
                                }
                                response.send({success: true});
                            });
                        });
                    });
                }).on("error", function () {
                    callback(null);
                });
            });
            res.on('error', function () {
                console.log("Static map error");
            });
        });
    staticMapReq.write(postData);
    staticMapReq.end();
});
app.post('/intersection', function (req, response) {
    var socketId, fileName, baseLayer, layers, buffer, db, schema, text;
    if (!req.body.wkt) {
        response.status(400);
        response.send({
            success: false,
            message: "WKT is required"
        });
        return;
    }
    db = req.body.db;
    schema = req.body.schema;
    buffer = req.body.buffer;
    socketId = req.body.socketid;
    text = req.body.text;
    baseLayer = req.body.baselayer;
    layers = req.body.layers;
    var conString = "postgres://" + nodeConfig.pg.user + ":" + nodeConfig.pg.pw + "@" + nodeConfig.pg.host + "/" + db;
    var url = "http://" + nodeConfig.host + "/api/v1/meta/" + db + "/" + schema;
    var wkt = req.body.wkt;
    var buffer4326 = null;
    var primitive = JSON.parse(terraformer.parse(wkt).toJson());
    if (buffer > 0) {
        // Get the UTM zone
        var log = primitive.bbox[0], lat = primitive.bbox[1],
            zoneNumber = Math.floor((log + 180) / 6) + 1;

        if (lat >= 56.0 && lat < 64.0 && log >= 3.0 && log < 12.0) {
            zoneNumber = 32;
        }
        //Special zones for Svalbard
        if (lat >= 72.0 && lat < 84.0) {
            if (log >= 0.0 && log < 9.0) {
                zoneNumber = 31;
            }
            else if (log >= 9.0 && log < 21.0) {
                zoneNumber = 33;
            }
            else if (log >= 21.0 && log < 33.0) {
                zoneNumber = 35;
            }
            else if (log >= 33.0 && log < 42.0) {
                zoneNumber = 37;
            }
        }
        console.log("Zone:" + zoneNumber);
        var crss = {
            "proj": "+proj=utm +zone=" + zoneNumber + " +ellps=WGS84 +datum=WGS84 +units=m +no_defs",
            "unproj": "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"
        };

        var reader = new jsts.io.GeoJSONParser();
        var writer = new jsts.io.GeoJSONWriter();

        var geom = reader.read(reproject.reproject(primitive, "unproj", "proj", crss));
        buffer4326 = reproject.reproject(writer.write(geom.buffer(buffer)), "proj", "unproj", crss);
    }
    fileName = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
    pg.connect(conString, function (err, client, done) {
        if (err) {
            return console.error('error fetching client from pool', err);
        }
        request.get(url, function (err, res, body) {
            if (!err) {
                var metaData = JSON.parse(body), count = 0, table, sql, geomField, bindings, startTime, hits = {}, hit, metaDataFinal = {data: []}, metaDataKeys = [];
                // Count layers
                for (var i = 0; i < metaData.data.length; i = i + 1) {
                    if (metaData.data[i].type !== "RASTER" &&
                        metaData.data[i].baselayer !== true &&
                        metaData.data[i].skipconflict !== true) {
                        metaDataFinal.data.push(metaData.data[i]);
                        metaDataKeys[metaData.data[i].f_table_name] = metaData.data[i];
                    }
                }
                (function iter() {
                    geomField = metaDataFinal.data[count].f_geometry_column;
                    table = metaDataFinal.data[count].f_table_schema + "." + metaDataFinal.data[count].f_table_name;
                    if (buffer > 0) {
                        sql = "SELECT geography(ST_transform(" + geomField + ",4326)) as _gc2_geom, * FROM " + table + " WHERE ST_DWithin(ST_GeogFromText($1), geography(ST_transform(" + geomField + ",4326)), $2);";
                        bindings = [wkt, buffer];
                    } else {
                        sql = "SELECT * FROM " + table + " WHERE ST_transform(" + geomField + ",900913) && ST_transform(ST_geomfromtext($1,4326),900913) AND ST_intersects(ST_transform(" + geomField + ",900913),ST_transform(ST_geomfromtext($1,4326),900913))";
                        bindings = [wkt];
                    }
                    startTime = new Date().getTime();
                    client.query(sql, bindings, function (err, result) {
                        var time = new Date().getTime() - startTime, queryables, data = [], tmp = [];
                        count++;
                        if (!err) {
                            // Get values if queryable
                            queryables = JSON.parse(metaDataKeys[table.split(".")[1]].fieldconf);
                            for (var i = 0; i < result.rows.length; i++) {
                                for (var prop in queryables) {
                                    if (queryables.hasOwnProperty(prop)) {
                                        if (queryables[prop].conflict) {
                                            tmp.push({
                                                name: prop,
                                                alias: queryables[prop].alias || prop,
                                                value: result.rows[i][prop],
                                                sort_id: queryables[prop].sort_id,
                                                key: false
                                            })
                                        }
                                    }
                                }
                                if (tmp.length > 0) {
                                    tmp.push({
                                        name: metaDataKeys[table.split(".")[1]].pkey,
                                        alias: null,
                                        value: result.rows[i][metaDataKeys[table.split(".")[1]].pkey],
                                        sort_id: null,
                                        key: true
                                    });
                                    data.push(tmp);
                                }
                                tmp = [];
                            }
                            hit = {
                                table: table,
                                title: metaDataKeys[table.split(".")[1]].f_table_title,
                                group: metaDataKeys[table.split(".")[1]].layergroup,
                                hits: result.rows.length,
                                data: data,
                                num: count + "/" + metaDataFinal.data.length,
                                time: time,
                                id: socketId,
                                error: null
                            };
                        } else {
                            hit = {
                                table: table,
                                title: metaDataKeys[table.split(".")[1]].f_table_title,
                                group: metaDataKeys[table.split(".")[1]].layergroup,
                                hits: null,
                                num: null,
                                time: time,
                                id: socketId,
                                error: err.severity,
                                hint: err.hint
                            };
                        }
                        hits[table] = hit;
                        io.emit(socketId, hit);
                        if (metaDataFinal.data.length === count) {
                            client.end();
                            var report = {
                                hits: hits,
                                file: fileName,
                                geom: buffer4326 || primitive,
                                primitive: primitive,
                                text: text
                            };
                            response.send(report);
                            // Add meta data and date/time to report before writing to file
                            report.metaData = metaDataFinal;
                            report.dateTime = moment().format('MMMM Do YYYY, hh:mm');
                            fs.writeFile(__dirname + "/tmp/" + fileName, JSON.stringify(report, null, 4), function (err) {
                                if (err) {
                                    console.log(err);
                                } else {
                                    console.log("Repport saved");
                                }
                            });
                            return;
                        }
                        iter();
                    });

                })();
                //winston.log('info', resultsObj.message, resultsObj);
            } else {
                console.log(err);
                //winston.log('error', err);
            }
        });
    });
});

var server = app.listen(8080, function () {
    var host = server.address().address;
    var port = server.address().port;
    console.log('App listening at http://%s:%s', host, port);
});
var io = require('socket.io')(server);
io.on('connection', function (socket) {
    console.log(socket.id);
});

<|endoftext|>


<commit_before>'use strict';

var app = angular.module('playApp', [
  'ngRoute',
  'playApp.units',
  'playApp.address',
  'playApp.hdkeys',
  'playApp.transaction',
  'playApp.unspent',
  'playApp.bitauth',
  'playApp.multisig'
]);

// Config
app.config(['$routeProvider', function($routeProvider) {
  $routeProvider.otherwise({redirectTo: '/units'});
}]);

app.constant('bitcore', require('bitcore-lib-dash'));

// Filters
app.filter('btc', function(bitcore) {
  return function(satoshis) {
    return bitcore.Unit.fromSatoshis(satoshis).toBTC();
  };
})
.filter('permalink', function(bitcore) {
  return function(data, section) {
    var url = './#/' + section + '?data=' + encodeURI(data);
    if (url.length > 2083) throw new Error('URL too long')
    return url;
  };
})
.filter('ellipsify', function() {
  return function(data) {
    return data.substr(0, 4) + '...' + data.substr(data.length - 4, data.length);
  };
});

// Directives
app.directive('exampleCode', function() {
  return {
    link: function(scope, element, attrs) {
      scope.$watch(attrs.exampleCode, function(value) {
        element.text(value);
        hljs.highlightBlock(element[0]);
      });
    }
  };
})
.directive('autoSelect', function() {
  return {
    link: function(scope, element, attrs) {
      $(element).focus(function(){
        $(this).select();
      });
      element.attr('spellcheck', false);
    }
  };
})
.directive('requireTooltip', function() {
  return {
    link: function(scope, element, attrs) {
     $(document).foundation();
     $(document).foundation('tooltip', 'reflow');
    }
  };
})
.directive('requireModal', function() {
  return {
    link: function(scope, element, attrs) {
     $(document).foundation();
     $(document).foundation('reveal', 'reflow');
    }
  };
});

// Filters
function registerValidator(app, name, validator) {
  app.directive(name, function(bitcore) {
    return {
      require: 'ngModel',
      link: function(scope, elem, attr, ngModel) {
        function validate(value) {
          var valid = validator(bitcore, value, scope, attr);
          ngModel.$setValidity(null, valid);
          return value;
        }
        ngModel.$parsers.unshift(validate);
        ngModel.$formatters.unshift(validate);
      }
    };
  });
}

registerValidator(app, 'privateKey', function(bitcore, value) {
  return bitcore.PrivateKey.isValid(value);
});
registerValidator(app, 'publicKey', function(bitcore, value) {
  return bitcore.PublicKey.isValid(value);
});
registerValidator(app, 'xprivateKey', function(bitcore, value) {
  return bitcore.HDPrivateKey.isValidSerialized(value);
});
registerValidator(app, 'xpublicKey', function(bitcore, value) {
  return bitcore.HDPublicKey.isValidSerialized(value);
});
registerValidator(app, 'privateHdpath', function(bitcore, value, scope) {
  return !!(/^[mM][']?(\/[0-9]+[']?)*[/]?$/.exec(value));
});
registerValidator(app, 'publicHdpath', function(bitcore, value, scope) {
  return !!(/^[mM](\/[0-9]+)*[/]?$/.exec(value));
});
registerValidator(app, 'address', function(bitcore, value) {
  return bitcore.Address.isValid(value);
});

// Sidebar
app.controller('SideBar', function($scope, $rootScope, $timeout, $location) {
  $timeout(function(){
    $rootScope.showFooter = true;
    $rootScope.$apply();
  }, 100);

  $scope.getClass = function(path) {
    return $location.path().substr(0, path.length) === path ? "current" : "";
  }

})
.controller('Network', function($scope, $rootScope, $timeout, bitcore) {
  var networks = bitcore.Networks;
  networks.defaultNetwork = networks.testnet;
  $rootScope.$broadcast('networkUpdate');

  $scope.setTestnet = function(value) {
    networks.defaultNetwork = value ? networks.livenet : networks.testnet;
    $rootScope.$broadcast('networkUpdate');
  };
});
<commit_msg>wip: add module<commit_after>'use strict';

var app = angular.module('playApp', [
  'ngRoute',
  'playApp.units',
  'playApp.address',
  'playApp.hdkeys',
  'playApp.transaction',
  'playApp.unspent',
  'playApp.bitauth',
  'playApp.multisig'
]);

// Config
app.config(['$routeProvider', function($routeProvider) {
  $routeProvider.otherwise({redirectTo: '/units'});
}]);

app.constant('bitcore', require('bitcore-lib-dash'));

// Filters
app.filter('btc', function(bitcore) {
  return function(satoshis) {
    return bitcore.Unit.fromSatoshis(satoshis).toBTC();
  };
})
.filter('permalink', function(bitcore) {
  return function(data, section) {
    var url = './#/' + section + '?data=' + encodeURI(data);ß
    if (url.length > 2083) throw new Error('URL too long')
    return url;
  };
})
.filter('ellipsify', function() {
  return function(data) {
    return data.substr(0, 4) + '...' + data.substr(data.length - 4, data.length);
  };
});

// Directives
app.directive('exampleCode', function() {
  return {
    link: function(scope, element, attrs) {
      scope.$watch(attrs.exampleCode, function(value) {
        element.text(value);
        hljs.highlightBlock(element[0]);
      });
    }
  };
})
.directive('autoSelect', function() {
  return {
    link: function(scope, element, attrs) {
      $(element).focus(function(){
        $(this).select();
      });
      element.attr('spellcheck', false);
    }
  };
})
.directive('requireTooltip', function() {
  return {
    link: function(scope, element, attrs) {
     $(document).foundation();
     $(document).foundation('tooltip', 'reflow');
    }
  };
})
.directive('requireModal', function() {
  return {
    link: function(scope, element, attrs) {
     $(document).foundation();
     $(document).foundation('reveal', 'reflow');
    }
  };
});

// Filters
function registerValidator(app, name, validator) {
  app.directive(name, function(bitcore) {
    return {
      require: 'ngModel',
      link: function(scope, elem, attr, ngModel) {
        function validate(value) {
          var valid = validator(bitcore, value, scope, attr);
          ngModel.$setValidity(null, valid);
          return value;
        }
        ngModel.$parsers.unshift(validate);
        ngModel.$formatters.unshift(validate);
      }
    };
  });
}

registerValidator(app, 'privateKey', function(bitcore, value) {
  return bitcore.PrivateKey.isValid(value);
});
registerValidator(app, 'publicKey', function(bitcore, value) {
  return bitcore.PublicKey.isValid(value);
});
registerValidator(app, 'xprivateKey', function(bitcore, value) {
  return bitcore.HDPrivateKey.isValidSerialized(value);
});
registerValidator(app, 'xpublicKey', function(bitcore, value) {
  return bitcore.HDPublicKey.isValidSerialized(value);
});
registerValidator(app, 'privateHdpath', function(bitcore, value, scope) {
  return !!(/^[mM][']?(\/[0-9]+[']?)*[/]?$/.exec(value));
});
registerValidator(app, 'publicHdpath', function(bitcore, value, scope) {
  return !!(/^[mM](\/[0-9]+)*[/]?$/.exec(value));
});
registerValidator(app, 'address', function(bitcore, value) {
  return bitcore.Address.isValid(value);
});

// Sidebar
app.controller('SideBar', function($scope, $rootScope, $timeout, $location) {
  $timeout(function(){
    $rootScope.showFooter = true;
    $rootScope.$apply();
  }, 100);

  $scope.getClass = function(path) {
    return $location.path().substr(0, path.length) === path ? "current" : "";
  }

})
.controller('Network', function($scope, $rootScope, $timeout, bitcore) {
  var networks = bitcore.Networks;
  networks.defaultNetwork = networks.testnet;
  $rootScope.$broadcast('networkUpdate');

  $scope.setTestnet = function(value) {
    networks.defaultNetwork = value ? networks.livenet : networks.testnet;
    $rootScope.$broadcast('networkUpdate');
  };
});
<|endoftext|>