<commit_before>"use strict";
/*!
 * tabulator
 * 2015 Codenautas
 * GNU Licensed
 */

/**
 * Module dependencies.
 */

var _=require('lodash');
var html=require('js-to-html').html;

 // import used by this file
// var dependency = dependency || require('dependency');

function array_combine(keys, values) {
  var new_array = {};
  for (var i = 0; i < keys.length; i++) {
    new_array[keys[i]] = values[i];
  }
  return new_array;
}

var Tabulator = function(){
};

(function(){

Tabulator.prototype.captionPart = function captionPart(matrix){
    return matrix.caption?html.caption(matrix.caption):null;
}

Tabulator.prototype.colGroups = function colGroups(matrix){
    var lineVariablesPart= matrix.lineVariables? html.colgroup({'class':'headers'},matrix.lineVariables.map(function(lineVariable){
        return html.col({'class':lineVariable})})):null;
    var columnVariablesPart=(matrix.columns)? html.colgroup({'class':'data'},matrix.columns.map(function(column){
        return html.col({'class':JSON.stringify(array_combine(matrix.columnVariables,column.titles))}) })):null;
    return [].concat(lineVariablesPart,columnVariablesPart);
}

Tabulator.prototype.tHeadPart = function tHeadPart(matrix){
    if(!matrix.columnVariables) return null;
    return html.thead(
        [
            html.tr(
                matrix.lineVariables.map(function(varName){
                    return html.th({'class':'variable', 'rowspan':2*matrix.columnVariables.length},varName);
                }).concat(
                    html.th({'class':'variable', colspan:matrix.columns.length},matrix.columnVariables[0])
                )
            )
        ].concat(_.flatten(matrix.columnVariables.map(function(columnVariable,iColumnVariable){
            var lineTitles=[];
            var lineVariables=[];
            var previousValuesUptoThisRowJson="none";
            var colspan=1;
            function updateColspan(){
                if(colspan>1){
                    titleCellAttrs.colspan=colspan;
                    variableCellAttrs.colspan=colspan;
                }
            }
            for(var i=0; i<matrix.columns.length; i++){
                var actualValues=matrix.columns[i].titles;
                var actualValuesUptoThisRow=actualValues.slice(0,iColumnVariable+1);
                var actualValuesUptoThisRowJson=JSON.stringify(actualValuesUptoThisRow);
                if(actualValuesUptoThisRowJson!=previousValuesUptoThisRowJson){
                    updateColspan();
                    var titleCellAttrs={'class':'var_'+matrix.columnVariables[iColumnVariable]};
                    lineTitles.push(html.th(titleCellAttrs, actualValues[iColumnVariable]));
                    if(iColumnVariable+1<matrix.columnVariables.length){
                        var variableCellAttrs={'class':'variable'};
                        lineVariables.push(html.th(variableCellAttrs, matrix.columnVariables[iColumnVariable+1]))
                    }
                    previousValuesUptoThisRowJson=actualValuesUptoThisRowJson;
                    colspan=0;
                };
                colspan++;
            }
            updateColspan();
            if(iColumnVariable+1<matrix.columnVariables.length){
                return [html.tr(lineTitles), html.tr(lineVariables)];
            }else{
                return [html.tr(lineTitles)];
            }
        }))
    ));
}

Tabulator.prototype.defaultShowAttribute='show';

Tabulator.prototype.toLeftCellTable=function(cell){
    return html.th(cell,cell instanceof Object?cell[this.defaultShowAttribute]:null);
}

Tabulator.prototype.toCellTable=function(cell){
    return html.td(cell,cell instanceof Object?cell[this.defaultShowAttribute]:null);
}

Tabulator.prototype.tBodyPart = function tBodyPart(matrix){
    var trList=[];
    var previousLineTitles=[];
    var titleLineAttrs=[];
    var colspans=[];
    if(matrix.lines && matrix.lines[0] && matrix.lines[0].titles){
        for(var j=0;j<matrix.lines[0].titles.length;j++){
            colspans[j]=0;
        }
    }
    for(var i=0; i<matrix.lines.length;i++){
        var actualLine=matrix.lines[i]
        var actualLineTitles=actualLine.titles;
        var thListActualLine=[];
        var actualLineCells=matrix.lines[i].cells;
        var td=actualLineCells.map(function(cell){
            return (this.toCellTable(cell));
        },this);
        if(actualLineTitles){
            for(var j=0;j<actualLineTitles.length;j++){
                var actualLineTitlesUpToNow=actualLineTitles.slice(0,j+1);
                var previousLineTitlesUpToNow=previousLineTitles.slice(0,j+1);
                colspans[j]++
                if(colspans[j]>1){
                    titleLineAttrs[j].colspan=colspans[j];
                }
                if(JSON.stringify(actualLineTitlesUpToNow)!=JSON.stringify(previousLineTitlesUpToNow)){
                    colspans[j]=0;
                    titleLineAttrs[j]={};
                    thListActualLine.push(html.th(titleLineAttrs[j],actualLineTitles[j]));
                }
            }
            previousLineTitles=actualLineTitles;
        }
        trList.push(html.tr(thListActualLine.concat(td)));
    }
    return html.tbody(trList)
}

Tabulator.prototype.toHtmlTable = function toHtmlTable(matrix){
    this.controls(matrix);
    return html.table([].concat(
        this.captionPart(matrix),
        this.colGroups(matrix),
        this.tHeadPart(matrix),
        this.tBodyPart(matrix)
    ));
}

Tabulator.prototype.controls=function controls(matrix){
    var  matrixLineVariables=matrix.lineVariables;
    var  matrixLines=matrix.lines;
    var  matrixColumnVariables=matrix.columnVariables;
    var  matrixColumns=matrix.columns;

    if(matrixColumnVariables && matrixColumns){
        variableExistanceAndQuantity(matrixColumnVariables,matrixColumns,'columnVariables');
    }
    if(matrixLineVariables && matrixLines){
        variableExistanceAndQuantity(matrixLineVariables,matrixLines,'lineVariables');
    }
    if(matrixColumns && matrixLines){
        cellExistanceAndQuantity(matrixColumns,matrixLines,'cells')
    }

    function variableExistanceAndQuantity(arrVar,objVar,nameArrVar){
        var variablesQuantity=arrVar.length;
        for(var i=0;i<objVar.length;i++){
            if(objVar[i].titles){
                if(objVar[i].titles.length!=variablesQuantity){
                    throw new Error('column 1 has 0 values but columnVariables has 1'+'line 2 has 3 values but lineVariables has 2');
                }
            }else{
                throw new Error('there are no titles in column 0 but columnVariables exists'+'there are no titles in line 1 but lineVariables exists');
            }
        }
    }

    function cellExistanceAndQuantity(matrixColumns,matrixLines,varName){
        var columnQuantity=matrixColumns.length;
        for(var i=0;i<matrixLines.length;i++){
            if(matrixLines[i].cells.length>0){
                if(matrixLines[i].cells!=columnQuantity){
                    throw new Error('line 2 has 1 cells but columns has 3');
                }
            }else{
                throw new Error('there are no cells in line 0 but columns exists');
            }
        }
    }
}

Tabulator.prototype.toMatrix = function toMatrix(datum){
    var places={
        left:{place:'lineVariables'},
        top:{place:'columnVariables'},
        data:{place:'dataVariables'},
    };
    var matrix={lineVariables:[],columnVariables:[], dataVariables:[], columns:[], lines:[]};
    for(var i=0; i<datum.vars.length;i++){
        var cadaVar=datum.vars[i];
        matrix[places[cadaVar.place].place].push(cadaVar.name);
    }
    var vistosColumnVariables={};
    var vistosLineVariables={};
    for(var iList=0; iList<datum.list.length; iList++){
        var iCell;
        var iLine;
        var cadaList=datum.list[iList];
        for(var iColumn=0; iColumn<matrix.columnVariables.length;iColumn++){
            var cadaNameTop=matrix.columnVariables[iColumn];
            if (!vistosColumnVariables[cadaList[cadaNameTop]]){
                iCell=matrix.columns.push({titles:[cadaList[cadaNameTop]]})-1;
                vistosColumnVariables[cadaList[cadaNameTop]]={index: iCell};
            }else{
                iCell=vistosColumnVariables[cadaList[cadaNameTop]].index;
            }
        }
        var cadaDatoLeft=[];
        var cadaDatoData=[];
        for(var j=0; j<matrix.lineVariables.length;j++){
            cadaDatoLeft.push(cadaList[matrix.lineVariables[j]]);
            cadaDatoData.push(cadaList[matrix.dataVariables[j]]);
        }
        var jsonCadaDatoLeft=JSON.stringify(cadaDatoLeft);
        if (vistosLineVariables[jsonCadaDatoLeft]){
            iLine=vistosLineVariables[jsonCadaDatoLeft].index;
        }else{
            iLine=matrix.lines.push({titles:cadaDatoLeft, cells:[]})-1;
            vistosLineVariables[jsonCadaDatoLeft]={index: iLine};
        }
        var newCell={};
        if(datum.showFunction){
            newCell.display=datum.showFunction(cadaList);
        }
        for(var k=0; k<matrix.dataVariables.length; k++){
            var nombreVariable=matrix.dataVariables[k];
            newCell[nombreVariable]=cadaList[nombreVariable];
        }
        matrix.lines[iLine].cells[iCell]=newCell;
    }
    for(var l=0; l<matrix.lines.length; l++){
        for(var m=0; m<matrix.columns.length; m++){
            if (matrix.lines[l].cells[m]===undefined){
                matrix.lines[l].cells[m]=null;
            }
        }
    }
    return matrix;
};

// module system:

/* istanbul ignore else  */
if (typeof module !== 'undefined' && module.exports) {
    module.exports = Tabulator;
}
})();
<commit_msg>Arreglé los mensajes de error para que sean genéricos<commit_after>"use strict";
/*!
 * tabulator
 * 2015 Codenautas
 * GNU Licensed
 */

/**
 * Module dependencies.
 */

var _=require('lodash');
var html=require('js-to-html').html;

 // import used by this file
// var dependency = dependency || require('dependency');

function array_combine(keys, values) {
  var new_array = {};
  for (var i = 0; i < keys.length; i++) {
    new_array[keys[i]] = values[i];
  }
  return new_array;
}

var Tabulator = function(){
};

