<commit_before>require('datejs');

function describe(tMinus, descriptor) {

  var options = [];

  switch(descriptor) {
    case "дней":
      options = ["день", "дня", "дней"];
      break;
    case "часов":
      options = ["час", "часа", "часов"];
      break;
    case "минут":
      options = ["минута", "минуты", "минут"];
      break;
    case "секунд":
      options = ["секунда", "секунды", "секунд"];
      break;
  }

  if (tMinus >= 11 && tMinus <= 20) {
    return options[2];
  } else if (tMinus % 10 == 1) {
    return options[0];
  } else if (tMinus % 10 > 1 && tMinus % 10 < 5) {
    return options[1];
  } else {
    return options[2];
  }

}

module.exports = function() {

  // Everything here is based on UTC time; need to change if daylight saving time is introduced again in Russia

  // convert to UTC time
  var now_loc = new Date();
  var now = new Date(now_loc.getUTCFullYear(), now_loc.getUTCMonth(), now_loc.getUTCDate(), now_loc.getUTCHours(), now_loc.getUTCMinutes(), now_loc.getUTCSeconds());

  var offset = new Date(now).getTimezoneOffset();
  // now = new Date(2016, 7, 9, 23, 32, 41); // testing data
  console.log("-- current data and time in UTC: " + new Date(now).toISOString());
  console.log("-- current data and time in server time zone: " + new Date(now).toString());
  console.log("-- timezone offset UTC: " + offset);

  var days = (1000 * 60 * 60 * 24);
  var hours = (60 * 60 * 1000);
  var minutes = (60 * 1000);
  var seconds = 1000;

  if (now.getDay() == 3 && now.getHours() >= 16 && now.getHours() <= 19) {
    var start = new Date(now).setHours(16);
    start = new Date(start).setMinutes(0);
    start = new Date(start).setSeconds(0);
    var diff = Math.abs(start - new Date(now));
    var hoursRunning = Math.floor(diff / hours);
    var minutesRunning = Math.floor(((diff - hoursRunning * hours) % hours) / minutes);
    var secondsRunning = Math.floor(((diff - hoursRunning * hours - minutesRunning * minutes) % minutes) / seconds);

    var running = [hoursRunning, minutesRunning, secondsRunning];
    var descriptors = running.map(function(el, idx) {
      var temp = describe(el, ["часов", "минут", "секунд"][idx]);
      var out;
      switch (temp) {
        case "минута":
          out = "минуту";
          break;
        case "секунда":
          out = "секунду";
          break;
        default:
          out = temp;
          break;
      }
      return out;
    });

    return ("Баня в активной фазе " +
              running[0] + " " + descriptors[0] + " " +
              running[1] + " " + descriptors[1] + " " +
              running[2] + " " + descriptors[2] + ".");
  }

  var next = new Date(now);

  if (next.getDay() != 3 || (next.getDay() == 3 && next.getHours() >= 19)) {
    next = next.next().wednesday();
  }

  next = new Date(next).setSeconds(0);
  next = new Date(next).setMinutes(0);
  next = new Date(next).setHours(16); // UTC time is used; need to change if daylight saving time is introduced
  console.log("-- next data and time in UTC: " + new Date(next).toISOString());
  console.log("-- next data and time in server time zone: " + new Date(next).toString());

  var diff = next - new Date(now); // UTC time is used; change if daylight saving time is introduced

  var daysLeft = Math.floor(diff / days);
  var hoursLeft = Math.floor((diff % days) / hours);
  var minutesLeft = Math.floor((diff % hours) / minutes);
  var secondsLeft = Math.floor((diff % minutes) / seconds);

  var tMinus = [daysLeft, hoursLeft, minutesLeft, secondsLeft];
  var tMinusDescriptors = tMinus.map(function(el, idx) {
    return describe(el, ["дней", "часов", "минут", "секунд"][idx]);
  });

  // console.log("T minus " + tMinus[0] + ":" + tMinus[1] + ":" + tMinus[2] + ":" + tMinus[3] + " and counting");
  return ("До бани осталось " +
              tMinus[0] + " " + tMinusDescriptors[0] + " " +
              tMinus[1] + " " + tMinusDescriptors[1] + " " +
              tMinus[2] + " " + tMinusDescriptors[2] + " " +
              tMinus[3] + " " + tMinusDescriptors[3] + ".");
}<commit_msg>minor edits<commit_after>require('datejs');

function incrementDate(currentDay) {
	if (currentDay >= 0 && currentDay < 3) return 3 - currentDay;
	if (currentDay == 3) return 3;
	return 7 - currentDay + 3;
}

function describe(tMinus, descriptor) {

  var options = [];

  switch(descriptor) {
    case "дней":
      options = ["день", "дня", "дней"];
      break;
    case "часов":
      options = ["час", "часа", "часов"];
      break;
    case "минут":
      options = ["минута", "минуты", "минут"];
      break;
    case "секунд":
      options = ["секунда", "секунды", "секунд"];
      break;
  }

  if (tMinus >= 11 && tMinus <= 20) {
    return options[2];
  } else if (tMinus % 10 == 1) {
    return options[0];
  } else if (tMinus % 10 > 1 && tMinus % 10 < 5) {
    return options[1];
  } else {
    return options[2];
  }

}

module.exports = function() {

  // Everything here is based on UTC time; need to change if daylight saving time is introduced again in Russia

  // convert to UTC time
  var now_loc = new Date();
  var now = new Date(now_loc.getUTCFullYear(), now_loc.getUTCMonth(), now_loc.getUTCDate(), now_loc.getUTCHours(), now_loc.getUTCMinutes(), now_loc.getUTCSeconds());

  var offset = new Date(now).getTimezoneOffset();
  // now = new Date(2016, 7, 9, 23, 32, 41); // testing data
  console.log("-- current data and time in UTC: " + new Date(now).toISOString());
  console.log("-- current data and time in server time zone: " + new Date(now).toString());
  console.log("-- timezone offset UTC: " + offset);

  var days = (1000 * 60 * 60 * 24);
  var hours = (60 * 60 * 1000);
  var minutes = (60 * 1000);
  var seconds = 1000;

  if (now.getDay() == 3 && now.getHours() >= 16 && now.getHours() <= 19) {
    var start = new Date(now).setHours(16);
    start = new Date(start).setMinutes(0);
    start = new Date(start).setSeconds(0);
    var diff = Math.abs(start - new Date(now));
    var hoursRunning = Math.floor(diff / hours);
    var minutesRunning = Math.floor(((diff - hoursRunning * hours) % hours) / minutes);
    var secondsRunning = Math.floor(((diff - hoursRunning * hours - minutesRunning * minutes) % minutes) / seconds);

    var running = [hoursRunning, minutesRunning, secondsRunning];
    var descriptors = running.map(function(el, idx) {
      var temp = describe(el, ["часов", "минут", "секунд"][idx]);
      var out;
      switch (temp) {
        case "минута":
          out = "минуту";
          break;
        case "секунда":
          out = "секунду";
          break;
        default:
          out = temp;
          break;
      }
      return out;
    });

    return ("Баня в активной фазе " +
              running[0] + " " + descriptors[0] + " " +
              running[1] + " " + descriptors[1] + " " +
              running[2] + " " + descriptors[2] + ".");
  }

  var next = new Date(now);

  if (now.getDay() != 3 || (now.getDay() == 3 && now.getHours() >= 19)) {
    next = next.next().wednesday();
  }

  next = new Date(next).setSeconds(0);
  next = new Date(next).setMinutes(0);
  next = new Date(next).setHours(16); // UTC time is used; need to change if daylight saving time is introduced
  console.log("-- next data and time in UTC: " + new Date(next).toISOString());
  console.log("-- next data and time in server time zone: " + new Date(next).toString());

  var diff = next - new Date(now); // UTC time is used; change if daylight saving time is introduced

  var daysLeft = Math.floor(diff / days);
  var hoursLeft = Math.floor((diff % days) / hours);
  var minutesLeft = Math.floor((diff % hours) / minutes);
  var secondsLeft = Math.floor((diff % minutes) / seconds);

  var tMinus = [daysLeft, hoursLeft, minutesLeft, secondsLeft];
  var tMinusDescriptors = tMinus.map(function(el, idx) {
    return describe(el, ["дней", "часов", "минут", "секунд"][idx]);
  });

  // console.log("T minus " + tMinus[0] + ":" + tMinus[1] + ":" + tMinus[2] + ":" + tMinus[3] + " and counting");
  return ("До бани осталось " +
              tMinus[0] + " " + tMinusDescriptors[0] + " " +
              tMinus[1] + " " + tMinusDescriptors[1] + " " +
              tMinus[2] + " " + tMinusDescriptors[2] + " " +
              tMinus[3] + " " + tMinusDescriptors[3] + ".");
}<|endoftext|>


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

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, brackets, $, window */

