<commit_before>import React from 'react';
import PropTypes from 'prop-types';

import DayPicker from './DayPicker';
import { getModifiersForDay } from './ModifiersUtils';
import { ESC, TAB } from './keys';

// When clicking on a day cell, overlay will be hidden after this timeout
export const HIDE_TIMEOUT = 100;

function isDate(date) {
  return date instanceof Date && !isNaN(date.valueOf());
}

export function defaultFormat(d) {
  if (isDate(d)) {
    const year = d.getFullYear();
    const month = `${d.getMonth() + 1}`;
    const day = `${d.getDate()}`;
    return `${year}-${month}-${day}`;
  }
  return '';
}

export function defaultParse(str) {
  if (typeof str !== 'string') {
    return undefined;
  }
  const split = str.split('-');
  if (split.length !== 3) {
    return undefined;
  }
  const year = parseInt(split[0], 10);
  const month = parseInt(split[1], 10) - 1;
  const day = parseInt(split[2], 10);
  if (
    isNaN(year) ||
    isNaN(month) ||
    isNaN(day) ||
    day <= 0 ||
    day > 31 ||
    month < 0 ||
    month >= 12
  ) {
    return undefined;
  }

  return new Date(year, month, day);
}

export default class DayPickerInput extends React.Component {
  static propTypes = {
    value: PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(Date)]),
    inputProps: PropTypes.object,
    placeholder: PropTypes.string,

    format: PropTypes.oneOfType([
      PropTypes.string,
      PropTypes.arrayOf(PropTypes.string),
    ]),

    formatDate: PropTypes.func,
    parseDate: PropTypes.func,

    showOverlay: PropTypes.bool,
    dayPickerProps: PropTypes.object,
    hideOnDayClick: PropTypes.bool,
    clickUnselectsDay: PropTypes.bool,
    keepFocus: PropTypes.bool,
    component: PropTypes.any,
    overlayComponent: PropTypes.any,

    classNames: PropTypes.shape({
      container: PropTypes.string,
      overlayWrapper: PropTypes.string,
      overlay: PropTypes.string.isRequired,
    }),

    onDayChange: PropTypes.func,
    onChange: PropTypes.func,
    onClick: PropTypes.func,
    onFocus: PropTypes.func,
    onBlur: PropTypes.func,
    onKeyUp: PropTypes.func,
  };

  static defaultProps = {
    dayPickerProps: {},
    value: '',
    placeholder: 'YYYY-M-D',
    format: 'L',
    formatDate: defaultFormat,
    parseDate: defaultParse,
    showOverlay: false,
    hideOnDayClick: true,
    clickUnselectsDay: false,
    keepFocus: true,
    component: 'input',
    inputProps: {},
    overlayComponent: ({ children, classNames }) => (

{children}

    ),
    classNames: {
      container: 'DayPickerInput',
      overlayWrapper: 'DayPickerInput-OverlayWrapper',
      overlay: 'DayPickerInput-Overlay',
    },
  };

  constructor(props) {
    super(props);

    this.state = this.getStateFromProps(props);
    this.state.showOverlay = props.showOverlay;

    this.hideAfterDayClick = this.hideAfterDayClick.bind(this);
    this.handleInputClick = this.handleInputClick.bind(this);
    this.handleInputFocus = this.handleInputFocus.bind(this);
    this.handleInputBlur = this.handleInputBlur.bind(this);
    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleInputKeyDown = this.handleInputKeyDown.bind(this);
    this.handleInputKeyUp = this.handleInputKeyUp.bind(this);
    this.handleDayClick = this.handleDayClick.bind(this);
    this.handleMonthChange = this.handleMonthChange.bind(this);
    this.handleOverlayFocus = this.handleOverlayFocus.bind(this);
    this.handleOverlayBlur = this.handleOverlayBlur.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    const monthFromProps = this.props.dayPickerProps.month;
    const nextMonthFromProps = nextProps.dayPickerProps.month;

    const selectedDaysFromProps = this.props.dayPickerProps.selectedDays;
    const nextSelectedDaysFromProps = nextProps.dayPickerProps.selectedDays;

    let nextValue = nextProps.value;
    const currentValue = this.props.value;

    const monthChanged =
      (nextMonthFromProps && !monthFromProps) ||
      (nextMonthFromProps &&
        (nextMonthFromProps.getFullYear() !== monthFromProps.getFullYear() ||
          nextMonthFromProps.getMonth() !== monthFromProps.getMonth()));

    if (nextValue !== currentValue) {
      if (isDate(nextValue)) {
        nextValue = this.props.formatDate(
          nextValue,
          this.props.format,
          this.props.dayPickerProps.locale
        );
      }
      this.setState({
        value: nextValue,
      });
    }
    if (monthChanged) {
      this.setState({ month: nextMonthFromProps });
    }
    if (selectedDaysFromProps !== nextSelectedDaysFromProps) {
      this.setState({ selectedDays: nextSelectedDaysFromProps });
    }
  }

  componentWillUnmount() {
    clearTimeout(this.clickTimeout);
    clearTimeout(this.hideTimeout);
    clearTimeout(this.ieInputFocusTimeout);
    clearTImeout(this.ieInputBlurTimeout);
  }

  getStateFromProps(props) {
    const { dayPickerProps, formatDate, format } = props;
    let { value } = props;

    let day;
    if (props.value) {
      if (isDate(props.value)) {
        day = props.value;
        value = formatDate(props.value, format, dayPickerProps.locale);
      } else {
        day = props.parseDate(props.value, format, dayPickerProps.locale);
      }
    }

    // Use DayPicker's controlled month. Then try the current `value`. Finally default to today.
    const month =
      dayPickerProps.initialMonth || dayPickerProps.month || day || new Date();

    return {
      value,
      month,
      selectedDays: dayPickerProps.selectedDays,
    };
  }

  getInput() {
    return this.input;
  }

  getDayPicker() {
    return this.daypicker;
  }

  isIE() {
    return /*@cc_on!@*/false || !!document.documentMode;
  }

  setStateFrom(relatedTarget) {
    this.setState({
        showOverlay:
          this.overlayNode && this.overlayNode.contains(relatedTarget),
    });
  }

  resetHideTimeout() {
    if(this.hideTimeout) {
      this.hideTimeout = setTimeout(() => {
          this.hideDayPicker();
          this.hideTimeout = null;
        }, HIDE_TIMEOUT);
    }
  }

  input = null;
  daypicker = null;
  overlayNode = null;
  clickTimeout = null;
  hideTimeout = null;
  ieInputFocusTimeout = null;
  ieInputBlutTimeout = null;

  /**
   * Update the component's state and fire the `onDayChange` event
   * passing the day's modifiers to it
   * @param {Date} day - Will be used for changing the month
   * @param {String} value - Input field value
   * @private
   */
  updateState(day, value, callback) {
    const { dayPickerProps, onDayChange } = this.props;
    this.setState({ month: day, value }, () => {
      if (callback) {
        callback();
      }
      if (!onDayChange) {
        return;
      }
      const modifiersObj = {
        disabled: dayPickerProps.disabledDays,
        selected: dayPickerProps.selectedDays,
        ...dayPickerProps.modifiers,
      };
      const modifiers = getModifiersForDay(day, modifiersObj).reduce(
        (obj, modifier) => {
          const newObj = { ...obj };
          newObj[modifier] = true;
          return newObj;
        },
        {}
      );
      onDayChange(day, modifiers);
    });
  }

  /**
   * Show the Day Picker overlay.
   *
   * @memberof DayPickerInput
   */
  showDayPicker() {
    this.setState({ showOverlay: true });
  }

  /**
   * Hide the Day Picker overlay
   *
   * @memberof DayPickerInput
   */
  hideDayPicker() {
    this.setState({ showOverlay: false });
  }

  hideAfterDayClick() {
    if (!this.props.hideOnDayClick) {
      return;
    }
    this.hideTimeout = setTimeout(() => this.hideDayPicker(), HIDE_TIMEOUT);
  }

  handleInputClick(e) {
    this.showDayPicker();
    if (this.props.inputProps.onClick) {
      e.persist();
      this.props.inputProps.onClick(e);
    }
  }

  handleInputFocus(e) {
    this.showDayPicker();
    if (this.props.inputProps.onFocus) {
      e.persist();
      this.props.inputProps.onFocus(e);
    }
  }

  handleInputBlur(e) {
    if(this.isIE()) {
        this.ieInputBlurTimeout = setTimeout(() =>
            this.setStateFrom(e.relatedTarget), HIDE_TIMEOUT);
    } else {
        this.setStateFrom(e.relatedTarget);
    }
    if (this.props.inputProps.onBlur) {
      e.persist();
      this.props.inputProps.onBlur(e);
    }
  }

  handleOverlayFocus(e) {
    if (this.props.keepFocus === true) {
      e.preventDefault();
      if(this.isIE()) {
        this.ieInputFocusTimeout = setTimeout(() => {
            this.input.focus();
            this.resetHideTimeout();
          }, HIDE_TIMEOUT);
      } else {
        this.input.focus();
      }
    }
  }

  handleOverlayBlur(e) {
    this.setState({
      showOverlay:
        this.overlayNode && this.overlayNode.contains(e.relatedTarget),
    });
  }

  handleInputChange(e) {
    const {
      dayPickerProps,
      format,
      inputProps,
      onDayChange,
      parseDate,
    } = this.props;
    if (inputProps.onChange) {
      e.persist();
      inputProps.onChange(e);
    }
    const { value } = e.target;
    if (value.trim() === '') {
      this.setState({ value });
      if (onDayChange) onDayChange(undefined, {});
      return;
    }
    const day = parseDate(value, format, dayPickerProps.locale);
    if (!day) {
      this.setState({ value });
      if (onDayChange) onDayChange(undefined, {});
      return;
    }
    this.updateState(day, value);
  }

  handleInputKeyDown(e) {
    if (e.keyCode === TAB) {
      this.hideDayPicker();
    }
    if (this.props.inputProps.onKeyDown) {
      e.persist();
      this.props.inputProps.onKeyDown(e);
    }
  }

  handleInputKeyUp(e) {
    // Hide the overlay if the ESC key is pressed
    if (e.keyCode === ESC) {
      this.hideDayPicker();
    }
    if (this.props.inputProps.onKeyUp) {
      e.persist();
      this.props.inputProps.onKeyUp(e);
    }
  }

  handleMonthChange(month) {
    this.setState({ month }, () => {
      if (
        this.props.dayPickerProps &&
        this.props.dayPickerProps.onMonthChange
      ) {
        this.props.dayPickerProps.onMonthChange(month);
      }
    });
  }

  handleDayClick(day, modifiers, e) {
    const {
      clickUnselectsDay,
      dayPickerProps,
      onDayChange,
      formatDate,
      format,
    } = this.props;
    if (dayPickerProps.onDayClick) {
      dayPickerProps.onDayClick(day, modifiers, e);
    }

    // Do nothing if the day is disabled
    if (modifiers.disabled) {
      return;
    }

    // If the clicked day is already selected, remove the clicked day
    // from the selected days and empty the field value
    if (modifiers.selected && clickUnselectsDay) {
      let { selectedDays } = this.state;
      if (Array.isArray(selectedDays)) {
        selectedDays = selectedDays.slice(0);
        const selectedDayIdx = selectedDays.indexOf(day);
        selectedDays.splice(selectedDayIdx, 1);
      } else if (selectedDays) {
        selectedDays = null;
      }
      this.setState({ value: '', selectedDays }, this.hideAfterDayClick);
      if (onDayChange) {
        onDayChange(undefined, modifiers);
      }
      return;
    }

    const value = formatDate(day, format, dayPickerProps.locale);
    this.setState({ value, month: day }, () => {
      if (onDayChange) {
        onDayChange(day, modifiers);
      }
      this.hideAfterDayClick();
    });
  }

  renderOverlay() {
    const {
      classNames,
      dayPickerProps,
      parseDate,
      formatDate,
      format,
    } = this.props;
    const { selectedDays, value } = this.state;
    let selectedDay;
    if (!selectedDays && value) {
      const day = parseDate(value, format, dayPickerProps.locale);
      if (day) {
        selectedDay = day;
      }
    } else if (selectedDays) {
      selectedDay = selectedDays;
    }
    let onTodayButtonClick;
    if (dayPickerProps.todayButton) {
      // Set the current day when clicking the today button
      onTodayButtonClick = () =>
        this.updateState(
          new Date(),
          formatDate(new Date(), format, dayPickerProps.locale),
          this.hideAfterDayClick
        );
    }
    const Overlay = this.props.overlayComponent;
    return (
       (this.overlayNode = el)}
        onBlur={this.handleOverlayBlur}
      >
        <Overlay
          classNames={classNames}
          month={this.state.month}
          selectedDay={selectedDay}
          input={this.input}
        >
          <DayPicker
            ref={el => (this.daypicker = el)}
            onTodayButtonClick={onTodayButtonClick}
            {...dayPickerProps}
            month={this.state.month}
            selectedDays={selectedDay}
            onDayClick={this.handleDayClick}
            onMonthChange={this.handleMonthChange}
          />
        </Overlay>

    );
  }

  render() {
    const Input = this.props.component;
    return (

        <Input
          ref={el => (this.input = el)}
          placeholder={this.props.placeholder}
          {...this.props.inputProps}
          value={this.state.value}
          onChange={this.handleInputChange}
          onFocus={this.handleInputFocus}
          onBlur={this.handleInputBlur}
          onKeyDown={this.handleInputKeyDown}
          onKeyUp={this.handleInputKeyUp}
          onClick={this.handleInputClick}
        />
        {this.state.showOverlay && this.renderOverlay()}

    );
  }
}
<commit_msg>fix typo in clearTimeout<commit_after>import React from 'react';
import PropTypes from 'prop-types';

