<commit_before>var entityHPToolTipIds = [];
//var selectedToolTipIds = {};
var entityAllDataToolTipIds = [];
var hoveredAllDataToolTipIds = {};

function createToolTips(shapeInfo) {
    createHPToolTip(shapeInfo);
    createAllDataToolTip(shapeInfo);
    gameboard_canvas.onmouseleave = function(evt) {
		hideAllTooltips(evt);
	};
}

function hideAllTooltips(evt) {
    for (var sId in hoveredAllDataToolTipIds) {
        if (hoveredAllDataToolTipIds[sId] != "hide") {
            var shapeId = sId;
            shapeId.replace("metadata_all","");
        }
        hoveredAllDataToolTipIds[sId] = "hide";
        $("#" + sId).addClass('tooltip-invisible');
    }
}
// function removeFullShapeIdFromTrackingLists(fullShapeId){
//     removeMemoryOfToolTip(selectedToolTipIds, entityHPToolTipIds, fullShapeId);
//     removeMemoryOfToolTip(hoveredAllDataToolTipIds, entityAllDataToolTipIds, fullShapeId);
//   }

// function removeMemoryOfToolTip(someDict, someArray, someId) {
//     var index = someArray.indexOf(someId);
//     if (index !== -1) {
//       someArray.splice(index, 1);
//       delete someDict[someId];
//     }
// }

function cleanToolTips(){
    if (entityHPToolTipIds != undefined) {
        for (var i in entityHPToolTipIds){
            var id = entityHPToolTipIds[i];
            $("#"+id).remove();
        }
        entityHPToolTipIds = [];
    }
    if (entityAllDataToolTipIds != undefined){
        for (var i in entityAllDataToolTipIds){
            var id = entityAllDataToolTipIds[i];
            $("#"+id).remove();
        }
        entityAllDataToolTipIds = [];
    }
    hoveredAllDataToolTipIds = {};
  }

function createHPToolTip(shapeInfo) {
    var si = shapeInfo;
    if (undefined != si.percentHPRemaining) {
        var canvas_bounds = gameboard_canvas.getBoundingClientRect();
        var hpDiv = document.createElement("div");
        // var setToShow = selectedToolTipIds[si.shapeId];
        // if (setToShow == undefined || setToShow == "hide"){
        //   hpDiv.setAttribute("class","tooltip-invisible");
        // }

        var id = "metadata_hp" + si.shapeId;
        hpDiv.setAttribute("id",id);
         // position it relative to where origin of bounding box of gameboard is
        var y = si.tooltipY + canvas_bounds.top;
        var x = si.tooltipX + canvas_bounds.left;
        var hpWidgetWidth = 20;
        var hpWidgetHeight = 3;
        hpDiv.setAttribute("class", "flex-row");
        hpDiv.setAttribute("style", 'background-color:black;position:absolute;left:' + x + 'px;top:' + y + 'px;color:' + si.colorRGBA + ';height:' + hpWidgetHeight + 'px;width:' + hpWidgetWidth + 'px');
        $("#scaii-gameboard").append(hpDiv);

        hpDiv.onclick = function(e) {
            highlightShapeForIdForClickCollectionFeedback(si.shapeId);
            var targetName = "hitpoints-" + getQuadrantName() + "-" + shapeLogStrings[si.shapeId];
            targetClickHandler(e, "clickHitPoints:" + targetName);
        };

        var hpRemainingDivWidth = hpWidgetWidth * si.percentHPRemaining;
        var hpLostDivWidth = hpWidgetWidth - hpRemainingDivWidth;

        var remainingHpDiv = document.createElement("div");
        remainingHpDiv.setAttribute("style", 'background-color:white;height:' + hpWidgetHeight + 'px;width:' + hpRemainingDivWidth + 'px');
        hpDiv.append(remainingHpDiv);

        entityHPToolTipIds.push(id);
      }
}

function createAllDataToolTip(shapeInfo) {
    var si = shapeInfo;
    var canvas_bounds = gameboard_canvas.getBoundingClientRect();
    var valuesDiv = document.createElement("div");
    var setToShow = hoveredAllDataToolTipIds[si.shapeId];
    if (setToShow == undefined || setToShow == "hide"){
      valuesDiv.setAttribute("class","tooltip-invisible");
    }
    var id = "metadata_all" + si.shapeId;
    //console.log("allData tooltip id:" + id);
    hoveredAllDataToolTipIds[id] = "hide";
    valuesDiv.setAttribute("id",id);
     // position it relative to where origin of bounding box of gameboard is
    var y = si.y + canvas_bounds.top + 20;
    var x = si.x + canvas_bounds.left + -125;
    valuesDiv.setAttribute("style", 'position:absolute;padding:4px;background-color:black;z-index:' + zIndexMap["tooltip"] + ';left:' + x + 'px;top:' + y + 'px;color:white;	display: flex;flex-direction: column;font-family:Arial');
    $("#scaii-gameboard").append(valuesDiv);
    entityAllDataToolTipIds.push(id);

    var tooltipInfo = {};
    gatherMapInfo(tooltipInfo, si.entity.stringmetadataMap, false)
    gatherMapInfo(tooltipInfo, si.entity.boolstringmetadataMap, valuesDiv, false);
    gatherMapInfo(tooltipInfo, si.entity.floatstringmetadataMap, valuesDiv, true);
    gatherMapInfo(tooltipInfo, si.entity.intmetadataMap, valuesDiv, false);
    gatherMapInfo(tooltipInfo, si.entity.boolmetadataMap, valuesDiv,false);
    gatherMapInfo(tooltipInfo, si.entity.floatmetadataMap, valuesDiv, true);
    renderTooltipInfo(tooltipInfo, valuesDiv);
    shapeLogStrings[si.shapeId] = getShapeLogString(tooltipInfo);
}

function getShapeLogString(tooltipInfo) {
    var result = "";
    var friend = tooltipInfo["Friend?"];
    if (friend == "true"){
        result = result + "friendly-";
    }
    else {
        result = result + "enemy-";
    }
    result = result + renameEntityInfoForIUI(tooltipInfo["Unit Type"]);
    return result;
}

function gatherMapInfo(ttInfo, map, limitToTwoDecimals) {
    var entryList = map.getEntryList();
    for (var i in entryList ){
        var entry = entryList[i];
        var key = entry[0];
        var val = entry[1];
        // not sure why true/false were being handled as numbers given the limitToTwoDecimals should have caught it
        if (val != "true"  && val != "false") {
            if (limitToTwoDecimals) {
                val = (Number(val)).toFixed(2);
            }
        }
        ttInfo[key] = val;
    }
}

function renderTooltipInfo(ttInfo, div) {
    var debugKeys = [];
    var nonDebugKeys = [];
    var keys = Object.keys(ttInfo);
    for (var i in keys) {
        var key = keys[i];
        if (key.startsWith('debug_')) {
            debugKeys.push(key);
        }
        else {
            nonDebugKeys.push(key);
        }
    }
    debugKeys.sort();
    nonDebugKeys.sort();
    // pull out friend/vs enemy and unit type to show first
    var friendLabel = getLabelForInfo(collectUnitInfoForConciseMessage(ttInfo, nonDebugKeys));
    div.append(friendLabel);

    // pull out hp values and print first
    var hpLabel = getLabelForInfo(collectHitpointsForConciseMessage(ttInfo, nonDebugKeys));
    div.append(hpLabel);

    // fabricate damageDealt
    var unitType = ttInfo["Unit Type"];
    unitType = renameEntityInfoForIUI(unitType);
    var damageDealtlabel = getLabelForInfo(getDamageDealtStringForUnit(unitType));
    div.append(damageDealtlabel);

    for (var i in nonDebugKeys) {
        var key = nonDebugKeys[i];
        var val = ttInfo[key];
        div.append(createMetadataTooltipEntry(key, val));
    }
    for (var i in debugKeys) {
        var key = debugKeys[i];
        var val = ttInfo[key];
        div.append(createMetadataTooltipEntry(key, val));
    }
}

function getLabelForInfo(s){
    var label = document.createElement("div");
    label.innerHTML = s;
    return label;
}
function getDamageDealtStringForUnit(unitType){
    var result = "Attack Damage: ";
    if (unitType == "Tank"){
        return result + "50 points/sec";
    }
    else if (unitType == "City"){
        return result + "0 points/sec";
    }
    else if (unitType == "Town"){
        return result + "0 points/sec";
    }
    else if (unitType == "Big Fort"){
        return result + "50 points/sec";
    }
    else if (unitType == "Small Fort"){
        return result + "25 points/sec";
    }
    else {
        return result + "unknown";
    }
}

function collectUnitInfoForConciseMessage(ttInfo, nonDebugKeys) {
    var isFriend = ttInfo["Friend?"];
    index = nonDebugKeys.indexOf("Friend?");
    if (index > -1) {
        nonDebugKeys.splice(index, 1);
    }
    index = nonDebugKeys.indexOf("Enemy?");
    if (index > -1) {
        nonDebugKeys.splice(index, 1);
    }

    var unitType = ttInfo["Unit Type"];
    unitType = renameEntityInfoForIUI(unitType);
    index = nonDebugKeys.indexOf("Unit Type");
    if (index > -1) {
        nonDebugKeys.splice(index, 1);
    }

    var friendLabel = document.createElement("div");
    if (isFriend == "true"){
        return "Friendly " + unitType;
    }
    else {
        return "Enemy " + unitType;
    }
}

function collectHitpointsForConciseMessage(ttInfo,nonDebugKeys){
    var hp = ttInfo["Hitpoints"];
    var maxHp = ttInfo["Max Hp"];
    var index = nonDebugKeys.indexOf("Hitpoints");
    if (index > -1) {
        nonDebugKeys.splice(index, 1);
    }
    index = nonDebugKeys.indexOf("Max Hp");
    if (index > -1) {
        nonDebugKeys.splice(index, 1);
    }
    var hpFloored = Math.floor(Number(hp));
    var maxHpFloored = Math.floor(Number(maxHp));
    var hpString = "Health Points: " + hpFloored + " of " + maxHpFloored;
    return hpString;
}
function renameEntityInfoForIUI(s) {
    if (s == "Small Tower"){
        return "Small Fort";
    }
    else if (s == "Big Tower"){
        return "Big Fort";
    }
    if (s == "Small City"){
        return "Town";
    }
    else if (s == "Big City"){
        return "City";
    }
    else if (s == "Ship"){
        return "Tank";
    }
    else {
        return s;
    }
}
function createMetadataTooltipEntry(key, val) {
    var label = document.createElement("div");
    label.innerHTML = key + ':' + val;
    return label;
}<commit_msg>Rephrased tooltips<commit_after>var entityHPToolTipIds = [];
//var selectedToolTipIds = {};
var entityAllDataToolTipIds = [];
var hoveredAllDataToolTipIds = {};

function createToolTips(shapeInfo) {
    createHPToolTip(shapeInfo);
    createAllDataToolTip(shapeInfo);
    gameboard_canvas.onmouseleave = function(evt) {
		hideAllTooltips(evt);
	};
}

function hideAllTooltips(evt) {
    for (var sId in hoveredAllDataToolTipIds) {
        if (hoveredAllDataToolTipIds[sId] != "hide") {
            var shapeId = sId;
            shapeId.replace("metadata_all","");
        }
        hoveredAllDataToolTipIds[sId] = "hide";
        $("#" + sId).addClass('tooltip-invisible');
    }
}
// function removeFullShapeIdFromTrackingLists(fullShapeId){
//     removeMemoryOfToolTip(selectedToolTipIds, entityHPToolTipIds, fullShapeId);
//     removeMemoryOfToolTip(hoveredAllDataToolTipIds, entityAllDataToolTipIds, fullShapeId);
//   }

