<commit_before>import PropTypes from 'prop-types';
import withSeriesType from './components/WithSeriesType'

// Graphs
export { default as HighchartsChart }  from './components/HighchartsChart';
export { default as HighchartsSparkline }  from './components/HighchartsSparkline';
export { default as Highcharts3dChart }  from './components/Highcharts3dChart';

// Graph parts
export { default as Annotation }  from './components/Annotation';
export { default as Chart }  from './components/Chart';
export { default as Credits }  from './components/Credits';
export { default as Loading }  from './components/Loading';
export { default as Legend }  from './components/Legend';
export { default as Pane }  from './components/Pane';
export { default as PlotBand }  from './components/PlotBand';
export { default as PlotLine }  from './components/PlotLine';
export { default as Subtitle }  from './components/Subtitle';
export { default as Title }  from './components/Title';
export { default as Tooltip }  from './components/Tooltip';
export { default as XAxis }  from './components/XAxis';
export { default as YAxis }  from './components/YAxis';
export { default as ZAxis }  from './components/ZAxis';

const axisNotRequired = { requiresAxis: false };
const hasParentSeries = { baseSeries: PropTypes.string.isRequired };

// Series
export const AreaRangeSeries = withSeriesType('AreaRange');
export const AreaSeries = withSeriesType('Area');
export const AreaSplineRangeSeries = withSeriesType('AreaSplineRange');
export const AreaSplineSeries = withSeriesType('AreaSpline');
export { default as BarSeries }  from './components/BarSeries';
export const BellCurveSeries = withSeriesType('BellCurve', {}, hasParentSeries);
export const BoxPlotSeries = withSeriesType('BoxPlot');
export const BubbleSeries = withSeriesType('Bubble');
export const BulletSeries = withSeriesType('Bullet');
export const ColumnPyramidSeries = withSeriesType('ColumnPyramid');
export const ColumnRangeSeries = withSeriesType('ColumnRange');
export const ColumnSeries = withSeriesType('Column');
export const CylinderSeries = withSeriesType('Cylinder');
export const ErrorBarSeries = withSeriesType('ErrorBar');
export const FunnelSeries = withSeriesType('Funnel', axisNotRequired);
export const GaugeSeries = withSeriesType('Gauge');
export const HeatmapSeries = withSeriesType('Heatmap');
export const HistogramSeries = withSeriesType('Histogram', {}, hasParentSeries);
export const LineSeries = withSeriesType('Line');
export const NetworkGraphSeries = withSeriesType('NetworkGraph');
export const PackedBubbleSeries = withSeriesType('PackedBubble', axisNotRequired);
export const ParetoSeries = withSeriesType('Pareto', {}, hasParentSeries);
export const PieSeries = withSeriesType('Pie', axisNotRequired);
export const PolygonSeries = withSeriesType('Polygon');
export const PyramidSeries = withSeriesType('Pyramid', axisNotRequired);
export const SankeySeries = withSeriesType('Sankey');
export const ScatterSeries = withSeriesType('Scatter');
export const Scatter3dSeries = withSeriesType('Scatter3d');
export const SolidGaugeSeries = withSeriesType('SolidGauge');
export const SplineSeries = withSeriesType('Spline');
export const StreamGraphSeries = withSeriesType('StreamGraph');
export const SunburstSeries = withSeriesType('Sunburst');
export const TilemapSeries = withSeriesType('Tilemap');
export const TreemapSeries = withSeriesType('Treemap');
export const VariablePieSeries = withSeriesType('VariablePie', axisNotRequired);
export const VariwideSeries = withSeriesType('Variwide');
export const VennSeries = withSeriesType('Venn', axisNotRequired);
export const VectorSeries = withSeriesType('Vector');
export const WaterfallSeries = withSeriesType('Waterfall');
export const WindBarbSeries = withSeriesType('WindBarb');
export const XRangeSeries = withSeriesType('XRange');

// Providers
export { Consumer, Provider } from './components/HighchartsContext';
export { default as provideHighcharts }  from './components/HighchartsProvider';
export { default as provideChart }  from './components/ChartProvider';
export { default as provideAxis }  from './components/AxisProvider';
export { default as provideSeries }  from './components/SeriesProvider';

// Helpers
export { default as withHighcharts }  from './components/WithHighcharts';
export { default as Axis }  from './components/Axis';
export { default as BaseChart }  from './components/BaseChart';
export { default as Debug }  from './components/Debug';
export { default as Hidden }  from './components/Hidden';
export { default as Series }  from './components/Series';

// Utils
export { default as getModifiedProps } from './utils/getModifiedProps';
export { getNonEventHandlerProps } from './utils/events';
export { getEventsConfig } from './utils/events';
export { withSeriesType }
<commit_msg>Update packages/react-jsx-highcharts/src/index.js<commit_after>import PropTypes from 'prop-types';
import withSeriesType from './components/WithSeriesType'

// Graphs
export { default as HighchartsChart }  from './components/HighchartsChart';
export { default as HighchartsSparkline }  from './components/HighchartsSparkline';
export { default as Highcharts3dChart }  from './components/Highcharts3dChart';

// Graph parts
export { default as Annotation }  from './components/Annotation';
export { default as Chart }  from './components/Chart';
export { default as Credits }  from './components/Credits';
export { default as Loading }  from './components/Loading';
export { default as Legend }  from './components/Legend';
export { default as Pane }  from './components/Pane';
export { default as PlotBand }  from './components/PlotBand';
export { default as PlotLine }  from './components/PlotLine';
export { default as Subtitle }  from './components/Subtitle';
export { default as Title }  from './components/Title';
export { default as Tooltip }  from './components/Tooltip';
export { default as XAxis }  from './components/XAxis';
export { default as YAxis }  from './components/YAxis';
export { default as ZAxis }  from './components/ZAxis';

const axisNotRequired = { requiresAxis: false };
const hasParentSeries = { baseSeries: PropTypes.string.isRequired };

// Series
export const AreaRangeSeries = withSeriesType('AreaRange');
export const AreaSeries = withSeriesType('Area');
export const AreaSplineRangeSeries = withSeriesType('AreaSplineRange');
export const AreaSplineSeries = withSeriesType('AreaSpline');
export { default as BarSeries }  from './components/BarSeries';
export const BellCurveSeries = withSeriesType('BellCurve', {}, hasParentSeries);
export const BoxPlotSeries = withSeriesType('BoxPlot');
export const BubbleSeries = withSeriesType('Bubble');
export const BulletSeries = withSeriesType('Bullet');
export const ColumnPyramidSeries = withSeriesType('ColumnPyramid');
export const ColumnRangeSeries = withSeriesType('ColumnRange');
export const ColumnSeries = withSeriesType('Column');
export const CylinderSeries = withSeriesType('Cylinder');
export const ErrorBarSeries = withSeriesType('ErrorBar');
export const FunnelSeries = withSeriesType('Funnel', axisNotRequired);
export const GaugeSeries = withSeriesType('Gauge');
export const HeatmapSeries = withSeriesType('Heatmap');
export const HistogramSeries = withSeriesType('Histogram', {}, hasParentSeries);
export const LineSeries = withSeriesType('Line');
export const NetworkGraphSeries = withSeriesType('NetworkGraph');
export const PackedBubbleSeries = withSeriesType('PackedBubble', axisNotRequired);
export const ParetoSeries = withSeriesType('Pareto', {}, hasParentSeries);
export const PieSeries = withSeriesType('Pie', axisNotRequired);
export const PolygonSeries = withSeriesType('Polygon');
export const PyramidSeries = withSeriesType('Pyramid', axisNotRequired);
export const SankeySeries = withSeriesType('Sankey');
export const ScatterSeries = withSeriesType('Scatter');
export const Scatter3dSeries = withSeriesType('Scatter3d');
export const SolidGaugeSeries = withSeriesType('SolidGauge');
export const SplineSeries = withSeriesType('Spline');
export const StreamGraphSeries = withSeriesType('StreamGraph');
export const SunburstSeries = withSeriesType('Sunburst');
export const TilemapSeries = withSeriesType('Tilemap');
export const TreemapSeries = withSeriesType('Treemap');
export const VariablePieSeries = withSeriesType('VariablePie', axisNotRequired);
export const VariwideSeries = withSeriesType('Variwide');
export const VennSeries = withSeriesType('Venn', axisNotRequired);
export const VectorSeries = withSeriesType('Vector');
export const WaterfallSeries = withSeriesType('Waterfall');
export const WindBarbSeries = withSeriesType('WindBarb');
export const XRangeSeries = withSeriesType('XRange');

// Providers
export { Consumer as HighchartsConsumer, Provider as HighchartsProvider } from './components/HighchartsContext';
export { default as provideHighcharts }  from './components/HighchartsProvider';
export { default as provideChart }  from './components/ChartProvider';
export { default as provideAxis }  from './components/AxisProvider';
export { default as provideSeries }  from './components/SeriesProvider';

// Helpers
export { default as withHighcharts }  from './components/WithHighcharts';
export { default as Axis }  from './components/Axis';
export { default as BaseChart }  from './components/BaseChart';
export { default as Debug }  from './components/Debug';
export { default as Hidden }  from './components/Hidden';
export { default as Series }  from './components/Series';

// Utils
export { default as getModifiedProps } from './utils/getModifiedProps';
export { getNonEventHandlerProps } from './utils/events';
export { getEventsConfig } from './utils/events';
export { withSeriesType }
<|endoftext|>


<commit_before>Template.sidebar_left_fixed.rendered = function() {
  var $sidebar   = $("#toc"),
  $window    = $(window),
  offset     = $sidebar.offset(),
  topPadding = 100;

  $window.scroll(function() {
    if ($window.scrollTop() > offset.top && $window.width() > 700) {
      $sidebar.stop().animate({
        marginTop: $window.scrollTop() - offset.top + topPadding
      });
    } else if ($window.width() > 700) {
      $sidebar.stop().animate({
        marginTop: 50
      });
    }
  });
}<commit_msg>Fixed link to anchor (note: Iron-router anchor links do not work!)<commit_after>Template.sidebar_left_fixed.rendered = function() {
  var $sidebar   = $("#toc"),
  $window    = $(window),
  offset     = $sidebar.offset(),
  topPadding = 100;

  $window.scroll(function() {
    if ($window.scrollTop() > offset.top && $window.width() > 700) {
      $sidebar.stop().animate({
        marginTop: $window.scrollTop() - offset.top + topPadding
      });
    } else if ($window.width() > 700) {
      $sidebar.stop().animate({
        marginTop: 50
      });
    }
  });
}

Template.sidebar_left_fixed.events = {
  'click #toc a': function(e) {
    e.preventDefault();
    var hash = $(e.currentTarget).attr('href');
    if($(hash).length > 0) $('html,body').animate({scrollTop: $(hash).offset().top}, 500);
  }
}<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Text as RNText } from 'react-native';
import _ from 'lodash';

