<commit_before>
function websocket (env, server, entries, treatments) {
"use strict";
// CONSTANTS
var ONE_HOUR = 3600000,
    ONE_MINUTE = 60000,
    FIVE_MINUTES = 300000,
    FORTY_MINUTES = 2400000,
    TWO_DAYS = 172800000;

var dir2Char = {
  'NONE': '⇼',
  'DoubleUp': '⇈',
  'SingleUp': '↑',
  'FortyFiveUp': '↗',
  'Flat': '→',
  'FortyFiveDown': '↘',
  'SingleDown': '↓',
  'DoubleDown': '⇊',
  'NOT COMPUTABLE': '-',
  'RATE OUT OF RANGE': '↮'
};

  var io;
  var watchers = 0;
  var now = new Date().getTime();

  var cgmData = [],
    treatmentData = [],
    mbgData = [],
    patientData = [];

  function start ( ) {
    io = require('socket.io').listen(server);
  }
  // get data from database and setup to update every minute
  function kickstart (fn) {
    //TODO: test server to see how data is stored (timestamps, entry values, etc)
    //TODO: check server settings to configure alerts, entry units, etc
    console.log(now, new Date(now), fn.name);
    fn( );
    return fn;
  }

  function emitData ( ) {
    console.log('running emitData', now, patientData && patientData.length);
    if (patientData.length > 0) {
      io.sockets.emit("now", now);
      io.sockets.emit("sgv", patientData);
    }
  }

  function configure ( ) {
    // reduce logging
    io.set('log level', 0);

    //TODO: make websockets support an option
    io.configure(function () {
        io.set('transports', ['xhr-polling']);
    });
  }

  function listeners ( ) {
    io.sockets.on('connection', function (socket) {
        io.sockets.emit("now", now);
        io.sockets.emit("sgv", patientData);
        io.sockets.emit("clients", ++watchers);
        socket.on('ack', function(alarmType, silenceTime) {
            ackAlarm(alarmType, silenceTime);
            if (alarmType == "urgent_alarm") {
              //also clean normal alarm so we don't get a double alarm as BG comes back into range
              ackAlarm("alarm", silenceTime);
            }
            io.sockets.emit("clear_alarm", true);
            console.log("alarm cleared");
        });
        socket.on('disconnect', function () {
            io.sockets.emit("clients", --watchers);
        });
    });
  }

///////////////////////////////////////////////////
// data handling functions
///////////////////////////////////////////////////

function directionToChar(direction) {
  return dir2Char[direction] || '-';
}

var Alarm = function(_typeName, _threshold) {
    this.typeName = _typeName;
    this.silenceTime = FORTY_MINUTES;
    this.lastAckTime = 0;
    this.threshold = _threshold;
};

// list of alarms with their thresholds
var alarms = {
    "alarm" : new Alarm("Regular", 0.05),
    "urgent_alarm": new Alarm("Urgent", 0.10)
};

function ackAlarm(alarmType, silenceTime) {
    alarms[alarmType].lastAckTime = new Date().getTime();
    alarms[alarmType].silenceTime = silenceTime ? silenceTime : FORTY_MINUTES;
    delete alarms[alarmType].lastEmitTime;
}

//should only be used when auto acking the alarms after going back in range or when an error corrects
//setting the silence time to 1ms so the alarm will be retriggered as soon as the condition changes
//since this wasn't ack'd by a user action
function autoAckAlarms() {
    var sendClear = false;
    for (var alarmType in alarms) {
        if (alarms.hasOwnProperty(alarmType)) {
            var alarm = alarms[alarmType];
            if (alarm.lastEmitTime) {
                console.info("auto acking " + alarmType);
                ackAlarm(alarmType, 1);
                sendClear = true;
            }
        }
    }
    if (sendClear) {
        io.sockets.emit("clear_alarm", true);
        console.info("emitted clear_alarm to all clients");
    }
}

function emitAlarm(alarmType) {
    var alarm = alarms[alarmType];
    if (now > alarm.lastAckTime + alarm.silenceTime) {
        io.sockets.emit(alarmType);
        alarm.lastEmitTime = now;
        console.info("emitted " + alarmType + " to all clients");
    } else {
        console.log(alarm.typeName + " alarm is silenced for " + Math.floor((alarm.silenceTime - (now - alarm.lastAckTime)) / 60000) + " minutes more");
    }
}

function update() {

    console.log('running update');
    now = Date.now();

    cgmData = [];
    treatmentData = [];
    mbgData = [];
    var earliest_data = now - TWO_DAYS;
    var q = { find: {"date": {"$gte": earliest_data}} };
    entries.list(q, function (err, results) {
      results.forEach(function(element, index, array) {
          if (element) {
              if (element.mbg) {
                  var obj = {};
                  obj.y = element.mbg;
                  obj.x = element.date;
                  obj.d = element.dateString;
                  obj.device = element.device;
                  mbgData.push(obj);
              } else if (element.sgv) {
                  var obj = {};
                  obj.y = element.sgv;
                  obj.x = element.date;
                  obj.d = element.dateString;
                  obj.device = element.device;
                  obj.direction = directionToChar(element.direction);
                  cgmData.push(obj);
              }
          }
      });
      var tq = { find: {"created_at": {"$gte": new Date(earliest_data).toISOString()}} };
      treatments.list(tq, function (err, results) {
          treatmentData = results.map(function(treatment) {
              var timestamp = new Date(treatment.timestamp || treatment.created_at);
              treatment.x = timestamp.getTime();
              return treatment;
          });
          // all done, do loadData
          loadData( );
      });
    });

    return update;
}

function loadData() {

    console.log('running loadData');

    var actual = [],
        actualCurrent,
        treatment = [],
        mbg = [],
        errorCode;

    if (cgmData) {
        actual = cgmData.slice();
        actual.sort(function(a, b) {
            return a.x - b.x;
        });

        actualCurrent = actual.length > 0 ? actual[actual.length - 1].y : null;

        // sgv less than or equal to 10 means error code
        // or warm up period code, so ignore
        actual = actual.filter(function (a) {
            return a.y > 10;
        })
    }

    if (treatmentData) {
        treatment = treatmentData.slice();
        treatment.sort(function(a, b) {
            return a.x - b.x;
        });
    }

    if (mbgData) {
        mbg = mbgData.slice();
        mbg.sort(function(a, b) {
            return a.x - b.x;
        });
    }

    if (actualCurrent && actualCurrent < 39) errorCode = actualCurrent;

    var actualLength = actual.length - 1;

    if (actualLength > 1) {
        // predict using AR model
        var predicted = [];
        var lastValidReadingTime = actual[actualLength].x;
        var elapsedMins = (actual[actualLength].x - actual[actualLength - 1].x) / ONE_MINUTE;
        var BG_REF = 140;
        var BG_MIN = 36;
        var BG_MAX = 400;
        var y = Math.log(actual[actualLength].y / BG_REF);
        if (elapsedMins < 5.1) {
            y = [Math.log(actual[actualLength - 1].y / BG_REF), y];
        } else {
            y = [y, y];
        }
        var n = Math.ceil(12 * (1 / 2 + (now - lastValidReadingTime) / ONE_HOUR));
        var AR = [-0.723, 1.716];
        var dt = actual[actualLength].x;
        for (var i = 0; i <= n; i++) {
            y = [y[1], AR[0] * y[0] + AR[1] * y[1]];
            dt = dt + FIVE_MINUTES;
            predicted[i] = {
                x: dt,
                y: Math.max(BG_MIN, Math.min(BG_MAX, Math.round(BG_REF * Math.exp(y[1]))))
            };
        }

        //TODO: need to consider when data being sent has less than the 2 day minimum

        // consolidate and send the data to the client
        var shouldEmit = is_different(actual, predicted, mbg, treatment, errorCode);
        patientData = [actual, predicted, mbg, treatment, errorCode];
        console.log('patientData', patientData.length);
        if (shouldEmit) {
          emitData( );
        }

        var emitAlarmType = null;

        if (env.alarm_types.indexOf("simple") > -1) {
            var lastBG = actual[actualLength].y;

            if (lastBG > env.thresholds.bg_high) {
                emitAlarmType = 'urgent_alarm';
                console.info(lastBG + " > " + env.thresholds.bg_high + " will emmit " + emitAlarmType);
            } else if (lastBG > env.thresholds.bg_target_top) {
                emitAlarmType = 'alarm';
                console.info(lastBG + " > " + env.thresholds.bg_target_top + " will emmit " + emitAlarmType);
            } else if (lastBG < env.thresholds.bg_low) {
                emitAlarmType = 'urgent_alarm';
                console.info(lastBG + " < " + env.thresholds.bg_low + " will emmit " + emitAlarmType);
            } else if (lastBG < env.thresholds.bg_target_bottom) {
                emitAlarmType = 'alarm';
                console.info(lastBG + " < " + env.thresholds.bg_target_bottom + " will emmit " + emitAlarmType);
            }
        }

        if (!emitAlarmType && env.alarm_types.indexOf("predict") > -1) {
            // compute current loss
            var avgLoss = 0;
            var size = Math.min(predicted.length - 1, 6);
            for (var j = 0; j <= size; j++) {
                avgLoss += 1 / size * Math.pow(log10(predicted[j].y / 120), 2);
            }

            if (avgLoss > alarms['urgent_alarm'].threshold) {
                emitAlarmType = 'urgent_alarm';
                console.info(avgLoss + " < " + alarms['urgent_alarm'].threshold + " will emmit " + emitAlarmType);
            } else if (avgLoss > alarms['alarm'].threshold) {
                emitAlarmType = 'alarm';
                console.info(avgLoss + " < " + alarms['alarm'].threshold + " will emmit " + emitAlarmType);
            }
        }

        if (errorCode) {
            emitAlarmType = 'urgent_alarm';
        }

        if (emitAlarmType) {
            emitAlarm(emitAlarmType);
        } else {
            autoAckAlarms();
        }
    }
}
  function is_different (actual, predicted, mbg, treatment, errorCode) {
    if (patientData && patientData.length < 3) {
      return true;
    }
    var old =  {
        actual: patientData[0].slice(-1).pop( )
      , predicted: patientData[1].slice(-1).pop( )
      , mbg: patientData[2].slice(-1).pop( )
      , treatment: patientData[3].slice(-1).pop( )
      , errorCode: patientData.length >= 5 ? patientData[4] : 0
    };
    var last = {
        actual: actual.slice(-1).pop( )
      , predicted: predicted.slice(-1).pop( )
      , mbg: mbg.slice(-1).pop( )
      , treatment: treatment.slice(-1).pop( )
      , errorCode: errorCode
    };

    // textual diff of objects
    if (JSON.stringify(old) == JSON.stringify(last)) {
      return false;
    }
    return true;
  }

  start( );
  configure( );
  listeners( );
  setInterval(kickstart(update), ONE_MINUTE);

  return io;
}

///////////////////////////////////////////////////
// helper functions
///////////////////////////////////////////////////

function log10(val) { return Math.log(val) / Math.LN10; }

