<commit_before>/*
 * Licensed to Cloudkick, Inc ('Cloudkick') under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * Cloudkick licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var sys = require('sys');

var sprintf = require('extern/sprintf').sprintf;

var terminal = require('util/terminal');
var http = require('util/http');

var config = {
  shortDescription: 'List all the bundles which are currently deployed.',
  longDescription: 'List all the bundles which are currently deployed.',
  requiredArguments: [],
  optionalArguments: [],
  usesGlobalOptions: ['remote']
};

var handleCommand = function(args) {
  http.getApiResponse(args.remote, '1.0', '/bundles/', 'GET', true,
                    function(error, response) {
    if (error) {
      return sys.puts(sprintf('Error: %s', error.message));
    }

    if (response.statusCode !== 200) {
      return sys.puts(sprintf('HTTP Error, status code: %d, returned body: %s', response.statusCode,
                                                                                response.body.message));
    }

    var bundles = response.body;
    terminal.printTable([{'title': 'Name', 'value_property': 'name', 'padding_right': 30},
                          {'title': 'Version', 'value_property': 'version', 'padding_right': 20}],
                          bundles,
                          'No bundles available');
  });
};

exports.config = config;
exports.handleCommand = handleCommand;
<commit_msg>fix call to printTable in 'bundles list'<commit_after>/*
 * Licensed to Cloudkick, Inc ('Cloudkick') under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * Cloudkick licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var sys = require('sys');

var sprintf = require('extern/sprintf').sprintf;

var terminal = require('util/terminal');
var http = require('util/http');

var config = {
  shortDescription: 'List all the bundles which are currently deployed.',
  longDescription: 'List all the bundles which are currently deployed.',
  requiredArguments: [],
  optionalArguments: [],
  usesGlobalOptions: ['remote']
};

var handleCommand = function(args) {
  http.getApiResponse(args.remote, '1.0', '/bundles/', 'GET', true,
                    function(error, response) {
    if (error) {
      return sys.puts(sprintf('Error: %s', error.message));
    }

    if (response.statusCode !== 200) {
      return sys.puts(sprintf('HTTP Error, status code: %d, returned body: %s', response.statusCode,
                                                                                response.body.message));
    }

    var bundles = response.body;
    terminal.printTable([
      {
        title: 'Name',
        valueProperty: 'name',
        paddingRight: 30
      },
      {
        title: 'Version',
        valueProperty: 'version',
        paddingRight: 20
      }
    ], bundles, 'No bundles available');
  });
};

exports.config = config;
exports.handleCommand = handleCommand;
<|endoftext|>


<commit_before>import crossfilter from 'crossfilter'; // eslint-disable-line import/no-unresolved
import moment from 'moment-timezone';
import _ from 'lodash';
import bows from 'bows';

import { getTotalBasalFromEndpoints, getBasalGroupDurationsFromEndpoints } from './basal';
import { getTotalBolus } from './bolus';
import { cgmSampleFrequency, classifyBgValue, reshapeBgClassesToBgBounds } from './bloodglucose';
import { addDuration } from './datetime';
import { getLatestPumpUpload } from './device';
import { MGDL_UNITS, MGDL_PER_MMOLL, MS_IN_DAY } from './constants';

/* eslint-disable lodash/prefer-lodash-method, no-underscore-dangle, no-param-reassign */

export class DataUtil {
  /**
   * @param {Object} bgBounds - object describing boundaries for blood glucose categories
   * @param {Array} data Unfiltered tideline data
   * @param {Array} endpoints Array ISO strings [start, end]
   */
  constructor(data, opts = {}) {
    this.log = bows('DataUtil');

    this.data = crossfilter(data);
    this._endpoints = opts.endpoints || [];
    this._chartPrefs = opts.chartPrefs || {};
    this.bgBounds = reshapeBgClassesToBgBounds(opts.bgPrefs);
    this.timeZoneName = _.get(opts, 'timePrefs.timezoneName', 'UTC');
    this.bgUnits = _.get(opts, 'bgPrefs.bgUnits');
    this.days = this.getDayCountFromEndpoints();
    this.dimension = {};
    this.filter = {};
    this.sort = {};

    this.buildDimensions();
    this.buildFilters();
    this.buildSorts();

    this.bgSources = this.getBgSources();
    this.defaultBgSource = this.getDefaultBgSource();
    this.latestPump = this.getLatestPump();

    this.log('bgSource', this.bgSource);
    this.log('timeZoneName', this.timeZoneName);
    this.log('endpoints', this._endpoints);
  }

  get bgSource() {
    return _.get(this._chartPrefs, ['bgSource'], this.defaultBgSource);
  }

  set chartPrefs(chartPrefs = {}) {
    this._chartPrefs = chartPrefs;
  }

  set endpoints(endpoints = []) {
    this._endpoints = endpoints;
    this.days = this.getDayCountFromEndpoints();

    this.log('endpoints', this._endpoints);
  }

  addData = data => {
    this.data.add(data);
    this.bgSources = this.getBgSources();
    this.defaultBgSource = this.getDefaultBgSource();
  };

  addBasalOverlappingStart = (basalData) => {
    if (basalData.length && basalData[0].normalTime > this._endpoints[0]) {
      // Fetch last basal from previous day
      this.filter.byEndpoints([
        addDuration(this._endpoints[0], -MS_IN_DAY),
        this._endpoints[0],
      ]);

      const previousBasalDatum = this.sort
        .byDate(this.filter.byType('basal').top(Infinity))
        .reverse()[0];

      // Add to top of basal data array if it overlaps the start endpoint
      const datumOverlapsStart = previousBasalDatum
        && previousBasalDatum.normalTime < this._endpoints[0]
        && previousBasalDatum.normalEnd > this._endpoints[0];

      if (datumOverlapsStart) {
        basalData.unshift(previousBasalDatum);
      }
    }
    return basalData;
  };

  applyDateFilters = () => {
    this.filter.byEndpoints(this._endpoints);

    this.dimension.byDayOfWeek.filterAll();

    const daysInRange = this.getDayCountFromEndpoints();
    this.days = daysInRange;

    if (this._chartPrefs.activeDays) {
      const activeDays = _.reduce(this._chartPrefs.activeDays, (result, active, day) => {
        if (active) {
          result.push(this.getDayIndex(day));
        }
        return result;
      }, []);

      this.filter.byActiveDays(activeDays);

      this.days = daysInRange / 7 * activeDays.length;
    }
  }

  buildDimensions = () => {
    this.dimension.byDate = this.data.dimension(d => d.normalTime);

    this.dimension.byDayOfWeek = this.data.dimension(
      d => moment.utc(d.normalTime).tz(this.timeZoneName).day()
    );

    this.dimension.byType = this.data.dimension(d => d.type);
  };

  buildFilters = () => {
    this.filter.byActiveDays = activeDays => this.dimension.byDayOfWeek
      .filterFunction(d => _.includes(activeDays, d));

    this.filter.byEndpoints = endpoints => this.dimension.byDate.filterRange(endpoints);
    this.filter.byType = type => this.dimension.byType.filterExact(type);
  };

  buildSorts = () => {
    this.sort.byDate = array => (
      crossfilter.quicksort.by(d => d.normalTime)(array, 0, array.length)
    );
  };

  clearFilters = () => {
    this.dimension.byDate.filterAll();
    this.dimension.byDayOfWeek.filterAll();
    this.dimension.byType.filterAll();
  };

  getAverageGlucoseData = (returnBgData = false) => {
    this.applyDateFilters();

    const bgData = this.filter.byType(this.bgSource).top(Infinity);

    const data = {
      averageGlucose: _.meanBy(bgData, 'value'),
      total: bgData.length,
    };

    if (returnBgData) {
      data.bgData = bgData;
    }

    return data;
  };

  getBasalBolusData = () => {
    this.applyDateFilters();

    const bolusData = this.filter.byType('bolus').top(Infinity);
    let basalData = this.sort.byDate(this.filter.byType('basal').top(Infinity).reverse());
    basalData = this.addBasalOverlappingStart(basalData);

    const basalBolusData = {
      basal: basalData.length
        ? parseFloat(getTotalBasalFromEndpoints(basalData, this._endpoints))
        : NaN,
      bolus: bolusData.length ? getTotalBolus(bolusData) : NaN,
    };

    if (this.days > 1) {
      basalBolusData.basal = basalBolusData.basal / this.days;
      basalBolusData.bolus = basalBolusData.bolus / this.days;
    }

    return basalBolusData;
  };

  getBgSources = () => {
    this.clearFilters();
    return {
      cbg: this.filter.byType('cbg').top(Infinity).length > 0,
      smbg: this.filter.byType('smbg').top(Infinity).length > 0,
    };
  };

  getCarbsData = () => {
    this.applyDateFilters();

    const wizardData = this.filter.byType('wizard').top(Infinity);

    let carbs = _.reduce(
      wizardData,
      (result, datum) => result + _.get(datum, 'carbInput', 0),
      0
    );

    if (this.days > 1) {
      carbs = carbs / this.days;
    }

    return {
      carbs,
      total: wizardData.length,
    };
  };

  getCoefficientOfVariationData = () => {
    const {
      averageGlucose,
      insufficientData,
      standardDeviation,
      total,
    } = this.getStandardDevData();

    const coefficientOfVariationData = {
      coefficientOfVariation: standardDeviation / averageGlucose * 100,
      total,
    };

    if (insufficientData) {
      coefficientOfVariationData.insufficientData = true;
    }

    return coefficientOfVariationData;
  };

  getDailyAverageSums = data => {
    const clone = _.clone(data);

    _.each(clone, (value, key) => {
      if (key !== 'total') {
        clone[key] = value / this.days;
      }
    });

    return clone;
  };

  getDailyAverageDurations = data => {
    const clone = _.clone(data);
    const total = data.total || _.sum(_.values(data));

    _.each(clone, (value, key) => {
      if (key !== 'total') {
        clone[key] = (value / total) * MS_IN_DAY;
      }
    });

    return clone;
  };

  getDefaultBgSource = () => {
    let source;
    if (this.bgSources.cbg) {
      source = 'cbg';
    } else if (this.bgSources.smbg) {
      source = 'smbg';
    }
    return source;
  };

  getDayCountFromEndpoints = () => moment.utc(this._endpoints[1])
    .diff(moment.utc(this._endpoints[0])) / MS_IN_DAY;

  getDayIndex = day => {
    const dayMap = {
      sunday: 0,
      monday: 1,
      tuesday: 2,
      wednesday: 3,
      thursday: 4,
      friday: 5,
      saturday: 6,
    };

    return dayMap[day];
  };

  getGlucoseManagementIndicatorData = () => {
    const { averageGlucose, bgData, total } = this.getAverageGlucoseData(true);

    const getTotalCbgDuration = () => _.reduce(
      bgData,
      (result, datum) => {
        result += cgmSampleFrequency(datum);
        return result;
      },
      0
    );

    const insufficientData = this.bgSource === 'smbg'
      || this.getDayCountFromEndpoints() < 14
      || getTotalCbgDuration() < 14 * MS_IN_DAY * 0.7;

    if (insufficientData) {
      return {
        glucoseManagementIndicator: NaN,
        insufficientData: true,
      };
    }

    const meanInMGDL = this.bgUnits === MGDL_UNITS
      ? averageGlucose
      : averageGlucose * MGDL_PER_MMOLL;

    const glucoseManagementIndicator = (3.31 + 0.02392 * meanInMGDL);

    return {
      glucoseManagementIndicator,
      total,
    };
  };