define(function (require, exports, module) {
    'use strict';

    var EditorManager   = brackets.getModule("editor/EditorManager"),
        PerfUtils       = brackets.getModule("utils/PerfUtils");

    function KeystrokeData(init) {
        init = init || 0;
        this.input = init;
        this.firstPaint = init;
        this.paintBeforeChange = init;
        this.onChange = init;
        this.paintAfterChange = init;
    }

    var min,
        sum,
        avg,
        max,
        inputCount,
        perfData = PerfUtils.perfData;

    function _writePerfData(metricName, propName, recent) {
        perfData[metricName] = min[propName]
            + " / " + avg[propName]
            + " / " + max[propName]
            + " / " + recent[propName];
    }

    function _updateKeystrokeStats(data) {
        min.firstPaint = Math.min(min.firstPaint, data.firstPaint);
        min.paintBeforeChange = Math.min(min.paintBeforeChange, data.paintBeforeChange);
        min.onChange = Math.min(min.onChange, data.onChange);
        min.paintAfterChange = Math.min(min.paintAfterChange, data.paintAfterChange);

        sum.firstPaint += data.firstPaint;
        sum.paintBeforeChange += data.paintBeforeChange;
        sum.onChange += data.onChange;
        sum.paintAfterChange += data.paintAfterChange;

        avg.firstPaint = Math.round(sum.firstPaint / inputCount);
        avg.paintBeforeChange = Math.round(sum.paintBeforeChange / inputCount);
        avg.onChange = Math.round(sum.onChange / inputCount);
        avg.paintAfterChange = Math.round(sum.paintAfterChange / inputCount);

        max.firstPaint = Math.max(max.firstPaint, data.firstPaint);
        max.paintBeforeChange = Math.max(max.paintBeforeChange, data.paintBeforeChange);
        max.onChange = Math.max(max.onChange, data.onChange);
        max.paintAfterChange = Math.max(max.paintAfterChange, data.paintAfterChange);

        _writePerfData("Typing Speed: First repaint (min / avg / max / recent)", "firstPaint", data);
        _writePerfData("Typing Speed: Paint before DOM update", "paintBeforeChange", data);
        _writePerfData("Typing Speed: DOM update complete", "onChange", data);
        _writePerfData("Typing Speed: Paint after DOM update", "paintAfterChange", data);
    }

    function _getInputField(editor) {
        return editor._codeMirror.getInputField();
    }

    function resetTypingSpeedLogs() {
        min = new KeystrokeData(Number.POSITIVE_INFINITY);
        sum = new KeystrokeData(0);
        avg = new KeystrokeData(0);
        max = new KeystrokeData(Number.NEGATIVE_INFINITY);
        inputCount = 0;
    }

    /**
     * Installs input event handler on the current editor (full or inline).
     */
    function initTypingSpeedLogging() {
        var editor = null,
            inputField = null,
            inProgress = false;

        resetTypingSpeedLogs();

        var inputChangedHandler = function () {
            // CodeMirror's fastPoll will batch up input events into a consolidated change
            if (inProgress) {
                return;
            }

            inProgress = true;
            inputCount++;

            var startPos = editor.getCursorPos(),
                key = startPos.line + ":" + startPos.ch;

            if (inProgress[key]) {
                return;
            }

            var data = new KeystrokeData(0);
            data.input = Date.now();

            var repaintBeforeChangeHandler = function () {
                if (data.firstPaint === 0) {
                    data.firstPaint = Date.now() - data.input;
                }

                // keep logging until we hit onChange
                if (data.onChange === 0) {
                    data.paintBeforeChange = Date.now() - data.input;
                    window.webkitRequestAnimationFrame(repaintBeforeChangeHandler);
                }
            };

            var repaintAfterChangeHandler = function () {
                data.paintAfterChange = Date.now() - data.input;

                inProgress = false;

                // we have all the data for this input sequence. compute min/avg/max.
                _updateKeystrokeStats(data);
            };

            var onChangeHandler = function (event, editor, change) {
                // match the change from position to the original input event position
                if ((startPos.line === change.from.line) && (startPos.ch === change.from.ch)) {
                    data.onChange = Date.now() - data.input;
                    $(editor).off("change.typingSpeedLogger", onChangeHandler);

                    window.webkitRequestAnimationFrame(repaintAfterChangeHandler);
                }
            };

            window.webkitRequestAnimationFrame(repaintBeforeChangeHandler);
            $(editor).on("change.typingSpeedLogger", onChangeHandler);
        };

        var updateFocusedEditor = function (focusedEditor) {
            if (editor) {
                inputField.removeEventListener("input", inputChangedHandler, true);
            }

            if (focusedEditor) {
                editor = focusedEditor;
                inputField = _getInputField(focusedEditor);

                // Listen for input changes in the capture phase, before
                // CodeMirror's event handling.
                inputField.addEventListener("input", inputChangedHandler, true);
            }
        };

        $(EditorManager).on("focusedEditorChange", function (event, focusedEditor) {
            updateFocusedEditor(focusedEditor);
        });
        updateFocusedEditor(EditorManager.getFocusedEditor());
    }

    (function () {
        initTypingSpeedLogging();
    }());

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

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, brackets, $, window */

define(function (require, exports, module) {
    'use strict';

    var EditorManager   = brackets.getModule("editor/EditorManager"),
        PerfUtils       = brackets.getModule("utils/PerfUtils");

    function KeystrokeData(init) {
        init = init || 0;
        this.input = init;
        this.firstPaint = init;
        this.paintBeforeChange = init;
        this.onChange = init;
        this.paintAfterChange = init;
    }

    var min,
        sum,
        avg,
        max,
        charCount, /* using charCount instead of inputEventCount will artificially lower metrics */
        inputEventCount,
        perfData = PerfUtils.perfData;

    function _writePerfData(metricName, propName, recent) {
        perfData[metricName] = min[propName]
            + " / " + avg[propName]
            + " / " + max[propName]
            + " / " + recent[propName];
    }

    function _updateKeystrokeStats(data) {
        min.firstPaint = Math.min(min.firstPaint, data.firstPaint);
        min.paintBeforeChange = Math.min(min.paintBeforeChange, data.paintBeforeChange);
        min.onChange = Math.min(min.onChange, data.onChange);
        min.paintAfterChange = Math.min(min.paintAfterChange, data.paintAfterChange);

        sum.firstPaint += data.firstPaint;
        sum.paintBeforeChange += data.paintBeforeChange;
        sum.onChange += data.onChange;
        sum.paintAfterChange += data.paintAfterChange;

        avg.firstPaint = Math.round(sum.firstPaint / inputEventCount);
        avg.paintBeforeChange = Math.round(sum.paintBeforeChange / inputEventCount);
        avg.onChange = Math.round(sum.onChange / inputEventCount);
        avg.paintAfterChange = Math.round(sum.paintAfterChange / inputEventCount);

        max.firstPaint = Math.max(max.firstPaint, data.firstPaint);
        max.paintBeforeChange = Math.max(max.paintBeforeChange, data.paintBeforeChange);
        max.onChange = Math.max(max.onChange, data.onChange);
        max.paintAfterChange = Math.max(max.paintAfterChange, data.paintAfterChange);

        _writePerfData("Typing Speed: First repaint (min / avg / max / recent)", "firstPaint", data);
        _writePerfData("Typing Speed: Paint before DOM update", "paintBeforeChange", data);
        _writePerfData("Typing Speed: DOM update complete", "onChange", data);
        _writePerfData("Typing Speed: Paint after DOM update", "paintAfterChange", data);
    }

    function _getInputField(editor) {
        return editor._codeMirror.getInputField();
    }

    function resetTypingSpeedLogs() {
        min = new KeystrokeData(Number.POSITIVE_INFINITY);
        sum = new KeystrokeData(0);
        avg = new KeystrokeData(0);
        max = new KeystrokeData(Number.NEGATIVE_INFINITY);
        inputEventCount = 0;
    }

    /**
     * Installs input event handler on the current editor (full or inline).
     */
    function initTypingSpeedLogging() {
        var editor = null,
            inputField = null,
            inProgress = false;

        resetTypingSpeedLogs();

        var inputChangedHandler = function () {
            // CodeMirror's fastPoll will batch up input events into a consolidated change
            if (inProgress) {
                return;
            }

            inProgress = true;

            // Since input events are batched, inputEventCount isn't 1:1 with actual input events.
            inputEventCount++;

            var data = new KeystrokeData(0);
            data.input = Date.now();

            var repaintBeforeChangeHandler = function () {
                if (data.firstPaint === 0) {
                    data.firstPaint = Date.now() - data.input;
                }

                // keep logging until we hit onChange
                if (data.onChange === 0) {
                    data.paintBeforeChange = Date.now() - data.input;
                    window.webkitRequestAnimationFrame(repaintBeforeChangeHandler);
                }
            };

            var repaintAfterChangeHandler = function () {
                data.paintAfterChange = Date.now() - data.input;

                inProgress = false;

                // we have all the data for this input sequence. compute min/avg/max.
                _updateKeystrokeStats(data);
            };

            var onChangeHandler = function (event, editor, change) {
                var textChangesLen = change.text.length,
                    i = 0;

                data.onChange = Date.now() - data.input;
                $(editor).off("change.typingSpeedLogger", onChangeHandler);

                for (i = 0; i < textChangesLen; i++) {
                    charCount += change.text[i].length;
                }

                window.webkitRequestAnimationFrame(repaintAfterChangeHandler);
            };

            window.webkitRequestAnimationFrame(repaintBeforeChangeHandler);
            $(editor).on("change.typingSpeedLogger", onChangeHandler);
        };

        var updateFocusedEditor = function (focusedEditor) {
            if (editor) {
                inputField.removeEventListener("input", inputChangedHandler, true);
            }

            if (focusedEditor) {
                editor = focusedEditor;
                inputField = _getInputField(focusedEditor);

                // Listen for input changes in the capture phase, before
                // CodeMirror's event handling.
                inputField.addEventListener("input", inputChangedHandler, true);
            }
        };

        $(EditorManager).on("focusedEditorChange", function (event, focusedEditor) {
            updateFocusedEditor(focusedEditor);
        });
        updateFocusedEditor(EditorManager.getFocusedEditor());
    }

    (function () {
        initTypingSpeedLogging();
    }());

    exports.resetTypingSpeedLogs = resetTypingSpeedLogs;
});
<|endoftext|>


<commit_before>'use strict';

var React = require('react-native');
var {
  PropTypes,
  StyleSheet,
  PanResponder,
  View,
  TouchableHighlight
} = React;

var converter = require('./converter.js');
var mockProps = require('./mockProps.js');

var sliderProps = {
  values: PropTypes.arrayOf(PropTypes.number),

  onValuesChangeStart: PropTypes.func,
  onValuesChange: PropTypes.func,
  onValuesChangeFinish: PropTypes.func,

  sliderLength: PropTypes.number,
  sliderOrientation: PropTypes.string,
  touchDimensions: PropTypes.object,

  customMarker: PropTypes.func,

  min: PropTypes.number,
  max: PropTypes.number,
  step: PropTypes.number,

  optionsArray: PropTypes.array,

  containerStyle: View.propTypes.style,
  trackStyle: View.propTypes.style,
  selectedStyle: View.propTypes.style,
  unselectedStyle: View.propTypes.style,
  markerStyle: View.propTypes.style,
  pressedMarkerStyle: View.propTypes.style
};

var Slider = React.createClass({

  propTypes: sliderProps,

  getDefaultProps: function() {
    return mockProps;
  },

  getInitialState() {
    this.optionsArray = this.props.optionsArray || converter.createArray(this.props.min,this.props.max,this.props.step);
    this.stepLength = this.props.sliderLength/this.optionsArray.length;

    var initialValues = this.props.values.map(value => converter.valueToPosition(value,this.optionsArray,this.props.sliderLength));

    return {
      pressedOne: true,
      valueOne: this.props.values[0],
      valueTwo: this.props.values[1],
      pastOne: initialValues[0],
      pastTwo: initialValues[1],
      positionOne: initialValues[0],
      positionTwo: initialValues[1]
    };
  },

  componentWillMount() {
    var customPanResponder = function (start,move,end) {
      return PanResponder.create({
        onStartShouldSetPanResponder: (evt, gestureState) => true,
        onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
        onMoveShouldSetPanResponder: (evt, gestureState) => true,
        onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
        onPanResponderGrant: (evt, gestureState) => start(),
        onPanResponderMove: (evt, gestureState) => move(gestureState),
        onPanResponderTerminationRequest: (evt, gestureState) => true,
        onPanResponderRelease: (evt, gestureState) => end(gestureState),
        onPanResponderTerminate: (evt, gestureState) => end(gestureState),
        onShouldBlockNativeResponder: (evt, gestureState) => true
      })
    };

    this._panResponderOne = customPanResponder(this.startOne, this.moveOne, this.endOne);
    this._panResponderTwo = customPanResponder(this.startTwo, this.moveTwo, this.endTwo);

  },

  componentWillReceiveProps(nextProps) {
    var { values } = this.props;

    // Maybe there is a more fancy way to check array
    // inequality, but for now it works :).
    if (nextProps.values.join() !== values.join()) {
      this.set(nextProps.values, nextProps.min, nextProps.max, nextProps.step);
    }
  },

  set(values, min, max, step) {
    this.optionsArray = this.props.optionsArray || converter.createArray(min, max, step);
    this.stepLength = this.props.sliderLength/this.optionsArray.length;

    var initialValues = values.map(value => converter.valueToPosition(value,this.optionsArray,this.props.sliderLength));

    this.setState({
      pressedOne: true,
      valueOne: values[0],
      valueTwo: values[1],
      pastOne: initialValues[0],
      pastTwo: initialValues[1],
      positionOne: initialValues[0],
      positionTwo: initialValues[1]
    });
  },

  startOne () {
    this.props.onValuesChangeStart();
    this.setState({
      onePressed: !this.state.onePressed
    });
  },

  startTwo () {
    this.props.onValuesChangeStart();
    this.setState({
      twoPressed: !this.state.twoPressed
    });
  },

  moveOne(gestureState) {
    var unconfined = gestureState.dx + this.state.pastOne;
    var bottom     = 0;
    var top        = (this.state.positionTwo - this.stepLength) || this.props.sliderLength;
    var confined   = unconfined < bottom ? bottom : (unconfined > top ? top : unconfined);
    var value      = converter.positionToValue(this.state.positionOne, this.optionsArray, this.props.sliderLength);

    var slipDisplacement = this.props.touchDimensions.slipDisplacement;

    if (Math.abs(gestureState.dy) < slipDisplacement || !slipDisplacement) {
      this.setState({
        positionOne: confined
      });
    }
    if ( value !== this.state.valueOne ) {
      this.setState({
        valueOne: value
      }, function () {
        var change = [this.state.valueOne];
        if (this.state.valueTwo) {
          change.push(this.state.valueTwo);
        }
        this.props.onValuesChange(change);
      });
    }
  },

  moveTwo(gestureState) {
    var unconfined  = gestureState.dx + this.state.pastTwo;
    var bottom      = this.state.positionOne + this.stepLength;
    var top         = this.props.sliderLength;
    var confined    = unconfined < bottom ? bottom : (unconfined > top ? top : unconfined);
    var value       = converter.positionToValue(this.state.positionTwo, this.optionsArray, this.props.sliderLength);
    var slipDisplacement = this.props.touchDimensions.slipDisplacement;

    if (Math.abs(gestureState.dy) < slipDisplacement || !slipDisplacement) {
      this.setState({
        positionTwo: confined
      });
    }
    if ( value !== this.state.valueTwo ) {
      this.setState({
        valueTwo: value
      }, function () {
        this.props.onValuesChange([this.state.valueOne,this.state.valueTwo]);
      });
    }
  },

  endOne(gestureState) {
    this.setState({
      pastOne: this.state.positionOne,
      onePressed: !this.state.onePressed
    }, function () {
      var change = [this.state.valueOne];
      if (this.state.valueTwo) {
        change.push(this.state.valueTwo);
      }
      this.props.onValuesChangeFinish(change);
    });
  },

  endTwo(gestureState) {
    this.setState({
      twoPressed: !this.state.twoPressed,
      pastTwo: this.state.positionTwo,
    }, function () {
      this.props.onValuesChangeFinish([this.state.valueOne,this.state.valueTwo]);
    });
  },

  render() {

    var {positionOne, positionTwo} = this.state;
    var {selectedStyle, unselectedStyle, sliderLength} = this.props;
    var twoMarkers = positionTwo;

    var trackOneLength = positionOne;
    var trackOneStyle = twoMarkers ? unselectedStyle : selectedStyle;
    var trackThreeLength = twoMarkers ? sliderLength - (positionTwo) : 0;
    var trackThreeStyle = unselectedStyle;
    var trackTwoLength = sliderLength - trackOneLength - trackThreeLength;
    var trackTwoStyle = twoMarkers ? selectedStyle : unselectedStyle;
    var Marker = this.props.customMarker;
    var {slipDisplacement, height, width, borderRadius} = this.props.touchDimensions;
    var touchStyle = {
      height: height,
      width: width,
      left: -width/2,
      borderRadius: borderRadius || 0
    };

    return (
      <View style={[styles.container, this.props.containerStyle]}>
        <View style={[styles.fullTrack, {width:sliderLength}]}>
          <View style={[this.props.trackStyle, styles.track, trackOneStyle, {width: trackOneLength}]} />
          <View style={[this.props.trackStyle, styles.track, trackTwoStyle, {width: trackTwoLength}]}>
            <View
              style={[styles.touch,touchStyle]}
              ref={component => this._markerOne = component}
              {...this._panResponderOne.panHandlers}
            >
              <Marker
                pressed={this.state.onePressed}
                markerStyle={this.props.markerStyle}
                pressedMarkerStyle={this.props.pressedMarkerStyle}
              />
            </View>
          </View>
          {twoMarkers && (
            <View style={[this.props.trackStyle, styles.track, trackThreeStyle, {width: trackThreeLength}]}>
              {(positionOne !== this.props.sliderLength) && (
                <View
                  style={[styles.touch,touchStyle]}
                  ref={component => this._markerTwo = component}
                  {...this._panResponderTwo.panHandlers}
                >
                  <Marker
                    pressed={this.state.twoPressed}
                    markerStyle={this.props.markerStyle}
                    pressedMarkerStyle={this.props.pressedMarkerStyle}
                  />
                </View>
              )}
            </View>
          )}
        </View>
      </View>
    );
  }
});

module.exports = Slider;

var styles = StyleSheet.create({
  container: {
    justifyContent: 'center',
  },
  fullTrack: {
    flexDirection: 'row',
  },
  track: {
    justifyContent: 'center'
  },
  touch: {
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'transparent'
  }
});
<commit_msg>Update sliders optionsArray<commit_after>'use strict';

var React = require('react-native');
var {
  PropTypes,
  StyleSheet,
  PanResponder,
  View,
  TouchableHighlight
} = React;

var converter = require('./converter.js');
var mockProps = require('./mockProps.js');

var sliderProps = {
  values: PropTypes.arrayOf(PropTypes.number),

  onValuesChangeStart: PropTypes.func,
  onValuesChange: PropTypes.func,
  onValuesChangeFinish: PropTypes.func,

  sliderLength: PropTypes.number,
  sliderOrientation: PropTypes.string,
  touchDimensions: PropTypes.object,

  customMarker: PropTypes.func,

  min: PropTypes.number,
  max: PropTypes.number,
  step: PropTypes.number,

  optionsArray: PropTypes.array,

  containerStyle: View.propTypes.style,
  trackStyle: View.propTypes.style,
  selectedStyle: View.propTypes.style,
  unselectedStyle: View.propTypes.style,
  markerStyle: View.propTypes.style,
  pressedMarkerStyle: View.propTypes.style
};

var Slider = React.createClass({

  propTypes: sliderProps,

  getDefaultProps: function() {
    return mockProps;
  },

  getInitialState() {
    this.optionsArray = this.props.optionsArray || converter.createArray(this.props.min,this.props.max,this.props.step);
    this.stepLength = this.props.sliderLength/this.optionsArray.length;

    var initialValues = this.props.values.map(value => converter.valueToPosition(value,this.optionsArray,this.props.sliderLength));

    return {
      pressedOne: true,
      valueOne: this.props.values[0],
      valueTwo: this.props.values[1],
      pastOne: initialValues[0],
      pastTwo: initialValues[1],
      positionOne: initialValues[0],
      positionTwo: initialValues[1]
    };
  },

  componentWillMount() {
    var customPanResponder = function (start,move,end) {
      return PanResponder.create({
        onStartShouldSetPanResponder: (evt, gestureState) => true,
        onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
        onMoveShouldSetPanResponder: (evt, gestureState) => true,
        onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
        onPanResponderGrant: (evt, gestureState) => start(),
        onPanResponderMove: (evt, gestureState) => move(gestureState),
        onPanResponderTerminationRequest: (evt, gestureState) => true,
        onPanResponderRelease: (evt, gestureState) => end(gestureState),
        onPanResponderTerminate: (evt, gestureState) => end(gestureState),
        onShouldBlockNativeResponder: (evt, gestureState) => true
      })
    };

    this._panResponderOne = customPanResponder(this.startOne, this.moveOne, this.endOne);
    this._panResponderTwo = customPanResponder(this.startTwo, this.moveTwo, this.endTwo);

  },

  componentWillReceiveProps(nextProps) {
    var { values } = this.props;
    if (nextProps.values.join() !== values.join()) {
      this.set(nextProps);
    }
  },

  set(config) {
    var { max, min, optionsArray, step, values } = config || this.props;
    this.optionsArray = optionsArray || converter.createArray(min, max, step);
    this.stepLength = this.props.sliderLength/this.optionsArray.length;

    var initialValues = values.map(value => converter.valueToPosition(value,this.optionsArray,this.props.sliderLength));

    this.setState({
      pressedOne: true,
      valueOne: values[0],
      valueTwo: values[1],
      pastOne: initialValues[0],
      pastTwo: initialValues[1],
      positionOne: initialValues[0],
      positionTwo: initialValues[1]
    });
  },

  startOne () {
    this.props.onValuesChangeStart();
    this.setState({
      onePressed: !this.state.onePressed
    });
  },

  startTwo () {
    this.props.onValuesChangeStart();
    this.setState({
      twoPressed: !this.state.twoPressed
    });
  },

  moveOne(gestureState) {
    var unconfined = gestureState.dx + this.state.pastOne;
    var bottom     = 0;
    var top        = (this.state.positionTwo - this.stepLength) || this.props.sliderLength;
    var confined   = unconfined < bottom ? bottom : (unconfined > top ? top : unconfined);
    var value      = converter.positionToValue(this.state.positionOne, this.optionsArray, this.props.sliderLength);

    var slipDisplacement = this.props.touchDimensions.slipDisplacement;

    if (Math.abs(gestureState.dy) < slipDisplacement || !slipDisplacement) {
      this.setState({
        positionOne: confined
      });
    }
    if ( value !== this.state.valueOne ) {
      this.setState({
        valueOne: value
      }, function () {
        var change = [this.state.valueOne];
        if (this.state.valueTwo) {
          change.push(this.state.valueTwo);
        }
        this.props.onValuesChange(change);
      });
    }
  },

  moveTwo(gestureState) {
    var unconfined  = gestureState.dx + this.state.pastTwo;
    var bottom      = this.state.positionOne + this.stepLength;
    var top         = this.props.sliderLength;
    var confined    = unconfined < bottom ? bottom : (unconfined > top ? top : unconfined);
    var value       = converter.positionToValue(this.state.positionTwo, this.optionsArray, this.props.sliderLength);
    var slipDisplacement = this.props.touchDimensions.slipDisplacement;

    if (Math.abs(gestureState.dy) < slipDisplacement || !slipDisplacement) {
      this.setState({
        positionTwo: confined
      });
    }
    if ( value !== this.state.valueTwo ) {
      this.setState({
        valueTwo: value
      }, function () {
        this.props.onValuesChange([this.state.valueOne,this.state.valueTwo]);
      });
    }
  },

  endOne(gestureState) {
    this.setState({
      pastOne: this.state.positionOne,
      onePressed: !this.state.onePressed
    }, function () {
      var change = [this.state.valueOne];
      if (this.state.valueTwo) {
        change.push(this.state.valueTwo);
      }
      this.props.onValuesChangeFinish(change);
    });
  },

  endTwo(gestureState) {
    this.setState({
      twoPressed: !this.state.twoPressed,
      pastTwo: this.state.positionTwo,
    }, function () {
      this.props.onValuesChangeFinish([this.state.valueOne,this.state.valueTwo]);
    });
  },

  render() {

    var {positionOne, positionTwo} = this.state;
    var {selectedStyle, unselectedStyle, sliderLength} = this.props;
    var twoMarkers = positionTwo;

    var trackOneLength = positionOne;
    var trackOneStyle = twoMarkers ? unselectedStyle : selectedStyle;
    var trackThreeLength = twoMarkers ? sliderLength - (positionTwo) : 0;
    var trackThreeStyle = unselectedStyle;
    var trackTwoLength = sliderLength - trackOneLength - trackThreeLength;
    var trackTwoStyle = twoMarkers ? selectedStyle : unselectedStyle;
    var Marker = this.props.customMarker;
    var {slipDisplacement, height, width, borderRadius} = this.props.touchDimensions;
    var touchStyle = {
      height: height,
      width: width,
      left: -width/2,
      borderRadius: borderRadius || 0
    };

    return (
      <View style={[styles.container, this.props.containerStyle]}>
        <View style={[styles.fullTrack, {width:sliderLength}]}>
          <View style={[this.props.trackStyle, styles.track, trackOneStyle, {width: trackOneLength}]} />
          <View style={[this.props.trackStyle, styles.track, trackTwoStyle, {width: trackTwoLength}]}>
            <View
              style={[styles.touch,touchStyle]}
              ref={component => this._markerOne = component}
              {...this._panResponderOne.panHandlers}
            >
              <Marker
                pressed={this.state.onePressed}
                markerStyle={this.props.markerStyle}
                pressedMarkerStyle={this.props.pressedMarkerStyle}
              />
            </View>
          </View>
          {twoMarkers && (
            <View style={[this.props.trackStyle, styles.track, trackThreeStyle, {width: trackThreeLength}]}>
              {(positionOne !== this.props.sliderLength) && (
                <View
                  style={[styles.touch,touchStyle]}
                  ref={component => this._markerTwo = component}
                  {...this._panResponderTwo.panHandlers}
                >
                  <Marker
                    pressed={this.state.twoPressed}
                    markerStyle={this.props.markerStyle}
                    pressedMarkerStyle={this.props.pressedMarkerStyle}
                  />
                </View>
              )}
            </View>
          )}
        </View>
      </View>
    );
  }
});

module.exports = Slider;

var styles = StyleSheet.create({
  container: {
    justifyContent: 'center',
  },
  fullTrack: {
    flexDirection: 'row',
  },
  track: {
    justifyContent: 'center'
  },
  touch: {
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'transparent'
  }
});
<|endoftext|>


<commit_before>const path = require('path');
const simpleGit = require('simple-git');
const { repositoryRootPath } = require('../../config');
const git = simpleGit(repositoryRootPath);
const packageJsonFilePath = path.join(repositoryRootPath, 'package.json');
const packageLockFilePath = path.join(repositoryRootPath, 'package-lock.json');

// TODO config git.credentials()
module.exports = {
  switchToMaster: async function() {
    const { current } = await git.branch();
    if (current !== 'master') {
      await git.checkout('master');
    }
    await git.pull('origin', 'master');
  },
  makeBranch: async function(dependency) {
    const newBranch = `${dependency.moduleName}-${dependency.latest}`;
    const { branches } = await git.branch();
    const { files } = await git.status();
    if (files.length > 0) {
      await git.reset('hard');
    }
    const found = Object.keys(branches).find(
      branch => branch.indexOf(newBranch) > -1
    );
    found
      ? await git.checkout(found)
      : await git.checkoutLocalBranch(newBranch);
    return { found, newBranch };
  },
  createCommit: async function({ moduleName, latest }) {
    try {
      const commitMessage = `:arrow_up: ${moduleName}@${latest}`;
      await git.add([packageJsonFilePath, packageLockFilePath]);
      await git.commit(commitMessage);
    } catch (ex) {
      throw Error(ex.message);
    }
  },
  publishBranch: async function(branch) {
    try {
      await git.push('origin', branch);
    } catch (ex) {
      throw Error(ex.message);
    }
  },
  deleteBranch: async function(branch) {
    try {
      await git.deleteLocalBranch(branch, true);
    } catch (ex) {
      throw Error(ex.message);
    }
  }
};
<commit_msg>used current branch<commit_after>const path = require('path');
const simpleGit = require('simple-git');
const { repositoryRootPath } = require('../../config');
const git = simpleGit(repositoryRootPath);
const packageJsonFilePath = path.join(repositoryRootPath, 'package.json');
const packageLockFilePath = path.join(repositoryRootPath, 'package-lock.json');

// TODO config git.credentials()
module.exports = {
  switchToMaster: async function() {
    const { current } = await git.branch();
    if (current !== 'dependency-automation') {
      await git.checkout('dependency-automation');
    }
    // await git.pull('origin', 'dependency-automation');
  },
  makeBranch: async function(dependency) {
    const newBranch = `${dependency.moduleName}-${dependency.latest}`;
    const { branches } = await git.branch();
    const { files } = await git.status();
    if (files.length > 0) {
      await git.reset('hard');
    }
    const found = Object.keys(branches).find(
      branch => branch.indexOf(newBranch) > -1
    );
    found
      ? await git.checkout(found)
      : await git.checkoutLocalBranch(newBranch);
    return { found, newBranch };
  },
  createCommit: async function({ moduleName, latest }) {
    try {
      const commitMessage = `:arrow_up: ${moduleName}@${latest}`;
      await git.add([packageJsonFilePath, packageLockFilePath]);
      await git.commit(commitMessage);
    } catch (ex) {
      throw Error(ex.message);
    }
  },
  publishBranch: async function(branch) {
    try {
      await git.push('origin', branch);
    } catch (ex) {
      throw Error(ex.message);
    }
  },
  deleteBranch: async function(branch) {
    try {
      await git.deleteLocalBranch(branch, true);
    } catch (ex) {
      throw Error(ex.message);
    }
  }
};
<|endoftext|>


<commit_before>/* global define */

define([
  'jquery',
  'underscore',
  'controllers/base-controller',
  'views/loading-view',
  'buses/command-bus'
], function ($, _, BaseController, LoadingView, CommandBus) {
  'use strict';

  var LoadingController = BaseController.extend({
    busEvents: {
      'fetch:done': 'closeLoading',
    },

    style: {
      loading: function (options) {
        this.show(new LoadingView({ title: options.title }), options);
      },

      opacity: function (options) {
        options.region.$el.addClass('opacity');
        $('body,html').animate({ scrollTop: 0 }, 800);
      }
    },

    initialize: function (options) {
      var config = options.config === true ? {} : options.config;

      this.view = options.view;
      _.defaults(config, this._getDefaults(options.options));

      this._bindCommand();
      this._showLoading(config, options.options);
      this._fetchEntities(this.view, config);
    },

    closeLoading: function () {
      this.region.$el.removeClass('opacity');
      if (!this.view) {
        this.unregister();
      }
    },

    /**
     * Display the current progress
     * @param  {Object} data An object containing the current progress (total and loaded)
     */
    displayProgress: function (data) {
      if (this.mainView) {
        this.mainView.progress(data);
      }
    },

    _bindCommand: function () {
      CommandBus.setHandler('loading:progress', this.displayProgress, this);
    },

    _showLoading: function (config, options) {
      if (this.style.hasOwnProperty(config.style)) {
        this.style[config.style].bind(this)(options);
      }
    },

    _fetchEntities: function (view, config) {
      CommandBus.execute('when:fetched', config.entities, config.done, config.fail);
    },

    _getDefaults: function (options) {
      return {
        entities:  this._getEntities(this.view),
        operation: 'fetch',
        style:     'loading',

        done: function () {
          this.show(this.view, { region: options.region });
        }.bind(this),

        fail: function () {}
      };
    },

    _getEntities: function (view) {
      return _.chain(view).pick('model', 'collection')
                          .toArray()
                          .compact()
                          .value();
    }
  });

  CommandBus.setHandler('show:loading', function (view, options) {
    new LoadingController({
      view:    view,
      options: { region: options.region, title: options.title },
      config:  options.loading
    });
  });

  return LoadingController;
});<commit_msg>Add a no-style loading and minor adjustment in default done<commit_after>/* global define */

define([
  'jquery',
  'underscore',
  'controllers/base-controller',
  'views/loading-view',
  'buses/command-bus'
], function ($, _, BaseController, LoadingView, CommandBus) {
  'use strict';

  var LoadingController = BaseController.extend({
    busEvents: {
      'fetch:done': 'closeLoading',
    },

    style: {
      'no-style': function () {
        // do nothing
      },

      loading: function (options) {
        this.show(new LoadingView({ title: options.title }), options);
      },

      opacity: function (options) {
        options.region.$el.addClass('opacity');
        $('body,html').animate({ scrollTop: 0 }, 800);
      }
    },

    initialize: function (options) {
      var config = options.config === true ? {} : options.config;

      this.view = options.view;
      _.defaults(config, this._getDefaults(options.options));

      this._bindCommand();
      this._showLoading(config, options.options);
      this._fetchEntities(this.view, config);
    },

    closeLoading: function () {
      this.region.$el.removeClass('opacity');
      if (!this.view) {
        this.unregister();
      }
    },

    /**
     * Display the current progress
     * @param  {Object} data An object containing the current progress (total and loaded)
     */
    displayProgress: function (data) {
      if (this.mainView) {
        this.mainView.progress(data);
      }
    },

    _bindCommand: function () {
      CommandBus.setHandler('loading:progress', this.displayProgress, this);
    },

    _showLoading: function (config, options) {
      if (this.style.hasOwnProperty(config.style)) {
        this.style[config.style].bind(this)(options);
      }
    },

    _fetchEntities: function (view, config) {
      CommandBus.execute('when:fetched', config.entities, config.done, config.fail);
    },

    _getDefaults: function (options) {
      return {
        entities:  this._getEntities(this.view),
        operation: 'fetch',
        style:     'loading',

        done: function () {
          if (this.view) {
            this.show(this.view, { region: options.region });
          }
        }.bind(this),

        fail: function () {}
      };
    },

    _getEntities: function (view) {
      return _.chain(view).pick('model', 'collection')
                          .toArray()
                          .compact()
                          .value();
    }
  });

  CommandBus.setHandler('show:loading', function (view, options) {
    new LoadingController({
      view:    view,
      options: { region: options.region, title: options.title },
      config:  options.loading
    });
  });

  return LoadingController;
});<|endoftext|>


<commit_before>import {
  TextureLoader,
  ObjectLoader,
} from "three";

import "three/examples/js/loaders/ColladaLoader.js";
import "three/examples/js/loaders/OBJLoader.js";

import Loader from "../utils/Loader.js";

let PROMISES = Loader.promises;

export default class THREELoader {
  static get onLoad() {
    return Loader.onLoad;
  }

  static load(value) {
    let loader;

    if(/\.(png|jpg)$/.test(value)) {
      loader = new TextureLoader();
    }
    else if(/\.(dae)$/.test(value)) {
      loader = new THREE.ColladaLoader();
    }
    else if(/\.(obj)$/.test(value)) {
      loader = new THREE.OBJLoader();
    }
    else if(/\.(json)$/.test(value)) {
      loader = new ObjectLoader();
    }

    let promise = new Promise((resolve) => {
      value = loader.load(value, (data) => {
        PROMISES.delete(value);
        resolve(data);
      });
    });

    PROMISES.set(value, promise);

    return loader instanceof TextureLoader ? value : promise;
  }
}
<commit_msg>add colladaLoader data fix<commit_after>import {
  TextureLoader,
  ObjectLoader,
  Mesh,
} from "three";

import "three/examples/js/loaders/ColladaLoader.js";
import "three/examples/js/loaders/OBJLoader.js";

import Loader from "../utils/Loader.js";

let PROMISES = Loader.promises;

function fixColladaLoaderData(data) {
  let meshContainers = [];
  data.scene.traverse((object3D) => {
    if(object3D.children[0] instanceof Mesh) {
      meshContainers.push(object3D);
    }
    [object3D.position.y, object3D.position.z] = [object3D.position.z, -object3D.position.y];
    [object3D.rotation.y, object3D.rotation.z] = [object3D.rotation.z, -object3D.rotation.y];
    [object3D.scale.y, object3D.scale.z] = [object3D.scale.z, object3D.scale.y];
  });
  for (let object3D of meshContainers) {
    let mesh = object3D.children[0];
    object3D.remove(mesh);
    mesh.name = object3D.name;
    mesh.position.copy(object3D.position);
    mesh.rotation.copy(object3D.rotation);
    mesh.scale.copy(object3D.scale);
    mesh.geometry.rotateX(-Math.PI * .5);
    object3D.parent.add(mesh);
    object3D.parent.remove(object3D);
  }
}

export default class THREELoader {
  static get onLoad() {
    return Loader.onLoad;
  }

  static load(value) {
    let loader;
    let texture;

    if(/\.(png|jpg)$/.test(value)) {
      loader = new TextureLoader();
    }
    else if(/\.(dae)$/.test(value)) {
      loader = new THREE.ColladaLoader();
    }
    else if(/\.(obj)$/.test(value)) {
      loader = new THREE.OBJLoader();
    }
    else if(/\.(json)$/.test(value)) {
      loader = new ObjectLoader();
    }

    let promise = new Promise((resolve) => {
      texture = loader.load(value, (data) => {
        PROMISES.delete(value);
        if(/\.(dae)$/.test(value)) {
          fixColladaLoaderData(data);
        }
        resolve(data);
      });
    });

    PROMISES.set(value, promise);

    return loader instanceof TextureLoader ? texture : promise;
  }
}
<|endoftext|>


<commit_before>//  Author: Dustin Hardin
//
//  Description:
//  Used to display a 5 day forecast for weather by City,Location where location can be a state, province, etc.
//  Utilizes the Yahoo Query Language (yql) webservice to query for the city,location woeid and then query
//  for the weather for the returend woied.
//
//  References:
//  jQuery: https://jquery.com/
//  jQuery UI: https://jqueryui.com/
//  GitHub: https://github.com/dhardin/jTable

var jTable = (function ($) {
    //----------------- END MODULE SCOPE VARIABLES ---------------
    var configMap = {
        row_highlight_class: 'jTable-Row',
        cell_edit_class: 'jTable-Edit'
    },
    stateMap = { $container: null },
    jqueryMap = {},
    setJqueryMap, onClick, onDoubleClick,
    objectCreate, extendObject,
    publicMethod, initModule;
    //------------------- BEGIN UTILITY METHODS ------------------
    // ** Utility function to set inheritance
    // Cross-browser method to inherit Object.create()
    // Newer js engines (v1.8.5+) support it natively
    objectCreate = function (arg) {
        if (!arg) { return {}; }
        function obj() { };
        obj.prototype = arg;
        return new obj;
    };

    Object.create = Object.create || objectCreate;

    // ** Utility function to extend an object
    extendObject = function (orig_obj, ext_obj) {
        var key_name;
        for (key_name in ext_obj) {
            if (ext_obj.hasOwnProperty(key_name)) {
                orig_obj[key_name] = ext_obj[key_name];
            }
        }
    };
    //-------------------- END UTILITY METHODS -------------------
    //--------------------- BEGIN DOM METHODS --------------------
    // Begin dom method /setJqueryMap/
    setJqueryMap = function () {
        var $container = stateMap.$container;
        jqueryMap.$container = $container;
    };
    // end dom method /setJqueryMap/
    //---------------------- END DOM METHODS ---------------------
    //------------------- BEGIN EVENT HANDLERS -------------------
    // Begin Event handler /onClick/
    onClick = function (e) {
        e.preventDefault();
        var row_highlight_class = configMap.row_highlight_class;
        jqueryMap.$container.find('.' + row_highlight_class).removeClass(row_highlight_class);
        $(this).siblings().andSelf().addClass(row_highlight_class);
    };
    // End Event handler /onClick/

    // Begin Event handler /onDoubleClick/
    onDoubleClick = function (e) {
        e.preventDefault();
        var $td = $(this),
        cell_edit_class = configMap.cell_edit_class,
        $prevEditDiv = jqueryMap.$container.find('.' + cell_edit_class);

        $prevEditDiv.parent().html($prevEditDiv.html());

        $td.html('
' + $td.html() + '
');
        $td.focus();
    };
    // End Event handler /onDoubleClick/
    //-------------------- END EVENT HANDLERS --------------------
    // Begin public method /configModule/
    // Purpose : Adjust configuration of allowed keys
    // Arguments : A map of settable keys and values
    // * color_name - color to use
    // Settings :
    // * configMap.settable_map declares allowed keys
    // Returns : true
    // Throws : none
    //
    configModule = function (input_map) {
        jTable.butil.setConfigMap({
            input_map: input_map,
            settable_map: configMap.settable_map,
            config_map: configMap
        });
        return true;
    };
    // End public method /configModule/
    // Begin public method /initModule/
    // Purpose : Initializes module
    // Arguments :
    // * $container the jquery element used by this feature
    // Returns : true
    // Throws : nonaccidental
    //
    initModule = function ($container) {
        if ($container[0].nodeName == "TABLE") {
            stateMap.$container = $container;
            setJqueryMap();

            jqueryMap.$container.find("td")
            .on('click', onClick);

            jqueryMap.$container.find("td")
            .on('dblclick', onDoubleClick);

            return true;
        }
        else {
            return false;
        }
    };
    // End public method /initModule/
    // return public methods
    return {
        configModule: configModule,
        initModule: initModule
    };
    //------------------- END PUBLIC METHODS ---------------------

})(jQuery);<commit_msg>Added onBlur event handler to commit changes to edited cells<commit_after>//  Author: Dustin Hardin
//
//  Description:
//  Used to display a 5 day forecast for weather by City,Location where location can be a state, province, etc.
//  Utilizes the Yahoo Query Language (yql) webservice to query for the city,location woeid and then query
//  for the weather for the returend woied.
//
//  References:
//  jQuery: https://jquery.com/
//  jQuery UI: https://jqueryui.com/
//  GitHub: https://github.com/dhardin/jTable

var jTable = (function ($) {
    //----------------- END MODULE SCOPE VARIABLES ---------------
    var configMap = {
        row_highlight_class: 'jTable-Row',
        cell_edit_class: 'jTable-Edit'
    },
    stateMap = { $container: null },
    jqueryMap = {},
    setJqueryMap, onClick, onDoubleClick, onBlur,
    objectCreate, extendObject, addSelectEdit,
    publicMethod, initModule;
    //------------------- BEGIN UTILITY METHODS ------------------
    // ** Utility function to set inheritance
    // Cross-browser method to inherit Object.create()
    // Newer js engines (v1.8.5+) support it natively
    objectCreate = function (arg) {
        if (!arg) { return {}; }
        function obj() { };
        obj.prototype = arg;
        return new obj;
    };

    Object.create = Object.create || objectCreate;

    // ** Utility function to extend an object
    extendObject = function (orig_obj, ext_obj) {
        var key_name;
        for (key_name in ext_obj) {
            if (ext_obj.hasOwnProperty(key_name)) {
                orig_obj[key_name] = ext_obj[key_name];
            }
        }
    };
    //-------------------- END UTILITY METHODS -------------------
    //--------------------- BEGIN DOM METHODS --------------------
    // Begin dom method /setJqueryMap/
    setJqueryMap = function () {
        var $container = stateMap.$container;
        jqueryMap.$container = $container;
    };

    addSelectEdit = function () {
    };
    // end dom method /setJqueryMap/
    //---------------------- END DOM METHODS ---------------------
    //------------------- BEGIN EVENT HANDLERS -------------------
    // Begin Event handler /onClick/
    onClick = function (e) {

        var row_highlight_class = configMap.row_highlight_class;
        jqueryMap.$container.find('.' + row_highlight_class).removeClass(row_highlight_class);
        $(this).siblings().andSelf().addClass(row_highlight_class);
    };
    // End Event handler /onClick/

    // Begin Event handler /onDoubleClick/
    onDoubleClick = function (e) {

        var $td = $(this),
        cell_edit_class = configMap.cell_edit_class,
        $prevEditDiv = jqueryMap.$container.find('.' + cell_edit_class);

        $prevEditDiv.parent().html($prevEditDiv.html());

        $td.html('
' + $td.html() + '
');
        $td.find('.' + cell_edit_class).focus();
    };
    // End Event handler /onDoubleClick/

    // Begin Event handler /onBlur/
    onBlur = function (e) {

        var cell_edit_class = configMap.cell_edit_class,
        $this = $(this),
        $prevEditDiv = $this.find('.' + cell_edit_class);

        if (typeof $prevEditDiv !== "undefined")
        {
            $this.html($prevEditDiv.html());
        }

    };
    // End Event handler /onBlur/

    //-------------------- END EVENT HANDLERS --------------------
    // Begin public method /configModule/
    // Purpose : Adjust configuration of allowed keys
    // Arguments : A map of settable keys and values
    // * color_name - color to use
    // Settings :
    // * configMap.settable_map declares allowed keys
    // Returns : true
    // Throws : none
    //
    configModule = function (input_map) {
        jTable.butil.setConfigMap({
            input_map: input_map,
            settable_map: configMap.settable_map,
            config_map: configMap
        });
        return true;
    };
    // End public method /configModule/
    // Begin public method /initModule/
    // Purpose : Initializes module
    // Arguments :
    // * $container the jquery element used by this feature
    // Returns : true
    // Throws : nonaccidental
    //
    initModule = function ($container) {
        if ($container[0].nodeName == "TABLE") {
            stateMap.$container = $container;
            setJqueryMap();

            jqueryMap.$container.find("td")
            .on('click', onClick);

            jqueryMap.$container.find("td")
            .on('dblclick', onDoubleClick);

            jqueryMap.$container.find('td')
            .on('focusout', onBlur);

            return true;
        }
        else {
            return false;
        }
    };
    // End public method /initModule/
    // return public methods
    return {
        configModule: configModule,
        initModule: initModule
    };
    //------------------- END PUBLIC METHODS ---------------------

})(jQuery);<|endoftext|>


<commit_before>/* -*- mode: espresso; espresso-indent-level: 2; indent-tabs-mode: nil -*- */
/* vim: set softtabstop=2 shiftwidth=2 tabstop=2 expandtab: */

(function(CATMAID) {

  "use strict";

  var ConnectivityMatrixWidget = function() {
    this.widgetID = this.registerInstance();
    this.matrix = new CATMAID.ConnectivityMatrix();
    this.rowDimension = new CATMAID.BasicSkeletonSource(this.getName() + " Rows");
    this.colDimension = new CATMAID.BasicSkeletonSource(this.getName() + " Columns");
  };

  ConnectivityMatrixWidget.prototype = {};
  $.extend(ConnectivityMatrixWidget.prototype, new InstanceRegistry());

  // Make connectivity matrix widget available in CATMAID namespace
  CATMAID.ConnectivityMatrixWidget = ConnectivityMatrixWidget;

  /* Implement interfaces */

  ConnectivityMatrixWidget.prototype.getName = function()
  {
    return "Connectivity Matrix " + this.widgetID;
  };

  /**
   * Handle destruction of widget.
   */
  ConnectivityMatrixWidget.prototype.destroy = function() {
    NeuronNameService.getInstance().unregister(this);
    this.content = null;
    this.rowDimension.destroy();
    this.colDimension.destroy();
    this.unregisterInstance();
  };

  /* Non-interface methods */

  /**
   * Create an object with all relevant information for creating a CATMAID
   * widget. All methods can expect to be executed in the context of this
   * object.
   */
  ConnectivityMatrixWidget.prototype.getWidgetConfiguration = function() {
    return {
      class: 'connectivity_matrix',
      controlsID: 'connectivity_matrix_controls' + this.widgetID,
      contentID: 'connectivity_matrix' + this.widgetID,

      /**
       * Create widget controls.
       */
      createControls: function(controls) {
        // Create hidden select elements for row and column sources
        var rowSelect = CATMAID.skeletonListSources.createSelect(this.rowDimension);
        rowSelect.style.display = 'none';
        controls.appendChild(rowSelect);
        var colSelect = CATMAID.skeletonListSources.createSelect(this.colDimension);
        colSelect.style.display = 'none';
        controls.appendChild(colSelect);

        // This UI combines two skeleton source selects into one.
        controls.appendChild(document.createTextNode('From'));
        var sourceSelect = CATMAID.skeletonListSources.createSelect(this,
           [this.rowDimension.getName(), this.colDimension.getName()]);
        controls.appendChild(sourceSelect);
        sourceSelect.onchange = function() {
          rowSelect.value = this.value;
          colSelect.value = this.value;
        };

        // Indicates if loaded skeletons should be part of a group
        var loadAsGroup = false;

        /**
         * Load rows and/or coulmns and refresh.
         */
        var loadWith = function(withRows, withCols) {
          if (loadAsGroup) {
            // Ask for group name
            askForGroupName((function(name) {
              return (!withRows || isValidGroupName(Object.keys(
                                   this.rowDimension.groups), name)) &&
                     (!withCols || isValidGroupName(Object.keys(
                                   this.colDimension.groups), name));
            }).bind(this), (function(groupName) {
              if (withRows) this.rowDimension.loadAsGroup(groupName);
              if (withCols) this.colDimension.loadAsGroup(groupName);
              if (withRows || withCols) this.update();
            }).bind(this));
          } else {
            if (withRows) this.rowDimension.loadSource();
            if (withCols) this.colDimension.loadSource();
            if (withRows || withCols) this.update();
          }
        };

        var asGroupCb = document.createElement('input');
        asGroupCb.setAttribute('type', 'checkbox');
        asGroupCb.checked = loadAsGroup;
        asGroupCb.onclick = function() {
          loadAsGroup = this.checked;
        };
        var asGroup = document.createElement('label');
        asGroup.appendChild(asGroupCb);
        asGroup.appendChild(document.createTextNode('As group'));
        controls.appendChild(asGroup);

        var loadRows = document.createElement('input');
        loadRows.setAttribute("type", "button");
        loadRows.setAttribute("value", "Append rows");
        loadRows.onclick = loadWith.bind(this, true, false);
        controls.appendChild(loadRows);

        var loadColumns = document.createElement('input');
        loadColumns.setAttribute("type", "button");
        loadColumns.setAttribute("value", "Append columns");
        loadColumns.onclick = loadWith.bind(this, false, true);
        controls.appendChild(loadColumns);

        var loadAll = document.createElement('input');
        loadAll.setAttribute("type", "button");
        loadAll.setAttribute("value", "Append to both");
        loadAll.onclick = loadWith.bind(this, true, true);
        controls.appendChild(loadAll);

        var clear = document.createElement('input');
        clear.setAttribute("type", "button");
        clear.setAttribute("value", "Clear");
        clear.onclick = (function() {
          if (confirm("Do you really want to clear the current selection?")) {
            this.clear();
          }
        }).bind(this);
        controls.appendChild(clear);

        var update = document.createElement('input');
        update.setAttribute("type", "button");
        update.setAttribute("value", "Refresh");
        update.onclick = this.update.bind(this);
        controls.appendChild(update);
      },

      /**
       * Create widget content.
       */
      createContent: function(container) {
        this.content = container;
        this.update();
      }
    };
  };

  /**
   * Clear all sources.
   */
  ConnectivityMatrixWidget.prototype.clear = function() {
    this.rowDimension.clear();
    this.colDimension.clear();
    this.update();
  };

  /**
   * Update names of neurons in connectivity widget.
   */
  ConnectivityMatrixWidget.prototype.updateNeuronNames = function() {
    this.refresh();
  };

  /**
   * Refresh the UI without recreating the connectivity matrix.
   */
  ConnectivityMatrixWidget.prototype.refresh = function(container) {
    // Clrear container and add new table
    $(this.content).empty();
    this.addConnectivityMatrixTable(this.matrix, this.content);
  };

  /**
   * Recreate the connectivity matrix and refresh the UI.
   */
  ConnectivityMatrixWidget.prototype.update = function(container) {
    if (!this.matrix) {
      return;
    }

    // Clrear container
    var $content = $(this.content);
    $content.empty();

    var nRows = this.rowDimension.orderedSkeletonIDs.length;
    var nCols = this.colDimension.orderedSkeletonIDs.length;

    // If there are now row or column skeletons, display a message and return
    if (0 === nRows && 0 === nCols) {
      this.content.dataset.msg = "Please append row and column skeletons";
      return;
    } else if (0 === nRows) {
      this.content.dataset.msg = "Please append row skeletons, " + nCols +
          " column skeletons are already available.";
      return;
    } else if (0 === nCols) {
      this.content.dataset.msg = "Please append column skeletons, " + nRows +
          " row skeletons are already available.";
      return;
    } else {
      this.content.dataset.msg = "Please wait, connectivity information is retrieved.";
    }

    // Update connectivity matrix and make sure all currently looked at
    // skeletons are known to the neuron name service.
    var nns = NeuronNameService.getInstance();
    this.matrix.setRowSkeletonIDs(this.rowDimension.orderedSkeletonIDs);
    this.matrix.setColumnSkeletonIDs(this.colDimension.orderedSkeletonIDs);
    this.matrix.refresh()
      .then(nns.registerAll.bind(nns, this, this.rowDimension.getSelectedSkeletonModels()))
      .then(nns.registerAll.bind(nns, this, this.colDimension.getSelectedSkeletonModels()))
      .then((function() {
        // Clear any message
        if (this.content.dataset.msg) delete this.content.dataset.msg;
        // Create table
        this.addConnectivityMatrixTable(this.matrix, this.content);
      }).bind(this));
  };

  /**
   * Add a tabular representation of the connectivity matrix to the given DOM
   * element.
   *
   * @param {ConnectivityMatrix} The connectivity matrix to add.
   * @param {DOMElement} The element to add the table to.
   * @returns the content element passed in.
   */
  ConnectivityMatrixWidget.prototype.addConnectivityMatrixTable = function(
      matrix, content) {
    var nRows = matrix.getNumberOfRows();
    var nCols = matrix.getNumberOfColumns();
    if (0 === nRows || 0 === nCols) {
      return;
    }

    var m = matrix.get();
    var nns = NeuronNameService.getInstance();

    // Get group information
    var nDisplayRows = this.rowDimension.orderedElements.length;
    var nDisplayCols = this.colDimension.orderedElements.length;

    // Create table representation for connectivity matrix
    var table = document.createElement('table');
    table.setAttribute('class', 'partner_table');
    // Add column header, prepend one blank cell for row headers
    var colHeader = table.appendChild(document.createElement('tr'));
    colHeader.appendChild(document.createElement('th'));
    for (var c=0; c<nDisplayCols; ++c) {
      // Get skeleton or group name
      var id = this.colDimension.orderedElements[c];
      var colGroup = this.colDimension.groups[id];
      var name = colGroup ? id : nns.getName(id);
      // Create column
      var th = document.createElement('th');
      th.appendChild(document.createTextNode(name));
      th.setAttribute('colspan', 2);
      if (colGroup) {
        th.setAttribute('title', 'This colGroup contains ' + colGroup.length +
            ' skeleton(s): ' + colGroup.join(', '));
      }
      colHeader.appendChild(th);
    }
    // Add row headers and connectivity matrix rows
    var r = 0, c = 0;
    for (var dr=0; dr<nDisplayRows; ++dr) {
      // Get skeleton or rowGroup name and increase row skeleton counter
      var rowId = this.rowDimension.orderedElements[dr];
      var rowGroup = this.rowDimension.groups[rowId];
      var name, title;
      if (rowGroup) {
        name = rowId;
        title = 'This rowGroup contains ' + rowGroup.length + ' skeleton(s): ' +
            rowGroup.join(', ');
      } else {
        name = nns.getName(rowId);
      }
      // Create row
      var row = document.createElement('tr');
      table.appendChild(row);
      var th = document.createElement('th');
      th.appendChild(document.createTextNode(name));
      if (title) th.setAttribute('title', title);
      row.appendChild(th);

      // Crete cells for each column in this row
      for (var dc=0; dc<nDisplayCols; ++dc) {
        // Aggregate group counts (if any)
        var colId = this.colDimension.orderedElements[dc];
        var colGroup = this.colDimension.groups[colId];
        var connections = aggregateMatrix(m, r, c,
            rowGroup ? rowGroup.length : 1,
            colGroup ? colGroup.length : 1);

        var rowSkid = 42;
        var colSkid = 42; //this.colDimension.orderedSkeletonIDs[c];

        // Create and append in and out cells
        var tdIn = createSynapseCountCell(rowSkid, colSkid, connections[0]);
        var tdOut = createSynapseCountCell(colSkid, rowSkid, connections[1]);
        row.appendChild(tdIn);
        row.appendChild(tdOut);
      }

      // Increase index for next iteration
      r = rowGroup ? r + rowGroup.length : r + 1;
    }
    content.appendChild(table);

    // Add a handler for openening connector selections for individual partners
    $('a[partnerID]', table).click(function () {
      var sourceID = $(this).attr('sourceID');
      var partnerID = $(this).attr('partnerID');
      if (sourceID && partnerID) {
        CATMAID.ConnectorSelection.show_shared_connectors(sourceID, [partnerID],
           "postsynaptic_to");
      } else {
        CATMAID.error("Could not find partner or source ID!");
      }

      return true;
    });

    return content;
  };

  /**
   * Aggregate the values of a connectivity matrix over the specified number of
   * rows and columns, starting from the given position.
   */
  function aggregateMatrix(matrix, r, c, nRows, nCols) {
    var nr = 0, nc = 0;

    for (var i=0; i<nRows; ++i) {
      for (var j=0; j<nCols; ++j) {
        nr += matrix[r + i][c + j][0];
        nc += matrix[r + i][c + j][1];
      }
    }

    return [nr, nc];
  }

  /**
   * Create a synapse count table cell.
   */
  function createSynapseCountCell(sourceID, partnerID, count) {
    var td = document.createElement('td');
    td.setAttribute('class', 'syncount');
    if (count > 0) {
      // Create a links that will open a connector selection when clicked. The
      // handler to do this is created separate to only require one handler.
      var a = document.createElement('a');
      td.appendChild(a);
      a.appendChild(document.createTextNode(count));
      a.setAttribute('href', '#');
      a.setAttribute('sourceID', sourceID);
      a.setAttribute('partnerID', partnerID);
    } else {
      // Make a hidden span including the zero for semantic clarity and table exports.
      var s = document.createElement('span');
      td.appendChild(s);
      s.appendChild(document.createTextNode(count));
      s.style.display = 'none';
    }
    return td;
  }

  /**
   * Display a modal dialog to ask the user for a group name.
   */
  function askForGroupName(validGroupName, callback) {
    var options = new OptionsDialog("Group properties");
    options.appendMessage("Please choose a name for the new group.");
    var nameField = options.appendField("Name: ", "groupname-typed", "", null);
    var invalidMessage = options.appendMessage("Please choose a different name!");
    invalidMessage.style.display = "none";
    nameField.onkeyup = function(e) {
      // Show a message if this name is already taken or invalid
      var valid = validGroupName(this.value);
      invalidMessage.style.display = valid ? "none" : "block";
    };
    options.onOK = function() {
      if (!validGroupName(nameField.value)) {
        CATMAID.error("Please choose a different group name!");
        return false;
      }
      callback(nameField.value);
    };

    options.show("auto", "auto", true);
  }

  /**
   * Test if a group name is valid, based on a list of existing group names.
   */
  function isValidGroupName(existingNames, name) {
    return -1 === existingNames.indexOf(name);
  }

})(CATMAID);
<commit_msg>Connectivity matrix: open connector table with all synapses in cell<commit_after>/* -*- mode: espresso; espresso-indent-level: 2; indent-tabs-mode: nil -*- */
/* vim: set softtabstop=2 shiftwidth=2 tabstop=2 expandtab: */

(function(CATMAID) {

  "use strict";

  var ConnectivityMatrixWidget = function() {
    this.widgetID = this.registerInstance();
    this.matrix = new CATMAID.ConnectivityMatrix();
    this.rowDimension = new CATMAID.BasicSkeletonSource(this.getName() + " Rows");
    this.colDimension = new CATMAID.BasicSkeletonSource(this.getName() + " Columns");
  };

  ConnectivityMatrixWidget.prototype = {};
  $.extend(ConnectivityMatrixWidget.prototype, new InstanceRegistry());

  // Make connectivity matrix widget available in CATMAID namespace
  CATMAID.ConnectivityMatrixWidget = ConnectivityMatrixWidget;

  /* Implement interfaces */

  ConnectivityMatrixWidget.prototype.getName = function()
  {
    return "Connectivity Matrix " + this.widgetID;
  };

  /**
   * Handle destruction of widget.
   */
  ConnectivityMatrixWidget.prototype.destroy = function() {
    NeuronNameService.getInstance().unregister(this);
    this.content = null;
    this.rowDimension.destroy();
    this.colDimension.destroy();
    this.unregisterInstance();
  };

  /* Non-interface methods */

  /**
   * Create an object with all relevant information for creating a CATMAID
   * widget. All methods can expect to be executed in the context of this
   * object.
   */
  ConnectivityMatrixWidget.prototype.getWidgetConfiguration = function() {
    return {
      class: 'connectivity_matrix',
      controlsID: 'connectivity_matrix_controls' + this.widgetID,
      contentID: 'connectivity_matrix' + this.widgetID,

      /**
       * Create widget controls.
       */
      createControls: function(controls) {
        // Create hidden select elements for row and column sources
        var rowSelect = CATMAID.skeletonListSources.createSelect(this.rowDimension);
        rowSelect.style.display = 'none';
        controls.appendChild(rowSelect);
        var colSelect = CATMAID.skeletonListSources.createSelect(this.colDimension);
        colSelect.style.display = 'none';
        controls.appendChild(colSelect);

        // This UI combines two skeleton source selects into one.
        controls.appendChild(document.createTextNode('From'));
        var sourceSelect = CATMAID.skeletonListSources.createSelect(this,
           [this.rowDimension.getName(), this.colDimension.getName()]);
        controls.appendChild(sourceSelect);
        sourceSelect.onchange = function() {
          rowSelect.value = this.value;
          colSelect.value = this.value;
        };

        // Indicates if loaded skeletons should be part of a group
        var loadAsGroup = false;

        /**
         * Load rows and/or coulmns and refresh.
         */
        var loadWith = function(withRows, withCols) {
          if (loadAsGroup) {
            // Ask for group name
            askForGroupName((function(name) {
              return (!withRows || isValidGroupName(Object.keys(
                                   this.rowDimension.groups), name)) &&
                     (!withCols || isValidGroupName(Object.keys(
                                   this.colDimension.groups), name));
            }).bind(this), (function(groupName) {
              if (withRows) this.rowDimension.loadAsGroup(groupName);
              if (withCols) this.colDimension.loadAsGroup(groupName);
              if (withRows || withCols) this.update();
            }).bind(this));
          } else {
            if (withRows) this.rowDimension.loadSource();
            if (withCols) this.colDimension.loadSource();
            if (withRows || withCols) this.update();
          }
        };

        var asGroupCb = document.createElement('input');
        asGroupCb.setAttribute('type', 'checkbox');
        asGroupCb.checked = loadAsGroup;
        asGroupCb.onclick = function() {
          loadAsGroup = this.checked;
        };
        var asGroup = document.createElement('label');
        asGroup.appendChild(asGroupCb);
        asGroup.appendChild(document.createTextNode('As group'));
        controls.appendChild(asGroup);

        var loadRows = document.createElement('input');
        loadRows.setAttribute("type", "button");
        loadRows.setAttribute("value", "Append rows");
        loadRows.onclick = loadWith.bind(this, true, false);
        controls.appendChild(loadRows);

        var loadColumns = document.createElement('input');
        loadColumns.setAttribute("type", "button");
        loadColumns.setAttribute("value", "Append columns");
        loadColumns.onclick = loadWith.bind(this, false, true);
        controls.appendChild(loadColumns);

        var loadAll = document.createElement('input');
        loadAll.setAttribute("type", "button");
        loadAll.setAttribute("value", "Append to both");
        loadAll.onclick = loadWith.bind(this, true, true);
        controls.appendChild(loadAll);

        var clear = document.createElement('input');
        clear.setAttribute("type", "button");
        clear.setAttribute("value", "Clear");
        clear.onclick = (function() {
          if (confirm("Do you really want to clear the current selection?")) {
            this.clear();
          }
        }).bind(this);
        controls.appendChild(clear);

        var update = document.createElement('input');
        update.setAttribute("type", "button");
        update.setAttribute("value", "Refresh");
        update.onclick = this.update.bind(this);
        controls.appendChild(update);
      },

      /**
       * Create widget content.
       */
      createContent: function(container) {
        this.content = container;
        this.update();
      }
    };
  };

  /**
   * Clear all sources.
   */
  ConnectivityMatrixWidget.prototype.clear = function() {
    this.rowDimension.clear();
    this.colDimension.clear();
    this.update();
  };

  /**
   * Update names of neurons in connectivity widget.
   */
  ConnectivityMatrixWidget.prototype.updateNeuronNames = function() {
    this.refresh();
  };

  /**
   * Refresh the UI without recreating the connectivity matrix.
   */
  ConnectivityMatrixWidget.prototype.refresh = function(container) {
    // Clrear container and add new table
    $(this.content).empty();
    this.addConnectivityMatrixTable(this.matrix, this.content);
  };

  /**
   * Recreate the connectivity matrix and refresh the UI.
   */
  ConnectivityMatrixWidget.prototype.update = function(container) {
    if (!this.matrix) {
      return;
    }

    // Clrear container
    var $content = $(this.content);
    $content.empty();

    var nRows = this.rowDimension.orderedSkeletonIDs.length;
    var nCols = this.colDimension.orderedSkeletonIDs.length;

    // If there are now row or column skeletons, display a message and return
    if (0 === nRows && 0 === nCols) {
      this.content.dataset.msg = "Please append row and column skeletons";
      return;
    } else if (0 === nRows) {
      this.content.dataset.msg = "Please append row skeletons, " + nCols +
          " column skeletons are already available.";
      return;
    } else if (0 === nCols) {
      this.content.dataset.msg = "Please append column skeletons, " + nRows +
          " row skeletons are already available.";
      return;
    } else {
      this.content.dataset.msg = "Please wait, connectivity information is retrieved.";
    }

    // Update connectivity matrix and make sure all currently looked at
    // skeletons are known to the neuron name service.
    var nns = NeuronNameService.getInstance();
    this.matrix.setRowSkeletonIDs(this.rowDimension.orderedSkeletonIDs);
    this.matrix.setColumnSkeletonIDs(this.colDimension.orderedSkeletonIDs);
    this.matrix.refresh()
      .then(nns.registerAll.bind(nns, this, this.rowDimension.getSelectedSkeletonModels()))
      .then(nns.registerAll.bind(nns, this, this.colDimension.getSelectedSkeletonModels()))
      .then((function() {
        // Clear any message
        if (this.content.dataset.msg) delete this.content.dataset.msg;
        // Create table
        this.addConnectivityMatrixTable(this.matrix, this.content);
      }).bind(this));
  };

  /**
   * Add a tabular representation of the connectivity matrix to the given DOM
   * element.
   *
   * @param {ConnectivityMatrix} The connectivity matrix to add.
   * @param {DOMElement} The element to add the table to.
   * @returns the content element passed in.
   */
  ConnectivityMatrixWidget.prototype.addConnectivityMatrixTable = function(
      matrix, content) {
    var nRows = matrix.getNumberOfRows();
    var nCols = matrix.getNumberOfColumns();
    if (0 === nRows || 0 === nCols) {
      return;
    }

    var m = matrix.get();
    var nns = NeuronNameService.getInstance();

    // Get group information
    var nDisplayRows = this.rowDimension.orderedElements.length;
    var nDisplayCols = this.colDimension.orderedElements.length;

    // Create table representation for connectivity matrix
    var table = document.createElement('table');
    table.setAttribute('class', 'partner_table');
    // Add column header, prepend one blank cell for row headers
    var colHeader = table.appendChild(document.createElement('tr'));
    colHeader.appendChild(document.createElement('th'));
    for (var c=0; c<nDisplayCols; ++c) {
      // Get skeleton or group name
      var id = this.colDimension.orderedElements[c];
      var colGroup = this.colDimension.groups[id];
      var name = colGroup ? id : nns.getName(id);
      // Create column
      var th = document.createElement('th');
      th.appendChild(document.createTextNode(name));
      th.setAttribute('colspan', 2);
      if (colGroup) {
        th.setAttribute('title', 'This colGroup contains ' + colGroup.length +
            ' skeleton(s): ' + colGroup.join(', '));
      }
      colHeader.appendChild(th);
    }
    // Add row headers and connectivity matrix rows
    var r = 0, c = 0;
    for (var dr=0; dr<nDisplayRows; ++dr) {
      // Get skeleton or rowGroup name and increase row skeleton counter
      var rowId = this.rowDimension.orderedElements[dr];
      var rowGroup = this.rowDimension.groups[rowId];
      var name, title;
      if (rowGroup) {
        name = rowId;
        title = 'This rowGroup contains ' + rowGroup.length + ' skeleton(s): ' +
            rowGroup.join(', ');
      } else {
        name = nns.getName(rowId);
      }
      // Create row
      var row = document.createElement('tr');
      table.appendChild(row);
      var th = document.createElement('th');
      th.appendChild(document.createTextNode(name));
      if (title) th.setAttribute('title', title);
      row.appendChild(th);

      // Crete cells for each column in this row
      for (var dc=0; dc<nDisplayCols; ++dc) {
        // Aggregate group counts (if any)
        var colId = this.colDimension.orderedElements[dc];
        var colGroup = this.colDimension.groups[colId];
        var connections = aggregateMatrix(m, r, c,
            rowGroup ? rowGroup.length : 1,
            colGroup ? colGroup.length : 1);

        // Create and append in and out cells
        var rowSkids = rowGroup ? rowGroup : [rowId];
        var colSkids = colGroup ? colGroup : [colId];
        var tdIn = createSynapseCountCell(rowSkids, colSkids, connections[0]);
        var tdOut = createSynapseCountCell(colSkids, rowSkids, connections[1]);
        row.appendChild(tdIn);
        row.appendChild(tdOut);
      }

      // Increase index for next iteration
      r = rowGroup ? r + rowGroup.length : r + 1;
    }
    content.appendChild(table);

    // Add a handler for openening connector selections for individual partners
    $('a[partnerIDs]', table).click(function () {
      var sourceIDs = $(this).attr('sourceIDs');
      var partnerIDs = $(this).attr('partnerIDs');
      if (sourceIDs && partnerIDs) {
        sourceIDs = JSON.parse(sourceIDs);
        partnerIDs = JSON.parse(partnerIDs);
        CATMAID.ConnectorSelection.show_shared_connectors(sourceIDs, partnerIDs,
           "postsynaptic_to");
      } else {
        CATMAID.error("Could not find partner or source IDs!");
      }

      return true;
    });

    return content;
  };

  /**
   * Aggregate the values of a connectivity matrix over the specified number of
   * rows and columns, starting from the given position.
   */
  function aggregateMatrix(matrix, r, c, nRows, nCols) {
    var nr = 0, nc = 0;

    for (var i=0; i<nRows; ++i) {
      for (var j=0; j<nCols; ++j) {
        nr += matrix[r + i][c + j][0];
        nc += matrix[r + i][c + j][1];
      }
    }

    return [nr, nc];
  }

  /**
   * Create a synapse count table cell.
   */
  function createSynapseCountCell(sourceIDs, partnerIDs, count) {
    var td = document.createElement('td');
    td.setAttribute('class', 'syncount');
    if (count > 0) {
      // Create a links that will open a connector selection when clicked. The
      // handler to do this is created separate to only require one handler.
      var a = document.createElement('a');
      td.appendChild(a);
      a.appendChild(document.createTextNode(count));
      a.setAttribute('href', '#');
      a.setAttribute('sourceIDs', JSON.stringify(sourceIDs));
      a.setAttribute('partnerIDs', JSON.stringify(partnerIDs));
    } else {
      // Make a hidden span including the zero for semantic clarity and table exports.
      var s = document.createElement('span');
      td.appendChild(s);
      s.appendChild(document.createTextNode(count));
      s.style.display = 'none';
    }
    return td;
  }

  /**
   * Display a modal dialog to ask the user for a group name.
   */
  function askForGroupName(validGroupName, callback) {
    var options = new OptionsDialog("Group properties");
    options.appendMessage("Please choose a name for the new group.");
    var nameField = options.appendField("Name: ", "groupname-typed", "", null);
    var invalidMessage = options.appendMessage("Please choose a different name!");
    invalidMessage.style.display = "none";
    nameField.onkeyup = function(e) {
      // Show a message if this name is already taken or invalid
      var valid = validGroupName(this.value);
      invalidMessage.style.display = valid ? "none" : "block";
    };
    options.onOK = function() {
      if (!validGroupName(nameField.value)) {
        CATMAID.error("Please choose a different group name!");
        return false;
      }
      callback(nameField.value);
    };

    options.show("auto", "auto", true);
  }

  /**
   * Test if a group name is valid, based on a list of existing group names.
   */
  function isValidGroupName(existingNames, name) {
    return -1 === existingNames.indexOf(name);
  }

})(CATMAID);
<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';
import populateCountries from '../../../../public/javascript/countries.js';
import Details from '../Details.jsx';

describe('Details step', () => {
    let detailsForm;
    let defaultFormValues = {
                        isEnrolled: '',
                        residentialStatus: '',
                        isMemberOfOtherParty: '',
                        eligibility: '',
                        firstName: '',
                        lastName: '',
                        dateOfBirth: '',
                        gender: '',
                        email: '',
                        primaryPhoneNumber: '',
                        secondaryPhoneNumber: '',
                        residentialAddress: {
                            address: '',
                            suburb: '',
                            country: '',
                            state: '',
                            postcode: ''
                        },
                        postalAddress: {
                            address: '',
                            suburb: '',
                            country: '',
                            state: '',
                            postcode: ''
                        }
                    };
    beforeEach(() => {
        spyOn(populateCountries, 'populateCountries');
        spyOn(populateCountries, 'setCountryAddress');

        detailsForm = TestUtils.renderIntoDocument(<Details
                                membershipType='full'
                                formValues={defaultFormValues}/>);
    });

    it('should show list of invalid fields if the details entered were invalid', () => {
        let expectedErrors = 'First NameLast NameEmailPhone NumberDate of BirthResidential AddressResidential SuburbResidential PostcodeResidential Country';
        let continueButton = TestUtils.findRenderedDOMComponentWithTag(detailsForm, 'button');
        TestUtils.Simulate.click(continueButton);
        var errors = TestUtils.scryRenderedDOMComponentsWithClass(detailsForm, "errors");
        expect(ReactDOM.findDOMNode(errors[0]).textContent).toMatch(expectedErrors);
    });

    it('should show first name error message if it wasn\'t filled in', () => {
        let continueButton = TestUtils.findRenderedDOMComponentWithTag(detailsForm, 'button');
        TestUtils.Simulate.click(continueButton);
        var errors = TestUtils.scryRenderedDOMComponentsWithClass(detailsForm, "errors");
        expect(ReactDOM.findDOMNode(errors[1]).textContent).toMatch(/first name/);
    });

    it('should show last name error message if it wasn\'t filled in', () => {
        let continueButton = TestUtils.findRenderedDOMComponentWithTag(detailsForm, 'button');
        TestUtils.Simulate.click(continueButton);
        var errors = TestUtils.scryRenderedDOMComponentsWithClass(detailsForm, "errors");
        expect(ReactDOM.findDOMNode(errors[2]).textContent).toMatch(/last name/);
    });

    it('should show date of birth error message if it wasn\'t filled in', () => {
        let continueButton = TestUtils.findRenderedDOMComponentWithTag(detailsForm, 'button');
        TestUtils.Simulate.click(continueButton);
        var errors = TestUtils.scryRenderedDOMComponentsWithClass(detailsForm, "errors");
        expect(ReactDOM.findDOMNode(errors[3]).textContent).toMatch(/Must be in the format/);
    });

    it('should show email error message if it wasn\'t filled in', () => {
        let continueButton = TestUtils.findRenderedDOMComponentWithTag(detailsForm, 'button');
        TestUtils.Simulate.click(continueButton);
        var errors = TestUtils.scryRenderedDOMComponentsWithClass(detailsForm, "errors");
        expect(ReactDOM.findDOMNode(errors[4]).textContent).toMatch(/Please enter your address./);
    });
});
<commit_msg>Updated component tests for new user details<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';
import populateCountries from '../../../../public/javascript/countries.js';
import Details from '../Details.jsx';

describe('Details step', () => {
    let detailsForm;
    let defaultFormValues = {
                        labSelection: '',
                        contactName: '',
                        contactEmail: '',
                        contactNumber: '',
                        childName: '',
                        childBirthYear: '',
                        schoolType: '',
                        contactLastName: '',
                        childLastName: '',
                        additionalInfo: ''
                    };

    beforeEach(() => {

        detailsForm = TestUtils.renderIntoDocument(<Details
                                membershipType='full'
                                formValues={defaultFormValues}/>);
    });

    it('should show list of invalid fields if the details entered were invalid', () => {
        let expectedErrors = 'Contact NameContact EmailContact NumberChild NameBirth YearLab SelectionSchool Type';
        let continueButton = TestUtils.findRenderedDOMComponentWithTag(detailsForm, 'button');
        TestUtils.Simulate.click(continueButton);
        var errors = TestUtils.scryRenderedDOMComponentsWithClass(detailsForm, "errors");
        expect(ReactDOM.findDOMNode(errors[0]).textContent).toMatch(expectedErrors);
    });

    it('should show lab selection error message if it wasn\'t filled in', () => {
        let continueButton = TestUtils.findRenderedDOMComponentWithTag(detailsForm, 'button');
        TestUtils.Simulate.click(continueButton);
        var errors = TestUtils.scryRenderedDOMComponentsWithClass(detailsForm, "errors");
        expect(ReactDOM.findDOMNode(errors[1]).textContent).toMatch(/Please select a lab to attend/);
    });

    it('should show contact name error message if it wasn\'t filled in', () => {
        let continueButton = TestUtils.findRenderedDOMComponentWithTag(detailsForm, 'button');
        TestUtils.Simulate.click(continueButton);
        var errors = TestUtils.scryRenderedDOMComponentsWithClass(detailsForm, "errors");
        expect(ReactDOM.findDOMNode(errors[2]).textContent).toMatch(/Please enter a contact name. No symbols allowed/);
    });

    it('should show contact number error message if it wasn\'t filled in', () => {
        let continueButton = TestUtils.findRenderedDOMComponentWithTag(detailsForm, 'button');
        TestUtils.Simulate.click(continueButton);
        var errors = TestUtils.scryRenderedDOMComponentsWithClass(detailsForm, "errors");
        expect(ReactDOM.findDOMNode(errors[3]).textContent).toMatch(/Please enter a valid phone number/);
    });

    it('should show contact email error message if it wasn\'t filled in', () => {
        let continueButton = TestUtils.findRenderedDOMComponentWithTag(detailsForm, 'button');
        TestUtils.Simulate.click(continueButton);
        var errors = TestUtils.scryRenderedDOMComponentsWithClass(detailsForm, "errors");
        expect(ReactDOM.findDOMNode(errors[4]).textContent).toMatch(/Please enter a valid email address i.e. valid@email.com/);
    });

    it('should show child name error message if it wasn\'t filled in', () => {
        let continueButton = TestUtils.findRenderedDOMComponentWithTag(detailsForm, 'button');
        TestUtils.Simulate.click(continueButton);
        var errors = TestUtils.scryRenderedDOMComponentsWithClass(detailsForm, "errors");
        expect(ReactDOM.findDOMNode(errors[5]).textContent).toMatch(/Please enter the child's name. No symbols allowed/);
    });

    it('should show child birth year error message if it wasn\'t filled in', () => {
        let continueButton = TestUtils.findRenderedDOMComponentWithTag(detailsForm, 'button');
        TestUtils.Simulate.click(continueButton);
        var errors = TestUtils.scryRenderedDOMComponentsWithClass(detailsForm, "errors");
        expect(ReactDOM.findDOMNode(errors[6]).textContent).toMatch(/Please select the year of birth/);
    });

    it('should show school type error message if it wasn\'t filled in', () => {
        let continueButton = TestUtils.findRenderedDOMComponentWithTag(detailsForm, 'button');
        TestUtils.Simulate.click(continueButton);
        var errors = TestUtils.scryRenderedDOMComponentsWithClass(detailsForm, "errors");
        expect(ReactDOM.findDOMNode(errors[7]).textContent).toMatch(/Please select a school/);
    });

});
<|endoftext|>