<commit_before>var charts = {
    byCountry: {
        sankey: null
    },
    byCommodity: {
        pie:null,
        hist:null
    }
}

function initCharts() {
    //charts for International Trading
    charts.byCountry.sankey = new google.visualization.Sankey(document.getElementById('sankey'));
    //charts for commodites
    charts.byCommodity.pie = new google.visualization.PieChart(document.getElementById('pie'));
    charts.byCommodity.hist = new google.visualization.Histogram(document.getElementById('histogram'));
}

function drawSankeyChart() {
    //Set the data
    var type = getWorldSelectedType();
    var reg = regions.toArray();
    var data = (reg.length > 0 && worldSelectedYears.length > 0)
        ? getSankeyDataForCountry(type, reg, worldSelectedYears)
        : new google.visualization.DataTable({cols:[{type:'string'},{type:'string'},{type:'number'}]});

    // Set chart options
    var options = {
      width: 1215,
      sankey: {
        link: { color: { stroke: 'lightgrey', strokeWidth: 1 } },
        node: { label: { fontFamily: 'sans-serif',
                         fontSize: 14,
                         color: '#871b47',
                         bold: true },
                nodePadding: 10}
      }
    };

    // Instantiate and draw Sankey chart
    charts.byCountry.sankey.draw(data, options);
}

function getSankeyDataForCountry(type, states, years) {
    var ct;
    var t = getCountriesYearUngrouped(type, states, years, true);
    ct = states.length > 1 ? getCountriesYear(type, states, years) : t;
    var yearCols = [];
    if (type === Type.ImportExportDiff) {
        for (var i = 2; i < years.length+2; ++i)
            yearCols.push(i);
    } else {
        $.each(years, function(k,v) { yearCols.push(getCountryYearCol(v)); });
    }
    var i;
    var maxMost = [];
    var countries = [];
    function ascSort(a,b) {return a[0]-b[0]}
    for (i = 0; i < ct.getNumberOfRows(); ++i) {
        var sum = 0;
        if (t === ct) {
            $.each(yearCols, function(k,v) { sum += ct.getValue(i, v); });
            if (type === Type.ImportExportDiff) {
                $.each(yearCols, function(k,v) { sum -= ct.getValue(i, v+years.length); });
            }
        } else {
            sum = ct.getValue(i, 1);
        }
        if (isNaN(sum)) throw new Error("NaN sum");
        // pick at most the 15 largest values
        if (maxMost.length < 15) {
            maxMost.push([sum,i]);
        } else {
            maxMost = maxMost.sort(ascSort);
            if (sum > maxMost[0][0])
                maxMost[0] = [sum, i];
        }
    }
    maxMost = maxMost.sort(ascSort);
    var col = (type === Type.ImportExportDiff ? 1 : Column.Country);
    if (t === ct) {
        if (ct.getColumnLabel(col) !== "Country")
          throw new Error("bah");
        for (i = 0; i < maxMost.length; ++i)
            countries.push(ct.getValue(i, col));
    } else {
        if (ct.getColumnLabel(0) !== "Country")
          throw new Error("bah");
        for (i = 0; i < maxMost.length; ++i)
            countries.push(ct.getValue(i, 0));
    }
    var v = new google.visualization.DataView(t);
    var rows = [];
    var sumOther = {};
    $.each(states, function(k,v) { sumOther[v] = 0; });
    for (i = 0; i < t.getNumberOfRows(); ++i) {
        var country = t.getValue(i, col);
        if (t.getColumnLabel(col) !== "Country")
          throw new Error("bah");
        var val = 0;
        $.each(yearCols, function(k,v) { val += t.getValue(i, v); });
        if (type === Type.ImportExportDiff) {
            $.each(yearCols, function(k,v) { val -= t.getValue(i, v+years.length); });
            val *= -1; // it's e-i but imports are listed first
        }
        if (isNaN(val)) throw new Error("NaN val");
        if (val <= 0 || countries.indexOf(country) < 0) // ignore negative values on ImportExportDiff
            sumOther[t.getValue(i, Column.State)] += val;
        else
            rows.push(i);
    }
    $.each(states, function(k,v) {
        if (sumOther[v] > 0) {
            t.addRow();
            t.setCell(i, Column.State, v);
            t.setCell(i, (type === Type.ImportExportDiff ? 1 : Column.Country), "Others");
            t.setCell(i, yearCols[0], sumOther[v]);
            rows.push(i);
            ++i;
        }
    });
    v.setRows(rows);
    if (type === Type.ImportExportDiff) {
        v.setColumns([Column.State, 1, yearCols[0]]);
    } else {
        v.setColumns([Column.State, Column.Country, yearCols[0]]);
    }
    return v;
}

function drawPieChart(){//Only two sets of data possibles (sum previous years in case of multiple selection?)
    var comView = getExportCommoditiesYear(regions.toArray()[0], select_commodities[0], commoditiesSelectedYears[0]);
    console.log(comView)
    var i = 0;
    if(typeof commoditiesSelectedYears[1] !== 'undefined') i=1;
    var comView1 = getExportCommoditiesYear(regions.toArray()[0], select_commodities[0], commoditiesSelectedYears[i]);
    if (i==0) str = 'Hscode: ' + select_commodities[0] + ', for the year: ' + commoditiesSelectedYears[0];
    else str = 'Hscode: ' + select_commodities[0] + ' Export Diff ' + commoditiesSelectedYears[0] + '-' + commoditiesSelectedYears[i];
        var options = {
          title: str,
          legend: 'none',
          diff: {comView: { opacity: 0.15 }} ,
          pieSliceText: 'percentage',
          width: 300,
          height: 340
        };

        var diffData = charts.byCommodity.pie.computeDiff(comView, comView1);
        charts.byCommodity.pie.draw(diffData, options);
}

function drawHistogram(){
    var data = getImportCommoditiesYear(regions.toArray()[0], select_commodities[0], commoditiesSelectedYears[0]);
    console.log(data);
    /*var data = google.visualization.arrayToDataTable([
          ['Dinosaur', 'Length'],
          ['Acrocanthosaurus (top-spined lizard)', 12.2],
          ['Albertosaurus (Alberta lizard)', 9.1],
          ['Allosaurus (other lizard)', 12.2],
          ['Apatosaurus (deceptive lizard)', 22.9],
          ['Archaeopteryx (ancient wing)', 0.9]]);*/
    var options = {
          title: 'Distribution for selected States',
          legend: { position: 'none' },
          width:300,
          height: 100
        };

        charts.byCommodity.hist.draw(data, options);
}
<commit_msg>Rename variable (cont' after merge)<commit_after>var charts = {
    byCountry: {
        sankey: null
    },
    byCommodity: {
        pie:null,
        hist:null
    }
}

function initCharts() {
    //charts for International Trading
    charts.byCountry.sankey = new google.visualization.Sankey(document.getElementById('sankey'));
    //charts for commodites
    charts.byCommodity.pie = new google.visualization.PieChart(document.getElementById('pie'));
    charts.byCommodity.hist = new google.visualization.Histogram(document.getElementById('histogram'));
}

function drawSankeyChart() {
    //Set the data
    var type = getWorldSelectedType();
    var reg = regions.toArray();
    var data = (reg.length > 0 && worldSelectedYears.length > 0)
        ? getSankeyDataForCountry(type, reg, worldSelectedYears)
        : new google.visualization.DataTable({cols:[{type:'string'},{type:'string'},{type:'number'}]});

    // Set chart options
    var options = {
      width: 1215,
      sankey: {
        link: { color: { stroke: 'lightgrey', strokeWidth: 1 } },
        node: { label: { fontFamily: 'sans-serif',
                         fontSize: 14,
                         color: '#871b47',
                         bold: true },
                nodePadding: 10}
      }
    };

    // Instantiate and draw Sankey chart
    charts.byCountry.sankey.draw(data, options);
}

function getSankeyDataForCountry(type, states, years) {
    var ct;
    var t = getCountriesYearUngrouped(type, states, years, true);
    ct = states.length > 1 ? getCountriesYear(type, states, years) : t;
    var yearCols = [];
    if (type === Type.ImportExportDiff) {
        for (var i = 2; i < years.length+2; ++i)
            yearCols.push(i);
    } else {
        $.each(years, function(k,v) { yearCols.push(getCountryYearCol(v)); });
    }
    var i;
    var maxMost = [];
    var countries = [];
    function ascSort(a,b) {return a[0]-b[0]}
    for (i = 0; i < ct.getNumberOfRows(); ++i) {
        var sum = 0;
        if (t === ct) {
            $.each(yearCols, function(k,v) { sum += ct.getValue(i, v); });
            if (type === Type.ImportExportDiff) {
                $.each(yearCols, function(k,v) { sum -= ct.getValue(i, v+years.length); });
            }
        } else {
            sum = ct.getValue(i, 1);
        }
        if (isNaN(sum)) throw new Error("NaN sum");
        // pick at most the 15 largest values
        if (maxMost.length < 15) {
            maxMost.push([sum,i]);
        } else {
            maxMost = maxMost.sort(ascSort);
            if (sum > maxMost[0][0])
                maxMost[0] = [sum, i];
        }
    }
    maxMost = maxMost.sort(ascSort);
    var col = (type === Type.ImportExportDiff ? 1 : Column.Country);
    if (t === ct) {
        if (ct.getColumnLabel(col) !== "Country")
          throw new Error("bah");
        for (i = 0; i < maxMost.length; ++i)
            countries.push(ct.getValue(i, col));
    } else {
        if (ct.getColumnLabel(0) !== "Country")
          throw new Error("bah");
        for (i = 0; i < maxMost.length; ++i)
            countries.push(ct.getValue(i, 0));
    }
    var v = new google.visualization.DataView(t);
    var rows = [];
    var sumOther = {};
    $.each(states, function(k,v) { sumOther[v] = 0; });
    for (i = 0; i < t.getNumberOfRows(); ++i) {
        var country = t.getValue(i, col);
        if (t.getColumnLabel(col) !== "Country")
          throw new Error("bah");
        var val = 0;
        $.each(yearCols, function(k,v) { val += t.getValue(i, v); });
        if (type === Type.ImportExportDiff) {
            $.each(yearCols, function(k,v) { val -= t.getValue(i, v+years.length); });
            val *= -1; // it's e-i but imports are listed first
        }
        if (isNaN(val)) throw new Error("NaN val");
        if (val <= 0 || countries.indexOf(country) < 0) // ignore negative values on ImportExportDiff
            sumOther[t.getValue(i, Column.State)] += val;
        else
            rows.push(i);
    }
    $.each(states, function(k,v) {
        if (sumOther[v] > 0) {
            t.addRow();
            t.setCell(i, Column.State, v);
            t.setCell(i, (type === Type.ImportExportDiff ? 1 : Column.Country), "Others");
            t.setCell(i, yearCols[0], sumOther[v]);
            rows.push(i);
            ++i;
        }
    });
    v.setRows(rows);
    if (type === Type.ImportExportDiff) {
        v.setColumns([Column.State, 1, yearCols[0]]);
    } else {
        v.setColumns([Column.State, Column.Country, yearCols[0]]);
    }
    return v;
}