// function removeMemoryOfToolTip(someDict, someArray, someId) {
//     var index = someArray.indexOf(someId);
//     if (index !== -1) {
//       someArray.splice(index, 1);
//       delete someDict[someId];
//     }
// }

function cleanToolTips(){
    if (entityHPToolTipIds != undefined) {
        for (var i in entityHPToolTipIds){
            var id = entityHPToolTipIds[i];
            $("#"+id).remove();
        }
        entityHPToolTipIds = [];
    }
    if (entityAllDataToolTipIds != undefined){
        for (var i in entityAllDataToolTipIds){
            var id = entityAllDataToolTipIds[i];
            $("#"+id).remove();
        }
        entityAllDataToolTipIds = [];
    }
    hoveredAllDataToolTipIds = {};
  }

function createHPToolTip(shapeInfo) {
    var si = shapeInfo;
    if (undefined != si.percentHPRemaining) {
        var canvas_bounds = gameboard_canvas.getBoundingClientRect();
        var hpDiv = document.createElement("div");
        // var setToShow = selectedToolTipIds[si.shapeId];
        // if (setToShow == undefined || setToShow == "hide"){
        //   hpDiv.setAttribute("class","tooltip-invisible");
        // }

        var id = "metadata_hp" + si.shapeId;
        hpDiv.setAttribute("id",id);
         // position it relative to where origin of bounding box of gameboard is
        var y = si.tooltipY + canvas_bounds.top;
        var x = si.tooltipX + canvas_bounds.left;
        var hpWidgetWidth = 20;
        var hpWidgetHeight = 3;
        hpDiv.setAttribute("class", "flex-row");
        hpDiv.setAttribute("style", 'background-color:black;position:absolute;left:' + x + 'px;top:' + y + 'px;color:' + si.colorRGBA + ';height:' + hpWidgetHeight + 'px;width:' + hpWidgetWidth + 'px');
        $("#scaii-gameboard").append(hpDiv);

        hpDiv.onclick = function(e) {
            highlightShapeForIdForClickCollectionFeedback(si.shapeId);
            var targetName = "hitpoints-" + getQuadrantName() + "-" + shapeLogStrings[si.shapeId];
            targetClickHandler(e, "clickHitPoints:" + targetName);
        };

        var hpRemainingDivWidth = hpWidgetWidth * si.percentHPRemaining;
        var hpLostDivWidth = hpWidgetWidth - hpRemainingDivWidth;

        var remainingHpDiv = document.createElement("div");
        remainingHpDiv.setAttribute("style", 'background-color:white;height:' + hpWidgetHeight + 'px;width:' + hpRemainingDivWidth + 'px');
        hpDiv.append(remainingHpDiv);

        entityHPToolTipIds.push(id);
      }
}

function createAllDataToolTip(shapeInfo) {
    var si = shapeInfo;
    var canvas_bounds = gameboard_canvas.getBoundingClientRect();
    var valuesDiv = document.createElement("div");
    var setToShow = hoveredAllDataToolTipIds[si.shapeId];
    if (setToShow == undefined || setToShow == "hide"){
      valuesDiv.setAttribute("class","tooltip-invisible");
    }
    var id = "metadata_all" + si.shapeId;
    //console.log("allData tooltip id:" + id);
    hoveredAllDataToolTipIds[id] = "hide";
    valuesDiv.setAttribute("id",id);
     // position it relative to where origin of bounding box of gameboard is
    var y = si.y + canvas_bounds.top + 20;
    var x = si.x + canvas_bounds.left + -125;
    valuesDiv.setAttribute("style", 'position:absolute;padding:4px;background-color:black;z-index:' + zIndexMap["tooltip"] + ';left:' + x + 'px;top:' + y + 'px;color:white;	display: flex;flex-direction: column;font-family:Arial');
    $("#scaii-gameboard").append(valuesDiv);
    entityAllDataToolTipIds.push(id);

    var tooltipInfo = {};
    gatherMapInfo(tooltipInfo, si.entity.stringmetadataMap, false)
    gatherMapInfo(tooltipInfo, si.entity.boolstringmetadataMap, valuesDiv, false);
    gatherMapInfo(tooltipInfo, si.entity.floatstringmetadataMap, valuesDiv, true);
    gatherMapInfo(tooltipInfo, si.entity.intmetadataMap, valuesDiv, false);
    gatherMapInfo(tooltipInfo, si.entity.boolmetadataMap, valuesDiv,false);
    gatherMapInfo(tooltipInfo, si.entity.floatmetadataMap, valuesDiv, true);
    renderTooltipInfo(tooltipInfo, valuesDiv);
    shapeLogStrings[si.shapeId] = getShapeLogString(tooltipInfo);
}

function getShapeLogString(tooltipInfo) {
    var result = "";
    var friend = tooltipInfo["Friend?"];
    if (friend == "true"){
        result = result + "friendly-";
    }
    else {
        result = result + "enemy-";
    }
    result = result + renameEntityInfoForIUI(tooltipInfo["Unit Type"]);
    return result;
}

function gatherMapInfo(ttInfo, map, limitToTwoDecimals) {
    var entryList = map.getEntryList();
    for (var i in entryList ){
        var entry = entryList[i];
        var key = entry[0];
        var val = entry[1];
        // not sure why true/false were being handled as numbers given the limitToTwoDecimals should have caught it
        if (val != "true"  && val != "false") {
            if (limitToTwoDecimals) {
                val = (Number(val)).toFixed(2);
            }
        }
        ttInfo[key] = val;
    }
}

function renderTooltipInfo(ttInfo, div) {
    var debugKeys = [];
    var nonDebugKeys = [];
    var keys = Object.keys(ttInfo);
    for (var i in keys) {
        var key = keys[i];
        if (key.startsWith('debug_')) {
            debugKeys.push(key);
        }
        else {
            nonDebugKeys.push(key);
        }
    }
    debugKeys.sort();
    nonDebugKeys.sort();
    // pull out friend/vs enemy and unit type to show first
    var friendLabel = getLabelForInfo(collectUnitInfoForConciseMessage(ttInfo, nonDebugKeys));
    div.append(friendLabel);

    // pull out hp values and print first
    var hpLabel = getLabelForInfo(collectHitpointsForConciseMessage(ttInfo, nonDebugKeys));
    div.append(hpLabel);

    // fabricate damageDealt
    var unitType = ttInfo["Unit Type"];
    unitType = renameEntityInfoForIUI(unitType);
    var damageDealtlabel = getLabelForInfo(getDamageDealtStringForUnit(unitType));
    div.append(damageDealtlabel);

    for (var i in nonDebugKeys) {
        var key = nonDebugKeys[i];
        var val = ttInfo[key];
        div.append(createMetadataTooltipEntry(key, val));
    }
    for (var i in debugKeys) {
        var key = debugKeys[i];
        var val = ttInfo[key];
        div.append(createMetadataTooltipEntry(key, val));
    }
}

function getLabelForInfo(s){
    var label = document.createElement("div");
    label.innerHTML = s;
    return label;
}
function getDamageDealtStringForUnit(unitType){
    var result = "Avg Attack Damage: ";
    if (unitType == "Tank"){
        return result + "1 point/step";
    }
    else if (unitType == "City"){
        return result + "0 points/step";
    }
    else if (unitType == "Town"){
        return result + "0 points/step";
    }
    else if (unitType == "Big Fort"){
        return result + "2 points/step";
    }
    else if (unitType == "Small Fort"){
        return result + "1 point/step";
    }
    else {
        return result + "unknown";
    }
}

function collectUnitInfoForConciseMessage(ttInfo, nonDebugKeys) {
    var isFriend = ttInfo["Friend?"];
    index = nonDebugKeys.indexOf("Friend?");
    if (index > -1) {
        nonDebugKeys.splice(index, 1);
    }
    index = nonDebugKeys.indexOf("Enemy?");
    if (index > -1) {
        nonDebugKeys.splice(index, 1);
    }

    var unitType = ttInfo["Unit Type"];
    unitType = renameEntityInfoForIUI(unitType);
    index = nonDebugKeys.indexOf("Unit Type");
    if (index > -1) {
        nonDebugKeys.splice(index, 1);
    }

    var friendLabel = document.createElement("div");
    if (isFriend == "true"){
        return "Name: Friendly " + unitType;
    }
    else {
        return "Name: Enemy " + unitType;
    }
}

function collectHitpointsForConciseMessage(ttInfo,nonDebugKeys){
    var hp = ttInfo["Hitpoints"];
    var maxHp = ttInfo["Max Hp"];
    var index = nonDebugKeys.indexOf("Hitpoints");
    if (index > -1) {
        nonDebugKeys.splice(index, 1);
    }
    index = nonDebugKeys.indexOf("Max Hp");
    if (index > -1) {
        nonDebugKeys.splice(index, 1);
    }
    var hpFloored = Math.floor(Number(hp));
    var maxHpFloored = Math.floor(Number(maxHp));
    var hpString = "Health Points: " + hpFloored + " of " + maxHpFloored;
    return hpString;
}
function renameEntityInfoForIUI(s) {
    if (s == "Small Tower"){
        return "Small Fort";
    }
    else if (s == "Big Tower"){
        return "Big Fort";
    }
    if (s == "Small City"){
        return "Town";
    }
    else if (s == "Big City"){
        return "City";
    }
    else if (s == "Ship"){
        return "Tank";
    }
    else {
        return s;
    }
}
function createMetadataTooltipEntry(key, val) {
    var label = document.createElement("div");
    label.innerHTML = key + ':' + val;
    return label;
}<|endoftext|>


<commit_before>(function() {
    function SongPlayer() {
         var SongPlayer = {};
         var currentSong = null;
         /**
         * @desc Buzz object audio file
         * @type {Object}
         */
         var currentBuzzObject = null;

         /**
         * @function setSong
         * @desc Stops currently playing song and loads new audio file as currentBuzzObject
         * @param {Object} song
         */

         var setSong = function(song) {
           if (currentBuzzObject) {
             currentBuzzObject.stop();
             currentSong.playing = null;
           }

           currentBuzzObject = new buzz.sound(song.audioUrl, {
             formats: ['mp3'],
             preload: true
           });

           currentSong = song;
         };

         SongPlayer.play = function(song) {
           if (currentSong !== song) {
             setSong(song);
             currentBuzzObject.play();
             song.playing = true;
           } else if (currentSong === song) {
               if (currentBuzzObject.isPaused()) {
                 currentBuzzObject.play();
               }
             }
          };

          SongPlayer.pause = function(song) {
            currentBuzzObject.pause();
            song.playing = false;
            }
        }
      }

    return SongPlayer;
  }

    angular
        .module('blocJams')
        .factory('SongPlayer', SongPlayer);
})();
<commit_msg>SongPlayer.js update<commit_after>(function() {
    function SongPlayer() {
          /**
          * @desc Allows users to play and pause songs
          * @type function
          */
         var SongPlayer = {};
         /**
         * @desc Play or pause songs
         * @type Object
         */
         var currentSong = null;

         /**
         * @desc Buzz object audio file
         * @type {Object}
         */
         var currentBuzzObject = null;

         /**
         * @function setSong
         * @desc Stops currently playing song and loads new audio file as currentBuzzObject
         * @param {Object} song
         */

        var setSong = function(song) {
           if (currentBuzzObject) {
             currentBuzzObject.stop();
             currentSong.playing = null;
           }

           /**
           * @desc Sets a song to the currently playing song
           * @type function
           */

        var playSong = function() {
          currentBuzzObject.play();
          song.playing = true;
        }

           currentBuzzObject = new buzz.sound(song.audioUrl, {
             formats: ['mp3'],
             preload: true
           });

           currentSong = song;
         };

         /**
         * @desc Plays the currenly set song
         * @type function
         */

         SongPlayer.play = function(song) {
           if (currentSong !== song) {
             setSong(song);
             currentBuzzObject.play();
             song.playing = true;
           } else if (currentSong === song) {
               if (currentBuzzObject.isPaused()) {
                 currentBuzzObject.play();
               }
             }
          };

          /**
          * @desc Allows users to play a song via the song player
          * @type function
          */

          SongPlayer.pause = function(song) {
            currentBuzzObject.pause();
            song.playing = false;
            /**
            * @desc Allows users to pause a song via the song player
            * @type function
            */
            }
        }
      }

    return SongPlayer;
  }

    angular
        .module('blocJams')
        .factory('SongPlayer', SongPlayer);
})();
<|endoftext|>