module.exports = websocket;
<commit_msg>stop emitting 'now' message to clients; log when data isn't being sent since it's not different<commit_after>
function websocket (env, server, entries, treatments) {
"use strict";
// CONSTANTS
var ONE_HOUR = 3600000,
    ONE_MINUTE = 60000,
    FIVE_MINUTES = 300000,
    FORTY_MINUTES = 2400000,
    TWO_DAYS = 172800000;

var dir2Char = {
  'NONE': '⇼',
  'DoubleUp': '⇈',
  'SingleUp': '↑',
  'FortyFiveUp': '↗',
  'Flat': '→',
  'FortyFiveDown': '↘',
  'SingleDown': '↓',
  'DoubleDown': '⇊',
  'NOT COMPUTABLE': '-',
  'RATE OUT OF RANGE': '↮'
};

  var io;
  var watchers = 0;
  var now = new Date().getTime();

  var cgmData = [],
    treatmentData = [],
    mbgData = [],
    patientData = [];

  function start ( ) {
    io = require('socket.io').listen(server);
  }
  // get data from database and setup to update every minute
  function kickstart (fn) {
    //TODO: test server to see how data is stored (timestamps, entry values, etc)
    //TODO: check server settings to configure alerts, entry units, etc
    console.log(now, new Date(now), fn.name);
    fn( );
    return fn;
  }

  function emitData ( ) {
    console.log('running emitData', now, patientData && patientData.length);
    if (patientData.length > 0) {
      io.sockets.emit("sgv", patientData);
    }
  }

  function configure ( ) {
    // reduce logging
    io.set('log level', 0);

    //TODO: make websockets support an option
    io.configure(function () {
        io.set('transports', ['xhr-polling']);
    });
  }

  function listeners ( ) {
    io.sockets.on('connection', function (socket) {
        io.sockets.emit("sgv", patientData);
        io.sockets.emit("clients", ++watchers);
        socket.on('ack', function(alarmType, silenceTime) {
            ackAlarm(alarmType, silenceTime);
            if (alarmType == "urgent_alarm") {
              //also clean normal alarm so we don't get a double alarm as BG comes back into range
              ackAlarm("alarm", silenceTime);
            }
            io.sockets.emit("clear_alarm", true);
            console.log("alarm cleared");
        });
        socket.on('disconnect', function () {
            io.sockets.emit("clients", --watchers);
        });
    });
  }

///////////////////////////////////////////////////
// data handling functions
///////////////////////////////////////////////////

function directionToChar(direction) {
  return dir2Char[direction] || '-';
}

var Alarm = function(_typeName, _threshold) {
    this.typeName = _typeName;
    this.silenceTime = FORTY_MINUTES;
    this.lastAckTime = 0;
    this.threshold = _threshold;
};

// list of alarms with their thresholds
var alarms = {
    "alarm" : new Alarm("Regular", 0.05),
    "urgent_alarm": new Alarm("Urgent", 0.10)
};

function ackAlarm(alarmType, silenceTime) {
    alarms[alarmType].lastAckTime = new Date().getTime();
    alarms[alarmType].silenceTime = silenceTime ? silenceTime : FORTY_MINUTES;
    delete alarms[alarmType].lastEmitTime;
}

//should only be used when auto acking the alarms after going back in range or when an error corrects
//setting the silence time to 1ms so the alarm will be retriggered as soon as the condition changes
//since this wasn't ack'd by a user action
function autoAckAlarms() {
    var sendClear = false;
    for (var alarmType in alarms) {
        if (alarms.hasOwnProperty(alarmType)) {
            var alarm = alarms[alarmType];
            if (alarm.lastEmitTime) {
                console.info("auto acking " + alarmType);
                ackAlarm(alarmType, 1);
                sendClear = true;
            }
        }
    }
    if (sendClear) {
        io.sockets.emit("clear_alarm", true);
        console.info("emitted clear_alarm to all clients");
    }
}

function emitAlarm(alarmType) {
    var alarm = alarms[alarmType];
    if (now > alarm.lastAckTime + alarm.silenceTime) {
        io.sockets.emit(alarmType);
        alarm.lastEmitTime = now;
        console.info("emitted " + alarmType + " to all clients");
    } else {
        console.log(alarm.typeName + " alarm is silenced for " + Math.floor((alarm.silenceTime - (now - alarm.lastAckTime)) / 60000) + " minutes more");
    }
}

function update() {

    console.log('running update');
    now = Date.now();

    cgmData = [];
    treatmentData = [];
    mbgData = [];
    var earliest_data = now - TWO_DAYS;
    var q = { find: {"date": {"$gte": earliest_data}} };
    entries.list(q, function (err, results) {
      results.forEach(function(element, index, array) {
          if (element) {
              if (element.mbg) {
                  var obj = {};
                  obj.y = element.mbg;
                  obj.x = element.date;
                  obj.d = element.dateString;
                  obj.device = element.device;
                  mbgData.push(obj);
              } else if (element.sgv) {
                  var obj = {};
                  obj.y = element.sgv;
                  obj.x = element.date;
                  obj.d = element.dateString;
                  obj.device = element.device;
                  obj.direction = directionToChar(element.direction);
                  cgmData.push(obj);
              }
          }
      });
      var tq = { find: {"created_at": {"$gte": new Date(earliest_data).toISOString()}} };
      treatments.list(tq, function (err, results) {
          treatmentData = results.map(function(treatment) {
              var timestamp = new Date(treatment.timestamp || treatment.created_at);
              treatment.x = timestamp.getTime();
              return treatment;
          });
          // all done, do loadData
          loadData( );
      });
    });

    return update;
}

function loadData() {

    console.log('running loadData');

    var actual = [],
        actualCurrent,
        treatment = [],
        mbg = [],
        errorCode;

    if (cgmData) {
        actual = cgmData.slice();
        actual.sort(function(a, b) {
            return a.x - b.x;
        });

        actualCurrent = actual.length > 0 ? actual[actual.length - 1].y : null;

        // sgv less than or equal to 10 means error code
        // or warm up period code, so ignore
        actual = actual.filter(function (a) {
            return a.y > 10;
        })
    }

    if (treatmentData) {
        treatment = treatmentData.slice();
        treatment.sort(function(a, b) {
            return a.x - b.x;
        });
    }

    if (mbgData) {
        mbg = mbgData.slice();
        mbg.sort(function(a, b) {
            return a.x - b.x;
        });
    }

    if (actualCurrent && actualCurrent < 39) errorCode = actualCurrent;

    var actualLength = actual.length - 1;

    if (actualLength > 1) {
        // predict using AR model
        var predicted = [];
        var lastValidReadingTime = actual[actualLength].x;
        var elapsedMins = (actual[actualLength].x - actual[actualLength - 1].x) / ONE_MINUTE;
        var BG_REF = 140;
        var BG_MIN = 36;
        var BG_MAX = 400;
        var y = Math.log(actual[actualLength].y / BG_REF);
        if (elapsedMins < 5.1) {
            y = [Math.log(actual[actualLength - 1].y / BG_REF), y];
        } else {
            y = [y, y];
        }
        var n = Math.ceil(12 * (1 / 2 + (now - lastValidReadingTime) / ONE_HOUR));
        var AR = [-0.723, 1.716];
        var dt = actual[actualLength].x;
        for (var i = 0; i <= n; i++) {
            y = [y[1], AR[0] * y[0] + AR[1] * y[1]];
            dt = dt + FIVE_MINUTES;
            predicted[i] = {
                x: dt,
                y: Math.max(BG_MIN, Math.min(BG_MAX, Math.round(BG_REF * Math.exp(y[1]))))
            };
        }

        //TODO: need to consider when data being sent has less than the 2 day minimum

        // consolidate and send the data to the client
        var shouldEmit = is_different(actual, predicted, mbg, treatment, errorCode);
        patientData = [actual, predicted, mbg, treatment, errorCode];
        console.log('patientData', patientData.length);
        if (shouldEmit) {
          emitData( );
        }

        var emitAlarmType = null;

        if (env.alarm_types.indexOf("simple") > -1) {
            var lastBG = actual[actualLength].y;

            if (lastBG > env.thresholds.bg_high) {
                emitAlarmType = 'urgent_alarm';
                console.info(lastBG + " > " + env.thresholds.bg_high + " will emmit " + emitAlarmType);
            } else if (lastBG > env.thresholds.bg_target_top) {
                emitAlarmType = 'alarm';
                console.info(lastBG + " > " + env.thresholds.bg_target_top + " will emmit " + emitAlarmType);
            } else if (lastBG < env.thresholds.bg_low) {
                emitAlarmType = 'urgent_alarm';
                console.info(lastBG + " < " + env.thresholds.bg_low + " will emmit " + emitAlarmType);
            } else if (lastBG < env.thresholds.bg_target_bottom) {
                emitAlarmType = 'alarm';
                console.info(lastBG + " < " + env.thresholds.bg_target_bottom + " will emmit " + emitAlarmType);
            }
        }

        if (!emitAlarmType && env.alarm_types.indexOf("predict") > -1) {
            // compute current loss
            var avgLoss = 0;
            var size = Math.min(predicted.length - 1, 6);
            for (var j = 0; j <= size; j++) {
                avgLoss += 1 / size * Math.pow(log10(predicted[j].y / 120), 2);
            }

            if (avgLoss > alarms['urgent_alarm'].threshold) {
                emitAlarmType = 'urgent_alarm';
                console.info(avgLoss + " < " + alarms['urgent_alarm'].threshold + " will emmit " + emitAlarmType);
            } else if (avgLoss > alarms['alarm'].threshold) {
                emitAlarmType = 'alarm';
                console.info(avgLoss + " < " + alarms['alarm'].threshold + " will emmit " + emitAlarmType);
            }
        }

        if (errorCode) {
            emitAlarmType = 'urgent_alarm';
        }

        if (emitAlarmType) {
            emitAlarm(emitAlarmType);
        } else {
            autoAckAlarms();
        }
    }
}

  function is_different (actual, predicted, mbg, treatment, errorCode) {
    if (patientData && patientData.length < 3) {
      return true;
    }
    var old =  {
        actual: patientData[0].slice(-1).pop( )
      , predicted: patientData[1].slice(-1).pop( )
      , mbg: patientData[2].slice(-1).pop( )
      , treatment: patientData[3].slice(-1).pop( )
      , errorCode: patientData.length >= 5 ? patientData[4] : 0
    };
    var last = {
        actual: actual.slice(-1).pop( )
      , predicted: predicted.slice(-1).pop( )
      , mbg: mbg.slice(-1).pop( )
      , treatment: treatment.slice(-1).pop( )
      , errorCode: errorCode
    };

    // textual diff of objects
    if (JSON.stringify(old) == JSON.stringify(last)) {
      console.info("data isn't different, will not send to clients");
      return false;
    }
    return true;
  }

  start( );
  configure( );
  listeners( );
  setInterval(kickstart(update), ONE_MINUTE);

  return io;
}

///////////////////////////////////////////////////
// helper functions
///////////////////////////////////////////////////

function log10(val) { return Math.log(val) / Math.LN10; }

module.exports = websocket;
<|endoftext|>


<commit_before>const { exec } = require('child_process');

class ManageElectronProcessPlugin {

  apply(compiler) {
    if (compiler.options.watch) {
      let electron = null;
      compiler.hooks.done.tap(
        'RestartElectronPlugin',
        () => {
          if (electron === null) {
            electron = exec("yarn electron .");
            electron.once('close', () => {
              electron = null;
            });
          } else {
            electron.kill();
            electron = exec("yarn electron .");
          }
        }
      );
    }
  }
}

module.exports = ManageElectronProcessPlugin;
<commit_msg>[DDW-596] Improve electron process webpack plugin<commit_after>const { exec } = require('child_process');

class ManageElectronProcessPlugin {

  apply(compiler) {
    if (compiler.options.watch) {
      let electronMainProcess = null;
      let isMainProcessBeingRestarted = false;
      compiler.hooks.done.tap(
        'RestartElectronPlugin',
        () => {
          if (electronMainProcess === null) {
            electronMainProcess = exec("yarn electron .");
            electronMainProcess.once('close', () => {
              electronMainProcess = null;
              if (isMainProcessBeingRestarted) {
                electronMainProcess = exec("yarn electron .");
                isMainProcessBeingRestarted = false;
              }
            });
          } else if (!isMainProcessBeingRestarted) {
            isMainProcessBeingRestarted = true;
            electronMainProcess.kill();
          }
        }
      );
    }
  }
}

module.exports = ManageElectronProcessPlugin;
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

foam.CLASS({
  package: 'com.google.flow',
  name: 'Clock',
  extends: 'com.google.foam.demos.clock.Clock',
  implements: [ 'foam.physics.Physical' ],
  properties: [
    [ 'gravity', 1 ],
    [ 'radius', 45 ],
    [ 'width',  90 ],
    [ 'height', 90 ]
  ]
});

foam.CLASS({
  package: 'com.google.flow',
  name: 'Text',
  extends: 'foam.graphics.Label',
  implements: [ 'foam.physics.Physical' ],
  properties: [
    [ 'gravity', 1 ],
    [ 'width',  150 ],
    [ 'height', 50 ],
    [ 'text', 'Text' ],
    [ 'color', '#000000' ],
    [ 'font', '50px Arial' ]
  ]
});

foam.CLASS({
  package: 'com.google.flow',
  name: 'Circle',
  extends: 'foam.graphics.Circle',
  implements: [ 'foam.physics.Physical' ],
  properties: [
    [ 'arcWidth', 1 ],
    [ 'gravity', 1 ],
    [ 'radius',  25 ]
  ]
});