function drawPieChart(){//Only two sets of data possibles (sum previous years in case of multiple selection?)
    var comView = getExportCommoditiesYear(regions.toArray()[0], select_commodities[0], commSelectedYears[0]);
    console.log(comView)
    var i = 0;
    if(typeof commSelectedYears[1] !== 'undefined') i=1;
    var comView1 = getExportCommoditiesYear(regions.toArray()[0], select_commodities[0], commSelectedYears[i]);
    if (i==0) str = 'Hscode: ' + select_commodities[0] + ', for the year: ' + commSelectedYears[0];
    else str = 'Hscode: ' + select_commodities[0] + ' Export Diff ' + commSelectedYears[0] + '-' + commSelectedYears[i];
        var options = {
          title: str,
          legend: 'none',
          diff: {comView: { opacity: 0.15 }} ,
          pieSliceText: 'percentage',
          width: 300,
          height: 340
        };

        var diffData = charts.byCommodity.pie.computeDiff(comView, comView1);
        charts.byCommodity.pie.draw(diffData, options);
}

function drawHistogram(){
    var data = getImportCommoditiesYear(regions.toArray()[0], select_commodities[0], commSelectedYears[0]);
    console.log(data);
    /*var data = google.visualization.arrayToDataTable([
          ['Dinosaur', 'Length'],
          ['Acrocanthosaurus (top-spined lizard)', 12.2],
          ['Albertosaurus (Alberta lizard)', 9.1],
          ['Allosaurus (other lizard)', 12.2],
          ['Apatosaurus (deceptive lizard)', 22.9],
          ['Archaeopteryx (ancient wing)', 0.9]]);*/
    var options = {
          title: 'Distribution for selected States',
          legend: { position: 'none' },
          width:300,
          height: 100
        };

        charts.byCommodity.hist.draw(data, options);
}
<|endoftext|>


<commit_before>import React from 'react-native';
const {
  ActivityIndicatorIOS,
  StyleSheet,
  Image,
  Text,
  View,
  TextInput,
  TouchableOpacity,
  Vibration,
} = React;

import Dimensions from 'Dimensions';
const {width, height} = Dimensions.get('window');
import globalVariables from '../globalVariables.js';
import Storage from './Storage.js';
import RCTDeviceEventEmitter from 'RCTDeviceEventEmitter';
import Icon from 'react-native-vector-icons/FontAwesome';

const Login = React.createClass({
  getInitialState() {
    return {
      username: '',
      password: '',
    };
  },

  getDefaultProps() {
    return {
    };
  },

  render() {

    return (
      <View style={{backgroundColor:'#f4f4f4',flex:1}}
       keyboardDismissMode='on-drag'
     keyboardShouldPersistTaps={false} >
          <Icon name="user" size={90} color="#666" style={styles.style_image} />
          <TextInput
              style={styles.style_user_input}
              placeholder='UserId'
              numberOfLines={1}
              autoFocus={true}
              textAlign='center'
              ref="username"
              clearButtonMode='while-editing'
              keyboardType='twitter'
              value={this.state.username}
              onChangeText={username => this.setState({username})}

          />
          <View
              style={{height:1,backgroundColor:'#f4f4f4'}}
          />
          <TextInput
              style={styles.style_pwd_input}
              placeholder='PassWord'
              numberOfLines={1}
              secureTextEntry={true}
              textAlign='center'
              ref="password"
              clearButtonMode='while-editing'
              value={this.state.password}
              onChangeText={password => this.setState({password})}
              onSubmitEditing={this.login}
          />
           <TouchableOpacity
            onPress={this.login}
            >
          <View
              style={styles.style_view_commit}
           >
            <Text style={{color:'#fff'}}>
               Log In
            </Text>

          </View>
          </TouchableOpacity>
      </View>
    );
  },

  login() {
    const { username, password } = this.state;
    if(!username||!password){
      Vibration.vibrate();
      return;
    }
    var body='user[email]='+username+'&user[password]='+password;
    globalVariables.queryRromServer(globalVariables.apiServer+'login',this.processsResults,{
      method:"POST",
      Content:"application/x-www-form-urlencoded",
      body:body,
      callBackHeaders:function(data){
        if(data["set-cookie"]&&data["set-cookie"][0]){
          Storage.setItem('cookie', data["set-cookie"][0])
          .then(()=>{
              return "";
            }
          ).catch(function (error) {});
        }
      }
    });
  },
  processsResults(data) {
    if (!data||!data.status.toLocaleLowerCase()=='success'){
      Vibration.vibrate();
      return;
    }

    globalVariables.saveMeInfo(
      {
        hypedLookIds:data.hyped_look_ids||[],
        fannedUserIds:data.fanned_user_ids||[],
        user:data.user||{},
        hypedCallBack:()=>{},
        fannedCallBack:()=>{},
        userCallBack:()=>{
          this._sendNotification();
          this.props.navigator.pop();
        }
      });
  },
  _sendNotification() {
    RCTDeviceEventEmitter.emit('Login');
  }
});

const styles = StyleSheet.create({
 style_image:{
    borderRadius:35,
    height:70,
    width:70,
    marginTop:40,
    alignSelf:'center',
  },
  style_user_input:{
      backgroundColor:'#fff',
      marginTop:10,
      height:35,
  },
   style_pwd_input:{
      backgroundColor:'#fff',
      height:35,
  },
   style_view_commit:{
      marginTop:15,
      marginLeft:10,
      marginRight:10,
      backgroundColor:'#63B8FF',
      height:35,
      borderRadius:5,
      justifyContent: 'center',
      alignItems: 'center',
  },
  style_view_unlogin:{
    fontSize:12,
    color:'#63B8FF',
    marginLeft:10,
  },
  style_view_register:{
    fontSize:12,
    color:'#63B8FF',
    marginRight:10,
    alignItems:'flex-end',
    flex:1,
    flexDirection:'row',
    textAlign:'right',
  }
});

export default Login;
<commit_msg>no message<commit_after>import React from 'react-native';
const {
  ActivityIndicatorIOS,
  StyleSheet,
  Image,
  Text,
  View,
  TextInput,
  TouchableOpacity,
  Vibration,
} = React;

import Dimensions from 'Dimensions';
const {width, height} = Dimensions.get('window');
import globalVariables from '../globalVariables.js';
import Storage from './Storage.js';
import RCTDeviceEventEmitter from 'RCTDeviceEventEmitter';
import Icon from 'react-native-vector-icons/FontAwesome';

const Login = React.createClass({
  getInitialState() {
    return {
      username: '',
      password: '',
    };
  },

  getDefaultProps() {
    return {
    };
  },

  render() {

    return (
      <View style={{backgroundColor:'#f4f4f4',flex:1,marginLeft:40,marginRight:40,}}
        keyboardDismissMode='on-drag'
        keyboardShouldPersistTaps={false} >
          <Icon name="user" size={90} color={globalVariables.base} style={styles.style_image} />
          <TextInput
              style={styles.style_user_input}
              placeholder='UserId'
              numberOfLines={1}
              autoFocus={true}
              textAlign='center'
              ref="username"
              clearButtonMode='while-editing'
              keyboardType='twitter'
              value={this.state.username}
              onChangeText={username => this.setState({username})} />

          <TextInput
              style={styles.style_user_input}
              placeholder='Password'
              numberOfLines={1}
              secureTextEntry={true}
              textAlign='center'
              ref="password"
              clearButtonMode='while-editing'
              value={this.state.password}
              onChangeText={password => this.setState({password})}
              onSubmitEditing={this.login} />

          <TouchableOpacity onPress={this.login} >
            <View style={styles.style_view_commit} >
              <Text style={{color: globalVariables.base,}}>
                 Log In
              </Text>
            </View>
          </TouchableOpacity>
      </View>
    );
  },

  login() {
    const { username, password } = this.state;
    if(!username||!password){
      Vibration.vibrate();
      return;
    }
    var body='user[email]='+username+'&user[password]='+password;
    globalVariables.queryRromServer(globalVariables.apiServer+'login',this.processsResults,{
      method:"POST",
      Content:"application/x-www-form-urlencoded",
      body:body,
      callBackHeaders:function(data){
        if(data["set-cookie"]&&data["set-cookie"][0]){
          Storage.setItem('cookie', data["set-cookie"][0])
          .then(()=>{
              return "";
            }
          ).catch(function (error) {});
        }
      }
    });
  },
  processsResults(data) {
    if (!data||!data.status.toLocaleLowerCase()=='success'){
      Vibration.vibrate();
      return;
    }

    globalVariables.saveMeInfo(
      {
        hypedLookIds:data.hyped_look_ids||[],
        fannedUserIds:data.fanned_user_ids||[],
        user:data.user||{},
        hypedCallBack:()=>{},
        fannedCallBack:()=>{},
        userCallBack:()=>{
          this._sendNotification();
          this.props.navigator.pop();
        }
      });
  },
  _sendNotification() {
    RCTDeviceEventEmitter.emit('Login');
  }
});

const styles = StyleSheet.create({
 style_image:{
    borderRadius:35,
    height:70,
    width:70,
    marginTop:80,
    alignSelf:'center',
  },
  style_user_input:{
      // backgroundColor:'#fff',
      marginTop:20,
      height:40,
      borderColor: globalVariables.base,
      borderWidth: 1,
       borderRadius:3,
  },
   style_pwd_input:{
      // backgroundColor:'#fff',
      height:40,
      borderColor: globalVariables.base,
      borderWidth: 1,
       borderRadius:3,
  },
   style_view_commit:{
      marginTop:25,
      borderColor:globalVariables.base,
      borderWidth:1,
      height:40,
      borderRadius:3,
      justifyContent: 'center',
      alignItems: 'center',
  },
});

export default Login;
<|endoftext|>


<commit_before>'use strict'

function FloatingSlider(current_value, minimum_value, maximum_value, width, position, normal, world) {
    this.__init__(current_value, minimum_value, maximum_value, width, position, normal, world)
}