<commit_before>require('dotenv').config({path: __dirname + '/../.env'})

const NEXMO_TO_NUMBER = process.env.NEXMO_TO_NUMBER
const NEXMO_FROM_NUMBER = process.env.NEXMO_FROM_NUMBER

const NEXMO_API_KEY = process.env.NEXMO_API_KEY
const NEXMO_API_SECRET = process.env.NEXMO_API_SECRET
const NEXMO_APPLICATION_ID = process.env.NEXMO_APPLICATION_ID
const NEXMO_APPLICATION_PRIVATE_KEY_PATH = __dirname +"/../"+ process.env.NEXMO_APPLICATION_PRIVATE_KEY_PATH

const Nexmo = require('nexmo')

const nexmo = new Nexmo({
  apiKey: NEXMO_API_KEY,
  apiSecret: NEXMO_API_SECRET,
  applicationId: NEXMO_APPLICATION_ID,
  privateKey: NEXMO_APPLICATION_PRIVATE_KEY_PATH,
}, {
  debug: true
})

nexmo.calls.create({
  to: [{
    type: 'phone',
    number: NEXMO_TO_NUMBER
  }],
  from: {
    type: 'phone',
    number: NEXMO_FROM_NUMBER
  },
  answer_url: ['https://developer.nexmo.com/ncco/tts.json']
})
<commit_msg>Disable debug<commit_after>require('dotenv').config({path: __dirname + '/../.env'})

const NEXMO_TO_NUMBER = process.env.NEXMO_TO_NUMBER
const NEXMO_FROM_NUMBER = process.env.NEXMO_FROM_NUMBER

const NEXMO_API_KEY = process.env.NEXMO_API_KEY
const NEXMO_API_SECRET = process.env.NEXMO_API_SECRET
const NEXMO_APPLICATION_ID = process.env.NEXMO_APPLICATION_ID
const NEXMO_APPLICATION_PRIVATE_KEY_PATH = __dirname +"/../"+ process.env.NEXMO_APPLICATION_PRIVATE_KEY_PATH

const Nexmo = require('nexmo')

const nexmo = new Nexmo({
  apiKey: NEXMO_API_KEY,
  apiSecret: NEXMO_API_SECRET,
  applicationId: NEXMO_APPLICATION_ID,
  privateKey: NEXMO_APPLICATION_PRIVATE_KEY_PATH
})

nexmo.calls.create({
  to: [{
    type: 'phone',
    number: NEXMO_TO_NUMBER
  }],
  from: {
    type: 'phone',
    number: NEXMO_FROM_NUMBER
  },
  answer_url: ['https://developer.nexmo.com/ncco/tts.json']
})
<|endoftext|>


<commit_before>var pg = require('pg');
var config = require('../config.js');
var pgMap = require('../model/pgMap.js');
var debug = require('debug')('OSMBC:logModule');

module.exports.log = function log(object,callback) {
	debug("log");
  pg.connect(config.pgstring, function(err, client, pgdone) {
  	if (err) {
  		pgdone();
  		return (callback(err));
  	}
    object.timestamp = new Date();
  	var query = client.query("insert into changes (data) values ($1) ", [object]);
  	query.on('end',function (result) {
  		pgdone();
  		callback();
  	})
  })
}

module.exports.find = function(obj1,obj2,callback) {
  debug('find');
  pgMap.find(this,obj1,obj2,callback);
}
module.exports.findById = function(id,callback) {
  debug('findById');
  pgMap.findById(id,this,callback);
}

module.exports.create = function() {
  return {};
}

function createTable(cb) {
  debug('createTable');
  createString = 'CREATE TABLE changes (  id bigserial NOT NULL,  data json,  \
                  CONSTRAINT changes_pkey PRIMARY KEY (id) ) WITH (  OIDS=FALSE);'
  createView = '';
  pgMap.createTable('changes',createString,createView,cb)
}

function dropTable(cb) {
  debug('dropTable');
  pgMap.dropTable('changes',cb);
}

module.exports.table = "changes";
module.exports.createTable = createTable;
module.exports.dropTable = dropTable;<commit_msg>Prepare logging for references in importfile.<commit_after>var pg = require('pg');
var async = require('async');
var config = require('../config.js');
var pgMap = require('../model/pgMap.js');
var debug = require('debug')('OSMBC:logModule');
var should = require('should');

var articleModule = require('../model/article.js');
var blogModule = require('../model/blog.js');
var userModule = require('../model/user.js');

module.exports.log = function log(object,callback) {
	debug("log");
  async.series([
    function checkOid(callback) {

      if (typeof(object.oid)!="object") return callback();

      var table = oid.table;
      var reference = oid.r;
      var module;

      switch (table) {
        case "article": module = articleModule;break;
        case "blog": module = blogModule;break;
        case "user": module = userModule;break;
        default: module = null;
      }
      pgMap.find(module,reference,function(err,result) {
        if (err) return callback(err);
        if (result ==null) return callback(new Error("Object Id Not Found in Log Module"));
        object.oid = result.id;
        callback();
      })
    },
    function saveData(callback) {
      pg.connect(config.pgstring, function(err, client, pgdone) {
      	if (err) {
      		pgdone();
      		return (callback(err));
      	}
        object.timestamp = new Date();
      	var query = client.query("insert into changes (data) values ($1) ", [object]);
      	query.on('end',function (result) {
      		pgdone();
      		callback();
      	})
      })
    }],
    function(err) {callback(err)}
  )
}

module.exports.find = function(obj1,obj2,callback) {
  debug('find');
  pgMap.find(this,obj1,obj2,callback);
}
module.exports.findById = function(id,callback) {
  debug('findById');
  pgMap.findById(id,this,callback);
}

module.exports.create = function() {
  return {};
}

function createTable(cb) {
  debug('createTable');
  createString = 'CREATE TABLE changes (  id bigserial NOT NULL,  data json,  \
                  CONSTRAINT changes_pkey PRIMARY KEY (id) ) WITH (  OIDS=FALSE);'
  createView = '';
  pgMap.createTable('changes',createString,createView,cb)
}

function dropTable(cb) {
  debug('dropTable');
  pgMap.dropTable('changes',cb);
}

module.exports.table = "changes";
module.exports.createTable = createTable;
module.exports.dropTable = dropTable;<|endoftext|>


<commit_before>// This file configures the development web server
// which supports hot reloading and synchronized testing.

// Require Browsersync along with webpack and middleware for it
import browserSync from 'browser-sync';
// Required for react-router browserHistory
// see https://github.com/BrowserSync/browser-sync/issues/204#issuecomment-102623643
import historyApiFallback from 'connect-history-api-fallback';
import webpack from 'webpack';
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';
import config from '../webpack.config.dev';

const bundler = webpack(config);

// Run Browsersync and use middleware for Hot Module Replacement
browserSync({
  server: {
    baseDir: 'src',

    middleware: [
      webpackDevMiddleware(bundler, {
        // Dev middleware can't access config, so we provide publicPath
        publicPath: config.output.publicPath,

        // pretty colored output
        stats: { colors: true },

        // Set to false to display a list of each file that is being bundled.
        noInfo: true

        // for other settings see
        // http://webpack.github.io/docs/webpack-dev-middleware.html
      }),

      // bundler should be the same as above
      webpackHotMiddleware(bundler),

      historyApiFallback()
    ]
  },

  // no need to watch '*.js' here, webpack will take care of it for us,
  // including full page reloads if HMR won't work
  files: [
    'src/*.html'
  ]
});<commit_msg>made dev ports explicit<commit_after>// This file configures the development web server
// which supports hot reloading and synchronized testing.

// Require Browsersync along with webpack and middleware for it
import browserSync from 'browser-sync';
// Required for react-router browserHistory
// see https://github.com/BrowserSync/browser-sync/issues/204#issuecomment-102623643
import historyApiFallback from 'connect-history-api-fallback';
import webpack from 'webpack';
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';
import config from '../webpack.config.dev';

const bundler = webpack(config);

// Run Browsersync and use middleware for Hot Module Replacement
browserSync({
  port: 3000,
  ui: {
    port: 3001
  },
  server: {
    baseDir: 'src',

    middleware: [
      webpackDevMiddleware(bundler, {
        // Dev middleware can't access config, so we provide publicPath
        publicPath: config.output.publicPath,

        // pretty colored output
        stats: { colors: true },

        // Set to false to display a list of each file that is being bundled.
        noInfo: true

        // for other settings see
        // http://webpack.github.io/docs/webpack-dev-middleware.html
      }),

      // bundler should be the same as above
      webpackHotMiddleware(bundler),

      historyApiFallback()
    ]
  },

  // no need to watch '*.js' here, webpack will take care of it for us,
  // including full page reloads if HMR won't work
  files: [
    'src/*.html'
  ]
});<|endoftext|>


<commit_before>Question = new Mongo.Collection('question');

Question.attachSchema(
  new SimpleSchema({
    title: {
      type: String
    },
    content: {
      type: String
    },
    tag: {
      type: [String]
    },
    room: {
      type: String,
      regEx: SimpleSchema.RegEx.Id
    },
    createdBy: {
      type: String,
      regEx: SimpleSchema.RegEx.Id,
      autoValue: function() { if(this.isInsert) return Meteor.userId }
    },
    postedAt: {
      type: Date,
      denyUpdate: true,
      autoValue: function() { if(this.isInsert) return new Date() }
    }
  })
);

// Collection2 already does schema checking
// Add custom permission rules if needed
if (Meteor.isServer) {
  Question.allow({
    insert: function() {
      return true;
    },
    update: function() {
      return true;
    },
    remove: function() {
      return true;
    }
  });
}
<commit_msg>Pluralized question<commit_after>Questions = new Mongo.Collection('questions');

Questions.attachSchema(
  new SimpleSchema({
    title: {
      type: String
    },
    content: {
      type: String
    },
    tag: {
      type: [String]
    },
    room: {
      type: String,
      regEx: SimpleSchema.RegEx.Id
    },
    createdBy: {
      type: String,
      regEx: SimpleSchema.RegEx.Id,
      autoValue: function() { if(this.isInsert) return Meteor.userId }
    },
    postedAt: {
      type: Date,
      denyUpdate: true,
      autoValue: function() { if(this.isInsert) return new Date() }
    }
  })
);

// Collection2 already does schema checking
// Add custom permission rules if needed
if (Meteor.isServer) {
  Questions.allow({
    insert: function() {
      return true;
    },
    update: function() {
      return true;
    },
    remove: function() {
      return true;
    }
  });
}
<|endoftext|>


<commit_before>'use strict'
/**
 * Sequence model (Start from 0)
 * @param mongoose
 * @author CodeHz
 * @returns {Model|*}
 */
module.exports = function (mongoose) {
    let Schema = mongoose.Schema;
    let sequenceSchema = new Schema({
        _id: { type: String, required: true, index: true },
        seq: { type: Number, default: -1 }
    });

    /**
     * Get next document id of collection
     * @param name Collection name
     * @param cb
     */
    sequenceSchema.statics.getNextSequence = (name, cb) => {
        mongoose.model('Seqs').findOneAndUpdate({ _id: name },
            { $inc: { seq: 1 } },
            { upsert: true },
            (err, idDoc) => cb && cb(err, idDoc.seq));
    };

    sequenceSchema.statics.SequenceRollback = (name, cb) => {
        mongoose.model('Seqs').findOneAndUpdate({ _id: name },
            { $inc: { seq: -1 } },
            { upsert: true },
            (err, idDoc) => cb && cb(err, idDoc.seq));
    };

    return mongoose.model('Seqs', sequenceSchema);
}<commit_msg>change seq gen<commit_after>'use strict'
/**
 * Sequence model (Start from 0)
 * @param mongoose
 * @author CodeHz
 * @returns {Model|*}
 */