foam.CLASS({
  package: 'com.google.flow',
  name: 'Box',
  extends: 'foam.graphics.Box',
  implements: [ 'foam.physics.Physical' ],
  properties: [
    [ 'width',  50 ],
    [ 'height', 50 ]
  ]
});

foam.CLASS({
  package: 'com.google.flow',
  name: 'Desk',
  extends: 'foam.graphics.CView',

  properties: [
    {
      name: 'desk',
      hidden: true,
      factory: function() { return foam.graphics.Box.create({x:0, y:0, width:28, height:14, color:'gray'}); }
    },
    {
      name: 'cabinet',
      hidden: true,
      factory: function() { return foam.graphics.Box.create({x:29, y:0, width:9, height:12, color: 'white'}); }
    },
    {
      name: 'person',
      hidden: true,
      factory: function() { return foam.graphics.Circle.create({x:14, y:21, radius:3, border: null, color:'blue'}); }
    }
  ],

  methods: [
    function init() {
      this.SUPER();
      this.add(this.desk, this.person, this.cabinet);
      this.width  = this.desk.width + this.cabinet.width + 2;
      this.height = this.desk.height * 2.75;
    }
  ]
});

foam.CLASS({
  package: 'com.google.flow',
  name: 'DuplexDesk',
  extends: 'foam.graphics.CView',

  requires: [ 'com.google.flow.Desk' ],

  properties: [
    {
      name: 'desk1',
      hidden: true,
      factory: function() { return this.Desk.create({}); }
    },
    {
      name: 'desk2',
      hidden: true,
      factory: function() { return this.Desk.create({}); }
    },
  ],

  methods: [
    function init() {
      this.SUPER();
      this.desk1.y = this.desk2.y = this.desk1.height;
      this.desk1.scaleY = -1;
      this.width = this.desk1.width;
      this.height = this.desk1.height * 2;
      this.add(this.desk1, this.desk2);
    }
  ]
});

foam.CLASS({
  package: 'com.google.flow',
  name: 'Desks',
  extends: 'foam.graphics.Box',

  properties: [
    {
      class: 'Class',
      name: 'of',
      value: 'com.google.flow.DuplexDesk'
//      hidden: true
    },
    {
      class: 'Boolean',
      name: 'feedback_',
      hidden: true
    },
    [ 'border', null ],
    { name: 'cellWidth',  hidden: true },
    { name: 'cellHeight', hidden: true },
    { class: 'Int', name: 'rows',    postSet: function(o, n) { if ( this.feedback_ ) return o; this.feedback_ = true; this.height  = this.cellHeight * n; this.feedback_ = false; return n;  } },
    { class: 'Int', name: 'columns', postSet: function(o, n) { if ( this.feedback_ ) return o; this.feedback_ = true; this.width   = this.cellWidth * n; this.feedback_ = false; return n;  } },
    { name: 'width',   postSet: function(o, n) { if ( this.feedback_ ) return o; this.feedback_ = true; this.columns = Math.floor(n/this.cellWidth); this.feedback_ = false; return n;  } },
    { name: 'height',  postSet: function(o, n) { if ( this.feedback_ ) return o; this.feedback_ = true; this.rows    = Math.floor(n/this.cellHeight); this.feedback_ = false; return n;  } }
  ],

  methods: [
    function init() {
      this.SUPER();

      this.updateCellSize();
      this.rows = this.columns = 2;

      this.onResize();
      this.propertyChange.sub('of',     this.onResize);
      this.propertyChange.sub('width',  this.onResize);
      this.propertyChange.sub('height', this.onResize);
    },

    function updateCellSize() {
      var o = this.of$cls.create();
      this.cellWidth  = o.width;
      this.cellHeight = o.height;
    }
  ],

  listeners: [
    {
      name: 'onResize',
      isFramed: true,
      code: function() {
        this.children.forEach(function(c) {
          if ( ! com.google.flow.Halo.isInstance(c) ) this.remove(c);
        }.bind(this));

        this.updateCellSize();
        this.width  = this.width;
        this.height = this.height;
        var w = this.cellWidth, h = this.cellHeight;

        for ( var i = 0 ; i < this.rows ; i++ ) {
          for ( var j = 0 ; j < this.columns ; j++ ) {
            var o = this.of$cls.create(null, this.__subContext__);
            o.x = w  * j;
            o.y = h * i;
            this.add(o);
          }
        }
      }
    }
  ]
});

foam.CLASS({
  package: 'com.google.flow',
  name: 'Mushroom',
  extends: 'foam.graphics.Circle',

  implements: [ 'foam.physics.Physical' ],

  requires: [ 'foam.graphics.Box' ],

  properties: [
    [ 'mass', foam.physics.Physical.INFINITE_MASS ],
    [ 'border', null ],
    [ 'color', 'red' ],
    [ 'start',  Math.PI ],
    [ 'radius', 20 ],
    [ 'width', 42 ],
    [ 'height', 45 ],
    { name: 'stem', hidden: true/*, view: 'foam.u2.DetailView'*/ }
  ],

  methods: [
    function init() {
      this.SUPER();

      this.gravity = 0;

      this.add(this.stem = this.Box.create({
        x: -7.5,
        y: -0.5,
        width: 15,
        height: 20,
        color: 'gray',
        border: null
      }));
    }
  ],

  actions: [
    function explode() {
      this.stem.color = 'red';
      // Movement.animate(200, function() {
      //   this.scaleX = this.scaleY = 30;
      //   this.alpha = 0;
      //   this.a = Math.PI * 1.5;
      //   this.stem.alpha = 0;
      // }.bind(this)/*, function() { this.table.removeChild(o2); }.bind(this)*/)();
    }
  ]
});

foam.CLASS({
  package: 'com.google.flow',
  name: 'Cursor',
  extends: 'foam.graphics.CView',

  properties: [
    {
      class: 'Float',
      name: 'lineWidth',
      view: { class: 'foam.u2.RangeView', minValue: 0, maxValue: 5, step: 1, onKey: true },
      value: 1
    },
    { name: 'width', value: 0, hidden: true },
    { name: 'height', value: 0, hidden: true },
    [ 'color', 'red' ],
    [ 'alpha', 0.5 ],
    {
      name: 'x'
    },
    {
      name: 'y'
    }
  ],

  methods: [
    function initCView() {
      this.SUPER();
      this.canvas.on('mousemove', this.onMouseMove);
    },

    function hitTest(p) { return false; },

    function paintSelf(x) {
      if ( ! this.color || ! this.lineWidth ) return;

      x.strokeStyle = this.color;
      x.lineWidth   = this.lineWidth;

      // Draw the lines longer than needed in case the
      // cursor is rotated.
      x.beginPath();
      x.moveTo(-this.parent.width*2, 0);
      x.lineTo(this.parent.width*2, 0);
      x.stroke();

      x.beginPath();
      x.moveTo(0, -this.parent.height*2);
      x.lineTo(0, this.parent.height*2);
      x.stroke();
    },
  ],

  listeners: [
    {
      name: 'onMouseMove',
//      isFramed: true,
      code: function(evt) {
        this.x = evt.offsetX;
        this.y = evt.offsetY;
      }
    }
  ]
});

foam.CLASS({
  package: 'com.google.flow',
  name: 'Gate',
  extends: 'foam.graphics.Box',

  implements: [ 'foam.physics.Physical' ],

  requires: [
    'foam.graphics.Circle',
    'foam.graphics.Label'
  ],

  properties: [
    {
      class: 'Int',
      name: 'count'
    },
    {
      hidden: true,
      name: 'lastCollision_'
    },
    {
      name: 'width',
      value: 2,
      hidden: true,
      preSet: function() { return 1; }
    },
    {
      name: 'height',
      value: 50
    },
    [ 'mass', 0 ],
    [ 'gravity', 0 ],
    {
      name: 'border',
      vale: '#444444',
      hidden: true
    },
    {
      name: 'circle',
      hidden: true,
      factory: function() {
        return this.Circle.create({
          alpha: 0.8,
          border: null,
          color: 'green',
          radius: 10
        });
      }
    },
    {
      name: 'text',
      hidden: true,
      factory: function() {
        return this.Label.create({
          align: 'center',
          y:-7,
          color: 'white',
          text$: this.count$
        });
      }
    },
    {
      name: 'collisionSet_',
      hidden: true
    },
    {
      name: 'lastCollisionSet_',
      hidden: true
    },
  ],

  methods: [
    function init() {
      this.add(this.circle);
      this.circle.add(this.text);
      this.collisionSet_ = {};
      this.lastCollisionSet_ = {};
    },

    function collideWith(c) {
      this.lastCollision_ = Date.now();
      var id = c.$UID;
      if ( ! this.collisionSet_[id] && ! this.lastCollisionSet_[id] ) this.count++;
      this.collisionSet_[id] = true;
    },

    function paint(x) {
      this.lastCollisionSet_ = this.collisionSet_;
      this.collisionSet_ = {};

      if ( Date.now() - this.lastCollision_ > 250 ) {
        this.border = this.BORDER.value;
      } else {
        this.border = 'orange';
      }

      this.originX  = this.width/2;
      this.originY  = this.height/2;
      this.circle.x = this.width/2;
      this.circle.y = this.height/2;
      this.circle.rotation = - this.rotation;
      this.SUPER(x);
    }
  ]
});

// foam.json.stringify(flow.memento.map(function(o) { var v = o.value; var r = {name: o.name, factory: 'function() { return ' + v.cls_.id + '.create(' + foam.json.stringify(v.instance_) + ')}'};  return r;})).replace(/\"/g,"'").replace(/\\/g,'');
<commit_msg>Formatting.<commit_after>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

foam.CLASS({
  package: 'com.google.flow',
  name: 'Clock',
  extends: 'com.google.foam.demos.clock.Clock',
  implements: [ 'foam.physics.Physical' ],
  properties: [
    [ 'gravity', 1 ],
    [ 'radius', 45 ],
    [ 'width',  90 ],
    [ 'height', 90 ]
  ]
});

foam.CLASS({
  package: 'com.google.flow',
  name: 'Text',
  extends: 'foam.graphics.Label',
  implements: [ 'foam.physics.Physical' ],
  properties: [
    [ 'gravity', 1 ],
    [ 'width',  150 ],
    [ 'height', 50 ],
    [ 'text', 'Text' ],
    [ 'color', '#000000' ],
    [ 'font', '50px Arial' ]
  ]
});

foam.CLASS({
  package: 'com.google.flow',
  name: 'Circle',
  extends: 'foam.graphics.Circle',
  implements: [ 'foam.physics.Physical' ],
  properties: [
    [ 'arcWidth', 1 ],
    [ 'gravity', 1 ],
    [ 'radius',  25 ]
  ]
});

foam.CLASS({
  package: 'com.google.flow',
  name: 'Box',
  extends: 'foam.graphics.Box',
  implements: [ 'foam.physics.Physical' ],
  properties: [
    [ 'width',  50 ],
    [ 'height', 50 ]
  ]
});

foam.CLASS({
  package: 'com.google.flow',
  name: 'Desk',
  extends: 'foam.graphics.CView',

  properties: [
    {
      name: 'desk',
      hidden: true,
      factory: function() { return foam.graphics.Box.create({x:0, y:0, width:28, height:14, color:'gray'}); }
    },
    {
      name: 'cabinet',
      hidden: true,
      factory: function() { return foam.graphics.Box.create({x:29, y:0, width:9, height:12, color: 'white'}); }
    },
    {
      name: 'person',
      hidden: true,
      factory: function() { return foam.graphics.Circle.create({x:14, y:21, radius:3, border: null, color:'blue'}); }
    }
  ],

  methods: [
    function init() {
      this.SUPER();
      this.add(this.desk, this.person, this.cabinet);
      this.width  = this.desk.width + this.cabinet.width + 2;
      this.height = this.desk.height * 2.75;
    }
  ]
});

foam.CLASS({
  package: 'com.google.flow',
  name: 'DuplexDesk',
  extends: 'foam.graphics.CView',

  requires: [ 'com.google.flow.Desk' ],

  properties: [
    {
      name: 'desk1',
      hidden: true,
      factory: function() { return this.Desk.create({}); }
    },
    {
      name: 'desk2',
      hidden: true,
      factory: function() { return this.Desk.create({}); }
    },
  ],

  methods: [
    function init() {
      this.SUPER();
      this.desk1.y = this.desk2.y = this.desk1.height;
      this.desk1.scaleY = -1;
      this.width = this.desk1.width;
      this.height = this.desk1.height * 2;
      this.add(this.desk1, this.desk2);
    }
  ]
});

