<commit_before>import PropTypes from 'prop-types';
import React from 'react';
import { FormattedMessage, injectIntl } from 'react-intl';
import { connect } from 'react-redux';
import MenuItem from '@material-ui/core/MenuItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import { fetchQuerySplitStoryCount, fetchDemoQuerySplitStoryCount, resetSentenceCounts } from '../../../actions/explorerActions';
import withSummary from '../../common/hocs/SummarizedVizualization';
import { DownloadButton } from '../../common/IconButton';
import AppButton from '../../common/AppButton';
import ActionMenu from '../../common/ActionMenu';
import BubbleRowChart from '../../vis/BubbleRowChart';
import { queryChangedEnoughToUpdate, postToDownloadUrl, ensureSafeResults } from '../../../lib/explorerUtil';
import messages from '../../../resources/messages';
import { FETCH_INVALID } from '../../../lib/fetchConstants';
import withQueryResults from './QueryResultsSelector';

const BUBBLE_CHART_DOM_ID = 'bubble-chart-story-total';

const localMessages = {
  title: { id: 'explorer.storyCount.title', defaultMessage: 'Total Attention' },
  helpIntro: { id: 'explorer.storyCount.help.into',
    defaultMessage: '
Compare the total number of stories where at least one sentence matched each of your queries.  Rollover the circles to see the exact numbers, or click the menu in the bottom right to download the data.
',
  },
  helpDetails: { id: 'explorer.storyCount.help.details',
    defaultMessage: '
It is harder to determine how much of the media\'s attention your search got. If you want to dig into that, a good place to start is comparing your query to a search for everything from the sources and collections you are searching.  You can do this by searching for * in the same date range and media; that matches every story.
',
  },
  downloadOneCsv: { id: 'explorer.attention.total.downloadCsv', defaultMessage: 'Download all story URLs' },
  downloadCsv: { id: 'explorer.attention.total.downloadCsv', defaultMessage: 'Download all story URLs for {name}' },
  viewNormalized: { id: 'explorer.attention.mode.viewNormalized', defaultMessage: 'View by Story Count (default)' },
  viewRegular: { id: 'explorer.attention.mode.viewRegular', defaultMessage: 'View by Story Percentage' },
};

const VIEW_NORMALIZED = 'VIEW_NORMALIZED';
const VIEW_REGULAR = 'VIEW_REGULAR';
const DOWNLOAD_PATH = '/api/explorer/stories/all-story-urls.csv';

class QueryTotalAttentionResultsContainer extends React.Component {
  state = {
    view: VIEW_REGULAR, // which view to show (see view constants above)
  }

  shouldComponentUpdate(nextProps, nextState) {
    const { results, queries } = this.props;
    return queryChangedEnoughToUpdate(queries, nextProps.queries, results, nextProps.results)
    || (this.state.view !== nextState.view);
  }

  setView = (nextView) => {
    this.setState({ view: nextView });
  }

  downloadCsv = (query) => {
    postToDownloadUrl(DOWNLOAD_PATH, query);
  }

  render() {
    const { results, queries, selectedQuery } = this.props;
    const { formatNumber, formatMessage } = this.props.intl;
    let content = null;

    const safeResults = ensureSafeResults(queries, results);
    if (safeResults) {
      let bubbleData = [];
      bubbleData = safeResults.map((query, idx) => {
        const value = (this.state.view === VIEW_REGULAR) ? query.results.total : query.results.ratio;
        let centerText;
        if (this.state.view === VIEW_REGULAR) {
          centerText = formatNumber(value);
        } else {
          centerText = formatNumber(value, { style: 'percent', maximumFractionDigits: 2 });
        }
        const rolloverText = `${query.label}: ${centerText}`;
        return {
          value,
          aboveText: (idx % 2 === 0) ? query.label : null,
          belowText: (idx % 2 !== 0) ? query.label : null,
          centerText,
          rolloverText,
          centerTextColor: '#FFFFFF',
          fill: query.color,
        };
      });
      let downloadOptimizer = null;
      if (queries.length === 1) {
        downloadOptimizer = (
          <AppButton
            variant="text"
            className="action-menu-single-download"
            onClick={() => this.downloadCsv(selectedQuery)}
            aria-controls="action-menu"
            aria-haspopup="true"
            aria-owns="action-menu"
            label={formatMessage(localMessages.downloadCsv, { name: selectedQuery.label })}
            size="small"
          />
        );
      } else {
        downloadOptimizer = (
          <ActionMenu actionTextMsg={messages.downloadOptions}>
            {queries.map((q, idx) => (
              <MenuItem
                className="action-icon-menu-item"
                onClick={() => this.downloadCsv(q)}
                key={idx}
              >
                <ListItemText>
                  <FormattedMessage {...localMessages.downloadCsv} values={{ name: q.label }} />
                </ListItemText>
                <ListItemIcon>
                  <DownloadButton />
                </ListItemIcon>
              </MenuItem>
            ))}
          </ActionMenu>
        );
      }
      content = (

          <BubbleRowChart
            data={bubbleData}
            padding={0}
            domId={BUBBLE_CHART_DOM_ID}
            width={650}
          />

            {downloadOptimizer}
            <ActionMenu actionTextMsg={messages.viewOptions}>
              <MenuItem
                className="action-icon-menu-item"
                disabled={this.state.view === VIEW_REGULAR}
                onClick={() => this.setView(VIEW_REGULAR)}
              >
                <ListItemText>
                  <FormattedMessage {...localMessages.viewNormalized} />
                </ListItemText>
              </MenuItem>
              <MenuItem
                className="action-icon-menu-item"
                disabled={this.state.view === VIEW_NORMALIZED}
                onClick={() => this.setView(VIEW_NORMALIZED)}
              >
                <ListItemText>
                  <FormattedMessage {...localMessages.viewRegular} />
                </ListItemText>
              </MenuItem>
            </ActionMenu>

      );
    }
    return (content);
  }
}

QueryTotalAttentionResultsContainer.propTypes = {
  // from parent
  lastSearchTime: PropTypes.number.isRequired,
  queries: PropTypes.array.isRequired,
  isLoggedIn: PropTypes.bool.isRequired,
  selectedQuery: PropTypes.object.isRequired,
  // from composition
  intl: PropTypes.object.isRequired,
  // from dispatch
  results: PropTypes.object.isRequired,
  // from state
  fetchStatus: PropTypes.string.isRequired,
};

const mapStateToProps = state => ({
  lastSearchTime: state.explorer.lastSearchTime.time,
  fetchStatus: state.explorer.storySplitCount.fetchStatus || FETCH_INVALID,
  results: state.explorer.storySplitCount.results,
});

const mapDispatchToProps = (dispatch, ownProps) => ({
  handleExplore: () => {
    if (ownProps.queries.length === 1) {
      const q = ownProps.queries[0];
      return (
        <AppButton
          variant="text"
          className="action-menu-single-download"
          onClick={() => postToDownloadUrl(DOWNLOAD_PATH, q)}
          aria-controls="action-menu"
          aria-haspopup="true"
          aria-owns="action-menu"
          label={ownProps.intl.formatMessage(localMessages.downloadOneCsv, { name: q.label })}
          size="small"
        />
      );
    }
    return (
      <ActionMenu className="border-button" actionTextMsg={messages.downloadOptions}>
        {ownProps.queries.map((q, idx) => (
          <MenuItem
            className="action-icon-menu-item"
            onClick={() => postToDownloadUrl(DOWNLOAD_PATH, q)}
            key={idx}
          >
            <ListItemText>
              <FormattedMessage {...localMessages.downloadCsv} values={{ name: q.label }} />
            </ListItemText>
            <ListItemIcon>
              <DownloadButton />
            </ListItemIcon>
          </MenuItem>
        ))}
      </ActionMenu>
    );
  },
});

function mergeProps(stateProps, dispatchProps, ownProps) {
  return {
    ...stateProps,
    ...dispatchProps,
    ...ownProps,
    shouldUpdate: (nextProps) => { // QueryResultsSelector needs to ask the child for internal repainting
      const { selectedTimePeriod } = stateProps;
      return nextProps.selectedTimePeriod !== selectedTimePeriod;
    },
  };
}