module.exports = function (mongoose) {
    let Schema = mongoose.Schema;
    let sequenceSchema = new Schema({
        _id: { type: String, required: true, index: true },
        seq: { type: Number, default: 0 }
    });

    /**
     * Get next document id of collection
     * @param name Collection name
     * @param cb
     */
    sequenceSchema.statics.getNextSequence = (name, cb) => {
        mongoose.model('Seqs').findOneAndUpdate({ _id: name },
            { $inc: { seq: 1 } },
            { upsert: true },
            (err, idDoc) => cb && cb(err, idDoc.seq - 1));
    };

    sequenceSchema.statics.SequenceRollback = (name, cb) => {
        mongoose.model('Seqs').findOneAndUpdate({ _id: name },
            { $inc: { seq: -1 } },
            { upsert: true },
            (err, idDoc) => cb && cb(err));
    };

    return mongoose.model('Seqs', sequenceSchema);
}<|endoftext|>


<commit_before>'use strict';
module.exports = function(sequelize, DataTypes) {
  var Response = sequelize.define('Response', {
    GuestId: DataTypes.INTEGER,
  }, {
    classMethods: {
      associate: function(models) {
        // associations can be defined here

        models.Response.belongsTo(models.Guest);
        models.Response.belongsTo(models.Question);
        models.Response.belongsTo(models.Choice);
      },
    },
  });
  return Response;
};
<commit_msg>Apply ES5 lint feedback to models/response.js.<commit_after>'use strict';
module.exports = function(sequelize, DataTypes) {
  var Response = sequelize.define('Response', {
    GuestId: DataTypes.INTEGER
  }, {
    classMethods: {
      associate: function(models) {
        // associations can be defined here

        models.Response.belongsTo(models.Guest);
        models.Response.belongsTo(models.Question);
        models.Response.belongsTo(models.Choice);
      }
    }
  });
  return Response;
};
<|endoftext|>


<commit_before>(function(root) {

var fs = null
var path = null
var app = null

if (typeof require != 'undefined') {
    var remote = require('electron').remote

    fs = require('fs')
    path = require('path')
    app = remote ? remote.app : require('electron').app
}

var context = typeof module != 'undefined' ? module.exports : (window.setting = {})

var namesort = function(x, y) { return x.name < y.name ? -1 : +(x.name != y.name) }
var settingspath = null

if (path && typeof describe == 'undefined' && typeof it == 'undefined') {
    var directory = app.getPath('userData')

    try { fs.mkdirSync(directory) } catch(e) {}
    settingspath = path.join(directory, 'settings.json')
}

var settings = {}
var engines = []

var defaults = {
    'app.startup_check_updates': true,
    'app.startup_check_updates_delay': 100,
    'app.loadgame_delay': 100,
    'app.hide_busy_delay': 200,
    'autoscroll.max_interval': 200,
    'autoscroll.min_interval': 50,
    'autoscroll.diff': 10,
    'board.stone_image_-1': '../img/goban/stone_-1.svg',
    'board.stone_image_1': '../img/goban/stone_1.svg',
    'board.stone_image_0': '../img/goban/stone_0.svg',
    'console.blocked_commands': [
        'boardsize', 'clear_board', 'play',
        'genmove', 'undo', 'fixed_handicap',
        'place_free_handicap', 'set_free_handicap',
        'loadsgf'
    ],
    'console.max_history_count': 30,
    'edit.click_currentvertex_to_remove': true,
    'edit.show_removenode_warning': true,
    'edit.undo_delay': 100,
    'engines.list': engines,
    'find.delay': 100,
    'game.default_board_size': 19,
    'game.default_komi': 6.5,
    'game.goto_end_after_loading': false,
    'game.show_ko_warning': true,
    'game.show_suicide_warning': true,
    'gamechooser.show_delay': 100,
    'gamechooser.thumbnail_size': 153,
    'graph.collapse_min_depth': 1,
    'graph.collapse_tokens_count': 100000,
    'graph.delay': 300,
    'graph.grid_size': 25,
    'graph.node_active_color': '#f76047',
    'graph.node_bookmark_color': '#c678dd',
    'graph.node_collapsed_color': '#333',
    'graph.node_inactive_color': '#777',
    'graph.node_color': '#eee',
    'graph.node_comment_color': '#6bb1ff',
    'graph.node_size': 4,
    'gtp.attach_delay': 300,
    'gtp.move_delay': 300,
    'scoring.method': 'territory',
    'sgf.comment_properties': ['C', 'N', 'UC', 'GW', 'DM', 'GB', 'BM', 'TE', 'DO', 'IT'],
    'sound.capture_delay_max': 500,
    'sound.capture_delay_min': 300,
    'sound.enable': true,
    'view.properties_height': 50,
    'view.properties_minheight': 20,
    'view.fuzzy_stone_placement': true,
    'view.show_leftsidebar': false,
    'view.show_comments': false,
    'view.show_coordinates': false,
    'view.show_graph': false,
    'view.show_next_moves': true,
    'view.leftsidebar_width': 250,
    'view.leftsidebar_minwidth': 100,
    'view.sidebar_width': 200,
    'view.sidebar_minwidth': 100,
    'window.height': 622,
    'window.minheight': 590,
    'window.minwidth': 550,
    'window.width': 578
}

context.load = function() {
    if (!settingspath) return settings = defaults

    try {
        settings = JSON.parse(fs.readFileSync(settingspath, { encoding: 'utf8' }))
    } catch(e) {
        settings = {}
    }

    // Load default settings

    for (var key in defaults) {
        if (key in settings) continue
        settings[key] = defaults[key]
    }

    engines = settings['engines.list']
    engines.sort(namesort)

    return context
}

context.save = function() {
    if (!settingspath) return context

    fs.writeFileSync(settingspath, JSON.stringify(settings, null, '  '))
    return context
}

context.get = function(key) {
    if (key in settings) return settings[key]
    if (key in defaults) return defaults[key]
    return null
}

context.set = function(key, value) {
    settings[key] = value
    return context.save()
}

context.addEngine = function(name, path, args) {
    engines.push({
        name: name,
        path: path,
        args: args
    })
    engines.sort(namesort)
    return context
}

context.getEngines = function() {
    return engines.slice(0)
}

context.clearEngines = function() {
    engines.length = 0
    return context
}

context.load()

}).call(null, typeof module != 'undefined' ? module : window)
<commit_msg>Add setting overwrite mechanic<commit_after>(function(root) {

var fs = null
var path = null
var app = null

if (typeof require != 'undefined') {
    var remote = require('electron').remote

    fs = require('fs')
    path = require('path')
    app = remote ? remote.app : require('electron').app
}

var context = typeof module != 'undefined' ? module.exports : (window.setting = {})

var namesort = function(x, y) { return x.name < y.name ? -1 : +(x.name != y.name) }
var settingspath = null

if (path && typeof describe == 'undefined' && typeof it == 'undefined') {
    var directory = app.getPath('userData')

    try { fs.mkdirSync(directory) } catch(e) {}
    settingspath = path.join(directory, 'settings.json')
}

var settings = {}
var engines = []

var defaults = {
    'app.startup_check_updates': true,
    'app.startup_check_updates_delay': 100,
    'app.loadgame_delay': 100,
    'app.hide_busy_delay': 200,
    'autoscroll.max_interval': 200,
    'autoscroll.min_interval': 50,
    'autoscroll.diff': 10,
    'board.stone_image_-1': '../img/goban/stone_-1.png',
    'board.stone_image_1': '../img/goban/stone_1.png',
    'board.stone_image_0': '../img/goban/stone_0.svg',
    'console.blocked_commands': [
        'boardsize', 'clear_board', 'play',
        'genmove', 'undo', 'fixed_handicap',
        'place_free_handicap', 'set_free_handicap',
        'loadsgf'
    ],
    'console.max_history_count': 30,
    'edit.click_currentvertex_to_remove': true,
    'edit.show_removenode_warning': true,
    'edit.undo_delay': 100,
    'engines.list': engines,
    'find.delay': 100,
    'game.default_board_size': 19,
    'game.default_komi': 6.5,
    'game.goto_end_after_loading': false,
    'game.show_ko_warning': true,
    'game.show_suicide_warning': true,
    'gamechooser.show_delay': 100,
    'gamechooser.thumbnail_size': 153,
    'graph.collapse_min_depth': 1,
    'graph.collapse_tokens_count': 100000,
    'graph.delay': 300,
    'graph.grid_size': 25,
    'graph.node_active_color': '#f76047',
    'graph.node_bookmark_color': '#c678dd',
    'graph.node_collapsed_color': '#333',
    'graph.node_inactive_color': '#777',
    'graph.node_color': '#eee',
    'graph.node_comment_color': '#6bb1ff',
    'graph.node_size': 4,
    'gtp.attach_delay': 300,
    'gtp.move_delay': 300,
    'scoring.method': 'territory',
    'setting.overwrite.v0.12.4': ['board.stone_image_-1', 'board.stone_image_1'],
    'sgf.comment_properties': ['C', 'N', 'UC', 'GW', 'DM', 'GB', 'BM', 'TE', 'DO', 'IT'],
    'sound.capture_delay_max': 500,
    'sound.capture_delay_min': 300,
    'sound.enable': true,
    'view.properties_height': 50,
    'view.properties_minheight': 20,
    'view.fuzzy_stone_placement': true,
    'view.show_leftsidebar': false,
    'view.show_comments': false,
    'view.show_coordinates': false,
    'view.show_graph': false,
    'view.show_next_moves': true,
    'view.leftsidebar_width': 250,
    'view.leftsidebar_minwidth': 100,
    'view.sidebar_width': 200,
    'view.sidebar_minwidth': 100,
    'window.height': 622,
    'window.minheight': 590,
    'window.minwidth': 550,
    'window.width': 578
}

context.load = function() {
    if (!settingspath) return settings = defaults

    try {
        settings = JSON.parse(fs.readFileSync(settingspath, { encoding: 'utf8' }))
    } catch(e) {
        settings = {}
    }

    // Load default settings

    for (var key in defaults) {
        if (key in settings) continue
        settings[key] = defaults[key]
    }

    engines = settings['engines.list']
    engines.sort(namesort)

    // Overwrite settings

    for (var overwriteKey in settings) {
        if (overwriteKey.indexOf('setting.overwrite.') != 0) continue

        var overwrites = settings[overwriteKey]
        if (!overwrites.length) continue

        for (var i = 0; i < overwrites.length; i++) {
            settings[overwrites[i]] = defaults[overwrites[i]]
        }

        settings[overwriteKey] = []
    }

    return context.save()
}

context.save = function() {
    if (!settingspath) return context

    fs.writeFileSync(settingspath, JSON.stringify(settings, null, '  '))
    return context
}

context.get = function(key) {
    if (key in settings) return settings[key]
    if (key in defaults) return defaults[key]
    return null
}

context.set = function(key, value) {
    settings[key] = value
    return context.save()
}

context.addEngine = function(name, path, args) {
    engines.push({
        name: name,
        path: path,
        args: args
    })
    engines.sort(namesort)
    return context
}

context.getEngines = function() {
    return engines.slice(0)
}

context.clearEngines = function() {
    engines.length = 0
    return context
}

context.load()

}).call(null, typeof module != 'undefined' ? module : window)
<|endoftext|>