foam.CLASS({
  package: 'com.google.flow',
  name: 'Desks',
  extends: 'foam.graphics.Box',

  properties: [
    {
      class: 'Class',
      name: 'of',
      value: 'com.google.flow.DuplexDesk'
//      hidden: true
    },
    {
      class: 'Boolean',
      name: 'feedback_',
      hidden: true
    },
    [ 'border', null ],
    { name: 'cellWidth',  hidden: true },
    { name: 'cellHeight', hidden: true },
    { class: 'Int', name: 'rows',    postSet: function(o, n) { if ( this.feedback_ ) return o; this.feedback_ = true; this.height  = this.cellHeight * n; this.feedback_ = false; return n;  } },
    { class: 'Int', name: 'columns', postSet: function(o, n) { if ( this.feedback_ ) return o; this.feedback_ = true; this.width   = this.cellWidth * n; this.feedback_ = false; return n;  } },
    { name: 'width',   postSet: function(o, n) { if ( this.feedback_ ) return o; this.feedback_ = true; this.columns = Math.floor(n/this.cellWidth); this.feedback_ = false; return n;  } },
    { name: 'height',  postSet: function(o, n) { if ( this.feedback_ ) return o; this.feedback_ = true; this.rows    = Math.floor(n/this.cellHeight); this.feedback_ = false; return n;  } }
  ],

  methods: [
    function init() {
      this.SUPER();

      this.updateCellSize();
      this.rows = this.columns = 2;

      this.onResize();
      this.propertyChange.sub('of',     this.onResize);
      this.propertyChange.sub('width',  this.onResize);
      this.propertyChange.sub('height', this.onResize);
    },

    function updateCellSize() {
      var o = this.of$cls.create();
      this.cellWidth  = o.width;
      this.cellHeight = o.height;
    }
  ],

  listeners: [
    {
      name: 'onResize',
      isFramed: true,
      code: function() {
        this.children.forEach(function(c) {
          if ( ! com.google.flow.Halo.isInstance(c) ) this.remove(c);
        }.bind(this));

        this.updateCellSize();
        this.width  = this.width;
        this.height = this.height;
        var w = this.cellWidth, h = this.cellHeight;

        for ( var i = 0 ; i < this.rows ; i++ ) {
          for ( var j = 0 ; j < this.columns ; j++ ) {
            var o = this.of$cls.create(null, this.__subContext__);
            o.x = w  * j;
            o.y = h * i;
            this.add(o);
          }
        }
      }
    }
  ]
});

foam.CLASS({
  package: 'com.google.flow',
  name: 'Mushroom',
  extends: 'foam.graphics.Circle',

  implements: [ 'foam.physics.Physical' ],

  requires: [ 'foam.graphics.Box' ],

  properties: [
    [ 'mass', foam.physics.Physical.INFINITE_MASS ],
    [ 'border', null ],
    [ 'color', 'red' ],
    [ 'start',  Math.PI ],
    [ 'radius', 20 ],
    [ 'width', 42 ],
    [ 'height', 45 ],
    { name: 'stem', hidden: true/*, view: 'foam.u2.DetailView'*/ }
  ],

  methods: [
    function init() {
      this.SUPER();

      this.gravity = 0;

      this.add(this.stem = this.Box.create({
        x: -7.5,
        y: -0.5,
        width: 15,
        height: 20,
        color: 'gray',
        border: null
      }));
    }
  ],

  actions: [
    function explode() {
      this.stem.color = 'red';
      // Movement.animate(200, function() {
      //   this.scaleX = this.scaleY = 30;
      //   this.alpha = 0;
      //   this.a = Math.PI * 1.5;
      //   this.stem.alpha = 0;
      // }.bind(this)/*, function() { this.table.removeChild(o2); }.bind(this)*/)();
    }
  ]
});

foam.CLASS({
  package: 'com.google.flow',
  name: 'Cursor',
  extends: 'foam.graphics.CView',

  properties: [
    {
      class: 'Float',
      name: 'lineWidth',
      view: { class: 'foam.u2.RangeView', minValue: 0, maxValue: 5, step: 1, onKey: true },
      value: 1
    },
    { name: 'width',  value: 0, hidden: true },
    { name: 'height', value: 0, hidden: true },
    [ 'color', 'red' ],
    [ 'alpha', 0.5 ],
    {
      name: 'x'
    },
    {
      name: 'y'
    }
  ],

  methods: [
    function initCView() {
      this.SUPER();
      this.canvas.on('mousemove', this.onMouseMove);
    },

    function hitTest(p) { return false; },

    function paintSelf(x) {
      if ( ! this.color || ! this.lineWidth ) return;

      x.strokeStyle = this.color;
      x.lineWidth   = this.lineWidth;

      // Draw the lines longer than needed in case the
      // cursor is rotated.
      x.beginPath();
      x.moveTo(-this.parent.width*2, 0);
      x.lineTo(this.parent.width*2, 0);
      x.stroke();

      x.beginPath();
      x.moveTo(0, -this.parent.height*2);
      x.lineTo(0, this.parent.height*2);
      x.stroke();
    },
  ],

  listeners: [
    {
      name: 'onMouseMove',
//      isFramed: true,
      code: function(evt) {
        this.x = evt.offsetX;
        this.y = evt.offsetY;
      }
    }
  ]
});

foam.CLASS({
  package: 'com.google.flow',
  name: 'Gate',
  extends: 'foam.graphics.Box',

  implements: [ 'foam.physics.Physical' ],

  requires: [
    'foam.graphics.Circle',
    'foam.graphics.Label'
  ],

  properties: [
    {
      class: 'Int',
      name: 'count'
    },
    {
      hidden: true,
      name: 'lastCollision_'
    },
    {
      name: 'width',
      value: 2,
      hidden: true,
      preSet: function() { return 1; }
    },
    {
      name: 'height',
      value: 50
    },
    [ 'mass', 0 ],
    [ 'gravity', 0 ],
    {
      name: 'border',
      vale: '#444444',
      hidden: true
    },
    {
      name: 'circle',
      hidden: true,
      factory: function() {
        return this.Circle.create({
          alpha: 0.8,
          border: null,
          color: 'green',
          radius: 10
        });
      }
    },
    {
      name: 'text',
      hidden: true,
      factory: function() {
        return this.Label.create({
          align: 'center',
          y:-7,
          color: 'white',
          text$: this.count$
        });
      }
    },
    {
      name: 'collisionSet_',
      hidden: true
    },
    {
      name: 'lastCollisionSet_',
      hidden: true
    },
  ],

  methods: [
    function init() {
      this.add(this.circle);
      this.circle.add(this.text);
      this.collisionSet_ = {};
      this.lastCollisionSet_ = {};
    },

    function collideWith(c) {
      this.lastCollision_ = Date.now();
      var id = c.$UID;
      if ( ! this.collisionSet_[id] && ! this.lastCollisionSet_[id] ) this.count++;
      this.collisionSet_[id] = true;
    },

    function paint(x) {
      this.lastCollisionSet_ = this.collisionSet_;
      this.collisionSet_ = {};

      if ( Date.now() - this.lastCollision_ > 250 ) {
        this.border = this.BORDER.value;
      } else {
        this.border = 'orange';
      }

      this.originX  = this.width/2;
      this.originY  = this.height/2;
      this.circle.x = this.width/2;
      this.circle.y = this.height/2;
      this.circle.rotation = - this.rotation;
      this.SUPER(x);
    }
  ]
});

// foam.json.stringify(flow.memento.map(function(o) { var v = o.value; var r = {name: o.name, factory: 'function() { return ' + v.cls_.id + '.create(' + foam.json.stringify(v.instance_) + ')}'};  return r;})).replace(/\"/g,"'").replace(/\\/g,'');
<|endoftext|>


<commit_before>/*jslint devel: true*/
/*global perfis */

// variables
var project, beam, vk, mk, lbForm, section, steel, fyForm, fuForm, EForm;
var ml, d, bf, tw, tf, h, dl, area, ix, wx, rx, zx, iy, wy, ry, zy, rt, it, mesa, alma, cw, u;
var fy, fu, E, aw, gama, gama1, cb, kv, lb, kc, tr, beta1, a;
var lambV, lambpV, lambrV, vpl, vrd;
var mpl, lambA, lambpA, lambrA, mrA, mcrA, mrdA;
var lambM, lambpM, lambrM, mrM, mcrM, mrdM;
var lambT, lambpT, lambrT, mrT, mcrT, mrdT;
var vsd, msd, vrd, mrd, mrdOut, situationV, situationA, situationM, situationT, result;
var ratioCSV, ratioCSM, ratiopCSV, ratiopCSM;

var steelProp = [
    {
        "steelType": "ASTM A36/ MR250",
        "fy": 250,
        "fu": 400,
        "E": 200000
    },
    {
        "steelType": "ASTM A572 G50/ AR345",
        "fy": 345,
        "fu": 450,
        "E": 200000
    }
];

