<commit_before>"use strict";
var GenericParser = require('./GenericParser');
var rawer         = require('../../../rawer');
var util          = require('util');
var sha1          = require('sha1');
var split         = require('../../../split');
var unix2dos      = require('../../../unix2dos');
var constants     = require('../../../constants');
var _             = require('underscore');

module.exports = PeerParser;

var BMA_REGEXP = /^BASIC_MERKLED_API( ([a-z_][a-z0-9-_.]+))?( ([0-9.]+))?( ([0-9a-f:]+))?( ([0-9]+))$/;

function PeerParser (onError) {

  var captures = [
    {prop: "version",           regexp: /Version: (.*)/},
    {prop: "currency",          regexp: /Currency: (.*)/},
    {prop: "pubkey",            regexp: /PublicKey: (.*)/},
    {prop: "block",             regexp: constants.PEER.BLOCK},
    {prop: "endpoints",         regexp: /Endpoints:\n([\s\S]*)/, parser: split("\n")},
  ];
  var multilineFields = [];
  GenericParser.call(this, captures, multilineFields, rawer.getPeer, onError);

  this._clean = function (obj) {
    obj.documentType = 'peer';
    obj.endpoints = obj.endpoints || [];
    // Removes trailing space
    if (obj.endpoints.length > 0)
      obj.endpoints.splice(obj.endpoints.length - 1, 1);
    // Removes trailing signature
    if (obj.endpoints.length > 0)
      obj.endpoints.splice(obj.endpoints.length - 1, 1);
    obj.getBMA = function() {
      var bma = null;
      obj.endpoints.forEach(function(ep){
        var matches = !bma && ep.match(BMA_REGEXP);
        if (matches) {
          bma = {
            "dns": matches[2] || '',
            "ipv4": matches[4] || '',
            "ipv6": matches[6] || '',
            "port": matches[8] || 9101
          };
        }
      });
      return bma || {};
    };
  };

  this._verify = function(obj){
    var err = null;
    var code = 150;
    var codes = {
      'BAD_VERSION': 150,
      'BAD_CURRENCY': 151,
      'BAD_DNS': 152,
      'BAD_IPV4': 153,
      'BAD_IPV6': 154,
      'BAD_PORT': 155,
      'BAD_FINGERPRINT': 156,
      'BAD_BLOCK': 157,
      'NO_IP_GIVEN': 158
    }
    if(!err){
      // Version
      if(!obj.version || !obj.version.match(/^1$/))
        err = {code: codes.BAD_VERSION, message: "Version unknown"};
    }
    if(!err){
      // PublicKey
      if(!obj.pubkey || !obj.pubkey.match(constants.BASE58))
        err = {code: codes.BAD_FINGERPRINT, message: "Incorrect PublicKey field"};
    }
    if(!err){
      // Block
      if(!obj.block)
        err = {code: codes.BAD_BLOCK, message: "Incorrect Block field"};
    }
    // Basic Merkled API requirements
    var bma = obj.getBMA();
    if(!err){
      // DNS
      if(bma.dns && !bma.dns.match(/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/))
        err = {code: codes.BAD_DNS, message: "Incorrect Dns field"};
    }
    if(!err){
      // IPv4
      if(bma.ipv4 && !bma.ipv4.match(/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/))
        err = {code: codes.BAD_IPV4, message: "Incorrect IPv4 field"};
    }
    if(!err){
      // IPv6
      if(bma.ipv6 && !bma.ipv6.match(/^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/))
        err = {code: codes.BAD_IPV6, message: "Incorrect IPv6 field"};
    }
    if(!err){
      // IP
      if(!bma.ipv4 && !bma.ipv6)
        err = {code: codes.NO_IP_GIVEN, message: "It must be given at least one IP, either v4 or v6"};
    }
    if(!err){
      // Port
      if(bma.port && !(bma.port + "").match(/^\d+$/))
        err = {code: codes.BAD_PORT, message: "Port must be provided and match an integer format"};
    }
    return err && err.message;
  };
}

util.inherits(PeerParser, GenericParser);
<commit_msg>Fix: peers without any IP but with DNS were rejected<commit_after>"use strict";
var GenericParser = require('./GenericParser');
var rawer         = require('../../../rawer');
var util          = require('util');
var sha1          = require('sha1');
var split         = require('../../../split');
var unix2dos      = require('../../../unix2dos');
var constants     = require('../../../constants');
var _             = require('underscore');

module.exports = PeerParser;

var BMA_REGEXP = /^BASIC_MERKLED_API( ([a-z_][a-z0-9-_.]+))?( ([0-9.]+))?( ([0-9a-f:]+))?( ([0-9]+))$/;

function PeerParser (onError) {

  var captures = [
    {prop: "version",           regexp: /Version: (.*)/},
    {prop: "currency",          regexp: /Currency: (.*)/},
    {prop: "pubkey",            regexp: /PublicKey: (.*)/},
    {prop: "block",             regexp: constants.PEER.BLOCK},
    {prop: "endpoints",         regexp: /Endpoints:\n([\s\S]*)/, parser: split("\n")},
  ];
  var multilineFields = [];
  GenericParser.call(this, captures, multilineFields, rawer.getPeer, onError);

  this._clean = function (obj) {
    obj.documentType = 'peer';
    obj.endpoints = obj.endpoints || [];
    // Removes trailing space
    if (obj.endpoints.length > 0)
      obj.endpoints.splice(obj.endpoints.length - 1, 1);
    // Removes trailing signature
    if (obj.endpoints.length > 0)
      obj.endpoints.splice(obj.endpoints.length - 1, 1);
    obj.getBMA = function() {
      var bma = null;
      obj.endpoints.forEach(function(ep){
        var matches = !bma && ep.match(BMA_REGEXP);
        if (matches) {
          bma = {
            "dns": matches[2] || '',
            "ipv4": matches[4] || '',
            "ipv6": matches[6] || '',
            "port": matches[8] || 9101
          };
        }
      });
      return bma || {};
    };
  };

  this._verify = function(obj){
    var err = null;
    var code = 150;
    var codes = {
      'BAD_VERSION': 150,
      'BAD_CURRENCY': 151,
      'BAD_DNS': 152,
      'BAD_IPV4': 153,
      'BAD_IPV6': 154,
      'BAD_PORT': 155,
      'BAD_FINGERPRINT': 156,
      'BAD_BLOCK': 157,
      'NO_IP_GIVEN': 158
    }
    if(!err){
      // Version
      if(!obj.version || !obj.version.match(/^1$/))
        err = {code: codes.BAD_VERSION, message: "Version unknown"};
    }
    if(!err){
      // PublicKey
      if(!obj.pubkey || !obj.pubkey.match(constants.BASE58))
        err = {code: codes.BAD_FINGERPRINT, message: "Incorrect PublicKey field"};
    }
    if(!err){
      // Block
      if(!obj.block)
        err = {code: codes.BAD_BLOCK, message: "Incorrect Block field"};
    }
    // Basic Merkled API requirements
    var bma = obj.getBMA();
    if(!err){
      // DNS
      if(bma.dns && !bma.dns.match(/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/))
        err = {code: codes.BAD_DNS, message: "Incorrect Dns field"};
    }
    if(!err){
      // IPv4
      if(bma.ipv4 && !bma.ipv4.match(/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/))
        err = {code: codes.BAD_IPV4, message: "Incorrect IPv4 field"};
    }
    if(!err){
      // IPv6
      if(bma.ipv6 && !bma.ipv6.match(/^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/))
        err = {code: codes.BAD_IPV6, message: "Incorrect IPv6 field"};
    }
    if(!err){
      // IP
      if(!bma.dns && !bma.ipv4 && !bma.ipv6)
        err = {code: codes.NO_IP_GIVEN, message: "It must be given at least DNS or one IP, either v4 or v6"};
    }
    if(!err){
      // Port
      if(bma.port && !(bma.port + "").match(/^\d+$/))
        err = {code: codes.BAD_PORT, message: "Port must be provided and match an integer format"};
    }
    return err && err.message;
  };
}

util.inherits(PeerParser, GenericParser);
<|endoftext|>


<commit_before>
if(typeof(Storage) == "undefined") {
  // Sorry! No Web Storage support..
  printError('Sorry! No Web Storage support..');
}

var savedTimes = [];

function saveTime() {
  var currentTime = document.getElementById("chronotime").innerHTML
  // savedTimes = localStorage.getItem("savedTimes")
  // if (savedTimes == null) savedTimes = [];
  savedTimes.push(currentTime)
  localStorage.setItem("savedTimes", savedTimes)
  var scroll = document.getElementById('scroll')
  scroll.scrollTop = scroll.scrollHeight;
}

function updateTimes() {
  //savedTimes = localStorage.getItem("savedTimes")
  var table = '';
  for (i = 0; i < savedTimes.length; i++) {
    table += '
'+(i+1)+'	'+savedTimes[i]+'	X
';
  }
  document.getElementById('savedTimes').innerHTML = table
}

function deleteTime(index) {
  savedTimes.splice(parseInt(index), 1);
  updateTimes();
}
<commit_msg>fixed error in windows<commit_after>
if(typeof(Storage) == "undefined") {
  // Sorry! No Web Storage support..
  printError('Sorry! No Web Storage support..');
}

var savedTimes = [];

function saveTime() {
  var currentTime = document.getElementById("chronotime").innerHTML
  // savedTimes = localStorage.getItem("savedTimes")
  // if (savedTimes == null) savedTimes = [];
  savedTimes.push(currentTime)
  //localStorage.setItem("savedTimes", savedTimes)
  var scroll = document.getElementById('scroll')
  scroll.scrollTop = scroll.scrollHeight;
}

function updateTimes() {
  //savedTimes = localStorage.getItem("savedTimes")
  var table = '';
  for (i = 0; i < savedTimes.length; i++) {
    table += '
'+(i+1)+'	'+savedTimes[i]+'	X
';
  }
  document.getElementById('savedTimes').innerHTML = table
}

function deleteTime(index) {
  savedTimes.splice(parseInt(index), 1);
  updateTimes();
}
<|endoftext|>


<commit_before>'use strict';

function add(){
    const key = globalThis.prompt(
      'Key:',
      ''
    );
    if(key === null
      || key.length === 0){
        return;
    }

    const value = globalThis.prompt(
      'Value:',
      ''
    );
    if(value === null){
        return;
    }

    globalThis.localStorage.setItem(
      key,
      value
    );
    refresh();
}

function clearAll(){
    if(!globalThis.confirm('Clear all localStorage items?')){
        return;
    }

    globalThis.localStorage.clear();
    refresh();
}

function exportAll(){
    const exported = {};
    for(const key in globalThis.localStorage){
        if(!globalThis.localStorage.hasOwnProperty(key)){
            continue;
        }

        exported[key] = globalThis.localStorage.getItem(key);
    }

    globalThis.prompt(
      'Exported iterami localStorage:',
      JSON.stringify(exported)
    );
}

function importItems(){
    let json = globalThis.prompt(
      'Import JSON:',
      '{}'
    );
    if(json === null
      || json.length === 0){
        return;
    }

    json = JSON.parse(json);
    for(const key in json){
        globalThis.localStorage.setItem(
          key,
          json[key]
        );
    }
    refresh();
}