import DayPicker from './DayPicker';
import { getModifiersForDay } from './ModifiersUtils';
import { ESC, TAB } from './keys';

// When clicking on a day cell, overlay will be hidden after this timeout
export const HIDE_TIMEOUT = 100;

function isDate(date) {
  return date instanceof Date && !isNaN(date.valueOf());
}

export function defaultFormat(d) {
  if (isDate(d)) {
    const year = d.getFullYear();
    const month = `${d.getMonth() + 1}`;
    const day = `${d.getDate()}`;
    return `${year}-${month}-${day}`;
  }
  return '';
}

export function defaultParse(str) {
  if (typeof str !== 'string') {
    return undefined;
  }
  const split = str.split('-');
  if (split.length !== 3) {
    return undefined;
  }
  const year = parseInt(split[0], 10);
  const month = parseInt(split[1], 10) - 1;
  const day = parseInt(split[2], 10);
  if (
    isNaN(year) ||
    isNaN(month) ||
    isNaN(day) ||
    day <= 0 ||
    day > 31 ||
    month < 0 ||
    month >= 12
  ) {
    return undefined;
  }

  return new Date(year, month, day);
}

export default class DayPickerInput extends React.Component {
  static propTypes = {
    value: PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(Date)]),
    inputProps: PropTypes.object,
    placeholder: PropTypes.string,

    format: PropTypes.oneOfType([
      PropTypes.string,
      PropTypes.arrayOf(PropTypes.string),
    ]),

    formatDate: PropTypes.func,
    parseDate: PropTypes.func,

    showOverlay: PropTypes.bool,
    dayPickerProps: PropTypes.object,
    hideOnDayClick: PropTypes.bool,
    clickUnselectsDay: PropTypes.bool,
    keepFocus: PropTypes.bool,
    component: PropTypes.any,
    overlayComponent: PropTypes.any,

    classNames: PropTypes.shape({
      container: PropTypes.string,
      overlayWrapper: PropTypes.string,
      overlay: PropTypes.string.isRequired,
    }),

    onDayChange: PropTypes.func,
    onChange: PropTypes.func,
    onClick: PropTypes.func,
    onFocus: PropTypes.func,
    onBlur: PropTypes.func,
    onKeyUp: PropTypes.func,
  };

  static defaultProps = {
    dayPickerProps: {},
    value: '',
    placeholder: 'YYYY-M-D',
    format: 'L',
    formatDate: defaultFormat,
    parseDate: defaultParse,
    showOverlay: false,
    hideOnDayClick: true,
    clickUnselectsDay: false,
    keepFocus: true,
    component: 'input',
    inputProps: {},
    overlayComponent: ({ children, classNames }) => (

{children}

    ),
    classNames: {
      container: 'DayPickerInput',
      overlayWrapper: 'DayPickerInput-OverlayWrapper',
      overlay: 'DayPickerInput-Overlay',
    },
  };

  constructor(props) {
    super(props);

    this.state = this.getStateFromProps(props);
    this.state.showOverlay = props.showOverlay;

    this.hideAfterDayClick = this.hideAfterDayClick.bind(this);
    this.handleInputClick = this.handleInputClick.bind(this);
    this.handleInputFocus = this.handleInputFocus.bind(this);
    this.handleInputBlur = this.handleInputBlur.bind(this);
    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleInputKeyDown = this.handleInputKeyDown.bind(this);
    this.handleInputKeyUp = this.handleInputKeyUp.bind(this);
    this.handleDayClick = this.handleDayClick.bind(this);
    this.handleMonthChange = this.handleMonthChange.bind(this);
    this.handleOverlayFocus = this.handleOverlayFocus.bind(this);
    this.handleOverlayBlur = this.handleOverlayBlur.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    const monthFromProps = this.props.dayPickerProps.month;
    const nextMonthFromProps = nextProps.dayPickerProps.month;

    const selectedDaysFromProps = this.props.dayPickerProps.selectedDays;
    const nextSelectedDaysFromProps = nextProps.dayPickerProps.selectedDays;

    let nextValue = nextProps.value;
    const currentValue = this.props.value;

    const monthChanged =
      (nextMonthFromProps && !monthFromProps) ||
      (nextMonthFromProps &&
        (nextMonthFromProps.getFullYear() !== monthFromProps.getFullYear() ||
          nextMonthFromProps.getMonth() !== monthFromProps.getMonth()));

    if (nextValue !== currentValue) {
      if (isDate(nextValue)) {
        nextValue = this.props.formatDate(
          nextValue,
          this.props.format,
          this.props.dayPickerProps.locale
        );
      }
      this.setState({
        value: nextValue,
      });
    }
    if (monthChanged) {
      this.setState({ month: nextMonthFromProps });
    }
    if (selectedDaysFromProps !== nextSelectedDaysFromProps) {
      this.setState({ selectedDays: nextSelectedDaysFromProps });
    }
  }

  componentWillUnmount() {
    clearTimeout(this.clickTimeout);
    clearTimeout(this.hideTimeout);
    clearTimeout(this.ieInputFocusTimeout);
    clearTimeout(this.ieInputBlurTimeout);
  }

  getStateFromProps(props) {
    const { dayPickerProps, formatDate, format } = props;
    let { value } = props;

    let day;
    if (props.value) {
      if (isDate(props.value)) {
        day = props.value;
        value = formatDate(props.value, format, dayPickerProps.locale);
      } else {
        day = props.parseDate(props.value, format, dayPickerProps.locale);
      }
    }

    // Use DayPicker's controlled month. Then try the current `value`. Finally default to today.
    const month =
      dayPickerProps.initialMonth || dayPickerProps.month || day || new Date();

    return {
      value,
      month,
      selectedDays: dayPickerProps.selectedDays,
    };
  }

  getInput() {
    return this.input;
  }

  getDayPicker() {
    return this.daypicker;
  }

  isIE() {
    return /*@cc_on!@*/false || !!document.documentMode;
  }

  setStateFrom(relatedTarget) {
    this.setState({
        showOverlay:
          this.overlayNode && this.overlayNode.contains(relatedTarget),
    });
  }

  resetHideTimeout() {
    if(this.hideTimeout) {
      this.hideTimeout = setTimeout(() => {
          this.hideDayPicker();
          this.hideTimeout = null;
        }, HIDE_TIMEOUT);
    }
  }

  input = null;
  daypicker = null;
  overlayNode = null;
  clickTimeout = null;
  hideTimeout = null;
  ieInputFocusTimeout = null;
  ieInputBlutTimeout = null;

  /**
   * Update the component's state and fire the `onDayChange` event
   * passing the day's modifiers to it
   * @param {Date} day - Will be used for changing the month
   * @param {String} value - Input field value
   * @private
   */
  updateState(day, value, callback) {
    const { dayPickerProps, onDayChange } = this.props;
    this.setState({ month: day, value }, () => {
      if (callback) {
        callback();
      }
      if (!onDayChange) {
        return;
      }
      const modifiersObj = {
        disabled: dayPickerProps.disabledDays,
        selected: dayPickerProps.selectedDays,
        ...dayPickerProps.modifiers,
      };
      const modifiers = getModifiersForDay(day, modifiersObj).reduce(
        (obj, modifier) => {
          const newObj = { ...obj };
          newObj[modifier] = true;
          return newObj;
        },
        {}
      );
      onDayChange(day, modifiers);
    });
  }

  /**
   * Show the Day Picker overlay.
   *
   * @memberof DayPickerInput
   */
  showDayPicker() {
    this.setState({ showOverlay: true });
  }

  /**
   * Hide the Day Picker overlay
   *
   * @memberof DayPickerInput
   */
  hideDayPicker() {
    this.setState({ showOverlay: false });
  }

  hideAfterDayClick() {
    if (!this.props.hideOnDayClick) {
      return;
    }
    this.hideTimeout = setTimeout(() => this.hideDayPicker(), HIDE_TIMEOUT);
  }

  handleInputClick(e) {
    this.showDayPicker();
    if (this.props.inputProps.onClick) {
      e.persist();
      this.props.inputProps.onClick(e);
    }
  }

  handleInputFocus(e) {
    this.showDayPicker();
    if (this.props.inputProps.onFocus) {
      e.persist();
      this.props.inputProps.onFocus(e);
    }
  }

  handleInputBlur(e) {
    if(this.isIE()) {
        this.ieInputBlurTimeout = setTimeout(() =>
            this.setStateFrom(e.relatedTarget), HIDE_TIMEOUT);
    } else {
        this.setStateFrom(e.relatedTarget);
    }
    if (this.props.inputProps.onBlur) {
      e.persist();
      this.props.inputProps.onBlur(e);
    }
  }

  handleOverlayFocus(e) {
    if (this.props.keepFocus === true) {
      e.preventDefault();
      if(this.isIE()) {
        this.ieInputFocusTimeout = setTimeout(() => {
            this.input.focus();
            this.resetHideTimeout();
          }, HIDE_TIMEOUT);
      } else {
        this.input.focus();
      }
    }
  }

  handleOverlayBlur(e) {
    this.setState({
      showOverlay:
        this.overlayNode && this.overlayNode.contains(e.relatedTarget),
    });
  }

  handleInputChange(e) {
    const {
      dayPickerProps,
      format,
      inputProps,
      onDayChange,
      parseDate,
    } = this.props;
    if (inputProps.onChange) {
      e.persist();
      inputProps.onChange(e);
    }
    const { value } = e.target;
    if (value.trim() === '') {
      this.setState({ value });
      if (onDayChange) onDayChange(undefined, {});
      return;
    }
    const day = parseDate(value, format, dayPickerProps.locale);
    if (!day) {
      this.setState({ value });
      if (onDayChange) onDayChange(undefined, {});
      return;
    }
    this.updateState(day, value);
  }

  handleInputKeyDown(e) {
    if (e.keyCode === TAB) {
      this.hideDayPicker();
    }
    if (this.props.inputProps.onKeyDown) {
      e.persist();
      this.props.inputProps.onKeyDown(e);
    }
  }

  handleInputKeyUp(e) {
    // Hide the overlay if the ESC key is pressed
    if (e.keyCode === ESC) {
      this.hideDayPicker();
    }
    if (this.props.inputProps.onKeyUp) {
      e.persist();
      this.props.inputProps.onKeyUp(e);
    }
  }

  handleMonthChange(month) {
    this.setState({ month }, () => {
      if (
        this.props.dayPickerProps &&
        this.props.dayPickerProps.onMonthChange
      ) {
        this.props.dayPickerProps.onMonthChange(month);
      }
    });
  }

  handleDayClick(day, modifiers, e) {
    const {
      clickUnselectsDay,
      dayPickerProps,
      onDayChange,
      formatDate,
      format,
    } = this.props;
    if (dayPickerProps.onDayClick) {
      dayPickerProps.onDayClick(day, modifiers, e);
    }

    // Do nothing if the day is disabled
    if (modifiers.disabled) {
      return;
    }

    // If the clicked day is already selected, remove the clicked day
    // from the selected days and empty the field value
    if (modifiers.selected && clickUnselectsDay) {
      let { selectedDays } = this.state;
      if (Array.isArray(selectedDays)) {
        selectedDays = selectedDays.slice(0);
        const selectedDayIdx = selectedDays.indexOf(day);
        selectedDays.splice(selectedDayIdx, 1);
      } else if (selectedDays) {
        selectedDays = null;
      }
      this.setState({ value: '', selectedDays }, this.hideAfterDayClick);
      if (onDayChange) {
        onDayChange(undefined, modifiers);
      }
      return;
    }

    const value = formatDate(day, format, dayPickerProps.locale);
    this.setState({ value, month: day }, () => {
      if (onDayChange) {
        onDayChange(day, modifiers);
      }
      this.hideAfterDayClick();
    });
  }

  renderOverlay() {
    const {
      classNames,
      dayPickerProps,
      parseDate,
      formatDate,
      format,
    } = this.props;
    const { selectedDays, value } = this.state;
    let selectedDay;
    if (!selectedDays && value) {
      const day = parseDate(value, format, dayPickerProps.locale);
      if (day) {
        selectedDay = day;
      }
    } else if (selectedDays) {
      selectedDay = selectedDays;
    }
    let onTodayButtonClick;
    if (dayPickerProps.todayButton) {
      // Set the current day when clicking the today button
      onTodayButtonClick = () =>
        this.updateState(
          new Date(),
          formatDate(new Date(), format, dayPickerProps.locale),
          this.hideAfterDayClick
        );
    }
    const Overlay = this.props.overlayComponent;
    return (
       (this.overlayNode = el)}
        onBlur={this.handleOverlayBlur}
      >
        <Overlay
          classNames={classNames}
          month={this.state.month}
          selectedDay={selectedDay}
          input={this.input}
        >
          <DayPicker
            ref={el => (this.daypicker = el)}
            onTodayButtonClick={onTodayButtonClick}
            {...dayPickerProps}
            month={this.state.month}
            selectedDays={selectedDay}
            onDayClick={this.handleDayClick}
            onMonthChange={this.handleMonthChange}
          />
        </Overlay>

    );
  }

  render() {
    const Input = this.props.component;
    return (

        <Input
          ref={el => (this.input = el)}
          placeholder={this.props.placeholder}
          {...this.props.inputProps}
          value={this.state.value}
          onChange={this.handleInputChange}
          onFocus={this.handleInputFocus}
          onBlur={this.handleInputBlur}
          onKeyDown={this.handleInputKeyDown}
          onKeyUp={this.handleInputKeyUp}
          onClick={this.handleInputClick}
        />
        {this.state.showOverlay && this.renderOverlay()}

    );
  }
}
<|endoftext|>