import { connectStyle } from 'native-base-shoutem-theme';
import { connectAnimation } from '@shoutem/animation';
import mapPropsToStyleNames from '../Utils/mapPropsToStyleNames';

class Text extends Component {
  render() {
    console.log('children', this.props.children);
    return (
      <RNText ref={c => (this._root = c)} {...this.props}>
        {this.props.uppercase
          ? _.toUpper(this.props.children)
          : this.props.children}
      </RNText>
    );
  }
}

Text.propTypes = {
  ...RNText.propTypes,
  uppercase: React.PropTypes.bool,
  style: React.PropTypes.object,
};

Text.defaultProps = {
  uppercase: false,
};

const AnimatedText = connectAnimation(Text);
const StyledText = connectStyle('NativeBase.Text', {}, mapPropsToStyleNames)(
  Text
);

export { StyledText as Text };
<commit_msg>Text add debug code<commit_after>import React, { Component } from 'react';
import { Text as RNText } from 'react-native';
import _ from 'lodash';

import { connectStyle } from 'native-base-shoutem-theme';
import { connectAnimation } from '@shoutem/animation';
import mapPropsToStyleNames from '../Utils/mapPropsToStyleNames';

class Text extends Component {
  render() {
    console.log('Text.props.children', this.props.children);
    return (
      <RNText ref={c => (this._root = c)} {...this.props}>
        {this.props.uppercase
          ? _.toUpper(this.props.children)
          : this.props.children}
      </RNText>
    );
  }
}

Text.propTypes = {
  ...RNText.propTypes,
  uppercase: React.PropTypes.bool,
  style: React.PropTypes.object,
};

Text.defaultProps = {
  uppercase: false,
};

const AnimatedText = connectAnimation(Text);
const StyledText = connectStyle('NativeBase.Text', {}, mapPropsToStyleNames)(
  Text
);

export { StyledText as Text };
<|endoftext|>


<commit_before>(function (factory) {
  if (typeof define === 'function' && define.amd) {
    define(['basil.js'], factory); // AMD
  } else if (typeof exports === 'object') {
    module.exports = factory(require( './basil.js')); // Node
  } else {
    factory(window.Basil); // Browser global
  }
}(function (Basil) {
  BasilList = function (options) {
    return new Basil.utils.extend(Basil.Storage().init(options), Basil.List(options));
  };

  Basil.List = function () {
    return {
      _listPlugin: true,
      blpop: function () {
        throw new Error('not implemented yet');
      },
      brpop: function () {
        throw new Error('not implemented yet');
      },
      brpoplpush: function (source, destination) {
        throw new Error('not implemented yet');
      },
      lindex: function (key, index) {
        var list = this.get(key) || [];

        if (index < 0)
          index = list.length + index;

        return list[index] || null;
      },
      linsert: function (key, where, pivot, value) {
        var
          index = -1,
          list = this.get(key) || [];

        if ('BEFORE' !== where && 'AFTER' !== where)
          throw new Error('AFTER|BEFORE');

        if ('string' !== typeof value && 'number' !== typeof value)
          throw new Error('supported values are only strings and numbers');

        for (var i = 0; i < list.length; i++) {
          if (pivot === list[i]) {
            index = i;
            break;
          }
        }

        if (-1 === index)
          return index;

        list.splice('AFTER' === where ? i - 1 : i, 0, value);
        this.set(key, list);

        return list.length;
      },
      llen: function (key) {
        return (this.get(key) || []).length;
      },
      lpop: function (key) {
        var
          list = this.get(key) || [],
          value = list.shift();
        this.set(key, list);

        return value || null;
      },
      lpush: function (key, value) {
        var list = this.get(key) || [];
        list.unshift(value);
        this.set(key, list);

        return list.length;
      },
      lpushx: function (key, value) {
        throw new Error('not implemented yet');
      },
      lrange: function (key, start, stop) {
        var list = this.get(key) || [];

        if (-1 === stop)
          return list.slice(start);

        return list.slice(start, stop + 1);
      },
      lrem: function (key, count, value) {
        throw new Error('not implemented yet');
      },
      lset: function (key, index, value) {
        var list = this.get(key) || [];

        if (index < 0)
          index = list.length + i;

        if (index < 0 || index >= list.length)
          throw new Error("ERR index out of range");

        list[index] = value;
        return 'OK';
      },
      ltrim: function (key, start, stop) {
        throw new Error('not implemented yet');
      },
      rpop: function (key) {
        var
          list = this.get(key) || [],
          value = list.pop();
        this.set(key, list);

        return value || null;
      },
      rpoplpush: function (source, destination) {
        throw new Error('not implemented yet');
      },
      rpush: function (key, value) {
        var list = this.get(key) || [];
        list.push(value);
        this.set(key, list);

        return list.length;
      },
      rpushx: function (key, value) {
        throw new Error('not implemented yet');
      }
    };
  };

  window.Basil = BasilList;

  // AMD export
  if (typeof define === 'function' && define.amd) {
    define(function() {
      return BasilList;
    });
  // commonjs export
  } else if (typeof module !== 'undefined' && module.exports) {
    module.exports = BasilList;
  }

}));
<commit_msg>- fix typo - factorize lset and lindex index<commit_after>(function (factory) {
  if (typeof define === 'function' && define.amd) {
    define(['basil.js'], factory); // AMD
  } else if (typeof exports === 'object') {
    module.exports = factory(require( './basil.js')); // Node
  } else {
    factory(window.Basil); // Browser global
  }
}(function (Basil) {
  var BasilList = function (options) {
    return new Basil.utils.extend(Basil.Storage().init(options), Basil.List(options));
  };

  Basil.List = function () {
    var _toIndex = function (index, length) {
        if (index < 0)
          index = length + index;

        if (index < 0 || index >= length)
          throw new Error("ERR index out of range");
        return index;
    };

    return {
      _listPlugin: true,
      blpop: function () {
        throw new Error('not implemented yet');
      },
      brpop: function () {
        throw new Error('not implemented yet');
      },
      brpoplpush: function (source, destination) {
        throw new Error('not implemented yet');
      },
      lindex: function (key, index) {
        var list = this.get(key) || [];
        index = _toIndex(index, list.length);

        return list[index] || null;
      },
      linsert: function (key, where, pivot, value) {
        var index = -1,
          list = this.get(key) || [];

        if ('BEFORE' !== where && 'AFTER' !== where)
          throw new Error('AFTER|BEFORE');

        if ('string' !== typeof value && 'number' !== typeof value)
          throw new Error('supported values are only strings and numbers');

        for (var i = 0; i < list.length; i++) {
          if (pivot === list[i]) {
            index = i;
            break;
          }
        }

        if (-1 === index)
          return index;

        list.splice('AFTER' === where ? i - 1 : i, 0, value);
        this.set(key, list);

        return list.length;
      },
      llen: function (key) {
        return (this.get(key) || []).length;
      },
      lpop: function (key) {
        var list = this.get(key) || [],
          value = list.shift();
        this.set(key, list);

        return value || null;
      },
      lpush: function (key, value) {
        var list = this.get(key) || [];
        list.unshift(value);
        this.set(key, list);

        return list.length;
      },
      lpushx: function (key, value) {
        throw new Error('not implemented yet');
      },
      lrange: function (key, start, stop) {
        var list = this.get(key) || [];

        if (-1 === stop)
          return list.slice(start);

        return list.slice(start, stop + 1);
      },
      lrem: function (key, count, value) {
        throw new Error('not implemented yet');
      },
      lset: function (key, index, value) {
        var list = this.get(key) || [];
        index = _toIndex(index, list.length);
        list[index] = value;
        this.set(key, list);

        return 'OK';
      },
      ltrim: function (key, start, stop) {
        throw new Error('not implemented yet');
      },
      rpop: function (key) {
        var list = this.get(key) || [],
          value = list.pop();
        this.set(key, list);

        return value || null;
      },
      rpoplpush: function (source, destination) {
        throw new Error('not implemented yet');
      },
      rpush: function (key, value) {
        var list = this.get(key) || [];
        list.push(value);
        this.set(key, list);

        return list.length;
      },
      rpushx: function (key, value) {
        throw new Error('not implemented yet');
      }
    };
  };

  // browser export
  window.Basil = BasilList;

  // AMD export
  if (typeof define === 'function' && define.amd) {
    define(function() {
      return BasilList;
    });
  // commonjs export
  } else if (typeof module !== 'undefined' && module.exports) {
    module.exports = BasilList;
  }

}));
<|endoftext|>


<commit_before>// @flow
import type { ComponentType } from 'react';
import {
  type IndicatorContainerProps,
  type ContainerProps,
  type ValueContainerProps,
  IndicatorsContainer,
  SelectContainer,
  ValueContainer,
} from './containers';
import {
  type IndicatorProps,
  type LoadingIconProps,
  ClearIndicator,
  DropdownIndicator,
  LoadingIndicator,
  IndicatorSeparator,
} from './indicators';

import Control, { type ControlProps } from './Control';
import Group, { type GroupProps, GroupHeading } from './Group';
import Input, { type InputProps } from './Input';
import Menu, {
  type MenuProps,
  MenuList,
  type MenuListComponentProps,
  MenuPortal,
  type MenuPortalProps,
  type NoticeProps,
  NoOptionsMessage,
  LoadingMessage,
} from './Menu';
import MultiValue, {
  type MultiValueProps,
  MultiValueContainer,
  MultiValueLabel,
  MultiValueRemove,
} from './MultiValue';
import Option, { type OptionProps } from './Option';
import Placeholder, { type PlaceholderProps } from './Placeholder';
import SingleValue, { type SingleValueProps } from './SingleValue';

type IndicatorComponentType = ComponentType<IndicatorProps>;

export type SelectComponents = {
  ClearIndicator: IndicatorComponentType,
  Control: ComponentType<ControlProps>,
  DropdownIndicator: IndicatorComponentType,
  Group: ComponentType<GroupProps>,
  GroupHeading: ComponentType<any>,
  IndicatorsContainer: ComponentType<IndicatorContainerProps>,
  IndicatorSeparator: IndicatorComponentType,
  Input: ComponentType<InputProps>,
  LoadingIndicator: ComponentType<LoadingIconProps>,
  Menu: ComponentType<MenuProps>,
  MenuList: ComponentType<MenuListComponentProps>,
  MenuPortal: ComponentType<MenuPortalProps>,
  LoadingMessage: ComponentType<NoticeProps>,
  NoOptionsMessage: ComponentType<NoticeProps>,
  MultiValue: ComponentType<MultiValueProps>,
  MultiValueContainer: ComponentType<any>,
  MultiValueLabel: ComponentType<any>,
  MultiValueRemove: ComponentType<any>,
  Option: ComponentType<OptionProps>,
  Placeholder: ComponentType<PlaceholderProps>,
  SelectContainer: ComponentType<ContainerProps>,
  SingleValue: ComponentType<SingleValueProps>,
  ValueContainer: ComponentType<ValueContainerProps>,
};