export default
injectIntl(
  connect(mapStateToProps, mapDispatchToProps, mergeProps)(
    withSummary(localMessages.title, localMessages.helpIntro, [localMessages.helpDetails, messages.countsVsPercentageHelp], null, true)(
      withQueryResults(resetSentenceCounts, fetchQuerySplitStoryCount, fetchDemoQuerySplitStoryCount)(
        QueryTotalAttentionResultsContainer
      )
    )
  )
);
<commit_msg>Added SVG download for Explorer attention bubble chart (#1841)<commit_after>import PropTypes from 'prop-types';
import React from 'react';
import { FormattedMessage, injectIntl } from 'react-intl';
import { connect } from 'react-redux';
import MenuItem from '@material-ui/core/MenuItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import { fetchQuerySplitStoryCount, fetchDemoQuerySplitStoryCount, resetSentenceCounts } from '../../../actions/explorerActions';
import withSummary from '../../common/hocs/SummarizedVizualization';
import { DownloadButton } from '../../common/IconButton';
import AppButton from '../../common/AppButton';
import ActionMenu from '../../common/ActionMenu';
import BubbleRowChart from '../../vis/BubbleRowChart';
import { queryChangedEnoughToUpdate, postToDownloadUrl, ensureSafeResults } from '../../../lib/explorerUtil';
import { downloadSvg } from '../../util/svg';
import messages from '../../../resources/messages';
import { FETCH_INVALID } from '../../../lib/fetchConstants';
import withQueryResults from './QueryResultsSelector';

const BUBBLE_CHART_DOM_ID = 'bubble-chart-story-total';

const localMessages = {
  title: { id: 'explorer.storyCount.title', defaultMessage: 'Total Attention' },
  helpIntro: { id: 'explorer.storyCount.help.into',
    defaultMessage: '
Compare the total number of stories where at least one sentence matched each of your queries.  Rollover the circles to see the exact numbers, or click the menu in the bottom right to download the data.
',
  },
  helpDetails: { id: 'explorer.storyCount.help.details',
    defaultMessage: '
It is harder to determine how much of the media\'s attention your search got. If you want to dig into that, a good place to start is comparing your query to a search for everything from the sources and collections you are searching.  You can do this by searching for * in the same date range and media; that matches every story.
',
  },
  downloadOneCsv: { id: 'explorer.attention.total.downloadCsv', defaultMessage: 'Download all story URLs' },
  downloadCsv: { id: 'explorer.attention.total.downloadCsv', defaultMessage: 'Download all story URLs for {name}' },
  viewNormalized: { id: 'explorer.attention.mode.viewNormalized', defaultMessage: 'View by Story Count (default)' },
  viewRegular: { id: 'explorer.attention.mode.viewRegular', defaultMessage: 'View by Story Percentage' },
};

const VIEW_NORMALIZED = 'VIEW_NORMALIZED';
const VIEW_REGULAR = 'VIEW_REGULAR';
const DOWNLOAD_PATH = '/api/explorer/stories/all-story-urls.csv';

class QueryTotalAttentionResultsContainer extends React.Component {
  state = {
    view: VIEW_REGULAR, // which view to show (see view constants above)
  }

  shouldComponentUpdate(nextProps, nextState) {
    const { results, queries } = this.props;
    return queryChangedEnoughToUpdate(queries, nextProps.queries, results, nextProps.results)
    || (this.state.view !== nextState.view);
  }

  setView = (nextView) => {
    this.setState({ view: nextView });
  }

  downloadCsv = (query) => {
    postToDownloadUrl(DOWNLOAD_PATH, query);
  }

  render() {
    const { results, queries } = this.props;
    const { formatNumber } = this.props.intl;
    let content = null;

    const safeResults = ensureSafeResults(queries, results);
    if (safeResults) {
      let bubbleData = [];
      bubbleData = safeResults.map((query, idx) => {
        const value = (this.state.view === VIEW_REGULAR) ? query.results.total : query.results.ratio;
        let centerText;
        if (this.state.view === VIEW_REGULAR) {
          centerText = formatNumber(value);
        } else {
          centerText = formatNumber(value, { style: 'percent', maximumFractionDigits: 2 });
        }
        const rolloverText = `${query.label}: ${centerText}`;
        return {
          value,
          aboveText: (idx % 2 === 0) ? query.label : null,
          belowText: (idx % 2 !== 0) ? query.label : null,
          centerText,
          rolloverText,
          centerTextColor: '#FFFFFF',
          fill: query.color,
        };
      });
      const downloadOptimizer = (
        <ActionMenu actionTextMsg={messages.downloadOptions}>
          {queries.map((q, idx) => (
            <MenuItem
              className="action-icon-menu-item"
              onClick={() => this.downloadCsv(q)}
              key={`csv-download-${idx}`}
            >
              <ListItemText>
                <FormattedMessage {...localMessages.downloadCsv} values={{ name: q.label }} />
              </ListItemText>
              <ListItemIcon>
                <DownloadButton />
              </ListItemIcon>
            </MenuItem>
          ))}
          <MenuItem
            className="action-icon-menu-item"
            onClick={() => downloadSvg('attention-bubble', BUBBLE_CHART_DOM_ID)}
          >
            <ListItemText>
              <FormattedMessage {...messages.downloadSVG} />
            </ListItemText>
            <ListItemIcon>
              <DownloadButton />
            </ListItemIcon>
          </MenuItem>
        </ActionMenu>
      );
      content = (

          <BubbleRowChart
            data={bubbleData}
            padding={0}
            domId={BUBBLE_CHART_DOM_ID}
            width={650}
          />

            {downloadOptimizer}
            <ActionMenu actionTextMsg={messages.viewOptions}>
              {[{
                view: VIEW_REGULAR,
                msg: localMessages.viewNormalized,
              }, {
                view: VIEW_NORMALIZED,
                msg: localMessages.viewRegular,
              }].map(item => (
                <MenuItem
                  className="action-icon-menu-item"
                  key={`view-options-${item.view}`}
                  disabled={this.state.view === item.view}
                  onClick={() => this.setView(item.view)}
                >
                  <ListItemText>
                    <FormattedMessage {...item.msg} />
                  </ListItemText>
                </MenuItem>
              ))}
            </ActionMenu>

      );
    }
    return content;
  }
}

QueryTotalAttentionResultsContainer.propTypes = {
  // from parent
  lastSearchTime: PropTypes.number.isRequired,
  queries: PropTypes.array.isRequired,
  isLoggedIn: PropTypes.bool.isRequired,
  // from composition
  intl: PropTypes.object.isRequired,
  // from dispatch
  results: PropTypes.object.isRequired,
  // from state
  fetchStatus: PropTypes.string.isRequired,
};

const mapStateToProps = state => ({
  lastSearchTime: state.explorer.lastSearchTime.time,
  fetchStatus: state.explorer.storySplitCount.fetchStatus || FETCH_INVALID,
  results: state.explorer.storySplitCount.results,
});

const mapDispatchToProps = (dispatch, ownProps) => ({
  handleExplore: () => {
    if (ownProps.queries.length === 1) {
      const q = ownProps.queries[0];
      return (
        <AppButton
          variant="text"
          className="action-menu-single-download"
          onClick={() => postToDownloadUrl(DOWNLOAD_PATH, q)}
          aria-controls="action-menu"
          aria-haspopup="true"
          aria-owns="action-menu"
          label={ownProps.intl.formatMessage(localMessages.downloadOneCsv, { name: q.label })}
          size="small"
        />
      );
    }
    return (
      <ActionMenu className="border-button" actionTextMsg={messages.downloadOptions}>
        {ownProps.queries.map((q, idx) => (
          <MenuItem
            className="action-icon-menu-item"
            onClick={() => postToDownloadUrl(DOWNLOAD_PATH, q)}
            key={idx}
          >
            <ListItemText>
              <FormattedMessage {...localMessages.downloadCsv} values={{ name: q.label }} />
            </ListItemText>
            <ListItemIcon>
              <DownloadButton />
            </ListItemIcon>
          </MenuItem>
        ))}
      </ActionMenu>
    );
  },
});

function mergeProps(stateProps, dispatchProps, ownProps) {
  return {
    ...stateProps,
    ...dispatchProps,
    ...ownProps,
    shouldUpdate: (nextProps) => { // QueryResultsSelector needs to ask the child for internal repainting
      const { selectedTimePeriod } = stateProps;
      return nextProps.selectedTimePeriod !== selectedTimePeriod;
    },
  };
}

export default
injectIntl(
  connect(mapStateToProps, mapDispatchToProps, mergeProps)(
    withSummary(localMessages.title, localMessages.helpIntro, [localMessages.helpDetails, messages.countsVsPercentageHelp], null, true)(
      withQueryResults(resetSentenceCounts, fetchQuerySplitStoryCount, fetchDemoQuerySplitStoryCount)(
        QueryTotalAttentionResultsContainer
      )
    )
  )
);
<|endoftext|>


<commit_before>var searchFilter = $('#search-filter').val();
var pageLen = $('#page-len').val();
var dateRange = $('#date-range').val();

function failedAjaxCall() {
    'use strict';
    $('#table-loading').remove();
}

function countFailCallback() {
    'use strict';
    JSBase.replaceContentByClass('.count-badge', '∞');
}

function batchCountElements(data) {
    'use strict';
    var localData = data.result,
        len = localData.length,
        i = 0,
        j = 0,
        batchElements = 4,
        jobName = '',
        queriesLen = len * 4,
        batchQueries = new Array(queriesLen),
        errorReason = 'Batch count failed',
        deferredAjaxCall = null,
        ajaxData = null;

    if (len > 0) {
        for (i; i < queriesLen; i += batchElements) {
            j = i;
            jobName = localData[i / batchElements].job;

            // Get successful defconfig count.
            batchQueries[i] = {
                'method': 'GET',
                'operation_id': '#defconf-success-count-' + jobName,
                'collection': 'count',
                'document_id': 'defconfig',
                'query': 'status=PASS&date_range=' + dateRange +
                    '&job=' + jobName
            };

            // Get failed defconfig count.
            batchQueries[j + 1] = {
                'method': 'GET',
                'operation_id': '#defconf-fail-count-' + jobName,
                'collection': 'count',
                'document_id': 'defconfig',
                'query': 'status=FAIL&date_range=' + dateRange +
                    '&job=' + jobName
            };

            // Get successful boot reports count.
            batchQueries[j + 2] = {
                'method': 'GET',
                'operation_id': '#boot-success-count-' + jobName,
                'collection': 'count',
                'document_id': 'boot',
                'query': 'status=PASS&date_range=' + dateRange +
                    '&job=' + jobName
            };

            // Get failed boot reports count.
            batchQueries[j + 3] = {
                'method': 'GET',
                'operation_id': '#boot-fail-count-' + jobName,
                'collection': 'count',
                'document_id': 'boot',
                'query': 'status=FAIL&date_range=' + dateRange +
                    '&job=' + jobName
            };
        }

        ajaxData = JSON.stringify({
            'batch': batchQueries
        });
        deferredAjaxCall = JSBase.createDeferredCall(
            '/_ajax/batch',
            'POST',
            ajaxData,
            null,
            countFailCallback,
            errorReason,
            {'Content-Type': 'application/json'},
            'batch-failed'
        );

        $.when(deferredAjaxCall).done(function(data) {
            var batchData = data.result,
                batchLen = batchData.length,
                batchResult = null,
                idx = 0;

            if (batchLen > 0) {
                for (idx; idx < batchLen; idx = idx + 1) {
                    batchResult = batchData[idx].result[0];
                    $(batchData[idx].operation_id).empty().append(
                        batchResult.count);
                }
            }
        });
    }
}

function createJobsTable(data) {
    'use strict';

    var localData = data.result,
        table = $('#jobstable').dataTable({
        'dom': '<"row"<"col-xs-12 col-sm-12 col-md-6 col-lg-6"' +
            '<"length-menu"l>>' +
            '<"col-xs-12 col-sm-12 col-md-4 col-lg-4 col-lg-offset-2"f>' +
            'r' +
            '<"col-xs-12 col-sm-12 col-md-12 col-lg-12"t>>' +
            '<"row"<"col-xs-12 col-sm-12 col-md-6 col-lg-6"i>' +
            '<"col-xs-12 col-sm-12 col-md-6 col-lg-6"p>>',
        'language': {
            'lengthMenu': '_MENU_ jobs per page',
            'zeroRecords': '
No jobs to display.
',
            'search': '
' +
                '' +
                '_INPUT_
'
        },
        'initComplete': function() {
            $('#table-loading').remove();
            $('#table-div').fadeIn('slow', 'linear');

            var api = this.api();

            if (pageLen !== undefined && pageLen !== null) {
                if (pageLen.length > 0) {
                    pageLen = Number(pageLen);
                    if (isNaN(pageLen)) {
                        pageLen = 25;
                    }

                    api.page.len(pageLen).draw();
                }
            }

            if (searchFilter !== null && searchFilter !== undefined) {
                if (searchFilter.length > 0) {
                    api.search(searchFilter, true).draw();
                }
            }
        },
        'lengthMenu': [25, 50, 75, 100],
        'deferRender': true,
        'ordering': true,
        'processing': true,
        'stateDuration': -1,
        'stateSave': true,
        'order': [3, 'desc'],
        'search': {
            'regex': true,
            'smart': true
        },
        'data': localData,
        'columns': [
            {
                'data': 'job',
                'title': 'Tree ‐ Branch',
                'type': 'string',
                'render': function(data, type, object) {
                    return '' + data + ' ‐ ' +
                        object.git_branch + '';
                }
            },
            {
                'data': 'job',
                'title': '' +
                    'Build Status',
                'type': 'String',
                'searchable': false,
                'orderable': false,
                'className': 'pull-center',
                'render': function(data) {
                    return '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '';
                }
            },
            {
                'data': 'job',
                'title': '' +
                    'Boot Status',
                'type': 'string',
                'searchable': false,
                'orderable': false,
                'className': 'pull-center',
                'render': function(data) {
                    return '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '';
                }
            },
            {
                'data': 'created_on',
                'title': 'Date',
                'type': 'date',
                'render': function(data) {
                    var created = new Date(data.$date);
                    return created.getCustomISODate();
                }
            },
            {
                'data': 'status',
                'title': 'Status',
                'type': 'string',
                'className': 'pull-center',
                'render': function(data) {
                    var displ;
                    switch (data) {
                        case 'BUILD':
                            displ = '' +
                                '' +
                                '';
                            break;
                        case 'PASS':
                            displ = '' +
                                '' +
                                '';
                            break;
                        case 'FAIL':
                            displ = '' +
                                '' +
                                '' +
                                '';
                            break;
                        default:
                            displ = '' +
                                '' +
                                '' +
                                '';
                            break;
                    }
                    return displ;
                }
            },
            {
                'data': 'job',
                'title': '',
                'searchable': false,
                'orderable': false,
                'width': '30px',
                'className': 'pull-center',
                'render': function(data) {
                    return '' +
                        '' +
                        '';
                }
            }
        ]
    });

    $(document).on('click', '#jobstable tbody tr', function() {
        var tableData = table.fnGetData(this);
        if (tableData) {
            window.location = '/job/' + tableData.job + '/';
        }
    });

    $('#search-area > .input-sm').attr('placeholder', 'Filter the results');
    $('.input-sm').keyup(function(key) {
        // Remove focus from input when Esc is pressed.
        if (key.keyCode === 27) {
            $(this).blur();
        }
    });

    return data;
}

function updateJobsPage(data) {
    'use strict';
    // Simple function needed to wrap another deferred call.
    // Create the table, then update it with the batch count operation.
    $.when(createJobsTable(data)).done(batchCountElements);
}

$(document).ready(function() {
    'use strict';

    $('#li-job').addClass('active');
    $('#table-div').hide();

    var errorReason = 'Job data call failed',
        deferredAjaxCall = null,
        ajaxData = null;

    ajaxData = {
        'aggregate': 'job',
        'sort': 'created_on',
        'sort_order': -1,
        'date_range': $('#date-range').val(),
        'field': [
            'job', 'created_on', 'status', 'git_branch'
        ]
    };
    deferredAjaxCall = JSBase.createDeferredCall(
        '/_ajax/job',
        'GET',
        ajaxData,
        null,
        failedAjaxCall,
        errorReason,
        null,
        'failed-job'
    );

    $.when(deferredAjaxCall).done(updateJobsPage);
});
<commit_msg>Show only count of latest build/boot for each job.<commit_after>var searchFilter = $('#search-filter').val();
var pageLen = $('#page-len').val();
var dateRange = $('#date-range').val();

function failedAjaxCall() {
    'use strict';
    $('#table-loading').remove();
}

function countFailCallback() {
    'use strict';
    JSBase.replaceContentByClass('.count-badge', '∞');
}

function batchCountElements(data) {
    'use strict';
    var localData = data.result,
        len = localData.length,
        i = 0,
        j = 0,
        batchElements = 4,
        jobName = '',
        kernelName = '',
        queriesLen = len * 4,
        batchQueries = new Array(queriesLen),
        errorReason = 'Batch count failed',
        deferredAjaxCall = null,
        ajaxData = null;

    if (len > 0) {
        for (i; i < queriesLen; i += batchElements) {
            j = i;
            jobName = localData[i / batchElements].job;
            kernelName = localData[i / batchElements].kernel;

            // Get successful defconfig count.
            batchQueries[i] = {
                'method': 'GET',
                'operation_id': '#defconf-success-count-' + jobName,
                'collection': 'count',
                'document_id': 'defconfig',
                'query': 'status=PASS&job=' + jobName + '&kernel=' + kernelName
            };

            // Get failed defconfig count.
            batchQueries[j + 1] = {
                'method': 'GET',
                'operation_id': '#defconf-fail-count-' + jobName,
                'collection': 'count',
                'document_id': 'defconfig',
                'query': 'status=FAIL&job=' + jobName + '&kernel=' + kernelName
            };

            // Get successful boot reports count.
            batchQueries[j + 2] = {
                'method': 'GET',
                'operation_id': '#boot-success-count-' + jobName,
                'collection': 'count',
                'document_id': 'boot',
                'query': 'status=PASS&job=' + jobName + '&kernel=' + kernelName
            };

            // Get failed boot reports count.
            batchQueries[j + 3] = {
                'method': 'GET',
                'operation_id': '#boot-fail-count-' + jobName,
                'collection': 'count',
                'document_id': 'boot',
                'query': 'status=FAIL&job=' + jobName + '&kernel=' + kernelName
            };
        }

        ajaxData = JSON.stringify({
            'batch': batchQueries
        });
        deferredAjaxCall = JSBase.createDeferredCall(
            '/_ajax/batch',
            'POST',
            ajaxData,
            null,
            countFailCallback,
            errorReason,
            {'Content-Type': 'application/json'},
            'batch-failed'
        );

        $.when(deferredAjaxCall).done(function(data) {
            var batchData = data.result,
                batchLen = batchData.length,
                batchResult = null,
                idx = 0;

            if (batchLen > 0) {
                for (idx; idx < batchLen; idx = idx + 1) {
                    batchResult = batchData[idx].result[0];
                    $(batchData[idx].operation_id).empty().append(
                        batchResult.count);
                }
            }
        });
    }
}

function createJobsTable(data) {
    'use strict';

    var localData = data.result,
        table = $('#jobstable').dataTable({
        'dom': '<"row"<"col-xs-12 col-sm-12 col-md-6 col-lg-6"' +
            '<"length-menu"l>>' +
            '<"col-xs-12 col-sm-12 col-md-4 col-lg-4 col-lg-offset-2"f>' +
            'r' +
            '<"col-xs-12 col-sm-12 col-md-12 col-lg-12"t>>' +
            '<"row"<"col-xs-12 col-sm-12 col-md-6 col-lg-6"i>' +
            '<"col-xs-12 col-sm-12 col-md-6 col-lg-6"p>>',
        'language': {
            'lengthMenu': '_MENU_ jobs per page',
            'zeroRecords': '
No jobs to display.
',
            'search': '
' +
                '' +
                '_INPUT_
'
        },
        'initComplete': function() {
            $('#table-loading').remove();
            $('#table-div').fadeIn('slow', 'linear');

            var api = this.api();

            if (pageLen !== undefined && pageLen !== null) {
                if (pageLen.length > 0) {
                    pageLen = Number(pageLen);
                    if (isNaN(pageLen)) {
                        pageLen = 25;
                    }

                    api.page.len(pageLen).draw();
                }
            }

            if (searchFilter !== null && searchFilter !== undefined) {
                if (searchFilter.length > 0) {
                    api.search(searchFilter, true).draw();
                }
            }
        },
        'lengthMenu': [25, 50, 75, 100],
        'deferRender': true,
        'ordering': true,
        'processing': true,
        'stateDuration': -1,
        'stateSave': true,
        'order': [3, 'desc'],
        'search': {
            'regex': true,
            'smart': true
        },
        'data': localData,
        'columns': [
            {
                'data': 'job',
                'title': 'Tree ‐ Branch',
                'type': 'string',
                'render': function(data, type, object) {
                    return '' + data + ' ‐ ' +
                        object.git_branch + '';
                }
            },
            {
                'data': 'job',
                'title': '' +
                    'Latest Build Status',
                'type': 'String',
                'searchable': false,
                'orderable': false,
                'className': 'pull-center',
                'render': function(data) {
                    return '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '';
                }
            },
            {
                'data': 'job',
                'title': '' +
                    'Latest Boot Status',
                'type': 'string',
                'searchable': false,
                'orderable': false,
                'className': 'pull-center',
                'render': function(data) {
                    return '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '';
                }
            },
            {
                'data': 'created_on',
                'title': 'Date',
                'type': 'date',
                'render': function(data) {
                    var created = new Date(data.$date);
                    return created.getCustomISODate();
                }
            },
            {
                'data': 'status',
                'title': 'Status',
                'type': 'string',
                'className': 'pull-center',
                'render': function(data) {
                    var displ;
                    switch (data) {
                        case 'BUILD':
                            displ = '' +
                                '' +
                                '';
                            break;
                        case 'PASS':
                            displ = '' +
                                '' +
                                '';
                            break;
                        case 'FAIL':
                            displ = '' +
                                '' +
                                '' +
                                '';
                            break;
                        default:
                            displ = '' +
                                '' +
                                '' +
                                '';
                            break;
                    }
                    return displ;
                }
            },
            {
                'data': 'job',
                'title': '',
                'searchable': false,
                'orderable': false,
                'width': '30px',
                'className': 'pull-center',
                'render': function(data) {
                    return '' +
                        '' +
                        '';
                }
            }
        ]
    });

    $(document).on('click', '#jobstable tbody tr', function() {
        var tableData = table.fnGetData(this);
        if (tableData) {
            window.location = '/job/' + tableData.job + '/';
        }
    });

    $('#search-area > .input-sm').attr('placeholder', 'Filter the results');
    $('.input-sm').keyup(function(key) {
        // Remove focus from input when Esc is pressed.
        if (key.keyCode === 27) {
            $(this).blur();
        }
    });

    return data;
}

function updateJobsPage(data) {
    'use strict';
    // Simple function needed to wrap another deferred call.
    // Create the table, then update it with the batch count operation.
    $.when(createJobsTable(data)).done(batchCountElements);
}

$(document).ready(function() {
    'use strict';

    $('#li-job').addClass('active');
    $('#table-div').hide();

    var errorReason = 'Job data call failed',
        deferredAjaxCall = null,
        ajaxData = null;

    ajaxData = {
        'aggregate': 'job',
        'sort': 'created_on',
        'sort_order': -1,
        'date_range': $('#date-range').val(),
        'field': [
            'job', 'created_on', 'status', 'git_branch', 'kernel'
        ]
    };
    deferredAjaxCall = JSBase.createDeferredCall(
        '/_ajax/job',
        'GET',
        ajaxData,
        null,
        failedAjaxCall,
        errorReason,
        null,
        'failed-job'
    );

    $.when(deferredAjaxCall).done(updateJobsPage);
});
<|endoftext|>


<commit_before>const koe = require('koe')
const path = require('path')

// define a sample config that overrides/extends some default keys
const config = {
  destination: path.join(__dirname, 'dest'),
  exclude: [
    'npm-debug.log',
    'yarn.lock'
  ]
}

// define a sample middleware
function middleware (site) {
  site.log('hey!')
  site.foo = 'bar'
}

// you can also hook into specific parts of the build process
function preconfigHook (site) {
  site.config.destination = path.join(__dirname, 'dest2')
}

// the main execution thread. should return a promise
async function run () {
  const site = koe(config)
  site.use(middleware)

  // use the pre_config hook
  site.hook('pre_config', preconfigHook)

  return site.build()
}

// execute the build process and log results
run().then(res => {
  console.log(res)
}).catch(err => {
  // optionally, log errors
  throw new Error(err)
})
<commit_msg>update example<commit_after>const koe = require('./index')
const path = require('path')

// define a sample config that overrides/extends some default keys
const config = {
  source: 'test/sample',
  destination: path.join(__dirname, 'dest'),
  exclude: [
    'npm-debug.log',
    'yarn.lock'
  ]
}

// define a sample middleware
function middleware (site) {
  site.files[path.join(__dirname, 'test/sample/test.md')].contents = 'sup'
}

// the main execution thread. should return a promise
async function run () {
  const site = koe(config)
  site.use(middleware)

  return site.build()
}

// execute the build process and log results
run().then(res => {
  console.log(res)
}).catch(err => {
  // optionally, log errors
  throw new Error(err)
})
<|endoftext|>


<commit_before>angular.module("plantApp")
.controller("questionnaireCtrl",function($scope, QA){
	var msg=angular.element("#reply");
	var msgicon=angular.element("#replyicon");
	var selecticon=angular.element("#selecticon");
	var type=5;
	angular.element('.ui.dropdown').dropdown();

	$scope.getquestion = function(typeOfQ){
		type = typeOfQ;
		selecticon.attr("class","loading icon");
		msg.attr("class","");
	  msgicon.attr("class","");
	  $scope.disablebtn = false;
		$scope.showanswer = false;
		$scope.problem = null;
		$scope.solution = null;
		$scope.reply = null;
		QA.get({id : typeOfQ}).$promise.then(function(data){
			$scope.problem = data;
			$scope.qtitle = data.qtitle;
			$scope.question = data.question;
			$scope.question2 = data.equation2;
			$scope.answer = data.answer;
			selecticon.attr("class","dropdown icon");
			$scope.placeholder="Please enter your answer here"
			if(typeOfQ==1)
				$scope.placeholder="Please enter your answer in the format of (x,y)";
			var form = angular.element("#qaform");
			form.modal('show');
		});
	}
	$scope.getanswer = function(){
		if($scope.problem!=null){
			$scope.answer = $scope.problem.answer;
			$scope.showanswer = true;
			$scope.disablebtn=true;
		}
	}

	$scope.postsolution = function(){
		if($scope.problem!=null && $scope.solution!=null && !$scope.disablebtn){
			var solution = $scope.solution;
			var answer = $scope.problem.answer;
			solution =solution.toString().replace(/ |\s+/g,"");
			answer =answer.toString().replace(/ |\s+/g,"");

			/* remove characters such as '$' that might be in the solution */
			solution.replace(/[^a-zA-Z0-9\(\)\.]/,"");

			/* complicated answer check for factorization, see below */
			if(type==0)
				result=checkanswer(solution,answer);

			/* linear equations: check for both x and y */
			/* use eval to deal with decimals (E.g. 1 vs 1.0) */
			else if(type==1){
				/* value of x variable */
				xvalsol = solution.split(/[\(\),]+/)[1];
				xvalans = answer.split(/[\(\),]+/)[1];

				/* value of y variable */
				yvalsol = solution.split(/[\(\),]+/)[2];
				yvalans = answer.split(/[\(\),]+/)[2];

				if((eval(xvalans)!=eval(xvalsol))||(eval(xvalans)!=eval(xvalsol)))
					result=false;
				else result=true;

			}

			/* check answer value for calculation and word problems */
			else
				result=(eval(solution) == eval(answer));
			if(result){
				$scope.reply="Correct";
				msg.attr("class","ui icon success message");
				msgicon.attr("class","smile icon");
				$scope.disablebtn = true;
			}
			else{
				$scope.reply="Incorrect";
				msg.attr("class","ui icon error message");
				msgicon.attr("class","frown icon");
			}
		}
	}

	function checkanswer(answer, solution){
		/* convert answer/solution string into valid js math expressions */
		solution =solution.replace(")(",")*(");
		answer =answer.replace(")(",")*(");
		solution = solution.replace(/(\d+|\))(x)/g,"$1*$2");
		answer =answer.replace(/(\d+|\))(x)/g,"$1*$2");

		/* plug in values 0,1,2 for x and check if expressions evaluate to same number */
		/* this can be proved... */
		for(x=0;x<3;x++){
			if(eval(solution)!=eval(answer))
				return false;
		}
		return true;
	}

});
<commit_msg>minor fix<commit_after>angular.module("plantApp")
.controller("questionnaireCtrl",function($scope, QA){
	var msg=angular.element("#reply");
	var msgicon=angular.element("#replyicon");
	var selecticon=angular.element("#selecticon");
	var type=5;
	angular.element('.ui.dropdown').dropdown();

	$scope.getquestion = function(typeOfQ){
		type = typeOfQ;
		selecticon.attr("class","loading icon");
		msg.attr("class","");
	  msgicon.attr("class","");
	  $scope.disablebtn = false;
		$scope.showanswer = false;
		$scope.problem = null;
		$scope.solution = null;
		$scope.reply = null;
		QA.get({id : typeOfQ}).$promise.then(function(data){
			$scope.problem = data;
			$scope.qtitle = data.qtitle;
			$scope.question = data.question;
			$scope.question2 = data.equation2;
			$scope.answer = data.answer;
			selecticon.attr("class","dropdown icon");
			$scope.placeholder="Please enter your answer here"
			if(typeOfQ==1)
				$scope.placeholder="Please enter your answer in the format of (x,y)";
			var form = angular.element("#qaform");
			form.modal('show');
		});
	}
	$scope.getanswer = function(){
		if($scope.problem!=null){
			$scope.answer = $scope.problem.answer;
			$scope.showanswer = true;
			$scope.disablebtn=true;
		}
	}

	$scope.postsolution = function(){
		if($scope.problem!=null && $scope.solution!=null && !$scope.disablebtn){
			var solution = $scope.solution;
			var answer = $scope.problem.answer;
			solution =solution.toString().replace(/ |\s+/g,"");
			answer =answer.toString().replace(/ |\s+/g,"");

			/* remove characters such as '$' that might be in the solution */
			solution.replace(/[^a-zA-Z0-9\(\)\.]/,"");

			/* complicated answer check for factorization, see below */
			if(type==0)
				result=checkanswer(solution,answer);

			/* linear equations: check for both x and y */
			/* use eval to deal with decimals (E.g. 1 vs 1.0) */
			else if(type==1){
				/* value of x variable */
				xvalsol = solution.split(/[\(\),]+/)[1];
				xvalans = answer.split(/[\(\),]+/)[1];

				/* value of y variable */
				yvalsol = solution.split(/[\(\),]+/)[2];
				yvalans = answer.split(/[\(\),]+/)[2];

				if((eval(xvalans)!=eval(xvalsol))||(eval(yvalans)!=eval(yvalsol)))
					result=false;
				else result=true;

			}

			/* check answer value for calculation and word problems */
			else
				result=(eval(solution) == eval(answer));
			if(result){
				$scope.reply="Correct";
				msg.attr("class","ui icon success message");
				msgicon.attr("class","smile icon");
				$scope.disablebtn = true;
			}
			else{
				$scope.reply="Incorrect";
				msg.attr("class","ui icon error message");
				msgicon.attr("class","frown icon");
			}
		}
	}

	function checkanswer(answer, solution){
		/* convert answer/solution string into valid js math expressions */
		solution =solution.replace(")(",")*(");
		answer =answer.replace(")(",")*(");
		solution = solution.replace(/(\d+|\))(x)/g,"$1*$2");
		answer =answer.replace(/(\d+|\))(x)/g,"$1*$2");

		/* plug in values 0,1,2 for x and check if expressions evaluate to same number */
		/* this can be proved... */
		for(x=0;x<3;x++){
			if(eval(solution)!=eval(answer))
				return false;
		}
		return true;
	}

});
<|endoftext|>


