<commit_before>import './Breadcrumb.scss';
import { withRouter, Link } from 'react-router-dom';
import { Breadcrumb } from 'antd';
import axios from 'axios';
import PropTypes from 'prop-types'
import React, { Component } from 'react';

@withRouter
export default class BreadcrumbNavigation extends Component {
  constructor(props) {
    super(props);
    this.state = {
      // breadcrumb: [{name:'首页', path: '/'}],
      hash: '',
      breadcrumb: []
    }
  }
  static propTypes = {
    location: PropTypes.object
  }

  getBreadcrumb = (pathSnippets) => {
    // 重置 state 中的 breadcrumb，防止重复渲染
    this.setState({
      breadcrumb: []
    });
    if (/project|group|add-interface]/.test(pathSnippets[0])) {
      const type = pathSnippets[0] === 'add-interface' ? 'interface' : pathSnippets[0],
        id = pathSnippets[1];
      const params = { type, id };
      axios.get('/user/nav', {params: params}).then( (res) => {
        const data = res.data.data;
        // 依次填入group/projec/interface
        if (data.group_name) {
          this.setState({
            breadcrumb: this.state.breadcrumb.concat([{
              name: data.group_name,
              path: '/group/' + data.group_id
            }])
          });
        }
        if (data.project_name) {
          this.setState({
            breadcrumb: this.state.breadcrumb.concat([{
              name: data.project_name,
              path: '/project/' + data.project_id
            }])
          });
        }
        if (data.interface_name) {
          this.setState({
            breadcrumb: this.state.breadcrumb.concat([{
              name: data.interface_name,
              path: '/project/' + data.interface_id
            }])
          });
        }
      });
    } else if (pathSnippets[0] == 'user') {
      this.setState({
        breadcrumb: [{
          name: '个人中心',
          path: '/' + pathSnippets.join('/')
        }]
      });
    } else {
      console.log(2);
    }
  }
  componentDidMount() {
    console.log(location.hash);
    const pathSnippets = location.hash.split('#')[1].split('/').filter(i => i);
    this.getBreadcrumb(pathSnippets);
    this.setState({
      hash: location.hash.split('#')[1]
    })
  }
  componentWillReceiveProps(nextProps) {
    // this.setState({
    //   hash: nextProps.location.pathname
    // })
    const pathSnippets = location.hash.split('#')[1].split('/').filter(i => i);
    // console.log(nextProps.location.pathname, this.props.location.pathname);
    if (nextProps.location.pathname !== this.props.location.pathname) {
      // console.log('in');
      this.getBreadcrumb(pathSnippets);
      this.setState({
        hash: nextProps.location.pathname
      })
    }
  }
  render () {
    // console.log(this.state.hash);
    const pathSnippets = location.hash.split('#')[1].split('/').filter(i => i);
    // 获取接口路径并分割
    // console.log(this.state);
    const extraBreadcrumbItems = this.state.breadcrumb.map((item) => {
      // const url = `/${pathSnippets.slice(0, index + 1).join('/')}`;
      return (
        <Breadcrumb.Item key={item.path}>
          <Link to={item.path}>
            {item.name}
          </Link>
        </Breadcrumb.Item>
      );
    });
    const breadcrumbItems = [(
      <Breadcrumb.Item key="home">
        <Link to="/">首页</Link>
      </Breadcrumb.Item>
    )].concat(extraBreadcrumbItems);
    if (pathSnippets.length) {
      return (
        <Breadcrumb className="breadcrumb-container">
          {breadcrumbItems}
        </Breadcrumb>
      )
    } else {
      return ;
    }
  }
}
<commit_msg>fix: 暂时隐藏Breadcrumb<commit_after>import './Breadcrumb.scss';
import { withRouter, Link } from 'react-router-dom';
import { Breadcrumb } from 'antd';
import axios from 'axios';
import PropTypes from 'prop-types'
import React, { Component } from 'react';

@withRouter
export default class BreadcrumbNavigation extends Component {
  constructor(props) {
    super(props);
    this.state = {
      // breadcrumb: [{name:'首页', path: '/'}],
      hash: '',
      breadcrumb: []
    }
  }
  static propTypes = {
    location: PropTypes.object
  }

  getBreadcrumb = (pathSnippets) => {
    console.log(pathSnippets);
    // 重置 state 中的 breadcrumb，防止重复渲染
    this.setState({
      breadcrumb: []
    });
    if (/project|group|add-interface/.test(pathSnippets[0])) {
      let type = pathSnippets[0] === 'add-interface' ? 'interface' : pathSnippets[0],
        id = pathSnippets[pathSnippets.length-1];
      if (!pathSnippets.includes('edit')) {
        type = 'project';
      }
      const params = { type, id };
      axios.get('/user/nav', {params: params}).then( (res) => {
        const data = res.data.data;
        // 依次填入group/projec/interface
        if (data.group_name) {
          this.setState({
            breadcrumb: this.state.breadcrumb.concat([{
              name: data.group_name,
              path: '/group/' + data.group_id
            }])
          });
        }
        if (data.project_name) {
          this.setState({
            breadcrumb: this.state.breadcrumb.concat([{
              name: data.project_name,
              path: '/project/' + data.project_id
            }])
          });
        }
        if (data.interface_name) {
          this.setState({
            breadcrumb: this.state.breadcrumb.concat([{
              name: data.interface_name,
              path: '/add-interface/' + data.interface_id
            }])
          });
        }
      });
    } else if (pathSnippets[0] == 'user') {
      this.setState({
        breadcrumb: [{
          name: '个人中心',
          path: '/' + pathSnippets.join('/')
        }]
      });
    } else {
      console.log(2);
    }
  }
  componentDidMount() {
    console.log(location.hash);
    const pathSnippets = location.hash.split('#')[1].split('/').filter(i => i);
    this.getBreadcrumb(pathSnippets);
    this.setState({
      hash: location.hash.split('#')[1]
    })
  }
  componentWillReceiveProps(nextProps) {
    // this.setState({
    //   hash: nextProps.location.pathname
    // })
    const pathSnippets = location.hash.split('#')[1].split('/').filter(i => i);
    // console.log(nextProps.location.pathname, this.props.location.pathname);
    if (nextProps.location.pathname !== this.props.location.pathname) {
      // console.log('in');
      this.getBreadcrumb(pathSnippets);
      this.setState({
        hash: nextProps.location.pathname
      })
    }
  }
  render () {
    // console.log(this.state.hash);
    const pathSnippets = location.hash.split('#')[1].split('/').filter(i => i);
    // 获取接口路径并分割
    // console.log(this.state);
    const extraBreadcrumbItems = this.state.breadcrumb.map((item) => {
      // const url = `/${pathSnippets.slice(0, index + 1).join('/')}`;
      return (
        <Breadcrumb.Item key={item.path}>
          <Link to={item.path}>
            {item.name}
          </Link>
        </Breadcrumb.Item>
      );
    });
    const breadcrumbItems = [(
      <Breadcrumb.Item key="home">
        <Link to="/">首页</Link>
      </Breadcrumb.Item>
    )].concat(extraBreadcrumbItems);
    if (pathSnippets.length) {
      return (
        <Breadcrumb className="breadcrumb-container">
          {breadcrumbItems}
        </Breadcrumb>
      )
    } else {
      return ;
    }
  }
}
<|endoftext|>


<commit_before>module.exports = require("babel-loader").custom(babel => {
    // function myPlugin() {
    //     return {
    //         visitor: {},
    //     };
    // }

    return {
        // Passed the loader options.
        customOptions({ /*opt1, opt2,*/ ...loader }) {
            return {
                // Pull out any custom options that the loader might have.
                custom: { /*opt1, opt2*/ },

                // Pass the options back with the two custom options removed.
                loader,
            };
        },

        // Passed Babel's 'PartialConfig' object.
        config(cfg) {
            // if (cfg.hasFilesystemConfig()) {
            //     // Use the normal config
            //     return cfg.options;
            // }

            const { plugins, ...options } = cfg.options

            /** @type {Boolean} 已有的 plugin 中是否存在 `react-hot-loader/babel` */
            let hasRHL = false
            const newPlugins = plugins.filter(plugin => {
                if (typeof plugin.file === 'object' &&
                    /react-hot-loader(\/|\\)babel/.test(plugin.file.request)
                ) {
                    hasRHL = true
                    // 非开发模式下不应存在 RHL
                    if (process.env.WEBPACK_BUILD_ENV !== 'dev') {
                        return false
                    }
                }
                // console.log(plugin.file.request)
                return true
            })
            if (!hasRHL &&
                process.env.WEBPACK_BUILD_ENV === 'dev'
            ) {
                newPlugins.push(require('react-hot-loader/babel'))
            }

            // console.log('')
            // console.log({
            //     'plugin[].file': newPlugins.map(plugin => {
            //         return plugin.file.request
            //     })
            // })
            // console.log('')

            return {
                ...options,
                plugins: newPlugins,
            };
        },

        result(result) {
            return {
                ...result,
                // code: result.code + "\n// Generated by some custom loader",
            };
        },
    };
});
<commit_msg>[koot-webpack] modify `@babel/preset-env`<commit_after>module.exports = require("babel-loader").custom(babel => {
    // function myPlugin() {
    //     return {
    //         visitor: {},
    //     };
    // }

    return {
        // Passed the loader options.
        customOptions({ /*opt1, opt2,*/ ...loader }) {
            return {
                // Pull out any custom options that the loader might have.
                custom: { /*opt1, opt2*/ },

                // Pass the options back with the two custom options removed.
                loader,
            };
        },

        // Passed Babel's 'PartialConfig' object.
        config(cfg) {
            // if (cfg.hasFilesystemConfig()) {
            //     // Use the normal config
            //     return cfg.options;
            // }

            const { presets, plugins, ...options } = cfg.options

            const newPresets = presets.map(preset => {
                if (typeof preset.file === 'object' &&
                    /^@babel\/preset-env$/.test(preset.file.request)
                ) {
                    if (!preset.options)
                        preset.options = {}
                    if (process.env.WEBPACK_BUILD_STAGE === 'server') {
                        preset.options.modules = 'auto'
                        // preset.options.targets = {
                        //     node: "8"
                        // }
                        // console.log(preset.options)
                    }
                    return preset
                }
                return preset
            })

            /** @type {Boolean} 已有的 plugin 中是否存在 `react-hot-loader/babel` */
            let hasRHL = false
            const newPlugins = plugins.filter(plugin => {
                if (typeof plugin.file === 'object' &&
                    /react-hot-loader(\/|\\)babel/.test(plugin.file.request)
                ) {
                    hasRHL = true
                    // 非开发模式下不应存在 RHL
                    if (process.env.WEBPACK_BUILD_ENV !== 'dev') {
                        return false
                    }
                }
                // console.log(plugin.file.request)
                return true
            })
            if (!hasRHL &&
                process.env.WEBPACK_BUILD_ENV === 'dev'
            ) {
                newPlugins.push(require('react-hot-loader/babel'))
            }

            // console.log('')
            // presets.forEach(preset => {
            //     console.log('')
            //     console.log('options', preset.options)
            //     console.log('file', preset.file)
            // })
            // console.log({
            //     'plugin[].file': newPlugins.map(plugin => {
            //         return plugin.file.request
            //     })
            // })
            // console.log('')

            return {
                ...options,
                presets: newPresets,
                plugins: newPlugins,
            };
        },

        result(result) {
            return {
                ...result,
                // code: result.code + "\n// Generated by some custom loader",
            };
        },
    };
});
<|endoftext|>