  getLatestPump = () => {
    const uploadData = this.sort.byDate(this.filter.byType('upload').top(Infinity));
    const latestPumpUpload = getLatestPumpUpload(uploadData);
    const latestUploadSource = _.get(latestPumpUpload, 'source', '').toLowerCase();
    return {
      deviceModel: _.get(latestPumpUpload, 'deviceModel', ''),
      manufacturer: latestUploadSource === 'carelink' ? 'medtronic' : latestUploadSource,
    };
  };

  getReadingsInRangeData = () => {
    this.applyDateFilters();

    let smbgData = _.reduce(
      this.filter.byType('smbg').top(Infinity),
      (result, datum) => {
        const classification = classifyBgValue(this.bgBounds, datum.value, 'fiveWay');
        result[classification]++;
        result.total++;
        return result;
      },
      {
        veryLow: 0,
        low: 0,
        target: 0,
        high: 0,
        veryHigh: 0,
        total: 0,
      }
    );

    if (this.days > 1) {
      smbgData = this.getDailyAverageSums(smbgData);
    }

    return smbgData;
  };

  getSensorUsage = () => {
    this.applyDateFilters();
    const cbgData = this.filter.byType('cbg').top(Infinity);

    const duration = _.reduce(
      cbgData,
      (result, datum) => {
        result += cgmSampleFrequency(datum);
        return result;
      },
      0
    );

    const total = this.days * MS_IN_DAY;

    return {
      sensorUsage: duration,
      total,
    };
  };

  getStandardDevData = () => {
    const { averageGlucose, bgData, total } = this.getAverageGlucoseData(true);

    if (bgData.length < 3) {
      return {
        averageGlucose,
        insufficientData: true,
        standardDeviation: NaN,
        total,
      };
    }

    const squaredDiffs = _.map(bgData, d => (d.value - averageGlucose) ** 2);
    const standardDeviation = Math.sqrt(_.sum(squaredDiffs) / (bgData.length - 1));

    return {
      averageGlucose,
      standardDeviation,
      total,
    };
  };

  getTimeInAutoData = () => {
    this.applyDateFilters();

    let basalData = this.sort.byDate(this.filter.byType('basal').top(Infinity));
    basalData = this.addBasalOverlappingStart(basalData);

    let durations = basalData.length
      ? _.transform(
        getBasalGroupDurationsFromEndpoints(basalData, this._endpoints),
        (result, value, key) => {
          result[key] = value;
          return result;
        },
        {},
      )
      : NaN;

    if (this.days > 1 && !_.isNaN(durations)) {
      durations = this.getDailyAverageDurations(durations);
    }

    return durations;
  };

  getTimeInRangeData = () => {
    this.applyDateFilters();
    const cbgData = this.filter.byType('cbg').top(Infinity);

    let durations = _.reduce(
      cbgData,
      (result, datum) => {
        const classification = classifyBgValue(this.bgBounds, datum.value, 'fiveWay');
        const duration = cgmSampleFrequency(datum);
        result[classification] += duration;
        result.total += duration;
        return result;
      },
      {
        veryLow: 0,
        low: 0,
        target: 0,
        high: 0,
        veryHigh: 0,
        total: 0,
      }
    );

    if (this.days > 1) {
      durations = this.getDailyAverageDurations(durations);
    }

    return durations;
  };

  getTotalInsulinData = () => {
    const { basal, bolus } = this.getBasalBolusData();

    const totalInsulin = _.reduce([basal, bolus], (result, value) => {
      const delivered = _.isNaN(value) ? 0 : value || 0;
      return result + delivered;
    }, 0);

    return {
      totalInsulin,
    };
  };
}

export default DataUtil;
<commit_msg>Log days in range when dataUtil enpoints are set<commit_after>import crossfilter from 'crossfilter'; // eslint-disable-line import/no-unresolved
import moment from 'moment-timezone';
import _ from 'lodash';
import bows from 'bows';

import { getTotalBasalFromEndpoints, getBasalGroupDurationsFromEndpoints } from './basal';
import { getTotalBolus } from './bolus';
import { cgmSampleFrequency, classifyBgValue, reshapeBgClassesToBgBounds } from './bloodglucose';
import { addDuration } from './datetime';
import { getLatestPumpUpload } from './device';
import { MGDL_UNITS, MGDL_PER_MMOLL, MS_IN_DAY } from './constants';

/* eslint-disable lodash/prefer-lodash-method, no-underscore-dangle, no-param-reassign */

export class DataUtil {
  /**
   * @param {Object} bgBounds - object describing boundaries for blood glucose categories
   * @param {Array} data Unfiltered tideline data
   * @param {Array} endpoints Array ISO strings [start, end]
   */
  constructor(data, opts = {}) {
    this.log = bows('DataUtil');

    this.data = crossfilter(data);
    this._endpoints = opts.endpoints || [];
    this._chartPrefs = opts.chartPrefs || {};
    this.bgBounds = reshapeBgClassesToBgBounds(opts.bgPrefs);
    this.timeZoneName = _.get(opts, 'timePrefs.timezoneName', 'UTC');
    this.bgUnits = _.get(opts, 'bgPrefs.bgUnits');
    this.days = this.getDayCountFromEndpoints();
    this.dimension = {};
    this.filter = {};
    this.sort = {};

    this.buildDimensions();
    this.buildFilters();
    this.buildSorts();

    this.bgSources = this.getBgSources();
    this.defaultBgSource = this.getDefaultBgSource();
    this.latestPump = this.getLatestPump();

    this.log('bgSource', this.bgSource);
    this.log('timeZoneName', this.timeZoneName);
    this.log('endpoints', this._endpoints);
  }

  get bgSource() {
    return _.get(this._chartPrefs, ['bgSource'], this.defaultBgSource);
  }

  set chartPrefs(chartPrefs = {}) {
    this._chartPrefs = chartPrefs;
  }

  set endpoints(endpoints = []) {
    this._endpoints = endpoints;
    this.days = this.getDayCountFromEndpoints();

    this.log('endpoints', this._endpoints, 'days in range', this.days);
  }

  addData = data => {
    this.data.add(data);
    this.bgSources = this.getBgSources();
    this.defaultBgSource = this.getDefaultBgSource();
  };

  addBasalOverlappingStart = (basalData) => {
    if (basalData.length && basalData[0].normalTime > this._endpoints[0]) {
      // Fetch last basal from previous day
      this.filter.byEndpoints([
        addDuration(this._endpoints[0], -MS_IN_DAY),
        this._endpoints[0],
      ]);

      const previousBasalDatum = this.sort
        .byDate(this.filter.byType('basal').top(Infinity))
        .reverse()[0];

      // Add to top of basal data array if it overlaps the start endpoint
      const datumOverlapsStart = previousBasalDatum
        && previousBasalDatum.normalTime < this._endpoints[0]
        && previousBasalDatum.normalEnd > this._endpoints[0];

      if (datumOverlapsStart) {
        basalData.unshift(previousBasalDatum);
      }
    }
    return basalData;
  };

  applyDateFilters = () => {
    this.filter.byEndpoints(this._endpoints);

    this.dimension.byDayOfWeek.filterAll();

    const daysInRange = this.getDayCountFromEndpoints();
    this.days = daysInRange;

    if (this._chartPrefs.activeDays) {
      const activeDays = _.reduce(this._chartPrefs.activeDays, (result, active, day) => {
        if (active) {
          result.push(this.getDayIndex(day));
        }
        return result;
      }, []);

      this.filter.byActiveDays(activeDays);

      this.days = daysInRange / 7 * activeDays.length;
    }
  }

  buildDimensions = () => {
    this.dimension.byDate = this.data.dimension(d => d.normalTime);

    this.dimension.byDayOfWeek = this.data.dimension(
      d => moment.utc(d.normalTime).tz(this.timeZoneName).day()
    );

    this.dimension.byType = this.data.dimension(d => d.type);
  };

  buildFilters = () => {
    this.filter.byActiveDays = activeDays => this.dimension.byDayOfWeek
      .filterFunction(d => _.includes(activeDays, d));

    this.filter.byEndpoints = endpoints => this.dimension.byDate.filterRange(endpoints);
    this.filter.byType = type => this.dimension.byType.filterExact(type);
  };

  buildSorts = () => {
    this.sort.byDate = array => (
      crossfilter.quicksort.by(d => d.normalTime)(array, 0, array.length)
    );
  };

  clearFilters = () => {
    this.dimension.byDate.filterAll();
    this.dimension.byDayOfWeek.filterAll();
    this.dimension.byType.filterAll();
  };

  getAverageGlucoseData = (returnBgData = false) => {
    this.applyDateFilters();

    const bgData = this.filter.byType(this.bgSource).top(Infinity);

    const data = {
      averageGlucose: _.meanBy(bgData, 'value'),
      total: bgData.length,
    };

    if (returnBgData) {
      data.bgData = bgData;
    }

    return data;
  };

  getBasalBolusData = () => {
    this.applyDateFilters();

    const bolusData = this.filter.byType('bolus').top(Infinity);
    let basalData = this.sort.byDate(this.filter.byType('basal').top(Infinity).reverse());
    basalData = this.addBasalOverlappingStart(basalData);

    const basalBolusData = {
      basal: basalData.length
        ? parseFloat(getTotalBasalFromEndpoints(basalData, this._endpoints))
        : NaN,
      bolus: bolusData.length ? getTotalBolus(bolusData) : NaN,
    };

    if (this.days > 1) {
      basalBolusData.basal = basalBolusData.basal / this.days;
      basalBolusData.bolus = basalBolusData.bolus / this.days;
    }

    return basalBolusData;
  };

  getBgSources = () => {
    this.clearFilters();
    return {
      cbg: this.filter.byType('cbg').top(Infinity).length > 0,
      smbg: this.filter.byType('smbg').top(Infinity).length > 0,
    };
  };

  getCarbsData = () => {
    this.applyDateFilters();

    const wizardData = this.filter.byType('wizard').top(Infinity);

    let carbs = _.reduce(
      wizardData,
      (result, datum) => result + _.get(datum, 'carbInput', 0),
      0
    );

    if (this.days > 1) {
      carbs = carbs / this.days;
    }

    return {
      carbs,
      total: wizardData.length,
    };
  };

  getCoefficientOfVariationData = () => {
    const {
      averageGlucose,
      insufficientData,
      standardDeviation,
      total,
    } = this.getStandardDevData();

    const coefficientOfVariationData = {
      coefficientOfVariation: standardDeviation / averageGlucose * 100,
      total,
    };

    if (insufficientData) {
      coefficientOfVariationData.insufficientData = true;
    }

    return coefficientOfVariationData;
  };

  getDailyAverageSums = data => {
    const clone = _.clone(data);

    _.each(clone, (value, key) => {
      if (key !== 'total') {
        clone[key] = value / this.days;
      }
    });

    return clone;
  };