<commit_before>// Peity jQuery plugin version 1.1.2
// (c) 2013 Ben Pickles
//
// http://benpickles.github.com/peity
//
// Released under MIT license.
(function($, document, Math, devicePixelRatio) {
  var canvasSupported = document.createElement("canvas").getContext

  var peity = $.fn.peity = function(type, options) {
    if (canvasSupported) {
      this.each(function() {
        var $this = $(this)
        var chart = $this.data("peity")

        if (chart) {
          chart.type = type
          $.extend(chart.opts, options)
          chart.draw()
        } else {
          var defaults = peity.defaults[type]
          var data = {}

          $.each($this.data(), function(name, value) {
            if (name in defaults) data[name] = value
          })

          var opts = $.extend({}, defaults, data, options)
          var chart = new Peity($this, type, opts)
          chart.draw()

          $this
            .change(function() { chart.draw() })
            .data("peity", chart)
        }
      });
    }

    return this;
  };

  var Peity = function($el, type, opts) {
    this.$el = $el
    this.type = type
    this.opts = opts
  }

  var PeityPrototype = Peity.prototype

  PeityPrototype.colours = function() {
    var colours = this.opts.colours
    var func = colours

    if (!$.isFunction(func)) {
      func = function(_, i) {
        return colours[i % colours.length]
      }
    }

    return func
  }

  PeityPrototype.draw = function() {
    peity.graphers[this.type].call(this, this.opts)
  }

  PeityPrototype.prepareCanvas = function(width, height) {
    var canvas = this.canvas

    if (canvas) {
      this.context.clearRect(0, 0, canvas.width, canvas.height)
    } else {
      canvas = $("<canvas>").attr({
        height: height * devicePixelRatio,
        width: width * devicePixelRatio
      }).data("peity", this)

      if (devicePixelRatio != 1) {
        canvas.css({
          height: height,
          width: width
        })
      }

      this.canvas = canvas = canvas[0]
      this.context = canvas.getContext("2d")
      this.$el.hide().before(canvas)
    }

    return canvas
  }

  PeityPrototype.values = function() {
    return $.map(this.$el.text().split(this.opts.delimiter), function(value) {
      return parseFloat(value)
    })
  }

  peity.defaults = {}
  peity.graphers = {}

  peity.register = function(type, defaults, grapher) {
    this.defaults[type] = defaults
    this.graphers[type] = grapher
  }

  peity.register(
    'pie',
    {
      colours: ["#ff9900", "#fff4dd", "#ffc66e"],
      delimiter: null,
      diameter: 16
    },
    function(opts) {
      if (!opts.delimiter) {
        var delimiter = this.$el.text().match(/[^0-9\.]/)
        opts.delimiter = delimiter ? delimiter[0] : ","
      }

      var values = this.values()

      if (opts.delimiter == "/") {
        var v1 = values[0]
        var v2 = values[1]
        values = [v1, v2 - v1]
      }

      var i = 0
      var length = values.length
      var sum = 0

      for (; i < length; i++) {
        sum += values[i]
      }

      var canvas = this.prepareCanvas(opts.diameter, opts.diameter)
      var context = this.context
      var half = canvas.width / 2
      var pi = Math.PI
      var colours = this.colours()

      context.save()
      context.translate(half, half)
      context.rotate(-pi / 2)

      for (i = 0; i < length; i++) {
        var value = values[i]
        var slice = (value / sum) * pi * 2

        context.beginPath()
        context.moveTo(0, 0)
        context.arc(0, 0, half, 0, slice, false)
        context.fillStyle = colours.call(this, value, i, values)
        context.fill()
        context.rotate(slice)
      }

      context.restore()
    }
  )

  peity.register(
    "line",
    {
      colour: "#c6d9fd",
      strokeColour: "#4d89f9",
      strokeWidth: 1,
      delimiter: ",",
      height: 16,
      max: null,
      min: 0,
      width: 32
    },
    function(opts) {
      var values = this.values()
      if (values.length == 1) values.push(values[0])
      var max = Math.max.apply(Math, values.concat([opts.max]));
      var min = Math.min.apply(Math, values.concat([opts.min]))

      var canvas = this.prepareCanvas(opts.width, opts.height)
      var context = this.context
      var width = canvas.width
      var height = canvas.height
      var xQuotient = width / (values.length - 1)
      var yQuotient = height / (max - min)

      var coords = [];
      var i;

      context.beginPath();
      context.moveTo(0, height + (min * yQuotient))

      for (i = 0; i < values.length; i++) {
        var x = i * xQuotient
        var y = height - (yQuotient * (values[i] - min))

        coords.push({ x: x, y: y });
        context.lineTo(x, y);
      }

      context.lineTo(width, height + (min * yQuotient))
      context.fillStyle = opts.colour;
      context.fill();

      if (opts.strokeWidth) {
        context.beginPath();
        context.moveTo(0, coords[0].y);
        for (i = 0; i < coords.length; i++) {
          context.lineTo(coords[i].x, coords[i].y);
        }
        context.lineWidth = opts.strokeWidth * devicePixelRatio;
        context.strokeStyle = opts.strokeColour;
        context.stroke();
      }
    }
  );

  peity.register(
    'bar',
    {
      colours: ["#4D89F9"],
      delimiter: ",",
      height: 16,
      max: null,
      min: 0,
      spacing: devicePixelRatio,
      width: 32
    },
    function(opts) {
      var values = this.values()
      var max = Math.max.apply(Math, values.concat([opts.max]));
      var min = Math.min.apply(Math, values.concat([opts.min]))

      var canvas = this.prepareCanvas(opts.width, opts.height)
      var context = this.context

      var width = canvas.width
      var height = canvas.height
      var yQuotient = height / (max - min)
      var space = opts.spacing
      var xQuotient = (width + space) / values.length
      var colours = this.colours()

      for (var i = 0; i < values.length; i++) {
        var value = values[i]
        var y = height - (yQuotient * (value - min))
        var h

        if (value == 0) {
          if (min >= 0 || max > 0) y -= 1
          h = 1
        } else {
          h = yQuotient * values[i]
        }

        context.fillStyle = colours.call(this, value, i, values)
        context.fillRect(i * xQuotient, y, xQuotient - space, h)
      }
    }
  );
})(jQuery, document, Math, window.devicePixelRatio || 1);
<commit_msg>Get percentage dimensions working for line and bar charts.<commit_after>// Peity jQuery plugin version 1.1.2
// (c) 2013 Ben Pickles
//
// http://benpickles.github.com/peity
//
// Released under MIT license.
(function($, document, Math, devicePixelRatio) {
  var canvasSupported = document.createElement("canvas").getContext

  var peity = $.fn.peity = function(type, options) {
    if (canvasSupported) {
      this.each(function() {
        var $this = $(this)
        var chart = $this.data("peity")

        if (chart) {
          chart.type = type
          $.extend(chart.opts, options)
          chart.draw()
        } else {
          var defaults = peity.defaults[type]
          var data = {}

          $.each($this.data(), function(name, value) {
            if (name in defaults) data[name] = value
          })

          var opts = $.extend({}, defaults, data, options)
          var chart = new Peity($this, type, opts)
          chart.draw()

          $this
            .change(function() { chart.draw() })
            .data("peity", chart)
        }
      });
    }

    return this;
  };

  var Peity = function($el, type, opts) {
    this.$el = $el
    this.type = type
    this.opts = opts
  }

  var PeityPrototype = Peity.prototype

  PeityPrototype.colours = function() {
    var colours = this.opts.colours
    var func = colours

    if (!$.isFunction(func)) {
      func = function(_, i) {
        return colours[i % colours.length]
      }
    }

    return func
  }

  PeityPrototype.draw = function() {
    peity.graphers[this.type].call(this, this.opts)
  }

  PeityPrototype.prepareCanvas = function(width, height) {
    var canvas = this.canvas

    if (canvas) {
      this.context.clearRect(0, 0, canvas.width, canvas.height)
    } else {
      var $canvas = $("<canvas>").css({
        height: height,
        width: width
      }).data("peity", this)

      this.canvas = canvas = $canvas[0]
      this.context = canvas.getContext("2d")
      this.$el.hide().before(canvas)

      $canvas.attr({
        height: $canvas.height() * devicePixelRatio,
        width: $canvas.width() * devicePixelRatio
      })
    }

    return canvas
  }

  PeityPrototype.values = function() {
    return $.map(this.$el.text().split(this.opts.delimiter), function(value) {
      return parseFloat(value)
    })
  }

  peity.defaults = {}
  peity.graphers = {}

  peity.register = function(type, defaults, grapher) {
    this.defaults[type] = defaults
    this.graphers[type] = grapher
  }

  peity.register(
    'pie',
    {
      colours: ["#ff9900", "#fff4dd", "#ffc66e"],
      delimiter: null,
      diameter: 16
    },
    function(opts) {
      if (!opts.delimiter) {
        var delimiter = this.$el.text().match(/[^0-9\.]/)
        opts.delimiter = delimiter ? delimiter[0] : ","
      }

      var values = this.values()

      if (opts.delimiter == "/") {
        var v1 = values[0]
        var v2 = values[1]
        values = [v1, v2 - v1]
      }

      var i = 0
      var length = values.length
      var sum = 0

      for (; i < length; i++) {
        sum += values[i]
      }

      var canvas = this.prepareCanvas(opts.diameter, opts.diameter)
      var context = this.context
      var half = canvas.width / 2
      var pi = Math.PI
      var colours = this.colours()

      context.save()
      context.translate(half, half)
      context.rotate(-pi / 2)

      for (i = 0; i < length; i++) {
        var value = values[i]
        var slice = (value / sum) * pi * 2

        context.beginPath()
        context.moveTo(0, 0)
        context.arc(0, 0, half, 0, slice, false)
        context.fillStyle = colours.call(this, value, i, values)
        context.fill()
        context.rotate(slice)
      }

      context.restore()
    }
  )

  peity.register(
    "line",
    {
      colour: "#c6d9fd",
      strokeColour: "#4d89f9",
      strokeWidth: 1,
      delimiter: ",",
      height: 16,
      max: null,
      min: 0,
      width: 32
    },
    function(opts) {
      var values = this.values()
      if (values.length == 1) values.push(values[0])
      var max = Math.max.apply(Math, values.concat([opts.max]));
      var min = Math.min.apply(Math, values.concat([opts.min]))

      var canvas = this.prepareCanvas(opts.width, opts.height)
      var context = this.context
      var width = canvas.width
      var height = canvas.height
      var xQuotient = width / (values.length - 1)
      var yQuotient = height / (max - min)

      var coords = [];
      var i;

      context.beginPath();
      context.moveTo(0, height + (min * yQuotient))

      for (i = 0; i < values.length; i++) {
        var x = i * xQuotient
        var y = height - (yQuotient * (values[i] - min))

        coords.push({ x: x, y: y });
        context.lineTo(x, y);
      }

      context.lineTo(width, height + (min * yQuotient))
      context.fillStyle = opts.colour;
      context.fill();

      if (opts.strokeWidth) {
        context.beginPath();
        context.moveTo(0, coords[0].y);
        for (i = 0; i < coords.length; i++) {
          context.lineTo(coords[i].x, coords[i].y);
        }
        context.lineWidth = opts.strokeWidth * devicePixelRatio;
        context.strokeStyle = opts.strokeColour;
        context.stroke();
      }
    }
  );

  peity.register(
    'bar',
    {
      colours: ["#4D89F9"],
      delimiter: ",",
      height: 16,
      max: null,
      min: 0,
      spacing: devicePixelRatio,
      width: 32
    },
    function(opts) {
      var values = this.values()
      var max = Math.max.apply(Math, values.concat([opts.max]));
      var min = Math.min.apply(Math, values.concat([opts.min]))

      var canvas = this.prepareCanvas(opts.width, opts.height)
      var context = this.context

      var width = canvas.width
      var height = canvas.height
      var yQuotient = height / (max - min)
      var space = opts.spacing
      var xQuotient = (width + space) / values.length
      var colours = this.colours()

      for (var i = 0; i < values.length; i++) {
        var value = values[i]
        var y = height - (yQuotient * (value - min))
        var h

        if (value == 0) {
          if (min >= 0 || max > 0) y -= 1
          h = 1
        } else {
          h = yQuotient * values[i]
        }

        context.fillStyle = colours.call(this, value, i, values)
        context.fillRect(i * xQuotient, y, xQuotient - space, h)
      }
    }
  );
})(jQuery, document, Math, window.devicePixelRatio || 1);
<|endoftext|>