(function(){

Tabulator.prototype.captionPart = function captionPart(matrix){
    return matrix.caption?html.caption(matrix.caption):null;
}

Tabulator.prototype.colGroups = function colGroups(matrix){
    var lineVariablesPart= matrix.lineVariables? html.colgroup({'class':'headers'},matrix.lineVariables.map(function(lineVariable){
        return html.col({'class':lineVariable})})):null;
    var columnVariablesPart=(matrix.columns)? html.colgroup({'class':'data'},matrix.columns.map(function(column){
        return html.col({'class':JSON.stringify(array_combine(matrix.columnVariables,column.titles))}) })):null;
    return [].concat(lineVariablesPart,columnVariablesPart);
}

Tabulator.prototype.tHeadPart = function tHeadPart(matrix){
    if(!matrix.columnVariables) return null;
    return html.thead(
        [
            html.tr(
                matrix.lineVariables.map(function(varName){
                    return html.th({'class':'variable', 'rowspan':2*matrix.columnVariables.length},varName);
                }).concat(
                    html.th({'class':'variable', colspan:matrix.columns.length},matrix.columnVariables[0])
                )
            )
        ].concat(_.flatten(matrix.columnVariables.map(function(columnVariable,iColumnVariable){
            var lineTitles=[];
            var lineVariables=[];
            var previousValuesUptoThisRowJson="none";
            var colspan=1;
            function updateColspan(){
                if(colspan>1){
                    titleCellAttrs.colspan=colspan;
                    variableCellAttrs.colspan=colspan;
                }
            }
            for(var i=0; i<matrix.columns.length; i++){
                var actualValues=matrix.columns[i].titles;
                var actualValuesUptoThisRow=actualValues.slice(0,iColumnVariable+1);
                var actualValuesUptoThisRowJson=JSON.stringify(actualValuesUptoThisRow);
                if(actualValuesUptoThisRowJson!=previousValuesUptoThisRowJson){
                    updateColspan();
                    var titleCellAttrs={'class':'var_'+matrix.columnVariables[iColumnVariable]};
                    lineTitles.push(html.th(titleCellAttrs, actualValues[iColumnVariable]));
                    if(iColumnVariable+1<matrix.columnVariables.length){
                        var variableCellAttrs={'class':'variable'};
                        lineVariables.push(html.th(variableCellAttrs, matrix.columnVariables[iColumnVariable+1]))
                    }
                    previousValuesUptoThisRowJson=actualValuesUptoThisRowJson;
                    colspan=0;
                };
                colspan++;
            }
            updateColspan();
            if(iColumnVariable+1<matrix.columnVariables.length){
                return [html.tr(lineTitles), html.tr(lineVariables)];
            }else{
                return [html.tr(lineTitles)];
            }
        }))
    ));
}

Tabulator.prototype.defaultShowAttribute='show';

Tabulator.prototype.toLeftCellTable=function(cell){
    return html.th(cell,cell instanceof Object?cell[this.defaultShowAttribute]:null);
}

Tabulator.prototype.toCellTable=function(cell){
    return html.td(cell,cell instanceof Object?cell[this.defaultShowAttribute]:null);
}

Tabulator.prototype.tBodyPart = function tBodyPart(matrix){
    var trList=[];
    var previousLineTitles=[];
    var titleLineAttrs=[];
    var colspans=[];
    if(matrix.lines && matrix.lines[0] && matrix.lines[0].titles){
        for(var j=0;j<matrix.lines[0].titles.length;j++){
            colspans[j]=0;
        }
    }
    for(var i=0; i<matrix.lines.length;i++){
        var actualLine=matrix.lines[i]
        var actualLineTitles=actualLine.titles;
        var thListActualLine=[];
        var actualLineCells=matrix.lines[i].cells;
        var td=actualLineCells.map(function(cell){
            return (this.toCellTable(cell));
        },this);
        if(actualLineTitles){
            for(var j=0;j<actualLineTitles.length;j++){
                var actualLineTitlesUpToNow=actualLineTitles.slice(0,j+1);
                var previousLineTitlesUpToNow=previousLineTitles.slice(0,j+1);
                colspans[j]++
                if(colspans[j]>1){
                    titleLineAttrs[j].colspan=colspans[j];
                }
                if(JSON.stringify(actualLineTitlesUpToNow)!=JSON.stringify(previousLineTitlesUpToNow)){
                    colspans[j]=0;
                    titleLineAttrs[j]={};
                    thListActualLine.push(html.th(titleLineAttrs[j],actualLineTitles[j]));
                }
            }
            previousLineTitles=actualLineTitles;
        }
        trList.push(html.tr(thListActualLine.concat(td)));
    }
    return html.tbody(trList)
}

Tabulator.prototype.toHtmlTable = function toHtmlTable(matrix){
    this.controls(matrix);
    return html.table([].concat(
        this.captionPart(matrix),
        this.colGroups(matrix),
        this.tHeadPart(matrix),
        this.tBodyPart(matrix)
    ));
}

Tabulator.prototype.controls=function controls(matrix){
    var  matrixLineVariables=matrix.lineVariables;
    var  matrixLines=matrix.lines;
    var  matrixColumnVariables=matrix.columnVariables;
    var  matrixColumns=matrix.columns;
    if(matrixColumnVariables && matrixColumns){
        variableExistanceAndQuantity(matrixColumnVariables,matrixColumns,'columnVariables');
    }
    if(matrixLineVariables && matrixLines){
        variableExistanceAndQuantity(matrixLineVariables,matrixLines,'lineVariables');
    }
    if(matrixColumns && matrixLines){
        cellExistanceAndQuantity(matrixColumns,matrixLines,'cells')
    }
    function variableExistanceAndQuantity(arrVar,objVar,nameArrVar){
        var varName=nameArrVar=='columnVariables'?'column ':'line ';
        var variablesQuantity=arrVar.length;
        for(var i=0;i<objVar.length;i++){
            if(objVar[i].titles){
                if(objVar[i].titles.length!=variablesQuantity){
                    var errorMessage=varName+i+' has '+objVar[i].titles.length+' values but '+nameArrVar+' has '+variablesQuantity;
                    throw new Error(errorMessage);
                }
            }else{
                var errorMessage='there are no titles in '+ varName +i+' but '+nameArrVar+ ' exists';
                throw new Error(errorMessage);
            }
        }
    }

    function cellExistanceAndQuantity(matrixColumns,matrixLines,varName){
        var columnQuantity=matrixColumns.length;
        for(var i=0;i<matrixLines.length;i++){
            if(matrixLines[i].cells.length>0){
                if(matrixLines[i].cells.length!=columnQuantity){
                    var errorMessage='line '+i+' has '+matrixLines[i].cells.length+' cells but columns has '+columnQuantity;
                    throw new Error(errorMessage);
                }
            }else{
                var errorMessage='there are no cells in line '+i+' but columns exists';
                throw new Error(errorMessage);
            }
        }
    }
}

Tabulator.prototype.toMatrix = function toMatrix(datum){
    var places={
        left:{place:'lineVariables'},
        top:{place:'columnVariables'},
        data:{place:'dataVariables'},
    };
    var matrix={lineVariables:[],columnVariables:[], dataVariables:[], columns:[], lines:[]};
    for(var i=0; i<datum.vars.length;i++){
        var cadaVar=datum.vars[i];
        matrix[places[cadaVar.place].place].push(cadaVar.name);
    }
    var vistosColumnVariables={};
    var vistosLineVariables={};
    for(var iList=0; iList<datum.list.length; iList++){
        var iCell;
        var iLine;
        var cadaList=datum.list[iList];
        for(var iColumn=0; iColumn<matrix.columnVariables.length;iColumn++){
            var cadaNameTop=matrix.columnVariables[iColumn];
            if (!vistosColumnVariables[cadaList[cadaNameTop]]){
                iCell=matrix.columns.push({titles:[cadaList[cadaNameTop]]})-1;
                vistosColumnVariables[cadaList[cadaNameTop]]={index: iCell};
            }else{
                iCell=vistosColumnVariables[cadaList[cadaNameTop]].index;
            }
        }
        var cadaDatoLeft=[];
        var cadaDatoData=[];
        for(var j=0; j<matrix.lineVariables.length;j++){
            cadaDatoLeft.push(cadaList[matrix.lineVariables[j]]);
            cadaDatoData.push(cadaList[matrix.dataVariables[j]]);
        }
        var jsonCadaDatoLeft=JSON.stringify(cadaDatoLeft);
        if (vistosLineVariables[jsonCadaDatoLeft]){
            iLine=vistosLineVariables[jsonCadaDatoLeft].index;
        }else{
            iLine=matrix.lines.push({titles:cadaDatoLeft, cells:[]})-1;
            vistosLineVariables[jsonCadaDatoLeft]={index: iLine};
        }
        var newCell={};
        if(datum.showFunction){
            newCell.display=datum.showFunction(cadaList);
        }
        for(var k=0; k<matrix.dataVariables.length; k++){
            var nombreVariable=matrix.dataVariables[k];
            newCell[nombreVariable]=cadaList[nombreVariable];
        }
        matrix.lines[iLine].cells[iCell]=newCell;
    }
    for(var l=0; l<matrix.lines.length; l++){
        for(var m=0; m<matrix.columns.length; m++){
            if (matrix.lines[l].cells[m]===undefined){
                matrix.lines[l].cells[m]=null;
            }
        }
    }
    return matrix;
};

// module system:

/* istanbul ignore else  */
if (typeof module !== 'undefined' && module.exports) {
    module.exports = Tabulator;
}
})();
<|endoftext|>


<commit_before>/*
 * grunt-sst
 * https://github.com/tflynn/grunt-sst
 *
 * Copyright (c) 2015 Ted Flynn
 * Licensed under the MIT license.
 */

'use strict';

var swig = require('swig');
var path = require('path');

var SwigTemplate = function(grunt, task) {
    this.grunt = grunt;
    this.files = task.files;
    this.options = task.options();

    if (this.options.swigDefaults) {
        this.mergeDefaults();
    }

    this.renderTemplates();
};

var proto = SwigTemplate.prototype;

proto.mergeDefaults = function() {
    var grunt = this.grunt;
    var options = this.options;
    var swigOpts = this.options.swigDefaults;

    if (swigOpts.locals && typeof swigOpts.locals === 'string') {
        var localsObject = grunt.file.readJSON(swigOpts.locals);
    } else {
        grunt.fail.warn('The locals property must be a file path string to an actual JSON file.');
    }

    swigOpts.locals = localsObject;

    swig.setDefaults(swigOpts);

    return this;
}

proto.renderTemplates = function() {
    var grunt = this.grunt;
    var files = this.files;

    files.forEach(function(file, index) {
        var cwd = file.orig.cwd || '';
        var src = file.src[0];
        var dirname = path.dirname(src);
        var basename = path.basename(src, '.swig');
        var outFile = basename + '.html';
        var tplContextFile = path.join(dirname, basename) + '.json';
        var tplVars = null;

        if (grunt.file.exists(tplContextFile)) {
            tplVars = grunt.file.readJSON(tplContextFile);
            grunt.log.write('Template-specific data found; merging "%s" with "%s".' + '\n', tplContextFile, src);
        }

        grunt.log.write('Processing: "%s"' + '\n', src);

        grunt.file.write(file.dest, swig.renderFile(src, tplVars));

    });

    return this;
};

module.exports = function(grunt) {
    grunt.registerMultiTask('swig', 'Compiles Swig templates with Grunt.', function() {
        new SwigTemplate(grunt, this);
  });
};<commit_msg>Addresses minor linting issues.<commit_after>/*
 * grunt-sst
 * https://github.com/tflynn/grunt-sst
 *
 * Copyright (c) 2015 Ted Flynn
 * Licensed under the MIT license.
 */

'use strict';

var swig = require('swig');
var path = require('path');

var SwigTemplate = function(grunt, task) {
    this.grunt = grunt;
    this.files = task.files;
    this.options = task.options();

    if (this.options.swigDefaults) {
        this.mergeDefaults();
    }

    this.renderTemplates();
};

var proto = SwigTemplate.prototype;

proto.mergeDefaults = function() {
    var grunt = this.grunt;
    var options = this.options;
    var swigOpts = this.options.swigDefaults;
    var localsObject;

    if (swigOpts.locals && typeof swigOpts.locals === 'string') {
        localsObject = grunt.file.readJSON(swigOpts.locals);
    } else {
        grunt.fail.warn('The locals property must be a file path string to an actual JSON file.');
    }

    swigOpts.locals = localsObject;

    swig.setDefaults(swigOpts);

    return this;
};

proto.renderTemplates = function() {
    var grunt = this.grunt;
    var files = this.files;

    files.forEach(function(file, index) {
        var cwd = file.orig.cwd || '';
        var src = file.src[0];
        var dirname = path.dirname(src);
        var basename = path.basename(src, '.swig');
        var outFile = basename + '.html';
        var tplContextFile = path.join(dirname, basename) + '.json';
        var tplVars = null;

        if (grunt.file.exists(tplContextFile)) {
            tplVars = grunt.file.readJSON(tplContextFile);
            grunt.log.write('Template-specific data found; merging "%s" with "%s".' + '\n', tplContextFile, src);
        }

        grunt.log.write('Processing: "%s"' + '\n', src);

        grunt.file.write(file.dest, swig.renderFile(src, tplVars));

    });

    return this;
};