<commit_before>(function(root) {

var fs = null
var path = null
var app = null

if (typeof require != 'undefined') {
    fs = require('fs')
    path = require('path')

    try {
        var remote = require('electron').remote
        app = remote ? remote.app : require('electron').app
    } catch(e) {}
}

var context = typeof module != 'undefined' ? module.exports : (window.setting = {})

var namesort = function(x, y) { return x.name < y.name ? -1 : +(x.name != y.name) }
var settingspath = null

if (app && path) {
    var directory = app.getPath('userData')

    try { fs.mkdirSync(directory) } catch(e) {}
    settingspath = path.join(directory, 'settings.json')
}

var settings = {}
var engines = []

var defaults = {
    'app.startup_check_updates': true,
    'app.startup_check_updates_delay': 100,
    'app.loadgame_delay': 100,
    'app.hide_busy_delay': 200,
    'autoscroll.max_interval': 200,
    'autoscroll.min_interval': 50,
    'autoscroll.diff': 10,
    'console.blocked_commands': [
        'boardsize', 'clear_board', 'play',
        'genmove', 'undo', 'fixed_handicap',
        'place_free_handicap', 'set_free_handicap',
        'loadsgf'
    ],
    'console.max_history_count': 30,
    'edit.click_currentvertex_to_remove': true,
    'edit.show_removenode_warning': true,
    'edit.undo_delay': 100,
    'engines.list': engines,
    'find.delay': 100,
    'game.default_board_size': 19,
    'game.default_komi': 6.5,
    'game.goto_end_after_loading': false,
    'game.show_ko_warning': true,
    'game.show_suicide_warning': true,
    'gamechooser.show_delay': 100,
    'gamechooser.thumbnail_size': 153,
    'graph.collapse_min_depth': 1,
    'graph.collapse_tokens_count': 100000,
    'graph.delay': 300,
    'graph.grid_size': 25,
    'graph.node_active_color': '#f76047',
    'graph.node_bookmark_color': '#c678dd',
    'graph.node_collapsed_color': '#333',
    'graph.node_inactive_color': '#777',
    'graph.node_color': '#eee',
    'graph.node_comment_color': '#6bb1ff',
    'graph.node_size': 4,
    'gtp.attach_delay': 300,
    'gtp.move_delay': 300,
    'scoring.method': 'territory',
    'sgf.comment_properties': ['C', 'N', 'UC', 'GW', 'DM', 'GB', 'BM', 'TE', 'DO', 'IT'],
    'sound.capture_delay_max': 500,
    'sound.capture_delay_min': 300,
    'sound.enable': true,
    'view.properties_height': 50,
    'view.properties_minheight': 20,
    'view.fuzzy_stone_placement': true,
    'view.show_leftsidebar': false,
    'view.show_comments': false,
    'view.show_coordinates': false,
    'view.show_graph': false,
    'view.show_next_moves': true,
    'view.show_siblings': true,
    'view.leftsidebar_width': 250,
    'view.leftsidebar_minwidth': 100,
    'view.sidebar_width': 200,
    'view.sidebar_minwidth': 100,
    'window.height': 622,
    'window.minheight': 590,
    'window.minwidth': 550,
    'window.width': 578
}

context.load = function() {
    if (!settingspath) return settings = defaults

    try {
        settings = JSON.parse(fs.readFileSync(settingspath, { encoding: 'utf8' }))
    } catch(e) {
        settings = {}
    }

    // Load default settings

    for (var key in defaults) {
        if (key in settings) continue
        settings[key] = defaults[key]
    }

    engines = settings['engines.list']
    engines.sort(namesort)

    // Overwrite settings

    for (var overwriteKey in settings) {
        if (overwriteKey.indexOf('setting.overwrite.') != 0) continue

        var overwrites = settings[overwriteKey]
        if (!overwrites.length) continue

        for (var i = 0; i < overwrites.length; i++) {
            settings[overwrites[i]] = defaults[overwrites[i]]
        }

        settings[overwriteKey] = []
    }

    return context.save()
}

context.save = function() {
    if (!settingspath) return context

    fs.writeFileSync(settingspath, JSON.stringify(settings, null, '  '))
    return context
}

context.get = function(key) {
    if (key in settings) return settings[key]
    if (key in defaults) return defaults[key]
    return null
}

context.set = function(key, value) {
    settings[key] = value
    return context.save()
}

context.addEngine = function(name, path, args) {
    engines.push({
        name: name,
        path: path,
        args: args
    })
    engines.sort(namesort)
    return context
}

context.getEngines = function() {
    return engines.slice(0)
}

context.clearEngines = function() {
    engines.length = 0
    return context
}

context.load()

}).call(null, typeof module != 'undefined' ? module : window)
<commit_msg>Create styles.css in app data folder<commit_after>(function(root) {

var fs = null
var path = null
var app = null

if (typeof require != 'undefined') {
    fs = require('fs')
    path = require('path')

    try {
        var remote = require('electron').remote
        app = remote ? remote.app : require('electron').app
    } catch(e) {}
}

var context = typeof module != 'undefined' ? module.exports : (window.setting = {})

var namesort = function(x, y) { return x.name < y.name ? -1 : +(x.name != y.name) }
var settingspath = null
var stylespath = null

if (app && path) {
    var directory = app.getPath('userData')
    try { fs.mkdirSync(directory) } catch(e) {}

    settingspath = path.join(directory, 'settings.json')
    stylespath = path.join(directory, 'styles.css')

    try {
        fs.accessSync(stylespath, fs.R_OK)
    } catch(e) {
        fs.writeFileSync(stylespath, '/* This stylesheet is loaded when ' + app.getName() + ' starts up. */')
    }
}

var settings = {}
var engines = []

var defaults = {
    'app.startup_check_updates': true,
    'app.startup_check_updates_delay': 100,
    'app.loadgame_delay': 100,
    'app.hide_busy_delay': 200,
    'autoscroll.max_interval': 200,
    'autoscroll.min_interval': 50,
    'autoscroll.diff': 10,
    'console.blocked_commands': [
        'boardsize', 'clear_board', 'play',
        'genmove', 'undo', 'fixed_handicap',
        'place_free_handicap', 'set_free_handicap',
        'loadsgf'
    ],
    'console.max_history_count': 30,
    'edit.click_currentvertex_to_remove': true,
    'edit.show_removenode_warning': true,
    'edit.undo_delay': 100,
    'engines.list': engines,
    'find.delay': 100,
    'game.default_board_size': 19,
    'game.default_komi': 6.5,
    'game.goto_end_after_loading': false,
    'game.show_ko_warning': true,
    'game.show_suicide_warning': true,
    'gamechooser.show_delay': 100,
    'gamechooser.thumbnail_size': 153,
    'graph.collapse_min_depth': 1,
    'graph.collapse_tokens_count': 100000,
    'graph.delay': 300,
    'graph.grid_size': 25,
    'graph.node_active_color': '#f76047',
    'graph.node_bookmark_color': '#c678dd',
    'graph.node_collapsed_color': '#333',
    'graph.node_inactive_color': '#777',
    'graph.node_color': '#eee',
    'graph.node_comment_color': '#6bb1ff',
    'graph.node_size': 4,
    'gtp.attach_delay': 300,
    'gtp.move_delay': 300,
    'scoring.method': 'territory',
    'sgf.comment_properties': ['C', 'N', 'UC', 'GW', 'DM', 'GB', 'BM', 'TE', 'DO', 'IT'],
    'sound.capture_delay_max': 500,
    'sound.capture_delay_min': 300,
    'sound.enable': true,
    'view.properties_height': 50,
    'view.properties_minheight': 20,
    'view.fuzzy_stone_placement': true,
    'view.show_leftsidebar': false,
    'view.show_comments': false,
    'view.show_coordinates': false,
    'view.show_graph': false,
    'view.show_next_moves': true,
    'view.show_siblings': true,
    'view.leftsidebar_width': 250,
    'view.leftsidebar_minwidth': 100,
    'view.sidebar_width': 200,
    'view.sidebar_minwidth': 100,
    'window.height': 622,
    'window.minheight': 590,
    'window.minwidth': 550,
    'window.width': 578
}

context.load = function() {
    if (!settingspath) return settings = defaults

    try {
        settings = JSON.parse(fs.readFileSync(settingspath, { encoding: 'utf8' }))
    } catch(e) {
        settings = {}
    }

    // Load default settings

    for (var key in defaults) {
        if (key in settings) continue
        settings[key] = defaults[key]
    }

    engines = settings['engines.list']
    engines.sort(namesort)

    // Overwrite settings

    for (var overwriteKey in settings) {
        if (overwriteKey.indexOf('setting.overwrite.') != 0) continue

        var overwrites = settings[overwriteKey]
        if (!overwrites.length) continue

        for (var i = 0; i < overwrites.length; i++) {
            settings[overwrites[i]] = defaults[overwrites[i]]
        }

        settings[overwriteKey] = []
    }

    return context.save()
}

context.save = function() {
    if (!settingspath || !stylespath) return context

    fs.writeFileSync(settingspath, JSON.stringify(settings, null, '  '))
    return context
}

context.get = function(key) {
    if (key in settings) return settings[key]
    if (key in defaults) return defaults[key]
    return null
}

context.set = function(key, value) {
    settings[key] = value
    return context.save()
}

context.addEngine = function(name, path, args) {
    engines.push({
        name: name,
        path: path,
        args: args
    })
    engines.sort(namesort)
    return context
}

context.getEngines = function() {
    return engines.slice(0)
}

context.clearEngines = function() {
    engines.length = 0
    return context
}

context.load()

}).call(null, typeof module != 'undefined' ? module : window)
<|endoftext|>


<commit_before>// Partially based on cashew asm.js parser (see Upstream/cashew/LICENSE)

'use strict';