  getDailyAverageDurations = data => {
    const clone = _.clone(data);
    const total = data.total || _.sum(_.values(data));

    _.each(clone, (value, key) => {
      if (key !== 'total') {
        clone[key] = (value / total) * MS_IN_DAY;
      }
    });

    return clone;
  };

  getDefaultBgSource = () => {
    let source;
    if (this.bgSources.cbg) {
      source = 'cbg';
    } else if (this.bgSources.smbg) {
      source = 'smbg';
    }
    return source;
  };

  getDayCountFromEndpoints = () => moment.utc(this._endpoints[1])
    .diff(moment.utc(this._endpoints[0])) / MS_IN_DAY;

  getDayIndex = day => {
    const dayMap = {
      sunday: 0,
      monday: 1,
      tuesday: 2,
      wednesday: 3,
      thursday: 4,
      friday: 5,
      saturday: 6,
    };

    return dayMap[day];
  };

  getGlucoseManagementIndicatorData = () => {
    const { averageGlucose, bgData, total } = this.getAverageGlucoseData(true);

    const getTotalCbgDuration = () => _.reduce(
      bgData,
      (result, datum) => {
        result += cgmSampleFrequency(datum);
        return result;
      },
      0
    );

    const insufficientData = this.bgSource === 'smbg'
      || this.getDayCountFromEndpoints() < 14
      || getTotalCbgDuration() < 14 * MS_IN_DAY * 0.7;

    if (insufficientData) {
      return {
        glucoseManagementIndicator: NaN,
        insufficientData: true,
      };
    }

    const meanInMGDL = this.bgUnits === MGDL_UNITS
      ? averageGlucose
      : averageGlucose * MGDL_PER_MMOLL;

    const glucoseManagementIndicator = (3.31 + 0.02392 * meanInMGDL);

    return {
      glucoseManagementIndicator,
      total,
    };
  };

  getLatestPump = () => {
    const uploadData = this.sort.byDate(this.filter.byType('upload').top(Infinity));
    const latestPumpUpload = getLatestPumpUpload(uploadData);
    const latestUploadSource = _.get(latestPumpUpload, 'source', '').toLowerCase();
    return {
      deviceModel: _.get(latestPumpUpload, 'deviceModel', ''),
      manufacturer: latestUploadSource === 'carelink' ? 'medtronic' : latestUploadSource,
    };
  };

  getReadingsInRangeData = () => {
    this.applyDateFilters();

    let smbgData = _.reduce(
      this.filter.byType('smbg').top(Infinity),
      (result, datum) => {
        const classification = classifyBgValue(this.bgBounds, datum.value, 'fiveWay');
        result[classification]++;
        result.total++;
        return result;
      },
      {
        veryLow: 0,
        low: 0,
        target: 0,
        high: 0,
        veryHigh: 0,
        total: 0,
      }
    );

    if (this.days > 1) {
      smbgData = this.getDailyAverageSums(smbgData);
    }

    return smbgData;
  };

  getSensorUsage = () => {
    this.applyDateFilters();
    const cbgData = this.filter.byType('cbg').top(Infinity);

    const duration = _.reduce(
      cbgData,
      (result, datum) => {
        result += cgmSampleFrequency(datum);
        return result;
      },
      0
    );

    const total = this.days * MS_IN_DAY;

    return {
      sensorUsage: duration,
      total,
    };
  };

  getStandardDevData = () => {
    const { averageGlucose, bgData, total } = this.getAverageGlucoseData(true);

    if (bgData.length < 3) {
      return {
        averageGlucose,
        insufficientData: true,
        standardDeviation: NaN,
        total,
      };
    }

    const squaredDiffs = _.map(bgData, d => (d.value - averageGlucose) ** 2);
    const standardDeviation = Math.sqrt(_.sum(squaredDiffs) / (bgData.length - 1));

    return {
      averageGlucose,
      standardDeviation,
      total,
    };
  };

  getTimeInAutoData = () => {
    this.applyDateFilters();

    let basalData = this.sort.byDate(this.filter.byType('basal').top(Infinity));
    basalData = this.addBasalOverlappingStart(basalData);

    let durations = basalData.length
      ? _.transform(
        getBasalGroupDurationsFromEndpoints(basalData, this._endpoints),
        (result, value, key) => {
          result[key] = value;
          return result;
        },
        {},
      )
      : NaN;

    if (this.days > 1 && !_.isNaN(durations)) {
      durations = this.getDailyAverageDurations(durations);
    }

    return durations;
  };

  getTimeInRangeData = () => {
    this.applyDateFilters();
    const cbgData = this.filter.byType('cbg').top(Infinity);

    let durations = _.reduce(
      cbgData,
      (result, datum) => {
        const classification = classifyBgValue(this.bgBounds, datum.value, 'fiveWay');
        const duration = cgmSampleFrequency(datum);
        result[classification] += duration;
        result.total += duration;
        return result;
      },
      {
        veryLow: 0,
        low: 0,
        target: 0,
        high: 0,
        veryHigh: 0,
        total: 0,
      }
    );

    if (this.days > 1) {
      durations = this.getDailyAverageDurations(durations);
    }

    return durations;
  };

  getTotalInsulinData = () => {
    const { basal, bolus } = this.getBasalBolusData();

    const totalInsulin = _.reduce([basal, bolus], (result, value) => {
      const delivered = _.isNaN(value) ? 0 : value || 0;
      return result + delivered;
    }, 0);

    return {
      totalInsulin,
    };
  };
}

export default DataUtil;
<|endoftext|>


<commit_before>const Keys = {
  backspace: 8,
  tab: 9,
  enter: 13,
  'return': 13,
  esc: 27,
  space: 32,
  left: 37,
  up: 38,
  right: 39,
  down: 40
};

export default Keys;
<commit_msg>Added ‘/‘ to keys utility.<commit_after>const Keys = {
  backspace: 8,
  tab: 9,
  enter: 13,
  'return': 13,
  esc: 27,
  space: 32,
  left: 37,
  up: 38,
  right: 39,
  down: 40,
  forwardSlash: 191
};

export default Keys;
<|endoftext|>


<commit_before>import {extend} from "lodash";
import SeqCollection from "../model/SeqCollection";

const TreeHelper =  function(msa) {
  this.msa = msa;
  return this;
};

var tf =

    {loadTree: function(cb) {
      return this.msa.g.package.loadPackages(["msa-tnt", "biojs-io-newick"], cb);
    },

    showTree: function(newickStr) {
      var newick = window.require("biojs-io-newick");
      var mt = window.require("msa-tnt");

      if (typeof newickStr === "string") {
        var newickObj = newick.parse_newick(newickStr);
      } else {
        newickObj = newickStr;
      }

      var sel = new mt.selections();
      var treeDiv;
      if(this.msa.el.childNodes.length === 1){
        treeDiv = document.createElement("div");
        this.msa.el.appendChild(treeDiv);
      } else {
        console.log('A tree already exists. It will be overridden.');
        treeDiv = this.msa.el.childNodes[1];
        treeDiv.innerHTML = '';
      }

      const seqs = this.msa.seqs.toJSON();
      //adapt tree ids to sequence ids
      function iterateTree(nwck){
        if(nwck.children != null){
          nwck.children.forEach(x => iterateTree(x));
        } else {
          //found a leave
          let seq = seqs.filter(s => s.name === nwck.name)[0];
          if(seq != null){
            seq.ids = [seq.id];
            nwck.name = seq.id;
          }
        }
      }
      iterateTree(newickObj);

      var nodes = mt.app({
        seqs: seqs,
        tree: newickObj
      });

      console.log("nodes", nodes.seqs);

      var t = new mt.adapters.tree({
        model: nodes,
        el: treeDiv,
        sel: sel
      });

      //treeDiv.style.width = "500px"

      // construct msa in a virtual dom
      var m = new mt.adapters.msa({
          model: nodes,
          sel: sel,
          msa: this.msa
      });

      // remove top collection
      nodes.models.forEach((e) => {
        delete e.collection;
        return Object.setPrototypeOf(e, require("backbone-thin").Model.prototype);
      });

      this.msa.seqs.reset(nodes.models);
      //@msa.draw()
      //@msa.render()
      return console.log(this.msa.seqs);
    },

    // workaround against browserify's static analysis
    require(pkg) {
      return require(pkg);
    }
    };

extend(TreeHelper.prototype , tf);
export default TreeHelper;
<commit_msg>fixed a bug that would cause one sequence to be missing from the alignment/tree<commit_after>import {extend} from "lodash";
import SeqCollection from "../model/SeqCollection";

const TreeHelper =  function(msa) {
  this.msa = msa;
  return this;
};

var tf =

    {loadTree: function(cb) {
      return this.msa.g.package.loadPackages(["msa-tnt", "biojs-io-newick"], cb);
    },

    showTree: function(newickStr) {
      var newick = window.require("biojs-io-newick");
      var mt = window.require("msa-tnt");

      if (typeof newickStr === "string") {
        var newickObj = newick.parse_newick(newickStr);
      } else {
        newickObj = newickStr;
      }

      var sel = new mt.selections();
      var treeDiv;
      if(this.msa.el.childNodes.length === 1){
        treeDiv = document.createElement("div");
        this.msa.el.appendChild(treeDiv);
      } else {
        console.log('A tree already exists. It will be overridden.');
        treeDiv = this.msa.el.childNodes[1];
        treeDiv.innerHTML = '';
      }

      const seqs = this.msa.seqs.toJSON();
      //adapt tree ids to sequence ids
      function iterateTree(nwck){
        if(nwck.children != null){
          nwck.children.forEach(x => iterateTree(x));
        } else {
          //found a leave
          let seq = seqs.filter(s => s.name === nwck.name)[0];
          if(seq != null){
            seq.ids = [`s${seq.id + 1}`];
            nwck.name = `s${seq.id + 1}`;
          }
        }
      }
      iterateTree(newickObj);

      var nodes = mt.app({
        seqs: seqs,
        tree: newickObj
      });

      console.log("nodes", nodes.seqs);

      var t = new mt.adapters.tree({
        model: nodes,
        el: treeDiv,
        sel: sel
      });

      //treeDiv.style.width = "500px"

      // construct msa in a virtual dom
      var m = new mt.adapters.msa({
          model: nodes,
          sel: sel,
          msa: this.msa
      });

      // remove top collection
      nodes.models.forEach((e) => {
        delete e.collection;
        return Object.setPrototypeOf(e, require("backbone-thin").Model.prototype);
      });

      this.msa.seqs.reset(nodes.models);
      //@msa.draw()
      //@msa.render()
      return console.log(this.msa.seqs);
    },

    // workaround against browserify's static analysis
    require(pkg) {
      return require(pkg);
    }
    };

extend(TreeHelper.prototype , tf);
export default TreeHelper;
<|endoftext|>


<commit_before>"use strict";

const Constants = require("../Constants");
const Events = Constants.Events;
const Utils = require("../core/Utils");
const BaseCollection = require("./BaseCollection");

const GuildMember = require("../models/GuildMember");

function createGuildMember(member) {
  if (member.user) member.id = member.user.id;

  return new GuildMember({
    id: member.id,
    guild_id: member.guild_id,
    roles: member.roles,
    mute: member.mute || false,
    deaf: member.deaf || false,
    joined_at: member.joined_at
  });
}