module.exports = function(grunt) {
    grunt.registerMultiTask('sst', 'Compiles Swig templates with Grunt.', function() {
        new SwigTemplate(grunt, this);
  });
};<|endoftext|>


<commit_before>/*
 *    (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

var fs = require('fs');
var path = require('path');

module.exports = function (config) {
  var xstaticPath;
  var basePaths = [
    './.venv',
    './.tox/py27'
  ];

  for (var i = 0; i < basePaths.length; i++) {
    var basePath = path.resolve(basePaths[i]);

    if (fs.existsSync(basePath)) {
      xstaticPath = basePath + '/lib/python2.7/site-packages/xstatic/pkg/';
      break;
    }
  }

  if (!xstaticPath) {
    console.error('xStatic libraries not found, please set up venv');
    process.exit(1);
  }

  config.set({
    preprocessors: {
      // Used to collect templates for preprocessing.
      // NOTE: the templates must also be listed in the files section below.
      './**/*.html': ['ng-html2js'],
      // Used to indicate files requiring coverage reports.
      './**/!(*.spec).js': ['coverage']
    },

    // Sets up module to process templates.
    ngHtml2JsPreprocessor: {
      prependPrefix: '/static/',
      moduleName: 'templates'
    },

    // Assumes you're in the top-level horizon directory.
    basePath: './static/',

    // Contains both source and test files.
    files: [
      /*
       * shim, partly stolen from /i18n/js/horizon/
       * Contains expected items not provided elsewhere (dynamically by
       * Django or via jasmine template.
       */
      '../../test-shim.js',

      // from jasmine.html
      xstaticPath + 'jquery/data/jquery.js',
      xstaticPath + 'angular/data/angular.js',
      xstaticPath + 'angular/data/angular-mocks.js',
      xstaticPath + 'angular/data/angular-cookies.js',
      xstaticPath + 'angular_bootstrap/data/angular-bootstrap.js',
      xstaticPath + 'angular_gettext/data/angular-gettext.js',
      xstaticPath + 'angular/data/angular-sanitize.js',
      xstaticPath + 'd3/data/d3.js',
      xstaticPath + 'rickshaw/data/rickshaw.js',
      xstaticPath + 'angular_smart_table/data/smart-table.js',
      xstaticPath + 'angular_lrdragndrop/data/lrdragndrop.js',
      xstaticPath + 'spin/data/spin.js',
      xstaticPath + 'spin/data/spin.jquery.js',

      // TODO: These should be mocked.
      '../../horizon/static/horizon/js/horizon.js',

      /**
       * Include framework source code from horizon that we need.
       * Otherwise, karma will not be able to find them when testing.
       * These files should be mocked in the foreseeable future.
       */
      '../../horizon/static/framework/**/*.module.js',
      '../../horizon/static/framework/**/!(*.spec|*.mock).js',

      /**
       * First, list all the files that defines application's angular modules.
       * Those files have extension of `.module.js`. The order among them is
       * not significant.
       */
      '**/*.module.js',
      '../dashboards/**/static/**/*.module.js',

      /**
       * Followed by other JavaScript files that defines angular providers
       * on the modules defined in files listed above. And they are not mock
       * files or spec files defined below. The order among them is not
       * significant.
       */
      '**/!(*.spec|*.mock).js',
      '../dashboards/**/static/**/!(*.spec|*.mock).js',

      /**
       * Then, list files for mocks with `mock.js` extension. The order
       * among them should not be significant.
       */
      '**/*.mock.js',
      '../dashboards/**/static/**/*.mock.js',

      /**
       * Finally, list files for spec with `spec.js` extension. The order
       * among them should not be significant.
       */
      '**/*.spec.js',
      '../dashboards/**/static/**/*.spec.js',

      /**
       * Angular external templates
       */
      '**/*.html',
      '../dashboards/**/static/**/*.html'
    ],

    autoWatch: true,

    frameworks: ['jasmine'],

    browsers: ['PhantomJS'],

    phantomjsLauncher: {
      // Have phantomjs exit if a ResourceError is encountered
      // (useful if karma exits without killing phantom)
      exitOnResourceError: true
    },

    reporters: ['progress', 'coverage', 'threshold'],

    plugins: [
      'karma-phantomjs-launcher',
      'karma-jasmine',
      'karma-ng-html2js-preprocessor',
      'karma-coverage',
      'karma-threshold-reporter'
    ],

    coverageReporter: {
      type: 'html',
      dir: '../.coverage-karma/'
    },

    // Coverage threshold values.
    thresholdReporter: {
      statements: 93, // target 100
      branches: 93, // target 100
      functions: 93, // target 100
      lines: 93 // target 100
    }
  });
};
<commit_msg>Include JS from openstack_dashboard/**/static for code coverage<commit_after>/*
 *    (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

var fs = require('fs');
var path = require('path');

module.exports = function (config) {
  var xstaticPath;
  var basePaths = [
    './.venv',
    './.tox/py27'
  ];

  for (var i = 0; i < basePaths.length; i++) {
    var basePath = path.resolve(basePaths[i]);

    if (fs.existsSync(basePath)) {
      xstaticPath = basePath + '/lib/python2.7/site-packages/xstatic/pkg/';
      break;
    }
  }

  if (!xstaticPath) {
    console.error('xStatic libraries not found, please set up venv');
    process.exit(1);
  }

  config.set({
    preprocessors: {
      // Used to collect templates for preprocessing.
      // NOTE: the templates must also be listed in the files section below.
      './**/*.html': ['ng-html2js'],
      // Used to indicate files requiring coverage reports.
      '../static/**/!(*.spec).js': ['coverage'],
      '../dashboards/**/static/**/!(*.spec).js': ['coverage']
    },

    // Sets up module to process templates.
    ngHtml2JsPreprocessor: {
      prependPrefix: '/static/',
      moduleName: 'templates'
    },

    // Assumes you're in the top-level horizon directory.
    basePath: './static/',

    // Contains both source and test files.
    files: [
      /*
       * shim, partly stolen from /i18n/js/horizon/
       * Contains expected items not provided elsewhere (dynamically by
       * Django or via jasmine template.
       */
      '../../test-shim.js',

      // from jasmine.html
      xstaticPath + 'jquery/data/jquery.js',
      xstaticPath + 'angular/data/angular.js',
      xstaticPath + 'angular/data/angular-mocks.js',
      xstaticPath + 'angular/data/angular-cookies.js',
      xstaticPath + 'angular_bootstrap/data/angular-bootstrap.js',
      xstaticPath + 'angular_gettext/data/angular-gettext.js',
      xstaticPath + 'angular/data/angular-sanitize.js',
      xstaticPath + 'd3/data/d3.js',
      xstaticPath + 'rickshaw/data/rickshaw.js',
      xstaticPath + 'angular_smart_table/data/smart-table.js',
      xstaticPath + 'angular_lrdragndrop/data/lrdragndrop.js',
      xstaticPath + 'spin/data/spin.js',
      xstaticPath + 'spin/data/spin.jquery.js',

      // TODO: These should be mocked.
      '../../horizon/static/horizon/js/horizon.js',

      /**
       * Include framework source code from horizon that we need.
       * Otherwise, karma will not be able to find them when testing.
       * These files should be mocked in the foreseeable future.
       */
      '../../horizon/static/framework/**/*.module.js',
      '../../horizon/static/framework/**/!(*.spec|*.mock).js',

      /**
       * First, list all the files that defines application's angular modules.
       * Those files have extension of `.module.js`. The order among them is
       * not significant.
       */
      '**/*.module.js',
      '../dashboards/**/static/**/*.module.js',

      /**
       * Followed by other JavaScript files that defines angular providers
       * on the modules defined in files listed above. And they are not mock
       * files or spec files defined below. The order among them is not
       * significant.
       */
      '**/!(*.spec|*.mock).js',
      '../dashboards/**/static/**/!(*.spec|*.mock).js',

      /**
       * Then, list files for mocks with `mock.js` extension. The order
       * among them should not be significant.
       */
      '**/*.mock.js',
      '../dashboards/**/static/**/*.mock.js',

      /**
       * Finally, list files for spec with `spec.js` extension. The order
       * among them should not be significant.
       */
      '**/*.spec.js',
      '../dashboards/**/static/**/*.spec.js',

      /**
       * Angular external templates
       */
      '**/*.html',
      '../dashboards/**/static/**/*.html'
    ],

    autoWatch: true,

    frameworks: ['jasmine'],

    browsers: ['PhantomJS'],

    phantomjsLauncher: {
      // Have phantomjs exit if a ResourceError is encountered
      // (useful if karma exits without killing phantom)
      exitOnResourceError: true
    },

    reporters: ['progress', 'coverage', 'threshold'],

    plugins: [
      'karma-phantomjs-launcher',
      'karma-jasmine',
      'karma-ng-html2js-preprocessor',
      'karma-coverage',
      'karma-threshold-reporter'
    ],

    coverageReporter: {
      type: 'html',
      dir: '../.coverage-karma/'
    },

    // Coverage threshold values.
    thresholdReporter: {
      statements: 89, // target 100
      branches: 82, // target 100
      functions: 88, // target 100
      lines: 89 // target 100
    }
  });
};
<|endoftext|>