FloatingSlider.prototype = {

    minimum_value: null,
    maximum_value: null,
    current_value: null,

    slider_increased: function() {
        if (this.current_value < this.maximum_value) {
            this.current_value += this.one_percent_value
        }
        if (this.current_value > this.maximum_value) {
            this.current_value = this.maximum_value
        }
        this.update()
    },

    slider_decreased: function() {
        if (this.current_value > this.minimum_value) {
            this.current_value -= this.one_percent_value
        }
        if (this.current_value < this.minimum_value) {
            this.current_value = this.minimum_value
        }
        this.update()
    },

    update: function() {
        var current_percentage = (this.current_value - this.minimum_value) / (this.maximum_value - this.minimum_value)
        this.current_value_text.update_text(current_percentage.toString())
        this.current_value_text.update_position_and_look_at(this._get_current_position_on_slider(0, 50, 0), this._get_current_look_at_on_slider(0, 50, 0))
        this.slider_object.update_position_and_look_at(this._get_current_position_on_slider(this.normal.x * 2, this.normal.y * 2, this.normal.z * 2), this._get_current_look_at_on_slider(this.normal.x * 2, this.normal.y * 2, this.normal.z * 2))
        WORLD_MANAGER.player.look_at(this.slider_object.get_position())
    },

    __init__: function(current_value, minimum_value, maximum_value, width, position, normal, world) {
        this.object3D = new THREE.Object3D()

        // Visibility must be inherited after interactive.
        Interactive.call(this)
        Visibility.call(this)

        this.current_value = current_value
        this.minimum_value = minimum_value
        this.maximum_value = maximum_value
        this.one_percent_value = (this.maximum_value - this.minimum_value) * 0.01
        this.width         = width
        this.half_width    = this.width / 2.0
        this.position      = position
        this.normal        = normal
        this.world         = world

        this.slider_offset = 0

        this.left_right = new THREE.Vector3(0, 1, 0)
        this.left_right.cross(this.normal)
        this.left_right.normalize()

        // Create the slider wall here.
        this.wall = new PlaneAPI(this.width, 20)
        this.object3D.add(this.wall.mesh)

        // Create the actual slider object.
        var current_percentage = (this.current_value - this.minimum_value) / (this.maximum_value - this.minimum_value)
        this.current_value_text = new Floating2DText(100, current_percentage.toString(), COLOR_TEXT_CONSTANT, this.world.scene)
        this.slider_object = new Floating2DText(12, '|||||||||', COLOR_TEXT_CONSTANT, this.world.scene)

        // Minimum Value Label
        this.minimum_value_label = new Floating2DText(25, this.minimum_value.toString(), COLOR_TEXT_CONSTANT, this.world.scene)
        this.minimum_value_label.update_position_and_look_at()

        // Maximum Value Label

        this.object3D.position.x = position.x
        this.object3D.position.y = position.y
        this.object3D.position.z = position.z
        this.object3D.lookAt(new THREE.Vector3(position.x + normal.x, position.y + normal.y, position.z + normal.z))

        this.current_value_text.update_position_and_look_at(this._get_current_position_on_slider(50), this._get_current_look_at_on_slider(50))
        this.slider_object.update_position_and_look_at(this._get_current_position_on_slider(this.normal.x * 2, this.normal.y * 2, this.normal.z * 2), this._get_current_look_at_on_slider(this.normal.x * 2, this.normal.y * 2, this.normal.z * 2))
        this.slider_object.requires_mouse_x_movement = true

        this.slider_object.bind_increase_and_decrease_functions(this.slider_increased.bind(this), this.slider_decreased.bind(this))

        this.world.scene.add(this.object3D)
        this.world.interactive_objects.push(this.slider_object)
    },

    get_current_value: function() {
        return this.current_value
    },

    get_position_on_slider_based_off_percentage: function(percentage, y_offset) {
        var position = new THREE.Vector3(this.position.x, this.position.y, this.position.z)
        //var current_percentage = (this.current_value - this.minimum_value) / (this.maximum_value - this.minimum_value)

        if (percentage < 0.5) {
            position.addScaledVector(this.left_right, -percentage * this.width)
        } else {
            position.addScaledVector(this.left_right, (percentage - 0.5) * this.width)
        }

        if (is_defined(y_offset)) {
            position.y += y_offset
        }
        return position
    },

    _get_current_position_on_slider: function(y_offset) {
        return this.get_position_on_slider_based_off_percentage((this.current_value - this.minimum_value) / (this.maximum_value - this.minimum_value), y_offset)
    },

    _get_current_look_at_on_slider: function(y_offset) {
        var position = this._get_current_position_on_slider(y_offset)
        return new THREE.Vector3(position.x + this.normal.x, position.y + this.normal.y, position.z + this.normal.z)
    }

}<commit_msg>general updating 45<commit_after>'use strict'

function FloatingSlider(current_value, minimum_value, maximum_value, width, position, normal, world) {
    this.__init__(current_value, minimum_value, maximum_value, width, position, normal, world)
}

FloatingSlider.prototype = {

    minimum_value: null,
    maximum_value: null,
    current_value: null,

    slider_increased: function() {
        if (this.current_value < this.maximum_value) {
            this.current_value += this.one_percent_value
        }
        if (this.current_value > this.maximum_value) {
            this.current_value = this.maximum_value
        }
        this.update()
    },

    slider_decreased: function() {
        if (this.current_value > this.minimum_value) {
            this.current_value -= this.one_percent_value
        }
        if (this.current_value < this.minimum_value) {
            this.current_value = this.minimum_value
        }
        this.update()
    },

    update: function() {
        var current_percentage = (this.current_value - this.minimum_value) / (this.maximum_value - this.minimum_value)
        this.current_value_text.update_text(current_percentage.toString())
        this.current_value_text.update_position_and_look_at(this._get_current_position_on_slider(0, 50, 0), this._get_current_look_at_on_slider(0, 50, 0))
        this.slider_object.update_position_and_look_at(this._get_current_position_on_slider(this.normal.x * 2, this.normal.y * 2, this.normal.z * 2), this._get_current_look_at_on_slider(this.normal.x * 2, this.normal.y * 2, this.normal.z * 2))
        WORLD_MANAGER.player.look_at(this.slider_object.get_position())
    },

    __init__: function(current_value, minimum_value, maximum_value, width, position, normal, world) {
        this.object3D = new THREE.Object3D()

        // Visibility must be inherited after interactive.
        Interactive.call(this)
        Visibility.call(this)

        this.current_value = current_value
        this.minimum_value = minimum_value
        this.maximum_value = maximum_value
        this.one_percent_value = (this.maximum_value - this.minimum_value) * 0.01
        this.width         = width
        this.half_width    = this.width / 2.0
        this.position      = position
        this.normal        = normal
        this.world         = world

        this.slider_offset = 0

        this.left_right = new THREE.Vector3(0, 1, 0)
        this.left_right.cross(this.normal)
        this.left_right.normalize()

        // Create the slider wall here.
        this.wall = new PlaneAPI(this.width, 20)
        this.object3D.add(this.wall.mesh)

        // Create the actual slider object.
        var current_percentage = (this.current_value - this.minimum_value) / (this.maximum_value - this.minimum_value)
        this.current_value_text = new Floating2DText(100, current_percentage.toString(), COLOR_TEXT_CONSTANT, this.world.scene)
        this.slider_object = new Floating2DText(12, '|||||||||', COLOR_TEXT_CONSTANT, this.world.scene)

        // Minimum Value Label
        //this.minimum_value_label = new Floating2DText(25, this.minimum_value.toString(), COLOR_TEXT_CONSTANT, this.world.scene)
        //this.minimum_value_label.update_position_and_look_at()

        // Maximum Value Label

        this.object3D.position.x = position.x
        this.object3D.position.y = position.y
        this.object3D.position.z = position.z
        this.object3D.lookAt(new THREE.Vector3(position.x + normal.x, position.y + normal.y, position.z + normal.z))

        this.current_value_text.update_position_and_look_at(this._get_current_position_on_slider(50), this._get_current_look_at_on_slider(50))
        this.slider_object.update_position_and_look_at(this._get_current_position_on_slider(this.normal.x * 2, this.normal.y * 2, this.normal.z * 2), this._get_current_look_at_on_slider(this.normal.x * 2, this.normal.y * 2, this.normal.z * 2))
        this.slider_object.requires_mouse_x_movement = true

        this.slider_object.bind_increase_and_decrease_functions(this.slider_increased.bind(this), this.slider_decreased.bind(this))

        this.world.scene.add(this.object3D)
        this.world.interactive_objects.push(this.slider_object)
    },

    get_current_value: function() {
        return this.current_value
    },

    get_position_on_slider_based_off_percentage: function(percentage, y_offset) {
        var position = new THREE.Vector3(this.position.x, this.position.y, this.position.z)
        //var current_percentage = (this.current_value - this.minimum_value) / (this.maximum_value - this.minimum_value)

        if (percentage < 0.5) {
            position.addScaledVector(this.left_right, -percentage * this.width)
        } else {
            position.addScaledVector(this.left_right, (percentage - 0.5) * this.width)
        }

        if (is_defined(y_offset)) {
            position.y += y_offset
        }
        return position
    },

    _get_current_position_on_slider: function(y_offset) {
        return this.get_position_on_slider_based_off_percentage((this.current_value - this.minimum_value) / (this.maximum_value - this.minimum_value), y_offset)
    },

    _get_current_look_at_on_slider: function(y_offset) {
        var position = this._get_current_position_on_slider(y_offset)
        return new THREE.Vector3(position.x + this.normal.x, position.y + this.normal.y, position.z + this.normal.z)
    }

}<|endoftext|>


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

  angular
    .module('decks')
    .controller('DecksController', DecksController);

  /** @ngInject */
  function DecksController(BackendService, $log, $stateParams,
                           orderByLocaleAwareConfig) {
    var vm = this;
    vm.getDecks = getDecks;

    orderByLocaleAwareConfig.localeId = 'pl';

    function getDecks() {
      vm.access = $stateParams.access;
      BackendService.getDecks(vm.access, true)
      .then(function (result) {
        vm.categories=result;
      }, function (e) {
        $log.error(e);
      });
    }

    getDecks();
  }

})();
<commit_msg>flshcard count<commit_after>(function() {
  'use strict';

  angular
    .module('decks')
    .controller('DecksController', DecksController);

  /** @ngInject */
  function DecksController(BackendService, $log, $stateParams,
                           orderByLocaleAwareConfig) {
    var vm = this;
    vm.getDecks = getDecks;
    vm.count = true;

    orderByLocaleAwareConfig.localeId = 'pl';

    function getDecks() {
      vm.access = $stateParams.access;
      BackendService.getDecks(vm.access, vm.count)
      .then(function (result) {
        vm.categories=result;
      }, function (e) {
        $log.error(e);
      });
    }

    getDecks();
  }

})();
<|endoftext|>


<commit_before>window.onload = function(e) {
  if (isIframe()) {
    // Send message to parent
    let PADDING = 30;
    let sessionId = getParameterByName('sessionId');
    if (!sessionId) {
      console.error("URL[" + window.location.href + "] does not contain session id");
    }
    else {
      sendHeightData();

      let key = sessionId + "-childFrameWidth";
      let width = $(document).width() + PADDING;
      let message = {
        "key" : key,
        "value" : width
      };

      console.log("Page for session [" + key + "] has width: " + width + " px");
      parent.postMessage(JSON.stringify(message), "*");
    }
  }
  else {
    // Redirect to the proper page
    let target = location.origin + '?goto=' +
      location.pathname.replace('/pages/', '/page/').replace('.html', '') +
      location.search.replace('?', '&');
    location.href = target;
  }
};

// Monitor page height to send it to parent
$(function () {
  let previousHeight = $(document).height();
  $(document).attrchange({
    callback: function (e) {
      let currentHeight = $(this).height();
      if (previousHeight !== currentHeight) {
        let msg = '[ChildFrame.ChangedHeight] Change height: ' + previousHeight;
        msg = msg + 'px to ' + currentHeight + 'px';
        console.log(msg);

        sendHeightData();
        previousHeight = currentHeight;
      }
    }
  }).resizable();
});

/**
 * Sends height data to parent frame
 */
function sendHeightData() {
  let sessionId = getParameterByName('sessionId');
  let key = sessionId + "-childFrameHeight";
  let height = $(document).height();
  let message = {
    "key" : key,
    "value" : height
  };

  console.log("[ChildFrame] Page for session [" + key + "] has height: " + height + " px");
  parent.postMessage(JSON.stringify(message), "*");
}

/**
 * Parses current url and retrieve the given parameter
 * query string: ?foo=lorem&bar=&baz
 * var foo = getParameterByName('foo'); // "lorem"
 * var bar = getParameterByName('bar'); // "" (present with empty value)
 * var baz = getParameterByName('baz'); // "" (present with no value)
 * var qux = getParameterByName('qux'); // null (absent)
 * @param {*} name
 * @param {*} url
 */