<commit_before>module.exports = {
    /**
     * Initializes a item (fetches all required parameters, etc) before the actual authorization step.
     *
     * @param {RequestContext} context
     * @param {Requester} requester
     * @param done
     */
    init: function (context, requester, done) {
        done(null);
    },

    /**
     * Verifies whether the request has valid basic auth credentials (which is always).
     *
     * @param {RequestContext} context
     * @param {Requester} requester
     * @param done
     */
    pre: function (context, requester, done) {
        done(null, true);
    },

    /**
     * Verifies whether the no auth succeeded. (Which means, does nothing.)
     *
     * @param {RequestContext} context
     * @param {Requester} requester
     * @param done
     */
    post: function (context, requester, done) {
        done(null, true);
    },

    /**
     * Signs a request.
     *
     * @param {Request} request
     * @todo - this should be made into ".sign" after the signature calculation is moved out of the SDK.
     */
    _sign: function (request) {
        return this.authorize(request);
    }
};
<commit_msg>Copy sign function for noauth from sdk<commit_after>module.exports = {
    /**
     * Initializes a item (fetches all required parameters, etc) before the actual authorization step.
     *
     * @param {RequestContext} context
     * @param {Requester} requester
     * @param done
     */
    init: function (context, requester, done) {
        done(null);
    },

    /**
     * Verifies whether the request has valid basic auth credentials (which is always).
     *
     * @param {RequestContext} context
     * @param {Requester} requester
     * @param done
     */
    pre: function (context, requester, done) {
        done(null, true);
    },

    /**
     * Verifies whether the no auth succeeded. (Which means, does nothing.)
     *
     * @param {RequestContext} context
     * @param {Requester} requester
     * @param done
     */
    post: function (context, requester, done) {
        done(null, true);
    },

    /**
     * Signs a request.
     *
     * @param {Request} request
     * @todo - this should be made into ".sign" after the signature calculation is moved out of the SDK.
     */
    _sign: function (request) {
        return request;
    }
};
<|endoftext|>