function processFormDS() {
    "use strict";
    var i, j;

    // Getting project values from HTML form inputs

    project = document.formDS.projectDS.value;
    /* if (project === "") {
        alert("Por favor preencha o campo Projeto.");
     console.log("Por favor preencha o campo Projeto.");
        return false;
    } */
    if (project === "") {
        project = "Exemplo 1";
    }

    beam = document.formDS.beamDS.value;
    /* if (beam === "") {
        alert("Por favor preencha o campo Viga.");
        console.log("Por favor preencha o campo Viga.");
        return false;
    } */
    if (beam === "") {
        beam = "V1";
    }

    vk = Number(document.formDS.vDS.value);
    if (document.formDS.vDS.value === "" || isNaN(vk)) {
        alert("Por favor preencha o campo Cortante com números.");
        console.log("Por favor preencha o campo Cortante.");
        return false;
    }

    mk = Number(document.formDS.mDS.value);
    if (document.formDS.mDS.value === "" || isNaN(mk)) {
        alert("Por favor preencha o campo Momento com números.");
        console.log("Por favor preencha o campo Momento.");
        return false;
    }

    lbForm = Number(document.formDS.lbDS.value);
    if (document.formDS.lbDS.value === "" || isNaN(lbForm)) {
        alert("Por favor preencha o campo Distância entre travamentos laterais com números.");
        console.log("Por favor preencha o campo Distância entre travamentos laterais com números.");
        return false;
    }

    steel = steelProp[Number(document.formDS.typeS.value)].steelType;
    gama = Number(document.formDS.gama.value);
    gama1 = Number(document.formDS.gama1.value);
    cb = Number(document.formDS.cb.value);

    for (i = 0; i < perfis.length; i += 1) { //Looping through our available sections
        section = perfis[i].bitola;

        // START OF FUNCTION TO SAVE CHECK EACH SECTION

        // Getting section properties

        ml = perfis[i].ml;
        d = perfis[i].d;
        bf = perfis[i].bf;
        tw = perfis[i].tw;
        tf = perfis[i].tf;
        h = perfis[i].h;
        dl = perfis[i].dl;
        area = perfis[i].area;
        ix = perfis[i].ix;
        wx = perfis[i].wx;
        rx = perfis[i].rx;
        zx = perfis[i].zx;
        iy = perfis[i].iy;
        wy = perfis[i].wy;
        ry = perfis[i].ry;
        zy = perfis[i].zy;
        rt = perfis[i].rt;
        it = perfis[i].it;
        mesa = perfis[i].mesa;
        alma = perfis[i].alma;
        cw = perfis[i].cw;
        u = perfis[i].u;

        // Getting values from steel properties array
        j = Number(document.getElementById("acos").value);

        fyForm = steelProp[j].fy;
        fuForm = steelProp[j].fu;
        EForm = steelProp[j].E;

        // Calculating kv
        if (((a / h) > 3) || ((a / h) > Math.pow(260 / (h / tw), 2)) || (document.getElementById("stiffeningCS").checked === true)) {
            kv = 5;
        } else {
            kv = 5 + 5 / (Math.pow(a / h, 2));
        }

        // Calculating parameters
        aw = (d * tw) / 100;
        lb = lbForm * 100;
        fy = fyForm / 10;
        fu = fuForm / 10;
        E = EForm / 10;
        beta1 = (0.7 * fy * wx) / (E * it);
        kc = 4 / Math.sqrt(h / tw);
        tr = 0.3 * fy;

        // Shear Vrd
        lambV = h / tw;
        lambpV = (1.1 * Math.sqrt(kv * E / fy));
        lambrV = (1.37 * Math.sqrt(kv * E / fy));
        vpl = 0.6 * fy * aw;

        if (lambV <= lambpV) {
            situationV = "Caso 1";
        } else if (lambpV < lambV && lambV <= lambrV) {
            situationV = "Caso 2";
        } else if (lambrV < lambV) {
            situationV = "Caso 3";
        } else {
            situationV = "Error";
        }

        switch (situationV) {
        case "Caso 1":
            vrd = vpl / gama1;
            break;
        case "Caso 2":
            vrd = (lambpV / lambV) * (vpl / gama1);
            break;
        case "Caso 3":
            vrd = 1.24 * Math.pow(lambpV / lambV, 2) * (vpl / gama1);
            break;
        }

        // Bending
        //FLA
        mpl = zx * fy;
        lambA = dl / tw; // lambA = h / tw;
        lambpA = 3.76 * Math.sqrt(E / fy);
        lambrA = 5.7 * Math.sqrt(E / fy);

        if (lambA <= lambpA) {
            situationA = "Caso 1";
        } else if (lambpA < lambA && lambA <= lambrA) {
            situationA = "Caso 2";
        } else if (lambrA < lambA) {
            situationA = "Caso 3";
        } else {
            situationA = "Error";
        }

        switch (situationA) {
        case "Caso 1":
            mrdA = mpl / gama1;
            break;
        case "Caso 2":
            mrA = 0.7 * fy * wx;
            mrdA = (cb / gama1) * (mpl - ((mpl - mrA) * ((lambA - lambpA) / (lambrA - lambpA))));
            break;
        case "Caso 3":
            // mcrA = Anexo H
            mrdA = mcrA / gama1;
            break;
        }

        //FLM
        lambM = mesa;
        lambpM = 0.38 * Math.sqrt(E / fy);
        lambrM = 0.83 * Math.sqrt(E / (fy - tr));

        if (lambM <= lambpM) {
            situationM = "Caso 1";
        } else if (lambpM < lambM && lambM <= lambrM) {
            situationM = "Caso 2";
        } else if (lambrM < lambM) {
            situationM = "Caso 3";
        } else {
            situationM = "Error";
        }

        switch (situationM) {
        case "Caso 1":
            mrdM = mpl / gama1;
            break;
        case "Caso 2":
            mrM = 0.7 * fy * wx;
            mrdM = (cb / gama1) * (mpl - ((mpl - mrM) * ((lambM - lambpM) / (lambrM - lambpM))));
            break;
        case "Caso 3":
            mcrM = ((0.69 * E) / (lambM * lambM)) * wx;
            mrdM = mcrM / gama1;
            break;
        }

        // FLT
        lambT = lb / ry;
        lambpT = 1.76 * Math.sqrt(E / fy);
        lambrT = ((1.38 * Math.sqrt(iy * it)) / (ry * it * beta1)) * Math.sqrt(1 + Math.sqrt(1 + (27 * cw * beta1 * beta1) / iy));

        if (lambT <= lambpT) {
            situationT = "Caso 1";
        } else if (lambpT < lambT && lambT <= lambrT) {
            situationT = "Caso 2";
        } else if (lambrT < lambT) {
            situationT = "Caso 3";
        } else {
            situationT = "Error";
        }

        switch (situationT) {
        case "Caso 1":
            mrdT = mpl / gama1;
            break;
        case "Caso 2":
            mrT = 0.7 * fy * wx;
            mrdT = (cb / gama1) * (mpl - ((mpl - mrT) * ((lambT - lambpT) / (lambrT - lambpT))));
            break;
        case "Caso 3":
            mcrT = ((cb * Math.PI * Math.PI * E * iy) / Math.pow(lb, 2)) * Math.sqrt((cw / iy) * (1 + 0.039 * (it * lb * lb) / cw));
            mrdT = mcrT / gama1;
            break;
        }

        //Compare & Results
        vsd = vk * gama;
        msd = mk * gama;
        mrd = Math.min(mrdA, mrdM, mrdT);
        mrdOut = mrd / 100;
        ratioCSV = vsd / vrd;
        ratioCSM = msd / mrdOut;
        ratiopCSV = ratioCSV * 100;
        ratiopCSM = ratioCSM * 100;

        if (vsd <= vrd && msd <= mrdOut) {
            result = "OK";
            alert("OK");
        } else {
            result = "Não OK";
            alert("Não OK");
        }

     // END OF FUNCTION TO SAVE CHECK EACH SECTION

    }

/*
    Cria um objeto aco
*/

}

var acoLista = document.getElementById("acos"),
    i;

function criarAco(nomeAco, linhaAco) {
    "use strict";
    var opcao = document.createElement("OPTION"),
        texto = document.createTextNode(nomeAco);
    opcao.value = linhaAco;
    opcao.appendChild(texto);
    return opcao;
}

for (i = 0; i < steelProp.length; i += 1) {
    acoLista.appendChild(criarAco(steelProp[i].steelType, i));
}
<commit_msg>Update scriptDS.js<commit_after>/*jslint devel: true*/
/*global perfis */

// variables
var project, beam, vk, mk, lbForm, section, steel, fyForm, fuForm, EForm;
var ml, d, bf, tw, tf, h, dl, area, ix, wx, rx, zx, iy, wy, ry, zy, rt, it, mesa, alma, cw, u;
var fy, fu, E, aw, gama, gama1, cb, kv, lb, kc, tr, beta1, a;
var lambV, lambpV, lambrV, vpl, vrd;
var mpl, lambA, lambpA, lambrA, mrA, mcrA, mrdA;
var lambM, lambpM, lambrM, mrM, mcrM, mrdM;
var lambT, lambpT, lambrT, mrT, mcrT, mrdT;
var vsd, msd, vrd, mrd, mrdOut, situationV, situationA, situationM, situationT, result;
var ratioCSV, ratioCSM, ratiopCSV, ratiopCSM;

var steelProp = [
    {
        "steelType": "ASTM A36/ MR250",
        "fy": 250,
        "fu": 400,
        "E": 200000
    },
    {
        "steelType": "ASTM A572 G50/ AR345",
        "fy": 345,
        "fu": 450,
        "E": 200000
    }
];

kv = 5; // "Enricejedor" not available Kv = 5

function processFormDS() {
    "use strict";
    var i, j;

    // Getting project values from HTML form inputs

    project = document.formDS.projectDS.value;
    /* if (project === "") {
        alert("Por favor preencha o campo Projeto.");
     console.log("Por favor preencha o campo Projeto.");
        return false;
    } */
    if (project === "") {
        project = "Exemplo 1";
    }

    beam = document.formDS.beamDS.value;
    /* if (beam === "") {
        alert("Por favor preencha o campo Viga.");
        console.log("Por favor preencha o campo Viga.");
        return false;
    } */
    if (beam === "") {
        beam = "V1";
    }

    vk = Number(document.formDS.vDS.value);
    if (document.formDS.vDS.value === "" || isNaN(vk)) {
        alert("Por favor preencha o campo Cortante com números.");
        console.log("Por favor preencha o campo Cortante.");
        return false;
    }

    mk = Number(document.formDS.mDS.value);
    if (document.formDS.mDS.value === "" || isNaN(mk)) {
        alert("Por favor preencha o campo Momento com números.");
        console.log("Por favor preencha o campo Momento.");
        return false;
    }

    lbForm = Number(document.formDS.lbDS.value);
    if (document.formDS.lbDS.value === "" || isNaN(lbForm)) {
        alert("Por favor preencha o campo Distância entre travamentos laterais com números.");
        console.log("Por favor preencha o campo Distância entre travamentos laterais com números.");
        return false;
    }

    steel = steelProp[Number(document.formDS.typeS.value)].steelType;
    gama = Number(document.formDS.gama.value);
    gama1 = Number(document.formDS.gama1.value);
    cb = Number(document.formDS.cb.value);

    for (i = 0; i < perfis.length; i += 1) { //Looping through our available sections
        section = perfis[i].bitola;

        // START OF FUNCTION TO SAVE CHECK EACH SECTION

        // Getting section properties

        ml = perfis[i].ml;
        d = perfis[i].d;
        bf = perfis[i].bf;
        tw = perfis[i].tw;
        tf = perfis[i].tf;
        h = perfis[i].h;
        dl = perfis[i].dl;
        area = perfis[i].area;
        ix = perfis[i].ix;
        wx = perfis[i].wx;
        rx = perfis[i].rx;
        zx = perfis[i].zx;
        iy = perfis[i].iy;
        wy = perfis[i].wy;
        ry = perfis[i].ry;
        zy = perfis[i].zy;
        rt = perfis[i].rt;
        it = perfis[i].it;
        mesa = perfis[i].mesa;
        alma = perfis[i].alma;
        cw = perfis[i].cw;
        u = perfis[i].u;

        // Getting values from steel properties array
        j = Number(document.getElementById("acos").value);

        fyForm = steelProp[j].fy;
        fuForm = steelProp[j].fu;
        EForm = steelProp[j].E;

        // Calculating parameters
        aw = (d * tw) / 100;
        lb = lbForm * 100;
        fy = fyForm / 10;
        fu = fuForm / 10;
        E = EForm / 10;
        beta1 = (0.7 * fy * wx) / (E * it);
        kc = 4 / Math.sqrt(h / tw);
        tr = 0.3 * fy;

        // Shear Vrd
        lambV = h / tw;
        lambpV = (1.1 * Math.sqrt(kv * E / fy));
        lambrV = (1.37 * Math.sqrt(kv * E / fy));
        vpl = 0.6 * fy * aw;

        if (lambV <= lambpV) {
            situationV = "Caso 1";
        } else if (lambpV < lambV && lambV <= lambrV) {
            situationV = "Caso 2";
        } else if (lambrV < lambV) {
            situationV = "Caso 3";
        } else {
            situationV = "Error";
        }

        switch (situationV) {
        case "Caso 1":
            vrd = vpl / gama1;
            break;
        case "Caso 2":
            vrd = (lambpV / lambV) * (vpl / gama1);
            break;
        case "Caso 3":
            vrd = 1.24 * Math.pow(lambpV / lambV, 2) * (vpl / gama1);
            break;
        }

        // Bending
        //FLA
        mpl = zx * fy;
        lambA = dl / tw; // lambA = h / tw;
        lambpA = 3.76 * Math.sqrt(E / fy);
        lambrA = 5.7 * Math.sqrt(E / fy);

        if (lambA <= lambpA) {
            situationA = "Caso 1";
        } else if (lambpA < lambA && lambA <= lambrA) {
            situationA = "Caso 2";
        } else if (lambrA < lambA) {
            situationA = "Caso 3";
        } else {
            situationA = "Error";
        }

        switch (situationA) {
        case "Caso 1":
            mrdA = mpl / gama1;
            break;
        case "Caso 2":
            mrA = 0.7 * fy * wx;
            mrdA = (cb / gama1) * (mpl - ((mpl - mrA) * ((lambA - lambpA) / (lambrA - lambpA))));
            break;
        case "Caso 3":
            // mcrA = Anexo H
            mrdA = mcrA / gama1;
            break;
        }

        //FLM
        lambM = mesa;
        lambpM = 0.38 * Math.sqrt(E / fy);
        lambrM = 0.83 * Math.sqrt(E / (fy - tr));

        if (lambM <= lambpM) {
            situationM = "Caso 1";
        } else if (lambpM < lambM && lambM <= lambrM) {
            situationM = "Caso 2";
        } else if (lambrM < lambM) {
            situationM = "Caso 3";
        } else {
            situationM = "Error";
        }

        switch (situationM) {
        case "Caso 1":
            mrdM = mpl / gama1;
            break;
        case "Caso 2":
            mrM = 0.7 * fy * wx;
            mrdM = (cb / gama1) * (mpl - ((mpl - mrM) * ((lambM - lambpM) / (lambrM - lambpM))));
            break;
        case "Caso 3":
            mcrM = ((0.69 * E) / (lambM * lambM)) * wx;
            mrdM = mcrM / gama1;
            break;
        }

        // FLT
        lambT = lb / ry;
        lambpT = 1.76 * Math.sqrt(E / fy);
        lambrT = ((1.38 * Math.sqrt(iy * it)) / (ry * it * beta1)) * Math.sqrt(1 + Math.sqrt(1 + (27 * cw * beta1 * beta1) / iy));

        if (lambT <= lambpT) {
            situationT = "Caso 1";
        } else if (lambpT < lambT && lambT <= lambrT) {
            situationT = "Caso 2";
        } else if (lambrT < lambT) {
            situationT = "Caso 3";
        } else {
            situationT = "Error";
        }

        switch (situationT) {
        case "Caso 1":
            mrdT = mpl / gama1;
            break;
        case "Caso 2":
            mrT = 0.7 * fy * wx;
            mrdT = (cb / gama1) * (mpl - ((mpl - mrT) * ((lambT - lambpT) / (lambrT - lambpT))));
            break;
        case "Caso 3":
            mcrT = ((cb * Math.PI * Math.PI * E * iy) / Math.pow(lb, 2)) * Math.sqrt((cw / iy) * (1 + 0.039 * (it * lb * lb) / cw));
            mrdT = mcrT / gama1;
            break;
        }

        //Compare & Results
        vsd = vk * gama;
        msd = mk * gama;
        mrd = Math.min(mrdA, mrdM, mrdT);
        mrdOut = mrd / 100;
        ratioCSV = vsd / vrd;
        ratioCSM = msd / mrdOut;
        ratiopCSV = ratioCSV * 100;
        ratiopCSM = ratioCSM * 100;

        if (vsd <= vrd && msd <= mrdOut) {
            result = "OK";
            alert("OK");
        } else {
            result = "Não OK";
            alert("Não OK");
        }

     // END OF FUNCTION TO SAVE CHECK EACH SECTION

    }

/*
    Cria um objeto aco
*/

}