function getParameterByName(name, url) {
  if (!url) url = window.location.href;
  name = name.replace(/[\[\]]/g, "\\$&");
  var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
    results = regex.exec(url);
  if (!results) return null;
  if (!results[2]) return '';
  return decodeURIComponent(results[2].replace(/\+/g, " "));
}

/**
 * Detects whether the page is running inside an iFrame or not
 */
function isIframe() {
  try {
    return window.self !== window.top;
  }
  catch (e) {
    return true;
  }
}
<commit_msg>Minor fixes<commit_after>window.onload = function(e) {
  if (isIframe()) {
    // Send message to parent
    let PADDING = 30;
    let sessionId = getParameterByName('sessionId');
    if (!sessionId) {
      console.error("URL[" + window.location.href + "] does not contain session id");
    }
    else {
      sendHeightData();

      let key = sessionId + "-childFrameWidth";
      let width = $(document).width() + PADDING;
      let message = {
        "key" : key,
        "value" : width
      };

      console.log("Page for session [" + key + "] has width: " + width + " px");
      parent.postMessage(JSON.stringify(message), "*");
    }
  }
  else {
    // Redirect to the proper page
    let target = location.origin + '?goto=' +
      location.pathname.replace('/pages/', '/page/').replace('.html', '') +
      location.search.replace('?', '&');
    location.href = target;
  }

  // Monitor page height to send it to parent
  $(function () {
    let previousHeight = $(document).height();
    $(document).attrchange({
      callback: function (e) {
        let currentHeight = $(this).height();
        if (previousHeight !== currentHeight) {
          let msg = '[ChildFrame.ChangedHeight] Change height: ' + previousHeight;
          msg = msg + 'px to ' + currentHeight + 'px';
          console.log(msg);

          sendHeightData();
          previousHeight = currentHeight;
        }
      }
    }).resizable();
  });
};

/**
 * Sends height data to parent frame
 */
function sendHeightData() {
  let sessionId = getParameterByName('sessionId');
  let key = sessionId + "-childFrameHeight";
  let height = $(document).height();
  let message = {
    "key" : key,
    "value" : height
  };

  console.log("[ChildFrame] Page for session [" + key + "] has height: " + height + " px");
  parent.postMessage(JSON.stringify(message), "*");
}

/**
 * Parses current url and retrieve the given parameter
 * query string: ?foo=lorem&bar=&baz
 * var foo = getParameterByName('foo'); // "lorem"
 * var bar = getParameterByName('bar'); // "" (present with empty value)
 * var baz = getParameterByName('baz'); // "" (present with no value)
 * var qux = getParameterByName('qux'); // null (absent)
 * @param {*} name
 * @param {*} url
 */
function getParameterByName(name, url) {
  if (!url) url = window.location.href;
  name = name.replace(/[\[\]]/g, "\\$&");
  var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
    results = regex.exec(url);
  if (!results) return null;
  if (!results[2]) return '';
  return decodeURIComponent(results[2].replace(/\+/g, " "));
}

/**
 * Detects whether the page is running inside an iFrame or not
 */
function isIframe() {
  try {
    return window.self !== window.top;
  }
  catch (e) {
    return true;
  }
}
<|endoftext|>


