<commit_before>import EventEmitter from 'eventemitter3';
import _ from 'lodash';
import { uuidRegExp } from './utils/helpers';

import {
    getUri,
    getParallel,
    getAllContainers,
    getAllNodes,
    getAllTasks,
    getAllServices,
    getAllNodeClusters,
    getWebSocket
    } from './utils/request';

let STARTED = 0;

let SINGLETON;
let CURRENT_SERVICES_URIS;

let PHYSICAL_STRUCT;

let tutumEventHandler = (e) => {
  console.log(e);
};

let nodeOrContainerExists = (arr, value) => {

  for (var i=0, iLen=arr.length; i<iLen; i++) {

    if (arr[i].ID == value) return true;
  }
  return false;
};

let strToHash = (str) => {
  let hash = 0;
  for (let i = 0; i < str.length; i++) {
    hash = str.charCodeAt(i) + ((hash << 5) - hash);
  }
  return hash;
};

let hashToHexColor = (hash) => {
  let color = "#";
  for (var i = 0; i < 3; ) {
    color += ("00" + ((hash >> i++ * 8) & 0xFF).toString(16)).slice(-2);
  }
  return color;
}

let stringToColor = (str) => {
  let hash = strToHash(str);
  let color = hashToHexColor(hash);
  return color;
};

let physicalStructProvider = ([initialNodes, initialContainers]) => {
  let containers = _.map(initialContainers, _.cloneDeep);
  let nodeClusters = [{uuid:"clusterid", name:""}];
  let nodes = _.map(initialNodes, _.cloneDeep);
  let root = [];

  let addContainer = (container) => {
    var cloned = Object.assign({},container);
    let NodeID = cloned.NodeID;
    _.find(root,(cluster) => {
    var node = _.find(cluster.children,{ ID:NodeID });
    if(!node) return;
    var dt = new Date(cloned.UpdatedAt);
    var color =  stringToColor(cloned.ServiceID);
    let serviceName = cloned.ServiceName;
    let imageNameRegex = /([^/]+?)(\:([^/]+))?$/;
    let imageNameMatches = imageNameRegex.exec(cloned.Spec.ContainerSpec.Image);
    let tagName = imageNameMatches[3];
    let dateStamp = dt.getDate()+"/"+(dt.getMonth()+1)+" "+ dt.getHours()+":"+dt.getMinutes();
    let startState=cloned.Status.State;

    let imageTag ="
"+
        ""+ serviceName +""+
        "
 image : " + imageNameMatches[0] +
        "
 tag : " + (tagName ? tagName : "latest") +
        "
" + (cloned.Spec.ContainerSpec.Args?" cmd : "+cloned.Spec.ContainerSpec.Args+"
" : "" ) +
        " updated : " + dateStamp +
        "
"+ cloned.Status.ContainerStatus.ContainerID +
        "
 state : "+startState +
        "
";

    if (node.Spec.Role=='manager')  {
      let containerlink = window.location.href+  "apis/containers/"+cloned.Status.ContainerStatus.ContainerID + "/json";
      cloned.link = containerlink;
    }
    cloned.tag = imageTag;
    cloned.state = startState;

    node.children.push(cloned);
    return true;
  });
},

updateContainer = (container, services) => {
  let {uuid, node} = container;
  let [nodeUuid] = uuidRegExp.exec(node);
  _.find(root,(cluster) => {
    let node = _.findWhere(cluster.children,{ uuid: nodeUuid });
  if(!node) return;

  let target = _.findWhere(node.children,{ uuid }) || {};
  if(!target) return;

  Object.assign(target,container);
  return true;
});
},

data = () => {
  let clone = _.cloneDeep(root);
  _.remove(clone,({uuid,children}) => {
    return uuid === 'BYON' && !children.length
  });

  return {root: clone};
},

addNodeCluster = (nodeCluster) => {
  var cloned = Object.assign({},nodeCluster);
  cloned.children = [];
  console.log(cloned);
  root.push(cloned);
},

removeNodeCluster = (nodeCluster) => {
  _.remove(root,{ uuid: nodeCluster.uuid });
},

updateNodeCluster = (nodeCluster) => {
  var currentCluster = _.findWhere(root,{ uuid: nodeCluster.uuid });
  Object.assign(currentCluster,nodeCluster);
},

addNode = (node) => {
  let cloned = Object.assign({},node);
  cloned.children = [];
  console.log(cloned);
  let clusterUuid = "clusterid";
  let cluster = _.findWhere(root,{ uuid: clusterUuid });
  if(cluster) cluster.children.push(cloned);
},
updateNode = (node, state,spec) => {
  node.state = state;
  node.Spec = spec;
},
updateData = (resources) => {
  updateNodes(resources[0]);

  updateContainers(resources[1], resources[2]);
  data();
},
updateNodes = (nodes) => {
  //console.log(nodes);
  let currentnodelist = root[0].children;
  for (let node of nodes) {
    if(!nodeOrContainerExists(currentnodelist,node.ID)) {
      updateNode(node,'ready');

      addNode(node);
    } else {
      for (let currentnode of currentnodelist) {
        if (node.ID == currentnode.ID) {
          name = node.Description.Hostname;
          if(name.length>0) {
            currentnode.Description.Hostname = name ;
            currentnode.name = name+"
 "+ node.Spec.Role+
            "
"+(currentnode.Description.Resources.MemoryBytes/1024/1024/1024).toFixed(0)+"G RAM";
          }
          updateNode(currentnode, node.state, node.Spec);
        }
      }

    }
  }
  for (let node of currentnodelist) {
    if(!nodeOrContainerExists(nodes,node.ID)){
      updateNode(node,'down');
    }
  }
},
updateContainers = (containers, services) => {
  let nodes = root[0].children;
  for (let container of containers) {
    let contNodeId = container.NodeID;
    let service = _.find(services, function(o) { return o.ID == container.ServiceID; });
    container.ServiceName = service.Spec.Name;
    for (var i=0, iLen=nodes.length; i<iLen; i++) {
      if (nodes[i].ID == contNodeId) {
        while(nodeOrContainerExists(nodes[i].children,container.ID)){
          let index = nodes[i].children.indexOf(container);
          nodes[i].children.splice(index,1);
        }
        addContainer(container);
      }
    }

  }
  for(let node of nodes) {
    for(let container of node.children) {
      if(!nodeOrContainerExists(containers,container.ID)){
        let index = node.children.indexOf(container);
        node.children.splice(index,1);
      }
    }
  }

};

nodeClusters.forEach(addNodeCluster);
nodes.forEach(addNode);

containers.forEach(addContainer);

return {
  addContainer,
  updateData,
  updateContainer,
  data,
  addNode,
  updateNode,
  addNodeCluster,
  removeNodeCluster,
  updateNodeCluster,
};
}

class DataProvider extends EventEmitter {
  constructor() {
    super()
  }

  start() {
    STARTED = 1;
    //console.log(STARTED);
    var clusterInit = Promise.all([
          getAllNodes(),
          getAllTasks(),
          getAllServices()
        ])
            .then((resources) => {
          _.remove(resources[1],(nc) => nc.state === 'Empty cluster' || nc.state === 'Terminated');
    return resources;
  });

  Promise.all([ clusterInit ])
.then(([resources]) => {
  PHYSICAL_STRUCT = physicalStructProvider(resources);
      this.emit('infrastructure-data',PHYSICAL_STRUCT.data());
      this.emit('start-reload');
});
}

reload() {
  if(STARTED == 0) return;
  STARTED++;

  // console.log(STARTED);
  var clusterInit = Promise.all([
        getAllNodes(),
        getAllTasks(),
        getAllServices()
      ])
          .then((resources) => {
        _.remove(resources[1],(nc) => nc.state === 'Empty cluster' || nc.state === 'Terminated');
  return resources;
});

Promise.all([ clusterInit ])
    .then(([resources]) => {
      if (!PHYSICAL_STRUCT)
        PHYSICAL_STRUCT = physicalStructProvider(resources);
  PHYSICAL_STRUCT.updateData(resources);
this.emit('infrastructure-data', PHYSICAL_STRUCT.data());
});
}
}

export default SINGLETON = new DataProvider();
<commit_msg>Fixes issue while updating containers<commit_after>import EventEmitter from 'eventemitter3';
import _ from 'lodash';
import { uuidRegExp } from './utils/helpers';

import {
    getUri,
    getParallel,
    getAllContainers,
    getAllNodes,
    getAllTasks,
    getAllServices,
    getAllNodeClusters,
    getWebSocket
    } from './utils/request';

let STARTED = 0;

let SINGLETON;
let CURRENT_SERVICES_URIS;

let PHYSICAL_STRUCT;

let tutumEventHandler = (e) => {
  console.log(e);
};

let nodeOrContainerExists = (arr, value) => {

  for (var i=0, iLen=arr.length; i<iLen; i++) {

    if (arr[i].ID == value) return true;
  }
  return false;
};

let strToHash = (str) => {
  let hash = 0;
  for (let i = 0; i < str.length; i++) {
    hash = str.charCodeAt(i) + ((hash << 5) - hash);
  }
  return hash;
};

let hashToHexColor = (hash) => {
  let color = "#";
  for (var i = 0; i < 3; ) {
    color += ("00" + ((hash >> i++ * 8) & 0xFF).toString(16)).slice(-2);
  }
  return color;
}

let stringToColor = (str) => {
  let hash = strToHash(str);
  let color = hashToHexColor(hash);
  return color;
};