(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    define(['exports'], factory);
  } else if (typeof exports !== 'undefined') {
    factory(exports);
  } else {
    factory((root.asmParse = {}));
  }
}(this, function (exports) {
  var tokenizer = require("./asm-tokenizer.js");

  var Tokenizer = tokenizer.Tokenizer;

  function JsonTreeBuilder () {
    this.result = null;
    this.protos = Object.create(null);
  };

  JsonTreeBuilder.prototype.make = function (type) {
    var proto = this.protos[type];
    if (!proto) {
      this.protos[type] = proto = Object.create(null);
      proto.type = type;
    }

    return Object.create(proto);
  };

  JsonTreeBuilder.prototype.makeTopLevelBlock = function () {
    return this._makeBlock("TopLevel");
  };

  JsonTreeBuilder.prototype.makeBlock = function () {
    return this._makeBlock("Block");
  };

  JsonTreeBuilder.prototype.makeExpressionStatement = function (expression) {
    var result = this.make("Statement");
    result.expression = expression;
    return result;
  };

  JsonTreeBuilder.prototype.makeBlockStatement = function (block) {
    var result = this.make("BlockStatement");
    result.block = block;
    return result;
  };

  JsonTreeBuilder.prototype.makeLiteralExpression = function (type, value) {
    var result = this.make("Literal");
    result.valueType = type;
    result.value = value;
    return result;
  };

  JsonTreeBuilder.prototype.makeIdentifierExpression = function (identifier) {
    var result = this.make("Identifier");
    result.identifier = identifier;
    return result;
  };

  JsonTreeBuilder.prototype._makeBlock = function (typeTag) {
    var result = this.make(typeTag);
    result.statements = [];
    return result;
  };

  JsonTreeBuilder.prototype.appendToBlock = function (block, statement) {
    block.statements.push(statement);
  };

  function Parser (tokenizer, treeBuilder) {
    this.tokenizer = tokenizer;
    this.builder = treeBuilder;
    this._rewound = null;
  };

  Parser.prototype.readToken = function () {
    var result;

    if (this._rewound) {
      result = this._rewound;
      this._rewound = null;
    } else {
      result = this.tokenizer.read();
    }

    console.log(result);
    return result;
  };

  Parser.prototype.rewind = function (token) {
    if (this._rewound)
      throw new Error("Already rewound");
    else
      this._rewound = token;
  };

  Parser.prototype.abort = function () {
    console.log.apply(console, arguments);
    throw new Error(arguments[0] || "Aborted");
  };

  Parser.prototype.parseTopLevel = function () {
    var result = this.builder.makeTopLevelBlock();

    this.parseBlockInterior(result);

    return result;
  };

  // parses the interior of a multi-statement block (i.e. the { has been consumed)
  // aborts at eof or uneven } (end of multi-statement block)
  Parser.prototype.parseBlockInterior = function (block) {
    while (true) {
      var stmt = this.parseStatement(block);

      if (stmt === false)
        break;

      this.builder.appendToBlock(block, stmt);
    }
  };

  // Parses an identifier into an expression. Most identifiers are a single token,
  //  but we special-case ones like 'function' by parsing the stuff that follows.
  Parser.prototype.parseIdentifier = function (initialToken) {
    if (initialToken.type !== "identifier")
      return this.abort("Expected an identifier");

    if (initialToken.value === "function") {
      this.abort("Function");
    } else {
      return this.builder.makeIdentifierExpression(initialToken.value);
    }
  }

  // Parses a single expression. If it encounters a ( it handles nesting.
  Parser.prototype.parseExpression = function (isNested) {
    var token = null, lhs = null;

    iter:
    while (token = this.readToken()) {
      switch (token.type) {
        case "separator":

          switch (token.value) {
            case "(":
              // Subexpression or function invocation

              if (lhs) {
                // Function invocation
                lhs = this.builder.makeInvocationExpression(
                  lhs, this.parseArgumentList()
                );
              } else {
                // Subexpression
                lhs = this.parseExpression(true);
              }

              break;

            case ")":
              // Subexpression terminator
              if (isNested)
                break iter;
              else
                return this.abort("Unexpected ) within free-standing expression");

            case "{":
              // Object literal
              return this.abort("object literal");

            case "[":
              // Array literal
              return this.abort("array literal");

            case ";":
              // End of enclosing statement.
              if (isNested)
                return this.abort("Unexpected ; within parenthesized expression");
              else
                break iter;

            default:

              return this.abort("Unexpected ", token);
          }

          break;

        case "identifier":
          lhs = this.parseIdentifier(token);
          break;

        case "integer":
        case "double":
        case "string":
          lhs = this.builder.makeLiteralExpression(token.type, token.value);
          break;
      }
    }

    if (!lhs)
      this.abort("No expression parsed");

    return lhs;
  };

  // parses a single statement, returns false if it hit a block-closing token.
  // handles nested blocks.
  Parser.prototype.parseStatement = function (block) {
    var token = null, stmt = null, expr = null;

    iter:
    while (token = this.readToken()) {
      switch (token.type) {
        case "separator":
          // Read nested block scope. Meaningless, but important to parse
          //  correctly.

          switch (token.value) {
            case "{":
              var childBlock = this.builder.makeBlock();
              stmt = this.builder.makeBlockStatement(childBlock);

              this.parseBlockInterior(childBlock);

              return stmt;

            case "}":
              return false;

            case ";":
              // HACK: Just skip stray semicolons. We don't care about
              //  no-op statements, and this lets us avoid conditionally
              //  eating a trailing ;.
              continue iter;

            case "(":
              expr = this.parseExpression(true);
              stmt = this.builder.makeExpressionStatement(expr);

              return stmt;

            default:
              // Fall-through
          }

        default:
          this.rewind(token);
          expr = this.parseExpression(false);
          stmt = this.builder.makeExpressionStatement(expr);

          return stmt;

      }
    }

    this.abort("No tokens read");
  };

  // parses an input character stream into a tree of asm.js AST nodes
  // input is a ByteReader (see encoding.js)
  // treebuilder is an object that implements the abstract TreeBuilder interface
  function parse (input, treeBuilder) {
    var tokenizer = new Tokenizer(input);
    var parser    = new Parser(tokenizer, treeBuilder);

    return parser.parseTopLevel();
  };

  exports.JsonTreeBuilder = JsonTreeBuilder;
  exports.Tokenizer       = Tokenizer;
  exports.Parser          = Parser;

  exports.parse = parse;
}));<commit_msg>Parse function prologues<commit_after>// Partially based on cashew asm.js parser (see Upstream/cashew/LICENSE)

'use strict';