<commit_before>(function (angular) {
  'use strict';
  angular.module('BotPicker', [])
    .directive("bootpicker", ['$filter', function ($filter) {

      Array.prototype.groupBy = function (prop) {
        return this.reduce(function (groups, item) {
          var val = item[prop];
          groups[val] = groups[val] || [];
          groups[val].push(item);
          return groups;
        }, {});
      };

      return {
        require: 'ngModel',
        restrict: "AE",
        scope: {
          locale: '@',
          options: '='
        },
        link: function (scope, elem, attrs, ngModel) {

          scope.startDate = getFormatDate(new Date(), attrs.format);
          scope.endDate = getFormatDate(new Date(), attrs.format);

          scope.dateMap = {};
          //attr format that it was arrived form directive
          var date = new Date();//$filter('date')(new Date(), 'dd/MM/yyyy');

          var changeDate = function (date) {
            var month = getFormatDate(date, 'MMMM');
            var year = getFormatDate(date, 'yyyy');

            scope.dateMap = { month: month, year: year, result: setRangeDay(date) };

            var createGroupedArray = function (arr, chunkSize) {
              var groups = [];
              for (var index = 0; index < arr.length; index += chunkSize) {
                groups.push(arr.slice(index, index + chunkSize));
              }
              return groups;
            };

            scope.dateMap.result = createGroupedArray(scope.dateMap.result, 7);

            function setRangeDay(date) {
              var days = [];
              var start = new Date(date.getFullYear(), date.getMonth(), 1);
              var end = new Date(date.getFullYear(), date.getMonth() + 1, 0);

              for (var index = start.getDate(); index <= end.getDate(); index++) {
                start.setDate(index);
                days.push({ day: index, week: getFormatDate(start, 'EEEE') });
              }

              return days;
            }
          };

          changeDate(date);

          scope.nextMonth = function () {
            if (date.getMonth() == 11) {
              date = new Date(date.getFullYear() + 1, 0, 1);
            } else {
              date = new Date(date.getFullYear(), date.getMonth() + 1, 1);
            }
            changeDate(date);
          };

          scope.lastMonth = function () {
            if (date.getMonth() === 0) {
              date = new Date(date.getFullYear() - 1, 11, 1);
            } else {
              date = new Date(date.getFullYear(), date.getMonth() - 1, 1);
            }
            changeDate(date);
          };

          function getFormatDate(date, format) {
            return $filter('date')(date, format);
          }

          var between = [];
          between.push(getFormatDate(new Date(), attrs.format));
          ngModel.$setViewValue(between);

          angular.element(elem).on('change', function (event) {
            between = [];
            SetRangeDate();
          });

          scope.selectTrimester = function () {
            var today = new Date();
            today.setMonth(today.getMonth() - 3);
            scope.startDate = getFormatDate(today, attrs.format);
            scope.endDate = getFormatDate(new Date(), attrs.format);
            between = [];
            SetRangeDate();
          };

          scope.selectSemester = function () {
            var today = new Date();
            today.setMonth(today.getMonth() - 6);
            scope.startDate = getFormatDate(today, attrs.format);
            scope.endDate = getFormatDate(new Date(), attrs.format);
            between = [];
            SetRangeDate();
          };

          scope.selectYear = function () {
            var today = new Date();
            today.setMonth(today.getMonth() - 12);
            scope.startDate = getFormatDate(today, attrs.format);
            scope.endDate = getFormatDate(new Date(), attrs.format);
            between = [];
            SetRangeDate();
          };

          scope.selectMonth = function () {
            var today = new Date();
            today.setMonth(today.getMonth() - 1);
            scope.startDate = getFormatDate(today, attrs.format);;
            scope.endDate = getFormatDate(new Date(), attrs.format);
            between = [];
            SetRangeDate();
          };

          scope.selectYear = function () {
            var today = new Date();
            today.setMonth(today.getMonth() - 12)
            scope.startDate = getFormatDate(today, attrs.format);;
            scope.endDate = getFormatDate(new Date(), attrs.format);
            between = [];
            SetRangeDate();
          };

          scope.selectMonth = function () {
            var today = new Date();
            today.setMonth(today.getMonth() - 1);
            scope.startDate = getFormatDate(today, attrs.format);
            scope.endDate = getFormatDate(new Date(), attrs.format);
            between = [];
            SetRangeDate();
          };

          scope.selectToday = function () {
            scope.startDate = getFormatDate(new Date(), attrs.format);
            scope.endDate = getFormatDate(new Date(), attrs.format);
            between = [];
            SetRangeDate();
          };

          scope.selectWeek = function () {
            var today = new Date();
            today.setDate(today.getDate() - 7)
            scope.startDate = getFormatDate(today, attrs.format);
            scope.endDate = getFormatDate(new Date(), attrs.format);
            between = [];
            SetRangeDate();
          };

          scope.selectLastDay = function () {
            var today = new Date();
            today.setDate(today.getDate() - 1);
            scope.startDate = getFormatDate(today, attrs.format);
            scope.endDate = getFormatDate(today, attrs.format);
            between = [];
            SetRangeDate();
          };

          function SetRangeDate() {
            var start = scope.startDate;
            var end = scope.endDate.split("/");
            end = new Date(end[2], end[1] - 1, end[0]);
            var from = start.split("/");
            var currentDate = new Date(from[2], from[1] - 1, from[0]);
            while (currentDate <= end) {
              var dt = getFormatDate(currentDate, attrs.format);
              between.push(dt);
              currentDate.setDate(currentDate.getDate() + 1);
            }
            ngModel.$setViewValue(between);
            ngModel.$render();
            console.log('quantity ', between.length);
          }
        },
        templateUrl: '/timePicker.html'
      };
    }]);
})(angular);
<commit_msg>Remove groupby function<commit_after>(function (angular) {
  'use strict';
  angular.module('BotPicker', [])
    .directive("bootpicker", ['$filter', function ($filter) {
      return {
        require: 'ngModel',
        restrict: "AE",
        scope: {
          locale: '@',
          options: '='
        },
        link: function (scope, elem, attrs, ngModel) {

          scope.startDate = getFormatDate(new Date(), attrs.format);
          scope.endDate = getFormatDate(new Date(), attrs.format);

          scope.dateMap = {};
          //attr format that it was arrived form directive
          var date = new Date();//$filter('date')(new Date(), 'dd/MM/yyyy');

          var changeDate = function (date) {
            var month = getFormatDate(date, 'MMMM');
            var year = getFormatDate(date, 'yyyy');

            scope.dateMap = { month: month, year: year, result: setRangeDay(date) };

            var createGroupedArray = function (arr, chunkSize) {
              var groups = [];
              for (var index = 0; index < arr.length; index += chunkSize) {
                groups.push(arr.slice(index, index + chunkSize));
              }
              return groups;
            };

            scope.dateMap.result = createGroupedArray(scope.dateMap.result, 7);

            function setRangeDay(date) {
              var days = [];
              var start = new Date(date.getFullYear(), date.getMonth(), 1);
              var end = new Date(date.getFullYear(), date.getMonth() + 1, 0);

              for (var index = start.getDate(); index <= end.getDate(); index++) {
                start.setDate(index);
                days.push({ day: index, week: getFormatDate(start, 'EEEE') });
              }

              return days;
            }
          };

          changeDate(date);

          scope.nextMonth = function () {
            if (date.getMonth() == 11) {
              date = new Date(date.getFullYear() + 1, 0, 1);
            } else {
              date = new Date(date.getFullYear(), date.getMonth() + 1, 1);
            }
            changeDate(date);
          };

          scope.lastMonth = function () {
            if (date.getMonth() === 0) {
              date = new Date(date.getFullYear() - 1, 11, 1);
            } else {
              date = new Date(date.getFullYear(), date.getMonth() - 1, 1);
            }
            changeDate(date);
          };

          function getFormatDate(date, format) {
            return $filter('date')(date, format);
          }

          var between = [];
          between.push(getFormatDate(new Date(), attrs.format));
          ngModel.$setViewValue(between);

          angular.element(elem).on('change', function (event) {
            between = [];
            SetRangeDate();
          });

          scope.selectTrimester = function () {
            var today = new Date();
            today.setMonth(today.getMonth() - 3);
            scope.startDate = getFormatDate(today, attrs.format);
            scope.endDate = getFormatDate(new Date(), attrs.format);
            between = [];
            SetRangeDate();
          };

          scope.selectSemester = function () {
            var today = new Date();
            today.setMonth(today.getMonth() - 6);
            scope.startDate = getFormatDate(today, attrs.format);
            scope.endDate = getFormatDate(new Date(), attrs.format);
            between = [];
            SetRangeDate();
          };

          scope.selectYear = function () {
            var today = new Date();
            today.setMonth(today.getMonth() - 12);
            scope.startDate = getFormatDate(today, attrs.format);
            scope.endDate = getFormatDate(new Date(), attrs.format);
            between = [];
            SetRangeDate();
          };

          scope.selectMonth = function () {
            var today = new Date();
            today.setMonth(today.getMonth() - 1);
            scope.startDate = getFormatDate(today, attrs.format);;
            scope.endDate = getFormatDate(new Date(), attrs.format);
            between = [];
            SetRangeDate();
          };

          scope.selectYear = function () {
            var today = new Date();
            today.setMonth(today.getMonth() - 12)
            scope.startDate = getFormatDate(today, attrs.format);;
            scope.endDate = getFormatDate(new Date(), attrs.format);
            between = [];
            SetRangeDate();
          };

          scope.selectMonth = function () {
            var today = new Date();
            today.setMonth(today.getMonth() - 1);
            scope.startDate = getFormatDate(today, attrs.format);
            scope.endDate = getFormatDate(new Date(), attrs.format);
            between = [];
            SetRangeDate();
          };

          scope.selectToday = function () {
            scope.startDate = getFormatDate(new Date(), attrs.format);
            scope.endDate = getFormatDate(new Date(), attrs.format);
            between = [];
            SetRangeDate();
          };

          scope.selectWeek = function () {
            var today = new Date();
            today.setDate(today.getDate() - 7)
            scope.startDate = getFormatDate(today, attrs.format);
            scope.endDate = getFormatDate(new Date(), attrs.format);
            between = [];
            SetRangeDate();
          };

          scope.selectLastDay = function () {
            var today = new Date();
            today.setDate(today.getDate() - 1);
            scope.startDate = getFormatDate(today, attrs.format);
            scope.endDate = getFormatDate(today, attrs.format);
            between = [];
            SetRangeDate();
          };

          function SetRangeDate() {
            var start = scope.startDate;
            var end = scope.endDate.split("/");
            end = new Date(end[2], end[1] - 1, end[0]);
            var from = start.split("/");
            var currentDate = new Date(from[2], from[1] - 1, from[0]);
            while (currentDate <= end) {
              var dt = getFormatDate(currentDate, attrs.format);
              between.push(dt);
              currentDate.setDate(currentDate.getDate() + 1);
            }
            ngModel.$setViewValue(between);
            ngModel.$render();
            console.log('quantity ', between.length);
          }
        },
        templateUrl: '/timePicker.html'
      };
    }]);
})(angular);
<|endoftext|>


<commit_before>import React,{ Component } from 'react'
import { connect } from 'dva'
import CSSModules from 'react-css-modules'
import styles from './page.less'
import { Link } from 'react-router'
import classNames from 'classnames'
import { getCookie, setCookie, priceFormat } from 'libs/util'
import { fetchPosts } from "components/common/fetch"

import ProjectItem from "./ProjectItem.js"
import News from "./news";

class Home extends Component {
  levelOption = {"暂无":0,"C":25,"B":50,"A":75,"PRO":100,"":0}

  constructor(props) {
    super(props)
    fetchPosts("/api/user/userId",{},"GET")
      .then(data => {
        props.getLevel()
        props.getUserInfo()
        props.getProjList()
      })

    this.state = {
      isShowCover: !getCookie("isShowCover","storage"),
      isGaugeRendered: false,
    }
  }

  showCoverHandler = (e) => {
    if (e) e.stopPropagation();
    this.setState({
      isShowCover: true
    });
  }

  hideCoverHandler = () => {
    setCookie("isShowCover","1","storage")
    this.setState({
      isShowCover: false
    });
  }

  componentDidMount() {

  }

  componentDidUpdate() {
    if( !!this.props.userInfo.level && !this.state.isGaugeRendered) {
      this.renderGauge(this.levelOption[this.props.userInfo.level.toUpperCase()])
      // this.renderGauge(this.levelOption[this.props.userInfo.level]);
      this.setState({
        isGaugeRendered: true
      });
    }
  }

  render() {
    let projItems = this.props.projList.length>0 ? this.props.projList.map((item,index) => <ProjectItem projInfo={item} key={index} />) : ""
    return (

            <canvas id="dash" styleName="dash" width='240' height='210'></canvas>

QBII

认证等级

              {this.props.userInfo.level}

等级越高，可投项目越多

              QBFK.Business.go('/Theme')}>晒身份
              QBFK.Business.go('/About')}>了解QBII

QBFK.Business.go('/OrderList')} styleName="item">
            投入资产(元)

{priceFormat(this.props.userInfo.assets/100)||0.00}

QBFK.Business.go('/ProfitList')} styleName="item">
            累计收益(元)

{priceFormat(this.props.userInfo.profit/100)||0.00}

          {projItems}

最新资讯

              {/* 查看更多
               */}

          <News/>

          更多项目，敬请期待

钱宝 5.0
开启你的资本之路

当前认证等级