<commit_before>define([
    "dojo/Evented",
    "dojo/_base/declare",
    "dojo/_base/lang",
    "dojo/has",
    "esri/kernel",
    "dijit/_WidgetBase",
    "dijit/a11yclick",
    "dijit/_TemplatedMixin",
    "dojo/on",
    "dojo/Deferred",
    // load template
    "dojo/text!zesri/dijit/templates/LocateButton.html",
    "dojo/i18n!zesri/nls/jsapi",
    "dojo/dom-class",
    "dojo/dom-style",
    "dojo/dom-attr",
    "esri/geometry/Point",
    "esri/SpatialReference",
    "esri/graphic",
    "esri/symbols/PictureMarkerSymbol",
    "esri/layers/GraphicsLayer"
],
function (
    Evented,
    declare,
    lang,
    has, esriNS,
    _WidgetBase, a11yclick, _TemplatedMixin,
    on,
    Deferred,
    dijitTemplate, i18n,
    domClass, domStyle, domAttr,
    Point, SpatialReference,
    Graphic, PictureMarkerSymbol,
    GraphicsLayer
) {
    var Widget = declare([_WidgetBase, _TemplatedMixin, Evented], {
        declaredClass: "esri.dijit.LocateButton",
        templateString: dijitTemplate,
        options: {
            theme: "LocateButton",
            map: null,
            visible: true,
            highlightLocation: true,
            symbol: new PictureMarkerSymbol(require.toUrl("esri/dijit") + '/images/blue-dot.png', 21, 21),
            infoTemplate: null,
            scale: null,
            useTracking: false,
            setScale: true,
            centerAt: true,
            geolocationOptions: {
                maximumAge: 0,
                timeout: 15000,
                enableHighAccuracy: true
            }
        },
        // lifecycle: 1
        constructor: function(options, srcRefNode) {
            // mix in settings and defaults
            var defaults = lang.mixin({}, this.options, options);
            // widget node
            this.domNode = srcRefNode;
            this._i18n = i18n;
            // hide if unsupported
            if (!navigator.geolocation) {
                defaults.visible = false;
                console.log('LocateButton::navigator.geolocation unsupported.');
            }
            // properties
            this.set("map", defaults.map);
            this.set("theme", defaults.theme);
            this.set("visible", defaults.visible);
            this.set("scale", defaults.scale);
            this.set("highlightLocation", defaults.highlightLocation);
            this.set("symbol", defaults.symbol);
            this.set("infoTemplate", defaults.infoTemplate);
            this.set("geolocationOptions", defaults.geolocationOptions);
            this.set("useTracking", defaults.useTracking); // new
            this.set("setScale", defaults.setScale); // new
            this.set("centerAt", defaults.centerAt); // new
            // listeners
            this.watch("theme", this._updateThemeWatch);
            this.watch("visible", this._visible);
            this.watch("tracking", this._locate);
            this.watch("useTracking", lang.hitch(this, function() {
                if (this.get("tracking") && !this.get("useTracking")) {
                    this._stopTracking();
                }
                // update title of button
                this._setTitle();
            }));
            // classes
            this._css = {
                container: "locateContainer",
                locate: "zoomLocateButton",
                loading: "loading",
                tracking: "tracking" // new
            };
        },
        // bind listener for button to action
        postCreate: function() {
            this.inherited(arguments);
            this.own(
            on(this._locateNode, a11yclick, lang.hitch(this, this.locate)));
        },
        // start widget. called by user
        startup: function() {
            // map not defined
            if (!this.get("map")) {
                this.destroy();
                console.log('LocateButton::map required');
            }
            // graphics layer
            this.set("graphicsLayer", new GraphicsLayer());
            // add graphics layer to the map
            this.get("map").addLayer(this.get("graphicsLayer"));
            // graphics remove highlight on clear
            this._graphicsEvent = on(this.get("graphicsLayer"), 'graphics-clear', lang.hitch(this, function() {
                this.set("highlightGraphic", null);
            }));
            // when map is loaded
            if (this.get("map").loaded) {
                this._init();
            } else {
                on.once(this.get("map"), "load", lang.hitch(this, function() {
                    this._init();
                }));
            }
        },
        // connections/subscriptions will be cleaned up during the destroy() lifecycle phase
        destroy: function() {
            // remove graphics layer event
            if (this._graphicsEvent) {
                this._graphicsEvent.remove();
            }
            // remove graphics layer
            if (this.graphicsLayer && this.map) {
                this.map.removeLayer(this.graphicsLayer);
            }
            // remove watch if there
            this._removeWatchPosition();
            // do other stuff
            this.inherited(arguments);
        },
        /* ---------------- */
        /* Public Events */
        /* ---------------- */
        // locate
        // load
        /* ---------------- */
        /* Public Functions */
        /* ---------------- */
        clear: function() {
            this.get("graphicsLayer").clear();
        },
        locate: function() {
            // toggle tracking
            if (this.get("useTracking")) {
                this.set("tracking", !this.get("tracking"));
            }
            return this._locate();
        },
        show: function() {
            this.set("visible", true);
        },
        hide: function() {
            this.set("visible", false);
        },
        /* ---------------- */
        /* Private Functions */
        /* ---------------- */
        _setTitle: function(){
            if(this.get("useTracking")){
                if(this.get("tracking")){
                    domAttr.set(this._locateNode, "title", this._i18n.widgets.locateButton.locate.stopTracking);
                }
                else{
                    domAttr.set(this._locateNode, "title", this._i18n.widgets.locateButton.locate.tracking);
                }
            }
            else{
                domAttr.set(this._locateNode, "title", this._i18n.widgets.locateButton.locate.title);
            }
        },
        _removeWatchPosition: function() {
            if (this.get("watchPosition")) {
                // remove watch event
                navigator.geolocation.clearWatch(this.get("watchPosition"));
                // set watch event
                this.set("watchPosition", null);
            }
        },
        _stopTracking: function() {
            domClass.remove(this._locateNode, this._css.tracking);
            this._removeWatchPosition();
            // remove loading class
            this._hideLoading();
        },
        _startTracking: function() {
            domClass.add(this._locateNode, this._css.tracking);
            this._removeWatchPosition();
            var watchEvent = navigator.geolocation.watchPosition(lang.hitch(this, function(position) {
                this._setPosition(position);
            }), lang.hitch(this, function(error) {
                this._logError(error);
            }), this.get('geolocationOptions'));
            // set watch event
            this.set("watchPosition", watchEvent);
        },
        _getCurrentPosition: function() {
            var def = new Deferred();
            // get location
            navigator.geolocation.getCurrentPosition(lang.hitch(this, function(position) {
                this._setPosition(position).then(lang.hitch(this, function(response) {
                    def.resolve(response);
                }), lang.hitch(this, function(error) {
                    this._logError(error);
                    def.reject(error);
                }));
            }), lang.hitch(this, function(error) {
                this._logError(error);
                def.reject(error);
            }), this.get('geolocationOptions'));
            // return deferred
            return def.promise;
        },
        _locate: function() {
            var def = new Deferred();
            // add loading class
            this._showLoading();
            // geolocation support
            if (navigator.geolocation) {
                // watch position
                if (this.get("useTracking")) {
                    // watch position exists
                    if (this.get("tracking")) {
                        this._startTracking();
                        def.resolve({
                            tracking: true
                        });
                    } else {
                        this._stopTracking();
                        def.resolve({
                            tracking: false
                        });
                    }
                } else {
                    this._getCurrentPosition().then(lang.hitch(this, function(response) {
                        def.resolve(response);
                    }), lang.hitch(this, function(error) {
                        this._logError(error);
                        def.reject(error);
                    }));
                }
            } else {
                this._hideLoading();
                console.log('LocateButton::geolocation unsupported');
                def.reject('LocateButton::geolocation unsupported');
            }
            this._setTitle();
            return def.promise;
        },
        _setPosition: function(position) {
            var def = new Deferred();
            // position returned
            if (position && position.coords) {
                // point info
                var latitude = position.coords.latitude;
                var longitude = position.coords.longitude;
                // scale info
                var scale = this.get("scale") || position.coords.accuracy || 50000;
                // set point
                var pt = new Point([longitude, latitude], new SpatialReference({
                    wkid: 4326
                }));
                if (pt) {
                    // highlight enabled
                    // if setScale is enabled
                    if (this.get("setScale")) {
                        // set scale
                        this.get("map").setScale(scale);
                    }
                    if (this.get("centerAt")) {
                        // center on point
                        this.get("map").centerAt(pt).then(lang.hitch(this, function() {
                            var evt = this._locateEvent(pt, scale, position);
                            def.resolve(evt);
                        }), lang.hitch(this, function(error) {
                            def.reject(error);
                        }));
                    } else {
                        var evt = this._locateEvent(pt, scale, position);
                        def.resolve(evt);
                    }
                } else {
                    // remove loading class
                    this._hideLoading();
                    def.reject('LocateButton::Invalid point');
                    console.log('LocateButton::Invalid point');
                }
            } else {
                // remove loading class
                this._hideLoading();
                console.log('LocateButton::Invalid position');
                def.reject('LocateButton::Invalid position');
            }
            return def.promise;
        },
        _locateEvent: function(pt, scale, position) {
            // graphic attributes
            var attributes = {
                position: position
            };
            // graphic variable
            var g;
            // if graphic currently on map
            if (this.get("highlightGraphic")) {
                g = this.get("highlightGraphic");
                g.setGeometry(pt);
                g.setAttributes(attributes);
                g.setInfoTemplate(this.get("infoTemplate"));
                g.setSymbol(this.get("symbol"));
            } else {
                // create graphic
                g = new Graphic(pt, this.get("symbol"), attributes, this.get("infoTemplate"));
                // highlight enabled
                if (this.get("highlightLocation")) {
                    this.get("graphicsLayer").add(g);
                }
            }
            // set highlight graphic
            this.set("highlightGraphic", g);
            // hide loading class
            this._hideLoading();
            // set event
            var locateEvt = {
                graphic: g,
                scale: scale,
                position: position
            };
            // emit event
            this.emit("locate", locateEvt);
            // return event object
            return locateEvt;
        },
        _logError: function(error) {
            // remove loading class
            this._hideLoading();
            // error info
            var errorCode = error.code || "";
            // error message
            var errorMessage = error.message || "";
            // error log
            var e = 'LocateButton::' + errorCode + ":" + errorMessage;
            console.log(e);
        },
        _showLoading: function() {
            if (!this.get("useTracking")) {
                domClass.add(this._locateNode, this._css.loading);
            }
        },
        _hideLoading: function() {
            if (!this.get("useTracking")) {
                domClass.remove(this._locateNode, this._css.loading);
            }
        },
        _init: function() {
            this._visible();
            this._setTitle();
            this.set("loaded", true);
            this.emit("load", {});
        },
        _updateThemeWatch: function(attr, oldVal, newVal) {
            domClass.remove(this.domNode, oldVal);
            domClass.add(this.domNode, newVal);
        },
        _visible: function() {
            if (this.get("visible")) {
                domStyle.set(this.domNode, 'display', 'block');
            } else {
                domStyle.set(this.domNode, 'display', 'none');
            }
        }
    });
    if (has("extend-esri")) {
        lang.setObject("dijit.LocateButton", Widget, esriNS);
    }
    return Widget;
});
<commit_msg>no message<commit_after>define([
    "dojo/Evented",
    "dojo/_base/declare",
    "dojo/_base/lang",
    "dojo/has",
    "esri/kernel",
    "dijit/_WidgetBase",
    "dijit/a11yclick",
    "dijit/_TemplatedMixin",
    "dojo/on",
    "dojo/Deferred",
    // load template
    "dojo/text!zesri/dijit/templates/LocateButton.html",
    "dojo/i18n!zesri/nls/jsapi",
    "dojo/dom-class",
    "dojo/dom-style",
    "dojo/dom-attr",
    "esri/geometry/Point",
    "esri/SpatialReference",
    "esri/graphic",
    "esri/symbols/PictureMarkerSymbol",
    "esri/layers/GraphicsLayer"
],
function (
    Evented,
    declare,
    lang,
    has, esriNS,
    _WidgetBase, a11yclick, _TemplatedMixin,
    on,
    Deferred,
    dijitTemplate, i18n,
    domClass, domStyle, domAttr,
    Point, SpatialReference,
    Graphic, PictureMarkerSymbol,
    GraphicsLayer
) {
    var Widget = declare([_WidgetBase, _TemplatedMixin, Evented], {
        declaredClass: "esri.dijit.LocateButton",
        templateString: dijitTemplate,
        options: {
            theme: "LocateButton",
            map: null,
            visible: true,
            highlightLocation: true,
            symbol: new PictureMarkerSymbol(require.toUrl("esri/dijit") + '/images/blue-dot.png', 21, 21),
            infoTemplate: null,
            scale: null,
            useTracking: false,
            setScale: true,
            centerAt: true,
            geolocationOptions: {
                maximumAge: 0,
                timeout: 15000,
                enableHighAccuracy: true
            }
        },
        // lifecycle: 1
        constructor: function(options, srcRefNode) {
            // mix in settings and defaults
            var defaults = lang.mixin({}, this.options, options);
            // widget node
            this.domNode = srcRefNode;
            this._i18n = i18n;
            // hide if unsupported
            if (!navigator.geolocation) {
                defaults.visible = false;
                console.log('LocateButton::navigator.geolocation unsupported.');
            }
            // properties
            this.set("map", defaults.map);
            this.set("theme", defaults.theme);
            this.set("visible", defaults.visible);
            this.set("scale", defaults.scale);
            this.set("highlightLocation", defaults.highlightLocation);
            this.set("symbol", defaults.symbol);
            this.set("infoTemplate", defaults.infoTemplate);
            this.set("geolocationOptions", defaults.geolocationOptions);
            this.set("useTracking", defaults.useTracking);
            this.set("setScale", defaults.setScale);
            this.set("centerAt", defaults.centerAt);
            // listeners
            this.watch("theme", this._updateThemeWatch);
            this.watch("visible", this._visible);
            this.watch("tracking", this._locate);
            this.watch("useTracking", lang.hitch(this, function() {
                if (this.get("tracking") && !this.get("useTracking")) {
                    this._stopTracking();
                }
                // update title of button
                this._setTitle();
            }));
            // classes
            this._css = {
                container: "locateContainer",
                locate: "zoomLocateButton",
                loading: "loading",
                tracking: "tracking"
            };
        },
        // bind listener for button to action
        postCreate: function() {
            this.inherited(arguments);
            this.own(on(this._locateNode, a11yclick, lang.hitch(this, this.locate)));
        },
        // start widget. called by user
        startup: function() {
            // map not defined
            if (!this.get("map")) {
                this.destroy();
                console.log('LocateButton::map required');
            }
            // graphics layer
            this.set("graphicsLayer", new GraphicsLayer());
            // add graphics layer to the map
            this.get("map").addLayer(this.get("graphicsLayer"));
            // graphics remove highlight on clear
            this._graphicsEvent = on(this.get("graphicsLayer"), 'graphics-clear', lang.hitch(this, function() {
                this.set("highlightGraphic", null);
            }));
            // when map is loaded
            if (this.get("map").loaded) {
                this._init();
            } else {
                on.once(this.get("map"), "load", lang.hitch(this, function() {
                    this._init();
                }));
            }
        },
        // connections/subscriptions will be cleaned up during the destroy() lifecycle phase
        destroy: function() {
            // remove graphics layer event
            if (this._graphicsEvent) {
                this._graphicsEvent.remove();
            }
            // remove graphics layer
            if (this.get("graphicsLayer") && this.get("map")) {
                this.get("map").removeLayer(this.get("graphicsLayer"));
            }
            // remove watch if there
            this._removeWatchPosition();
            // do other stuff
            this.inherited(arguments);
        },
        /* ---------------- */
        /* Public Events */
        /* ---------------- */
        // locate
        // load
        /* ---------------- */
        /* Public Functions */
        /* ---------------- */
        clear: function() {
            this.get("graphicsLayer").clear();
        },
        locate: function() {
            // toggle tracking
            if (this.get("useTracking")) {
                this.set("tracking", !this.get("tracking"));
            }
            return this._locate();
        },
        show: function() {
            this.set("visible", true);
        },
        hide: function() {
            this.set("visible", false);
        },
        /* ---------------- */
        /* Private Functions */
        /* ---------------- */
        _setTitle: function(){
            if(this.get("useTracking")){
                if(this.get("tracking")){
                    domAttr.set(this._locateNode, "title", this._i18n.widgets.locateButton.locate.stopTracking);
                }
                else{
                    domAttr.set(this._locateNode, "title", this._i18n.widgets.locateButton.locate.tracking);
                }
            }
            else{
                domAttr.set(this._locateNode, "title", this._i18n.widgets.locateButton.locate.title);
            }
        },
        _removeWatchPosition: function() {
            if (this.get("watchId")) {
                // remove watch event
                navigator.geolocation.clearWatch(this.get("watchId"));
                // set watch event
                this.set("watchId", null);
            }
        },
        _stopTracking: function() {
            domClass.remove(this._locateNode, this._css.tracking);
            this._removeWatchPosition();
            // remove loading class
            this._hideLoading();
        },
        _startTracking: function() {
            domClass.add(this._locateNode, this._css.tracking);
            this._removeWatchPosition();
            var WatchId = navigator.geolocation.watchPosition(lang.hitch(this, function(position) {
                this._setPosition(position);
            }), lang.hitch(this, function(error) {
                this._logError(error);
            }), this.get('geolocationOptions'));
            // set watch event
            this.set("watchId", WatchId);
        },
        _getCurrentPosition: function() {
            var def = new Deferred();
            // get location
            navigator.geolocation.getCurrentPosition(lang.hitch(this, function(position) {
                this._setPosition(position).then(lang.hitch(this, function(response) {
                    def.resolve(response);
                }), lang.hitch(this, function(error) {
                    this._logError(error);
                    def.reject(error);
                }));
            }), lang.hitch(this, function(error) {
                this._logError(error);
                def.reject(error);
            }), this.get('geolocationOptions'));
            // return deferred
            return def.promise;
        },
        _locate: function() {
            var def = new Deferred();
            // add loading class
            this._showLoading();
            // geolocation support
            if (navigator.geolocation) {
                // watch position
                if (this.get("useTracking")) {
                    // watch position exists
                    if (this.get("tracking")) {
                        this._startTracking();
                        def.resolve({
                            tracking: true
                        });
                    } else {
                        this._stopTracking();
                        def.resolve({
                            tracking: false
                        });
                    }
                } else {
                    this._getCurrentPosition().then(lang.hitch(this, function(response) {
                        def.resolve(response);
                    }), lang.hitch(this, function(error) {
                        this._logError(error);
                        def.reject(error);
                    }));
                }
            } else {
                this._hideLoading();
                console.log('LocateButton::geolocation unsupported');
                def.reject('LocateButton::geolocation unsupported');
            }
            this._setTitle();
            return def.promise;
        },
        _setPosition: function(position) {
            var def = new Deferred();
            // position returned
            if (position && position.coords) {
                // point info
                var latitude = position.coords.latitude;
                var longitude = position.coords.longitude;
                // scale info
                var scale = this.get("scale") || position.coords.accuracy || 50000;
                // set point
                var pt = new Point([longitude, latitude], new SpatialReference({
                    wkid: 4326
                }));
                if (pt) {
                    // highlight enabled
                    // if setScale is enabled
                    if (this.get("setScale")) {
                        // set scale
                        this.get("map").setScale(scale);
                    }
                    if (this.get("centerAt")) {
                        // center on point
                        this.get("map").centerAt(pt).then(lang.hitch(this, function() {
                            var evt = this._locateEvent(pt, scale, position);
                            def.resolve(evt);
                        }), lang.hitch(this, function(error) {
                            def.reject(error);
                        }));
                    } else {
                        var evt = this._locateEvent(pt, scale, position);
                        def.resolve(evt);
                    }
                } else {
                    // remove loading class
                    this._hideLoading();
                    def.reject('LocateButton::Invalid point');
                    console.log('LocateButton::Invalid point');
                }
            } else {
                // remove loading class
                this._hideLoading();
                console.log('LocateButton::Invalid position');
                def.reject('LocateButton::Invalid position');
            }
            return def.promise;
        },
        _locateEvent: function(pt, scale, position) {
            // graphic attributes
            var attributes = {
                position: position
            };
            // graphic variable
            var g;
            // if graphic currently on map
            if (this.get("highlightGraphic")) {
                g = this.get("highlightGraphic");
                g.setGeometry(pt);
                g.setAttributes(attributes);
                g.setInfoTemplate(this.get("infoTemplate"));
                g.setSymbol(this.get("symbol"));
            } else {
                // create graphic
                g = new Graphic(pt, this.get("symbol"), attributes, this.get("infoTemplate"));
                // highlight enabled
                if (this.get("highlightLocation")) {
                    this.get("graphicsLayer").add(g);
                }
            }
            // set highlight graphic
            this.set("highlightGraphic", g);
            // hide loading class
            this._hideLoading();
            // set event
            var locateEvt = {
                graphic: g,
                scale: scale,
                position: position
            };
            // emit event
            this.emit("locate", locateEvt);
            // return event object
            return locateEvt;
        },
        _logError: function(error) {
            // remove loading class
            this._hideLoading();
            // error info
            var errorCode = error.code || "";
            // error message
            var errorMessage = error.message || "";
            // error log
            var e = 'LocateButton::' + errorCode + ":" + errorMessage;
            console.log(e);
        },
        _showLoading: function() {
            if (!this.get("useTracking")) {
                domClass.add(this._locateNode, this._css.loading);
            }
        },
        _hideLoading: function() {
            if (!this.get("useTracking")) {
                domClass.remove(this._locateNode, this._css.loading);
            }
        },
        _init: function() {
            this._visible();
            this._setTitle();
            this.set("loaded", true);
            this.emit("load", {});
        },
        _updateThemeWatch: function(attr, oldVal, newVal) {
            domClass.remove(this.domNode, oldVal);
            domClass.add(this.domNode, newVal);
        },
        _visible: function() {
            if (this.get("visible")) {
                domStyle.set(this.domNode, 'display', 'block');
            } else {
                domStyle.set(this.domNode, 'display', 'none');
            }
        }
    });
    if (has("extend-esri")) {
        lang.setObject("dijit.LocateButton", Widget, esriNS);
    }
    return Widget;
});
<|endoftext|>