<commit_before>(function () {
    'use strict';

    angular
        .module('atlas')
        .factory('stateUrlConverter', stateUrlConverterFactory);

    stateUrlConverterFactory.$inject = ['STATE_URL_CONVERSION', 'dpBaseCoder'];

    function stateUrlConverterFactory (STATE_URL_CONVERSION, dpBaseCoder) {
        const URL_ARRAY_SEPARATOR = ':';    // Choose any of -._~:[]@!$'()*+,;`.
        const ARRAY_DENOTATOR = '[]';
        const MAIN_STATE = 'DEFAULT';
        const BOOLEAN_TRUE = 'T';
        const BOOLEAN_FALSE = 'F';
        const TYPENAME = {
            STRING: /^string$/,
            BOOLEAN: /^boolean$/,
            NUMBER: /^number$/,
            BASE62: /^base62$/,
            KEYVALUES: /^keyvalues$/,
            OBJECT: /^object\((\w+:\w+[\[\]]*)(,\w+:\w+[\[\]]*)*\)$/,
            ARRAY: /\[\]$/
        };

        const base62Coder = dpBaseCoder.getCoderForBase(62);  // Code coordinates in base62

        // url-state converters for every possible type

        class StringValue {
            static urlValue (s) { return s; }
            static stateValue (s) { return s; }
        }

        class NumberValue {
            static getNumberValue (n, precision) {
                // eg return 10.1 for 10.123
                return precision === null ? n : dpBaseCoder.toPrecision(n, precision);
            }
            static urlValue (n, precision) { return NumberValue.getNumberValue(n, precision); }
            static stateValue (s, precision) { return NumberValue.getNumberValue(Number(s), precision); }
        }

        class Base62Value {
            static urlValue (n, precision) { return base62Coder.encode(n, precision); }
            static stateValue (s, precision) { return base62Coder.decode(s, precision); }
        }

        class BooleanValue {
            static urlValue (b) { return b ? BOOLEAN_TRUE : BOOLEAN_FALSE; }
            static stateValue (s) { return s === BOOLEAN_TRUE; }
        }

        class KeyValuesValue {
            static urlValue (kv, typeName, asValue, precision, separator) {
                // { key: value, key:value, ... } => key::value:key::value...
                return asValue(Object.keys(kv).map(key => [key, kv[key]]), 'string[][]', precision, separator);
            }
            static stateValue (s, typeName, asValue, precision, separator) {
                // key::value:key::value... => { key: value, key:value, ... }
                return asValue(s, 'string[][]', precision, separator)
                    .reduce((result, [key, keyValue]) => {
                        result[key] = keyValue;
                        return result;
                    }, {});
            }
        }

        class ObjectValue {
            static getKeyTypes (typeName) {
                // object(key:type,key:type,...) => ['key:type', 'key:type', ...]
                return typeName.substring('object('.length, typeName.length - 1).split(',');
            }
            static urlValue (o, typeName, asValue, precision, separator) {
                // { id:anyValue, ... } => anyValue:anyValue:...
                return ObjectValue.getKeyTypes(typeName)
                    .map(keyValue => {
                        const [key, keyType] = keyValue.split(':'); // key:type => key, type
                        return asValue(o[key], keyType, precision, separator + URL_ARRAY_SEPARATOR);
                    })
                    .join(separator);
            }
            static stateValue (s, typeName, asValue, precision, separator) {
                // anyValue:anyValue:... => { id:anyValue, ... }
                const fields = asValue(s, 'string[]', precision, separator); // [ anyValue, anyValue, ...]
                return ObjectValue.getKeyTypes(typeName)
                    .reduce((result, keyAndType, i) => {
                        const [key, keyType] = keyAndType.split(':'); // key:type => key, type
                        result[key] = asValue(fields[i], keyType, precision, separator + URL_ARRAY_SEPARATOR);
                        return result;
                    }, {});
            }
        }

        class ArrayValue {
            static getBaseType (typeName) {
                return typeName.substr(0, typeName.length - ARRAY_DENOTATOR.length);
            }
            static urlValue (a, typeName, asValue, precision, separator) {
                // [ x, y, z, ... ] => x:y:z:...
                const baseType = ArrayValue.getBaseType(typeName);
                return a
                    .map(v => asValue(v, baseType, precision, separator + URL_ARRAY_SEPARATOR))
                    .join(separator);
            }
            static stateValue (s, typeName, asValue, precision, separator) {
                // x:y:z:... => [ x, y, z, ... ]
                const baseType = ArrayValue.getBaseType(typeName);
                // Split the array, replace the split char by a tmp split char because org split char can repeat
                const TMP_SPLIT_CHAR = '|';
                const surroundBy = '(^|[^' + URL_ARRAY_SEPARATOR + ']|$)';
                const splitOn = new RegExp(surroundBy + separator + surroundBy, 'g');
                const splitValue = s.replace(splitOn, '$1' + TMP_SPLIT_CHAR + '$2');
                return splitValue
                    .split(TMP_SPLIT_CHAR)
                    .map(v => asValue(v, baseType, precision, separator + URL_ARRAY_SEPARATOR));
            }
        }

        return {
            state2params,
            state2url,
            params2state,
            urlSafeState,
            getDefaultState
        };

        function getDefaultState () {
            return params2state({}, {});
        }

        function urlSafeState (state) {
            // modifies the given state so that state2url and url2state are identical
            // This means that all values that are 'truncated' to a certain precision
            // are truncated before they get in the url
            Object.keys(STATE_URL_CONVERSION.stateVariables)
                .map(key => STATE_URL_CONVERSION.stateVariables[key])
                .filter(attribute => angular.isDefined(attribute.precision))
                .map(attribute => [attribute, getValueForKey(state, attribute.name)])
                .filter(([attribute, value]) => value !== null)
                .forEach(([attribute, value]) => {
                    // Convert the state value so that when it is read from the url no change exists
                    // between the current state and the state read from the url
                    // This prevents erroneous back-button behaviour
                    const newValue = dpBaseCoder.toPrecision(value, attribute.precision);
                    setValueForKey(state, state, attribute.name, newValue);
                });
            return state;
        }

        function state2url (state) {
            // Convert the url parameters object into a url parameter string
            const params = state2params(state);
            return '#' + Object.keys(params).reduce((result, key) => {
                result += result ? '&' : '?';
                result += `${key}=${(params[key])}`;
                return result;
            }, '');
        }

        function createObject (oldObj, key, params) {
            // create a state object by using its initial value (default {}) and onCreate method if defined
            const initialValues = STATE_URL_CONVERSION.initialValues,
                initialValue = initialValues[key] || {},
                onCreate = STATE_URL_CONVERSION.onCreate[key];

            let newObj = angular.copy(initialValue);
            if (angular.isFunction(onCreate)) {
                newObj = onCreate(oldObj, newObj, params, initialValues);
            }
            return newObj;
        }

        function getFullKey (key) {
            // decompose 'map.viewCenter' in {mainKey: 'map', subKey: 'viewCenter'}
            // or 'isPrintmode' in {mainKey: 'isPrintmode'}
            const dot = key.indexOf('.');
            if (dot >= 0) {
                return {
                    mainKey: key.substr(0, dot),
                    subKey: key.substr(dot + 1)
                };
            } else {
                return {
                    mainKey: key
                };
            }
        }

        function getValueForKey (obj, key) {
            // return 9 for obj={map: {zoom: 9}} and key = 'map.zoom', null when no value available
            // Uses recursion for endless depth
            const {mainKey, subKey} = getFullKey(key);
            if (subKey) {
                return angular.isObject(obj[mainKey]) ? getValueForKey(obj[mainKey], subKey) : null;
            } else {
                return obj[mainKey] || null;
            }
        }

        function setValueForKey (obj, oldObj, key, value) {
            // set obj:{map: {zoom: 9}} to {map: {zoom: 8}} for key 'map.zoom' and value 8
            // the old object is used for createObject() in case of any onCreate method for the state object
            const {mainKey, subKey} = getFullKey(key);
            if (subKey) {
                obj[mainKey] = obj[mainKey] || createObject(oldObj[mainKey], mainKey);
                setValueForKey(obj[mainKey], oldObj[mainKey] || {}, subKey, value);
            } else {
                obj[mainKey] = value;
            }
        }

        function asUrlValue (value, typeName, precision = null, separator = URL_ARRAY_SEPARATOR) {
            // returns the value as a valid url value (URI-encoded string representation)
            let urlValue = '';

            if (typeName.match(TYPENAME.STRING)) {
                urlValue = StringValue.urlValue(value);
            } else if (typeName.match(TYPENAME.NUMBER)) {
                urlValue = NumberValue.urlValue(value, precision);
            } else if (typeName.match(TYPENAME.BASE62)) {
                urlValue = Base62Value.urlValue(value, precision);
            } else if (typeName.match(TYPENAME.BOOLEAN)) {
                urlValue = BooleanValue.urlValue(value);
            } else if (typeName.match(TYPENAME.KEYVALUES)) {
                return KeyValuesValue.urlValue(value, typeName, asUrlValue, precision, separator);
            } else if (typeName.match(TYPENAME.OBJECT)) {
                return ObjectValue.urlValue(value, typeName, asUrlValue, precision, separator);
            } else if (typeName.match(TYPENAME.ARRAY)) {
                return ArrayValue.urlValue(value, typeName, asUrlValue, precision, separator);
            }

            return encodeURI(urlValue.toString());
        }

        function asStateValue (decodedValue, typeName, precision = null, separator = URL_ARRAY_SEPARATOR) {
            // returns the value as a state value by using the URI-decoded string representation
            const value = decodeURI(decodedValue);
            let stateValue = null;

            if (typeName.match(TYPENAME.STRING)) {
                stateValue = StringValue.stateValue(value);
            } else if (typeName.match(TYPENAME.NUMBER)) {
                stateValue = NumberValue.stateValue(value, precision);
            } else if (typeName.match(TYPENAME.BASE62)) {
                stateValue = Base62Value.stateValue(value, precision);
            } else if (typeName.match(TYPENAME.BOOLEAN)) {
                stateValue = BooleanValue.stateValue(value);
            } else if (typeName.match(TYPENAME.KEYVALUES)) {
                return KeyValuesValue.stateValue(value, typeName, asStateValue, precision, separator);
            } else if (typeName.match(TYPENAME.OBJECT)) {
                return ObjectValue.stateValue(value, typeName, asStateValue, precision, separator);
            } else if (typeName.match(TYPENAME.ARRAY)) {
                return ArrayValue.stateValue(value, typeName, asStateValue, precision, separator);
            }

            return stateValue;
        }

        function state2params (state) {
            // Converts a state to a params object that is stored in the url
            return Object.keys(STATE_URL_CONVERSION.stateVariables).reduce((result, key) => {
                const attribute = STATE_URL_CONVERSION.stateVariables[key];
                let value = getValueForKey(state, attribute.name);
                if (value !== null) {
                    // store value in url
                    if (angular.isFunction(attribute.getValue)) {
                        value = attribute.getValue(value);
                    }
                    value = asUrlValue(value, attribute.type, attribute.precision);
                    if (value) {
                        result[key] = value;
                    }
                }
                return result;
            }, {});
        }

        function params2state (oldState, params) {
            // Converts a params object (payload or url value) to a new state object
            let newState = createObject (oldState, MAIN_STATE, params);

            newState = Object.keys(STATE_URL_CONVERSION.stateVariables).reduce((result, key) => {
                const attribute = STATE_URL_CONVERSION.stateVariables[key];
                let value = params[key];
                if (angular.isDefined(value)) {
                    // store value in state
                    value = asStateValue(value, attribute.type, attribute.precision);
                    if (angular.isFunction(attribute.setValue)) {
                        value = attribute.setValue(value);
                    }
                    if (value !== null) {
                        setValueForKey(result, oldState, attribute.name, value);
                    }
                }
                return result;
            }, newState);

            // Set any missing state objects to null
            Object.keys(STATE_URL_CONVERSION.initialValues).forEach(key => {
                if (key !== MAIN_STATE && !angular.isObject(newState[key])) {
                    newState[key] = null;
                }
            });

            // Execute the post processing methods
            Object.keys(STATE_URL_CONVERSION.post).forEach(key => {
                if (angular.isObject(newState[key])) {
                    STATE_URL_CONVERSION.post[key](oldState[key], newState[key]);
                }
            });

            return newState;
        }
    }
})();
<commit_msg>Restore fix<commit_after>(function () {
    'use strict';

    angular
        .module('atlas')
        .factory('stateUrlConverter', stateUrlConverterFactory);

    stateUrlConverterFactory.$inject = ['STATE_URL_CONVERSION', 'dpBaseCoder'];

    function stateUrlConverterFactory (STATE_URL_CONVERSION, dpBaseCoder) {
        const URL_ARRAY_SEPARATOR = ':';    // Choose any of -._~:[]@!$'()*+,;`.
        const ARRAY_DENOTATOR = '[]';
        const MAIN_STATE = 'DEFAULT';
        const BOOLEAN_TRUE = 'T';
        const BOOLEAN_FALSE = 'F';
        const TYPENAME = {
            STRING: /^string$/,
            BOOLEAN: /^boolean$/,
            NUMBER: /^number$/,
            BASE62: /^base62$/,
            KEYVALUES: /^keyvalues$/,
            OBJECT: /^object\((\w+:\w+[\[\]]*)(,\w+:\w+[\[\]]*)*\)$/,
            ARRAY: /\[\]$/
        };

        const base62Coder = dpBaseCoder.getCoderForBase(62);  // Code coordinates in base62

        // url-state converters for every possible type

        class StringValue {
            static urlValue (s) { return s; }
            static stateValue (s) { return s; }
        }

        class NumberValue {
            static getNumberValue (n, precision) {
                // eg return 10.1 for 10.123
                return precision === null ? n : dpBaseCoder.toPrecision(n, precision);
            }
            static urlValue (n, precision) { return NumberValue.getNumberValue(n, precision); }
            static stateValue (s, precision) { return NumberValue.getNumberValue(Number(s), precision); }
        }

        class Base62Value {
            static urlValue (n, precision) { return base62Coder.encode(n, precision); }
            static stateValue (s, precision) { return base62Coder.decode(s, precision); }
        }

        class BooleanValue {
            static urlValue (b) { return b ? BOOLEAN_TRUE : BOOLEAN_FALSE; }
            static stateValue (s) { return s === BOOLEAN_TRUE; }
        }

        class KeyValuesValue {
            static urlValue (kv, typeName, asValue, precision, separator) {
                // { key: value, key:value, ... } => key::value:key::value...
                return asValue(Object.keys(kv).map(key => [key, kv[key]]), 'string[][]', precision, separator);
            }
            static stateValue (s, typeName, asValue, precision, separator) {
                // key::value:key::value... => { key: value, key:value, ... }
                return asValue(s, 'string[][]', precision, separator)
                    .reduce((result, [key, keyValue]) => {
                        result[key] = keyValue;
                        return result;
                    }, {});
            }
        }

        class ObjectValue {
            static getKeyTypes (typeName) {
                // object(key:type,key:type,...) => ['key:type', 'key:type', ...]
                return typeName.substring('object('.length, typeName.length - 1).split(',');
            }
            static urlValue (o, typeName, asValue, precision, separator) {
                // { id:anyValue, ... } => anyValue:anyValue:...
                return ObjectValue.getKeyTypes(typeName)
                    .map(keyValue => {
                        const [key, keyType] = keyValue.split(':'); // key:type => key, type
                        return asValue(o[key], keyType, precision, separator + URL_ARRAY_SEPARATOR);
                    })
                    .join(separator);
            }
            static stateValue (s, typeName, asValue, precision, separator) {
                // anyValue:anyValue:... => { id:anyValue, ... }
                const fields = asValue(s, 'string[]', precision, separator); // [ anyValue, anyValue, ...]
                return ObjectValue.getKeyTypes(typeName)
                    .reduce((result, keyAndType, i) => {
                        const [key, keyType] = keyAndType.split(':'); // key:type => key, type
                        result[key] = asValue(fields[i], keyType, precision, separator + URL_ARRAY_SEPARATOR);
                        return result;
                    }, {});
            }
        }

        class ArrayValue {
            static getBaseType (typeName) {
                return typeName.substr(0, typeName.length - ARRAY_DENOTATOR.length);
            }
            static urlValue (a, typeName, asValue, precision, separator) {
                // [ x, y, z, ... ] => x:y:z:...
                const baseType = ArrayValue.getBaseType(typeName);
                return a
                    .map(v => asValue(v, baseType, precision, separator + URL_ARRAY_SEPARATOR))
                    .join(separator);
            }
            static stateValue (s, typeName, asValue, precision, separator) {
                // x:y:z:... => [ x, y, z, ... ]
                const baseType = ArrayValue.getBaseType(typeName);
                // Split the array, replace the split char by a tmp split char because org split char can repeat
                const TMP_SPLIT_CHAR = '|';
                const surroundBy = '(^|[^' + URL_ARRAY_SEPARATOR + ']|$)';
                const splitOn = new RegExp(surroundBy + separator + surroundBy, 'g');
                const splitValue = s.replace(splitOn, '$1' + TMP_SPLIT_CHAR + '$2');
                return splitValue
                    .split(TMP_SPLIT_CHAR)
                    .map(v => asValue(v, baseType, precision, separator + URL_ARRAY_SEPARATOR));
            }
        }

        return {
            state2params,
            state2url,
            params2state,
            getDefaultState
        };

        function getDefaultState () {
            return params2state({}, {});
        }

        function state2url (state) {
            // Convert the url parameters object into a url parameter string
            const params = state2params(state);
            return '#' + Object.keys(params).reduce((result, key) => {
                result += result ? '&' : '?';
                result += `${key}=${(params[key])}`;
                return result;
            }, '');
        }

        function createObject (oldObj, key, params) {
            // create a state object by using its initial value (default {}) and onCreate method if defined
            const initialValues = STATE_URL_CONVERSION.initialValues,
                initialValue = initialValues[key] || {},
                onCreate = STATE_URL_CONVERSION.onCreate[key];

            let newObj = angular.copy(initialValue);
            if (angular.isFunction(onCreate)) {
                newObj = onCreate(oldObj, newObj, params, initialValues);
            }
            return newObj;
        }

        function getFullKey (key) {
            // decompose 'map.viewCenter' in {mainKey: 'map', subKey: 'viewCenter'}
            // or 'isPrintmode' in {mainKey: 'isPrintmode'}
            const dot = key.indexOf('.');
            if (dot >= 0) {
                return {
                    mainKey: key.substr(0, dot),
                    subKey: key.substr(dot + 1)
                };
            } else {
                return {
                    mainKey: key
                };
            }
        }

        function getValueForKey (obj, key) {
            // return 9 for obj={map: {zoom: 9}} and key = 'map.zoom', null when no value available
            // Uses recursion for endless depth
            const {mainKey, subKey} = getFullKey(key);
            if (subKey) {
                return angular.isObject(obj[mainKey]) ? getValueForKey(obj[mainKey], subKey) : null;
            } else {
                return obj[mainKey] || null;
            }
        }

        function setValueForKey (obj, oldObj, key, value) {
            // set obj:{map: {zoom: 9}} to {map: {zoom: 8}} for key 'map.zoom' and value 8
            // the old object is used for createObject() in case of any onCreate method for the state object
            const {mainKey, subKey} = getFullKey(key);
            if (subKey) {
                obj[mainKey] = obj[mainKey] || createObject(oldObj[mainKey], mainKey);
                setValueForKey(obj[mainKey], oldObj[mainKey] || {}, subKey, value);
            } else {
                obj[mainKey] = value;
            }
        }

        function asUrlValue (value, typeName, precision = null, separator = URL_ARRAY_SEPARATOR) {
            // returns the value as a valid url value (URI-encoded string representation)
            let urlValue = '';

            if (typeName.match(TYPENAME.STRING)) {
                urlValue = StringValue.urlValue(value);
            } else if (typeName.match(TYPENAME.NUMBER)) {
                urlValue = NumberValue.urlValue(value, precision);
            } else if (typeName.match(TYPENAME.BASE62)) {
                urlValue = Base62Value.urlValue(value, precision);
            } else if (typeName.match(TYPENAME.BOOLEAN)) {
                urlValue = BooleanValue.urlValue(value);
            } else if (typeName.match(TYPENAME.KEYVALUES)) {
                return KeyValuesValue.urlValue(value, typeName, asUrlValue, precision, separator);
            } else if (typeName.match(TYPENAME.OBJECT)) {
                return ObjectValue.urlValue(value, typeName, asUrlValue, precision, separator);
            } else if (typeName.match(TYPENAME.ARRAY)) {
                return ArrayValue.urlValue(value, typeName, asUrlValue, precision, separator);
            }

            return encodeURI(urlValue.toString());
        }

        function asStateValue (decodedValue, typeName, precision = null, separator = URL_ARRAY_SEPARATOR) {
            // returns the value as a state value by using the URI-decoded string representation
            const value = decodeURI(decodedValue);
            let stateValue = null;

            if (typeName.match(TYPENAME.STRING)) {
                stateValue = StringValue.stateValue(value);
            } else if (typeName.match(TYPENAME.NUMBER)) {
                stateValue = NumberValue.stateValue(value, precision);
            } else if (typeName.match(TYPENAME.BASE62)) {
                stateValue = Base62Value.stateValue(value, precision);
            } else if (typeName.match(TYPENAME.BOOLEAN)) {
                stateValue = BooleanValue.stateValue(value);
            } else if (typeName.match(TYPENAME.KEYVALUES)) {
                return KeyValuesValue.stateValue(value, typeName, asStateValue, precision, separator);
            } else if (typeName.match(TYPENAME.OBJECT)) {
                return ObjectValue.stateValue(value, typeName, asStateValue, precision, separator);
            } else if (typeName.match(TYPENAME.ARRAY)) {
                return ArrayValue.stateValue(value, typeName, asStateValue, precision, separator);
            }

            return stateValue;
        }

        function state2params (state) {
            // Converts a state to a params object that is stored in the url
            return Object.keys(STATE_URL_CONVERSION.stateVariables).reduce((result, key) => {
                const attribute = STATE_URL_CONVERSION.stateVariables[key];
                let value = getValueForKey(state, attribute.name);
                if (value !== null) {
                    // store value in url
                    if (angular.isFunction(attribute.getValue)) {
                        value = attribute.getValue(value);
                    }
                    value = asUrlValue(value, attribute.type, attribute.precision);
                    if (value) {
                        result[key] = value;
                    }
                }
                return result;
            }, {});
        }

        function params2state (oldState, params) {
            // Converts a params object (payload or url value) to a new state object
            let newState = createObject (oldState, MAIN_STATE, params);

            newState = Object.keys(STATE_URL_CONVERSION.stateVariables).reduce((result, key) => {
                const attribute = STATE_URL_CONVERSION.stateVariables[key];
                let value = params[key];
                if (angular.isDefined(value)) {
                    // store value in state
                    value = asStateValue(value, attribute.type, attribute.precision);
                    if (angular.isFunction(attribute.setValue)) {
                        value = attribute.setValue(value);
                    }
                    if (value !== null) {
                        setValueForKey(result, oldState, attribute.name, value);
                    }
                }
                return result;
            }, newState);

            // Set any missing state objects to null
            Object.keys(STATE_URL_CONVERSION.initialValues).forEach(key => {
                if (key !== MAIN_STATE && !angular.isObject(newState[key])) {
                    newState[key] = null;
                }
            });

            // Execute the post processing methods
            Object.keys(STATE_URL_CONVERSION.post).forEach(key => {
                if (angular.isObject(newState[key])) {
                    STATE_URL_CONVERSION.post[key](oldState[key], newState[key]);
                }
            });

            return newState;
        }
    }
})();
<|endoftext|>