{this.props.levelInfo.level}

          即刻加入

    )
  }

  renderGauge(displayValue) {
  	var angle = 0.14, innerAngle = angle;
  	var displayAngle = getAngle(displayValue), innerDisplayAngle = displayAngle;
  	var radius = 100, innerRadius = radius - 8, iconRadius = radius - 16;
  	var canvas = document.getElementById("dash");
  	var ctx = canvas.getContext("2d");
  	var w = 240 / 2;
    var h = 210 / 2;

  	ctx.strokeStyle = "rgba(173, 141, 114, 0.3)";
    ctx.beginPath();
    ctx.arc(w, h, radius, (1 - angle) * Math.PI, (2 + angle) * Math.PI, false);
    ctx.lineWidth = 1;
    ctx.lineCap = "round";
    ctx.stroke();

  	ctx.beginPath();
  	ctx.arc(w, h, innerRadius, (1 - angle) * Math.PI, (2 + angle) * Math.PI, false);
    ctx.setLineDash([1,4])
    ctx.stroke();
    ctx.restore();

  	ctx.strokeStyle = "#ae8e72";
    ctx.beginPath();
  	ctx.setLineDash([]);
    ctx.arc(w, h, radius, (1 - angle) * Math.PI, displayAngle, false);
    ctx.stroke();

  	ctx.beginPath();
  	ctx.setLineDash([1,3]);
    ctx.arc(w, h, innerRadius, (1 - innerAngle) * Math.PI, innerDisplayAngle, false);
    ctx.stroke();

  	ctx.strokeStyle = "#F6E284";
    ctx.beginPath();
  	ctx.lineWidth = 4;
  	ctx.setLineDash([2,1000]);
    ctx.arc(w, h, radius,  displayAngle,(2 + angle) * Math.PI, false);
  	ctx.shadowColor = '#fff';
  	ctx.shadowOffsetX = ctx.shadowOffsetY = 0;
  	ctx.shadowBlur = 5;
    ctx.stroke();

  	var startX, startY, x, y, length = 88;
  	var img = document.createElement("img");
  	img.src = require("static/imgs/home/pointer.png");
  	img.addEventListener("load",function(){
  		startX = Math.round(w + 5 * Math.cos(displayAngle - Math.PI / 2))
  		startY = Math.round(h + 7.25 * Math.sin(displayAngle - Math.PI / 2));
  			ctx.save();
  			ctx.shadowBlur = 0;
  			ctx.translate(startX,startY);
  			ctx.rotate(displayAngle + Math.PI / 2);
  			ctx.drawImage(img, 0, -length, 10, 14.5);
  			ctx.restore();
        canvas.style.zIndex="2";
    },false);

  	function getAngle(value) {
  		var min=2.72,max=6.65;
  		return (max - min) / 100 * value + min;
  	}
  }

};

/*

QBFK.Business.go('/NewsDetail/4')}>

              QBII钱宝5.0全国巡回落幕
              一路相伴，一路前行

QBFK.Business.go('/NewsDetail/1')}>

              全新身份QBII
              钱宝5.0时代身具跨时代新标识

QBFK.Business.go('/NewsDetail/3')}>

              QBII的深刻解读
              让商业回归本质，守住初心

           */
function mapStateToProps(state) {
    return state.home;
}

function mapDispatchToProps(dispatch) {
    return {
      getLevel(levelInfo){
          dispatch({type: 'home/getLevel', levelInfo});
      },
      getUserInfo(userInfo){
          dispatch({type: 'home/getUserInfo', userInfo});
      },
      getProjList(projList){
          dispatch({type: 'home/getProjList', projList});
      },
      getProgressInfo(progressInfo){
          dispatch({type: 'home/getProgressInfo', progressInfo});
      }
    }
}
Home.PropTypes = {
    enterAnimation: {
        duration: 2000,
        animation: "slideDown"
    },
    leaveAnimation:{
        duration: 2000,
        animation:"slideUp"
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(CSSModules(Home,styles,{allowMultiple:true}));
<commit_msg>首页新增无列表  不点击<commit_after>import React,{ Component } from 'react'
import { connect } from 'dva'
import CSSModules from 'react-css-modules'
import styles from './page.less'
import { Link } from 'react-router'
import classNames from 'classnames'
import { getCookie, setCookie, priceFormat } from 'libs/util'
import { fetchPosts } from "components/common/fetch"

import ProjectItem from "./ProjectItem.js"
import News from "./news";

import isArray from "lodash/isArray";

class Home extends Component {
  levelOption = {"暂无":0,"C":25,"B":50,"A":75,"PRO":100,"":0}

  constructor(props) {
    super(props)
    fetchPosts("/api/user/userId",{},"GET")
      .then(data => {
        props.getLevel()
        props.getUserInfo()
        props.getProjList()
      })

    this.state = {
      isShowCover: !getCookie("isShowCover","storage"),
      isGaugeRendered: false,
    }
  }

  showCoverHandler = (e) => {
    if (e) e.stopPropagation();
    this.setState({
      isShowCover: true
    });
  }

  hideCoverHandler = () => {
    setCookie("isShowCover","1","storage")
    this.setState({
      isShowCover: false
    });
  }

  componentDidMount() {

  }

  componentDidUpdate() {
    if( !!this.props.userInfo.level && !this.state.isGaugeRendered) {
      this.renderGauge(this.levelOption[this.props.userInfo.level.toUpperCase()])
      // this.renderGauge(this.levelOption[this.props.userInfo.level]);
      this.setState({
        isGaugeRendered: true
      });
    }
  }

  render() {
    let projItems = this.props.projList.length>0 ? this.props.projList.map((item,index) => <ProjectItem projInfo={item} key={index} />) : ""
    return (

            <canvas id="dash" styleName="dash" width='240' height='210'></canvas>

QBII

认证等级

              {this.props.userInfo.level}

等级越高，可投项目越多

              QBFK.Business.go('/Theme')}>晒身份
              QBFK.Business.go('/About')}>了解QBII

{
              isArray(this.props.projList)&&this.props.projList.length!==0&&QBFK.Business.go('/OrderList')
            }} styleName="item">
            投入资产(元)

{priceFormat(this.props.userInfo.assets/100)||0.00}

isArray(this.props.projList)&&this.props.projList.length!==0&&QBFK.Business.go('/ProfitList')} styleName="item">
            累计收益(元)

{priceFormat(this.props.userInfo.profit/100)||0.00}

          {projItems}

最新资讯

              {/* 查看更多
               */}

          <News/>

          更多项目，敬请期待

钱宝 5.0
开启你的资本之路

当前认证等级

{this.props.levelInfo.level}

          即刻加入

    )
  }

  renderGauge(displayValue) {
  	var angle = 0.14, innerAngle = angle;
  	var displayAngle = getAngle(displayValue), innerDisplayAngle = displayAngle;
  	var radius = 100, innerRadius = radius - 8, iconRadius = radius - 16;
  	var canvas = document.getElementById("dash");
  	var ctx = canvas.getContext("2d");
  	var w = 240 / 2;
    var h = 210 / 2;

  	ctx.strokeStyle = "rgba(173, 141, 114, 0.3)";
    ctx.beginPath();
    ctx.arc(w, h, radius, (1 - angle) * Math.PI, (2 + angle) * Math.PI, false);
    ctx.lineWidth = 1;
    ctx.lineCap = "round";
    ctx.stroke();

  	ctx.beginPath();
  	ctx.arc(w, h, innerRadius, (1 - angle) * Math.PI, (2 + angle) * Math.PI, false);
    ctx.setLineDash([1,4])
    ctx.stroke();
    ctx.restore();

  	ctx.strokeStyle = "#ae8e72";
    ctx.beginPath();
  	ctx.setLineDash([]);
    ctx.arc(w, h, radius, (1 - angle) * Math.PI, displayAngle, false);
    ctx.stroke();

  	ctx.beginPath();
  	ctx.setLineDash([1,3]);
    ctx.arc(w, h, innerRadius, (1 - innerAngle) * Math.PI, innerDisplayAngle, false);
    ctx.stroke();

  	ctx.strokeStyle = "#F6E284";
    ctx.beginPath();
  	ctx.lineWidth = 4;
  	ctx.setLineDash([2,1000]);
    ctx.arc(w, h, radius,  displayAngle,(2 + angle) * Math.PI, false);
  	ctx.shadowColor = '#fff';
  	ctx.shadowOffsetX = ctx.shadowOffsetY = 0;
  	ctx.shadowBlur = 5;
    ctx.stroke();

  	var startX, startY, x, y, length = 88;
  	var img = document.createElement("img");
  	img.src = require("static/imgs/home/pointer.png");
  	img.addEventListener("load",function(){
  		startX = Math.round(w + 5 * Math.cos(displayAngle - Math.PI / 2))
  		startY = Math.round(h + 7.25 * Math.sin(displayAngle - Math.PI / 2));
  			ctx.save();
  			ctx.shadowBlur = 0;
  			ctx.translate(startX,startY);
  			ctx.rotate(displayAngle + Math.PI / 2);
  			ctx.drawImage(img, 0, -length, 10, 14.5);
  			ctx.restore();
        canvas.style.zIndex="2";
    },false);

  	function getAngle(value) {
  		var min=2.72,max=6.65;
  		return (max - min) / 100 * value + min;
  	}
  }

};

/*

QBFK.Business.go('/NewsDetail/4')}>

              QBII钱宝5.0全国巡回落幕
              一路相伴，一路前行

QBFK.Business.go('/NewsDetail/1')}>

              全新身份QBII
              钱宝5.0时代身具跨时代新标识

QBFK.Business.go('/NewsDetail/3')}>

              QBII的深刻解读
              让商业回归本质，守住初心

           */
function mapStateToProps(state) {
    return state.home;
}