function refresh(){
    let keys = [];
    let output = '';

    for(const key in globalThis.localStorage){
        if(!globalThis.localStorage.hasOwnProperty(key)){
            continue;
        }

        keys.push(key);
    }

    keys = core_sort_strings({
      'array': keys,
    });

    for(let key in keys){
        key = keys[key];

        const repository = key.slice(
          0,
          key.indexOf('.htm-') + 4
        );
        const value = globalThis.localStorage.getItem(key);

        output += '
'
          + '' + key + '
<input id="checkbox-'
          + key
          + '" type=checkbox><input onclick="removeItem(\'' + key + '\')" type=button value=X><input onclick="updateItem(\'' + key + '\')" type=button value=Save>'
          + '
Length: ' + value.length
          + '<textarea id="textarea-' + key + '">' + value + '</textarea>';
    }

    document.getElementById('result').innerHTML = output;
}

function removeAll(){
    if(!globalThis.confirm('Remove all iterami localStorage items?')){
        return;
    }

    for(const key in globalThis.localStorage){
        if(!globalThis.localStorage.hasOwnProperty(key)){
            continue;
        }

        globalThis.localStorage.removeItem(key);
    }

    refresh();
}

function removeSelected(){
    if(!globalThis.confirm('Remove selected iterami localStorage items?')){
        return;
    }

    for(const key in globalThis.localStorage){
        if(!globalThis.localStorage.hasOwnProperty(key)){
            continue;
        }

        if(document.getElementById('checkbox-' + key).checked){
            globalThis.localStorage.removeItem(key);
        }
    }

    refresh();
}

function removeItem(key){
    if(!globalThis.confirm('Remove ' + key + '?')){
        return;
    }

    globalThis.localStorage.removeItem(key);
    document.getElementById(key).remove();
}

function updateItem(key){
    if(!globalThis.confirm('Save ' + key + '?')){
        return;
    }

    globalThis.localStorage.setItem(
      key,
      document.getElementById('textarea-' + key).value
    );
}

function selectAll(){
    const inputs = document.getElementsByTagName('input');
    for(const input in inputs){
        if(inputs[input].type === 'checkbox'){
            inputs[input].checked = true;
        }
    }
}
<commit_msg>changed repository to repo<commit_after>'use strict';

function add(){
    const key = globalThis.prompt(
      'Key:',
      ''
    );
    if(key === null
      || key.length === 0){
        return;
    }

    const value = globalThis.prompt(
      'Value:',
      ''
    );
    if(value === null){
        return;
    }

    globalThis.localStorage.setItem(
      key,
      value
    );
    refresh();
}

function clearAll(){
    if(!globalThis.confirm('Clear all localStorage items?')){
        return;
    }

    globalThis.localStorage.clear();
    refresh();
}

function exportAll(){
    const exported = {};
    for(const key in globalThis.localStorage){
        if(!globalThis.localStorage.hasOwnProperty(key)){
            continue;
        }

        exported[key] = globalThis.localStorage.getItem(key);
    }

    globalThis.prompt(
      'Exported iterami localStorage:',
      JSON.stringify(exported)
    );
}

function importItems(){
    let json = globalThis.prompt(
      'Import JSON:',
      '{}'
    );
    if(json === null
      || json.length === 0){
        return;
    }

    json = JSON.parse(json);
    for(const key in json){
        globalThis.localStorage.setItem(
          key,
          json[key]
        );
    }
    refresh();
}

function refresh(){
    let keys = [];
    let output = '';

    for(const key in globalThis.localStorage){
        if(!globalThis.localStorage.hasOwnProperty(key)){
            continue;
        }

        keys.push(key);
    }

    keys = core_sort_strings({
      'array': keys,
    });

    for(let key in keys){
        key = keys[key];

        const repo = key.slice(
          0,
          key.indexOf('.htm-') + 4
        );
        const value = globalThis.localStorage.getItem(key);

        output += '
'
          + '' + key + '
<input id="checkbox-'
          + key
          + '" type=checkbox><input onclick="removeItem(\'' + key + '\')" type=button value=X><input onclick="updateItem(\'' + key + '\')" type=button value=Save>'
          + '
Length: ' + value.length
          + '<textarea id="textarea-' + key + '">' + value + '</textarea>';
    }

    document.getElementById('result').innerHTML = output;
}

function removeAll(){
    if(!globalThis.confirm('Remove all iterami localStorage items?')){
        return;
    }

    for(const key in globalThis.localStorage){
        if(!globalThis.localStorage.hasOwnProperty(key)){
            continue;
        }

        globalThis.localStorage.removeItem(key);
    }

    refresh();
}

function removeSelected(){
    if(!globalThis.confirm('Remove selected iterami localStorage items?')){
        return;
    }

    for(const key in globalThis.localStorage){
        if(!globalThis.localStorage.hasOwnProperty(key)){
            continue;
        }

        if(document.getElementById('checkbox-' + key).checked){
            globalThis.localStorage.removeItem(key);
        }
    }

    refresh();
}

function removeItem(key){
    if(!globalThis.confirm('Remove ' + key + '?')){
        return;
    }

    globalThis.localStorage.removeItem(key);
    document.getElementById(key).remove();
}

function updateItem(key){
    if(!globalThis.confirm('Save ' + key + '?')){
        return;
    }

    globalThis.localStorage.setItem(
      key,
      document.getElementById('textarea-' + key).value
    );
}

function selectAll(){
    const inputs = document.getElementsByTagName('input');
    for(const input in inputs){
        if(inputs[input].type === 'checkbox'){
            inputs[input].checked = true;
        }
    }
}
<|endoftext|>


<commit_before>// GLOBAL VARIABLES
var downloadArea = document.getElementById('downloadArea');
var inputArea = document.getElementById('inputArea');
var jsonArea = document.getElementById('jsonArea');
var transcriptionBox = document.getElementById('transcriptionBox');
var translationBox = document.getElementById('translationBox');

var phrase = {
	transcription: '',
	translation: '',
	words: []
};

// CONSTRUCTORS
function Word(token, gloss, partOfSpeech) {
	this.token = token;
	this.gloss = gloss;
	this.partOfSpeech = partOfSpeech;
};

// GLOBAL FUNCTIONS
function displayDictionary() {

};

function displayInterlinear() {

};

function displayJSON() {
	jsonArea.innerHTML = JSON.stringify(phrase, null, 2);
};

function downloadJSON(){
	// Get the JSON data
	var text = document.getElementById('jsonArea').innerHTML;
	// Encode
	var data = "text/json;charset=utf-8," + encodeURIComponent(text);
	// Create a download link
	document.getElementById('downloadArea').innerHTML = 'Download your data!'
}

// Updates the phrase object, and (re-)renders the JSON, interlinear, and lexicon visualizations
function render() {
	updatePhrase();
	displayJSON();
	displayInterlinear();
	displayDictionary();
};

function updatePhrase() {
	var transcription = transcriptionBox.value;
	var translation = translationBox.value;
	var tokens = transcription.split(/[\u3000 .,!?]/g);

	var words = [];
	tokens.forEach(function(token) {
		var word = new Word(token, '', '');
		words.push(word);
	});
	phrase.words = words;

	phrase.transcription = transcription;
	phrase.translation = translation;
};

// EVENT LISTENERS
inputArea.addEventListener('input', downloadJSON);
window.addEventListener('load', downloadJSON);

inputArea.addEventListener('input', render);
window.addEventListener('load', render);
<commit_msg>Updated code to follow coding practices<commit_after>// GLOBAL VARIABLES
var nodes = {
	downloadArea: document.querySelector('#downloadArea'),
	inputArea: document.querySelector('#inputArea'),
	jsonArea: document.querySelector('#jsonArea'),
	transcriptionBox: document.querySelector('#transcriptionBox'),
	translationBox: document.querySelector('#translationBox')
};

var phrase = {
	transcription: '',
	translation: '',
	words: []
};

// CONSTRUCTORS
function Word(token, gloss, partOfSpeech) {
	this.token = token;
	this.gloss = gloss;
	this.partOfSpeech = partOfSpeech;
};

// GLOBAL FUNCTIONS
function displayDictionary() {

};

function displayInterlinear() {

};

function displayJSON() {
	nodes.jsonArea.innerHTML = JSON.stringify(phrase, null, 2);
};

function downloadJSON(){
	// Get the JSON data
	var text = nodes.jsonArea.innerHTML;
	// Encode
	var data = "text/json;charset=utf-8," + encodeURIComponent(text);
	// Create a download link
	nodes.downloadArea.innerHTML = 'Download your data!'
}

// Updates the phrase object, and (re-)renders the JSON, interlinear, and lexicon visualizations
function render() {
	updatePhrase();
	displayJSON();
	displayInterlinear();
	displayDictionary();
};

function updatePhrase() {
	var transcription = nodes.transcriptionBox.value;
	var translation = nodes.translationBox.value;
	var tokens = transcription.split(/[\u3000 .,!?]/g);

	var words = [];
	tokens.forEach(function(token) {
		var word = new Word(token, '', '');
		words.push(word);
	});
	phrase.words = words;

	phrase.transcription = transcription;
	phrase.translation = translation;
};

// EVENT LISTENERS
nodes.inputArea.addEventListener('input', downloadJSON);
window.addEventListener('load', downloadJSON);

nodes.inputArea.addEventListener('input', render);
window.addEventListener('load', render);
<|endoftext|>


<commit_before>$(function(){
  var toggles = $('.toggle a'),
      codes = $('.code');

  toggles.on("click", function(event){
    event.preventDefault();
    var $this = $(this);

    if (!$this.hasClass("active")) {
      toggles.removeClass("active");
      $this.addClass("active");
      codes.hide().filter(this.hash).show();
    }
  });
  toggles.first().click();
});<commit_msg>remove demo.js<commit_after><|endoftext|>


<commit_before>var demo = (function () {
    var fileInput = document.getElementById('upload'),
        widthInput = document.getElementById('section-width'),
        heightInput = document.getElementById('section-height'),
        pixelateBtn = document.getElementById('pixelate-btn'),

        outputContainer = document.getElementById('output-container'),
            beforeImg = document.getElementById('before'),
            afterImg = document.getElementById('after'),
            downloadLink = document.getElementById('download'),

        errorContainer = document.getElementById('error-container');

    pixelateBtn.addEventListener('click', function () {
        var file = fileInput.files[0];

        hide(errorContainer);

        if (file instanceof File && /\.(jpe?g|png|gif)$/i.test(file.name)) {
            var reader = new FileReader(),
                canvas = document.createElement('canvas'),
                ctx = canvas.getContext('2d');

            reader.addEventListener('load', function () {
                var dataURL = this.result,

                    width,
                    height,

                    pixelator;

                beforeImg.src = dataURL;

                width = beforeImg.width;
                height = beforeImg.height;

                canvas.width = width;
                canvas.height = height;

                ctx.drawImage(beforeImg, 0, 0, width, height);

                pixelator = new Pixelator(ctx.getImageData(0, 0, width, height));

                window.varOnlyForDebug = pixelator.pixelate((widthInput.value | 0) || 10, (heightInput.value | 0) || 10);

                show(outputContainer);
            });

            reader.readAsDataURL(file);
        } else {
            error('As of now, this tool only supports jpg, jpeg, png, and gif files.');
        }
    });

    function error(msg) {
        show(errorContainer);
        hide(outputContainer);

        errorContainer.innerHTML = msg;
    }

    function show(elem) {
        elem.style.display = 'inherit';
    }

    function hide(elem) {
        elem.style.display = 'none';
    }

    return {
        error: error,
        show: show,
        hide: hide
    }; // Nothing to export so far.
})();
<commit_msg>Update demo.js<commit_after>var demo = (function () {
    var fileInput = document.getElementById('upload'),
        widthInput = document.getElementById('section-width'),
        heightInput = document.getElementById('section-height'),
        pixelateBtn = document.getElementById('pixelate-btn'),

        outputContainer = document.getElementById('output-container'),
            beforeImg = document.getElementById('before'),
            afterImg = document.getElementById('after'),
            downloadLink = document.getElementById('download'),

        errorContainer = document.getElementById('error-container');

    pixelateBtn.addEventListener('click', function () {
        var file = fileInput.files[0];

        hide(errorContainer);

        if (file instanceof File && /\.(jpe?g|png|gif)$/i.test(file.name)) {
            var reader = new FileReader(),
                canvas = document.createElement('canvas'),
                ctx = canvas.getContext('2d');

            reader.addEventListener('load', function () {
                var dataURL = this.result,

                    width,
                    height,

                    pixelator;

                beforeImg.src = dataURL;

                width = beforeImg.width;
                height = beforeImg.height;

                canvas.width = width;
                canvas.height = height;

                ctx.drawImage(beforeImg, 0, 0, width, height);

                pixelator = new Pixelator(ctx.getImageData(0, 0, width, height));

                afterImg.src = pixelator.pixelate((widthInput.value | 0) || 10, (heightInput.value | 0) || 10).canvas.toDataURL('image/png', 1);

                show(outputContainer);
            });

            reader.readAsDataURL(file);
        } else {
            error('As of now, this tool only supports jpg, jpeg, png, and gif files.');
        }
    });

    function error(msg) {
        show(errorContainer);
        hide(outputContainer);

        errorContainer.innerHTML = msg;
    }

    function show(elem) {
        elem.style.display = 'inherit';
    }

    function hide(elem) {
        elem.style.display = 'none';
    }

    return {
        error: error,
        show: show,
        hide: hide
    }; // Nothing to export so far.
})();
<|endoftext|>