<commit_before>const React = require('react');
const Radium = require('radium');

const Icon = require('./Icon');

const StyleConstants = require('../constants/Style');

class Modal extends React.Component {
  constructor (props) {
    super(props);
    this.state = {
      showTooltip: false
    };
  }

  _handleTooltipToggle (show) {
    this.setState({
      showTooltip: show
    });
  }

  _renderTitleBar () {
    if (this.props.showTitleBar) {
      return (

          {this.props.title}

      );
    }
  }

  _renderFooter () {
    if (this.props.showFooter) {
      return (

          {this._renderTooltipIconAndLabel()}
          {this._renderFooterContent()}

            {this.props.buttons.map((button, i) => {
              return (

                  {button.label}

              );
            })}

      );
    }
  }

  _renderFooterContent () {
    return (

        {this.props.footerContent ? this.props.footerContent : null}

    );
  }

  _renderTooltip () {
    if (this.state.showTooltip) {
      return (

            {this.props.tooltipTitle}

            {this.props.tooltip}

      );
    }
  }

  _renderTooltipIconAndLabel () {
    if (this.props.tooltip) {
      return (

          <Icon
            className='mx-modal-tooltip-label-icon'
            onMouseOut={this._handleTooltipToggle.bind(this, false)}
            onMouseOver={this._handleTooltipToggle.bind(this, true)}
            size={18}
            style={{ color: this.props.color }}
            type='info'
          />

            {this.props.tooltipLabel}

      );
    }
  }

  render () {
    if (this.props.isOpen)
      return (

            <Icon
              className='mx-modal-close'
              onClick={this.props.onRequestClose}
              size={24}
              style={styles.close}
              type='close-solid'
            />
            {this._renderTitleBar()}

              {this.props.children}
              {this._renderTooltip()}

            {this._renderFooter()}

      );
    else
      return (
        null
      );
  }
}

const styles = {
  scrim: {
    zIndex: 1000,
    position: 'fixed',
    top: 0,
    right: 0,
    bottom: 0,
    left: 0,
    textAlign: 'center'
  },
  relative: {
    position: 'absolute'
  },
  overlay: {
    backgroundColor: StyleConstants.Colors.SCRIM
  },
  close: {
    position: 'absolute',
    top: 0,
    right: 0,
    margin: '-12px -12px 0 0',
    cursor: 'pointer',
    color: StyleConstants.Colors.CHARCOAL
  },
  container: {
    fontFamily: StyleConstants.FontFamily,
    boxSizing: 'border-box',
    position: 'relative',
    zIndex: 1001,
    backgroundColor: StyleConstants.Colors.WHITE,
    boxShadow: '0 0 30px 5px rgba(0,0,0,0.1)',
    borderRadius: 2,
    top: 20,
    maxWidth: 'calc(100% - 40px)',
    display: 'inline-block',
    textAlign: 'left'
  },
  titleBar: {
    backgroundColor: StyleConstants.Colors.PORCELAIN,
    borderTopLeftRadius: 2,
    borderTopRightRadius: 2,
    padding: '15px 20px',
    color: StyleConstants.Colors.ASH,
    fontSize: StyleConstants.FontSizes.SMALL,
    textTransform: 'uppercase'
  },
  content: {
    position: 'relative',
    maxHeight: 'calc(100% - 140px)',
    overflow: 'auto'
  },
  footer: {
    backgroundColor: StyleConstants.Colors.PORCELAIN,
    borderBottomLeftRadius: 2,
    borderBottomRightRadius: 2,
    padding: '10px 20px',
    display: 'flex',
    justifyContent: 'space-between'
  },
  footerContent: {
    padding: '5px 0',
    textAlign: 'left'
  },
  tooltipLabel: {
    padding: '5px 0'
  },
  tooltipLabelText: {
    fontSize: StyleConstants.FontSizes.SMALL
  },
  tooltip: {
    backgroundColor: StyleConstants.Colors.PORCELAIN,
    borderColor: StyleConstants.Colors.FOG,
    borderStyle: 'solid',
    borderWidth: 1,
    boxSizing: 'border-box',
    bottom: 10,
    left: 10,
    position: 'absolute',
    width: 250,
    maxWidth: '100%',
    padding: 10
  },
  tooltipTitle: {
    fontSize: StyleConstants.FontSizes.MEDIUM,
    marginBottom: 5
  },
  tooltipContent: {
    color: StyleConstants.Colors.ASH,
    fontSize: StyleConstants.FontSizes.SMALL,
    lineHeight: '1.5em',
    textAlign: 'left'
  },
  buttons: {
    textAlign: 'right'
  },
  button: {
    display: 'inline-block',
    borderRadius: 2,
    cursor: 'pointer',
    fontSize: StyleConstants.FontSizes.MEDIUM,
    fontWeight: 600,
    padding: '7px 14px',
    marginLeft: 5
  },
  primaryButton: {
    backgroundColor: StyleConstants.Colors.PRIMARY,
    color: StyleConstants.Colors.WHITE
  },
  secondaryButton: {
    backgroundColor: StyleConstants.Colors.FOG,
    color: StyleConstants.Colors.CHARCOAL
  },
  small: {
    width: 400,
    textAlign: 'center'
  }
};

Modal.propTypes = {
  buttons: React.PropTypes.arrayOf(React.PropTypes.shape({
    className: React.PropTypes.string,
    label: React.PropTypes.string,
    onClick: React.PropTypes.func,
    style: React.PropTypes.oneOfType([
      React.PropTypes.array,
      React.PropTypes.object
    ]),
    type: React.PropTypes.oneOf(['primary', 'secondary'])
  })),
  color: React.PropTypes.string,
  contentStyle: React.PropTypes.object,
  footerContent: React.PropTypes.node,
  isOpen: React.PropTypes.bool,
  isRelative: React.PropTypes.bool,
  onRequestClose: React.PropTypes.func,
  showFooter: React.PropTypes.bool,
  showTitleBar: React.PropTypes.bool,
  title: React.PropTypes.string,
  tooltip: React.PropTypes.string,
  tooltipLabel: React.PropTypes.string,
  tooltipTitle: React.PropTypes.string
};

Modal.defaultProps = {
  buttons: [],
  color: StyleConstants.Colors.PRIMARY,
  isOpen: false,
  isRelative: false,
  showFooter: false,
  showTitleBar: false,
  title: '',
  tooltip: null,
  tooltipLabel: '',
  tooltipTitle: null
};

module.exports = Radium(Modal);
<commit_msg>remove check around footerContent<commit_after>const React = require('react');
const Radium = require('radium');

const Icon = require('./Icon');

const StyleConstants = require('../constants/Style');

class Modal extends React.Component {
  constructor (props) {
    super(props);
    this.state = {
      showTooltip: false
    };
  }

  _handleTooltipToggle (show) {
    this.setState({
      showTooltip: show
    });
  }

  _renderTitleBar () {
    if (this.props.showTitleBar) {
      return (

          {this.props.title}

      );
    }
  }

  _renderFooter () {
    if (this.props.showFooter) {
      return (

          {this._renderTooltipIconAndLabel()}
          {this._renderFooterContent()}

            {this.props.buttons.map((button, i) => {
              return (

                  {button.label}

              );
            })}

      );
    }
  }

  _renderFooterContent () {
    return (

        {this.props.footerContent}

    );
  }

  _renderTooltip () {
    if (this.state.showTooltip) {
      return (

            {this.props.tooltipTitle}

            {this.props.tooltip}

      );
    }
  }

  _renderTooltipIconAndLabel () {
    if (this.props.tooltip) {
      return (

          <Icon
            className='mx-modal-tooltip-label-icon'
            onMouseOut={this._handleTooltipToggle.bind(this, false)}
            onMouseOver={this._handleTooltipToggle.bind(this, true)}
            size={18}
            style={{ color: this.props.color }}
            type='info'
          />

            {this.props.tooltipLabel}

      );
    }
  }

  render () {
    if (this.props.isOpen)
      return (

            <Icon
              className='mx-modal-close'
              onClick={this.props.onRequestClose}
              size={24}
              style={styles.close}
              type='close-solid'
            />
            {this._renderTitleBar()}

              {this.props.children}
              {this._renderTooltip()}

            {this._renderFooter()}

      );
    else
      return (
        null
      );
  }
}