<commit_before>var http = require('http');
var fs = require('fs');
var os = require('os');
var exec = require('child_process').exec;

var targetDir = __dirname + '/tools/';
try {
    fs.statSync(targetDir);
} catch (e) {
    fs.mkdirSync(targetDir);
}

var platform = null;
if (os.type() == 'Darwin') {
    platform = 'macosx';
} else if (os.type() == 'Linux') {
    platform = 'linux';
} else {
    throw new Error('Unknown OS!');
}

var url = "http://dl-ssl.google.com/android/repository/platform-tools_r16-" + platform + ".zip";
var tempFile = "/tmp/platform-tools-" + (new Date().getTime()) + ".zip";

var file = fs.createWriteStream(tempFile);
var request = http.get(url, function(response) {
    response.pipe(file);
    response.on('end', function () {
        exec("unzip -j -o " + tempFile + " platform-tools/aapt -d tools/", function (err) {
            if (err) {
                throw err;
            }
            fs.chmodSync('tools/aapt', '755');
            fs.unlinkSync(tempFile);
            process.exit();
        });
    });
});
<commit_msg>Try to install aapt three times, it sometimes fails.<commit_after>var http = require('http');
var fs = require('fs');
var os = require('os');
var exec = require('child_process').exec;

var targetDir = __dirname + '/tools/';
try {
    fs.statSync(targetDir);
} catch (e) {
    fs.mkdirSync(targetDir);
}

var platform = null;
if (os.type() == 'Darwin') {
    platform = 'macosx';
} else if (os.type() == 'Linux') {
    platform = 'linux';
} else {
    throw new Error('Unknown OS!');
}

function attemptDownload(attemptsLeft) {
    var url = "http://dl-ssl.google.com/android/repository/platform-tools_r16-" + platform + ".zip";
    var tempFile = "/tmp/platform-tools-" + (new Date().getTime()) + ".zip";

    var file = fs.createWriteStream(tempFile);
    var request = http.get(url, function(response) {
        response.pipe(file);
        response.on('end', function () {
            exec("unzip -j -o " + tempFile + " platform-tools/aapt -d tools/", function (err) {
                if (err) {
                    if (attemptsLeft === 0) {
                        throw err;
                    } else {
                        attemptDownload(attemptsLeft - 1);
                        return;
                    }
                }
                fs.chmodSync('tools/aapt', '755');
                fs.unlinkSync(tempFile);
                process.exit();
            });
        });
    });
}

attemptDownload(3);
<|endoftext|>


<commit_before>'use strict';

module.exports = {
  HOST: process.env.VRFOX_HOST || process.env.HOST || '0.0.0.0',
  PORT: process.env.VRFOX_PORT || process.env.PORT || 5000,

  CORS: true,

  // Register your Twitter application here: https://apps.twitter.com/app/new
  TWITTER_CONSUMER_KEY: process.env.TWEET2DB_TWITTER_CONSUMER_KEY || '',
  TWITTER_CONSUMER_SECRET: process.env.TWEET2DB_TWITTER_CONSUMER_SECRET || '',
  TWITTER_ACCESS_TOKEN: process.env.TWEET2DB_TWITTER_ACCESS_TOKEN || '',
  TWITTER_ACCESS_TOKEN_SECRET: process.env.TWEET2DB_TWITTER_ACCESS_TOKEN_SECRET || ''
};

var settings_path = process.env.TWEET2DB_SETTINGS || process.env.SETTINGS || './settings_local';

var settings_local;

if (settings_path[0] !== '/' && settings_path.substr(0, 2) !== './') {
  // Assume it's a relative path.
  settings_path = './' + settings_path;
}

try {
  settings_local = require(settings_path);
} catch (e) {
}

if (settings_local) {
  console.log('Using settings file ' + settings_path);
  Object.keys(settings_local).forEach(function (k) {
    module.exports[k] = settings_local[k];
  });
}
<commit_msg>fix HOST and PORT in settings<commit_after>'use strict';

module.exports = {
  HOST: process.env.TWEET2DB_HOST || process.env.HOST || '0.0.0.0',
  PORT: process.env.TWEET2DB_PORT || process.env.PORT || 5000,

  CORS: true,

  // Register your Twitter application here: https://apps.twitter.com/app/new
  TWITTER_CONSUMER_KEY: process.env.TWEET2DB_TWITTER_CONSUMER_KEY || '',
  TWITTER_CONSUMER_SECRET: process.env.TWEET2DB_TWITTER_CONSUMER_SECRET || '',
  TWITTER_ACCESS_TOKEN: process.env.TWEET2DB_TWITTER_ACCESS_TOKEN || '',
  TWITTER_ACCESS_TOKEN_SECRET: process.env.TWEET2DB_TWITTER_ACCESS_TOKEN_SECRET || ''
};

var settings_path = process.env.TWEET2DB_SETTINGS || process.env.SETTINGS || './settings_local';

var settings_local;

if (settings_path[0] !== '/' && settings_path.substr(0, 2) !== './') {
  // Assume it's a relative path.
  settings_path = './' + settings_path;
}

try {
  settings_local = require(settings_path);
} catch (e) {
}

if (settings_local) {
  console.log('Using settings file ' + settings_path);
  Object.keys(settings_local).forEach(function (k) {
    module.exports[k] = settings_local[k];
  });
}
<|endoftext|>


<commit_before>import Ember from 'ember';
import MapFacade from '../facades/map';

const {isEmpty, computed, on, K, run} = Ember;

export default Ember.Component.extend({

  classNames: ['ui-map'],

  readyAction: 'mapReady',

  mapClickAction: 'mapClick',
  mapBoundsChangedAction: 'mapBoundsChanged',
  mapCenterChangedAction: 'mapCenterChanged',
  mapDoubleClickAction: 'mapDoubleClick',
  mapRightClickAction: 'mapRightClick',
  mapTilesLoadedAction: 'mapTilesLoaded',
  mapZoomChangedAction: 'mapZoomChanged',
  mapDragAction: 'mapDrag',
  mapDragEndAction: 'mapDragEnd',
  mapDragStartAction: 'mapDragStart',
  mapHeadingChangedAction: 'mapHeadingChanged',
  mapIdleAction: 'mapIdle',
  mapTypeIdChangedAction: 'mapTypeIdChanged',
  mapProjectionChangedAction: 'mapProjectionChanged',
  mapMouseMoveAction: 'mapMouseMove',
  mapMouseUpAction: 'mapMouseUp',
  mapMouseDownAction: 'mapMouseDown',
  mapMouseOverAction: 'mapMouseOver',
  mapMouseOutAction: 'mapMouseOut',

  markerClickAction: 'markerClick',
  markerAnimationChangedAction: 'markerAnimationChanged',
  markerClickableChangedAction: 'markerClickableChanged',
  markerCursorChangedAction: 'markerCursorChanged',
  markerDoubleClickAction: 'markerDoubleClick',
  markerDragAction: 'markerDrag',
  markerDragEndAction: 'markerDragEnd',
  markerDraggableChangedAction: 'markerDraggableChanged',
  markerDragStartAction: 'markerDragStart',
  markerFlatChangedAction: 'markerFlatChanged',
  markerIconChangedAction: 'markerIconChanged',
  markerMouseDownAction: 'markerMouseDown',
  markerMouseOutAction: 'markerMouseOut',
  markerMouseOverAction: 'markerMouseOver',
  markerMouseUpAction: 'markerMouseUp',
  markerPositionChangedAction: 'markerPositionChanged',
  markerRightClickAction: 'markerRightClick',
  markerShapeChangedAction: 'markerShapeChanged',
  markerTitleChangedAction: 'markerTitleChanged',
  markerVisibleChangedAction: 'markerVisibleChanged',
  markerZIndexChangedAction: 'markerZIndexChanged',

  _isReady: false,

  markers: Ember.A([]),

  _registerFacade: on('willInsertElement', function () {
    let mapFacade = this.get('mapFacade');

    if (isEmpty(mapFacade)) {
      mapFacade = MapFacade.create();
      this.set('mapFacade', mapFacade);
    }
  }),

  _setup: on('didInsertElement', function () {
    run.next(() => {
      this.setup();
      this.addMarkers(this.get('markers'));
      this.get('mapFacade').register(this);
      this.set('_isReady', true);
      this.sendAction('readyAction', this.get('mapFacade'));
    });
  }),

  _teardown: on('willDestroyElement', function () {
    const {mapFacade, markerMap} = this.getProperties('mapFacade', 'markerMap');

    this.teardown(markerMap);

    mapFacade.unregister(this);

    this.set('_isReady', false);

    markerMap.clear();
  }),

  markerMap: computed(function () {
    return Ember.Map.create();
  }),

  config: {
    options: {
      zoom: 13,
      center: {
        lat: 0,
        lng: 0
      }
    }
  },

  isReady() {
    return this.get('_isReady');
  },

  getElement() {
    return this.$()[0];
  },

  getMapPixel() {
    return this.$().position();
  },

  getMarkerPixel(id) {
    return this._getMarkerPixel(this.getMarker(id));
  },

  size: function () {
    return this.get('markerMap.size');
  },

  hasMarker(id) {
    return this.get('markerMap').has(id);
  },

  getMarker(id) {
    Ember.assert('MapKit: This marker has no mapping', this.hasMarker(id));

    return this.get('markerMap').get(id);
  },

  addMarkers(markers) {
    markers.forEach((marker) => {
      this.addMarker(marker);
    });
  },

  addListeners(eventNames) {
    eventNames.forEach((eventName) => {
      this.addListener(eventName);
    });
  },

  getMarkers() {
    return this.get('markerMap');
  },

  getMap() {
    return this.get('map');
  },

  setup: K,

  teardown: K,

  getCenter: K,

  setCenter: K,

  getZoom: K,

  setZoom: K,

  getBounds: K,

  setOptions: K,

  getTilt: K,

  getMapType: K,

  setMapType: K,

  setTitle: K,

  addListener: K,

  removeListener: K,

  addMarker: K,

  addMarkerListener: K,

  removeMarker: K,

  removeMarkerListener: K,

  setMarkerIcon: K,

  setMarkerPosition: K,

  getMarkerPosition: K,

  setMarkerDraggable: K,

  setMarkerVisible: K,

  setMarkerTitle: K,

  panTo: K,

  fitToMarkers: K
});

<commit_msg>blank<commit_after>import Ember from 'ember';
import MapFacade from '../facades/map';