<commit_before>/*
 Highcharts JS v4.2.3 (2016-02-08)
 Exporting module

 (c) 2010-2016 Torstein Honsi

 License: www.highcharts.com/license
*/
(function(f){typeof module==="object"&&module.exports?module.exports=f:f(Highcharts)})(function(f){var r=f.win,m=r.document,A=f.Chart,t=f.addEvent,B=f.removeEvent,C=f.fireEvent,n=f.createElement,s=f.discardElement,v=f.css,l=f.merge,i=f.each,q=f.extend,F=f.splat,G=Math.max,H=f.isTouchDevice,I=f.Renderer.prototype.symbols,y=f.getOptions(),z;q(y.lang,{printChart:"Print chart",downloadPNG:"Download PNG image",downloadJPEG:"Download JPEG image",downloadPDF:"Download PDF document",downloadSVG:"Download SVG vector image",
contextButtonTitle:"Chart context menu"});y.navigation={menuStyle:{border:"1px solid #A0A0A0",background:"#FFFFFF",padding:"5px 0"},menuItemStyle:{padding:"0 10px",background:"none",color:"#303030",fontSize:H?"14px":"11px"},menuItemHoverStyle:{background:"#4572A5",color:"#FFFFFF"},buttonOptions:{symbolFill:"#E0E0E0",symbolSize:14,symbolStroke:"#666",symbolStrokeWidth:3,symbolX:12.5,symbolY:10.5,align:"right",buttonSpacing:3,height:22,theme:{fill:"white",stroke:"none"},verticalAlign:"top",width:24}};
y.exporting={type:"image/png",url:"http://export.highcharts.com/",buttons:{contextButton:{menuClassName:"highcharts-contextmenu",symbol:"menu",_titleKey:"contextButtonTitle",menuItems:[{textKey:"printChart",onclick:function(){this.print()}},{separator:!0},{textKey:"downloadPNG",onclick:function(){this.exportChart()}},{textKey:"downloadJPEG",onclick:function(){this.exportChart({type:"image/jpeg"})}},{textKey:"downloadPDF",onclick:function(){this.exportChart({type:"application/pdf"})}},{textKey:"downloadSVG",
onclick:function(){this.exportChart({type:"image/svg+xml"})}}]}}};f.post=function(a,b,e){var c,a=n("form",l({method:"post",action:a,enctype:"multipart/form-data"},e),{display:"none"},m.body);for(c in b)n("input",{type:"hidden",name:c,value:b[c]},null,a);a.submit();s(a)};q(A.prototype,{sanitizeSVG:function(a){return a.replace(/zIndex="[^"]+"/g,"").replace(/isShadow="[^"]+"/g,"").replace(/symbolName="[^"]+"/g,"").replace(/jQuery[0-9]+="[^"]+"/g,"").replace(/url\([^#]+#/g,"url(#").replace(/<svg /,'<svg xmlns:xlink="http://www.w3.org/1999/xlink" ').replace(/ (NS[0-9]+\:)?href=/g,
" xlink:href=").replace(/\n/," ").replace(/<\/svg>.*?$/,"</svg>").replace(/(fill|stroke)="rgba\(([ 0-9]+,[ 0-9]+,[ 0-9]+),([ 0-9\.]+)\)"/g,'$1="rgb($2)" $1-opacity="$3"').replace(/ /g,"\u00a0").replace(//g,"\u00ad").replace(/<IMG /g,"<image ").replace(/<(\/?)TITLE>/g,"<$1title>").replace(/height=([^" ]+)/g,'height="$1"').replace(/width=([^" ]+)/g,'width="$1"').replace(/hc-svg-href="([^"]+)">/g,'xlink:href="$1"/>').replace(/ id=([^" >]+)/g,' id="$1"').replace(/class=([^" >]+)/g,'class="$1"').replace(/ transform /g,
" ").replace(/:(path|rect)/g,"$1").replace(/style="([^"]+)"/g,function(b){return b.toLowerCase()})},getChartHTML:function(){return this.container.innerHTML},getSVG:function(a){var b=this,e,c,g,j,k,d=l(b.options,a),J=d.exporting.allowHTML;if(!m.createElementNS)m.createElementNS=function(b,a){return m.createElement(a)};c=n("div",null,{position:"absolute",top:"-9999em",width:b.chartWidth+"px",height:b.chartHeight+"px"},m.body);g=b.renderTo.style.width;k=b.renderTo.style.height;g=d.exporting.sourceWidth||
d.chart.width||/px$/.test(g)&&parseInt(g,10)||600;k=d.exporting.sourceHeight||d.chart.height||/px$/.test(k)&&parseInt(k,10)||400;q(d.chart,{animation:!1,renderTo:c,forExport:!0,renderer:"SVGRenderer",width:g,height:k});d.exporting.enabled=!1;delete d.data;d.series=[];i(b.series,function(a){j=l(a.userOptions,{animation:!1,enableMouseTracking:!1,showCheckbox:!1,visible:a.visible});j.isInternal||d.series.push(j)});a&&i(["xAxis","yAxis"],function(b){i(F(a[b]),function(a,c){d[b][c]=l(d[b][c],a)})});e=
new f.Chart(d,b.callback);i(["xAxis","yAxis"],function(a){i(b[a],function(b,c){var d=e[a][c],f=b.getExtremes(),g=f.userMin,f=f.userMax;d&&(g!==void 0||f!==void 0)&&d.setExtremes(g,f,!0,!1)})});g=e.getChartHTML();d=null;e.destroy();s(c);if(J&&(c=g.match(/<\/svg>(.*?$)/)))c='<foreignObject x="0" y="0" width="200" height="200"><body xmlns="http://www.w3.org/1999/xhtml">'+c[1]+"</body></foreignObject>",g=g.replace("</svg>",c+"</svg>");g=this.sanitizeSVG(g);return g=g.replace(/(url\(#highcharts-[0-9]+)"/g,
"$1").replace(/"/g,"'")},getSVGForExport:function(a,b){var e=this.options.exporting;return this.getSVG(l({chart:{borderRadius:0}},e.chartOptions,b,{exporting:{sourceWidth:a&&a.sourceWidth||e.sourceWidth,sourceHeight:a&&a.sourceHeight||e.sourceHeight}}))},exportChart:function(a,b){var e=this.getSVGForExport(a,b),a=l(this.options.exporting,a);f.post(a.url,{filename:a.filename||"chart",type:a.type,width:a.width||0,scale:a.scale||2,svg:e},a.formAttributes)},print:function(){var a=this,b=a.container,
e=[],c=b.parentNode,f=m.body,j=f.childNodes;if(!a.isPrinting)a.isPrinting=!0,a.pointer.reset(null,0),C(a,"beforePrint"),i(j,function(a,b){if(a.nodeType===1)e[b]=a.style.display,a.style.display="none"}),f.appendChild(b),r.focus(),r.print(),setTimeout(function(){c.appendChild(b);i(j,function(a,b){if(a.nodeType===1)a.style.display=e[b]});a.isPrinting=!1;C(a,"afterPrint")},1E3)},contextMenu:function(a,b,e,c,f,j,k){var d=this,l=d.options.navigation,D=l.menuItemStyle,o=d.chartWidth,p=d.chartHeight,E="cache-"+
a,h=d[E],u=G(f,j),w,x,r,s=function(b){d.pointer.inClass(b.target,a)||x()};if(!h)d[E]=h=n("div",{className:a},{position:"absolute",zIndex:1E3,padding:u+"px"},d.container),w=n("div",null,q({MozBoxShadow:"3px 3px 10px #888",WebkitBoxShadow:"3px 3px 10px #888",boxShadow:"3px 3px 10px #888"},l.menuStyle),h),x=function(){v(h,{display:"none"});k&&k.setState(0);d.openMenu=!1},t(h,"mouseleave",function(){r=setTimeout(x,500)}),t(h,"mouseenter",function(){clearTimeout(r)}),t(m,"mouseup",s),t(d,"destroy",function(){B(m,
"mouseup",s)}),i(b,function(a){if(a){var b=a.separator?n("hr",null,null,w):n("div",{onmouseover:function(){v(this,l.menuItemHoverStyle)},onmouseout:function(){v(this,D)},onclick:function(b){b&&b.stopPropagation();x();a.onclick&&a.onclick.apply(d,arguments)},innerHTML:a.text||d.options.lang[a.textKey]},q({cursor:"pointer"},D),w);d.exportDivElements.push(b)}}),d.exportDivElements.push(w,h),d.exportMenuWidth=h.offsetWidth,d.exportMenuHeight=h.offsetHeight;b={display:"block"};e+d.exportMenuWidth>o?b.right=
o-e-f-u+"px":b.left=e-u+"px";c+j+d.exportMenuHeight>p&&k.alignOptions.verticalAlign!=="top"?b.bottom=p-c-u+"px":b.top=c+j-u+"px";v(h,b);d.openMenu=!0},addButton:function(a){var b=this,e=b.renderer,c=l(b.options.navigation.buttonOptions,a),g=c.onclick,j=c.menuItems,k,d,m={stroke:c.symbolStroke,fill:c.symbolFill},i=c.symbolSize||12;if(!b.btnCount)b.btnCount=0;if(!b.exportDivElements)b.exportDivElements=[],b.exportSVGElements=[];if(c.enabled!==!1){var o=c.theme,p=o.states,n=p&&p.hover,p=p&&p.select,
h;delete o.states;g?h=function(a){a.stopPropagation();g.call(b,a)}:j&&(h=function(){b.contextMenu(d.menuClassName,j,d.translateX,d.translateY,d.width,d.height,d);d.setState(2)});c.text&&c.symbol?o.paddingLeft=f.pick(o.paddingLeft,25):c.text||q(o,{width:c.width,height:c.height,padding:0});d=e.button(c.text,0,0,h,o,n,p).attr({title:b.options.lang[c._titleKey],"stroke-linecap":"round",zIndex:3});d.menuClassName=a.menuClassName||"highcharts-menu-"+b.btnCount++;c.symbol&&(k=e.symbol(c.symbol,c.symbolX-
i/2,c.symbolY-i/2,i,i).attr(q(m,{"stroke-width":c.symbolStrokeWidth||1,zIndex:1})).add(d));d.add().align(q(c,{width:d.width,x:f.pick(c.x,z)}),!0,"spacingBox");z+=(d.width+c.buttonSpacing)*(c.align==="right"?-1:1);b.exportSVGElements.push(d,k)}},destroyExport:function(a){var a=a.target,b,e;for(b=0;b<a.exportSVGElements.length;b++)if(e=a.exportSVGElements[b])e.onclick=e.ontouchstart=null,a.exportSVGElements[b]=e.destroy();for(b=0;b<a.exportDivElements.length;b++)e=a.exportDivElements[b],B(e,"mouseleave"),
a.exportDivElements[b]=e.onmouseout=e.onmouseover=e.ontouchstart=e.onclick=null,s(e)}});I.menu=function(a,b,e,c){return["M",a,b+2.5,"L",a+e,b+2.5,"M",a,b+c/2+0.5,"L",a+e,b+c/2+0.5,"M",a,b+c-1.5,"L",a+e,b+c-1.5]};A.prototype.callbacks.push(function(a){var b,e=a.options.exporting,c=e.buttons;z=0;if(e.enabled!==!1){for(b in c)a.addButton(c[b]);t(a,"destroy",a.destroyExport)}})});
<commit_msg>Delete exporting.js<commit_after><|endoftext|>


<commit_before>            function captureUserMedia(mediaConstraints, successCallback, errorCallback) {
                navigator.mediaDevices.getUserMedia(mediaConstraints).then(successCallback).catch(errorCallback);
            }

            var mediaConstraints = {
                audio: true
            };

		alert("JS demo is applied!");
            $('#start-recording').click(function () {
		alert("Function start is called!");
                this.disabled = true;
                captureUserMedia(mediaConstraints, onMediaSuccess, onMediaError);
            });

            $('#stop-recording').onclick = function() {
                this.disabled = true;
                mediaRecorder.stop();
                mediaRecorder.stream.stop();

                $('#pause-recording').disabled = true;
                $('#start-recording').disabled = false;
            };

            $('#pause-recording').onclick = function() {
                this.disabled = true;
                mediaRecorder.pause();

                $('#resume-recording').disabled = false;
            };

            $('#resume-recording').onclick = function() {
                this.disabled = true;
                mediaRecorder.resume();

                $('#pause-recording').disabled = false;
            };

            $('#save-recording').onclick = function() {
                this.disabled = true;
                mediaRecorder.save();
            };

            var mediaRecorder;

            function onMediaSuccess(stream) {
                var audio = document.createElement('audio');

                audio = mergeProps(audio, {
                    controls: true,
                    muted: true,
                    src: URL.createObjectURL(stream)
                });
                audio.play();

                audiosContainer.appendChild(audio);
                audiosContainer.appendChild(document.createElement('hr'));

                mediaRecorder = new MediaStreamRecorder(stream);
                mediaRecorder.stream = stream;
                mediaRecorder.mimeType = document.getElementById('audio-mimeType').value;
                mediaRecorder.audioChannels = !!document.getElementById('left-channel').checked ? 1 : 2;
                mediaRecorder.ondataavailable = function(blob) {
                    var a = document.createElement('a');
                    a.target = '_blank';
                    a.innerHTML = 'Open Recorded Audio No. ' + (index++) + ' (Size: ' + bytesToSize(blob.size) + ') Time Length: ' + getTimeLength(timeInterval);

                    a.href = URL.createObjectURL(blob);

                    audiosContainer.appendChild(a);
                    audiosContainer.appendChild(document.createElement('hr'));
                };

                var timeInterval = $('#time-interval').value;
                if (timeInterval) timeInterval = parseInt(timeInterval);
                else timeInterval = 5 * 1000;

                // get blob after specific time interval
                mediaRecorder.start(timeInterval);

                $('#stop-recording').disabled = false;
                $('#pause-recording').disabled = false;
                $('#save-recording').disabled = false;
            }

            function onMediaError(e) {
                console.error('media error', e);
            }

            var audiosContainer = document.getElementById('audios-container');
            var index = 1;

            // below function via: http://goo.gl/B3ae8c
            function bytesToSize(bytes) {
                var k = 1000;
                var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
                if (bytes === 0) return '0 Bytes';
                var i = parseInt(Math.floor(Math.log(bytes) / Math.log(k)), 10);
                return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i];
            }

            // below function via: http://goo.gl/6QNDcI
            function getTimeLength(milliseconds) {
                var data = new Date(milliseconds);
                return data.getUTCHours() + " hours, " + data.getUTCMinutes() + " minutes and " + data.getUTCSeconds() + " second(s)";
            }

            window.onbeforeunload = function() {
                $('#start-recording').disabled = false;
            };
<commit_msg>Changed demo.js to jquery Testing<commit_after>            function captureUserMedia(mediaConstraints, successCallback, errorCallback) {
                navigator.mediaDevices.getUserMedia(mediaConstraints).then(successCallback).catch(errorCallback);
            }

            var mediaConstraints = {
                audio: true
            };

		alert("JS demo is applied!");
            $('#start-recording').click(function () {
		alert("Function start is called!");
                this.disabled = true;
                captureUserMedia(mediaConstraints, onMediaSuccess, onMediaError);
            });

            $('#stop-recording').click(function() {
                this.disabled = true;
                mediaRecorder.stop();
                mediaRecorder.stream.stop();

                $('#pause-recording').disabled = true;
                $('#start-recording').disabled = false;
            });

            $('#pause-recording').click(function() {
                this.disabled = true;
                mediaRecorder.pause();

                $('#resume-recording').disabled = false;
            });

            $('#resume-recording').click(function() {
                this.disabled = true;
                mediaRecorder.resume();

                $('#pause-recording').disabled = false;
            });

            $('#save-recording').click(function() {
                this.disabled = true;
                mediaRecorder.save();
            });

            var mediaRecorder;

            function onMediaSuccess(stream) {
                var audio = document.createElement('audio');

                audio = mergeProps(audio, {
                    controls: true,
                    muted: true,
                    src: URL.createObjectURL(stream)
                });
                audio.play();

                audiosContainer.appendChild(audio);
                audiosContainer.appendChild(document.createElement('hr'));

                mediaRecorder = new MediaStreamRecorder(stream);
                mediaRecorder.stream = stream;
                mediaRecorder.mimeType = document.getElementById('audio-mimeType').value;
                mediaRecorder.audioChannels = !!document.getElementById('left-channel').checked ? 1 : 2;
                mediaRecorder.ondataavailable = function(blob) {
                    var a = document.createElement('a');
                    a.target = '_blank';
                    a.innerHTML = 'Open Recorded Audio No. ' + (index++) + ' (Size: ' + bytesToSize(blob.size) + ') Time Length: ' + getTimeLength(timeInterval);

                    a.href = URL.createObjectURL(blob);

                    audiosContainer.appendChild(a);
                    audiosContainer.appendChild(document.createElement('hr'));
                };

                var timeInterval = $('#time-interval').value;
                if (timeInterval) timeInterval = parseInt(timeInterval);
                else timeInterval = 5 * 1000;

                // get blob after specific time interval
                mediaRecorder.start(timeInterval);

                $('#stop-recording').disabled = false;
                $('#pause-recording').disabled = false;
                $('#save-recording').disabled = false;
            }

            function onMediaError(e) {
                console.error('media error', e);
            }

            var audiosContainer = document.getElementById('audios-container');
            var index = 1;

            // below function via: http://goo.gl/B3ae8c
            function bytesToSize(bytes) {
                var k = 1000;
                var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
                if (bytes === 0) return '0 Bytes';
                var i = parseInt(Math.floor(Math.log(bytes) / Math.log(k)), 10);
                return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i];
            }

            // below function via: http://goo.gl/6QNDcI
            function getTimeLength(milliseconds) {
                var data = new Date(milliseconds);
                return data.getUTCHours() + " hours, " + data.getUTCMinutes() + " minutes and " + data.getUTCSeconds() + " second(s)";
            }

            window.onbeforeunload = function() {
                $('#start-recording').disabled = false;
            };
<|endoftext|>


<commit_before>/*
  Copyright (c) 2010  Seneca College
  MIT LICENSE

  Version:  0.1
  Author:   Andor Salga
            asalga.wordpress.com
  Date:     November 16, 2010

  Notes:
  This parser parses .ASC filetypes. These files are ASCII
  files which have their data stored in one of the following ways:

  X, Y, Z
  X, Y, Z, R, G, B
  X, Y, Z, I, J, K
  X, Y, Z, R, G, B, I, J, K
*/

var ASCParser = (function() {

  /**
    Constructor
  */
  function ASCParser(config) {

    var undef;

    // defined once to reduce number of empty functions
    var __empty_func = function(){};

    var start = config.start || __empty_func;
    var parse = config.parse || __empty_func;
    var end = config.end || __empty_func;

    var version = "0.1";

    const UNKNOWN = -1;

    const XHR_DONE = 4;
    const STARTED = 1;

    var pathToFile = null;
    var fileSizeInBytes = 0;

    //
    var numParsedPoints = 0;
    var numTotalPoints = 0;
    var progress = 0;

    //
    var numValuesPerLine = -1;
    var normalsPresent = false;
    var colorsPresent = false;
    var layoutCode = UNKNOWN;

    //
    var parsedVerts = [];
    var parsedCols = [];
    var parsedNorms = [];

    // keep track if onprogress event handler was called to
    // handle Chrome/WebKit vs. Minefield differences.
    //
    // Minefield will call onprogress zero or many times
    // Chrome/WebKit will call onprogress one or many times
    var onProgressCalled = false;
    var AJAX = null;

    // WebGL compatibility wrapper
    try{
      Float32Array;
    }catch(ex){
      Float32Array = WebGLFloatArray;
    }

    /**
      @private

      ASC files can either contain
      X, Y, Z
      X, Y, Z, R,  G,  B
      X, Y, Z, NX, NY, NZ
      X, Y, Z, R,  G,  B, NX, NY, NZ

      @returns {Number}
      0 first case
      1 second case
      2 third case
      3 fourth case
    */
    var getDataLayout = function(values){
      var normalsPresent = false;
      var colorsPresent = false;

      var VERTS = 0;
      var VERTS_COLS = 1;
      var VERTS_NORMS = 2;
      var VERTS_COLS_NORMS = 3;

      // first check if there are 9 values, which would mean we have
      // xyz rgb and normals

      // We can do this by counting the number of whitespace on the first line
      var i = 0;
      var numSpaces = 0;
      do{
        i++;
        if(values[i] == " "){
          numSpaces++;
        }
      }while(values[i] != '\n');

      // Vertices, Colors, Normals:
      // 1.916 -2.421 -4.0   64 32 16   -0.3727 -0.2476 -0.8942
      if(numSpaces === 8){
        return VERTS_COLS_NORMS;
      }

      // Just vertices:
      // 1.916 -2.421 -4.0339
      if(numSpaces == 2){
        return VERTS;
      }

      var str = "";

      //
      // !! fix me
      for(i = 0; i < 500; i++){
        str += values[i];
      }

      var str_split = str.split(/\s+/);
      var data = [];

      for(var i = 3; i < str_split.length;){
        data.push(str_split[i++]);
        data.push(str_split[i++]);
        data.push(str_split[i++]);
        i += 3;
      }

      for(var i = 0; i < data.length; i++){
        if(data[i] < 0 || data[i] > 255){
          normalsPresent = true;
          return VERTS_NORMS;
        }
      }

      // Vertices and Normals:
      // 1.916 -2.421 -4.0   -0.3727 -0.2476 -0.8942
      return VERTS_COLS;
    };

    /*
      Returns the version of this parser.

      @returns {String} parser version.
    */
    this.__defineGetter__("version", function(){
      return version;
    });

    /*
      Get the number of parsed points so far.

      @returns {Number} number of points parsed.
    */
    this.__defineGetter__("numParsedPoints", function(){
      return numParsedPoints;
    });

    /*
      Get the total number of points in the point cloud.

      @returns {Number}
    */
    this.__defineGetter__("numTotalPoints", function(){
      return numTotalPoints;
    });

    /**
      Returns the progress of downloading the point cloud between zero and one.

      @returns {Number} value from zero to one or -1 if unknown.
    */
    this.__defineGetter__("progress", function(){
      return progress;
    });

    /**
      Returns the file size of the resource in bytes.

      @returns {Number} size of resource in bytes.
    */
    this.__defineGetter__("fileSize", function(){
      return fileSizeInBytes;
    });

    /**
      @param path Path to the resource
    */
    this.load = function(path){
      pathToFile = path;

      AJAX = new XMLHttpRequest();

      // put a reference to the parser in the AJAX object
      // so we can give the library a reference to the
      // parser within the AJAX event handler scope.
      // !! eventually need to fix this
      AJAX.parser = this;

      /**
        occurs exactly once when the resource begins
        to be downloaded
      */
      AJAX.onloadstart = function(evt){
        start(AJAX.parser);
      };

      /*
        occurs exactly once, when the file is done
        being downloaded
      */
      AJAX.onload = function(evt){

        var ascData = AJAX.responseText;
        var chunk = null;

        // if the onprogress event didn't get called--we simply got
        // the file in one go, we can parse from start to finish.
        if(onProgressCalled === false){
          chunk = ascData;
        }
        // otherwise the onprogress event was called at least once,
        // that means we need to get the data from a specific point to the end.
        else if(ascData.length - AJAX.lastNewLineIndex > 1){
          chunk = ascData.substring(AJAX.lastNewLineIndex, ascData.length);
        }

        // if the last chunk doesn't have any digits (just spaces)
        // don't parse it.
        if(chunk && chunk.match(/[0-9]/)){
          AJAX.parseChunk(chunk);
        }

        numTotalPoints = numParsedPoints;

        progress = 1;

        end(AJAX.parser);
      }

      /**
        !! fix me
      */
      AJAX.parseChunk = function(chunkData){
        var chunk = chunkData;

        // !! fix this
        // this occurs over network connections, but not locally.
        if(chunk !== ""){

          // !! fix this
          if(layoutCode === UNKNOWN){
            layoutCode = getDataLayout(chunk);
            numValuesPerLine = -1;

            switch(layoutCode){
              case 0: numValuesPerLine = 3;
                      break;
              case 1: numValuesPerLine = 6;
                      colorsPresent = true;
                      break;
              case 2: numValuesPerLine = 6;
                      normalsPresent = true;
                      break;
              case 3: numValuesPerLine = 9;
                      normalsPresent = true;
                      colorsPresent = true;
                      break;
            }
            gotLayout = true;
          }

          // trim trailing spaces
          chunk = chunk.replace(/\s+$/,"");

          // trim leading spaces
          chunk = chunk.replace(/^\s+/,"");

          // split on white space
          chunk = chunk.split(/\s+/);

          var numVerts = chunk.length/numValuesPerLine;
          numParsedPoints += numVerts;

          var verts = new Float32Array(numVerts*3);
          var cols = null;
          var norms = null;

          if(colorsPresent){
            cols = new Float32Array(numVerts*3);
          }

          if(normalsPresent){
            norms = new Float32Array(numVerts*3);
          }

          // depending if there are colors,
          // we'll need to read different indices.
          // if there aren't:
          // x  y  z  r  g  b  nx ny nz
          // 0  1  2  3  4  5  6  7  8 <- normals start at index 6
          //
          // if there are:
          // x  y  z  nx ny nz
          // 0  1  2  3  4  5 <- normals start at index 3
          var valueOffset = 0;
          if(colorsPresent){
            valueOffset = 3;
          }

          // xyz  rgb  normals
          for(var i = 0, j = 0, len = chunk.length; i < len; i += numValuesPerLine, j += 3){
            verts[j]   = parseFloat(chunk[i]);
            verts[j+1] = parseFloat(chunk[i+1]);
            verts[j+2] = parseFloat(chunk[i+2]);

            // XBPS spec for parsers requires colors to be normalized
            if(cols){
              cols[j]   = parseInt(chunk[i+3])/255;
              cols[j+1] = parseInt(chunk[i+4])/255;
              cols[j+2] = parseInt(chunk[i+5])/255;
            }

            if(norms){
              norms[j]   = parseFloat(chunk[i + 3 + valueOffset]);
              norms[j+1] = parseFloat(chunk[i + 4 + valueOffset]);
              norms[j+2] = parseFloat(chunk[i + 5 + valueOffset]);
            }
          }

          // !! pushing on null?
          parsedVerts.push(verts);
          parsedCols.push(cols);
          parsedNorms.push(norms);

          // !! needs test
          // !! needs comment
          var test = {};
          if(verts){test["VERTEX"] = verts;}
          if(cols){test["COLOR"] = cols;}
          if(norms){test["NORMAL"] = norms;}

          parse(AJAX.parser, test);
        }
      };

      /**
        On Minefield, this will occur zero or many times
        On Chrome/WebKit this will occur one or many times
      */
      AJAX.onprogress = function(evt){

       if(evt.lengthComputable){
          fileSizeInBytes = evt.total;
          progress = evt.loaded/evt.total;
        }

        onProgressCalled = true;

        // if we have something to actually parse
        if(AJAX.responseText){
          var ascData = AJAX.responseText;

          // we likely stopped getting data somewhere in the middle of
          // a line in the ASC file

          // 5.813 2.352 6.500 0 0 0 2.646 3.577 2.516\n
          // 1.079 1.296 9.360 0 0 0 4.307 1.181 5.208\n
          // 3.163 2.225 6.139 0 0 0 0.6<-- stopped here

          // So find the last known newline. Everything from the last
          // request to this last newline can be placed in a buffer.
          var lastNewLineIndex = ascData.lastIndexOf("\n");
          AJAX.lastNewLineIndex = lastNewLineIndex;

          // if the status just changed and we finished downloading the
          // file, grab everyting until the end. If there is only a bunch
          // of whitespace, make a note of that and don't bother parsing.
          if(AJAX.readyState === XHR_DONE){
            var chunk = ascData.substring(AJAX.startOfNextChunk, ascData.length);
            // If the last chunk doesn't have any digits (just spaces)
            // don't parse it.
            if(chunk.match(/[0-9]/)){
              AJAX.parseChunk(chunk);
            }
          }
          // if we still have more data to go
          else{
            // Start of the next chunk starts after the newline.
            var chunk = ascData.substring(AJAX.startOfNextChunk, lastNewLineIndex + 1);
            AJAX.startOfNextChunk = lastNewLineIndex + 1;
            AJAX.parseChunk(chunk);
          }
        }
      };//onprogress

      // open an asynchronous request to the path
      AJAX.open("GET", path, true);
      AJAX.send(null);
    };// load
  }//ctor
  return ASCParser;
}());
<commit_msg>renamed test variable<commit_after>/*
  Copyright (c) 2010  Seneca College
  MIT LICENSE

  Version:  0.1
  Author:   Andor Salga
            asalga.wordpress.com
  Date:     November 16, 2010

  Notes:
  This parser parses .ASC filetypes. These files are ASCII
  files which have their data stored in one of the following ways:

  X, Y, Z
  X, Y, Z, R, G, B
  X, Y, Z, I, J, K
  X, Y, Z, R, G, B, I, J, K
*/

var ASCParser = (function() {

  /**
    Constructor
  */
  function ASCParser(config) {

    var undef;

    // defined once to reduce number of empty functions
    var __empty_func = function(){};

    var start = config.start || __empty_func;
    var parse = config.parse || __empty_func;
    var end = config.end || __empty_func;

    var version = "0.1";

    const UNKNOWN = -1;

    const XHR_DONE = 4;
    const STARTED = 1;

    var pathToFile = null;
    var fileSizeInBytes = 0;

    //
    var numParsedPoints = 0;
    var numTotalPoints = 0;
    var progress = 0;

    //
    var numValuesPerLine = -1;
    var normalsPresent = false;
    var colorsPresent = false;
    var layoutCode = UNKNOWN;

    //
    var parsedVerts = [];
    var parsedCols = [];
    var parsedNorms = [];

    // keep track if onprogress event handler was called to
    // handle Chrome/WebKit vs. Minefield differences.
    //
    // Minefield will call onprogress zero or many times
    // Chrome/WebKit will call onprogress one or many times
    var onProgressCalled = false;
    var AJAX = null;

    // WebGL compatibility wrapper
    try{
      Float32Array;
    }catch(ex){
      Float32Array = WebGLFloatArray;
    }

    /**
      @private

      ASC files can either contain
      X, Y, Z
      X, Y, Z, R,  G,  B
      X, Y, Z, NX, NY, NZ
      X, Y, Z, R,  G,  B, NX, NY, NZ

      @returns {Number}
      0 first case
      1 second case
      2 third case
      3 fourth case
    */
    var getDataLayout = function(values){
      var normalsPresent = false;
      var colorsPresent = false;

      var VERTS = 0;
      var VERTS_COLS = 1;
      var VERTS_NORMS = 2;
      var VERTS_COLS_NORMS = 3;

      // first check if there are 9 values, which would mean we have
      // xyz rgb and normals

      // We can do this by counting the number of whitespace on the first line
      var i = 0;
      var numSpaces = 0;
      do{
        i++;
        if(values[i] == " "){
          numSpaces++;
        }
      }while(values[i] != '\n');

      // Vertices, Colors, Normals:
      // 1.916 -2.421 -4.0   64 32 16   -0.3727 -0.2476 -0.8942
      if(numSpaces === 8){
        return VERTS_COLS_NORMS;
      }

      // Just vertices:
      // 1.916 -2.421 -4.0339
      if(numSpaces == 2){
        return VERTS;
      }

      var str = "";

      //
      // !! fix me
      for(i = 0; i < 500; i++){
        str += values[i];
      }

      var str_split = str.split(/\s+/);
      var data = [];

      for(var i = 3; i < str_split.length;){
        data.push(str_split[i++]);
        data.push(str_split[i++]);
        data.push(str_split[i++]);
        i += 3;
      }

      for(var i = 0; i < data.length; i++){
        if(data[i] < 0 || data[i] > 255){
          normalsPresent = true;
          return VERTS_NORMS;
        }
      }

      // Vertices and Normals:
      // 1.916 -2.421 -4.0   -0.3727 -0.2476 -0.8942
      return VERTS_COLS;
    };

    /*
      Returns the version of this parser.

      @returns {String} parser version.
    */
    this.__defineGetter__("version", function(){
      return version;
    });

    /*
      Get the number of parsed points so far.

      @returns {Number} number of points parsed.
    */
    this.__defineGetter__("numParsedPoints", function(){
      return numParsedPoints;
    });

    /*
      Get the total number of points in the point cloud.

      @returns {Number}
    */
    this.__defineGetter__("numTotalPoints", function(){
      return numTotalPoints;
    });

    /**
      Returns the progress of downloading the point cloud between zero and one.

      @returns {Number} value from zero to one or -1 if unknown.
    */
    this.__defineGetter__("progress", function(){
      return progress;
    });

    /**
      Returns the file size of the resource in bytes.

      @returns {Number} size of resource in bytes.
    */
    this.__defineGetter__("fileSize", function(){
      return fileSizeInBytes;
    });

    /**
      @param path Path to the resource
    */
    this.load = function(path){
      pathToFile = path;

      AJAX = new XMLHttpRequest();

      // put a reference to the parser in the AJAX object
      // so we can give the library a reference to the
      // parser within the AJAX event handler scope.
      // !! eventually need to fix this
      AJAX.parser = this;

      /**
        occurs exactly once when the resource begins
        to be downloaded
      */
      AJAX.onloadstart = function(evt){
        start(AJAX.parser);
      };

      /*
        occurs exactly once, when the file is done
        being downloaded
      */
      AJAX.onload = function(evt){

        var ascData = AJAX.responseText;
        var chunk = null;

        // if the onprogress event didn't get called--we simply got
        // the file in one go, we can parse from start to finish.
        if(onProgressCalled === false){
          chunk = ascData;
        }
        // otherwise the onprogress event was called at least once,
        // that means we need to get the data from a specific point to the end.
        else if(ascData.length - AJAX.lastNewLineIndex > 1){
          chunk = ascData.substring(AJAX.lastNewLineIndex, ascData.length);
        }

        // if the last chunk doesn't have any digits (just spaces)
        // don't parse it.
        if(chunk && chunk.match(/[0-9]/)){
          AJAX.parseChunk(chunk);
        }

        numTotalPoints = numParsedPoints;

        progress = 1;

        end(AJAX.parser);
      }

      /**
        !! fix me
      */
      AJAX.parseChunk = function(chunkData){
        var chunk = chunkData;

        // !! fix this
        // this occurs over network connections, but not locally.
        if(chunk !== ""){

          // !! fix this
          if(layoutCode === UNKNOWN){
            layoutCode = getDataLayout(chunk);
            numValuesPerLine = -1;

            switch(layoutCode){
              case 0: numValuesPerLine = 3;
                      break;
              case 1: numValuesPerLine = 6;
                      colorsPresent = true;
                      break;
              case 2: numValuesPerLine = 6;
                      normalsPresent = true;
                      break;
              case 3: numValuesPerLine = 9;
                      normalsPresent = true;
                      colorsPresent = true;
                      break;
            }
            gotLayout = true;
          }

          // trim trailing spaces
          chunk = chunk.replace(/\s+$/,"");

          // trim leading spaces
          chunk = chunk.replace(/^\s+/,"");

          // split on white space
          chunk = chunk.split(/\s+/);

          var numVerts = chunk.length/numValuesPerLine;
          numParsedPoints += numVerts;

          var verts = new Float32Array(numVerts*3);
          var cols = null;
          var norms = null;

          if(colorsPresent){
            cols = new Float32Array(numVerts*3);
          }

          if(normalsPresent){
            norms = new Float32Array(numVerts*3);
          }

          // depending if there are colors,
          // we'll need to read different indices.
          // if there aren't:
          // x  y  z  r  g  b  nx ny nz
          // 0  1  2  3  4  5  6  7  8 <- normals start at index 6
          //
          // if there are:
          // x  y  z  nx ny nz
          // 0  1  2  3  4  5 <- normals start at index 3
          var valueOffset = 0;
          if(colorsPresent){
            valueOffset = 3;
          }

          // xyz  rgb  normals
          for(var i = 0, j = 0, len = chunk.length; i < len; i += numValuesPerLine, j += 3){
            verts[j]   = parseFloat(chunk[i]);
            verts[j+1] = parseFloat(chunk[i+1]);
            verts[j+2] = parseFloat(chunk[i+2]);

            // XBPS spec for parsers requires colors to be normalized
            if(cols){
              cols[j]   = parseInt(chunk[i+3])/255;
              cols[j+1] = parseInt(chunk[i+4])/255;
              cols[j+2] = parseInt(chunk[i+5])/255;
            }

            if(norms){
              norms[j]   = parseFloat(chunk[i + 3 + valueOffset]);
              norms[j+1] = parseFloat(chunk[i + 4 + valueOffset]);
              norms[j+2] = parseFloat(chunk[i + 5 + valueOffset]);
            }
          }

          // !! pushing on null?
          parsedVerts.push(verts);
          parsedCols.push(cols);
          parsedNorms.push(norms);

          // !! needs test
          // !! needs comment
          var attributes = {};
          if(verts){attributes["VERTEX"] = verts;}
          if(cols){attributes["COLOR"] = cols;}
          if(norms){attributes["NORMAL"] = norms;}

          parse(AJAX.parser, attributes);
        }
      };

      /**
        On Minefield, this will occur zero or many times
        On Chrome/WebKit this will occur one or many times
      */
      AJAX.onprogress = function(evt){

       if(evt.lengthComputable){
          fileSizeInBytes = evt.total;
          progress = evt.loaded/evt.total;
        }

        onProgressCalled = true;

        // if we have something to actually parse
        if(AJAX.responseText){
          var ascData = AJAX.responseText;

          // we likely stopped getting data somewhere in the middle of
          // a line in the ASC file

          // 5.813 2.352 6.500 0 0 0 2.646 3.577 2.516\n
          // 1.079 1.296 9.360 0 0 0 4.307 1.181 5.208\n
          // 3.163 2.225 6.139 0 0 0 0.6<-- stopped here

          // So find the last known newline. Everything from the last
          // request to this last newline can be placed in a buffer.
          var lastNewLineIndex = ascData.lastIndexOf("\n");
          AJAX.lastNewLineIndex = lastNewLineIndex;

          // if the status just changed and we finished downloading the
          // file, grab everyting until the end. If there is only a bunch
          // of whitespace, make a note of that and don't bother parsing.
          if(AJAX.readyState === XHR_DONE){
            var chunk = ascData.substring(AJAX.startOfNextChunk, ascData.length);
            // If the last chunk doesn't have any digits (just spaces)
            // don't parse it.
            if(chunk.match(/[0-9]/)){
              AJAX.parseChunk(chunk);
            }
          }
          // if we still have more data to go
          else{
            // Start of the next chunk starts after the newline.
            var chunk = ascData.substring(AJAX.startOfNextChunk, lastNewLineIndex + 1);
            AJAX.startOfNextChunk = lastNewLineIndex + 1;
            AJAX.parseChunk(chunk);
          }
        }
      };//onprogress

      // open an asynchronous request to the path
      AJAX.open("GET", path, true);
      AJAX.send(null);
    };// load
  }//ctor
  return ASCParser;
}());
<|endoftext|>


<commit_before>clui
/**
 * Clipy Tools - User Interface
 *
 * Inject global namespace: clui
 */
=(function(){"use strict";

  /////////////////////////////////////////////////////////////////////////////
  // Public Functions

  /**
   * Request a video inquiry for the particulars like title, duration and description
   *
   * We get back JSON in the response and convert it to an object then load it into the the cache
   * and then insert a display panel for it.
   */
  function inquire() {
    let
      video = document.getElementById('input-video').value,
      url = '/api/inquire?video=' + encodeURIComponent(video),
      _;

    http.get( url )
    .then( json.parse  )
 // .then( _inload     )
    .then( _insert     )
    .fail( console.log )
  }

  /**
   * Display the progress bars
   *
   * Called every few seconds with the servers list of streams actively downloading
   *
   * data: { actives: [ { bytesdone: 91750, elapsed: 7.58, total: 627020, hash: "k12h3..." },... ]}
   */
  function show_progress( data ) {
    let
      status = document.getElementById('running'),
      _;

    if ( u.isObject( data ) ) {
      status.checked = true;

      if ( data.actives ) {
        _add_active_progress_bars( data.actives )
        _remove_dead_progress_bars( data.actives )
      }
    }
    else {
      status.checked = false;
    }
  }

  /**
   * Remove all panels
   */
  function clear() {
    let
      old_panels = document.getElementById('panels'),
      new_panels = document.createElement('ol'),
      contaniner = document.getElementById('panels-container'),
      _;

    // clipy_cache = { 0: null };
    // clipy_index = 1;

    old_panels.remove()
    new_panels.setAttribute('id', 'panels')
    contaniner.appendChild( new_panels )
  }

  /////////////////////////////////////////////////////////////////////////////
  // Private Functions

  /**
   * Surround the given value with corresponding html
   */
  function _markup_value( o ) {
    if ( u.isArray( o )) {
      let
        list = document.createElement('ul'),
        _;

      for ( let i = 0; i < o.length; i++ ) {
        const
          item = document.createElement('li'),
          text = document.createTextNode( o[i] );
        item.appendChild( text )
        list.appendChild( item )
      }
      return list
    }
    return document.createTextNode( o )
  }

  /**
   * Surround the given streams list with corresponding html
   */
  function _markup_streams( streams, vid ) {
    let
      list = document.createElement('ol'),
      _;

    for ( let i = 0; i < streams.length; i++ ) {
      const
        item = document.createElement('li'),
        text = document.createTextNode( streams[i] );

      item.setAttribute('class', 'stream')
      item.setAttribute('title', 'Download this stream')
      item.setAttribute('stream', i )
      item.setAttribute('vid', vid )
      item.appendChild( text )
      item.addEventListener('click', _download, false)

      list.setAttribute('start', 0 )
      list.appendChild( item )
    }
    return list
  }

  /**
   * Load the data into the cache
   */
  function _inload( data ) {
    if ( 'error' in data ) {
      console.log(data.error)
      console.log(data)
      return
    }
    // clipy_cache[ clipy_index++ ] = data;

    return data // chaining
  }

  /**
   * Display the data summary in a new panel
   */
  function _insert( data ) {
    let
      head = _get_panel_header( data ),
      panel = document.createElement('li'),
      panels = document.getElementById('panels'),
      details = _get_details( data ),
      _;

    panel.setAttribute('class', 'panel')
    panel.setAttribute('title', data.vid )
    panel.setAttribute('vid', data.vid )
    panel.appendChild( head )
    panel.appendChild( details )
    panels.appendChild( panel )

    return data // chaining
  }

  /**
   * Construct the panel header line with togglable title and close button
   */
  function _get_panel_header( data ) {
    let
      row = document.createElement('div'),
      left = document.createElement('div'),
      right = document.createElement('div'),
      close = document.createElement('button'),
      text = document.createElement('span'),
      _;

    text.innerText = data.title;
    text.setAttribute('class', 'toggle')
    text.addEventListener('click', _toggle, false)

    left.setAttribute('class', 'eleven columns')
    left.appendChild( text )

    close.setAttribute('class', 'button close')
    close.setAttribute('title', 'Close this panel')
    close.innerText = 'X';
    close.addEventListener('click', _close, false)

    right.setAttribute('class', 'one columns')
    right.appendChild( close )

    row.setAttribute('class', 'row')
    row.appendChild( left )
    row.appendChild( right )

    return row
  }

  /**
   * Construct the video data details
   */
  function _get_details( data ) {
    let
      list = document.createElement('dl'),
      details = document.createElement('div'),
      _;

    for (const [key,val] of es.objectEntries( data )) {
      let value = key === 'streams' ? _markup_streams( val, data.vid ) : _markup_value( val );
      let term = document.createElement('dt'); term.appendChild( document.createTextNode( key ))
      let item = document.createElement('dd'); item.appendChild( value )
      // console.log(`${key}: ${value}`);
      list.appendChild( term )
      list.appendChild( item )
    }
    details.style.display = 'none';
    details.setAttribute('class', 'details')
    details.appendChild( list )

    return details
  }

  /**
   * Show / hide the video details
   */
  function _close( e ) {
    let
      panel = e.target.parentElement.parentElement.parentElement;

    panel.remove()
  }

  /**
   * Show / hide the video details
   */
  function _toggle( e ) {
    let
      style = e.target.parentElement.parentElement.parentElement.children[1].style;

    if ( style.display === 'none' )
      style.display = '';
    else
      style.display = 'none';
  }

  /**
   * Get the goods
   */
  function _download( e ) {
    let
      vid = e.target.attributes.vid.value,
      stream = e.target.attributes.stream.value,
      url = '/api/download?vid=' + encodeURIComponent(vid) + '&stream=' + encodeURIComponent(stream),
      _;

    http.get( url )
    .then( json.parse  )
    .then( console.log )
    .fail( console.log )
  }

  /**
   * Cancel a download in progress
   */
  function _cancel( e ) {
    let
      id = e.target.id,
      url = '/api/cancel?hash=' + encodeURIComponent(id),
      _;

    http.get( url )
    .then( json.parse  )
    .then( console.log )
    .fail( console.log )
  }

  /**
   * Display the progress bars
   *
   * streams: [ { bytesdone: 91750, elapsed: 7.58, total: 627020, hash: "60b6f8b8898d4..."" },... ]
   */
  function _add_active_progress_bars( streams ) {
    for ( let stream of streams ) {
      let
        progress = document.getElementById( stream.hash ),
        item = undefined,
        _;

      if ( !progress ) {
        progress = document.createElement('progress');
        progress.id = stream.hash;
        progress.setAttribute('title', stream.name )
        item = document.createElement('li');
        item.appendChild( progress )
        item.addEventListener('click', _cancel, false)
        document.getElementById('progress-bars').appendChild( item )
      }
      progress.setAttribute('value', stream.bytesdone )
      progress.setAttribute('max', stream.total )
    }
  }

  /**
   * Remove and progress bars that are no longer active
   *
   * streams: [ { bytesdone: 91750, elapsed: 7.58, total: 627020, hash: "60b6f8b8898d4..."" },... ]
   */
  function _remove_dead_progress_bars( streams ) {
    let
      bars = document.getElementsByTagName('progress'),
      _;

    for (let i = bars.length - 1; i >= 0; i--) {
      let progress = bars.item(i);

      function active( value, index ) {
        return value.hash === progress.id
      }

      if ( !streams.find( active ) ) {
        progress.parentElement.remove()
      }
    }
  }

  /////////////////////////////////////////////////////////////////////////////
  // Declare Public interface

  return {
    show_progress: show_progress,
    inquire: inquire,
    clear: clear,
  }

}())
<commit_msg>click progress does inquire not canel<commit_after>clui
/**
 * Clipy Tools - User Interface
 *
 * Inject global namespace: clui
 */
=(function(){"use strict";

  /////////////////////////////////////////////////////////////////////////////
  // Public Functions

  /**
   * Request a video inquiry for the particulars like title, duration and description
   *
   * We get back JSON in the response and convert it to an object then load it into the the cache
   * and then insert a display panel for it.
   */
  function inquire( element ) {
    let
      vid = element ? element.target.vid : undefined,
      video = vid ? vid : document.getElementById('input-video').value,
      url = '/api/inquire?video=' + encodeURIComponent(video),
      _;

    http.get( url )
    .then( json.parse  )
 // .then( _inload     )
    .then( _insert     )
    .fail( console.log )
  }

  /**
   * Display the progress bars
   *
   * Called every few seconds with the servers list of streams actively downloading
   *
   * data: { actives: [ { bytesdone: 91750, elapsed: 7.58, total: 627020, hash: "k12h3..." },... ]}
   */
  function show_progress( data ) {
    let
      status = document.getElementById('running'),
      _;

    if ( u.isObject( data ) ) {
      status.checked = true;

      if ( data.actives ) {
        _add_active_progress_bars( data.actives )
        _remove_dead_progress_bars( data.actives )
      }
    }
    else {
      status.checked = false;
    }
  }

  /**
   * Remove all panels
   */
  function clear() {
    let
      old_panels = document.getElementById('panels'),
      new_panels = document.createElement('ol'),
      contaniner = document.getElementById('panels-container'),
      _;

    // clipy_cache = { 0: null };
    // clipy_index = 1;

    old_panels.remove()
    new_panels.setAttribute('id', 'panels')
    contaniner.appendChild( new_panels )
  }

  /////////////////////////////////////////////////////////////////////////////
  // Private Functions

  /**
   * Surround the given value with corresponding html
   */
  function _markup_value( o ) {
    if ( u.isArray( o )) {
      let
        list = document.createElement('ul'),
        _;

      for ( let i = 0; i < o.length; i++ ) {
        const
          item = document.createElement('li'),
          text = document.createTextNode( o[i] );
        item.appendChild( text )
        list.appendChild( item )
      }
      return list
    }
    return document.createTextNode( o )
  }

  /**
   * Surround the given streams list with corresponding html
   */
  function _markup_streams( streams, vid ) {
    let
      list = document.createElement('ol'),
      _;

    for ( let i = 0; i < streams.length; i++ ) {
      const
        item = document.createElement('li'),
        text = document.createTextNode( streams[i] );

      item.setAttribute('class', 'stream')
      item.setAttribute('title', 'Download this stream')
      item.setAttribute('stream', i )
      item.setAttribute('vid', vid )
      item.appendChild( text )
      item.addEventListener('click', _download, false)

      list.setAttribute('start', 0 )
      list.appendChild( item )
    }
    return list
  }

  /**
   * Load the data into the cache
   */
  function _inload( data ) {
    if ( 'error' in data ) {
      console.log(data.error)
      console.log(data)
      return
    }
    // clipy_cache[ clipy_index++ ] = data;

    return data // chaining
  }

  /**
   * Display the data summary in a new panel
   */
  function _insert( data ) {
    let
      head = _get_panel_header( data ),
      panel = document.createElement('li'),
      panels = document.getElementById('panels'),
      details = _get_details( data ),
      _;

    panel.setAttribute('class', 'panel')
    panel.setAttribute('title', data.vid )
    panel.setAttribute('vid', data.vid )
    panel.appendChild( head )
    panel.appendChild( details )
    panels.appendChild( panel )

    return data // chaining
  }

  /**
   * Construct the panel header line with togglable title and close button
   */
  function _get_panel_header( data ) {
    let
      row = document.createElement('div'),
      left = document.createElement('div'),
      right = document.createElement('div'),
      close = document.createElement('button'),
      text = document.createElement('span'),
      _;

    text.innerText = data.title;
    text.setAttribute('class', 'toggle')
    text.addEventListener('click', _toggle, false)

    left.setAttribute('class', 'eleven columns')
    left.appendChild( text )

    close.setAttribute('class', 'button close')
    close.setAttribute('title', 'Close this panel')
    close.innerText = 'X';
    close.addEventListener('click', _close, false)

    right.setAttribute('class', 'one columns')
    right.appendChild( close )

    row.setAttribute('class', 'row')
    row.appendChild( left )
    row.appendChild( right )

    return row
  }

  /**
   * Construct the video data details
   */
  function _get_details( data ) {
    let
      list = document.createElement('dl'),
      details = document.createElement('div'),
      _;

    for (const [key,val] of es.objectEntries( data )) {
      let value = key === 'streams' ? _markup_streams( val, data.vid ) : _markup_value( val );
      let term = document.createElement('dt'); term.appendChild( document.createTextNode( key ))
      let item = document.createElement('dd'); item.appendChild( value )
      // console.log(`${key}: ${value}`);
      list.appendChild( term )
      list.appendChild( item )
    }
    details.style.display = 'none';
    details.setAttribute('class', 'details')
    details.appendChild( list )

    return details
  }

  /**
   * Show / hide the video details
   */
  function _close( e ) {
    let
      panel = e.target.parentElement.parentElement.parentElement;

    panel.remove()
  }

  /**
   * Show / hide the video details
   */
  function _toggle( e ) {
    let
      style = e.target.parentElement.parentElement.parentElement.children[1].style;

    if ( style.display === 'none' )
      style.display = '';
    else
      style.display = 'none';
  }

  /**
   * Get the goods
   */
  function _download( e ) {
    let
      vid = e.target.attributes.vid.value,
      stream = e.target.attributes.stream.value,
      url = '/api/download?vid=' + encodeURIComponent(vid) + '&stream=' + encodeURIComponent(stream),
      _;

    http.get( url )
    .then( json.parse  )
    .then( console.log )
    .fail( console.log )
  }

  /**
   * Cancel a download in progress
   */
  function _cancel( element ) {
    let
      hash = element.target.hash,
      url = '/api/cancel?hash=' + encodeURIComponent(hash),
      _;

    http.get( url )
    .then( json.parse  )
    .then( console.log )
    .fail( console.log )
  }

  /**
   * Display the progress bars
   *
   * streams: [ { bytesdone: 91750, elapsed: 7.58, total: 627020, hash: "60b6f8b8898d4..."" },... ]
   */
  function _add_active_progress_bars( streams ) {
    for ( let stream of streams ) {
      let
        progress = document.getElementById( stream.hash ),
        item = undefined,
        _;

      if ( !progress ) {
        progress = document.createElement('progress');
        progress.vid = stream.vid;
        progress.id = stream.hash;
        progress.setAttribute('title', stream.name )
        item = document.createElement('li');
        item.appendChild( progress )
        item.addEventListener('click', inquire, false)
        // item.addEventListener('click', _cancel, false)
        document.getElementById('progress-bars').appendChild( item )
      }
      progress.setAttribute('value', stream.bytesdone )
      progress.setAttribute('max', stream.total )
    }
  }

  /**
   * Remove and progress bars that are no longer active
   *
   * streams: [ { bytesdone: 91750, elapsed: 7.58, total: 627020, hash: "60b6f8b8898d4..."" },... ]
   */
  function _remove_dead_progress_bars( streams ) {
    let
      bars = document.getElementsByTagName('progress'),
      _;

    for (let i = bars.length - 1; i >= 0; i--) {
      let progress = bars.item(i);

      function active( value, index ) {
        return value.hash === progress.id
      }

      if ( !streams.find( active ) ) {
        progress.parentElement.remove()
      }
    }
  }

  /////////////////////////////////////////////////////////////////////////////
  // Declare Public interface

  return {
    show_progress: show_progress,
    inquire: inquire,
    clear: clear,
  }

}())
<|endoftext|>


<commit_before>// SELECTOR BOX ------------------------------------------------------------------------------------
console.log("DepthJS: Loading SelectorBox");

DepthJS.selectorBox.firstMove = null;

DepthJS.selectorBox.init = function() {
  console.log("Initing selector box");
  var $box = $("

");
  $box.appendTo("body").hide();
  DepthJS.selectorBox.$box = $box;
  console.log(DepthJS.selectorBox.$box);
  console.log($("body"));
};

DepthJS.selectorBox.show = function() {
  DepthJS.selectorBox.$box.show();
  DepthJS.selectorBox.firstMove = null;
};

DepthJS.selectorBox.hide = function() {
  DepthJS.selectorBox.$box.hide();
  DepthJS.selectorBox.firstMove = null;
};

DepthJS.selectorBox.move = function(x, y) {
  if (DepthJS.selectorBox.firstMove == null) {
    DepthJS.selectorBox.firstMove = [x, y];
    console.log("first move, x=" + x + " y=" + y);
    return;
  }

  // x = x - DepthJS.selectorBox.firstMove[0];
  // y = y - DepthJS.selectorBox.firstMove[1];

  x = (x - 50) / 15.0;
  y = (y - 50) / 15.0;

  var hwidth = $(window).width() * 0.5;
  var hheight = $(window).height() * 0.5;
  x =  hwidth*x + hwidth;
  y =  hheight*y + hheight;

   // Constrain to window
  if (x < 0) x = 0;
  if (y < 0) y = 0;
  var $box = DepthJS.selectorBox.$box;
  x = Math.min(x, $(window).width() - $box.width());
  y = Math.min(y, $(window).height() - $box.height());
  console.log("move selector box to " + x + ", " + y);
  if (x != $box.css("left") || y != $box.css("top")) {
    $box.css({left: x, top: y});
  }
};

DepthJS.selectorBox.activate = function() {
  if (DepthJS.verbose) console.log("DepthJS: Activating underneath selectorBox");
  // Lame code for now...

  var $intersectingLinks = $("a").filter(function() {
    var $a = $(this);
    var ax = $a.offset().left + $(window).scrollLeft();
    var aw = $a.width();
    var ay = $a.offset().top + $(window).scrollTop();
    var ah = $a.height();

    var $box = DepthJS.selectorBox.$box;
    var bx = $box.position().left;
    var by = $box.position().top;
    var bw = $box.width();
    var bh = $box.height();

    if (by > ay + ah || // box-top is lower than link-bottom
        by + bh < ay || // box-bottom is higher than link-top
        bx > ax + aw || // box-left is right of link right
        bx + bw < aw) { // box-right is left of link left
      return false;
    }
    return true;
  });

  if (DepthJS.verbose) console.log("Got " + $intersectingLinks.length + " links");
  if (DepthJS.verbose) console.log($intersectingLinks);
  if ($intersectingLinks.length > 0) {
    DepthJS.selectorBoxPopup.$links = $intersectingLinks;
    DepthJS.selectorBoxPopup.activate();
  }
};

// SELECTOR BOX POPUP ------------------------------------------------------------------------------
DepthJS.selectorBoxPopup.activate = function(){
  if (DepthJS.verbose) console.log("Activating selectorbox popup");
  var $links = DepthJS.selectorBoxPopup.$links;
  DepthJS.state = "selectorBoxPopup";
  var $box = DepthJS.selectorBox.$box;
  var position = "top:" + $box.position().top + "px; left:" + $box.position().left + "px";
  $("body").append("

");
  var popupContent = "";
  var popupItemIndex = 0;
  for(var i = 0; i < $links.length; i++){
    var linkText = $($links[i]).text();

    if (linkText.length <= 0) continue;

    if (linkText.indexOf(" 0) {
      popupContent += "
" +
      linkText.substring(0,70) + "
";
    } else {
      popupContent += "
" +
      $($links[i]).html() + "
";
    }
    popupItemIndex += 1;
  }
  DepthJS.selectorBox.$box.hide();
  $("#DepthJS_selectorBoxPopup").html(popupContent);
};

DepthJS.selectorBoxPopup.move = function(x, y) {
  if (DepthJS.verbose) console.log("move selector box popup (" + x + ", " + y + ")");
  if (y == 0) y = 1;

  var $links = DepthJS.selectorBoxPopup.$links;
  var popupHeight = $("#DepthJS_selectorBoxPopup").height();
  y = (y * popupHeight / 100) / (popupHeight / $links.length);
  var closestLinkIndex = Math.min($links.length-1, Math.round(y));
  if (DepthJS.verbose) console.log("Closest link is " + closestLinkIndex);

  var $lastHighlightedLink = DepthJS.selectorBoxPopup.$lastHighlightedLink;
  if ($lastHighlightedLink != null){
    $lastHighlightedLink.removeClass("DepthJS_selectorBoxPopupItemHighlight");
  }
  var $closestLink = $("#DepthJS_popupItem" + closestLinkIndex);
  $closestLink.addClass("DepthJS_selectorBoxPopupItemHighlight");
  DepthJS.selectorBoxPopup.lastHighlightedLinkIndex = closestLinkIndex;
  DepthJS.selectorBoxPopup.$lastHighlightedLink = $closestLink;
};

DepthJS.selectorBoxPopup.openHighlightedLink = function(){
  var $links = DepthJS.selectorBoxPopup.$links;
  var lastHighlightedLinkIndex = DepthJS.selectorBoxPopup.lastHighlightedLinkIndex;

  if (lastHighlightedLinkIndex < 0 || lastHighlightedLinkIndex > $links.length) return;
  var $linkToOpen = $links.eq(lastHighlightedLinkIndex);

  var evt = document.createEvent("MouseEvents");
  evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
  $linkToOpen[0].dispatchEvent(evt);
};

DepthJS.selectorBoxPopup.hide = function(){
  $("#DepthJS_selectorBoxPopup").fadeOut(300, function(){
    $("#DepthJS_selectorBoxPopup").remove();
  });
};<commit_msg>trying to fix js bug in selector box<commit_after>// SELECTOR BOX ------------------------------------------------------------------------------------
console.log("DepthJS: Loading SelectorBox");

DepthJS.selectorBox.firstMove = null;

DepthJS.selectorBox.init = function() {
  console.log("Initing selector box");
  var $box = $("

");
  $box.appendTo("body").hide();
  DepthJS.selectorBox.$box = $box;
  console.log(DepthJS.selectorBox.$box);
  console.log($("body"));
};

DepthJS.selectorBox.show = function() {
  DepthJS.selectorBox.$box.show();
  DepthJS.selectorBox.firstMove = null;
};

DepthJS.selectorBox.hide = function() {
  DepthJS.selectorBox.$box.hide();
  DepthJS.selectorBox.firstMove = null;
};

DepthJS.selectorBox.move = function(x, y) {
  if (DepthJS.selectorBox.firstMove == null) {
    DepthJS.selectorBox.firstMove = [x, y];
    console.log("first move, x=" + x + " y=" + y);
    return;
  }

  // x = x - DepthJS.selectorBox.firstMove[0];
  // y = y - DepthJS.selectorBox.firstMove[1];

  x = (x - 50) / 15.0;
  y = (y - 50) / 15.0;

  var hwidth = $(window).width() * 0.5;
  var hheight = $(window).height() * 0.5;
  x =  hwidth*x + hwidth;
  y =  hheight*y + hheight;

   // Constrain to window
  if (x < 0) x = 0;
  if (y < 0) y = 0;
  var $box = DepthJS.selectorBox.$box;
  x = Math.min(x, $(window).width() - $box.width());
  y = Math.min(y, $(window).height() - $box.height());
  console.log("move selector box to " + x + ", " + y);
  if (x != $box.css("left") || y != $box.css("top")) {
    $box.css({left: x, top: y});
  }
};

DepthJS.selectorBox.activate = function() {
  if (DepthJS.verbose) console.log("DepthJS: Activating underneath selectorBox");
  // Lame code for now...

  var $intersectingLinks = $("a").filter(function() {
    var $a = $(this);
    var ax = $a.offset().left + $(window).scrollLeft();
    var aw = $a.width();
    var ay = $a.offset().top + $(window).scrollTop();
    var ah = $a.height();

    var $box = DepthJS.selectorBox.$box;
    var bx = $box.position().left;
    var by = $box.position().top;
    var bw = $box.width();
    var bh = $box.height();

    if (by > ay + ah || // box-top is lower than link-bottom
        by + bh < ay || // box-bottom is higher than link-top
        bx > ax + aw || // box-left is right of link right
        bx + bw < aw) { // box-right is left of link left
      return false;
    }
    return true;
  });

  if (DepthJS.verbose) console.log("Got " + $intersectingLinks.length + " links");
  if (DepthJS.verbose) console.log($intersectingLinks);
  if ($intersectingLinks.length > 0) {
    DepthJS.selectorBoxPopup.$links = $intersectingLinks;
    DepthJS.selectorBoxPopup.activate();
  }
};

// SELECTOR BOX POPUP ------------------------------------------------------------------------------
DepthJS.selectorBoxPopup.activate = function(){
  if (DepthJS.verbose) console.log("Activating selectorbox popup");
  var $links = DepthJS.selectorBoxPopup.$links;

  if ($links.length == 1){
    var evt = document.createEvent("MouseEvents");
    evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
    $links[0].dispatchEvent(evt);
    return;
  }

  DepthJS.state = "selectorBoxPopup";
  var $box = DepthJS.selectorBox.$box;
  var position = "top:" + $box.position().top + "px; left:" + $box.position().left + "px";
  $("body").append("

");

  var popupContent = "";
  var popupItemIndex = 0;

  for(var i = 0; i < $links.length; i++){
    var linkText = $($links[i]).text();

    if (linkText.length <= 0) continue;

    if (linkText.indexOf(" 0) {
      popupContent += "
" +
      linkText.substring(0,70) + "
";
    } else {
      popupContent += "
" +
      $($links[i]).html() + "
";
    }
    popupItemIndex += 1;
  }
  DepthJS.selectorBox.$box.hide();
  $("#DepthJS_selectorBoxPopup").html(popupContent);
};

DepthJS.selectorBoxPopup.move = function(x, y) {
  if (DepthJS.verbose) console.log("move selector box popup (" + x + ", " + y + ")");
  if (y == 0) y = 1;

  var $links = DepthJS.selectorBoxPopup.$links;
  var popupHeight = $("#DepthJS_selectorBoxPopup").height();
  y = (y * popupHeight / 100) / (popupHeight / $links.length);
  var closestLinkIndex = Math.min($links.length-1, Math.round(y));
  if (DepthJS.verbose) console.log("Closest link is " + closestLinkIndex);

  var $lastHighlightedLink = DepthJS.selectorBoxPopup.$lastHighlightedLink;
  if ($lastHighlightedLink != null){
    $lastHighlightedLink.removeClass("DepthJS_selectorBoxPopupItemHighlight");
  }
  var $closestLink = $("#DepthJS_popupItem" + closestLinkIndex);
  $closestLink.addClass("DepthJS_selectorBoxPopupItemHighlight");
  DepthJS.selectorBoxPopup.lastHighlightedLinkIndex = closestLinkIndex;
  DepthJS.selectorBoxPopup.$lastHighlightedLink = $closestLink;
};

DepthJS.selectorBoxPopup.openHighlightedLink = function(){
  var $links = DepthJS.selectorBoxPopup.$links;
  var lastHighlightedLinkIndex = DepthJS.selectorBoxPopup.lastHighlightedLinkIndex;

  if (lastHighlightedLinkIndex < 0 || lastHighlightedLinkIndex > $links.length) return;
  var $linkToOpen = $links.eq(lastHighlightedLinkIndex);

  var evt = document.createEvent("MouseEvents");
  evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
  $linkToOpen[0].dispatchEvent(evt);
};

DepthJS.selectorBoxPopup.hide = function(){
  $("#DepthJS_selectorBoxPopup").fadeOut(300, function(){
    $("#DepthJS_selectorBoxPopup").remove();
  });
};<|endoftext|>