<commit_before>const fs = require('fs'), os = require('os');
const sqlite = require('sqlite3');

var out = fs.createWriteStream('tweets.csv');
out.write('ID\tUser\tTimestamp' + os.EOL);

var db = new sqlite.Database('tweets.db', function(err) {
  if (err) throw err;
  db.each('SELECT tweet_id, user, timestamp, body FROM tweets', (err, row) => {
    if (err) throw err;
    out.write([row.tweet_id, row.user, row.timestamp].join('\t') + os.EOL);
  }, (err, n) => {
    if (err) throw err;
    console.log('wrote %d rows', n);
    out.end((err) => {
      if (err) throw err;
    });
  })
});
<commit_msg>Write CSV file with Julian date<commit_after>const fs = require('fs'), os = require('os');
const sqlite = require('sqlite3');

var out = fs.createWriteStream('tweets.csv');
out.write('ID,User,Time' + os.EOL);

var db = new sqlite.Database('tweets.db', function(err) {
  if (err) throw err;
  db.each("SELECT tweet_id, user, julianday(timestamp) - julianday('1900-01-01') AS date, body FROM tweets", (err, row) => {
    if (err) throw err;
    out.write([row.tweet_id, row.user, row.date].join(',') + os.EOL);
  }, (err, n) => {
    if (err) throw err;
    console.log('wrote %d rows', n);
    out.end((err) => {
      if (err) throw err;
    });
  })
});
<|endoftext|>