<commit_before><commit_msg>ajuste posicao texto<commit_after><|endoftext|>


<commit_before>/*
 * map.js: Stream responsible for mapping events before emitting them.
 *
 * (C) 2012, Nodejitsu Inc.
 *
 */

var util = require('util'),
    ReadWriteStream = require('../common/read-write-stream');

//
// ### function Map (mapFn)
// #### @mapFn {function} Map function to call on each event.
// Constructor function of the Map stream responsible for mapping
// events before emitting them.
//
var Map = module.exports = function (mapFn) {
  if (!mapFn || typeof mapFn !== 'function') {
    throw new Error('map function is required.');
  }

  ReadWriteStream.call(this);
  this.mapFn = mapFn;
  this.async = mapFn.length === 2;
};

//
// Inherit from ReadWriteStream
//
util.inherits(Map, ReadWriteStream);

//
// ### function write (data)
// #### @data {Object} JSON to filter
// Emits data after it is mutating with `this.mapFn`.
//
Map.prototype.write = function (data) {
  var self = this;
  if (!this.async) {
    this.emit('data', this.mapFn(data));
    return;
  }

  this.mapFn(data, function (err, data) {
    return err
      ? self.emit('error', err)
      : self.emit('data', data);
  });
};
<commit_msg>[api] allow map reactor to accept a `passThrough` option which allows you to accomplish async operations triggered by the data stream without blocking it<commit_after>/*
 * map.js: Stream responsible for mapping events before emitting them.
 *
 * (C) 2012, Nodejitsu Inc.
 *
 */

var util = require('util'),
    ReadWriteStream = require('../common/read-write-stream');

//
// ### function Map (mapFn)
// #### @mapFn {function} Map function to call on each event.
// #### @options {Object} options to pass into reactor to customize behavior
// Constructor function of the Map stream responsible for mapping
// events before emitting them.
//
var Map = module.exports = function (mapFn, options) {
  if (!mapFn || typeof mapFn !== 'function') {
    throw new Error('map function is required.');
  }

  options = options || {};

  ReadWriteStream.call(this);
  this.mapFn = mapFn;
  this.async = mapFn.length === 2;
  //
  // So by default the behavior is to block the stream when running through
  // the async function. This option is here to allow you to do an async
  // operation that does not block the stream
  // TODO: Think of a better API for this behavior
  //
  this.passThrough = options.passThrough || false;
};

//
// Inherit from ReadWriteStream
//
util.inherits(Map, ReadWriteStream);