let physicalStructProvider = ([initialNodes, initialContainers]) => {
  let containers = _.map(initialContainers, _.cloneDeep);
  let nodeClusters = [{uuid:"clusterid", name:""}];
  let nodes = _.map(initialNodes, _.cloneDeep);
  let root = [];

  let addContainer = (container) => {
    var cloned = Object.assign({},container);
    let NodeID = cloned.NodeID;
    _.find(root,(cluster) => {
    var node = _.find(cluster.children,{ ID:NodeID });
    if(!node) return;
    var dt = new Date(cloned.UpdatedAt);
    var color =  stringToColor(cloned.ServiceID);
    let serviceName = cloned.ServiceName;
    let imageNameRegex = /([^/]+?)(\:([^/]+))?$/;
    let imageNameMatches = imageNameRegex.exec(cloned.Spec.ContainerSpec.Image);
    let tagName = imageNameMatches[3];
    let dateStamp = dt.getDate()+"/"+(dt.getMonth()+1)+" "+ dt.getHours()+":"+dt.getMinutes();
    let startState=cloned.Status.State;

    let imageTag ="
"+
        ""+ serviceName +""+
        "
 image : " + imageNameMatches[0] +
        "
 tag : " + (tagName ? tagName : "latest") +
        "
" + (cloned.Spec.ContainerSpec.Args?" cmd : "+cloned.Spec.ContainerSpec.Args+"
" : "" ) +
        " updated : " + dateStamp +
        "
"+ cloned.Status.ContainerStatus.ContainerID +
        "
 state : "+startState +
        "
";

    if (node.Spec.Role=='manager')  {
      let containerlink = window.location.href+  "apis/containers/"+cloned.Status.ContainerStatus.ContainerID + "/json";
      cloned.link = containerlink;
    }
    cloned.tag = imageTag;
    cloned.state = startState;

    node.children.push(cloned);
    return true;
  });
},

updateContainer = (container, services) => {
  let {uuid, node} = container;
  let [nodeUuid] = uuidRegExp.exec(node);
  _.find(root,(cluster) => {
    let node = _.findWhere(cluster.children,{ uuid: nodeUuid });
  if(!node) return;

  let target = _.findWhere(node.children,{ uuid }) || {};
  if(!target) return;

  Object.assign(target,container);
  return true;
});
},

data = () => {
  let clone = _.cloneDeep(root);
  _.remove(clone,({uuid,children}) => {
    return uuid === 'BYON' && !children.length
  });

  return {root: clone};
},

addNodeCluster = (nodeCluster) => {
  var cloned = Object.assign({},nodeCluster);
  cloned.children = [];
  root.push(cloned);
},

removeNodeCluster = (nodeCluster) => {
  _.remove(root,{ uuid: nodeCluster.uuid });
},

updateNodeCluster = (nodeCluster) => {
  var currentCluster = _.findWhere(root,{ uuid: nodeCluster.uuid });
  Object.assign(currentCluster,nodeCluster);
},

addNode = (node) => {
  let cloned = Object.assign({},node);
  cloned.children = [];
  let clusterUuid = "clusterid";
  let cluster = _.findWhere(root,{ uuid: clusterUuid });
  if(cluster) cluster.children.push(cloned);
},
updateNode = (node, state,spec) => {
  node.state = state;
  node.Spec = spec;
},
updateData = (resources) => {
  updateNodes(resources[0]);

  updateContainers(resources[1], resources[2]);
  data();
},
updateNodes = (nodes) => {
  let currentnodelist = root[0].children;
  for (let node of nodes) {
    if(!nodeOrContainerExists(currentnodelist,node.ID)) {
      updateNode(node,'ready');

      addNode(node);
    } else {
      for (let currentnode of currentnodelist) {
        if (node.ID == currentnode.ID) {
          name = node.Description.Hostname;
          if(name.length>0) {
            currentnode.Description.Hostname = name ;
            currentnode.name = name+"
 "+ node.Spec.Role+
            "
"+(currentnode.Description.Resources.MemoryBytes/1024/1024/1024).toFixed(0)+"G RAM";
          }
          updateNode(currentnode, node.state, node.Spec);
        }
      }

    }
  }
  for (let node of currentnodelist) {
    if(!nodeOrContainerExists(nodes,node.ID)){
      updateNode(node,'down');
    }
  }
},
updateContainers = (containers, services) => {
  let nodes = root[0].children;
  // clearn all current children before rendering
  for(let node of nodes) {
    node.children = [];
  }

  for (let container of containers) {
    let contNodeId = container.NodeID;
    let service = _.find(services, function(o) { return o.ID == container.ServiceID; });
    container.ServiceName = service.Spec.Name;
    for (var i=0, iLen=nodes.length; i<iLen; i++) {
      if (nodes[i].ID == contNodeId) {
        addContainer(container);
      }
    }

  }

};

nodeClusters.forEach(addNodeCluster);
nodes.forEach(addNode);

containers.forEach(addContainer);

return {
  addContainer,
  updateData,
  updateContainer,
  data,
  addNode,
  updateNode,
  addNodeCluster,
  removeNodeCluster,
  updateNodeCluster,
};
}

class DataProvider extends EventEmitter {
  constructor() {
    super()
  }

  start() {
    STARTED = 1;
    //console.log(STARTED);
    var clusterInit = Promise.all([
          getAllNodes(),
          getAllTasks(),
          getAllServices()
        ])
            .then((resources) => {
          _.remove(resources[1],(nc) => nc.state === 'Empty cluster' || nc.state === 'Terminated');
    return resources;
  });

  Promise.all([ clusterInit ])
.then(([resources]) => {
  PHYSICAL_STRUCT = physicalStructProvider(resources);
      this.emit('infrastructure-data',PHYSICAL_STRUCT.data());
      this.emit('start-reload');
});
}

reload() {
  if(STARTED == 0) return;
  STARTED++;

  // console.log(STARTED);
  var clusterInit = Promise.all([
        getAllNodes(),
        getAllTasks(),
        getAllServices()
      ])
          .then((resources) => {
        _.remove(resources[1],(nc) => nc.state === 'Empty cluster' || nc.state === 'Terminated');
  return resources;
});

Promise.all([ clusterInit ])
    .then(([resources]) => {
      if (!PHYSICAL_STRUCT)
        PHYSICAL_STRUCT = physicalStructProvider(resources);
  PHYSICAL_STRUCT.updateData(resources);
this.emit('infrastructure-data', PHYSICAL_STRUCT.data());
});
}
}

export default SINGLETON = new DataProvider();
<|endoftext|>