export type SelectComponentsConfig = $Shape<SelectComponents>;

export const components: SelectComponents = {
  ClearIndicator: ClearIndicator,
  Control: Control,
  DropdownIndicator: DropdownIndicator,
  Group: Group,
  GroupHeading: GroupHeading,
  IndicatorsContainer: IndicatorsContainer,
  IndicatorSeparator: IndicatorSeparator,
  Input: Input,
  LoadingIndicator: LoadingIndicator,
  Menu: Menu,
  MenuList: MenuList,
  MenuPortal: MenuPortal,
  LoadingMessage: LoadingMessage,
  NoOptionsMessage: NoOptionsMessage,
  MultiValue: MultiValue,
  MultiValueContainer: MultiValueContainer,
  MultiValueLabel: MultiValueLabel,
  MultiValueRemove: MultiValueRemove,
  Option: Option,
  Placeholder: Placeholder,
  SelectContainer: SelectContainer,
  SingleValue: SingleValue,
  ValueContainer: ValueContainer,
};

type Props = {
  components: SelectComponentsConfig,
};

export const defaultComponents = (props: Props) => ({
  ...components,
  ...props.components,
});
<commit_msg>Export indicator icons for use in customizations<commit_after>// @flow
import type { ComponentType } from 'react';
import {
  type IndicatorContainerProps,
  type ContainerProps,
  type ValueContainerProps,
  IndicatorsContainer,
  SelectContainer,
  ValueContainer,
} from './containers';
import {
  type IndicatorProps,
  type LoadingIconProps,
  ClearIndicator,
  DropdownIndicator,
  LoadingIndicator,
  IndicatorSeparator,
  DownChevron,
  CrossIcon,
} from './indicators';

import Control, { type ControlProps } from './Control';
import Group, { type GroupProps, GroupHeading } from './Group';
import Input, { type InputProps } from './Input';
import Menu, {
  type MenuProps,
  MenuList,
  type MenuListComponentProps,
  MenuPortal,
  type MenuPortalProps,
  type NoticeProps,
  NoOptionsMessage,
  LoadingMessage,
} from './Menu';
import MultiValue, {
  type MultiValueProps,
  MultiValueContainer,
  MultiValueLabel,
  MultiValueRemove,
} from './MultiValue';
import Option, { type OptionProps } from './Option';
import Placeholder, { type PlaceholderProps } from './Placeholder';
import SingleValue, { type SingleValueProps } from './SingleValue';

type IndicatorComponentType = ComponentType<IndicatorProps>;

export type SelectComponents = {
  ClearIndicator: IndicatorComponentType,
  Control: ComponentType<ControlProps>,
  DropdownIndicator: IndicatorComponentType,
  DownChevron: ComponentType<any>,
  CrossIcon: ComponentType<any>,
  Group: ComponentType<GroupProps>,
  GroupHeading: ComponentType<any>,
  IndicatorsContainer: ComponentType<IndicatorContainerProps>,
  IndicatorSeparator: IndicatorComponentType,
  Input: ComponentType<InputProps>,
  LoadingIndicator: ComponentType<LoadingIconProps>,
  Menu: ComponentType<MenuProps>,
  MenuList: ComponentType<MenuListComponentProps>,
  MenuPortal: ComponentType<MenuPortalProps>,
  LoadingMessage: ComponentType<NoticeProps>,
  NoOptionsMessage: ComponentType<NoticeProps>,
  MultiValue: ComponentType<MultiValueProps>,
  MultiValueContainer: ComponentType<any>,
  MultiValueLabel: ComponentType<any>,
  MultiValueRemove: ComponentType<any>,
  Option: ComponentType<OptionProps>,
  Placeholder: ComponentType<PlaceholderProps>,
  SelectContainer: ComponentType<ContainerProps>,
  SingleValue: ComponentType<SingleValueProps>,
  ValueContainer: ComponentType<ValueContainerProps>,
};

export type SelectComponentsConfig = $Shape<SelectComponents>;

export const components: SelectComponents = {
  ClearIndicator: ClearIndicator,
  Control: Control,
  DropdownIndicator: DropdownIndicator,
  DownChevron: DownChevron,
  CrossIcon: CrossIcon,
  Group: Group,
  GroupHeading: GroupHeading,
  IndicatorsContainer: IndicatorsContainer,
  IndicatorSeparator: IndicatorSeparator,
  Input: Input,
  LoadingIndicator: LoadingIndicator,
  Menu: Menu,
  MenuList: MenuList,
  MenuPortal: MenuPortal,
  LoadingMessage: LoadingMessage,
  NoOptionsMessage: NoOptionsMessage,
  MultiValue: MultiValue,
  MultiValueContainer: MultiValueContainer,
  MultiValueLabel: MultiValueLabel,
  MultiValueRemove: MultiValueRemove,
  Option: Option,
  Placeholder: Placeholder,
  SelectContainer: SelectContainer,
  SingleValue: SingleValue,
  ValueContainer: ValueContainer,
};

type Props = {
  components: SelectComponentsConfig,
};

export const defaultComponents = (props: Props) => ({
  ...components,
  ...props.components,
});
<|endoftext|>


<commit_before>__resources__["/resourceLoader.js"] = {
  meta: {
    mimetype: "application/javascript"
  },

  data: function(exports, require, module, __filename, __dirname) {
    var pomelo = window.pomelo;
    var dataApi = require('dataApi');
    var imgURL = require('config').IMAGE_URL;
    var EventEmitter = window.EventEmitter;
		var EntityType = require('consts').EntityType;
		var ObjectPoolFactory = require('objectPoolFactory');

    function ResourceLoader(opt) {
      EventEmitter.call(this);
      opt || (opt = {});
      this.totalCount = 0;
      this.loadedCount = 0;
      this.jsonLoad = !!opt.jsonLoad;
    }

    var pro = ResourceLoader.prototype = Object.create(EventEmitter.prototype);

    pro.setTotalCount = function(count) {
      this.totalCount = count;
      this.emit('loading', {total: this.totalCount, loaded: this.loadedCount});
    };

    pro.setLoadedCount = function(count) {
      this.loadedCount = count;
      this.emit('loading', {total: this.totalCount, loaded: this.loadedCount});
      if (this.loadedCount === this.totalCount) {
        this.emit('complete');
      }
    };

    pro.loadJsonResource = function(callback) {
      if (this.jsonLoad === false) {
        if (callback) {
          setTimeout(function(){
            callback();
          }, 50);
        }
        return;
      }
      var version = dataApi.getVersion();
      pomelo.request('area.resourceHandler.loadResource', {version: version},  function(result) {
        dataApi.setData(result.data);
        dataApi.setVersion(result.version);
        this.jsonLoad = false;
        if (callback) {
          callback();
        }
      });
    };

    pro.loadAreaResource = function() {
      var self = this;
      pomelo.request('area.resourceHandler.loadAreaResource',  {},function(data) {
        self.setTotalCount(1 + 1 + data.players.length * 8 + data.mobs.length * 8 + data.npcs.length + data.items.length + data.equipments.length);

        self.loadJsonResource(function(){
          self.setLoadedCount(self.loadedCount + 1);
          self.loadMap(data.mapName);
          self.loadCharacter(data.players);
          self.loadCharacter(data.mobs);
          self.loadNpc(data.npcs);
          self.loadItem(data.items);
          self.loadEquipment(data.equipments);
        });
        initObjectPools(data.mobs, EntityType.MOB);
        initObjectPools(data.players, EntityType.PLAYER);
      });
    };

    pro.loadImg = function(src) {
      var self = this;
      var img = new Image();
      img.onload = function() {
        self.setLoadedCount(self.loadedCount + 1);
      };

      img.onerror = function() {
        self.setLoadedCount(self.loadedCount + 1);
      };

      img.src = src;
    };

    pro.loadMap = function(name) {
      this.loadImg(imgURL + 'map/' + name + ".jpg");
    };

    pro.loadCharacter = function(ids) {
      var animation = ['Attack', 'Stand', 'Walk', 'Die'];
      var self = this;
      ids.forEach(function(id) {
        animation.forEach(function(action) {
          self.loadImg(imgURL + 'animation/character/' + id + '/Left' + action + '.png');
          self.loadImg(imgURL + 'animation/character/' + id + '/Right' + action + '.png');
        });
      });
    };

    pro.loadNpc = function(ids) {
      var self = this;
      ids.forEach(function(id) {
        self.loadImg(imgURL + 'npc/' + id + '/stand/frame_0.png');
      });
    };

    pro.loadItem = function(ids) {
      if (ids.length > 0) {
        var self = this;
        var items = dataApi.item.all();
        ids.forEach(function(id) {
          self.loadImg(imgURL + 'item/' + items[id].imgId + '.png');
        });
      }
    };

    pro.loadEquipment = function(ids) {
      if (ids.length > 0) {
        var self = this;
        var equipments = dataApi.equipment.all();
        ids.forEach(function(id) {
          self.loadImg(imgURL + 'equipment/60/' + equipments[id].imgId + '.png');
        });
      }
    };

    /**
     * Initialize objectPool
     *
		 * @param {Array} ids
		 * @api private
		 */
		var initObjectPools = function(ids, type) {
			var of = new ObjectPoolFactory();
			for (var i = 0; i < ids.length; i ++) {
				var kindId = ids[i];
			  of.createPools(kindId, type);
			}
		};

    module.exports = ResourceLoader;
  }
};
<commit_msg>modify resource url<commit_after>__resources__["/resourceLoader.js"] = {
  meta: {
    mimetype: "application/javascript"
  },

  data: function(exports, require, module, __filename, __dirname) {
    var pomelo = window.pomelo;
    var dataApi = require('dataApi');
    var imgURL = require('config').IMAGE_URL;
    var EventEmitter = window.EventEmitter;
		var EntityType = require('consts').EntityType;
		var ObjectPoolFactory = require('objectPoolFactory');

    function ResourceLoader(opt) {
      EventEmitter.call(this);
      opt || (opt = {});
      this.totalCount = 0;
      this.loadedCount = 0;
      this.jsonLoad = !!opt.jsonLoad;
    }

    var pro = ResourceLoader.prototype = Object.create(EventEmitter.prototype);

    pro.setTotalCount = function(count) {
      this.totalCount = count;
      this.emit('loading', {total: this.totalCount, loaded: this.loadedCount});
    };

    pro.setLoadedCount = function(count) {
      this.loadedCount = count;
      this.emit('loading', {total: this.totalCount, loaded: this.loadedCount});
      if (this.loadedCount === this.totalCount) {
        this.emit('complete');
      }
    };

    pro.loadJsonResource = function(callback) {
      if (this.jsonLoad === false) {
        if (callback) {
          setTimeout(function(){
            callback();
          }, 50);
        }
        return;
      }
      var version = dataApi.getVersion();
      pomelo.request('area.resourceHandler.loadResource', {version: version},  function(result) {
        dataApi.setData(result.data);
        dataApi.setVersion(result.version);
        this.jsonLoad = false;
        if (callback) {
          callback();
        }
      });
    };

    pro.loadAreaResource = function() {
      var self = this;
      pomelo.request('area.resourceHandler.loadAreaResource',  {},function(data) {
        self.setTotalCount(1 + 1 + data.players.length * 8 + data.mobs.length * 8 + data.npcs.length + data.items.length + data.equipments.length);

        self.loadJsonResource(function(){
          self.setLoadedCount(self.loadedCount + 1);
          self.loadMap(data.mapName);
          self.loadCharacter(data.players);
          self.loadCharacter(data.mobs);
          self.loadNpc(data.npcs);
          self.loadItem(data.items);
          self.loadEquipment(data.equipments);
        });
        initObjectPools(data.mobs, EntityType.MOB);
        initObjectPools(data.players, EntityType.PLAYER);
      });
    };

    pro.loadImg = function(src) {
      var self = this;
      var img = new Image();
      img.onload = function() {
        self.setLoadedCount(self.loadedCount + 1);
      };

      img.onerror = function() {
        self.setLoadedCount(self.loadedCount + 1);
      };

      img.src = src;
    };

    pro.loadMap = function(name) {
      this.loadImg(imgURL + 'map/' + name + ".jpg");
    };

    pro.loadCharacter = function(ids) {
      var animation = ['Attack', 'Stand', 'Walk', 'Die'];
      var self = this;
      ids.forEach(function(id) {
        animation.forEach(function(action) {
          self.loadImg(imgURL + 'animation/' + id + '/Left' + action + '.png');
          self.loadImg(imgURL + 'animation/' + id + '/Right' + action + '.png');
        });
      });
    };

    pro.loadNpc = function(ids) {
      var self = this;
      ids.forEach(function(id) {
        self.loadImg(imgURL + 'npc/' + id + '.png');
      });
    };

    pro.loadItem = function(ids) {
      if (ids.length > 0) {
        var self = this;
        var items = dataApi.item.all();
        ids.forEach(function(id) {
          self.loadImg(imgURL + 'item/item_' + items[id].imgId + '.png');
        });
      }
    };

    pro.loadEquipment = function(ids) {
      if (ids.length > 0) {
        var self = this;
        var equipments = dataApi.equipment.all();
        ids.forEach(function(id) {
          self.loadImg(imgURL + 'item/item_' + equipments[id].imgId + '.png');
        });
      }
    };

    /**
     * Initialize objectPool
     *
		 * @param {Array} ids
		 * @api private
		 */
		var initObjectPools = function(ids, type) {
			var of = new ObjectPoolFactory();
			for (var i = 0; i < ids.length; i ++) {
				var kindId = ids[i];
			  of.createPools(kindId, type);
			}
		};

    module.exports = ResourceLoader;
  }
};
<|endoftext|>