function handleConnectionOpen(data) {
  this.clear();
  data.guilds.forEach(guild => handleCreateGuild.call(this, guild));
  return true;
}

function handleGuildMemberUpdate(member) {
  const memberCollection = this.get(member.guild_id);
  if (!memberCollection) return true;
  memberCollection.mergeOrSet(member.user.id, createGuildMember(member));
  return true;
}

function handleGuildMemberRemove(member) {
  const memberCollection = this.get(member.guild_id);
  if (!memberCollection) return true;
  memberCollection.delete(member.user.id);
  return true;
}

function handleCreateGuild(guild) {
  if (!guild || guild.unavailable) return true;

  const memberCollection = new BaseCollection();
  this.set(guild.id, memberCollection);

  guild.members.forEach(member => {
    member.guild_id = guild.id;
    memberCollection.set(member.user.id, createGuildMember(member));
  });
  return true;
}

function handleDeleteGuild(guild) {
  this.delete(guild.id);
  return true;
}

function handleVoiceStateUpdate(data) {
  const memberCollection = this.get(data.guild_id);
  if (!memberCollection) return true;
  const member = memberCollection.get(data.user_id);
  if (!member) return true;
  memberCollection.set(data.user_id,
    member.merge({
      mute: data.mute,
      deaf: data.deaf
    })
  );
  return true;
}

function handlePresenceUpdate(presence) {
  if (!presence.user || !presence.user.id) return true;

  const memberCollection = this.get(presence.guild_id);
  if (!memberCollection) return true;

  const cachedMember = memberCollection.get(presence.user.id);
  if (!cachedMember) {
    // note: presences only contain roles
    memberCollection.set(presence.user.id, createGuildMember(presence));
  }

  return true;
}

class GuildMemberCollection extends BaseCollection {
  constructor(discordie, gateway) {
    super();

    if (typeof gateway !== "function")
      throw new Error("Gateway parameter must be a function");

    discordie.Dispatcher.on(Events.GATEWAY_READY, e => {
      if (e.socket != gateway()) return;
      (handleConnectionOpen.bind(this))(e.data);
    });
    discordie.Dispatcher.on(Events.GATEWAY_DISPATCH, e => {
      if (e.socket != gateway()) return;

      Utils.bindGatewayEventHandlers(this, e, {
        GUILD_CREATE: handleCreateGuild,
        GUILD_DELETE: handleDeleteGuild,
        GUILD_MEMBER_ADD: handleGuildMemberUpdate,
        GUILD_MEMBER_UPDATE: handleGuildMemberUpdate,
        GUILD_MEMBER_REMOVE: handleGuildMemberRemove,
        VOICE_STATE_UPDATE: handleVoiceStateUpdate,
        PRESENCE_UPDATE: handlePresenceUpdate,
      });
    });

    this._discordie = discordie;
    Utils.privatify(this);
  }
  getMember(guildId, userId) {
    const memberCollection = this.get(guildId);
    if (!memberCollection) return true;
    return memberCollection.get(userId);
  }
}

module.exports = GuildMemberCollection;
<commit_msg>Fix GuildMemberCollection.getMember return value<commit_after>"use strict";

const Constants = require("../Constants");
const Events = Constants.Events;
const Utils = require("../core/Utils");
const BaseCollection = require("./BaseCollection");

const GuildMember = require("../models/GuildMember");

function createGuildMember(member) {
  if (member.user) member.id = member.user.id;

  return new GuildMember({
    id: member.id,
    guild_id: member.guild_id,
    roles: member.roles,
    mute: member.mute || false,
    deaf: member.deaf || false,
    joined_at: member.joined_at
  });
}

function handleConnectionOpen(data) {
  this.clear();
  data.guilds.forEach(guild => handleCreateGuild.call(this, guild));
  return true;
}

function handleGuildMemberUpdate(member) {
  const memberCollection = this.get(member.guild_id);
  if (!memberCollection) return true;
  memberCollection.mergeOrSet(member.user.id, createGuildMember(member));
  return true;
}

function handleGuildMemberRemove(member) {
  const memberCollection = this.get(member.guild_id);
  if (!memberCollection) return true;
  memberCollection.delete(member.user.id);
  return true;
}

function handleCreateGuild(guild) {
  if (!guild || guild.unavailable) return true;

  const memberCollection = new BaseCollection();
  this.set(guild.id, memberCollection);

  guild.members.forEach(member => {
    member.guild_id = guild.id;
    memberCollection.set(member.user.id, createGuildMember(member));
  });
  return true;
}

function handleDeleteGuild(guild) {
  this.delete(guild.id);
  return true;
}

function handleVoiceStateUpdate(data) {
  const memberCollection = this.get(data.guild_id);
  if (!memberCollection) return true;
  const member = memberCollection.get(data.user_id);
  if (!member) return true;
  memberCollection.set(data.user_id,
    member.merge({
      mute: data.mute,
      deaf: data.deaf
    })
  );
  return true;
}

function handlePresenceUpdate(presence) {
  if (!presence.user || !presence.user.id) return true;

  const memberCollection = this.get(presence.guild_id);
  if (!memberCollection) return true;

  const cachedMember = memberCollection.get(presence.user.id);
  if (!cachedMember) {
    // note: presences only contain roles
    memberCollection.set(presence.user.id, createGuildMember(presence));
  }

  return true;
}

class GuildMemberCollection extends BaseCollection {
  constructor(discordie, gateway) {
    super();

    if (typeof gateway !== "function")
      throw new Error("Gateway parameter must be a function");

    discordie.Dispatcher.on(Events.GATEWAY_READY, e => {
      if (e.socket != gateway()) return;
      (handleConnectionOpen.bind(this))(e.data);
    });
    discordie.Dispatcher.on(Events.GATEWAY_DISPATCH, e => {
      if (e.socket != gateway()) return;

      Utils.bindGatewayEventHandlers(this, e, {
        GUILD_CREATE: handleCreateGuild,
        GUILD_DELETE: handleDeleteGuild,
        GUILD_MEMBER_ADD: handleGuildMemberUpdate,
        GUILD_MEMBER_UPDATE: handleGuildMemberUpdate,
        GUILD_MEMBER_REMOVE: handleGuildMemberRemove,
        VOICE_STATE_UPDATE: handleVoiceStateUpdate,
        PRESENCE_UPDATE: handlePresenceUpdate,
      });
    });

    this._discordie = discordie;
    Utils.privatify(this);
  }
  getMember(guildId, userId) {
    const memberCollection = this.get(guildId);
    if (!memberCollection) return null;
    return memberCollection.get(userId);
  }
}

module.exports = GuildMemberCollection;
<|endoftext|>


<commit_before>function listen(...fields) {
  return function(target, key, descriptor) {
    descriptor.value.listen = fields;
  };
}

export class Validation {
  constructor(i18n) {
    this.i18n = i18n;
  }

  required(field) {
    if (field.isEmpty()) {
      return {
        valid: false,
        error: this.i18n.tr('validation.required-is-empty')
      };
    }
    return { valid: true };
  }

  requiredIfLegendTypeIsReference(field) {
    if (field.isEmpty() && field.resolveRef('../x-oad-type').getValue() === 'reference') {
      return {
        valid: false,
        error: this.i18n.tr('validation.required-is-empty')
      };
    }
    return { valid: true };
  }

  keyRequired(field) {
    if (field.key.length === 0) {
      return {
        valid: false,
        error: this.i18n.tr('validation.key-is-required')
      };
    }
    return { valid: true };
  }

  @listen('..')
  requiredIfParent(field) {
    if (field.isEmpty() && !field.parent.isEmpty()) {
      return {
        valid: false,
        error: this.i18n.tr('validation.required-is-empty')
      };
    }
    return { valid: true };
  }

  @listen('..')
  noDuplicateKeys(field) {
    const parent = field.parent;
    if (parent.type !== 'array' || parent.format !== 'map') {
      return {
        valid: false,
        error: 'Invalid validator noDuplicateKeys for field with non-map parent'
      };
    }

    const keyField = parent.keyField;
    const key = field.getValue()[parent.keyField];
    for (const child of parent.children) {
      if (child === field) {
        continue;
      }
      if (child.getValue()[keyField] === key) {
        return {
          valid: false,
          error: `Duplicate key ${key}`
        };
      }
    }
    return { valid: true };
  }

  @listen('..')
  noDuplicateValues(field) {
    const parent = field.parent;
    if (parent.type !== 'array') {
      return {
        valid: false,
        error: 'Invalid validator noDuplicateKeys for field with non-array parent'
      };
    }

    const value = field.getValue();
    for (const child of parent.children) {
      if (child === field) {
        continue;
      }
      if (child.getValue() === value) {
        return {
          valid: false,
          error: `Duplicate value ${value}`
        };
      }
    }
    return { valid: true };
  }

  path(field) {
    const val = field.getValue();
    if (!val.startsWith('/')) {
      return {
        valid: false,
        replacement: `/${val}`
      };
    }
    return { valid: true };
  }

  @listen('..')
  requiredTrueIfInPath(field) {
    const locationField = field.resolveRef('../in');
    if (!locationField) {
      return { valid: true };
    }
    const location = locationField.getValue();
    if (location === 'path' && !field.getValue()) {
      return {
        valid: false,
        replacement: true
      };
    }
    return { valid: true };
  }

  keyHTTPStatus(field) {
    if (field.key !== 'default' && /^[1-5]{1}[0-9]{2}$/.exec(field.key) === null) {
      return {
        valid: false,
        error: this.i18n.tr('validation.invalid-http-status')
      };
    }
    return { valid: true };
  }

  pathParametersExistsInAllOperations(field) {
    if (field.getType() !== 'operation') {
      // We don't need to check references here, they're checked wherever the
      // reference is pointing.
      return { valid: true };
    }

    const parseParamRef = target => {
      // Matches `#/parameters/<paramName>`
      const [, paramName] = /^\#\/parameters\/(.+)$/.exec(target);
      if (!paramName) {
        return undefined;
      }
      return field.resolveRef(`/global-definitions/${paramName}`).getValue();
    };
    const isParamInArray = (paramsField, lookingForParam) => {
      for (const arrayParam of paramsField.children) {
        let paramData = arrayParam.getValue();
        if (paramData.$ref) {
          paramData = parseParamRef(paramData.$ref);
          // No handling for nested $refs due to risk of circular reference.
          if (!paramData || paramData.$ref) {
            continue;
          }
        }
        if (paramData.in === 'path' && paramData.name === lookingForParam) {
          return true;
        }
      }
      return false;
    };

    const path = field.key;
    // The outer path field is a Typefield, but we only need the inner non-reference
    // Path field.
    field = field.child;

    const matches = path.match(/\{([^}]+?)\}/g);
    if (!matches) {
      // No parameters defined.
      return { valid: true };
    }