<commit_before>(function() {
    Set.prototype.intersection = function(setB) {
        var intersection = new Set();
        for (var elem of setB) {
            if (this.has(elem)) {
                intersection.add(elem);
            }
        }
        return intersection;
    }
    function displaySearchResults(results, store, usedLabels) {
        var searchResults = $('#search-results');
        if (results.length) { // Are there any results?
            var appendString = '';

            appendString += '
';
            for (var i = 0; i < results.length; i++) {  // Iterate over the results
                var item = store[results[i].ref];
                if (item.state == "open") {
                    appendString += '';
                    appendString += '
';
                    appendString += '
';
                    appendString += '
' + item.title + '
';
                    appendString += '
';
                    appendString += '
';

                    appendString += '';
                    appendString += '
' + item.content.substring(0, 250) + '...
'
                    appendString += '
' + item.date + '
'
                    appendString += '';

                    appendString += '
';
                    appendString += '
';
                    itemLabels = new Set(item.label.split(','));
                    appendString += Array.from(itemLabels.intersection(usedLabels).values());
                    appendString += '
';
                    appendString += '
';
                    appendString += '';
                }
            }
            appendString += '
';

            appendString += '
';
            for (var i = 0; i < results.length; i++) {  // Iterate over the results
                var item = store[results[i].ref];
                if (item.state != "open") {
                    appendString += '';
                    appendString += '
';
                    appendString += '
';
                    appendString += '
' + item.title + '
';
                    appendString += '
';
                    appendString += '
';

                    appendString += '';
                    appendString += '
' + item.content.substring(0, 250) + '...
'
                    appendString += '
' + item.date + '
'
                    appendString += '';

                    appendString += '
';
                    appendString += '
';
                    itemLabels = new Set(item.label.split(','));
                    appendString += Array.from(itemLabels.intersection(usedLabels).values());
                    appendString += '
';
                    appendString += '
';
                    appendString += '';
                }
            }
            appendString += '
';

            searchResults.html(appendString);
        } else {
            searchResults.html('
Nessuna segnalazione trovata
');
        }
    }

    function displayAllResults(searchLabel,store) {
        var searchResults = $('#search-results');
        if (Object.keys(store).length) { // Are there any results?
            var appendString = '';

            appendString += '
';
            for (var item of Object.values(store)) {  // Iterate over the results
                if (!searchLabel || $.inArray(searchLabel,item.label.toLowerCase().split(","))>=0) {
                    if (item.state == "open") {
                        appendString += '';
                        appendString += '
';
                        appendString += '
';
                        appendString += '
' + item.title + '
';
                        appendString += '
';
                        appendString += '
';

                        appendString += '';
                        appendString += '
' + item.content.substring(0, 250) + '...
'
                        appendString += '
' + item.date + '
'
                        appendString += '';

                        appendString += '
';
                        appendString += '
';
                        itemLabels = new Set(item.label.split(','));
                        appendString += Array.from(itemLabels.intersection(usedLabels).values());
                        appendString += '
';
                        appendString += '
';
                        appendString += '';
                    }
                }
            }
            appendString += '
';

            appendString += '
';
            for (var item of Object.values(store)) {  // Iterate over the results
                if (!searchLabel || $.inArray(searchLabel,item.label.toLowerCase().split(","))>=0) {
                    if (item.state != "open") {
                        appendString += '';
                        appendString += '
';
                        appendString += '
';
                        appendString += '
' + item.title + '
';
                        appendString += '
';
                        appendString += '
';

                        appendString += '';
                        appendString += '
' + item.content.substring(0, 250) + '...
'
                        appendString += '
' + item.date + '
'
                        appendString += '';

                        appendString += '
';
                        appendString += '
';
                        itemLabels = new Set(item.label.split(','));
                        appendString += Array.from(itemLabels.intersection(usedLabels).values());
                        appendString += '
';
                        appendString += '
';
                        appendString += '';
                    }
                }
            }
            appendString += '
';

            searchResults.html(appendString);
        } else {
            /searchResults.html('
Nessuna segnalazione trovata
');
        }
    }

    function getQueryVariable(variable) {
        var query = window.location.search.substring(1);
        var vars = query.split('&');

        for (var i = 0; i < vars.length; i++) {
            var pair = vars[i].split('=');

            if (pair[0] === variable) {
                return decodeURIComponent(pair[1].replace(/\+/g, '%20'));
            }
        }
    }

    function loadIssue(searchTerm,searchLabel,usedLabels){
        NProgress.start();

        if (searchTerm) {
            for (var key in window.store) { // Add the data to lunr
                if (!searchLabel || $.inArray(searchLabel,window.store[key].label.toLowerCase().split(","))>=0) {
                    idx.addDoc({
                        'id': key,
                        'title': window.store[key].title,
                        'content': window.store[key].content,
                        'state': window.store[key].state,
                        'date': window.store[key].date,
                        'label': window.store[key].label,
                    });
                }
            }
            var results = idx.search(searchTerm,{
                "fields": {
                    "title": {"boost": 10},
                },
                bool: "OR"
            }); // Get elasticlunr to perform a search

            displaySearchResults(results, window.store,usedLabels); // We'll write this in the next section
        } else {
            displayAllResults(searchLabel, window.store,usedLabels); // We'll write this in the next section
        }
        NProgress.done();
    }

    var usedLabels= new Set([ "Alloggi", "acquisto solidale", "Bollettino", "Bufale", "Contatti", "Donazioni", "Fabbisogni", "Notizie Utili", "Raccolte Fondi",]);

    var searchTerm = getQueryVariable('query');
    var searchLabel = getQueryVariable('label');

    if (searchLabel) {
        document.getElementById('labelchoice').value= searchLabel;
        searchLabel=searchLabel.toLowerCase();
    }

    NProgress.start();
    if (searchTerm) {
        document.getElementById('search-box').setAttribute("value", searchTerm);
    }

    // Initalize lunr with the fields it will be searching on. I've given title
    // a boost of 10 to indicate matches on this field are more important.
    var idx = elasticlunr(function () {
        this.use(elasticlunr.it);
        this.addField('title', { boost: 10 });
        this.addField('label');
        this.addField('content');
        this.addField('state');
        this.setRef('id');
    });

    setTimeout( function() {
            if (window.store) {
                    loadIssue(searchTerm,searchLabel,usedLabels); // We'll write this in the next section
            }
    }, 0 );
})();

document.getElementById('search-box').onkeydown = function(e){
   if(e.keyCode == 13){
     NProgress.start();
   }
};
<commit_msg>search: typo<commit_after>(function() {
    Set.prototype.intersection = function(setB) {
        var intersection = new Set();
        for (var elem of setB) {
            if (this.has(elem)) {
                intersection.add(elem);
            }
        }
        return intersection;
    }
    function displaySearchResults(results, store, usedLabels) {
        var searchResults = $('#search-results');
        if (results.length) { // Are there any results?
            var appendString = '';

            appendString += '
';
            for (var i = 0; i < results.length; i++) {  // Iterate over the results
                var item = store[results[i].ref];
                if (item.state == "open") {
                    appendString += '';
                    appendString += '
';
                    appendString += '
';
                    appendString += '
' + item.title + '
';
                    appendString += '
';
                    appendString += '
';

                    appendString += '';
                    appendString += '
' + item.content.substring(0, 250) + '...
'
                    appendString += '
' + item.date + '
'
                    appendString += '';

                    appendString += '
';
                    appendString += '
';
                    itemLabels = new Set(item.label.split(','));
                    appendString += Array.from(itemLabels.intersection(usedLabels).values());
                    appendString += '
';
                    appendString += '
';
                    appendString += '';
                }
            }
            appendString += '
';

            appendString += '
';
            for (var i = 0; i < results.length; i++) {  // Iterate over the results
                var item = store[results[i].ref];
                if (item.state != "open") {
                    appendString += '';
                    appendString += '
';
                    appendString += '
';
                    appendString += '
' + item.title + '
';
                    appendString += '
';
                    appendString += '
';

                    appendString += '';
                    appendString += '
' + item.content.substring(0, 250) + '...
'
                    appendString += '
' + item.date + '
'
                    appendString += '';

                    appendString += '
';
                    appendString += '
';
                    itemLabels = new Set(item.label.split(','));
                    appendString += Array.from(itemLabels.intersection(usedLabels).values());
                    appendString += '
';
                    appendString += '
';
                    appendString += '';
                }
            }
            appendString += '
';

            searchResults.html(appendString);
        } else {
            searchResults.html('
Nessuna segnalazione trovata
');
        }
    }

    function displayAllResults(searchLabel,store) {
        var searchResults = $('#search-results');
        if (Object.keys(store).length) { // Are there any results?
            var appendString = '';

            appendString += '
';
            for (var item of Object.values(store)) {  // Iterate over the results
                if (!searchLabel || $.inArray(searchLabel,item.label.toLowerCase().split(","))>=0) {
                    if (item.state == "open") {
                        appendString += '';
                        appendString += '
';
                        appendString += '
';
                        appendString += '
' + item.title + '
';
                        appendString += '
';
                        appendString += '
';

                        appendString += '';
                        appendString += '
' + item.content.substring(0, 250) + '...
'
                        appendString += '
' + item.date + '
'
                        appendString += '';

                        appendString += '
';
                        appendString += '
';
                        itemLabels = new Set(item.label.split(','));
                        appendString += Array.from(itemLabels.intersection(usedLabels).values());
                        appendString += '
';
                        appendString += '
';
                        appendString += '';
                    }
                }
            }
            appendString += '
';

            appendString += '
';
            for (var item of Object.values(store)) {  // Iterate over the results
                if (!searchLabel || $.inArray(searchLabel,item.label.toLowerCase().split(","))>=0) {
                    if (item.state != "open") {
                        appendString += '';
                        appendString += '
';
                        appendString += '
';
                        appendString += '
' + item.title + '
';
                        appendString += '
';
                        appendString += '
';

                        appendString += '';
                        appendString += '
' + item.content.substring(0, 250) + '...
'
                        appendString += '
' + item.date + '
'
                        appendString += '';

                        appendString += '
';
                        appendString += '
';
                        itemLabels = new Set(item.label.split(','));
                        appendString += Array.from(itemLabels.intersection(usedLabels).values());
                        appendString += '
';
                        appendString += '
';
                        appendString += '';
                    }
                }
            }
            appendString += '
';

            searchResults.html(appendString);
        } else {
            searchResults.html('
Nessuna segnalazione trovata
');
        }
    }

    function getQueryVariable(variable) {
        var query = window.location.search.substring(1);
        var vars = query.split('&');

        for (var i = 0; i < vars.length; i++) {
            var pair = vars[i].split('=');

            if (pair[0] === variable) {
                return decodeURIComponent(pair[1].replace(/\+/g, '%20'));
            }
        }
    }

    function loadIssue(searchTerm,searchLabel,usedLabels){
        NProgress.start();

        if (searchTerm) {
            for (var key in window.store) { // Add the data to lunr
                if (!searchLabel || $.inArray(searchLabel,window.store[key].label.toLowerCase().split(","))>=0) {
                    idx.addDoc({
                        'id': key,
                        'title': window.store[key].title,
                        'content': window.store[key].content,
                        'state': window.store[key].state,
                        'date': window.store[key].date,
                        'label': window.store[key].label,
                    });
                }
            }
            var results = idx.search(searchTerm,{
                "fields": {
                    "title": {"boost": 10},
                },
                bool: "OR"
            }); // Get elasticlunr to perform a search

            displaySearchResults(results, window.store,usedLabels); // We'll write this in the next section
        } else {
            displayAllResults(searchLabel, window.store,usedLabels); // We'll write this in the next section
        }
        NProgress.done();
    }

    var usedLabels= new Set([ "Alloggi", "acquisto solidale", "Bollettino", "Bufale", "Contatti", "Donazioni", "Fabbisogni", "Notizie Utili", "Raccolte Fondi",]);

    var searchTerm = getQueryVariable('query');
    var searchLabel = getQueryVariable('label');

    if (searchLabel) {
        document.getElementById('labelchoice').value= searchLabel;
        searchLabel=searchLabel.toLowerCase();
    }

    NProgress.start();
    if (searchTerm) {
        document.getElementById('search-box').setAttribute("value", searchTerm);
    }

    // Initalize lunr with the fields it will be searching on. I've given title
    // a boost of 10 to indicate matches on this field are more important.
    var idx = elasticlunr(function () {
        this.use(elasticlunr.it);
        this.addField('title', { boost: 10 });
        this.addField('label');
        this.addField('content');
        this.addField('state');
        this.setRef('id');
    });

    setTimeout( function() {
            if (window.store) {
                    loadIssue(searchTerm,searchLabel,usedLabels); // We'll write this in the next section
            }
    }, 0 );
})();

document.getElementById('search-box').onkeydown = function(e){
   if(e.keyCode == 13){
     NProgress.start();
   }
};
<|endoftext|>


<commit_before>$(function() {
    var appID = "28E04352";
    var namespace = "urn:x-cast:codenames.update";
    var session = null;
    var board = null;

    function Board(words) {
        this.words = words;
        this.selectedCards = [];

        var seed = _.shuffle(_.range(25));
        this.currentBlue = (Math.random() > 0.5);
        this.blue = seed.splice(0, 7);
        this.red = seed.splice(0, 7);
        this.assassin = seed.splice(0, 1);
        this.currentBlue ? this.blue.push(seed[0]) : this.red.push(seed[0]);
    }

    if (!chrome.cast || !chrome.cast.isAvailable) {
        setTimeout(initializeCastApi, 1000);
    }

    function initializeCastApi() {
        var request = new chrome.cast.SessionRequest(appID);
        var apiConfig = new chrome.cast.ApiConfig(request, sessionListener, function() {});
        chrome.cast.initialize(apiConfig, onInitSuccess, onError);
    }

    function sessionListener(e) {
        session = e;
    }

    function onInitSuccess() {
        console.log("Successfully initialized");
    }

    function onError(message) {
        console.log(message);
    }

    function initialize() {
      clearBoard();
      createBoard();
    }

    function clearBoard() {
        $(".card").text("");
        $(".card").removeClass("blue-team red-team assassin");
    }

    function createBoard() {
      fetch("../words.txt").then(function(response) {
            response.text().then(function(text) {
                parseWords(text);
                displayBoard();
            });
        });
    }

    function displayBoard() {
      displayCurrent();
      displayTeams();
      displayWords();
      updateReceiver();
      console.log(JSON.stringify(board));
    }

    function parseWords(text) {
        var words = _.shuffle(text.split("\n")).splice(200, 25);
        board = new Board(words);
    }

    function displayCurrent() {
        $(".team-indicator").removeClass("blue-team red-team").addClass(board.currentBlue ? "blue-team" : "red-team");
        $(".team-indicator").text(board.currentBlue? "Blue Team" : "Red Team");
    }

    function displayTeams() {
        $(".card").addClass(function(index, currentClassName) {
            if (board.blue.includes(index)) {
                return "blue-team";
            } else if (board.red.includes(index)) {
                return "red-team";
            } else if (board.assassin.includes(index)) {
                return "assassin";
            }
        });
    }

    function displayWords() {
        $(".card").each(function(index) {
            this.textContent = board.words[index];
        });
    }

    function updateReceiver() {
      session.sendMessage(namespace, JSON.stringify(board));
    }

    initialize();
});<commit_msg>Debugging message sending<commit_after>$(function() {
    var appID = "28E04352";
    var namespace = "urn:x-cast:codenames.update";
    var session = null;
    var board = null;

    function Board(words) {
        this.words = words;
        this.selectedCards = [];

        var seed = _.shuffle(_.range(25));
        this.currentBlue = (Math.random() > 0.5);
        this.blue = seed.splice(0, 7);
        this.red = seed.splice(0, 7);
        this.assassin = seed.splice(0, 1);
        this.currentBlue ? this.blue.push(seed[0]) : this.red.push(seed[0]);
    }

    if (!chrome.cast || !chrome.cast.isAvailable) {
        setTimeout(initializeCastApi, 1000);
    }

    function initializeCastApi() {
        var request = new chrome.cast.SessionRequest(appID);
        var apiConfig = new chrome.cast.ApiConfig(request, sessionListener, function() {});
        chrome.cast.initialize(apiConfig, onInitSuccess, onError);
    }

    function sessionListener(e) {
        session = e;
        updateReceiver();
        console.log(JSON.stringify(board));
        console.log("Found a session!");
    }

    function onInitSuccess() {
        console.log("Successfully initialized");
    }

    function onError(message) {
        console.log(message);
    }

    function initialize() {
      clearBoard();
      createBoard();
    }

    function clearBoard() {
        $(".card").text("");
        $(".card").removeClass("blue-team red-team assassin");
    }

    function createBoard() {
      fetch("../words.txt").then(function(response) {
            response.text().then(function(text) {
                parseWords(text);
                displayBoard();
            });
        });
    }

    function displayBoard() {
      displayCurrent();
      displayTeams();
      displayWords();
    }

    function parseWords(text) {
        var words = _.shuffle(text.split("\n")).splice(200, 25);
        board = new Board(words);
    }

    function displayCurrent() {
        $(".team-indicator").removeClass("blue-team red-team").addClass(board.currentBlue ? "blue-team" : "red-team");
        $(".team-indicator").text(board.currentBlue? "Blue Team" : "Red Team");
    }

    function displayTeams() {
        $(".card").addClass(function(index, currentClassName) {
            if (board.blue.includes(index)) {
                return "blue-team";
            } else if (board.red.includes(index)) {
                return "red-team";
            } else if (board.assassin.includes(index)) {
                return "assassin";
            }
        });
    }

    function displayWords() {
        $(".card").each(function(index) {
            this.textContent = board.words[index];
        });
    }

    function updateReceiver() {
      session.sendMessage(namespace, JSON.stringify(board)).then(function(response) {
        console.log("Successfully sent message.");
      });
    }

    initialize();
});<|endoftext|>


<commit_before>"use strict";

////////////////////////////////////
//
//   Emulator Execution
//
////////////////////////////////////

//must be set > 0
var scaleFactor = 5;
//dom id for canvas element
var renderTarget = "target";

const optionFlags = [
	"tickrate",
	"fillColor",
	"fillColor2",
	"blendColor",
	"backgroundColor",
	"buzzColor",
	"quietColor",
	"shiftQuirks",
	"loadStoreQuirks",
	"vfOrderQuirks",
	"clipQuirks",
	"vBlankQuirks",
	"jumpQuirks",
	"screenRotation",
	"maxSize",
	"touchInputMode",
	"logicQuirks",
	"fontStyle",
]
function unpackOptions(emulator, options) {
	optionFlags.forEach(x => { if (x in options) emulator[x] = options[x] })
	if (options["enableXO"]) emulator.maxSize = 65024 // legacy option
}
function packOptions(emulator) {
	const r = {}
	optionFlags.forEach(x => r[x] = emulator[x])
	return r
}

function setRenderTarget(scale, canvas) {
	scaleFactor = scale;
	renderTarget = canvas;
	var c = document.getElementById(canvas);

	// Remove any existing previous delta frame so first frame is always drawn:
	c.last = undefined;

	var w  = scaleFactor * 128;
	var h  = scaleFactor *  64;

	if (emulator.screenRotation == 90 || emulator.screenRotation == 270) {
		c.width  = h;
		c.height = w;
	}
	else {
		c.width  = w;
		c.height = h;
	}
}

function setTransform(emulator, g) {
	g.setTransform(1, 0, 0, 1, 0, 0);
	var x = scaleFactor * 128;
	var y = scaleFactor *  64;
	switch(emulator.screenRotation) {
		case 90:
			g.rotate(0.5 * Math.PI);
			g.translate(0, -y);
			break;
		case 180:
			g.rotate(1.0 * Math.PI);
			g.translate(-x, -y);
			break;
		case 270:
			g.rotate(1.5 * Math.PI);
			g.translate(-x, 0);
			break;
		default:
			console.assert(emulator.screenRotation === 0, 'Screen rotation not set to 0, 90, 180, or 270. Treating as 0.')
	}
}

function arrayEqual(a, b) {
	var length = a.length;
	if (length !== b.length) { return false; }
	for (var i = 0; i < length; i++) {
		if (a[i] !== b[i]) { return false; }
	}
	return true;
}

function getColor(id) {
	switch(id) {
		case 0: return emulator.backgroundColor;
		case 1: return emulator.fillColor;
		case 2: return emulator.fillColor2;
		case 3: return emulator.blendColor;
	}
	throw "invalid color: " + id;
}

function renderDisplay(emulator) {
	var c = document.getElementById(renderTarget);

	// Canvas rendering can be expensive. Exit out early if nothing has changed.
	var colors = [emulator.backgroundColor, emulator.fillColor, emulator.fillColor2, emulator.blendColor];
	if (c.last !== undefined) {
		if (arrayEqual(c.last.p[0], emulator.p[0]) && arrayEqual(c.last.p[1], emulator.p[1])
				&& arrayEqual(c.last.colors, colors)) {
			return;
		}
		if (c.last.hires !== emulator.hires)
			c.last = undefined;  // full redraw when switching resolution
	}
	var g = c.getContext("2d");
	setTransform(emulator, g);
	var w      = emulator.hires ? 128         : 64;
	var h      = emulator.hires ? 64          : 32;
	var size   = emulator.hires ? scaleFactor : scaleFactor*2;
	var lastPixels = c.last !== undefined? c.last.p: [[], []]

	g.scale(size, size)
	var z = 0;
	for(var y = 0; y < h; ++y) {
		for(var x = 0; x < w; ++x, ++z) {
			var oldColorIdx = lastPixels[0][z] + (lastPixels[1][z] << 1);
			var colorIdx = emulator.p[0][z] + (emulator.p[1][z] << 1);
			if (oldColorIdx !== colorIdx) {
				g.fillStyle = getColor(colorIdx);
				g.fillRect(x, y, 1, 1);
			}
		}
	}
	g.scale(1, 1) //restore scale to 1,1 just in case

	c.last = {
		colors: colors,
		p: [emulator.p[0].slice(), emulator.p[1].slice()],
		hires: emulator.hires,
	};
}

////////////////////////////////////
//
//   Audio Playback
//
////////////////////////////////////

var audio;
var audioNode;
var audioSource;
var audioData;

var AudioBuffer = function(buffer, duration) {
	if (!(this instanceof AudioBuffer)) {
		return new AudioBuffer(buffer, duration);
	}

	this.pointer = 0;
	this.buffer = buffer;
	this.duration = duration;
}

AudioBuffer.prototype.write = function(buffer, index, size) {
	size = Math.max(0, Math.min(size, this.duration))
	if (!size) { return size; }

	this.duration -= size;
	var bufferSize = this.buffer.length;
	var end = index + size;

	for(var i = index; i < end; ++i) {
		buffer[i] = this.buffer[this.pointer++];
		this.pointer %= bufferSize;
	}

	return size;
}

AudioBuffer.prototype.dequeue = function(duration) {
	this.duration -= duration;
}

var FREQ = 4000;
var PITCH_BIAS = 64;

function audioEnable() {
	// this will only work if called directly from a user-generated input handler:
	if (audio && audio.state == 'suspended') audio.resume()
}

function audioSetup() {
	if (!audio) {
		if (typeof AudioContext !== 'undefined') {
			audio = new AudioContext();
		}
		else if (typeof webkitAudioContext !== 'undefined') {
			audio = new webkitAudioContext();
		}
	}
	audioEnable()
	if (audio && !audioNode) {
		audioNode = audio.createScriptProcessor(4096, 1, 1);
		audioNode.gain = audio.createGain();
		audioNode.gain.gain.value = VOLUME ;
		audioNode.onaudioprocess = function(audioProcessingEvent) {
			var outputBuffer = audioProcessingEvent.outputBuffer;
			var outputData = outputBuffer.getChannelData(0);
			var samples_n = outputBuffer.length;
			var index = 0;
			while(audioData.length && index < samples_n) {
				var size = samples_n - index;
				var written = audioData[0].write(outputData, index, size);
				index += written;
				if (written < size) {
					audioData.shift();
				}
			}

			while(index < samples_n) {
				outputData[index++] = 0;
			}
			//the last one can be long sound with high value of buzzer, so always keep it
			if (audioData.length > 1) {
				var audioDataSize = 0;
				var audioBufferSize = audioNode.bufferSize;
				audioData.forEach(function(buffer) { audioDataSize += buffer.duration; })
				while(audioDataSize > audioBufferSize && audioData.length > 1) {
					audioDataSize -= audioData.shift().duration;
				}
			}
		}
		audioData = [];
		audioNode.connect(audioNode.gain);
		audioNode.gain.connect(audio.destination);
		return true;
	}
	if (audio && audioNode) { return true; }
	return false;
}

function stopAudio() {
	if (!audio) { return; }
	if (audioNode) {
		audioNode.disconnect();
		audioNode = null;
	}
	audioData = [];
}

var VOLUME = 0.25;

function playPattern(soundLength,buffer,remainingTime=0,startPos=0,pitch=PITCH_BIAS) {
	if (!audio) { return; }
	audioEnable()

	var freq = FREQ*2**((pitch-PITCH_BIAS)/48);
	var samples = Math.ceil(audio.sampleRate * soundLength);
	var samplesBack = Math.ceil(audio.sampleRate * remainingTime);

	if (remainingTime && audioData.length > 0)
		audioData[audioData.length - 1].dequeue(samplesBack);

	var bufflen = buffer.length * 8;

	var audioBuffer = new Float32Array(samples);

	var step = freq / audio.sampleRate, pos = startPos;
	for(var i = 0, il = samples; i < il; i++) {
		var cell = pos >> 3, shift = pos & 7 ^ 7;
		audioBuffer[i] = buffer[cell] >> shift & 1;
		pos = ( pos + step ) % bufflen;
	}

	audioData.push(new AudioBuffer(audioBuffer, samples));

	return ( startPos + step * ( samples - samplesBack) ) % bufflen;
}

function AudioControl(){
	this.position = 0;
	this.reset = true;
	this.buffer = [];

	this.timer = 0;
	this.pitch = PITCH_BIAS;

	this.refresh = _ => {
		if (this.reset) this.position = 0; this.reset = false;
		if (this.timer == 0) playPattern(_,[0]); // play silence
		else this.position = playPattern(_,this.buffer,0,this.position,this.pitch);
		if((this.timer -= this.timer>0) == 0) this.reset = true;
		while(audioData > 16) audioData.shift();
	}
	this.setTimer = (timer) => {
		if(timer == 0) this.reset = true;
		this.timer = timer;
	}
	this.setBuffer = buffer => this.buffer = buffer;
	this.setPitch = pitch => this.pitch = pitch;
}

function escapeHtml(str) {
    var div = document.createElement('div');
    div.appendChild(document.createTextNode(str));
    return div.innerHTML;
}
<commit_msg>correcting the queue limit<commit_after>"use strict";

////////////////////////////////////
//
//   Emulator Execution
//
////////////////////////////////////

//must be set > 0
var scaleFactor = 5;
//dom id for canvas element
var renderTarget = "target";

const optionFlags = [
	"tickrate",
	"fillColor",
	"fillColor2",
	"blendColor",
	"backgroundColor",
	"buzzColor",
	"quietColor",
	"shiftQuirks",
	"loadStoreQuirks",
	"vfOrderQuirks",
	"clipQuirks",
	"vBlankQuirks",
	"jumpQuirks",
	"screenRotation",
	"maxSize",
	"touchInputMode",
	"logicQuirks",
	"fontStyle",
]
function unpackOptions(emulator, options) {
	optionFlags.forEach(x => { if (x in options) emulator[x] = options[x] })
	if (options["enableXO"]) emulator.maxSize = 65024 // legacy option
}
function packOptions(emulator) {
	const r = {}
	optionFlags.forEach(x => r[x] = emulator[x])
	return r
}

function setRenderTarget(scale, canvas) {
	scaleFactor = scale;
	renderTarget = canvas;
	var c = document.getElementById(canvas);

	// Remove any existing previous delta frame so first frame is always drawn:
	c.last = undefined;

	var w  = scaleFactor * 128;
	var h  = scaleFactor *  64;

	if (emulator.screenRotation == 90 || emulator.screenRotation == 270) {
		c.width  = h;
		c.height = w;
	}
	else {
		c.width  = w;
		c.height = h;
	}
}

function setTransform(emulator, g) {
	g.setTransform(1, 0, 0, 1, 0, 0);
	var x = scaleFactor * 128;
	var y = scaleFactor *  64;
	switch(emulator.screenRotation) {
		case 90:
			g.rotate(0.5 * Math.PI);
			g.translate(0, -y);
			break;
		case 180:
			g.rotate(1.0 * Math.PI);
			g.translate(-x, -y);
			break;
		case 270:
			g.rotate(1.5 * Math.PI);
			g.translate(-x, 0);
			break;
		default:
			console.assert(emulator.screenRotation === 0, 'Screen rotation not set to 0, 90, 180, or 270. Treating as 0.')
	}
}

function arrayEqual(a, b) {
	var length = a.length;
	if (length !== b.length) { return false; }
	for (var i = 0; i < length; i++) {
		if (a[i] !== b[i]) { return false; }
	}
	return true;
}

function getColor(id) {
	switch(id) {
		case 0: return emulator.backgroundColor;
		case 1: return emulator.fillColor;
		case 2: return emulator.fillColor2;
		case 3: return emulator.blendColor;
	}
	throw "invalid color: " + id;
}

function renderDisplay(emulator) {
	var c = document.getElementById(renderTarget);

	// Canvas rendering can be expensive. Exit out early if nothing has changed.
	var colors = [emulator.backgroundColor, emulator.fillColor, emulator.fillColor2, emulator.blendColor];
	if (c.last !== undefined) {
		if (arrayEqual(c.last.p[0], emulator.p[0]) && arrayEqual(c.last.p[1], emulator.p[1])
				&& arrayEqual(c.last.colors, colors)) {
			return;
		}
		if (c.last.hires !== emulator.hires)
			c.last = undefined;  // full redraw when switching resolution
	}
	var g = c.getContext("2d");
	setTransform(emulator, g);
	var w      = emulator.hires ? 128         : 64;
	var h      = emulator.hires ? 64          : 32;
	var size   = emulator.hires ? scaleFactor : scaleFactor*2;
	var lastPixels = c.last !== undefined? c.last.p: [[], []]

	g.scale(size, size)
	var z = 0;
	for(var y = 0; y < h; ++y) {
		for(var x = 0; x < w; ++x, ++z) {
			var oldColorIdx = lastPixels[0][z] + (lastPixels[1][z] << 1);
			var colorIdx = emulator.p[0][z] + (emulator.p[1][z] << 1);
			if (oldColorIdx !== colorIdx) {
				g.fillStyle = getColor(colorIdx);
				g.fillRect(x, y, 1, 1);
			}
		}
	}
	g.scale(1, 1) //restore scale to 1,1 just in case

	c.last = {
		colors: colors,
		p: [emulator.p[0].slice(), emulator.p[1].slice()],
		hires: emulator.hires,
	};
}

////////////////////////////////////
//
//   Audio Playback
//
////////////////////////////////////

var audio;
var audioNode;
var audioSource;
var audioData;

var AudioBuffer = function(buffer, duration) {
	if (!(this instanceof AudioBuffer)) {
		return new AudioBuffer(buffer, duration);
	}

	this.pointer = 0;
	this.buffer = buffer;
	this.duration = duration;
}

AudioBuffer.prototype.write = function(buffer, index, size) {
	size = Math.max(0, Math.min(size, this.duration))
	if (!size) { return size; }

	this.duration -= size;
	var bufferSize = this.buffer.length;
	var end = index + size;

	for(var i = index; i < end; ++i) {
		buffer[i] = this.buffer[this.pointer++];
		this.pointer %= bufferSize;
	}

	return size;
}

AudioBuffer.prototype.dequeue = function(duration) {
	this.duration -= duration;
}

var FREQ = 4000;
var PITCH_BIAS = 64;

function audioEnable() {
	// this will only work if called directly from a user-generated input handler:
	if (audio && audio.state == 'suspended') audio.resume()
}

function audioSetup() {
	if (!audio) {
		if (typeof AudioContext !== 'undefined') {
			audio = new AudioContext();
		}
		else if (typeof webkitAudioContext !== 'undefined') {
			audio = new webkitAudioContext();
		}
	}
	audioEnable()
	if (audio && !audioNode) {
		audioNode = audio.createScriptProcessor(4096, 1, 1);
		audioNode.gain = audio.createGain();
		audioNode.gain.gain.value = VOLUME ;
		audioNode.onaudioprocess = function(audioProcessingEvent) {
			var outputBuffer = audioProcessingEvent.outputBuffer;
			var outputData = outputBuffer.getChannelData(0);
			var samples_n = outputBuffer.length;
			var index = 0;
			while(audioData.length && index < samples_n) {
				var size = samples_n - index;
				var written = audioData[0].write(outputData, index, size);
				index += written;
				if (written < size) {
					audioData.shift();
				}
			}

			while(index < samples_n) {
				outputData[index++] = 0;
			}
			//the last one can be long sound with high value of buzzer, so always keep it
			if (audioData.length > 1) {
				var audioDataSize = 0;
				var audioBufferSize = audioNode.bufferSize;
				audioData.forEach(function(buffer) { audioDataSize += buffer.duration; })
				while(audioDataSize > audioBufferSize && audioData.length > 1) {
					audioDataSize -= audioData.shift().duration;
				}
			}
		}
		audioData = [];
		audioNode.connect(audioNode.gain);
		audioNode.gain.connect(audio.destination);
		return true;
	}
	if (audio && audioNode) { return true; }
	return false;
}

function stopAudio() {
	if (!audio) { return; }
	if (audioNode) {
		audioNode.disconnect();
		audioNode = null;
	}
	audioData = [];
}

var VOLUME = 0.25;

function playPattern(soundLength,buffer,remainingTime=0,startPos=0,pitch=PITCH_BIAS) {
	if (!audio) { return; }
	audioEnable()

	var freq = FREQ*2**((pitch-PITCH_BIAS)/48);
	var samples = Math.ceil(audio.sampleRate * soundLength);
	var samplesBack = Math.ceil(audio.sampleRate * remainingTime);

	if (remainingTime && audioData.length > 0)
		audioData[audioData.length - 1].dequeue(samplesBack);

	var bufflen = buffer.length * 8;

	var audioBuffer = new Float32Array(samples);

	var step = freq / audio.sampleRate, pos = startPos;
	for(var i = 0, il = samples; i < il; i++) {
		var cell = pos >> 3, shift = pos & 7 ^ 7;
		audioBuffer[i] = buffer[cell] >> shift & 1;
		pos = ( pos + step ) % bufflen;
	}

	audioData.push(new AudioBuffer(audioBuffer, samples));

	return ( startPos + step * ( samples - samplesBack) ) % bufflen;
}

function AudioControl(){
	this.position = 0;
	this.reset = true;
	this.buffer = [];

	this.timer = 0;
	this.pitch = PITCH_BIAS;

	this.refresh = _ => {
		if (this.reset) this.position = 0; this.reset = false;
		if (this.timer == 0) playPattern(_,[0]); // play silence
		else this.position = playPattern(_,this.buffer,0,this.position,this.pitch);
		if((this.timer -= this.timer>0) == 0) this.reset = true;
		while(audioData.length > 16) audioData.shift();
	}
	this.setTimer = (timer) => {
		if(timer == 0) this.reset = true;
		this.timer = timer;
	}
	this.setBuffer = buffer => this.buffer = buffer;
	this.setPitch = pitch => this.pitch = pitch;
}

function escapeHtml(str) {
    var div = document.createElement('div');
    div.appendChild(document.createTextNode(str));
    return div.innerHTML;
}
<|endoftext|>


<commit_before>function Solver() {
  this.listen();
  this.events = {};
}

Solver.prototype.passGrid = function(Grid){
	this.grid = Grid;
}

Solver.prototype.on = function (event, callback) {
  if (!this.events[event]) {
    this.events[event] = [];
  }
  this.events[event].push(callback);
};

Solver.prototype.emit = function (event, data) {
  var callbacks = this.events[event];
  if (callbacks) {
    callbacks.forEach(function (callback) {
      callback(data);
    });
  }
};

Solver.prototype.listen = function () {
  var self = this;

  document.addEventListener("keydown", function (event) {
    var modifiers = event.altKey || event.ctrlKey || event.metaKey ||
                    event.shiftKey;

    if (!modifiers) {
      if (event.which == 13) {
        event.preventDefault();
		var direction = self.solve();
        self.emit("move", direction);
      }

      if (event.which === 32) self.restart.bind(self)(event);
    }
  });

  var retry = document.getElementsByClassName("retry-button")[0];
  retry.addEventListener("click", this.restart.bind(this));
  retry.addEventListener("touchend", this.restart.bind(this));
};

Solver.prototype.restart = function (event) {
  event.preventDefault();
  this.emit("restart");
};

Solver.prototype.solve = function(){
    var self = this;
    var xtilecount = 0;
    var ytilecount = 0;
    for (var pos = 0; pos < 4; pos++){
        xtilecount += self.findMerges(pos, 0)//rows
        ytilecount += self.findMerges(pos, 1)//col
    }

    self.checkNextIter();

    if (xtilecount == 0 && ytilecount == 0){
        return Math.floor((Math.random()*4));
        //return self.MovableSpace();
    }else if (xtilecount == ytilecount){
        return Math.floor((Math.random()*4));
    }else{
       var dir = (xtilecount > ytilecount)?0:1;
       return Math.floor((Math.random()*2))*2 +dir;
    }
};

Solver.prototype.checkNextIter = function(){
    next = cloneGrid(this.grid);
    next.insertTile(new Tile({x:0, y:0}, 12));
    alert(next.cellContent({x:0, y:0}).value);
    alert(this.grid.cellContent({x:0, y:0}).value);

};

Solver.prototype.findMerges = function(apos, dir){
    var self = this;
    var counter = 0;
    var length = 1;
    var cellVal = null;
    var cells = [];

    for (var bpos = 0; bpos < 4; bpos ++){
        if (dir == 0){
            cells.push({x:apos, y:bpos});
        }else{
            cells.push({x:bpos, y:apos});
        }
    }

    cells.forEach(function(cell){
        tile = self.grid.cellContent(cell);
        if (tile){
            if (tile.value == cellVal){
                length++;
                if (length%2 == 0){
                    counter++;
                }
            }else{
                length = 1;
                cellVal = tile.value;
            }
        }
    });
    return counter;
};

cloneGrid = function(grid) {
    var copy = new Grid(grid.size);
    for (var x = 0; x < grid.size; x++) {
        for (var y = 0; y < grid.size; y++) {
            if (grid.cellOccupied({x:x,y:y})){
                copy.insertTile(grid.cellContent({x:x, y:y}));
            }
        }
    }
    return copy;
};

<commit_msg>cping and modifying moveTile code from game manager; fixing clone bug<commit_after>function Solver() {
  this.listen();
  this.events = {};
}

Solver.prototype.passGrid = function(Grid){
	this.grid = Grid;
}

Solver.prototype.on = function (event, callback) {
  if (!this.events[event]) {
    this.events[event] = [];
  }
  this.events[event].push(callback);
};

Solver.prototype.emit = function (event, data) {
  var callbacks = this.events[event];
  if (callbacks) {
    callbacks.forEach(function (callback) {
      callback(data);
    });
  }
};

Solver.prototype.listen = function () {
  var self = this;

  document.addEventListener("keydown", function (event) {
    var modifiers = event.altKey || event.ctrlKey || event.metaKey ||
                    event.shiftKey;

    if (!modifiers) {
      if (event.which == 13) {
        event.preventDefault();
		var direction = self.solve();
        self.emit("move", direction);
      }

      if (event.which === 32) self.restart.bind(self)(event);
    }
  });

  var retry = document.getElementsByClassName("retry-button")[0];
  retry.addEventListener("click", this.restart.bind(this));
  retry.addEventListener("touchend", this.restart.bind(this));
};

Solver.prototype.restart = function (event) {
  event.preventDefault();
  this.emit("restart");
};

Solver.prototype.solve = function(){
    var self = this;
    var xtilecount = 0;
    var ytilecount = 0;
    for (var pos = 0; pos < 4; pos++){
        xtilecount += self.findMerges(pos, 0, self.grid)//rows
        ytilecount += self.findMerges(pos, 1, self.grid)//col
    }

    self.checkNextIter();

    if (xtilecount == 0 && ytilecount == 0){
        return Math.floor((Math.random()*4));
        //return self.MovableSpace();
    }else if (xtilecount == ytilecount){
        return Math.floor((Math.random()*4));
    }else{
       var dir = (xtilecount > ytilecount)?0:1;
       return Math.floor((Math.random()*2))*2 +dir;
    }
};

Solver.prototype.checkNextIter = function(){
    next = cloneGrid(this.grid);
    moveTiles(0, next);
    alert(next.cellContent({x:0, y:0}));
    alert(this.grid.cellContent({x:0, y:0}));

};

Solver.prototype.findMerges = function(apos, dir, grid){
    var self = this;
    var counter = 0;
    var length = 1;
    var cellVal = null;
    var cells = [];

    for (var bpos = 0; bpos < 4; bpos ++){
        if (dir == 0){
            cells.push({x:apos, y:bpos});
        }else{
            cells.push({x:bpos, y:apos});
        }
    }

    cells.forEach(function(cell){
        tile = grid.cellContent(cell);
        if (tile){
            if (tile.value == cellVal){
                length++;
                if (length%2 == 0){
                    counter++;
                }
            }else{
                length = 1;
                cellVal = tile.value;
            }
        }
    });
    return counter;
};

cloneGrid = function(grid) {
    var copy = new Grid(grid.size);
    for (var x = 0; x < grid.size; x++) {
        for (var y = 0; y < grid.size; y++) {
            if (grid.cellOccupied({x:x,y:y})){
                oldTile = grid.cellContent({x:x, y:y});
                newTile = new Tile({x:oldTile.x, y:oldTile.y}, oldTile.value);
                copy.insertTile(newTile);
            }
        }
    }
    return copy;
};

moveTiles = function (direction, grid) {
  // 0: up, 1: right, 2:down, 3: left

  var cell, tile;

  var vector     = getVector(direction);
  var traversals = buildTraversals(vector);

  // Save the current tile positions and remove merger information
  prepareTiles(grid);

  // Traverse the grid in the right direction and move tiles
  traversals.x.forEach(function (x) {
    traversals.y.forEach(function (y) {
      cell = { x: x, y: y };
      tile = grid.cellContent(cell);

      if (tile) {
        var positions = findFarthestPosition(cell, vector,grid);
        var next      = grid.cellContent(positions.next);

        // Only one merger per row traversal?
        if (next && next.value === tile.value && !next.mergedFrom) {
          var merged = new Tile(positions.next, tile.value * 2);
          merged.mergedFrom = [tile, next];

          grid.insertTile(merged);
          grid.removeTile(tile);

          tile.updatePosition(positions.next);

        }else{
          moveTile(tile, positions.farthest, grid);
        }
      }
    });
  });
};

getVector = function (direction) {
  // Vectors representing tile movement
  var map = {
    0: { x: 0,  y: -1 }, // up
    1: { x: 1,  y: 0 },  // right
    2: { x: 0,  y: 1 },  // down
    3: { x: -1, y: 0 }   // left
  };

  return map[direction];
};

buildTraversals = function (vector) {
  var traversals = { x: [], y: [] };

  for (var pos = 0; pos < 4; pos++) {
    traversals.x.push(pos);
    traversals.y.push(pos);
  }

  // Always traverse from the farthest cell in the chosen direction
  if (vector.x === 1) traversals.x = traversals.x.reverse();
  if (vector.y === 1) traversals.y = traversals.y.reverse();

  return traversals;
};

prepareTiles = function (grid) {
  grid.eachCell(function (x, y, tile) {
    if (tile) {
      tile.mergedFrom = null;
      tile.savePosition();
    }
  });
};

findFarthestPosition = function (cell, vector, grid) {
  var previous;

  // Progress towards the vector direction until an obstacle is found
  do {
    previous = cell;
    cell     = { x: previous.x + vector.x, y: previous.y + vector.y };
  } while (grid.withinBounds(cell) &&
           grid.cellAvailable(cell));

  return {
    farthest: previous,
    next: cell // Used to check if a merge is required
  };
};

moveTile = function (tile, cell, grid) {
  grid.cells[tile.x][tile.y] = null;
  grid.cells[cell.x][cell.y] = tile;
  tile.updatePosition(cell);
};
<|endoftext|>


<commit_before>'use strict';

function check(){
    // Check if every button has correct solution on it.
    var win = true;
    var loop_counter = 80;
    do{
        if(document.getElementById(loop_counter).value != puzzle[loop_counter]){
            win = false;
            break;
        }
    }while(loop_counter--);

    window.alert(
      win
        ? 'Correct! You win!'
        : 'Incorrect, try again.'
    );
}

function display_number_select(id){
    // Reset button zIndex values.
    var loop_counter = 80;
    do{
        document.getElementById(loop_counter).style.zIndex = 0;
    }while(loop_counter--);

    if(selected_button === -1
      || selected_button != id){
        selected_button = id;

        // Increase zIndex of selected button.
        document.getElementById(selected_button).style.zIndex = 2;

        // Display number-select behind selected button.
        update_number_select(id);
        document.getElementById('number-select').style.display = 'block';

    }else{
        // Hide number select.
        selected_button = -1;
        document.getElementById('number-select').style.display = 'none';
    }
}

function generate_puzzle(skip){
    if(!skip
      && !window.confirm('Generate new puzzle?')){
        return;
    }

    core_storage_save();

    document.getElementById('game-div').style.marginTop = parseInt(
      core_storage_data['y-margin'],
      10
    ) + 'px';

    var first = 0;
    var second = 0;
    var which = 0;

    // Base sudoku puzzle.
    puzzle = [
      8,7,6, 5,4,3, 2,1,9,
      5,4,3, 2,1,9, 8,7,6,
      2,1,9, 8,7,6, 5,4,3,

      7,6,5, 4,3,2, 1,9,8,
      4,3,2, 1,9,8, 7,6,5,
      1,9,8, 7,6,5, 4,3,2,

      6,5,4, 3,2,1, 9,8,7,
      3,2,1, 9,8,7, 6,5,4,
      9,8,7, 6,5,4, 3,2,1,
    ];

    // Switch all instances of two random numbers 100 times.
    var loop_counter = 99;
    do{
        // Pick two different numbers between 1 and 9.
        first = core_random_integer({
          'max': 9,
          'todo': 'ceil',
        });
        do{
            second = core_random_integer({
              'max': 9,
              'todo': 'ceil',
            });
        }while(first === second);

        // Iterate through all buttons and switch those two numbers.
        times = 80;
        do{
            if(puzzle[times] === first){
                puzzle[times] = second;

            }else if(puzzle[times] === second){
                puzzle[times] = first;
            }
        }while(times--);
    }while(loop_counter--);

    // Switch columns between different blocks of 3 columns 100 times.
    loop_counter = 99;
    do{
        // Pick a column number to switch.
        which = core_random_integer({
          'max': 3,
        });

        // Pick two different blocks of 3 columns to switch the selected column number between.
        first = core_random_integer({
          'max': 3,
        });
        do{
            second = core_random_integer({
              'max': 3,
            });
        }while(first === second);

        // Iterate through each value in the selected column.
        // Swap them between the two selected blocks of 3 columns.
        times = 8;
        do{
            var temp = puzzle[9 * times + 3 * first + which];
            puzzle[9 * times + 3 * first + which] = puzzle[9 * times + 3 * second + which];
            puzzle[9 * times + 3 * second + which] = temp;
        }while(times--);
    }while(loop_counter--);

    // Switch columns within a block of 3 columns 100 times.
    loop_counter = 99;
    do{
        // Pick the block of 3 columns in which to switch two columns.
        which = core_random_integer({
          'max': 3,
        });

        // Pick two different columns to switch.
        first = core_random_integer({
          'max': 3,
        });
        do{
            second = core_random_integer({
              'max': 3,
            });
        }while(first === second);

        // Iterate through each value and swap the values between the two selected columns.
        times = 8;
        do{
            var temp = puzzle[9 * times + 3 * which + first];
            puzzle[9 * times + 3 * which + first] = puzzle[9 * times + 3 * which + second];
            puzzle[9 * times + 3 * which + second] = temp;
        }while(times--);
    }while(loop_counter--);

    // Switch random rows within a block of 3 rows 100 times.
    loop_counter = 99;
    do{
        // Pick one of the 3 blocks of 3 rows.
        which = core_random_integer({
          'max': 3,
        });

        // Pick two different rows.
        first = core_random_integer({
          'max': 3,
        });
        do{
            second = core_random_integer({
              'max': 3,
            });
        }while(first === second);

        // Iterate through each value and swap the values between the two selected rows.
        times = 8;
        do{
            var temp = puzzle[which * 27 + first * 9 + times];
            puzzle[which * 27 + first * 9 + times] = puzzle[which * 27 + second * 9 + times];
            puzzle[which * 27 + second * 9 + times] = temp;
        }while(times--);
    }while(loop_counter--);

    // Reset all buttons.
    loop_counter = 80;
    do{
        var element = document.getElementById(loop_counter);
        element.disabled = false;
        element.style.background = '#333';
        element.style.color = '#aaa';
        element.style.position = 'relative';
        element.value = ' ';
    }while(loop_counter--);

    // Add solutions to some random buttons.
    loop_counter = core_storage_data['locked'] - 1;
    if(loop_counter >= 0){
        do{
            first = core_random_integer({
              'max': 81,
            });
            var first_element = document.getElementById(first);
            var element_80 = document.getElementById(80 - first);

            first_element.disabled = true;
            element_80.disabled = true;

            first_element.style.background = '#777';
            element_80.style.background = '#777';

            first_element.style.color = '#000';
            element_80.style.color = '#000';

            first_element.value = puzzle[first];
            element_80.value = puzzle[80 - first];
        }while(loop_counter--);
    }
}

function repo_escape(){
    if(selected_button != -1){
        display_number_select(selected_button);
    }
}

function repo_init(){
    core_repo_init({
      'keybinds': {
        67: {
          'todo': check,
        },
        71: {
          'todo': function(){
              generate_puzzle(false);
          },
        },
      },
      'storage': {
        'locked': 15,
        'y-margin': 50,
      },
      'storage-menu': '

<input id=locked maxlength=2>*2 > Locked
<input id=y-margin>Y Margin
',
      'title': 'Sudoku.htm',
    });

    // Create buttons and add to game-div.
    var loop_counter = 80;
    var output = '';
    do{
        output +=
          '<input class=gridbuttonclickable id='
          + loop_counter
          + ' onclick=display_number_select('
          + loop_counter
          + ') type=button>';
        if(loop_counter % 9 === 0
          && loop_counter !== 0){
            output += '
';
        }
    }while(loop_counter--);
    document.getElementById('game-div').innerHTML = output;

    // Setup margins.
    loop_counter = 8;
    do{
        document.getElementById(3 + 9 * loop_counter).style.marginRight = '5px';
        document.getElementById(27 + loop_counter).style.marginBottom = '5px';
        document.getElementById(54 + loop_counter).style.marginBottom = '5px';
        document.getElementById(6 + 9 * loop_counter).style.marginRight = '5px';
    }while(loop_counter--);

    // Setup number-select.
    document.getElementById('number-select').style.position = 'fixed';
    document.getElementById('number-select').style.zIndex = 1;

    generate_puzzle(true);

    document.getElementById('check').onclick = check;
    document.getElementById('generate').onclick = function(){
        generate_puzzle(false);
    };

    // Setup select-X onclicks.
    loop_counter = 9;
    do{
        document.getElementById('select-' + loop_counter).onclick = function(){
            var id = this.id;
            select_number(id.substring(id.indexOf('-') + 1));
        };
    }while(loop_counter--);

    window.onresize
      = window.onscroll = function(e){
        // Update position of number select if visible.
        if(selected_button != -1){
            update_number_select(selected_button);
        }
    };
}

function select_number(number){
    document.getElementById(selected_button).value = number > 0
      ? number
      : ' ';
    selected_button = -1;
    document.getElementById('number-select').style.display = 'none';
}

function update_number_select(id){
    // Make sure the number select box doesn't go past the left/right edges.
    var xpos = document.getElementById(id).offsetLeft - 100 - window.pageXOffset;
    if(xpos < 0){
        xpos = 0;

    }else if(xpos > window.innerWidth - 150){
        xpos = window.innerWidth - 150;
    }

    var number_select = document.getElementById('number-select');
    number_select.style.left = xpos + 'px';

    // There is no worry of the number select box going past the top/bottom edges.
    number_select.style.top  =
      (document.getElementById(id).offsetTop  - 50 - window.pageYOffset)
      + 'px';
}

var puzzle = [];
var selected_button = -1;
var times = 0;
<commit_msg>removed y-margin<commit_after>'use strict';

function check(){
    // Check if every button has correct solution on it.
    var win = true;
    var loop_counter = 80;
    do{
        if(document.getElementById(loop_counter).value != puzzle[loop_counter]){
            win = false;
            break;
        }
    }while(loop_counter--);

    window.alert(
      win
        ? 'Correct! You win!'
        : 'Incorrect, try again.'
    );
}

function display_number_select(id){
    // Reset button zIndex values.
    var loop_counter = 80;
    do{
        document.getElementById(loop_counter).style.zIndex = 0;
    }while(loop_counter--);

    if(selected_button === -1
      || selected_button != id){
        selected_button = id;

        // Increase zIndex of selected button.
        document.getElementById(selected_button).style.zIndex = 2;

        // Display number-select behind selected button.
        update_number_select(id);
        document.getElementById('number-select').style.display = 'block';

    }else{
        // Hide number select.
        selected_button = -1;
        document.getElementById('number-select').style.display = 'none';
    }
}

function generate_puzzle(skip){
    if(!skip
      && !window.confirm('Generate new puzzle?')){
        return;
    }

    core_storage_save();

    var first = 0;
    var second = 0;
    var which = 0;

    // Base sudoku puzzle.
    puzzle = [
      8,7,6, 5,4,3, 2,1,9,
      5,4,3, 2,1,9, 8,7,6,
      2,1,9, 8,7,6, 5,4,3,

      7,6,5, 4,3,2, 1,9,8,
      4,3,2, 1,9,8, 7,6,5,
      1,9,8, 7,6,5, 4,3,2,

      6,5,4, 3,2,1, 9,8,7,
      3,2,1, 9,8,7, 6,5,4,
      9,8,7, 6,5,4, 3,2,1,
    ];

    // Switch all instances of two random numbers 100 times.
    var loop_counter = 99;
    do{
        // Pick two different numbers between 1 and 9.
        first = core_random_integer({
          'max': 9,
          'todo': 'ceil',
        });
        do{
            second = core_random_integer({
              'max': 9,
              'todo': 'ceil',
            });
        }while(first === second);

        // Iterate through all buttons and switch those two numbers.
        times = 80;
        do{
            if(puzzle[times] === first){
                puzzle[times] = second;

            }else if(puzzle[times] === second){
                puzzle[times] = first;
            }
        }while(times--);
    }while(loop_counter--);

    // Switch columns between different blocks of 3 columns 100 times.
    loop_counter = 99;
    do{
        // Pick a column number to switch.
        which = core_random_integer({
          'max': 3,
        });

        // Pick two different blocks of 3 columns to switch the selected column number between.
        first = core_random_integer({
          'max': 3,
        });
        do{
            second = core_random_integer({
              'max': 3,
            });
        }while(first === second);

        // Iterate through each value in the selected column.
        // Swap them between the two selected blocks of 3 columns.
        times = 8;
        do{
            var temp = puzzle[9 * times + 3 * first + which];
            puzzle[9 * times + 3 * first + which] = puzzle[9 * times + 3 * second + which];
            puzzle[9 * times + 3 * second + which] = temp;
        }while(times--);
    }while(loop_counter--);

    // Switch columns within a block of 3 columns 100 times.
    loop_counter = 99;
    do{
        // Pick the block of 3 columns in which to switch two columns.
        which = core_random_integer({
          'max': 3,
        });

        // Pick two different columns to switch.
        first = core_random_integer({
          'max': 3,
        });
        do{
            second = core_random_integer({
              'max': 3,
            });
        }while(first === second);

        // Iterate through each value and swap the values between the two selected columns.
        times = 8;
        do{
            var temp = puzzle[9 * times + 3 * which + first];
            puzzle[9 * times + 3 * which + first] = puzzle[9 * times + 3 * which + second];
            puzzle[9 * times + 3 * which + second] = temp;
        }while(times--);
    }while(loop_counter--);

    // Switch random rows within a block of 3 rows 100 times.
    loop_counter = 99;
    do{
        // Pick one of the 3 blocks of 3 rows.
        which = core_random_integer({
          'max': 3,
        });

        // Pick two different rows.
        first = core_random_integer({
          'max': 3,
        });
        do{
            second = core_random_integer({
              'max': 3,
            });
        }while(first === second);

        // Iterate through each value and swap the values between the two selected rows.
        times = 8;
        do{
            var temp = puzzle[which * 27 + first * 9 + times];
            puzzle[which * 27 + first * 9 + times] = puzzle[which * 27 + second * 9 + times];
            puzzle[which * 27 + second * 9 + times] = temp;
        }while(times--);
    }while(loop_counter--);

    // Reset all buttons.
    loop_counter = 80;
    do{
        var element = document.getElementById(loop_counter);
        element.disabled = false;
        element.style.background = '#333';
        element.style.color = '#aaa';
        element.style.position = 'relative';
        element.value = ' ';
    }while(loop_counter--);

    // Add solutions to some random buttons.
    loop_counter = core_storage_data['locked'] - 1;
    if(loop_counter >= 0){
        do{
            first = core_random_integer({
              'max': 81,
            });
            var first_element = document.getElementById(first);
            var element_80 = document.getElementById(80 - first);

            first_element.disabled = true;
            element_80.disabled = true;

            first_element.style.background = '#777';
            element_80.style.background = '#777';

            first_element.style.color = '#000';
            element_80.style.color = '#000';

            first_element.value = puzzle[first];
            element_80.value = puzzle[80 - first];
        }while(loop_counter--);
    }
}

function repo_escape(){
    if(selected_button != -1){
        display_number_select(selected_button);
    }
}

function repo_init(){
    core_repo_init({
      'keybinds': {
        67: {
          'todo': check,
        },
        71: {
          'todo': function(){
              generate_puzzle(false);
          },
        },
      },
      'storage': {
        'locked': 15,
      },
      'storage-menu': '

<input id=locked maxlength=2>*2 > Locked
',
      'title': 'Sudoku.htm',
    });

    // Create buttons and add to game-div.
    var loop_counter = 80;
    var output = '';
    do{
        output +=
          '<input class=gridbuttonclickable id='
          + loop_counter
          + ' onclick=display_number_select('
          + loop_counter
          + ') type=button>';
        if(loop_counter % 9 === 0
          && loop_counter !== 0){
            output += '
';
        }
    }while(loop_counter--);
    document.getElementById('game-div').innerHTML = output;

    // Setup margins.
    loop_counter = 8;
    do{
        document.getElementById(3 + 9 * loop_counter).style.marginRight = '5px';
        document.getElementById(27 + loop_counter).style.marginBottom = '5px';
        document.getElementById(54 + loop_counter).style.marginBottom = '5px';
        document.getElementById(6 + 9 * loop_counter).style.marginRight = '5px';
    }while(loop_counter--);

    // Setup number-select.
    document.getElementById('number-select').style.position = 'fixed';
    document.getElementById('number-select').style.zIndex = 1;

    generate_puzzle(true);

    document.getElementById('check').onclick = check;
    document.getElementById('generate').onclick = function(){
        generate_puzzle(false);
    };

    // Setup select-X onclicks.
    loop_counter = 9;
    do{
        document.getElementById('select-' + loop_counter).onclick = function(){
            var id = this.id;
            select_number(id.substring(id.indexOf('-') + 1));
        };
    }while(loop_counter--);

    window.onresize
      = window.onscroll = function(e){
        // Update position of number select if visible.
        if(selected_button != -1){
            update_number_select(selected_button);
        }
    };
}

function select_number(number){
    document.getElementById(selected_button).value = number > 0
      ? number
      : ' ';
    selected_button = -1;
    document.getElementById('number-select').style.display = 'none';
}

function update_number_select(id){
    // Make sure the number select box doesn't go past the left/right edges.
    var xpos = document.getElementById(id).offsetLeft - 100 - window.pageXOffset;
    if(xpos < 0){
        xpos = 0;

    }else if(xpos > window.innerWidth - 150){
        xpos = window.innerWidth - 150;
    }

    var number_select = document.getElementById('number-select');
    number_select.style.left = xpos + 'px';

    // There is no worry of the number select box going past the top/bottom edges.
    number_select.style.top  =
      (document.getElementById(id).offsetTop  - 50 - window.pageYOffset)
      + 'px';
}

var puzzle = [];
var selected_button = -1;
var times = 0;
<|endoftext|>


<commit_before>var common = require('./common');

exports.roll_dice = function (frag, post, extra) {
	var ms = frag.split(common.dice_re);
	var dice = [];
	for (var i = 1; i < ms.length; i += 2) {
		var info = common.parse_dice(ms[i]);
		if (!info)
			continue;
		var f = info.faces;
		var rolls = [f];
		for (var j = 0; j < info.n; j++)
			rolls.push(Math.floor(Math.random() * f) + 1);
		if (info.bias)
			rolls.push({bias: info.bias})
		dice.push(rolls);
	}
	if (dice.length) {
		extra.new_dice = dice;
		dice = post.dice ? post.dice.concat(dice) : dice;
		post.dice = dice;
		// Would prefer an appending scheme for adding new rolls but
		// there's no hash value append redis command...
		// I don't want to spill into a separate redis list.
		// Overwriting the whole log every time is quadratic though.
		// TODO: Limit the total number of dice rolls per post
	}
};

exports.inline_dice = function (post, dice) {
	if (dice && dice.length) {
		dice = JSON.stringify(dice);
		post.dice = dice.substring(1, dice.length - 1);
	}
};

exports.extract_dice = function (post) {
	if (!post.dice)
		return;
	try {
		post.dice = JSON.parse('[' + post.dice + ']');
	}
	catch (e) {
		delete post.dice;
	}
};
<commit_msg>Per-post dice roll limit<commit_after>var common = require('./common');

var rollLimit = 5;

exports.roll_dice = function (frag, post, extra) {
	var ms = frag.split(common.dice_re);
	var dice = [];
	for (var i = 1; i < ms.length && dice.length < rollLimit; i += 2) {
		var info = common.parse_dice(ms[i]);
		if (!info)
			continue;
		var f = info.faces;
		var rolls = [f];
		for (var j = 0; j < info.n; j++)
			rolls.push(Math.floor(Math.random() * f) + 1);
		if (info.bias)
			rolls.push({bias: info.bias})
		dice.push(rolls);
	}
	if (dice.length) {
		// Would prefer an appending scheme for adding new rolls but
		// there's no hash value append redis command...
		// I don't want to spill into a separate redis list.
		// Overwriting the whole log every time is quadratic though.
		// Enforcing a roll limit to deter that and for sanity
		var exist = post.dice ? post.dice.length : 0;
		if (dice.length + exist > rollLimit)
			dice = dice.slice(0, Math.max(0, rollLimit - exist));
		if (dice.length) {
			extra.new_dice = dice;
			dice = post.dice ? post.dice.concat(dice) : dice;
			post.dice = dice;
		}
	}
};

exports.inline_dice = function (post, dice) {
	if (dice && dice.length) {
		dice = JSON.stringify(dice);
		post.dice = dice.substring(1, dice.length - 1);
	}
};

exports.extract_dice = function (post) {
	if (!post.dice)
		return;
	try {
		post.dice = JSON.parse('[' + post.dice + ']');
	}
	catch (e) {
		delete post.dice;
	}
};
<|endoftext|>


<commit_before>angular.module('webble', [ 'ui.bootstrap' ])

  // Interaction controller
  .controller('InteractionCtrl', function($scope, $interval) {
    $scope.device = JSON.stringify({}, null, ' ');
    $scope.compatibilityError = 'None';
    $scope.scanError = 'None';
    $scope.isChrome = !!window.chrome && !!window.chrome.webstore;

    $scope.scan = function() {
      try {
        navigator.bluetooth.requestDevice({
          filters: [{
            //name: 'reelyActive'
            //services: ['battery_service', 'heart_rate', 0xfed8, 0xfeed, 0xcbbfe0e1f7f3420684e084cbb3d09dfc]
            services: [0x2a23]
          }]
        })
        .then(device => {
          $scope.device.name = device.name;
          $scope.device.uuids = device.uuids;
          return device.gatt.connect();
        })
        .catch(error => { $scope.scanError = error.toString(); });
      }
      catch(err) {
        $scope.compatibilityError = err.toString();
      }
    }

  });
<commit_msg>Device information service<commit_after>angular.module('webble', [ 'ui.bootstrap' ])

  // Interaction controller
  .controller('InteractionCtrl', function($scope, $interval) {
    $scope.device = JSON.stringify({}, null, ' ');
    $scope.compatibilityError = 'None';
    $scope.scanError = 'None';
    $scope.isChrome = !!window.chrome && !!window.chrome.webstore;

    $scope.scan = function() {
      try {
        navigator.bluetooth.requestDevice({
          filters: [{
            //name: 'reelyActive'
            //services: ['battery_service', 'heart_rate', 0xfed8, 0xfeed, 0xcbbfe0e1f7f3420684e084cbb3d09dfc]
            services: [0x180a]
          }]
        })
        .then(device => {
          $scope.device.name = device.name;
          $scope.device.uuids = device.uuids;
          return device.gatt.connect();
        })
        .catch(error => { $scope.scanError = error.toString(); });
      }
      catch(err) {
        $scope.compatibilityError = err.toString();
      }
    }

  });
<|endoftext|>


<commit_before>'use strict'
let net = require('net')
let http = require('http')
let https = require('http2')

exports.createServer = (opts, handler) => {

    let server = net.createServer(socket => {
        socket.once('data', buffer => {
            // Pause the socket
            socket.pause()

            // Determine if this is an HTTP(s) request
            let byte = buffer[0]
            let protocol
            if (byte === 22) {
                protocol = 'https'
            } else if (32 < byte && byte < 127) {
                protocol = 'http'
            }

            let proxy = server[protocol]
            if (proxy) {
                // Push the buffer back onto the front of the data stream
                socket.unshift(buffer)

                // Emit the socket to the HTTP(s) server
                proxy.emit('connection', socket)
            }

            // As of NodeJS 10.x the socket must be
            // resumed asynchronously or the socket
            // connection hangs, potentially crashing
            // the process. Prior to NodeJS 10.x
            // the socket may be resumed synchronously.
            process.nextTick(() => socket.resume())
        })
    })

    server.http = http.createServer(handler)
    server.https = https.createSecureServer(opts, handler)
    return server
}
<commit_msg>Small improvements<commit_after>'use strict'
let net = require('net')
let http2 = require('http2')

exports.createServer = (opts, handler) => {

    let server = net.createServer(socket => {
        socket.once('data', buffer => {
            // Pause the socket
            socket.pause()

            // Determine if this is an HTTP(s) request
            let byte = buffer[0]
            let protocol
            if (byte === 22) {
                protocol = 'https'
            } else if (32 < byte && byte < 127) {
                protocol = 'http'
            }

            let proxy = server[protocol]
            if (proxy) {
                // Push the buffer back onto the front of the data stream
                socket.unshift(buffer)

                // Emit the socket to the HTTP(s) server
                proxy.emit('connection', socket)
            }

            // As of NodeJS 10.x the socket must be
            // resumed asynchronously or the socket
            // connection hangs, potentially crashing
            // the process. Prior to NodeJS 10.x
            // the socket may be resumed synchronously.
            process.nextTick(() => socket.resume())
        })

        socket.once('end', () => {
            //console.log('server socket end')
        })
    })

    server.http = http2.createServer(handler)
    server.https = http2.createSecureServer(opts, handler)
    return server
}
<|endoftext|>


<commit_before>// To use it create some files under `mocks/`
// e.g. `server/mocks/ember-hamsters.js`
//
// module.exports = function(app) {
//   app.get('/ember-hamsters', function(req, res) {
//     res.send('hello');
//   });
// };

var path = require('path');
var morgan = require('morgan');
var apiWs = require('./api-ws');
var changelog = require('./changelog');
var dav = require('./dav');
var capabilities = require('./dav/capabilities');
var publishing = require('./publishing');
var sandstormPermissions = require('./sandstorm_permissions');

var thumbnail = require('./api/thumbnail');
var fileUpload = require('./api/file-upload');
var downloadDirectory = require('./api/download-directory');
var previewDocument = require('./api/preview-document');

module.exports = function(app, options) {
  var root = path.resolve(process.env.STORAGE_PATH || __dirname + '/../data');

  apiWs.serve(options.httpServer);

  // Log proxy requests
  app.use(morgan('dev'));

  app.use(sandstormPermissions);

  // WebDAV: /remote.php/webdav/*
  var davServer = dav.server(root);
  app.use(davServer);

  app.use('/status.php', capabilities.status);
  app.use('/ocs/v1.php/cloud/capabilities', capabilities.ocs);

  app.use('/api/upload', fileUpload(davServer));
  app.use('/api/thumbnail', thumbnail(davServer));
  app.use('/api/preview', previewDocument(davServer));
  app.get('/api/archive', downloadDirectory(root));

  app.get('/api/publish/info', publishing.getInfo);
  app.post('/api/publish', publishing.publish);
  app.post('/api/unpublish', publishing.unpublish);

  app.get('/changelog', changelog);
};
<commit_msg>Try and fix weird circular dependency problem<commit_after>// To use it create some files under `mocks/`
// e.g. `server/mocks/ember-hamsters.js`
//
// module.exports = function(app) {
//   app.get('/ember-hamsters', function(req, res) {
//     res.send('hello');
//   });
// };

// Try and fix weird circular dependency problem
var jsDAV_Server = require('jsDAV/lib/DAV/server');
var path = require('path');
var morgan = require('morgan');
var apiWs = require('./api-ws');
var changelog = require('./changelog');
var dav = require('./dav');
var capabilities = require('./dav/capabilities');
var publishing = require('./publishing');
var sandstormPermissions = require('./sandstorm_permissions');

var thumbnail = require('./api/thumbnail');
var fileUpload = require('./api/file-upload');
var downloadDirectory = require('./api/download-directory');
var previewDocument = require('./api/preview-document');

module.exports = function(app, options) {
  var root = path.resolve(process.env.STORAGE_PATH || __dirname + '/../data');

  apiWs.serve(options.httpServer);

  // Log proxy requests
  app.use(morgan('dev'));

  app.use(sandstormPermissions);

  // WebDAV: /remote.php/webdav/*
  var davServer = dav.server(root);
  app.use(davServer);

  app.use('/status.php', capabilities.status);
  app.use('/ocs/v1.php/cloud/capabilities', capabilities.ocs);

  app.use('/api/upload', fileUpload(davServer));
  app.use('/api/thumbnail', thumbnail(davServer));
  app.use('/api/preview', previewDocument(davServer));
  app.get('/api/archive', downloadDirectory(root));

  app.get('/api/publish/info', publishing.getInfo);
  app.post('/api/publish', publishing.publish);
  app.post('/api/unpublish', publishing.unpublish);

  app.get('/changelog', changelog);
};
<|endoftext|>