<commit_before>import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { chainPropTypes, deepmerge } from '@material-ui/utils';
import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled';
import { keyframes } from '@material-ui/styled-engine';
import capitalize from '../utils/capitalize';

import useThemeProps from '../styles/useThemeProps';
import experimentalStyled from '../styles/experimentalStyled';
import circularProgressClasses, {
  getCircularProgressUtilityClass,
} from './circularProgressClasses';

const SIZE = 44;

const circularRotateKeyframe = keyframes`
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
`;

const circularDashKeyframe = keyframes`
  0% {
    stroke-dasharray: 1px, 200px;
    stroke-dashoffset: 0;
  }

  50% {
    stroke-dasharray: 100px, 200px;
    stroke-dashoffset: -15px;
  }

  100% {
    stroke-dasharray: 100px, 200px;
    stroke-dashoffset: -125px;
  }
`;

const overridesResolver = (props, styles) => {
  const { styleProps } = props;

  return deepmerge(styles.root || {}, {
    ...styles[styleProps.variant],
    ...styles[`color${capitalize(styleProps.color)}`],
    [`& .${circularProgressClasses.svg}`]: styles.svg,
    [`& .${circularProgressClasses.circle}`]: {
      ...styles.circle,
      ...styles[`circle${capitalize(styleProps.variant)}`],
      ...(styleProps.disableShrink && styles.circleDisableShrink),
    },
  });
};

const useUtilityClasses = (styleProps) => {
  const { classes, variant, color, disableShrink } = styleProps;

  const slots = {
    root: ['root', variant, `color${capitalize(color)}`],
    svg: ['svg'],
    circle: ['circle', `circle${capitalize(variant)}`, disableShrink && 'circleDisableShrink'],
  };

  return composeClasses(slots, getCircularProgressUtilityClass, classes);
};

// This `styled()` function invokes keyframes. `styled-components` only supports keyframes
// in string templates. Do not convert these styles in JS object as it will break.
const CircularProgressRoot = experimentalStyled(
  'span',
  {},
  {
    name: 'MuiCircularProgress',
    slot: 'Root',
    overridesResolver,
  },
)`
  display: inline-block;

  transition: ${({ styleProps, theme }) =>
    styleProps.variant === 'determinate' ? theme.transitions.create('transform') : undefined};

  animation-name: ${({ styleProps }) =>
    styleProps.variant === 'indeterminate' && circularRotateKeyframe};
  animation-duration: ${({ styleProps }) => styleProps.variant === 'indeterminate' && '1.4s'};
  animation-timing-function: ${({ styleProps }) =>
    styleProps.variant === 'indeterminate' && 'linear'};
  animation-iteration-count: ${({ styleProps }) =>
    styleProps.variant === 'indeterminate' && 'infinite'};

  color: ${({ styleProps, theme }) =>
    styleProps.color === 'primary' || styleProps.color === 'secondary'
      ? theme.palette[styleProps.color].main
      : undefined};
`;

const CircularProgressSVG = experimentalStyled(
  'svg',
  {},
  {
    name: 'MuiCircularProgress',
    slot: 'Svg',
  },
)({
  /* Styles applied to the svg element. */
  display: 'block', // Keeps the progress centered
});

// This `styled()` function invokes keyframes. `styled-components` only supports keyframes
// in string templates. Do not convert these styles in JS object as it will break.
const CircularProgressCircle = experimentalStyled(
  'circle',
  {},
  {
    name: 'MuiCircularProgress',
    slot: 'Circle',
  },
)`
  stroke: currentColor;

  transition: ${({ styleProps, theme }) =>
    styleProps.variant === 'determinate'
      ? theme.transitions.create('stroke-dashoffset')
      : undefined};

  animation-name: ${({ styleProps }) => {
    if (styleProps.disableShrink) {
      return 'none';
    }
    return styleProps.variant === 'indeterminate' ? circularDashKeyframe : undefined;
  }};
  animation-duration: ${({ styleProps }) => styleProps.variant === 'indeterminate' && '1.4s'};
  animation-timing-function: ${({ styleProps }) =>
    styleProps.variant === 'indeterminate' && 'ease-in-out'};
  animation-iteration-count: ${({ styleProps }) =>
    styleProps.variant === 'indeterminate' && 'infinite'};
  stroke-dasharray: ${({ styleProps }) => styleProps.variant === 'indeterminate' && '80px, 200px'};
  stroke-dashoffset: ${({ styleProps }) => styleProps.variant === 'indeterminate' && '0px'};
`;

/**
 * ## ARIA
 *
 * If the progress bar is describing the loading progress of a particular region of a page,
 * you should use `aria-describedby` to point to the progress bar, and set the `aria-busy`
 * attribute to `true` on that region until it has finished loading.
 */
const CircularProgress = React.forwardRef(function CircularProgress(inProps, ref) {
  const props = useThemeProps({ props: inProps, name: 'MuiCircularProgress' });
  const {
    className,
    color = 'primary',
    disableShrink = false,
    size = 40,
    style,
    thickness = 3.6,
    value = 0,
    variant = 'indeterminate',
    ...other
  } = props;

  const styleProps = {
    ...props,
    color,
    disableShrink,
    size,
    thickness,
    value,
    variant,
  };

  const classes = useUtilityClasses(styleProps);

  const circleStyle = {};
  const rootStyle = {};
  const rootProps = {};

  if (variant === 'determinate') {
    const circumference = 2 * Math.PI * ((SIZE - thickness) / 2);
    circleStyle.strokeDasharray = circumference.toFixed(3);
    rootProps['aria-valuenow'] = Math.round(value);
    circleStyle.strokeDashoffset = `${(((100 - value) / 100) * circumference).toFixed(3)}px`;
    rootStyle.transform = 'rotate(-90deg)';
  }

  return (
    <CircularProgressRoot
      className={clsx(classes.root, className)}
      style={{ width: size, height: size, ...rootStyle, ...style }}
      styleProps={styleProps}
      ref={ref}
      role="progressbar"
      {...rootProps}
      {...other}
    >
      <CircularProgressSVG
        className={classes.svg}
        styleProps={styleProps}
        viewBox={`${SIZE / 2} ${SIZE / 2} ${SIZE} ${SIZE}`}
      >
        <CircularProgressCircle
          className={classes.circle}
          style={circleStyle}
          styleProps={styleProps}
          cx={SIZE}
          cy={SIZE}
          r={(SIZE - thickness) / 2}
          fill="none"
          strokeWidth={thickness}
        />
      </CircularProgressSVG>
    </CircularProgressRoot>
  );
});

CircularProgress.propTypes = {
  // ----------------------------- Warning --------------------------------
  // | These PropTypes are generated from the TypeScript type definitions |
  // |     To update them edit the d.ts file and run "yarn proptypes"     |
  // ----------------------------------------------------------------------
  /**
   * Override or extend the styles applied to the component.
   */
  classes: PropTypes.object,
  /**
   * @ignore
   */
  className: PropTypes.string,
  /**
   * The color of the component. It supports those theme colors that make sense for this component.
   * @default 'primary'
   */
  color: PropTypes.oneOf(['inherit', 'primary', 'secondary']),
  /**
   * If `true`, the shrink animation is disabled.
   * This only works if variant is `indeterminate`.
   * @default false
   */
  disableShrink: chainPropTypes(PropTypes.bool, (props) => {
    if (props.disableShrink && props.variant && props.variant !== 'indeterminate') {
      return new Error(
        'Material-UI: You have provided the `disableShrink` prop ' +
          'with a variant other than `indeterminate`. This will have no effect.',
      );
    }

    return null;
  }),
  /**
   * The size of the component.
   * If using a number, the pixel unit is assumed.
   * If using a string, you need to provide the CSS unit, e.g '3rem'.
   * @default 40
   */
  size: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  /**
   * @ignore
   */
  style: PropTypes.object,
  /**
   * The system prop that allows defining system overrides as well as additional CSS styles.
   */
  sx: PropTypes.object,
  /**
   * The thickness of the circle.
   * @default 3.6
   */
  thickness: PropTypes.number,
  /**
   * The value of the progress indicator for the determinate variant.
   * Value between 0 and 100.
   * @default 0
   */
  value: PropTypes.number,
  /**
   * The variant to use.
   * Use indeterminate when there is no progress value.
   * @default 'indeterminate'
   */
  variant: PropTypes.oneOf(['determinate', 'indeterminate']),
};