//
// ### function write (data)
// #### @data {Object} JSON to filter
// Emits data after it is mutating with `this.mapFn`.
//
Map.prototype.write = function (data) {
  var self = this;

  if (!this.async) {
    this.emit('data', this.mapFn(data));
    return;
  }

  if (!this.passThrough) {
    return this.mapFn(data, function (err, data) {
      return err
        ? self.emit('error', err)
        : self.emit('data', data);
    });
  }

  this.mapFn(data, function (err) {
    if (err) { self.emit('error', err) }
  });

  this.emit('data', data);
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import {Image, Text, View} from  'react-native';
import {Marker} from 'react-native-maps';
import { width as w , height as h } from 'react-native-dimension';

const height = h(100);
const width = w(100);

export default class CustomMarker extends Component {

    constructor(props){
        super(props);
        this.state = {
            isLoaded:false,
            coordinates: null,
            props: {},
            point_count: 0,
            clusterId: null
        };
    }

    shouldComponentUpdate(nextProps, nextState){
        if(this.state.geometry === nextProps.geometry
            && this.state.point_count === nextProps.properties.point_count){
            return(false);
        }else{
            return(true);
        }
    }

    render(){
        this.state.point_count = this.props.properties.point_count;
        if(this.state.point_count === 0){
            this.state.props = this.props.item.props;
        }else{
            this.state.clusterId = this.props.properties.cluster_id;
            this.state.props = {};
        }

        let coordinates = {longitude: this.props.geometry.coordinates[0],
            latitude: this.props.geometry.coordinates[1]};
        this.state.coordinates = coordinates;

        let textForCluster = '';
        let markerWidth, markerHeight, textSize;
        let point_count = this.state.point_count;

        if(point_count>=2 && point_count<=10){
            textForCluster = point_count.toString();
            markerWidth = width*2/15;
            markerHeight = width*2/15;
            textSize = GLOBAL.clusterTextSize;
        }if(point_count>10&&point_count<=25){
            textForCluster = '10+';
            markerWidth = width/7;
            markerHeight = width/7;
            textSize = GLOBAL.clusterTextSize;
        }if(point_count>25&&point_count<=50){
            textForCluster = '25+';
            markerWidth = width*2/13;
            markerHeight = width*2/13;
            textSize = GLOBAL.clusterTextSize;
        }if(point_count>50&&point_count<=100){
            textForCluster = '50+';
            markerWidth = width/6;
            markerHeight = width/6;
            textSize = GLOBAL.clusterTextSize;
        }if(point_count>100){
            textForCluster = '100+';
            markerWidth = width*2/11;
            markerHeight = width*2/11;
            textSize = GLOBAL.clusterTextSize;
        }

        if(GLOBAL.clusterTextSize){
            textSize = GLOBAL.clusterTextSize;
        }
        let clusterColor;
        let markers;
        if (this.state.clusterId) {
            markers = GLOBAL[this.props.superCluster].getLeaves(this.state.clusterId);
        }

        if (this.props.getClusterColor && markers) {
            clusterColor = this.props.getClusterColor(markers) || GLOBAL.clusterTextColor;
        } else {
            clusterColor = GLOBAL.clusterTextColor
        }

        let htmlElement;
        let isCluster;
        if(textForCluster !== ''){
            isCluster = 1;
            if(this.props.customClusterMarkerDesign && typeof this.props.customClusterMarkerDesign === "function") {
                htmlElement = <View
                    style={{width: markerWidth, height: markerHeight, justifyContent: 'center', alignItems: 'center'}}>
                    {this.props.customClusterMarkerDesign(markers || [])}
                    <Text style={{
                        width: markerWidth, textAlign: 'center', position: 'absolute',
                        fontSize: textSize, backgroundColor: 'transparent', color: clusterColor, fontWeight: 'bold'
                    }}
                          children={textForCluster}/>
                </View>;
            } else if(this.props.customClusterMarkerDesign && typeof this.props.customClusterMarkerDesign === "object"){
                htmlElement = <View style = {{width: markerWidth, height: markerHeight, justifyContent: 'center', alignItems: 'center'}}>
                    {this.props.customClusterMarkerDesign}
                    <Text style = {{width: markerWidth, textAlign: 'center', position:'absolute',
                        fontSize: textSize, backgroundColor: 'transparent', color: clusterColor, fontWeight: 'bold'}}
                          children = {textForCluster}/>
                </View>;
            }else{
                htmlElement = (
                    <View style = {{ borderRadius: markerWidth, position: 'relative', backgroundColor: GLOBAL.clusterColor, width: markerWidth, height: markerHeight,
                        borderWidth: GLOBAL.clusterBorderWidth, borderColor: GLOBAL.clusterBorderColor, justifyContent: 'center', alignItems: 'center'}}>
                        <Text
                            style = {{width: markerWidth, textAlign: 'center',
                                fontSize: textSize, backgroundColor: 'transparent', color: clusterColor, fontWeight: 'bold'}}>
                            {textForCluster}</Text>
                    </View>);
            }
        }else{
            isCluster = 0;
            htmlElement = this.props.item;
        }

        if(isCluster === 1){
            if(this.props.onClusterPress){
                return(
                    <Marker
                        key = {isCluster}
                        {...this.state.props}
                        coordinate = {coordinates}
                        onPress = {()=>{
                            if (!markers) {
                                markers = GLOBAL[this.props.superCluster].getLeaves(this.state.clusterId);
                            }
                            this.props.onClusterPress(this.state.coordinates, markers);
                        }}>
                        {htmlElement}
                    </Marker>
                );
            }else{
                return(
                    <Marker
                        key = {isCluster}
                        coordinate = {coordinates}
                        {...this.state.props}>
                        {htmlElement}
                    </Marker>
                );
            }
        }else{
            return(htmlElement);
        }
    }
}
<commit_msg>Fixing the fact that clusters hijack pan and zoom<commit_after>import React, { Component } from 'react';
import {Image, Text, View} from  'react-native';
import {Marker} from 'react-native-maps';
import { width as w , height as h } from 'react-native-dimension';

const height = h(100);
const width = w(100);

export default class CustomMarker extends Component {

    constructor(props){
        super(props);
        this.state = {
            isLoaded:false,
            coordinates: null,
            props: {},
            point_count: 0,
            clusterId: null
        };
    }

    shouldComponentUpdate(nextProps, nextState){
        if(this.state.geometry === nextProps.geometry
            && this.state.point_count === nextProps.properties.point_count){
            return(false);
        }else{
            return(true);
        }
    }

    render(){
        this.state.point_count = this.props.properties.point_count;
        if(this.state.point_count === 0){
            this.state.props = this.props.item.props;
        }else{
            this.state.clusterId = this.props.properties.cluster_id;
            this.state.props = {};
        }

        let coordinates = {longitude: this.props.geometry.coordinates[0],
            latitude: this.props.geometry.coordinates[1]};
        this.state.coordinates = coordinates;

        let textForCluster = '';
        let markerWidth, markerHeight, textSize;
        let point_count = this.state.point_count;

        if(point_count>=2 && point_count<=10){
            textForCluster = point_count.toString();
            markerWidth = width*2/15;
            markerHeight = width*2/15;
            textSize = GLOBAL.clusterTextSize;
        }if(point_count>10&&point_count<=25){
            textForCluster = '10+';
            markerWidth = width/7;
            markerHeight = width/7;
            textSize = GLOBAL.clusterTextSize;
        }if(point_count>25&&point_count<=50){
            textForCluster = '25+';
            markerWidth = width*2/13;
            markerHeight = width*2/13;
            textSize = GLOBAL.clusterTextSize;
        }if(point_count>50&&point_count<=100){
            textForCluster = '50+';
            markerWidth = width/6;
            markerHeight = width/6;
            textSize = GLOBAL.clusterTextSize;
        }if(point_count>100){
            textForCluster = '100+';
            markerWidth = width*2/11;
            markerHeight = width*2/11;
            textSize = GLOBAL.clusterTextSize;
        }

        if(GLOBAL.clusterTextSize){
            textSize = GLOBAL.clusterTextSize;
        }
        let clusterColor;
        let markers;
        if (this.state.clusterId) {
            markers = GLOBAL[this.props.superCluster].getLeaves(this.state.clusterId);
        }

        if (this.props.getClusterColor && markers) {
            clusterColor = this.props.getClusterColor(markers) || GLOBAL.clusterTextColor;
        } else {
            clusterColor = GLOBAL.clusterTextColor
        }

        let htmlElement;
        let isCluster;
        if(textForCluster !== ''){
            isCluster = 1;
            if(this.props.customClusterMarkerDesign && typeof this.props.customClusterMarkerDesign === "function") {
                htmlElement = <View
                    style={{width: markerWidth, height: markerHeight, justifyContent: 'center', alignItems: 'center'}}>
                    {this.props.customClusterMarkerDesign(markers || [])}
                    <Text style={{
                        width: markerWidth, textAlign: 'center', position: 'absolute',
                        fontSize: textSize, backgroundColor: 'transparent', color: clusterColor, fontWeight: 'bold'
                    }}
                          children={textForCluster}/>
                </View>;
            } else if(this.props.customClusterMarkerDesign && typeof this.props.customClusterMarkerDesign === "object"){
                htmlElement = <View style = {{width: markerWidth, height: markerHeight, justifyContent: 'center', alignItems: 'center'}}>
                    {this.props.customClusterMarkerDesign}
                    <Text style = {{width: markerWidth, textAlign: 'center', position:'absolute',
                        fontSize: textSize, backgroundColor: 'transparent', color: clusterColor, fontWeight: 'bold'}}
                          children = {textForCluster}/>
                </View>;
            }else{
                htmlElement = (
                    <View style = {{ borderRadius: markerWidth, position: 'relative', backgroundColor: GLOBAL.clusterColor, width: markerWidth, height: markerHeight,
                        borderWidth: GLOBAL.clusterBorderWidth, borderColor: GLOBAL.clusterBorderColor, justifyContent: 'center', alignItems: 'center'}}>
                        <Text
                            style = {{width: markerWidth, textAlign: 'center',
                                fontSize: textSize, backgroundColor: 'transparent', color: clusterColor, fontWeight: 'bold'}}>
                            {textForCluster}</Text>
                    </View>);
            }
        }else{
            isCluster = 0;
            htmlElement = this.props.item;
        }

        if(isCluster === 1){
            if(this.props.onClusterPress){
                return(
                    <Marker
                        key = {isCluster}
                        {...this.state.props}
                        coordinate = {coordinates}
                        onPress = {()=>{
                            if (!markers) {
                                markers = GLOBAL[this.props.superCluster].getLeaves(this.state.clusterId);
                            }
                            this.props.onClusterPress(this.state.coordinates, markers);
                        }}>
                        {htmlElement}
                    </Marker>
                );
            }else{
                return(
                    <Marker
                        pointerEvents={'none'}
                        key = {isCluster}
                        coordinate = {coordinates}
                        {...this.state.props}>
                        {htmlElement}
                    </Marker>
                );
            }
        }else{
            return(htmlElement);
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var assert = require('assert');

module.exports = PeerHeap;

// A max-score (pre-computed) for peer selection

// This is used for every DFS. It will end up being the size of the largest
// peer list.
var dfsStack = [0, 1, 2];

function PeerHeap(random) {
    var self = this;

    self.array = [];

    self.random = random || Math.random;
    assert(typeof self.random === 'function', 'PeerHeap expected random fn');

    // We cache the range los and his so they can be stored as a contiguous
    // array of boxed doubles. This has a noticable speed increase.
    self.rangehis = [];
    self.rangelos = [];

    self.maxRangeStart = 0;
}

PeerHeap.prototype.choose1 = function choose1(threshold, filter) {
    var self = this;
    if (self.array[0].range.lo >= threshold && (!filter || filter(self.array[0].peer))) {
        return self.array[0].peer;
    }
};

PeerHeap.prototype.choose2 = function choose2(threshold, filter) {
    var self = this;
    var prob1 = self.array[0].peer.getScore();
    var prob2 = self.array[1].peer.getScore();

    if (prob1 > threshold && prob1 >= prob2 && (!filter || filter(self.array[0].peer))) {
        return self.array[0].peer;
    } else if (prob2 > threshold && (!filter || filter(self.array[1].peer))) {
        return self.array[1].peer;
    }
};

/*eslint-disable complexity */
/*eslint-disable max-statements */
PeerHeap.prototype.choose = function choose(threshold, filter) {
    var self = this;

    if (!self.array.length) {
        return null;
    }

    if (self.array.length === 1) {
        return self.choose1(threshold, filter);
    }

    if (self.array.length === 2) {
        return self.choose2(threshold, filter);
    }

    var chosenPeer = null;
    var highestProbability = 0;
    var firstScore = self.array[0].peer.getScore();

    // Pointers into dfsStack
    var stackBegin = 0;
    var stackEnd = 0;

    if (firstScore > threshold && (!filter || filter(self.array[0].peer))) {
        // Don't check first peer if it looks good, check its children though
        chosenPeer = self.array[0].peer;
        highestProbability = firstScore;
        // The array is seeded with 0, 1, 2 so we just have to advance the
        // stack pointers
        stackBegin = 1;
        stackEnd = 2;
    }

    while (stackBegin <= stackEnd) {
        var i = dfsStack[stackBegin];
        stackBegin++;

        var el = self.array[i];

        if (self.rangehis[i] <= self.maxRangeStart) {
            // This range ends before the range with the largest start begins,
            // so it can't possibly be chosen over any of the ranges we've
            // seen. All ranges below this one have a smaller end, so this
            // range and any below it can't be chosen.
            continue;
        } else if (!filter || filter(el.peer)) {
            // INLINE of TChannelPeer#getScore
            var lo = self.rangelos[i];
            var hi = self.rangehis[i];
            var rand = self.random();
            if (rand === 0) {
                rand = 1;
            }
            var probability = lo + ((hi - lo) * rand);

            if ((probability > highestProbability) && (probability > threshold)) {
                highestProbability = probability;
                chosenPeer = el.peer;
            }
        }

        // Continue DFS by 'pushing' left and right indexes onto end of
        // dfsStack, if the source array is long enough for that
        var left = 2 * i + 1;
        var right = left + 1;
        if (left < self.array.length) {
            dfsStack[++stackEnd] = left;
            if (right < self.array.length) {
                dfsStack[++stackEnd] = right;
            }
        }
    }

    return chosenPeer;
};
/*eslint-enable complexity */
/*eslint-enable max-statements */

PeerHeap.prototype.clear = function clear() {
    var self = this;

    for (var i = 0; i < self.array.length; i++) {
        var el = self.array[i];
        el.heap = null;
        el.peer = null;
        el.index = 0;
        el.range = null;
    }
    self.array.length = 0;
    self.rangehis.length = 0;
    self.rangelos.length = 0;
};

PeerHeap.prototype.add = function add(peer) {
    var self = this;

    var range = peer.scoreRange;
    var i = self.push(peer, range);
    var el = self.array[i];
    return el;
};

PeerHeap.prototype.rescore = function rescore() {
    var self = this;

    for (var i = 0; i < self.array.length; i++) {
        var el = self.array[i];
        el.range = el.peer.getScoreRange();
    }
    self.heapify();
};

PeerHeap.prototype.heapify = function heapify() {
    var self = this;

    if (self.array.length <= 1) {
        return;
    }

    for (var i = Math.floor(self.array.length / 2 - 1); i >= 0; i--) {
        self.siftdown(i);
    }
};

PeerHeap.prototype.remove = function remove(i) {
    var self = this;

    if (i >= self.array.length) {
        return;
    }

    if (self.array.length === 1) {
        self.array.pop();
        return;
    }

    var j = self.array.length - 1;
    if (i === j) {
        self.array.pop();
        return;
    }

    self.swap(i, j);
    self.array.pop();
    self.siftup(i);
};

PeerHeap.prototype.push = function push(peer, range) {
    var self = this;

    var el = new PeerHeapElement(self);
    el.peer = peer;
    el.range = peer.scoreRange;
    el.index = self.array.length;

    self.array.push(el);
    return self.siftup(el.index);
};

PeerHeap.prototype.pop = function pop() {
    var self = this;
    var peer = null;

    if (!self.array.length) {
        return peer;
    }

    if (self.array.length === 1) {
        peer = self.array.pop();
        return peer;
    }

    peer = self.array[0].peer;
    self.array[0] = self.array.pop();
    self.siftdown(0);

    return peer;
};

PeerHeap.prototype.siftdown = function siftdown(i) {
    var self = this;

    for (;;) {
        var left = (2 * i) + 1;
        if (left >= self.array.length) {
            self.rangehis[i] = self.array[i].range.hi;
            self.rangelos[i] = self.array[i].range.lo;
            self.maxRangeStart = Math.max(self.rangelos[i], self.maxRangeStart);
            return i;
        }

        var right = left + 1;
        var child = left;
        if (right < self.array.length &&
            self.array[right].range.hi > self.array[left].range.hi) {
            child = right;
        }

        if (self.array[child].range.hi > self.array[i].range.hi) {
            self.swap(i, child);
            i = child;
        } else {
            self.rangehis[i] = self.array[i].range.hi;
            self.rangelos[i] = self.array[i].range.lo;
            self.maxRangeStart = Math.max(self.rangelos[i], self.maxRangeStart);
            return i;
        }
    }
};

PeerHeap.prototype.siftup = function siftup(i) {
    var self = this;

    while (i > 0) {
        var par = Math.floor((i - 1) / 2);
        if (self.array[i].range.hi > self.array[par].range.hi) {
            self.swap(i, par);
            i = par;
        } else {
            self.rangehis[i] = self.array[i].range.hi;
            self.rangelos[i] = self.array[i].range.lo;
            self.maxRangeStart = Math.max(self.rangelos[i], self.maxRangeStart);
            return i;
        }
    }

    self.rangehis[0] = self.array[0].range.hi;
    self.rangelos[0] = self.array[0].range.lo;
    self.maxRangeStart = Math.max(self.rangelos[i], self.maxRangeStart);

    return 0;
};

PeerHeap.prototype.swap = function swap(i, j) {
    var self = this;

    var a = self.array[i];
    var b = self.array[j];

    self.array[i] = b;
    self.array[j] = a;
    b.index = i;
    a.index = j;

    self.rangehis[j] = a.range.hi;
    self.rangelos[j] = a.range.lo;
    self.maxRangeStart = Math.max(self.rangelos[j], self.maxRangeStart);

    self.rangehis[i] = b.range.hi;
    self.rangelos[i] = b.range.lo;
    self.maxRangeStart = Math.max(self.rangelos[i], self.maxRangeStart);
};

function PeerHeapElement(heap) {
    var self = this;

    self.heap = heap;
    self.peer = null;
    self.index = 0;
    self.range = null;
}

PeerHeapElement.prototype.rescore = function rescore(range) {
    var self = this;

    if (!self.heap) {
        return;
    }

    self.range = self.peer.scoreRange;
    self.index = self.heap.siftup(self.index);
    self.index = self.heap.siftdown(self.index);
};
<commit_msg>PeerHeap: drop .self access pattern from constructor<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var assert = require('assert');

module.exports = PeerHeap;

// A max-score (pre-computed) for peer selection

// This is used for every DFS. It will end up being the size of the largest
// peer list.
var dfsStack = [0, 1, 2];

function PeerHeap(random) {
    this.array = [];

    this.random = random || Math.random;
    assert(typeof this.random === 'function', 'PeerHeap expected random fn');

    // We cache the range los and his so they can be stored as a contiguous
    // array of boxed doubles. This has a noticable speed increase.
    this.rangehis = [];
    this.rangelos = [];

    this.maxRangeStart = 0;
}

PeerHeap.prototype.choose1 = function choose1(threshold, filter) {
    var self = this;
    if (self.array[0].range.lo >= threshold && (!filter || filter(self.array[0].peer))) {
        return self.array[0].peer;
    }
};

PeerHeap.prototype.choose2 = function choose2(threshold, filter) {
    var self = this;
    var prob1 = self.array[0].peer.getScore();
    var prob2 = self.array[1].peer.getScore();

    if (prob1 > threshold && prob1 >= prob2 && (!filter || filter(self.array[0].peer))) {
        return self.array[0].peer;
    } else if (prob2 > threshold && (!filter || filter(self.array[1].peer))) {
        return self.array[1].peer;
    }
};

/*eslint-disable complexity */
/*eslint-disable max-statements */
PeerHeap.prototype.choose = function choose(threshold, filter) {
    var self = this;

    if (!self.array.length) {
        return null;
    }

    if (self.array.length === 1) {
        return self.choose1(threshold, filter);
    }

    if (self.array.length === 2) {
        return self.choose2(threshold, filter);
    }

    var chosenPeer = null;
    var highestProbability = 0;
    var firstScore = self.array[0].peer.getScore();

    // Pointers into dfsStack
    var stackBegin = 0;
    var stackEnd = 0;

    if (firstScore > threshold && (!filter || filter(self.array[0].peer))) {
        // Don't check first peer if it looks good, check its children though
        chosenPeer = self.array[0].peer;
        highestProbability = firstScore;
        // The array is seeded with 0, 1, 2 so we just have to advance the
        // stack pointers
        stackBegin = 1;
        stackEnd = 2;
    }

    while (stackBegin <= stackEnd) {
        var i = dfsStack[stackBegin];
        stackBegin++;

        var el = self.array[i];

        if (self.rangehis[i] <= self.maxRangeStart) {
            // This range ends before the range with the largest start begins,
            // so it can't possibly be chosen over any of the ranges we've
            // seen. All ranges below this one have a smaller end, so this
            // range and any below it can't be chosen.
            continue;
        } else if (!filter || filter(el.peer)) {
            // INLINE of TChannelPeer#getScore
            var lo = self.rangelos[i];
            var hi = self.rangehis[i];
            var rand = self.random();
            if (rand === 0) {
                rand = 1;
            }
            var probability = lo + ((hi - lo) * rand);

            if ((probability > highestProbability) && (probability > threshold)) {
                highestProbability = probability;
                chosenPeer = el.peer;
            }
        }

        // Continue DFS by 'pushing' left and right indexes onto end of
        // dfsStack, if the source array is long enough for that
        var left = 2 * i + 1;
        var right = left + 1;
        if (left < self.array.length) {
            dfsStack[++stackEnd] = left;
            if (right < self.array.length) {
                dfsStack[++stackEnd] = right;
            }
        }
    }

    return chosenPeer;
};
/*eslint-enable complexity */
/*eslint-enable max-statements */

PeerHeap.prototype.clear = function clear() {
    var self = this;

    for (var i = 0; i < self.array.length; i++) {
        var el = self.array[i];
        el.heap = null;
        el.peer = null;
        el.index = 0;
        el.range = null;
    }
    self.array.length = 0;
    self.rangehis.length = 0;
    self.rangelos.length = 0;
};

PeerHeap.prototype.add = function add(peer) {
    var self = this;

    var range = peer.scoreRange;
    var i = self.push(peer, range);
    var el = self.array[i];
    return el;
};

PeerHeap.prototype.rescore = function rescore() {
    var self = this;

    for (var i = 0; i < self.array.length; i++) {
        var el = self.array[i];
        el.range = el.peer.getScoreRange();
    }
    self.heapify();
};

PeerHeap.prototype.heapify = function heapify() {
    var self = this;

    if (self.array.length <= 1) {
        return;
    }

    for (var i = Math.floor(self.array.length / 2 - 1); i >= 0; i--) {
        self.siftdown(i);
    }
};

PeerHeap.prototype.remove = function remove(i) {
    var self = this;

    if (i >= self.array.length) {
        return;
    }

    if (self.array.length === 1) {
        self.array.pop();
        return;
    }

    var j = self.array.length - 1;
    if (i === j) {
        self.array.pop();
        return;
    }

    self.swap(i, j);
    self.array.pop();
    self.siftup(i);
};

PeerHeap.prototype.push = function push(peer, range) {
    var self = this;

    var el = new PeerHeapElement(self);
    el.peer = peer;
    el.range = peer.scoreRange;
    el.index = self.array.length;

    self.array.push(el);
    return self.siftup(el.index);
};

PeerHeap.prototype.pop = function pop() {
    var self = this;
    var peer = null;

    if (!self.array.length) {
        return peer;
    }

    if (self.array.length === 1) {
        peer = self.array.pop();
        return peer;
    }

    peer = self.array[0].peer;
    self.array[0] = self.array.pop();
    self.siftdown(0);

    return peer;
};

PeerHeap.prototype.siftdown = function siftdown(i) {
    var self = this;

    for (;;) {
        var left = (2 * i) + 1;
        if (left >= self.array.length) {
            self.rangehis[i] = self.array[i].range.hi;
            self.rangelos[i] = self.array[i].range.lo;
            self.maxRangeStart = Math.max(self.rangelos[i], self.maxRangeStart);
            return i;
        }

        var right = left + 1;
        var child = left;
        if (right < self.array.length &&
            self.array[right].range.hi > self.array[left].range.hi) {
            child = right;
        }

        if (self.array[child].range.hi > self.array[i].range.hi) {
            self.swap(i, child);
            i = child;
        } else {
            self.rangehis[i] = self.array[i].range.hi;
            self.rangelos[i] = self.array[i].range.lo;
            self.maxRangeStart = Math.max(self.rangelos[i], self.maxRangeStart);
            return i;
        }
    }
};

PeerHeap.prototype.siftup = function siftup(i) {
    var self = this;

    while (i > 0) {
        var par = Math.floor((i - 1) / 2);
        if (self.array[i].range.hi > self.array[par].range.hi) {
            self.swap(i, par);
            i = par;
        } else {
            self.rangehis[i] = self.array[i].range.hi;
            self.rangelos[i] = self.array[i].range.lo;
            self.maxRangeStart = Math.max(self.rangelos[i], self.maxRangeStart);
            return i;
        }
    }

    self.rangehis[0] = self.array[0].range.hi;
    self.rangelos[0] = self.array[0].range.lo;
    self.maxRangeStart = Math.max(self.rangelos[i], self.maxRangeStart);

    return 0;
};

PeerHeap.prototype.swap = function swap(i, j) {
    var self = this;

    var a = self.array[i];
    var b = self.array[j];

    self.array[i] = b;
    self.array[j] = a;
    b.index = i;
    a.index = j;

    self.rangehis[j] = a.range.hi;
    self.rangelos[j] = a.range.lo;
    self.maxRangeStart = Math.max(self.rangelos[j], self.maxRangeStart);

    self.rangehis[i] = b.range.hi;
    self.rangelos[i] = b.range.lo;
    self.maxRangeStart = Math.max(self.rangelos[i], self.maxRangeStart);
};

function PeerHeapElement(heap) {
    var self = this;

    self.heap = heap;
    self.peer = null;
    self.index = 0;
    self.range = null;
}

PeerHeapElement.prototype.rescore = function rescore(range) {
    var self = this;

    if (!self.heap) {
        return;
    }

    self.range = self.peer.scoreRange;
    self.index = self.heap.siftup(self.index);
    self.index = self.heap.siftdown(self.index);
};
<|endoftext|>


<commit_before>'use strict'

import Reporter from 'chiffchaff-reporter'
import Promise from 'bluebird'
import Bottleneck from 'bottleneck'
import express from 'express'
import socketIo from 'socket.io'
import defaults from 'defaults'
import open from 'open'
import path from 'path'
import http from 'http'

export default class WwwReporter extends Reporter {
  constructor (options) {
    super()
    this._options = defaults(options, {
      hostname: '127.0.0.1',
      port: 0,
      updateInterval: 250
    })
    this._lastData = []
    this._disposed = false
    this._limiter = new Bottleneck(1, this._options.updateInterval)
    this._boundReport = this._scheduledReport.bind(this)
  }

  start () {
    this._createApp()
    this._createServer()
    this._createIo()
    return this._listen()
      .then(() => Promise.all([this._openBrowser(), this._waitForConnection()]))
  }

  report (data) {
    if (this._disposed) {
      throw new Error('Reporter disposed')
    }
    this._lastData = data
    this._scheduleReport()
  }

  dispose () {
    return new Promise(resolve => {
      this._disposed = true
      this._scheduleReport()
      resolve()
    })
  }

  _scheduleReport () {
    this._limiter.schedule(this._boundReport)
  }

  _scheduledReport () {
    return new Promise(resolve => {
      this._io.emit('data', this._lastData)
      resolve()
    }).then(() => this._disposed && this._completeDisposal())
  }

  _completeDisposal () {
    this._limiter.stopAll()
    this._io.emit('end')
    this._io.close()
    this._limiter = null
    this._app = null
    this._server = null
    this._io = null
  }

  _createApp () {
    const root = path.resolve(__dirname, '..')
    this._app = express()
    this._app.use(express.static(path.resolve(root, 'public')))
  }

  _createServer () {
    this._server = http.Server(this._app)
  }

  _createIo () {
    this._io = socketIo(this._server, {serveClient: false})
    this._io.on('connection', socket => this._onConnection(socket))
  }

  _listen () {
    return Promise.promisify(this._server.listen).call(this._server,
      this._options.port, this._options.hostname)
  }

  _openBrowser () {
    const port = this._server.address().port
    open(`http://127.0.0.1:${port}/`)
  }

  _waitForConnection () {
    return new Promise(resolve => this._io.on('connection', resolve))
  }

  _onConnection (socket) {
    socket.emit('init', this._lastData)
  }
}
<commit_msg>Force-closing connections so server doesn't hang<commit_after>'use strict'

import Reporter from 'chiffchaff-reporter'
import Promise from 'bluebird'
import Bottleneck from 'bottleneck'
import express from 'express'
import socketIo from 'socket.io'
import defaults from 'defaults'
import open from 'open'
import path from 'path'
import http from 'http'

export default class WwwReporter extends Reporter {
  constructor (options) {
    super()
    this._options = defaults(options, {
      hostname: '127.0.0.1',
      port: 0,
      updateInterval: 250,
      closeTimeout: 500
    })
    this._lastData = []
    this._connections = []
    this._disposed = false
    this._limiter = new Bottleneck(1, this._options.updateInterval)
    this._boundReport = this._scheduledReport.bind(this)
  }

  start () {
    this._createApp()
    this._createServer()
    this._createIo()
    return this._listen()
      .then(() => Promise.all([this._openBrowser(), this._waitForConnection()]))
  }

  report (data) {
    if (this._disposed) {
      throw new Error('Reporter disposed')
    }
    this._lastData = data
    this._scheduleReport()
  }

  dispose () {
    return new Promise(resolve => {
      this._disposed = true
      this._scheduleReport()
      resolve()
    })
  }

  _scheduleReport () {
    this._limiter.schedule(this._boundReport)
  }

  _scheduledReport () {
    return new Promise(resolve => {
      this._io.emit('data', this._lastData)
      resolve()
    }).then(() => this._disposed && this._completeDisposal())
  }

  _completeDisposal () {
    return new Promise(resolve => {
      this._limiter.stopAll()
      this._io.emit('end')
      this._io.close()
      this._server.close()
      resolve()
    })
      .delay(this._options.closeTimeout)
      .then(() => {
        this._closeAllConnections()
        this._limiter = null
        this._app = null
        this._server = null
        this._io = null
      })
  }

  _closeAllConnections () {
    for (let conn of this._connections) {
      conn.destroy()
    }
    this._connections.length = 0
  }

  _createApp () {
    const root = path.resolve(__dirname, '..')
    this._app = express()
    this._app.use(express.static(path.resolve(root, 'public')))
  }

  _createServer () {
    this._server = http.Server(this._app)
    this._server.on('connection', conn => {
      this._connections.push(conn)
      conn.on('close', () => {
        conn.destroy()
        const idx = this._connections.indexOf(conn)
        if (idx >= 0) {
          this._connections.splice(idx, 1)
        }
      })
    })
  }

  _createIo () {
    this._io = socketIo(this._server, {serveClient: false})
    this._io.on('connection', socket => this._onConnection(socket))
  }

  _listen () {
    return Promise.promisify(this._server.listen).call(this._server,
      this._options.port, this._options.hostname)
  }

  _openBrowser () {
    const port = this._server.address().port
    open(`http://127.0.0.1:${port}/`)
  }

  _waitForConnection () {
    return new Promise(resolve => this._io.on('connection', resolve))
  }

  _onConnection (socket) {
    socket.emit('init', this._lastData)
  }
}
<|endoftext|>


<commit_before>/**
 * Implementation of the queue (FIFO) using JavaScript
 *
 * author: Przemyslaw Jazlo <przemek@devrunner.pl>
 *
 */
module.exports = (function Queue(){

	var queue = [];

    function enqueue(newElement){
    	queue.push(newElement);
    }

    function dequeue(){
    	return queue.shift();
    }

    function getSize(){
		return queue.length;
	}

	function peek(){
		return queue[0];
	}

	function isEmpty(){
		return (queue.length === 0);
	}

	function clear(){
		queue = [];
	}

	var publicApi = {
		enqueue: enqueue,
		dequeue: dequeue,
		getSize: getSize,
		peek: peek,
		isEmpty: isEmpty,
		clear: clear
	};

	return publicApi;

})();<commit_msg>added comments in the queue implementation<commit_after>/**
 * Implementation of the queue (FIFO) using JavaScript
 *
 * author: Przemyslaw Jazlo <przemek@devrunner.pl>
 *
 */
var Queue = (function Queue(){

	var queue = [];

	// add new element to the queue
    function enqueue(newElement){
		queue.push(newElement);
    }

    // remove element from the queue
    function dequeue(){
    	return queue.shift();
    }

    // returns size of the queue
    function getSize(){
		return queue.length;
	}

	// returns first element without removing from the queue
	function peek(){
		return queue[0];
	}

	// checks if queue is empty
	function isEmpty(){
		return (queue.length === 0);
	}

	// clears the queue
	function clear(){
		queue = [];
	}

	var publicApi = {
		enqueue: enqueue,
		dequeue: dequeue,
		getSize: getSize,
		peek: peek,
		isEmpty: isEmpty,
		clear: clear
	};

	return publicApi;

})();

module.exports = Queue;<|endoftext|>


<commit_before>
/*
* View Source
* Generates copy/pastable markup from actual rendered markup.
*
* Copyright (c) 2016 Filament Group, Inc.
* Licensed under the MIT, GPL licenses.
 */

window.jQuery = window.jQuery || window.shoestring;

(function( $ ) {
  var pluginName = "xrayhtml",
		o = {
		text: {
			open: "View Source",
			close: "View Demo",
			titlePrefix: "Example",
			antipattern: "Do Not Use"
		},
		classes: {
			button: "btn btn-small",
			open: "view-source",
			sourcepanel: "source-panel",
			title: "xraytitle",
			antipattern: "antipattern"
		},
		initSelector: "[data-" + pluginName + "]",
		defaultReveal: "inline"
	},
	methods = {
		_create: function() {
			return $( this ).each(function() {
				var init = $( this ).data( "init." + pluginName );

				if( init ) {
					return false;
				}

				$( this )
					.data( "init." + pluginName, true )
					[ pluginName ]( "_init" )
					.trigger( "create." +  pluginName );
			});
		},
		_init: function() {
			var method = $( this ).attr( "data-" + pluginName ) || o.defaultReveal;

			if( method === "flip" ) {
				$( this )[ pluginName ]( "_createButton" );
			}

			$( this )
				.addClass( pluginName + " " + "method-" + method )
				[ pluginName ]( "_createSource" );
		},
		_createButton: function() {
			var btn = document.createElement( "a" ),
				txt = document.createTextNode( o.text.open ),
				el = $( this );

			btn.setAttribute( "class", o.classes.button );
			btn.href = "#";
			btn.appendChild( txt );

			$( btn )
				.bind( "click", function( e ) {
					var isOpen = el.attr( "class" ).indexOf( o.classes.open ) > -1;

					el[ isOpen ? "removeClass" : "addClass" ]( o.classes.open );
					btn.innerHTML = ( isOpen ? o.text.open : o.text.close );

					e.preventDefault();

				})
				.insertBefore( el );
		},
		_createSource: function() {
			var el = this;
			var getPrefixText = function () {
				if( el.className.match( new RegExp( "\\b" + o.classes.antipattern + "\\b", "gi" ) ) ) {
					return o.text.antipattern;
				}
				return o.text.titlePrefix;
			};
			var title = el.getElementsByClassName( o.classes.title );
			var deprecatedTitle;
			var preel = document.createElement( "pre" );
			var codeel = document.createElement( "code" );
			var wrap = document.createElement( "div" );
			var sourcepanel = document.createElement( "div" );
			var code;
			var leadingWhiteSpace;
			var source;

			if( title.length ) {
				title = title[ 0 ];
				title.parentNode.removeChild( title );
				title.innerHTML = getPrefixText() + ": " + title.innerHTML;
			} else {
				deprecatedTitle = el.getAttribute( "data-title" );
				title = document.createElement( "div" );
				title.className = o.classes.title;
				title.innerHTML = getPrefixText() + ( deprecatedTitle ? ": " + deprecatedTitle : "" );
			}

			// remove empty value attributes
			code = el.innerHTML.replace( /\=\"\"/g, '' );
			leadingWhiteSpace = code.match( /(^[\s]+)/ );

			if( leadingWhiteSpace ) {
				code = code.replace( new RegExp( leadingWhiteSpace[ 1 ], "gmi" ), "\n" );
			}

			source = document.createTextNode( code );

			wrap.setAttribute( "class", "snippet" );

			$( el ).wrapInner( wrap );

			codeel.appendChild( source );
			preel.appendChild( codeel );

			sourcepanel.setAttribute( "class", o.classes.sourcepanel );
			sourcepanel.appendChild( preel );

			this.appendChild( sourcepanel );
			this.insertBefore( title, this.firstChild );
		}
	};

	// Collection method.
	$.fn[ pluginName ] = function( arrg, a, b, c ) {
		return this.each(function() {

			// if it's a method
			if( arrg && typeof( arrg ) === "string" ){
				return $.fn[ pluginName ].prototype[ arrg ].call( this, a, b, c );
			}

			// don't re-init
			if( $( this ).data( pluginName + "data" ) ){
				return $( this );
			}

			// otherwise, init
			$( this ).data( pluginName + "active", true );
			$.fn[ pluginName ].prototype._create.call( this );
		});
	};

	// add methods
	$.extend( $.fn[ pluginName ].prototype, methods );

	//  auto-init
	var initted;
	function init(){
		if( !initted ){
			$( o.initSelector )[ pluginName ]();
			initted = true;
		}
	}
	// init either on beforeenhance event or domready, whichever comes first.
	$( document ).bind("beforeenhance", init );
	$( init );

}( jQuery ));
<commit_msg>first hack to go along with xray iframe<commit_after>
/*
* View Source
* Generates copy/pastable markup from actual rendered markup.
*
* Copyright (c) 2016 Filament Group, Inc.
* Licensed under the MIT, GPL licenses.
 */

window.jQuery = window.jQuery || window.shoestring;

(function( $ ) {
  var pluginName = "xrayhtml",
		o = {
		text: {
			open: "View Source",
			close: "View Demo",
			titlePrefix: "Example",
			antipattern: "Do Not Use"
		},
		classes: {
			button: "btn btn-small",
			open: "view-source",
			sourcepanel: "source-panel",
			title: "xraytitle",
			antipattern: "antipattern"
		},
		initSelector: "[data-" + pluginName + "]",
		defaultReveal: "inline"
	},
	methods = {
		_create: function() {
			return $( this ).each(function() {
				var init = $( this ).data( "init." + pluginName );

				if( init ) {
					return false;
				}

				$( this )
					.data( "init." + pluginName, true )
					[ pluginName ]( "_init" )
					.trigger( "create." +  pluginName );
			});
		},
		_init: function() {
			var self = this;
			var method = $( this ).attr( "data-" + pluginName ) || o.defaultReveal;

			if( method === "flip" ) {
				$( this )[ pluginName ]( "_createButton" );
			}

			$( this )
				.addClass( pluginName + " " + "method-" + method )
				[ pluginName ]( "_createSource" );

			if( $(this).is("[data-" + pluginName + "-iframe]") ){
				var snippetHTML = $(this).find(".snippet").html();
				var url = $(this).attr("data-" + pluginName + "-iframe");
				var $iframe = $("<iframe src='" + url + "'/>");

				$iframe.bind("load",function(){
					debugger;
					$iframe[0].contentWindow.postMessage({
						html: snippetHTML,
					}, "*");
				});

				$(this).html($iframe);
			}

		},
		_createButton: function() {
			var btn = document.createElement( "a" ),
				txt = document.createTextNode( o.text.open ),
				el = $( this );

			btn.setAttribute( "class", o.classes.button );
			btn.href = "#";
			btn.appendChild( txt );

			$( btn )
				.bind( "click", function( e ) {
					var isOpen = el.attr( "class" ).indexOf( o.classes.open ) > -1;

					el[ isOpen ? "removeClass" : "addClass" ]( o.classes.open );
					btn.innerHTML = ( isOpen ? o.text.open : o.text.close );

					e.preventDefault();

				})
				.insertBefore( el );
		},
		_createSource: function() {
			var el = this;
			var getPrefixText = function () {
				if( el.className.match( new RegExp( "\\b" + o.classes.antipattern + "\\b", "gi" ) ) ) {
					return o.text.antipattern;
				}
				return o.text.titlePrefix;
			};
			var title = el.getElementsByClassName( o.classes.title );
			var deprecatedTitle;
			var preel = document.createElement( "pre" );
			var codeel = document.createElement( "code" );
			var wrap = document.createElement( "div" );
			var sourcepanel = document.createElement( "div" );
			var code;
			var leadingWhiteSpace;
			var source;

			if( title.length ) {
				title = title[ 0 ];
				title.parentNode.removeChild( title );
				title.innerHTML = getPrefixText() + ": " + title.innerHTML;
			} else {
				deprecatedTitle = el.getAttribute( "data-title" );
				title = document.createElement( "div" );
				title.className = o.classes.title;
				title.innerHTML = getPrefixText() + ( deprecatedTitle ? ": " + deprecatedTitle : "" );
			}

			// remove empty value attributes
			code = el.innerHTML.replace( /\=\"\"/g, '' );
			leadingWhiteSpace = code.match( /(^[\s]+)/ );

			if( leadingWhiteSpace ) {
				code = code.replace( new RegExp( leadingWhiteSpace[ 1 ], "gmi" ), "\n" );
			}

			source = document.createTextNode( code );

			wrap.setAttribute( "class", "snippet" );

			$( el ).wrapInner( wrap );

			codeel.appendChild( source );
			preel.appendChild( codeel );

			sourcepanel.setAttribute( "class", o.classes.sourcepanel );
			sourcepanel.appendChild( preel );

			this.appendChild( sourcepanel );
			this.insertBefore( title, this.firstChild );
		}
	};

	// Collection method.
	$.fn[ pluginName ] = function( arrg, a, b, c ) {
		return this.each(function() {

			// if it's a method
			if( arrg && typeof( arrg ) === "string" ){
				return $.fn[ pluginName ].prototype[ arrg ].call( this, a, b, c );
			}

			// don't re-init
			if( $( this ).data( pluginName + "data" ) ){
				return $( this );
			}

			// otherwise, init
			$( this ).data( pluginName + "active", true );
			$.fn[ pluginName ].prototype._create.call( this );
		});
	};

	// add methods
	$.extend( $.fn[ pluginName ].prototype, methods );

	//  auto-init
	var initted;
	function init(){
		if( !initted ){
			$( o.initSelector )[ pluginName ]();
			initted = true;
		}
	}
	// init either on beforeenhance event or domready, whichever comes first.
	$( document ).bind("beforeenhance", init );
	$( init );

}( jQuery ));
<|endoftext|>


<commit_before>const INDENT_REGEXP = /(?:\n)[ \t]+/g;

function changeIndent(str, diff) {
  return str.replace(INDENT_REGEXP, matched => "\n" + " ".repeat(matched.length + diff));
}

function getIndents(strings) {
  return strings
    .map(s => s.match(INDENT_REGEXP) || [])
    .reduce((a, b) => a.concat(b), [])
    .map(s => s.length);
}

function fixIndents(strings, indent) {
  const indents = getIndents(strings);
  const origIndent = indents.length > 0 ? Math.min(...indents) : 0;
  return strings.map(s => changeIndent(s, indent - origIndent));
}

// TODO: source map support

export default
function render(indentLevel) {
  const indent = indentLevel * 2;
  return function (strings, ...values) {
    const indentedStrings = fixIndents(strings, indent);

    let ret = "";

    for (let i = 0; i < strings.length; ++i) {
      ret += indentedStrings[i];
      if (i < values.length) {
        ret += String(values[i]);
      }
    }
    return ret;
  }
}
<commit_msg>Add trimLast<commit_after>const INDENT_REGEXP = /(?:\n)[ \t]+/g;

function trimLast(strings) {
  return strings.map((s, i) => {
    if (i === strings.length - 1) {
      return s.trim();
    }
    return s;
  });
}

function changeIndent(str, diff) {
  return str.replace(INDENT_REGEXP, matched => "\n" + " ".repeat(matched.length + diff));
}

function getIndents(strings) {
  return strings
    .map(s => s.match(INDENT_REGEXP) || [])
    .reduce((a, b) => a.concat(b), [])
    .map(s => s.length);
}

function fixIndents(strings, indent) {
  const indents = getIndents(strings);
  const origIndent = indents.length > 0 ? Math.min(...indents) : 0;
  return strings.map(s => changeIndent(s, indent - origIndent));
}

// TODO: source map support

export default
function render(indentLevel) {
  const indent = indentLevel * 2;
  return function (strings, ...values) {
    const indentedStrings = fixIndents(trimLast(strings), indent);

    let ret = "";

    for (let i = 0; i < strings.length; ++i) {
      ret += indentedStrings[i];
      if (i < values.length) {
        ret += String(values[i]);
      }
    }
    return ret;
  }
}
<|endoftext|>


<commit_before>/**
 * Heatmap Service
 */

HeatmapService = (function(smartRHeatmap){

    var service = {
        statusInterval : 0,
        jobs : []
    };

    /**
     * Create analysis constraints
     * @param params
     * @returns {{conceptKey: _conceptPath, dataType: string, resultInstanceId: *, projection: string, label: string}}
     * @private
     */
    var _createAnalysisConstraints = function (params) {

        var _retval = {
            conceptKey : params.conceptPath,
            dataType: 'mrna',
            resultInstanceId: params.resultInstanceId,
            projection: 'log_intensity',
            label: '_TEST_LABEL_'
        };

        return  _retval;
    };

    /**
     * Create r-session id
     * @returns {*}
     */
    service.initialize = function () {

        // ajax call to session creation
        jQuery.ajax({
            url: pageInfo.basePath + '/RSession/create',
            type: 'POST',
            timeout: '600000',
            contentType: 'application/json',
            data : JSON.stringify( {
                workflow : 'heatmap'
            })
        }).done(function(response) {
            GLOBAL.HeimAnalyses = {
                type : 'heatmap',
                sessionId :response.sessionId
            };

            return GLOBAL.HeimAnalyses;
        }).fail(function() {
            // TODO: error displayed in a placeholder somewhere in main heim-analysis page
            console.error('Cannot create r-session');
            return null;
        });

    };

    /**
     * To get summary loaded data (at the moment for fetched data)
     * @param params
     * @returns {*}
     */
    service.getSummary = function (params) {
        var retval;

        console.log('About to get load data summary');

        jQuery.ajax({
            type: 'POST',
            url: pageInfo.basePath + '/ScriptExecution/run',
            data: JSON.stringify({
                sessionId : GLOBAL.HeimAnalyses.sessionId,
                arguments : {},
                taskType : 'summary'}
            ),
            contentType: 'application/json'
        })
            .done(function (data) {
                console.log(data);
                //var scriptExecObj = JSON.parse(data.responseText);
                GLOBAL.HeimAnalyses.executionId = data.executionId;
                console.log(GLOBAL.HeimAnalyses);
                service.statusInterval =  setInterval(function () {
                    service.checkStatus('getSummary');
                }, 1000);
            })
            .fail(function (jqXHR, textStatus, errorThrown) {
                console.log(jqXHR);
                console.log(textStatus);
                console.log(errorThrown);
            });
        return retval;
    };

    /**
     * Fetch data
     * @param eventObj
     */
    service.fetchData = function (params) {
        var _args = _createAnalysisConstraints(params);
        console.log('Analysis Constraints', _args);

        jQuery.ajax({
            url: pageInfo.basePath + '/ScriptExecution/run',
            type: 'POST',
            timeout: '600000',
            contentType: 'application/json',
            data: JSON.stringify({
                sessionId : GLOBAL.HeimAnalyses.sessionId,
                arguments : _args,
                taskType : 'fetchData',
                workflow : 'heatmap'
            })
        }).done(function (d) {
            console.log(d);
            //var scriptExecObj = JSON.parse(d.responseText);
            GLOBAL.HeimAnalyses.executionId = d.executionId;
            console.log(GLOBAL.HeimAnalyses);
            service.statusInterval =  setInterval(function () {
                service.checkStatus('fetchData');
            }, 1000);
        })
            .fail(function (jqXHR, textStatus, errorThrown) {
                var _err = JSON.parse(jqXHR.responseText);
                console.error(jqXHR);
                console.error(textStatus);
                console.error(errorThrown);
                jQuery('#heim-fetch-data-output')
                    .html('
Error:'+ errorThrown +'
 ' + _err.message + '
');
            });
    };

    /**
     *
     * @param request
     * @param response
     */
    service.getIndentifierSuggestions = function (request, response) {
        jQuery.get("/transmart/search/loadSearchPathways", {
            query: request.term
        }, function (data) {
            data = data.substring(5, data.length - 1);  // loadSearchPathways returns String with null (JSON).
                                                        // This strips it off
            data = JSON.parse(data);// String rep of JSON to actual JSON
            data = data['rows'];// Response is encapsulated in rows
            var suggestions = [];
            for (var i = 0; i < data.length;i++){
                var geneName = data[i]['keyword']; //I assume we use keywords, not synonyms or IDs
                suggestions.push(geneName);
            }
            response(suggestions);
        });

    };

    /**
     * Check status of a task
     * TODO: Refactor
     * @param task
     */
    service.checkStatus = function (task) {
        if (task === 'fetchData') {
            jQuery('#heim-fetch-data-output').html('
_Fetching data, please wait ..
');
        } else if (task === 'runHeatmap') {
            jQuery('#heim-run-output').show();
            jQuery('#heim-run-output').html('
Calculating, please wait ..
');
        } else if (task === 'getSummary') {
            jQuery('#heim-fetch-data-output').html('

_Getting summary, please wait ..
');
        }

        jQuery.ajax({
            type : 'GET',
            url : pageInfo.basePath + '/ScriptExecution/status',
            data : {
                sessionId : GLOBAL.HeimAnalyses.sessionId,
                executionId : GLOBAL.HeimAnalyses.executionId
            }
        })
        .done(function (d) {

                console.log('Done checking', d);

                if (d.state === 'FINISHED') {
                    clearInterval(service.statusInterval);
                    console.log('Okay, I am finished checking now ..', d);
                    if (task === 'fetchData') {
                        jQuery('#heim-fetch-data-output')
                            .html('
 ' +
                            'Data is successfully fetched in . Proceed with Run Heatmap
');

                        // render summary stat
                        service.getSummary();
                    } else if (task === 'runHeatmap') {
                        jQuery('#heim-run-output').hide();
                        jQuery.ajax({
                            url : pageInfo.basePath
                            + '/ScriptExecution/downloadFile?sessionId='
                            + GLOBAL.HeimAnalyses.sessionId
                            + '&executionId='
                            + GLOBAL.HeimAnalyses.executionId
                            + '&filename=heatmap.json',
                            dataType : 'json'
                        })
                            .done(function (d, status, jqXHR) {
                                console.log(d);
                                smartRHeatmap.create(d);
                            });
                    } else if (task === 'getSummary') {

                        console.log('getSummary');

                        jQuery('#heim-run-output').hide();
                        jQuery.ajax({
                            url : pageInfo.basePath
                            + '/ScriptExecution/downloadFile?sessionId='
                            + GLOBAL.HeimAnalyses.sessionId
                            + '&executionId='
                            + GLOBAL.HeimAnalyses.executionId
                            + '&filename=summary_stats_node.json',
                            dataType : 'json'
                        })
                            .done(function (d, status, jqXHR) {
                                console.log(d);
                                console.log(status);
                                console.log( jqXHR);
                                var _summaryObj = service.displaySummaryStats(d);
                                console.log(_summaryObj.table);
                                console.log(_summaryObj.plot);
                                jQuery('#heim-fetch-data-output')
                                    .empty()
                                    .append(_summaryObj.plot)
                                    .append(_summaryObj.table);

                            });
                    }
                } else if (d.state === 'FAILED') {
                    clearInterval(service.statusInterval);
                    jQuery('#heim-fetch-data-output')
                        .html('
 ' +
                        d.result.exception + '
');
                    console.error('FAILED', d.result);
                }
        })
        .fail(function (jqXHR, textStatus, errorThrown) {
                console.log(jqXHR);
                console.log(textStatus);
                console.log(errorThrown);
                clearInterval(service.statusInterval);
                if (task === 'fetchData') {
                    jQuery('#heim-fetch-data-output').html(''+errorThrown+'');
                } else if (task === 'runHeatmap') {
                    jQuery('#heim-run-output').html(''+errorThrown+'</spanp>');
                }
        })
        .always(function () {
            console.log('checked!');
        });
    };

    /**
     * Display Plot
     * @param data
     * @returns {{table: *, plot: *}}
     */
    service.displaySummaryStats = function (data) {

        var _table = jQuery('

').addClass('sr-summary-table');
        _table.append('
Loaded	Values
');

        jQuery.each(data,  function (idx, item) {
            _table.append('
Max	' + item.max + '
');
            _table.append('
Mean	' + item.mean + '
');
            _table.append('
Median	' + item.median + '
');
            _table.append('
No. of missing values	' + item.numberOfMissingValues + '
');
            _table.append('
Q1	' + item.q1 + '
');
            _table.append('
Q3	' + item.q3 + '
');
            _table.append('
Standard Deviation	' + item.standardDeviation + '
');
            _table.append('
Total no. of values (incl. missing)	' +
                item.totalNumberOfValuesIncludingMissing + '
');
            _table.append('
Variable Label	' + item.variableLabel + '
');
        });

        var _plot = jQuery('')
            .attr('src', pageInfo.basePath
            + '/ScriptExecution/downloadFile?sessionId='
            + GLOBAL.HeimAnalyses.sessionId
            + '&executionId='
            + GLOBAL.HeimAnalyses.executionId
            + '&filename=box_plot_node.png');

        return {table:_table,  plot:_plot};
    };

    service.runAnalysis = function (params) {
        jQuery.ajax({
            type: 'POST',
            url: pageInfo.basePath + '/ScriptExecution/run',
            data: JSON.stringify({
                sessionId : GLOBAL.HeimAnalyses.sessionId,
                arguments : params,
                taskType : 'run'}
            ),
            contentType: 'application/json',
            complete: function(data) {
                var scriptExecObj = JSON.parse(data.responseText);
                GLOBAL.HeimAnalyses.executionId = scriptExecObj.executionId;
                console.log(GLOBAL.HeimAnalyses);
                service.statusInterval =  setInterval(function () {
                    service.checkStatus('runHeatmap');
                }, 1000);
            }
        });
    };

    return service;
})(SmartRHeatmap);
<commit_msg>Fix wrong error msg placement<commit_after>/**
 * Heatmap Service
 */

HeatmapService = (function(smartRHeatmap){

    var service = {
        statusInterval : 0
    };

    /**
     * Create analysis constraints
     * @param params
     * @returns {{conceptKey: _conceptPath, dataType: string, resultInstanceId: *, projection: string, label: string}}
     * @private
     */
    var _createAnalysisConstraints = function (params) {
        console.log(params);
        var _retval = {
            conceptKey : params.conceptPath,
            dataType: 'mrna',
            resultInstanceId: params.resultInstanceId,
            projection: 'log_intensity',
            label: '_TEST_LABEL_'
        };

        return  _retval;
    };

    /**
     * Create r-session id
     * @returns {*}
     */
    service.initialize = function () {

        // ajax call to session creation
        jQuery.ajax({
            url: pageInfo.basePath + '/RSession/create',
            type: 'POST',
            timeout: '600000',
            contentType: 'application/json',
            data : JSON.stringify( {
                workflow : 'heatmap'
            })
        }).done(function(response) {
            GLOBAL.HeimAnalyses = {
                type : 'heatmap',
                sessionId :response.sessionId
            };

            return GLOBAL.HeimAnalyses;
        }).fail(function() {
            // TODO: error displayed in a placeholder somewhere in main heim-analysis page
            console.error('Cannot create r-session');
            return null;
        });

    };

    /**
     * To get summary loaded data (at the moment for fetched data)
     * @param params
     * @returns {*}
     */
    service.getSummary = function (params) {
        var retval;

        console.log('About to get load data summary');

        jQuery.ajax({
            type: 'POST',
            url: pageInfo.basePath + '/ScriptExecution/run',
            data: JSON.stringify({
                sessionId : GLOBAL.HeimAnalyses.sessionId,
                arguments : {},
                taskType : 'summary'}
            ),
            contentType: 'application/json'
        })
            .done(function (data) {
                console.log(data);
                //var scriptExecObj = JSON.parse(data.responseText);
                GLOBAL.HeimAnalyses.executionId = data.executionId;
                console.log(GLOBAL.HeimAnalyses);
                service.statusInterval =  setInterval(function () {
                    service.checkStatus('getSummary');
                }, 1000);
            })
            .fail(function (jqXHR, textStatus, errorThrown) {
                console.log(jqXHR);
                console.log(textStatus);
                console.log(errorThrown);
            });
        return retval;
    };

    /**
     * Fetch data
     * @param eventObj
     */
    service.fetchData = function (params) {
        var _args = _createAnalysisConstraints(params);
        console.log('Analysis Constraints', _args);

        jQuery.ajax({
            url: pageInfo.basePath + '/ScriptExecution/run',
            type: 'POST',
            timeout: '600000',
            contentType: 'application/json',
            data: JSON.stringify({
                sessionId : GLOBAL.HeimAnalyses.sessionId,
                arguments : _args,
                taskType : 'fetchData',
                workflow : 'heatmap'
            })
        }).done(function (d) {
            console.log(d);
            //var scriptExecObj = JSON.parse(d.responseText);
            GLOBAL.HeimAnalyses.executionId = d.executionId;
            console.log(GLOBAL.HeimAnalyses);
            service.statusInterval =  setInterval(function () {
                service.checkStatus('fetchData');
            }, 1000);
        })
            .fail(function (jqXHR, textStatus, errorThrown) {
                var _err = JSON.parse(jqXHR.responseText);
                console.error(jqXHR);
                console.error(textStatus);
                console.error(errorThrown);
                jQuery('#heim-fetch-data-output')
                    .html('
Error:'+ errorThrown +'
 ' + _err.message + '
');
            });
    };

    /**
     *
     * @param request
     * @param response
     */
    service.getIndentifierSuggestions = function (request, response) {
        jQuery.get("/transmart/search/loadSearchPathways", {
            query: request.term
        }, function (data) {
            data = data.substring(5, data.length - 1);  // loadSearchPathways returns String with null (JSON).
                                                        // This strips it off
            data = JSON.parse(data);// String rep of JSON to actual JSON
            data = data['rows'];// Response is encapsulated in rows
            var suggestions = [];
            for (var i = 0; i < data.length;i++){
                var geneName = data[i]['keyword']; //I assume we use keywords, not synonyms or IDs
                suggestions.push(geneName);
            }
            response(suggestions);
        });

    };

    /**
     * Check status of a task
     * TODO: Refactor
     * @param task
     */
    service.checkStatus = function (task) {
        if (task === 'fetchData') {
            jQuery('#heim-fetch-data-output').html('
_Fetching data, please wait ..
');
        } else if (task === 'runHeatmap') {
            jQuery('#heim-run-output').show();
            jQuery('#heim-run-output').html('
Calculating, please wait ..
');
        } else if (task === 'getSummary') {
            jQuery('#heim-fetch-data-output').html('
_Getting summary, please wait ..
');
        }

        jQuery.ajax({
            type : 'GET',
            url : pageInfo.basePath + '/ScriptExecution/status',
            data : {
                sessionId : GLOBAL.HeimAnalyses.sessionId,
                executionId : GLOBAL.HeimAnalyses.executionId
            }
        })
        .done(function (d) {

                console.log('Done checking', d);

                if (d.state === 'FINISHED') {
                    clearInterval(service.statusInterval);
                    console.log('Okay, I am finished checking now ..', d);
                    if (task === 'fetchData') {
                        jQuery('#heim-fetch-data-output')
                            .html('
 ' +
                            'Data is successfully fetched in . Proceed with Run Heatmap
');

                        // render summary stat
                        service.getSummary();
                    } else if (task === 'runHeatmap') {
                        jQuery('#heim-run-output').hide();
                        jQuery.ajax({
                            url : pageInfo.basePath
                            + '/ScriptExecution/downloadFile?sessionId='
                            + GLOBAL.HeimAnalyses.sessionId
                            + '&executionId='
                            + GLOBAL.HeimAnalyses.executionId
                            + '&filename=heatmap.json',
                            dataType : 'json'
                        })
                            .done(function (d, status, jqXHR) {
                                console.log(d);
                                smartRHeatmap.create(d);
                            });
                    } else if (task === 'getSummary') {

                        console.log('getSummary');

                        jQuery('#heim-run-output').hide();
                        jQuery.ajax({
                            url : pageInfo.basePath
                            + '/ScriptExecution/downloadFile?sessionId='
                            + GLOBAL.HeimAnalyses.sessionId
                            + '&executionId='
                            + GLOBAL.HeimAnalyses.executionId
                            + '&filename=summary_stats_node.json',
                            dataType : 'json'
                        })
                            .done(function (d, status, jqXHR) {
                                console.log(d);
                                console.log(status);
                                console.log( jqXHR);
                                var _summaryObj = service.displaySummaryStats(d);
                                console.log(_summaryObj.table);
                                console.log(_summaryObj.plot);
                                jQuery('#heim-fetch-data-output')
                                    .empty()
                                    .append(_summaryObj.plot)
                                    .append(_summaryObj.table);

                            });
                    }
                } else if (d.state === 'FAILED') {

                    clearInterval(service.statusInterval); // stop checking backend

                    if (task === 'runHeatmap') {
                        jQuery('#heim-run-output').html('' + d.result.exception +'');
                    }
                    console.error('FAILED', d.result);
                }
        })
        .fail(function (jqXHR, textStatus, errorThrown) {

                console.log(jqXHR);
                console.log(textStatus);
                console.log(errorThrown);

                clearInterval(service.statusInterval); // stop checking backend

                if (task === 'fetchData') {
                    jQuery('#heim-fetch-data-output').html(''+errorThrown+'');
                } else if (task === 'runHeatmap') {
                    jQuery('#heim-run-output').html(''+errorThrown+'</spanp>');
                }
        })
        .always(function () {
            console.log('checked!');
        });
    };

    /**
     * Display Plot
     * @param data
     * @returns {{table: *, plot: *}}
     */
    service.displaySummaryStats = function (data) {

        var _table = jQuery('

').addClass('sr-summary-table');
        _table.append('
Loaded	Values
');

        jQuery.each(data,  function (idx, item) {
            _table.append('
Max	' + item.max + '
');
            _table.append('
Mean	' + item.mean + '
');
            _table.append('
Median	' + item.median + '
');
            _table.append('
No. of missing values	' + item.numberOfMissingValues + '
');
            _table.append('
Q1	' + item.q1 + '
');
            _table.append('
Q3	' + item.q3 + '
');
            _table.append('
Standard Deviation	' + item.standardDeviation + '
');
            _table.append('
Total no. of values (incl. missing)	' +
                item.totalNumberOfValuesIncludingMissing + '
');
            _table.append('
Variable Label	' + item.variableLabel + '
');
        });

        var _plot = jQuery('')
            .attr('src', pageInfo.basePath
            + '/ScriptExecution/downloadFile?sessionId='
            + GLOBAL.HeimAnalyses.sessionId
            + '&executionId='
            + GLOBAL.HeimAnalyses.executionId
            + '&filename=box_plot_node.png');

        return {table:_table,  plot:_plot};
    };

    service.runAnalysis = function (params) {
        jQuery.ajax({
            type: 'POST',
            url: pageInfo.basePath + '/ScriptExecution/run',
            data: JSON.stringify({
                sessionId : GLOBAL.HeimAnalyses.sessionId,
                arguments : params,
                taskType : 'run'}
            ),
            contentType: 'application/json',
            complete: function(data) {
                var scriptExecObj = JSON.parse(data.responseText);
                GLOBAL.HeimAnalyses.executionId = scriptExecObj.executionId;
                console.log(GLOBAL.HeimAnalyses);
                service.statusInterval =  setInterval(function () {
                    service.checkStatus('runHeatmap');
                }, 1000);
            }
        });
    };

    return service;
})(SmartRHeatmap);
<|endoftext|>


<commit_before><commit_msg>Cepage revendiqué au lieu d'assemblage<commit_after><|endoftext|>


<commit_before>
const parse = require('../lib/sync')
const assert = require('assert')

const data = `
# At the begening of a record
"hello"
"world"# At the end of a record
`.trim()
const records = parse(data, {
  comment: "#"
})
assert.deepStrictEqual(records, [
  [ "hello" ],
  [ "world" ]
])
<commit_msg>docs: fix typo in comment sample<commit_after>
const parse = require('../lib/sync')
const assert = require('assert')

const data = `
# At the beginning of a record
"hello"
"world"# At the end of a record
`.trim()
const records = parse(data, {
  comment: "#"
})
assert.deepStrictEqual(records, [
  [ "hello" ],
  [ "world" ]
])
<|endoftext|>