var acoLista = document.getElementById("acos"),
    i;

function criarAco(nomeAco, linhaAco) {
    "use strict";
    var opcao = document.createElement("OPTION"),
        texto = document.createTextNode(nomeAco);
    opcao.value = linhaAco;
    opcao.appendChild(texto);
    return opcao;
}

for (i = 0; i < steelProp.length; i += 1) {
    acoLista.appendChild(criarAco(steelProp[i].steelType, i));
}
<|endoftext|>


<commit_before>"use strict";

var _ = require("underscore");
var util = require("substance-util");
var Document = require("substance-document");

// Lens.Article
// -----------------

var Article = function(options) {
  options = options || {};

  // Check if format is compatible

  // Extend Schema
  // --------

  options.schema = util.deepclone(Document.schema);

  options.schema.id = "lens-article";
  options.schema.version = "0.1.0";

  // Merge in custom types
  _.each(Article.types, function(type, key) {
    options.schema.types[key] = type;
  });

  // Register annotation types
  _.each(Article.annotations, function(aType, key) {
    options.schema.types[key] = aType;
  });

  // Merge in node types
  _.each(Article.nodeTypes, function(node, key) {
    options.schema.types[key] = node.type;
  });

  // Merge in custom indexes
  _.each(Article.indexes, function(index, key) {
    options.schema.indexes[key] = index;
  });

  // Call parent constructor
  // --------

  Document.call(this, options);

  this.nodeTypes = Article.nodeTypes;

  // Seed the doc
  // --------

  if (options.seed === undefined) {
    this.create({
      id: "document",
      type: "document",
      guid: options.id, // external global document id
      creator: options.creator,
      created_at: options.created_at,
      views: ["content"], // is views really needed on the instance level
      title: "",
      abstract: ""
    });

    // Create views on the doc
    _.each(Article.views, function(view) {
      this.create({
        id: view,
        "type": "view",
        nodes: []
      });
    }, this);
  }
};

// Renders an article
// --------
//

Article.Renderer = function(doc) {
  this.doc = doc;
  // var that = this;

  this.nodeTypes = Article.nodeTypes;

  // this.viewFactory = {
  //   createView: function(node) {
  //     var NodeView = Article.nodeTypes[node.type].View;

  //     if (!NodeView) {
  //       throw new Error('Node type "'+node.type+'" not supported');
  //     }

  //     // Note: passing the factory to the node views
  //     // to allow creation of nested views
  //     var nodeView = new NodeView(node, this);

  //     // we connect the listener here to avoid to pass the document itself into the nodeView
  //     nodeView.listenTo(that.doc, "operation:applied", nodeView.onGraphUpdate);

  //     return nodeView;
  //   }
  // };

  // Collect all node views
  this.nodes = {};

  // Build views
  _.each(this.doc.getNodes(), function(node) {
    this.nodes[node.id] = this.createView(node);
  }, this);

};

Article.Renderer.Prototype = function() {

  // Create a node view
  // --------
  //
  // Experimental: using a factory which creates a view for a given node type
  // As we want to be able to reuse views
  // However, as the matter is still under discussion consider the solution here only as provisional.
  // We should create views, not only elements, as we need more, e.g., event listening stuff
  // which needs to be disposed later.

  this.createView = function(node) {
    var NodeView = this.nodeTypes[node.type].View;

    if (!NodeView) {
      throw new Error('Node type "'+node.type+'" not supported');
    }

    // Note: passing the factory to the node views
    // to allow creation of nested views
    var nodeView = new NodeView(node, this);

    // we connect the listener here to avoid to pass the document itself into the nodeView
    nodeView.listenTo(this.doc, "operation:applied", nodeView.onGraphUpdate);
    return nodeView;
  };

  // Render it
  // --------
  //

  this.render = function() {
    var frag = document.createDocumentFragment();

    var docNodes = this.doc.getNodes();
    _.each(docNodes, function(n) {
      frag.appendChild(this.nodes[n.id].render().el);
    }, this);
    return frag;
  }
}

Article.Renderer.prototype = new Article.Renderer.Prototype();

Article.Prototype = function() {
  this.fromSnapshot = function(data, options) {
    return Article.fromSnapshot(data, options);
  };
};

// Factory method
// --------
//
// TODO: Ensure the snapshot doesn't get chronicled

Article.fromSnapshot = function(data, options) {
  options = options || {};
  options.seed = data;
  return new Article(options);
};

// Define available views
// --------

Article.views = ["content"];

// Register node types
// --------

Article.nodeTypes = require("./nodes");

// Define annotation types
// --------

Article.annotations = {

  "strong": {
    "parent": "annotation",
    "properties": {
    }
  },

  "emphasis": {
    "properties": {
    },
    "parent": "annotation"
  },

  "code": {
    "parent": "annotation",
    "properties": {
    }
  },

  "link": {
    "parent": "annotation",
    "properties": {
      "url": "string"
    }
  },

  "idea": {
    "parent": "annotation",
    "properties": {
    }
  },

  "error": {
    "parent": "annotation",
    "properties": {
    }
  },

  "question": {
    "parent": "annotation",
    "properties": {
    }
  },

  // Greenish figure references in the text

  "figure_reference": {
    "parent": "annotation",
    "properties": {
      "target": "figure"
    }
  },

  // Blueish citation references in the text

  "citation_reference": {
    "parent": "annotation",
    "properties": {
      "target": "content"
    }
  },

  "cross_reference": {
    "parent": "annotation",
    "properties": {
      "target": "content"
    }
  }

};

// Custom type definitions
// --------
//
// Holds comments

Article.types = {

  // Abstarct Annotation Node
  // --------

  "annotation": {
    "properties": {
      "path": ["array", "string"], // -> e.g. ["text_1", "content"]
      "range": "object"
    }
  },

  // Abstract Figure Type
  // --------

  "figure": {
    "properties": {
    }
  },

  // Abstract Citation Type
  // --------

  "citation": {
    "properties": {
    }
  },

  // Document
  // --------

  "document": {
    "properties": {
      "views": ["array", "view"],
      "guid": "string",
      "creator": "string",
      "title": "string",
      "abstract": "string"
    }
  },

  // Comments
  // --------

  "comment": {
    "properties": {
      "content": "string",
      "created_at": "string", // should be date
      "creator": "string", // should be date
      "node": "node" // references either a content node or annotation
    }
  }
};

// Custom indexes
// --------
//

Article.indexes = {
  // All annotations are now indexed by node
  // "annotations": {
  //   "type": "annotation",
  //   "properties": ["node"]
  // },
  // all comments are now indexed by node association
  "comments": {
    "type": "comment",
    "properties": ["node"]
  }
};

Article.Prototype.prototype = Document.prototype;
Article.prototype = new Article.Prototype();
Article.prototype.constructor = Article;

// Add convenience accessors for builtin document attributes
Object.defineProperties(Document.prototype, {
  id: {
    get: function () {
      return this.get("document").guid;
    },
    set: function() {
      throw "doc.id is immutable";
    }
  },
  creator: {
    get: function () {
      return this.get("document").creator;
    }
  },
  created_at: {
    get: function () {
      return this.get("document").created_at;
    }
  },
  title: {
    get: function () {
      return this.get("document").title;
    }
  },
  abstract: {
    get: function () {
      return this.get("document").abstract;
    }
  },
  views: {
    get: function () {
      // Note: returing a copy to avoid inadvertent changes
      return this.get("document").views.slice(0);
    }
  },
});

module.exports = Article;
<commit_msg>Adjust indexes. We don't need them at the moment.<commit_after>"use strict";

var _ = require("underscore");
var util = require("substance-util");
var Document = require("substance-document");

// Lens.Article
// -----------------

var Article = function(options) {
  options = options || {};

  // Check if format is compatible

  // Extend Schema
  // --------

  options.schema = util.deepclone(Document.schema);

  options.schema.id = "lens-article";
  options.schema.version = "0.1.0";

  // Merge in custom types
  _.each(Article.types, function(type, key) {
    options.schema.types[key] = type;
  });

  // Register annotation types
  _.each(Article.annotations, function(aType, key) {
    options.schema.types[key] = aType;
  });

  // Merge in node types
  _.each(Article.nodeTypes, function(node, key) {
    options.schema.types[key] = node.type;
  });

  // Merge in custom indexes
  _.each(Article.indexes, function(index, key) {
    options.schema.indexes[key] = index;
  });

  // Call parent constructor
  // --------

  Document.call(this, options);

  this.nodeTypes = Article.nodeTypes;

  // Seed the doc
  // --------

  if (options.seed === undefined) {
    this.create({
      id: "document",
      type: "document",
      guid: options.id, // external global document id
      creator: options.creator,
      created_at: options.created_at,
      views: ["content"], // is views really needed on the instance level
      title: "",
      abstract: ""
    });

    // Create views on the doc
    _.each(Article.views, function(view) {
      this.create({
        id: view,
        "type": "view",
        nodes: []
      });
    }, this);
  }
};

// Renders an article
// --------
//

Article.Renderer = function(doc) {
  this.doc = doc;
  // var that = this;

  this.nodeTypes = Article.nodeTypes;

  // this.viewFactory = {
  //   createView: function(node) {
  //     var NodeView = Article.nodeTypes[node.type].View;

  //     if (!NodeView) {
  //       throw new Error('Node type "'+node.type+'" not supported');
  //     }

  //     // Note: passing the factory to the node views
  //     // to allow creation of nested views
  //     var nodeView = new NodeView(node, this);

  //     // we connect the listener here to avoid to pass the document itself into the nodeView
  //     nodeView.listenTo(that.doc, "operation:applied", nodeView.onGraphUpdate);

  //     return nodeView;
  //   }
  // };

  // Collect all node views
  this.nodes = {};

  // Build views
  _.each(this.doc.getNodes(), function(node) {
    this.nodes[node.id] = this.createView(node);
  }, this);

};

Article.Renderer.Prototype = function() {

  // Create a node view
  // --------
  //
  // Experimental: using a factory which creates a view for a given node type
  // As we want to be able to reuse views
  // However, as the matter is still under discussion consider the solution here only as provisional.
  // We should create views, not only elements, as we need more, e.g., event listening stuff
  // which needs to be disposed later.

  this.createView = function(node) {
    var NodeView = this.nodeTypes[node.type].View;

    if (!NodeView) {
      throw new Error('Node type "'+node.type+'" not supported');
    }

    // Note: passing the factory to the node views
    // to allow creation of nested views
    var nodeView = new NodeView(node, this);

    // we connect the listener here to avoid to pass the document itself into the nodeView
    nodeView.listenTo(this.doc, "operation:applied", nodeView.onGraphUpdate);
    return nodeView;
  };

  // Render it
  // --------
  //

  this.render = function() {
    var frag = document.createDocumentFragment();

    var docNodes = this.doc.getNodes();
    _.each(docNodes, function(n) {
      frag.appendChild(this.nodes[n.id].render().el);
    }, this);
    return frag;
  }
}