<commit_before>import moment from 'moment';
import { updateIntl } from 'react-intl-redux';

import { savePersistLocale } from 'store/middleware/persistState';
import enMessages from 'i18n/messages/en.json';
import fiMessages from 'i18n/messages/fi.json';
import svMessages from 'i18n/messages/sv.json';

const messages = {
  fi: fiMessages,
  en: enMessages,
  sv: svMessages,
};

function changeLocale(language) {
  savePersistLocale(language);
  const locale = language === 'sv' ? 'se' : language;
  moment.locale(`varaamo-${locale}`);
  return updateIntl({
    locale,
    messages: messages[language],
  });
}

export default changeLocale;
<commit_msg>fix persisted state of locale is language to locale se<commit_after>import moment from 'moment';
import { updateIntl } from 'react-intl-redux';

import { savePersistLocale } from 'store/middleware/persistState';
import enMessages from 'i18n/messages/en.json';
import fiMessages from 'i18n/messages/fi.json';
import svMessages from 'i18n/messages/sv.json';

const messages = {
  fi: fiMessages,
  en: enMessages,
  sv: svMessages,
};

function changeLocale(language) {
  const locale = language === 'sv' ? 'se' : language;
  savePersistLocale(locale);

  moment.locale(`varaamo-${locale}`);
  return updateIntl({
    locale,
    messages: messages[language],
  });
}