    const pathwideParams = field.children.parameters;
    ParamsInPath: for (const match of matches) {
      // Remove first and last character (the curly braces)
      const parameter = match.slice(1, -1);
      if (isParamInArray(pathwideParams, parameter)) {
        continue ParamsInPath;
      }
      Methods: for (const [method, child] of Object.entries(field.children)) {
        if (method === 'parameters' || child.isEmpty()) {
          continue Methods;
        }

        if (!isParamInArray(child.children.parameters, parameter)) {
          return {
            valid: false,
            error: this.i18n.tr('validation.param-not-implemented', {
              parameter,
              method: method.toUpperCase()
            })
          };
        }
      }
      return { valid: true };
    }
    return { valid: true };
  }

  keyPath(field) {
    if (!field.key.startsWith('/')) {
      field.key = `/${field.key}`;
    }
    return { valid: true };
  }

  hostname(field) {
    const val = field.getValue();
    if (!val || /^[^\.\s\n:]+(\.[^\.\s\n:]+)+(\:[0-9]{1,5})?$/.exec(val) !== null) {
      return { valid: true };
    } else if (/^\[?([0-9A-Fa-f]{0,4}:?)+\]?(\:[0-9]{1,5})?$/.exec(val) !== null) {
      return { valid: true };
    }
    return {
      valid: false,
      error: this.i18n.tr('validation.invalid-hostname')
    };
  }

  email(field) {
    const val = field.getValue();
    if (!val || /^\S+@\S+$/.exec(val) !== null) {
      return { valid: true };
    }
    return {
      valid: false,
      error: this.i18n.tr('validation.invalid-email')
    };
  }

  url(field) {
    return { valid: true };
  }
}
<commit_msg>Comment regexes<commit_after>function listen(...fields) {
  return function(target, key, descriptor) {
    descriptor.value.listen = fields;
  };
}

export class Validation {
  constructor(i18n) {
    this.i18n = i18n;
  }

  required(field) {
    if (field.isEmpty()) {
      return {
        valid: false,
        error: this.i18n.tr('validation.required-is-empty')
      };
    }
    return { valid: true };
  }

  requiredIfLegendTypeIsReference(field) {
    if (field.isEmpty() && field.resolveRef('../x-oad-type').getValue() === 'reference') {
      return {
        valid: false,
        error: this.i18n.tr('validation.required-is-empty')
      };
    }
    return { valid: true };
  }

  keyRequired(field) {
    if (field.key.length === 0) {
      return {
        valid: false,
        error: this.i18n.tr('validation.key-is-required')
      };
    }
    return { valid: true };
  }

  @listen('..')
  requiredIfParent(field) {
    if (field.isEmpty() && !field.parent.isEmpty()) {
      return {
        valid: false,
        error: this.i18n.tr('validation.required-is-empty')
      };
    }
    return { valid: true };
  }

  @listen('..')
  noDuplicateKeys(field) {
    const parent = field.parent;
    if (parent.type !== 'array' || parent.format !== 'map') {
      return {
        valid: false,
        error: 'Invalid validator noDuplicateKeys for field with non-map parent'
      };
    }

    const keyField = parent.keyField;
    const key = field.getValue()[parent.keyField];
    for (const child of parent.children) {
      if (child === field) {
        continue;
      }
      if (child.getValue()[keyField] === key) {
        return {
          valid: false,
          error: `Duplicate key ${key}`
        };
      }
    }
    return { valid: true };
  }

  @listen('..')
  noDuplicateValues(field) {
    const parent = field.parent;
    if (parent.type !== 'array') {
      return {
        valid: false,
        error: 'Invalid validator noDuplicateKeys for field with non-array parent'
      };
    }

    const value = field.getValue();
    for (const child of parent.children) {
      if (child === field) {
        continue;
      }
      if (child.getValue() === value) {
        return {
          valid: false,
          error: `Duplicate value ${value}`
        };
      }
    }
    return { valid: true };
  }

  path(field) {
    const val = field.getValue();
    if (!val.startsWith('/')) {
      return {
        valid: false,
        replacement: `/${val}`
      };
    }
    return { valid: true };
  }

  @listen('..')
  requiredTrueIfInPath(field) {
    const locationField = field.resolveRef('../in');
    if (!locationField) {
      return { valid: true };
    }
    const location = locationField.getValue();
    if (location === 'path' && !field.getValue()) {
      return {
        valid: false,
        replacement: true
      };
    }
    return { valid: true };
  }

  keyHTTPStatus(field) {
    if (field.key !== 'default' && /^[1-5]{1}[0-9]{2}$/.exec(field.key) === null) {
      return {
        valid: false,
        error: this.i18n.tr('validation.invalid-http-status')
      };
    }
    return { valid: true };
  }

  pathParametersExistsInAllOperations(field) {
    if (field.getType() !== 'operation') {
      // We don't need to check references here, they're checked wherever the
      // reference is pointing.
      return { valid: true };
    }

    const parseParamRef = target => {
      // Matches `#/parameters/<paramName>`
      const [, paramName] = /^\#\/parameters\/(.+)$/.exec(target);
      if (!paramName) {
        return undefined;
      }
      return field.resolveRef(`/global-definitions/${paramName}`).getValue();
    };
    const isParamInArray = (paramsField, lookingForParam) => {
      for (const arrayParam of paramsField.children) {
        let paramData = arrayParam.getValue();
        if (paramData.$ref) {
          paramData = parseParamRef(paramData.$ref);
          // No handling for nested $refs due to risk of circular reference.
          if (!paramData || paramData.$ref) {
            continue;
          }
        }
        if (paramData.in === 'path' && paramData.name === lookingForParam) {
          return true;
        }
      }
      return false;
    };

    const path = field.key;
    // The outer path field is a Typefield, but we only need the inner non-reference
    // Path field.
    field = field.child;

    // Matches all path parameters: {paramName}
    const matches = path.match(/\{([^}]+?)\}/g);
    if (!matches) {
      // No parameters defined.
      return { valid: true };
    }

    const pathwideParams = field.children.parameters;
    ParamsInPath: for (const match of matches) {
      // Remove first and last character (the curly braces)
      const parameter = match.slice(1, -1);
      if (isParamInArray(pathwideParams, parameter)) {
        continue ParamsInPath;
      }
      Methods: for (const [method, child] of Object.entries(field.children)) {
        if (method === 'parameters' || child.isEmpty()) {
          continue Methods;
        }

        if (!isParamInArray(child.children.parameters, parameter)) {
          return {
            valid: false,
            error: this.i18n.tr('validation.param-not-implemented', {
              parameter,
              method: method.toUpperCase()
            })
          };
        }
      }
      return { valid: true };
    }
    return { valid: true };
  }

  keyPath(field) {
    if (!field.key.startsWith('/')) {
      field.key = `/${field.key}`;
    }
    return { valid: true };
  }

  hostname(field) {
    const val = field.getValue();
    // Loosely matches IPv4 addresses and hostnames. Port is allowed but optional.
    if (!val || /^[^\.\s\n:]+(\.[^\.\s\n:]+)+(\:[0-9]{1,5})?$/.exec(val) !== null) {
      return { valid: true };
    // Loosely matches IPv6 addresses. Port is allowed but optional.
    } else if (/^\[?([0-9A-Fa-f]{0,4}:?)+\]?(\:[0-9]{1,5})?$/.exec(val) !== null) {
      return { valid: true };
    }
    return {
      valid: false,
      error: this.i18n.tr('validation.invalid-hostname')
    };
  }

  email(field) {
    const val = field.getValue();
    // Very loosely matches email addresses: `name@host`
    if (!val || /^\S+@\S+$/.exec(val) !== null) {
      return { valid: true };
    }
    return {
      valid: false,
      error: this.i18n.tr('validation.invalid-email')
    };
  }

  url(field) {
    return { valid: true };
  }
}
<|endoftext|>


<commit_before>/**
* Wrapper on top of the Document object model javascript API,
*   to make our life easier when we need to interact with such API in our tests
*
* @constructor VirtualDom
*/
window.getJasmineRequireObj().VirtualDom = function () {
    var oldDocument,

    getElementById = function (parent, id) {
        var children = parent.childNodes,
            child,
            result,
            i;

        for (i = 0; i < children.length; i++) {
            child = children[i];

            if (child.id === id) {
                return child;
            }

            result = getElementById.call(this, child, id);

            if (result) {
                return result;
            }
        }
    },

    isAlreadyInstalled = function () {
        return !!oldDocument;
    },

    mergeConfigIntoEventObject = function (eventObj, config) {
        var prop;

        for (prop in config) {
            if (config.hasOwnProperty(prop)) {
                eventObj[prop] = config[prop];
            }
        }
    };

    /**
    * This method will override the document API to use the virtual one, instead of the real one.
    *
    * @param {String} [body]. HTML template to be added into the virtual dom when installing it
    * @memberof VirtualDom
    */
    this.install = function (body) {
        var dom ;

        if (isAlreadyInstalled.call(this)) {
            throw 'Virtual dom already installed';
        }

        dom = document.createElement('html');
        dom.innerHTML = body;

        oldDocument = {
            getElementsByTagName: document.getElementsByTagName,
            getElementById: document.getElementById,
            querySelector: document.querySelector,
            querySelectorAll: document.querySelectorAll,
            getElementsByClassName: document.getElementsByClassName
        };

        document.getElementsByTagName = function (tagName) {
            if (tagName.toLowerCase() === 'html') {
                return [dom];
            }
            return dom.getElementsByTagName(tagName);
        };
        document.getElementById = function (id) {
            return getElementById.call(this, dom, id);
        };
        document.getElementsByClassName = function (className) {
            return dom.getElementsByClassName(className);
        };
        document.querySelector = function (selector) {
            return dom.querySelector(selector);
        };
        document.querySelectorAll = function (selector) {
            return dom.querySelectorAll(selector);
        };

        // Object.defineProperty(document, 'body', {
        //     get: function () {
        //         return this.getElementsByTagName('body')[0];
        //     },
        //     configurable: true
        // });

        // Object.defineProperty(document, 'head', {
        //     get: function () {
        //         return this.getElementsByTagName('head')[0];
        //     },
        //     configurable: true
        // });
    };

    /**
    * @memberof VirtualDom
    */
    this.uninstall = function () {
        var method;

        for (method in oldDocument) {
            if (oldDocument.hasOwnProperty(method)) {
                document[method] = oldDocument[method];
            }
        }

        oldDocument = null;
    };

    /**
    * Trigger any kind of event from any element, native or custom events
    * @param {Object} element. Dom Element
    * @param {String} event. Event name
    * @param {Object} config. parameters to be added to the event object
    * @memberof VirtualDom
    */
    this.trigger = function (element, event, config) {
        var eventObject = new Event(event);

        mergeConfigIntoEventObject.call(this, eventObject, config);

        element.dispatchEvent(eventObject);
    };

    /**
    * Uninstall and install the virtual dom with a new html
    * @param {String} [body]. HTML template to be added into the virtual dom when installing it
    * @memberof VirtualDom
    */
    this.resetDom = function (body) {
        this.uninstall();
        this.install(body);
    };
};