const {isEmpty, computed, on, K, run} = Ember;

export default Ember.Component.extend({

  classNames: ['ui-map'],

  readyAction: 'mapReady',

  mapClickAction: 'mapClick',
  mapBoundsChangedAction: 'mapBoundsChanged',
  mapCenterChangedAction: 'mapCenterChanged',
  mapDoubleClickAction: 'mapDoubleClick',
  mapRightClickAction: 'mapRightClick',
  mapTilesLoadedAction: 'mapTilesLoaded',
  mapZoomChangedAction: 'mapZoomChanged',
  mapDragAction: 'mapDrag',
  mapDragEndAction: 'mapDragEnd',
  mapDragStartAction: 'mapDragStart',
  mapHeadingChangedAction: 'mapHeadingChanged',
  mapIdleAction: 'mapIdle',
  mapTypeIdChangedAction: 'mapTypeIdChanged',
  mapProjectionChangedAction: 'mapProjectionChanged',
  mapMouseMoveAction: 'mapMouseMove',
  mapMouseUpAction: 'mapMouseUp',
  mapMouseDownAction: 'mapMouseDown',
  mapMouseOverAction: 'mapMouseOver',
  mapMouseOutAction: 'mapMouseOut',

  markerClickAction: 'markerClick',
  markerAnimationChangedAction: 'markerAnimationChanged',
  markerClickableChangedAction: 'markerClickableChanged',
  markerCursorChangedAction: 'markerCursorChanged',
  markerDoubleClickAction: 'markerDoubleClick',
  markerDragAction: 'markerDrag',
  markerDragEndAction: 'markerDragEnd',
  markerDraggableChangedAction: 'markerDraggableChanged',
  markerDragStartAction: 'markerDragStart',
  markerFlatChangedAction: 'markerFlatChanged',
  markerIconChangedAction: 'markerIconChanged',
  markerMouseDownAction: 'markerMouseDown',
  markerMouseOutAction: 'markerMouseOut',
  markerMouseOverAction: 'markerMouseOver',
  markerMouseUpAction: 'markerMouseUp',
  markerPositionChangedAction: 'markerPositionChanged',
  markerRightClickAction: 'markerRightClick',
  markerShapeChangedAction: 'markerShapeChanged',
  markerTitleChangedAction: 'markerTitleChanged',
  markerVisibleChangedAction: 'markerVisibleChanged',
  markerZIndexChangedAction: 'markerZIndexChanged',

  _isReady: false,

  markers: Ember.A([]),

  _registerFacade: on('willInsertElement', function () {
    let mapFacade = this.get('mapFacade');

    if (isEmpty(mapFacade)) {
      mapFacade = MapFacade.create();
      this.set('mapFacade', mapFacade);
    }
  }),

  _setup: on('didInsertElement', function () {
    run.scheduleOnce('afterRender', () => {
      this.setup();
      this.addMarkers(this.get('markers'));
      this.get('mapFacade').register(this);
      this.set('_isReady', true);
      this.sendAction('readyAction', this.get('mapFacade'));
    });
  }),

  _teardown: on('willDestroyElement', function () {
    const {mapFacade, markerMap} = this.getProperties('mapFacade', 'markerMap');

    this.teardown(markerMap);

    mapFacade.unregister(this);

    this.set('_isReady', false);

    markerMap.clear();
  }),

  markerMap: computed(function () {
    return Ember.Map.create();
  }),

  config: {
    options: {
      zoom: 13,
      center: {
        lat: 0,
        lng: 0
      }
    }
  },

  isReady() {
    return this.get('_isReady');
  },

  getElement() {
    return this.$()[0];
  },

  getMapPixel() {
    return this.$().position();
  },

  getMarkerPixel(id) {
    return this._getMarkerPixel(this.getMarker(id));
  },

  size: function () {
    return this.get('markerMap.size');
  },

  hasMarker(id) {
    return this.get('markerMap').has(id);
  },

  getMarker(id) {
    Ember.assert('MapKit: This marker has no mapping', this.hasMarker(id));

    return this.get('markerMap').get(id);
  },

  addMarkers(markers) {
    markers.forEach((marker) => {
      this.addMarker(marker);
    });
  },

  addListeners(eventNames) {
    eventNames.forEach((eventName) => {
      this.addListener(eventName);
    });
  },

  getMarkers() {
    return this.get('markerMap');
  },

  getMap() {
    return this.get('map');
  },

  setup: K,

  teardown: K,

  getCenter: K,

  setCenter: K,

  getZoom: K,

  setZoom: K,

  getBounds: K,

  setOptions: K,

  getTilt: K,

  getMapType: K,

  setMapType: K,

  setTitle: K,

  addListener: K,

  removeListener: K,

  addMarker: K,

  addMarkerListener: K,

  removeMarker: K,

  removeMarkerListener: K,

  setMarkerIcon: K,

  setMarkerPosition: K,

  getMarkerPosition: K,

  setMarkerDraggable: K,

  setMarkerVisible: K,

  setMarkerTitle: K,

  panTo: K,

  fitToMarkers: K
});

<|endoftext|>


<commit_before><commit_msg>add logging<commit_after><|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies.
 */
var passport = require('passport'),
	SamlStrategy = require('passport-saml').Strategy,
  fs = require('fs'),
	User = require('mongoose').model('User'),
  pvk = fs.readFileSync('./config/keys/mykey.key', 'utf-8');

// Set in global scope, so it can be used again for the metadata route
global.SAMLStrategy = new SamlStrategy({
      path: '/login/callback',
      entryPoint: 'https://engine.surfconext.nl/authentication/idp/single-sign-on',
      issuer: 'goalsetting.ihatestatistics.com',
      //decryptionPvk: pvk,
      //cert: 'MIID3zCCAsegAwIBAgIJAMVC9xn1ZfsuMA0GCSqGSIb3DQEBCwUAMIGFMQswCQYDVQQGEwJOTDEQMA4GA1UECAwHVXRyZWNodDEQMA4GA1UEBwwHVXRyZWNodDEVMBMGA1UECgwMU1VSRm5ldCBCLlYuMRMwEQYDVQQLDApTVVJGY29uZXh0MSYwJAYDVQQDDB1lbmdpbmUuc3VyZmNvbmV4dC5ubCAyMDE0MDUwNTAeFw0xNDA1MDUxNDIyMzVaFw0xOTA1MDUxNDIyMzVaMIGFMQswCQYDVQQGEwJOTDEQMA4GA1UECAwHVXRyZWNodDEQMA4GA1UEBwwHVXRyZWNodDEVMBMGA1UECgwMU1VSRm5ldCBCLlYuMRMwEQYDVQQLDApTVVJGY29uZXh0MSYwJAYDVQQDDB1lbmdpbmUuc3VyZmNvbmV4dC5ubCAyMDE0MDUwNTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKthMDbB0jKHefPzmRu9t2h7iLP4wAXr42bHpjzTEk6gttHFb4l/hFiz1YBI88TjiH6hVjnozo/YHA2c51us+Y7g0XoS7653lbUN/EHzvDMuyis4Xi2Ijf1A/OUQfH1iFUWttIgtWK9+fatXoGUS6tirQvrzVh6ZstEp1xbpo1SF6UoVl+fh7tM81qz+Crr/Kroan0UjpZOFTwxPoK6fdLgMAieKSCRmBGpbJHbQ2xxbdykBBrBbdfzIX4CDepfjE9h/40ldw5jRn3e392jrS6htk23N9BWWrpBT5QCk0kH3h/6F1Dm6TkyG9CDtt73/anuRkvXbeygI4wml9bL3rE8CAwEAAaNQME4wHQYDVR0OBBYEFD+Ac7akFxaMhBQAjVfvgGfY8hNKMB8GA1UdIwQYMBaAFD+Ac7akFxaMhBQAjVfvgGfY8hNKMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAC8L9D67CxIhGo5aGVu63WqRHBNOdo/FAGI7LURDFeRmG5nRw/VXzJLGJksh4FSkx7aPrxNWF1uFiDZ80EuYQuIv7bDLblK31ZEbdg1R9LgiZCdYSr464I7yXQY9o6FiNtSKZkQO8EsscJPPy/Zp4uHAnADWACkOUHiCbcKiUUFu66dX0Wr/v53Gekz487GgVRs8HEeT9MU1reBKRgdENR8PNg4rbQfLc3YQKLWK7yWnn/RenjDpuCiePj8N8/80tGgrNgK/6fzM3zI18sSywnXLswxqDb/J+jgVxnQ6MrsTf1urM8MnfcxG/82oHIwfMh/sXPCZpo+DTLkhQxctJ3M=',
      identifierFormat: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
      callbackUrl: 'https://goalsetting.ihatestatistics.com/login/callback',
      acceptedClockSkewMs: -1
    },
    function(profile, done) {
      User.find({email: profile.email}).exec(function (err, user) {
        if (err) {
          return done(err);
        } else {
          if (user) {
            console.log('found');
            console.log(user);
            return done(null, user);
          }

          var newUser = new User();
          newUser.firstName = profile['urn:mace:dir:attribute-def:givenName'];
          newUser.lastName = profile['urn:mace:dir:attribute-def:sn'];
          newUser.email = profile['urn:mace:dir:attribute-def:mail'];
          newUser.provider = 'SurfConext';
          newUser.roles = [];
          newUser.roles.push(profile['urn:mace:dir:attribute-def:eduPersonAffiliation']);
          newUser.save(function (err) {
            if (err) {
              return done(err);
            }
            console.log('new');
            console.log(newUser);
            return done(null, newUser);
          });
        }
      });
    }
);

module.exports = function() {
  var samlStrategy = global.SAMLStrategy;

  // Use SAML strategy for Surfconext
  passport.use(samlStrategy);
};<commit_msg>User should be falsy now<commit_after>'use strict';

/**
 * Module dependencies.
 */
var passport = require('passport'),
	SamlStrategy = require('passport-saml').Strategy,
  fs = require('fs'),
	User = require('mongoose').model('User'),
  pvk = fs.readFileSync('./config/keys/mykey.key', 'utf-8');

// Set in global scope, so it can be used again for the metadata route
global.SAMLStrategy = new SamlStrategy({
      path: '/login/callback',
      entryPoint: 'https://engine.surfconext.nl/authentication/idp/single-sign-on',
      issuer: 'goalsetting.ihatestatistics.com',
      //decryptionPvk: pvk,
      //cert: 'MIID3zCCAsegAwIBAgIJAMVC9xn1ZfsuMA0GCSqGSIb3DQEBCwUAMIGFMQswCQYDVQQGEwJOTDEQMA4GA1UECAwHVXRyZWNodDEQMA4GA1UEBwwHVXRyZWNodDEVMBMGA1UECgwMU1VSRm5ldCBCLlYuMRMwEQYDVQQLDApTVVJGY29uZXh0MSYwJAYDVQQDDB1lbmdpbmUuc3VyZmNvbmV4dC5ubCAyMDE0MDUwNTAeFw0xNDA1MDUxNDIyMzVaFw0xOTA1MDUxNDIyMzVaMIGFMQswCQYDVQQGEwJOTDEQMA4GA1UECAwHVXRyZWNodDEQMA4GA1UEBwwHVXRyZWNodDEVMBMGA1UECgwMU1VSRm5ldCBCLlYuMRMwEQYDVQQLDApTVVJGY29uZXh0MSYwJAYDVQQDDB1lbmdpbmUuc3VyZmNvbmV4dC5ubCAyMDE0MDUwNTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKthMDbB0jKHefPzmRu9t2h7iLP4wAXr42bHpjzTEk6gttHFb4l/hFiz1YBI88TjiH6hVjnozo/YHA2c51us+Y7g0XoS7653lbUN/EHzvDMuyis4Xi2Ijf1A/OUQfH1iFUWttIgtWK9+fatXoGUS6tirQvrzVh6ZstEp1xbpo1SF6UoVl+fh7tM81qz+Crr/Kroan0UjpZOFTwxPoK6fdLgMAieKSCRmBGpbJHbQ2xxbdykBBrBbdfzIX4CDepfjE9h/40ldw5jRn3e392jrS6htk23N9BWWrpBT5QCk0kH3h/6F1Dm6TkyG9CDtt73/anuRkvXbeygI4wml9bL3rE8CAwEAAaNQME4wHQYDVR0OBBYEFD+Ac7akFxaMhBQAjVfvgGfY8hNKMB8GA1UdIwQYMBaAFD+Ac7akFxaMhBQAjVfvgGfY8hNKMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAC8L9D67CxIhGo5aGVu63WqRHBNOdo/FAGI7LURDFeRmG5nRw/VXzJLGJksh4FSkx7aPrxNWF1uFiDZ80EuYQuIv7bDLblK31ZEbdg1R9LgiZCdYSr464I7yXQY9o6FiNtSKZkQO8EsscJPPy/Zp4uHAnADWACkOUHiCbcKiUUFu66dX0Wr/v53Gekz487GgVRs8HEeT9MU1reBKRgdENR8PNg4rbQfLc3YQKLWK7yWnn/RenjDpuCiePj8N8/80tGgrNgK/6fzM3zI18sSywnXLswxqDb/J+jgVxnQ6MrsTf1urM8MnfcxG/82oHIwfMh/sXPCZpo+DTLkhQxctJ3M=',
      identifierFormat: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
      callbackUrl: 'https://goalsetting.ihatestatistics.com/login/callback',
      acceptedClockSkewMs: -1
    },
    function(profile, done) {
      User.findOne({email: profile.email}).exec(function (err, user) {
        if (err) {
          return done(err);
        } else {
          if (user) {
            console.log('found');
            console.log(user);
            return done(null, user);
          }

          var newUser = new User();
          newUser.firstName = profile['urn:mace:dir:attribute-def:givenName'];
          newUser.lastName = profile['urn:mace:dir:attribute-def:sn'];
          newUser.email = profile['urn:mace:dir:attribute-def:mail'];
          newUser.provider = 'SurfConext';
          newUser.roles = [];
          newUser.roles.push(profile['urn:mace:dir:attribute-def:eduPersonAffiliation']);
          newUser.save(function (err) {
            if (err) {
              return done(err);
            }
            console.log('new');
            console.log(newUser);
            return done(null, newUser);
          });
        }
      });
    }
);