<commit_before>import {v4 as uuid} from 'uuid'

import IcarusParser from './parser'

/**
 * 'Transceiver MODE' Buffer for future comparison.
 * Helps ignoring messages from transceiver.
 * @private
 * @type {Buffer}
 */
// TODO: check with the CanSat on: is this what we receive?
const tmBuffer = Buffer.from('Transceiver MODE')

/**
 * Creates and returns a "byteDelimiter" parser.
 * DISCLAIMER: It's a patched version of node-serialport's byteDelimiter parser.
 * You can find it's source here: https://github.com/EmergingTechnologyAdvisors/node-serialport/tree/master/lib/parsers.js
 * Changes from the original: trailing delimiters are removed, buffer passes through packetParser.parse before being emitted
 * and empty buffers and 'Transceiver MODE' messages are ignored.
 * Separates packets by a byte delimiter and passes them through {@link packetParser}
 * @returns {Function} The parser itself
 */
/*
LICENSE OF THE ORIGINAL "byteDelimiter" parser:

Copyright 2010, 2011, 2012 Christopher Williams. All rights reserved.
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.
*/
export function parser() {
	const delimiter = [254, 255]
	let buf = []
	let nextDelimIndex = 0

	return (emitter, buffer) => {
		for (let i = 0; i < buffer.length; i++) {
			buf[buf.length] = buffer[i]

			if (buf[buf.length - 1] === delimiter[nextDelimIndex]) {
				nextDelimIndex++
			}

			if (nextDelimIndex === delimiter.length) {
				// Remove trailing 254, 255 and ignore empty packets/'Transceiver MODE'
				// Spare the parser the trouble, packets are always at least 6 bytes
				if (buf.length >= 8 && !Buffer.from(buf).equals(tmBuffer)) {
					// Create one packetParser object per packet
					// If this one crashes, the others have a chance.
					// It shouldn't throw any exception, but sometimes weird things happen.
					// Let us not forget Murphy's Law.
					const packetParser = new IcarusParser()

					emitter.emit('data', packetParser.parse(Buffer.from(buf.slice(0, buf.length - 2))))
				}

				buf = []
				nextDelimIndex = 0
			}
		}
	}
}

/**
 * A handler for incoming {@link Serial#data}.
 * Saves packets to the local database.
 * Should be called bound to a {@link Station}.
 * @param {Object} packet Packet to be parsed and saved.
 * @return {Promise} Resolves when all is done.
 */
export function dataHandler(packet) {
	// Properly handle bad packets
	if (packet.type.length === 1 && packet.type !== '?') {
		// Assign packet score
		packet.score = this.classifier.classifyPacket(packet)
	} else {
		// Bad packets have score 0
		packet.score = 0
		this.classifier.classifyStationInc(0)

		// Generate a mostly random id
		packet._id = `?${packet.receivedAt}-${uuid()}`
	}

	// Alert UI through station
	this.emit('packet', packet)

	// Save to DB
	return this.db.put(packet)
		.then(() => this._log.trace('packet saved', {packet}))
		.catch(err => this._log.error(err))
}
<commit_msg>fix(data-handler): Split packets or \r\n<commit_after>import {v4 as uuid} from 'uuid'

import IcarusParser from './parser'

/**
 * 'Transceiver MODE' Buffer for future comparison.
 * Helps ignoring messages from transceiver.
 * @private
 * @type {Buffer}
 */
// TODO: check with the CanSat on: is this what we receive?
const tmBuffer = Buffer.from('Transceiver MODE')

/**
 * Creates and returns a "byteDelimiter" parser.
 * DISCLAIMER: It's a patched version of node-serialport's byteDelimiter parser.
 * You can find it's source here: https://github.com/EmergingTechnologyAdvisors/node-serialport/tree/master/lib/parsers.js
 * Changes from the original: trailing delimiters are removed, buffer passes through packetParser.parse before being emitted
 * and empty buffers and 'Transceiver MODE' messages are ignored.
 * Separates packets by a byte delimiter and passes them through {@link packetParser}
 * @returns {Function} The parser itself
 */
/*
LICENSE OF THE ORIGINAL "byteDelimiter" parser:

Copyright 2010, 2011, 2012 Christopher Williams. All rights reserved.
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.
*/
export function parser() {
	const delimiter = [13, 10] // \r\n
	let buf = []
	let nextDelimIndex = 0

	return (emitter, buffer) => {
		for (let i = 0; i < buffer.length; i++) {
			buf[buf.length] = buffer[i]

			if (buf[buf.length - 1] === delimiter[nextDelimIndex]) {
				nextDelimIndex++
			}

			if (nextDelimIndex === delimiter.length) {
				// Remove trailing 254, 255 and ignore empty packets/'Transceiver MODE'
				// Spare the parser the trouble, packets are always at least 6 bytes
				if (buf.length >= 8 && !Buffer.from(buf).equals(tmBuffer)) {
					// Create one packetParser object per packet
					// If this one crashes, the others have a chance.
					// It shouldn't throw any exception, but sometimes weird things happen.
					// Let us not forget Murphy's Law.
					const packetParser = new IcarusParser()

					emitter.emit('data', packetParser.parse(Buffer.from(buf.slice(0, buf.length - 2))))
				}

				buf = []
				nextDelimIndex = 0
			}
		}
	}
}

/**
 * A handler for incoming {@link Serial#data}.
 * Saves packets to the local database.
 * Should be called bound to a {@link Station}.
 * @param {Object} packet Packet to be parsed and saved.
 * @return {Promise} Resolves when all is done.
 */
export function dataHandler(packet) {
	// Properly handle bad packets
	if (packet.type.length === 1 && packet.type !== '?') {
		// Assign packet score
		packet.score = this.classifier.classifyPacket(packet)
	} else {
		// Bad packets have score 0
		packet.score = 0
		this.classifier.classifyStationInc(0)

		// Generate a mostly random id
		packet._id = `?${packet.receivedAt}-${uuid()}`
	}

	// Alert UI through station
	this.emit('packet', packet)

	// Save to DB
	return this.db.put(packet)
		.then(() => this._log.trace('packet saved', {packet}))
		.catch(err => this._log.error(err))
}
<|endoftext|>


<commit_before>import {
  letterP,
  digitP,
  whiteP,
  choice,
  stringP,
  anyOf,
  opt, // returns a Success(Maybe)
  sequenceP, // returns an array
  many1, // returns a Success(_)
  many,
  pchar,
  pstring,
} from './lib/parsers';

const array2String = res => res.join('');
const tuple2String = res => res.toArray().join('');

export const lineP = parser => parser.discardSecond(pstring('§§'))
  .setLabel('On one line: ' + parser.label);
const symbolicCharP = anyOf(symbolicChars());
export const numberP = many1(digitP).fmap(res => parseInt(res.join(''), 10))
  .setLabel('numberP');
export const whateverP = many(choice([letterP, digitP, whiteP, symbolicCharP]))
  .fmap(array2String).setLabel('Parsing whatever...');