const styles = {
  scrim: {
    zIndex: 1000,
    position: 'fixed',
    top: 0,
    right: 0,
    bottom: 0,
    left: 0,
    textAlign: 'center'
  },
  relative: {
    position: 'absolute'
  },
  overlay: {
    backgroundColor: StyleConstants.Colors.SCRIM
  },
  close: {
    position: 'absolute',
    top: 0,
    right: 0,
    margin: '-12px -12px 0 0',
    cursor: 'pointer',
    color: StyleConstants.Colors.CHARCOAL
  },
  container: {
    fontFamily: StyleConstants.FontFamily,
    boxSizing: 'border-box',
    position: 'relative',
    zIndex: 1001,
    backgroundColor: StyleConstants.Colors.WHITE,
    boxShadow: '0 0 30px 5px rgba(0,0,0,0.1)',
    borderRadius: 2,
    top: 20,
    maxWidth: 'calc(100% - 40px)',
    display: 'inline-block',
    textAlign: 'left'
  },
  titleBar: {
    backgroundColor: StyleConstants.Colors.PORCELAIN,
    borderTopLeftRadius: 2,
    borderTopRightRadius: 2,
    padding: '15px 20px',
    color: StyleConstants.Colors.ASH,
    fontSize: StyleConstants.FontSizes.SMALL,
    textTransform: 'uppercase'
  },
  content: {
    position: 'relative',
    maxHeight: 'calc(100% - 140px)',
    overflow: 'auto'
  },
  footer: {
    backgroundColor: StyleConstants.Colors.PORCELAIN,
    borderBottomLeftRadius: 2,
    borderBottomRightRadius: 2,
    padding: '10px 20px',
    display: 'flex',
    justifyContent: 'space-between'
  },
  footerContent: {
    padding: '5px 0',
    textAlign: 'left'
  },
  tooltipLabel: {
    padding: '5px 0'
  },
  tooltipLabelText: {
    fontSize: StyleConstants.FontSizes.SMALL
  },
  tooltip: {
    backgroundColor: StyleConstants.Colors.PORCELAIN,
    borderColor: StyleConstants.Colors.FOG,
    borderStyle: 'solid',
    borderWidth: 1,
    boxSizing: 'border-box',
    bottom: 10,
    left: 10,
    position: 'absolute',
    width: 250,
    maxWidth: '100%',
    padding: 10
  },
  tooltipTitle: {
    fontSize: StyleConstants.FontSizes.MEDIUM,
    marginBottom: 5
  },
  tooltipContent: {
    color: StyleConstants.Colors.ASH,
    fontSize: StyleConstants.FontSizes.SMALL,
    lineHeight: '1.5em',
    textAlign: 'left'
  },
  buttons: {
    textAlign: 'right'
  },
  button: {
    display: 'inline-block',
    borderRadius: 2,
    cursor: 'pointer',
    fontSize: StyleConstants.FontSizes.MEDIUM,
    fontWeight: 600,
    padding: '7px 14px',
    marginLeft: 5
  },
  primaryButton: {
    backgroundColor: StyleConstants.Colors.PRIMARY,
    color: StyleConstants.Colors.WHITE
  },
  secondaryButton: {
    backgroundColor: StyleConstants.Colors.FOG,
    color: StyleConstants.Colors.CHARCOAL
  },
  small: {
    width: 400,
    textAlign: 'center'
  }
};

Modal.propTypes = {
  buttons: React.PropTypes.arrayOf(React.PropTypes.shape({
    className: React.PropTypes.string,
    label: React.PropTypes.string,
    onClick: React.PropTypes.func,
    style: React.PropTypes.oneOfType([
      React.PropTypes.array,
      React.PropTypes.object
    ]),
    type: React.PropTypes.oneOf(['primary', 'secondary'])
  })),
  color: React.PropTypes.string,
  contentStyle: React.PropTypes.object,
  footerContent: React.PropTypes.node,
  isOpen: React.PropTypes.bool,
  isRelative: React.PropTypes.bool,
  onRequestClose: React.PropTypes.func,
  showFooter: React.PropTypes.bool,
  showTitleBar: React.PropTypes.bool,
  title: React.PropTypes.string,
  tooltip: React.PropTypes.string,
  tooltipLabel: React.PropTypes.string,
  tooltipTitle: React.PropTypes.string
};

Modal.defaultProps = {
  buttons: [],
  color: StyleConstants.Colors.PRIMARY,
  isOpen: false,
  isRelative: false,
  showFooter: false,
  showTitleBar: false,
  title: '',
  tooltip: null,
  tooltipLabel: '',
  tooltipTitle: null
};

module.exports = Radium(Modal);
<|endoftext|>


<commit_before><commit_msg>[IMP] point_of_sale: better merge detection<commit_after><|endoftext|>


<commit_before>// Service that propagates business process flow changes
//
// Most updates are delayed to next tick, so eventual preTrigger setups have chance to catch up
// for cases when file is loaded in inconsistent state

'use strict';

var aFrom           = require('es5-ext/array/from')
  , ensureIterable  = require('es5-ext/iterable/validate-object')
  , ensureCallable  = require('es5-ext/object/valid-callable')
  , Set             = require('es6-set')
  , ensureType      = require('dbjs/valid-dbjs-type')
  , debug           = require('debug-ext')('business-process-flow')
  , delay           = require('timers-ext/delay')
  , resolveStepPath = require('../../utils/resolve-processing-step-full-path')
  , setupTriggers   = require('../_setup-triggers');

module.exports = function (BusinessProcessType, stepShortPaths/*, options*/) {
	var businessProcesses = ensureType(BusinessProcessType).instances
		.filterByKey('isFromEregistrations', true).filterByKey('isDemo', false)
	  , options = Object(arguments[2])
	  , customStepReturnHandler, onSubmitted, onStepRedelegate, onStepStatus, onUserProcessingEnd;

	if (options.customStepReturnHandler != null) {
		customStepReturnHandler = ensureCallable(options.customStepReturnHandler);
	}
	if (options.onStepRedelegate != null) onStepRedelegate = ensureCallable(options.onStepRedelegate);
	if (options.onStepStatus != null) onStepStatus = ensureCallable(options.onStepStatus);
	if (options.onSubmitted != null) onSubmitted = ensureCallable(options.onSubmitted);
	if (options.onUserProcessingEnd != null) {
		onUserProcessingEnd = ensureCallable(options.onUserProcessingEnd);
	}

	var stepPaths = aFrom(ensureIterable(stepShortPaths)).map(function (shortPath) {
		return 'processingSteps/map/' + resolveStepPath(shortPath);
	});

	// Business process: isSubmitted
	setupTriggers({
		trigger: businessProcesses.filterByKey('isSubmittedReady', true)
			.filterByKey('isSubmitted', false)
	}, delay(function (businessProcess) {
		debug('%s submitted', businessProcess.__id__);
		if (onSubmitted) onSubmitted(businessProcess);
		businessProcess.isSubmitted = true;
	}));
	setupTriggers({
		trigger: businessProcesses.filterByKey('isSubmitted', true)
	}, function (businessProcess) {
		if (!businessProcess.dataForms.dataSnapshot.jsonString) {
			debug('%s generate initial data snapshots', businessProcess.__id__);
		}
		businessProcess.dataForms.dataSnapshot.generate();
		businessProcess.requirementUploads.dataSnapshot.generate();
		businessProcess.paymentReceiptUploads.dataSnapshot.generate();
	});

	var businessProcessesSubmitted = businessProcesses.filterByKey('isSubmitted', true);

	// Business process: sentBack finalization
	setupTriggers({
		trigger: businessProcessesSubmitted.filterByKey('isSubmittedReady', true)
			.filterByKey('isSentBack', true)
	}, delay(function (businessProcess) {
		debug('%s finalize sentBack', businessProcess.__id__);
		businessProcess.delete('isSentBack');
		businessProcess.dataForms.dataSnapshot.regenerate();
		businessProcess.requirementUploads.dataSnapshot.regenerate();
		businessProcess.paymentReceiptUploads.dataSnapshot.regenerate();
	}));

	// Business process: isUserProcessing initialization
	setupTriggers({
		trigger: businessProcessesSubmitted.filterByKey('isUserProcessingReady', true)
			.filterByKey('isUserProcessing', false)
	}, delay(function (businessProcess) {
		debug('%s initialize user processing', businessProcess.__id__);
		businessProcess.submissionForms.delete('isAffidavitSigned');
		businessProcess.isUserProcessing = true;
	}));

	// Business process: isUserProcessing finalization
	setupTriggers({
		trigger: businessProcessesSubmitted.filterByKey('isSubmittedReady', true)
			.filterByKey('isUserProcessing', true)
	}, delay(function (businessProcess) {
		debug('%s finalize user processing', businessProcess.__id__);
		if (onUserProcessingEnd) onUserProcessingEnd(businessProcess);
		businessProcess.delete('isUserProcessing');
		businessProcess.dataForms.dataSnapshot.regenerate();
		businessProcess.requirementUploads.dataSnapshot.regenerate();
		businessProcess.paymentReceiptUploads.dataSnapshot.regenerate();
	}));

	// Business process: isApproved preservation
	setupTriggers({
		trigger: businessProcessesSubmitted.filterByKey('isApprovedReady', true)
			.filterByKey('isApproved', false)
	}, delay(function (businessProcess) {
		debug('%s approved', businessProcess.__id__);
		businessProcess.isApproved = true;
	}));
	setupTriggers({
		trigger: businessProcesses.filterByKey('isClosed', true)
	}, function (businessProcess) {
		if (!businessProcess.certificates.dataSnapshot.jsonString) {
			debug('%s generate certificates data snapshots', businessProcess.__id__);
		}
		businessProcess.certificates.dataSnapshot.generate();
		businessProcess.requirementUploads.dataSnapshot.finalize();
		businessProcess.paymentReceiptUploads.dataSnapshot.finalize();
	});

	// Processing steps:
	var nonFinalStatuses = new Set(['pending', 'paused']);
	stepPaths.forEach(function (stepPath, index) {
		// status
		setupTriggers({
			trigger: businessProcessesSubmitted.filterByKeyPath(stepPath + '/status', function (value) {
				return value && !nonFinalStatuses.has(value);
			})
		}, delay(function (businessProcess) {
			var step = businessProcess.getBySKeyPath(stepPath), targetStep;
			if (step.hasOwnProperty('status')) return; // Already shadowed
			debug('%s %s step %s', businessProcess.__id__, step.shortPath, step.status);
			if (onStepStatus) onStepStatus(step);
			if (!step.hasOwnProperty('isReady')) step.isReady = true;
			if (step.revisionStatus && !nonFinalStatuses.has(step.revisionStatus)) {
				step.set('revisionStatus', step.revisionStatus);
			}
			step.set('status', step.status);

			if (step.status === 'sentBack') {
				if (businessProcess.isSentBack) return;

				// Sent back initialization
				debug('%s sent back by %s step', businessProcess.__id__, step.shortPath);
				businessProcess.submissionForms.delete('isAffidavitSigned');
				businessProcess.isSentBack = true;

			} else if (step.status === 'redelegated') {

				// Redelegation initialization
				targetStep = step.redelegatedTo;
				debug('%s redelegated to %s from %s', businessProcess.__id__,
					targetStep.shortPath, step.shortPath);
				if (onStepRedelegate) onStepRedelegate(step);
				if (targetStep.hasOwnProperty('revisionOfficialStatus')) {
					targetStep.delete('revisionOfficialStatus');
				}
				targetStep.delete('officialStatus');
				if (targetStep.hasOwnProperty('revisionStatus')) targetStep.delete('revisionStatus');
				targetStep.delete('status');
				if (targetStep.hasOwnProperty('isSatisfied')) targetStep.delete('isSatisfied');
			} else if (step.status === 'rejected') {

				// Business process rejection
				debug('%s rejected at %s', businessProcess.__id__, step.shortPath);
				businessProcess.isRejected = true;
			}
		}));

		// isSatisfied
		setupTriggers({
			trigger: businessProcessesSubmitted.filterByKeyPath(stepPath + '/isSatisfiedReady', true)
				.filterByKeyPath(stepPath + '/isSatisfied', false)
		}, delay(function (businessProcess) {
			var step = businessProcess.getBySKeyPath(stepPath);
			debug('%s %s step satisfied', businessProcess.__id__, step.shortPath);
			step.isSatisfied = true;
		}));

		// Valid returns
		var returnStatuses = new Set(['sentBack', 'redelegated']);
		setupTriggers({
			preTrigger: businessProcessesSubmitted
				.filterByKeyPath(stepPath + '/isPreviousStepsSatisfiedDeep', false),
			trigger: businessProcessesSubmitted
				.filterByKeyPath(stepPath + '/isPreviousStepsSatisfiedDeep', true)
		}, delay(function (businessProcess) {
			var step = businessProcess.getBySKeyPath(stepPath)
			  , returnHandlerResult;

			if (!step.isApplicable) return;
			if (!step.status || (step.status === 'pending')) return;

			if (customStepReturnHandler) {
				returnHandlerResult = customStepReturnHandler(step);
			}

			if (returnHandlerResult == null) {
				if (step.statusComputed && (step.statusComputed !== 'pending') &&
						!returnStatuses.has(step.status)) {
					return;
				}
			} else if (!returnHandlerResult) {
				// Skip if customStepReturnHandler 'explicitly' decided so
				return;
			}

			debug('%s %s step reset from %s to pending state', businessProcess.__id__,
				step.shortPath, step.status);
			if (step.hasOwnProperty('revisionOfficialStatus')) step.delete('revisionOfficialStatus');
			step.delete('officialStatus');
			if (step.hasOwnProperty('revisionStatus')) step.delete('revisionStatus');
			step.delete('status');
			if (step.hasOwnProperty('isSatisfied')) step.delete('isSatisfied');
		}));
	});
};
<commit_msg>Do not delay pretriggered change<commit_after>// Service that propagates business process flow changes
//
// Most updates are delayed to next tick, so eventual preTrigger setups have chance to catch up
// for cases when file is loaded in inconsistent state