Article.Renderer.prototype = new Article.Renderer.Prototype();

Article.Prototype = function() {
  this.fromSnapshot = function(data, options) {
    return Article.fromSnapshot(data, options);
  };
};

// Factory method
// --------
//
// TODO: Ensure the snapshot doesn't get chronicled

Article.fromSnapshot = function(data, options) {
  options = options || {};
  options.seed = data;
  return new Article(options);
};

// Define available views
// --------

Article.views = ["content"];

// Register node types
// --------

Article.nodeTypes = require("./nodes");

// Define annotation types
// --------

Article.annotations = {

  "strong": {
    "parent": "annotation",
    "properties": {
    }
  },

  "emphasis": {
    "properties": {
    },
    "parent": "annotation"
  },

  "code": {
    "parent": "annotation",
    "properties": {
    }
  },

  "link": {
    "parent": "annotation",
    "properties": {
      "url": "string"
    }
  },

  "idea": {
    "parent": "annotation",
    "properties": {
    }
  },

  "error": {
    "parent": "annotation",
    "properties": {
    }
  },

  "question": {
    "parent": "annotation",
    "properties": {
    }
  },

  // Greenish figure references in the text

  "figure_reference": {
    "parent": "annotation",
    "properties": {
      "target": "figure"
    }
  },

  // Blueish citation references in the text

  "citation_reference": {
    "parent": "annotation",
    "properties": {
      "target": "content"
    }
  },

  "cross_reference": {
    "parent": "annotation",
    "properties": {
      "target": "content"
    }
  }

};

// Custom type definitions
// --------
//
// Holds comments

Article.types = {

  // Abstarct Annotation Node
  // --------

  "annotation": {
    "properties": {
      "path": ["array", "string"], // -> e.g. ["text_1", "content"]
      "range": "object"
    }
  },

  // Abstract Figure Type
  // --------

  "figure": {
    "properties": {
    }
  },

  // Abstract Citation Type
  // --------

  "citation": {
    "properties": {
    }
  },

  // Document
  // --------

  "document": {
    "properties": {
      "views": ["array", "view"],
      "guid": "string",
      "creator": "string",
      "title": "string",
      "abstract": "string"
    }
  },

  // Comments
  // --------

  "comment": {
    "properties": {
      "content": "string",
      "created_at": "string", // should be date
      "creator": "string", // should be date
      "node": "node" // references either a content node or annotation
    }
  }
};

// Custom indexes
// --------
//

Article.indexes = {
  // All annotations are now indexed by node
  "annotations": {
    "type": "annotation",
    "properties": ["node"]
  },

  // "figure_references": {
  //   "type": "figure_reference"
  // },

  // "citation_references": {
  //   "type": "citation_reference"
  // }
};

Article.Prototype.prototype = Document.prototype;
Article.prototype = new Article.Prototype();
Article.prototype.constructor = Article;

// Add convenience accessors for builtin document attributes
Object.defineProperties(Document.prototype, {
  id: {
    get: function () {
      return this.get("document").guid;
    },
    set: function() {
      throw "doc.id is immutable";
    }
  },
  creator: {
    get: function () {
      return this.get("document").creator;
    }
  },
  created_at: {
    get: function () {
      return this.get("document").created_at;
    }
  },
  title: {
    get: function () {
      return this.get("document").title;
    }
  },
  abstract: {
    get: function () {
      return this.get("document").abstract;
    }
  },
  views: {
    get: function () {
      // Note: returing a copy to avoid inadvertent changes
      return this.get("document").views.slice(0);
    }
  },
});

module.exports = Article;
<|endoftext|>


<commit_before>export { InputsOutputs };

//import * as FloatValue from "../../Unpacker/FloatValue.js";
import * as ActivationEscaping from "../ActivationEscaping.js";

/**
 * Element value bounds (per channel) for inputs and outputs of an operation.
 *
 * The main purpose is to find out the activationEscaping_ScaleArraySet so that it can be used to let channel escape from
 * activation function's non-linear effect.
 *
 *
 * @member {number} inputTensorCount
 *   How many input tensors. It is 1, if only input0 exists. It is 2, if both input0 and input1 exist.
 *
 * @member {ActivationEscaping.ScaleBoundsArray} input0
 *   The element value bounds (per channel) of 1st input (can NOT null). It is the domain of the operation. It (from constructor)
 * will be kept (not cloned) directly. So caller should not modify them.
 *
 * @member {ActivationEscaping.ScaleBoundsArray} input1
 *   The element value bounds (per channel) of 2nd input (can null or undefined). It is the domain of the operation. It (from
 * constructor) will be kept (not cloned) directly. So caller should not modify them.
 *
 * @member {number} inputChannelCount0
 *   The channel count of 1st input (i.e. this.input0.channelCount).
 *
 * @member {number} inputChannelCount1
 *   The channel count of 2nd input (i.e. this.input1.channelCount).
 *
 * @member {number} outputTensorCount
 *   How many output tensors. It is 1, if only output0 exists. It is 2, if both output0 and output1 exist.
 *
 * @member {ActivationEscaping.ScaleBoundsArray} output0
 *   The element value bounds (per channel) of 1st output. It is the range of the operation). It is created by constructor
 * according to outputChannelCount0 (must be positive).
 *
 * @member {ActivationEscaping.ScaleBoundsArray} output1
 *   The element value bounds (per channel) of 2nd output. It is the range of the operation). It is created by constructor
 * according to outputChannelCount1 (if positive).
 *
 * @member {number} outputChannelCount0
 *   The channel count of 1st output (i.e. this.output0.channelCount).
 *
 * @member {number} inputChannelCount1
 *   The channel count of 2nd output (i.e. this.output1.channelCount).
 *
 * @member {ActivationEscaping.ScaleArraySet} activationEscaping_ScaleArraySet
 *   The scales for moving this.afterBias bounds into the linear domain of the activation function. That is, for
 * letting this.afterBias escape from activation function's non-linear domain. And the .undo for undoing the scales.
 * Only output0 has this information.
 */
class InputsOutputs {

  /**
   *
   * @param {number} outputChannelCount0
   *   The channel count of 1st output. (MUST positive)
   *
   * @param {number} outputChannelCount1
   *   The channel count of 2nd output. (If undefined or null or zero or negative, there will be no output1.)
   */
  constructor( input0, input1, outputChannelCount0, outputChannelCount1 ) {

    tf.util.assert( ( input0 instanceof ActivationEscaping.ScaleBoundsArray ),
      `BoundsArraySet.InputsOutputs.constructor(): `
        + `input0 ( ${input0} ) must exist and be an instance of class ActivationEscaping.ScaleBoundsArray.`
    );

    this.input0 = input0;

    if ( input1 )
      this.input1 = input1;

    // Determine outputs.
    if ( outputChannelCount0 > 0 ) {
      this.output0 = new ActivationEscaping.ScaleBoundsArray( outputChannelCount0 );

      if ( outputChannelCount1 > 0 ) { // Two outputs.
        this.output1 = new ActivationEscaping.ScaleBoundsArray( outputChannelCount1 );

      // ( outputChannelCount1 <= 0 ), One output.
      }

    } else { // ( outputChannelCount0 <= 0 ), Illegal.

      tf.util.assert( ( ( outputChannelCount0 <= 0 ) && ( outputChannelCount1 <= 0 ) ),
        `BoundsArraySet.InputsOutputs.constructor(): `
          + `output0 must exist (i.e. outputChannelCount0 ( ${outputChannelCount0} ) must > 0 ).`
      );
    }
  }

//!!! ...unfinished... (2022/04/13)
//   get length() {
//     return this.boundsArray.length;
//   }
//
//   get channelCount() {
//     return this.length;
//   }
//
//   set length( newLength ) {
//     this.boundsArray.length = newLength;
//     this.activationEscaping_ScaleArraySet.length = newLength;
//   }
//
//   set channelCount( newChannelCount ) {
//     this.length = newChannelCount;
//   }

  /**
   * @return {InputsOutputs}
   *   Return a newly created InputsOutputs which is a copy of this InputsOutputs. The .input0 (, .input1) will just past
   * to new InputsOutputs (i.e. NOT copied). But the .output0 (, .output1) will be copied.
   */
  clone() {
    let result = new InputsOutputs( this.input0, this.input1, this.outputChannelCount0, this.outputChannelCount1 );
    result.set_outputs_all_byBoundsArraySet( this );
    return result;
  }

  /**
   * Set all outputs .activationEscaping_ScaleArraySet to scale 1 (i.e. all are no scale).
   *
   * @return {InputsOutputs}
   *   Return this (modified) object.
   */
  set_outputs_all_activationEscaping_all_none() {
    this.output0.set_activationEscaping_all_none();
    this.output1?.set_activationEscaping_all_none();
    return this;
  }

  /**
   * @param {FloatValue.Bounds} aBounds
   *   Set all .output0 (and output1) to the same as the specified aBounds. Set their this.activationEscaping_ScaleArraySet
   * to default ( 1 ). The .input0 (and .input1) are not modified.
   *
   * @return {InputsOutputs}
   *   Return this (modified) object.
   */
  set_outputs_all_byBounds( aBounds ) {
    this.output0.set_all_byBounds( aBounds );
    this.output1?.set_all_byBounds( aBounds );
    return this;
  }

  /**
   * @param {BoundsArray} outputBoundsArray
   *   The BoundsArray to be copied to .output0 (and .output1). Set their this.activationEscaping_ScaleArraySet
   * to default ( 1 ). The .input0 (and .input1) are not modified.
   *
   * @return {InputsOutputs}
   *   Return this (modified) object.
   */
  set_outputs_all_byBoundsArray( outputBoundsArray ) {
    this.output0.set_all_byBoundsArray( outputBoundsArray );
    this.output1?.set_all_byBoundsArray( outputBoundsArray );
    return this;
  }

  /**
   * @param {ActivationEscaping.ScaleBoundsArray} aScaleBoundsArray
   *   The ScaleBoundsArray to be copied to .output0 (and .output1). The .activationEscaping_ScaleArraySet are also
   * copied. The .input0 (and .input1) are not modified.
   *
   * @return {InputsOutputs}
   *   Return this (modified) object.
   */
  set_outputs_all_byScaleBoundsArray( aScaleBoundsArray ) {
    this.output0.set_all_byScaleBoundsArray( aScaleBoundsArray );
    this.output1?.set_all_byScaleBoundsArray( aScaleBoundsArray );
    return this;
  }

  /**
   * @param {BoundsArraySet.InputsOutputs} aBoundsArraySet
   *   The BoundsArraySet to be copied. Precondition: ( this.output0.channelCount == aBoundsArraySet.output0.channelCount )
   * && ( this.output1.channelCount == aBoundsArraySet.output1.channelCount ).
   *
   * @return {InputsOutputs}
   *   Return this (modified) object which is copied from aBoundsArraySet. The .input0 (, .input1) will just past
   * to new InputsOutputs (i.e. NOT copied). But the .output0 (, .output1) will be copied (including .activationEscaping_ScaleArraySet).
   */
  set_outputs_all_byBoundsArraySet_Outputs( aBoundsArraySet_Outputs ) {
    this.output0.set_all_byScaleBoundsArray( aBoundsArraySet_Outputs.output0 );
    this.output1?.set_all_byScaleBoundsArray( aBoundsArraySet_Outputs.output1 );
    return this;
  }

  /**
   * Set .output0 (and .output1) by .input0 (including .activationEscaping_ScaleArraySet).
   *
   * @return {InputsOutputs}
   *   Return this (modified) object.
   */
  set_outputs_all_by_input0() {
    this.output0.set_all_byScaleBoundsArray( this.input0 );
    this.output1?.set_all_byScaleBoundsArray( this.input0 ); // Note: also use this.input0 (not this.input1).
    return this;
  }