(function () {
    var require = window.getJasmineRequireObj();
    window.jasmine.virtualDom = new require.VirtualDom();
})();
<commit_msg>Use old fashin way to create events<commit_after>/**
* Wrapper on top of the Document object model javascript API,
*   to make our life easier when we need to interact with such API in our tests
*
* @constructor VirtualDom
*/
window.getJasmineRequireObj().VirtualDom = function () {
    var oldDocument,

    getElementById = function (parent, id) {
        var children = parent.childNodes,
            child,
            result,
            i;

        for (i = 0; i < children.length; i++) {
            child = children[i];

            if (child.id === id) {
                return child;
            }

            result = getElementById.call(this, child, id);

            if (result) {
                return result;
            }
        }
    },

    isAlreadyInstalled = function () {
        return !!oldDocument;
    },

    mergeConfigIntoEventObject = function (eventObj, config) {
        var prop;

        for (prop in config) {
            if (config.hasOwnProperty(prop)) {
                eventObj[prop] = config[prop];
            }
        }
    };

    /**
    * This method will override the document API to use the virtual one, instead of the real one.
    *
    * @param {String} [body]. HTML template to be added into the virtual dom when installing it
    * @memberof VirtualDom
    */
    this.install = function (body) {
        var dom ;

        if (isAlreadyInstalled.call(this)) {
            throw 'Virtual dom already installed';
        }

        dom = document.createElement('html');
        dom.innerHTML = body;

        oldDocument = {
            getElementsByTagName: document.getElementsByTagName,
            getElementById: document.getElementById,
            querySelector: document.querySelector,
            querySelectorAll: document.querySelectorAll,
            getElementsByClassName: document.getElementsByClassName
        };

        document.getElementsByTagName = function (tagName) {
            if (tagName.toLowerCase() === 'html') {
                return [dom];
            }
            return dom.getElementsByTagName(tagName);
        };
        document.getElementById = function (id) {
            return getElementById.call(this, dom, id);
        };
        document.getElementsByClassName = function (className) {
            return dom.getElementsByClassName(className);
        };
        document.querySelector = function (selector) {
            return dom.querySelector(selector);
        };
        document.querySelectorAll = function (selector) {
            return dom.querySelectorAll(selector);
        };

        // Object.defineProperty(document, 'body', {
        //     get: function () {
        //         return this.getElementsByTagName('body')[0];
        //     },
        //     configurable: true
        // });

        // Object.defineProperty(document, 'head', {
        //     get: function () {
        //         return this.getElementsByTagName('head')[0];
        //     },
        //     configurable: true
        // });
    };

    /**
    * @memberof VirtualDom
    */
    this.uninstall = function () {
        var method;

        for (method in oldDocument) {
            if (oldDocument.hasOwnProperty(method)) {
                document[method] = oldDocument[method];
            }
        }

        oldDocument = null;
    };

    /**
    * Trigger any kind of event from any element, native or custom events
    * @param {Object} element. Dom Element
    * @param {String} event. Event name
    * @param {Object} config. parameters to be added to the event object
    * @memberof VirtualDom
    */
    this.trigger = function (element, event, config) {
        var eventObject = document.createEvent('Event');
        event.initEvent(event, true, true);

        mergeConfigIntoEventObject.call(this, eventObject, config);

        element.dispatchEvent(eventObject);
    };

    /**
    * Uninstall and install the virtual dom with a new html
    * @param {String} [body]. HTML template to be added into the virtual dom when installing it
    * @memberof VirtualDom
    */
    this.resetDom = function (body) {
        this.uninstall();
        this.install(body);
    };
};

(function () {
    var require = window.getJasmineRequireObj();
    window.jasmine.virtualDom = new require.VirtualDom();
})();
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies
 */

// Node.js core.
const fs = require('fs');
const path = require('path');

// Public node modules.
const _ = require('lodash');
const async = require('async');

// Local utilities.
const dictionary = require('../../../../util/dictionary');

/**
 * Async module loader to create a
 * dictionary of the user config
 */

module.exports = function (strapi) {
  const hook = {

    /**
     * Initialize the hook
     */

    initialize: function (cb) {
      async.auto({

        // Load common settings from `./config/*.json`.
        'config/*': function (cb) {
          dictionary.aggregate({
            dirname: path.resolve(strapi.config.appPath, strapi.config.paths.config),
            excludeDirs: /(locales|environments)$/,
            filter: /(.+)\.(json)$/,
            depth: 2
          }, cb);
        },

        // Load locales from `./config/locales/*.json`.
        'config/locales/*': function (cb) {
          dictionary.optional({
            dirname: path.resolve(strapi.config.appPath, strapi.config.paths.config, 'locales'),
            filter: /(.+)\.(json)$/,
            identity: false,
            depth: 1
          }, cb);
        },

        // Load functions config from `./config/functions/*.js`.
        'config/functions/*': function (cb) {
          dictionary.aggregate({
            dirname: path.resolve(strapi.config.appPath, strapi.config.paths.config, 'functions'),
            filter: /(.+)\.(js)$/,
            depth: 1
          }, cb);
        },

        // Load environment-specific config from `./config/environments/**/*.json`.
        'config/environments/**': function (cb) {
          dictionary.aggregate({
            dirname: path.resolve(strapi.config.appPath, strapi.config.paths.config, 'environments', strapi.config.environment),
            filter: /(.+)\.(json)$/,
            depth: 1
          }, cb);
        },

        // Load APIs from `./api/**/*.js|json`.
        'api/**': function (cb) {
          dictionary.optional({
            dirname: path.resolve(strapi.config.appPath, strapi.config.paths.api),
            filter: /(.+)\.(js|json)$/,
            depth: 5
          }, cb);
        }
      },

      // Callback.
      function (err, config) {

        // Just in case there is an error.
        if (err) {
          return cb(err);
        }

        // Merge every user config together.
        const mergedConfig = _.merge(
          config['config/*'],
          config['config/environments/**'],
          config['config/functions/*']
        );

        // Local `package.json`.
        const packageJSON = require(path.resolve(strapi.config.appPath, 'package.json'));

        // Merge default config and user loaded config together inside `strapi.config`.
        strapi.config = _.merge(strapi.config, mergedConfig, packageJSON);

        // Expose user APIs.
        strapi.api = config['api/**'];

        // Add user locales for the settings of the `i18n` hook
        // aiming to load locales automatically.
        if (_.isPlainObject(strapi.config.i18n) && !_.isEmpty(strapi.config.i18n)) {
          strapi.config.i18n.locales = [];
          _.forEach(config['config/locales/*'], function (strings, lang) {
            strapi.config.i18n.locales.push(lang);
          });
        }

        // Save different environments inside an array because we need it in the Strapi Studio.
        strapi.config.environments = fs.readdirSync(path.resolve(strapi.config.appPath, strapi.config.paths.config, 'environments'));

        // Make the application name in config match the server one.
        strapi.app.name = strapi.config.name;

        // Initialize empty API objects.
        strapi.controllers = {};
        strapi.models = {};
        strapi.policies = {};
      });

      cb();
    },

    /**
     * Reload the hook
     */

    reload: function () {
      hook.initialize(function (err) {
        if (err) {
          strapi.log.error('Failed to reinitialize the config hook.');
          strapi.stop();
        } else {
          strapi.emit('hook:_config:reloaded');
        }
      });
    }
  };

  return hook;
};
<commit_msg>Make sure the ORM config are good on the rebuild<commit_after>'use strict';

/**
 * Module dependencies
 */

// Node.js core.
const fs = require('fs');
const path = require('path');

// Public node modules.
const _ = require('lodash');
const async = require('async');

// Local utilities.
const dictionary = require('../../../../util/dictionary');

/**
 * Async module loader to create a
 * dictionary of the user config
 */

module.exports = function (strapi) {
  const hook = {

    /**
     * Initialize the hook
     */

    initialize: function (cb) {
      async.auto({

        // Load common settings from `./config/*.json`.
        'config/*': function (cb) {
          dictionary.aggregate({
            dirname: path.resolve(strapi.config.appPath, strapi.config.paths.config),
            excludeDirs: /(locales|environments)$/,
            filter: /(.+)\.(json)$/,
            depth: 2
          }, cb);
        },

        // Load locales from `./config/locales/*.json`.
        'config/locales/*': function (cb) {
          dictionary.optional({
            dirname: path.resolve(strapi.config.appPath, strapi.config.paths.config, 'locales'),
            filter: /(.+)\.(json)$/,
            identity: false,
            depth: 1
          }, cb);
        },

        // Load functions config from `./config/functions/*.js`.
        'config/functions/*': function (cb) {
          dictionary.aggregate({
            dirname: path.resolve(strapi.config.appPath, strapi.config.paths.config, 'functions'),
            filter: /(.+)\.(js)$/,
            depth: 1
          }, cb);
        },

        // Load environment-specific config from `./config/environments/**/*.json`.
        'config/environments/**': function (cb) {
          dictionary.aggregate({
            dirname: path.resolve(strapi.config.appPath, strapi.config.paths.config, 'environments', strapi.config.environment),
            filter: /(.+)\.(json)$/,
            depth: 1
          }, cb);
        },

        // Load APIs from `./api/**/*.js|json`.
        'api/**': function (cb) {
          dictionary.optional({
            dirname: path.resolve(strapi.config.appPath, strapi.config.paths.api),
            filter: /(.+)\.(js|json)$/,
            depth: 5
          }, cb);
        }
      },

      // Callback.
      function (err, config) {

        // Just in case there is an error.
        if (err) {
          return cb(err);
        }

        // Merge every user config together.
        const mergedConfig = _.merge(
          config['config/*'],
          config['config/environments/**'],
          config['config/functions/*']
        );

        // Local `package.json`.
        const packageJSON = require(path.resolve(strapi.config.appPath, 'package.json'));

        // Merge default config and user loaded config together inside `strapi.config`.
        strapi.config = _.merge(strapi.config, mergedConfig, packageJSON);

        // Expose user APIs.
        strapi.api = config['api/**'];

        // Add user locales for the settings of the `i18n` hook
        // aiming to load locales automatically.
        if (_.isPlainObject(strapi.config.i18n) && !_.isEmpty(strapi.config.i18n)) {
          strapi.config.i18n.locales = [];
          _.forEach(config['config/locales/*'], function (strings, lang) {
            strapi.config.i18n.locales.push(lang);
          });
        }

        // Make sure the ORM config are equals to the databases file
        // (aiming to not have issue with adapters when rebuilding the dictionary).
        // It's kind of messy, for now, but it works fine. If someone has a better
        // solution we'd be glad to accept a Pull Request.
        const ormConfig = JSON.parse(fs.readFileSync(path.resolve(strapi.config.appPath, strapi.config.paths.config, 'environments', strapi.config.environment, 'databases.json')));
        strapi.config.orm = ormConfig.orm;

        // Save different environments inside an array because we need it in the Strapi Studio.
        strapi.config.environments = fs.readdirSync(path.resolve(strapi.config.appPath, strapi.config.paths.config, 'environments'));

        // Make the application name in config match the server one.
        strapi.app.name = strapi.config.name;

        // Initialize empty API objects.
        strapi.controllers = {};
        strapi.models = {};
        strapi.policies = {};
      });

      cb();
    },

    /**
     * Reload the hook
     */

    reload: function () {
      hook.initialize(function (err) {
        if (err) {
          strapi.log.error('Failed to reinitialize the config hook.');
          strapi.stop();
        } else {
          strapi.emit('hook:_config:reloaded');
        }
      });
    }
  };

  return hook;
};
<|endoftext|>