module.exports = function() {
  var samlStrategy = global.SAMLStrategy;

  // Use SAML strategy for Surfconext
  passport.use(samlStrategy);
};<|endoftext|>


<commit_before>module.exports = function(app, settings) {
    /**
     * Map loader, express route middleware.
     */
    function loadMap(req, res, next) {
        if (req.param('mapfile_64')) {
            var Map = require('tilelive.js').Map;
            var map = new Map(req.param('mapfile_64'), settings.mapfile_dir, true);
            map.localize(function() {
                res.map = map.mapnik_map();
                next();
            });
        }
        else {
            next(new Error('Map could not be loaded.'));
        }
    }

    /**
     * @TODO: Implement once node-mapnik exposes layers.
     * Layer loader, express route middleware.
     */
    function loadLayer(req, res, next) {
        if (req.param('layer_64')) {
            next();
        }
        else {
            next(new Error('Layer could not be loaded.'));
        }
    }

    /**
     * @TODO: Implement once node-mapnik exposes layers.
     * Feature loader, express route middleware.
     */
    function loadFeature(req, res, next) {
        if (req.param('feature_64')) {
            next();
        }
        else {
            next(new Error('Feature could not be loaded.'));
        }
    }

    app.get('/status.json', function(req, res) {
        res.send({ status: 'true' });
    });

    /**
     * Inspect abilities.
     */
    app.get('/abilities', function(req, res) {
        mapnik = require('mapnik');
        res.send(
            {
                fonts: mapnik.fonts(),
                datasources: mapnik.datasources()
            }
        );
    });

    /**
     * Inspect fields
     */
    app.get('/:mapfile_64/fields.json', loadMap, function(req, res, next) {
        res.send({});
    });

    /**
     * Inspect data
     */
    app.get('/:mapfile_64/data.json', loadMap, function(req, res, next) {
        res.send({});
    });

    /**
     * Inspect layer
     */
    app.get('/:mapfile_64/:layer_64/layer.json', loadMap, loadLayer, function(req, res, next) {
        res.send({});
    });

    /**
     * Inspect field values
     */
    app.get('/:mapfile_64/:layer_64/:feature_64/values.json', loadMap, loadLayer, loadFeature, function(req, res, next) {
        res.send({});
    });
};
<commit_msg>Inspection layer loader endpoint.<commit_after>var _ = require('underscore')._;

/**
 * Map loader, express route middleware.
 */
function loadMap(req, res, next) {
    if (req.param('mapfile_64')) {
        var path = require('path');
        var Map = require('tilelive.js').Map;
        var map = new Map(req.param('mapfile_64'), path.join(__dirname, settings.mapfile_dir), true);
        map.localize(function() {
            res.map = map.mapnik_map();
            next();
        });
    }
    else {
        next(new Error('Map could not be loaded.'));
    }
}

/**
 * Layer loader, express route middleware.
 */
function loadLayer(req, res, next) {
    res.layers = [];
    var layers = res.map.layers();
    var data = res.map.describe_data();
    for (var i = 0; i < layers.length; i++) {
        var layer = {
            id: layers[i].datasource.id,
        };
        if (data[layer.id]) {
            _.extend(layer, data[layer.id]);
        }
        if (layer.fields) {
            for (var field in layer.fields) {
                layer.fields[field] = {
                    type: layer.fields[field],
                    values: [],
                };
            }
            var values = res.map.features(i);
            for (var j = 0; j < values.length; j++) {
                for (var field in values[j]) {
                    var layerValues = layer.fields[field].values;
                    var fieldValue = values[j][field];
                    if (
                        _.indexOf(layerValues, fieldValue)  === -1 &&
                        fieldValue !== ''
                    ) {
                        layerValues.push(fieldValue);
                    }
                }
            }
            for (var field in layer.fields) {
                if (layer.fields[field].values.length) {
                    if (layer.fields[field].type === 'Number') {
                        layer.fields[field].min = _.min(
                            layer.fields[field].values,
                            function(object) { return object; }
                        );
                        layer.fields[field].max = _.max(
                            layer.fields[field].values,
                            function(object) { return object; }
                        );
                    }
                    else if (layer.fields[field].type === 'String') {
                        layer.fields[field].min = _.min(
                            layer.fields[field].values,
                            function(object) { return object.length; }
                        );
                        layer.fields[field].max = _.max(
                            layer.fields[field].values,
                            function(object) { return object.length; }
                        );
                    }
                }
            }
        }

        if (!req.param('layer_id')) {
            res.layers.push(layer);
        }
        else if (req.param('layer_id') === layer.id) {
            res.layers.push(layer);
        }
    }
    if (req.param('layer_id') && res.layers.length === 0) {
        next(new Error('Layer could not be loaded.'));
    }
    next();
}

module.exports = function(app, settings) {
    /**
     * Inspect abilities.
     */
    app.get('/abilities', function(req, res) {
        var mapnik = require('mapnik');
        res.send(
            {
                fonts: mapnik.fonts(),
                datasources: mapnik.datasources()
            }
        );
    });

    /**
     * Load layer model.
     */
    app.get('/:mapfile_64/:layer_id?', loadMap, loadLayer, function(req, res, next) {
        if (req.param('layer_id')) {
            res.send(res.layers.pop());
        }
        else {
            res.send(res.layers);
        }
    });

    /**
     * @TODO datasource SRS autodetection endpoint.
     */
    /*
    app.get('/:datasource_64', loadDatasource, function(req, res, next) {
        res.send({});
    });
    */
};
<|endoftext|>


<commit_before>// var uwaterlooapi = require('uwaterloo-api');

angular.module('MyApp')
  .controller('homeCtrl', function ($scope, $auth, $http, $rootScope) {
    $scope.isEmptyCourse = true;
    $scope.courseInfo = {
      subject: 'Subject',
      catalog_number: 000
    }
    $scope.addCourse = function (subject, number) {
      var data = {
        'course_subject' : subject,
        'course_number' : number
      }
      $http.post('/courses', data)
      .then(
        function success(response) {
          $scope.goToCourse(subject, number)
        },
        function error(response) {
          console.log(response);
        }
      )
    }
    $scope.goToCourse = function (subject, number) {
      $scope.isEmptyCourse = false;
      $http.get('/courses' + subject + '/' + number)
      .then(
        function success(response) {
          // console.log(response.data);
          $scope.courseInfo = response.data;
        },
        function error(response) {
          console.log(response.message);
        }
      )
      $http.get('courses/' + subject + '/' + number + '/exams').then(
        function success(response) {
          $scope.examschedules = response.data.sections;
          // console.log($scope.examschedules);
        },
        function err(response) {
          console.log(response.message);
        }
      );
    }
    /*
    $scope.groups = [
      {
        id: 1,
        name: "124 section 002",
        course_name: "ECE 124",
        course_id: "013168",
        member_num: "4"
      },
      {
        id: 2,
        name: "106 section 002",
        course_name: "ECE 106",
        course_id: "013167",
        member_num: "10"
      },
      {
        id: 3,
        name: "155 lab 125",
        course_name: "ECE 155",
        course_id: "013170",
        member_num: "3"
      },
      {
        id: 4,
        name: "ELPE general",
        course_name: "EMLS 129r",
        course_id: "121132",
        member_num: "3"
      }
    ];*/

    $scope.disableTagButton = {'visibility': 'hidden'};

    var refresh = function(){
      $http.get('/getMes').success(function (res) {
        //console.log("I got requested data!");
        $scope.messages = res;
        $scope.mesToSend = "";
        //console.log($scope.messages);
      });
    };

    refresh();

    $scope.sendMessage = function(){
      var erroMsg = document.getElementById('erroMsg');
      if($scope.mesToSend == ""){
        $scope.disableTagButton = {'visibility': 'visible'};
        return;
      }
      $scope.disableTagButton = {'visibility': 'hidden'};
      var date = new Date();
      $scope.mesToSend.user = $rootScope.currentUser.name;
      $scope.mesToSend.time = date;
      console.log($scope.mesToSend);
      $http.post('/send', $scope.mesToSend).success(function(res){
        console.log(res);
        refresh();
      });
    }
  });
<commit_msg>no last commit for esports<commit_after>// var uwaterlooapi = require('uwaterloo-api');

angular.module('MyApp')
  .controller('homeCtrl', function ($scope, $auth, $http, $rootScope) {
    // Get auth status
    $scope.isAuthenticated = function() {
      return $auth.isAuthenticated();
    };

    $scope.isEmptyCourse = true;
    $scope.courseInfo = {
      subject: 'Subject',
      catalog_number: 000
    }
    $scope.addCourse = function (subject, number) {
      var data = {
        'course_subject' : subject,
        'course_number' : number
      }
      $http.post('/courses', data)
      .then(
        function success(response) {
          $scope.goToCourse(subject, number)
        },
        function error(response) {
          console.log(response);
        }
      )
    }
    $scope.goToCourse = function (subject, number) {
      $scope.isEmptyCourse = false;
      $http.get('/courses' + subject + '/' + number)
      .then(
        function success(response) {
          // console.log(response.data);
          $scope.courseInfo = response.data;
        },
        function error(response) {
          console.log(response.message);
        }
      )
      $http.get('courses/' + subject + '/' + number + '/exams').then(
        function success(response) {
          $scope.examschedules = response.data.sections;
          // console.log($scope.examschedules);
        },
        function err(response) {
          console.log(response.message);
        }
      );
    }
    /*
    $scope.groups = [
      {
        id: 1,
        name: "124 section 002",
        course_name: "ECE 124",
        course_id: "013168",
        member_num: "4"
      },
      {
        id: 2,
        name: "106 section 002",
        course_name: "ECE 106",
        course_id: "013167",
        member_num: "10"
      },
      {
        id: 3,
        name: "155 lab 125",
        course_name: "ECE 155",
        course_id: "013170",
        member_num: "3"
      },
      {
        id: 4,
        name: "ELPE general",
        course_name: "EMLS 129r",
        course_id: "121132",
        member_num: "3"
      }
    ];*/

    $scope.disableTagButton = {'visibility': 'hidden'};

    var refresh = function(){
      $http.get('/getMes').success(function (res) {
        //console.log("I got requested data!");
        $scope.messages = res;
        $scope.mesToSend = "";
        //console.log($scope.messages);
      });
    };

    refresh();

    $scope.sendMessage = function(){
      var erroMsg = document.getElementById('erroMsg');
      if($scope.mesToSend == ""){
        $scope.disableTagButton = {'visibility': 'visible'};
        return;
      }
      $scope.disableTagButton = {'visibility': 'hidden'};
      var date = new Date();
      $scope.mesToSend.user = $rootScope.currentUser.name;
      $scope.mesToSend.time = date;
      console.log($scope.mesToSend);
      $http.post('/send', $scope.mesToSend).success(function(res){
        console.log(res);
        refresh();
      });
    }
  });
<|endoftext|>