export default changeLocale;
<|endoftext|>


<commit_before>var bunyan = require("bunyan");
var splunkBunyan = require("splunk-bunyan-logger");

module.exports = function(RED) {
    function HTTPEventCollector(config) {
        RED.nodes.createNode(this,config);
        var context = this.context();
        var node = this;
        var myMessage = null;

        /**
         * Only the token property is required.
         */
        this.myURI = config.inputURI.toString();
        this.myToken = config.inputToken.toString();
        this.mySourcetype = config.inputSourcetype.toString();
        this.myHost = config.inputHost.toString();
        this.mySource = config.inputSource.toString();
        this.myIndex = config.inputIndex.toString();

        var config = {
            token: this.myToken,
            url: this.myURI
        };

        var splunkStream = splunkBunyan.createStream(config);

        // Note: splunkStream must be set to an element in the streams array
        var Logger = bunyan.createLogger({
            name: "my logger",
            streams: [
                splunkStream
            ]
        });

        Logger.error = function(err, context) {
            // Handle errors here
            console.log("error", err, "context", context);
        };

        this.on('input', function(msg) {

            // Attempt to convert msg.payload to a json structure.
            try{
                myMessage = JSON.parse(msg.payload)
            }
            catch(err){
                myMessage = msg.payload
            }

            var payload = {
                // Data sent from previous node msg.payload
                message : { payload: myMessage,
                    msgMetaData : msg
                },
                // Metadata
                metadata: {
                    source: this.mySource,
                    sourcetype: this.mySourcetype,
                    index: this.myIndex,
                    host: this.myHost
                },
                // Severity is also optional
                severity: "info"
            };

            delete payload.message.msgMetaData.payload;

            console.log("Sending payload", payload);
            Logger.info(payload);

        });
    }
    RED.nodes.registerType("http-event-collector",HTTPEventCollector);
};
<commit_msg>Update http-event-collector.js<commit_after>var bunyan = require("bunyan");
var splunkBunyan = require("splunk-bunyan-logger");

module.exports = function(RED) {
    function HTTPEventCollector(config) {
        RED.nodes.createNode(this,config);
        var context = this.context();
        var node = this;
        var myMessage = null;

        /**
         * Only the token property is required.
         */
        this.myURI = config.inputURI.toString();
        this.myToken = config.inputToken.toString();
        this.mySourcetype = config.inputSourcetype.toString();
        this.myHost = config.inputHost.toString();
        this.mySource = config.inputSource.toString();
        this.myIndex = config.inputIndex.toString();

        var config = {
            token: this.myToken,
            url: this.myURI
        };

        var splunkStream = splunkBunyan.createStream(config);

        // Note: splunkStream must be set to an element in the streams array
        var Logger = bunyan.createLogger({
            name: "my logger",
            streams: [
                splunkStream
            ]
        });

        Logger.error = function(err, context) {
            // Handle errors here
            console.log("error", err, "context", context);
        };

        this.on('input', function(msg) {

            // Attempt to convert msg.payload to a json structure.
            try{
                myMessage = JSON.parse(msg.payload)
            }
            catch(err){
                myMessage = msg.payload
            }

            var payload = {
                // Data sent from previous node msg.payload
                message : { payload: myMessage,
                    msgMetaData : msg
                },
                // Metadata
                metadata: {
                    source: this.mySource,
                    sourcetype: this.mySourcetype,
                    index: this.myIndex,
                    host: this.myHost
                },
                // Severity is also optional
                severity: "info"
            };

            delete payload.message.msgMetaData.payload;
            delete payload.msg;

            console.log("Sending payload", payload);
            Logger.info(payload);

        });
    }
    RED.nodes.registerType("http-event-collector",HTTPEventCollector);
};
<|endoftext|>


<commit_before>angular.module('project', ['ngRoute', 'firebase'])

.config(function($routeProvider) {

        $routeProvider
            .when('/', {
                controller: 'ProjectController as projectctrl',
                templateUrl: 'main.html'
                    //resolve: resolveProjects
            })
            // .when('/edit/:projectId', {
            //   controller:'EditProjectController as editProject',
            //   templateUrl:'detail.html',
            //   resolve: resolveProjects
            // })
            .otherwise({
                redirectTo: '/'
            });
    })
    .controller('ProjectController', function(projects) {
        var vm = this;
    });<commit_msg>Remove dependency<commit_after>angular.module('project', ['ngRoute', 'firebase'])