<commit_before>import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const state = {
  history: [],
  picks: [], // pick: { numberOverall, numberRound, player, round, team }, player: { position, name, id, team }
  rankings: [],
  settings: {
    app: {
      draftOrderTypes: {
        'random': 'ran',
        'sequential': 'seq',
        'serpentine': 'ser'
      },
      positions: [
        { key: 'QB', name: 'QB', category: 'Offense', order: 1 },
        { key: 'RB', name: 'RB', category: 'Offense', order: 2 },
        { key: 'WR', name: 'WR', category: 'Offense', order: 3 },
        { key: 'TE', name: 'TE', category: 'Offense', order: 4 },
        { key: 'DE', name: 'Defensive End', category: 'Defense', order: 5 },
        { key: 'DT', name: 'Defensive Tackle', category: 'Defense', order: 6 },
        { key: 'LB', name: 'Linebacker', category: 'Defense', order: 7 },
        { key: 'CB', name: 'Cornerback', category: 'Defense', order: 8 },
        { key: 'S', name: 'Safety', category: 'Defense', order: 9 },
        { key: 'Off', name: 'Offense', category: 'Team', order: 10 },
        { key: 'Def', name: 'Defense/Special Teams', category: 'Team', order: 11 },
        { key: 'TMQB', name: 'Team QB', category: 'Team', order: 12 },
        { key: 'TMRB', name: 'Team RB', category: 'Team', order: 13 },
        { key: 'TMWR', name: 'Team WR', category: 'Team', order: 14 },
        { key: 'TMTE', name: 'Team TE', category: 'Team', order: 15 },
        { key: 'TMDL', name: 'Team Defensive Line', category: 'Team', order: 16 },
        { key: 'TMLB', name: 'Team Linebackers', category: 'Team', order: 17 },
        { key: 'TMDB', name: 'Team Defensive Backs', category: 'Team', order: 18 },
        { key: 'TMPK', name: 'Team Place Kicker', category: 'Team', order: 19 },
        { key: 'TMPN', name: 'Team Punter', category: 'Team', order: 20 },
        { key: 'ST', name: 'Special Teams', category: 'Other', order: 21 },
        { key: 'PK', name: 'Kicker', category: 'Other', order: 22 },
        { key: 'PN', name: 'Punter', category: 'Other', order: 23 },
        { key: 'Coach', name: 'Coach', category: 'Other', order: 24 },
        { key: 'XX', name: 'Unknown', order: 25 }
      ]
    },
    /*
      CTS settings
    */
    league: {
      draftOrderType: 'ser',
      positions: [
        { key: 'QB', min: 1, max: 2 },
        { key: 'RB', min: 1, max: 2 },
        { key: 'WR', min: 1, max: 2 },
        { key: 'TE', min: 1, max: 2 },
        { key: 'PK', min: 1, max: 1 },
        { key: 'Def', min: 1, max: 1 }
      ],
      rosterSize: 7,
      secondsPerPick: 60,
      teams: [
        { name: 'Papa Peyton’s', owner: 'James Hostick', draftOrder: 1 },
        { name: 'Mark’s Team', owner: 'Mark', draftOrder: 2 },
        { name: 'London Sillinannies', owner: 'Zach Brown', draftOrder: 3 },
        { name: '[BANDWAGON TEAM]', owner: 'Ellis Hicks', draftOrder: 4 },
        { name: 'tim’s Bold Team', owner: 'Tim', draftOrder: 5 },
        { name: 'Luke’s Legit Team', owner: 'Luke', draftOrder: 6 },
        { name: 'Play It Again Sam', owner: 'Brian Koser', draftOrder: 7, user: true },
        { name: 'Christian’s Team', owner: 'Christian Boyer', draftOrder: 8 },
        { name: 'My Team Sucks!', owner: 'Steven', draftOrder: 9 },
        { name: 'Alderaan Explosions', owner: 'Brandon Ellison', draftOrder: 10 },
        { name: 'Scott H’s Swell Team', owner: 'Scott H', draftOrder: 11 }
      ]
    },

    /*
      Crossroads settings
    */
    // league: {
    //   draftOrderType: 'ser',
    //   positions: [
    //     { key: 'QB', min: 1, max: 4 },
    //     { key: 'RB', min: 1, max: 8 },
    //     { key: 'WR', min: 2, max: 8 },
    //     { key: 'TE', min: 1, max: 3 },
    //     { key: 'PK', min: 1, max: 3 },
    //     { key: 'Def', min: 1, max: 3 },
    //     { key: 'Coach', min: 1, max: 10 }
    //   ],
    //   rosterSize: 17,
    //   secondsPerPick: 60,
    //   teams: [
    //     { name: 'The Commish', owner: 'Aaron Smith', draftOrder: 12 },
    //     { name: '’Aints -', owner: 'Matt McLean' draftOrder: 11 },
    //     { name: 'Play It Again Sam', owner: 'Brian Koser', draftOrder: 10, user: true },
    //     { name: 'O. J.', owner: 'Tuck Chastain', draftOrder: 9 },
    //     { name: 'Buck stops here', owner: 'Terry Buckner', draftOrder: 8 },
    //     { name: 'Small Arms Dealer', owner: 'Scott Hopkins', draftOrder: 7 },
    //     { name: 'Fluoride Bandits', owner: 'Shane Herrington', draftOrder: 6 },
    //     { name: 'Brown Mikes DeadBeat Bums', owner: 'Brown Mike',  draftOrder: 5 },
    //     { name: 'Alabama Yard rats', owner: 'Philip Quinney', draftOrder: 4 },
    //     { name: 'Cam Burglar', owner: 'Justin Tolbert', draftOrder: 3 },
    //     { name: 'Amen Corner', owner: 'Ben Harris', draftOrder: 2 },
    //     { name: 'Crossroads Zealots', owner: 'Joe Chastain', draftOrder: 1 }
    //   ]
    // },
    team: {
      idealSize: [
        { key: 'QB', count: 2 },
        { key: 'RB', count: 4 },
        { key: 'WR', count: 5 },
        { key: 'TE', count: 2 },
        { key: 'PK', count: 1 },
        { key: 'Def', count: 2 },
        { key: 'Coach', count: 1 }
      ]
    }
  }
}

const mutations = {
  ADDPICK (state, pick) {
    state.picks.push(pick)
  },
  ADDSTATEENTRY (state, entry) {
    state.history.push(entry)
  },
  SETRANKINGS (state, rankings) {
    state.rankings = rankings
  },
  UNDOLASTPICK (state) {
    state.picks.pop()
  },
  UNDOSTATEENTRY (state) {
    state.history.pop()
  }
}

export default new Vuex.Store({
  state,
  mutations
})
<commit_msg>Ideal size for CTS<commit_after>import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const state = {
  history: [],
  picks: [], // pick: { numberOverall, numberRound, player, round, team }, player: { position, name, id, team }
  rankings: [],
  settings: {
    app: {
      draftOrderTypes: {
        'random': 'ran',
        'sequential': 'seq',
        'serpentine': 'ser'
      },
      positions: [
        { key: 'QB', name: 'QB', category: 'Offense', order: 1 },
        { key: 'RB', name: 'RB', category: 'Offense', order: 2 },
        { key: 'WR', name: 'WR', category: 'Offense', order: 3 },
        { key: 'TE', name: 'TE', category: 'Offense', order: 4 },
        { key: 'DE', name: 'Defensive End', category: 'Defense', order: 5 },
        { key: 'DT', name: 'Defensive Tackle', category: 'Defense', order: 6 },
        { key: 'LB', name: 'Linebacker', category: 'Defense', order: 7 },
        { key: 'CB', name: 'Cornerback', category: 'Defense', order: 8 },
        { key: 'S', name: 'Safety', category: 'Defense', order: 9 },
        { key: 'Off', name: 'Offense', category: 'Team', order: 10 },
        { key: 'Def', name: 'Defense/Special Teams', category: 'Team', order: 11 },
        { key: 'TMQB', name: 'Team QB', category: 'Team', order: 12 },
        { key: 'TMRB', name: 'Team RB', category: 'Team', order: 13 },
        { key: 'TMWR', name: 'Team WR', category: 'Team', order: 14 },
        { key: 'TMTE', name: 'Team TE', category: 'Team', order: 15 },
        { key: 'TMDL', name: 'Team Defensive Line', category: 'Team', order: 16 },
        { key: 'TMLB', name: 'Team Linebackers', category: 'Team', order: 17 },
        { key: 'TMDB', name: 'Team Defensive Backs', category: 'Team', order: 18 },
        { key: 'TMPK', name: 'Team Place Kicker', category: 'Team', order: 19 },
        { key: 'TMPN', name: 'Team Punter', category: 'Team', order: 20 },
        { key: 'ST', name: 'Special Teams', category: 'Other', order: 21 },
        { key: 'PK', name: 'Kicker', category: 'Other', order: 22 },
        { key: 'PN', name: 'Punter', category: 'Other', order: 23 },
        { key: 'Coach', name: 'Coach', category: 'Other', order: 24 },
        { key: 'XX', name: 'Unknown', order: 25 }
      ]
    },
    /*
      CTS settings
    */
    league: {
      draftOrderType: 'ser',
      positions: [
        { key: 'QB', min: 1, max: 2 },
        { key: 'RB', min: 1, max: 2 },
        { key: 'WR', min: 1, max: 2 },
        { key: 'TE', min: 1, max: 2 },
        { key: 'PK', min: 1, max: 1 },
        { key: 'Def', min: 1, max: 1 }
      ],
      rosterSize: 7,
      secondsPerPick: 60,
      teams: [
        { name: 'Papa Peyton’s', owner: 'James Hostick', draftOrder: 1 },
        { name: 'Mark’s Team', owner: 'Mark', draftOrder: 2 },
        { name: 'London Sillinannies', owner: 'Zach Brown', draftOrder: 3 },
        { name: '[BANDWAGON TEAM]', owner: 'Ellis Hicks', draftOrder: 4 },
        { name: 'tim’s Bold Team', owner: 'Tim', draftOrder: 5 },
        { name: 'Luke’s Legit Team', owner: 'Luke', draftOrder: 6 },
        { name: 'Play It Again Sam', owner: 'Brian Koser', draftOrder: 7, user: true },
        { name: 'Christian’s Team', owner: 'Christian Boyer', draftOrder: 8 },
        { name: 'My Team Sucks!', owner: 'Steven', draftOrder: 9 },
        { name: 'Alderaan Explosions', owner: 'Brandon Ellison', draftOrder: 10 },
        { name: 'Scott H’s Swell Team', owner: 'Scott H', draftOrder: 11 }
      ]
    },
    team: {
      idealSize: [
        { key: 'QB', count: 1 },
        { key: 'RB', count: 1 },
        { key: 'WR', count: 1 },
        { key: 'TE', count: 1 },
        { key: 'PK', count: 1 },
        { key: 'Def', count: 1 }
      ]
    }

    /*
      Crossroads settings
    */
    // league: {
    //   draftOrderType: 'ser',
    //   positions: [
    //     { key: 'QB', min: 1, max: 4 },
    //     { key: 'RB', min: 1, max: 8 },
    //     { key: 'WR', min: 2, max: 8 },
    //     { key: 'TE', min: 1, max: 3 },
    //     { key: 'PK', min: 1, max: 3 },
    //     { key: 'Def', min: 1, max: 3 },
    //     { key: 'Coach', min: 1, max: 10 }
    //   ],
    //   rosterSize: 17,
    //   secondsPerPick: 60,
    //   teams: [
    //     { name: 'The Commish', owner: 'Aaron Smith', draftOrder: 12 },
    //     { name: '’Aints -', owner: 'Matt McLean' draftOrder: 11 },
    //     { name: 'Play It Again Sam', owner: 'Brian Koser', draftOrder: 10, user: true },
    //     { name: 'O. J.', owner: 'Tuck Chastain', draftOrder: 9 },
    //     { name: 'Buck stops here', owner: 'Terry Buckner', draftOrder: 8 },
    //     { name: 'Small Arms Dealer', owner: 'Scott Hopkins', draftOrder: 7 },
    //     { name: 'Fluoride Bandits', owner: 'Shane Herrington', draftOrder: 6 },
    //     { name: 'Brown Mikes DeadBeat Bums', owner: 'Brown Mike',  draftOrder: 5 },
    //     { name: 'Alabama Yard rats', owner: 'Philip Quinney', draftOrder: 4 },
    //     { name: 'Cam Burglar', owner: 'Justin Tolbert', draftOrder: 3 },
    //     { name: 'Amen Corner', owner: 'Ben Harris', draftOrder: 2 },
    //     { name: 'Crossroads Zealots', owner: 'Joe Chastain', draftOrder: 1 }
    //   ]
    // },
    // team: {
    //   idealSize: [
    //     { key: 'QB', count: 2 },
    //     { key: 'RB', count: 4 },
    //     { key: 'WR', count: 5 },
    //     { key: 'TE', count: 2 },
    //     { key: 'PK', count: 1 },
    //     { key: 'Def', count: 2 },
    //     { key: 'Coach', count: 1 }
    //   ]
    // }
  }
}