export const weekdayP = choice(['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
  .map(stringP)).setLabel('weekdayP');
export const monthP = choice(['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
  .map(stringP)).setLabel('monthP');
export const yearP = many(digitP, 4).fmap(array2String).setLabel('yearP');
export const timezoneP = pchar('+').andThen(yearP)
  .fmap(tuple2String).setLabel('timezoneP');
export const daytimeP = sequenceP([
  numberP,
  pchar(':'),
  numberP,
  pchar(':'),
  numberP,
]).fmap(array2String).setLabel('daytimeP');

export const dateP = sequenceP([
  weekdayP,
  whiteP,
  monthP,
  whiteP,
  numberP,
  whiteP,
  daytimeP,
  whiteP,
  yearP,
  whiteP,
  timezoneP,
]).fmap(res => new Date(array2String(res))).setLabel('dateP');

const firstLineP = lineP(dateP);

export const filenameP = many1(choice([letterP, digitP, pchar('/'), pchar('.')])).fmap(array2String);

export const secondLineP = lineP(whiteP.discardFirst(filenameP).discardSecond(whateverP));

export const insertionsP = numberP.discardSecond(sequenceP([whiteP, pstring('insertion'), opt(pchar('s')), stringP('(+)')]));
export const deletionsP = numberP.discardSecond(sequenceP([whiteP, pstring('deletion'), opt(pchar('s')), stringP('(-)')]));

export const thirdLineP = lineP(sequenceP([whateverP, pchar(','), whiteP])
  .discardFirst(sequenceP([opt(insertionsP), opt(sequenceP([pchar(','), whiteP])), opt(deletionsP)])))
  .fmap(([maybeInsertions, maybeSeparator, maybeDeletions]) =>
      maybeInsertions.getOrElse(0) - maybeDeletions.getOrElse(0)) // deltaRows

//const commitP = ... // res = Tuple.Couple(filename, Tuple.Couple(date, deltaRows))

//const fileHistorySeparatorP = ...

//const fileHistoryP = ... // Tuple.Couple(filename, Tuple.Couple[](data, filesize))

//const gitLogFileP = ... // Tuple.Couple(filename, Tuple.Couple[](data, filesize))[]

function symbolicChars() {
  return [
    '/',
    '+',
    '-',
    '|',
    '\'',
    '¢',
    '©',
    '÷',
    'µ',
    '¶',
    '±',
    '€',
    '$',
    '£',
    '®',
    '™',
    '¥',
    '(', ')',
    'á', 'Á',
    'à', 'À',
    'â', 'Â',
    'å', 'Å',
    'ã', 'Ã',
    'ä', 'Ä',
    'æ', 'Æ',
    'ç', 'Ç',
    'é', 'É',
    'è', 'È',
    'ê', 'Ê',
    'ë', 'Ë',
    'í', 'Í',
    'ì', 'Ì',
    'î', 'Î',
    'ï', 'Ï',
    'ñ', 'Ñ',
    'ó', 'Ó',
    'ò', 'Ò',
    'ô', 'Ô',
    'ø', 'Ø',
    'õ', 'Õ',
    'ö', 'Ö',
    'ú', 'Ú',
    'ù', 'Ù',
    'û', 'Û',
    'ü', 'Ü',
    'ß', 'ÿ',
    '!',
    '?',
    '/',
    '=',
  ];
}
<commit_msg>puzzled by multiline parsers<commit_after>import {
  letterP,
  digitP,
  whiteP,
  choice,
  stringP,
  anyOf,
  opt, // returns a Success(Maybe)
  sequenceP, // returns an array
  many1, // returns a Success(_)
  many,
  pchar,
  pstring,
} from './lib/parsers';

import { Tuple } from './lib/tuples';
const Pair = Tuple.Pair;
const Triple = Tuple.Triple;

const array2String = res => res.join('');
const tuple2String = res => res.toArray().join('');

export const lineP = parser => parser.discardSecond(pstring('§§'))
  .setLabel('On one line: ' + parser.label);
const symbolicCharP = anyOf(symbolicChars());
export const numberP = many1(digitP).fmap(res => parseInt(res.join(''), 10))
  .setLabel('numberP');
export const whateverP = many(choice([letterP, digitP, whiteP, symbolicCharP]))
  .fmap(array2String).setLabel('Parsing whatever...');

export const weekdayP = choice(['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
  .map(stringP)).setLabel('weekdayP');
export const monthP = choice(['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
  .map(stringP)).setLabel('monthP');
export const yearP = many(digitP, 4).fmap(array2String).setLabel('yearP');
export const timezoneP = pchar('+').andThen(yearP)
  .fmap(tuple2String).setLabel('timezoneP');
export const daytimeP = sequenceP([
  numberP,
  pchar(':'),
  numberP,
  pchar(':'),
  numberP,
]).fmap(array2String).setLabel('daytimeP');

export const dateP = sequenceP([
  weekdayP,
  whiteP,
  monthP,
  whiteP,
  numberP,
  whiteP,
  daytimeP,
  whiteP,
  yearP,
  whiteP,
  timezoneP,
]).fmap(res => new Date(array2String(res))).setLabel('dateP');

const firstLineP = lineP(dateP);

export const filenameP = many1(choice([letterP, digitP, pchar('/'), pchar('.')])).fmap(array2String);

export const secondLineP = lineP(whiteP.discardFirst(filenameP).discardSecond(whateverP));

export const insertionsP = numberP.discardSecond(sequenceP([whiteP, pstring('insertion'), opt(pchar('s')), stringP('(+)')]));
export const deletionsP = numberP.discardSecond(sequenceP([whiteP, pstring('deletion'), opt(pchar('s')), stringP('(-)')]));

export const thirdLineP = lineP(sequenceP([whateverP, pchar(','), whiteP])
  .discardFirst(sequenceP([opt(insertionsP), opt(sequenceP([pchar(','), whiteP])), opt(deletionsP)])))
  .fmap(([maybeInsertions, maybeSeparator, maybeDeletions]) =>
      maybeInsertions.getOrElse(0) - maybeDeletions.getOrElse(0)) // deltaRows

export const commitP = sequenceP([firstLineP, secondLineP, thirdLineP])
  .fmap(([date, filename, deltaRows]) => Couple(filename, Couple(date, deltaRows)));

//const fileHistorySeparatorP = ...

//const fileHistoryP = ... // Couple(filename, Couple[](data, filesize))

//const gitLogFileP = ... // Couple(filename, Couple[](data, filesize))[]

function symbolicChars() {
  return [
    '/',
    '+',
    '-',
    '|',
    '\'',
    '¢',
    '©',
    '÷',
    'µ',
    '¶',
    '±',
    '€',
    '$',
    '£',
    '®',
    '™',
    '¥',
    '(', ')',
    'á', 'Á',
    'à', 'À',
    'â', 'Â',
    'å', 'Å',
    'ã', 'Ã',
    'ä', 'Ä',
    'æ', 'Æ',
    'ç', 'Ç',
    'é', 'É',
    'è', 'È',
    'ê', 'Ê',
    'ë', 'Ë',
    'í', 'Í',
    'ì', 'Ì',
    'î', 'Î',
    'ï', 'Ï',
    'ñ', 'Ñ',
    'ó', 'Ó',
    'ò', 'Ò',
    'ô', 'Ô',
    'ø', 'Ø',
    'õ', 'Õ',
    'ö', 'Ö',
    'ú', 'Ú',
    'ù', 'Ù',
    'û', 'Û',
    'ü', 'Ü',
    'ß', 'ÿ',
    '!',
    '?',
    '/',
    '=',
  ];
}
<|endoftext|>


<commit_before>/* global define */
/* jshint indent:2 */

define([
  'app',
  'services/rich-tree-factory',
  'services/tree-factory',
  'services/route-parameters-converter'
], function(app) {
  'use strict';

  app.factory('mbTreeCache', ['$q', '$rootScope', 'mbRichTreeFactory', 'mbTreeFactory', 'mbNodeFactory', 'mbRouteParametersConverter', 'mbObjectMapper',
    function($q, $rootScope, RichTreeFactory, TreeFactory, NodeFactory, RouteParametersConverter, ObjectMapper) {
    var cache = {},
        deferred,
        repository,
        workspace;

    var hooks = [
      {
        event: TreeFactory.HOOK_PRE_REFRESH,
        callback: function(next, path, node) {
          if (!node.collapsed) {
            return next();
          }

          ObjectMapper.find(repository.getName() + '/' + workspace.getName() + path, { cache: false }).then(function(_node) {
            node.children = _node.getRawData().children;
            next();
          }, next);
        }
      },
      {
        event: TreeFactory.HOOK_PRE_MOVE,
        callback: function(next, fromPath, toPath) {
          ObjectMapper.find('/' + repository.getName() + '/' + workspace.getName() + fromPath).then(function(nodeDropped) {
            nodeDropped.move(toPath).then(function() {
              next();
            }, next);
          }, next);
        }
      },
      {
        event: TreeFactory.HOOK_PRE_APPEND,
        callback: function(next, parentPath, childNode) {
          NodeFactory.build(childNode, workspace).create().then(function() {
            next();
          }, next);
        }
      },
      {
        event: TreeFactory.HOOK_PRE_REMOVE,
        callback: function(next, path) {
          ObjectMapper.find('/' + repository.getName() + '/' + workspace.getName() + path).then(function(node) {
            node.delete().then(function() {
              next();
            }, next);
          }, next);
        }
      }
    ];

    var buildRichTree = function() {
      // rich tree is not built, retrieve the current node with its reduced tree
      return RouteParametersConverter.getCurrentNode({ reducedTree: true, cache: false }).then(function(node) {
        repository = node.getWorkspace().getRepository();
        workspace = node.getWorkspace();
        return node;
      }).then(function(node) {
        // build the rich tree
        return RichTreeFactory.build(
          node.getReducedTree()[0],
          repository,
          hooks
        );
      }).then(function(richTree) {
        // save the built rich tree
        cache.richTree = richTree;
        return cache.richTree;
      }, function(err) {
        return $q.reject(err);
      });
    };

    var invalidateRichTreeCache = function() {
      delete cache.richTree;
    };

    var getRichTree = function() {
      if (cache.richTree) {
        // the rich tree is already build, we return it in a resolved promise
        return $q.when(cache.richTree);
      }

      return buildRichTree();
    };

    $rootScope.$on('workspace.open.start', invalidateRichTreeCache);

    return {
      getRichTree: getRichTree,
      invalidateRichTreeCache: invalidateRichTreeCache
    };
  }]);
});
<commit_msg>Add dockblock for TreeCache<commit_after>/* global define */
/* jshint indent:2 */

define([
  'app',
  'services/rich-tree-factory',
  'services/tree-factory',
  'services/route-parameters-converter'
], function(app) {
  'use strict';

  /**
   * The TreeCache aims to stored a shared RichTree during a session to avoid to always rebuild it.
   */
  app.factory('mbTreeCache', ['$q', '$rootScope', 'mbRichTreeFactory', 'mbTreeFactory', 'mbNodeFactory', 'mbRouteParametersConverter', 'mbObjectMapper',
    function($q, $rootScope, RichTreeFactory, TreeFactory, NodeFactory, RouteParametersConverter, ObjectMapper) {
    var cache = {},
        repository,
        workspace;

    var hooks = [
      {
        event: TreeFactory.HOOK_PRE_REFRESH,

        /**
         * Listener on pre refresh hook to perform the refresh over the REST API
         * @param  {Function} next
         * @param  {string}   path
         * @param  {object}   node
         */
        callback: function(next, path, node) {
          if (!node.collapsed) {
            return next();
          }

          ObjectMapper.find(repository.getName() + '/' + workspace.getName() + path, { cache: false }).then(function(_node) {
            node.children = _node.getRawData().children;
            next();
          }, next);
        }
      },
      {
        event: TreeFactory.HOOK_PRE_MOVE,

        /**
         * Listener on pre move hook to perform the move over the REST API
         * @param  {Function} next
         * @param  {string}   fromPath
         * @param  {string}   toPath
         */
        callback: function(next, fromPath, toPath) {
          ObjectMapper.find('/' + repository.getName() + '/' + workspace.getName() + fromPath).then(function(nodeDropped) {
            nodeDropped.move(toPath).then(function() {
              next();
            }, next);
          }, next);
        }
      },
      {
        event: TreeFactory.HOOK_PRE_APPEND,

        /**
         * Listener on pre append hook to perform the append over the REST API
         * @param  {Function} next
         * @param  {string}   parentPath
         * @param  {object}   childNode
         */
        callback: function(next, parentPath, childNode) {
          NodeFactory.build(childNode, workspace).create().then(function() {
            next();
          }, next);
        }
      },
      {
        event: TreeFactory.HOOK_PRE_REMOVE,

        /**
         * Listener on pre remove hook to perform the remove over the REST API
         * @param  {Function} next
         * @param  {string}   path
         * @return {Function}
         */
        callback: function(next, path) {
          ObjectMapper.find('/' + repository.getName() + '/' + workspace.getName() + path).then(function(node) {
            node.delete().then(function() {
              next();
            }, next);
          }, next);
        }
      }
    ];

    /**
     * Build a RichTree object based on the current node and cache it
     * @return {promise}
     */
    var buildRichTree = function() {
      // rich tree is not built, retrieve the current node with its reduced tree
      return RouteParametersConverter.getCurrentNode({ reducedTree: true, cache: false }).then(function(node) {
        repository = node.getWorkspace().getRepository();
        workspace = node.getWorkspace();
        return node;
      }).then(function(node) {
        // build the rich tree
        return RichTreeFactory.build(
          node.getReducedTree()[0],
          repository,
          hooks
        );
      }).then(function(richTree) {
        // save the built rich tree
        cache.richTree = richTree;
        return cache.richTree;
      }, function(err) {
        return $q.reject(err);
      });
    };

    /**
     * Invalidate the RichTree in cache to force rebuild
     */
    var invalidateRichTreeCache = function() {
      delete cache.richTree;
    };

    /**
     * Get the RichTree stored in the cache
     * @return {promise}
     */
    var getRichTree = function() {
      if (cache.richTree) {
        // the rich tree is already build, we return it in a resolved promise
        return $q.when(cache.richTree);
      }

      return buildRichTree();
    };

    /**
     * Listener on route change to invalidate the RichTree cache if needed
     */
    $rootScope.$on('workspace.open.start', invalidateRichTreeCache);

    return {
      getRichTree: getRichTree,
      invalidateRichTreeCache: invalidateRichTreeCache
    };
  }]);
});
<|endoftext|>


<commit_before>import calculator from './calculator/slidingWindow';
import d3 from 'd3';
import {noop} from '../../util/fn';

// applies an algorithm to an array, merging the result back into
// the source array using the given merge function.
export default function() {

    var merge = noop,
        algorithm = calculator();

    var mergeCompute = function(data) {
        return d3.zip(data, algorithm(data))
            .forEach(function(tuple) {
                merge(tuple[0], tuple[1]);
            });
    };

    mergeCompute.algorithm = function(x) {
        if (!arguments.length) {
            return algorithm;
        }
        algorithm = x;
        return mergeCompute;
    };

    mergeCompute.merge = function(x) {
        if (!arguments.length) {
            return merge;
        }
        merge = x;
        return mergeCompute;
    };

    return mergeCompute;
}
<commit_msg>feat: allow functional usage of merge<commit_after>import calculator from './calculator/slidingWindow';
import d3 from 'd3';
import {noop} from '../../util/fn';

// applies an algorithm to an array and merges the result using the given merge function.
export default function() {

    var merge = noop,
        algorithm = calculator();

    var mergeCompute = function(data) {
        return d3.zip(data, algorithm(data))
            .map(function(tuple) {
                return merge(tuple[0], tuple[1]);
            });
    };

    mergeCompute.algorithm = function(x) {
        if (!arguments.length) {
            return algorithm;
        }
        algorithm = x;
        return mergeCompute;
    };

    mergeCompute.merge = function(x) {
        if (!arguments.length) {
            return merge;
        }
        merge = x;
        return mergeCompute;
    };

    return mergeCompute;
}
<|endoftext|>


<commit_before>function resolveTemplateFiles(name) {

}
module.exports = resolveTemplateFiles;<commit_msg>Resolving files for custom and standard templates<commit_after>// Load in grunt
var grunt = require('grunt'),
    paths = require('./paths'),
    customDir = paths.custom,
    stdDir = paths.standard,
    expandFiles = grunt.file.expandFiles;

// Define a helper to find custom and standard template files
function resolveTemplateFiles(name) {
  // Create paths for resolving
  var customFile = customDir + '/' + name + '.js',
      customTemplateDir = customDir + '/' + name + '/**/*',
      stdFile = stdDir + '/' + name + '.js',
      stdTemplateDir = stdDir + '/' + name + '/**/*';

  // Grab any and all files
  var customFiles = expandFiles(customFile).concat(expandFiles(customTemplateDir)),
      stdFiles = expandFiles(stdFile).concat(expandFiles(stdTemplateDir));

  console.log(customFiles, stdFiles);

  // TODO: Use filter to remove custom + standard cross-over

}

// Expose resolveTemplateFiles
module.exports = resolveTemplateFiles;<|endoftext|>


<commit_before>$("#lighthouseTeamSummaryButton").mouseenter(function(ev){
  summary();
});

document.getElementById("lighthouseTeamSummaryButton").onclick = function() {
  summary();
}

function summary(){
  var hqs = filterViewModel.selectedEntities.peek();
  var start = new Date(filterViewModel.startDate.peek()._d);
  var end = new Date(filterViewModel.endDate.peek()._d);

  var hq = hqs.map(function(d){
    return d.Id;
  })

  if (hq.length !== 0) {
    $("#lighthouseTeamSummaryButton").attr("href",lighthouseUrl+"lighthouse/teamsummary.html?host="+location.hostname+"&hq="+hq+"&start="+encodeURIComponent(start.toISOString())+"&end="+encodeURIComponent(end.toISOString()));
  } else {
    $("#lighthouseTeamSummaryButton").attr("href",lighthouseUrl+"lighthouse/teamsummary.html?host="+location.hostname+"&start="+encodeURIComponent(start.toISOString())+"&end="+encodeURIComponent(end.toISOString()));
  }

}
<commit_msg>Fixed bad href on team summary page<commit_after>$("#lighthouseTeamSummaryButton").mouseenter(function(ev){
  summary();
});

document.getElementById("lighthouseTeamSummaryButton").onclick = function() {
  summary();
}

function summary(){
  var hqs = filterViewModel.selectedEntities.peek();
  var start = new Date(filterViewModel.startDate.peek()._d);
  var end = new Date(filterViewModel.endDate.peek()._d);

  var hq = hqs.map(function(d){
    return d.Id;
  })

  if (hq.length !== 0) {
    $("#lighthouseTeamSummaryButton").attr("href",lighthouseUrl+"pages/teamsummary.html?host="+location.hostname+"&hq="+hq+"&start="+encodeURIComponent(start.toISOString())+"&end="+encodeURIComponent(end.toISOString()));
  } else {
    $("#lighthouseTeamSummaryButton").attr("href",lighthouseUrl+"pages/teamsummary.html?host="+location.hostname+"&start="+encodeURIComponent(start.toISOString())+"&end="+encodeURIComponent(end.toISOString()));
  }

}
<|endoftext|>


<commit_before>module.exports = {
  plugins: [
    'transform-decorators-legacy',
    'transform-class-properties',
  ],
  presets: [
    'react-hmre',
    'stage-0',
    'es2015',
    'react',
  ],
};
<commit_msg>Cache files to speed up webpack<commit_after>module.exports = {
  plugins: [
    'transform-decorators-legacy',
    'transform-class-properties',
  ],
  presets: [
    'react-hmre',
    'stage-0',
    'es2015',
    'react',
  ],
  cacheDirectory: true,
};
<|endoftext|>


<commit_before>module.exports = {
  apiServerUrl: 'https://staging.jakduk.com:8080/api',
  origin: 'https://staging.jakduk.com',
  facebook: {
    callbackURL:  'https://staging.jakduk.com/auth/facebook/callback'
  },
  daum: {
    callbackURL:  'https://staging.jakduk.com/auth/daum/callback'
  }
};<commit_msg>Fix #2<commit_after>module.exports = {
  apiServerUrl: 'https://staging.jakduk.com:8080/api',
  thumbnailServerUrl: 'https://staging.jakduk.com:8080',
  origin: 'https://staging.jakduk.com',
  facebook: {
    callbackURL:  'https://staging.jakduk.com/auth/facebook/callback'
  },
  daum: {
    callbackURL:  'https://staging.jakduk.com/auth/daum/callback'
  }
};
<|endoftext|>


<commit_before>import Rx from 'rx'
let Observable= Rx.Observable;
let fromEvent = Observable.fromEvent;

import logger from '../utils/log'
let log = logger("interactions");
log.setLevel("info");

//various helpers
function preventEventDefault(event) {
  event.preventDefault();
}

function hasTwoTouchPoints(event) {
  return event.touches && event.touches.length === 2;
}

function getOffset(event) {
  return {
    x: event.offsetX === undefined ? event.layerX : event.offsetX,
    y: event.offsetY === undefined ? event.layerY : event.offsetY
  };
}

function isMovingOLD(startEnd, deltaSqr){
  let {start,end} = startEnd;
  let offset = {x:end.x-start.x, y:end.y-start.y}
  let distSqr  = (offset.x*offset.x + offset.y * offset.y);
  //log.info(offset,distSqr, deltaSqr)
  return distSqr > deltaSqr;
}

function isMoving(moveDelta, deltaSqr){
  return true;
  let distSqr  = (moveDelta.x * moveDelta.x + moveDelta.y*moveDelta.y);
  let isMoving = (distSqr > deltaSqr);
  //console.log("moving",isMoving)
  return isMoving;
}

function isStatic(moveDelta, deltaSqr){
  return !isMoving(moveDelta);
}

//TODO ,: regroup / refactor all "delta" operation ?
function isShort(elapsed, maxTime){
  return elapsed < maxTime;
}

function isLong(elapsed, maxTime){
  return elapsed > maxTime;
}

 //window resize event stream, throttled by throttle amount (250ms default)
 export let windowResizes=function(throttle=250)
 {
  //only get the fields we need
  let extractSize = function(x){
    let x = x.target;
    let bRect = {left:0,top:0,bottom:0,right:0,width:0,height:0}
    if(x.getBoundingClientRect) bRect = x.getBoundingClientRect();

    let res = {width:x.innerWidth, height:x.innerHeight, aspect:x.innerWidth/x.innerHeight, bRect:bRect}
    return res;
  }

  let throttledWinResize = fromEvent(window, 'resize')
  .throttleFirst(throttle /* ms */)
  .map( extractSize );

  return throttledWinResize;
 }

 export let clicks = function(mouseDowns, mouseUps, mouseMoves, timing=200, deltaSqr){
    /*
    "pseudo click" that does not trigger when there was
    a mouse movement
    */
    let fakeClicksOld = mouseDowns.flatMap( function( md ){
      let start   = { x: md.clientX, y: md.clientY };

      //get only valid moves
      let mMoves  = mouseMoves
        .map( false )
        .bufferWithTimeOrCount(timing,1)
        .filter( x => x.length == 1 )
        .map( x => x[0]);

      let __moves = mMoves.merge(Observable.return(true));//default to true

      return __moves.combineLatest(mouseUps, function(m, mu){
        //log.info(m, mu)
        var end = {x: mu.clientX, y: mu.clientY };
        return isStatic({start:start,end:end}, deltaSqr);//allow for small movement (shaky hands!)

      })
        .takeUntil(mouseUps)
        .filter( x => x===true )
    });

   let fakeClicks = mouseDowns
    .flatMap( function(downEvent){
        let target = downEvent.currentTarget;
        return Observable.amb(
          [
            // Skip if we get a movement before a mouse up
            mouseMoves.take(1).flatMap( x => Rx.Observable.empty() ),
            mouseUps.take(1)
          ])//.map(function(event){console.log(event); return event;})
      });

    return fakeClicks;
 }

function altMouseMoves( mouseMoves ){
 return mouseMoves
      .skip(1)
      .zip( mouseMoves, function(a, b){

        let data = {
            client:{x: a.clientX,y: a.clientY },
            delta:{x: a.clientX - b.clientX, y: a.clientY - b.clientY}
          };

          return Object.assign(data, b);
        }
      );
}

/*alternative "clicks" (ie mouseDown -> mouseUp ) implementation, with more fine
grained control*/
function altClicks(mouseDowns, mouseUps, mouseMoves, longPressDelay=800, deltaSqr){
  //only doing any "clicks if the time between mDOWN and mUP is below longpressDelay"
  //any small mouseMove is ignored (shaky hands)
   return mouseDowns
      .flatMap( function(downEvent){
        let target = downEvent.currentTarget;
        return Observable.amb(
          [
            // Skip if we get a movement before a mouse up
            mouseMoves
              .filter( data => isMoving(data.delta, deltaSqr) )//allow for small movement (shaky hands!)
              .take(1).flatMap( x => Rx.Observable.empty() ),

            mouseUps.take(1),

          ]).timeout(longPressDelay, Rx.Observable.empty());
    });
}

/*this emits events whenever pointers are held */
function holds(mouseDowns, mouseUps, mouseMoves, longPressDelay=800, deltaSqr){
   return mouseDowns
      .flatMap( function(downEvent){
        let target = downEvent.currentTarget;
        return Observable.amb(
          [
            // Skip if we get a movement before timeout
            mouseMoves
              .filter( data => isMoving(data.delta, deltaSqr) )//allow for small movement (shaky hands!)
              .take(1).flatMap( x => Rx.Observable.empty() ),

            //Skip if we get a mouseup before main timeout
            mouseUps.take(1).flatMap( x => Rx.Observable.empty() ),

            Rx.Observable.return(2).delay(longPressDelay).timeout(longPressDelay, Rx.Observable.return(42))

          ])
        //.timeout(longPressDelay, Rx.Observable.empty());
    });
}

function drags(mouseDowns, mouseUps, mouseMoves, longPressDelay=800, deltaSqr){
  return mouseDowns
      .flatMap( function(downEvent){
        let target = downEvent.currentTarget;
        //let origin = target.position();
        log.info("kldf")
        return Observable.amb(
          [
            // Skip if we get a mouse up before we move
            mouseUps.take(1).flatMap( x => Rx.Observable.empty() ),

            mouseMoves.take(1).map(function(x){
              return{
                target: target,
                //origin: target.position(),
                drags: mouseMoves.takeUntil(mouseUps).map(function(x){
                  return {
                    delta: x.delta,
                    offset: {
                      x: x.client.x - downEvent.clientX,
                      y: x.client.y - downEvent.clientY
                    }
                  }
                })
              }
            })

          ]);

      });
}

//this one just works by dispatching at the end of the movement
function drags2(mouseDowns, mouseUps, mouseMoves, longPressDelay=800, deltaSqr){
  return mouseDowns.flatMap(function (md) {
      var start = { x: md.clientX, y: md.clientY };
      return mouseMoves.combineLatest(mouseUps, function (mm, mu) {
        //log.info("mm",mm,"mu",mu)
        var stop = {x: mu.clientX, y: mu.clientY };
        return {
          start: start,
          end: stop
        };
      })
        //.delay(400)
        .takeUntil(mouseUps);
    });
}

//based on http://jsfiddle.net/mattpodwysocki/pfCqq/
function drags3(mouseDowns, mouseUps, mouseMoves, longPressDelay=800, deltaSqr){
  return mouseDowns.selectMany(function (md) {

            // calculate offsets when mouse down
            var startX = md.offsetX, startY = md.offsetY;

            // Calculate delta with mousemove until mouseup
            return mouseMoves.map(function (mm) {
                (mm.preventDefault) ? mm.preventDefault() : event.returnValue = false;

                let delta = {
                    left: mm.clientX - startX,
                    top: mm.clientY - startY
                };
                return Object.assign(mm, delta);

            }).takeUntil(mouseUps);
        });
}

//pinch, taken from https://github.com/hugobessaa/rx-react-pinch
function pinches(touchstarts, touchmoves, touchEnds) {
    return touchStarts
      .do(eventPreventDefault)
      .takeWhile(hasTwoTouchPoints)
      .flatMap(() => {
        return touchMoves
          .pluck('scale')
          .takeUntil(touchEnds)
      })
}

 export let pointerInteractions = function(targetEl){
    let multiClickDelay = 250;
    let longPressDelay  = 800;

    let minDelta        = 25;//max 50 pixels delta
    let deltaSqr        = (minDelta*minDelta);

    let mouseDowns  = fromEvent(targetEl, 'mousedown');
    let mouseUps    = fromEvent(targetEl, 'mouseup');
    let mouseMoves  = fromEvent(targetEl, 'mousemove');
    let rightclicks = fromEvent(targetEl, 'contextmenu').do(preventEventDefault);// disable the context menu / right click
    let mouseMoves2 = altMouseMoves(mouseMoves);
    let zoomIntents = fromEvent(targetEl, 'wheel');

    let touchStart  = fromEvent('touchstart');//dom.touchstart(window);
    let touchMove   = fromEvent('touchmove');//dom.touchmove(window);
    let touchEnd    = fromEvent('touchend');//dom.touchend(window);

    ///// now setup the more complex interactions
    let _clicks = altClicks(mouseDowns, mouseUps, mouseMoves2, longPressDelay, deltaSqr).share();

    let clickStreamBase = _clicks
      .filter( event => ('button' in event && event.button === 0) )
      .buffer(function() { return _clicks.debounce( multiClickDelay ); })
      .map( list => ({list:list,nb:list.length}) )
      .share();

    //we get our custom right clicks
    let rightClicks2 = _clicks.filter( event => ('button' in event && event.button === 2) );
    let _holds       = holds(mouseDowns, mouseUps, mouseMoves2, multiClickDelay, deltaSqr);

    let unpack = function(list){ return list.list};
    let extractData = function(event){ return {clientX:event.clientX,clientY:event.clientY}};

    let $singleClicks = clickStreamBase.filter( x => x.nb == 1 ).flatMap(unpack);
    let $doubleClicks = clickStreamBase.filter( x => x.nb == 2 ).flatMap(unpack).take(1).map(extractData).repeat();
    let $contextTaps  =  Observable.amb([
      _holds.map(function(x){ console.log("HOLDS");return x}),
      rightClicks2.map(function(x){ console.log("rightClicks2");return x}),
      // Skip if we get a movement
      mouseMoves
        .take(1).flatMap( x => Rx.Observable.empty() ),
      ]
    ).take(1).repeat();// contextTaps: either HELD leftmouse/pointer or right click

    let $dragMoves = drags3(mouseDowns, mouseUps, mouseMoves2, longPressDelay, deltaSqr);

    let $zoomIntents = zoomIntents;

    //zoomIntents.subscribe(function(event){console.log("ZOOM/WHEEL",event)})

    /*$drags.subscribe(function(event){
      console.log("drags",event)
    })*/

    /*_clicks.subscribe(function(event){
      console.log("mouse clicks alt",event)
    })*/

    //let $contextTaps2 = holds(mouseDowns, mouseUps, mouseMoves2, multiClickDelay, deltaSqr)

    /*$contextTaps.subscribe(function(event){
      console.log("holdIIIING/right click",event)
    })*/

    //DEBUG
    /*singleClicks.subscribe(function (event) {
        log.info( 'click', event );
    });
    doubleClicks.subscribe(function (event) {
        log.info( 'double click',event);
    });*/
    /*multiClicks.subscribe(function (numclicks) {
        log.info( numclicks+'x click');
    });
        // right click and left long click are the same
    //TODO need a better name
    //var interactions = Observable.merge(rightclick, clickhold);
    */
    Observable.merge($singleClicks, $doubleClicks, $contextTaps, $dragMoves, $zoomIntents)
        //.debounce(200)
        .subscribe(function (suggestion) {});

    return {
      taps:clickStreamBase,
      singleTaps: $singleClicks,
      doubleTaps: $doubleClicks,
      contextTaps:$contextTaps,
      dragMoves:  $dragMoves,
      zoomIntents:$zoomIntents
    }
 }

<commit_msg>- minor syntax fix : changes "$" prefix to suffix for datastreams<commit_after>import Rx from 'rx'
let Observable= Rx.Observable;
let fromEvent = Observable.fromEvent;

import logger from '../utils/log'
let log = logger("interactions");
log.setLevel("info");

//various helpers
function preventEventDefault(event) {
  event.preventDefault();
}

function hasTwoTouchPoints(event) {
  return event.touches && event.touches.length === 2;
}

function getOffset(event) {
  return {
    x: event.offsetX === undefined ? event.layerX : event.offsetX,
    y: event.offsetY === undefined ? event.layerY : event.offsetY
  };
}

function isMovingOLD(startEnd, deltaSqr){
  let {start,end} = startEnd;
  let offset = {x:end.x-start.x, y:end.y-start.y}
  let distSqr  = (offset.x*offset.x + offset.y * offset.y);
  //log.info(offset,distSqr, deltaSqr)
  return distSqr > deltaSqr;
}

function isMoving(moveDelta, deltaSqr){
  return true;
  let distSqr  = (moveDelta.x * moveDelta.x + moveDelta.y*moveDelta.y);
  let isMoving = (distSqr > deltaSqr);
  //console.log("moving",isMoving)
  return isMoving;
}

function isStatic(moveDelta, deltaSqr){
  return !isMoving(moveDelta);
}

//TODO ,: regroup / refactor all "delta" operation ?
function isShort(elapsed, maxTime){
  return elapsed < maxTime;
}

function isLong(elapsed, maxTime){
  return elapsed > maxTime;
}

 //window resize event stream, throttled by throttle amount (250ms default)
 export let windowResizes=function(throttle=250)
 {
  //only get the fields we need
  let extractSize = function(x){
    let x = x.target;
    let bRect = {left:0,top:0,bottom:0,right:0,width:0,height:0}
    if(x.getBoundingClientRect) bRect = x.getBoundingClientRect();

    let res = {width:x.innerWidth, height:x.innerHeight, aspect:x.innerWidth/x.innerHeight, bRect:bRect}
    return res;
  }

  let throttledWinResize = fromEvent(window, 'resize')
  .throttleFirst(throttle /* ms */)
  .map( extractSize );

  return throttledWinResize;
 }

 export let clicks = function(mouseDowns, mouseUps, mouseMoves, timing=200, deltaSqr){
    /*
    "pseudo click" that does not trigger when there was
    a mouse movement
    */
    let fakeClicksOld = mouseDowns.flatMap( function( md ){
      let start   = { x: md.clientX, y: md.clientY };

      //get only valid moves
      let mMoves  = mouseMoves
        .map( false )
        .bufferWithTimeOrCount(timing,1)
        .filter( x => x.length == 1 )
        .map( x => x[0]);

      let __moves = mMoves.merge(Observable.return(true));//default to true

      return __moves.combineLatest(mouseUps, function(m, mu){
        //log.info(m, mu)
        var end = {x: mu.clientX, y: mu.clientY };
        return isStatic({start:start,end:end}, deltaSqr);//allow for small movement (shaky hands!)

      })
        .takeUntil(mouseUps)
        .filter( x => x===true )
    });

   let fakeClicks = mouseDowns
    .flatMap( function(downEvent){
        let target = downEvent.currentTarget;
        return Observable.amb(
          [
            // Skip if we get a movement before a mouse up
            mouseMoves.take(1).flatMap( x => Rx.Observable.empty() ),
            mouseUps.take(1)
          ])//.map(function(event){console.log(event); return event;})
      });

    return fakeClicks;
 }

function altMouseMoves( mouseMoves ){
 return mouseMoves
      .skip(1)
      .zip( mouseMoves, function(a, b){

        let data = {
            client:{x: a.clientX,y: a.clientY },
            delta:{x: a.clientX - b.clientX, y: a.clientY - b.clientY}
          };

          return Object.assign(data, b);
        }
      );
}

/*alternative "clicks" (ie mouseDown -> mouseUp ) implementation, with more fine
grained control*/
function altClicks(mouseDowns, mouseUps, mouseMoves, longPressDelay=800, deltaSqr){
  //only doing any "clicks if the time between mDOWN and mUP is below longpressDelay"
  //any small mouseMove is ignored (shaky hands)
   return mouseDowns
      .flatMap( function(downEvent){
        let target = downEvent.currentTarget;
        return Observable.amb(
          [
            // Skip if we get a movement before a mouse up
            mouseMoves
              .filter( data => isMoving(data.delta, deltaSqr) )//allow for small movement (shaky hands!)
              .take(1).flatMap( x => Rx.Observable.empty() ),

            mouseUps.take(1),

          ]).timeout(longPressDelay, Rx.Observable.empty());
    });
}

/*this emits events whenever pointers are held */
function holds(mouseDowns, mouseUps, mouseMoves, longPressDelay=800, deltaSqr){
   return mouseDowns
      .flatMap( function(downEvent){
        let target = downEvent.currentTarget;
        return Observable.amb(
          [
            // Skip if we get a movement before timeout
            mouseMoves
              .filter( data => isMoving(data.delta, deltaSqr) )//allow for small movement (shaky hands!)
              .take(1).flatMap( x => Rx.Observable.empty() ),

            //Skip if we get a mouseup before main timeout
            mouseUps.take(1).flatMap( x => Rx.Observable.empty() ),

            Rx.Observable.return(2).delay(longPressDelay).timeout(longPressDelay, Rx.Observable.return(42))

          ])
        //.timeout(longPressDelay, Rx.Observable.empty());
    });
}

function drags(mouseDowns, mouseUps, mouseMoves, longPressDelay=800, deltaSqr){
  return mouseDowns
      .flatMap( function(downEvent){
        let target = downEvent.currentTarget;
        //let origin = target.position();
        log.info("kldf")
        return Observable.amb(
          [
            // Skip if we get a mouse up before we move
            mouseUps.take(1).flatMap( x => Rx.Observable.empty() ),

            mouseMoves.take(1).map(function(x){
              return{
                target: target,
                //origin: target.position(),
                drags: mouseMoves.takeUntil(mouseUps).map(function(x){
                  return {
                    delta: x.delta,
                    offset: {
                      x: x.client.x - downEvent.clientX,
                      y: x.client.y - downEvent.clientY
                    }
                  }
                })
              }
            })

          ]);

      });
}

//this one just works by dispatching at the end of the movement
function drags2(mouseDowns, mouseUps, mouseMoves, longPressDelay=800, deltaSqr){
  return mouseDowns.flatMap(function (md) {
      var start = { x: md.clientX, y: md.clientY };
      return mouseMoves.combineLatest(mouseUps, function (mm, mu) {
        //log.info("mm",mm,"mu",mu)
        var stop = {x: mu.clientX, y: mu.clientY };
        return {
          start: start,
          end: stop
        };
      })
        //.delay(400)
        .takeUntil(mouseUps);
    });
}

//based on http://jsfiddle.net/mattpodwysocki/pfCqq/
function drags3(mouseDowns, mouseUps, mouseMoves, longPressDelay=800, deltaSqr){
  return mouseDowns.selectMany(function (md) {

            // calculate offsets when mouse down
            var startX = md.offsetX, startY = md.offsetY;

            // Calculate delta with mousemove until mouseup
            return mouseMoves.map(function (mm) {
                (mm.preventDefault) ? mm.preventDefault() : event.returnValue = false;

                let delta = {
                    left: mm.clientX - startX,
                    top: mm.clientY - startY
                };
                return Object.assign(mm, delta);

            }).takeUntil(mouseUps);
        });
}

//pinch, taken from https://github.com/hugobessaa/rx-react-pinch
function pinches(touchstarts, touchmoves, touchEnds) {
    return touchStarts
      .do(eventPreventDefault)
      .takeWhile(hasTwoTouchPoints)
      .flatMap(() => {
        return touchMoves
          .pluck('scale')
          .takeUntil(touchEnds)
      })
}

 export let pointerInteractions = function(targetEl){
    let multiClickDelay = 250;
    let longPressDelay  = 800;

    let minDelta        = 25;//max 50 pixels delta
    let deltaSqr        = (minDelta*minDelta);

    let mouseDowns  = fromEvent(targetEl, 'mousedown');
    let mouseUps    = fromEvent(targetEl, 'mouseup');
    let mouseMoves  = fromEvent(targetEl, 'mousemove');
    let rightclicks = fromEvent(targetEl, 'contextmenu').do(preventEventDefault);// disable the context menu / right click
    let mouseMoves2 = altMouseMoves(mouseMoves);
    let zoomIntents = fromEvent(targetEl, 'wheel');

    let touchStart  = fromEvent('touchstart');//dom.touchstart(window);
    let touchMove   = fromEvent('touchmove');//dom.touchmove(window);
    let touchEnd    = fromEvent('touchend');//dom.touchend(window);

    ///// now setup the more complex interactions
    let _clicks = altClicks(mouseDowns, mouseUps, mouseMoves2, longPressDelay, deltaSqr).share();

    let clickStreamBase = _clicks
      .filter( event => ('button' in event && event.button === 0) )
      .buffer(function() { return _clicks.debounce( multiClickDelay ); })
      .map( list => ({list:list,nb:list.length}) )
      .share();

    //we get our custom right clicks
    let rightClicks2 = _clicks.filter( event => ('button' in event && event.button === 2) );
    let _holds       = holds(mouseDowns, mouseUps, mouseMoves2, multiClickDelay, deltaSqr);

    let unpack = function(list){ return list.list};
    let extractData = function(event){ return {clientX:event.clientX,clientY:event.clientY}};

    let singleClicks$ = clickStreamBase.filter( x => x.nb == 1 ).flatMap(unpack);
    let doubleClicks$ = clickStreamBase.filter( x => x.nb == 2 ).flatMap(unpack).take(1).map(extractData).repeat();
    let contextTaps$  =  Observable.amb([
      _holds.map(function(x){ console.log("HOLDS");return x}),
      rightClicks2.map(function(x){ console.log("rightClicks2");return x}),
      // Skip if we get a movement
      mouseMoves
        .take(1).flatMap( x => Rx.Observable.empty() ),
      ]
    ).take(1).repeat();// contextTaps: either HELD leftmouse/pointer or right click

    let dragMoves$ = drags3(mouseDowns, mouseUps, mouseMoves2, longPressDelay, deltaSqr);

    let zoomIntents$ = zoomIntents;

    //zoomIntents.subscribe(function(event){console.log("ZOOM/WHEEL",event)})

    /*$drags.subscribe(function(event){
      console.log("drags",event)
    })*/

    /*_clicks.subscribe(function(event){
      console.log("mouse clicks alt",event)
    })*/

    //let $contextTaps2 = holds(mouseDowns, mouseUps, mouseMoves2, multiClickDelay, deltaSqr)

    /*$contextTaps.subscribe(function(event){
      console.log("holdIIIING/right click",event)
    })*/

    //DEBUG
    /*singleClicks.subscribe(function (event) {
        log.info( 'click', event );
    });
    doubleClicks.subscribe(function (event) {
        log.info( 'double click',event);
    });*/
    /*multiClicks.subscribe(function (numclicks) {
        log.info( numclicks+'x click');
    });
        // right click and left long click are the same
    //TODO need a better name
    //var interactions = Observable.merge(rightclick, clickhold);
    */
    Observable.merge(singleClicks$, doubleClicks$, contextTaps$, dragMoves$, zoomIntents$)
        //.debounce(200)
        .subscribe(function (suggestion) {});

    return {
      taps:clickStreamBase,
      singleTaps: singleClicks$,
      doubleTaps: doubleClicks$,
      contextTaps:contextTaps$,
      dragMoves:  dragMoves$,
      zoomIntents:zoomIntents$
    }
 }

<|endoftext|>