export default CircularProgress;
<commit_msg>[CircularProgress] Make source easier to read (#24893)<commit_after>import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { chainPropTypes, deepmerge } from '@material-ui/utils';
import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled';
import { keyframes, css } from '@material-ui/styled-engine';
import capitalize from '../utils/capitalize';
import useThemeProps from '../styles/useThemeProps';
import experimentalStyled from '../styles/experimentalStyled';
import circularProgressClasses, {
  getCircularProgressUtilityClass,
} from './circularProgressClasses';

const SIZE = 44;

const circularRotateKeyframe = keyframes`
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
`;

const circularDashKeyframe = keyframes`
  0% {
    stroke-dasharray: 1px, 200px;
    stroke-dashoffset: 0;
  }

  50% {
    stroke-dasharray: 100px, 200px;
    stroke-dashoffset: -15px;
  }

  100% {
    stroke-dasharray: 100px, 200px;
    stroke-dashoffset: -125px;
  }
`;

const overridesResolver = (props, styles) => {
  const { styleProps } = props;

  return deepmerge(styles.root || {}, {
    ...styles[styleProps.variant],
    ...styles[`color${capitalize(styleProps.color)}`],
    [`& .${circularProgressClasses.svg}`]: styles.svg,
    [`& .${circularProgressClasses.circle}`]: {
      ...styles.circle,
      ...styles[`circle${capitalize(styleProps.variant)}`],
      ...(styleProps.disableShrink && styles.circleDisableShrink),
    },
  });
};

const useUtilityClasses = (styleProps) => {
  const { classes, variant, color, disableShrink } = styleProps;

  const slots = {
    root: ['root', variant, `color${capitalize(color)}`],
    svg: ['svg'],
    circle: ['circle', `circle${capitalize(variant)}`, disableShrink && 'circleDisableShrink'],
  };

  return composeClasses(slots, getCircularProgressUtilityClass, classes);
};

const CircularProgressRoot = experimentalStyled(
  'span',
  {},
  {
    name: 'MuiCircularProgress',
    slot: 'Root',
    overridesResolver,
  },
)(
  ({ styleProps, theme }) => ({
    /* Styles applied to the root element. */
    display: 'inline-block',
    /* Styles applied to the root element if `variant="determinate"`. */
    ...(styleProps.variant === 'determinate' && {
      transition: theme.transitions.create('transform'),
    }),
    /* Styles applied to the root element unless `color="inherit"`. */
    ...(styleProps.color !== 'inherit' && {
      color: theme.palette[styleProps.color].main,
    }),
  }),
  /* Styles applied to the root element if `variant="indeterminate"`. */
  ({ styleProps }) =>
    styleProps.variant === 'indeterminate' &&
    css`
      animation: ${circularRotateKeyframe} 1.4s linear infinite;
    `,
);

const CircularProgressSVG = experimentalStyled(
  'svg',
  {},
  {
    name: 'MuiCircularProgress',
    slot: 'Svg',
  },
)({
  /* Styles applied to the svg element. */
  display: 'block', // Keeps the progress centered
});

const CircularProgressCircle = experimentalStyled(
  'circle',
  {},
  {
    name: 'MuiCircularProgress',
    slot: 'Circle',
  },
)(
  ({ styleProps, theme }) => ({
    /* Styles applied to the `circle` svg path. */
    stroke: 'currentColor',
    // Use butt to follow the specification, by chance, it's already the default CSS value.
    // strokeLinecap: 'butt',
    /* Styles applied to the `circle` svg path if `variant="determinate"`. */
    ...(styleProps.variant === 'determinate' && {
      transition: theme.transitions.create('stroke-dashoffset'),
    }),
  }),
  /* Styles applied to the `circle` svg path if `variant="indeterminate"`. */
  ({ styleProps }) =>
    styleProps.variant === 'indeterminate' &&
    css`
      animation: ${circularDashKeyframe} 1.4s ease-in-out infinite;

      /* Some default value that looks fine waiting for the animation to kicks in. */
      stroke-dasharray: 80px, 200px;
      stroke-dashoffset: 0; /* Add the unit to fix a Edge 16 and below bug. */
    `,
);

/**
 * ## ARIA
 *
 * If the progress bar is describing the loading progress of a particular region of a page,
 * you should use `aria-describedby` to point to the progress bar, and set the `aria-busy`
 * attribute to `true` on that region until it has finished loading.
 */
const CircularProgress = React.forwardRef(function CircularProgress(inProps, ref) {
  const props = useThemeProps({ props: inProps, name: 'MuiCircularProgress' });
  const {
    className,
    color = 'primary',
    disableShrink = false,
    size = 40,
    style,
    thickness = 3.6,
    value = 0,
    variant = 'indeterminate',
    ...other
  } = props;

  const styleProps = {
    ...props,
    color,
    disableShrink,
    size,
    thickness,
    value,
    variant,
  };

  const classes = useUtilityClasses(styleProps);

  const circleStyle = {};
  const rootStyle = {};
  const rootProps = {};

  if (variant === 'determinate') {
    const circumference = 2 * Math.PI * ((SIZE - thickness) / 2);
    circleStyle.strokeDasharray = circumference.toFixed(3);
    rootProps['aria-valuenow'] = Math.round(value);
    circleStyle.strokeDashoffset = `${(((100 - value) / 100) * circumference).toFixed(3)}px`;
    rootStyle.transform = 'rotate(-90deg)';
  }

  return (
    <CircularProgressRoot
      className={clsx(classes.root, className)}
      style={{ width: size, height: size, ...rootStyle, ...style }}
      styleProps={styleProps}
      ref={ref}
      role="progressbar"
      {...rootProps}
      {...other}
    >
      <CircularProgressSVG
        className={classes.svg}
        styleProps={styleProps}
        viewBox={`${SIZE / 2} ${SIZE / 2} ${SIZE} ${SIZE}`}
      >
        <CircularProgressCircle
          className={classes.circle}
          style={circleStyle}
          styleProps={styleProps}
          cx={SIZE}
          cy={SIZE}
          r={(SIZE - thickness) / 2}
          fill="none"
          strokeWidth={thickness}
        />
      </CircularProgressSVG>
    </CircularProgressRoot>
  );
});

CircularProgress.propTypes = {
  // ----------------------------- Warning --------------------------------
  // | These PropTypes are generated from the TypeScript type definitions |
  // |     To update them edit the d.ts file and run "yarn proptypes"     |
  // ----------------------------------------------------------------------
  /**
   * Override or extend the styles applied to the component.
   */
  classes: PropTypes.object,
  /**
   * @ignore
   */
  className: PropTypes.string,
  /**
   * The color of the component. It supports those theme colors that make sense for this component.
   * @default 'primary'
   */
  color: PropTypes.oneOf(['inherit', 'primary', 'secondary']),
  /**
   * If `true`, the shrink animation is disabled.
   * This only works if variant is `indeterminate`.
   * @default false
   */
  disableShrink: chainPropTypes(PropTypes.bool, (props) => {
    if (props.disableShrink && props.variant && props.variant !== 'indeterminate') {
      return new Error(
        'Material-UI: You have provided the `disableShrink` prop ' +
          'with a variant other than `indeterminate`. This will have no effect.',
      );
    }

    return null;
  }),
  /**
   * The size of the component.
   * If using a number, the pixel unit is assumed.
   * If using a string, you need to provide the CSS unit, e.g '3rem'.
   * @default 40
   */
  size: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  /**
   * @ignore
   */
  style: PropTypes.object,
  /**
   * The system prop that allows defining system overrides as well as additional CSS styles.
   */
  sx: PropTypes.object,
  /**
   * The thickness of the circle.
   * @default 3.6
   */
  thickness: PropTypes.number,
  /**
   * The value of the progress indicator for the determinate variant.
   * Value between 0 and 100.
   * @default 0
   */
  value: PropTypes.number,
  /**
   * The variant to use.
   * Use indeterminate when there is no progress value.
   * @default 'indeterminate'
   */
  variant: PropTypes.oneOf(['determinate', 'indeterminate']),
};

export default CircularProgress;
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 Francisco Salavert (SGL-CIPF)
 * Copyright (c) 2014 Alejandro Alemán (SGL-CIPF)
 * Copyright (c) 2014 Ignacio Medina (EBI-EMBL)
 * Copyright (c) 2014 Jag Kandasamy (EBI-EMBL)
 *
 * This file is part of EVA.
 *
 * EVA is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * EVA is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with EVA. If not, see <http://www.gnu.org/licenses/>.
 */

function EvaVariantWidgetPanel(args) {
    var _this = this;
    _.extend(this, Backbone.Events);

    this.id = Utils.genId("VariantWidgetPanel");

    this.target;
    this.tools = [];
    _.extend(this, args);
    this.rendered = false;
    if (this.autoRender) {
        this.render();
    }
};

EvaVariantWidgetPanel.prototype = {
    render: function () {
        var _this = this;
        if(!this.rendered) {
            this.div = document.createElement('div');
            this.div.setAttribute('id', this.id);
            this.panel = this._createPanel();
            this.rendered = true;
        }

    },
    draw: function () {
        if(!this.rendered) {
            this.render();
        }
        this.targetDiv = (this.target instanceof HTMLElement ) ? this.target : document.querySelector('#' + this.target);
        if (!this.targetDiv) {
            console.log('EVAVariantWidgetPanel target not found');
            return;
        }
        this.targetDiv.appendChild(this.div);

        this.panel.render(this.div);

        this.variantWidgetDiv = document.querySelector('.variant-widget-div');
        this.variantWidget = this._createVariantWidget(this.variantWidgetDiv);
        this.variantWidget.draw();

        this.formPanelVariantFilterDiv = document.querySelector('.form-panel-variant-filter-div');
        this.formPanelVariantFilter = this._createFormPanelVariantFilter(this.formPanelVariantFilterDiv);
        this.formPanelVariantFilter.draw();
    },
    show: function () {
        this.panel.show()
    },
    hide: function () {
        this.panel.hide();
    },
    toggle: function () {
        if (this.panel.isVisible()) {
            this.panel.hide();
        } else {
            this.panel.show();
        }
    },
    _createPanel: function () {
        var tpl = new Ext.XTemplate(['

']);
        var view = Ext.create('Ext.view.View', {
            tpl: tpl
        });

        this.panel = Ext.create('Ext.panel.Panel', {
//            overflowX:true,
            border:true,
            layout: {
                type: 'vbox',
                align: 'left'
            },
            items: [view],
            height:3800,
            cls: 'variant-widget-panel'
        });

        return  this.panel;
    },
    _createVariantWidget: function (target) {
//        var width = this.width - parseInt(this.div.style.paddingLeft) - parseInt(this.div.style.paddingRight);
        var evaVariantWidget = new EvaVariantWidget({
            width: 1020,
            target: target,
            headerConfig: {
                baseCls: 'eva-header-1'
            },
            border: true,
            browserGridConfig: {
//                title: 'Variant Browser Assembly:GRCh37',
                title: 'Variant Browser',
                border: true
            },
            toolPanelConfig: {
                title: 'Variant Data',
                headerConfig: {
                    baseCls: 'eva-header-2'
                }
            },
            defaultToolConfig: {
                headerConfig: {
                    baseCls: 'eva-header-2'
                },
                genomeViewer: false,
                effect:false,
                rawData:false
            },
            responseParser: function (response) {
                var res = [];
                try {
                    res = response.response[0].result;
                } catch (e) {
                    console.log(e);
                }
                return  res;
            },
            dataParser: function (data) {
                for (var i = 0; i < data.length; i++) {
                    var variant = data[i];
                    if (variant.hgvs && variant.hgvs.genomic > 0) {
                        variant.hgvs_name = variant.hgvs.genomic[0];
                    }
                }
            }
        }); //the div must exist

        return evaVariantWidget;
    },
    _createFormPanelVariantFilter: function (target) {
        var _this = this;
        var positionFilter = new EvaPositionFilterFormPanel({
//            testRegion: '1:14000-200000',
//            testRegion: '1:3000760-3004790',
            testRegion: '1:78383460-78383470',
            emptyText: ''

        });

        var speciesFilter = new SpeciesFilterFormPanel({});

        this.studiesStore = Ext.create('Ext.data.Store', {
            pageSize: 50,
            proxy: {
                type: 'memory'
            },
            fields: [
                {name: 'studyName', type: 'string'},
                {name: 'studyId', type: 'string'}
            ],
            autoLoad: false
        });

        var studyFilter = new EvaStudyFilterFormPanel({
            collapsed: false,
            height: 550,
            studiesStore: this.studiesStore,
            studyFilterTpl:'<tpl if="studyId">
{studyName} ({studyId})
<tpl else>
{studyName}
</tpl>'
        });

//        _this._loadListStudies(studyFilter, '');

        studyFilter.on('studies:change', function (e) {
            var studies = _this.formPanelVariantFilter.getValues().studies;
            var submitButton = Ext.getCmp(_this.formPanelVariantFilter.submitButtonId);
            if(_.isUndefined(studies)){
                Ext.Msg.alert('','Please Select at least one study');
                submitButton.disable();

            }else{
                submitButton.enable();

            }

        });

        speciesFilter.on('species:change', function (e) {
            _this._loadListStudies(studyFilter, e.species);

            EvaManager.get({
                category: 'meta/studies',
                resource: 'list',
                params:{species:e.species},
                success: function (response) {
                    try {
                         projects = response.response[0].result;
                    } catch (e) {
                        console.log(e);
                    }
                }
            });

        });

        var conseqType = new ConsequenceTypeFilterFormPanel({
            consequenceTypes: consequenceTypes,
            collapsed: true,
            fields: [
                {name: 'name', type: 'string'}
            ],
            columns: [
                {
                    xtype: 'treecolumn',
                    flex: 1,
                    sortable: false,
                    dataIndex: 'name'
                }
            ]
        });

        var formPanel = new FormPanel({
            title: 'Filter',
            headerConfig: {
                baseCls: 'eva-header-1'
            },
            mode: 'accordion',
            target: target,
            submitButtonText: 'Submit',
            submitButtonId: 'vb-submit-button',
            filters: [speciesFilter,positionFilter, studyFilter],
            width: 300,
//            height: 1043,
            border: false,
            handlers: {
                'submit': function (e) {
                    _this.variantWidget.setLoading(true);
                    //POSITION CHECK
                    var regions = [];
                    if (typeof e.values.region !== 'undefined') {
                        if (e.values.region !== "") {
                            regions = e.values.region.split(",");
                        }
                        delete  e.values.region;
                    }
                    if(!_.isUndefined(e.values.species)){
                        var cellBaseSpecies = e.values.species.split("_")[0];
                    }

                    if (typeof e.values.gene !== 'undefined') {
                        CellBaseManager.get({
                            species: cellBaseSpecies,
                            category: 'feature',
                            subCategory: 'gene',
                            query: e.values.gene.toUpperCase(),
                            resource: "info",
                            async: false,
                            params: {
                                include: 'chromosome,start,end'
                            },
                            success: function (data) {
                                for (var i = 0; i < data.response.length; i++) {
                                    var queryResult = data.response[i];
                                    if(!_.isEmpty(queryResult.result[0])){
                                        var region = new Region(queryResult.result[0]);
                                        regions.push(region.toString());
                                    }
                                }
                            }
                        });
                        delete  e.values.gene;
                    }

                    if (typeof e.values.snp !== 'undefined') {
                        CellBaseManager.get({
                            species: cellBaseSpecies,
                            category: 'feature',
                            subCategory: 'snp',
                            query: e.values.snp,
                            resource: "info",
                            async: false,
                            params: {
                                include: 'chromosome,start,end'
                            },
                            success: function (data) {
                                for (var i = 0; i < data.response.length; i++) {
                                    var queryResult = data.response[i];
                                    var region = new Region(queryResult.result[0]);
                                    var fields2 = (""+region).split(/[:-]/);
                                    if(parseInt(fields2[1]) > parseInt(fields2[2])) {
                                        var swap = fields2[1];
                                        region.start = fields2[2];
                                        region.end = swap;
                                    }
                                    regions.push(region.toString());
                                }
                            }
                        });
                        delete  e.values.snp;
                    }

                    //CONSEQUENCE TYPES CHECK
                    if (typeof e.values.ct !== 'undefined') {
                        if (e.values.ct instanceof Array) {
                            e.values.ct = e.values.ct.join(",");
                        }
                    }

                    if (regions.length > 0) {
                        e.values['region'] = regions.join(',');
                    }

                    var url = EvaManager.url({
                        category: 'segments',
                        resource: 'variants',
                        query: regions,
//                        params:{merge:true}
                        params:{merge:true,exclude:'files'}
                    });

                    if(!_.isEmpty(e.values.studies)){
                        e.values.studies = e.values.studies.join(',');
                    }

                    _this.variantWidget.retrieveData(url, e.values)

                    if(e.values.species && e.values.species != 'chircus_10'){
                        var ensemblSepciesName = _.findWhere(speciesList, {taxonomyCode:e.values.species.split('_')[0]}).taxonomyScientificName;
                        ensemblSepciesName =  ensemblSepciesName.split(' ')[0]+'_'+ ensemblSepciesName.split(' ')[1];
                        var ensemblURL = 'http://www.ensembl.org/'+ensemblSepciesName+'/Variation/Explore?vdb=variation;v={id}';
                        var ncbiURL = 'http://www.ncbi.nlm.nih.gov/SNP/snp_ref.cgi?rs={id}';

                        var updateTpl = Ext.create('Ext.XTemplate', '<tpl if="id"> ' +
                            '' +
                            ' dbSNP' +
                            '<tpl else>  dbSNP</tpl>');
                    }else{
                        var updateTpl = Ext.create('Ext.XTemplate', '<tpl>  dbSNP</tpl>');
                    }

                    Ext.getCmp('variant-grid-view-column').tpl = updateTpl;
                }
            }
        });

        _this.on('studies:change', function (e) {
            _this.variantWidget.trigger('species:change', {values: _this.formPanelVariantFilter.getValues(), sender: _this});
            _this.formPanelVariantFilter.trigger('submit', {values: _this.formPanelVariantFilter.getValues(), sender: _this});
        });

//        formPanel.panel.addDocked({
//                                    xtype: 'toolbar',
//                                    dock: 'top',
//                                    height: 45,
//                                    html: '
Assembly: GRCh37
',
//                                    margin:-10
//                                });

        return formPanel;
    },
    _loadListStudies: function (filter, species) {
        var _this = this;
//        alert(species)
        var studies = [];
        var resource = '';
        if(_.isNull(species) ){
            resource = 'all'
        }else{
            resource = 'list'
        }
        EvaManager.get({
            category: 'meta/studies',
            resource: resource,
            params:{species:species},
            success: function (response) {
                try {
                    studies = response.response[0].result;
                } catch (e) {
                    console.log(e);
                }
                filter.studiesStore.loadRawData(studies);
                //set all records checked default
                filter.studiesStore.each(function(rec){
                    if(!_.isNull(species) ){
                        rec.set('uiactive', true)
                    }
                })
                _this.trigger('studies:change', {studies: studies, sender: _this});
            }
        });
    }

};

<commit_msg>variant widgte css overflow added<commit_after>/*
 * Copyright (c) 2014 Francisco Salavert (SGL-CIPF)
 * Copyright (c) 2014 Alejandro Alemán (SGL-CIPF)
 * Copyright (c) 2014 Ignacio Medina (EBI-EMBL)
 * Copyright (c) 2014 Jag Kandasamy (EBI-EMBL)
 *
 * This file is part of EVA.
 *
 * EVA is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * EVA is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with EVA. If not, see <http://www.gnu.org/licenses/>.
 */

function EvaVariantWidgetPanel(args) {
    var _this = this;
    _.extend(this, Backbone.Events);

    this.id = Utils.genId("VariantWidgetPanel");

    this.target;
    this.tools = [];
    _.extend(this, args);
    this.rendered = false;
    if (this.autoRender) {
        this.render();
    }
};

EvaVariantWidgetPanel.prototype = {
    render: function () {
        var _this = this;
        if(!this.rendered) {
            this.div = document.createElement('div');
            this.div.setAttribute('id', this.id);
            this.panel = this._createPanel();
            this.rendered = true;
        }

    },
    draw: function () {
        if(!this.rendered) {
            this.render();
        }
        this.targetDiv = (this.target instanceof HTMLElement ) ? this.target : document.querySelector('#' + this.target);
        if (!this.targetDiv) {
            console.log('EVAVariantWidgetPanel target not found');
            return;
        }
        this.targetDiv.appendChild(this.div);

        this.panel.render(this.div);

        this.variantWidgetDiv = document.querySelector('.variant-widget-div');
        this.variantWidget = this._createVariantWidget(this.variantWidgetDiv);
        this.variantWidget.draw();

        this.formPanelVariantFilterDiv = document.querySelector('.form-panel-variant-filter-div');
        this.formPanelVariantFilter = this._createFormPanelVariantFilter(this.formPanelVariantFilterDiv);
        this.formPanelVariantFilter.draw();
    },
    show: function () {
        this.panel.show()
    },
    hide: function () {
        this.panel.hide();
    },
    toggle: function () {
        if (this.panel.isVisible()) {
            this.panel.hide();
        } else {
            this.panel.show();
        }
    },
    _createPanel: function () {
        var tpl = new Ext.XTemplate(['

']);
        var view = Ext.create('Ext.view.View', {
            tpl: tpl
        });

        this.panel = Ext.create('Ext.panel.Panel', {
            overflowX:true,
            border:true,
            layout: {
                type: 'vbox',
                align: 'left'
            },
            items: [view],
            height:3800,
            cls: 'variant-widget-panel'
        });

        return  this.panel;
    },
    _createVariantWidget: function (target) {
//        var width = this.width - parseInt(this.div.style.paddingLeft) - parseInt(this.div.style.paddingRight);
        var evaVariantWidget = new EvaVariantWidget({
            width: 1020,
            target: target,
            headerConfig: {
                baseCls: 'eva-header-1'
            },
            border: true,
            browserGridConfig: {
//                title: 'Variant Browser Assembly:GRCh37',
                title: 'Variant Browser',
                border: true
            },
            toolPanelConfig: {
                title: 'Variant Data',
                headerConfig: {
                    baseCls: 'eva-header-2'
                }
            },
            defaultToolConfig: {
                headerConfig: {
                    baseCls: 'eva-header-2'
                },
                genomeViewer: false,
                effect:false,
                rawData:false
            },
            responseParser: function (response) {
                var res = [];
                try {
                    res = response.response[0].result;
                } catch (e) {
                    console.log(e);
                }
                return  res;
            },
            dataParser: function (data) {
                for (var i = 0; i < data.length; i++) {
                    var variant = data[i];
                    if (variant.hgvs && variant.hgvs.genomic > 0) {
                        variant.hgvs_name = variant.hgvs.genomic[0];
                    }
                }
            }
        }); //the div must exist

        return evaVariantWidget;
    },
    _createFormPanelVariantFilter: function (target) {
        var _this = this;
        var positionFilter = new EvaPositionFilterFormPanel({
//            testRegion: '1:14000-200000',
//            testRegion: '1:3000760-3004790',
            testRegion: '1:78383460-78383470',
            emptyText: ''

        });

        var speciesFilter = new SpeciesFilterFormPanel({});

        this.studiesStore = Ext.create('Ext.data.Store', {
            pageSize: 50,
            proxy: {
                type: 'memory'
            },
            fields: [
                {name: 'studyName', type: 'string'},
                {name: 'studyId', type: 'string'}
            ],
            autoLoad: false
        });

        var studyFilter = new EvaStudyFilterFormPanel({
            collapsed: false,
            height: 550,
            studiesStore: this.studiesStore,
            studyFilterTpl:'<tpl if="studyId">
{studyName} ({studyId})
<tpl else>
{studyName}
</tpl>'
        });

//        _this._loadListStudies(studyFilter, '');

        studyFilter.on('studies:change', function (e) {
            var studies = _this.formPanelVariantFilter.getValues().studies;
            var submitButton = Ext.getCmp(_this.formPanelVariantFilter.submitButtonId);
            if(_.isUndefined(studies)){
                Ext.Msg.alert('','Please Select at least one study');
                submitButton.disable();

            }else{
                submitButton.enable();

            }

        });

        speciesFilter.on('species:change', function (e) {
            _this._loadListStudies(studyFilter, e.species);

            EvaManager.get({
                category: 'meta/studies',
                resource: 'list',
                params:{species:e.species},
                success: function (response) {
                    try {
                         projects = response.response[0].result;
                    } catch (e) {
                        console.log(e);
                    }
                }
            });

        });

        var conseqType = new ConsequenceTypeFilterFormPanel({
            consequenceTypes: consequenceTypes,
            collapsed: true,
            fields: [
                {name: 'name', type: 'string'}
            ],
            columns: [
                {
                    xtype: 'treecolumn',
                    flex: 1,
                    sortable: false,
                    dataIndex: 'name'
                }
            ]
        });

        var formPanel = new FormPanel({
            title: 'Filter',
            headerConfig: {
                baseCls: 'eva-header-1'
            },
            mode: 'accordion',
            target: target,
            submitButtonText: 'Submit',
            submitButtonId: 'vb-submit-button',
            filters: [speciesFilter,positionFilter, studyFilter],
            width: 300,
//            height: 1043,
            border: false,
            handlers: {
                'submit': function (e) {
                    _this.variantWidget.setLoading(true);
                    //POSITION CHECK
                    var regions = [];
                    if (typeof e.values.region !== 'undefined') {
                        if (e.values.region !== "") {
                            regions = e.values.region.split(",");
                        }
                        delete  e.values.region;
                    }
                    if(!_.isUndefined(e.values.species)){
                        var cellBaseSpecies = e.values.species.split("_")[0];
                    }

                    if (typeof e.values.gene !== 'undefined') {
                        CellBaseManager.get({
                            species: cellBaseSpecies,
                            category: 'feature',
                            subCategory: 'gene',
                            query: e.values.gene.toUpperCase(),
                            resource: "info",
                            async: false,
                            params: {
                                include: 'chromosome,start,end'
                            },
                            success: function (data) {
                                for (var i = 0; i < data.response.length; i++) {
                                    var queryResult = data.response[i];
                                    if(!_.isEmpty(queryResult.result[0])){
                                        var region = new Region(queryResult.result[0]);
                                        regions.push(region.toString());
                                    }
                                }
                            }
                        });
                        delete  e.values.gene;
                    }

                    if (typeof e.values.snp !== 'undefined') {
                        CellBaseManager.get({
                            species: cellBaseSpecies,
                            category: 'feature',
                            subCategory: 'snp',
                            query: e.values.snp,
                            resource: "info",
                            async: false,
                            params: {
                                include: 'chromosome,start,end'
                            },
                            success: function (data) {
                                for (var i = 0; i < data.response.length; i++) {
                                    var queryResult = data.response[i];
                                    var region = new Region(queryResult.result[0]);
                                    var fields2 = (""+region).split(/[:-]/);
                                    if(parseInt(fields2[1]) > parseInt(fields2[2])) {
                                        var swap = fields2[1];
                                        region.start = fields2[2];
                                        region.end = swap;
                                    }
                                    regions.push(region.toString());
                                }
                            }
                        });
                        delete  e.values.snp;
                    }

                    //CONSEQUENCE TYPES CHECK
                    if (typeof e.values.ct !== 'undefined') {
                        if (e.values.ct instanceof Array) {
                            e.values.ct = e.values.ct.join(",");
                        }
                    }

                    if (regions.length > 0) {
                        e.values['region'] = regions.join(',');
                    }

                    var url = EvaManager.url({
                        category: 'segments',
                        resource: 'variants',
                        query: regions,
//                        params:{merge:true}
                        params:{merge:true,exclude:'files'}
                    });

                    if(!_.isEmpty(e.values.studies)){
                        e.values.studies = e.values.studies.join(',');
                    }

                    _this.variantWidget.retrieveData(url, e.values)

                    if(e.values.species && e.values.species != 'chircus_10'){
                        var ensemblSepciesName = _.findWhere(speciesList, {taxonomyCode:e.values.species.split('_')[0]}).taxonomyScientificName;
                        ensemblSepciesName =  ensemblSepciesName.split(' ')[0]+'_'+ ensemblSepciesName.split(' ')[1];
                        var ensemblURL = 'http://www.ensembl.org/'+ensemblSepciesName+'/Variation/Explore?vdb=variation;v={id}';
                        var ncbiURL = 'http://www.ncbi.nlm.nih.gov/SNP/snp_ref.cgi?rs={id}';

                        var updateTpl = Ext.create('Ext.XTemplate', '<tpl if="id"> ' +
                            '' +
                            ' dbSNP' +
                            '<tpl else>  dbSNP</tpl>');
                    }else{
                        var updateTpl = Ext.create('Ext.XTemplate', '<tpl>  dbSNP</tpl>');
                    }

                    Ext.getCmp('variant-grid-view-column').tpl = updateTpl;
                }
            }
        });

        _this.on('studies:change', function (e) {
            _this.variantWidget.trigger('species:change', {values: _this.formPanelVariantFilter.getValues(), sender: _this});
            _this.formPanelVariantFilter.trigger('submit', {values: _this.formPanelVariantFilter.getValues(), sender: _this});
        });

//        formPanel.panel.addDocked({
//                                    xtype: 'toolbar',
//                                    dock: 'top',
//                                    height: 45,
//                                    html: '
Assembly: GRCh37
',
//                                    margin:-10
//                                });

        return formPanel;
    },
    _loadListStudies: function (filter, species) {
        var _this = this;
//        alert(species)
        var studies = [];
        var resource = '';
        if(_.isNull(species) ){
            resource = 'all'
        }else{
            resource = 'list'
        }
        EvaManager.get({
            category: 'meta/studies',
            resource: resource,
            params:{species:species},
            success: function (response) {
                try {
                    studies = response.response[0].result;
                } catch (e) {
                    console.log(e);
                }
                filter.studiesStore.loadRawData(studies);
                //set all records checked default
                filter.studiesStore.each(function(rec){
                    if(!_.isNull(species) ){
                        rec.set('uiactive', true)
                    }
                })
                _this.trigger('studies:change', {studies: studies, sender: _this});
            }
        });
    }

};

<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';

class Hidden extends Component {

  static propTypes = {
    children: PropTypes.node
  };

  render () {
    const { children } = this.props;
    if (!children) return null;

    return [
      children
    ];
  }
}

export default Hidden;
<commit_msg>Rewrite Hidden<commit_after>import React from 'react';

const Hidden = ({ children = null}) => (
  [ children ]
)

export default Hidden;
<|endoftext|>


<commit_before>'use strict';
const validateAspectStatusRanges = require('../db/helpers/aspectUtils')
                                    .validateAspectStatusRanges;
const Aspect = require('../db/index').Aspect;

module.exports = {
  up(qi /* , Sequelize */) {
    /* If valueType is BOOLEAN or PERCENT and the current ranges wouldn't
     validate with new rules, change the valueType to NUMERIC.
     If valueType is NUMERIC, update invalid range with MIN and MAX NUMBER
     wherever applicable. */
    return qi.sequelize.transaction(() => {
      const aspQuery = 'SELECT * from "Aspects"';
      return qi.sequelize.query(aspQuery, {
        type: qi.sequelize.QueryTypes.SELECT,
      }).then((aspects) => {
        const promisesArr = [];
        aspects.forEach((asp) => {
          try {
            validateAspectStatusRanges(asp);
          } catch (err) {
            // if numeric, the only possible exception will be invalid range
            if (asp.valueType === 'NUMERIC') {
              const statusRangeMap = new Map();
              statusRangeMap.set('criticalRange', asp.criticalRange);
              statusRangeMap.set('warningRange', asp.warningRange);
              statusRangeMap.set('infoRange', asp.infoRange);
              statusRangeMap.set('okRange', asp.okRange);
              const updateObj = {};
              for (const [key, value] of statusRangeMap.entries()) {
                let minVal = value[0];
                let maxVal = value[1];

                if (value) {
                  if (value[0] < Number.MIN_SAFE_INTEGER ||
                    value[0] > Number.MAX_SAFE_INTEGER) {
                    minVal = Number.MIN_SAFE_INTEGER;
                  }

                  if (value[1] < Number.MIN_SAFE_INTEGER ||
                    value[1] > Number.MAX_SAFE_INTEGER) {
                    maxVal = Number.MAX_SAFE_INTEGER;
                  }

                  if (minVal !== value[0] || maxVal !== value[1]) {
                    updateObj[key] = [minVal, maxVal];
                  }
                }
              }

              if (Object.keys(updateObj).length !== 0) {
                promisesArr.push(
                  Aspect.update(updateObj, { where: { id: asp.id } })
                );
              }
            } else { // for all other exceptions, change valuetype to numeric
              promisesArr.push(Aspect.update(
                { valueType: 'NUMERIC' }, { where: { id: asp.id } }
              ));
            }
          }
        });

        // waits for all promises to resolve or reject
        return Promise.all(
          promisesArr.map((p) => p.catch(() => Promise.resolve()))
        );
      });
    });
  },

  // Not required to change the aspect rows back to previous vaueType.
  down: (queryInterface, Sequelize) => Promise.resolve(),
};
<commit_msg>null check (#1101)<commit_after>'use strict';
const validateAspectStatusRanges = require('../db/helpers/aspectUtils')
                                    .validateAspectStatusRanges;
const Aspect = require('../db/index').Aspect;

module.exports = {
  up(qi /* , Sequelize */) {
    /* If valueType is BOOLEAN or PERCENT and the current ranges wouldn't
     validate with new rules, change the valueType to NUMERIC.
     If valueType is NUMERIC, update invalid range with MIN and MAX NUMBER
     wherever applicable. */
    return qi.sequelize.transaction(() => {
      const aspQuery = 'SELECT * from "Aspects"';
      return qi.sequelize.query(aspQuery, {
        type: qi.sequelize.QueryTypes.SELECT,
      }).then((aspects) => {
        const promisesArr = [];
        aspects.forEach((asp) => {
          try {
            validateAspectStatusRanges(asp);
          } catch (err) {
            // if numeric, the only possible exception will be invalid range
            if (asp.valueType === 'NUMERIC') {
              const statusRangeMap = new Map();
              statusRangeMap.set('criticalRange', asp.criticalRange);
              statusRangeMap.set('warningRange', asp.warningRange);
              statusRangeMap.set('infoRange', asp.infoRange);
              statusRangeMap.set('okRange', asp.okRange);
              const updateObj = {};
              for (const [key, value] of statusRangeMap.entries()) {
                if (value) {
                  let minVal = value[0];
                  let maxVal = value[1];

                  if (value[0] < Number.MIN_SAFE_INTEGER ||
                    value[0] > Number.MAX_SAFE_INTEGER) {
                    minVal = Number.MIN_SAFE_INTEGER;
                  }

                  if (value[1] < Number.MIN_SAFE_INTEGER ||
                    value[1] > Number.MAX_SAFE_INTEGER) {
                    maxVal = Number.MAX_SAFE_INTEGER;
                  }

                  if (minVal !== value[0] || maxVal !== value[1]) {
                    updateObj[key] = [minVal, maxVal];
                  }
                }
              }

              if (Object.keys(updateObj).length !== 0) {
                promisesArr.push(
                  Aspect.update(updateObj, { where: { id: asp.id } })
                );
              }
            } else { // for all other exceptions, change valuetype to numeric
              promisesArr.push(Aspect.update(
                { valueType: 'NUMERIC' }, { where: { id: asp.id } }
              ));
            }
          }
        });

        // waits for all promises to resolve or reject
        return Promise.all(
          promisesArr.map((p) => p.catch(() => Promise.resolve()))
        );
      });
    });
  },

  // Not required to change the aspect rows back to previous vaueType.
  down: (queryInterface, Sequelize) => Promise.resolve(),
};
<|endoftext|>


<commit_before>'use strict';

// Create the 'chat' controller
angular.module('chat').controller('ChatController', ['$scope', '$location', 'Authentication', 'Socket',
  function ($scope, $location, Authentication, Socket) {
    // Create a messages array
    $scope.messages = [];

    // If user is not signed in then redirect back home
    if (!Authentication.user) {
      $location.path('/');
    }

    // Make sure the Socket is connected
    if (!Socket.socket) {
      Socket.connect();
    }

    // Add an event listener to the 'chatMessage' event
    Socket.on('chatMessage', function (message) {
      $scope.messages.unshift(message);
    });

    // Create a controller method for sending messages
    $scope.sendMessage = function () {
      // Create a new message object
      var message = {
        text: this.messageText
      };

      // Emit a 'chatMessage' message event
      Socket.emit('chatMessage', message);

      // Clear the message text
      this.messageText = '';
    };

    // Remove the event listener when the controller instance is destroyed
    $scope.$on('$destroy', function () {
      Socket.removeListener('chatMessage');
    });

    $scope.text = 'Hello';
    $scope.files = [];
    $scope.upload = () => {
      var input = angular.element('#fileinput');
      console.log(input);
      if (this.files && this.files[0]) {
        var FR = new FileReader();
        FR.onload = function (e) {
          angular.element('#fileimage').src = e.target.result;
          console.log(e.target.result);
        };
        FR.readAsDataURL(this.files[0]);
      } else {
        console.log('Not file');
      }
    };
  }
]);
<commit_msg>Commited from HaNhatLenh at Sat, Aug 19, 2017  1:58:49 AM<commit_after>'use strict';

// Create the 'chat' controller
angular.module('chat').controller('ChatController', ['$scope', '$location', 'Authentication', 'Socket',
  function ($scope, $location, Authentication, Socket) {
    // Create a messages array
    $scope.messages = [];

    // If user is not signed in then redirect back home
    if (!Authentication.user) {
      $location.path('/');
    }

    // Make sure the Socket is connected
    if (!Socket.socket) {
      Socket.connect();
    }

    // Add an event listener to the 'chatMessage' event
    Socket.on('chatMessage', function (message) {
      $scope.messages.unshift(message);
    });

    // Create a controller method for sending messages
    $scope.sendMessage = function () {
      // Create a new message object
      var message = {
        text: this.messageText
      };

      // Emit a 'chatMessage' message event
      Socket.emit('chatMessage', message);

      // Clear the message text
      this.messageText = '';
    };

    // Remove the event listener when the controller instance is destroyed
    $scope.$on('$destroy', function () {
      Socket.removeListener('chatMessage');
    });

    $scope.text = 'Hello';
    $scope.files = [];
    $scope.upload = () => {
      var input = angular.element('#fileinput');
      console.log(input);
      if (input.files && input.files[0]) {
        var FR = new FileReader();
        FR.onload = function (e) {
          angular.element('#fileimage').src = e.target.result;
          console.log(e.target.result);
        };
        FR.readAsDataURL(input.files[0]);
      } else {
        console.log('Not file');
      }
    };
  }
]);
<|endoftext|>


<commit_before>'use strict';

var path = require('path'),
    errorService = require('../services/error.server.service'),
    userProfile = require(path.resolve('./modules/users/server/controllers/users.profile.server.controller')),
    textService = require(path.resolve('./modules/core/server/services/text.server.service')),
    config = require(path.resolve('./config/config')),
    log = require(path.resolve('./config/lib/logger'));

/**
 * Render the main application page
 */
exports.renderIndex = function (req, res) {

  var renderVars = {
    user: null
  };

  // Expose user
  if (req.user) {
    renderVars.user = userProfile.sanitizeProfile(req.user, req.user);
  }

  // Expose tribe (when browsing `/tribes/tribe-name`)
  if (req.tribe) {
    renderVars.tribe = req.tribe;
  }

  // Show different `og:` tags for signup pages
  // https://expressjs.com/en/api.html#req.path
  if (req.path === '/signup') {
    renderVars.invite = true;
  }

  res.render('index.server.view.html', renderVars);
};

/**
 * Render the server not found responses
 * Performs content-negotiation on the Accept HTTP header
 */
exports.renderNotFound = function (req, res) {
  res.status(404).format({
    'text/html': function () {
      res.render('404.server.view.html');
    },
    'application/json': function () {
      res.json({ message: errorService.getErrorMessageByKey('not-found') });
    },
    'default': function () {
      res.send(errorService.getErrorMessageByKey('not-found'));
    }
  });
};

/**
 * Log received CSP violation report
 * See `config/lib/express.js` and `initHelmetHeaders()` for more
 */
exports.receiveCSPViolationReport = function (req, res) {
  if (process.env.NODE_ENV !== 'test') {
    log('warn', 'CSP violation report #ljeanw', {
      report: req.body ? textService.html(req.body) : 'No report available.'
    });
  }
  res.status(204).json();
};

/**
 * Log received CT report
 * See `config/lib/express.js` and `initHelmetHeaders()` for more
 * @link https://helmetjs.github.io/docs/expect-ct/
 * @link https://scotthelme.co.uk/a-new-security-header-expect-ct/
 */
exports.receiveExpectCTViolationReport = function (req, res) {
  if (process.env.NODE_ENV !== 'test') {
    log('warn', 'Expect-CT violation report #3hg8ha', {
      report: req.body ? textService.html(req.body) : 'No report available.'
    });
  }
  res.status(204).json();
};

/**
* Render javascript content containing service worker config.
*/
exports.renderServiceWorkerConfig = function (req, res) {
  res.set('Content-Type', 'text/javascript')
    .send('var FCM_SENDER_ID = ' + JSON.stringify(config.fcm.senderId) + ';\n');
};
<commit_msg>Log CSP violation reports in plain text<commit_after>'use strict';

var path = require('path'),
    errorService = require('../services/error.server.service'),
    userProfile = require(path.resolve('./modules/users/server/controllers/users.profile.server.controller')),
    textService = require(path.resolve('./modules/core/server/services/text.server.service')),
    config = require(path.resolve('./config/config')),
    log = require(path.resolve('./config/lib/logger'));

/**
 * Render the main application page
 */
exports.renderIndex = function (req, res) {

  var renderVars = {
    user: null
  };

  // Expose user
  if (req.user) {
    renderVars.user = userProfile.sanitizeProfile(req.user, req.user);
  }

  // Expose tribe (when browsing `/tribes/tribe-name`)
  if (req.tribe) {
    renderVars.tribe = req.tribe;
  }

  // Show different `og:` tags for signup pages
  // https://expressjs.com/en/api.html#req.path
  if (req.path === '/signup') {
    renderVars.invite = true;
  }

  res.render('index.server.view.html', renderVars);
};

/**
 * Render the server not found responses
 * Performs content-negotiation on the Accept HTTP header
 */
exports.renderNotFound = function (req, res) {
  res.status(404).format({
    'text/html': function () {
      res.render('404.server.view.html');
    },
    'application/json': function () {
      res.json({ message: errorService.getErrorMessageByKey('not-found') });
    },
    'default': function () {
      res.send(errorService.getErrorMessageByKey('not-found'));
    }
  });
};

/**
 * Log received CSP violation report
 * See `config/lib/express.js` and `initHelmetHeaders()` for more
 */
exports.receiveCSPViolationReport = function (req, res) {
  if (process.env.NODE_ENV !== 'test') {
    log('warn', 'CSP violation report #ljeanw', {
      report: req.body ? textService.plainText(JSON.stringify(req.body)) : 'No report available.'
    });
  }
  res.status(204).json();
};

/**
 * Log received CT report
 * See `config/lib/express.js` and `initHelmetHeaders()` for more
 * @link https://helmetjs.github.io/docs/expect-ct/
 * @link https://scotthelme.co.uk/a-new-security-header-expect-ct/
 */
exports.receiveExpectCTViolationReport = function (req, res) {
  if (process.env.NODE_ENV !== 'test') {
    log('warn', 'Expect-CT violation report #3hg8ha', {
      report: req.body ? textService.plainText(JSON.stringify(req.body)) : 'No report available.'
    });
  }
  res.status(204).json();
};

/**
* Render javascript content containing service worker config.
*/
exports.renderServiceWorkerConfig = function (req, res) {
  res.set('Content-Type', 'text/javascript')
    .send('var FCM_SENDER_ID = ' + JSON.stringify(config.fcm.senderId) + ';\n');
};
<|endoftext|>


<commit_before>'use strict';

/**
 * Task that checks for unread messages from the DB and sends
 * notification emails for users who have unread messages.
 *
 * Won't notify for very fresh (10min) messages, or else
 * people would get email for each line of chat message somebody writes.
 *
 * Also if people are reading their messages (and thus messages get marked read),
 * notifications aren't sent.
 *
 * This whole task might be a bit memory intensive (aggregate specificly).
 */

/**
 * Module dependencies.
 */
var _ = require('lodash'),
    path = require('path'),
    emailService = require(path.resolve('./modules/core/server/services/email.server.service')),
    async = require('async'),
    moment = require('moment'),
    mongoose = require('mongoose'),
    Message = mongoose.model('Message'),
    User = mongoose.model('User');

module.exports = function(job, agendaDone) {
  async.waterfall([

    // Aggregate unread messages
    function(done) {

      // Ignore very recent messages and look for only older than 10 minutes
      // Has to be a JS Date object, not a Moment object
      var createdTimeAgo = moment().subtract(moment.duration({ 'minutes': 10 })).toDate();

      Message.aggregate([
        {
          $match: {
            read: false,
            notified: false,
            created: { $lt: createdTimeAgo }
          }
        },
        {
          $group: {

            // Group separate emails
            _id: {
              'userTo': '$userTo',
              'userFrom': '$userFrom'
            },

            // Collect unread messages count
            total: { $sum: 1 },

            // Collect message contents
            messages: { $push: { id: '$_id', content: '$content' } }
          }
        }
      ], function(err, notifications) {
        done(err, notifications);
      });

    },

    // Fetch userTo and userFrom  email + displayName
    function(notifications, done) {

      var userIds = [];

      notifications.forEach(function(notification) {
        // Collect user ids
        userIds.push(notification._id.userTo, notification._id.userFrom);
      });

      // Make sure we don't have huge list of dublicate user ids
      // @link https://lodash.com/docs#uniq
      userIds = _.uniq(userIds);

      // Fetch email + displayName for all users involved
      // Remember to add these values also userNotFound object (see below)
      if (userIds.length > 0) {
        User
          .find({ '_id': { $in: userIds } }, 'email displayName username')
          .exec(function(err, users) {

            // Re-organise users into more handy array
            var usersArr = [];
            if (users) {
              users.forEach(function(user) {
                usersArr[user._id] = user;
              });
            }

            done(err, usersArr, notifications);
          });
      } else {
        done(null, [], notifications);
      }
    },

    // Send emails
    function(users, notifications, done) {

      var notificationsToProcess = notifications.length;
      var messageIds = [];

      if (notificationsToProcess > 0) {

        // Create a queue worker to send notifications in parallel
        // Process at most 3 notifications at the same time
        // @link https://github.com/caolan/async#queueworker-concurrency
        var notificationsQueue = async.queue(function (notification, notificationCallback) {

          var userTo = (users[notification._id.userTo.toString()]) ? users[notification._id.userTo.toString()] : false,
              userFrom = (users[notification._id.userFrom.toString()]) ? users[notification._id.userFrom.toString()] : false;

          // Collect message ids for updating documents to `notified:true` later
          notification.messages.forEach(function(message) {
            messageIds.push(message.id);
          });

          // If we don't have info about these users, they've been removed.
          // Don't send notification mail in such case.
          // Message will still be marked as notified.
          if (!userFrom || !userTo) {
            return notificationCallback(new Error('Could not find all users relevant for this message to notify about.'));
          }

          emailService.sendMessagesUnread(userFrom, userTo, notification, notificationCallback);

        }, 5); // How many notifications to process simultaneously?

        // Start processing notifications
        notificationsQueue.push(notifications);

        // Assign a final callback to work queue
        // All notification jobs done, continue
        notificationsQueue.drain = function(err) {
          if (err) {
            console.error('Sending message notification mails caused an error:');
            console.error(err);
          }
          done(null, messageIds);
        };
      } else {
        // No users to send emails to
        done(null, []);
      }

    },

    // Mark messages notified
    function(messageIds, done) {

      if (messageIds.length > 0) {
        Message.update(
          { _id: { '$in': messageIds } },
          { $set: { notified: true } },
          { multi: true },
          function(err) {
            if (err) {
              console.error('Error while marking messages as notified.');
              console.error(err);
            }
            done(err);
          });
      } else {
        done(null);
      }

    }

  ], function(err) {
    // Wrap it up
    return agendaDone(err);
  });

};
<commit_msg>Restructure unread messages job<commit_after>'use strict';

/**
 * Task that checks for unread messages from the DB and sends
 * notification emails for users who have unread messages.
 *
 * Won't notify for very fresh (10min) messages, or else
 * people would get email for each line of chat message somebody writes.
 *
 * Also if people are reading their messages (and thus messages get marked read),
 * notifications aren't sent.
 *
 * This whole task might be a bit memory intensive (aggregate specificly).
 */

/**
 * Module dependencies.
 */
var _ = require('lodash'),
    path = require('path'),
    emailService = require(path.resolve('./modules/core/server/services/email.server.service')),
    log = require(path.resolve('./config/lib/logger')),
    async = require('async'),
    moment = require('moment'),
    mongoose = require('mongoose'),
    Message = mongoose.model('Message'),
    User = mongoose.model('User');

module.exports = function(job, agendaDone) {
  async.waterfall([

    // Aggregate unread messages
    function(done) {

      // Ignore very recent messages and look for only older than 10 minutes
      // Has to be a JS Date object, not a Moment object
      var createdTimeAgo = moment().subtract(moment.duration({ 'minutes': 10 })).toDate();

      Message.aggregate([
        {
          $match: {
            read: false,
            notified: false,
            created: { $lt: createdTimeAgo }
          }
        },
        {
          $group: {

            // Group separate emails
            _id: {
              'userTo': '$userTo',
              'userFrom': '$userFrom'
            },

            // Collect unread messages count
            total: { $sum: 1 },

            // Collect message contents
            messages: { $push: { id: '$_id', content: '$content' } }
          }
        }
      ], function(err, notifications) {
        done(err, notifications);
      });

    },

    // Fetch `userTo` and `userFrom`  email + displayName
    function(notifications, done) {

      var userIds = [];

      // Collect all user ids from notifications
      notifications.forEach(function(notification) {
        userIds.push(notification._id.userTo, notification._id.userFrom);
      });

      // Make sure we don't have huge list of dublicate user ids
      // @link https://lodash.com/docs#uniq
      userIds = _.uniq(userIds);

      // Fetch email + displayName for all users involved
      // Remember to add these values also userNotFound object (see below)
      if (userIds.length > 0) {
        User
          .find(
          { '_id': { $in: userIds } },
          [
            // Fields to get for each user:
            'email',
            'displayName',
            'username'
          ].join(' ')
          )
          .exec(function(err, users) {

            // Re-organise users into more handy array (`collectedUsers`)
            var collectedUsers = {};
            if (users) {
              users.forEach(function(user) {
                // @link https://lodash.com/docs/#set
                _.set(collectedUsers, user._id.toString(), user);
              });
            }

            done(err, collectedUsers, notifications);
          });
      } else {
        done(null, [], notifications);
      }
    },

    // Broadcast notifications
    function(users, notifications, done) {

      // No users to send emails to
      if (!notifications.length) {
        return done(null, []);
      }

      // Create a queue worker to send notifications in parallel
      // Process at most 3 notifications at the same time
      // @link https://github.com/caolan/async#queueworker-concurrency
      var notificationsQueue = async.queue(function (notification, notificationCallback) {

        // Get users for this notification
        var userTo = _.get(users, notification._id.userTo.toString(), false),
            userFrom = _.get(users, notification._id.userFrom.toString(), false);

        // If we don't have info about these users, they've been removed.
        // Don't send notification mail in such case.
        // Message will still be marked as notified.
        if (!userFrom || !userTo) {
          return notificationCallback(new Error('Could not find all users relevant for this message to notify about.'));
        }

        // Process email notifications
        emailService.sendMessagesUnread(userFrom, userTo, notification, notificationCallback);

        // Process all types of notifications in series
        // @link https://caolan.github.io/async/docs.html#series
        // After all methods are done, calls `notificationCallback(err, res)`
        /*
        async.series({
          email: function(callback) {
            emailService.sendMessagesUnread(userFrom, userTo, notification, callback);
          }
          // More notification methods come here...
        }, notificationCallback);
        */

      }, 5); // How many notifications to process simultaneously?

      // Start processing notifications
      notificationsQueue.push(notifications);

      // Assign a final callback to work queue
      // All notification jobs done, continue
      notificationsQueue.drain = function(err) {
        // Log detected error but don't stop processing this job because of it
        // Otherwise this job might get stuck infinitely for some notification
        if (err) {
          // Log the failure to send the notification
          log('error', 'Sending unread message notifications caused an error. #j38vax', {
            error: err
          });
        }
        done(null, notifications);
      };
    },

    // Mark messages notified
    function(notifications, done) {

      // No notifications
      if (notifications.length === 0) {
        return done(null);
      }

      // Holds ids of messages to be set `notified:true`
      var messageIds = [];

      // Collect message ids for updating documents to `notified:true` later
      for (var i = 0, len = notifications.length; i < len; i++) {
        if (notifications[i].messages) {
          notifications[i].messages.forEach(function(message) {
            messageIds.push(message.id);
          });
        }
      }

      // No message ids (shouldn't happen, but just in case)
      if (messageIds.length === 0) {
        // Log the failure to send the notification
        log('warn', 'No messages to set notified. This probably should not happen. #hg38vs');
        return done(null);
      }

      // Update messages using ids
      Message.update(
        { _id: { '$in': messageIds } },
        { $set: { notified: true } },
        { multi: true },
        function(err) {
          if (err) {
            // Log the failure to send the notification
            log('error', 'Error while marking messages as notified. #9ehvbn', {
              error: err
            });
          }
          // Now fail the job if error happens
          done(err);
        });

    }

  ], function(err) {
    // Wrap it up
    return agendaDone(err);
  });

};
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies.
 */
var path = require('path'),
  mongoose = require('mongoose'),
  config = require(path.resolve('./config/config')),
  Tag = mongoose.model('Tag'),
  Polltag = mongoose.model('Polltag'),
  Polltag = mongoose.model('Polltag'),
  errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')),
  _ = require('lodash');
var pollController = require(path.resolve('./modules/polls/server/controllers/polls.server.controller'));

/**
 * Create a Tag
 */
exports.create = function (req, res) {
  var tag = new Tag(req.body);
  tag.user = req.user;

  tag.save(function (err) {
    if (err) {
      return res.status(400).send({
        message: errorHandler.getErrorMessage(err)
      });
    } else {
      res.jsonp(tag);
    }
  });
};

/**
 * Show the current Tag
 */
exports.read = function (req, res) {
  // convert mongoose document to JSON
  var tag = req.tag ? req.tag.toJSON() : {};

  // Add a custom field to the Article, for determining if the current User is the "owner".
  // NOTE: This field is NOT persisted to the database, since it doesn't exist in the Article model.
  tag.isCurrentUserOwner = req.user && tag.user && tag.user._id.toString() === req.user._id.toString();
  res.jsonp(tag);
};

/**
 * Update a Tag
 */
exports.update = function (req, res) {
  var tag = req.tag;

  tag = _.extend(tag, req.body);

  tag.save(function (err) {
    if (err) {
      return res.status(400).send({
        message: errorHandler.getErrorMessage(err)
      });
    } else {
      res.jsonp(tag);
    }
  });
};

/**
 * Delete an Tag
 */
exports.delete = function (req, res) {
  var tag = req.tag;

  tag.remove()
    .then(() => {
      return Polltag.remove({ tag: tag._id });
    }, handleError)
    .then(() => {
      res.jsonp(tag);
    }, handleError);

  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};

/**
 * List of Tags
 */
exports.list = function (req, res) {
  Tag.find().exec()
    .then(tags => {
      if (tags.length === 0) return res.jsonp(tags);
      var length = tags.length;
      var counter = 0;
      tags.forEach(function (instance, index, array) {
        array[index] = instance.toObject();
        count_polls_by_tagId(array[index]._id)
          .then(result => {
            array[index].count = result || 0;
            if (++counter === length) {
              res.jsonp(tags);
            }
          })
          .catch(err => {
            handleError(err);
          });
      });
    }, handleError);

  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};

/**
 * Tag middleware
 */
exports.tagByID = function (req, res, next, id) {

  var query = { $or: [{ slug: id }] };
  if (id.match(/^[0-9a-fA-F]{24}$/)) {
    query.$or.push({ _id: id });
  }

  Tag.findOne(query).populate('user', 'displayName slug').exec(function (err, tag) {
    if (err) {
      return res.status(400).send({
        message: 'Tag is invalid'
      });
    } else if (!tag) {
      return res.status(404).send({
        message: 'No Tag with that identifier has been found'
      });
    }
    req.tag = tag;
    next();
  });
};

exports.popular = function (req, res) {
  Tag.find().exec()
    .then(tags => {
      if (tags.length === 0) return res.jsonp(tags);
      var length = tags.length;
      var counter = 0;
      tags.forEach(function (instance, index, array) {
        array[index] = instance.toObject();
        count_polls_by_tagId(array[index]._id)
          .then(result => {
            array[index].count = result || 0;
            if (++counter === length) {
              tags = _.sortByOrder(tags, ['count'], ['desc']);
              tags = tags.splice(0, 10);
              res.jsonp(tags);
            }
          })
          .catch(err => {
            handleError(err);
          });
      });
    }, handleError);

  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};
/**
 * List poll su dung tag
 */
exports.polls = function (req, res) {
  var userId = req.user ? req.user._id : undefined;
  var page = req.params.page || 0;
  var language = req.params.language || config.mappingLanguages[req.locale];
  var sort = req.params.page || '-created';
  get_polls_by_tagId(req.tag._id, page, language)
    .then(polls => {
      if (polls.length === 0) return res.jsonp(polls);
      var length = polls.length;
      var counter = 0;
      polls.forEach(function (instance, index, array) {
        array[index] = instance.toObject();
        pollController.get_full_by_pollId(array[index]._id, userId)
          .then(result => {
            array[index].opts = result.opts;
            array[index].votes = result.votes;
            array[index].voteopts = result.voteopts;
            array[index].follow = result.follow;
            array[index].reported = result.reported;
            array[index].bookmarked = result.bookmarked;
            if (++counter === length) {
              res.jsonp(polls);
            }
          })
          .catch(handleError);
      });
    })
    .catch(handleError);

  function handleError(err) {
    console.log(err);
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};
/**
 * Đếm số poll trong tag
 */
function get_polls_by_tagId(tagId, page, language) {
  return new Promise((resolve, reject) => {
    Polltag.find({ tag: tagId })
      .populate({
        path: 'poll',
        model: 'Poll',
        match: { language: language },
        populate: [
          { path: 'user', select: 'displayName profileImageURL slug', model: 'User' },
          { path: 'category', select: 'name icon slug', model: 'Category' }
        ]
      })
      .skip(10 * page).limit(10)
      .exec((err, polltags) => {
        if (err) {
          return reject(err);
        } else {
          var polls = _.pluck(polltags, 'poll');
          return resolve(polls);
        }
      });
  });
}

/**
 * Đếm số poll trong tag
 */
function count_polls_by_tagId(tagId) {
  return new Promise((resolve, reject) => {
    Polltag.find({ tag: tagId })
      .count(function (err, count) {
        if (err) {
          return reject(err);
        } else {
          return resolve(count);
        }
      });
  });
}
<commit_msg>Commited from lenh at Mon, Sep 25, 2017  1:48:39 PM<commit_after>'use strict';

/**
 * Module dependencies.
 */
var path = require('path'),
  mongoose = require('mongoose'),
  config = require(path.resolve('./config/config')),
  Tag = mongoose.model('Tag'),
  Polltag = mongoose.model('Polltag'),
  Polltag = mongoose.model('Polltag'),
  errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')),
  _ = require('lodash');
var pollController = require(path.resolve('./modules/polls/server/controllers/polls.server.controller'));

/**
 * Create a Tag
 */
exports.create = function (req, res) {
  var tag = new Tag(req.body);
  tag.user = req.user;

  tag.save(function (err) {
    if (err) {
      return res.status(400).send({
        message: errorHandler.getErrorMessage(err)
      });
    } else {
      res.jsonp(tag);
    }
  });
};

/**
 * Show the current Tag
 */
exports.read = function (req, res) {
  // convert mongoose document to JSON
  var tag = req.tag ? req.tag.toJSON() : {};

  // Add a custom field to the Article, for determining if the current User is the "owner".
  // NOTE: This field is NOT persisted to the database, since it doesn't exist in the Article model.
  tag.isCurrentUserOwner = req.user && tag.user && tag.user._id.toString() === req.user._id.toString();
  res.jsonp(tag);
};

/**
 * Update a Tag
 */
exports.update = function (req, res) {
  var tag = req.tag;

  tag = _.extend(tag, req.body);

  tag.save(function (err) {
    if (err) {
      return res.status(400).send({
        message: errorHandler.getErrorMessage(err)
      });
    } else {
      res.jsonp(tag);
    }
  });
};

/**
 * Delete an Tag
 */
exports.delete = function (req, res) {
  var tag = req.tag;

  tag.remove()
    .then(() => {
      return Polltag.remove({ tag: tag._id });
    }, handleError)
    .then(() => {
      res.jsonp(tag);
    }, handleError);

  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};

/**
 * List of Tags
 */
exports.list = function (req, res) {
  Tag.find().exec()
    .then(tags => {
      if (tags.length === 0) return res.jsonp(tags);
      var length = tags.length;
      var counter = 0;
      tags.forEach(function (instance, index, array) {
        array[index] = instance.toObject();
        count_polls_by_tagId(array[index]._id)
          .then(result => {
            array[index].count = result || 0;
            if (++counter === length) {
              res.jsonp(tags);
            }
          })
          .catch(err => {
            handleError(err);
          });
      });
    }, handleError);

  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};

/**
 * Tag middleware
 */
exports.tagByID = function (req, res, next, id) {

  var query = { $or: [{ slug: id }] };
  if (id.match(/^[0-9a-fA-F]{24}$/)) {
    query.$or.push({ _id: id });
  }

  Tag.findOne(query).populate('user', 'displayName slug').exec(function (err, tag) {
    if (err) {
      return res.status(400).send({
        message: 'Tag is invalid'
      });
    } else if (!tag) {
      return res.status(404).send({
        message: 'No Tag with that identifier has been found'
      });
    }
    req.tag = tag;
    next();
  });
};

exports.popular = function (req, res) {
  Tag.find().exec()
    .then(tags => {
      if (tags.length === 0) return res.jsonp(tags);
      var length = tags.length;
      var counter = 0;
      tags.forEach(function (instance, index, array) {
        array[index] = instance.toObject();
        count_polls_by_tagId(array[index]._id)
          .then(result => {
            array[index].count = result || 0;
            if (++counter === length) {
              tags = _.sortByOrder(tags, ['count'], ['desc']);
              tags = tags.splice(0, 10);
              res.jsonp(tags);
            }
          })
          .catch(err => {
            handleError(err);
          });
      });
    }, handleError);

  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};
/**
 * List poll su dung tag
 */
exports.polls = function (req, res) {
  var userId = req.user ? req.user._id : undefined;
  var page = req.params.page || 0;
  var language = req.params.language || config.mappingLanguages[req.locale];
  var sort = req.params.page || '-created';
  get_polls_by_tagId(req.tag._id, page, language)
    .then(polls => {
      if (polls.length === 0) return res.jsonp(polls);
      var length = polls.length;
      var counter = 0;
      polls.forEach(function (instance, index, array) {
        array[index] = instance.toObject();
        pollController.get_full_by_pollId(array[index]._id, userId)
          .then(result => {
            array[index].opts = result.opts;
            array[index].votes = result.votes;
            array[index].voteopts = result.voteopts;
            array[index].follow = result.follow;
            array[index].reported = result.reported;
            array[index].bookmarked = result.bookmarked;
            if (++counter === length) {
              res.jsonp(polls);
            }
          })
          .catch(handleError);
      });
    })
    .catch(handleError);

  function handleError(err) {
    console.log(err);
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};
/**
 * Đếm số poll trong tag
 */
function get_polls_by_tagId(tagId, page, language) {
  return new Promise((resolve, reject) => {
    Polltag.find({ tag: tagId })
      .populate({
        path: 'poll',
        model: 'Poll',
        match: { language: language },
        populate: [
          { path: 'user', select: 'displayName profileImageURL slug', model: 'User' },
          { path: 'category', select: 'name icon slug', model: 'Category' }
        ]
      })
      .skip(10 * page).limit(10)
      .exec((err, polltags) => {
        if (err) {
          return reject(err);
        } else {
          console.log(polltags);
          var polls = _.pluck(polltags, 'poll');
          return resolve(polls);
        }
      });
  });
}

/**
 * Đếm số poll trong tag
 */
function count_polls_by_tagId(tagId) {
  return new Promise((resolve, reject) => {
    Polltag.find({ tag: tagId })
      .count(function (err, count) {
        if (err) {
          return reject(err);
        } else {
          return resolve(count);
        }
      });
  });
}
<|endoftext|>


<commit_before>Template.wizardRegistrant.helpers({
  "registrantAgeIsBelow": function (ageThreshold) {
    // Get current age value from form
    let age = AutoForm.getFieldValue("age")

    if (age) {
      // Compare current value versus desired age threshold
      return age < ageThreshold;
    }
  },
  "registrantAgeIsBetween": function (lowerAge, upperAge) {
    /*
    Check if registrant age is within lower age and upper age limits (inclusive)
    */

    // Get current age value from form
    let age = AutoForm.getFieldValue("age")

    if (age) {
      // Compare current value versus desired age range
      return (lowerAge <= age) && (age <= upperAge);
    }
  },
  "yesNoOptions": function () {
    return [
      {label: "Yes", value: "yes"},
      {label: "No", value: "no"}
    ];
  }
});
<commit_msg>Add registrantAgeIs helper<commit_after>Template.wizardRegistrant.helpers({
  "registrantAgeIs": function (age) {
    // Get current age value from form
    let registrantAge = AutoForm.getFieldValue("age")

    if (age) {
      // Compare current value versus desired age threshold
      return registrantAge === age;
    }
  },
  "registrantAgeIsBelow": function (ageThreshold) {
    // Get current age value from form
    let age = AutoForm.getFieldValue("age")

    if (age) {
      // Compare current value versus desired age threshold
      return age < ageThreshold;
    }
  },
  "registrantAgeIsBetween": function (lowerAge, upperAge) {
    /*
    Check if registrant age is within lower age and upper age limits (inclusive)
    */

    // Get current age value from form
    let age = AutoForm.getFieldValue("age")

    if (age) {
      // Compare current value versus desired age range
      return (lowerAge <= age) && (age <= upperAge);
    }
  },
  "yesNoOptions": function () {
    return [
      {label: "Yes", value: "yes"},
      {label: "No", value: "no"}
    ];
  }
});
<|endoftext|>


<commit_before>var net = require('net');

var Melted = {
    server: false,
    response: false,
    command: false,
    addFile: function(file) {
        this.sendCommand("uls");
        if (this.response.toLowerCase().indexOf("u0") == -1) {
            this.sendCommand("uadd sdl");
            this.sendCommand("load u0 " + file);
            this.sendCommand("play u0");
        } else {
            this.sendCommand("apnd u0");
        }
        console.log("Response: " + this.response);
        return this.response;
    },
    initServer: function() {
        this.server = new net.createConnection(5250);
        this.server.setEncoding('ascii');
        this.server.addListener("connect", function() {
            console.log("Connected to Melted Server" );
        });
        this.server.on('error', function(err) {
            console.log("Could not connect to Melted Server");
            console.log(err.toString());
        });
        this.server.on("data", this.bind(this, this.appendResponse));
        this.server.addListener("end", this.bind(this, this.parseResponse));
    },
    parseResponse: function() {
        var str = this.response.toString();
        str = str.replace(/100 VTR Ready\r\n20. OK\r\n/g, "");
        switch (this.command) {
        case 'usta':
            //0 playing "colour:green" 13632 1000 25.00 0 14999 15000 "colour:green" 13632 0 14999 15000 1 2 0
            var split = str.split("\"");
            var JSONresponse = {};
            JSONresponse.status = split[0];
            JSONresponse.filename = split[1];
            var splits = split[2].split("\ ");
            JSONresponse.position = splits[1];
                            JSONresponse.speed = splits[2];
            JSONresponse.fps = splits[3];
            JSONresponse.inpoint = splits[4];
            JSONresponse.outpoint = splits[5];
            JSONresponse.length = splits[6];
            JSONresponse.b_filename = split[3];

            splits = split[4].split("\ ");
            JSONresponse.b_position = splits[1];
            JSONresponse.b_inpoint = splits[2];
            JSONresponse.b_outpoint = splits[3];
            JSONresponse.b_length = splits[4];
            JSONresponse.seekable = splits[5];
            JSONresponse.playlist_number = splits[6];
            JSONresponse.clip_index = splits[7].replace(/\r\n/g, "");
            str = JSON.stringify(JSONresponse);
            this.response = str;
            break;
        case 'list':
            //"2\r\n0 \"colour:green\" 0 14999 15000 15000 25.00\r\n1 \"colour:red\" 0 14999 15000 15000 25.00\r\n\r\n"
            split = str.split("\r\n");
            JSONresponse = {};
            var len = (split.length - 2);
            for (var i = 1; i < len; i++) {
                JSONresponse.clips = {
                    "name": split[i]
                };
            }
            str = JSON.stringify(JSONresponse);
            this.response = str;
            break;
        case "uls":
            split = str.split("\r\n");
                            JSONresponse = {};
            len = (split.length - 2);
            for (i = 1; i < len; i++) {
                JSONresponse.clips = {
                    "unit": split[i]
                };
            }
            str = JSON.stringify(JSONresponse);
            this.response = str;
            break;
        default:
            this.response = "OK";
        }
    },
    appendResponse: function(data) {
        this.response += data;
    },
    bind: function(scope, fn) {
        return function () {
                        fn.apply(scope, arguments);
        };
    },
    sendCommand: function(command) {
        var split = command.split(" ");
        this.command = split[0];
        if (!this.server) {
            this.initServer();
        }
                    this.response = "";
        console.log("Command: " + command);
        this.server.write(command + "\n");
    },
};
<commit_msg>initServer, really, is connect()<commit_after>var net = require('net');

var Melted = {
    server: false,
    response: false,
    command: false,
    addFile: function(file) {
        this.sendCommand("uls");
        if (this.response.toLowerCase().indexOf("u0") == -1) {
            this.sendCommand("uadd sdl");
            this.sendCommand("load u0 " + file);
            this.sendCommand("play u0");
        } else {
            this.sendCommand("apnd u0");
        }
        console.log("Response: " + this.response);
        return this.response;
    },
    connect: function() {
        this.server = new net.createConnection(5250);
        this.server.setEncoding('ascii');
        this.server.addListener("connect", function() {
            console.log("Connected to Melted Server" );
        });
        this.server.on('error', function(err) {
            console.log("Could not connect to Melted Server");
            console.log(err.toString());
        });
        this.server.on("data", this.bind(this, this.appendResponse));
        this.server.addListener("end", this.bind(this, this.parseResponse));
    },
    parseResponse: function() {
        var str = this.response.toString();
        str = str.replace(/100 VTR Ready\r\n20. OK\r\n/g, "");
        switch (this.command) {
        case 'usta':
            //0 playing "colour:green" 13632 1000 25.00 0 14999 15000 "colour:green" 13632 0 14999 15000 1 2 0
            var split = str.split("\"");
            var JSONresponse = {};
            JSONresponse.status = split[0];
            JSONresponse.filename = split[1];
            var splits = split[2].split("\ ");
            JSONresponse.position = splits[1];
                            JSONresponse.speed = splits[2];
            JSONresponse.fps = splits[3];
            JSONresponse.inpoint = splits[4];
            JSONresponse.outpoint = splits[5];
            JSONresponse.length = splits[6];
            JSONresponse.b_filename = split[3];

            splits = split[4].split("\ ");
            JSONresponse.b_position = splits[1];
            JSONresponse.b_inpoint = splits[2];
            JSONresponse.b_outpoint = splits[3];
            JSONresponse.b_length = splits[4];
            JSONresponse.seekable = splits[5];
            JSONresponse.playlist_number = splits[6];
            JSONresponse.clip_index = splits[7].replace(/\r\n/g, "");
            str = JSON.stringify(JSONresponse);
            this.response = str;
            break;
        case 'list':
            //"2\r\n0 \"colour:green\" 0 14999 15000 15000 25.00\r\n1 \"colour:red\" 0 14999 15000 15000 25.00\r\n\r\n"
            split = str.split("\r\n");
            JSONresponse = {};
            var len = (split.length - 2);
            for (var i = 1; i < len; i++) {
                JSONresponse.clips = {
                    "name": split[i]
                };
            }
            str = JSON.stringify(JSONresponse);
            this.response = str;
            break;
        case "uls":
            split = str.split("\r\n");
                            JSONresponse = {};
            len = (split.length - 2);
            for (i = 1; i < len; i++) {
                JSONresponse.clips = {
                    "unit": split[i]
                };
            }
            str = JSON.stringify(JSONresponse);
            this.response = str;
            break;
        default:
            this.response = "OK";
        }
    },
    appendResponse: function(data) {
        this.response += data;
    },
    bind: function(scope, fn) {
        return function () {
                        fn.apply(scope, arguments);
        };
    },
    sendCommand: function(command) {
        var split = command.split(" ");
        this.command = split[0];
        if (!this.server) {
            this.connect();
        }
                    this.response = "";
        console.log("Command: " + command);
        this.server.write(command + "\n");
    },
};
<|endoftext|>


<commit_before>/**
 *
 *  Routes module expose route information used in home feature
 *
 *  @author  <%= answers.username %>
 *  @date    <%= answers.date %>
 *
 */
export default [
    {
        id: 'home',
        isDefault: true,
        when: '/home',
        template: '<home></home>'
    }
];
<commit_msg>Delete routes.js<commit_after><|endoftext|>