(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    define(['exports'], factory);
  } else if (typeof exports !== 'undefined') {
    factory(exports);
  } else {
    factory((root.asmParse = {}));
  }
}(this, function (exports) {
  var tokenizer = require("./asm-tokenizer.js");

  var Tokenizer = tokenizer.Tokenizer;

  function JsonTreeBuilder () {
    this.result = null;
    this.protos = Object.create(null);
  };

  JsonTreeBuilder.prototype.make = function (type) {
    var proto = this.protos[type];
    if (!proto) {
      this.protos[type] = proto = Object.create(null);
      proto.type = type;
    }

    return Object.create(proto);
  };

  JsonTreeBuilder.prototype.makeTopLevelBlock = function () {
    return this._makeBlock("TopLevel");
  };

  JsonTreeBuilder.prototype.makeBlock = function () {
    return this._makeBlock("Block");
  };

  JsonTreeBuilder.prototype.makeExpressionStatement = function (expression) {
    var result = this.make("Statement");
    result.expression = expression;
    return result;
  };

  JsonTreeBuilder.prototype.makeBlockStatement = function (block) {
    var result = this.make("BlockStatement");
    result.block = block;
    return result;
  };

  JsonTreeBuilder.prototype.makeLiteralExpression = function (name, argumentNames, body) {
    var result = this.make("Function");
    result.name = name;
    result.argumentNames = argumentNames;
    result.body = body;
    return result;
  };

  JsonTreeBuilder.prototype.makeLiteralExpression = function (type, value) {
    var result = this.make("Literal");
    result.valueType = type;
    result.value = value;
    return result;
  };

  JsonTreeBuilder.prototype.makeIdentifierExpression = function (identifier) {
    var result = this.make("Identifier");
    result.identifier = identifier;
    return result;
  };

  JsonTreeBuilder.prototype._makeBlock = function (typeTag) {
    var result = this.make(typeTag);
    result.statements = [];
    return result;
  };

  JsonTreeBuilder.prototype.appendToBlock = function (block, statement) {
    block.statements.push(statement);
  };

  function Parser (tokenizer, treeBuilder) {
    this.tokenizer = tokenizer;
    this.builder = treeBuilder;
    this._rewound = null;
  };

  Parser.prototype.readToken = function () {
    var result;

    if (this._rewound) {
      result = this._rewound;
      this._rewound = null;
    } else {
      result = this.tokenizer.read();
    }

    console.log(result);
    return result;
  };

  Parser.prototype.rewind = function (token) {
    if (this._rewound)
      throw new Error("Already rewound");
    else
      this._rewound = token;
  };

  Parser.prototype.expectToken = function (type, value) {
    var token = this.readToken();
    if (token.type === type) {
      if ((arguments.length === 2) && (token.value !== value)) {
        return this.abort("Expected a '" + type + "' with value '" + value + "', got '" + token.value + "'");
      } else {
        return token.value;
      }
    }

    return this.abort("Expected a token of type '" + type + "', got '" + token.type + "'.");
  };

  Parser.prototype.abort = function () {
    console.log.apply(console, arguments);
    throw new Error(arguments[0] || "Aborted");
  };

  Parser.prototype.parseTopLevel = function () {
    var result = this.builder.makeTopLevelBlock();

    this.parseBlockInterior(result);

    return result;
  };

  // parses the interior of a multi-statement block (i.e. the { has been consumed)
  // aborts at eof or uneven } (end of multi-statement block)
  Parser.prototype.parseBlockInterior = function (block) {
    while (true) {
      var stmt = this.parseStatement(block);

      if (stmt === false)
        break;

      this.builder.appendToBlock(block, stmt);
    }
  };

  // Parses an identifier into an expression. Most identifiers are a single token,
  //  but we special-case ones like 'function' by parsing the stuff that follows.
  Parser.prototype.parseIdentifier = function (initialToken) {
    if (initialToken.type !== "identifier")
      return this.abort("Expected an identifier");

    if (initialToken.value === "function") {
      return this.parseFunctionExpression();
    } else {
      return this.builder.makeIdentifierExpression(initialToken.value);
    }
  }

  Parser.prototype.parseFunctionExpression = function () {
    var name = null;

    var token = this.readToken();
    if (token.type === "identifier") {
      name = token.value;

      this.expectToken("separator", "(");
    } else if (
      (token.type !== "separator") ||
      (token.value !== "(")
    ) {
      return this.abort("Expected a function name or an argument name list");
    }

    var argumentNames = [];

    token = this.readToken();

    while (
      (token = this.readToken()) &&
      (
        (token.type === "identifier") ||
        (
          (token.type === "operator") &&
          (token.value === ",")
        )
      )
    ) {

      if (token.type === "identifier")
        argumentNames.push(token.value);
      else;
        // Ignore comma
    }

    if (
      (token.type !== "separator") ||
      (token.value !== ")")
    ) {
      return this.abort("Expected an argument name list terminator or another argument name");
    }

    this.expectToken("separator", "{");

    var body = this.builder.makeBlock();
    this.parseBlockInterior();

    return this.builder.makeFunctionExpression(
      name, argumentNames, body
    );
  };

  // Parses a single expression. If it encounters a ( it handles nesting.
  Parser.prototype.parseExpression = function (isNested) {
    var token = null, lhs = null;

    iter:
    while (token = this.readToken()) {
      switch (token.type) {
        case "separator":

          switch (token.value) {
            case "(":
              // Subexpression or function invocation

              if (lhs) {
                // Function invocation
                lhs = this.builder.makeInvocationExpression(
                  lhs, this.parseArgumentList()
                );
              } else {
                // Subexpression
                lhs = this.parseExpression(true);
              }

              break;

            case ")":
              // Subexpression terminator
              if (isNested)
                break iter;
              else
                return this.abort("Unexpected ) within free-standing expression");

            case "{":
              // Object literal
              return this.abort("object literal");

            case "[":
              // Array literal
              return this.abort("array literal");

            case ";":
              // End of enclosing statement.
              if (isNested)
                return this.abort("Unexpected ; within parenthesized expression");
              else
                break iter;

            default:
              return this.abort("Unexpected ", token);
          }

          break;

        case "identifier":
          lhs = this.parseIdentifier(token);
          break;

        case "integer":
        case "double":
        case "string":
          lhs = this.builder.makeLiteralExpression(token.type, token.value);
          break;
      }
    }

    if (!lhs)
      return this.abort("No expression parsed");

    return lhs;
  };

  // parses a single statement, returns false if it hit a block-closing token.
  // handles nested blocks.
  Parser.prototype.parseStatement = function (block) {
    var token = null, stmt = null, expr = null;

    iter:
    while (token = this.readToken()) {
      switch (token.type) {
        case "separator":
          // Read nested block scope. Meaningless, but important to parse
          //  correctly.

          switch (token.value) {
            case "{":
              var childBlock = this.builder.makeBlock();
              stmt = this.builder.makeBlockStatement(childBlock);

              this.parseBlockInterior(childBlock);

              return stmt;

            case "}":
              return false;

            case ";":
              // HACK: Just skip stray semicolons. We don't care about
              //  no-op statements, and this lets us avoid conditionally
              //  eating a trailing ;.
              continue iter;

            case "(":
              expr = this.parseExpression(true);
              stmt = this.builder.makeExpressionStatement(expr);

              return stmt;

            default:
              // Fall-through
          }

        default:
          this.rewind(token);
          expr = this.parseExpression(false);
          stmt = this.builder.makeExpressionStatement(expr);

          return stmt;

      }
    }

    this.abort("No tokens read");
  };

  // parses an input character stream into a tree of asm.js AST nodes
  // input is a ByteReader (see encoding.js)
  // treebuilder is an object that implements the abstract TreeBuilder interface
  function parse (input, treeBuilder) {
    var tokenizer = new Tokenizer(input);
    var parser    = new Parser(tokenizer, treeBuilder);

    return parser.parseTopLevel();
  };

  exports.JsonTreeBuilder = JsonTreeBuilder;
  exports.Tokenizer       = Tokenizer;
  exports.Parser          = Parser;

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


<commit_before>import {
    event as d3_event,
    select as d3_select
} from 'd3-selection';
import { dispatch as d3_dispatch } from 'd3-dispatch';

import { d3keybinding as d3_keybinding } from '../lib/d3.keybinding.js';

import { t, textDirection } from '../util/locale';
import { tooltip } from '../util/tooltip';

import { behaviorHash } from '../behavior';
import { modeBrowse } from '../modes';
import { services } from '../services';
import { svgDefs, svgIcon } from '../svg';
import { utilGetDimensions } from '../util/dimensions';
import { utilRebind } from '../util';

import { uiAccount } from './account';
import { uiAttribution } from './attribution';
import { uiBackground } from './background';
import { uiContributors } from './contributors';
import { uiFeatureInfo } from './feature_info';
import { uiFullScreen } from './full_screen';
import { uiGeolocate } from './geolocate';
import { uiHelp } from './help';
import { uiInfo } from './info';
import { uiIntro } from './intro';
import { uiLoading } from './loading';
import { uiMapData } from './map_data';
import { uiMapInMap } from './map_in_map';
import { uiModes } from './modes';
import { uiNotice } from './notice';
import { uiRestore } from './restore';
import { uiSave } from './save';
import { uiScale } from './scale';
import { uiShortcuts } from './shortcuts';
import { uiSidebar } from './sidebar';
import { uiSpinner } from './spinner';
import { uiSplash } from './splash';
import { uiStatus } from './status';
import { uiUndoRedo } from './undo_redo';
import { uiVersion } from './version';
import { uiZoom } from './zoom';
import { uiCmd } from './cmd';

export function uiInit(context) {
    var uiInitCounter = 0;
    var dispatch = d3_dispatch('photoviewerResize');

    function render(container) {
        container
            .attr('dir', textDirection);

        var map = context.map();

        var hash = behaviorHash(context);
        hash();

        if (!hash.hadHash) {
            map.centerZoom([0, 0], 2);
        }

        container
            .append('svg')
            .attr('id', 'defs')
            .call(svgDefs(context));

        container
            .append('div')
            .attr('id', 'sidebar')
            .attr('class', 'col4')
            .call(ui.sidebar);

        var content = container
            .append('div')
            .attr('id', 'content')
            .attr('class', 'active');

        var bar = content
            .append('div')
            .attr('id', 'bar')
            .attr('class', 'fillD');

        content
            .append('div')
            .attr('id', 'map')
            .attr('dir', 'ltr')
            .call(map);

        content
            .call(uiMapInMap(context))
            .call(uiInfo(context))
            .call(uiNotice(context));

        bar
            .append('div')
            .attr('class', 'spacer col4');

        var limiter = bar.append('div')
            .attr('class', 'limiter');

        limiter
            .append('div')
            .attr('class', 'button-wrap joined col3')
            .call(uiModes(context), limiter);

        limiter
            .append('div')
            .attr('class', 'button-wrap joined col1')
            .call(uiUndoRedo(context));

        limiter
            .append('div')
            .attr('class', 'button-wrap col1')
            .call(uiSave(context));

        bar
            .append('div')
            .attr('class', 'full-screen')
            .call(uiFullScreen(context));

        bar
            .append('div')
            .attr('class', 'spinner')
            .call(uiSpinner(context));

        var controls = bar
            .append('div')
            .attr('class', 'map-controls');

        controls
            .append('div')
            .attr('class', 'map-control zoombuttons')
            .call(uiZoom(context));

        controls
            .append('div')
            .attr('class', 'map-control geolocate-control')
            .call(uiGeolocate(context));

        controls
            .append('div')
            .attr('class', 'map-control background-control')
            .call(uiBackground(context));

        controls
            .append('div')
            .attr('class', 'map-control map-data-control')
            .call(uiMapData(context));

        controls
            .append('div')
            .attr('class', 'map-control help-control')
            .call(uiHelp(context));

        var about = content
            .append('div')
            .attr('id', 'about');

        about
            .append('div')
            .attr('id', 'attrib')
            .attr('dir', 'ltr')
            .call(uiAttribution(context));

        about
            .append('div')
            .attr('class', 'api-status')
            .call(uiStatus(context));

        var footer = about
            .append('div')
            .attr('id', 'footer')
            .attr('class', 'fillD');

        footer
            .append('div')
            .attr('id', 'flash-wrap')
            .attr('class', 'footer-hide');

        var footerWrap = footer
            .append('div')
            .attr('id', 'footer-wrap')
            .attr('class', 'footer-show');

        footerWrap
            .append('div')
            .attr('id', 'scale-block')
            .call(uiScale(context));

        var aboutList = footerWrap
            .append('div')
            .attr('id', 'info-block')
            .append('ul')
            .attr('id', 'about-list');

        if (!context.embed()) {
            aboutList
                .call(uiAccount(context));
        }

        aboutList
            .append('li')
            .attr('class', 'version')
            .call(uiVersion(context));

        var issueLinks = aboutList
            .append('li');

        issueLinks
            .append('a')
            .attr('target', '_blank')
            .attr('tabindex', -1)
            .attr('href', 'https://github.com/openstreetmap/iD/issues')
            .call(svgIcon('#iD-icon-bug', 'light'))
            .call(tooltip().title(t('report_a_bug')).placement('top'));

        issueLinks
            .append('a')
            .attr('target', '_blank')
            .attr('tabindex', -1)
            .attr('href', 'https://github.com/openstreetmap/iD/blob/master/CONTRIBUTING.md#translating')
            .call(svgIcon('#iD-icon-translate', 'light'))
            .call(tooltip().title(t('help_translate')).placement('top'));

        aboutList
            .append('li')
            .attr('class', 'feature-warning')
            .attr('tabindex', -1)
            .call(uiFeatureInfo(context));

        aboutList
            .append('li')
            .attr('class', 'user-list')
            .attr('tabindex', -1)
            .call(uiContributors(context));

        var photoviewer = content
            .append('div')
            .attr('id', 'photoviewer')
            .classed('al', true)       // 'al'=left,  'ar'=right
            .classed('hide', true);

        photoviewer
            .append('button')
            .attr('class', 'thumb-hide')
            .on('click', function () {
                if (services.streetside) { services.streetside.hideViewer(); }
                if (services.mapillary) { services.mapillary.hideViewer(); }
                if (services.openstreetcam) { services.openstreetcam.hideViewer(); }
            })
            .append('div')
            .call(svgIcon('#iD-icon-close'));

        photoviewer
            .append('button')
            .attr('class', 'resize-handle-xy')
            .on(
                'mousedown',
                buildResizeListener(photoviewer, 'photoviewerResize', dispatch, { resizeOnX: true, resizeOnY: true })
            );

        photoviewer
            .append('button')
            .attr('class', 'resize-handle-x')
            .on(
                'mousedown',
                buildResizeListener(photoviewer, 'photoviewerResize', dispatch, { resizeOnX: true })
            );

        photoviewer
            .append('button')
            .attr('class', 'resize-handle-y')
            .on(
                'mousedown',
                buildResizeListener(photoviewer, 'photoviewerResize', dispatch, { resizeOnY: true })
            );

        window.onbeforeunload = function() {
            return context.save();
        };

        window.onunload = function() {
            context.history().unlock();
        };

        var mapDimensions = map.dimensions();

        function onResize() {
            mapDimensions = utilGetDimensions(content, true);
            map.dimensions(mapDimensions);
        }

        d3_select(window)
            .on('resize.editor', onResize);

        onResize();

        function pan(d) {
            return function() {
                d3_event.preventDefault();
                context.pan(d, 100);
            };
        }

        // pan amount
        var pa = 80;

        var keybinding = d3_keybinding('main')
            .on('⌫', function() { d3_event.preventDefault(); })
            .on('←', pan([pa, 0]))
            .on('↑', pan([0, pa]))
            .on('→', pan([-pa, 0]))
            .on('↓', pan([0, -pa]))
            .on(['⇧←', uiCmd('⌘←')], pan([mapDimensions[0], 0]))
            .on(['⇧↑', uiCmd('⌘↑')], pan([0, mapDimensions[1]]))
            .on(['⇧→', uiCmd('⌘→')], pan([-mapDimensions[0], 0]))
            .on(['⇧↓', uiCmd('⌘↓')], pan([0, -mapDimensions[1]]));

        d3_select(document)
            .call(keybinding);

        context.enter(modeBrowse(context));

        if (!uiInitCounter++) {
            if (!hash.startWalkthrough) {
                context.container()
                    .call(uiSplash(context))
                    .call(uiRestore(context));
            }

            context.container()
                .call(uiShortcuts(context));
        }

        var osm = context.connection();
        var auth = uiLoading(context).message(t('loading_auth')).blocking(true);

        if (osm && auth) {
            osm
                .on('authLoading.ui', function() {
                    context.container()
                        .call(auth);
                })
                .on('authDone.ui', function() {
                    auth.close();
                });
        }

        uiInitCounter++;

        if (hash.startWalkthrough) {
            hash.startWalkthrough = false;
            context.container().call(uiIntro(context));
        }

        function buildResizeListener(target, eventName, dispatch, options) {
            var resizeOnX = !!options.resizeOnX;
            var resizeOnY = !!options.resizeOnY;
            var minHeight = options.minHeight || 240;
            var minWidth = options.minWidth || 320;
            var startX;
            var startY;
            var startWidth;
            var startHeight;

            function startResize() {
                var mapSize = context.map().dimensions();

                if (resizeOnX) {
                    var maxWidth = mapSize[0];
                    var newWidth = clamp((startWidth + d3_event.clientX - startX), minWidth, maxWidth);
                    target.style('width', newWidth + 'px');
                }

                if (resizeOnY) {
                    var maxHeight = mapSize[1] - 90;  // preserve space at top/bottom of map
                    var newHeight = clamp((startHeight + startY - d3_event.clientY), minHeight, maxHeight);
                    target.style('height', newHeight + 'px');
                }

                dispatch.call(eventName, target, utilGetDimensions(target, true));
            }

            function clamp(num, min, max) {
                return Math.max(min, Math.min(num, max));
            }

            function stopResize() {
                d3_select(window)
                    .on('.' + eventName, null);
            }

            return function initResize() {
                startX = d3_event.clientX;
                startY = d3_event.clientY;
                startWidth = target.node().getBoundingClientRect().width;
                startHeight = target.node().getBoundingClientRect().height;

                d3_select(window)
                    .on('mousemove.' + eventName, startResize, false)
                    .on('mouseup.' + eventName, stopResize, false);
            };
        }
    }

    var renderCallback;

    function ui(node, callback) {
        renderCallback = callback;
        var container = d3_select(node);
        context.container(container);
        context.loadLocale(function(err) {
            if (!err) {
                render(container);
            }
            if (callback) {
                callback(err);
            }
        });
    }

    ui.restart = function(arg) {
        context.locale(arg);
        context.loadLocale(function(err) {
            if (!err) {
                context.container().selectAll('*').remove();
                render(context.container());
                if (renderCallback) renderCallback();
            }
        });
    };

    ui.sidebar = uiSidebar(context);

    return utilRebind(ui, dispatch, 'on');
}
<commit_msg>Shrink the photo viewer if the map has been resized to be smaller<commit_after>import {
    event as d3_event,
    select as d3_select
} from 'd3-selection';
import { dispatch as d3_dispatch } from 'd3-dispatch';

import { d3keybinding as d3_keybinding } from '../lib/d3.keybinding.js';

import { t, textDirection } from '../util/locale';
import { tooltip } from '../util/tooltip';

import { behaviorHash } from '../behavior';
import { modeBrowse } from '../modes';
import { services } from '../services';
import { svgDefs, svgIcon } from '../svg';
import { utilGetDimensions } from '../util/dimensions';
import { utilRebind } from '../util';

import { uiAccount } from './account';
import { uiAttribution } from './attribution';
import { uiBackground } from './background';
import { uiContributors } from './contributors';
import { uiFeatureInfo } from './feature_info';
import { uiFullScreen } from './full_screen';
import { uiGeolocate } from './geolocate';
import { uiHelp } from './help';
import { uiInfo } from './info';
import { uiIntro } from './intro';
import { uiLoading } from './loading';
import { uiMapData } from './map_data';
import { uiMapInMap } from './map_in_map';
import { uiModes } from './modes';
import { uiNotice } from './notice';
import { uiRestore } from './restore';
import { uiSave } from './save';
import { uiScale } from './scale';
import { uiShortcuts } from './shortcuts';
import { uiSidebar } from './sidebar';
import { uiSpinner } from './spinner';
import { uiSplash } from './splash';
import { uiStatus } from './status';
import { uiUndoRedo } from './undo_redo';
import { uiVersion } from './version';
import { uiZoom } from './zoom';
import { uiCmd } from './cmd';

export function uiInit(context) {
    var uiInitCounter = 0;
    var dispatch = d3_dispatch('photoviewerResize');

    function render(container) {
        container
            .attr('dir', textDirection);

        var map = context.map();

        var hash = behaviorHash(context);
        hash();

        if (!hash.hadHash) {
            map.centerZoom([0, 0], 2);
        }

        container
            .append('svg')
            .attr('id', 'defs')
            .call(svgDefs(context));

        container
            .append('div')
            .attr('id', 'sidebar')
            .attr('class', 'col4')
            .call(ui.sidebar);

        var content = container
            .append('div')
            .attr('id', 'content')
            .attr('class', 'active');

        var bar = content
            .append('div')
            .attr('id', 'bar')
            .attr('class', 'fillD');

        content
            .append('div')
            .attr('id', 'map')
            .attr('dir', 'ltr')
            .call(map);

        content
            .call(uiMapInMap(context))
            .call(uiInfo(context))
            .call(uiNotice(context));

        bar
            .append('div')
            .attr('class', 'spacer col4');

        var limiter = bar.append('div')
            .attr('class', 'limiter');

        limiter
            .append('div')
            .attr('class', 'button-wrap joined col3')
            .call(uiModes(context), limiter);

        limiter
            .append('div')
            .attr('class', 'button-wrap joined col1')
            .call(uiUndoRedo(context));

        limiter
            .append('div')
            .attr('class', 'button-wrap col1')
            .call(uiSave(context));

        bar
            .append('div')
            .attr('class', 'full-screen')
            .call(uiFullScreen(context));

        bar
            .append('div')
            .attr('class', 'spinner')
            .call(uiSpinner(context));

        var controls = bar
            .append('div')
            .attr('class', 'map-controls');

        controls
            .append('div')
            .attr('class', 'map-control zoombuttons')
            .call(uiZoom(context));

        controls
            .append('div')
            .attr('class', 'map-control geolocate-control')
            .call(uiGeolocate(context));

        controls
            .append('div')
            .attr('class', 'map-control background-control')
            .call(uiBackground(context));

        controls
            .append('div')
            .attr('class', 'map-control map-data-control')
            .call(uiMapData(context));

        controls
            .append('div')
            .attr('class', 'map-control help-control')
            .call(uiHelp(context));

        var about = content
            .append('div')
            .attr('id', 'about');

        about
            .append('div')
            .attr('id', 'attrib')
            .attr('dir', 'ltr')
            .call(uiAttribution(context));

        about
            .append('div')
            .attr('class', 'api-status')
            .call(uiStatus(context));

        var footer = about
            .append('div')
            .attr('id', 'footer')
            .attr('class', 'fillD');

        footer
            .append('div')
            .attr('id', 'flash-wrap')
            .attr('class', 'footer-hide');

        var footerWrap = footer
            .append('div')
            .attr('id', 'footer-wrap')
            .attr('class', 'footer-show');

        footerWrap
            .append('div')
            .attr('id', 'scale-block')
            .call(uiScale(context));

        var aboutList = footerWrap
            .append('div')
            .attr('id', 'info-block')
            .append('ul')
            .attr('id', 'about-list');

        if (!context.embed()) {
            aboutList
                .call(uiAccount(context));
        }

        aboutList
            .append('li')
            .attr('class', 'version')
            .call(uiVersion(context));

        var issueLinks = aboutList
            .append('li');

        issueLinks
            .append('a')
            .attr('target', '_blank')
            .attr('tabindex', -1)
            .attr('href', 'https://github.com/openstreetmap/iD/issues')
            .call(svgIcon('#iD-icon-bug', 'light'))
            .call(tooltip().title(t('report_a_bug')).placement('top'));

        issueLinks
            .append('a')
            .attr('target', '_blank')
            .attr('tabindex', -1)
            .attr('href', 'https://github.com/openstreetmap/iD/blob/master/CONTRIBUTING.md#translating')
            .call(svgIcon('#iD-icon-translate', 'light'))
            .call(tooltip().title(t('help_translate')).placement('top'));

        aboutList
            .append('li')
            .attr('class', 'feature-warning')
            .attr('tabindex', -1)
            .call(uiFeatureInfo(context));

        aboutList
            .append('li')
            .attr('class', 'user-list')
            .attr('tabindex', -1)
            .call(uiContributors(context));

        var photoviewer = content
            .append('div')
            .attr('id', 'photoviewer')
            .classed('al', true)       // 'al'=left,  'ar'=right
            .classed('hide', true);

        photoviewer
            .append('button')
            .attr('class', 'thumb-hide')
            .on('click', function () {
                if (services.streetside) { services.streetside.hideViewer(); }
                if (services.mapillary) { services.mapillary.hideViewer(); }
                if (services.openstreetcam) { services.openstreetcam.hideViewer(); }
            })
            .append('div')
            .call(svgIcon('#iD-icon-close'));

        photoviewer
            .append('button')
            .attr('class', 'resize-handle-xy')
            .on(
                'mousedown',
                buildResizeListener(photoviewer, 'photoviewerResize', dispatch, { resizeOnX: true, resizeOnY: true })
            );

        photoviewer
            .append('button')
            .attr('class', 'resize-handle-x')
            .on(
                'mousedown',
                buildResizeListener(photoviewer, 'photoviewerResize', dispatch, { resizeOnX: true })
            );

        photoviewer
            .append('button')
            .attr('class', 'resize-handle-y')
            .on(
                'mousedown',
                buildResizeListener(photoviewer, 'photoviewerResize', dispatch, { resizeOnY: true })
            );

        var mapDimensions = map.dimensions();

        // bind events
        window.onbeforeunload = function() {
            return context.save();
        };

        window.onunload = function() {
            context.history().unlock();
        };

        d3_select(window)
            .on('resize.editor', onResize);

        onResize();

        var pa = 80;  // pan amount
        var keybinding = d3_keybinding('main')
            .on('⌫', function() { d3_event.preventDefault(); })
            .on('←', pan([pa, 0]))
            .on('↑', pan([0, pa]))
            .on('→', pan([-pa, 0]))
            .on('↓', pan([0, -pa]))
            .on(['⇧←', uiCmd('⌘←')], pan([mapDimensions[0], 0]))
            .on(['⇧↑', uiCmd('⌘↑')], pan([0, mapDimensions[1]]))
            .on(['⇧→', uiCmd('⌘→')], pan([-mapDimensions[0], 0]))
            .on(['⇧↓', uiCmd('⌘↓')], pan([0, -mapDimensions[1]]));

        d3_select(document)
            .call(keybinding);

        context.enter(modeBrowse(context));

        if (!uiInitCounter++) {
            if (!hash.startWalkthrough) {
                context.container()
                    .call(uiSplash(context))
                    .call(uiRestore(context));
            }

            context.container()
                .call(uiShortcuts(context));
        }

        var osm = context.connection();
        var auth = uiLoading(context).message(t('loading_auth')).blocking(true);

        if (osm && auth) {
            osm
                .on('authLoading.ui', function() {
                    context.container()
                        .call(auth);
                })
                .on('authDone.ui', function() {
                    auth.close();
                });
        }

        uiInitCounter++;

        if (hash.startWalkthrough) {
            hash.startWalkthrough = false;
            context.container().call(uiIntro(context));
        }

        function onResize() {
            mapDimensions = utilGetDimensions(content, true);
            map.dimensions(mapDimensions);

            // shrink photo viewer if it is too big
            // (-90 preserves space at top and bottom of map used by menus)
            var photoDimensions = utilGetDimensions(photoviewer, true);
            if (photoDimensions[0] > mapDimensions[0] || photoDimensions[1] > (mapDimensions[1] - 90)) {
                var setPhotoDimensions = [
                    Math.min(photoDimensions[0], mapDimensions[0]),
                    Math.min(photoDimensions[1], mapDimensions[1] - 90),
                ];

                photoviewer
                    .style('width', setPhotoDimensions[0] + 'px')
                    .style('height', setPhotoDimensions[1] + 'px');

                dispatch.call('photoviewerResize', photoviewer, setPhotoDimensions);
            }
        }

        function pan(d) {
            return function() {
                d3_event.preventDefault();
                context.pan(d, 100);
            };
        }

        function buildResizeListener(target, eventName, dispatch, options) {
            var resizeOnX = !!options.resizeOnX;
            var resizeOnY = !!options.resizeOnY;
            var minHeight = options.minHeight || 240;
            var minWidth = options.minWidth || 320;
            var startX;
            var startY;
            var startWidth;
            var startHeight;

            function startResize() {
                var mapSize = context.map().dimensions();

                if (resizeOnX) {
                    var maxWidth = mapSize[0];
                    var newWidth = clamp((startWidth + d3_event.clientX - startX), minWidth, maxWidth);
                    target.style('width', newWidth + 'px');
                }

                if (resizeOnY) {
                    var maxHeight = mapSize[1] - 90;  // preserve space at top/bottom of map
                    var newHeight = clamp((startHeight + startY - d3_event.clientY), minHeight, maxHeight);
                    target.style('height', newHeight + 'px');
                }

                dispatch.call(eventName, target, utilGetDimensions(target, true));
            }

            function clamp(num, min, max) {
                return Math.max(min, Math.min(num, max));
            }

            function stopResize() {
                d3_select(window)
                    .on('.' + eventName, null);
            }

            return function initResize() {
                startX = d3_event.clientX;
                startY = d3_event.clientY;
                startWidth = target.node().getBoundingClientRect().width;
                startHeight = target.node().getBoundingClientRect().height;

                d3_select(window)
                    .on('mousemove.' + eventName, startResize, false)
                    .on('mouseup.' + eventName, stopResize, false);
            };
        }
    }

    var renderCallback;

    function ui(node, callback) {
        renderCallback = callback;
        var container = d3_select(node);
        context.container(container);
        context.loadLocale(function(err) {
            if (!err) {
                render(container);
            }
            if (callback) {
                callback(err);
            }
        });
    }

    ui.restart = function(arg) {
        context.locale(arg);
        context.loadLocale(function(err) {
            if (!err) {
                context.container().selectAll('*').remove();
                render(context.container());
                if (renderCallback) renderCallback();
            }
        });
    };

    ui.sidebar = uiSidebar(context);

    return utilRebind(ui, dispatch, 'on');
}
<|endoftext|>