function mapDispatchToProps(dispatch) {
    return {
      getLevel(levelInfo){
          dispatch({type: 'home/getLevel', levelInfo});
      },
      getUserInfo(userInfo){
          dispatch({type: 'home/getUserInfo', userInfo});
      },
      getProjList(projList){
          dispatch({type: 'home/getProjList', projList});
      },
      getProgressInfo(progressInfo){
          dispatch({type: 'home/getProgressInfo', progressInfo});
      }
    }
}
Home.PropTypes = {
    enterAnimation: {
        duration: 2000,
        animation: "slideDown"
    },
    leaveAnimation:{
        duration: 2000,
        animation:"slideUp"
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(CSSModules(Home,styles,{allowMultiple:true}));
<|endoftext|>


<commit_before>var Gaffa = require('gaffa'),
    actionType = "browserStorage";

function BrowserStorage(actionDefinition){
}
BrowserStorage = Gaffa.createSpec(BrowserStorage, Gaffa.Action);
BrowserStorage.prototype.type = actionType;
BrowserStorage.prototype.trigger = function(parent, scope, event){

    var action = this,
        data = action.source.value;

    switch(action.method.value){
        case "get":
            data = window[action.storageType.value + 'Storage'].getItem(action.source.value);
            if(data === 'undefined'){
                data = undefined;
            }
            action.target.set(data ? JSON.parse(data) : undefined);
            break;

        case "set":
            window[action.storageType.value + 'Storage'].setItem(action.target.value, JSON.stringify(data));
            break;
    }

};
BrowserStorage.prototype.storageType = new Gaffa.Property({
    value: 'local'
});
BrowserStorage.prototype.method = new Gaffa.Property({
    value: 'get'
});
BrowserStorage.prototype.target = new Gaffa.Property();
BrowserStorage.prototype.source = new Gaffa.Property();

module.exports = BrowserStorage;
<commit_msg>added remove method<commit_after>var Gaffa = require('gaffa'),
    actionType = "browserStorage";

function BrowserStorage(actionDefinition){
}
BrowserStorage = Gaffa.createSpec(BrowserStorage, Gaffa.Action);
BrowserStorage.prototype.type = actionType;
BrowserStorage.prototype.trigger = function(parent, scope, event){

    var action = this,
        data = action.source.value;

    if(!action.method.value){
        console.warn('You should set the value of method.');
        return;
    }

    switch(action.method.value.toLowerCase()){
        case "get":
            data = window[action.storageType.value + 'Storage'].getItem(action.source.value);
            if(data === 'undefined'){
                data = undefined;
            }
            action.target.set(data ? JSON.parse(data) : undefined);
            break;

        case "set":
            window[action.storageType.value + 'Storage'].setItem(action.target.value, JSON.stringify(data));
            break;

        case "remove":
            window[action.storageType.value + 'Storage'].removeItem(action.target.value);
            break;
    }

};
BrowserStorage.prototype.storageType = new Gaffa.Property({
    value: 'local'
});
BrowserStorage.prototype.method = new Gaffa.Property({
    value: 'get'
});
BrowserStorage.prototype.target = new Gaffa.Property();
BrowserStorage.prototype.source = new Gaffa.Property();

module.exports = BrowserStorage;
<|endoftext|>


<commit_before>var mapApp = angular.module('mapApp', ["angular-lodash","ngAnimate"]);

mapApp.constant('ICONS', {
  RED: 'http://maps.google.com/mapfiles/ms/micons/red-dot.png',
  GREEN: 'http://maps.google.com/mapfiles/ms/micons/green-dot.png',
  BLUE: 'http://maps.google.com/mapfiles/ms/micons/blue-dot.png',
});

mapApp.controller('EventListCtrl', function($scope, $http, $interval, urls, mapSettings) {
  $scope.$location = window.location
  $scope.selectedEventsupport = {}
  $scope.selectedEventsupported = {}
  $scope.initGoogleMap = function(rootElement) {

    var fullBounds = new google.maps.LatLngBounds();
    var params = {status: 'A'};
    $http.get(urls.events, {params: params}).success(function(data) {
      for (i in data.objects) {
        var event = data.objects[i];
        if (event.latest_location != null) {
          var point = new google.maps.LatLng(
            event.latest_location.latitude,
            event.latest_location.longitude
          );
          fullBounds.extend(point)
        }
      };
    });

    var mapOptions = {
      zoom: 10,
      center: new google.maps.LatLng(50.444, 390.56),
      zoomControl: true,
      zoomControlOptions: {position: google.maps.ControlPosition.RIGHT_CENTER},
      panControl: true,
      panControlOptions: {position: google.maps.ControlPosition.RIGHT_TOP},
    };
    $scope.gmap = new google.maps.Map(rootElement, mapOptions);
    $scope.gwindow = new google.maps.InfoWindow({content: "Sup"});
    $scope.gwindow_opened = false;
  };
  $scope.zoomIn = function() {
    if ($scope.zoomedIn == false) {
      $scope.gmap.setZoom($scope.gmap.getZoom() + $scope.zoomScale);
      $scope.zoomedIn = true;
    }
  };
  $scope.zoomOut = function() {
    if ($scope.zoomedIn == true) {
      $scope.gmap.setZoom($scope.gmap.getZoom() - $scope.zoomScale);
      $scope.zoomedIn = false;
    }
  };
  $scope.select = function(event) {
    if (event == null) {
      $scope.zoomOut();
      $scope.selectedEvent = null;
      $scope.selectedEventsupport = {};
      $scope.selectedEventsupported = {};
      window.location.hash = '';
    } else {
      var params = {event__id: event.id};
      $http.get(urls.eventupdates, {params: params}).success(function(data) {
        event.updates = data.objects;
        $scope.focus(event.latest_location);
        $scope.zoomIn();
        $scope.selectedEvent = event;
        window.location.hash = event.id;
        $scope.selectedEvent.isNew = false;
      });

      var supportEvents = _.filter($scope.events, {"type": "support"});
      _.forEach(supportEvents,function (support) {
        if (_.any(support.supported,{"id":event.id})){
          $scope.selectedEventsupport[support.id] = support;
        }
        });
      _.forEach(event.supported, function(supported){
        $scope.selectedEventsupported[supported.id] = $scope.events[supported.id];
      });

    };
  };
  $scope.update = function(options, callback) {
    var params = {status: 'A'};
    $http.get(urls.events, {params: params}).success(function(data) {
      var eventsAppeared = false, newEvents = {};
      for (i in data.objects) {
        var event = data.objects[i];
        newEvents[event.id] = event;
      }
      // Deleting old events
      for (oldEventId in $scope.events) {
        if (newEvents[oldEventId] == null) {
          delete $scope.events[oldEventId];
        }
      }
      // Adding new events
      for (newEventId in newEvents) {
        if ($scope.events[newEventId] == null) {
          var new_event =  newEvents[newEventId]
            if (options.highightNew){
              new_event.isNew = true
            } else {
              new_event.isNew = false
            }
          $scope.events[newEventId] = new_event;
          eventsAppeared = true;
        }
      }
      if ($scope.$location.hash!=""){
          var id = parseFloat($scope.$location.hash.split('#')[1])
          $scope.select( $scope.events[id])
        }
      if (eventsAppeared && options.playSoundForNew)
        document.getElementById('audiotag').play();
      // Making map show all events
      if (options.centerMap) {
        var eventsBounds = new google.maps.LatLngBounds();
        for (eventId in $scope.events) {
          var event = $scope.events[eventId];
          eventsBounds.extend(new google.maps.LatLng(
            event.latest_location.latitude,
            event.latest_location.longitude
          ));
        }
        $scope.gmap.fitBounds(eventsBounds);
      }
      if (eventsAppeared){
          $scope.updateUserAttrs(newEvents);
      }

      if ('function' === typeof callback) callback();
    });
  };

  $scope.updateUserAttrs = function(events){
    _.forEach(events, function(event){
      //clojure for ajax callback
      var clojr = function(pevent,field){
        return function(data){
          pevent.user[field] = data;
        }
      }

      $http.get(urls.user_roles,
        {params:{id:event.user.id}}).success(clojr(event,'roles'))
      $http.get(urls.user_movement_types,
        {params:{id:event.user.id}}).success(clojr(event,'movement_types'))
    });
  }

  $scope.focus = function(location) {
    $scope.gmap.panTo(new google.maps.LatLng(location.latitude,
                                             location.longitude));
  };

  $scope.getRoles = function() {
    //populate list of avail roles for matching
    $scope.filters.roles={};
    $http.get(urls.roles).success(function(data) {
      _.forEach(data.objects, function(role){
        role.enabled = true;
        $scope.filters.roles[role.id] = role;
      });
    });
  }

  $scope.getMovementTypes = function() {
    //populate list of avail movement_types for matching
    $scope.filters.movement_types={};
    $http.get(urls.movement_types).success(function(data) {
      _.forEach(data.objects, function(mt){
        mt.enabled = true;
        $scope.filters.movement_types[mt.id] = mt;
      });
    });
  }
  $scope.setFiltersTo=function(filters,value){
      //set array of user filters to be disabled or enabled, all at once
      _.map(filters,function(el){el.enabled=value});
  }

  $scope.userFilters = function(event) {
      // filter events for attrs event.user.role or event.user.movement_type
      // if user has no attr - do not filter him.
      roles = event.user.roles;
      movement_types = event.user.movement_types;
      //do not filter elements without attrs
      if (_.isEmpty(roles) && _.isEmpty(movement_types)) return true;

      var hasRoles = _.any(roles, function(role_id){
        return $scope.filters.roles[role_id].enabled
      });

      var hasMovementTypes = _.any(movement_types, function(mtype_id){
        return $scope.filters.movement_types[mtype_id].enabled
      });

      return (hasRoles&&hasMovementTypes)
  }

  $scope.addEventUpdate = function() {
    var event = $scope.selectedEvent,
        text = $scope.fields.addEventUpdateText,
        url = urls.addEventUpdate;
    $http.post(url, {"event_id":event.id, "text":text}).success(function(data) {
        var params = {event__id: event.id};
        $http.get(urls.eventupdates, {params: params}).success(function(data) {
            event.updates = data.objects;
        })
    })
    $scope.fields.addEventUpdateText = '';
  };
  $scope.ctrlEnter = function(event) {
    var ctrlPressed = event.metaKey || event.ctrlKey;
    var enterPressed = event.keyCode == 13;
    var text = $scope.fields.addEventUpdateText;
    if (ctrlPressed && enterPressed && text.length) {
      $scope.addEventUpdate(text);
    }
  };
  $scope.closeEvent = function(event) {
    $http.post(urls.closeEvent, {event_id: event.id}).success(function(data) {
      $scope.select(null);
      delete $scope.events[event.id];
    });
  };
  $scope.notifySupporters = function(event) {
    var data = {
      event_id: $scope.selectedEvent.id,
      radius: $scope.fields.notifySupportersRadius
    };
    $scope.isNotifyingSupporters = true;
    $http.post(urls.notifySupporters, data).success(function(data) {
      $scope.isNotifyingSupporters = false;
    })
  };
  $scope.createTestEvent = function() {
    var center = $scope.gmap.getCenter(),
        data = {longitude: center.lng(), latitude: center.lat()};
    $http.post(urls.createTestEvent, data);
  };

  $scope.updatePerSeconds = 5;
  $scope.selectedEvent = null;
  $scope.zoomedIn = false;
  $scope.zoomScale = 1;
  $scope.initGoogleMap(document.getElementById("map-canvas"));
  $scope.events = {};
  $scope.isNotifyingSupporters = false;
  $scope.showFilterPanel = false;
  $scope.fields = {
    addEventUpdateText: '',
    notifySupportersRadius: '',
  };

  $scope.filters = {};
  $scope.getRoles();
  $scope.getMovementTypes();
  $scope.update({playSoundForNew:false, highightNew:false, centerMap:true});

  $interval(function() {
    document.getElementById('audiotag').play();
    alert('Do You sleep?');
  }, mapSettings.wakeup_interval * 60 * 1000);

  $interval(function() {
    $scope.update({playSoundForNew:mapSettings.sound,
      highightNew:mapSettings.highlight,
      centerMap:false});
  }, $scope.updatePerSeconds * 1000);

  $interval(function() {
    $scope.updateUserAttrs($scope.events);
  },30*1000);
})
.factory('markerFactory', function() {
  return function(scope, element, content, icon, location, map, onclick) {
    var markerArgs = {
      icon: icon,
      position: new google.maps.LatLng(location.latitude, location.longitude),
    };

    var marker = new google.maps.Marker(markerArgs);
    marker.setMap(map);
    if (onclick)
      google.maps.event.addListener(marker, 'click', function() {
        scope.$eval(onclick);
      });

    var markersWindow = new google.maps.InfoWindow();

    google.maps.event.addListener(marker, 'mouseover', function() {
      markersWindow.setContent(content);
      markersWindow.open(map, marker);
    });
    google.maps.event.addListener(marker, 'mouseout', function() {
      if (markersWindow != null) markersWindow.close();
    });

    element.on('$destroy', function() {
      marker.setMap(null);
      marker = null;
      if (markersWindow != null) {
        markersWindow.close();
        markersWindow = null;
      }
    });

    return marker;
  };
})
.directive('eventMarker', function(markerFactory, ICONS) {
  var linker = function(scope, element, attrs) {
    var content = element.children().detach()[0];
    var location = scope.event.latest_location;

    if (location) {
      var map = scope.$parent.gmap;
      var icon = (scope.event.type == 'victim') ? ICONS.RED : ICONS.GREEN;
      var marker = markerFactory(scope, element, content, icon, location,
                                 map, attrs.click);

      scope.$watch('event.isNew', function(isNew) {
        var animation = (isNew) ? google.maps.Animation.BOUNCE : null;
        marker.setAnimation(animation);
      });
    }
  };
  return {
    replace: true,
    template: '',
    restrict: 'E',
    link: linker,
  };
})
.directive('supportMarker', function(markerFactory, ICONS) {
  var linker = function(scope, element, attrs) {
    var content = element.children().detach()[0];
    var location = scope.support.latest_location;

    if (location) {
      var map = scope.$parent.gmap;
      var marker = markerFactory(scope, element, content, ICONS.GREEN, location,
                                 map, attrs.click);
    }
  };
  return {
    replace: true,
    template: '',
    restrict: 'E',
    link: linker,
  };
})
.directive('eventupdateMarker', function(markerFactory, ICONS) {
  var linker = function(scope, element, attrs) {
    var content = element.children().detach()[0];
    var location = scope.update.location != null;

    if (location) {
      var map = scope.$parent.gmap;
      var marker = markerFactory(scope, element, content, ICONS.BLUE,
                                 scope.update.location, map);
    }
  };
  return {
    replace: true,
    template: '',
    restrict: 'E',
    link: linker,
  };
})
.directive('supportedMarker', function(markerFactory, ICONS) {
  var linker = function(scope, element, attrs) {
    var content = element.children().detach()[0];
    var location = scope.supported.latest_location;

    if (location) {
      var map = scope.$parent.gmap;
      var marker = markerFactory(scope, element, content, ICONS.RED, location,
                                 map, attrs.click);
    }
  };
  return {
    replace: true,
    template: '',
    restrict: 'E',
    link: linker,
  };
})
<commit_msg>ticket:89 Fixed event selection<commit_after>var mapApp = angular.module('mapApp', ["angular-lodash","ngAnimate"]);

mapApp.constant('ICONS', {
  RED: 'http://maps.google.com/mapfiles/ms/micons/red-dot.png',
  GREEN: 'http://maps.google.com/mapfiles/ms/micons/green-dot.png',
  BLUE: 'http://maps.google.com/mapfiles/ms/micons/blue-dot.png',
});

mapApp.controller('EventListCtrl', function($scope, $http, $interval, urls, mapSettings) {
  $scope.$location = window.location
  $scope.selectedEventsupport = {}
  $scope.selectedEventsupported = {}
  $scope.initGoogleMap = function(rootElement) {

    var fullBounds = new google.maps.LatLngBounds();
    var params = {status: 'A'};
    $http.get(urls.events, {params: params}).success(function(data) {
      for (i in data.objects) {
        var event = data.objects[i];
        if (event.latest_location != null) {
          var point = new google.maps.LatLng(
            event.latest_location.latitude,
            event.latest_location.longitude
          );
          fullBounds.extend(point)
        }
      };
    });

    var mapOptions = {
      zoom: 10,
      center: new google.maps.LatLng(50.444, 390.56),
      zoomControl: true,
      zoomControlOptions: {position: google.maps.ControlPosition.RIGHT_CENTER},
      panControl: true,
      panControlOptions: {position: google.maps.ControlPosition.RIGHT_TOP},
    };
    $scope.gmap = new google.maps.Map(rootElement, mapOptions);
    $scope.gwindow = new google.maps.InfoWindow({content: "Sup"});
    $scope.gwindow_opened = false;
  };
  $scope.zoomIn = function() {
    if ($scope.zoomedIn == false) {
      $scope.gmap.setZoom($scope.gmap.getZoom() + $scope.zoomScale);
      $scope.zoomedIn = true;
    }
  };
  $scope.zoomOut = function() {
    if ($scope.zoomedIn == true) {
      $scope.gmap.setZoom($scope.gmap.getZoom() - $scope.zoomScale);
      $scope.zoomedIn = false;
    }
  };
  $scope.select = function(event) {
    if (event == null) {
      $scope.zoomOut();
      $scope.selectedEvent = null;
      $scope.selectedEventsupport = {};
      $scope.selectedEventsupported = {};
      window.location.hash = '';
    } else {
      var params = {event__id: event.id};
      $http.get(urls.eventupdates, {params: params}).success(function(data) {
        event.updates = data.objects;
        $scope.focus(event.latest_location);
        $scope.zoomIn();
        $scope.selectedEvent = event;
        window.location.hash = event.id;
        $scope.selectedEvent.isNew = false;
      });

      var supportEvents = _.filter($scope.events, {"type": "support"});
      _.forEach(supportEvents,function (support) {
        if (_.any(support.supported,{"id":event.id})){
          $scope.selectedEventsupport[support.id] = support;
        }
        });
      _.forEach(event.supported, function(supported){
        $scope.selectedEventsupported[supported.id] = $scope.events[supported.id];
      });

    };
  };
  $scope.update = function(options, callback) {
    var params = {status: 'A'};
    $http.get(urls.events, {params: params}).success(function(data) {
      var eventsAppeared = false, newEvents = {};
      for (i in data.objects) {
        var event = data.objects[i];
        newEvents[event.id] = event;
      }
      // Deleting old events
      for (oldEventId in $scope.events) {
        if (newEvents[oldEventId] == null) {
          delete $scope.events[oldEventId];
        }
      }
      // Adding new events
      for (newEventId in newEvents) {
        if ($scope.events[newEventId] == null) {
          var new_event =  newEvents[newEventId]
            if (options.highightNew){
              new_event.isNew = true
            } else {
              new_event.isNew = false
            }
          $scope.events[newEventId] = new_event;
          eventsAppeared = true;
        }
      }
      if (eventsAppeared && options.playSoundForNew)
        document.getElementById('audiotag').play();
      // Making map show all events
      if (options.centerMap) {
        var eventsBounds = new google.maps.LatLngBounds();
        for (eventId in $scope.events) {
          var event = $scope.events[eventId];
          eventsBounds.extend(new google.maps.LatLng(
            event.latest_location.latitude,
            event.latest_location.longitude
          ));
        }
        $scope.gmap.fitBounds(eventsBounds);
      }
      if (eventsAppeared){
          $scope.updateUserAttrs(newEvents);
      }

      if ('function' === typeof callback) callback();
    });
  };

  $scope.updateUserAttrs = function(events){
    _.forEach(events, function(event){
      //clojure for ajax callback
      var clojr = function(pevent,field){
        return function(data){
          pevent.user[field] = data;
        }
      }

      $http.get(urls.user_roles,
        {params:{id:event.user.id}}).success(clojr(event,'roles'))
      $http.get(urls.user_movement_types,
        {params:{id:event.user.id}}).success(clojr(event,'movement_types'))
    });
  }

  $scope.focus = function(location) {
    $scope.gmap.panTo(new google.maps.LatLng(location.latitude,
                                             location.longitude));
  };

  $scope.getRoles = function() {
    //populate list of avail roles for matching
    $scope.filters.roles={};
    $http.get(urls.roles).success(function(data) {
      _.forEach(data.objects, function(role){
        role.enabled = true;
        $scope.filters.roles[role.id] = role;
      });
    });
  }

  $scope.getMovementTypes = function() {
    //populate list of avail movement_types for matching
    $scope.filters.movement_types={};
    $http.get(urls.movement_types).success(function(data) {
      _.forEach(data.objects, function(mt){
        mt.enabled = true;
        $scope.filters.movement_types[mt.id] = mt;
      });
    });
  }
  $scope.setFiltersTo=function(filters,value){
      //set array of user filters to be disabled or enabled, all at once
      _.map(filters,function(el){el.enabled=value});
  }

  $scope.userFilters = function(event) {
      // filter events for attrs event.user.role or event.user.movement_type
      // if user has no attr - do not filter him.
      roles = event.user.roles;
      movement_types = event.user.movement_types;
      //do not filter elements without attrs
      if (_.isEmpty(roles) && _.isEmpty(movement_types)) return true;

      var hasRoles = _.any(roles, function(role_id){
        return $scope.filters.roles[role_id].enabled
      });

      var hasMovementTypes = _.any(movement_types, function(mtype_id){
        return $scope.filters.movement_types[mtype_id].enabled
      });

      return (hasRoles&&hasMovementTypes)
  }

  $scope.addEventUpdate = function() {
    var event = $scope.selectedEvent,
        text = $scope.fields.addEventUpdateText,
        url = urls.addEventUpdate;
    $http.post(url, {"event_id":event.id, "text":text}).success(function(data) {
        var params = {event__id: event.id};
        $http.get(urls.eventupdates, {params: params}).success(function(data) {
            event.updates = data.objects;
        })
    })
    $scope.fields.addEventUpdateText = '';
  };
  $scope.ctrlEnter = function(event) {
    var ctrlPressed = event.metaKey || event.ctrlKey;
    var enterPressed = event.keyCode == 13;
    var text = $scope.fields.addEventUpdateText;
    if (ctrlPressed && enterPressed && text.length) {
      $scope.addEventUpdate(text);
    }
  };
  $scope.closeEvent = function(event) {
    $http.post(urls.closeEvent, {event_id: event.id}).success(function(data) {
      $scope.select(null);
      delete $scope.events[event.id];
    });
  };
  $scope.notifySupporters = function(event) {
    var data = {
      event_id: $scope.selectedEvent.id,
      radius: $scope.fields.notifySupportersRadius
    };
    $scope.isNotifyingSupporters = true;
    $http.post(urls.notifySupporters, data).success(function(data) {
      $scope.isNotifyingSupporters = false;
    })
  };
  $scope.createTestEvent = function() {
    var center = $scope.gmap.getCenter(),
        data = {longitude: center.lng(), latitude: center.lat()};
    $http.post(urls.createTestEvent, data);
  };

  $scope.updatePerSeconds = 5;
  $scope.selectedEvent = null;
  $scope.zoomedIn = false;
  $scope.zoomScale = 1;
  $scope.initGoogleMap(document.getElementById("map-canvas"));
  $scope.events = {};
  $scope.isNotifyingSupporters = false;
  $scope.showFilterPanel = false;
  $scope.fields = {
    addEventUpdateText: '',
    notifySupportersRadius: '',
  };

  $scope.filters = {};
  $scope.getRoles();
  $scope.getMovementTypes();
  $scope.update({playSoundForNew:false, highightNew:false, centerMap:true}, function() {
    if ($scope.$location.hash != "") {
      var id = parseInt($scope.$location.hash.split('#')[1]);
      $scope.select($scope.events[id]);
    }
  });

  $interval(function() {
    document.getElementById('audiotag').play();
    alert('Do You sleep?');
  }, mapSettings.wakeup_interval * 60 * 1000);

  $interval(function() {
    $scope.update({playSoundForNew:mapSettings.sound,
      highightNew:mapSettings.highlight,
      centerMap:false});
  }, $scope.updatePerSeconds * 1000);

  $interval(function() {
    $scope.updateUserAttrs($scope.events);
  },30*1000);
})
.factory('markerFactory', function() {
  return function(scope, element, content, icon, location, map, onclick) {
    var markerArgs = {
      icon: icon,
      position: new google.maps.LatLng(location.latitude, location.longitude),
    };

    var marker = new google.maps.Marker(markerArgs);
    marker.setMap(map);
    if (onclick)
      google.maps.event.addListener(marker, 'click', function() {
        scope.$eval(onclick);
      });

    var markersWindow = new google.maps.InfoWindow();

    google.maps.event.addListener(marker, 'mouseover', function() {
      markersWindow.setContent(content);
      markersWindow.open(map, marker);
    });
    google.maps.event.addListener(marker, 'mouseout', function() {
      if (markersWindow != null) markersWindow.close();
    });

    element.on('$destroy', function() {
      marker.setMap(null);
      marker = null;
      if (markersWindow != null) {
        markersWindow.close();
        markersWindow = null;
      }
    });

    return marker;
  };
})
.directive('eventMarker', function(markerFactory, ICONS) {
  var linker = function(scope, element, attrs) {
    var content = element.children().detach()[0];
    var location = scope.event.latest_location;

    if (location) {
      var map = scope.$parent.gmap;
      var icon = (scope.event.type == 'victim') ? ICONS.RED : ICONS.GREEN;
      var marker = markerFactory(scope, element, content, icon, location,
                                 map, attrs.click);

      scope.$watch('event.isNew', function(isNew) {
        var animation = (isNew) ? google.maps.Animation.BOUNCE : null;
        marker.setAnimation(animation);
      });
    }
  };
  return {
    replace: true,
    template: '',
    restrict: 'E',
    link: linker,
  };
})
.directive('supportMarker', function(markerFactory, ICONS) {
  var linker = function(scope, element, attrs) {
    var content = element.children().detach()[0];
    var location = scope.support.latest_location;

    if (location) {
      var map = scope.$parent.gmap;
      var marker = markerFactory(scope, element, content, ICONS.GREEN, location,
                                 map, attrs.click);
    }
  };
  return {
    replace: true,
    template: '',
    restrict: 'E',
    link: linker,
  };
})
.directive('eventupdateMarker', function(markerFactory, ICONS) {
  var linker = function(scope, element, attrs) {
    var content = element.children().detach()[0];
    var location = scope.update.location != null;

    if (location) {
      var map = scope.$parent.gmap;
      var marker = markerFactory(scope, element, content, ICONS.BLUE,
                                 scope.update.location, map);
    }
  };
  return {
    replace: true,
    template: '',
    restrict: 'E',
    link: linker,
  };
})
.directive('supportedMarker', function(markerFactory, ICONS) {
  var linker = function(scope, element, attrs) {
    var content = element.children().detach()[0];
    var location = scope.supported.latest_location;

    if (location) {
      var map = scope.$parent.gmap;
      var marker = markerFactory(scope, element, content, ICONS.RED, location,
                                 map, attrs.click);
    }
  };
  return {
    replace: true,
    template: '',
    restrict: 'E',
    link: linker,
  };
})
<|endoftext|>


<commit_before>'use strict';

const mongo = require('mongo');
const co = require('co');
const dataCollection = mongo.connect().then(db => db.collection('data'));
const mfStatsCollection = mongo.connect().then(db => db.collection('mfStats'));

const defaultSearchEmOptions = {
    limit: 1e3,
    precision: 100
};
const searchEm = co.wrap(function* searchEm(value, options) {
    if (typeof value !== 'number') {
        throw new TypeError('value must be a number');
    }
    options = Object.assign({}, defaultSearchEmOptions, options);

    if (options.limit > 1e4) options.limit = 1e4;
    if (options.limit < 1) options.limit = 1;

    let error=value / 1e6 * options.precision;

    const data = yield dataCollection;
    const searchBottom = data.find({em: {$lte: value, $gte: value - error}}).sort({em: -1}).limit(options.limit).project({_id: -1, em: 1, mf: 1}).toArray();
    const searchTop = data.find({em: {$gt: value, $lte: value + error}}).sort({em: 1}).limit(options.limit).project({_id: -1, em: 1, mf: 1}).toArray();
    const results = yield Promise.all([searchBottom, searchTop]);

    const uniqueMFs = new Map();
    results.forEach(function treatResult(result) {
        for (const resultValue of result) {
            let element = uniqueMFs.get(resultValue.mf);
            if (!element) {
                element = {
                    mf: resultValue.mf,
                    em: resultValue.em,
                    ppm: Math.abs(resultValue.em - value) / value * 1e6,
                    total: 0
                };
                uniqueMFs.set(resultValue.mf, element);
            }
            element.total++;
        }
    });

    const finalResult = Array.from(uniqueMFs.values());
    finalResult.sort((a, b) => a.ppm - b.ppm);
    return finalResult;
});

exports.search = {
    em: searchEm
};

const moleculesEm = co.wrap(function* moleculesEm(query) {
    if (! query.em) {
        throw new Error('em parameters must be specified, mf is optional');
    }
    const em = +query.em;
    const mf = query.mf;

    const mongoQuery = {em};
    if (mf) mongoQuery.mf=mf;

    const data = yield dataCollection;
    const result = yield data.find(mongoQuery).project({_id: 1, iupac: 1, ocl: 1, mf: 1, em: 1, nbFragments: 1, charge: 1}).limit(10000).toArray();
    return result.map(el => {
        return {
            id: el._id,
            iupac: el.iupac,
            ocl: el.ocl,
            mf: el.mf,
            em: el.em,
            nbFragments: el.nbFragments,
            charge: el.charge
        };
    });
});

const moleculesMf = co.wrap(function* moleculesMf(query = {}) {
    if (typeof query.mf !== 'string') {
        throw new TypeError('value must be a string');
    }

    const data = yield dataCollection;
    const result = yield data.find({mf: query.mf}).project({_id: 1, iupac: 1, ocl: 1, mf: 1, em: 1, nbFragments: 1, charge: 1}).limit(10000).toArray();
    return result.map(el => {
        return {
            id: el._id,
            iupac: el.iupac,
            ocl: el.ocl,
            mf: el.mf,
            em: el.em,
            nbFragments: el.nbFragments,
            charge: el.charge
        };
    });
});

/*
Search statistics about a kind of molecular formula
You may specify the stepMass and elementRatios
 */
const mfStatsSearch = co.wrap(function* mfStatsSearch(query = {}) {
    var {
        stepMass = 25,
        elementRatios = 'C-H.C-N.C-O.C-S.C-P.C-FClBr.O-P.O-S.CCNP-HFClBr',
        id
    } = query;

    if (! id) id=stepMass+"_"+elementRatios;

    const stats = yield mfStatsCollection;
    return yield stats.findOne({_id: id});
});

const mfStatsToc = co.wrap(function* mfStatsSearch(query = {}) {
    const stats = yield mfStatsCollection;
    return yield stats.find().project({_id: 1, options: 1, date: 1}).limit(10000).toArray();
});

exports.molecules = {
    em: moleculesEm,
    mf: moleculesMf
};

exports.mfStats = {
    search: mfStatsSearch,
    toc: mfStatsToc
}<commit_msg>Add total number of formula<commit_after>'use strict';

const mongo = require('mongo');
const co = require('co');
const dataCollection = mongo.connect().then(db => db.collection('data'));
const mfStatsCollection = mongo.connect().then(db => db.collection('mfStats'));

const defaultSearchEmOptions = {
    limit: 1e3,
    precision: 100
};
const searchEm = co.wrap(function* searchEm(value, options) {
    if (typeof value !== 'number') {
        throw new TypeError('value must be a number');
    }
    options = Object.assign({}, defaultSearchEmOptions, options);

    if (options.limit > 1e4) options.limit = 1e4;
    if (options.limit < 1) options.limit = 1;

    let error=value / 1e6 * options.precision;

    const data = yield dataCollection;
    const searchBottom = data.find({em: {$lte: value, $gte: value - error}}).sort({em: -1}).limit(options.limit).project({_id: -1, em: 1, mf: 1}).toArray();
    const searchTop = data.find({em: {$gt: value, $lte: value + error}}).sort({em: 1}).limit(options.limit).project({_id: -1, em: 1, mf: 1}).toArray();
    const results = yield Promise.all([searchBottom, searchTop]);

    const uniqueMFs = new Map();
    results.forEach(function treatResult(result) {
        for (const resultValue of result) {
            let element = uniqueMFs.get(resultValue.mf);
            if (!element) {
                element = {
                    mf: resultValue.mf,
                    em: resultValue.em,
                    ppm: Math.abs(resultValue.em - value) / value * 1e6,
                    total: 0
                };
                uniqueMFs.set(resultValue.mf, element);
            }
            element.total++;
        }
    });

    const finalResult = Array.from(uniqueMFs.values());
    finalResult.sort((a, b) => a.ppm - b.ppm);
    return finalResult;
});

exports.search = {
    em: searchEm
};

const moleculesEm = co.wrap(function* moleculesEm(query) {
    if (! query.em) {
        throw new Error('em parameters must be specified, mf is optional');
    }
    const em = +query.em;
    const mf = query.mf;

    const mongoQuery = {em};
    if (mf) mongoQuery.mf=mf;

    const data = yield dataCollection;
    const result = yield data.find(mongoQuery).project({_id: 1, iupac: 1, ocl: 1, mf: 1, em: 1, nbFragments: 1, charge: 1}).limit(10000).toArray();
    return result.map(el => {
        return {
            id: el._id,
            iupac: el.iupac,
            ocl: el.ocl,
            mf: el.mf,
            em: el.em,
            nbFragments: el.nbFragments,
            charge: el.charge
        };
    });
});

const moleculesMf = co.wrap(function* moleculesMf(query = {}) {
    if (typeof query.mf !== 'string') {
        throw new TypeError('value must be a string');
    }

    const data = yield dataCollection;
    const result = yield data.find({mf: query.mf}).project({_id: 1, iupac: 1, ocl: 1, mf: 1, em: 1, nbFragments: 1, charge: 1}).limit(10000).toArray();
    return result.map(el => {
        return {
            id: el._id,
            iupac: el.iupac,
            ocl: el.ocl,
            mf: el.mf,
            em: el.em,
            nbFragments: el.nbFragments,
            charge: el.charge
        };
    });
});

/*
Search statistics about a kind of molecular formula
You may specify the stepMass and elementRatios
 */
const mfStatsSearch = co.wrap(function* mfStatsSearch(query = {}) {
    var {
        stepMass = 25,
        elementRatios = 'C-H.C-N.C-O.C-S.C-P.C-FClBr.O-P.O-S.CCNP-HFClBr',
        id
    } = query;

    if (! id) id=stepMass+"_"+elementRatios;

    const stats = yield mfStatsCollection;
    return yield stats.findOne({_id: id});
});

const mfStatsToc = co.wrap(function* mfStatsSearch(query = {}) {
    const stats = yield mfStatsCollection;
    return yield stats.find().project({_id: 1, options: 1, info: 1}).limit(10000).toArray();
});

exports.molecules = {
    em: moleculesEm,
    mf: moleculesMf
};

exports.mfStats = {
    search: mfStatsSearch,
    toc: mfStatsToc
}<|endoftext|>


<commit_before>goog.provide('og.Events');

og.Events = function () { };

og.Events.prototype.registerNames = function (eventNames) {
    for (var i = 0; i < eventNames.length; i++) {
        this[eventNames[i]] = { "active": true, "handlers": [] };
    }
};

og.Events.prototype.on = function (name, sender, callback) {
    this[name].handlers.push({ sender: sender, callback: callback });
};

og.Events.prototype.dispatch = function (event, obj) {
    if (event && event.active) {
        var h = event.handlers;
        var i = h.length;
        while (i--) {
            var e = h[i];
            e.callback.call(e.sender, obj);
        }
    }
};<commit_msg>Events dispatch order bug fixed.<commit_after>goog.provide('og.Events');

og.Events = function () { };

og.Events.prototype.registerNames = function (eventNames) {
    for (var i = 0; i < eventNames.length; i++) {
        this[eventNames[i]] = { "active": true, "handlers": [] };
    }
};

og.Events.prototype.on = function (name, sender, callback) {
    this[name].handlers.unshift({ sender: sender, callback: callback });
};

og.Events.prototype.dispatch = function (event, obj) {
    if (event && event.active) {
        var h = event.handlers;
        var i = h.length;
        while (i--) {
            var e = h[i];
            e.callback.call(e.sender, obj);
        }
    }
};<|endoftext|>