  /**
   * Set .output0 (and .output1) by concatenating .input0 and .input1. The length of .output0 (and .output1 if exists) will be modified.
   *
   * @return {InputsOutputs}
   *   Return this (modified) object.
   */
  set_outputs_all_by_concat_input0_input1() {
    this.output0.set_all_byScaleBoundsArray_concat_input0_input1( this.input0, this.input1 );
    this.output1?.set_all_byScaleBoundsArray( this.output0 ); // Note: the same as .output0.
    return this;
  }

  /**
   * Rearrange this.outputs[] channel information by interleaving as ( groupCount == 2 ). This channel count must be even
   * (i.e. divisible by 2).
   *
   * @param {Array} arrayTemp
   *   A temporary array for placing the original elements temporarily. Provide this array could reduce memory re-allocation
   * and improve performance.
   *
   * @return {InputsOutputs}
   *   Return this (modified) object.
   */
  set_outputs_all_byInterleave_asGrouptTwo( arrayTemp ) {
    this.output0.set_all_byInterleave_asGrouptTwo( arrayTemp );
    this.output1?.set_all_byInterleave_asGrouptTwo( arrayTemp );
    return this;
  }

  /**
   * Set .output0 and .output1 by splitting .input0. If .output1 does not exist, it will be created. The length
   * of both .output0 and .output1 will be modified.
   *
   * @return {InputsOutputs}
   *   Return this (modified) object.
   */
  set_outputs_all_byBoundsArray_split_input0() {

    if ( !this.output1 )
      this.output1 = new ActivationEscaping.ScaleBoundsArray( 0 ); // Use ( channelCount == 0 ) temporarily. It will be adjusted later.

    this.input0.split_to_lowerHalf_higherHalf( this.output0, this.output1 );
    return this;
  }

  get inputTensorCount() {
    if ( this.input0 )
      if ( this.input1 )
        return 2;
      else
        return 1;
    else
      if ( this.input1 )
        return 1;
      else
        return 0;
  }

  get inputChannelCount0() { return this.input0.length; }
  get inputChannelCount1() { return this.input1?.length ?? 0; }

  get outputTensorCount() {
    if ( this.output0 )
      if ( this.output1 )
        return 2;
      else
        return 1;
    else
      if ( this.output1 )
        return 1;
      else
        return 0;
  }

  get outputChannelCount0() { return this.output0.length; }
  get outputChannelCount1() { return this.output1?.length ?? 0; }

}

<commit_msg>Update BoundsArraySet_InputsOutputs.js<commit_after>export { InputsOutputs };

import * as ActivationEscaping from "../ActivationEscaping.js";

/**
 * Element value bounds (per channel) for inputs and outputs of an operation.
 *
 * The main purpose is to find out the activationEscaping_ScaleArraySet so that it can be used to let channel escape from
 * activation function's non-linear effect.
 *
 *
 * @member {number} inputTensorCount
 *   How many input tensors. It is 1, if only input0 exists. It is 2, if both input0 and input1 exist.
 *
 * @member {ActivationEscaping.ScaleBoundsArray} input0
 *   The element value bounds (per channel) of 1st input (can NOT null). It is the domain of the operation. It (from constructor)
 * will be kept (not cloned) directly. So caller should not modify them.
 *
 * @member {ActivationEscaping.ScaleBoundsArray} input1
 *   The element value bounds (per channel) of 2nd input (can null or undefined). It is the domain of the operation. It (from
 * constructor) will be kept (not cloned) directly. So caller should not modify them.
 *
 * @member {number} inputChannelCount0
 *   The channel count of 1st input (i.e. this.input0.channelCount).
 *
 * @member {number} inputChannelCount1
 *   The channel count of 2nd input (i.e. this.input1.channelCount).
 *
 * @member {number} outputTensorCount
 *   How many output tensors. It is 1, if only output0 exists. It is 2, if both output0 and output1 exist.
 *
 * @member {ActivationEscaping.ScaleBoundsArray} output0
 *   The element value bounds (per channel) of 1st output. It is the range of the operation). It is created by constructor
 * according to outputChannelCount0 (must be positive).
 *
 * @member {ActivationEscaping.ScaleBoundsArray} output1
 *   The element value bounds (per channel) of 2nd output. It is the range of the operation). It is created by constructor
 * according to outputChannelCount1 (if positive).
 *
 * @member {number} outputChannelCount0
 *   The channel count of 1st output (i.e. this.output0.channelCount).
 *
 * @member {number} outputChannelCount1
 *   The channel count of 2nd output (i.e. this.output1.channelCount).
 */
class InputsOutputs {

  /**
   *
   * @param {number} outputChannelCount0
   *   The channel count of 1st output. (MUST positive)
   *
   * @param {number} outputChannelCount1
   *   The channel count of 2nd output. (If undefined or null or zero or negative, there will be no output1.)
   */
  constructor( input0, input1, outputChannelCount0, outputChannelCount1 ) {

    tf.util.assert( ( input0 instanceof ActivationEscaping.ScaleBoundsArray ),
      `BoundsArraySet.InputsOutputs.constructor(): `
        + `input0 ( ${input0} ) must exist and be an instance of class ActivationEscaping.ScaleBoundsArray.`
    );

    this.input0 = input0;

    if ( input1 )
      this.input1 = input1;

    // Determine outputs.
    if ( outputChannelCount0 > 0 ) {
      this.output0 = new ActivationEscaping.ScaleBoundsArray( outputChannelCount0 );

      if ( outputChannelCount1 > 0 ) { // Two outputs.
        this.output1 = new ActivationEscaping.ScaleBoundsArray( outputChannelCount1 );

      // ( outputChannelCount1 <= 0 ), One output.
      }

    } else { // ( outputChannelCount0 <= 0 ), Illegal.

      tf.util.assert( ( ( outputChannelCount0 <= 0 ) && ( outputChannelCount1 <= 0 ) ),
        `BoundsArraySet.InputsOutputs.constructor(): `
          + `output0 must exist (i.e. outputChannelCount0 ( ${outputChannelCount0} ) must > 0 ).`
      );
    }
  }

  /**
   * @return {InputsOutputs}
   *   Return a newly created InputsOutputs which is a copy of this InputsOutputs. The .input0 (, .input1) will just past
   * to new InputsOutputs (i.e. NOT copied). But the .output0 (, .output1) will be copied.
   */
  clone() {
    let result = new InputsOutputs( this.input0, this.input1, this.outputChannelCount0, this.outputChannelCount1 );
    result.set_outputs_all_byBoundsArraySet( this );
    return result;
  }

  /**
   * Set all outputs .activationEscaping_ScaleArraySet to scale 1 (i.e. all are no scale).
   *
   * @return {InputsOutputs}
   *   Return this (modified) object.
   */
  set_outputs_all_activationEscaping_all_none() {
    this.output0.set_activationEscaping_all_none();
    this.output1?.set_activationEscaping_all_none();
    return this;
  }

  /**
   * @param {FloatValue.Bounds} aBounds
   *   Set all .output0 (and output1) to the same as the specified aBounds. Set their this.activationEscaping_ScaleArraySet
   * to default ( 1 ). The .input0 (and .input1) are not modified.
   *
   * @return {InputsOutputs}
   *   Return this (modified) object.
   */
  set_outputs_all_byBounds( aBounds ) {
    this.output0.set_all_byBounds( aBounds );
    this.output1?.set_all_byBounds( aBounds );
    return this;
  }

  /**
   * @param {BoundsArray} outputBoundsArray
   *   The BoundsArray to be copied to .output0 (and .output1). Set their this.activationEscaping_ScaleArraySet
   * to default ( 1 ). The .input0 (and .input1) are not modified.
   *
   * @return {InputsOutputs}
   *   Return this (modified) object.
   */
  set_outputs_all_byBoundsArray( outputBoundsArray ) {
    this.output0.set_all_byBoundsArray( outputBoundsArray );
    this.output1?.set_all_byBoundsArray( outputBoundsArray );
    return this;
  }

  /**
   * @param {ActivationEscaping.ScaleBoundsArray} aScaleBoundsArray
   *   The ScaleBoundsArray to be copied to .output0 (and .output1). The .activationEscaping_ScaleArraySet are also
   * copied. The .input0 (and .input1) are not modified.
   *
   * @return {InputsOutputs}
   *   Return this (modified) object.
   */
  set_outputs_all_byScaleBoundsArray( aScaleBoundsArray ) {
    this.output0.set_all_byScaleBoundsArray( aScaleBoundsArray );
    this.output1?.set_all_byScaleBoundsArray( aScaleBoundsArray );
    return this;
  }

  /**
   * @param {BoundsArraySet.InputsOutputs} aBoundsArraySet
   *   The BoundsArraySet to be copied. Precondition: ( this.output0.channelCount == aBoundsArraySet.output0.channelCount )
   * && ( this.output1.channelCount == aBoundsArraySet.output1.channelCount ).
   *
   * @return {InputsOutputs}
   *   Return this (modified) object which is copied from aBoundsArraySet. The .input0 (, .input1) will just past
   * to new InputsOutputs (i.e. NOT copied). But the .output0 (, .output1) will be copied (including .activationEscaping_ScaleArraySet).
   */
  set_outputs_all_byBoundsArraySet_Outputs( aBoundsArraySet_Outputs ) {
    this.output0.set_all_byScaleBoundsArray( aBoundsArraySet_Outputs.output0 );
    this.output1?.set_all_byScaleBoundsArray( aBoundsArraySet_Outputs.output1 );
    return this;
  }

  /**
   * Set .output0 (and .output1) by .input0 (including .activationEscaping_ScaleArraySet).
   *
   * @return {InputsOutputs}
   *   Return this (modified) object.
   */
  set_outputs_all_by_input0() {
    this.output0.set_all_byScaleBoundsArray( this.input0 );
    this.output1?.set_all_byScaleBoundsArray( this.input0 ); // Note: also use this.input0 (not this.input1).
    return this;
  }

  /**
   * Set .output0 (and .output1) by concatenating .input0 and .input1. The length of .output0 (and .output1 if exists) will be modified.
   *
   * @return {InputsOutputs}
   *   Return this (modified) object.
   */
  set_outputs_all_by_concat_input0_input1() {
    this.output0.set_all_byScaleBoundsArray_concat_input0_input1( this.input0, this.input1 );
    this.output1?.set_all_byScaleBoundsArray( this.output0 ); // Note: the same as .output0.
    return this;
  }

  /**
   * Rearrange this.outputs[] channel information by interleaving as ( groupCount == 2 ). This channel count must be even
   * (i.e. divisible by 2).
   *
   * @param {Array} arrayTemp
   *   A temporary array for placing the original elements temporarily. Provide this array could reduce memory re-allocation
   * and improve performance.
   *
   * @return {InputsOutputs}
   *   Return this (modified) object.
   */
  set_outputs_all_byInterleave_asGrouptTwo( arrayTemp ) {
    this.output0.set_all_byInterleave_asGrouptTwo( arrayTemp );
    this.output1?.set_all_byInterleave_asGrouptTwo( arrayTemp );
    return this;
  }

  /**
   * Set .output0 and .output1 by splitting .input0. If .output1 does not exist, it will be created. The length
   * of both .output0 and .output1 will be modified.
   *
   * @return {InputsOutputs}
   *   Return this (modified) object.
   */
  set_outputs_all_byBoundsArray_split_input0() {

    if ( !this.output1 )
      this.output1 = new ActivationEscaping.ScaleBoundsArray( 0 ); // Use ( channelCount == 0 ) temporarily. It will be adjusted later.

    this.input0.split_to_lowerHalf_higherHalf( this.output0, this.output1 );
    return this;
  }

  get inputTensorCount() {
    if ( this.input0 )
      if ( this.input1 )
        return 2;
      else
        return 1;
    else
      if ( this.input1 )
        return 1;
      else
        return 0;
  }

  get inputChannelCount0() { return this.input0.length; }
  get inputChannelCount1() { return this.input1?.length ?? 0; }

  get outputTensorCount() {
    if ( this.output0 )
      if ( this.output1 )
        return 2;
      else
        return 1;
    else
      if ( this.output1 )
        return 1;
      else
        return 0;
  }

  get outputChannelCount0() { return this.output0.length; }
  get outputChannelCount1() { return this.output1?.length ?? 0; }

}

<|endoftext|>