'use strict';

var aFrom           = require('es5-ext/array/from')
  , ensureIterable  = require('es5-ext/iterable/validate-object')
  , ensureCallable  = require('es5-ext/object/valid-callable')
  , Set             = require('es6-set')
  , ensureType      = require('dbjs/valid-dbjs-type')
  , debug           = require('debug-ext')('business-process-flow')
  , delay           = require('timers-ext/delay')
  , resolveStepPath = require('../../utils/resolve-processing-step-full-path')
  , setupTriggers   = require('../_setup-triggers');

module.exports = function (BusinessProcessType, stepShortPaths/*, options*/) {
	var businessProcesses = ensureType(BusinessProcessType).instances
		.filterByKey('isFromEregistrations', true).filterByKey('isDemo', false)
	  , options = Object(arguments[2])
	  , customStepReturnHandler, onSubmitted, onStepRedelegate, onStepStatus, onUserProcessingEnd;

	if (options.customStepReturnHandler != null) {
		customStepReturnHandler = ensureCallable(options.customStepReturnHandler);
	}
	if (options.onStepRedelegate != null) onStepRedelegate = ensureCallable(options.onStepRedelegate);
	if (options.onStepStatus != null) onStepStatus = ensureCallable(options.onStepStatus);
	if (options.onSubmitted != null) onSubmitted = ensureCallable(options.onSubmitted);
	if (options.onUserProcessingEnd != null) {
		onUserProcessingEnd = ensureCallable(options.onUserProcessingEnd);
	}

	var stepPaths = aFrom(ensureIterable(stepShortPaths)).map(function (shortPath) {
		return 'processingSteps/map/' + resolveStepPath(shortPath);
	});

	// Business process: isSubmitted
	setupTriggers({
		trigger: businessProcesses.filterByKey('isSubmittedReady', true)
			.filterByKey('isSubmitted', false)
	}, delay(function (businessProcess) {
		debug('%s submitted', businessProcess.__id__);
		if (onSubmitted) onSubmitted(businessProcess);
		businessProcess.isSubmitted = true;
	}));
	setupTriggers({
		trigger: businessProcesses.filterByKey('isSubmitted', true)
	}, function (businessProcess) {
		if (!businessProcess.dataForms.dataSnapshot.jsonString) {
			debug('%s generate initial data snapshots', businessProcess.__id__);
		}
		businessProcess.dataForms.dataSnapshot.generate();
		businessProcess.requirementUploads.dataSnapshot.generate();
		businessProcess.paymentReceiptUploads.dataSnapshot.generate();
	});

	var businessProcessesSubmitted = businessProcesses.filterByKey('isSubmitted', true);

	// Business process: sentBack finalization
	setupTriggers({
		trigger: businessProcessesSubmitted.filterByKey('isSubmittedReady', true)
			.filterByKey('isSentBack', true)
	}, delay(function (businessProcess) {
		debug('%s finalize sentBack', businessProcess.__id__);
		businessProcess.delete('isSentBack');
		businessProcess.dataForms.dataSnapshot.regenerate();
		businessProcess.requirementUploads.dataSnapshot.regenerate();
		businessProcess.paymentReceiptUploads.dataSnapshot.regenerate();
	}));

	// Business process: isUserProcessing initialization
	setupTriggers({
		trigger: businessProcessesSubmitted.filterByKey('isUserProcessingReady', true)
			.filterByKey('isUserProcessing', false)
	}, delay(function (businessProcess) {
		debug('%s initialize user processing', businessProcess.__id__);
		businessProcess.submissionForms.delete('isAffidavitSigned');
		businessProcess.isUserProcessing = true;
	}));

	// Business process: isUserProcessing finalization
	setupTriggers({
		trigger: businessProcessesSubmitted.filterByKey('isSubmittedReady', true)
			.filterByKey('isUserProcessing', true)
	}, delay(function (businessProcess) {
		debug('%s finalize user processing', businessProcess.__id__);
		if (onUserProcessingEnd) onUserProcessingEnd(businessProcess);
		businessProcess.delete('isUserProcessing');
		businessProcess.dataForms.dataSnapshot.regenerate();
		businessProcess.requirementUploads.dataSnapshot.regenerate();
		businessProcess.paymentReceiptUploads.dataSnapshot.regenerate();
	}));

	// Business process: isApproved preservation
	setupTriggers({
		trigger: businessProcessesSubmitted.filterByKey('isApprovedReady', true)
			.filterByKey('isApproved', false)
	}, delay(function (businessProcess) {
		debug('%s approved', businessProcess.__id__);
		businessProcess.isApproved = true;
	}));
	setupTriggers({
		trigger: businessProcesses.filterByKey('isClosed', true)
	}, function (businessProcess) {
		if (!businessProcess.certificates.dataSnapshot.jsonString) {
			debug('%s generate certificates data snapshots', businessProcess.__id__);
		}
		businessProcess.certificates.dataSnapshot.generate();
		businessProcess.requirementUploads.dataSnapshot.finalize();
		businessProcess.paymentReceiptUploads.dataSnapshot.finalize();
	});

	// Processing steps:
	var nonFinalStatuses = new Set(['pending', 'paused']);
	stepPaths.forEach(function (stepPath, index) {
		// status
		setupTriggers({
			trigger: businessProcessesSubmitted.filterByKeyPath(stepPath + '/status', function (value) {
				return value && !nonFinalStatuses.has(value);
			})
		}, delay(function (businessProcess) {
			var step = businessProcess.getBySKeyPath(stepPath), targetStep;
			if (step.hasOwnProperty('status')) return; // Already shadowed
			debug('%s %s step %s', businessProcess.__id__, step.shortPath, step.status);
			if (onStepStatus) onStepStatus(step);
			if (!step.hasOwnProperty('isReady')) step.isReady = true;
			if (step.revisionStatus && !nonFinalStatuses.has(step.revisionStatus)) {
				step.set('revisionStatus', step.revisionStatus);
			}
			step.set('status', step.status);

			if (step.status === 'sentBack') {
				if (businessProcess.isSentBack) return;

				// Sent back initialization
				debug('%s sent back by %s step', businessProcess.__id__, step.shortPath);
				businessProcess.submissionForms.delete('isAffidavitSigned');
				businessProcess.isSentBack = true;

			} else if (step.status === 'redelegated') {

				// Redelegation initialization
				targetStep = step.redelegatedTo;
				debug('%s redelegated to %s from %s', businessProcess.__id__,
					targetStep.shortPath, step.shortPath);
				if (onStepRedelegate) onStepRedelegate(step);
				if (targetStep.hasOwnProperty('revisionOfficialStatus')) {
					targetStep.delete('revisionOfficialStatus');
				}
				targetStep.delete('officialStatus');
				if (targetStep.hasOwnProperty('revisionStatus')) targetStep.delete('revisionStatus');
				targetStep.delete('status');
				if (targetStep.hasOwnProperty('isSatisfied')) targetStep.delete('isSatisfied');
			} else if (step.status === 'rejected') {

				// Business process rejection
				debug('%s rejected at %s', businessProcess.__id__, step.shortPath);
				businessProcess.isRejected = true;
			}
		}));

		// isSatisfied
		setupTriggers({
			trigger: businessProcessesSubmitted.filterByKeyPath(stepPath + '/isSatisfiedReady', true)
				.filterByKeyPath(stepPath + '/isSatisfied', false)
		}, delay(function (businessProcess) {
			var step = businessProcess.getBySKeyPath(stepPath);
			debug('%s %s step satisfied', businessProcess.__id__, step.shortPath);
			step.isSatisfied = true;
		}));

		// Valid returns
		var returnStatuses = new Set(['sentBack', 'redelegated']);
		setupTriggers({
			preTrigger: businessProcessesSubmitted
				.filterByKeyPath(stepPath + '/isPreviousStepsSatisfiedDeep', false),
			trigger: businessProcessesSubmitted
				.filterByKeyPath(stepPath + '/isPreviousStepsSatisfiedDeep', true)
		}, function (businessProcess) {
			var step = businessProcess.getBySKeyPath(stepPath)
			  , returnHandlerResult;

			if (!step.isApplicable) return;
			if (!step.status || (step.status === 'pending')) return;

			if (customStepReturnHandler) {
				returnHandlerResult = customStepReturnHandler(step);
			}

			if (returnHandlerResult == null) {
				if (step.statusComputed && (step.statusComputed !== 'pending') &&
						!returnStatuses.has(step.status)) {
					return;
				}
			} else if (!returnHandlerResult) {
				// Skip if customStepReturnHandler 'explicitly' decided so
				return;
			}

			debug('%s %s step reset from %s to pending state', businessProcess.__id__,
				step.shortPath, step.status);
			if (step.hasOwnProperty('revisionOfficialStatus')) step.delete('revisionOfficialStatus');
			step.delete('officialStatus');
			if (step.hasOwnProperty('revisionStatus')) step.delete('revisionStatus');
			step.delete('status');
			if (step.hasOwnProperty('isSatisfied')) step.delete('isSatisfied');
		});
	});
};
<|endoftext|>