const mutations = {
  ADDPICK (state, pick) {
    state.picks.push(pick)
  },
  ADDSTATEENTRY (state, entry) {
    state.history.push(entry)
  },
  SETRANKINGS (state, rankings) {
    state.rankings = rankings
  },
  UNDOLASTPICK (state) {
    state.picks.pop()
  },
  UNDOSTATEENTRY (state) {
    state.history.pop()
  }
}

export default new Vuex.Store({
  state,
  mutations
})
<|endoftext|>


<commit_before>/*
Copyright (c) 2015, EDINA.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this
   list of conditions and the following disclaimer in the documentation and/or
   other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software must
   display the following acknowledgement: This product includes software
   developed by the EDINA.
4. Neither the name of the EDINA nor the names of its contributors may be used to
   endorse or promote products derived from this software without specific prior
   written permission.

THIS SOFTWARE IS PROVIDED BY EDINA ''AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL EDINA BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
*/

'use strict';

/* global _ */
/* global cordova */

define(['records', 'utils', 'file', 'widgets'], function(records, utils, file, widgets) { // jshint ignore:line
    var dgroup, dtype;
    //var asAForm = false; // Flag to ignore the records.EVT_EDIT_ANNOTATION event

    var onFinishDtree;

    var pluginRoot = 'plugins/ble/';

    var fieldId = 'fieldcontain-ble-1';

    var inputValue = _.template(
        '
' +
            '
' +
                '<input type="text" ' +
                       'id="ble-value"' +
                       'value="<%= value %>" ' +
                       'data-ble-value="<%= dtree %>" ' +
                       'readonly >' +
            '
' +
            '
' +
                '' +
            '
' +
        '
'
    );

    var addRecordBLE = function(e, annotation) {
        var field;

        field = {
            id: fieldId,
            label: 'Bluetooth'
        };
        field.val = "";

        annotation.record.properties.fields.push(field);
    };

    /**
     * Implements the records.processEditor interface
     * @param editorName name of the editor
     * @param html html content of the editor
     * @param group from records.EDITOR_GROUP
     * @param online boolean value if the processing is held online
     */
    var processEditor = function(editorName, html, group, online) {
        var $form = $(html);
        var editorsObj = records.loadEditorsMetadata();

        // Add the dom class that will be used in the buttons
        var editorClass = $('#dtree-form-class-name', $form).text();
        if (editorClass !== '') {
            if (editorsObj[group][editorName] === undefined) {
                editorsObj[group][editorName] = {};
            }

            editorsObj[group][editorName]['class'] = editorClass;

            // Save the result
            records.saveEditorsMetadata(editorsObj);
        }
    };

    // Add the plugin editor process to the pipeline
    records.addProcessEditor(processEditor);

    var registerOnFinish = function(func) {
        onFinishDtree = func;
    };

    /*********EVENTS************/

    // Dtree from a button inside an editor
    $(document).off('vclick', '.annotate-ble');
    $(document).on('vclick', '.annotate-ble', function(event) {
        event.stopPropagation();
        event.preventDefault();
        console.log('annotate worked');
        //asAForm = false;

        if(cordova && cordova.plugins && cordova.plugins.cobwebbleplugin){
            console.log('cordova plugin exists');
            var addPropertFromCordova = function(result){
                console.log(result);
            };

            var addPropertFromCordovaError = function(error){
                console.log(error);
            };

            cordova.plugins.cobwebbleplugin.testArrayBLEData('', addPropertFromCordova, addPropertFromCordovaError);
        }

        return false;
    });

    $(document).off('vclick', '.ble-delete');
    $(document).on('vclick', '.ble-delete', function(event) {
        event.stopPropagation();
        event.preventDefault();

        var $target = $(event.currentTarget);
        $target.parent().remove();

        return false;
    });

    // TODO: do this in a more clean and modular way
    // Self register as a widget

    (function() {
        var WIDGET_NAME = 'ble';

        var initialize = function(index, element) {
            var $el = $(element);

            $.each($('.button-ble', element), function(index, input) {

                var btn = '' +
                              'Retrieve ' +
                          '';

                $(input)
                    .append(btn)
                    .trigger('create');
            });
        };

        var validate = function(html) {
            return {
                valid: true,
                errors: []
            };
        };

        var serialize = function(element) {
            var $el = $(element);
            var values = [];
            var label;

            $el.find('input[data-ble-value]').each(function(i, item) {
                values.push(item.value);
            });

            label = $el.find('label[for="' + element.id + '"]').text();

            return {
                serialize: true,
                label: label,
                value: values
            };
        };

        widgets.registerWidget({
            name: WIDGET_NAME,
            initialize: initialize,
            validate: validate,
            serialize: serialize
        });
    })();

    // listen on any page with class sync-page
    $(document).on(records.EVT_EDIT_ANNOTATION, addRecordBLE);

    $('head').prepend('<link rel="stylesheet" href="plugins/ble/css/style.css" type="text/css" />');
});
<commit_msg>cobweb-eu/cobweb#163: the weather data are saved on the record<commit_after>/*
Copyright (c) 2015, EDINA.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this
   list of conditions and the following disclaimer in the documentation and/or
   other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software must
   display the following acknowledgement: This product includes software
   developed by the EDINA.
4. Neither the name of the EDINA nor the names of its contributors may be used to
   endorse or promote products derived from this software without specific prior
   written permission.

THIS SOFTWARE IS PROVIDED BY EDINA ''AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL EDINA BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
*/

'use strict';

/* global _ */
/* global cordova */

define(['records', 'utils', 'file', 'widgets'], function(records, utils, file, widgets) { // jshint ignore:line
    var bleData;

    var onFinishDtree;

    var pluginRoot = 'plugins/ble/';

    var fieldId = 'fieldcontain-ble-1';

    var inputValue = _.template(
        '
' +
            '
' +
                '<input type="text" ' +
                       'id="ble-value"' +
                       'value="<%= value %>" ' +
                       'data-ble-value="<%= dtree %>" ' +
                       'readonly >' +
            '
' +
            '
' +
                '' +
            '
' +
        '
'
    );

    var addRecordBLE = function(e, annotation) {
        var field;

        field = {
            id: fieldId,
            label: 'Bluetooth'
        };
        field.val = bleData;

        annotation.record.properties.fields.push(field);
    };

    /**
     * Implements the records.processEditor interface
     * @param editorName name of the editor
     * @param html html content of the editor
     * @param group from records.EDITOR_GROUP
     * @param online boolean value if the processing is held online
     */
    var processEditor = function(editorName, html, group, online) {
        var $form = $(html);
        var editorsObj = records.loadEditorsMetadata();

        // Add the dom class that will be used in the buttons
        var editorClass = $('#dtree-form-class-name', $form).text();
        if (editorClass !== '') {
            if (editorsObj[group][editorName] === undefined) {
                editorsObj[group][editorName] = {};
            }

            editorsObj[group][editorName]['class'] = editorClass;

            // Save the result
            records.saveEditorsMetadata(editorsObj);
        }
    };

    // Add the plugin editor process to the pipeline
    records.addProcessEditor(processEditor);

    var registerOnFinish = function(func) {
        onFinishDtree = func;
    };

    /*********EVENTS************/

    // Dtree from a button inside an editor
    $(document).off('vclick', '.annotate-ble');
    $(document).on('vclick', '.annotate-ble', function(event) {
        event.stopPropagation();
        event.preventDefault();
        console.log('annotate worked');
        //asAForm = false;

        if(cordova && cordova.plugins && cordova.plugins.cobwebbleplugin){
            console.log('cordova plugin exists');
            utils.showPageLoadingMsg('The mobile is connecting to the weather station!');
            var addPropertFromCordova = function(result){
                $.mobile.loading('hide');
                bleData = JSON.stringify(result);
                console.log(result);
            };

            var addPropertFromCordovaError = function(error){
                console.log(error);
            };

            cordova.plugins.cobwebbleplugin.testArrayBLEData(addPropertFromCordova, addPropertFromCordovaError);
        }

        return false;
    });

    $(document).off('vclick', '.ble-delete');
    $(document).on('vclick', '.ble-delete', function(event) {
        event.stopPropagation();
        event.preventDefault();

        var $target = $(event.currentTarget);
        $target.parent().remove();

        return false;
    });

    // TODO: do this in a more clean and modular way
    // Self register as a widget

    (function() {
        var WIDGET_NAME = 'ble';

        var initialize = function(index, element) {
            var $el = $(element);

            $.each($('.button-ble', element), function(index, input) {

                var btn = '' +
                              'Retrieve ' +
                          '';

                $(input)
                    .append(btn)
                    .trigger('create');
            });
        };

        var validate = function(html) {
            return {
                valid: true,
                errors: []
            };
        };

        var serialize = function(element) {
            var $el = $(element);
            var values = [];
            var label;

            $el.find('input[data-ble-value]').each(function(i, item) {
                values.push(item.value);
            });

            label = $el.find('label[for="' + element.id + '"]').text();

            return {
                serialize: true,
                label: label,
                value: values
            };
        };

        widgets.registerWidget({
            name: WIDGET_NAME,
            initialize: initialize,
            validate: validate,
            serialize: serialize
        });
    })();

    // listen on any page with class sync-page
    $(document).on(records.EVT_EDIT_ANNOTATION, addRecordBLE);

    //$('head').prepend('<link rel="stylesheet" href="plugins/ble/css/style.css" type="text/css" />');
});
<|endoftext|>