.config(function($routeProvider) {

        $routeProvider
            .when('/', {
                controller: 'ProjectController as projectctrl',
                templateUrl: 'main.html'
                    //resolve: resolveProjects
            })
            // .when('/edit/:projectId', {
            //   controller:'EditProjectController as editProject',
            //   templateUrl:'detail.html',
            //   resolve: resolveProjects
            // })
            .otherwise({
                redirectTo: '/'
            });
    })
    .controller('ProjectController', function() {
        var vm = this;
    });<|endoftext|>


<commit_before>'use strict';
import config from './config';

console.log.apply(console, config.consoleMessage);
console.log('Environment', config.environment);

mapboxgl.accessToken = config.mapboxToken;
var nav = mapboxgl.NavigationControl();

if (!mapboxgl.supported()) {
  document.getElementById('map').innerHTML = 'Your browser does not support Mapbox GL';
} else {
  var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/light-v9',
    center: [60, 2.867],
    zoom: 1.5
  })
  attachDataToMap(map, config.dataLayer)
}

function attachDataToMap(theMap, tilejson) {
  theMap.on('load', function () {
    fetch(tilejson)
    .then(function (response) {
      return response.json()
    }).then(function (tilejson) {
      var layer = tilejson;
      layer.type = 'vector'
      theMap.addSource('data', layer)
      theMap.fitBounds([[layer.bounds[0], layer.bounds[1]], [layer.bounds[2], layer.bounds[3]]], {padding: 20})
      theMap.addControl(new mapboxgl.NavigationControl(), 'top-left')
      theMap.addLayer({
        'id': 'data',
        'type': 'line',
        'source': 'data',
        'source-layer': 'data_layer',
        'layout': {
          'line-join': 'round',
          'line-cap': 'round'
        },
        'paint': {
          'line-color': {
            'property': 'voltage_kV',
            'type': 'interval',
            'stops': [
              // LV
              [0, '#0288D1'],
              // MV
              [1, '#689F38'],
              // HV
              [66, '#F57C00'],
              // UHV
              [225, '#5D4037']
            ]
          },
          'line-width': {
            'stops': [
              [5,1],
              [10,2]
            ]
          },
          // 'line-width': {
          //   'property': 'status',
          //   'type': 'categorical',
          //   'stops': [
          //     ['Planned', 1],
          //     ['Existing', 3]
          //   ]
          // },
          // 'line-gap-width': {
          //   'property': 'status',
          //   'type': 'categorical',
          //   'stops': [
          //     ['Planned', 2]
          //   ]
          // },
          // 'line-blur': {
          //   'property': 'status',
          //   'type': 'categorical',
          //   'stops': [
          //     ['Planned', 1]
          //   ]
          // }
        }
      })
    })
  })
};

// Filter the map data by property
document.getElementById('filter').addEventListener('click',function(e) {
  if(e.target && e.target.className == 'status-filter') {
    var clickedOption = e.target.innerText;
    e.preventDefault();

    switch (clickedOption) {
      case 'All':
        map.setFilter('data', ['!=', 'status', 'Decommissioned']);
      case 'Planned':
        map.setFilter('data', ['in', 'status', 'Planned', 'Construction'])
      case 'Existing':
        map.setFilter('data', ['==', 'status', 'Existing'])
    }

    // Remove .active from all items
    document.querySelectorAll('.status-filter').forEach(function(o) {o.classList.remove('active')})
    e.target.classList.add('active')
  }
});

// Open the modal
document.getElementById('modal-open').addEventListener('click',function(e) {
  e.preventDefault();
  let modal = document.getElementById('about-modal')
  modal.classList.remove('modal-leave', 'modal-leave-active')
  modal.classList.add('modal-enter', 'modal-enter-active')
});

// Close the modal when somebody clicks the Dismiss icon, or outside the modal
document.querySelectorAll('#about-modal, #modal-dismiss').forEach(function(o) {
  o.addEventListener('click',function(e) {
    e.preventDefault();
    let modal = document.getElementById('about-modal')
    modal.classList.remove('modal-enter', 'modal-enter-active')
    modal.classList.add('modal-leave', 'modal-leave-active')
  })
})

// Don't close if somebody clicks on the model itself
document.getElementById('about-modal-inner').addEventListener('click', function(e) {
  e.stopPropagation();
});<commit_msg>Lowercase before comparing<commit_after>'use strict';
import config from './config';

console.log.apply(console, config.consoleMessage);
console.log('Environment', config.environment);

mapboxgl.accessToken = config.mapboxToken;
var nav = mapboxgl.NavigationControl();

if (!mapboxgl.supported()) {
  document.getElementById('map').innerHTML = 'Your browser does not support Mapbox GL';
} else {
  var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/light-v9',
    center: [60, 2.867],
    zoom: 1.5
  })
  attachDataToMap(map, config.dataLayer)
}

function attachDataToMap(theMap, tilejson) {
  theMap.on('load', function () {
    fetch(tilejson)
    .then(function (response) {
      return response.json()
    }).then(function (tilejson) {
      var layer = tilejson;
      layer.type = 'vector'
      theMap.addSource('data', layer)
      theMap.fitBounds([[layer.bounds[0], layer.bounds[1]], [layer.bounds[2], layer.bounds[3]]], {padding: 20})
      theMap.addControl(new mapboxgl.NavigationControl(), 'top-left')
      theMap.addLayer({
        'id': 'data',
        'type': 'line',
        'source': 'data',
        'source-layer': 'data_layer',
        'layout': {
          'line-join': 'round',
          'line-cap': 'round'
        },
        'paint': {
          'line-color': {
            'property': 'voltage_kV',
            'type': 'interval',
            'stops': [
              // LV
              [0, '#0288D1'],
              // MV
              [1, '#689F38'],
              // HV
              [66, '#F57C00'],
              // UHV
              [225, '#5D4037']
            ]
          },
          'line-width': {
            'stops': [
              [5,1],
              [10,2]
            ]
          },
          // 'line-width': {
          //   'property': 'status',
          //   'type': 'categorical',
          //   'stops': [
          //     ['Planned', 1],
          //     ['Existing', 3]
          //   ]
          // },
          // 'line-gap-width': {
          //   'property': 'status',
          //   'type': 'categorical',
          //   'stops': [
          //     ['Planned', 2]
          //   ]
          // },
          // 'line-blur': {
          //   'property': 'status',
          //   'type': 'categorical',
          //   'stops': [
          //     ['Planned', 1]
          //   ]
          // }
        }
      })
    })
  })
};

// Filter the map data by property
document.getElementById('filter').addEventListener('click',function(e) {
  if(e.target && e.target.className == 'status-filter') {
    var clickedOption = e.target.innerText.toLowerCase();
    e.preventDefault();

    switch (clickedOption) {
      case 'all':
        map.setFilter('data', ['!=', 'status', 'Decommissioned']);
        break
      case 'planned':
        map.setFilter('data', ['in', 'status', 'Planned', 'Construction'])
        break
      case 'existing':
        map.setFilter('data', ['==', 'status', 'Existing'])
    }

    // Remove .active from all items
    document.querySelectorAll('.status-filter').forEach(function(o) {o.classList.remove('active')})
    e.target.classList.add('active')
  }
});

// Open the modal
document.getElementById('modal-open').addEventListener('click',function(e) {
  e.preventDefault();
  let modal = document.getElementById('about-modal')
  modal.classList.remove('modal-leave', 'modal-leave-active')
  modal.classList.add('modal-enter', 'modal-enter-active')
});

// Close the modal when somebody clicks the Dismiss icon, or outside the modal
document.querySelectorAll('#about-modal, #modal-dismiss').forEach(function(o) {
  o.addEventListener('click',function(e) {
    e.preventDefault();
    let modal = document.getElementById('about-modal')
    modal.classList.remove('modal-enter', 'modal-enter-active')
    modal.classList.add('modal-leave', 'modal-leave-active')
  })
})

// Don't close if somebody clicks on the model itself
document.getElementById('about-modal-inner').addEventListener('click', function(e) {
  e.stopPropagation();
});<|endoftext|>


<commit_before>var assert = require('assert');
var should = require('should');

var options = {
  desiredCapabilities: {
    browserName: 'phantomjs'
  }
};

var client;
if (process.env.TRAVIS) {
  options = {
    browserA: {
      host: 'ondemand.saucelabs.com',
      port: 80,
      user: process.env.SAUCE_USERNAME,
      key: process.env.SAUCE_ACCESS_KEY,
      desiredCapabilities: {
        browserName: 'chrome',
        version: '27',
        platform: ['Windows 7', 'Windows 8']
      }
    },
    browserB: {
      host: 'ondemand.saucelabs.com',
      port: 80,
      user: process.env.SAUCE_USERNAME,
      key: process.env.SAUCE_ACCESS_KEY,
      desiredCapabilities: {
        browserName: 'internet explorer',
        version: '9',
        platform: 'Windows 7'
      }
    }

  };

  client = require('webdriverio').multiremote(options).init();
} else {
  client = require('webdriverio').remote(options).init();
}

describe('Docs website e2e', function() {
  this.timeout(1000000);

  before(function(done) {
    client.url('http://localhost:8000/docs/', done);
  });

  it('loads the title for the docs home page', function(done) {
    client
      .getTitle(function(err, title) {
        if (err) {
          should.fail('Expected the title to be returned.');
        }
        assert.equal(title, 'Grommet - User Experience for the Enterprise');
        done();
      });
  });

  after(function(done) {
    client.end(done);
  });
});<commit_msg>Removed multiremote for now.<commit_after>var assert = require('assert');
var should = require('should');

var options = {
  desiredCapabilities: {
    browserName: 'phantomjs'
  }
};

var client;
if (process.env.TRAVIS) {
  options = {
    host: 'ondemand.saucelabs.com',
    port: 80,
    user: process.env.SAUCE_USERNAME,
    key: process.env.SAUCE_ACCESS_KEY,
    desiredCapabilities: {
      browserName: 'chrome',
      version: '27',
      platform: ['Windows 7', 'Windows 8']
    }
  };
}

client = require('webdriverio').remote(options).init();

describe('Docs website e2e', function() {
  this.timeout(1000000);

  before(function(done) {
    client.url('http://localhost:8000/docs/', done);
  });

  it('loads the title for the docs home page', function(done) {
    client
      .getTitle(function(err, title) {
        if (err) {
          should.fail('Expected the title to be returned.');
        }
        assert.equal(title, 'Grommet - User Experience for the Enterprise');
        done();
      });
  });

  after(function(done) {
    client.end(done);
  });
});
<|endoftext|>