<commit_before>$(document).ready(function () {

	var map,
		infowindow,
		myLocation,
		map,
		marker,
		mapBlock = $('#map')[0],
		input = document.getElementById("pac-input");

	var url = window.location.hash;
	var hash = url.substring(url.indexOf("#")+1);

	//Check for Browser support
	if (navigator.geolocation) {
		navigator.geolocation.getCurrentPosition(function (position) {
			myLocation = {
				lat: position.coords.latitude,
				lng: position.coords.longitude
			};
			embedMap(myLocation);
		});
	} else {
		mapBlock.text('Your browser is out of fashion, there\'s no geolocation!');
	};

	//Embed map
	function embedMap(latlng) {
		console.log(latlng);

		map = new google.maps.Map(mapBlock, {
			center: latlng,
			zoom: 20
		});

		infowindow = new google.maps.InfoWindow();
		var marker = new google.maps.Marker({
		    map: map,
		    anchorPoint: new google.maps.Point(0, -29)
		  });

		var service = new google.maps.places.PlacesService(map);
		service.nearbySearch({
			location: latlng,
			radius: 500,
			types: [hash]
		}, callback);

		//map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
		var autocomplete = new google.maps.places.Autocomplete(input);
  		autocomplete.bindTo('bounds', map);

  		autocomplete.addListener('place_changed', function() {
  			infowindow.close();
  			marker.setVisible(false);

  			var place = autocomplete.getPlace();
		    if (!place.geometry) {
		      window.alert("Autocomplete's returned place contains no geometry");
		      return;
		    }

		    // If the place has a geometry, then present it on a map.
		    if (place.geometry.viewport) {
		      map.fitBounds(place.geometry.viewport);
		    } else {
		      map.setCenter(place.geometry.location);
		      map.setZoom(17);  // Why 17? Because it looks good.
		    }
		    marker.setIcon(/** @type {google.maps.Icon} */({
		      url: place.icon,
		      size: new google.maps.Size(71, 71),
		      origin: new google.maps.Point(0, 0),
		      anchor: new google.maps.Point(17, 34),
		      scaledSize: new google.maps.Size(35, 35)
		    }));
		    marker.setPosition(place.geometry.location);
		    marker.setVisible(true);

		    var address = '';
		    if (place.address_components) {
		      address = [
		        (place.address_components[0] && place.address_components[0].short_name || ''),
		        (place.address_components[1] && place.address_components[1].short_name || ''),
		        (place.address_components[2] && place.address_components[2].short_name || '')
		      ].join(' ');
		    }

		    infowindow.setContent('
' + place.name + '
' + address);
		    infowindow.open(map, marker);
  		})

	};

	function callback(results, status) {
		if (status === google.maps.places.PlacesServiceStatus.OK) {
			for (var i = 0; i < results.length; i++) {
				createMarker(results[i]);
			}
		}
	}

	function createMarker(place) {
		var placeLoc = place.geometry.location;
		var marker = new google.maps.Marker({
			map: map,
			position: place.geometry.location,
			animation: google.maps.Animation.DROP
		});

		google.maps.event.addListener(marker, 'click', function () {
			infowindow.setContent(place.name);
			infowindow.open(map, this);
		});
	}

});
<commit_msg>Update mapapp.js<commit_after>$(document).ready(function () {

	var map,
		infowindow,
		myLocation,
		map,
		marker,
		mapBlock = $('#map')[0],
		input = document.getElementById("pac-input");

	var url = window.location.hash;
	var hash = url.substring(url.indexOf("#")+1);

	//Check for Browser support
	if (navigator.geolocation) {
		navigator.geolocation.getCurrentPosition(function (position) {
			myLocation = {
				lat: position.coords.latitude,
				lng: position.coords.longitude
			};
			embedMap(myLocation);
		});
	} else {
		mapBlock.text('Your browser is out of fashion, there\'s no geolocation!');
	};

	//Embed map
	function embedMap(latlng) {
		console.log(latlng);

		map = new google.maps.Map(mapBlock, {
			center: latlng,
			zoom: 15
		});

		infowindow = new google.maps.InfoWindow();
		var marker = new google.maps.Marker({
		    map: map,
		    anchorPoint: new google.maps.Point(0, -29)
		  });

		var service = new google.maps.places.PlacesService(map);
		service.nearbySearch({
			location: latlng,
			radius: 500,
			types: [hash]
		}, callback);

		//map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
		var autocomplete = new google.maps.places.Autocomplete(input);
  		autocomplete.bindTo('bounds', map);

  		autocomplete.addListener('place_changed', function() {
  			infowindow.close();
  			marker.setVisible(false);

  			var place = autocomplete.getPlace();
		    if (!place.geometry) {
		      window.alert("Autocomplete's returned place contains no geometry");
		      return;
		    }

		    // If the place has a geometry, then present it on a map.
		    if (place.geometry.viewport) {
		      map.fitBounds(place.geometry.viewport);
		    } else {
		      map.setCenter(place.geometry.location);
		      map.setZoom(17);  // Why 17? Because it looks good.
		    }
		    marker.setIcon(/** @type {google.maps.Icon} */({
		      url: place.icon,
		      size: new google.maps.Size(71, 71),
		      origin: new google.maps.Point(0, 0),
		      anchor: new google.maps.Point(17, 34),
		      scaledSize: new google.maps.Size(35, 35)
		    }));
		    marker.setPosition(place.geometry.location);
		    marker.setVisible(true);

		    var address = '';
		    if (place.address_components) {
		      address = [
		        (place.address_components[0] && place.address_components[0].short_name || ''),
		        (place.address_components[1] && place.address_components[1].short_name || ''),
		        (place.address_components[2] && place.address_components[2].short_name || '')
		      ].join(' ');
		    }

		    infowindow.setContent('
' + place.name + '
' + address);
		    infowindow.open(map, marker);
  		})

	};

	function callback(results, status) {
		if (status === google.maps.places.PlacesServiceStatus.OK) {
			for (var i = 0; i < results.length; i++) {
				createMarker(results[i]);
			}
		}
	}

	function createMarker(place) {
		var placeLoc = place.geometry.location;
		var marker = new google.maps.Marker({
			map: map,
			position: place.geometry.location,
			animation: google.maps.Animation.DROP
		});

		google.maps.event.addListener(marker, 'click', function () {
			infowindow.setContent(place.name);
			infowindow.open(map, this);
		});
	}

});
<|endoftext|>


<commit_before>import Ember from 'ember';
import layout from '../templates/components/power-select-with-fallback';
import isIos from '../utils/is-ios';
import isAndroid from '../utils/is-android';
import isWindowsPhone from '../utils/is-windows-phone';
import isMobile from '../utils/is-mobile';

const { get, computed } = Ember;

export default Ember.Component.extend({
  layout,
  tagName: '',

  // CPs
  mustFallback: computed('fallback-when', function() {
    let fallbackStrategy = this.get('fallback-when');
    switch(fallbackStrategy) {
      case 'mobile':
        return isMobile();
      case 'ios':
        return isIos();
      case 'android':
        return isAndroid();
      case 'windows-phone':
        return isWindowsPhone();
      case undefined:
        return false;
      case null:
        return false;
      default:
        throw new Error(`Unknown fallback strategy ${fallbackStrategy}`);
    }
  }),

  // Actions
  actions: {
    handleChange(e) {
      let val = e.target.value;
      let selected;
      if (val.indexOf('.') > -1) {
        let [indexStr, subindexStr] = val.split('.');
        let index = parseInt(indexStr, 10);
        let subindex = parseInt(subindexStr, 10);
        let group = Ember.A(this.get('options')).objectAt(index);
        selected = Ember.A(get(group, 'options')).objectAt(subindex);
      } else {
        let index = parseInt(val, 10);
        selected = Ember.A(this.get('options')).objectAt(index);
      }
      this.get('onchange')(selected, null); // Public API is not passed
    }
  }
});
<commit_msg>Allow passing undefined `mustFallback` without overwriting default CP<commit_after>import Ember from 'ember';
import layout from '../templates/components/power-select-with-fallback';
import isIos from '../utils/is-ios';
import isAndroid from '../utils/is-android';
import isWindowsPhone from '../utils/is-windows-phone';
import isMobile from '../utils/is-mobile';

const { get, computed } = Ember;

export default Ember.Component.extend({
  layout,
  tagName: '',

  // CPs
  mustFallback: computed('fallback-when', {
    get() {
      let fallbackStrategy = this.get('fallback-when');
      switch(fallbackStrategy) {
        case 'mobile':
          return isMobile();
        case 'ios':
          return isIos();
        case 'android':
          return isAndroid();
        case 'windows-phone':
          return isWindowsPhone();
        case undefined:
          return false;
        case null:
          return false;
        default:
          throw new Error(`Unknown fallback strategy ${fallbackStrategy}`);
      }
    },
    set(_, v) {
      return v === undefined ? get(this, 'mustFallback') : v;
    }
  }),

  // Actions
  actions: {
    handleChange(e) {
      let val = e.target.value;
      let selected;
      if (val.indexOf('.') > -1) {
        let [indexStr, subindexStr] = val.split('.');
        let index = parseInt(indexStr, 10);
        let subindex = parseInt(subindexStr, 10);
        let group = Ember.A(this.get('options')).objectAt(index);
        selected = Ember.A(get(group, 'options')).objectAt(subindex);
      } else {
        let index = parseInt(val, 10);
        selected = Ember.A(this.get('options')).objectAt(index);
      }
      this.get('onchange')(selected, null); // Public API is not passed
    }
  }
});
<|endoftext|>


<commit_before>//
// To do: make all tests pass, leave the asserts unchanged!
// Follow the hints of the failure messages!

describe('Type conversion - to number', () => {
  it('`undefined` converts to `NaN`', () => {
    //// const toNumber = undefined;
    const toNumber = +undefined;
    assert(isNaN(toNumber));
  });
  it('`null` converts to `+0`', () => {
    //// const toNumber = null;
    const toNumber = +null;
    assert.deepEqual(toNumber, +0);
  });
});
<commit_msg>Fixes thanks to @shinenelson.<commit_after>//
// To do: make all tests pass, leave the asserts unchanged!
// Follow the hints of the failure messages!

describe('Type conversion - to number', () => {
  it('`undefined` converts to `NaN`', () => {
    //// const toNumber = Number(0);
    const toNumber = Number(undefined);
    assert(isNaN(toNumber));
  });
  it('`null` converts to `+0`', () => {
    //// const toNumber = null;
    const toNumber = Number(null);
    assert.equal(toNumber, +0);
  });
});
<|endoftext|>


<commit_before>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt

frappe.provide("erpnext.bom");

frappe.ui.form.on("BOM", {
	onload_post_render: function(frm) {
		frm.get_field("items").grid.set_multiple_add("item_code", "qty");
	},
	refresh: function(frm) {
		frm.toggle_enable("item", frm.doc.__islocal);
		toggle_operations(frm);

		if (!frm.doc.__islocal && frm.doc.docstatus<2) {
			frm.add_custom_button(__("Update Cost"), function() {
				frm.events.update_cost(frm);
			});
			frm.add_custom_button(__("Browse BOM"), function() {
				frappe.set_route("bom-browser", frm.doc.name);
			});
		}
	},
	update_cost: function(frm) {
		return frappe.call({
			doc: frm.doc,
			method: "update_cost",
			freeze: true,
			callback: function(r) {
				if(!r.exc) frm.refresh_fields();
			}
		})
	}
});

cur_frm.add_fetch("item", "description", "description");
cur_frm.add_fetch("item", "image", "image");
cur_frm.add_fetch("item", "item_name", "item_name");
cur_frm.add_fetch("item", "stock_uom", "uom");

cur_frm.cscript.hour_rate = function(doc, dt, dn) {
	erpnext.bom.calculate_op_cost(doc);
	erpnext.bom.calculate_total(doc);
}

cur_frm.cscript.time_in_mins = cur_frm.cscript.hour_rate;

cur_frm.cscript.item_code = function(doc, cdt, cdn) {
	get_bom_material_detail(doc, cdt, cdn);
}

cur_frm.cscript.bom_no	= function(doc, cdt, cdn) {
	get_bom_material_detail(doc, cdt, cdn);
}

cur_frm.cscript.is_default = function(doc) {
	if (doc.is_default) cur_frm.set_value("is_active", 1);
}

var get_bom_material_detail= function(doc, cdt, cdn) {
	var d = locals[cdt][cdn];
	if (d.item_code) {
		return frappe.call({
			doc: cur_frm.doc,
			method: "get_bom_material_detail",
			args: {
				'item_code': d.item_code,
				'bom_no': d.bom_no != null ? d.bom_no: '',
				'qty': d.qty
			},
			callback: function(r) {
				d = locals[cdt][cdn];
				$.extend(d, r.message);
				refresh_field("items");
				doc = locals[doc.doctype][doc.name];
				erpnext.bom.calculate_rm_cost(doc);
				erpnext.bom.calculate_total(doc);
			},
			freeze: true
		});
	}
}

cur_frm.cscript.qty = function(doc, cdt, cdn) {
	erpnext.bom.calculate_rm_cost(doc);
	erpnext.bom.calculate_total(doc);
}

cur_frm.cscript.rate = function(doc, cdt, cdn) {
	var d = locals[cdt][cdn];
	if (d.bom_no) {
		msgprint(__("You can not change rate if BOM mentioned agianst any item"));
		get_bom_material_detail(doc, cdt, cdn);
	} else {
		erpnext.bom.calculate_rm_cost(doc);
		erpnext.bom.calculate_total(doc);
	}
}

erpnext.bom.calculate_op_cost = function(doc) {
	var op = doc.operations || [];
	doc.operating_cost = 0.0;
	for(var i=0;i<op.length;i++) {
		operating_cost = flt(flt(op[i].hour_rate) * flt(op[i].time_in_mins) / 60, 2);
		frappe.model.set_value('BOM Operation',op[i].name, "operating_cost", operating_cost);

		doc.operating_cost += operating_cost;
	}
	refresh_field('operating_cost');
}

erpnext.bom.calculate_rm_cost = function(doc) {
	var rm = doc.items || [];
	total_rm_cost = 0;
	for(var i=0;i<rm.length;i++) {
		amt =	flt(rm[i].rate) * flt(rm[i].qty);
		set_multiple('BOM Item',rm[i].name, {'amount': amt}, 'items');
		set_multiple('BOM Item',rm[i].name,
			{'qty_consumed_per_unit': flt(rm[i].qty)/flt(doc.quantity)}, 'items');
		total_rm_cost += amt;
	}
	cur_frm.set_value("raw_material_cost", total_rm_cost);
}

// Calculate Total Cost
erpnext.bom.calculate_total = function(doc) {
	total_cost = flt(doc.operating_cost) + flt(doc.raw_material_cost);
	frappe.model.set_value(doc.doctype, doc.name, "total_cost", total_cost);
}

cur_frm.fields_dict['item'].get_query = function(doc) {
 	return{
		query: "erpnext.controllers.queries.item_query"
	}
}

cur_frm.fields_dict['project_name'].get_query = function(doc, dt, dn) {
	return{
		filters:[
			['Project', 'status', 'not in', 'Completed, Cancelled']
		]
	}
}

cur_frm.fields_dict['items'].grid.get_field('item_code').get_query = function(doc) {
	return{
		query: "erpnext.controllers.queries.item_query",
		filters: {
			"name": "!" + cstr(doc.item)
		}
	}
}

cur_frm.fields_dict['items'].grid.get_field('bom_no').get_query = function(doc, cdt, cdn) {
	var d = locals[cdt][cdn];
	return{
		filters:{
			'item': d.item_code,
			'is_active': 1,
			'docstatus': 1
		}
	}
}

cur_frm.cscript.validate = function(doc, dt, dn) {
	erpnext.bom.calculate_op_cost(doc);
	erpnext.bom.calculate_rm_cost(doc);
	erpnext.bom.calculate_total(doc);
}

frappe.ui.form.on("BOM Operation", "operation", function(frm, cdt, cdn) {
	var d = locals[cdt][cdn];

	if(!d.operation) return;

	frappe.call({
		"method": "frappe.client.get",
		args: {
			doctype: "Operation",
			name: d.operation
		},
		callback: function (data) {
			if(data.message.description) {
				frappe.model.set_value(d.doctype, d.name, "description", data.message.description);
			}
			if(data.message.workstation) {
				frappe.model.set_value(d.doctype, d.name, "workstation", data.message.workstation);
			}
		}
	})
});

frappe.ui.form.on("BOM Operation", "workstation", function(frm, cdt, cdn) {
	var d = locals[cdt][cdn];

	frappe.call({
		"method": "frappe.client.get",
		args: {
			doctype: "Workstation",
			name: d.workstation
		},
		callback: function (data) {
			frappe.model.set_value(d.doctype, d.name, "hour_rate", data.message.hour_rate);
			erpnext.bom.calculate_op_cost(frm.doc);
			erpnext.bom.calculate_total(frm.doc);
		}
	})
});

frappe.ui.form.on("BOM Operation", "operations_remove", function(frm) {
	erpnext.bom.calculate_op_cost(frm.doc);
	erpnext.bom.calculate_total(frm.doc);
});

frappe.ui.form.on("BOM Item", "items_remove", function(frm) {
	erpnext.bom.calculate_rm_cost(frm.doc);
	erpnext.bom.calculate_total(frm.doc);
});

var toggle_operations = function(frm) {
	frm.toggle_display("operations_section", cint(frm.doc.with_operations) == 1);
}

frappe.ui.form.on("BOM", "with_operations", function(frm) {
	if(!cint(frm.doc.with_operations)) {
		frm.set_value("operations", []);
	}
	toggle_operations(frm);
});

cur_frm.cscript.image = function() {
	refresh_field("image_view");
}

<commit_msg>[fix] bom client script<commit_after>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt

frappe.provide("erpnext.bom");

frappe.ui.form.on("BOM", {
	onload_post_render: function(frm) {
		frm.get_field("items").grid.set_multiple_add("item_code", "qty");
	},
	refresh: function(frm) {
		frm.toggle_enable("item", frm.doc.__islocal);
		toggle_operations(frm);

		if (!frm.doc.__islocal && frm.doc.docstatus<2) {
			frm.add_custom_button(__("Update Cost"), function() {
				frm.events.update_cost(frm);
			});
			frm.add_custom_button(__("Browse BOM"), function() {
				frappe.set_route("bom-browser", frm.doc.name);
			});
		}
	},
	update_cost: function(frm) {
		return frappe.call({
			doc: frm.doc,
			method: "update_cost",
			freeze: true,
			callback: function(r) {
				if(!r.exc) frm.refresh_fields();
			}
		})
	}
});

cur_frm.add_fetch("item", "description", "description");
cur_frm.add_fetch("item", "image", "image");
cur_frm.add_fetch("item", "item_name", "item_name");
cur_frm.add_fetch("item", "stock_uom", "uom");

cur_frm.cscript.hour_rate = function(doc, dt, dn) {
	erpnext.bom.calculate_op_cost(doc);
	erpnext.bom.calculate_total(doc);
}

cur_frm.cscript.time_in_mins = cur_frm.cscript.hour_rate;

cur_frm.cscript.item_code = function(doc, cdt, cdn) {
	get_bom_material_detail(doc, cdt, cdn);
}

cur_frm.cscript.bom_no	= function(doc, cdt, cdn) {
	get_bom_material_detail(doc, cdt, cdn);
}

cur_frm.cscript.is_default = function(doc) {
	if (doc.is_default) cur_frm.set_value("is_active", 1);
}

var get_bom_material_detail= function(doc, cdt, cdn) {
	var d = locals[cdt][cdn];
	if (d.item_code) {
		return frappe.call({
			doc: doc,
			method: "get_bom_material_detail",
			args: {
				'item_code': d.item_code,
				'bom_no': d.bom_no != null ? d.bom_no: '',
				'qty': d.qty
			},
			callback: function(r) {
				d = locals[cdt][cdn];
				$.extend(d, r.message);
				refresh_field("items");
				doc = locals[doc.doctype][doc.name];
				erpnext.bom.calculate_rm_cost(doc);
				erpnext.bom.calculate_total(doc);
			},
			freeze: true
		});
	}
}

cur_frm.cscript.qty = function(doc, cdt, cdn) {
	erpnext.bom.calculate_rm_cost(doc);
	erpnext.bom.calculate_total(doc);
}

cur_frm.cscript.rate = function(doc, cdt, cdn) {
	var d = locals[cdt][cdn];
	if (d.bom_no) {
		msgprint(__("You can not change rate if BOM mentioned agianst any item"));
		get_bom_material_detail(doc, cdt, cdn);
	} else {
		erpnext.bom.calculate_rm_cost(doc);
		erpnext.bom.calculate_total(doc);
	}
}

erpnext.bom.calculate_op_cost = function(doc) {
	var op = doc.operations || [];
	doc.operating_cost = 0.0;
	for(var i=0;i<op.length;i++) {
		operating_cost = flt(flt(op[i].hour_rate) * flt(op[i].time_in_mins) / 60, 2);
		frappe.model.set_value('BOM Operation',op[i].name, "operating_cost", operating_cost);

		doc.operating_cost += operating_cost;
	}
	refresh_field('operating_cost');
}

erpnext.bom.calculate_rm_cost = function(doc) {
	var rm = doc.items || [];
	total_rm_cost = 0;
	for(var i=0;i<rm.length;i++) {
		amt =	flt(rm[i].rate) * flt(rm[i].qty);
		set_multiple('BOM Item',rm[i].name, {'amount': amt}, 'items');
		set_multiple('BOM Item',rm[i].name,
			{'qty_consumed_per_unit': flt(rm[i].qty)/flt(doc.quantity)}, 'items');
		total_rm_cost += amt;
	}
	cur_frm.set_value("raw_material_cost", total_rm_cost);
}

// Calculate Total Cost
erpnext.bom.calculate_total = function(doc) {
	total_cost = flt(doc.operating_cost) + flt(doc.raw_material_cost);
	frappe.model.set_value(doc.doctype, doc.name, "total_cost", total_cost);
}

cur_frm.fields_dict['item'].get_query = function(doc) {
 	return{
		query: "erpnext.controllers.queries.item_query"
	}
}

cur_frm.fields_dict['project_name'].get_query = function(doc, dt, dn) {
	return{
		filters:[
			['Project', 'status', 'not in', 'Completed, Cancelled']
		]
	}
}

cur_frm.fields_dict['items'].grid.get_field('item_code').get_query = function(doc) {
	return{
		query: "erpnext.controllers.queries.item_query",
		filters: {
			"name": "!" + cstr(doc.item)
		}
	}
}

cur_frm.fields_dict['items'].grid.get_field('bom_no').get_query = function(doc, cdt, cdn) {
	var d = locals[cdt][cdn];
	return{
		filters:{
			'item': d.item_code,
			'is_active': 1,
			'docstatus': 1
		}
	}
}

cur_frm.cscript.validate = function(doc, dt, dn) {
	erpnext.bom.calculate_op_cost(doc);
	erpnext.bom.calculate_rm_cost(doc);
	erpnext.bom.calculate_total(doc);
}

frappe.ui.form.on("BOM Operation", "operation", function(frm, cdt, cdn) {
	var d = locals[cdt][cdn];

	if(!d.operation) return;

	frappe.call({
		"method": "frappe.client.get",
		args: {
			doctype: "Operation",
			name: d.operation
		},
		callback: function (data) {
			if(data.message.description) {
				frappe.model.set_value(d.doctype, d.name, "description", data.message.description);
			}
			if(data.message.workstation) {
				frappe.model.set_value(d.doctype, d.name, "workstation", data.message.workstation);
			}
		}
	})
});

frappe.ui.form.on("BOM Operation", "workstation", function(frm, cdt, cdn) {
	var d = locals[cdt][cdn];

	frappe.call({
		"method": "frappe.client.get",
		args: {
			doctype: "Workstation",
			name: d.workstation
		},
		callback: function (data) {
			frappe.model.set_value(d.doctype, d.name, "hour_rate", data.message.hour_rate);
			erpnext.bom.calculate_op_cost(frm.doc);
			erpnext.bom.calculate_total(frm.doc);
		}
	})
});

frappe.ui.form.on("BOM Operation", "operations_remove", function(frm) {
	erpnext.bom.calculate_op_cost(frm.doc);
	erpnext.bom.calculate_total(frm.doc);
});

frappe.ui.form.on("BOM Item", "items_remove", function(frm) {
	erpnext.bom.calculate_rm_cost(frm.doc);
	erpnext.bom.calculate_total(frm.doc);
});

var toggle_operations = function(frm) {
	frm.toggle_display("operations_section", cint(frm.doc.with_operations) == 1);
}

frappe.ui.form.on("BOM", "with_operations", function(frm) {
	if(!cint(frm.doc.with_operations)) {
		frm.set_value("operations", []);
	}
	toggle_operations(frm);
});

cur_frm.cscript.image = function() {
	refresh_field("image_view");
}
<|endoftext|>